mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-15 07:06:11 -04:00
Implement fake GetResponse and migrate fake_http_client to third_party/nearby/internal/test
PiperOrigin-RevId: 544518775
This commit is contained in:
committed by
Copybara-Service
parent
a7ad6303ec
commit
a8b6fdee59
@@ -543,6 +543,7 @@ let package = Package(
|
||||
"internal/test/fake_device_info_test.cc",
|
||||
"internal/test/fake_task_runner_test.cc",
|
||||
"internal/test/fake_data_set_test.cc",
|
||||
"internal/test/fake_http_client_test.cc",
|
||||
"internal/weave/base_socket_test.cc",
|
||||
"internal/weave/control_packet_write_request_test.cc",
|
||||
"internal/weave/message_write_request_test.cc",
|
||||
|
||||
@@ -27,6 +27,8 @@ cc_library(
|
||||
"fake_clock.h",
|
||||
"fake_data_set.h",
|
||||
"fake_device_info.h",
|
||||
"fake_http_client.h",
|
||||
"fake_http_client_factory.h",
|
||||
"fake_single_thread_executor.h",
|
||||
"fake_task_runner.h",
|
||||
"fake_timer.h",
|
||||
@@ -39,11 +41,14 @@ cc_library(
|
||||
deps = [
|
||||
"//internal/base:bluetooth_address",
|
||||
"//internal/data:data_manager",
|
||||
"//internal/network:types",
|
||||
"//internal/platform:comm",
|
||||
"//internal/platform:types",
|
||||
"//internal/platform/implementation:types",
|
||||
"@com_google_absl//absl/base:core_headers",
|
||||
"@com_google_absl//absl/container:flat_hash_map",
|
||||
"@com_google_absl//absl/status",
|
||||
"@com_google_absl//absl/status:statusor",
|
||||
"@com_google_absl//absl/strings",
|
||||
"@com_google_absl//absl/synchronization",
|
||||
"@com_google_absl//absl/time",
|
||||
@@ -59,6 +64,7 @@ cc_test(
|
||||
"fake_clock_test.cc",
|
||||
"fake_data_set_test.cc",
|
||||
"fake_device_info_test.cc",
|
||||
"fake_http_client_test.cc",
|
||||
"fake_task_runner_test.cc",
|
||||
"fake_timer_test.cc",
|
||||
],
|
||||
@@ -69,9 +75,14 @@ cc_test(
|
||||
deps = [
|
||||
":test",
|
||||
"//internal/data:data_manager",
|
||||
"//internal/network:types",
|
||||
"//internal/platform/implementation:types",
|
||||
"//internal/platform/implementation/g3", # fixdeps: keep
|
||||
"@com_github_protobuf_matchers//protobuf-matchers",
|
||||
"@com_google_absl//absl/container:flat_hash_map",
|
||||
"@com_google_absl//absl/status",
|
||||
"@com_google_absl//absl/status:statusor",
|
||||
"@com_google_absl//absl/strings",
|
||||
"@com_google_absl//absl/synchronization",
|
||||
"@com_google_absl//absl/time",
|
||||
"@com_google_googletest//:gtest_main",
|
||||
|
||||
@@ -0,0 +1,186 @@
|
||||
// Copyright 2021-2023 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef THIRD_PARTY_NEARBY_INTERNAL_TEST_FAKE_HTTP_CLIENT_H_
|
||||
#define THIRD_PARTY_NEARBY_INTERNAL_TEST_FAKE_HTTP_CLIENT_H_
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/status/status.h"
|
||||
#include "absl/status/statusor.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "internal/network/http_client.h"
|
||||
#include "internal/network/http_request.h"
|
||||
#include "internal/network/http_response.h"
|
||||
#include "internal/network/http_status_code.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace network {
|
||||
|
||||
class FakeHttpClient : public HttpClient {
|
||||
public:
|
||||
struct RequestInfo {
|
||||
HttpRequest request;
|
||||
std::function<void(const absl::StatusOr<HttpResponse>&)> callback;
|
||||
};
|
||||
|
||||
FakeHttpClient() = default;
|
||||
explicit FakeHttpClient(const HttpRequest& request);
|
||||
~FakeHttpClient() override = default;
|
||||
|
||||
FakeHttpClient(const FakeHttpClient&) = default;
|
||||
FakeHttpClient& operator=(const FakeHttpClient&) = default;
|
||||
FakeHttpClient(FakeHttpClient&&) = default;
|
||||
FakeHttpClient& operator=(FakeHttpClient&&) = default;
|
||||
|
||||
void StartRequest(const HttpRequest& request,
|
||||
std::function<void(const absl::StatusOr<HttpResponse>&)>
|
||||
callback) override {
|
||||
RequestInfo request_info;
|
||||
request_info.request = request;
|
||||
request_info.callback = callback;
|
||||
request_infos_.push_back(std::move(request_info));
|
||||
}
|
||||
|
||||
void StartCancellableRequest(
|
||||
std::unique_ptr<CancellableRequest> request,
|
||||
std::function<void(const absl::StatusOr<HttpResponse>&)> callback)
|
||||
override {
|
||||
RequestInfo request_info;
|
||||
request_info.request = request->http_request();
|
||||
request_info.callback = callback;
|
||||
request_infos_.push_back(std::move(request_info));
|
||||
}
|
||||
|
||||
absl::StatusOr<HttpResponse> GetResponse(
|
||||
const HttpRequest& request) override {
|
||||
if (sync_responses_.empty()) {
|
||||
return absl::FailedPreconditionError("No response.");
|
||||
}
|
||||
auto response = sync_responses_.front();
|
||||
sync_responses_.erase(sync_responses_.begin());
|
||||
return response;
|
||||
}
|
||||
|
||||
void SetResponseForSyncRequest(const absl::StatusOr<HttpResponse>& response) {
|
||||
sync_responses_.push_back(response);
|
||||
}
|
||||
|
||||
// Mock methods
|
||||
void CompleteRequest(const absl::StatusOr<HttpResponse>& response,
|
||||
size_t pos = 0) {
|
||||
if (pos >= request_infos_.size()) {
|
||||
return;
|
||||
}
|
||||
auto request_info = request_infos_.at(pos);
|
||||
if (request_info.callback != nullptr) {
|
||||
request_info.callback(response);
|
||||
}
|
||||
|
||||
request_infos_.erase(request_infos_.begin() + pos);
|
||||
}
|
||||
|
||||
void CompleteRequest(
|
||||
int error,
|
||||
std::optional<nearby::network::HttpStatusCode> response_code =
|
||||
std::nullopt,
|
||||
const std::optional<std::string>& response_string = std::nullopt,
|
||||
size_t pos = 0) {
|
||||
absl::StatusOr<nearby::network::HttpResponse> result;
|
||||
|
||||
nearby::network::HttpResponse response;
|
||||
if (error == 0) {
|
||||
absl::Status status =
|
||||
HTTPCodeToStatus(static_cast<int>(*response_code), "");
|
||||
if (status.ok()) {
|
||||
if (response_code.has_value()) {
|
||||
response.SetStatusCode(*response_code);
|
||||
}
|
||||
|
||||
if (response_string.has_value()) {
|
||||
response.SetBody(*response_string);
|
||||
}
|
||||
|
||||
response.SetHeaders({{"Content-type", {"text/html"}}});
|
||||
result = response;
|
||||
} else {
|
||||
result = status;
|
||||
}
|
||||
} else {
|
||||
result = absl::Status(absl::StatusCode::kFailedPrecondition,
|
||||
std::to_string(error));
|
||||
}
|
||||
|
||||
CompleteRequest(result, pos);
|
||||
}
|
||||
|
||||
absl::Status HTTPCodeToStatus(int status_code,
|
||||
absl::string_view status_message) {
|
||||
absl::Status status = absl::OkStatus();
|
||||
switch (status_code) {
|
||||
case 400:
|
||||
return absl::InvalidArgumentError(status_message);
|
||||
case 401:
|
||||
return absl::UnauthenticatedError(status_message);
|
||||
case 403:
|
||||
return absl::PermissionDeniedError(status_message);
|
||||
case 404:
|
||||
return absl::NotFoundError(status_message);
|
||||
case 409:
|
||||
return absl::AbortedError(status_message);
|
||||
case 416:
|
||||
return absl::OutOfRangeError(status_message);
|
||||
case 429:
|
||||
return absl::ResourceExhaustedError(status_message);
|
||||
case 499:
|
||||
return absl::CancelledError(status_message);
|
||||
case 504:
|
||||
return absl::DeadlineExceededError(status_message);
|
||||
case 501:
|
||||
return absl::UnimplementedError(status_message);
|
||||
case 503:
|
||||
return absl::UnavailableError(status_message);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (status_code >= 200 && status_code < 300) {
|
||||
return absl::OkStatus();
|
||||
} else if (status_code >= 400 && status_code < 500) {
|
||||
return absl::FailedPreconditionError(status_message);
|
||||
} else if (status_code >= 500 && status_code < 600) {
|
||||
return absl::InternalError(status_message);
|
||||
}
|
||||
return absl::UnknownError(status_message);
|
||||
}
|
||||
|
||||
const std::vector<RequestInfo>& GetPendingRequest() { return request_infos_; }
|
||||
|
||||
private:
|
||||
std::vector<RequestInfo> request_infos_;
|
||||
|
||||
// Response for sync request
|
||||
std::vector<absl::StatusOr<HttpResponse>> sync_responses_;
|
||||
};
|
||||
|
||||
} // namespace network
|
||||
} // namespace nearby
|
||||
|
||||
#endif // THIRD_PARTY_NEARBY_INTERNAL_TEST_FAKE_HTTP_CLIENT_H_
|
||||
@@ -0,0 +1,37 @@
|
||||
// Copyright 2022 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef THIRD_PARTY_NEARBY_INTERNAL_TEST_FAKE_HTTP_CLIENT_FACTORY_H_
|
||||
#define THIRD_PARTY_NEARBY_INTERNAL_TEST_FAKE_HTTP_CLIENT_FACTORY_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "internal/network/http_client.h"
|
||||
#include "internal/network/http_client_factory.h"
|
||||
#include "internal/test/fake_http_client.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace network {
|
||||
|
||||
class FakeHttpClientFactory : public HttpClientFactory {
|
||||
public:
|
||||
std::unique_ptr<HttpClient> CreateInstance() override {
|
||||
return std::make_unique<FakeHttpClient>();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace network
|
||||
} // namespace nearby
|
||||
|
||||
#endif // THIRD_PARTY_NEARBY_INTERNAL_TEST_FAKE_HTTP_CLIENT_FACTORY_H_
|
||||
@@ -0,0 +1,163 @@
|
||||
// Copyright 2021 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "internal/test/fake_http_client.h"
|
||||
|
||||
#include <functional>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "protobuf-matchers/protocol-buffer-matchers.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/container/flat_hash_map.h"
|
||||
#include "absl/status/status.h"
|
||||
#include "absl/status/statusor.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "internal/network/http_request.h"
|
||||
#include "internal/network/http_response.h"
|
||||
#include "internal/network/http_status_code.h"
|
||||
#include "internal/network/url.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace network {
|
||||
namespace {
|
||||
|
||||
class FakekHttpClientTest : public ::testing::Test {
|
||||
public:
|
||||
void StartRequest(
|
||||
absl::string_view request_url,
|
||||
std::function<void(const absl::StatusOr<HttpResponse>&)> callback) {
|
||||
HttpRequest request;
|
||||
Url url;
|
||||
url.SetUrlPath(request_url);
|
||||
request.SetUrl(url);
|
||||
request.SetMethod(HttpRequestMethod::kPost);
|
||||
request.SetBody("request body");
|
||||
client_.StartRequest(request, callback);
|
||||
}
|
||||
|
||||
void CompleteRequest(
|
||||
HttpStatusCode status, std::string status_message = "",
|
||||
absl::flat_hash_map<std::string, std::vector<std::string>> headers = {},
|
||||
std::string body = "", int pos = 0) {
|
||||
HttpResponse response;
|
||||
response.SetStatusCode(status);
|
||||
response.SetReasonPhrase(status_message);
|
||||
response.SetHeaders(headers);
|
||||
response.SetBody(body);
|
||||
client_.CompleteRequest(response, pos);
|
||||
}
|
||||
|
||||
void CompleteRequest(int error, int status = 200, int pos = 0) {
|
||||
client_.CompleteRequest(error, static_cast<HttpStatusCode>(status),
|
||||
std::nullopt, pos);
|
||||
}
|
||||
|
||||
void CheckHttpError(int status, absl::StatusCode expected_status) {
|
||||
absl::StatusOr<HttpResponse> response;
|
||||
StartRequest("http://www.google.com",
|
||||
[&response](const absl::StatusOr<HttpResponse>& res) {
|
||||
response = res;
|
||||
});
|
||||
|
||||
client_.CompleteRequest(0, static_cast<HttpStatusCode>(status),
|
||||
std::nullopt);
|
||||
if (status >= 200 & status < 300) {
|
||||
ASSERT_TRUE(response.ok());
|
||||
} else {
|
||||
ASSERT_FALSE(response.ok());
|
||||
}
|
||||
|
||||
EXPECT_EQ(response.status().code(), expected_status);
|
||||
}
|
||||
|
||||
protected:
|
||||
FakeHttpClient client_;
|
||||
};
|
||||
|
||||
TEST_F(FakekHttpClientTest, TestMockHttpResponse) {
|
||||
absl::StatusOr<HttpResponse> response;
|
||||
StartRequest(
|
||||
"http://www.google.com",
|
||||
[&response](const absl::StatusOr<HttpResponse>& res) { response = res; });
|
||||
|
||||
CompleteRequest(HttpStatusCode::kHttpOk);
|
||||
ASSERT_OK(response);
|
||||
EXPECT_EQ(response->GetStatusCode(), HttpStatusCode::kHttpOk);
|
||||
}
|
||||
|
||||
TEST_F(FakekHttpClientTest, TestGetResponse) {
|
||||
// Set up HttpRequest
|
||||
HttpRequest request;
|
||||
Url url;
|
||||
url.SetUrlPath("http://www.google.com");
|
||||
request.SetUrl(url);
|
||||
request.SetMethod(HttpRequestMethod::kGet);
|
||||
request.SetBody("request body");
|
||||
// Set up HttpResponse
|
||||
HttpResponse response;
|
||||
response.SetStatusCode(HttpStatusCode::kHttpOk);
|
||||
client_.SetResponseForSyncRequest(response);
|
||||
// Sync GetResponse
|
||||
absl::StatusOr<HttpResponse> result = client_.GetResponse(request);
|
||||
|
||||
ASSERT_OK(result);
|
||||
EXPECT_EQ(result->GetStatusCode(), HttpStatusCode::kHttpOk);
|
||||
}
|
||||
|
||||
TEST_F(FakekHttpClientTest, TestSystemError) {
|
||||
absl::StatusOr<HttpResponse> response;
|
||||
StartRequest(
|
||||
"http://www.google.com",
|
||||
[&response](const absl::StatusOr<HttpResponse>& res) { response = res; });
|
||||
|
||||
CompleteRequest(0xffff);
|
||||
ASSERT_FALSE(response.ok());
|
||||
EXPECT_EQ(response.status().code(), absl::StatusCode::kFailedPrecondition);
|
||||
}
|
||||
|
||||
TEST_F(FakekHttpClientTest, TestHttpErrorCodes) {
|
||||
CheckHttpError(200, absl::StatusCode::kOk);
|
||||
CheckHttpError(400, absl::StatusCode::kInvalidArgument);
|
||||
CheckHttpError(401, absl::StatusCode::kUnauthenticated);
|
||||
CheckHttpError(403, absl::StatusCode::kPermissionDenied);
|
||||
CheckHttpError(404, absl::StatusCode::kNotFound);
|
||||
CheckHttpError(409, absl::StatusCode::kAborted);
|
||||
CheckHttpError(416, absl::StatusCode::kOutOfRange);
|
||||
CheckHttpError(429, absl::StatusCode::kResourceExhausted);
|
||||
CheckHttpError(499, absl::StatusCode::kCancelled);
|
||||
CheckHttpError(504, absl::StatusCode::kDeadlineExceeded);
|
||||
CheckHttpError(501, absl::StatusCode::kUnimplemented);
|
||||
CheckHttpError(503, absl::StatusCode::kUnavailable);
|
||||
CheckHttpError(488, absl::StatusCode::kFailedPrecondition);
|
||||
CheckHttpError(522, absl::StatusCode::kInternal);
|
||||
CheckHttpError(777, absl::StatusCode::kUnknown);
|
||||
}
|
||||
|
||||
TEST_F(FakekHttpClientTest, TestCompleteNotExistingRequest) {
|
||||
int count = 0;
|
||||
StartRequest("http://www.google.com",
|
||||
[&count](const absl::StatusOr<HttpResponse>& res) { ++count; });
|
||||
|
||||
CompleteRequest(0xffff);
|
||||
EXPECT_EQ(count, 1);
|
||||
CompleteRequest(0xffff);
|
||||
EXPECT_EQ(count, 1);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace network
|
||||
} // namespace nearby
|
||||
Reference in New Issue
Block a user