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

wirenboard / wb-mqtt-serial / 2

29 Dec 2025 12:28PM UTC coverage: 76.817% (+4.0%) from 72.836%
2

Pull #1045

github

54aa0c
pgasheev
up changelog
Pull Request #1045: Fix firmware version in WB-M1W2 template

6873 of 9161 branches covered (75.02%)

12966 of 16879 relevant lines covered (76.82%)

1651.61 hits per line

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

86.61
/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)
16✔
14
        {}
16✔
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
18✔
28
        {
29
            LastRequest.assign(buf, buf + count);
18✔
30
        }
18✔
31

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

37
        TReadFrameResult ReadFrame(uint8_t* buf,
44✔
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;
44✔
44
            if (Pointer == Stream.size()) {
44✔
45
                std::this_thread::sleep_for(std::chrono::milliseconds(15));
4✔
46
                Pointer = 0;
4✔
47
            }
48
            res.Count = std::min(count, Stream.size() - Pointer);
44✔
49
            memcpy(buf, &Stream[Pointer], res.Count);
44✔
50
            Pointer += res.Count;
44✔
51
            return res;
44✔
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
34✔
61
        {
62
            return std::string();
34✔
63
        }
64

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

70
        std::chrono::microseconds GetSendTimeBytes(double bytesNumber) const override
×
71
        {
72
            // 8-N-2
73
            auto bits = std::ceil(11 * bytesNumber);
×
74
            return GetSendTimeBits(bits);
×
75
        }
76

77
        std::chrono::microseconds GetSendTimeBits(size_t bitsNumber) const override
×
78
        {
79
            // 115200 bps
80
            auto us = std::ceil((1000000.0 * bitsNumber) / 115200.0);
×
81
            return std::chrono::microseconds(static_cast<std::chrono::microseconds::rep>(us));
×
82
        }
83
    };
84
}
85

86
class TModbusTCPTraitsTest: public testing::Test
87
{
88
public:
89
    void TestEqual(const std::vector<uint8_t>& b1, const std::vector<uint8_t>& b2) const
8✔
90
    {
91
        ASSERT_EQ(b1.size(), b2.size());
8✔
92

93
        for (size_t i = 0; i < b1.size(); ++i) {
26✔
94
            ASSERT_EQ(b1[i], b2[i]) << i;
18✔
95
        }
96
    }
97
};
98

99
TEST_F(TModbusTCPTraitsTest, ReadFrameGood)
16✔
100
{
101
    std::vector<uint8_t> r = {0, 1, 0, 0, 0, 3, 100, 17, 18};
4✔
102
    TPortMock port(r);
4✔
103
    Modbus::TModbusTCPTraits::ResetTransactionId(port);
4✔
104
    Modbus::TModbusTCPTraits traits;
4✔
105
    std::chrono::milliseconds t(10);
4✔
106

107
    std::vector<uint8_t> req = {7, 8, 9};
4✔
108
    auto resp = traits.Transaction(port, 100, req, 2, t, t).Pdu;
4✔
109
    ASSERT_EQ(resp.size(), 2);
4✔
110
    TestEqual(resp, {17, 18});
4✔
111
}
112

113
TEST_F(TModbusTCPTraitsTest, ReadFrameSmallMBAP)
16✔
114
{
115
    TPortMock port({0, 1, 0, 0});
8✔
116
    Modbus::TModbusTCPTraits::ResetTransactionId(port);
4✔
117
    Modbus::TModbusTCPTraits traits;
4✔
118
    std::chrono::milliseconds t(10);
4✔
119

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

124
TEST_F(TModbusTCPTraitsTest, ReadFrameSmallMBAPLength)
16✔
125
{
126
    TPortMock port({0, 1, 0, 0, 0, 0, 100, 7, 8, 9});
8✔
127
    Modbus::TModbusTCPTraits::ResetTransactionId(port);
4✔
128
    Modbus::TModbusTCPTraits traits;
4✔
129
    std::chrono::milliseconds t(10);
4✔
130

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

135
TEST_F(TModbusTCPTraitsTest, ReadFrameSmallPDU)
16✔
136
{
137
    TPortMock port({0, 1, 0, 0, 0, 4, 100, 7});
8✔
138
    Modbus::TModbusTCPTraits::ResetTransactionId(port);
4✔
139
    Modbus::TModbusTCPTraits traits;
4✔
140
    std::chrono::milliseconds t(10);
4✔
141

142
    std::vector<uint8_t> req = {7, 8, 9};
4✔
143
    ASSERT_THROW(traits.Transaction(port, 100, req, 2, t, t), Modbus::TMalformedResponseError);
4✔
144
}
145

146
TEST_F(TModbusTCPTraitsTest, ReadFrameWrongUnitId)
16✔
147
{
148
    TPortMock port({0, 1, 0, 0, 0, 4, 101, 7, 8, 9});
8✔
149
    Modbus::TModbusTCPTraits::ResetTransactionId(port);
4✔
150
    Modbus::TModbusTCPTraits traits;
4✔
151
    std::chrono::milliseconds t(10);
4✔
152

153
    std::vector<uint8_t> req = {7, 8, 9};
4✔
154
    ASSERT_THROW(traits.Transaction(port, 100, req, 2, t, t), Modbus::TUnexpectedResponseError);
4✔
155
}
156

157
TEST_F(TModbusTCPTraitsTest, ReadFramePassWrongTransactionId)
16✔
158
{
159
    std::vector<uint8_t> goodResp = {0, 1, 0, 0, 0, 4, 100, 17, 18, 19};
8✔
160
    std::vector<uint8_t> r = {0, 2, 0, 0, 0, 8, 101, 7, 8, 9, 10, 11, 12, 13};
8✔
161
    r.insert(r.end(), goodResp.begin(), goodResp.end());
4✔
162
    TPortMock port(r);
8✔
163

164
    Modbus::TModbusTCPTraits::ResetTransactionId(port);
4✔
165
    Modbus::TModbusTCPTraits traits;
8✔
166
    std::chrono::milliseconds t(10);
4✔
167

168
    std::vector<uint8_t> req = {7, 8, 9};
4✔
169
    TestEqual(traits.Transaction(port, 100, req, 2, t, t).Pdu, {17, 18, 19});
4✔
170
}
4✔
171

172
TEST_F(TModbusTCPTraitsTest, ReadFrameTimeout)
16✔
173
{
174
    TPortMock port({0, 2, 0, 0, 0, 4, 101, 7, 8, 9});
8✔
175
    Modbus::TModbusTCPTraits::ResetTransactionId(port);
4✔
176
    Modbus::TModbusTCPTraits traits;
4✔
177
    std::chrono::milliseconds t(10);
4✔
178

179
    std::vector<uint8_t> req = {7, 8, 9};
4✔
180
    ASSERT_THROW(traits.Transaction(port, 100, req, 2, t, t), TResponseTimeoutException);
4✔
181
}
182

183
TEST_F(TModbusTCPTraitsTest, IncrementTransactionId)
8✔
184
{
185
    std::vector<uint8_t> r = {0, 1, 0, 0, 0, 3, 100, 17, 18, 0, 2, 0, 0, 0, 3, 100, 19, 20};
2✔
186
    TPortMock port(r);
2✔
187
    Modbus::TModbusTCPTraits::ResetTransactionId(port);
2✔
188
    Modbus::TModbusTCPTraits traits;
2✔
189
    std::chrono::milliseconds t(10);
2✔
190

191
    std::vector<uint8_t> req = {7, 8, 9};
2✔
192
    auto resp = traits.Transaction(port, 100, req, 2, t, t).Pdu;
2✔
193
    ASSERT_EQ(resp.size(), 2);
2✔
194
    TestEqual(resp, {17, 18});
2✔
195
    ASSERT_EQ(port.GetLastRequest()[0], 0);
2✔
196
    ASSERT_EQ(port.GetLastRequest()[1], 1);
2✔
197

198
    Modbus::TModbusTCPTraits traits2;
2✔
199
    req.assign({10, 11, 12});
2✔
200
    resp = traits2.Transaction(port, 100, req, 2, t, t).Pdu;
2✔
201
    ASSERT_EQ(resp.size(), 2);
2✔
202
    TestEqual(resp, {19, 20});
2✔
203
    ASSERT_EQ(port.GetLastRequest()[0], 0);
2✔
204
    ASSERT_EQ(port.GetLastRequest()[1], 2);
2✔
205
}
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