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 "OperationLimiter.h"
18
19 #include <gtest/gtest-spi.h>
20 #include <netdutils/NetNativeTestBase.h>
21
22 namespace android {
23 namespace netdutils {
24
25 class OperationLimiterTest : public NetNativeTestBase {};
26
TEST_F(OperationLimiterTest,limits)27 TEST_F(OperationLimiterTest, limits) {
28 OperationLimiter<int> limiter(3);
29
30 EXPECT_TRUE(limiter.start(42));
31 EXPECT_TRUE(limiter.start(42));
32 EXPECT_TRUE(limiter.start(42));
33
34 // Limit reached... calling any number of times should have no effect.
35 EXPECT_FALSE(limiter.start(42));
36 EXPECT_FALSE(limiter.start(42));
37 EXPECT_FALSE(limiter.start(42));
38
39 // Finishing a single operations is enough for starting a new one...
40 limiter.finish(42);
41 EXPECT_TRUE(limiter.start(42));
42
43 // ...but not two!
44 EXPECT_FALSE(limiter.start(42));
45
46 // Different ids should still have quota...
47 EXPECT_TRUE(limiter.start(666));
48 limiter.finish(666);
49
50 // Finish all pending operations
51 limiter.finish(42);
52 limiter.finish(42);
53 limiter.finish(42);
54 }
55
TEST_F(OperationLimiterTest,finishWithoutStart)56 TEST_F(OperationLimiterTest, finishWithoutStart) {
57 OperationLimiter<int> limiter(1);
58
59 // Will output a LOG(FATAL_WITHOUT_ABORT), but we have no way to probe this.
60 limiter.finish(42);
61
62 // This will ensure that the finish() above didn't set a negative value.
63 EXPECT_TRUE(limiter.start(42));
64 EXPECT_FALSE(limiter.start(42));
65 }
66
TEST_F(OperationLimiterTest,destroyWithActiveOperations)67 TEST_F(OperationLimiterTest, destroyWithActiveOperations) {
68 // The death message doesn't seem to be captured on Android.
69 EXPECT_DEBUG_DEATH(
70 {
71 OperationLimiter<int> limiter(3);
72 limiter.start(42);
73 },
74 "" /* "active operations */);
75 }
76
TEST_F(OperationLimiterTest,globalLimits)77 TEST_F(OperationLimiterTest, globalLimits) {
78 OperationLimiter<int> limiter(1);
79
80 EXPECT_TRUE(limiter.start(42, 2));
81
82 // Calling with a different key is okay.
83 EXPECT_TRUE(limiter.start(43, 2));
84
85 // Global limit reached... calling with a different key should have no effect.
86 EXPECT_FALSE(limiter.start(44, 2));
87
88 // Global limit extended... calling with a different key is available again.
89 EXPECT_TRUE(limiter.start(44, 4));
90
91 // Per-key limit reached.
92 EXPECT_FALSE(limiter.start(44, 4));
93
94 // Global limit is still available.
95 EXPECT_TRUE(limiter.start(45, 4));
96
97 // Global limit reached again.
98 EXPECT_FALSE(limiter.start(46, 4));
99
100 // Shrink global limit.
101 EXPECT_FALSE(limiter.start(46, 3));
102
103 // Finish all pending operations
104 for (const auto& key : {42, 43, 44, 45}) {
105 limiter.finish(key);
106 }
107 }
108
109 } // namespace netdutils
110 } // namespace android
111