blob: 2f1ccbc0331b332768646917fd87719685e1e3ff [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/developer/feedback/utils/fidl/data_provider_ptr.h"
#include <lib/async/cpp/executor.h>
#include <lib/fit/result.h>
#include <memory>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "fuchsia/feedback/cpp/fidl.h"
#include "src/developer/feedback/testing/gpretty_printers.h"
#include "src/developer/feedback/testing/stubs/data_provider.h"
#include "src/developer/feedback/testing/unit_test_fixture.h"
#include "src/developer/feedback/utils/errors.h"
namespace feedback {
namespace {
using fuchsia::feedback::Bugreport;
constexpr zx::duration kDefaultTimeout = zx::sec(35);
class DataProviderPtrTest : public UnitTestFixture {
public:
DataProviderPtrTest()
: UnitTestFixture(), executor_(dispatcher()), data_provider_ptr_(dispatcher(), services()) {}
protected:
void SetUpDataProviderServer(std::unique_ptr<stubs::DataProviderBase> data_provider_server) {
data_provider_server_ = std::move(data_provider_server);
if (data_provider_server_) {
InjectServiceProvider(data_provider_server_.get());
}
}
void CloseConnection() { data_provider_server_->CloseConnection(); }
bool is_server_bound() { return data_provider_server_->IsBound(); }
std::vector<::fit::result<Bugreport, Error>> GetBugreport(const size_t num_parallel_calls) {
std::vector<::fit::result<Bugreport, Error>> results(num_parallel_calls);
for (auto& result : results) {
executor_.schedule_task(data_provider_ptr_.GetBugreport(kDefaultTimeout)
.then([&](::fit::result<Bugreport, Error>& bugreport) {
result = std::move(bugreport);
}));
}
RunLoopUntilIdle();
return results;
}
protected:
async::Executor executor_;
fidl::DataProviderPtr data_provider_ptr_;
private:
std::unique_ptr<stubs::DataProviderBase> data_provider_server_;
};
TEST_F(DataProviderPtrTest, Check_ConnectionIsReused) {
const size_t num_calls = 5u;
SetUpDataProviderServer(std::make_unique<stubs::DataProviderTracksNumConnections>(1u));
const std::vector<::fit::result<Bugreport, Error>> results = GetBugreport(num_calls);
ASSERT_EQ(results.size(), num_calls);
for (const auto& result : results) {
EXPECT_TRUE(result.is_ok());
}
EXPECT_FALSE(is_server_bound());
}
TEST_F(DataProviderPtrTest, Check_ReconnectsCorrectly) {
const size_t num_calls = 5u;
SetUpDataProviderServer(std::make_unique<stubs::DataProviderTracksNumConnections>(2u));
std::vector<::fit::result<Bugreport, Error>> results = GetBugreport(num_calls);
ASSERT_EQ(results.size(), num_calls);
for (const auto& result : results) {
EXPECT_TRUE(result.is_ok());
}
EXPECT_FALSE(is_server_bound());
results.clear();
results = GetBugreport(num_calls);
ASSERT_EQ(results.size(), num_calls);
for (const auto& result : results) {
EXPECT_TRUE(result.is_ok());
}
EXPECT_FALSE(is_server_bound());
}
TEST_F(DataProviderPtrTest, Fail_OnNoServer) {
const size_t num_calls = 1u;
// We pass a nullptr stub so there will be no fuchsia.feedback.DataProvider service to connect to.
SetUpDataProviderServer(nullptr);
std::vector<::fit::result<Bugreport, Error>> results = GetBugreport(num_calls);
ASSERT_EQ(results.size(), num_calls);
EXPECT_TRUE(results[0].is_error());
EXPECT_EQ(results[0].error(), Error::kConnectionError);
}
TEST_F(DataProviderPtrTest, Fail_OnServerTakingTooLong) {
const size_t num_calls = 1u;
SetUpDataProviderServer(std::make_unique<stubs::DataProviderNeverReturning>());
std::vector<::fit::result<Bugreport, Error>> results = GetBugreport(num_calls);
RunLoopFor(kDefaultTimeout);
ASSERT_EQ(results.size(), num_calls);
EXPECT_TRUE(results[0].is_error());
EXPECT_EQ(results[0].error(), Error::kTimeout);
}
} // namespace
} // namespace feedback