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

mendersoftware / mender / 950534094

pending completion
950534094

push

gitlab-ci

kacf
chore: Add `StartsWith` and `EndsWith` generic utility functions.

Also use the latter in `states.cpp`.

Signed-off-by: Kristian Amlie <kristian.amlie@northern.tech>

1 of 1 new or added line in 1 file covered. (100.0%)

4931 of 6276 relevant lines covered (78.57%)

196.18 hits per line

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

71.43
/common/testing.hpp
1
// Copyright 2023 Northern.tech AS
2
//
3
//    Licensed under the Apache License, Version 2.0 (the "License");
4
//    you may not use this file except in compliance with the License.
5
//    You may obtain a copy of the License at
6
//
7
//        http://www.apache.org/licenses/LICENSE-2.0
8
//
9
//    Unless required by applicable law or agreed to in writing, software
10
//    distributed under the License is distributed on an "AS IS" BASIS,
11
//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
//    See the License for the specific language governing permissions and
13
//    limitations under the License.
14

15
#ifndef MENDER_COMMON_TESTING
16
#define MENDER_COMMON_TESTING
17

18
#include <memory>
19
#include <string>
20

21
#include <gtest/gtest.h>
22

23
#include <common/events.hpp>
24
#include <common/http.hpp>
25

26
namespace mender {
27
namespace common {
28
namespace testing {
29

30
using namespace std;
31

32
namespace http = mender::http;
33

34
shared_ptr<ostream> AssertInDeathTestHelper(const char *func, const char *file, int line);
35

36
// For unknown reasons, all test assertion output is disabled inside death test sub processes. It's
37
// extremely annoying to debug, because all errors will seem to come from the hook that invoked the
38
// death test sub method, and no additional output is printed. So make our own assert which aborts
39
// instead. Return a stream so that we can pipe into it as well, like we can with the Googletest
40
// asserts. Note two things in particular:
41
//
42
// 1. The use of an empty block when expression is true. This is to prevent streaming functions from
43
//    being called in that case, since they may not work then, for example for
44
//    `ASSERT_IN_DEATH_TEST(expected_reader) << expected_reader.error()`.
45
//
46
// 2. The usage of brace-less else. This is so that we can use the rest of the line to stream into
47
//    the helper without closing it with a brace.
48
//
49
#define ASSERT_IN_DEATH_TEST(EXPR) \
50
        if (EXPR) {                    \
51
        } else                         \
52
                *::mender::common::testing::AssertInDeathTestHelper(__PRETTY_FUNCTION__, __FILE__, __LINE__)
53

54
class TemporaryDirectory {
55
public:
56
        TemporaryDirectory();
57
        ~TemporaryDirectory();
58

59
        std::string Path() const;
60

61
private:
62
        std::string path_;
63
};
64

65
// An event loop which automatically times out after a given amount of time.
66
class TestEventLoop : public mender::common::events::EventLoop {
67
public:
68
        TestEventLoop(chrono::seconds seconds = chrono::seconds(5)) :
2✔
69
                timer_(*this) {
2✔
70
                timer_.AsyncWait(seconds, [this](error::Error err) {
2✔
71
                        Stop();
×
72
                        // Better to throw exception than FAIL(), since we want to escape the caller
73
                        // as well.
74
                        throw runtime_error("Test timed out");
×
75
                });
4✔
76
        }
2✔
77

78
private:
79
        mender::common::events::Timer timer_;
80
};
81

82
::testing::AssertionResult FileContains(const string &filename, const string &expected_content);
83
::testing::AssertionResult FileJsonEquals(const string &filename, const string &expected_content);
84
::testing::AssertionResult FilesEqual(const string &filename1, const string &filename2);
85

86
class RedirectStreamOutputs {
87
public:
88
        RedirectStreamOutputs() {
89
                cout_stream_ = cout.rdbuf(cout_string_.rdbuf());
90
                cerr_stream_ = cerr.rdbuf(cerr_string_.rdbuf());
91
        }
92
        ~RedirectStreamOutputs() {
93
                cout.rdbuf(cout_stream_);
94
                cerr.rdbuf(cerr_stream_);
95
        }
96

97
        string GetCout() const {
98
                return cout_string_.str();
99
        }
100

101
        string GetCerr() const {
102
                return cerr_string_.str();
103
        }
104

105
private:
106
        streambuf *cout_stream_;
107
        streambuf *cerr_stream_;
108
        stringstream cout_string_;
109
        stringstream cerr_string_;
110
};
111

112
class HttpFileServer {
113
public:
114
        HttpFileServer(const string &dir);
115
        ~HttpFileServer();
116

117
        const string &GetBaseUrl() const {
118
                return serve_address_;
119
        }
120

121
        void Serve(http::ExpectedIncomingRequestPtr req);
122

123
private:
124
        static const string serve_address_;
125

126
        string dir_;
127
        thread thread_;
128
        events::EventLoop loop_;
129
        http::Server server_;
130
};
131

132
} // namespace testing
133
} // namespace common
134
} // namespace mender
135

136
#endif // MENDER_COMMON_TESTING
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

© 2025 Coveralls, Inc