• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

wirenboard / wb-mqtt-serial / 1

08 Jul 2025 01:20PM UTC coverage: 73.854% (+1.0%) from 72.836%
1

Pull #963

github

39d9bc
KraPete
Bump version
Pull Request #963: Bump version

6444 of 9057 branches covered (71.15%)

12341 of 16710 relevant lines covered (73.85%)

305.53 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

91.51
/test/modbus_tcp_test.cpp
1
#include "fake_serial_port.h"
2
#include "modbus_common.h"
3

4
namespace
5
{
6
    class TPortMock: public TPort
7
    {
8
        size_t Pointer = 0;
9
        std::vector<uint8_t> Stream;
10
        std::vector<uint8_t> LastRequest;
11

12
    public:
13
        TPortMock(const std::vector<uint8_t>& stream): Stream(stream)
8✔
14
        {}
8✔
15

16
        void Open() override
×
17
        {}
18
        void Close() override
×
19
        {}
20
        bool IsOpen() const override
×
21
        {
22
            return false;
×
23
        }
24
        void CheckPortOpen() const override
×
25
        {}
26

27
        void WriteBytes(const uint8_t* buf, int count) override
9✔
28
        {
29
            LastRequest.assign(buf, buf + count);
9✔
30
        }
9✔
31

32
        uint8_t ReadByte(const std::chrono::microseconds& timeout) override
×
33
        {
34
            return 0;
×
35
        }
36

37
        TReadFrameResult ReadFrame(uint8_t* buf,
22✔
38
                                   size_t count,
39
                                   const std::chrono::microseconds& responseTimeout,
40
                                   const std::chrono::microseconds& frameTimeout,
41
                                   TFrameCompletePred frame_complete = 0) override
42
        {
43
            TReadFrameResult res;
22✔
44
            if (Pointer == Stream.size()) {
22✔
45
                std::this_thread::sleep_for(std::chrono::milliseconds(15));
2✔
46
                Pointer = 0;
2✔
47
            }
48
            res.Count = std::min(count, Stream.size() - Pointer);
22✔
49
            memcpy(buf, &Stream[Pointer], res.Count);
22✔
50
            Pointer += res.Count;
22✔
51
            return res;
22✔
52
        }
53

54
        void SkipNoise() override
×
55
        {}
56

57
        void SleepSinceLastInteraction(const std::chrono::microseconds& us) override
×
58
        {}
59

60
        std::string GetDescription(bool verbose) const override
17✔
61
        {
62
            return std::string();
17✔
63
        }
64

65
        const std::vector<uint8_t>& GetLastRequest() const
4✔
66
        {
67
            return LastRequest;
4✔
68
        }
69
    };
70
}
71

72
class TModbusTCPTraitsTest: public testing::Test
73
{
74
public:
75
    void TestEqual(const std::vector<uint8_t>& b1, const std::vector<uint8_t>& b2) const
4✔
76
    {
77
        ASSERT_EQ(b1.size(), b2.size());
4✔
78

79
        for (size_t i = 0; i < b1.size(); ++i) {
13✔
80
            ASSERT_EQ(b1[i], b2[i]) << i;
9✔
81
        }
82
    }
83
};
84

85
TEST_F(TModbusTCPTraitsTest, ReadFrameGood)
8✔
86
{
87
    std::vector<uint8_t> r = {0, 1, 0, 0, 0, 3, 100, 17, 18};
2✔
88
    TPortMock port(r);
2✔
89
    Modbus::TModbusTCPTraits::ResetTransactionId(port);
2✔
90
    Modbus::TModbusTCPTraits traits;
2✔
91
    std::chrono::milliseconds t(10);
2✔
92

93
    std::vector<uint8_t> req = {7, 8, 9};
2✔
94
    auto resp = traits.Transaction(port, 100, req, 2, t, t).Pdu;
2✔
95
    ASSERT_EQ(resp.size(), 2);
2✔
96
    TestEqual(resp, {17, 18});
2✔
97
}
98

99
TEST_F(TModbusTCPTraitsTest, ReadFrameSmallMBAP)
8✔
100
{
101
    TPortMock port({0, 1, 0, 0});
4✔
102
    Modbus::TModbusTCPTraits::ResetTransactionId(port);
2✔
103
    Modbus::TModbusTCPTraits traits;
2✔
104
    std::chrono::milliseconds t(10);
2✔
105

106
    std::vector<uint8_t> req = {7, 8, 9};
2✔
107
    ASSERT_THROW(traits.Transaction(port, 100, req, 2, t, t), Modbus::TMalformedResponseError);
2✔
108
}
109

110
TEST_F(TModbusTCPTraitsTest, ReadFrameSmallMBAPLength)
8✔
111
{
112
    TPortMock port({0, 1, 0, 0, 0, 0, 100, 7, 8, 9});
4✔
113
    Modbus::TModbusTCPTraits::ResetTransactionId(port);
2✔
114
    Modbus::TModbusTCPTraits traits;
2✔
115
    std::chrono::milliseconds t(10);
2✔
116

117
    std::vector<uint8_t> req = {7, 8, 9};
2✔
118
    ASSERT_THROW(traits.Transaction(port, 100, req, 2, t, t), Modbus::TMalformedResponseError);
2✔
119
}
120

121
TEST_F(TModbusTCPTraitsTest, ReadFrameSmallPDU)
8✔
122
{
123
    TPortMock port({0, 1, 0, 0, 0, 4, 100, 7});
4✔
124
    Modbus::TModbusTCPTraits::ResetTransactionId(port);
2✔
125
    Modbus::TModbusTCPTraits traits;
2✔
126
    std::chrono::milliseconds t(10);
2✔
127

128
    std::vector<uint8_t> req = {7, 8, 9};
2✔
129
    ASSERT_THROW(traits.Transaction(port, 100, req, 2, t, t), Modbus::TMalformedResponseError);
2✔
130
}
131

132
TEST_F(TModbusTCPTraitsTest, ReadFrameWrongUnitId)
8✔
133
{
134
    TPortMock port({0, 1, 0, 0, 0, 4, 101, 7, 8, 9});
4✔
135
    Modbus::TModbusTCPTraits::ResetTransactionId(port);
2✔
136
    Modbus::TModbusTCPTraits traits;
2✔
137
    std::chrono::milliseconds t(10);
2✔
138

139
    std::vector<uint8_t> req = {7, 8, 9};
2✔
140
    ASSERT_THROW(traits.Transaction(port, 100, req, 2, t, t), Modbus::TUnexpectedResponseError);
2✔
141
}
142

143
TEST_F(TModbusTCPTraitsTest, ReadFramePassWrongTransactionId)
8✔
144
{
145
    std::vector<uint8_t> goodResp = {0, 1, 0, 0, 0, 4, 100, 17, 18, 19};
4✔
146
    std::vector<uint8_t> r = {0, 2, 0, 0, 0, 8, 101, 7, 8, 9, 10, 11, 12, 13};
4✔
147
    r.insert(r.end(), goodResp.begin(), goodResp.end());
2✔
148
    TPortMock port(r);
4✔
149

150
    Modbus::TModbusTCPTraits::ResetTransactionId(port);
2✔
151
    Modbus::TModbusTCPTraits traits;
4✔
152
    std::chrono::milliseconds t(10);
2✔
153

154
    std::vector<uint8_t> req = {7, 8, 9};
2✔
155
    TestEqual(traits.Transaction(port, 100, req, 2, t, t).Pdu, {17, 18, 19});
2✔
156
}
2✔
157

158
TEST_F(TModbusTCPTraitsTest, ReadFrameTimeout)
8✔
159
{
160
    TPortMock port({0, 2, 0, 0, 0, 4, 101, 7, 8, 9});
4✔
161
    Modbus::TModbusTCPTraits::ResetTransactionId(port);
2✔
162
    Modbus::TModbusTCPTraits traits;
2✔
163
    std::chrono::milliseconds t(10);
2✔
164

165
    std::vector<uint8_t> req = {7, 8, 9};
2✔
166
    ASSERT_THROW(traits.Transaction(port, 100, req, 2, t, t), TResponseTimeoutException);
2✔
167
}
168

169
TEST_F(TModbusTCPTraitsTest, IncrementTransactionId)
4✔
170
{
171
    std::vector<uint8_t> r = {0, 1, 0, 0, 0, 3, 100, 17, 18, 0, 2, 0, 0, 0, 3, 100, 19, 20};
1✔
172
    TPortMock port(r);
1✔
173
    Modbus::TModbusTCPTraits::ResetTransactionId(port);
1✔
174
    Modbus::TModbusTCPTraits traits;
1✔
175
    std::chrono::milliseconds t(10);
1✔
176

177
    std::vector<uint8_t> req = {7, 8, 9};
1✔
178
    auto resp = traits.Transaction(port, 100, req, 2, t, t).Pdu;
1✔
179
    ASSERT_EQ(resp.size(), 2);
1✔
180
    TestEqual(resp, {17, 18});
1✔
181
    ASSERT_EQ(port.GetLastRequest()[0], 0);
1✔
182
    ASSERT_EQ(port.GetLastRequest()[1], 1);
1✔
183

184
    Modbus::TModbusTCPTraits traits2;
1✔
185
    req.assign({10, 11, 12});
1✔
186
    resp = traits2.Transaction(port, 100, req, 2, t, t).Pdu;
1✔
187
    ASSERT_EQ(resp.size(), 2);
1✔
188
    TestEqual(resp, {19, 20});
1✔
189
    ASSERT_EQ(port.GetLastRequest()[0], 0);
1✔
190
    ASSERT_EQ(port.GetLastRequest()[1], 2);
1✔
191
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc