103f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo// Copyright 2015 The Chromium OS Authors. All rights reserved. 203f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo// Use of this source code is governed by a BSD-style license that can be 303f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo// found in the LICENSE file. 403f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo 5ddf9db52938e67d4dcbf7c4f159b094eaddbabebAlex Deymo#include "bsdiff/extents_file.h" 603f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo 703f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo#include <gtest/gtest.h> 803f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo#include <gmock/gmock.h> 903f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo#include <string> 1003f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo#include <vector> 1103f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo 12ddf9db52938e67d4dcbf7c4f159b094eaddbabebAlex Deymo#include "bsdiff/file_interface.h" 1303f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo 1403f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymousing std::string; 1503f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymousing std::vector; 1603f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymousing testing::AnyNumber; 1703f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymousing testing::StrictMock; 1803f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymousing testing::Return; 1903f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymousing testing::InSequence; 2003f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymousing testing::_; 2103f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo 2203f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymonamespace bsdiff { 2303f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo 2403f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo// Mock class for the underlying file interface. 2503f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymoclass MockFile : public FileInterface { 2603f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo public: 2703f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo MOCK_METHOD3(Read, bool(void*, size_t, size_t*)); 2803f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo MOCK_METHOD3(Write, bool(const void*, size_t, size_t*)); 2903f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo MOCK_METHOD1(Seek, bool(off_t)); 3003f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo MOCK_METHOD0(Close, bool()); 31daf35169e3fa51cc9ff468f12acd435a9b075266Alex Deymo MOCK_METHOD1(GetSize, bool(uint64_t*)); 3203f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo}; 3303f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo 3403f1debab429e673ba5e9e317c5a04e36e850cefAlex DeymoACTION(SucceedIO) { 3503f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo // Check that arg1 (count) can be converted 3603f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo *arg2 = arg1; 3703f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo return true; 3803f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo} 3903f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo 4003f1debab429e673ba5e9e317c5a04e36e850cefAlex DeymoACTION_P(SucceedPartialIO, bytes) { 4103f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo // Check that arg1 (count) can be converted 4203f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo *arg2 = bytes; 4303f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo return true; 4403f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo} 4503f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo 4603f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymoclass ExtentsFileTest : public testing::Test { 4703f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo protected: 4803f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo void SetUp() { 4903f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo mock_file_ = new StrictMock<MockFile>(); 5003f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo mock_file_ptr_.reset(mock_file_); 5103f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo // The destructor of the ExtentsFile will call Close once. 5203f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo EXPECT_CALL(*mock_file_, Close()).WillOnce(Return(true)); 5303f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo } 5403f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo 5503f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo // Pointer to the underlying File owned by the ExtentsFile under test. This 5603f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo // pointer is invalidated whenever the ExtentsFile is destroyed. 5703f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo StrictMock<MockFile>* mock_file_; 5803f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo std::unique_ptr<FileInterface> mock_file_ptr_; 5903f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo}; 6003f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo 6103f1debab429e673ba5e9e317c5a04e36e850cefAlex DeymoTEST_F(ExtentsFileTest, DestructorCloses) { 6203f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo ExtentsFile file(std::move(mock_file_ptr_), {}); 6303f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo} 6403f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo 6503f1debab429e673ba5e9e317c5a04e36e850cefAlex DeymoTEST_F(ExtentsFileTest, CloseIsForwarded) { 6603f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo ExtentsFile file(std::move(mock_file_ptr_), {}); 6703f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo EXPECT_TRUE(file.Close()); 6803f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo EXPECT_CALL(*mock_file_, Close()).WillOnce(Return(false)); 6903f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo} 7003f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo 71daf35169e3fa51cc9ff468f12acd435a9b075266Alex DeymoTEST_F(ExtentsFileTest, GetSizeSumExtents) { 72daf35169e3fa51cc9ff468f12acd435a9b075266Alex Deymo ExtentsFile file(std::move(mock_file_ptr_), 73daf35169e3fa51cc9ff468f12acd435a9b075266Alex Deymo {ex_t{10, 5}, ex_t{20, 5}, {25, 2}}); 74daf35169e3fa51cc9ff468f12acd435a9b075266Alex Deymo uint64_t size; 75daf35169e3fa51cc9ff468f12acd435a9b075266Alex Deymo EXPECT_TRUE(file.GetSize(&size)); 76daf35169e3fa51cc9ff468f12acd435a9b075266Alex Deymo EXPECT_EQ(12U, size); 77daf35169e3fa51cc9ff468f12acd435a9b075266Alex Deymo} 78daf35169e3fa51cc9ff468f12acd435a9b075266Alex Deymo 7903f1debab429e673ba5e9e317c5a04e36e850cefAlex DeymoTEST_F(ExtentsFileTest, SeekToRightOffsets) { 8003f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo ExtentsFile file(std::move(mock_file_ptr_), 8103f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo {ex_t{10, 5}, ex_t{20, 5}, {25, 2}}); 8203f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo vector<std::pair<off_t, off_t>> tests = { 8303f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo // Seek to the beginning of the file. 8403f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo {0, 10}, 8503f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo // Seek to the middle of a extent. 8603f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo {3, 13}, 8703f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo {11, 26}, 8803f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo // Seek to the extent boundary. 8903f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo {5, 20}, // Seeks to the first byte in the second extent. 9003f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo {10, 25}, 9103f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo }; 9203f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo for (const auto& offset_pair : tests) { 9303f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo // We use a failing Read() call to trigger the actual seek call to the 9403f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo // underlying file. 9503f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo EXPECT_CALL(*mock_file_, Seek(offset_pair.second)).WillOnce(Return(true)); 9603f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo EXPECT_CALL(*mock_file_, Read(_, _, _)).WillOnce(Return(false)); 9703f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo 9803f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo EXPECT_TRUE(file.Seek(offset_pair.first)); 9903f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo size_t bytes_read; 10003f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo EXPECT_FALSE(file.Read(nullptr, 1, &bytes_read)); 10103f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo } 10203f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo 10303f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo // Seeking to the end of the file is ok, but not past it. 10403f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo EXPECT_TRUE(file.Seek(12)); 10503f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo EXPECT_FALSE(file.Seek(13)); 10603f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo 10703f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo EXPECT_FALSE(file.Seek(-1)); 10803f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo} 10903f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo 11003f1debab429e673ba5e9e317c5a04e36e850cefAlex DeymoTEST_F(ExtentsFileTest, ReadAcrossAllExtents) { 11103f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo ExtentsFile file(std::move(mock_file_ptr_), 11203f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo {ex_t{10, 5}, ex_t{20, 7}, {27, 3}}); 11303f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo InSequence s; 11403f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo char* buf = reinterpret_cast<char*>(0x1234); 11503f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo 11603f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo EXPECT_CALL(*mock_file_, Seek(10)).WillOnce(Return(true)); 11703f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo EXPECT_CALL(*mock_file_, Read(buf, 5, _)).WillOnce(SucceedIO()); 11803f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo EXPECT_CALL(*mock_file_, Seek(20)).WillOnce(Return(true)); 11903f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo EXPECT_CALL(*mock_file_, Read(buf + 5, 7, _)).WillOnce(SucceedIO()); 12003f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo EXPECT_CALL(*mock_file_, Seek(27)).WillOnce(Return(true)); 12103f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo EXPECT_CALL(*mock_file_, Read(buf + 12, 3, _)).WillOnce(SucceedIO()); 12203f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo 12303f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo // FileExtents::Read() should read everything in one shot, by reading all 12403f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo // the little chunks. Note that it doesn't attempt to read past the end of the 12503f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo // FileExtents. 12603f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo size_t bytes_read = 0; 12703f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo EXPECT_TRUE(file.Read(buf, 100, &bytes_read)); 12803f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo EXPECT_EQ(15U, bytes_read); 12903f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo} 13003f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo 131f822e6c031de113b790d622b0cd0e98f7d49ea5eSen JiangTEST_F(ExtentsFileTest, MultiReadAcrossAllExtents) { 132f822e6c031de113b790d622b0cd0e98f7d49ea5eSen Jiang ExtentsFile file(std::move(mock_file_ptr_), 133f822e6c031de113b790d622b0cd0e98f7d49ea5eSen Jiang {ex_t{10, 5}, ex_t{20, 7}, {27, 3}}); 134f822e6c031de113b790d622b0cd0e98f7d49ea5eSen Jiang InSequence s; 135f822e6c031de113b790d622b0cd0e98f7d49ea5eSen Jiang char* buf = reinterpret_cast<char*>(0x1234); 136f822e6c031de113b790d622b0cd0e98f7d49ea5eSen Jiang 137f822e6c031de113b790d622b0cd0e98f7d49ea5eSen Jiang EXPECT_CALL(*mock_file_, Seek(10)).WillOnce(Return(true)); 138f822e6c031de113b790d622b0cd0e98f7d49ea5eSen Jiang EXPECT_CALL(*mock_file_, Read(buf, 2, _)).WillOnce(SucceedIO()); 139f822e6c031de113b790d622b0cd0e98f7d49ea5eSen Jiang EXPECT_CALL(*mock_file_, Seek(12)).WillOnce(Return(true)); 140f822e6c031de113b790d622b0cd0e98f7d49ea5eSen Jiang EXPECT_CALL(*mock_file_, Read(buf, 3, _)).WillOnce(SucceedIO()); 141f822e6c031de113b790d622b0cd0e98f7d49ea5eSen Jiang EXPECT_CALL(*mock_file_, Seek(20)).WillOnce(Return(true)); 142f822e6c031de113b790d622b0cd0e98f7d49ea5eSen Jiang EXPECT_CALL(*mock_file_, Read(buf + 3, 5, _)).WillOnce(SucceedIO()); 143f822e6c031de113b790d622b0cd0e98f7d49ea5eSen Jiang EXPECT_CALL(*mock_file_, Seek(25)).WillOnce(Return(true)); 144f822e6c031de113b790d622b0cd0e98f7d49ea5eSen Jiang EXPECT_CALL(*mock_file_, Read(buf, 2, _)).WillOnce(SucceedIO()); 145f822e6c031de113b790d622b0cd0e98f7d49ea5eSen Jiang EXPECT_CALL(*mock_file_, Seek(27)).WillOnce(Return(true)); 146f822e6c031de113b790d622b0cd0e98f7d49ea5eSen Jiang EXPECT_CALL(*mock_file_, Read(buf + 2, 3, _)).WillOnce(SucceedIO()); 147f822e6c031de113b790d622b0cd0e98f7d49ea5eSen Jiang 148f822e6c031de113b790d622b0cd0e98f7d49ea5eSen Jiang size_t bytes_read = 0; 149f822e6c031de113b790d622b0cd0e98f7d49ea5eSen Jiang EXPECT_TRUE(file.Read(buf, 2, &bytes_read)); 150f822e6c031de113b790d622b0cd0e98f7d49ea5eSen Jiang EXPECT_EQ(2U, bytes_read); 151f822e6c031de113b790d622b0cd0e98f7d49ea5eSen Jiang EXPECT_TRUE(file.Read(buf, 8, &bytes_read)); 152f822e6c031de113b790d622b0cd0e98f7d49ea5eSen Jiang EXPECT_EQ(8U, bytes_read); 153f822e6c031de113b790d622b0cd0e98f7d49ea5eSen Jiang EXPECT_TRUE(file.Read(buf, 100, &bytes_read)); 154f822e6c031de113b790d622b0cd0e98f7d49ea5eSen Jiang EXPECT_EQ(5U, bytes_read); 155f822e6c031de113b790d622b0cd0e98f7d49ea5eSen Jiang} 156f822e6c031de113b790d622b0cd0e98f7d49ea5eSen Jiang 15703f1debab429e673ba5e9e317c5a04e36e850cefAlex DeymoTEST_F(ExtentsFileTest, ReadSmallChunks) { 15803f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo ExtentsFile file(std::move(mock_file_ptr_), {ex_t{10, 1}, ex_t{20, 10}}); 15903f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo InSequence s; 16003f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo char* buf = reinterpret_cast<char*>(0x1234); 16103f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo 16203f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo EXPECT_CALL(*mock_file_, Seek(10)).WillOnce(Return(true)); 16303f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo EXPECT_CALL(*mock_file_, Read(buf, 1, _)).WillOnce(SucceedIO()); 16403f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo EXPECT_CALL(*mock_file_, Seek(20)).WillOnce(Return(true)); 16503f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo // We expect to read only part of the second extent. 16603f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo EXPECT_CALL(*mock_file_, Read(buf + 1, 1, _)).WillOnce(SucceedIO()); 16703f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo 16803f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo size_t bytes_read = 0; 16903f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo EXPECT_TRUE(file.Read(buf, 2, &bytes_read)); 17003f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo EXPECT_EQ(2U, bytes_read); 17103f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo} 17203f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo 17303f1debab429e673ba5e9e317c5a04e36e850cefAlex DeymoTEST_F(ExtentsFileTest, ReadFailureFails) { 17403f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo ExtentsFile file(std::move(mock_file_ptr_), {ex_t{10, 1}, ex_t{20, 10}}); 17503f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo EXPECT_CALL(*mock_file_, Seek(_)) 17603f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo .Times(AnyNumber()) 17703f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo .WillRepeatedly(Return(true)); 17803f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo EXPECT_CALL(*mock_file_, Read(_, 1, _)).WillOnce(SucceedIO()); 17903f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo // A second read that fails will succeed if there was partial data read. 18003f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo EXPECT_CALL(*mock_file_, Read(_, 10, _)).WillOnce(Return(false)); 18103f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo 18203f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo size_t bytes_read = 0; 18303f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo EXPECT_TRUE(file.Read(nullptr, 100, &bytes_read)); 18403f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo EXPECT_EQ(1U, bytes_read); 18503f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo} 18603f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo 18703f1debab429e673ba5e9e317c5a04e36e850cefAlex DeymoTEST_F(ExtentsFileTest, ReadFails) { 18803f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo ExtentsFile file(std::move(mock_file_ptr_), {ex_t{10, 1}, ex_t{20, 10}}); 18903f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo EXPECT_CALL(*mock_file_, Seek(10)).WillOnce(Return(true)); 19003f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo EXPECT_CALL(*mock_file_, Read(_, 1, _)).WillOnce(Return(false)); 19103f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo size_t bytes_read; 19203f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo EXPECT_FALSE(file.Read(nullptr, 1, &bytes_read)); 19303f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo} 19403f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo 19503f1debab429e673ba5e9e317c5a04e36e850cefAlex DeymoTEST_F(ExtentsFileTest, ReadPartialReadsAndEOF) { 19603f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo ExtentsFile file(std::move(mock_file_ptr_), {ex_t{10, 1}, ex_t{20, 10}}); 19703f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo EXPECT_CALL(*mock_file_, Seek(_)) 19803f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo .Times(AnyNumber()) 19903f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo .WillRepeatedly(Return(true)); 20003f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo char* buf = reinterpret_cast<char*>(0x1234); 20103f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo InSequence s; 20203f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo EXPECT_CALL(*mock_file_, Read(buf, 1, _)).WillOnce(SucceedIO()); 20303f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo EXPECT_CALL(*mock_file_, Read(buf + 1, _, _)).WillOnce(SucceedPartialIO(3)); 20403f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo EXPECT_CALL(*mock_file_, Read(buf + 4, _, _)).WillOnce(SucceedPartialIO(0)); 20503f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo 20603f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo size_t bytes_read = 0; 20703f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo EXPECT_TRUE(file.Read(buf, 100, &bytes_read)); 20803f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo EXPECT_EQ(4U, bytes_read); 20903f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo} 21003f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo 21103f1debab429e673ba5e9e317c5a04e36e850cefAlex Deymo} // namespace bsdiff 212