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

mendersoftware / mender / 1022753986

02 Oct 2023 10:37AM UTC coverage: 78.168% (-2.0%) from 80.127%
1022753986

push

gitlab-ci

oleorhagen
feat: Run the authentication loop once upon bootstrap

Ticket: MEN-6658
Changelog: None

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

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

6996 of 8950 relevant lines covered (78.17%)

10353.4 hits per line

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

72.34
/common/events/platform/boost/events_io.cpp
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
#include <common/events_io.hpp>
16

17
#include <vector>
18

19
namespace mender {
20
namespace common {
21
namespace events {
22
namespace io {
23

24
AsyncFileDescriptorReader::AsyncFileDescriptorReader(events::EventLoop &loop, int fd) :
×
25
        pipe_(GetAsioIoContext(loop), fd),
26
        destroying_ {make_shared<bool>(false)} {
×
27
}
×
28

29
AsyncFileDescriptorReader::AsyncFileDescriptorReader(events::EventLoop &loop) :
×
30
        pipe_(GetAsioIoContext(loop)),
31
        destroying_ {make_shared<bool>(false)} {
×
32
}
×
33

34
AsyncFileDescriptorReader::~AsyncFileDescriptorReader() {
×
35
        *destroying_ = true;
×
36
        Cancel();
×
37
}
×
38

39
error::Error AsyncFileDescriptorReader::Open(const string &path) {
2✔
40
        int fd = open(path.c_str(), O_RDONLY);
2✔
41
        if (fd < 0) {
2✔
42
                int err = errno;
1✔
43
                return error::Error(generic_category().default_error_condition(err), "Cannot open " + path);
2✔
44
        }
45
        pipe_.close();
1✔
46
        pipe_.assign(fd);
1✔
47
        return error::NoError;
1✔
48
}
49

50
error::Error AsyncFileDescriptorReader::AsyncRead(
21✔
51
        vector<uint8_t>::iterator start,
52
        vector<uint8_t>::iterator end,
53
        mender::common::io::AsyncIoHandler handler) {
54
        if (end < start) {
21✔
55
                return error::Error(
56
                        make_error_condition(errc::invalid_argument), "AsyncRead: end cannot precede start");
2✔
57
        }
58
        if (!handler) {
20✔
59
                return error::Error(
60
                        make_error_condition(errc::invalid_argument), "AsyncRead: handler cannot be nullptr");
2✔
61
        }
62

63
        auto destroying {destroying_};
38✔
64

65
        asio::mutable_buffer buf {&start[0], size_t(end - start)};
19✔
66
        pipe_.async_read_some(buf, [destroying, handler](error_code ec, size_t n) {
19✔
67
                if (*destroying) {
19✔
68
                        return;
1✔
69
                } else if (ec == make_error_code(asio::error::operation_aborted)) {
18✔
70
                        handler(expected::unexpected(error::Error(
2✔
71
                                make_error_condition(errc::operation_canceled), "AsyncRead cancelled")));
3✔
72
                } else if (ec == make_error_code(asio::error::eof)) {
17✔
73
                        // n should always be zero. Handling this properly is possible, but tricky,
74
                        // so just relying on assert for now.
75
                        assert(n == 0);
3✔
76
                        handler(0);
3✔
77
                } else if (ec) {
14✔
78
                        handler(expected::unexpected(
×
79
                                error::Error(ec.default_error_condition(), "AsyncRead failed")));
×
80
                } else {
81
                        handler(n);
14✔
82
                }
83
        });
84

85
        return error::NoError;
19✔
86
}
87

88
void AsyncFileDescriptorReader::Cancel() {
16✔
89
        if (pipe_.is_open()) {
16✔
90
                pipe_.cancel();
15✔
91
        }
92
}
16✔
93

94
AsyncFileDescriptorWriter::AsyncFileDescriptorWriter(events::EventLoop &loop, int fd) :
×
95
        pipe_(GetAsioIoContext(loop), fd),
96
        destroying_ {make_shared<bool>(false)} {
×
97
}
×
98

99
AsyncFileDescriptorWriter::AsyncFileDescriptorWriter(events::EventLoop &loop) :
×
100
        pipe_(GetAsioIoContext(loop)),
101
        destroying_ {make_shared<bool>(false)} {
×
102
}
×
103

104
AsyncFileDescriptorWriter::~AsyncFileDescriptorWriter() {
×
105
        *destroying_ = true;
×
106
        Cancel();
×
107
}
×
108

109
error::Error AsyncFileDescriptorWriter::Open(const string &path, Append append) {
165✔
110
        int flags = O_WRONLY | O_CREAT;
165✔
111
        switch (append) {
165✔
112
        case Append::Disabled:
164✔
113
                flags |= O_TRUNC;
164✔
114
                break;
164✔
115
        case Append::Enabled:
1✔
116
                flags |= O_APPEND;
1✔
117
                break;
1✔
118
        }
119
        int fd = open(path.c_str(), flags, 0644);
165✔
120
        if (fd < 0) {
165✔
121
                int err = errno;
3✔
122
                return error::Error(generic_category().default_error_condition(err), "Cannot open " + path);
6✔
123
        }
124
        pipe_.close();
162✔
125
        pipe_.assign(fd);
162✔
126
        return error::NoError;
162✔
127
}
128

129
error::Error AsyncFileDescriptorWriter::AsyncWrite(
578✔
130
        vector<uint8_t>::const_iterator start,
131
        vector<uint8_t>::const_iterator end,
132
        mender::common::io::AsyncIoHandler handler) {
133
        if (end < start) {
578✔
134
                return error::Error(
135
                        make_error_condition(errc::invalid_argument), "AsyncWrite: end cannot precede start");
2✔
136
        }
137
        if (!handler) {
577✔
138
                return error::Error(
139
                        make_error_condition(errc::invalid_argument), "AsyncWrite: handler cannot be nullptr");
2✔
140
        }
141

142
        auto destroying {destroying_};
1,152✔
143

144
        asio::const_buffer buf {&start[0], size_t(end - start)};
576✔
145
        pipe_.async_write_some(buf, [destroying, handler](error_code ec, size_t n) {
576✔
146
                if (*destroying) {
576✔
147
                        return;
1✔
148
                } else if (ec == make_error_code(asio::error::operation_aborted)) {
575✔
149
                        handler(expected::unexpected(error::Error(
×
150
                                make_error_condition(errc::operation_canceled), "AsyncWrite cancelled")));
×
151
                } else if (ec == make_error_code(asio::error::broken_pipe)) {
575✔
152
                        // Let's translate broken_pipe. It's a common error, and we don't want to
153
                        // require the caller to match with Boost ASIO errors.
154
                        handler(expected::unexpected(
3✔
155
                                error::Error(make_error_condition(errc::broken_pipe), "AsyncWrite failed")));
6✔
156
                } else if (ec) {
572✔
157
                        handler(expected::unexpected(
×
158
                                error::Error(ec.default_error_condition(), "AsyncWrite failed")));
×
159
                } else {
160
                        handler(n);
572✔
161
                }
162
        });
163

164
        return error::NoError;
576✔
165
}
166

167
void AsyncFileDescriptorWriter::Cancel() {
175✔
168
        if (pipe_.is_open()) {
175✔
169
                pipe_.cancel();
172✔
170
        }
171
}
175✔
172

173
} // namespace io
174
} // namespace events
175
} // namespace common
176
} // namespace mender
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