Commit 501ef2f0 authored by Hoch Hochkeppel's avatar Hoch Hochkeppel Committed by Commit Bot

Add fake DataWriterFactory for testing

Adding a class to represent the Windows DataWriterFactory class within
tests, as well as basic unit tests to validate the test class behaviors.
The class behaves similarly to the Windows equivalent, except it
includes gtest validations for expected usage (and does not implement
methods that fall outside the expected usage).

Bug: 1035527
Change-Id: Icea55a3d5055d77f0b88ab6f71ce34fe9b285a61
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2491121Reviewed-by: default avatarEric Willigers <ericwilligers@chromium.org>
Commit-Queue: Hoch Hochkeppel <mhochk@microsoft.com>
Cr-Commit-Position: refs/heads/master@{#820005}
parent a707cd1a
This diff is collapsed.
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_WEBSHARE_WIN_FAKE_DATA_WRITER_FACTORY_H_
#define CHROME_BROWSER_WEBSHARE_WIN_FAKE_DATA_WRITER_FACTORY_H_
#include <windows.storage.streams.h>
#include <wrl/implements.h>
namespace webshare {
// Provides an implementation of IDataWriterFactory for use in GTests.
class __declspec(uuid("4A0022E7-D891-4B52-8736-77497F9FFE14"))
FakeDataWriterFactory final
: public Microsoft::WRL::RuntimeClass<
Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::WinRtClassicComMix>,
ABI::Windows::Storage::Streams::IDataWriterFactory> {
public:
FakeDataWriterFactory();
FakeDataWriterFactory(const FakeDataWriterFactory&) = delete;
FakeDataWriterFactory& operator=(const FakeDataWriterFactory&) = delete;
~FakeDataWriterFactory() final;
// ABI::Windows::Storage::Streams::IDataWriterFactory:
IFACEMETHODIMP CreateDataWriter(
ABI::Windows::Storage::Streams::IOutputStream* outputStream,
ABI::Windows::Storage::Streams::IDataWriter** data_writer) final;
};
} // namespace webshare
#endif // CHROME_BROWSER_WEBSHARE_WIN_FAKE_DATA_WRITER_FACTORY_H_
// Copyright 2020 The Chromium 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 "chrome/browser/webshare/win/fake_data_writer_factory.h"
#include <wrl/event.h>
#include <wrl/implements.h>
#include "base/run_loop.h"
#include "base/test/task_environment.h"
#include "chrome/browser/webshare/win/fake_buffer.h"
#include "chrome/browser/webshare/win/fake_random_access_stream.h"
#include "testing/gtest/include/gtest/gtest-spi.h"
#include "testing/gtest/include/gtest/gtest.h"
using ABI::Windows::Foundation::IAsyncOperation;
using ABI::Windows::Foundation::IAsyncOperationCompletedHandler;
using ABI::Windows::Foundation::IAsyncOperationWithProgress;
using ABI::Windows::Foundation::IAsyncOperationWithProgressCompletedHandler;
using ABI::Windows::Storage::Streams::IBuffer;
using ABI::Windows::Storage::Streams::IDataReader;
using ABI::Windows::Storage::Streams::IDataWriter;
using ABI::Windows::Storage::Streams::InputStreamOptions;
using Microsoft::WRL::Callback;
using Microsoft::WRL::ComPtr;
using Microsoft::WRL::Make;
namespace webshare {
TEST(FakeDataWriterFactoryTest, RacingStoreAsync) {
base::test::SingleThreadTaskEnvironment task_environment;
auto writer_factory = Make<FakeDataWriterFactory>();
auto stream = Make<FakeRandomAccessStream>();
ComPtr<IDataWriter> data_writer;
ASSERT_HRESULT_SUCCEEDED(
writer_factory->CreateDataWriter(stream.Get(), &data_writer));
std::vector<unsigned char> bytes = {'h', 'i'};
ASSERT_HRESULT_SUCCEEDED(data_writer->WriteBytes(bytes.size(), bytes.data()));
base::RunLoop run_loop;
ComPtr<IAsyncOperation<UINT32>> store_operation;
ASSERT_HRESULT_SUCCEEDED(data_writer->StoreAsync(&store_operation));
EXPECT_NONFATAL_FAILURE(ASSERT_HRESULT_FAILED(data_writer->WriteBytes(
bytes.size(), bytes.data())),
"WriteBytes");
ComPtr<IAsyncOperation<UINT32>> store_operation_2;
EXPECT_NONFATAL_FAILURE(
ASSERT_HRESULT_FAILED(data_writer->StoreAsync(&store_operation_2)),
"StoreAsync");
ComPtr<IAsyncOperation<bool>> flush_operation;
EXPECT_NONFATAL_FAILURE(
ASSERT_HRESULT_FAILED(data_writer->FlushAsync(&flush_operation)),
"FlushAsync");
store_operation->put_Completed(
Callback<IAsyncOperationCompletedHandler<UINT32>>(
[&run_loop](IAsyncOperation<UINT32>* async_operation,
AsyncStatus async_status) {
run_loop.Quit();
return S_OK;
})
.Get());
run_loop.Run();
// Expect a failure from the destructor due to the unflushed data
EXPECT_NONFATAL_FAILURE(data_writer.Reset(), "FlushAsync");
}
TEST(FakeDataWriterFactoryTest, UnstoredBytes) {
auto writer_factory = Make<FakeDataWriterFactory>();
auto stream = Make<FakeRandomAccessStream>();
ComPtr<IDataWriter> data_writer;
ASSERT_HRESULT_SUCCEEDED(
writer_factory->CreateDataWriter(stream.Get(), &data_writer));
std::vector<unsigned char> bytes = {'h', 'i'};
ASSERT_HRESULT_SUCCEEDED(data_writer->WriteBytes(bytes.size(), bytes.data()));
ComPtr<IAsyncOperation<bool>> flush_operation;
EXPECT_NONFATAL_FAILURE(
ASSERT_HRESULT_FAILED(data_writer->FlushAsync(&flush_operation)),
"FlushAsync");
// Expect failures from the destructor from not storing the data and not
// flushing the data
EXPECT_NONFATAL_FAILURE(
EXPECT_NONFATAL_FAILURE(data_writer.Reset(), "pending storage"),
"FlushAsync");
}
TEST(FakeDataWriterFactoryTest, WriteBytes) {
base::test::SingleThreadTaskEnvironment task_environment;
auto writer_factory = Make<FakeDataWriterFactory>();
auto stream = Make<FakeRandomAccessStream>();
ComPtr<IDataWriter> data_writer;
ASSERT_HRESULT_SUCCEEDED(
writer_factory->CreateDataWriter(stream.Get(), &data_writer));
{
std::vector<unsigned char> bytes = {'h', 'i'};
ASSERT_HRESULT_SUCCEEDED(
data_writer->WriteBytes(bytes.size(), bytes.data()));
base::RunLoop run_loop;
ComPtr<IAsyncOperation<UINT32>> store_operation;
ASSERT_HRESULT_SUCCEEDED(data_writer->StoreAsync(&store_operation));
store_operation->put_Completed(
Callback<IAsyncOperationCompletedHandler<UINT32>>(
[&run_loop, &bytes](IAsyncOperation<UINT32>* async_operation,
AsyncStatus async_status) {
EXPECT_EQ(async_status, AsyncStatus::Completed);
UINT32 results;
EXPECT_HRESULT_SUCCEEDED(async_operation->GetResults(&results));
EXPECT_EQ(results, bytes.size());
run_loop.Quit();
return S_OK;
})
.Get());
run_loop.Run();
}
{
base::RunLoop run_loop;
std::vector<unsigned char> more_bytes = {' ', 't', 'h', 'e', 'r', 'e'};
ASSERT_HRESULT_SUCCEEDED(
data_writer->WriteBytes(more_bytes.size(), more_bytes.data()));
ComPtr<IAsyncOperation<UINT32>> store_operation;
ASSERT_HRESULT_SUCCEEDED(data_writer->StoreAsync(&store_operation));
store_operation->put_Completed(
Callback<IAsyncOperationCompletedHandler<UINT32>>(
[&run_loop, &more_bytes](IAsyncOperation<UINT32>* async_operation,
AsyncStatus async_status) {
EXPECT_EQ(async_status, AsyncStatus::Completed);
UINT32 results;
EXPECT_HRESULT_SUCCEEDED(async_operation->GetResults(&results));
EXPECT_EQ(results, more_bytes.size());
run_loop.Quit();
return S_OK;
})
.Get());
run_loop.Run();
}
{
base::RunLoop run_loop;
ComPtr<IAsyncOperation<bool>> flush_operation;
ASSERT_HRESULT_SUCCEEDED(data_writer->FlushAsync(&flush_operation));
flush_operation->put_Completed(
Callback<IAsyncOperationCompletedHandler<bool>>(
[&run_loop](IAsyncOperation<bool>* async_operation,
AsyncStatus async_status) {
EXPECT_EQ(async_status, AsyncStatus::Completed);
boolean results;
EXPECT_HRESULT_SUCCEEDED(async_operation->GetResults(&results));
EXPECT_EQ(results, TRUE);
run_loop.Quit();
return S_OK;
})
.Get());
run_loop.Run();
}
ASSERT_HRESULT_SUCCEEDED(stream->Seek(0));
UINT64 size;
stream->get_Size(&size);
ASSERT_EQ(size, 8u);
auto buffer = Make<FakeBuffer>(size);
{
base::RunLoop run_loop;
ComPtr<IAsyncOperationWithProgress<IBuffer*, UINT32>> read_operation;
ASSERT_HRESULT_SUCCEEDED(stream->ReadAsync(
buffer.Get(), size, InputStreamOptions::InputStreamOptions_None,
&read_operation));
ASSERT_HRESULT_SUCCEEDED(read_operation->put_Completed(
Callback<IAsyncOperationWithProgressCompletedHandler<IBuffer*, UINT32>>(
[&run_loop, &buffer](
IAsyncOperationWithProgress<IBuffer*, UINT32>* async_operation,
AsyncStatus async_status) {
EXPECT_EQ(async_status, AsyncStatus::Completed);
ComPtr<IBuffer> results;
EXPECT_HRESULT_SUCCEEDED(async_operation->GetResults(&results));
EXPECT_EQ(results, buffer);
run_loop.Quit();
return S_OK;
})
.Get()));
run_loop.Run();
}
UINT32 length;
ASSERT_HRESULT_SUCCEEDED(buffer->get_Length(&length));
ASSERT_EQ(length, 8u);
byte* raw_buffer;
ASSERT_HRESULT_SUCCEEDED(buffer->Buffer(&raw_buffer));
ASSERT_EQ(raw_buffer[0], 'h');
ASSERT_EQ(raw_buffer[1], 'i');
ASSERT_EQ(raw_buffer[2], ' ');
ASSERT_EQ(raw_buffer[3], 't');
ASSERT_EQ(raw_buffer[4], 'h');
ASSERT_EQ(raw_buffer[5], 'e');
ASSERT_EQ(raw_buffer[6], 'r');
ASSERT_EQ(raw_buffer[7], 'e');
}
} // namespace webshare
...@@ -327,6 +327,8 @@ static_library("test_support") { ...@@ -327,6 +327,8 @@ static_library("test_support") {
"../browser/webshare/win/fake_data_transfer_manager.h", "../browser/webshare/win/fake_data_transfer_manager.h",
"../browser/webshare/win/fake_data_transfer_manager_interop.cc", "../browser/webshare/win/fake_data_transfer_manager_interop.cc",
"../browser/webshare/win/fake_data_transfer_manager_interop.h", "../browser/webshare/win/fake_data_transfer_manager_interop.h",
"../browser/webshare/win/fake_data_writer_factory.cc",
"../browser/webshare/win/fake_data_writer_factory.h",
"../browser/webshare/win/fake_iasync_operation_with_progress.h", "../browser/webshare/win/fake_iasync_operation_with_progress.h",
"../browser/webshare/win/fake_random_access_stream.cc", "../browser/webshare/win/fake_random_access_stream.cc",
"../browser/webshare/win/fake_random_access_stream.h", "../browser/webshare/win/fake_random_access_stream.h",
...@@ -5817,6 +5819,7 @@ test("unit_tests") { ...@@ -5817,6 +5819,7 @@ test("unit_tests") {
"../browser/webshare/win/fake_buffer_unittest.cc", "../browser/webshare/win/fake_buffer_unittest.cc",
"../browser/webshare/win/fake_data_transfer_manager_interop_unittest.cc", "../browser/webshare/win/fake_data_transfer_manager_interop_unittest.cc",
"../browser/webshare/win/fake_data_transfer_manager_unittest.cc", "../browser/webshare/win/fake_data_transfer_manager_unittest.cc",
"../browser/webshare/win/fake_data_writer_factory_unittest.cc",
"../browser/webshare/win/fake_random_access_stream_unittest.cc", "../browser/webshare/win/fake_random_access_stream_unittest.cc",
"../browser/webshare/win/fake_storage_file_statics_unittest.cc", "../browser/webshare/win/fake_storage_file_statics_unittest.cc",
"../browser/webshare/win/show_share_ui_for_window_operation_unittest.cc", "../browser/webshare/win/show_share_ui_for_window_operation_unittest.cc",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment