1 // Copyright 2015 The Chromium OS Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef LIBBRILLO_BRILLO_STREAMS_FAKE_STREAM_H_ 6 #define LIBBRILLO_BRILLO_STREAMS_FAKE_STREAM_H_ 7 8 #include <queue> 9 #include <string> 10 11 #include <base/callback_forward.h> 12 #include <base/macros.h> 13 #include <base/time/clock.h> 14 #include <base/time/time.h> 15 #include <brillo/secure_blob.h> 16 #include <brillo/streams/stream.h> 17 18 namespace brillo { 19 20 // Fake stream implementation for testing. 21 // This class allows to provide data for the stream in tests that can be later 22 // read through the Stream interface. Also, data written into the stream can be 23 // later inspected and verified. 24 // 25 // NOTE: This class provides a fake implementation for streams with separate 26 // input and output channels. That is, read and write operations do not affect 27 // each other. Also, the stream implementation is sequential only (no seeking). 28 // Good examples of a use case for fake stream are: 29 // - read-only sequential streams (file, memory, pipe, ...) 30 // - write-only sequential streams (same as above) 31 // - independent channel read-write streams (sockets, ...) 32 // 33 // For more complex read/write stream test scenarios using a real MemoryStream 34 // or temporary FileStream is probably a better choice. 35 class FakeStream : public Stream { 36 public: 37 // Construct a new instance of the fake stream. 38 // mode - expected read/write mode supported by the stream. 39 // clock - the clock to use to get the current time. 40 FakeStream(Stream::AccessMode mode, 41 base::Clock* clock); 42 43 // Add data packets to the read queue of the stream. 44 // Optional |delay| indicates that the data packet should be delayed. 45 void AddReadPacketData(base::TimeDelta delay, const void* data, size_t size); 46 void AddReadPacketData(base::TimeDelta delay, brillo::Blob data); 47 void AddReadPacketString(base::TimeDelta delay, const std::string& data); 48 49 // Schedule a read error by adding a special error packet to the queue. 50 void QueueReadError(base::TimeDelta delay); 51 void QueueReadErrorWithMessage(base::TimeDelta delay, 52 const std::string& message); 53 54 // Resets read queue and clears any input data buffers. 55 void ClearReadQueue(); 56 57 // Add expectations for output data packets to be written by the stream. 58 // Optional |delay| indicates that the initial write operation for the data in 59 // the packet should be delayed. 60 // ExpectWritePacketSize just limits the size of output packet while 61 // ExpectWritePacketData also validates that the data matches that of |data|. 62 void ExpectWritePacketSize(base::TimeDelta delay, size_t data_size); 63 void ExpectWritePacketData(base::TimeDelta delay, 64 const void* data, 65 size_t size); 66 void ExpectWritePacketData(base::TimeDelta delay, brillo::Blob data); 67 void ExpectWritePacketString(base::TimeDelta delay, const std::string& data); 68 69 // Schedule a write error by adding a special error packet to the queue. 70 void QueueWriteError(base::TimeDelta delay); 71 void QueueWriteErrorWithMessage(base::TimeDelta delay, 72 const std::string& message); 73 74 // Resets write queue and clears any output data buffers. 75 void ClearWriteQueue(); 76 77 // Returns the output data accumulated so far by all complete write packets, 78 // or explicitly flushed. 79 const brillo::Blob& GetFlushedOutputData() const; 80 std::string GetFlushedOutputDataAsString() const; 81 82 // Overrides from brillo::Stream. 83 bool IsOpen() const override { return is_open_; } 84 bool CanRead() const override; 85 bool CanWrite() const override; 86 bool CanSeek() const override { return false; } 87 bool CanGetSize() const override { return false; } 88 uint64_t GetSize() const override { return 0; } 89 bool SetSizeBlocking(uint64_t size, ErrorPtr* error) override; 90 uint64_t GetRemainingSize() const override { return 0; } 91 uint64_t GetPosition() const override { return 0; } 92 bool Seek(int64_t offset, 93 Whence whence, 94 uint64_t* new_position, 95 ErrorPtr* error) override; 96 97 bool ReadNonBlocking(void* buffer, 98 size_t size_to_read, 99 size_t* size_read, 100 bool* end_of_stream, 101 ErrorPtr* error) override; 102 bool WriteNonBlocking(const void* buffer, 103 size_t size_to_write, 104 size_t* size_written, 105 ErrorPtr* error) override; 106 bool FlushBlocking(ErrorPtr* error) override; 107 bool CloseBlocking(ErrorPtr* error) override; 108 bool WaitForData(AccessMode mode, 109 const base::Callback<void(AccessMode)>& callback, 110 ErrorPtr* error) override; 111 bool WaitForDataBlocking(AccessMode in_mode, 112 base::TimeDelta timeout, 113 AccessMode* out_mode, 114 ErrorPtr* error) override; 115 116 private: 117 // Input data packet to be placed on the read queue. 118 struct InputDataPacket { 119 brillo::Blob data; // Data to be read. 120 base::TimeDelta delay_before; // Possible delay for the first read. 121 bool read_error{false}; // Set to true if this packet generates an error. 122 }; 123 124 // Output data packet to be placed on the write queue. 125 struct OutputDataPacket { 126 size_t expected_size{0}; // Output packet size 127 brillo::Blob data; // Possible data to verify the output with. 128 base::TimeDelta delay_before; // Possible delay for the first write. 129 bool write_error{false}; // Set to true if this packet generates an error. 130 }; 131 132 // Check if there is any pending read data in the input buffer. 133 bool IsReadBufferEmpty() const; 134 // Pops the next read packet from the queue and sets its data into the 135 // internal input buffer. 136 bool PopReadPacket(); 137 138 // Check if the output buffer is full. 139 bool IsWriteBufferFull() const; 140 141 // Moves the current full output buffer into |all_output_data_|, clears the 142 // buffer, and pops the information about the next expected output packet 143 // from the write queue. 144 bool PopWritePacket(); 145 146 bool is_open_{true}; 147 Stream::AccessMode mode_; 148 base::Clock* clock_; 149 150 // Internal data for read operations. 151 std::queue<InputDataPacket> incoming_queue_; 152 base::Time delay_input_until_; 153 brillo::Blob input_buffer_; 154 size_t input_ptr_{0}; 155 bool report_read_error_{false}; 156 157 // Internal data for write operations. 158 std::queue<OutputDataPacket> outgoing_queue_; 159 base::Time delay_output_until_; 160 brillo::Blob output_buffer_; 161 brillo::Blob expected_output_data_; 162 size_t max_output_buffer_size_{0}; 163 bool report_write_error_{false}; 164 brillo::Blob all_output_data_; 165 166 DISALLOW_COPY_AND_ASSIGN(FakeStream); 167 }; 168 169 } // namespace brillo 170 171 #endif // LIBBRILLO_BRILLO_STREAMS_FAKE_STREAM_H_ 172