From 20d7ec11832e4e266d1173e3e03c127374743c8b Mon Sep 17 00:00:00 2001 From: Yevhenii Dudnyk Date: Wed, 26 Jan 2022 10:49:52 +0200 Subject: [PATCH] Add async methods for GetLatestVersion Creation of asynchronous methods is a part of task continuation changes, later will be used in asynchronous GetVersion method. GetVersion is not added in this commit as it's in the private section and cannot be covered with tests. Add asynchronous version of GetLatestVersion method which handles the logic of getting data from cache/network. Add asynchronous version of GetLatestCatalogVersion. Move common functionality of getting data from the cache and storing data returned from a request to the cache to the RetrieveLatestVersion function. Add unit tests which cover asynchronous methods for getting the latest version. Replaced mock expectation arguments with WithoutArgs. Relates-To: OLPEDGE-2718 Signed-off-by: Yevhenii Dudnyk --- .../src/generated/api/MetadataApi.cpp | 34 +- .../src/generated/api/MetadataApi.h | 21 + .../src/repositories/CatalogRepository.cpp | 159 ++++- .../src/repositories/CatalogRepository.h | 9 +- .../tests/CatalogRepositoryTest.cpp | 648 +++++++++++------- 5 files changed, 596 insertions(+), 275 deletions(-) diff --git a/olp-cpp-sdk-dataservice-read/src/generated/api/MetadataApi.cpp b/olp-cpp-sdk-dataservice-read/src/generated/api/MetadataApi.cpp index 6f1109ad7..73a031d88 100644 --- a/olp-cpp-sdk-dataservice-read/src/generated/api/MetadataApi.cpp +++ b/olp-cpp-sdk-dataservice-read/src/generated/api/MetadataApi.cpp @@ -124,7 +124,7 @@ MetadataApi::PartitionsExtendedResponse MetadataApi::GetPartitions( auto partitions_response = parser::parse_result(http_response.response); - if (!partitions_response.IsSuccessful()) { + if (!partitions_response) { return {{partitions_response.GetError()}, http_response.GetNetworkStatistics()}; } @@ -134,14 +134,14 @@ MetadataApi::PartitionsExtendedResponse MetadataApi::GetPartitions( } MetadataApi::CatalogVersionResponse MetadataApi::GetLatestCatalogVersion( - const client::OlpClient& client, std::int64_t startVersion, + const client::OlpClient& client, std::int64_t start_version, boost::optional billing_tag, const client::CancellationContext& context) { std::multimap header_params; header_params.emplace("Accept", "application/json"); std::multimap query_params; - query_params.emplace("startVersion", std::to_string(startVersion)); + query_params.emplace("startVersion", std::to_string(start_version)); if (billing_tag) { query_params.emplace("billingTag", *billing_tag); } @@ -158,6 +158,34 @@ MetadataApi::CatalogVersionResponse MetadataApi::GetLatestCatalogVersion( return parser::parse_result(api_response.response); } +client::CancellationToken MetadataApi::GetLatestCatalogVersion( + const client::OlpClient& client, int64_t start_version, + boost::optional billing_tag, CatalogVersionCallback callback) { + std::multimap header_params; + header_params.emplace("Accept", "application/json"); + + std::multimap query_params; + query_params.emplace("startVersion", std::to_string(start_version)); + if (billing_tag) { + query_params.emplace("billingTag", *billing_tag); + } + + std::string metadata_uri = "/versions/latest"; + + return client.CallApi( + metadata_uri, "GET", query_params, header_params, {}, nullptr, "", + [callback](client::HttpResponse api_response) { + if (api_response.status != http::HttpStatusCode::OK) { + callback(client::ApiError(api_response.status, + api_response.response.str())); + return; + } + + callback(parser::parse_result( + api_response.response)); + }); +} + MetadataApi::VersionsResponse MetadataApi::ListVersions( const client::OlpClient& client, std::int64_t start_version, std::int64_t end_version, boost::optional billing_tag, diff --git a/olp-cpp-sdk-dataservice-read/src/generated/api/MetadataApi.h b/olp-cpp-sdk-dataservice-read/src/generated/api/MetadataApi.h index 8b517a76f..e1e581ec2 100644 --- a/olp-cpp-sdk-dataservice-read/src/generated/api/MetadataApi.h +++ b/olp-cpp-sdk-dataservice-read/src/generated/api/MetadataApi.h @@ -27,6 +27,7 @@ #include #include "ExtendedApiResponse.h" #include "generated/model/LayerVersions.h" +#include "olp/dataservice/read/Types.h" #include "olp/dataservice/read/model/Partitions.h" #include "olp/dataservice/read/model/VersionInfos.h" #include "olp/dataservice/read/model/VersionResponse.h" @@ -130,6 +131,26 @@ class MetadataApi { boost::optional billing_tag, const client::CancellationContext& context); + /** + * @brief Retrieves the latest metadata version for the catalog. + * + * @param client Instance of OlpClient used to make REST request. + * @param start_version The catalog version returned from a prior request. + * Save the version from each request so it can used in the startVersion + * parameter of subsequent requests. If the version from a prior request is + * not avaliable, set the parameter to -1. + * @param billing_tag An optional free-form tag which is used for grouping + * billing records together. If supplied, it must be between 4 - 16 + * characters, contain only alpha/numeric ASCII characters [A-Za-z0-9]. + * @param callback The callback which returns a result of the operation. + * + * @return The `CancellationToken` instance. + */ + static client::CancellationToken GetLatestCatalogVersion( + const client::OlpClient& client, int64_t start_version, + boost::optional billing_tag, + read::CatalogVersionCallback callback); + static VersionsResponse ListVersions( const client::OlpClient& client, int64_t start_version, int64_t end_version, boost::optional billing_tag, diff --git a/olp-cpp-sdk-dataservice-read/src/repositories/CatalogRepository.cpp b/olp-cpp-sdk-dataservice-read/src/repositories/CatalogRepository.cpp index f5150ca71..a9cba193e 100644 --- a/olp-cpp-sdk-dataservice-read/src/repositories/CatalogRepository.cpp +++ b/olp-cpp-sdk-dataservice-read/src/repositories/CatalogRepository.cpp @@ -35,7 +35,64 @@ #include "olp/dataservice/read/VersionsRequest.h" namespace { +constexpr auto kDefaultStartVersion = 0; constexpr auto kLogTag = "CatalogRepository"; + +// The function retrieves the maximum version among cached/online/user-provided +// versions. +// Update the cache, if the retrieved version is greater than the cached one. +olp::dataservice::read::CatalogVersionResponse RetrieveLatestVersion( + const olp::client::HRN& catalog, + const olp::dataservice::read::CatalogVersionRequest& request, + olp::dataservice::read::repository::CatalogCacheRepository& repository, + olp::dataservice::read::CatalogVersionResponse&& version_response) { + auto cached_version = repository.GetVersion(); + auto fetch_option = request.GetFetchOption(); + + // Using `GetStartVersion` to set up a new latest version for CacheOnly + // requests in case of absence of the previous latest version or it's less + // than the new user set version. + if (fetch_option == olp::dataservice::read::FetchOptions::CacheOnly) { + const auto start_version = request.GetStartVersion(); + if (start_version >= kDefaultStartVersion && + (!cached_version || start_version > cached_version->GetVersion())) { + olp::dataservice::read::model::VersionResponse new_response; + new_response.SetVersion(start_version); + version_response = std::move(new_response); + } + } + + if (version_response) { + const auto new_version = version_response.GetResult().GetVersion(); + + // Write or update a version in the cache, updating happens only when the + // new version is greater than cached. + if (!cached_version || cached_version->GetVersion() < new_version) { + repository.PutVersion(version_response.GetResult()); + if (fetch_option == olp::dataservice::read::FetchOptions::CacheOnly) { + OLP_SDK_LOG_DEBUG_F( + kLogTag, "Latest user set version, hrn='%s', version=%" PRId64, + catalog.ToCatalogHRNString().c_str(), new_version); + } else { + OLP_SDK_LOG_DEBUG_F(kLogTag, + "Latest online version, hrn='%s', version=%" PRId64, + catalog.ToCatalogHRNString().c_str(), new_version); + } + } + + return std::move(version_response); + } + + if (cached_version) { + OLP_SDK_LOG_DEBUG_F( + kLogTag, "Latest cached version, hrn='%s', version=%" PRId64, + catalog.ToCatalogHRNString().c_str(), cached_version->GetVersion()); + version_response = std::move(*cached_version); + } + + return std::move(version_response); +} + } // namespace namespace olp { @@ -56,8 +113,8 @@ CatalogResponse CatalogRepository::GetCatalog( const auto fetch_options = request.GetFetchOption(); const auto catalog_str = catalog_.ToCatalogHRNString(); - repository::CatalogCacheRepository repository( - catalog_, settings_.cache, settings_.default_cache_expiration); + CatalogCacheRepository repository(catalog_, settings_.cache, + settings_.default_cache_expiration); if (fetch_options != OnlineOnly && fetch_options != CacheWithUpdate) { auto cached = repository.Get(); @@ -80,7 +137,7 @@ CatalogResponse CatalogRepository::GetCatalog( "config", "v1", static_cast(fetch_options), context); - if (!config_api.IsSuccessful()) { + if (!config_api) { return config_api.GetError(); } @@ -88,10 +145,11 @@ CatalogResponse CatalogRepository::GetCatalog( auto catalog_response = ConfigApi::GetCatalog( config_client, catalog_str, request.GetBillingTag(), context); - if (catalog_response.IsSuccessful() && fetch_options != OnlineOnly) { + if (catalog_response && fetch_options != OnlineOnly) { repository.Put(catalog_response.GetResult()); } - if (!catalog_response.IsSuccessful()) { + + if (!catalog_response) { const auto& error = catalog_response.GetError(); if (error.GetHttpStatusCode() == http::HttpStatusCode::FORBIDDEN) { OLP_SDK_LOG_WARNING_F(kLogTag, @@ -107,12 +165,12 @@ CatalogResponse CatalogRepository::GetCatalog( CatalogVersionResponse CatalogRepository::GetLatestVersion( const CatalogVersionRequest& request, client::CancellationContext context) { - repository::CatalogCacheRepository repository( - catalog_, settings_.cache, settings_.default_cache_expiration); + CatalogCacheRepository repository(catalog_, settings_.cache, + settings_.default_cache_expiration); const auto fetch_option = request.GetFetchOption(); - // in case get version online was never called and version was not found in - // cache + // In case `GetVersionOnline` was never called and version was not found in + // the cache CatalogVersionResponse version_response = { {client::ErrorCode::NotFound, "Failed to find version."}}; @@ -124,7 +182,7 @@ CatalogVersionResponse CatalogRepository::GetLatestVersion( return version_response; } - if (!version_response.IsSuccessful()) { + if (!version_response) { const auto& error = version_response.GetError(); if (error.GetHttpStatusCode() == http::HttpStatusCode::FORBIDDEN) { OLP_SDK_LOG_WARNING_F( @@ -143,8 +201,6 @@ CatalogVersionResponse CatalogRepository::GetLatestVersion( // requests in case of absence of previous latest version or it less than the // new user set version if (fetch_option == CacheOnly) { - constexpr auto kDefaultStartVersion = 0; - auto user_set_version = request.GetStartVersion(); if (user_set_version >= kDefaultStartVersion) { if (!cached_version || user_set_version > cached_version->GetVersion()) { @@ -155,11 +211,11 @@ CatalogVersionResponse CatalogRepository::GetLatestVersion( } } - if (version_response.IsSuccessful()) { + if (version_response) { const auto new_version = version_response.GetResult().GetVersion(); // Write or update the version in cache, updating happens only when the new // version is greater than cached. - if (!cached_version || (*cached_version).GetVersion() < new_version) { + if (!cached_version || cached_version->GetVersion() < new_version) { repository.PutVersion(version_response.GetResult()); if (fetch_option == CacheOnly) { OLP_SDK_LOG_DEBUG_F( @@ -171,25 +227,69 @@ CatalogVersionResponse CatalogRepository::GetLatestVersion( catalog_.ToCatalogHRNString().c_str(), new_version); } } + return version_response; } if (cached_version) { OLP_SDK_LOG_DEBUG_F( kLogTag, "Latest cached version, hrn='%s', version=%" PRId64, - catalog_.ToCatalogHRNString().c_str(), (*cached_version).GetVersion()); - version_response = *std::move(cached_version); + catalog_.ToCatalogHRNString().c_str(), cached_version->GetVersion()); + version_response = std::move(*cached_version); } return version_response; } +client::CancellationToken CatalogRepository::GetLatestVersion( + const CatalogVersionRequest& request, CatalogVersionCallback callback) { + CatalogCacheRepository repository(catalog_, settings_.cache, + settings_.default_cache_expiration); + + const auto fetch_option = request.GetFetchOption(); + + if (fetch_option == CacheOnly) { + // Initialize response to an error. It will be overwritten in case a valid + // version is found in the cache or user request. + CatalogVersionResponse version_response{ + {client::ErrorCode::NotFound, "Failed to find a catalog version."}}; + + callback(RetrieveLatestVersion(catalog_, request, repository, + std::move(version_response))); + return client::CancellationToken(); + } + + return GetLatestVersionOnline( + request.GetBillingTag(), [=](CatalogVersionResponse response) mutable { + if (fetch_option == OnlineOnly) { + callback(std::move(response)); + return; + } + + if (!response) { + const auto& error = response.GetError(); + if (error.GetHttpStatusCode() == http::HttpStatusCode::FORBIDDEN) { + OLP_SDK_LOG_WARNING_F( + kLogTag, + "Latest version request ended with 403 HTTP code, hrn='%s'", + catalog_.ToCatalogHRNString().c_str()); + repository.Clear(); + callback(std::move(response)); + return; + } + } + + callback(RetrieveLatestVersion(catalog_, request, repository, + std::move(response))); + }); +} + VersionsResponse CatalogRepository::GetVersionsList( const VersionsRequest& request, client::CancellationContext context) { auto metadata_api = lookup_client_.LookupApi("metadata", "v1", client::OnlineOnly, context); - if (!metadata_api.IsSuccessful()) { + if (!metadata_api) { return metadata_api.GetError(); } @@ -206,7 +306,7 @@ CatalogVersionResponse CatalogRepository::GetLatestVersionOnline( auto metadata_api = lookup_client_.LookupApi( "metadata", "v1", client::OnlineIfNotFound, context); - if (!metadata_api.IsSuccessful()) { + if (!metadata_api) { return metadata_api.GetError(); } @@ -216,13 +316,34 @@ CatalogVersionResponse CatalogRepository::GetLatestVersionOnline( context); } +client::CancellationToken CatalogRepository::GetLatestVersionOnline( + const boost::optional& billing_tag, + CatalogVersionCallback callback) { + return lookup_client_.LookupApi( + "metadata", "v1", client::OnlineIfNotFound, + [=](client::ApiLookupClient::LookupApiResponse response) { + if (!response) { + callback(response.GetError()); + return client::CancellationToken(); + } + + const auto& metadata_client = response.GetResult(); + + return MetadataApi::GetLatestCatalogVersion( + metadata_client, -1, billing_tag, + [=](CatalogVersionResponse catalog_version_response) { + callback(std::move(catalog_version_response)); + }); + }); +} + CompatibleVersionsResponse CatalogRepository::GetCompatibleVersions( const CompatibleVersionsRequest& request, client::CancellationContext context) { auto metadata_api = lookup_client_.LookupApi("metadata", "v1", client::OnlineOnly, context); - if (!metadata_api.IsSuccessful()) { + if (!metadata_api) { return metadata_api.GetError(); } diff --git a/olp-cpp-sdk-dataservice-read/src/repositories/CatalogRepository.h b/olp-cpp-sdk-dataservice-read/src/repositories/CatalogRepository.h index 1aeb6e88c..8d1924c3e 100644 --- a/olp-cpp-sdk-dataservice-read/src/repositories/CatalogRepository.h +++ b/olp-cpp-sdk-dataservice-read/src/repositories/CatalogRepository.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019-2020 HERE Europe B.V. + * Copyright (C) 2019-2022 HERE Europe B.V. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -49,6 +49,9 @@ class CatalogRepository final { CatalogVersionResponse GetLatestVersion(const CatalogVersionRequest& request, client::CancellationContext context); + client::CancellationToken GetLatestVersion( + const CatalogVersionRequest& request, CatalogVersionCallback callback); + VersionsResponse GetVersionsList(const VersionsRequest& request, client::CancellationContext context); @@ -61,6 +64,10 @@ class CatalogRepository final { const boost::optional& billing_tag, client::CancellationContext context); + client::CancellationToken GetLatestVersionOnline( + const boost::optional& billing_tag, + CatalogVersionCallback callback); + client::HRN catalog_; client::OlpClientSettings settings_; client::ApiLookupClient lookup_client_; diff --git a/olp-cpp-sdk-dataservice-read/tests/CatalogRepositoryTest.cpp b/olp-cpp-sdk-dataservice-read/tests/CatalogRepositoryTest.cpp index ce004c2ea..00fd69ab4 100644 --- a/olp-cpp-sdk-dataservice-read/tests/CatalogRepositoryTest.cpp +++ b/olp-cpp-sdk-dataservice-read/tests/CatalogRepositoryTest.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019-2021 HERE Europe B.V. + * Copyright (C) 2019-2022 HERE Europe B.V. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,11 +19,13 @@ #include "repositories/CatalogRepository.h" -#include +#include #include #include #include #include +#include +#include #include "ApiClientLookup.h" #include "olp/dataservice/read/CatalogRequest.h" #include "olp/dataservice/read/CatalogVersionRequest.h" @@ -36,6 +38,8 @@ constexpr auto kResponseLookupMetadata = R"jsonString([{"api":"metadata","version":"v1","baseURL":"https://metadata.data.api.platform.here.com/metadata/v1/catalogs/hereos-internal-test-v2","parameters":{}}])jsonString"; constexpr auto kLatestCatalogVersion = R"(https://metadata.data.api.platform.here.com/metadata/v1/catalogs/hereos-internal-test-v2/versions/latest?startVersion=-1)"; +constexpr auto kLatestCatalogVersionWithBillingTag = + R"(https://metadata.data.api.platform.here.com/metadata/v1/catalogs/hereos-internal-test-v2/versions/latest?billingTag=OlpCppSdkTest&startVersion=-1)"; constexpr auto kResponseLatestCatalogVersion = R"jsonString({"version":4})jsonString"; constexpr auto kUrlConfig = @@ -59,10 +63,12 @@ constexpr auto kHttpResponse = namespace { namespace read = olp::dataservice::read; +namespace client = olp::client; +namespace http = olp::http; namespace model = olp::dataservice::read::model; namespace repository = olp::dataservice::read::repository; -using olp::client::ApiLookupClient; -using ::testing::_; +using client::ApiLookupClient; +using testing::_; const std::string kCatalog = "hrn:here:data::olp-here-test:hereos-internal-test-v2"; @@ -80,7 +86,8 @@ const std::string kLookupUrl = kCatalog + "/apis/" + kMetadataServiceName + "/" + kServiceVersion; const std::string kVersionInfosCacheKey = kCatalog + "::3::4::versionInfos"; -const auto kHrn = olp::client::HRN::FromString(kCatalog); +const auto kHrn = client::HRN::FromString(kCatalog); +constexpr auto kMaxWaitMs = std::chrono::milliseconds(150); class CatalogRepositoryTest : public ::testing::Test { protected: @@ -91,8 +98,7 @@ class CatalogRepositoryTest : public ::testing::Test { settings_.network_request_handler = network_; settings_.cache = cache_; - lookup_client_ = - std::make_shared(kHrn, settings_); + lookup_client_ = std::make_shared(kHrn, settings_); } void TearDown() override { @@ -105,126 +111,245 @@ class CatalogRepositoryTest : public ::testing::Test { std::shared_ptr cache_; std::shared_ptr network_; - olp::client::OlpClientSettings settings_; - std::shared_ptr lookup_client_; + client::OlpClientSettings settings_; + std::shared_ptr lookup_client_; }; TEST_F(CatalogRepositoryTest, GetLatestVersionCacheOnlyFound) { - olp::client::CancellationContext context; + client::CancellationContext context; - auto request = read::CatalogVersionRequest(); - - request.WithFetchOption(read::CacheOnly); + const auto request = + read::CatalogVersionRequest().WithFetchOption(read::CacheOnly); model::VersionResponse cached_version; cached_version.SetVersion(10); EXPECT_CALL(*cache_, Get(kLatestVersionCacheKey, _)) - .Times(1) .WillOnce(testing::Return(cached_version)); ApiLookupClient lookup_client(kHrn, settings_); repository::CatalogRepository repository(kHrn, settings_, lookup_client); - auto response = repository.GetLatestVersion(request, context); + const auto response = repository.GetLatestVersion(request, context); - ASSERT_TRUE(response.IsSuccessful()); + ASSERT_TRUE(response); EXPECT_EQ(10, response.GetResult().GetVersion()); } TEST_F(CatalogRepositoryTest, GetLatestVersionCacheOnlyNotFound) { - olp::client::CancellationContext context; + client::CancellationContext context; - auto request = read::CatalogVersionRequest(); + const auto request = + read::CatalogVersionRequest().WithFetchOption(read::CacheOnly); - request.WithFetchOption(read::CacheOnly); + EXPECT_CALL(*cache_, Get(_, _)).WillOnce(testing::Return(boost::any{})); + + ON_CALL(*network_, Send(_, _, _, _, _)) + .WillByDefault(testing::WithoutArgs([]() { + ADD_FAILURE() << "Should not be called with CacheOnly"; + return http::SendOutcome(http::ErrorCode::UNKNOWN_ERROR); + })); + + ApiLookupClient lookup_client(kHrn, settings_); + repository::CatalogRepository repository(kHrn, settings_, lookup_client); + const auto response = repository.GetLatestVersion(request, context); + + EXPECT_FALSE(response); + EXPECT_EQ(response.GetError().GetErrorCode(), client::ErrorCode::NotFound); +} + +TEST_F(CatalogRepositoryTest, AsyncGetLatestVersionCacheOnlyNotFound) { + client::CancellationContext context; - EXPECT_CALL(*cache_, Get(_, _)) - .Times(1) - .WillOnce(testing::Return(boost::any{})); + const auto request = + read::CatalogVersionRequest().WithFetchOption(read::CacheOnly); + + EXPECT_CALL(*cache_, Get(_, _)).WillOnce(testing::Return(boost::any{})); ON_CALL(*network_, Send(_, _, _, _, _)) - .WillByDefault([](olp::http::NetworkRequest, olp::http::Network::Payload, - olp::http::Network::Callback, - olp::http::Network::HeaderCallback, - olp::http::Network::DataCallback) { + .WillByDefault(testing::WithoutArgs([]() { ADD_FAILURE() << "Should not be called with CacheOnly"; - return olp::http::SendOutcome(olp::http::ErrorCode::UNKNOWN_ERROR); - }); + return http::SendOutcome(http::ErrorCode::UNKNOWN_ERROR); + })); ApiLookupClient lookup_client(kHrn, settings_); repository::CatalogRepository repository(kHrn, settings_, lookup_client); - auto response = repository.GetLatestVersion(request, context); - EXPECT_FALSE(response.IsSuccessful()); - EXPECT_EQ(response.GetError().GetErrorCode(), - olp::client::ErrorCode::NotFound); + std::promise promise; + auto future = promise.get_future(); + repository.GetLatestVersion(request, + [&](read::CatalogVersionResponse response) { + promise.set_value(std::move(response)); + }); + + ASSERT_EQ(future.wait_for(kMaxWaitMs), std::future_status::ready); + const auto result = future.get(); + + EXPECT_FALSE(result); + EXPECT_EQ(result.GetError().GetErrorCode(), client::ErrorCode::NotFound); } TEST_F(CatalogRepositoryTest, GetLatestVersionCacheOnlyRequestWithMinVersion) { - olp::client::CancellationContext context; + client::CancellationContext context; - auto request = read::CatalogVersionRequest(); - request.WithFetchOption(olp::dataservice::read::CacheOnly) - .WithStartVersion(kStartVersion); + const auto request = read::CatalogVersionRequest() + .WithFetchOption(olp::dataservice::read::CacheOnly) + .WithStartVersion(kStartVersion); - EXPECT_CALL(*cache_, Get(_, _)) - .Times(1) - .WillOnce(testing::Return(boost::any{})); + EXPECT_CALL(*cache_, Get(_, _)).WillOnce(testing::Return(boost::any{})); EXPECT_CALL(*cache_, Put(_, _, _, _)).Times(1); ON_CALL(*network_, Send(_, _, _, _, _)) - .WillByDefault([](olp::http::NetworkRequest, olp::http::Network::Payload, - olp::http::Network::Callback, - olp::http::Network::HeaderCallback, - olp::http::Network::DataCallback) { + .WillByDefault(testing::WithoutArgs([]() { ADD_FAILURE() << "Should not be called with CacheOnly"; - return olp::http::SendOutcome(olp::http::ErrorCode::UNKNOWN_ERROR); - }); + return http::SendOutcome(http::ErrorCode::UNKNOWN_ERROR); + })); ApiLookupClient lookup_client(kHrn, settings_); repository::CatalogRepository repository(kHrn, settings_, lookup_client); - auto response = repository.GetLatestVersion(request, context); + const auto response = repository.GetLatestVersion(request, context); - EXPECT_TRUE(response.IsSuccessful()); + EXPECT_TRUE(response); EXPECT_EQ(response.GetResult().GetVersion(), kStartVersion); } -TEST_F(CatalogRepositoryTest, GetLatestVersionOnlineOnlyNotFound) { - olp::client::CancellationContext context; +TEST_F(CatalogRepositoryTest, + AsyncGetLatestVersionCacheOnlyRequestWithMinVersion) { + const auto request = read::CatalogVersionRequest() + .WithFetchOption(olp::dataservice::read::CacheOnly) + .WithStartVersion(kStartVersion); - auto request = read::CatalogVersionRequest(); + EXPECT_CALL(*cache_, Get(_, _)).WillOnce(testing::Return(boost::any{})); - request.WithFetchOption(read::OnlineOnly); + EXPECT_CALL(*cache_, Put(_, _, _, _)).Times(1); - ON_CALL(*cache_, Get(_, _)) - .WillByDefault([](const std::string&, const olp::cache::Decoder&) { - ADD_FAILURE() << "Cache should not be used in OnlineOnly request"; - return boost::any{}; + ON_CALL(*network_, Send(_, _, _, _, _)) + .WillByDefault(testing::WithoutArgs([]() { + ADD_FAILURE() << "Should not be called with CacheOnly"; + return http::SendOutcome(http::ErrorCode::UNKNOWN_ERROR); + })); + + ApiLookupClient lookup_client(kHrn, settings_); + repository::CatalogRepository repository(kHrn, settings_, lookup_client); + + std::promise promise; + auto future = promise.get_future(); + + const auto response = repository.GetLatestVersion( + request, [&](read::CatalogVersionResponse response) { + promise.set_value(std::move(response)); }); + ASSERT_EQ(future.wait_for(kMaxWaitMs), std::future_status::ready); + const auto result = future.get(); + + EXPECT_TRUE(result); + EXPECT_EQ(result.GetResult().GetVersion(), kStartVersion); +} + +TEST_F(CatalogRepositoryTest, AsyncGetLatestVersionCacheOnly) { + const auto request = read::CatalogVersionRequest() + .WithFetchOption(olp::dataservice::read::CacheOnly) + .WithStartVersion(-1); + + auto cached_version = read::model::VersionResponse(); + cached_version.SetVersion(1); + EXPECT_CALL(*cache_, Get(kLatestVersionCacheKey, _)) + .WillOnce(testing::Return(cached_version)); + + ApiLookupClient lookup_client(kHrn, settings_); + repository::CatalogRepository repository(kHrn, settings_, lookup_client); + + std::promise promise; + auto future = promise.get_future(); + repository.GetLatestVersion(request, + [&](read::CatalogVersionResponse response) { + promise.set_value(std::move(response)); + }); + + ASSERT_EQ(future.wait_for(kMaxWaitMs), std::future_status::ready); + const auto result = future.get(); + + EXPECT_TRUE(result); + EXPECT_EQ(result.GetResult().GetVersion(), cached_version.GetVersion()); +} + +TEST_F(CatalogRepositoryTest, AsyncGetLatestVersionOnlineOnlyNotFound) { + auto request = + read::CatalogVersionRequest().WithFetchOption(read::OnlineOnly); + + ON_CALL(*cache_, Get(_, _)).WillByDefault(testing::WithoutArgs([]() { + ADD_FAILURE() << "Cache should not be used in OnlineOnly request"; + return boost::any{}; + })); + EXPECT_CALL(*cache_, Get(testing::Eq(kMetadataCacheKey), _)) .WillOnce(testing::Return(boost::any())); EXPECT_CALL(*network_, Send(IsGetRequest(kLookupMetadata), _, _, _, _)) - .Times(1) - .WillOnce(ReturnHttpResponse(olp::http::NetworkResponse().WithStatus( - olp::http::HttpStatusCode::NOT_FOUND), - "")); + .WillOnce(ReturnHttpResponse( + http::NetworkResponse().WithStatus(http::HttpStatusCode::NOT_FOUND), + "")); ApiLookupClient lookup_client(kHrn, settings_); repository::CatalogRepository repository(kHrn, settings_, lookup_client); - auto response = repository.GetLatestVersion(request, context); - EXPECT_FALSE(response.IsSuccessful()); + std::promise promise; + auto future = promise.get_future(); + const auto response = repository.GetLatestVersion( + request, [&](read::CatalogVersionResponse response) { + promise.set_value(std::move(response)); + }); + + ASSERT_EQ(future.wait_for(kMaxWaitMs), std::future_status::ready); + const auto result = future.get(); + + EXPECT_FALSE(result); + EXPECT_EQ(result.GetError().GetErrorCode(), client::ErrorCode::NotFound); } -TEST_F(CatalogRepositoryTest, GetLatestVersionOnlineOnlyFound) { - olp::client::CancellationContext context; +TEST_F(CatalogRepositoryTest, AsyncGetLatestVersionOnlineOnlyForbidden) { + const auto request = + read::CatalogVersionRequest().WithFetchOption(read::OnlineIfNotFound); - auto request = read::CatalogVersionRequest(); + ON_CALL(*cache_, Get(_, _)).WillByDefault(testing::WithoutArgs([]() { + ADD_FAILURE() << "Cache should not be used in OnlineOnly request"; + return boost::any{}; + })); - request.WithFetchOption(read::OnlineOnly); + EXPECT_CALL(*cache_, RemoveKeysWithPrefix(_)); + + EXPECT_CALL(*cache_, Get(testing::Eq(kMetadataCacheKey), _)) + .WillOnce(testing::Return(boost::any())); + + EXPECT_CALL(*network_, Send(IsGetRequest(kLookupMetadata), _, _, _, _)) + .WillOnce(ReturnHttpResponse( + http::NetworkResponse().WithStatus(http::HttpStatusCode::FORBIDDEN), + "")); + + ApiLookupClient lookup_client(kHrn, settings_); + repository::CatalogRepository repository(kHrn, settings_, lookup_client); + + std::promise promise; + auto future = promise.get_future(); + const auto response = repository.GetLatestVersion( + request, [&](read::CatalogVersionResponse response) { + promise.set_value(std::move(response)); + }); + + ASSERT_EQ(future.wait_for(kMaxWaitMs), std::future_status::ready); + const auto result = future.get(); + + EXPECT_FALSE(result); + EXPECT_EQ(result.GetError().GetHttpStatusCode(), + http::HttpStatusCode::FORBIDDEN); +} + +TEST_F(CatalogRepositoryTest, GetLatestVersionOnlineOnlyFound2) { + client::CancellationContext context; + + auto request = + read::CatalogVersionRequest().WithFetchOption(read::OnlineOnly); ON_CALL(*cache_, Get(_, _)) .WillByDefault([](const std::string&, const olp::cache::Decoder&) { @@ -236,156 +361,209 @@ TEST_F(CatalogRepositoryTest, GetLatestVersionOnlineOnlyFound) { .WillOnce(testing::Return(boost::any())); EXPECT_CALL(*network_, Send(IsGetRequest(kLookupMetadata), _, _, _, _)) - .WillOnce(ReturnHttpResponse(olp::http::NetworkResponse().WithStatus( - olp::http::HttpStatusCode::OK), - kResponseLookupMetadata)); + .WillOnce(ReturnHttpResponse( + http::NetworkResponse().WithStatus(http::HttpStatusCode::OK), + kResponseLookupMetadata)); EXPECT_CALL(*cache_, Put(testing::Eq(kMetadataCacheKey), _, _, _)).Times(1); EXPECT_CALL(*network_, Send(IsGetRequest(kLatestCatalogVersion), _, _, _, _)) - .WillOnce(ReturnHttpResponse(olp::http::NetworkResponse().WithStatus( - olp::http::HttpStatusCode::OK), - kResponseLatestCatalogVersion)); + .WillOnce(ReturnHttpResponse( + http::NetworkResponse().WithStatus(http::HttpStatusCode::OK), + kResponseLatestCatalogVersion)); EXPECT_CALL(*cache_, Put(testing::Eq(kLatestVersionCacheKey), _, _, _)) .Times(0); ApiLookupClient lookup_client(kHrn, settings_); repository::CatalogRepository repository(kHrn, settings_, lookup_client); - auto response = repository.GetLatestVersion(request, context); + const auto response = repository.GetLatestVersion(request, context); - ASSERT_TRUE(response.IsSuccessful()); + ASSERT_TRUE(response); ASSERT_EQ(4, response.GetResult().GetVersion()); } -TEST_F(CatalogRepositoryTest, GetLatestVersionOnlineOnlyUserCancelled1) { - olp::client::CancellationContext context; +TEST_F(CatalogRepositoryTest, AsyncGetLatestVersionOnlineOnlyFound) { + const auto request = read::CatalogVersionRequest() + .WithFetchOption(read::OnlineOnly) + .WithBillingTag("OlpCppSdkTest"); + + ON_CALL(*cache_, Get(_, _)) + .WillByDefault([](const std::string&, const olp::cache::Decoder&) { + ADD_FAILURE() << "Cache should not be used in OnlineOnly request"; + return boost::any{}; + }); + + EXPECT_CALL(*cache_, Get(testing::Eq(kMetadataCacheKey), _)) + .WillOnce(testing::Return(boost::any())); + + EXPECT_CALL(*network_, Send(IsGetRequest(kLookupMetadata), _, _, _, _)) + .WillOnce(ReturnHttpResponse( + http::NetworkResponse().WithStatus(http::HttpStatusCode::OK), + kResponseLookupMetadata)); + + EXPECT_CALL(*cache_, Put(testing::Eq(kMetadataCacheKey), _, _, _)).Times(1); + + EXPECT_CALL(*network_, Send(IsGetRequest(kLatestCatalogVersionWithBillingTag), + _, _, _, _)) + .WillOnce(ReturnHttpResponse( + http::NetworkResponse().WithStatus(http::HttpStatusCode::OK), + kResponseLatestCatalogVersion)); - auto request = read::CatalogVersionRequest(); + ApiLookupClient lookup_client(kHrn, settings_); + repository::CatalogRepository repository(kHrn, settings_, lookup_client); - std::promise cancelled; + std::promise promise; + auto future = promise.get_future(); + repository.GetLatestVersion(request, + [&](read::CatalogVersionResponse response) { + promise.set_value(std::move(response)); + }); + + ASSERT_EQ(future.wait_for(kMaxWaitMs), std::future_status::ready); + const auto result = future.get(); + + EXPECT_TRUE(result); + ASSERT_EQ(result.GetResult().GetVersion(), 4); +} + +TEST_F(CatalogRepositoryTest, GetLatestVersionOnlineOnlyUserCancelled1) { + client::CancellationContext context; + + const auto request = read::CatalogVersionRequest(); ON_CALL(*network_, Send(IsGetRequest(kLookupMetadata), _, _, _, _)) - .WillByDefault([&context](olp::http::NetworkRequest, - olp::http::Network::Payload, - olp::http::Network::Callback, - olp::http::Network::HeaderCallback, - olp::http::Network::DataCallback) { + .WillByDefault(testing::WithoutArgs([&]() { std::thread([&context]() { context.CancelOperation(); }).detach(); constexpr auto unused_request_id = 5; - return olp::http::SendOutcome(unused_request_id); - }); + return http::SendOutcome(unused_request_id); + })); ON_CALL(*network_, Send(IsGetRequest(kLatestCatalogVersion), _, _, _, _)) - .WillByDefault([](olp::http::NetworkRequest, olp::http::Network::Payload, - olp::http::Network::Callback, - olp::http::Network::HeaderCallback, - olp::http::Network::DataCallback) { + .WillByDefault(testing::WithoutArgs([]() { ADD_FAILURE() << "Should not be called. Previous request was cancelled."; constexpr auto unused_request_id = 5; - return olp::http::SendOutcome(unused_request_id); - }); + return http::SendOutcome(unused_request_id); + })); ApiLookupClient lookup_client(kHrn, settings_); repository::CatalogRepository repository(kHrn, settings_, lookup_client); - auto response = repository.GetLatestVersion(request, context); + const auto response = repository.GetLatestVersion(request, context); - ASSERT_FALSE(response.IsSuccessful()); - EXPECT_EQ(olp::client::ErrorCode::Cancelled, - response.GetError().GetErrorCode()); + ASSERT_FALSE(response); + EXPECT_EQ(client::ErrorCode::Cancelled, response.GetError().GetErrorCode()); } TEST_F(CatalogRepositoryTest, GetLatestVersionOnlineOnlyUserCancelled2) { - olp::client::CancellationContext context; + client::CancellationContext context; - auto request = read::CatalogVersionRequest(); + const auto request = read::CatalogVersionRequest(); ON_CALL(*network_, Send(IsGetRequest(kLookupMetadata), _, _, _, _)) - .WillByDefault(ReturnHttpResponse(olp::http::NetworkResponse().WithStatus( - olp::http::HttpStatusCode::OK), - kResponseLookupMetadata)); + .WillByDefault(ReturnHttpResponse( + http::NetworkResponse().WithStatus(http::HttpStatusCode::OK), + kResponseLookupMetadata)); ON_CALL(*network_, Send(IsGetRequest(kLatestCatalogVersion), _, _, _, _)) - .WillByDefault([&](olp::http::NetworkRequest, olp::http::Network::Payload, - olp::http::Network::Callback, - olp::http::Network::HeaderCallback, - olp::http::Network::DataCallback) { + .WillByDefault(testing::WithoutArgs([&]() { std::thread([&]() { context.CancelOperation(); }).detach(); constexpr auto unused_request_id = 10; - return olp::http::SendOutcome(unused_request_id); - }); + return http::SendOutcome(unused_request_id); + })); ApiLookupClient lookup_client(kHrn, settings_); repository::CatalogRepository repository(kHrn, settings_, lookup_client); - auto response = repository.GetLatestVersion(request, context); + const auto response = repository.GetLatestVersion(request, context); - ASSERT_FALSE(response.IsSuccessful()); - EXPECT_EQ(olp::client::ErrorCode::Cancelled, - response.GetError().GetErrorCode()); + ASSERT_FALSE(response); + EXPECT_EQ(client::ErrorCode::Cancelled, response.GetError().GetErrorCode()); +} + +TEST_F(CatalogRepositoryTest, AsyncGetLatestVersionOnlineOnlyUserCancelled2) { + const auto request = read::CatalogVersionRequest(); + + ON_CALL(*network_, Send(IsGetRequest(kLookupMetadata), _, _, _, _)) + .WillByDefault(ReturnHttpResponse( + http::NetworkResponse().WithStatus(http::HttpStatusCode::OK), + kResponseLookupMetadata)); + + ON_CALL(*network_, Send(IsGetRequest(kLatestCatalogVersion), _, _, _, _)) + .WillByDefault(testing::WithoutArgs([]() { + return http::SendOutcome(http::ErrorCode::CANCELLED_ERROR); + })); + + ApiLookupClient lookup_client(kHrn, settings_); + repository::CatalogRepository repository(kHrn, settings_, lookup_client); + + std::promise promise; + auto future = promise.get_future(); + repository.GetLatestVersion(request, + [&](read::CatalogVersionResponse response) { + promise.set_value(std::move(response)); + }); + + ASSERT_EQ(future.wait_for(kMaxWaitMs), std::future_status::ready); + const auto result = future.get(); + + EXPECT_FALSE(result); + EXPECT_EQ(result.GetError().GetErrorCode(), client::ErrorCode::Cancelled); } TEST_F(CatalogRepositoryTest, GetLatestVersionCancelledBeforeExecution) { settings_.retry_settings.timeout = 0; - olp::client::CancellationContext context; + client::CancellationContext context; - auto request = read::CatalogVersionRequest(); + const auto request = read::CatalogVersionRequest(); ON_CALL(*network_, Send(_, _, _, _, _)) - .WillByDefault([&](olp::http::NetworkRequest, olp::http::Network::Payload, - olp::http::Network::Callback, - olp::http::Network::HeaderCallback, - olp::http::Network::DataCallback) { + .WillByDefault(testing::WithoutArgs([]() { ADD_FAILURE() << "Should not be called on cancelled operation"; constexpr auto unused_request_id = 10; - return olp::http::SendOutcome(unused_request_id); - }); + return http::SendOutcome(unused_request_id); + })); context.CancelOperation(); ApiLookupClient lookup_client(kHrn, settings_); repository::CatalogRepository repository(kHrn, settings_, lookup_client); - auto response = repository.GetLatestVersion(request, context); + const auto response = repository.GetLatestVersion(request, context); - ASSERT_FALSE(response.IsSuccessful()); - EXPECT_EQ(olp::client::ErrorCode::Cancelled, - response.GetError().GetErrorCode()); + ASSERT_FALSE(response); + EXPECT_EQ(client::ErrorCode::Cancelled, response.GetError().GetErrorCode()); } TEST_F(CatalogRepositoryTest, GetLatestVersionTimeouted) { - olp::client::CancellationContext context; + client::CancellationContext context; - auto request = read::CatalogVersionRequest(); + const auto request = read::CatalogVersionRequest(); ON_CALL(*network_, Send(IsGetRequest(kLookupMetadata), _, _, _, _)) - .WillByDefault(ReturnHttpResponse(olp::http::NetworkResponse().WithStatus( - olp::http::HttpStatusCode::OK), - kResponseLookupMetadata)); + .WillByDefault(ReturnHttpResponse( + http::NetworkResponse().WithStatus(http::HttpStatusCode::OK), + kResponseLookupMetadata)); ON_CALL(*network_, Send(IsGetRequest(kLatestCatalogVersion), _, _, _, _)) - .WillByDefault([&](olp::http::NetworkRequest, olp::http::Network::Payload, - olp::http::Network::Callback, - olp::http::Network::HeaderCallback, - olp::http::Network::DataCallback) { + .WillByDefault(testing::WithoutArgs([]() { constexpr auto unused_request_id = 10; - return olp::http::SendOutcome(unused_request_id); - }); + return http::SendOutcome(unused_request_id); + })); settings_.retry_settings.timeout = 0; ApiLookupClient lookup_client(kHrn, settings_); repository::CatalogRepository repository(kHrn, settings_, lookup_client); - auto response = repository.GetLatestVersion(request, context); + const auto response = repository.GetLatestVersion(request, context); - ASSERT_FALSE(response.IsSuccessful()); - EXPECT_EQ(olp::client::ErrorCode::RequestTimeout, + ASSERT_FALSE(response); + EXPECT_EQ(client::ErrorCode::RequestTimeout, response.GetError().GetErrorCode()); } TEST_F(CatalogRepositoryTest, GetCatalogOnlineOnlyFound) { - olp::client::CancellationContext context; + client::CancellationContext context; auto request = read::CatalogRequest(); request.WithFetchOption(read::OnlineOnly); @@ -401,24 +579,24 @@ TEST_F(CatalogRepositoryTest, GetCatalogOnlineOnlyFound) { EXPECT_CALL(*cache_, Put(testing::Eq(kConfigCacheKey), _, _, _)).Times(0); ON_CALL(*network_, Send(IsGetRequest(kUrlLookupConfig), _, _, _, _)) - .WillByDefault(ReturnHttpResponse(olp::http::NetworkResponse().WithStatus( - olp::http::HttpStatusCode::OK), - kResponseLookupConfig)); + .WillByDefault(ReturnHttpResponse( + http::NetworkResponse().WithStatus(http::HttpStatusCode::OK), + kResponseLookupConfig)); ON_CALL(*network_, Send(IsGetRequest(kUrlConfig), _, _, _, _)) - .WillByDefault(ReturnHttpResponse(olp::http::NetworkResponse().WithStatus( - olp::http::HttpStatusCode::OK), - kResponseConfig)); + .WillByDefault(ReturnHttpResponse( + http::NetworkResponse().WithStatus(http::HttpStatusCode::OK), + kResponseConfig)); ApiLookupClient lookup_client(kHrn, settings_); repository::CatalogRepository repository(kHrn, settings_, lookup_client); auto response = repository.GetCatalog(request, context); - ASSERT_TRUE(response.IsSuccessful()); + ASSERT_TRUE(response); } TEST_F(CatalogRepositoryTest, GetCatalogCacheOnlyFound) { - olp::client::CancellationContext context; + client::CancellationContext context; auto request = read::CatalogRequest(); @@ -428,46 +606,39 @@ TEST_F(CatalogRepositoryTest, GetCatalogCacheOnlyFound) { cached_version.SetHrn(kCatalog); EXPECT_CALL(*cache_, Get(kCatalogCacheKey, _)) - .Times(1) .WillOnce(testing::Return(cached_version)); ApiLookupClient lookup_client(kHrn, settings_); repository::CatalogRepository repository(kHrn, settings_, lookup_client); auto response = repository.GetCatalog(request, context); - ASSERT_TRUE(response.IsSuccessful()); + ASSERT_TRUE(response); EXPECT_EQ(kCatalog, response.GetResult().GetHrn()); } TEST_F(CatalogRepositoryTest, GetCatalogCacheOnlyNotFound) { - olp::client::CancellationContext context; + client::CancellationContext context; - auto request = read::CatalogVersionRequest(); - - request.WithFetchOption(read::CacheOnly); + const auto request = + read::CatalogVersionRequest().WithFetchOption(read::CacheOnly); - EXPECT_CALL(*cache_, Get(_, _)) - .Times(1) - .WillOnce(testing::Return(boost::any{})); + EXPECT_CALL(*cache_, Get(_, _)).WillOnce(testing::Return(boost::any{})); ON_CALL(*network_, Send(_, _, _, _, _)) - .WillByDefault([](olp::http::NetworkRequest, olp::http::Network::Payload, - olp::http::Network::Callback, - olp::http::Network::HeaderCallback, - olp::http::Network::DataCallback) { + .WillByDefault(testing::WithoutArgs([]() { ADD_FAILURE() << "Should not be called with CacheOnly"; - return olp::http::SendOutcome(olp::http::ErrorCode::UNKNOWN_ERROR); - }); + return http::SendOutcome(http::ErrorCode::UNKNOWN_ERROR); + })); ApiLookupClient lookup_client(kHrn, settings_); repository::CatalogRepository repository(kHrn, settings_, lookup_client); - auto response = repository.GetLatestVersion(request, context); + const auto response = repository.GetLatestVersion(request, context); - EXPECT_FALSE(response.IsSuccessful()); + EXPECT_FALSE(response); } TEST_F(CatalogRepositoryTest, GetCatalogOnlineOnlyNotFound) { - olp::client::CancellationContext context; + client::CancellationContext context; auto request = read::CatalogRequest(); @@ -480,33 +651,29 @@ TEST_F(CatalogRepositoryTest, GetCatalogOnlineOnlyNotFound) { }); EXPECT_CALL(*network_, Send(IsGetRequest(kUrlLookupConfig), _, _, _, _)) - .Times(1) - .WillOnce(ReturnHttpResponse(olp::http::NetworkResponse().WithStatus( - olp::http::HttpStatusCode::NOT_FOUND), - "")); + .WillOnce(ReturnHttpResponse( + http::NetworkResponse().WithStatus(http::HttpStatusCode::NOT_FOUND), + "")); ApiLookupClient lookup_client(kHrn, settings_); repository::CatalogRepository repository(kHrn, settings_, lookup_client); auto response = repository.GetCatalog(request, context); - EXPECT_FALSE(response.IsSuccessful()); + EXPECT_FALSE(response); } TEST_F(CatalogRepositoryTest, GetCatalogCancelledBeforeExecution) { settings_.retry_settings.timeout = 0; - olp::client::CancellationContext context; + client::CancellationContext context; auto request = read::CatalogRequest(); ON_CALL(*network_, Send(_, _, _, _, _)) - .WillByDefault([&](olp::http::NetworkRequest, olp::http::Network::Payload, - olp::http::Network::Callback, - olp::http::Network::HeaderCallback, - olp::http::Network::DataCallback) { + .WillByDefault(testing::WithoutArgs([]() { ADD_FAILURE() << "Should not be called on cancelled operation"; constexpr auto unused_request_id = 10; - return olp::http::SendOutcome(unused_request_id); - }); + return http::SendOutcome(unused_request_id); + })); context.CancelOperation(); @@ -514,106 +681,89 @@ TEST_F(CatalogRepositoryTest, GetCatalogCancelledBeforeExecution) { repository::CatalogRepository repository(kHrn, settings_, lookup_client); auto response = repository.GetCatalog(request, context); - ASSERT_FALSE(response.IsSuccessful()); - EXPECT_EQ(olp::client::ErrorCode::Cancelled, - response.GetError().GetErrorCode()); + ASSERT_FALSE(response); + EXPECT_EQ(client::ErrorCode::Cancelled, response.GetError().GetErrorCode()); } TEST_F(CatalogRepositoryTest, GetCatalogOnlineOnlyUserCancelled1) { - olp::client::CancellationContext context; + client::CancellationContext context; auto request = read::CatalogRequest(); - std::promise cancelled; - ON_CALL(*network_, Send(IsGetRequest(kUrlLookupConfig), _, _, _, _)) - .WillByDefault([&context](olp::http::NetworkRequest, - olp::http::Network::Payload, - olp::http::Network::Callback, - olp::http::Network::HeaderCallback, - olp::http::Network::DataCallback) { + .WillByDefault(testing::WithoutArgs([&]() { std::thread([&context]() { context.CancelOperation(); }).detach(); constexpr auto unused_request_id = 5; - return olp::http::SendOutcome(unused_request_id); - }); + return http::SendOutcome(unused_request_id); + })); ON_CALL(*network_, Send(IsGetRequest(kUrlConfig), _, _, _, _)) - .WillByDefault([](olp::http::NetworkRequest, olp::http::Network::Payload, - olp::http::Network::Callback, - olp::http::Network::HeaderCallback, - olp::http::Network::DataCallback) { + .WillByDefault(testing::WithoutArgs([]() { ADD_FAILURE() << "Should not be called. Previous request was cancelled."; constexpr auto unused_request_id = 5; - return olp::http::SendOutcome(unused_request_id); - }); + return http::SendOutcome(unused_request_id); + })); ApiLookupClient lookup_client(kHrn, settings_); repository::CatalogRepository repository(kHrn, settings_, lookup_client); auto response = repository.GetCatalog(request, context); - ASSERT_FALSE(response.IsSuccessful()); - EXPECT_EQ(olp::client::ErrorCode::Cancelled, - response.GetError().GetErrorCode()); + ASSERT_FALSE(response); + EXPECT_EQ(client::ErrorCode::Cancelled, response.GetError().GetErrorCode()); } TEST_F(CatalogRepositoryTest, GetCatalogOnlineOnlyUserCancelled2) { - olp::client::CancellationContext context; + client::CancellationContext context; auto request = read::CatalogRequest(); ON_CALL(*network_, Send(IsGetRequest(kUrlLookupConfig), _, _, _, _)) - .WillByDefault(ReturnHttpResponse(olp::http::NetworkResponse().WithStatus( - olp::http::HttpStatusCode::OK), - kResponseLookupConfig)); + .WillByDefault(ReturnHttpResponse( + http::NetworkResponse().WithStatus(http::HttpStatusCode::OK), + kResponseLookupConfig)); ON_CALL(*network_, Send(IsGetRequest(kUrlConfig), _, _, _, _)) - .WillByDefault([&](olp::http::NetworkRequest, olp::http::Network::Payload, - olp::http::Network::Callback, - olp::http::Network::HeaderCallback, - olp::http::Network::DataCallback) { + .WillByDefault(testing::WithoutArgs([&]() { std::thread([&]() { context.CancelOperation(); }).detach(); constexpr auto unused_request_id = 10; - return olp::http::SendOutcome(unused_request_id); - }); + return http::SendOutcome(unused_request_id); + })); ApiLookupClient lookup_client(kHrn, settings_); repository::CatalogRepository repository(kHrn, settings_, lookup_client); auto response = repository.GetCatalog(request, context); - ASSERT_FALSE(response.IsSuccessful()); - EXPECT_EQ(olp::client::ErrorCode::Cancelled, - response.GetError().GetErrorCode()); + ASSERT_FALSE(response); + EXPECT_EQ(client::ErrorCode::Cancelled, response.GetError().GetErrorCode()); } TEST_F(CatalogRepositoryTest, GetCatalogTimeout) { - olp::client::CancellationContext context; + client::CancellationContext context; auto request = read::CatalogRequest(); ON_CALL(*network_, Send(IsGetRequest(kUrlLookupConfig), _, _, _, _)) - .WillByDefault(ReturnHttpResponse(olp::http::NetworkResponse().WithStatus( - olp::http::HttpStatusCode::OK), - kResponseLookupConfig)); + .WillByDefault(ReturnHttpResponse( + http::NetworkResponse().WithStatus(http::HttpStatusCode::OK), + kResponseLookupConfig)); ON_CALL(*network_, Send(IsGetRequest(kUrlConfig), _, _, _, _)) - .WillByDefault([&](olp::http::NetworkRequest, olp::http::Network::Payload, - olp::http::Network::Callback, - olp::http::Network::HeaderCallback, - olp::http::Network::DataCallback) { + .WillByDefault(testing::WithoutArgs([]() { constexpr auto unused_request_id = 10; - return olp::http::SendOutcome(unused_request_id); - }); + return http::SendOutcome(unused_request_id); + })); + settings_.retry_settings.timeout = 0; ApiLookupClient lookup_client(kHrn, settings_); repository::CatalogRepository repository(kHrn, settings_, lookup_client); auto response = repository.GetCatalog(request, context); - ASSERT_FALSE(response.IsSuccessful()); - EXPECT_EQ(olp::client::ErrorCode::RequestTimeout, + ASSERT_FALSE(response); + EXPECT_EQ(client::ErrorCode::RequestTimeout, response.GetError().GetErrorCode()); } @@ -621,28 +771,26 @@ TEST_F(CatalogRepositoryTest, GetVersionsList) { { SCOPED_TRACE("Get versions list"); - olp::client::CancellationContext context; + client::CancellationContext context; auto request = read::VersionsRequest() .WithStartVersion(kStartVersion) .WithEndVersion(kEndVersion); ON_CALL(*network_, Send(IsGetRequest(kLookupMetadata), _, _, _, _)) - .WillByDefault( - ReturnHttpResponse(olp::http::NetworkResponse().WithStatus( - olp::http::HttpStatusCode::OK), - kResponseLookupMetadata)); + .WillByDefault(ReturnHttpResponse( + http::NetworkResponse().WithStatus(http::HttpStatusCode::OK), + kResponseLookupMetadata)); ON_CALL(*network_, Send(IsGetRequest(kUrlVersionsList), _, _, _, _)) - .WillByDefault( - ReturnHttpResponse(olp::http::NetworkResponse().WithStatus( - olp::http::HttpStatusCode::OK), - kHttpResponse)); + .WillByDefault(ReturnHttpResponse( + http::NetworkResponse().WithStatus(http::HttpStatusCode::OK), + kHttpResponse)); ApiLookupClient lookup_client(kHrn, settings_); repository::CatalogRepository repository(kHrn, settings_, lookup_client); auto response = repository.GetVersionsList(request, context); - ASSERT_TRUE(response.IsSuccessful()); + ASSERT_TRUE(response); auto result = response.GetResult(); ASSERT_EQ(1u, result.GetVersions().size()); @@ -653,28 +801,26 @@ TEST_F(CatalogRepositoryTest, GetVersionsList) { { SCOPED_TRACE("Get versions list start version -1"); - olp::client::CancellationContext context; + client::CancellationContext context; auto request = read::VersionsRequest().WithStartVersion(-1).WithEndVersion( kEndVersion); ON_CALL(*network_, Send(IsGetRequest(kLookupMetadata), _, _, _, _)) - .WillByDefault( - ReturnHttpResponse(olp::http::NetworkResponse().WithStatus( - olp::http::HttpStatusCode::OK), - kResponseLookupMetadata)); + .WillByDefault(ReturnHttpResponse( + http::NetworkResponse().WithStatus(http::HttpStatusCode::OK), + kResponseLookupMetadata)); ON_CALL(*network_, Send(IsGetRequest(kUrlVersionsListStartMinus), _, _, _, _)) - .WillByDefault( - ReturnHttpResponse(olp::http::NetworkResponse().WithStatus( - olp::http::HttpStatusCode::OK), - kHttpResponse)); + .WillByDefault(ReturnHttpResponse( + http::NetworkResponse().WithStatus(http::HttpStatusCode::OK), + kHttpResponse)); ApiLookupClient lookup_client(kHrn, settings_); repository::CatalogRepository repository(kHrn, settings_, lookup_client); auto response = repository.GetVersionsList(request, context); - ASSERT_TRUE(response.IsSuccessful()); + ASSERT_TRUE(response); auto result = response.GetResult(); ASSERT_EQ(1u, result.GetVersions().size()); @@ -685,29 +831,27 @@ TEST_F(CatalogRepositoryTest, GetVersionsList) { { SCOPED_TRACE("Get versions list response forbiden"); - olp::client::CancellationContext context; + client::CancellationContext context; auto request = read::VersionsRequest() .WithStartVersion(kStartVersion) .WithEndVersion(kEndVersion); ON_CALL(*network_, Send(IsGetRequest(kLookupMetadata), _, _, _, _)) - .WillByDefault( - ReturnHttpResponse(olp::http::NetworkResponse().WithStatus( - olp::http::HttpStatusCode::OK), - kResponseLookupMetadata)); + .WillByDefault(ReturnHttpResponse( + http::NetworkResponse().WithStatus(http::HttpStatusCode::OK), + kResponseLookupMetadata)); ON_CALL(*network_, Send(IsGetRequest(kUrlVersionsList), _, _, _, _)) - .WillByDefault( - ReturnHttpResponse(olp::http::NetworkResponse().WithStatus( - olp::http::HttpStatusCode::FORBIDDEN), - "Forbidden")); + .WillByDefault(ReturnHttpResponse( + http::NetworkResponse().WithStatus(http::HttpStatusCode::FORBIDDEN), + "Forbidden")); ApiLookupClient lookup_client(kHrn, settings_); repository::CatalogRepository repository(kHrn, settings_, lookup_client); auto response = repository.GetVersionsList(request, context); - ASSERT_FALSE(response.IsSuccessful()); - EXPECT_EQ(olp::client::ErrorCode::AccessDenied, + ASSERT_FALSE(response); + EXPECT_EQ(client::ErrorCode::AccessDenied, response.GetError().GetErrorCode()); } }