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

mendersoftware / mender / 1583599051

11 Dec 2024 09:04AM UTC coverage: 76.259% (-0.2%) from 76.43%
1583599051

push

gitlab-ci

vpodzime
fix: Cancel the previous request before scheduling a new one in HTTP resumer

The `http::Client()` class is designed to always have only one
HTTP request in progress. Thus, before scheduling a new request
using the same `http::Client` instance, cancel the previous
request to make sure everything is properly reset for the new
one.

Ticket: MEN-7810
Changelog: Fix download resuming to reset the HTTP state and
avoid repeatedly hitting the same error in case of a bad state

Signed-off-by: Vratislav Podzimek <vratislav.podzimek@northern.tech>

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

55 existing lines in 11 files now uncovered.

7375 of 9671 relevant lines covered (76.26%)

11182.97 hits per line

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

0.0
/src/common/yaml.hpp
1
// Copyright 2024 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_YAML_HPP
16
#define MENDER_COMMON_YAML_HPP
17

18
#include <common/config.h>
19

20
#include <map>
21
#include <string>
22
#include <unordered_map>
23

24
#include <common/common.hpp>
25
#include <common/error.hpp>
26
#include <common/expected.hpp>
27
#include <common/io.hpp>
28

29
#ifdef MENDER_USE_YAML_CPP
30
#include <yaml-cpp/yaml.h>
31
#endif
32

33
namespace mender {
34
namespace common {
35
namespace yaml {
36

37
using namespace std;
38

39
namespace error = mender::common::error;
40
namespace io = mender::common::io;
41
namespace common = mender::common;
42

43
enum YamlErrorCode {
44
        NoError = 0,
45
        ParseError,
46
        KeyError,
47
        IndexError,
48
        TypeError,
49
};
50

UNCOV
51
class YamlErrorCategoryClass : public error_category {
×
52
public:
53
        const char *name() const noexcept override;
54
        string message(int code) const override;
55
};
56
extern const YamlErrorCategoryClass YamlErrorCategory;
57

58
error::Error MakeError(YamlErrorCode code, const string &msg);
59

60
using ExpectedString = mender::common::expected::ExpectedString;
61
using ExpectedInt64 = mender::common::expected::ExpectedInt64;
62
using ExpectedDouble = mender::common::expected::ExpectedDouble;
63
using ExpectedBool = mender::common::expected::ExpectedBool;
64
using ExpectedSize = mender::common::expected::ExpectedSize;
65

66
class Yaml;
67
using ExpectedYaml = expected::expected<Yaml, error::Error>;
68
using ChildrenMap = map<string, Yaml>;
69
using ExpectedChildrenMap = expected::expected<ChildrenMap, error::Error>;
70

UNCOV
71
class Yaml {
×
72
public:
73
        Yaml() = default;
74

75
        Yaml(const Yaml &) = default;
76
        Yaml &operator=(const Yaml &) = default;
77

78
        Yaml(Yaml &&) = default;
79
        Yaml &operator=(Yaml &&) = default;
80

81
        string Dump(const int indent = 2) const;
82

83
        ExpectedYaml Get(const char *child_key) const;
84
        ExpectedYaml operator[](const char *child_key) const {
85
                return this->Get(child_key);
86
        }
87
        ExpectedYaml Get(const string &child_key) const {
88
                return this->Get(child_key.data());
89
        }
90
        ExpectedYaml operator[](const string &child_key) const {
91
                return this->Get(child_key.data());
92
        }
93
        ExpectedYaml Get(const size_t idx) const;
94
        ExpectedYaml operator[](const size_t idx) const {
95
                return this->Get(idx);
96
        }
97

98
        ExpectedChildrenMap GetChildren() const;
99

100
        bool IsObject() const;
101
        bool IsArray() const;
102
        bool IsString() const;
103
        bool IsInt64() const;
104
        bool IsNumber() const;
105
        bool IsDouble() const;
106
        bool IsBool() const;
107
        bool IsNull() const;
108

109
        // Defined in cpp file as specialized templates.
110
        template <typename T>
111
        typename enable_if<
112
                not is_integral<T>::value or is_same<T, int64_t>::value or is_same<T, bool>::value,
113
                expected::expected<T, error::Error>>::type
114
        Get() const;
115

116
        // Use this as a catch-all for all integral types besides int64_t and bool. It then
117
        // automates the process of checking whether it fits in the requested data type.
118
        template <typename T>
119
        typename enable_if<
120
                is_integral<T>::value and not is_same<T, int64_t>::value and not is_same<T, bool>::value,
121
                expected::expected<T, error::Error>>::type
122
        Get() const {
123
                auto num = Get<int64_t>();
124
                if (!num) {
125
                        return expected::unexpected(num.error());
126
                }
127
                bool fits = true;
128
                if (is_signed<T>()) {
129
                        if (num.value() < numeric_limits<T>::lowest()
130
                                or num.value() > numeric_limits<T>::max()) {
131
                                fits = false;
132
                        }
133
                } else {
134
                        if (static_cast<unsigned long long>(num.value()) > numeric_limits<T>::max()) {
135
                                fits = false;
136
                        }
137
                }
138
                if (not fits) {
139
                        return expected::unexpected(error::Error(
140
                                make_error_condition(errc::result_out_of_range),
141
                                "Json::Get(): Number " + to_string(num.value())
142
                                        + " does not fit in requested data type"));
143
                }
144
                return static_cast<T>(num.value());
145
        }
146

147
        ExpectedSize GetArraySize() const;
148

149
        string GetType() const;
150
        friend std::ostream &operator<<(std::ostream &os, const Yaml &y) {
151
#ifdef MENDER_USE_YAML_CPP
152
                os << y.n_yaml;
153
#endif
154
                return os;
155
        }
156

157
        friend ExpectedYaml LoadFromFile(string file_path);
158
        friend ExpectedYaml Load(string yaml_str);
159
        friend ExpectedYaml Load(istream &str);
160
        friend ExpectedYaml Load(io::Reader &reader);
161

162
public:
163
#ifdef MENDER_USE_YAML_CPP
164
        YAML::Node n_yaml;
165
        Yaml(YAML::Node n_yaml) :
166
                n_yaml(n_yaml) {};
167
#endif
168
};
169

170
ExpectedYaml LoadFromFile(string file_path);
171
ExpectedYaml Load(string yaml_str);
172
ExpectedYaml Load(istream &str);
173
ExpectedYaml Load(io::Reader &reader);
174

175
using ExpectedStringVector = expected::ExpectedStringVector;
176
using KeyValueMap = unordered_map<string, string>;
177
using ExpectedKeyValueMap = expected::expected<KeyValueMap, error::Error>;
178

179
ExpectedStringVector ToStringVector(const yaml::Yaml &j);
180
ExpectedKeyValueMap ToKeyValueMap(const yaml::Yaml &j);
181
ExpectedString ToString(const yaml::Yaml &j);
182
ExpectedInt64 ToInt64(const yaml::Yaml &j);
183
ExpectedBool ToBool(const yaml::Yaml &j);
184

185
template <typename T>
186
expected::expected<T, error::Error> To(const yaml::Yaml &j) {
187
        return j.Get<T>();
188
}
189

190
enum class MissingOk {
191
        No,
192
        Yes,
193
};
194

195
template <typename T>
196
expected::expected<T, error::Error> Get(
197
        const yaml::Yaml &yaml, const string &key, MissingOk missing_ok) {
198
        auto exp_value = yaml.Get(key);
199
        if (not exp_value) {
200
                if (missing_ok == MissingOk::Yes
201
                        and exp_value.error().code == yaml::MakeError(yaml::KeyError, "").code) {
202
                        return T();
203
                } else {
204
                        return expected::unexpected(
205
                                exp_value.error().WithContext(": Could not get `" + key + "` from the YAML data"));
206
                }
207
        }
208
        return exp_value.value().Get<T>();
209
}
210

211
} // namespace yaml
212
} // namespace common
213
} // namespace mender
214

215
#endif // MENDER_COMMON_YAML_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

© 2025 Coveralls, Inc