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

mendersoftware / mender / 951615729

pending completion
951615729

push

gitlab-ci

larsewi
fix: Add 'build/' to '.gitignore'

Ticket: None
Changelog: None
Signed-off-by: Lars Erik Wik <lars.erik.wik@northern.tech>

4199 of 5286 relevant lines covered (79.44%)

166.43 hits per line

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

93.1
/mender-update/update_module/v3/platform/c++17/update_module_call.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 <mender-update/update_module/v3/update_module.hpp>
16

17
#include <iostream>
18
#include <sstream>
19

20
#include <filesystem>
21

22
#include <common/common.hpp>
23
#include <common/events.hpp>
24
#include <common/log.hpp>
25
#include <common/processes.hpp>
26

27
namespace mender {
28
namespace update {
29
namespace update_module {
30
namespace v3 {
31

32
namespace error = mender::common::error;
33
namespace events = mender::common::events;
34
namespace log = mender::common::log;
35
namespace procs = mender::common::processes;
36
namespace fs = std::filesystem;
37

38
error::Error UpdateModule::CallState(State state, string *procOut) {
162✔
39
        string state_string = StateToString(state);
324✔
40
        string directory = GetModulesWorkPath();
324✔
41
        if (!fs::is_directory(directory)) {
162✔
42
                if (state == State::Cleanup) {
1✔
43
                        return error::NoError;
×
44
                } else {
45
                        return error::Error(
46
                                make_error_condition(errc::no_such_file_or_directory),
1✔
47
                                state_string + ": File tree does not exist: " + directory);
3✔
48
                }
49
        }
50

51
        procs::Process proc({GetModulePath(), state_string, GetModulesWorkPath()});
966✔
52
        proc.SetWorkDir(GetModulesWorkPath());
161✔
53
        error::Error processStart;
322✔
54
        bool first_line_captured = false;
161✔
55
        bool too_many_lines = false;
161✔
56
        if (procOut != nullptr) {
161✔
57
                processStart = proc.Start(
65✔
58
                        [&procOut, &first_line_captured, &too_many_lines](const char *data, size_t size) {
81✔
59
                                // At the moment, no state that queries output accepts more than one line,
60
                                // so reject multiple lines here. This would have been rejected anyway due
61
                                // to matching, but by doing it here, we also prevent using excessive memory
62
                                // if the process dumps a large log on us.
63
                                if (!first_line_captured) {
27✔
64
                                        auto lines = mender::common::SplitString(string(data, size), "\n");
104✔
65
                                        if (lines.size() >= 1) {
26✔
66
                                                *procOut = lines[0];
26✔
67
                                                first_line_captured = true;
26✔
68
                                        }
69
                                        if (lines.size() > 2 || (lines.size() == 2 && lines[1] != "")) {
26✔
70
                                                too_many_lines = true;
1✔
71
                                        }
72
                                } else {
73
                                        too_many_lines = true;
1✔
74
                                }
75
                        });
157✔
76
        } else {
77
                processStart = proc.Start([](const char *data, size_t size) {
96✔
78
                        auto lines = mender::common::SplitString(string(data, size), "\n");
36✔
79
                        for (auto line : lines) {
27✔
80
                                log::Info("Update Module output: " + line);
18✔
81
                        }
82
                });
201✔
83
        }
84
        if (processStart != error::NoError) {
161✔
85
                return GetProcessError(processStart).WithContext(state_string);
×
86
        }
87

88
        events::EventLoop loop;
322✔
89
        error::Error err;
322✔
90
        err = proc.AsyncWait(loop, [&loop, &err, &state_string](error::Error process_err) {
161✔
91
                err = process_err.WithContext(state_string);
160✔
92
                loop.Stop();
160✔
93
        });
482✔
94

95
        events::Timer timeout(loop);
322✔
96
        timeout.AsyncWait(
161✔
97
                chrono::seconds(ctx_.GetConfig().module_timeout_seconds),
161✔
98
                [&loop, &proc, &err, &state_string](error::Error inner_err) {
4✔
99
                        proc.EnsureTerminated();
1✔
100
                        err = error::Error(
1✔
101
                                make_error_condition(errc::timed_out),
1✔
102
                                state_string + ": Timed out while waiting for Update Module to complete");
3✔
103
                        loop.Stop();
1✔
104
                });
323✔
105

106
        loop.Run();
161✔
107

108
        if (state == State::Cleanup) {
161✔
109
                std::error_code ec;
28✔
110
                if (!fs::remove_all(directory, ec)) {
28✔
111
                        return error::Error(
112
                                ec.default_error_condition(),
×
113
                                state_string + ": Error removing directory: " + directory);
×
114
                }
115
        }
116

117
        if (err == error::NoError && too_many_lines) {
161✔
118
                return error::Error(
119
                        make_error_condition(errc::protocol_error),
2✔
120
                        "Too many lines when querying " + state_string);
6✔
121
        }
122

123
        return err;
159✔
124
}
125

126
} // namespace v3
127
} // namespace update_module
128
} // namespace update
129
} // 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