xref: /aosp_15_r20/external/tink/cc/internal/test_random_access_stream_test.cc (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
1 // Copyright 2023 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 ///////////////////////////////////////////////////////////////////////////////
16 #include "tink/internal/test_random_access_stream.h"
17 
18 #include <memory>
19 #include <string>
20 #include <utility>
21 
22 #include "gmock/gmock.h"
23 #include "gtest/gtest.h"
24 #include "absl/status/status.h"
25 #include "tink/subtle/random.h"
26 #include "tink/util/buffer.h"
27 #include "tink/util/status.h"
28 #include "tink/util/test_matchers.h"
29 
30 namespace crypto {
31 namespace tink {
32 namespace internal {
33 namespace {
34 
35 using ::crypto::tink::test::StatusIs;
36 
TEST(TestRandomAccessStreamTest,ReadAllSucceeds)37 TEST(TestRandomAccessStreamTest, ReadAllSucceeds) {
38   const int buffer_size = 4 * 1024;
39   const int stream_size = 100 * 1024;
40   std::string stream_content = subtle::Random::GetRandomBytes(stream_size);
41   auto rand_access_stream =
42       std::make_unique<TestRandomAccessStream>(stream_content);
43   auto buffer = *std::move(util::Buffer::New(buffer_size));
44   util::Status pread_status = util::OkStatus();
45   std::string result;
46   do {
47     pread_status =
48         rand_access_stream->PRead(result.size(), buffer_size, buffer.get());
49     result.append(buffer->get_mem_block(), buffer->size());
50   } while (pread_status.ok());
51   EXPECT_THAT(pread_status, StatusIs(absl::StatusCode::kOutOfRange));
52   EXPECT_EQ(result, stream_content);
53 }
54 
TEST(TestRandomAccessStreamTest,PreadAllInOnePread)55 TEST(TestRandomAccessStreamTest, PreadAllInOnePread) {
56   const int stream_size = 8 * 1024;
57   std::string stream_content = subtle::Random::GetRandomBytes(stream_size);
58   auto rand_access_stream =
59       std::make_unique<TestRandomAccessStream>(stream_content);
60   auto buffer = *std::move(util::Buffer::New(stream_size));
61   ASSERT_THAT(
62       rand_access_stream->PRead(/*position=*/0, stream_size, buffer.get()),
63       StatusIs(absl::StatusCode::kOutOfRange));
64   EXPECT_EQ(std::string(buffer->get_mem_block(), buffer->size()),
65             stream_content);
66 }
67 
TEST(TestRandomAccessStreamTest,PreadCountLargerThanBufferFails)68 TEST(TestRandomAccessStreamTest, PreadCountLargerThanBufferFails) {
69   const int buffer_size = 4 * 1024;
70   const int stream_size = 100 * 1024;
71   std::string stream_content = subtle::Random::GetRandomBytes(stream_size);
72   auto rand_access_stream =
73       std::make_unique<TestRandomAccessStream>(stream_content);
74   auto buffer = *std::move(util::Buffer::New(buffer_size));
75   EXPECT_THAT(
76       rand_access_stream->PRead(/*position=*/0, buffer_size + 1, buffer.get()),
77       StatusIs(absl::StatusCode::kInvalidArgument));
78 }
79 
TEST(TestRandomAccessStreamTest,InvalidPosition)80 TEST(TestRandomAccessStreamTest, InvalidPosition) {
81   const int buffer_size = 4 * 1024;
82   const int stream_size = 100 * 1024;
83   std::string stream_content = subtle::Random::GetRandomBytes(stream_size);
84   auto rand_access_stream =
85       std::make_unique<TestRandomAccessStream>(stream_content);
86   auto buffer = *std::move(util::Buffer::New(buffer_size));
87   EXPECT_THAT(rand_access_stream->PRead(-1, buffer_size, buffer.get()),
88               StatusIs(absl::StatusCode::kInvalidArgument));
89 }
90 
TEST(TestRandomAccessStreamTest,PreadWithNullBufferFails)91 TEST(TestRandomAccessStreamTest, PreadWithNullBufferFails) {
92   const int stream_size = 100 * 1024;
93   std::string stream_content = subtle::Random::GetRandomBytes(stream_size);
94   auto rand_access_stream =
95       std::make_unique<TestRandomAccessStream>(stream_content);
96   EXPECT_THAT(rand_access_stream->PRead(/*position=*/0, stream_size,
97                                         /*dest_buffer=*/nullptr),
98               StatusIs(absl::StatusCode::kInvalidArgument));
99 }
100 
TEST(TestRandomAccessStreamTest,PreadWithEmptyStreamEof)101 TEST(TestRandomAccessStreamTest, PreadWithEmptyStreamEof) {
102   const int buffer_size = 4 * 1024;
103   std::string stream_content;  // Empty string.
104   auto rand_access_stream =
105       std::make_unique<TestRandomAccessStream>(stream_content);
106   auto buffer = *std::move(util::Buffer::New(buffer_size));
107   EXPECT_THAT(
108       rand_access_stream->PRead(/*position=*/0, buffer_size, buffer.get()),
109       StatusIs(absl::StatusCode::kOutOfRange));
110 }
111 
112 // Pread of the last partial block populates the buffer with the remaining
113 // bytes and returns an EOF status.
TEST(TestRandomAccessStreamTest,PreadTheLastPartialBlockReturnsEof)114 TEST(TestRandomAccessStreamTest, PreadTheLastPartialBlockReturnsEof) {
115   const int buffer_size = 4 * 1024;
116   const int stream_size = 100 * 1024;
117   std::string stream_content = subtle::Random::GetRandomBytes(stream_size);
118   auto rand_access_stream =
119       std::make_unique<TestRandomAccessStream>(stream_content);
120   auto buffer = *std::move(util::Buffer::New(buffer_size));
121   // Read at a postion so that only buffer_size - 1 bytes are left.
122   EXPECT_THAT(rand_access_stream->PRead(stream_size - buffer_size + 1,
123                                         buffer_size, buffer.get()),
124               StatusIs(absl::StatusCode::kOutOfRange));
125   EXPECT_EQ(buffer->size(), buffer_size - 1);
126   EXPECT_EQ(std::string(buffer->get_mem_block(), buffer->size()),
127             stream_content.substr(stream_size - buffer_size + 1));
128 }
129 
TEST(TestRandomAccessStreamTest,ReadAllFromRandomAccessStreamSucceeds)130 TEST(TestRandomAccessStreamTest, ReadAllFromRandomAccessStreamSucceeds) {
131   std::string content_to_read = subtle::Random::GetRandomBytes(4 * 1024);
132   auto test_random_access_stream =
133       std::make_unique<TestRandomAccessStream>(content_to_read);
134   std::string read_content;
135   EXPECT_THAT(ReadAllFromRandomAccessStream(test_random_access_stream.get(),
136                                             read_content,
137                                             /*chunk_size=*/128),
138               StatusIs(absl::StatusCode::kOutOfRange));
139   EXPECT_EQ(content_to_read, read_content);
140 }
141 
TEST(TestRandomAccessStreamTest,ReadAllFromRandomAccessStreamFailsWhenChunkIsLessThanOne)142 TEST(TestRandomAccessStreamTest,
143      ReadAllFromRandomAccessStreamFailsWhenChunkIsLessThanOne) {
144   std::string content_to_read = subtle::Random::GetRandomBytes(4 * 1024);
145   auto test_random_access_stream =
146       std::make_unique<TestRandomAccessStream>(content_to_read);
147   std::string read_content;
148   EXPECT_THAT(ReadAllFromRandomAccessStream(test_random_access_stream.get(),
149                                             read_content,
150                                             /*chunk_size=*/0),
151               StatusIs(absl::StatusCode::kInvalidArgument));
152   EXPECT_THAT(ReadAllFromRandomAccessStream(test_random_access_stream.get(),
153                                             read_content,
154                                             /*chunk_size=*/-10),
155               StatusIs(absl::StatusCode::kInvalidArgument));
156 }
157 
158 }  // namespace
159 }  // namespace internal
160 }  // namespace tink
161 }  // namespace crypto
162