Commit 5b20ed18 authored by Hoch Hochkeppel's avatar Hoch Hochkeppel Committed by Commit Bot

Add fake StorageFileStatics for testing

Adding a class to represent the Windows StorageFileStatics 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, schedules all async
operations through a ThreadTaskRunner, and does not implement methods
that fall outside the expected usage.

Bug: 1035527
Change-Id: Ia3439718cb02773e7a6c6835adcdbc807f47a383
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2491050Reviewed-by: default avatarEric Willigers <ericwilligers@chromium.org>
Commit-Queue: Hoch Hochkeppel <mhochk@microsoft.com>
Cr-Commit-Position: refs/heads/master@{#819696}
parent 1741d81e
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_STORAGE_FILE_STATICS_H_
#define CHROME_BROWSER_WEBSHARE_WIN_FAKE_STORAGE_FILE_STATICS_H_
#include <windows.storage.h>
#include <wrl/implements.h>
namespace webshare {
// Provides an implementation of IStorageFileStatics for use in GTests.
class __declspec(uuid("70A03B12-27C0-499A-B8AE-18E6060BDEDD"))
FakeStorageFileStatics
: public Microsoft::WRL::RuntimeClass<
Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::WinRtClassicComMix>,
ABI::Windows::Storage::IStorageFileStatics> {
public:
FakeStorageFileStatics();
FakeStorageFileStatics(const FakeStorageFileStatics&) = delete;
FakeStorageFileStatics& operator=(const FakeStorageFileStatics&) = delete;
~FakeStorageFileStatics() final;
// ABI::Windows::Storage::IStorageFileStatics:
IFACEMETHODIMP GetFileFromPathAsync(
HSTRING path,
ABI::Windows::Foundation::IAsyncOperation<
ABI::Windows::Storage::StorageFile*>** operation) final;
IFACEMETHODIMP GetFileFromApplicationUriAsync(
ABI::Windows::Foundation::IUriRuntimeClass* uri,
ABI::Windows::Foundation::IAsyncOperation<
ABI::Windows::Storage::StorageFile*>** operation) final;
IFACEMETHODIMP CreateStreamedFileAsync(
HSTRING display_name_with_extension,
ABI::Windows::Storage::IStreamedFileDataRequestedHandler* data_requested,
ABI::Windows::Storage::Streams::IRandomAccessStreamReference* thumbnail,
ABI::Windows::Foundation::IAsyncOperation<
ABI::Windows::Storage::StorageFile*>** operation) final;
IFACEMETHODIMP ReplaceWithStreamedFileAsync(
ABI::Windows::Storage::IStorageFile* file_to_replace,
ABI::Windows::Storage::IStreamedFileDataRequestedHandler* data_requested,
ABI::Windows::Storage::Streams::IRandomAccessStreamReference* thumbnail,
ABI::Windows::Foundation::IAsyncOperation<
ABI::Windows::Storage::StorageFile*>** operation) final;
IFACEMETHODIMP CreateStreamedFileFromUriAsync(
HSTRING display_name_with_extension,
ABI::Windows::Foundation::IUriRuntimeClass* uri,
ABI::Windows::Storage::Streams::IRandomAccessStreamReference* thumbnail,
ABI::Windows::Foundation::IAsyncOperation<
ABI::Windows::Storage::StorageFile*>** operation) final;
IFACEMETHODIMP ReplaceWithStreamedFileFromUriAsync(
ABI::Windows::Storage::IStorageFile* file_to_replace,
ABI::Windows::Foundation::IUriRuntimeClass* uri,
ABI::Windows::Storage::Streams::IRandomAccessStreamReference* thumbnail,
ABI::Windows::Foundation::IAsyncOperation<
ABI::Windows::Storage::StorageFile*>** operation) final;
};
} // namespace webshare
#endif // CHROME_BROWSER_WEBSHARE_WIN_FAKE_STORAGE_FILE_STATICS_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_storage_file_statics.h"
#include <wrl/event.h>
#include <wrl/implements.h>
#include "base/run_loop.h"
#include "base/test/task_environment.h"
#include "base/win/scoped_hstring.h"
#include "chrome/browser/webshare/win/fake_buffer.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::Foundation::IClosable;
using ABI::Windows::Storage::FileAccessMode;
using ABI::Windows::Storage::IStorageFile;
using ABI::Windows::Storage::IStorageItem;
using ABI::Windows::Storage::IStreamedFileDataRequestedHandler;
using ABI::Windows::Storage::StorageFile;
using ABI::Windows::Storage::Streams::IBuffer;
using ABI::Windows::Storage::Streams::IInputStream;
using ABI::Windows::Storage::Streams::InputStreamOptions;
using ABI::Windows::Storage::Streams::IOutputStream;
using ABI::Windows::Storage::Streams::IRandomAccessStream;
using Microsoft::WRL::Callback;
using Microsoft::WRL::ComPtr;
using Microsoft::WRL::Make;
namespace webshare {
TEST(FakeStorageFileStaticsTest, CreateStreamedFileAsync) {
base::test::SingleThreadTaskEnvironment task_environment;
if (!base::win::ScopedHString::ResolveCoreWinRTStringDelayload())
return;
auto file_statics = Make<FakeStorageFileStatics>();
// Create a streamed file, populated on-demand by the provided callback.
ComPtr<IStorageFile> storage_file;
{
base::RunLoop run_loop;
auto file_name = base::win::ScopedHString::Create("MyTestFile.abc");
ComPtr<IAsyncOperation<StorageFile*>> create_operation;
file_statics->CreateStreamedFileAsync(
file_name.get(),
Callback<IStreamedFileDataRequestedHandler>([](IOutputStream* stream) {
// Create a small buffer of bytes to write to the stream
auto buffer = Make<FakeBuffer>(4);
EXPECT_HRESULT_SUCCEEDED(buffer->put_Length(4));
byte* raw_buffer;
EXPECT_HRESULT_SUCCEEDED(buffer->Buffer(&raw_buffer));
raw_buffer[0] = 'f';
raw_buffer[1] = 'i';
raw_buffer[2] = 's';
raw_buffer[3] = 'h';
// Write the bytes to the stream
ComPtr<IAsyncOperationWithProgress<UINT32, UINT32>> write_operation;
EXPECT_HRESULT_SUCCEEDED(
stream->WriteAsync(buffer.Get(), &write_operation));
ComPtr<IOutputStream> captured_output_stream = stream;
write_operation->put_Completed(
Callback<
IAsyncOperationWithProgressCompletedHandler<UINT32, UINT32>>(
[captured_output_stream](
IAsyncOperationWithProgress<UINT32, UINT32>*
async_operation,
AsyncStatus async_status) {
// Verify the write operation completed successfully
EXPECT_EQ(async_status, AsyncStatus::Completed);
UINT32 result;
EXPECT_HRESULT_SUCCEEDED(
async_operation->GetResults(&result));
EXPECT_EQ(result, 4u);
// Flush the stream
ComPtr<IAsyncOperation<bool>> flush_operation;
EXPECT_HRESULT_SUCCEEDED(
captured_output_stream->FlushAsync(&flush_operation));
flush_operation->put_Completed(
Callback<IAsyncOperationCompletedHandler<bool>>(
[captured_output_stream](
IAsyncOperation<bool>* async_operation,
AsyncStatus async_status) {
// Verify the flush operation completed
// successfully
EXPECT_EQ(async_status, AsyncStatus::Completed);
boolean result;
EXPECT_HRESULT_SUCCEEDED(
async_operation->GetResults(&result));
EXPECT_EQ(result, TRUE);
// Close the stream
ComPtr<IClosable> closable;
EXPECT_HRESULT_SUCCEEDED(
captured_output_stream.As(&closable));
EXPECT_HRESULT_SUCCEEDED(closable->Close());
return S_OK;
})
.Get());
return S_OK;
})
.Get());
return S_OK;
}).Get(),
/*thumbnail*/ nullptr, &create_operation);
ASSERT_HRESULT_SUCCEEDED(create_operation->put_Completed(
Callback<IAsyncOperationCompletedHandler<StorageFile*>>(
[&run_loop, &storage_file](
IAsyncOperation<StorageFile*>* async_operation,
AsyncStatus async_status) {
EXPECT_EQ(async_status, AsyncStatus::Completed);
EXPECT_HRESULT_SUCCEEDED(
async_operation->GetResults(&storage_file));
run_loop.Quit();
return S_OK;
})
.Get()));
run_loop.Run();
}
// Verify the created streamed file has the expected name
ComPtr<IStorageItem> storage_item;
ASSERT_HRESULT_SUCCEEDED(storage_file.As(&storage_item));
HSTRING name;
ASSERT_HRESULT_SUCCEEDED(storage_item->get_Name(&name));
ASSERT_EQ(base::win::ScopedHString(name).GetAsUTF8(), "MyTestFile.abc");
// Open the streamed file
ComPtr<IRandomAccessStream> opened_stream;
{
base::RunLoop run_loop;
ComPtr<IAsyncOperation<IRandomAccessStream*>> open_operation;
ASSERT_HRESULT_SUCCEEDED(storage_file->OpenAsync(
FileAccessMode::FileAccessMode_Read, &open_operation));
ASSERT_HRESULT_SUCCEEDED(open_operation->put_Completed(
Callback<IAsyncOperationCompletedHandler<IRandomAccessStream*>>(
[&run_loop, &opened_stream](
IAsyncOperation<IRandomAccessStream*>* async_operation,
AsyncStatus async_status) {
EXPECT_EQ(async_status, AsyncStatus::Completed);
EXPECT_HRESULT_SUCCEEDED(
async_operation->GetResults(&opened_stream));
run_loop.Quit();
return S_OK;
})
.Get()));
run_loop.Run();
}
ComPtr<IInputStream> input_stream;
ASSERT_HRESULT_SUCCEEDED(opened_stream->GetInputStreamAt(0, &input_stream));
UINT64 size;
ASSERT_HRESULT_SUCCEEDED(opened_stream->get_Size(&size));
// Read the opened stream
auto buffer = Make<FakeBuffer>(size);
{
base::RunLoop run_loop;
ComPtr<IAsyncOperationWithProgress<IBuffer*, UINT32>> read_operation;
ASSERT_HRESULT_SUCCEEDED(input_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> result;
EXPECT_HRESULT_SUCCEEDED(async_operation->GetResults(&result));
EXPECT_EQ(result.Get(), buffer.Get());
run_loop.Quit();
return S_OK;
})
.Get()));
run_loop.Run();
}
// Verify the stream read from the file has content matching what our
// DataRequested callback provided
UINT32 length;
ASSERT_HRESULT_SUCCEEDED(buffer->get_Length(&length));
ASSERT_EQ(length, size);
byte* raw_buffer;
ASSERT_HRESULT_SUCCEEDED(buffer->Buffer(&raw_buffer));
ASSERT_EQ(raw_buffer[0], 'f');
ASSERT_EQ(raw_buffer[1], 'i');
ASSERT_EQ(raw_buffer[2], 's');
ASSERT_EQ(raw_buffer[3], 'h');
}
} // namespace webshare
......@@ -330,6 +330,8 @@ static_library("test_support") {
"../browser/webshare/win/fake_iasync_operation_with_progress.h",
"../browser/webshare/win/fake_random_access_stream.cc",
"../browser/webshare/win/fake_random_access_stream.h",
"../browser/webshare/win/fake_storage_file_statics.cc",
"../browser/webshare/win/fake_storage_file_statics.h",
"../browser/webshare/win/scoped_fake_data_transfer_manager_interop.cc",
"../browser/webshare/win/scoped_fake_data_transfer_manager_interop.h",
"//chrome/app/chrome_crash_reporter_client_win.cc",
......@@ -5819,6 +5821,7 @@ test("unit_tests") {
"../browser/webshare/win/fake_data_transfer_manager_interop_unittest.cc",
"../browser/webshare/win/fake_data_transfer_manager_unittest.cc",
"../browser/webshare/win/fake_random_access_stream_unittest.cc",
"../browser/webshare/win/fake_storage_file_statics_unittest.cc",
"../browser/webshare/win/show_share_ui_for_window_operation_unittest.cc",
]
deps += [
......
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