Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(124)

Unified Diff: mojo/services/files/public/cpp/tests/input_stream_file_unittest.cc

Issue 1388413005: Move //mojo/services/X/public/... to //mojo/services/X/... (part 1). (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: mojo/services/files/public/cpp/tests/input_stream_file_unittest.cc
diff --git a/mojo/services/files/public/cpp/tests/input_stream_file_unittest.cc b/mojo/services/files/public/cpp/tests/input_stream_file_unittest.cc
deleted file mode 100644
index 71fb5bf1b1c6a6fa58a9059ac781c4a4b247284f..0000000000000000000000000000000000000000
--- a/mojo/services/files/public/cpp/tests/input_stream_file_unittest.cc
+++ /dev/null
@@ -1,539 +0,0 @@
-// Copyright 2015 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 "files/public/cpp/input_stream_file.h"
-
-#include <string.h>
-
-#include <string>
-#include <utility>
-
-#include "files/public/interfaces/files.mojom.h"
-#include "files/public/interfaces/types.mojom.h"
-#include "mojo/public/cpp/application/application_test_base.h"
-#include "mojo/public/cpp/bindings/interface_request.h"
-#include "mojo/public/cpp/environment/logging.h"
-#include "mojo/public/cpp/system/macros.h"
-#include "mojo/public/cpp/utility/run_loop.h"
-
-namespace files_impl {
-namespace {
-
-using InputStreamFileTest = mojo::test::ApplicationTestBase;
-
-void QuitMessageLoop() {
- mojo::RunLoop::current()->Quit();
-}
-
-void RunMessageLoop() {
- mojo::RunLoop::current()->Run();
-}
-
-void RunMessageLoopUntilIdle() {
- mojo::RunLoop::current()->RunUntilIdle();
-}
-
-void PostTaskToMessageLoop(const mojo::Closure& task) {
- mojo::RunLoop::current()->PostDelayedTask(task, 0);
-}
-
-// Converts a string to a |mojo::Array<uint8_t>|.
-mojo::Array<uint8_t> StringToArray(const std::string& s) {
- auto rv = mojo::Array<uint8_t>::New(s.size());
- if (s.size())
- memcpy(&rv[0], &s[0], s.size());
- return rv;
-}
-
-// Converts a |mojo::Array<uint8_t>| to a string. If the array is null, returns
-// the string "ARRAY_IS_NULL".
-std::string ArrayToString(const mojo::Array<uint8_t>& a) {
- if (a.is_null())
- return std::string("ARRAY_IS_NULL");
- return a.size() ? std::string(reinterpret_cast<const char*>(&a[0]), a.size())
- : std::string();
-}
-
-class TestClient : public InputStreamFile::Client {
- public:
- TestClient() { Reset(); }
- ~TestClient() override {}
-
- // Note: This doesn't reset |callback_|.
- void Reset() {
- data_ = StringToArray("OOPS");
- complete_synchronously_ = true;
- got_request_data_ = false;
- got_on_closed_ = false;
- }
-
- // Completes a pending callback. Note: |RequestData()| may be called again
- // "inside" this (i.e., "inside" the callback).
- void RunRequestDataCallback(mojo::Array<uint8_t> data) {
- MOJO_CHECK(!callback_.is_null());
- RequestDataCallback callback;
- std::swap(callback, callback_);
- callback.Run(mojo::files::Error::OK, data.Pass());
- }
-
- void set_data(mojo::Array<uint8_t> data) {
- MOJO_CHECK(!data.is_null());
- data_ = data.Pass();
- }
- void set_complete_synchronously(bool complete_synchronously) {
- complete_synchronously_ = complete_synchronously;
- }
-
- bool got_request_data() const { return got_request_data_; }
- bool got_on_closed() const { return got_on_closed_; }
-
- private:
- // |InputStreamFile::Client|:
- bool RequestData(size_t max_num_bytes,
- mojo::files::Error* error,
- mojo::Array<uint8_t>* data,
- const RequestDataCallback& callback) override {
- MOJO_CHECK(max_num_bytes);
- MOJO_CHECK(error);
- MOJO_CHECK(data);
- MOJO_CHECK(!callback.is_null());
-
- // This shouldn't be called while a callback is pending.
- MOJO_CHECK(callback_.is_null());
-
- got_request_data_ = true;
- QuitMessageLoop();
-
- if (!complete_synchronously_) {
- callback_ = callback;
- return false;
- }
-
- *error = mojo::files::Error::OK;
- *data = data_.Clone();
- return true;
- }
- void OnClosed() override {
- got_on_closed_ = true;
- QuitMessageLoop();
- }
-
- mojo::Array<uint8_t> data_;
- bool complete_synchronously_;
-
- bool got_request_data_;
- bool got_on_closed_;
-
- RequestDataCallback callback_;
-
- MOJO_DISALLOW_COPY_AND_ASSIGN(TestClient);
-};
-
-void TestReadSync(mojo::files::File* file,
- TestClient* client,
- const std::string& s) {
- bool read_cb_called = false;
- mojo::files::Error error = mojo::files::Error::INTERNAL;
- mojo::Array<uint8_t> data;
- file->Read(100u, 0, mojo::files::Whence::FROM_CURRENT,
- [&read_cb_called, &error, &data](mojo::files::Error e,
- mojo::Array<uint8_t> d) {
- read_cb_called = true;
- error = e;
- data = d.Pass();
- QuitMessageLoop();
- });
- if (client) {
- // If there's a client, since we're running everything on one thread, the
- // impl (which will call the client, which will quit the message loop) will
- // get called before the callback.
- client->Reset();
- client->set_data(StringToArray(s));
- RunMessageLoop();
- EXPECT_TRUE(client->got_request_data());
- EXPECT_FALSE(client->got_on_closed());
- EXPECT_FALSE(read_cb_called);
- // Spin the message loop again to get the callback.
- client->Reset();
- RunMessageLoop();
- EXPECT_FALSE(client->got_request_data());
- EXPECT_FALSE(client->got_on_closed());
- EXPECT_TRUE(read_cb_called);
- EXPECT_EQ(mojo::files::Error::OK, error);
- EXPECT_EQ(s, ArrayToString(data));
- } else {
- // Otherwise, only the read callback will be called and quit the message
- // loop.
- RunMessageLoop();
- EXPECT_TRUE(read_cb_called);
- EXPECT_EQ(mojo::files::Error::UNAVAILABLE, error);
- EXPECT_TRUE(data.is_null());
- }
-}
-
-void TestReadAsync(mojo::files::File* file,
- TestClient* client,
- const std::string& s) {
- MOJO_CHECK(client);
-
- bool read_cb_called = false;
- mojo::files::Error error = mojo::files::Error::INTERNAL;
- mojo::Array<uint8_t> data;
- file->Read(100u, 0, mojo::files::Whence::FROM_CURRENT,
- [&read_cb_called, &error, &data](mojo::files::Error e,
- mojo::Array<uint8_t> d) {
- read_cb_called = true;
- error = e;
- data = d.Pass();
- QuitMessageLoop();
- });
- client->Reset();
- client->set_complete_synchronously(false);
- RunMessageLoop();
- EXPECT_TRUE(client->got_request_data());
- EXPECT_FALSE(client->got_on_closed());
- EXPECT_FALSE(read_cb_called);
- // The read callback won't get called until we tell the client to run its
- // callback.
- client->Reset();
- client->RunRequestDataCallback(StringToArray(s));
- EXPECT_FALSE(client->got_request_data());
- EXPECT_FALSE(client->got_on_closed());
- EXPECT_FALSE(read_cb_called);
- // Spin the message loop again to get the read callback.
- client->Reset();
- RunMessageLoop();
- EXPECT_FALSE(client->got_request_data());
- EXPECT_FALSE(client->got_on_closed());
- EXPECT_TRUE(read_cb_called);
- EXPECT_EQ(mojo::files::Error::OK, error);
- EXPECT_EQ(s, ArrayToString(data));
-}
-
-void TestClose(mojo::files::File* file, TestClient* client) {
- bool close_cb_called = false;
- mojo::files::Error error = mojo::files::Error::INTERNAL;
- file->Close([&close_cb_called, &error](mojo::files::Error e) {
- close_cb_called = true;
- error = e;
- QuitMessageLoop();
- });
- if (client) {
- // (This is analogous to |TestReadSync()|.)
- client->Reset();
- RunMessageLoop();
- EXPECT_FALSE(client->got_request_data());
- EXPECT_TRUE(client->got_on_closed());
- EXPECT_FALSE(close_cb_called);
- client->Reset();
- RunMessageLoop();
- EXPECT_FALSE(client->got_request_data());
- EXPECT_FALSE(client->got_on_closed());
- } else {
- RunMessageLoop();
- }
- EXPECT_TRUE(close_cb_called);
- EXPECT_EQ(mojo::files::Error::OK, error);
-}
-
-TEST_F(InputStreamFileTest, BasicSync) {
- mojo::files::FilePtr file;
- TestClient client;
- std::unique_ptr<InputStreamFile> file_impl =
- InputStreamFile::Create(&client, GetProxy(&file));
-
- TestReadSync(file.get(), &client, "hello");
- TestReadSync(file.get(), &client, "world");
- TestClose(file.get(), &client);
-}
-
-TEST_F(InputStreamFileTest, BasicAsync) {
- mojo::files::FilePtr file;
- TestClient client;
- std::unique_ptr<InputStreamFile> file_impl =
- InputStreamFile::Create(&client, GetProxy(&file));
-
- TestReadAsync(file.get(), &client, "hello");
- TestReadAsync(file.get(), &client, "world");
- TestClose(file.get(), &client);
-}
-
-TEST_F(InputStreamFileTest, SetClient) {
- mojo::files::FilePtr file;
- TestClient client1;
- std::unique_ptr<InputStreamFile> file_impl =
- InputStreamFile::Create(&client1, GetProxy(&file));
-
- TestReadSync(file.get(), &client1, "hello");
-
- TestClient client2;
- file_impl->set_client(&client2);
- TestReadSync(file.get(), &client2, "world");
-
- file_impl->set_client(&client1);
- TestReadAsync(file.get(), &client1, "!");
- TestClose(file.get(), &client1);
-}
-
-TEST_F(InputStreamFileTest, NullClient) {
- mojo::files::FilePtr file;
- std::unique_ptr<InputStreamFile> file_impl =
- InputStreamFile::Create(nullptr, GetProxy(&file));
-
- TestReadSync(file.get(), nullptr, "hello");
- TestClose(file.get(), nullptr);
-}
-
-TEST_F(InputStreamFileTest, SetNullClient) {
- mojo::files::FilePtr file;
- TestClient client;
- std::unique_ptr<InputStreamFile> file_impl =
- InputStreamFile::Create(&client, GetProxy(&file));
-
- TestReadSync(file.get(), &client, "hello");
-
- file_impl->set_client(nullptr);
- client.Reset();
- TestReadSync(file.get(), nullptr, "hello");
- TestClose(file.get(), nullptr);
- EXPECT_FALSE(client.got_request_data());
- EXPECT_FALSE(client.got_on_closed());
-}
-
-TEST_F(InputStreamFileTest, ImplOnlyClosesMessagePipeOnDestruction) {
- mojo::files::FilePtr file;
- std::unique_ptr<InputStreamFile> file_impl =
- InputStreamFile::Create(nullptr, GetProxy(&file));
- bool got_connection_error = false;
- file.set_connection_error_handler([&got_connection_error]() {
- got_connection_error = true;
- QuitMessageLoop();
- });
-
- TestClose(file.get(), nullptr);
- // The impl should only close its end when it's destroyed (even if |Close()|
- // has been called).
- RunMessageLoopUntilIdle();
- EXPECT_FALSE(got_connection_error);
- file_impl.reset();
- RunMessageLoop();
- EXPECT_TRUE(got_connection_error);
-}
-
-TEST_F(InputStreamFileTest, ClosingMessagePipeCausesOnClosed) {
- mojo::files::FilePtr file;
- TestClient client;
- std::unique_ptr<InputStreamFile> file_impl =
- InputStreamFile::Create(&client, GetProxy(&file));
-
- file.reset();
- RunMessageLoop();
- EXPECT_FALSE(client.got_request_data());
- EXPECT_TRUE(client.got_on_closed());
-}
-
-// Clients may own the impl (and this is a typical pattern). This client will
-// own/destroy its impl on any |Client| call (and we'll test that this doesn't
-// result in any additional calls to the client).
-class TestClientDestroysImplClient : public InputStreamFile::Client {
- public:
- explicit TestClientDestroysImplClient(
- mojo::InterfaceRequest<mojo::files::File> request)
- : file_impl_(InputStreamFile::Create(this, request.Pass())) {}
- ~TestClientDestroysImplClient() override {}
-
- private:
- // InputStreamFile::Client|:
- bool RequestData(size_t /*max_num_bytes*/,
- mojo::files::Error* /*error*/,
- mojo::Array<uint8_t>* /*data*/,
- const RequestDataCallback& /*callback*/) override {
- // We reset the impl on any call, and afterwards it shouldn't call us.
- EXPECT_TRUE(file_impl_);
- file_impl_.reset();
- return true;
- }
- void OnClosed() override {
- // We reset the impl on any call, and afterwards it shouldn't call us.
- EXPECT_TRUE(file_impl_);
- file_impl_.reset();
- }
-
- std::unique_ptr<InputStreamFile> file_impl_;
-
- MOJO_DISALLOW_COPY_AND_ASSIGN(TestClientDestroysImplClient);
-};
-
-TEST_F(InputStreamFileTest, ClientDestroysImpl) {
- // Test destruction due to reading.
- {
- mojo::files::FilePtr file;
- TestClientDestroysImplClient client(GetProxy(&file));
- bool got_connection_error = false;
- file.set_connection_error_handler([&got_connection_error]() {
- got_connection_error = true;
- QuitMessageLoop();
- });
- // If the impl is destroyed while trying to answer a read, it doesn't
- // respond.
- // TODO(vtl): I'm not sure if this is the best behavior. Maybe it should
- // respond with an error?
- file->Read(100u, 0, mojo::files::Whence::FROM_CURRENT,
- [](mojo::files::Error, mojo::Array<uint8_t>) {
- MOJO_CHECK(false) << "Not reached";
- });
- RunMessageLoop();
- EXPECT_TRUE(got_connection_error);
- }
-
- // Test destruction due to closing.
- {
- mojo::files::FilePtr file;
- TestClientDestroysImplClient client(GetProxy(&file));
- bool got_connection_error = false;
- file.set_connection_error_handler([&got_connection_error]() {
- got_connection_error = true;
- QuitMessageLoop();
- });
- TestClose(file.get(), nullptr);
- if (!got_connection_error)
- RunMessageLoop();
- EXPECT_TRUE(got_connection_error);
- }
-}
-
-// This responds synchronously to any (non-zero-byte) read with a single byte,
-// starting with 0 and incrementing each time.
-class TestClientFifoSync : public InputStreamFile::Client {
- public:
- explicit TestClientFifoSync(mojo::InterfaceRequest<mojo::files::File> request)
- : file_impl_(InputStreamFile::Create(this, request.Pass())),
- next_byte_(0u) {}
- ~TestClientFifoSync() override {}
-
- private:
- // InputStreamFile::Client|:
- bool RequestData(size_t max_num_bytes,
- mojo::files::Error* error,
- mojo::Array<uint8_t>* data,
- const RequestDataCallback& callback) override {
- *error = mojo::files::Error::OK;
- data->resize(1);
- (*data)[0] = next_byte_++;
- return true;
- }
- void OnClosed() override {}
-
- std::unique_ptr<InputStreamFile> file_impl_;
- uint8_t next_byte_;
-
- MOJO_DISALLOW_COPY_AND_ASSIGN(TestClientFifoSync);
-};
-
-// Like |TestClientFifoSync|, but asynchronous.
-class TestClientFifoAsync : public InputStreamFile::Client {
- public:
- explicit TestClientFifoAsync(
- mojo::InterfaceRequest<mojo::files::File> request)
- : file_impl_(InputStreamFile::Create(this, request.Pass())),
- next_byte_(0u) {}
- ~TestClientFifoAsync() override {}
-
- private:
- // InputStreamFile::Client|:
- bool RequestData(size_t max_num_bytes,
- mojo::files::Error* error,
- mojo::Array<uint8_t>* data,
- const RequestDataCallback& callback) override {
- PostTaskToMessageLoop([this, callback]() {
- mojo::Array<uint8_t> data;
- data.push_back(next_byte_++);
- callback.Run(mojo::files::Error::OK, data.Pass());
- });
- return false;
- }
- void OnClosed() override {}
-
- std::unique_ptr<InputStreamFile> file_impl_;
- uint8_t next_byte_;
-
- MOJO_DISALLOW_COPY_AND_ASSIGN(TestClientFifoAsync);
-};
-
-void TestFifo(mojo::files::File* file) {
- int expect_callback = 0;
- uint8_t expect_byte = 0;
-
- // Test a couple of zero-byte reads.
- file->Read(0u, 0, mojo::files::Whence::FROM_CURRENT,
- [&expect_callback](mojo::files::Error e, mojo::Array<uint8_t> a) {
- EXPECT_EQ(0, expect_callback++);
- EXPECT_EQ(mojo::files::Error::OK, e);
- EXPECT_EQ(0u, a.size());
- });
- file->Read(0u, 0, mojo::files::Whence::FROM_CURRENT,
- [&expect_callback](mojo::files::Error e, mojo::Array<uint8_t> a) {
- EXPECT_EQ(1, expect_callback++);
- EXPECT_EQ(mojo::files::Error::OK, e);
- EXPECT_EQ(0u, a.size());
- });
-
- // Test a couple of non-zero-byte reads.
- file->Read(100u, 0, mojo::files::Whence::FROM_CURRENT,
- [&expect_callback, &expect_byte](mojo::files::Error e,
- mojo::Array<uint8_t> a) {
- EXPECT_EQ(2, expect_callback++);
- EXPECT_EQ(mojo::files::Error::OK, e);
- EXPECT_EQ(1u, a.size());
- EXPECT_EQ(expect_byte++, a[0]);
- });
- file->Read(100u, 0, mojo::files::Whence::FROM_CURRENT,
- [&expect_callback, &expect_byte](mojo::files::Error e,
- mojo::Array<uint8_t> a) {
- EXPECT_EQ(3, expect_callback++);
- EXPECT_EQ(mojo::files::Error::OK, e);
- EXPECT_EQ(1u, a.size());
- EXPECT_EQ(expect_byte++, a[0]);
- });
- // Throw in a zero-byte read.
- file->Read(0u, 0, mojo::files::Whence::FROM_CURRENT,
- [&expect_callback](mojo::files::Error e, mojo::Array<uint8_t> a) {
- EXPECT_EQ(4, expect_callback++);
- EXPECT_EQ(mojo::files::Error::OK, e);
- EXPECT_EQ(0u, a.size());
- });
- // And a final non-zero-byte read (we'll quit the message loop).
- file->Read(100u, 0, mojo::files::Whence::FROM_CURRENT,
- [&expect_callback, &expect_byte](mojo::files::Error e,
- mojo::Array<uint8_t> a) {
- EXPECT_EQ(5, expect_callback++);
- EXPECT_EQ(mojo::files::Error::OK, e);
- EXPECT_EQ(1u, a.size());
- EXPECT_EQ(expect_byte++, a[0]);
- QuitMessageLoop();
- });
- RunMessageLoop();
-
- // Check that all the callbacks ran.
- EXPECT_EQ(6, expect_callback);
- EXPECT_EQ(3u, expect_byte);
-}
-
-// Tests that if multiple reads are sent, they are completed in FIFO order. This
-// tests the synchronous completion path.
-TEST_F(InputStreamFileTest, FifoSync) {
- mojo::files::FilePtr file;
- TestClientFifoSync client(GetProxy(&file));
- TestFifo(file.get());
-}
-
-// Like |InputStreamFileTest.FifoSync|, but asynchronous.
-TEST_F(InputStreamFileTest, FifoAsync) {
- mojo::files::FilePtr file;
- TestClientFifoAsync client(GetProxy(&file));
- TestFifo(file.get());
-}
-
-} // namespace
-} // namespace files_impl

Powered by Google App Engine
This is Rietveld 408576698