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

mendersoftware / mender / 968408678

pending completion
968408678

push

gitlab-ci

oleorhagen
feat(artifact/scripts): Add support for executing state scripts

Ticket: MEN-6636
Changelog: None

Signed-off-by: Ole Petter <ole.orhagen@northern.tech>

126 of 126 new or added lines in 4 files covered. (100.0%)

5405 of 6857 relevant lines covered (78.82%)

195.75 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
        void CreateSubDirectory(const string &dirname);
62

63
private:
64
        std::string path_;
65
};
66

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

80
private:
81
        mender::common::events::Timer timer_;
82
};
83

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

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

99
        string GetCout() const {
100
                return cout_string_.str();
101
        }
102

103
        string GetCerr() const {
104
                return cerr_string_.str();
105
        }
106

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

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

119
        const string &GetBaseUrl() const {
120
                return serve_address_;
121
        }
122

123
        void Serve(http::ExpectedIncomingRequestPtr req);
124

125
private:
126
        static const string serve_address_;
127

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

134
} // namespace testing
135
} // namespace common
136
} // namespace mender
137

138
#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