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

mavlink / MAVSDK / 15862163887

24 Jun 2025 09:44PM UTC coverage: 44.907% (+0.5%) from 44.374%
15862163887

push

github

web-flow
Merge pull request #2599 from mavlink/pr-unit-tests-fixup

Unit tests fixup

76 of 95 new or added lines in 5 files covered. (80.0%)

14 existing lines in 6 files now uncovered.

15197 of 33841 relevant lines covered (44.91%)

129286.15 hits per line

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

98.39
/src/mavsdk/core/http_loader_test.cpp
1
#include "mavsdk.h"
2
#include "http_loader.h"
3
#include "curl_include.h"
4
#include "curl_wrapper.h"
5
#include "curl_wrapper_types.h"
6
#include <fstream>
7
#include <iostream>
8
#include <chrono>
9
#include <vector>
10
#include <numeric>
11
#include <thread>
12
#include <gtest/gtest.h>
13

14
using namespace mavsdk;
15

16
class HttpLoaderTest : public testing::Test {
17
protected:
18
    const std::string _file_url_1 = "http://subdomain.domain.com/some_folder/some_file";
19
    const std::string _file_url_2 = "http://subdomain.domain.com/some_folder/another_file.txt";
20
    const std::string _file_url_3 = "http://subdomain.domain.com/some_folder/yet_another_file.mp4";
21
    const std::string _file_local_path_1 = "some_file";
22
    const std::string _file_local_path_2 = "another_file.txt";
23
    const std::string _file_local_path_3 = "yet_another_file.mp4";
24

25
    virtual void SetUp() { clean(); }
2✔
26

27
    virtual void TearDown() { clean(); }
2✔
28

29
    void clean()
6✔
30
    {
31
        remove(_file_local_path_1.c_str());
6✔
32
        remove(_file_local_path_2.c_str());
6✔
33
        remove(_file_local_path_3.c_str());
6✔
34
    }
6✔
35

36
    bool check_file_exists(const std::string& file_path)
6✔
37
    {
38
        std::ifstream infile(file_path.c_str());
6✔
39
        return infile.good();
6✔
40
    }
6✔
41

42
    void write_file(const std::string& path, const std::string& content)
5✔
43
    {
44
        std::ofstream file;
5✔
45
        file.open(path);
5✔
46
        file << content;
5✔
47
        file.close();
5✔
48
    }
5✔
49

50
    void expect_all_simulated_downloads_to_succeed(CurlWrapperMock* curl_wrapper)
1✔
51
    {
52
        EXPECT_CALL(*curl_wrapper, download_file_to_path(_, _, _))
3✔
53
            .WillRepeatedly(Invoke([&](const std::string& /*url*/,
3✔
54
                                       const std::string& path,
55
                                       const ProgressCallback& progress_callback) {
56
                for (size_t i = 0; i <= 100; i++) {
306✔
57
                    if (progress_callback != nullptr) {
303✔
58
                        progress_callback(i, HttpStatus::Downloading, CURLcode::CURLE_OK);
303✔
59
                    }
60
                }
61

62
                write_file(path, "downloaded file content\n");
3✔
63

64
                std::this_thread::sleep_for(std::chrono::milliseconds(20));
3✔
65

66
                progress_callback(100, HttpStatus::Finished, CURLcode::CURLE_OK);
3✔
67
                return true;
3✔
68
            }));
69
    }
1✔
70

71
    void expect_one_simulated_download_to_fail(
1✔
72
        CurlWrapperMock* curl_wrapper, const std::string& url, const std::string& path)
73
    {
74
        EXPECT_CALL(*curl_wrapper, download_file_to_path(url, path, _))
3✔
75
            .WillOnce(Invoke([&](const std::string& /*url*/,
3✔
76
                                 const std::string& /*path*/,
77
                                 const ProgressCallback& progress_callback) {
78
                std::this_thread::sleep_for(std::chrono::milliseconds(20));
1✔
79
                progress_callback(0, HttpStatus::Error, CURLcode::CURLE_COULDNT_RESOLVE_HOST);
1✔
80
                return false;
1✔
81
            }));
82
    }
1✔
83

84
    void expect_one_simulated_download_to_succeed(
2✔
85
        CurlWrapperMock* curl_wrapper, const std::string& url, const std::string& path)
86
    {
87
        EXPECT_CALL(*curl_wrapper, download_file_to_path(url, path, _))
6✔
88
            .WillOnce(Invoke([&](const std::string& /*url*/,
6✔
89
                                 const std::string& got_path,
90
                                 const ProgressCallback& progress_callback) {
91
                for (size_t i = 0; i <= 100; i++) {
204✔
92
                    if (progress_callback != nullptr) {
202✔
93
                        progress_callback(i, HttpStatus::Downloading, CURLcode::CURLE_OK);
202✔
94
                    }
95
                }
96

97
                write_file(got_path, "downloaded file content\n");
2✔
98

99
                std::this_thread::sleep_for(std::chrono::milliseconds(20));
2✔
100

101
                progress_callback(100, HttpStatus::Finished, CURLcode::CURLE_OK);
2✔
102
                return true;
2✔
103
            }));
104
    }
2✔
105
};
106

107
TEST_F(HttpLoaderTest, HttpLoader_DownloadAsync_OneBad)
4✔
108
{
109
    auto curl_wrapper_mock = std::make_unique<CurlWrapperMock>();
1✔
110
    auto* curl_wrapper_raw = curl_wrapper_mock.get();
1✔
111
    auto http_loader = std::make_shared<HttpLoader>(std::move(curl_wrapper_mock));
1✔
112

113
    expect_one_simulated_download_to_succeed(curl_wrapper_raw, _file_url_1, _file_local_path_1);
1✔
114
    expect_one_simulated_download_to_fail(curl_wrapper_raw, _file_url_2, _file_local_path_2);
1✔
115
    expect_one_simulated_download_to_succeed(curl_wrapper_raw, _file_url_3, _file_local_path_3);
1✔
116

117
    std::vector<int> callback_results_progress;
1✔
118
    int callback_finished_counter = 0;
1✔
119
    int callback_error_counter = 0;
1✔
120

121
    ProgressCallback progress =
1✔
122
        [&callback_results_progress, &callback_finished_counter, &callback_error_counter](
205✔
123
            int got_progress, HttpStatus status, CURLcode curl_code) -> int {
205✔
124
        if (status == HttpStatus::Downloading) {
205✔
125
            callback_results_progress.push_back(got_progress);
202✔
126
        } else if (
3✔
127
            status == HttpStatus::Error && curl_code == CURLcode::CURLE_COULDNT_RESOLVE_HOST) {
1✔
128
            callback_error_counter++;
1✔
129
        } else if (status == HttpStatus::Finished && curl_code == CURLcode::CURLE_OK) {
2✔
130
            callback_finished_counter++;
2✔
131
        }
132
        return 0;
205✔
133
    };
1✔
134

135
    http_loader->download_async(_file_url_1, _file_local_path_1, progress);
1✔
136
    http_loader->download_async(_file_url_2, _file_local_path_2, progress);
1✔
137
    http_loader->download_async(_file_url_3, _file_local_path_3, progress);
1✔
138

139
    // Wait for downloads to complete (2 success + 1 error) with timeout
140
    auto start_time = std::chrono::steady_clock::now();
1✔
141
    while ((callback_finished_counter + callback_error_counter) < 3 &&
14✔
142
           std::chrono::steady_clock::now() - start_time < std::chrono::milliseconds(1000)) {
13✔
143
        std::this_thread::sleep_for(std::chrono::milliseconds(10));
3✔
144
    }
145

146
    EXPECT_EQ(check_file_exists(_file_local_path_1), true);
1✔
147
    EXPECT_EQ(check_file_exists(_file_local_path_2), false);
1✔
148
    EXPECT_EQ(check_file_exists(_file_local_path_3), true);
1✔
149

150
    int callback_results_sum =
1✔
151
        std::accumulate(callback_results_progress.begin(), callback_results_progress.end(), 0);
1✔
152
    EXPECT_EQ(callback_results_sum, 2 * 5050);
1✔
153
    EXPECT_EQ(callback_results_progress.size(), 2 * 101);
1✔
154
    EXPECT_EQ(callback_finished_counter, 2);
1✔
155
    EXPECT_EQ(callback_error_counter, 1);
1✔
156

157
    clean();
1✔
158
}
1✔
159

160
TEST_F(HttpLoaderTest, HttpLoader_DownloadAsync_AllGood)
4✔
161
{
162
    auto curl_wrapper_mock = std::make_unique<CurlWrapperMock>();
1✔
163
    auto* curl_wrapper_raw = curl_wrapper_mock.get();
1✔
164
    auto http_loader = std::make_shared<HttpLoader>(std::move(curl_wrapper_mock));
1✔
165

166
    expect_all_simulated_downloads_to_succeed(curl_wrapper_raw);
1✔
167

168
    std::vector<int> callback_results_progress;
1✔
169
    int callback_finished_counter = 0;
1✔
170
    int callback_error_counter = 0;
1✔
171

172
    ProgressCallback progress =
1✔
173
        [&callback_results_progress, &callback_finished_counter, &callback_error_counter](
306✔
174
            int got_progress, HttpStatus status, CURLcode curl_code) -> int {
306✔
175
        if (status == HttpStatus::Downloading) {
306✔
176
            callback_results_progress.push_back(got_progress);
303✔
177
        } else if (
3✔
NEW
178
            status == HttpStatus::Error && curl_code == CURLcode::CURLE_COULDNT_RESOLVE_HOST) {
×
179
            callback_error_counter++;
×
180
        } else if (status == HttpStatus::Finished && curl_code == CURLcode::CURLE_OK) {
3✔
181
            callback_finished_counter++;
3✔
182
        }
183
        return 0;
306✔
184
    };
1✔
185

186
    http_loader->download_async(_file_url_1, _file_local_path_1, progress);
1✔
187
    http_loader->download_async(_file_url_2, _file_local_path_2, progress);
1✔
188
    http_loader->download_async(_file_url_3, _file_local_path_3, progress);
1✔
189

190
    // Wait for all downloads to complete with timeout
191
    auto start_time = std::chrono::steady_clock::now();
1✔
192
    while (callback_finished_counter < 3 && callback_error_counter == 0 &&
14✔
193
           std::chrono::steady_clock::now() - start_time < std::chrono::milliseconds(1000)) {
13✔
194
        std::this_thread::sleep_for(std::chrono::milliseconds(10));
3✔
195
    }
196

197
    EXPECT_EQ(check_file_exists(_file_local_path_1), true);
1✔
198
    EXPECT_EQ(check_file_exists(_file_local_path_2), true);
1✔
199
    EXPECT_EQ(check_file_exists(_file_local_path_3), true);
1✔
200

201
    int callback_results_sum =
1✔
202
        std::accumulate(callback_results_progress.begin(), callback_results_progress.end(), 0);
1✔
203
    EXPECT_EQ(callback_results_sum, 3 * 5050);
1✔
204
    EXPECT_EQ(callback_results_progress.size(), 3 * 101);
1✔
205
    EXPECT_EQ(callback_finished_counter, 3);
1✔
206
    EXPECT_EQ(callback_error_counter, 0);
1✔
207

208
    clean();
1✔
209
}
1✔
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