mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-14 22:56:12 -04:00
Refactor Input/Output file to use const char* instead of standard string, and to use parent_folder and file_name for input and output files. This also incorporates the move from nearby_connections to nearby.
PiperOrigin-RevId: 415587802
This commit is contained in:
committed by
Copybara-Service
parent
5ba6623eac
commit
f12bb6c405
@@ -26,11 +26,9 @@ cc_library(
|
||||
"condition_variable.h",
|
||||
"executor.h",
|
||||
"future.h",
|
||||
"input_file.h",
|
||||
"listenable_future.h",
|
||||
"log_message.h",
|
||||
"mutex.h",
|
||||
"output_file.h",
|
||||
"scheduled_executor.h",
|
||||
"settable_future.h",
|
||||
"submittable_executor.h",
|
||||
|
||||
@@ -125,20 +125,25 @@ TEST(ExecutorTests, SingleThreadedExecutorMultipleTasksSucceeds) {
|
||||
// Container to note threads that ran
|
||||
std::unique_ptr<std::vector<DWORD>> threadIds =
|
||||
std::make_unique<std::vector<DWORD>>();
|
||||
CRITICAL_SECTION crit_sec;
|
||||
InitializeCriticalSection(&crit_sec);
|
||||
|
||||
threadIds->push_back(GetCurrentThreadId());
|
||||
|
||||
// Act
|
||||
for (int index = 0; index < 5; index++) {
|
||||
executor->Execute([&output, &threadIds, index]() {
|
||||
executor->Execute([&output, &threadIds, &crit_sec, index]() {
|
||||
EnterCriticalSection(&crit_sec);
|
||||
threadIds->push_back(GetCurrentThreadId());
|
||||
char buffer[128];
|
||||
snprintf(buffer, sizeof(buffer), "%s%d, ", RUNNABLE_TEXT.c_str(), index);
|
||||
output.append(std::string(buffer));
|
||||
LeaveCriticalSection(&crit_sec);
|
||||
});
|
||||
}
|
||||
|
||||
executor->Shutdown();
|
||||
DeleteCriticalSection(&crit_sec);
|
||||
|
||||
// Assert
|
||||
// We should've run 1 time on the main thread, and 5 times on the
|
||||
@@ -200,19 +205,25 @@ TEST(ExecutorTests, MultiThreadedExecutorMultipleTasksSucceeds) {
|
||||
|
||||
std::shared_ptr<std::string> output = std::make_shared<std::string>();
|
||||
|
||||
CRITICAL_SECTION crit_sec;
|
||||
InitializeCriticalSection(&crit_sec);
|
||||
|
||||
threadIds->push_back(GetCurrentThreadId());
|
||||
|
||||
// Act
|
||||
for (int index = 0; index < 5; index++) {
|
||||
executor->Execute([&output, &threadIds, index]() {
|
||||
executor->Execute([&output, &threadIds, &crit_sec, index]() {
|
||||
EnterCriticalSection(&crit_sec);
|
||||
threadIds->push_back(GetCurrentThreadId());
|
||||
char buffer[128];
|
||||
snprintf(buffer, sizeof(buffer), "%s %d, ", RUNNABLE_TEXT.c_str(), index);
|
||||
output->append(std::string(buffer));
|
||||
LeaveCriticalSection(&crit_sec);
|
||||
});
|
||||
}
|
||||
|
||||
executor->Shutdown();
|
||||
DeleteCriticalSection(&crit_sec);
|
||||
|
||||
// Assert
|
||||
// We should've run 1 time on the main thread, and 5 times on the
|
||||
|
||||
@@ -1,50 +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 "platform/api/input_file.h"
|
||||
#include "platform/base/byte_array.h"
|
||||
#include "platform/base/exception.h"
|
||||
|
||||
namespace location {
|
||||
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<ByteArray> Read(std::int64_t size) override {
|
||||
return ExceptionOr<ByteArray>(Exception::kFailed);
|
||||
}
|
||||
// throws Exception::kIo
|
||||
// TODO(b/184975123): replace with real implementation.
|
||||
Exception Close() override { return Exception{}; }
|
||||
};
|
||||
|
||||
} // namespace windows
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
#endif // PLATFORM_IMPL_WINDOWS_INPUT_FILE_H_
|
||||
@@ -12,8 +12,6 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "platform/impl/windows/input_file.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "platform/base/exception.h"
|
||||
#include "platform/base/payload_id.h"
|
||||
@@ -24,21 +22,18 @@ class InputFileTests : public testing::Test {
|
||||
protected:
|
||||
// You can define per-test set-up logic as usual.
|
||||
void SetUp() override {
|
||||
location::nearby::PayloadId payloadId(TEST_PAYLOAD_ID);
|
||||
|
||||
hFile_ = CreateFileA(
|
||||
test_utils::GetPayloadPath(payloadId).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
|
||||
hFile_ = CreateFileA(TEST_FILE_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());
|
||||
"Failed to create OutputFile with file path: %s and error: %d",
|
||||
TEST_FILE_PATH.c_str(), GetLastError());
|
||||
}
|
||||
|
||||
const char* buffer = TEST_STRING;
|
||||
@@ -52,9 +47,8 @@ class InputFileTests : public testing::Test {
|
||||
|
||||
// You can define per-test tear-down logic as usual.
|
||||
void TearDown() override {
|
||||
location::nearby::PayloadId payloadId(TEST_PAYLOAD_ID);
|
||||
if (FileExists(test_utils::GetPayloadPath(payloadId).c_str())) {
|
||||
DeleteFileA(test_utils::GetPayloadPath(payloadId).c_str());
|
||||
if (FileExists(TEST_FILE_PATH.c_str())) {
|
||||
DeleteFileA(TEST_FILE_PATH.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,7 +68,7 @@ TEST_F(InputFileTests, SuccessfulCreation) {
|
||||
std::unique_ptr<location::nearby::api::InputFile> inputFile = nullptr;
|
||||
|
||||
inputFile = location::nearby::api::ImplementationPlatform::CreateInputFile(
|
||||
payloadId, strlen(TEST_STRING));
|
||||
TEST_FILE_PATH.c_str());
|
||||
|
||||
EXPECT_NE(inputFile, nullptr);
|
||||
EXPECT_EQ(inputFile->Close(),
|
||||
@@ -82,28 +76,27 @@ TEST_F(InputFileTests, SuccessfulCreation) {
|
||||
}
|
||||
|
||||
TEST_F(InputFileTests, SuccessfulGetFilePath) {
|
||||
location::nearby::PayloadId payloadId(TEST_PAYLOAD_ID);
|
||||
std::unique_ptr<location::nearby::api::InputFile> inputFile = nullptr;
|
||||
std::string fileName;
|
||||
std::string expected(TEST_FILE_PATH.c_str());
|
||||
|
||||
inputFile = location::nearby::api::ImplementationPlatform::CreateInputFile(
|
||||
payloadId, strlen(TEST_STRING));
|
||||
TEST_FILE_PATH.c_str());
|
||||
|
||||
fileName = inputFile->GetFilePath();
|
||||
|
||||
EXPECT_EQ(inputFile->Close(),
|
||||
location::nearby::Exception{location::nearby::Exception::kSuccess});
|
||||
|
||||
EXPECT_EQ(fileName, test_utils::GetPayloadPath(payloadId).c_str());
|
||||
EXPECT_EQ(fileName, expected);
|
||||
}
|
||||
|
||||
TEST_F(InputFileTests, SuccessfulGetTotalSize) {
|
||||
location::nearby::PayloadId payloadId(TEST_PAYLOAD_ID);
|
||||
std::unique_ptr<location::nearby::api::InputFile> inputFile = nullptr;
|
||||
int64_t size = -1;
|
||||
|
||||
inputFile = location::nearby::api::ImplementationPlatform::CreateInputFile(
|
||||
payloadId, strlen(TEST_STRING));
|
||||
TEST_FILE_PATH.c_str());
|
||||
|
||||
size = inputFile->GetTotalSize();
|
||||
|
||||
@@ -114,11 +107,10 @@ TEST_F(InputFileTests, SuccessfulGetTotalSize) {
|
||||
}
|
||||
|
||||
TEST_F(InputFileTests, SuccessfulRead) {
|
||||
location::nearby::PayloadId payloadId(TEST_PAYLOAD_ID);
|
||||
std::unique_ptr<location::nearby::api::InputFile> inputFile = nullptr;
|
||||
|
||||
inputFile = location::nearby::api::ImplementationPlatform::CreateInputFile(
|
||||
payloadId, strlen(TEST_STRING));
|
||||
TEST_FILE_PATH.c_str());
|
||||
|
||||
auto fileSize = inputFile->GetTotalSize();
|
||||
auto dataRead = inputFile->Read(fileSize);
|
||||
@@ -131,11 +123,10 @@ TEST_F(InputFileTests, SuccessfulRead) {
|
||||
}
|
||||
|
||||
TEST_F(InputFileTests, FailedRead) {
|
||||
location::nearby::PayloadId payloadId(TEST_PAYLOAD_ID);
|
||||
std::unique_ptr<location::nearby::api::InputFile> inputFile = nullptr;
|
||||
|
||||
inputFile = location::nearby::api::ImplementationPlatform::CreateInputFile(
|
||||
payloadId, strlen(TEST_STRING));
|
||||
TEST_FILE_PATH.c_str());
|
||||
|
||||
auto fileSize = inputFile->GetTotalSize();
|
||||
EXPECT_NE(fileSize, -1);
|
||||
|
||||
@@ -1,47 +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 "platform/api/output_file.h"
|
||||
#include "platform/base/byte_array.h"
|
||||
#include "platform/base/exception.h"
|
||||
|
||||
namespace location {
|
||||
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
|
||||
} // namespace location
|
||||
|
||||
#endif // PLATFORM_IMPL_WINDOWS_OUTPUT_FILE_H_
|
||||
@@ -12,8 +12,6 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "platform/impl/windows/output_file.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "platform/api/platform.h"
|
||||
#include "platform/base/exception.h"
|
||||
@@ -24,17 +22,15 @@ class OutputFileTests : public testing::Test {
|
||||
protected:
|
||||
// You can define per-test set-up logic as usual.
|
||||
void SetUp() override {
|
||||
location::nearby::PayloadId payloadId(TEST_PAYLOAD_ID);
|
||||
if (FileExists(test_utils::GetPayloadPath(payloadId).c_str())) {
|
||||
DeleteFileA(test_utils::GetPayloadPath(payloadId).c_str());
|
||||
if (FileExists(TEST_FILE_PATH.c_str())) {
|
||||
DeleteFileA(TEST_FILE_PATH.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
// You can define per-test tear-down logic as usual.
|
||||
void TearDown() override {
|
||||
location::nearby::PayloadId payloadId(TEST_PAYLOAD_ID);
|
||||
if (FileExists(test_utils::GetPayloadPath(payloadId).c_str())) {
|
||||
DeleteFileA(test_utils::GetPayloadPath(payloadId).c_str());
|
||||
if (FileExists(TEST_FILE_PATH.c_str())) {
|
||||
DeleteFileA(TEST_FILE_PATH.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,44 +43,41 @@ class OutputFileTests : public testing::Test {
|
||||
};
|
||||
|
||||
TEST_F(OutputFileTests, SuccessfulCreation) {
|
||||
location::nearby::PayloadId payloadId(TEST_PAYLOAD_ID);
|
||||
std::unique_ptr<location::nearby::api::OutputFile> outputFile = nullptr;
|
||||
|
||||
EXPECT_NO_THROW(
|
||||
outputFile =
|
||||
location::nearby::api::ImplementationPlatform::CreateOutputFile(
|
||||
payloadId));
|
||||
TEST_FILE_PATH.c_str()));
|
||||
|
||||
EXPECT_NE(outputFile, nullptr);
|
||||
EXPECT_NO_THROW(outputFile->Close());
|
||||
}
|
||||
|
||||
TEST_F(OutputFileTests, SuccessfulClose) {
|
||||
location::nearby::PayloadId payloadId(TEST_PAYLOAD_ID);
|
||||
std::unique_ptr<location::nearby::api::OutputFile> outputFile = nullptr;
|
||||
|
||||
EXPECT_NO_THROW(
|
||||
outputFile =
|
||||
location::nearby::api::ImplementationPlatform::CreateOutputFile(
|
||||
payloadId));
|
||||
TEST_FILE_PATH.c_str()));
|
||||
|
||||
EXPECT_NO_THROW(outputFile->Close());
|
||||
|
||||
DeleteFileA(test_utils::GetPayloadPath(payloadId).c_str());
|
||||
DeleteFileA(TEST_FILE_PATH.c_str());
|
||||
}
|
||||
|
||||
TEST_F(OutputFileTests, SuccessfulWrite) {
|
||||
location::nearby::PayloadId payloadId(TEST_PAYLOAD_ID);
|
||||
location::nearby::ByteArray data(std::string(TEST_STRING));
|
||||
std::unique_ptr<location::nearby::api::OutputFile> outputFile = nullptr;
|
||||
|
||||
EXPECT_NO_THROW(
|
||||
outputFile =
|
||||
location::nearby::api::ImplementationPlatform::CreateOutputFile(
|
||||
payloadId));
|
||||
TEST_FILE_PATH.c_str()));
|
||||
|
||||
EXPECT_NO_THROW(outputFile->Write(data));
|
||||
EXPECT_NO_THROW(outputFile->Close());
|
||||
|
||||
DeleteFileA(test_utils::GetPayloadPath(payloadId).c_str());
|
||||
DeleteFileA(TEST_FILE_PATH.c_str());
|
||||
}
|
||||
|
||||
@@ -41,9 +41,9 @@
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
namespace api {
|
||||
namespace {
|
||||
|
||||
std::string GetPayloadPath(PayloadId payload_id) {
|
||||
std::unique_ptr<std::string> ImplementationPlatform::GetDownloadPath(
|
||||
std::unique_ptr<std::string> path) {
|
||||
PWSTR basePath;
|
||||
|
||||
// Retrieves the full path of a known folder identified by the folder's
|
||||
@@ -61,13 +61,12 @@ std::string GetPayloadPath(PayloadId payload_id) {
|
||||
// is no longer needed by calling CoTaskMemFree, whether
|
||||
// SHGetKnownFolderPath succeeds or not.
|
||||
|
||||
char* fullpathUTF8 = new char((wcslen(basePath) + 1) * sizeof(char));
|
||||
wcstombs(fullpathUTF8, basePath, (wcslen(basePath) + 1) * sizeof(char));
|
||||
std::string fullPath = std::string(fullpathUTF8);
|
||||
auto retval = absl::StrCat(fullPath += "/", payload_id);
|
||||
return retval;
|
||||
auto basePathLength = (wcslen(basePath) + 1) * sizeof(char);
|
||||
char* fullpathUTF8 = new char(basePathLength);
|
||||
wcstombs(fullpathUTF8, basePath, basePathLength);
|
||||
return std::make_unique<std::string>(std::string(fullpathUTF8) +=
|
||||
"/" + *path);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
std::unique_ptr<AtomicBoolean> ImplementationPlatform::CreateAtomicBoolean(
|
||||
bool initial_value) {
|
||||
@@ -94,14 +93,13 @@ ImplementationPlatform::CreateConditionVariable(Mutex* mutex) {
|
||||
}
|
||||
|
||||
std::unique_ptr<InputFile> ImplementationPlatform::CreateInputFile(
|
||||
PayloadId payload_id, std::int64_t total_size) {
|
||||
return absl::make_unique<shared::InputFile>(GetPayloadPath(payload_id),
|
||||
total_size);
|
||||
const char* file_path) {
|
||||
return absl::make_unique<shared::InputFile>(file_path);
|
||||
}
|
||||
|
||||
std::unique_ptr<OutputFile> ImplementationPlatform::CreateOutputFile(
|
||||
PayloadId payload_id) {
|
||||
return absl::make_unique<shared::OutputFile>(GetPayloadPath(payload_id));
|
||||
const char* file_path) {
|
||||
return absl::make_unique<shared::OutputFile>(file_path);
|
||||
}
|
||||
|
||||
// TODO(b/184975123): replace with real implementation.
|
||||
|
||||
@@ -31,15 +31,21 @@ TEST(ScheduledExecutorTests, ExecuteSucceeds) {
|
||||
std::unique_ptr<std::vector<DWORD>> threadIds =
|
||||
std::make_unique<std::vector<DWORD>>();
|
||||
|
||||
CRITICAL_SECTION crit_sec;
|
||||
InitializeCriticalSection(&crit_sec);
|
||||
|
||||
threadIds->push_back(GetCurrentThreadId());
|
||||
|
||||
// Act
|
||||
submittableExecutor->Execute([&output, &threadIds]() {
|
||||
submittableExecutor->Execute([&output, &threadIds, &crit_sec]() {
|
||||
EnterCriticalSection(&crit_sec);
|
||||
threadIds->push_back(GetCurrentThreadId());
|
||||
output.append(RUNNABLE_0_TEXT.c_str());
|
||||
LeaveCriticalSection(&crit_sec);
|
||||
});
|
||||
|
||||
submittableExecutor->Shutdown();
|
||||
DeleteCriticalSection(&crit_sec);
|
||||
|
||||
// Assert
|
||||
// We should've run 1 time on the main thread, and 1 times on the
|
||||
@@ -63,6 +69,9 @@ TEST(ScheduledExecutorTests, ScheduleSucceeds) {
|
||||
std::unique_ptr<std::vector<DWORD>> threadIds =
|
||||
std::make_unique<std::vector<DWORD>>();
|
||||
|
||||
CRITICAL_SECTION crit_sec;
|
||||
InitializeCriticalSection(&crit_sec);
|
||||
|
||||
threadIds->push_back(GetCurrentThreadId());
|
||||
|
||||
std::chrono::system_clock::time_point timeNow =
|
||||
@@ -71,16 +80,19 @@ TEST(ScheduledExecutorTests, ScheduleSucceeds) {
|
||||
|
||||
// Act
|
||||
submittableExecutor->Schedule(
|
||||
[&output, &threadIds, &timeExecuted]() {
|
||||
[&output, &threadIds, &timeExecuted, &crit_sec]() {
|
||||
EnterCriticalSection(&crit_sec);
|
||||
timeExecuted = std::chrono::system_clock::now();
|
||||
threadIds->push_back(GetCurrentThreadId());
|
||||
output.append(RUNNABLE_0_TEXT.c_str());
|
||||
LeaveCriticalSection(&crit_sec);
|
||||
},
|
||||
absl::Milliseconds(50));
|
||||
|
||||
SleepEx(100, true); // Yield the thread
|
||||
|
||||
submittableExecutor->Shutdown();
|
||||
DeleteCriticalSection(&crit_sec);
|
||||
|
||||
auto difference = std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||
timeExecuted - timeNow)
|
||||
@@ -148,13 +160,18 @@ TEST(ScheduledExecutorTests, CancelAfterStartedFails) {
|
||||
std::unique_ptr<std::vector<DWORD>> threadIds =
|
||||
std::make_unique<std::vector<DWORD>>();
|
||||
|
||||
CRITICAL_SECTION crit_sec;
|
||||
InitializeCriticalSection(&crit_sec);
|
||||
|
||||
threadIds->push_back(GetCurrentThreadId());
|
||||
|
||||
// Act
|
||||
auto cancelable = submittableExecutor->Schedule(
|
||||
[&output, &threadIds]() {
|
||||
[&output, &threadIds, &crit_sec]() {
|
||||
EnterCriticalSection(&crit_sec);
|
||||
threadIds->push_back(GetCurrentThreadId());
|
||||
output.append(RUNNABLE_0_TEXT.c_str());
|
||||
LeaveCriticalSection(&crit_sec);
|
||||
},
|
||||
absl::Milliseconds(100));
|
||||
|
||||
@@ -163,6 +180,7 @@ TEST(ScheduledExecutorTests, CancelAfterStartedFails) {
|
||||
auto actual = cancelable->Cancel();
|
||||
|
||||
submittableExecutor->Shutdown();
|
||||
DeleteCriticalSection(&crit_sec);
|
||||
|
||||
// Assert
|
||||
ASSERT_FALSE(actual);
|
||||
|
||||
@@ -164,19 +164,25 @@ TEST(SubmittableExecutorTests, SingleThreadedExecuteMultipleTasksSucceeds) {
|
||||
std::unique_ptr<std::vector<DWORD>> threadIds =
|
||||
std::make_unique<std::vector<DWORD>>();
|
||||
|
||||
CRITICAL_SECTION crit_sec;
|
||||
InitializeCriticalSection(&crit_sec);
|
||||
|
||||
threadIds->push_back(GetCurrentThreadId());
|
||||
|
||||
// Act
|
||||
for (int index = 0; index < 5; index++) {
|
||||
submittableExecutor->Execute([&output, &threadIds, index]() {
|
||||
submittableExecutor->Execute([&output, &threadIds, &crit_sec, index]() {
|
||||
EnterCriticalSection(&crit_sec);
|
||||
threadIds->push_back(GetCurrentThreadId());
|
||||
char buffer[128];
|
||||
snprintf(buffer, sizeof(buffer), "%s%d, ", RUNNABLE_TEXT.c_str(), index);
|
||||
output->append(std::string(buffer));
|
||||
LeaveCriticalSection(&crit_sec);
|
||||
});
|
||||
}
|
||||
|
||||
submittableExecutor->Shutdown();
|
||||
DeleteCriticalSection(&crit_sec);
|
||||
|
||||
// Assert
|
||||
// We should've run 1 time on the main thread, and 5 times on the
|
||||
@@ -206,20 +212,27 @@ TEST(SubmittableExecutorTests, SingleThreadedDoSubmitMultipleTasksSucceeds) {
|
||||
std::unique_ptr<std::vector<DWORD>> threadIds =
|
||||
std::make_unique<std::vector<DWORD>>();
|
||||
|
||||
CRITICAL_SECTION crit_sec;
|
||||
InitializeCriticalSection(&crit_sec);
|
||||
|
||||
threadIds->push_back(GetCurrentThreadId());
|
||||
|
||||
// Act
|
||||
bool result = true;
|
||||
for (int index = 0; index < 5; index++) {
|
||||
result &= submittableExecutor->DoSubmit([&output, &threadIds, index]() {
|
||||
result &= submittableExecutor->DoSubmit([&output, &threadIds, &crit_sec,
|
||||
index]() {
|
||||
EnterCriticalSection(&crit_sec);
|
||||
threadIds->push_back(GetCurrentThreadId());
|
||||
char buffer[128];
|
||||
snprintf(buffer, sizeof(buffer), "%s%d, ", RUNNABLE_TEXT.c_str(), index);
|
||||
output->append(std::string(buffer));
|
||||
LeaveCriticalSection(&crit_sec);
|
||||
});
|
||||
}
|
||||
|
||||
submittableExecutor->Shutdown();
|
||||
DeleteCriticalSection(&crit_sec);
|
||||
|
||||
// Assert
|
||||
// All of these should have submitted
|
||||
|
||||
@@ -19,39 +19,14 @@
|
||||
#include "absl/strings/str_cat.h"
|
||||
|
||||
namespace test_utils {
|
||||
std::wstring StringToWideString(const std::string& s) {
|
||||
std::wstring StringToWideString(const std::string &s) {
|
||||
int len;
|
||||
int slength = (int)s.length() + 1;
|
||||
len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0);
|
||||
wchar_t* buf = new wchar_t[len];
|
||||
wchar_t *buf = new wchar_t[len];
|
||||
MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len);
|
||||
std::wstring r(buf);
|
||||
delete[] buf;
|
||||
return r;
|
||||
}
|
||||
|
||||
std::string GetPayloadPath(location::nearby::PayloadId payload_id) {
|
||||
PWSTR basePath;
|
||||
|
||||
// Retrieves the full path of a known folder identified by the folder's
|
||||
// KNOWNFOLDERID.
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/shlobj_core/nf-shlobj_core-shgetknownfolderpath
|
||||
SHGetKnownFolderPath(
|
||||
FOLDERID_Downloads, // rfid: A reference to the KNOWNFOLDERID that
|
||||
// identifies the folder.
|
||||
0, // dwFlags: Flags that specify special retrieval options.
|
||||
NULL, // hToken: An access token that represents a particular user.
|
||||
&basePath); // ppszPath: When this method returns, contains the address
|
||||
// of a pointer to a null-terminated Unicode string that
|
||||
// specifies the path of the known folder. The calling
|
||||
// process is responsible for freeing this resource once it
|
||||
// is no longer needed by calling CoTaskMemFree, whether
|
||||
// SHGetKnownFolderPath succeeds or not.
|
||||
|
||||
char* fullpathUTF8 = new char((wcslen(basePath) + 1) * sizeof(char));
|
||||
wcstombs(fullpathUTF8, basePath, (wcslen(basePath) + 1) * sizeof(char));
|
||||
std::string fullPath = std::string(fullpathUTF8);
|
||||
auto retval = absl::StrCat(fullPath += "/", payload_id);
|
||||
return retval;
|
||||
}
|
||||
} // namespace test_utils
|
||||
|
||||
@@ -15,14 +15,8 @@
|
||||
#ifndef PLATFORM_IMPL_WINDOWS_TEST_UTILS_H_
|
||||
#define PLATFORM_IMPL_WINDOWS_TEST_UTILS_H_
|
||||
|
||||
#include <Windows.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <string>
|
||||
#include <xstring>
|
||||
|
||||
#include "platform/base/payload_id.h"
|
||||
|
||||
#define TEST_BUFFER_SIZE 256
|
||||
#define TEST_PAYLOAD_ID 64l
|
||||
#define TEST_STRING \
|
||||
@@ -39,9 +33,21 @@
|
||||
"eu tellus. Cras feugiat ornare vestibulum. Nullam at ipsum vestibulum " \
|
||||
"sapien luctus dictum ac vel ligula."
|
||||
|
||||
#define TEST_FILE_PATH std::string("testfilename.txt")
|
||||
|
||||
namespace test_utils {
|
||||
std::wstring StringToWideString(const std::string& s);
|
||||
std::string GetPayloadPath(location::nearby::PayloadId payload_id);
|
||||
|
||||
class TempPath {
|
||||
public:
|
||||
enum Location {
|
||||
Local, // Some local directory, works for unittest and on borglets.
|
||||
CNSTest, // Creates a directory on the cns test cell.
|
||||
};
|
||||
TempPath(Location location) : location_(location) {}
|
||||
Location location_;
|
||||
const std::string path() { return ""; }
|
||||
};
|
||||
} // namespace test_utils
|
||||
|
||||
#endif // PLATFORM_IMPL_WINDOWS_TEST_UTILS_H_
|
||||
|
||||
Reference in New Issue
Block a user