11e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko// Copyright 2015 The Chromium OS Authors. All rights reserved.
21e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko// Use of this source code is governed by a BSD-style license that can be
31e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko// found in the LICENSE file.
41e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko
59ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko#include <brillo/streams/stream_utils.h>
61e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko
71e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko#include <limits>
81e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko
949fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko#include <base/bind.h>
109ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko#include <brillo/message_loops/fake_message_loop.h>
119ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko#include <brillo/message_loops/message_loop.h>
129ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko#include <brillo/streams/mock_stream.h>
139ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko#include <brillo/streams/stream_errors.h>
1449fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko#include <gmock/gmock.h>
151e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko#include <gtest/gtest.h>
161e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko
1749fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenkousing testing::DoAll;
1849fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenkousing testing::InSequence;
1949fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenkousing testing::Return;
2049fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenkousing testing::StrictMock;
2149fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenkousing testing::_;
2249fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko
2349fb1ce7956110497bd7cad33b3a954faca4b77cAlex VakulenkoACTION_TEMPLATE(InvokeAsyncCallback,
2449fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko                HAS_1_TEMPLATE_PARAMS(int, k),
2549fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko                AND_1_VALUE_PARAMS(size)) {
269ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko  brillo::MessageLoop::current()->PostTask(
2749fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko      FROM_HERE, base::Bind(std::get<k>(args), size));
2849fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko  return true;
2949fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko}
3049fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko
3149fb1ce7956110497bd7cad33b3a954faca4b77cAlex VakulenkoACTION_TEMPLATE(InvokeAsyncCallback,
3249fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko                HAS_1_TEMPLATE_PARAMS(int, k),
3349fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko                AND_0_VALUE_PARAMS()) {
349ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko  brillo::MessageLoop::current()->PostTask(FROM_HERE, std::get<k>(args));
3549fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko  return true;
3649fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko}
3749fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko
3849fb1ce7956110497bd7cad33b3a954faca4b77cAlex VakulenkoACTION_TEMPLATE(InvokeAsyncErrorCallback,
3949fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko                HAS_1_TEMPLATE_PARAMS(int, k),
4049fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko                AND_1_VALUE_PARAMS(code)) {
419ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko  brillo::ErrorPtr error;
429ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko  brillo::Error::AddTo(&error, FROM_HERE, "test", code, "message");
439ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko  brillo::MessageLoop::current()->PostTask(
4449fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko      FROM_HERE, base::Bind(std::get<k>(args), base::Owned(error.release())));
4549fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko  return true;
4649fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko}
4749fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko
489ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenkonamespace brillo {
491e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko
501e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex VakulenkoTEST(StreamUtils, ErrorStreamClosed) {
511e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko  ErrorPtr error;
521e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko  EXPECT_FALSE(stream_utils::ErrorStreamClosed(FROM_HERE, &error));
531e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko  EXPECT_EQ(errors::stream::kDomain, error->GetDomain());
541e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko  EXPECT_EQ(errors::stream::kStreamClosed, error->GetCode());
551e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko  EXPECT_EQ("Stream is closed", error->GetMessage());
561e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko}
571e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko
581e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex VakulenkoTEST(StreamUtils, ErrorOperationNotSupported) {
591e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko  ErrorPtr error;
601e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko  EXPECT_FALSE(stream_utils::ErrorOperationNotSupported(FROM_HERE, &error));
611e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko  EXPECT_EQ(errors::stream::kDomain, error->GetDomain());
621e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko  EXPECT_EQ(errors::stream::kOperationNotSupported, error->GetCode());
631e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko  EXPECT_EQ("Stream operation not supported", error->GetMessage());
641e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko}
651e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko
661e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex VakulenkoTEST(StreamUtils, ErrorReadPastEndOfStream) {
671e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko  ErrorPtr error;
681e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko  EXPECT_FALSE(stream_utils::ErrorReadPastEndOfStream(FROM_HERE, &error));
691e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko  EXPECT_EQ(errors::stream::kDomain, error->GetDomain());
701e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko  EXPECT_EQ(errors::stream::kPartialData, error->GetCode());
711e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko  EXPECT_EQ("Reading past the end of stream", error->GetMessage());
721e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko}
731e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko
741e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex VakulenkoTEST(StreamUtils, CheckInt64Overflow) {
751e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko  const int64_t max_int64 = std::numeric_limits<int64_t>::max();
761e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko  const uint64_t max_uint64 = std::numeric_limits<uint64_t>::max();
771e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko  EXPECT_TRUE(stream_utils::CheckInt64Overflow(FROM_HERE, 0, 0, nullptr));
781e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko  EXPECT_TRUE(stream_utils::CheckInt64Overflow(
791e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko      FROM_HERE, 0, max_int64, nullptr));
801e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko  EXPECT_TRUE(stream_utils::CheckInt64Overflow(
811e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko      FROM_HERE, max_int64, 0, nullptr));
821e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko  EXPECT_TRUE(stream_utils::CheckInt64Overflow(FROM_HERE, 100, -90, nullptr));
831e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko  EXPECT_TRUE(stream_utils::CheckInt64Overflow(
841e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko      FROM_HERE, 1000, -1000, nullptr));
851e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko
861e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko  ErrorPtr error;
871e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko  EXPECT_FALSE(stream_utils::CheckInt64Overflow(FROM_HERE, 100, -101, &error));
881e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko  EXPECT_EQ(errors::stream::kDomain, error->GetDomain());
891e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko  EXPECT_EQ(errors::stream::kInvalidParameter, error->GetCode());
901e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko  EXPECT_EQ("The stream offset value is out of range", error->GetMessage());
911e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko
921e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko  EXPECT_FALSE(stream_utils::CheckInt64Overflow(
931e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko      FROM_HERE, max_int64, 1, nullptr));
941e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko  EXPECT_FALSE(stream_utils::CheckInt64Overflow(
951e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko      FROM_HERE, max_uint64, 0, nullptr));
961e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko  EXPECT_FALSE(stream_utils::CheckInt64Overflow(
971e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko      FROM_HERE, max_uint64, max_int64, nullptr));
981e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko}
991e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko
1001e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex VakulenkoTEST(StreamUtils, CalculateStreamPosition) {
1011e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko  using Whence = Stream::Whence;
1021e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko  const uint64_t current_pos = 1234;
1031e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko  const uint64_t end_pos = 2000;
1041e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko  uint64_t pos = 0;
1051e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko
1061e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko  EXPECT_TRUE(stream_utils::CalculateStreamPosition(
1071e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko      FROM_HERE, 0, Whence::FROM_BEGIN, current_pos, end_pos, &pos, nullptr));
1081e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko  EXPECT_EQ(0u, pos);
1091e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko
1101e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko  EXPECT_TRUE(stream_utils::CalculateStreamPosition(
1111e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko      FROM_HERE, 0, Whence::FROM_CURRENT, current_pos, end_pos, &pos, nullptr));
1121e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko  EXPECT_EQ(current_pos, pos);
1131e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko
1141e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko  EXPECT_TRUE(stream_utils::CalculateStreamPosition(
1151e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko      FROM_HERE, 0, Whence::FROM_END, current_pos, end_pos, &pos, nullptr));
1161e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko  EXPECT_EQ(end_pos, pos);
1171e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko
1181e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko  EXPECT_TRUE(stream_utils::CalculateStreamPosition(
1191e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko      FROM_HERE, 10, Whence::FROM_BEGIN, current_pos, end_pos, &pos, nullptr));
1201e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko  EXPECT_EQ(10u, pos);
1211e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko
1221e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko  EXPECT_TRUE(stream_utils::CalculateStreamPosition(
1231e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko      FROM_HERE, 10, Whence::FROM_CURRENT, current_pos, end_pos, &pos,
1241e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko      nullptr));
1251e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko  EXPECT_EQ(current_pos + 10, pos);
1261e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko
1271e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko  EXPECT_TRUE(stream_utils::CalculateStreamPosition(
1281e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko      FROM_HERE, 10, Whence::FROM_END, current_pos, end_pos, &pos, nullptr));
1291e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko  EXPECT_EQ(end_pos + 10, pos);
1301e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko
1311e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko  EXPECT_TRUE(stream_utils::CalculateStreamPosition(
1321e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko      FROM_HERE, -10, Whence::FROM_CURRENT, current_pos, end_pos, &pos,
1331e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko      nullptr));
1341e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko  EXPECT_EQ(current_pos - 10, pos);
1351e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko
1361e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko  EXPECT_TRUE(stream_utils::CalculateStreamPosition(
1371e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko      FROM_HERE, -10, Whence::FROM_END, current_pos, end_pos, &pos, nullptr));
1381e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko  EXPECT_EQ(end_pos - 10, pos);
1391e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko
1401e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko  ErrorPtr error;
1411e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko  EXPECT_FALSE(stream_utils::CalculateStreamPosition(
1421e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko      FROM_HERE, -1, Whence::FROM_BEGIN, current_pos, end_pos, &pos, &error));
1431e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko  EXPECT_EQ(errors::stream::kInvalidParameter, error->GetCode());
1441e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko  EXPECT_EQ("The stream offset value is out of range", error->GetMessage());
1451e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko
1461e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko  EXPECT_FALSE(stream_utils::CalculateStreamPosition(
1471e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko      FROM_HERE, -1001, Whence::FROM_CURRENT, 1000, end_pos, &pos, nullptr));
1481e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko
1491e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko  const uint64_t max_int64 = std::numeric_limits<int64_t>::max();
1501e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko  EXPECT_FALSE(stream_utils::CalculateStreamPosition(
1511e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko      FROM_HERE, 1, Whence::FROM_CURRENT, max_int64, end_pos, &pos, nullptr));
1521e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko}
1531e582b39cf77c6ec0ed908153b40e3875a30a2e5Alex Vakulenko
15449fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenkoclass CopyStreamDataTest : public testing::Test {
15549fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko public:
15649fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko  void SetUp() override {
15749fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko    fake_loop_.SetAsCurrent();
15849fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko    in_stream_.reset(new StrictMock<MockStream>{});
15949fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko    out_stream_.reset(new StrictMock<MockStream>{});
16049fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko  }
16149fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko
16249fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko  FakeMessageLoop fake_loop_{nullptr};
16349fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko  std::unique_ptr<StrictMock<MockStream>> in_stream_;
16449fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko  std::unique_ptr<StrictMock<MockStream>> out_stream_;
16549fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko  bool succeeded_{false};
16649fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko  bool failed_{false};
16749fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko
16849fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko  void OnSuccess(uint64_t expected,
1692fd46ba1458275cd16b0949675bff70cc8abcdadChristopher Wiley                 StreamPtr /* in_stream */,
1702fd46ba1458275cd16b0949675bff70cc8abcdadChristopher Wiley                 StreamPtr /* out_stream */,
17149fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko                 uint64_t copied) {
17249fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko    EXPECT_EQ(expected, copied);
17349fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko    succeeded_ = true;
17449fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko  }
17549fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko
17649fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko  void OnError(const std::string& expected_error,
1772fd46ba1458275cd16b0949675bff70cc8abcdadChristopher Wiley               StreamPtr /* in_stream */,
1782fd46ba1458275cd16b0949675bff70cc8abcdadChristopher Wiley               StreamPtr /* out_stream */,
17949fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko               const Error* error) {
18049fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko    EXPECT_EQ(expected_error, error->GetCode());
18149fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko    failed_ = true;
18249fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko  }
18349fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko
18449fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko  void ExpectSuccess() {
18549fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko    EXPECT_TRUE(succeeded_);
18649fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko    EXPECT_FALSE(failed_);
18749fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko  }
18849fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko
18949fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko  void ExpectFailure() {
19049fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko    EXPECT_FALSE(succeeded_);
19149fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko    EXPECT_TRUE(failed_);
19249fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko  }
19349fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko};
19449fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko
19549fb1ce7956110497bd7cad33b3a954faca4b77cAlex VakulenkoTEST_F(CopyStreamDataTest, CopyAllAtOnce) {
19649fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko  {
19749fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko    InSequence seq;
19849fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko    EXPECT_CALL(*in_stream_, ReadAsync(_, 100, _, _, _))
19949fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko        .WillOnce(InvokeAsyncCallback<2>(100));
20049fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko    EXPECT_CALL(*out_stream_, WriteAllAsync(_, 100, _, _, _))
20149fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko        .WillOnce(InvokeAsyncCallback<2>());
20249fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko  }
20349fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko  stream_utils::CopyData(
20449fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko      std::move(in_stream_), std::move(out_stream_), 100, 4096,
20549fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko      base::Bind(&CopyStreamDataTest::OnSuccess, base::Unretained(this), 100),
20649fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko      base::Bind(&CopyStreamDataTest::OnError, base::Unretained(this), ""));
20749fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko  fake_loop_.Run();
20849fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko  ExpectSuccess();
20949fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko}
21049fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko
21149fb1ce7956110497bd7cad33b3a954faca4b77cAlex VakulenkoTEST_F(CopyStreamDataTest, CopyInBlocks) {
21249fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko  {
21349fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko    InSequence seq;
21449fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko    EXPECT_CALL(*in_stream_, ReadAsync(_, 100, _, _, _))
21549fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko        .WillOnce(InvokeAsyncCallback<2>(60));
21649fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko    EXPECT_CALL(*out_stream_, WriteAllAsync(_, 60, _, _, _))
21749fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko        .WillOnce(InvokeAsyncCallback<2>());
21849fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko    EXPECT_CALL(*in_stream_, ReadAsync(_, 40, _, _, _))
21949fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko        .WillOnce(InvokeAsyncCallback<2>(40));
22049fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko    EXPECT_CALL(*out_stream_, WriteAllAsync(_, 40, _, _, _))
22149fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko        .WillOnce(InvokeAsyncCallback<2>());
22249fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko  }
22349fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko  stream_utils::CopyData(
22449fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko      std::move(in_stream_), std::move(out_stream_), 100, 4096,
22549fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko      base::Bind(&CopyStreamDataTest::OnSuccess, base::Unretained(this), 100),
22649fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko      base::Bind(&CopyStreamDataTest::OnError, base::Unretained(this), ""));
22749fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko  fake_loop_.Run();
22849fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko  ExpectSuccess();
22949fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko}
23049fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko
23149fb1ce7956110497bd7cad33b3a954faca4b77cAlex VakulenkoTEST_F(CopyStreamDataTest, CopyTillEndOfStream) {
23249fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko  {
23349fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko    InSequence seq;
23449fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko    EXPECT_CALL(*in_stream_, ReadAsync(_, 100, _, _, _))
23549fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko        .WillOnce(InvokeAsyncCallback<2>(60));
23649fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko    EXPECT_CALL(*out_stream_, WriteAllAsync(_, 60, _, _, _))
23749fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko        .WillOnce(InvokeAsyncCallback<2>());
23849fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko    EXPECT_CALL(*in_stream_, ReadAsync(_, 40, _, _, _))
23949fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko        .WillOnce(InvokeAsyncCallback<2>(0));
24049fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko  }
24149fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko  stream_utils::CopyData(
24249fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko      std::move(in_stream_), std::move(out_stream_), 100, 4096,
24349fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko      base::Bind(&CopyStreamDataTest::OnSuccess, base::Unretained(this), 60),
24449fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko      base::Bind(&CopyStreamDataTest::OnError, base::Unretained(this), ""));
24549fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko  fake_loop_.Run();
24649fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko  ExpectSuccess();
24749fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko}
24849fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko
24949fb1ce7956110497bd7cad33b3a954faca4b77cAlex VakulenkoTEST_F(CopyStreamDataTest, CopyInSmallBlocks) {
25049fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko  {
25149fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko    InSequence seq;
25249fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko    EXPECT_CALL(*in_stream_, ReadAsync(_, 60, _, _, _))
25349fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko        .WillOnce(InvokeAsyncCallback<2>(60));
25449fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko    EXPECT_CALL(*out_stream_, WriteAllAsync(_, 60, _, _, _))
25549fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko        .WillOnce(InvokeAsyncCallback<2>());
25649fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko    EXPECT_CALL(*in_stream_, ReadAsync(_, 40, _, _, _))
25749fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko        .WillOnce(InvokeAsyncCallback<2>(40));
25849fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko    EXPECT_CALL(*out_stream_, WriteAllAsync(_, 40, _, _, _))
25949fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko        .WillOnce(InvokeAsyncCallback<2>());
26049fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko  }
26149fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko  stream_utils::CopyData(
26249fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko      std::move(in_stream_), std::move(out_stream_), 100, 60,
26349fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko      base::Bind(&CopyStreamDataTest::OnSuccess, base::Unretained(this), 100),
26449fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko      base::Bind(&CopyStreamDataTest::OnError, base::Unretained(this), ""));
26549fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko  fake_loop_.Run();
26649fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko  ExpectSuccess();
26749fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko}
26849fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko
26949fb1ce7956110497bd7cad33b3a954faca4b77cAlex VakulenkoTEST_F(CopyStreamDataTest, ErrorRead) {
27049fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko  {
27149fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko    InSequence seq;
27249fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko    EXPECT_CALL(*in_stream_, ReadAsync(_, 60, _, _, _))
27349fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko        .WillOnce(InvokeAsyncErrorCallback<3>("read"));
27449fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko  }
27549fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko  stream_utils::CopyData(
27649fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko      std::move(in_stream_), std::move(out_stream_), 100, 60,
27749fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko      base::Bind(&CopyStreamDataTest::OnSuccess, base::Unretained(this), 0),
27849fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko      base::Bind(&CopyStreamDataTest::OnError, base::Unretained(this), "read"));
27949fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko  fake_loop_.Run();
28049fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko  ExpectFailure();
28149fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko}
28249fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko
28349fb1ce7956110497bd7cad33b3a954faca4b77cAlex VakulenkoTEST_F(CopyStreamDataTest, ErrorWrite) {
28449fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko  {
28549fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko    InSequence seq;
28649fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko    EXPECT_CALL(*in_stream_, ReadAsync(_, 60, _, _, _))
28749fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko        .WillOnce(InvokeAsyncCallback<2>(60));
28849fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko    EXPECT_CALL(*out_stream_, WriteAllAsync(_, 60, _, _, _))
28949fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko        .WillOnce(InvokeAsyncErrorCallback<3>("write"));
29049fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko  }
29149fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko  stream_utils::CopyData(
29249fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko      std::move(in_stream_), std::move(out_stream_), 100, 60,
29349fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko      base::Bind(&CopyStreamDataTest::OnSuccess, base::Unretained(this), 0),
29449fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko      base::Bind(&CopyStreamDataTest::OnError, base::Unretained(this),
29549fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko                 "write"));
29649fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko  fake_loop_.Run();
29749fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko  ExpectFailure();
29849fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko}
29949fb1ce7956110497bd7cad33b3a954faca4b77cAlex Vakulenko
3009ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko}  // namespace brillo
301