diff --git a/Package.swift b/Package.swift index 6add6dba..5eab087a 100644 --- a/Package.swift +++ b/Package.swift @@ -521,6 +521,7 @@ let package = Package( "internal/flags/nearby_flags_test.cc", "internal/proto/analytics/connections_log_test.cc", "internal/platform/feature_flags_test.cc", + "internal/platform/file_test.cc", "internal/platform/cancelable_alarm_test.cc", "internal/platform/crypto_test.cc", "internal/platform/byte_array_test.cc", diff --git a/internal/platform/BUILD b/internal/platform/BUILD index 3eaea91c..8c650e31 100644 --- a/internal/platform/BUILD +++ b/internal/platform/BUILD @@ -547,6 +547,7 @@ cc_test( "count_down_latch_test.cc", "crypto_test.cc", "direct_executor_test.cc", + "file_test.cc", "future_test.cc", "multi_thread_executor_test.cc", "mutex_test.cc", @@ -565,6 +566,8 @@ cc_test( ":test_util", ":types", ":uuid", + "//internal/base:file_path", + "//internal/base:files", "//internal/crypto_cros", "//internal/flags:nearby_flags", "//internal/platform/flags:platform_flags", diff --git a/internal/platform/file.h b/internal/platform/file.h index f88cab1c..44af1d3b 100644 --- a/internal/platform/file.h +++ b/internal/platform/file.h @@ -15,6 +15,7 @@ #ifndef PLATFORM_PUBLIC_FILE_H_ #define PLATFORM_PUBLIC_FILE_H_ +#include #include #include #include @@ -26,6 +27,7 @@ #include "internal/platform/implementation/platform.h" #include "internal/platform/input_stream.h" #include "internal/platform/output_stream.h" +#include "internal/platform/payload_id.h" namespace nearby { diff --git a/internal/platform/file_test.cc b/internal/platform/file_test.cc new file mode 100644 index 00000000..6a8c926a --- /dev/null +++ b/internal/platform/file_test.cc @@ -0,0 +1,221 @@ +// Copyright 2025 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/platform/file.h" + +#include +#include + +#include "gtest/gtest.h" +#include "absl/strings/str_cat.h" +#include "internal/base/file_path.h" +#include "internal/base/files.h" +#include "internal/platform/byte_array.h" +#include "internal/platform/exception.h" +#include "internal/platform/input_stream.h" + +namespace nearby { +namespace { + +class FileTest : public ::testing::Test { + protected: + void SetUp() override { temp_dir_ = Files::GetTemporaryDirectory(); } + + FilePath GetTempFilePath(const std::string& file_name) { + return FilePath(absl::StrCat(temp_dir_.ToString(), "/", file_name)); + } + + FilePath temp_dir_; +}; + +TEST_F(FileTest, ConstructorDestructorWorks) { + // Setup + FilePath file_path = GetTempFilePath("test_file.txt"); + std::string data = "test data"; + // Create an output file and write to it. + OutputFile output_file(file_path.ToString()); + ASSERT_TRUE(output_file.IsValid()); + output_file.Write(ByteArray(data)); + output_file.Close(); + + // Create an input file and read from it. + InputFile input_file(file_path.ToString(), data.size()); + ExceptionOr read_bytes = input_file.Read(data.size()); + ASSERT_TRUE(read_bytes.ok()); + EXPECT_EQ(read_bytes.result(), ByteArray(data)); + input_file.Close(); +} + +TEST_F(FileTest, SimpleWriteRead) { + FilePath file_path = GetTempFilePath("test_file.txt"); + std::string data = "ABCD"; + + // Write to file. + OutputFile output_file(file_path.ToString()); + ASSERT_TRUE(output_file.IsValid()); + EXPECT_TRUE(output_file.Write(ByteArray(data)).Ok()); + EXPECT_TRUE(output_file.Close().Ok()); + + // Read from file. + InputFile input_file(file_path.ToString(), data.size()); + ExceptionOr read_data = input_file.Read(data.size()); + EXPECT_TRUE(read_data.ok()); + EXPECT_EQ(std::string(read_data.result()), data); + EXPECT_TRUE(input_file.Close().Ok()); +} + +TEST_F(FileTest, WriteThenCloseThenRead) { + FilePath file_path = GetTempFilePath("test_file_persistence.txt"); + std::string data = "Persistent data"; + + // Write and close. + OutputFile output_file(file_path.ToString()); + ASSERT_TRUE(output_file.IsValid()); + EXPECT_TRUE(output_file.Write(ByteArray(data)).Ok()); + EXPECT_TRUE(output_file.Close().Ok()); + + // Re-open and read. + InputFile input_file(file_path.ToString(), data.size()); + ExceptionOr read_data = input_file.Read(data.size()); + EXPECT_TRUE(read_data.ok()); + EXPECT_EQ(std::string(read_data.result()), data); + EXPECT_TRUE(input_file.Close().Ok()); +} + +TEST_F(FileTest, ReadEmptyFile) { + FilePath file_path = GetTempFilePath("empty_file.txt"); + + // Create empty file. + OutputFile output_file(file_path.ToString()); + ASSERT_TRUE(output_file.IsValid()); + EXPECT_TRUE(output_file.Close().Ok()); + + // Read from empty file. + InputFile input_file(file_path.ToString(), 0); + ExceptionOr read_data = input_file.Read(1024); + EXPECT_TRUE(read_data.ok()); + EXPECT_TRUE(read_data.result().Empty()); + EXPECT_TRUE(input_file.Close().Ok()); +} + +TEST_F(FileTest, ReadExactly) { + FilePath file_path = GetTempFilePath("read_exactly_file.txt"); + std::string data = "read this exactly"; + + OutputFile output_file(file_path.ToString()); + ASSERT_TRUE(output_file.IsValid()); + EXPECT_TRUE(output_file.Write(ByteArray(data)).Ok()); + EXPECT_TRUE(output_file.Close().Ok()); + + InputFile input_file(file_path.ToString(), data.size()); + ExceptionOr read_data = + input_file.GetInputStream().ReadExactly(data.size()); + EXPECT_TRUE(read_data.ok()); + EXPECT_EQ(std::string(read_data.result()), data); + EXPECT_TRUE(input_file.Close().Ok()); +} + +TEST_F(FileTest, ReadTooMuch) { + FilePath file_path = GetTempFilePath("read_too_much_file.txt"); + std::string data = "some data"; + + OutputFile output_file(file_path.ToString()); + ASSERT_TRUE(output_file.IsValid()); + EXPECT_TRUE(output_file.Write(ByteArray(data)).Ok()); + EXPECT_TRUE(output_file.Close().Ok()); + + InputFile input_file(file_path.ToString(), data.size()); + ExceptionOr read_data = input_file.Read(data.size() * 2); + EXPECT_TRUE(read_data.ok()); + EXPECT_EQ(std::string(read_data.result()), data); + EXPECT_TRUE(input_file.Close().Ok()); +} + +TEST_F(FileTest, Skip) { + FilePath file_path = GetTempFilePath("skip_file.txt"); + std::string data_to_skip = "skip_this"; + std::string data_to_read = "read_this"; + std::string full_data = data_to_skip + data_to_read; + + OutputFile output_file(file_path.ToString()); + ASSERT_TRUE(output_file.IsValid()); + EXPECT_TRUE(output_file.Write(ByteArray(full_data)).Ok()); + EXPECT_TRUE(output_file.Close().Ok()); + + InputFile input_file(file_path.ToString(), full_data.size()); + ExceptionOr skipped_bytes = input_file.Skip(data_to_skip.size()); + EXPECT_TRUE(skipped_bytes.ok()); + EXPECT_EQ(skipped_bytes.result(), data_to_skip.size()); + + ExceptionOr read_data = input_file.Read(data_to_read.size()); + EXPECT_TRUE(read_data.ok()); + EXPECT_EQ(std::string(read_data.result()), data_to_read); + EXPECT_TRUE(input_file.Close().Ok()); +} + +TEST_F(FileTest, MultipleWrites) { + FilePath file_path = GetTempFilePath("multiple_writes.txt"); + std::string data1 = "first part, "; + std::string data2 = "second part."; + std::string full_data = data1 + data2; + + OutputFile output_file(file_path.ToString()); + ASSERT_TRUE(output_file.IsValid()); + EXPECT_TRUE(output_file.Write(ByteArray(data1)).Ok()); + EXPECT_TRUE(output_file.Write(ByteArray(data2)).Ok()); + EXPECT_TRUE(output_file.Close().Ok()); + + InputFile input_file(file_path.ToString(), full_data.size()); + ExceptionOr read_data = input_file.Read(full_data.size()); + EXPECT_TRUE(read_data.ok()); + EXPECT_EQ(std::string(read_data.result()), full_data); + EXPECT_TRUE(input_file.Close().Ok()); +} + +TEST_F(FileTest, CloseTwice) { + FilePath file_path = GetTempFilePath("close_twice.txt"); + OutputFile output_file(file_path.ToString()); + ASSERT_TRUE(output_file.IsValid()); + EXPECT_TRUE(output_file.Close().Ok()); + EXPECT_TRUE(output_file.Close().Ok()); + + InputFile input_file(file_path.ToString(), 0); + EXPECT_TRUE(input_file.Close().Ok()); + EXPECT_TRUE(input_file.Close().Ok()); +} + +TEST_F(FileTest, WriteLargeFile) { + FilePath file_path = GetTempFilePath("large_file.txt"); + std::string chunk(1024, 'a'); + std::string large_data; + for (int i = 0; i < 10; ++i) { + large_data += chunk; + } + + OutputFile output_file(file_path.ToString()); + ASSERT_TRUE(output_file.IsValid()); + EXPECT_TRUE(output_file.Write(ByteArray(large_data)).Ok()); + EXPECT_TRUE(output_file.Close().Ok()); + + InputFile input_file(file_path.ToString(), large_data.size()); + ExceptionOr read_data = + input_file.GetInputStream().ReadExactly(large_data.size()); + EXPECT_TRUE(read_data.ok()); + EXPECT_EQ(read_data.result().size(), large_data.size()); + EXPECT_EQ(std::string(read_data.result()), large_data); + EXPECT_TRUE(input_file.Close().Ok()); +} + +} // namespace +} // namespace nearby diff --git a/internal/platform/implementation/windows/BUILD b/internal/platform/implementation/windows/BUILD index c0f422e5..84bedfb5 100644 --- a/internal/platform/implementation/windows/BUILD +++ b/internal/platform/implementation/windows/BUILD @@ -28,10 +28,8 @@ cc_library( "device_info.h", "executor.h", "future.h", - "input_file.h", "listenable_future.h", "mutex.h", - "output_file.h", "preferences_manager.h", "scheduled_executor.h", "settable_future.h", diff --git a/internal/platform/implementation/windows/condition_variable_test.cc b/internal/platform/implementation/windows/condition_variable_test.cc deleted file mode 100644 index 8b208025..00000000 --- a/internal/platform/implementation/windows/condition_variable_test.cc +++ /dev/null @@ -1,103 +0,0 @@ -// 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/platform/implementation/windows/condition_variable.h" - -#include // NOLINT - -#include "absl/time/clock.h" -#include "internal/platform/exception.h" -#include "internal/platform/implementation/windows/mutex.h" - -#include "gtest/gtest.h" - -class ConditionVariableTests : public testing::Test { - public: - class ConditionVariableTest { - public: - ConditionVariableTest() {} - - std::future WaitForEvent(bool timedWait, // NOLINT - const absl::Duration* timeout) { - return std::async( - std::launch::async, - [this, timedWait, timeout]() mutable { - std::thread::id currentThread = std::this_thread::get_id(); - - if (timedWait == true) { - auto result = this->condition_variable_actual_.Wait(*timeout); - if (result.value == nearby::Exception::kSuccess) { - return true; - } else { - return false; - } - } else { - this->condition_variable_actual_.Wait(); - } - return true; - }); - } - - void PostEvent() { - absl::MutexLock::MutexLock(&mutex_actual_.GetMutex()); - condition_variable_actual_.Notify(); - } - - private: - nearby::windows::Mutex mutex_actual_ = - nearby::windows::Mutex(nearby::windows::Mutex::Mode::kRegular); - nearby::windows::Mutex& mutex_ = mutex_actual_; - nearby::windows::ConditionVariable condition_variable_actual_ = - nearby::windows::ConditionVariable(&mutex_); - nearby::windows::ConditionVariable& condition_variable_ = - condition_variable_actual_; - }; -}; - -TEST_F(ConditionVariableTests, SuccessfulCreation) { - // Arrange - ConditionVariableTest conditionVariableTest; - - auto result = conditionVariableTest.WaitForEvent(false, nullptr); - - Sleep(1); - - // Act - conditionVariableTest.PostEvent(); - - // Assert - ASSERT_TRUE(result.get()); -} - -TEST_F(ConditionVariableTests, TimedCreation) { - // Arrange - ConditionVariableTest conditionVariableTest; - const absl::Duration duration = absl::Milliseconds(100); - - // Act - auto result = conditionVariableTest.WaitForEvent(true, &duration); - - // Assert - ASSERT_FALSE(result.get()); // Timed out - - // Act - result = conditionVariableTest.WaitForEvent(true, &duration); - - Sleep(1); - - conditionVariableTest.PostEvent(); - - // Assert - ASSERT_TRUE(result.get()); // Didn't timeout -} diff --git a/internal/platform/implementation/windows/file.cc b/internal/platform/implementation/windows/file.cc index c134288b..8f129883 100644 --- a/internal/platform/implementation/windows/file.cc +++ b/internal/platform/implementation/windows/file.cc @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -38,8 +39,8 @@ std::unique_ptr IOFile::CreateInputFile(absl::string_view file_path, IOFile::IOFile(absl::string_view file_path, size_t size) : path_(file_path) { // Always open input file path as wide string on Windows platform. - std::wstring wide_path = string_utils::StringToWideString( - std::string(file_path)); + std::wstring wide_path = + string_utils::StringToWideString(std::string(file_path)); file_.open(wide_path, std::ios::binary | std::ios::in | std::ios::ate); total_size_ = file_.tellg(); @@ -60,8 +61,7 @@ std::unique_ptr IOFile::CreateOutputFile(absl::string_view path) { IOFile::IOFile(absl::string_view file_path) : file_(), path_(file_path), total_size_(0) { // Always open input file path as wide string on Windows platform. - std::wstring wide_path = - string_utils::StringToWideString(path_); + std::wstring wide_path = string_utils::StringToWideString(path_); file_.open(wide_path, std::ios::binary | std::ios::out); } @@ -71,12 +71,12 @@ ExceptionOr IOFile::Read(std::int64_t size) { return ExceptionOr{Exception::kIo}; } - if (!file_.good()) { - return ExceptionOr{Exception::kIo}; + if (file_.peek() == EOF) { + return ExceptionOr{ByteArray{}}; } - if (file_.eof()) { - return ExceptionOr{ByteArray{}}; + if (!file_.good()) { + return ExceptionOr{Exception::kIo}; } if (buffer_.size() < size) { diff --git a/internal/platform/implementation/windows/input_file.h b/internal/platform/implementation/windows/input_file.h deleted file mode 100644 index 618c5145..00000000 --- a/internal/platform/implementation/windows/input_file.h +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2020 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 PLATFORM_IMPL_WINDOWS_INPUT_FILE_H_ -#define PLATFORM_IMPL_WINDOWS_INPUT_FILE_H_ - -#include "internal/platform/implementation/input_file.h" -#include "internal/platform/byte_array.h" -#include "internal/platform/exception.h" - -namespace nearby { -namespace windows { - -// An InputFile represents a readable file on the system. -class InputFile : public api::InputFile { - public: - // TODO(b/184975123): replace with real implementation. - ~InputFile() override = default; - // TODO(b/184975123): replace with real implementation. - std::string GetFilePath() const override { return "Un-implemented"; } - // TODO(b/184975123): replace with real implementation. - std::int64_t GetTotalSize() const override { return 0; } - - // throws Exception::kIo - // TODO(b/184975123): replace with real implementation. - ExceptionOr Read(std::int64_t size) override { - return ExceptionOr(Exception::kFailed); - } - // throws Exception::kIo - // TODO(b/184975123): replace with real implementation. - Exception Close() override { return Exception{}; } -}; - -} // namespace windows -} // namespace nearby - -#endif // PLATFORM_IMPL_WINDOWS_INPUT_FILE_H_ diff --git a/internal/platform/implementation/windows/input_file_test.cc b/internal/platform/implementation/windows/input_file_test.cc deleted file mode 100644 index 0ad20be6..00000000 --- a/internal/platform/implementation/windows/input_file_test.cc +++ /dev/null @@ -1,148 +0,0 @@ -// Copyright 2020 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/platform/implementation/windows/input_file.h" - -#include "gtest/gtest.h" -#include "internal/platform/exception.h" -#include "internal/platform/payload_id.h" -#include "internal/platform/implementation/windows/test_utils.h" -#include "internal/platform/logging.h" - -class InputFileTests : public testing::Test { - protected: - // You can define per-test set-up logic as usual. - void SetUp() override { - nearby::PayloadId payloadId(TEST_PAYLOAD_ID); - auto path = test_utils::GetPayloadPath(payloadId); - - hFile_ = CreateFileA(path.c_str(), // name of the write - GENERIC_WRITE, // open for writing - 0, // do not share - NULL, // default security - CREATE_ALWAYS, // create new file only - FILE_ATTRIBUTE_NORMAL, // normal file - NULL); // no attr. template - - if (hFile_ == INVALID_HANDLE_VALUE) { - NEARBY_LOG(ERROR, - "Failed to create OutputFile with payloadId: %s and error: %d", - test_utils::GetPayloadPath(payloadId).c_str(), GetLastError()); - } - - const char* buffer = TEST_STRING; - DWORD bytesWritten; - - WriteFile(hFile_, buffer, lstrlenA(buffer) * sizeof(char), &bytesWritten, - nullptr); - - CloseHandle(hFile_); - } - - // You can define per-test tear-down logic as usual. - void TearDown() override { - nearby::PayloadId payloadId(TEST_PAYLOAD_ID); - if (FileExists(test_utils::GetPayloadPath(payloadId).c_str())) { - DeleteFileA(test_utils::GetPayloadPath(payloadId).c_str()); - } - } - - BOOL FileExists(const char* szPath) { - DWORD dwAttrib = GetFileAttributesA(szPath); - - return (dwAttrib != INVALID_FILE_ATTRIBUTES && - !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY)); - } - - private: - HANDLE hFile_ = nullptr; -}; - -TEST_F(InputFileTests, SuccessfulCreation) { - nearby::PayloadId payloadId(TEST_PAYLOAD_ID); - std::unique_ptr inputFile = nullptr; - - inputFile = nearby::api::ImplementationPlatform::CreateInputFile( - payloadId, strlen(TEST_STRING)); - - EXPECT_NE(inputFile, nullptr); - EXPECT_EQ(inputFile->Close(), nearby::Exception{nearby::Exception::kSuccess}); -} - -TEST_F(InputFileTests, SuccessfulGetFilePath) { - nearby::PayloadId payloadId(TEST_PAYLOAD_ID); - std::unique_ptr inputFile = nullptr; - std::string fileName; - - inputFile = nearby::api::ImplementationPlatform::CreateInputFile( - payloadId, strlen(TEST_STRING)); - - fileName = inputFile->GetFilePath(); - - EXPECT_EQ(inputFile->Close(), nearby::Exception{nearby::Exception::kSuccess}); - - EXPECT_EQ(fileName, test_utils::GetPayloadPath(payloadId).c_str()); -} - -TEST_F(InputFileTests, SuccessfulGetTotalSize) { - nearby::PayloadId payloadId(TEST_PAYLOAD_ID); - std::unique_ptr inputFile = nullptr; - int64_t size = -1; - - inputFile = nearby::api::ImplementationPlatform::CreateInputFile( - payloadId, strlen(TEST_STRING)); - - size = inputFile->GetTotalSize(); - - EXPECT_EQ(inputFile->Close(), nearby::Exception{nearby::Exception::kSuccess}); - - EXPECT_EQ(size, strlen(TEST_STRING)); -} - -TEST_F(InputFileTests, SuccessfulRead) { - nearby::PayloadId payloadId(TEST_PAYLOAD_ID); - std::unique_ptr inputFile = nullptr; - - inputFile = nearby::api::ImplementationPlatform::CreateInputFile( - payloadId, strlen(TEST_STRING)); - - auto fileSize = inputFile->GetTotalSize(); - auto dataRead = inputFile->Read(fileSize); - - EXPECT_TRUE(dataRead.ok()); - EXPECT_EQ(inputFile->Close(), nearby::Exception{nearby::Exception::kSuccess}); - - EXPECT_STREQ(std::string(dataRead.result()).c_str(), TEST_STRING); -} - -TEST_F(InputFileTests, FailedRead) { - nearby::PayloadId payloadId(TEST_PAYLOAD_ID); - std::unique_ptr inputFile = nullptr; - - inputFile = nearby::api::ImplementationPlatform::CreateInputFile( - payloadId, strlen(TEST_STRING)); - - auto fileSize = inputFile->GetTotalSize(); - EXPECT_NE(fileSize, -1); - - auto dataRead = inputFile->Read(fileSize); - EXPECT_TRUE(dataRead.ok()); - - dataRead = inputFile->Read(fileSize); - std::string data = std::string(dataRead.result()); - - inputFile->Close(); - - EXPECT_STREQ(data.c_str(), ""); -} diff --git a/internal/platform/implementation/windows/mutex_test.cc b/internal/platform/implementation/windows/mutex_test.cc deleted file mode 100644 index 211b441d..00000000 --- a/internal/platform/implementation/windows/mutex_test.cc +++ /dev/null @@ -1,105 +0,0 @@ -// 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/platform/implementation/windows/mutex.h" - -#include // NOLINT - -#include "gtest/gtest.h" - -class MutexTests : public testing::Test { - public: - class MutexTest { - public: - MutexTest(nearby::windows::Mutex& mutex) : mutex_(mutex) {} - - std::future WaitForLock() { // NOLINT - return std::async(std::launch::async, - // for this lambda you need C++14 - [this]() mutable { - absl::MutexLock::MutexLock(&mutex_.GetMutex()); - return true; - }); - } - - void PostEvent() { - absl::MutexLock::MutexLock(&mutex_.GetMutex()); - mutex_.Unlock(); - } - - private: - nearby::windows::Mutex& mutex_; - }; -}; - -TEST_F(MutexTests, SuccessfulRecursiveCreation) { - // Arrange - nearby::windows::Mutex mutex = - nearby::windows::Mutex(nearby::windows::Mutex::Mode::kRecursive); - - // Act - std::recursive_mutex& actual = mutex.GetRecursiveMutex(); - - // Assert - ASSERT_TRUE(actual.native_handle() != nullptr); -} - -TEST_F(MutexTests, SuccessfulCreation) { - // Arrange - nearby::windows::Mutex mutex(nearby::windows::Mutex::Mode::kRegular); - - // Act - absl::Mutex& actual = mutex.GetMutex(); - - // Assert - ASSERT_TRUE(&actual != nullptr); -} - -TEST_F(MutexTests, SuccessfulSignal) { - // Arrange - nearby::windows::Mutex mutex(nearby::windows::Mutex::Mode::kRegular); - - nearby::windows::Mutex& mutexRef = mutex; - MutexTest mutexTest(mutexRef); - - mutex.Lock(); - - // Act - auto result = mutexTest.WaitForLock(); - mutex.Unlock(); - - // Assert - ASSERT_TRUE(result.get()); -} - -TEST_F(MutexTests, SuccessfulRecursiveSignal) { - // Arrange - nearby::windows::Mutex mutex(nearby::windows::Mutex::Mode::kRecursive); - - nearby::windows::Mutex& mutexRef = mutex; - MutexTest mutexTest(mutexRef); - - mutex.Lock(); - mutex.Lock(); - mutex.Lock(); - - // Act - auto result = mutexTest.WaitForLock(); - mutex.Unlock(); - mutex.Unlock(); - mutex.Unlock(); - - // Assert - ASSERT_TRUE(result.get()); -} diff --git a/internal/platform/implementation/windows/output_file.h b/internal/platform/implementation/windows/output_file.h deleted file mode 100644 index 7a7d6b85..00000000 --- a/internal/platform/implementation/windows/output_file.h +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2020 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 PLATFORM_IMPL_WINDOWS_OUTPUT_FILE_H_ -#define PLATFORM_IMPL_WINDOWS_OUTPUT_FILE_H_ - -#include "internal/platform/implementation/output_file.h" -#include "internal/platform/byte_array.h" -#include "internal/platform/exception.h" - -namespace nearby { -namespace windows { - -// An OutputFile represents a writable file on the system. -class OutputFile : public api::OutputFile { - public: - // TODO(b/184975123): replace with real implementation. - ~OutputFile() override = default; - - // throws Exception::kIo - // TODO(b/184975123): replace with real implementation. - Exception Write(const ByteArray& data) override { return Exception{}; } - // throws Exception::kIo - // TODO(b/184975123): replace with real implementation. - Exception Flush() override { return Exception{}; } - // throws Exception::kIo - // TODO(b/184975123): replace with real implementation. - Exception Close() override { return Exception{}; } -}; - -} // namespace windows -} // namespace nearby - -#endif // PLATFORM_IMPL_WINDOWS_OUTPUT_FILE_H_ diff --git a/internal/platform/implementation/windows/output_file_test.cc b/internal/platform/implementation/windows/output_file_test.cc deleted file mode 100644 index beb8798c..00000000 --- a/internal/platform/implementation/windows/output_file_test.cc +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright 2020 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/platform/implementation/windows/output_file.h" - -#include "gtest/gtest.h" -#include "internal/platform/implementation/platform.h" -#include "internal/platform/exception.h" -#include "internal/platform/payload_id.h" -#include "internal/platform/implementation/windows/test_utils.h" - -class OutputFileTests : public testing::Test { - protected: - // You can define per-test set-up logic as usual. - void SetUp() override { - nearby::PayloadId payloadId(TEST_PAYLOAD_ID); - if (FileExists(test_utils::GetPayloadPath(payloadId).c_str())) { - DeleteFileA(test_utils::GetPayloadPath(payloadId).c_str()); - } - } - - // You can define per-test tear-down logic as usual. - void TearDown() override { - nearby::PayloadId payloadId(TEST_PAYLOAD_ID); - if (FileExists(test_utils::GetPayloadPath(payloadId).c_str())) { - DeleteFileA(test_utils::GetPayloadPath(payloadId).c_str()); - } - } - - BOOL FileExists(const char* szPath) { - DWORD dwAttrib = GetFileAttributesA(szPath); - - return (dwAttrib != INVALID_FILE_ATTRIBUTES && - !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY)); - } -}; - -TEST_F(OutputFileTests, SuccessfulCreation) { - nearby::PayloadId payloadId(TEST_PAYLOAD_ID); - std::unique_ptr outputFile = nullptr; - - EXPECT_NO_THROW( - outputFile = - nearby::api::ImplementationPlatform::CreateOutputFile(payloadId)); - - EXPECT_NE(outputFile, nullptr); - EXPECT_NO_THROW(outputFile->Close()); -} - -TEST_F(OutputFileTests, SuccessfulClose) { - nearby::PayloadId payloadId(TEST_PAYLOAD_ID); - std::unique_ptr outputFile = nullptr; - - EXPECT_NO_THROW( - outputFile = - nearby::api::ImplementationPlatform::CreateOutputFile(payloadId)); - - EXPECT_NO_THROW(outputFile->Close()); - - DeleteFileA(test_utils::GetPayloadPath(payloadId).c_str()); -} - -TEST_F(OutputFileTests, SuccessfulWrite) { - nearby::PayloadId payloadId(TEST_PAYLOAD_ID); - nearby::ByteArray data(std::string(TEST_STRING)); - std::unique_ptr outputFile = nullptr; - - EXPECT_NO_THROW( - outputFile = - nearby::api::ImplementationPlatform::CreateOutputFile(payloadId)); - - EXPECT_NO_THROW(outputFile->Write(data)); - EXPECT_NO_THROW(outputFile->Close()); - - DeleteFileA(test_utils::GetPayloadPath(payloadId).c_str()); -}