18b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko// Copyright 2015 The Chromium OS Authors. All rights reserved. 28b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko// Use of this source code is governed by a BSD-style license that can be 38b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko// found in the LICENSE file. 48b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko 5fed60b0c640828b320f56293c8bebc43fd2b1da8Alex Vakulenko#ifndef LIBBRILLO_BRILLO_STREAMS_FAKE_STREAM_H_ 6fed60b0c640828b320f56293c8bebc43fd2b1da8Alex Vakulenko#define LIBBRILLO_BRILLO_STREAMS_FAKE_STREAM_H_ 78b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko 88b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko#include <queue> 98b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko#include <string> 108b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko 118b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko#include <base/callback_forward.h> 128b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko#include <base/macros.h> 138b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko#include <base/time/clock.h> 148b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko#include <base/time/time.h> 159ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko#include <brillo/secure_blob.h> 169ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko#include <brillo/streams/stream.h> 178b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko 189ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenkonamespace brillo { 198b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko 208b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko// Fake stream implementation for testing. 218b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko// This class allows to provide data for the stream in tests that can be later 228b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko// read through the Stream interface. Also, data written into the stream can be 238b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko// later inspected and verified. 248b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko// 258b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko// NOTE: This class provides a fake implementation for streams with separate 268b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko// input and output channels. That is, read and write operations do not affect 278b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko// each other. Also, the stream implementation is sequential only (no seeking). 288b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko// Good examples of a use case for fake stream are: 298b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko// - read-only sequential streams (file, memory, pipe, ...) 308b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko// - write-only sequential streams (same as above) 318b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko// - independent channel read-write streams (sockets, ...) 328b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko// 338b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko// For more complex read/write stream test scenarios using a real MemoryStream 348b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko// or temporary FileStream is probably a better choice. 358b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenkoclass FakeStream : public Stream { 368b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko public: 378b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko // Construct a new instance of the fake stream. 388b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko // mode - expected read/write mode supported by the stream. 398b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko // clock - the clock to use to get the current time. 408b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko FakeStream(Stream::AccessMode mode, 418b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko base::Clock* clock); 428b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko 438b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko // Add data packets to the read queue of the stream. 448b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko // Optional |delay| indicates that the data packet should be delayed. 458b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko void AddReadPacketData(base::TimeDelta delay, const void* data, size_t size); 469ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko void AddReadPacketData(base::TimeDelta delay, brillo::Blob data); 478b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko void AddReadPacketString(base::TimeDelta delay, const std::string& data); 488b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko 498b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko // Schedule a read error by adding a special error packet to the queue. 508b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko void QueueReadError(base::TimeDelta delay); 518b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko void QueueReadErrorWithMessage(base::TimeDelta delay, 528b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko const std::string& message); 538b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko 548b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko // Resets read queue and clears any input data buffers. 558b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko void ClearReadQueue(); 568b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko 578b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko // Add expectations for output data packets to be written by the stream. 588b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko // Optional |delay| indicates that the initial write operation for the data in 598b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko // the packet should be delayed. 608b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko // ExpectWritePacketSize just limits the size of output packet while 618b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko // ExpectWritePacketData also validates that the data matches that of |data|. 628b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko void ExpectWritePacketSize(base::TimeDelta delay, size_t data_size); 638b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko void ExpectWritePacketData(base::TimeDelta delay, 648b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko const void* data, 658b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko size_t size); 669ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko void ExpectWritePacketData(base::TimeDelta delay, brillo::Blob data); 678b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko void ExpectWritePacketString(base::TimeDelta delay, const std::string& data); 688b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko 698b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko // Schedule a write error by adding a special error packet to the queue. 708b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko void QueueWriteError(base::TimeDelta delay); 718b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko void QueueWriteErrorWithMessage(base::TimeDelta delay, 728b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko const std::string& message); 738b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko 748b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko // Resets write queue and clears any output data buffers. 758b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko void ClearWriteQueue(); 768b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko 778b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko // Returns the output data accumulated so far by all complete write packets, 788b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko // or explicitly flushed. 799ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko const brillo::Blob& GetFlushedOutputData() const; 808b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko std::string GetFlushedOutputDataAsString() const; 818b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko 829ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko // Overrides from brillo::Stream. 838b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko bool IsOpen() const override { return is_open_; } 848b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko bool CanRead() const override; 858b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko bool CanWrite() const override; 869ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko bool CanSeek() const override { return false; } 878b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko bool CanGetSize() const override { return false; } 888b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko uint64_t GetSize() const override { return 0; } 898b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko bool SetSizeBlocking(uint64_t size, ErrorPtr* error) override; 908b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko uint64_t GetRemainingSize() const override { return 0; } 918b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko uint64_t GetPosition() const override { return 0; } 928b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko bool Seek(int64_t offset, 938b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko Whence whence, 948b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko uint64_t* new_position, 958b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko ErrorPtr* error) override; 968b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko 978b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko bool ReadNonBlocking(void* buffer, 988b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko size_t size_to_read, 998b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko size_t* size_read, 1008b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko bool* end_of_stream, 1018b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko ErrorPtr* error) override; 1028b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko bool WriteNonBlocking(const void* buffer, 1038b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko size_t size_to_write, 1048b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko size_t* size_written, 1058b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko ErrorPtr* error) override; 1068b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko bool FlushBlocking(ErrorPtr* error) override; 1078b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko bool CloseBlocking(ErrorPtr* error) override; 1088b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko bool WaitForData(AccessMode mode, 1098b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko const base::Callback<void(AccessMode)>& callback, 1108b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko ErrorPtr* error) override; 1118b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko bool WaitForDataBlocking(AccessMode in_mode, 1121b79239785bf964fd5f1a607a6ed9c9bbb57a4b1Alex Vakulenko base::TimeDelta timeout, 1138b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko AccessMode* out_mode, 1148b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko ErrorPtr* error) override; 1158b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko 1168b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko private: 1178b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko // Input data packet to be placed on the read queue. 1188b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko struct InputDataPacket { 1199ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko brillo::Blob data; // Data to be read. 1208b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko base::TimeDelta delay_before; // Possible delay for the first read. 1218b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko bool read_error{false}; // Set to true if this packet generates an error. 1228b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko }; 1238b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko 1248b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko // Output data packet to be placed on the write queue. 1258b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko struct OutputDataPacket { 1268b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko size_t expected_size{0}; // Output packet size 1279ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko brillo::Blob data; // Possible data to verify the output with. 1288b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko base::TimeDelta delay_before; // Possible delay for the first write. 1298b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko bool write_error{false}; // Set to true if this packet generates an error. 1308b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko }; 1318b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko 1328b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko // Check if there is any pending read data in the input buffer. 1338b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko bool IsReadBufferEmpty() const; 1348b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko // Pops the next read packet from the queue and sets its data into the 1358b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko // internal input buffer. 1368b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko bool PopReadPacket(); 1378b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko 1388b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko // Check if the output buffer is full. 1398b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko bool IsWriteBufferFull() const; 1408b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko 1418b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko // Moves the current full output buffer into |all_output_data_|, clears the 1428b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko // buffer, and pops the information about the next expected output packet 1438b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko // from the write queue. 1448b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko bool PopWritePacket(); 1458b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko 1468b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko bool is_open_{true}; 1478b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko Stream::AccessMode mode_; 1488b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko base::Clock* clock_; 1498b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko 1508b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko // Internal data for read operations. 1518b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko std::queue<InputDataPacket> incoming_queue_; 1528b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko base::Time delay_input_until_; 1539ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko brillo::Blob input_buffer_; 1548b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko size_t input_ptr_{0}; 1558b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko bool report_read_error_{false}; 1568b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko 1578b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko // Internal data for write operations. 1588b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko std::queue<OutputDataPacket> outgoing_queue_; 1598b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko base::Time delay_output_until_; 1609ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko brillo::Blob output_buffer_; 1619ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko brillo::Blob expected_output_data_; 1628b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko size_t max_output_buffer_size_{0}; 1638b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko bool report_write_error_{false}; 1649ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko brillo::Blob all_output_data_; 1658b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko 1668b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko DISALLOW_COPY_AND_ASSIGN(FakeStream); 1678b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko}; 1688b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko 1699ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko} // namespace brillo 1708b8d60940e09a04bc5c8894779f2d2fc1ac32b7dAlex Vakulenko 171fed60b0c640828b320f56293c8bebc43fd2b1da8Alex Vakulenko#endif // LIBBRILLO_BRILLO_STREAMS_FAKE_STREAM_H_ 172