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

mendersoftware / mender / 2281564137

23 Jan 2026 10:59AM UTC coverage: 81.48% (+1.7%) from 79.764%
2281564137

push

gitlab-ci

michalkopczan
fix: Schedule next deployment poll if current one failed early causing no handler to be called

Ticket: MEN-9144
Changelog: Fix a hang when polling for deployment failed early causing no handler of API response
to be called. Added handler call for this case, causing the deployment polling
to continue.

Signed-off-by: Michal Kopczan <michal.kopczan@northern.tech>

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

327 existing lines in 44 files now uncovered.

8839 of 10848 relevant lines covered (81.48%)

20226.53 hits per line

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

85.42
/src/common/common.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_HPP
16
#define MENDER_COMMON_HPP
17

18
#include <common/expected.hpp>
19

20
#include <cstdint>
21
#include <cstring>
22

23
#include <algorithm>
24
#include <limits>
25
#include <string>
26
#include <unordered_map>
27
#include <vector>
28

29
// GCC and Clang method, respectively.
30
#if defined(__has_feature)
31
#if __has_feature(cxx_rtti)
32
#define __MENDER_RTTI_AVAILABLE
33
#include <typeinfo>
34
#endif
35
#elif defined(__GXX_RTTI)
36
#define __MENDER_RTTI_AVAILABLE
37
#include <typeinfo>
38
#endif
39

40
namespace mender {
41
namespace common {
42

43
using namespace std;
44

45
struct def_bool {
46
        bool value;
47

48
        def_bool() :
52✔
49
                value {false} {};
45✔
50
        def_bool(bool init_value) :
1✔
51
                value {init_value} {
154✔
52
        }
53

54
        operator bool() const {
55
                return value;
442✔
56
        }
57
};
58

59
template <typename T, T default_value>
60
struct def_value {
61
        T value;
62

63
        def_value() :
53✔
64
                value(default_value) {
53✔
65
        }
66

67
        def_value(T init_value) :
68
                value(init_value) {
69
        }
70

71
        operator T() const {
72
                return value;
132✔
73
        }
74
};
75

76
using StringPair = std::pair<string, string>;
77
using ExpectedStringPair = expected::expected<StringPair, error::Error>;
78

79
inline static vector<uint8_t> ByteVectorFromString(const char *str) {
265✔
80
        return vector<uint8_t>(
81
                reinterpret_cast<const uint8_t *>(str),
82
                reinterpret_cast<const uint8_t *>(str + strlen(str)));
265✔
83
}
84

85
// Using a template here allows use of `string_view`, which is C++17. The
86
// includer can decide which standard to use.
87
template <typename STR>
88
vector<uint8_t> ByteVectorFromString(const STR &str) {
2,065✔
89
        return vector<uint8_t>(str.begin(), str.end());
2,065✔
90
}
91

92
inline static string StringFromByteVector(const vector<uint8_t> &vec) {
957✔
93
        return string(vec.begin(), vec.end());
957✔
94
}
95

96
mender::common::expected::ExpectedLongLong StringToLongLong(const string &str, int base = 10);
97

98
template <typename T>
99
expected::expected<T, error::Error> StringTo(const string &str, int base = 10) {
554✔
100
        auto num = StringToLongLong(str, base);
554✔
101
        if (!num) {
554✔
UNCOV
102
                return expected::unexpected(num.error());
×
103
        }
104
        bool fits = true;
105
        if (is_signed<T>()) {
106
                if (num.value() < numeric_limits<T>::lowest() or num.value() > numeric_limits<T>::max()) {
107
                        fits = false;
108
                }
109
        } else {
110
                if (static_cast<unsigned long long>(num.value()) > numeric_limits<T>::max()) {
554✔
111
                        fits = false;
112
                }
113
        }
114
        if (not fits) {
UNCOV
115
                return expected::unexpected(error::Error(
×
UNCOV
116
                        make_error_condition(errc::result_out_of_range),
×
UNCOV
117
                        "StringTo(): Number " + to_string(num.value())
×
UNCOV
118
                                + " does not fit in requested data type"));
×
119
        }
120
        return static_cast<T>(num.value());
554✔
121
}
122

123
string StringToLower(const string &str);
124

125
vector<string> SplitString(const string &str, const string &delim);
126
string JoinStrings(const vector<string> &str, const string &delim);
127
vector<string> JoinStringsMaxWidth(
128
        const vector<string> &str, const string &delim, const size_t max_width);
129

130
template <typename T>
131
bool StartsWith(const T &str, const T &sub) {
73✔
132
        return (sub.size() <= str.size()) && equal(str.begin(), str.begin() + sub.size(), sub.begin());
73✔
133
}
134

135
template <typename T>
136
bool EndsWith(const T &str, const T &sub) {
21✔
137
        return (sub.size() <= str.size()) && equal(str.end() - sub.size(), str.end(), sub.begin());
21✔
138
}
139

140
template <typename T>
141
string BestAvailableTypeName(const T &object) {
4,245✔
142
#ifdef __MENDER_RTTI_AVAILABLE
143
        return typeid(object).name();
4,245✔
144
#else
145
        return "<Type name not available>";
146
#endif
147
}
148

149
static inline bool VectorContainsString(const vector<string> &vec, const string &str) {
1,238✔
150
        return std::find(vec.begin(), vec.end(), str) != vec.end();
1,238✔
151
}
152

153
// Should not be used with user provided data
154
static inline string StringVectorToString(const vector<string> &vec, const string delim = ",") {
4✔
155
        string ret = "{";
4✔
156
        auto sz = vec.size();
157
        if (sz > 0) {
4✔
158
                for (decltype(sz) i = 0; i < (sz - 1); i++) {
4✔
UNCOV
159
                        ret += "\"" + vec[i] + "\"" + delim;
×
160
                }
161
                ret += "\"" + vec[sz - 1] + "\"";
8✔
162
        }
163
        ret += "}";
4✔
164
        return ret;
4✔
165
}
166

167
template <typename ValueType>
168
static inline bool MapContainsStringKey(
382✔
169
        const unordered_map<string, ValueType> &map, const string &str) {
170
        return map.find(str) != map.end();
382✔
171
}
172

173
template <typename KeyType, typename ValueType>
174
static inline vector<KeyType> GetMapKeyVector(const unordered_map<KeyType, ValueType> &map) {
21✔
175
        vector<KeyType> ret;
176
        ret.reserve(map.size());
21✔
177
        for (const auto &kv : map) {
90✔
178
                ret.push_back(kv.first);
69✔
179
        }
180
        return ret;
21✔
UNCOV
181
}
×
182

183
} // namespace common
184
} // namespace mender
185

186
#endif // MENDER_COMMON_HPP
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