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 22 static IOVector::block_type create_block(const std::string& string) { 23 return IOVector::block_type(string.begin(), string.end()); 24 } 25 26 static IOVector::block_type create_block(char value, size_t len) { 27 auto block = IOVector::block_type(); 28 block.resize(len); 29 memset(&(block)[0], value, len); 30 return block; 31 } 32 33 template <typename T> 34 static IOVector::block_type copy_block(const T& block) { 35 auto copy = IOVector::block_type(); 36 copy.assign(block.begin(), block.end()); 37 return copy; 38 } 39 40 TEST(IOVector, empty) { 41 // Empty IOVector. 42 IOVector bc; 43 CHECK_EQ(0ULL, bc.coalesce().size()); 44 } 45 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 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 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 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 121 TEST(IOVector, drop_front) { 122 IOVector vec; 123 124 vec.append(create_block('x', 2)); 125 vec.append(create_block('y', 1000)); 126 ASSERT_EQ(2U, vec.front_size()); 127 ASSERT_EQ(1002U, vec.size()); 128 129 vec.drop_front(1); 130 ASSERT_EQ(1U, vec.front_size()); 131 ASSERT_EQ(1001U, vec.size()); 132 133 vec.drop_front(1); 134 ASSERT_EQ(1000U, vec.front_size()); 135 ASSERT_EQ(1000U, vec.size()); 136 } 137