#include "core/internal/encryption_runner.h" #include "core/internal/client_proxy.h" #include "core/internal/endpoint_channel.h" #include "platform/base/byte_array.h" #include "platform/public/count_down_latch.h" #include "platform/public/pipe.h" #include "platform/public/system_clock.h" #include "proto/connections_enums.pb.h" #include "gmock/gmock.h" #include "gtest/gtest.h" #include "absl/time/clock.h" namespace location { namespace nearby { namespace connections { namespace { using ::location::nearby::proto::connections::Medium; class FakeEndpointChannel : public EndpointChannel { public: FakeEndpointChannel(InputStream* in, OutputStream* out) : in_(in), out_(out) {} ExceptionOr Read() override { read_timestamp_ = SystemClock::ElapsedRealtime(); return in_ ? in_->Read(Pipe::kChunkSize) : ExceptionOr{Exception::kIo}; } Exception Write(const ByteArray& data) override { return out_ ? out_->Write(data) : Exception{Exception::kIo}; } void Close() override { if (in_) in_->Close(); if (out_) out_->Close(); } void Close(proto::connections::DisconnectionReason reason) override { Close(); } std::string GetType() const override { return "fake-channel-type"; } std::string GetName() const override { return "fake-channel"; } Medium GetMedium() const override { return Medium::BLE; } void EnableEncryption(std::shared_ptr context) override {} bool IsPaused() const override { return false; } void Pause() override {} void Resume() override {} absl::Time GetLastReadTimestamp() const override { return read_timestamp_; } private: InputStream* in_ = nullptr; OutputStream* out_ = nullptr; absl::Time read_timestamp_ = absl::InfinitePast(); }; struct User { User(Pipe* reader, Pipe* writer) : channel(&reader->GetInputStream(), &writer->GetOutputStream()) {} FakeEndpointChannel channel; EncryptionRunner crypto; ClientProxy client; }; struct Response { enum class Status { kUnknown = 0, kDone = 1, kFailed = 2, }; CountDownLatch latch{2}; Status server_status = Status::kUnknown; Status client_status = Status::kUnknown; }; TEST(EncryptionRunnerTest, ConstructorDestructorWorks) { EncryptionRunner enc; } TEST(EncryptionRunnerTest, ReadWrite) { Pipe from_a_to_b; Pipe from_b_to_a; User user_a(/*reader=*/&from_b_to_a, /*writer=*/&from_a_to_b); User user_b(/*reader=*/&from_a_to_b, /*writer=*/&from_b_to_a); Response response; user_a.crypto.StartServer( &user_a.client, "endpoint_id", &user_a.channel, { .on_success_cb = [&response](const string& endpoint_id, std::unique_ptr ukey2, const string& auth_token, const ByteArray& raw_auth_token) { response.server_status = Response::Status::kDone; response.latch.CountDown(); }, .on_failure_cb = [&response](const string& endpoint_id, EndpointChannel* channel) { response.server_status = Response::Status::kFailed; response.latch.CountDown(); }, }); user_b.crypto.StartClient( &user_b.client, "endpoint_id", &user_b.channel, { .on_success_cb = [&response](const string& endpoint_id, std::unique_ptr ukey2, const string& auth_token, const ByteArray& raw_auth_token) { response.client_status = Response::Status::kDone; response.latch.CountDown(); }, .on_failure_cb = [&response](const string& endpoint_id, EndpointChannel* channel) { response.client_status = Response::Status::kFailed; response.latch.CountDown(); }, }); EXPECT_TRUE(response.latch.Await(absl::Milliseconds(5000)).result()); EXPECT_EQ(response.server_status, Response::Status::kDone); EXPECT_EQ(response.client_status, Response::Status::kDone); } } // namespace } // namespace connections } // namespace nearby } // namespace location