blob: 7f00daee440a692b19994ee70ac5ab9887973c81 [file] [log] [blame]
Jae Hoon Kim0ae8fe12019-06-26 14:32:50 -07001//
2// Copyright (C) 2019 The Android Open Source Project
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
16
17#include "update_engine/libcurl_http_fetcher.h"
18
19#include <string>
20
21#include <brillo/message_loops/fake_message_loop.h>
22#include <gtest/gtest.h>
23
24#include "update_engine/common/fake_hardware.h"
25#include "update_engine/common/mock_proxy_resolver.h"
26
27using std::string;
28
29namespace chromeos_update_engine {
30
31namespace {
32constexpr char kHeaderName[] = "X-Goog-Test-Header";
33}
34
35class LibcurlHttpFetcherTest : public ::testing::Test {
36 protected:
37 void SetUp() override {
38 loop_.SetAsCurrent();
39 fake_hardware_.SetIsOfficialBuild(true);
40 fake_hardware_.SetIsOOBEEnabled(false);
41 }
42
43 brillo::FakeMessageLoop loop_{nullptr};
44 FakeHardware fake_hardware_;
45 LibcurlHttpFetcher libcurl_fetcher_{nullptr, &fake_hardware_};
Xiaochu Liub5ba7972019-07-11 09:51:06 -070046 UnresolvedHostStateMachine state_machine_;
Jae Hoon Kim0ae8fe12019-06-26 14:32:50 -070047};
48
49TEST_F(LibcurlHttpFetcherTest, GetEmptyHeaderValueTest) {
50 const string header_value = "";
51 string actual_header_value;
52 libcurl_fetcher_.SetHeader(kHeaderName, header_value);
53 EXPECT_TRUE(libcurl_fetcher_.GetHeader(kHeaderName, &actual_header_value));
54 EXPECT_EQ("", actual_header_value);
55}
56
57TEST_F(LibcurlHttpFetcherTest, GetHeaderTest) {
58 const string header_value = "This-is-value 123";
59 string actual_header_value;
60 libcurl_fetcher_.SetHeader(kHeaderName, header_value);
61 EXPECT_TRUE(libcurl_fetcher_.GetHeader(kHeaderName, &actual_header_value));
62 EXPECT_EQ(header_value, actual_header_value);
63}
64
65TEST_F(LibcurlHttpFetcherTest, GetNonExistentHeaderValueTest) {
66 string actual_header_value;
67 // Skip |SetHeaader()| call.
68 EXPECT_FALSE(libcurl_fetcher_.GetHeader(kHeaderName, &actual_header_value));
69 // Even after a failed |GetHeaderValue()|, enforce that the passed pointer to
70 // modifiable string was cleared to be empty.
71 EXPECT_EQ("", actual_header_value);
72}
73
74TEST_F(LibcurlHttpFetcherTest, GetHeaderEdgeCaseTest) {
75 const string header_value = "\a\b\t\v\f\r\\ edge:-case: \a\b\t\v\f\r\\";
76 string actual_header_value;
77 libcurl_fetcher_.SetHeader(kHeaderName, header_value);
78 EXPECT_TRUE(libcurl_fetcher_.GetHeader(kHeaderName, &actual_header_value));
79 EXPECT_EQ(header_value, actual_header_value);
80}
81
Xiaochu Liub5ba7972019-07-11 09:51:06 -070082TEST_F(LibcurlHttpFetcherTest, InvalidURLTest) {
83 int no_network_max_retries = 1;
84 libcurl_fetcher_.set_no_network_max_retries(no_network_max_retries);
85
86 libcurl_fetcher_.BeginTransfer("not-an-URL");
87 while (loop_.PendingTasks()) {
88 loop_.RunOnce(true);
89 }
90
91 EXPECT_EQ(libcurl_fetcher_.get_no_network_max_retries(),
92 no_network_max_retries);
93}
94
95TEST_F(LibcurlHttpFetcherTest, CouldntResolveHostTest) {
96 int no_network_max_retries = 1;
97 libcurl_fetcher_.set_no_network_max_retries(no_network_max_retries);
98
99 // This test actually sends request to internet but according to
100 // https://tools.ietf.org/html/rfc2606#section-2, .invalid domain names are
101 // reserved and sure to be invalid. Ideally we should mock libcurl or
102 // reorganize LibcurlHttpFetcher so the part that sends request can be mocked
103 // easily.
104 // TODO(xiaochu) Refactor LibcurlHttpFetcher (and its relates) so it's
105 // easier to mock the part that depends on internet connectivity.
106 libcurl_fetcher_.BeginTransfer("https://An-uNres0lvable-uRl.invalid");
107 while (loop_.PendingTasks()) {
108 loop_.RunOnce(true);
109 }
110
111 // If libcurl fails to resolve the name, we call res_init() to reload
112 // resolv.conf and retry exactly once more. See crbug.com/982813 for details.
113 EXPECT_EQ(libcurl_fetcher_.get_no_network_max_retries(),
114 no_network_max_retries + 1);
115}
116
117TEST_F(LibcurlHttpFetcherTest, HttpFetcherStateMachineRetryFailedTest) {
118 state_machine_.UpdateState(true);
119 state_machine_.UpdateState(true);
120 EXPECT_EQ(state_machine_.getState(),
121 UnresolvedHostStateMachine::State::kNotRetry);
122}
123
124TEST_F(LibcurlHttpFetcherTest, HttpFetcherStateMachineRetrySucceedTest) {
125 state_machine_.UpdateState(true);
126 state_machine_.UpdateState(false);
127 EXPECT_EQ(state_machine_.getState(),
128 UnresolvedHostStateMachine::State::kRetriedSuccess);
129}
130
131TEST_F(LibcurlHttpFetcherTest, HttpFetcherStateMachineNoRetryTest) {
132 state_machine_.UpdateState(false);
133 state_machine_.UpdateState(false);
134 EXPECT_EQ(state_machine_.getState(),
135 UnresolvedHostStateMachine::State::kInit);
136}
137
Jae Hoon Kim0ae8fe12019-06-26 14:32:50 -0700138} // namespace chromeos_update_engine