1 /*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <gtest/gtest.h>
18
19 #include <memory>
20 #include "types.h"
21
create_block(const std::string & string)22 static std::unique_ptr<IOVector::block_type> create_block(const std::string& string) {
23 return std::make_unique<IOVector::block_type>(string.begin(), string.end());
24 }
25
create_block(char value,size_t len)26 static std::unique_ptr<IOVector::block_type> create_block(char value, size_t len) {
27 auto block = std::make_unique<IOVector::block_type>();
28 block->resize(len);
29 memset(&(*block)[0], value, len);
30 return block;
31 }
32
33 template <typename T>
copy_block(T && block)34 static std::unique_ptr<IOVector::block_type> copy_block(T&& block) {
35 auto copy = std::make_unique<IOVector::block_type>();
36 copy->assign(block->begin(), block->end());
37 return copy;
38 }
39
TEST(IOVector,empty)40 TEST(IOVector, empty) {
41 // Empty IOVector.
42 IOVector bc;
43 CHECK_EQ(0ULL, bc.coalesce().size());
44 }
45
TEST(IOVector,single_block)46 TEST(IOVector, single_block) {
47 // A single block.
48 auto block = create_block('x', 100);
49 IOVector bc;
50 bc.append(copy_block(block));
51 ASSERT_EQ(100ULL, bc.size());
52 auto coalesced = bc.coalesce();
53 ASSERT_EQ(*block, coalesced);
54 }
55
TEST(IOVector,single_block_split)56 TEST(IOVector, single_block_split) {
57 // One block split.
58 IOVector bc;
59 bc.append(create_block("foobar"));
60 IOVector foo = bc.take_front(3);
61 ASSERT_EQ(3ULL, foo.size());
62 ASSERT_EQ(3ULL, bc.size());
63 ASSERT_EQ(*create_block("foo"), foo.coalesce());
64 ASSERT_EQ(*create_block("bar"), bc.coalesce());
65 }
66
TEST(IOVector,aligned_split)67 TEST(IOVector, aligned_split) {
68 IOVector bc;
69 bc.append(create_block("foo"));
70 bc.append(create_block("bar"));
71 bc.append(create_block("baz"));
72 ASSERT_EQ(9ULL, bc.size());
73
74 IOVector foo = bc.take_front(3);
75 ASSERT_EQ(3ULL, foo.size());
76 ASSERT_EQ(*create_block("foo"), foo.coalesce());
77
78 IOVector bar = bc.take_front(3);
79 ASSERT_EQ(3ULL, bar.size());
80 ASSERT_EQ(*create_block("bar"), bar.coalesce());
81
82 IOVector baz = bc.take_front(3);
83 ASSERT_EQ(3ULL, baz.size());
84 ASSERT_EQ(*create_block("baz"), baz.coalesce());
85
86 ASSERT_EQ(0ULL, bc.size());
87 }
88
TEST(IOVector,misaligned_split)89 TEST(IOVector, misaligned_split) {
90 IOVector bc;
91 bc.append(create_block("foo"));
92 bc.append(create_block("bar"));
93 bc.append(create_block("baz"));
94 bc.append(create_block("qux"));
95 bc.append(create_block("quux"));
96
97 // Aligned left, misaligned right, across multiple blocks.
98 IOVector foob = bc.take_front(4);
99 ASSERT_EQ(4ULL, foob.size());
100 ASSERT_EQ(*create_block("foob"), foob.coalesce());
101
102 // Misaligned left, misaligned right, in one block.
103 IOVector a = bc.take_front(1);
104 ASSERT_EQ(1ULL, a.size());
105 ASSERT_EQ(*create_block("a"), a.coalesce());
106
107 // Misaligned left, misaligned right, across two blocks.
108 IOVector rba = bc.take_front(3);
109 ASSERT_EQ(3ULL, rba.size());
110 ASSERT_EQ(*create_block("rba"), rba.coalesce());
111
112 // Misaligned left, misaligned right, across three blocks.
113 IOVector zquxquu = bc.take_front(7);
114 ASSERT_EQ(7ULL, zquxquu.size());
115 ASSERT_EQ(*create_block("zquxquu"), zquxquu.coalesce());
116
117 ASSERT_EQ(1ULL, bc.size());
118 ASSERT_EQ(*create_block("x"), bc.coalesce());
119 }
120