• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright (C) 2022 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 #include <unordered_set>
17 
18 #include "common/libs/utils/contains.h"
19 #include "common/libs/utils/unique_resource_allocator.h"
20 #include "common/libs/utils/unique_resource_allocator_test.h"
21 
22 namespace cuttlefish {
23 
TEST_P(OneEachTest,GetAnyAvailableOne)24 TEST_P(OneEachTest, GetAnyAvailableOne) {
25   const auto resources = GetParam();
26   auto allocator = UniqueResourceAllocator<unsigned>::New(resources);
27   if (!allocator) {
28     GTEST_SKIP() << "Memory allocation failed but we aren't testing it.";
29   }
30   std::unordered_set<unsigned> expected_ids{resources.cbegin(),
31                                             resources.cend()};
32   using Reservation = UniqueResourceAllocator<unsigned>::Reservation;
33 
34   std::vector<Reservation> allocated;
35   for (int i = 0; i < resources.size(); i++) {
36     auto id_opt = allocator->UniqueItem();
37     ASSERT_TRUE(id_opt);
38     ASSERT_TRUE(Contains(expected_ids, id_opt->Get()));
39     allocated.emplace_back(std::move(*id_opt));
40   }
41   ASSERT_FALSE(allocator->UniqueItem());
42 }
43 
44 INSTANTIATE_TEST_SUITE_P(
45     CvdIdAllocator, OneEachTest,
46     testing::Values(std::vector<unsigned>{}, std::vector<unsigned>{1},
47                     std::vector<unsigned>{1, 22, 3, 43, 5}));
48 
TEST_F(CvdIdAllocatorTest,ClaimAll)49 TEST_F(CvdIdAllocatorTest, ClaimAll) {
50   std::vector<unsigned> inputs{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
51   auto allocator = UniqueResourceAllocator<unsigned>::New(inputs);
52   if (!allocator) {
53     GTEST_SKIP() << "Memory allocation failed but we aren't testing it.";
54   }
55 
56   // request inputs.size() items
57   auto allocated_items_opt = allocator->UniqueItems(inputs.size());
58   ASSERT_TRUE(allocated_items_opt);
59   ASSERT_EQ(allocated_items_opt->size(), inputs.size());
60   // did it claim all?
61   ASSERT_FALSE(allocator->UniqueItem());
62 }
63 
TEST_F(CvdIdAllocatorTest,StrideBeyond)64 TEST_F(CvdIdAllocatorTest, StrideBeyond) {
65   std::vector<unsigned> inputs{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
66   auto allocator = UniqueResourceAllocator<unsigned>::New(inputs);
67   if (!allocator) {
68     GTEST_SKIP() << "Memory allocation failed but we aren't testing it.";
69   }
70 
71   auto three_opt = allocator->UniqueItems(3);
72   auto four_opt = allocator->UniqueItems(4);
73   auto five_opt = allocator->UniqueItems(5);
74   auto two_opt = allocator->UniqueItems(2);
75   auto another_two_opt = allocator->UniqueItems(2);
76 
77   ASSERT_TRUE(three_opt);
78   ASSERT_TRUE(four_opt);
79   ASSERT_FALSE(five_opt);
80   ASSERT_TRUE(two_opt);
81   ASSERT_FALSE(another_two_opt);
82 }
83 
TEST_F(CvdIdAllocatorTest,Consecutive)84 TEST_F(CvdIdAllocatorTest, Consecutive) {
85   std::vector<unsigned> inputs{1, 2, 4, 5, 6, 7, 9, 10, 11};
86   auto allocator = UniqueResourceAllocator<unsigned>::New(inputs);
87   if (!allocator) {
88     GTEST_SKIP() << "Memory allocation failed but we aren't testing it.";
89   }
90 
91   auto four_consecutive = allocator->UniqueConsecutiveItems(4);
92   auto three_consecutive = allocator->UniqueConsecutiveItems(3);
93   auto another_three_consecutive = allocator->UniqueConsecutiveItems(3);
94   auto two_consecutive = allocator->UniqueConsecutiveItems(2);
95 
96   ASSERT_TRUE(four_consecutive);
97   ASSERT_TRUE(three_consecutive);
98   ASSERT_FALSE(another_three_consecutive);
99   ASSERT_TRUE(two_consecutive);
100   // it's empty
101   ASSERT_FALSE(allocator->UniqueItem()) << "one or more left";
102 }
103 
TEST_F(CvdIdAllocatorTest,Take)104 TEST_F(CvdIdAllocatorTest, Take) {
105   std::vector<unsigned> inputs{4, 5, 9};
106   auto allocator = UniqueResourceAllocator<unsigned>::New(inputs);
107   if (!allocator) {
108     GTEST_SKIP() << "Memory allocation failed but we aren't testing it.";
109   }
110 
111   auto four = allocator->Take(4);
112   auto nine = allocator->Take(9);
113   // wrong
114   auto twenty = allocator->Take(20);
115 
116   ASSERT_TRUE(four);
117   ASSERT_TRUE(nine);
118   ASSERT_FALSE(twenty);
119 }
120 
TEST_F(CvdIdAllocatorTest,TakeAll)121 TEST_F(CvdIdAllocatorTest, TakeAll) {
122   std::vector<unsigned> inputs{4, 5, 9, 10};
123   auto allocator = UniqueResourceAllocator<unsigned>::New(inputs);
124   if (!allocator) {
125     GTEST_SKIP() << "Memory allocation failed but we aren't testing it.";
126   }
127 
128   auto take_4_5_11 = allocator->TakeAll<std::vector<unsigned>>({4, 5, 11});
129   auto take_4_5_10 = allocator->TakeAll<std::vector<unsigned>>({4, 5, 10});
130   auto take_9_10 = allocator->TakeAll<std::vector<unsigned>>({9, 10});
131   auto take_9 = allocator->TakeAll<std::vector<unsigned>>({9});
132 
133   ASSERT_FALSE(take_4_5_11);
134   ASSERT_TRUE(take_4_5_10);
135   ASSERT_FALSE(take_9_10);
136   ASSERT_TRUE(take_9);
137 }
138 
TEST_F(CvdIdAllocatorTest,TakeRange)139 TEST_F(CvdIdAllocatorTest, TakeRange) {
140   std::vector<unsigned> inputs{1, 2, 4, 5, 6, 7, 8, 9, 10, 11};
141   auto allocator = UniqueResourceAllocator<unsigned>::New(inputs);
142   if (!allocator) {
143     GTEST_SKIP() << "Memory allocation failed but we aren't testing it.";
144   }
145 
146   auto take_range_5_12 = allocator->TakeRange(5, 12);
147   // shall fail as 3 is missing
148   auto take_range_2_4 = allocator->TakeRange(2, 4);
149 
150   ASSERT_TRUE(take_range_5_12);
151   ASSERT_FALSE(take_range_2_4);
152 }
153 
TEST_F(CvdIdAllocatorTest,Reclaim)154 TEST_F(CvdIdAllocatorTest, Reclaim) {
155   std::vector<unsigned> inputs{1, 2, 4, 5, 6, 7, 8, 9, 10, 11};
156   auto allocator = UniqueResourceAllocator<unsigned>::New(inputs);
157   if (!allocator) {
158     GTEST_SKIP() << "Memory allocation failed but we aren't testing it.";
159   }
160   unsigned one_resource = 0;
161   {
162     auto take_range_5_12 = allocator->TakeRange(5, 12);
163     auto any_single_item = allocator->UniqueItem();
164 
165     ASSERT_TRUE(take_range_5_12);
166     ASSERT_TRUE(any_single_item);
167     one_resource = any_single_item->Get();
168 
169     ASSERT_FALSE(allocator->TakeRange(5, 12));
170     ASSERT_FALSE(allocator->Take(one_resource));
171   }
172   // take_range_5_12 went out of scope, so resources were reclaimed
173   ASSERT_TRUE(allocator->TakeRange(5, 12));
174   ASSERT_TRUE(allocator->Take(one_resource));
175 }
176 
TEST(CvdIdAllocatorExpandTest,Expand)177 TEST(CvdIdAllocatorExpandTest, Expand) {
178   std::vector<unsigned> inputs{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
179   auto allocator = UniqueResourceAllocator<unsigned>::New(inputs);
180   if (!allocator) {
181     GTEST_SKIP() << "Memory allocation failed but we aren't testing it.";
182   }
183   auto hold_6_to_10 = allocator->TakeRange(6, 11);
184   if (!hold_6_to_10) {
185     GTEST_SKIP() << "TakeRange(6, 11) failed but it's not what is tested here";
186   }
187 
188   auto expand =
189       allocator->ExpandPool(std::vector<unsigned>{2, 4, 6, 8, 12, 14});
190   auto take_12 = allocator->Take(12);
191   auto take_14 = allocator->Take(14);
192   auto take_6 = allocator->Take(6);
193 
194   std::vector<unsigned> expected_return_from_expand{2, 4, 6, 8};
195   ASSERT_EQ(expand, expected_return_from_expand);
196   ASSERT_TRUE(take_12);
197   ASSERT_TRUE(take_14);
198   ASSERT_FALSE(take_6);
199 }
200 
201 }  // namespace cuttlefish
202