Luke Huang | f40df9c | 2020-04-21 08:51:48 +0800 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2020 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 | |
Mike Yu | be3e76d | 2021-11-16 20:10:02 +0800 | [diff] [blame] | 17 | #include <map> |
Luke Huang | f40df9c | 2020-04-21 08:51:48 +0800 | [diff] [blame] | 18 | #include <mutex> |
| 19 | #include <string> |
| 20 | #include <string_view> |
Luke Huang | f40df9c | 2020-04-21 08:51:48 +0800 | [diff] [blame] | 21 | |
| 22 | #include <android-base/format.h> |
Luke Huang | f40df9c | 2020-04-21 08:51:48 +0800 | [diff] [blame] | 23 | #include <android-base/test_utils.h> |
| 24 | #include <gmock/gmock.h> |
| 25 | #include <gtest/gtest.h> |
| 26 | |
| 27 | #include "Experiments.h" |
Chiachang Wang | e016848 | 2022-03-09 14:24:32 +0800 | [diff] [blame] | 28 | #include "tests/resolv_test_base.h" |
Luke Huang | f40df9c | 2020-04-21 08:51:48 +0800 | [diff] [blame] | 29 | |
| 30 | namespace android::net { |
| 31 | |
Chiachang Wang | e016848 | 2022-03-09 14:24:32 +0800 | [diff] [blame] | 32 | class ExperimentsTest : public ResolvTestBase { |
Luke Huang | f40df9c | 2020-04-21 08:51:48 +0800 | [diff] [blame] | 33 | public: |
| 34 | ExperimentsTest() : mExperiments(fakeGetExperimentFlagInt) {} |
| 35 | |
| 36 | protected: |
| 37 | static int fakeGetExperimentFlagInt(const std::string& key, int defaultValue) { |
| 38 | auto it = sFakeFlagsMapInt.find(key); |
| 39 | if (it != sFakeFlagsMapInt.end()) { |
| 40 | return it->second; |
| 41 | } |
| 42 | return defaultValue; |
| 43 | } |
| 44 | |
| 45 | void setupFakeMap(int value) { |
| 46 | for (const auto& key : Experiments::kExperimentFlagKeyList) { |
| 47 | sFakeFlagsMapInt[key] = value; |
| 48 | } |
| 49 | } |
| 50 | |
| 51 | void setupExperimentsMap(int value) { |
| 52 | setupFakeMap(value); |
| 53 | std::lock_guard guard(mExperiments.mMutex); |
| 54 | mExperiments.mFlagsMapInt = sFakeFlagsMapInt; |
| 55 | } |
| 56 | |
| 57 | void expectFlagsMapInt() { |
| 58 | std::lock_guard guard(mExperiments.mMutex); |
| 59 | EXPECT_THAT(mExperiments.mFlagsMapInt, ::testing::ContainerEq(sFakeFlagsMapInt)); |
| 60 | } |
| 61 | |
Luke Huang | a893556 | 2020-04-30 11:26:41 +0800 | [diff] [blame] | 62 | void expectFlagsMapIntDefault() { |
| 63 | std::lock_guard guard(mExperiments.mMutex); |
| 64 | for (const auto& [key, value] : mExperiments.mFlagsMapInt) { |
| 65 | EXPECT_EQ(value, Experiments::kFlagIntDefault); |
| 66 | } |
| 67 | } |
| 68 | |
| 69 | void expectGetDnsExperimentFlagIntDefault(int value) { |
| 70 | for (const auto& key : Experiments::kExperimentFlagKeyList) { |
| 71 | EXPECT_EQ(mExperiments.getFlag(key, value), value); |
| 72 | } |
| 73 | } |
| 74 | |
Luke Huang | f40df9c | 2020-04-21 08:51:48 +0800 | [diff] [blame] | 75 | void expectGetDnsExperimentFlagInt() { |
Mike Yu | be3e76d | 2021-11-16 20:10:02 +0800 | [diff] [blame] | 76 | std::map<std::string_view, int> tempMap; |
Luke Huang | f40df9c | 2020-04-21 08:51:48 +0800 | [diff] [blame] | 77 | for (const auto& key : Experiments::kExperimentFlagKeyList) { |
| 78 | tempMap[key] = mExperiments.getFlag(key, 0); |
| 79 | } |
| 80 | EXPECT_THAT(tempMap, ::testing::ContainerEq(sFakeFlagsMapInt)); |
| 81 | } |
| 82 | |
| 83 | void expectDumpOutput() { |
| 84 | netdutils::DumpWriter dw(STDOUT_FILENO); |
| 85 | CapturedStdout captured; |
| 86 | mExperiments.dump(dw); |
| 87 | const std::string dumpString = captured.str(); |
| 88 | const std::string title = "Experiments list:"; |
| 89 | EXPECT_EQ(dumpString.find(title), 0U); |
| 90 | size_t startPos = title.size(); |
| 91 | std::lock_guard guard(mExperiments.mMutex); |
| 92 | for (const auto& [key, value] : mExperiments.mFlagsMapInt) { |
| 93 | std::string flagDump = fmt::format("{}: {}", key, value); |
Luke Huang | a893556 | 2020-04-30 11:26:41 +0800 | [diff] [blame] | 94 | if (value == Experiments::kFlagIntDefault) { |
| 95 | flagDump = fmt::format("{}: UNSET", key); |
| 96 | } |
Luke Huang | f40df9c | 2020-04-21 08:51:48 +0800 | [diff] [blame] | 97 | SCOPED_TRACE(flagDump); |
| 98 | size_t pos = dumpString.find(flagDump, startPos); |
| 99 | EXPECT_NE(pos, std::string::npos); |
| 100 | startPos = pos + flagDump.size(); |
| 101 | } |
| 102 | EXPECT_EQ(startPos + 1, dumpString.size()); |
| 103 | EXPECT_EQ(dumpString.substr(startPos), "\n"); |
| 104 | } |
| 105 | |
Mike Yu | be3e76d | 2021-11-16 20:10:02 +0800 | [diff] [blame] | 106 | static std::map<std::string_view, int> sFakeFlagsMapInt; |
Luke Huang | f40df9c | 2020-04-21 08:51:48 +0800 | [diff] [blame] | 107 | Experiments mExperiments; |
| 108 | }; |
| 109 | |
Mike Yu | be3e76d | 2021-11-16 20:10:02 +0800 | [diff] [blame] | 110 | std::map<std::string_view, int> ExperimentsTest::sFakeFlagsMapInt; |
Luke Huang | f40df9c | 2020-04-21 08:51:48 +0800 | [diff] [blame] | 111 | |
| 112 | TEST_F(ExperimentsTest, update) { |
| 113 | std::vector<int> testValues = {50, 3, 5, 0}; |
| 114 | for (int testValue : testValues) { |
| 115 | setupFakeMap(testValue); |
| 116 | mExperiments.update(); |
| 117 | expectFlagsMapInt(); |
| 118 | } |
| 119 | } |
| 120 | |
| 121 | TEST_F(ExperimentsTest, getDnsExperimentFlagInt) { |
| 122 | std::vector<int> testValues = {5, 1, 6, 0}; |
| 123 | for (int testValue : testValues) { |
| 124 | setupExperimentsMap(testValue); |
| 125 | expectGetDnsExperimentFlagInt(); |
| 126 | } |
| 127 | } |
| 128 | |
Luke Huang | a893556 | 2020-04-30 11:26:41 +0800 | [diff] [blame] | 129 | TEST_F(ExperimentsTest, getDnsExperimentFlagIntDefaultValue) { |
| 130 | // Clear the map and make mExperiments initialized with our default int value. |
| 131 | sFakeFlagsMapInt.clear(); |
| 132 | mExperiments.update(); |
| 133 | expectFlagsMapIntDefault(); |
| 134 | std::vector<int> testValues = {100, 50, 30, 5}; |
| 135 | for (int testValue : testValues) { |
| 136 | expectGetDnsExperimentFlagIntDefault(testValue); |
| 137 | } |
| 138 | } |
| 139 | |
Luke Huang | f40df9c | 2020-04-21 08:51:48 +0800 | [diff] [blame] | 140 | TEST_F(ExperimentsTest, dump) { |
| 141 | std::vector<int> testValues = {100, 37, 0, 30}; |
| 142 | for (int testValue : testValues) { |
| 143 | setupFakeMap(testValue); |
| 144 | mExperiments.update(); |
| 145 | expectDumpOutput(); |
| 146 | } |
Luke Huang | a893556 | 2020-04-30 11:26:41 +0800 | [diff] [blame] | 147 | sFakeFlagsMapInt.clear(); |
| 148 | mExperiments.update(); |
| 149 | expectDumpOutput(); |
Luke Huang | f40df9c | 2020-04-21 08:51:48 +0800 | [diff] [blame] | 150 | } |
| 151 | |
| 152 | } // namespace android::net |