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