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#include <brillo/streams/openssl_stream_bio.h>
6
7#include <memory>
8#include <openssl/bio.h>
9
10#include <brillo/streams/mock_stream.h>
11#include <gmock/gmock.h>
12#include <gtest/gtest.h>
13
14using testing::DoAll;
15using testing::Return;
16using testing::SetArgPointee;
17using testing::StrictMock;
18using testing::_;
19
20namespace brillo {
21
22class StreamBIOTest : public testing::Test {
23 public:
24  void SetUp() override {
25    stream_.reset(new StrictMock<MockStream>{});
26    bio_ = BIO_new_stream(stream_.get());
27  }
28
29  void TearDown() override {
30    BIO_free(bio_);
31    bio_ = nullptr;
32    stream_.reset();
33  }
34
35  std::unique_ptr<StrictMock<MockStream>> stream_;
36  BIO* bio_{nullptr};
37};
38
39TEST_F(StreamBIOTest, ReadFull) {
40  char buffer[10];
41  EXPECT_CALL(*stream_, ReadNonBlocking(buffer, 10, _, _, _))
42      .WillOnce(DoAll(SetArgPointee<2>(10),
43                      SetArgPointee<3>(false),
44                      Return(true)));
45  EXPECT_EQ(10, BIO_read(bio_, buffer, sizeof(buffer)));
46}
47
48TEST_F(StreamBIOTest, ReadPartial) {
49  char buffer[10];
50  EXPECT_CALL(*stream_, ReadNonBlocking(buffer, 10, _, _, _))
51      .WillOnce(DoAll(SetArgPointee<2>(3),
52                      SetArgPointee<3>(false),
53                      Return(true)));
54  EXPECT_EQ(3, BIO_read(bio_, buffer, sizeof(buffer)));
55}
56
57TEST_F(StreamBIOTest, ReadWouldBlock) {
58  char buffer[10];
59  EXPECT_CALL(*stream_, ReadNonBlocking(buffer, 10, _, _, _))
60      .WillOnce(DoAll(SetArgPointee<2>(0),
61                      SetArgPointee<3>(false),
62                      Return(true)));
63  EXPECT_EQ(-1, BIO_read(bio_, buffer, sizeof(buffer)));
64  EXPECT_TRUE(BIO_should_retry(bio_));
65}
66
67TEST_F(StreamBIOTest, ReadEndOfStream) {
68  char buffer[10];
69  EXPECT_CALL(*stream_, ReadNonBlocking(buffer, 10, _, _, _))
70      .WillOnce(DoAll(SetArgPointee<2>(0),
71                      SetArgPointee<3>(true),
72                      Return(true)));
73  EXPECT_EQ(0, BIO_read(bio_, buffer, sizeof(buffer)));
74  EXPECT_FALSE(BIO_should_retry(bio_));
75}
76
77TEST_F(StreamBIOTest, ReadError) {
78  char buffer[10];
79  EXPECT_CALL(*stream_, ReadNonBlocking(buffer, 10, _, _, _))
80      .WillOnce(Return(false));
81  EXPECT_EQ(-1, BIO_read(bio_, buffer, sizeof(buffer)));
82  EXPECT_FALSE(BIO_should_retry(bio_));
83}
84
85TEST_F(StreamBIOTest, WriteFull) {
86  char buffer[10] = {};
87  EXPECT_CALL(*stream_, WriteNonBlocking(buffer, 10, _, _))
88      .WillOnce(DoAll(SetArgPointee<2>(10), Return(true)));
89  EXPECT_EQ(10, BIO_write(bio_, buffer, sizeof(buffer)));
90}
91
92TEST_F(StreamBIOTest, WritePartial) {
93  char buffer[10] = {};
94  EXPECT_CALL(*stream_, WriteNonBlocking(buffer, 10, _, _))
95      .WillOnce(DoAll(SetArgPointee<2>(3), Return(true)));
96  EXPECT_EQ(3, BIO_write(bio_, buffer, sizeof(buffer)));
97}
98
99TEST_F(StreamBIOTest, WriteWouldBlock) {
100  char buffer[10] = {};
101  EXPECT_CALL(*stream_, WriteNonBlocking(buffer, 10, _, _))
102      .WillOnce(DoAll(SetArgPointee<2>(0), Return(true)));
103  EXPECT_EQ(-1, BIO_write(bio_, buffer, sizeof(buffer)));
104  EXPECT_TRUE(BIO_should_retry(bio_));
105}
106
107TEST_F(StreamBIOTest, WriteError) {
108  char buffer[10] = {};
109  EXPECT_CALL(*stream_, WriteNonBlocking(buffer, 10, _, _))
110      .WillOnce(Return(false));
111  EXPECT_EQ(-1, BIO_write(bio_, buffer, sizeof(buffer)));
112  EXPECT_FALSE(BIO_should_retry(bio_));
113}
114
115TEST_F(StreamBIOTest, FlushSuccess) {
116  EXPECT_CALL(*stream_, FlushBlocking(_)).WillOnce(Return(true));
117  EXPECT_EQ(1, BIO_flush(bio_));
118}
119
120TEST_F(StreamBIOTest, FlushError) {
121  EXPECT_CALL(*stream_, FlushBlocking(_)).WillOnce(Return(false));
122  EXPECT_EQ(0, BIO_flush(bio_));
123}
124
125}  // namespace brillo
126