1 // 2 // Copyright (C) 2015 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 "update_engine/metrics_utils.h" 18 19 #include <gtest/gtest.h> 20 21 #include "update_engine/common/fake_clock.h" 22 #include "update_engine/common/fake_prefs.h" 23 #include "update_engine/fake_system_state.h" 24 25 namespace chromeos_update_engine { 26 namespace metrics_utils { 27 28 class MetricsUtilsTest : public ::testing::Test {}; 29 30 TEST(MetricsUtilsTest, GetConnectionType) { 31 // Check that expected combinations map to the right value. 32 EXPECT_EQ(metrics::ConnectionType::kUnknown, 33 GetConnectionType(NetworkConnectionType::kUnknown, 34 NetworkTethering::kUnknown)); 35 EXPECT_EQ(metrics::ConnectionType::kEthernet, 36 GetConnectionType(NetworkConnectionType::kEthernet, 37 NetworkTethering::kUnknown)); 38 EXPECT_EQ(metrics::ConnectionType::kWifi, 39 GetConnectionType(NetworkConnectionType::kWifi, 40 NetworkTethering::kUnknown)); 41 EXPECT_EQ(metrics::ConnectionType::kWimax, 42 GetConnectionType(NetworkConnectionType::kWimax, 43 NetworkTethering::kUnknown)); 44 EXPECT_EQ(metrics::ConnectionType::kBluetooth, 45 GetConnectionType(NetworkConnectionType::kBluetooth, 46 NetworkTethering::kUnknown)); 47 EXPECT_EQ(metrics::ConnectionType::kCellular, 48 GetConnectionType(NetworkConnectionType::kCellular, 49 NetworkTethering::kUnknown)); 50 EXPECT_EQ(metrics::ConnectionType::kTetheredEthernet, 51 GetConnectionType(NetworkConnectionType::kEthernet, 52 NetworkTethering::kConfirmed)); 53 EXPECT_EQ(metrics::ConnectionType::kTetheredWifi, 54 GetConnectionType(NetworkConnectionType::kWifi, 55 NetworkTethering::kConfirmed)); 56 57 // Ensure that we don't report tethered ethernet unless it's confirmed. 58 EXPECT_EQ(metrics::ConnectionType::kEthernet, 59 GetConnectionType(NetworkConnectionType::kEthernet, 60 NetworkTethering::kNotDetected)); 61 EXPECT_EQ(metrics::ConnectionType::kEthernet, 62 GetConnectionType(NetworkConnectionType::kEthernet, 63 NetworkTethering::kSuspected)); 64 EXPECT_EQ(metrics::ConnectionType::kEthernet, 65 GetConnectionType(NetworkConnectionType::kEthernet, 66 NetworkTethering::kUnknown)); 67 68 // Ditto for tethered wifi. 69 EXPECT_EQ(metrics::ConnectionType::kWifi, 70 GetConnectionType(NetworkConnectionType::kWifi, 71 NetworkTethering::kNotDetected)); 72 EXPECT_EQ(metrics::ConnectionType::kWifi, 73 GetConnectionType(NetworkConnectionType::kWifi, 74 NetworkTethering::kSuspected)); 75 EXPECT_EQ(metrics::ConnectionType::kWifi, 76 GetConnectionType(NetworkConnectionType::kWifi, 77 NetworkTethering::kUnknown)); 78 } 79 80 TEST(MetricsUtilsTest, WallclockDurationHelper) { 81 FakeSystemState fake_system_state; 82 FakeClock fake_clock; 83 base::TimeDelta duration; 84 const std::string state_variable_key = "test-prefs"; 85 FakePrefs fake_prefs; 86 87 fake_system_state.set_clock(&fake_clock); 88 fake_system_state.set_prefs(&fake_prefs); 89 90 // Initialize wallclock to 1 sec. 91 fake_clock.SetWallclockTime(base::Time::FromInternalValue(1000000)); 92 93 // First time called so no previous measurement available. 94 EXPECT_FALSE(metrics_utils::WallclockDurationHelper(&fake_system_state, 95 state_variable_key, 96 &duration)); 97 98 // Next time, we should get zero since the clock didn't advance. 99 EXPECT_TRUE(metrics_utils::WallclockDurationHelper(&fake_system_state, 100 state_variable_key, 101 &duration)); 102 EXPECT_EQ(duration.InSeconds(), 0); 103 104 // We can also call it as many times as we want with it being 105 // considered a failure. 106 EXPECT_TRUE(metrics_utils::WallclockDurationHelper(&fake_system_state, 107 state_variable_key, 108 &duration)); 109 EXPECT_EQ(duration.InSeconds(), 0); 110 EXPECT_TRUE(metrics_utils::WallclockDurationHelper(&fake_system_state, 111 state_variable_key, 112 &duration)); 113 EXPECT_EQ(duration.InSeconds(), 0); 114 115 // Advance the clock one second, then we should get 1 sec on the 116 // next call and 0 sec on the subsequent call. 117 fake_clock.SetWallclockTime(base::Time::FromInternalValue(2000000)); 118 EXPECT_TRUE(metrics_utils::WallclockDurationHelper(&fake_system_state, 119 state_variable_key, 120 &duration)); 121 EXPECT_EQ(duration.InSeconds(), 1); 122 EXPECT_TRUE(metrics_utils::WallclockDurationHelper(&fake_system_state, 123 state_variable_key, 124 &duration)); 125 EXPECT_EQ(duration.InSeconds(), 0); 126 127 // Advance clock two seconds and we should get 2 sec and then 0 sec. 128 fake_clock.SetWallclockTime(base::Time::FromInternalValue(4000000)); 129 EXPECT_TRUE(metrics_utils::WallclockDurationHelper(&fake_system_state, 130 state_variable_key, 131 &duration)); 132 EXPECT_EQ(duration.InSeconds(), 2); 133 EXPECT_TRUE(metrics_utils::WallclockDurationHelper(&fake_system_state, 134 state_variable_key, 135 &duration)); 136 EXPECT_EQ(duration.InSeconds(), 0); 137 138 // There's a possibility that the wallclock can go backwards (NTP 139 // adjustments, for example) so check that we properly handle this 140 // case. 141 fake_clock.SetWallclockTime(base::Time::FromInternalValue(3000000)); 142 EXPECT_FALSE(metrics_utils::WallclockDurationHelper(&fake_system_state, 143 state_variable_key, 144 &duration)); 145 fake_clock.SetWallclockTime(base::Time::FromInternalValue(4000000)); 146 EXPECT_TRUE(metrics_utils::WallclockDurationHelper(&fake_system_state, 147 state_variable_key, 148 &duration)); 149 EXPECT_EQ(duration.InSeconds(), 1); 150 } 151 152 TEST(MetricsUtilsTest, MonotonicDurationHelper) { 153 int64_t storage = 0; 154 FakeSystemState fake_system_state; 155 FakeClock fake_clock; 156 base::TimeDelta duration; 157 158 fake_system_state.set_clock(&fake_clock); 159 160 // Initialize monotonic clock to 1 sec. 161 fake_clock.SetMonotonicTime(base::Time::FromInternalValue(1000000)); 162 163 // First time called so no previous measurement available. 164 EXPECT_FALSE(metrics_utils::MonotonicDurationHelper(&fake_system_state, 165 &storage, 166 &duration)); 167 168 // Next time, we should get zero since the clock didn't advance. 169 EXPECT_TRUE(metrics_utils::MonotonicDurationHelper(&fake_system_state, 170 &storage, 171 &duration)); 172 EXPECT_EQ(duration.InSeconds(), 0); 173 174 // We can also call it as many times as we want with it being 175 // considered a failure. 176 EXPECT_TRUE(metrics_utils::MonotonicDurationHelper(&fake_system_state, 177 &storage, 178 &duration)); 179 EXPECT_EQ(duration.InSeconds(), 0); 180 EXPECT_TRUE(metrics_utils::MonotonicDurationHelper(&fake_system_state, 181 &storage, 182 &duration)); 183 EXPECT_EQ(duration.InSeconds(), 0); 184 185 // Advance the clock one second, then we should get 1 sec on the 186 // next call and 0 sec on the subsequent call. 187 fake_clock.SetMonotonicTime(base::Time::FromInternalValue(2000000)); 188 EXPECT_TRUE(metrics_utils::MonotonicDurationHelper(&fake_system_state, 189 &storage, 190 &duration)); 191 EXPECT_EQ(duration.InSeconds(), 1); 192 EXPECT_TRUE(metrics_utils::MonotonicDurationHelper(&fake_system_state, 193 &storage, 194 &duration)); 195 EXPECT_EQ(duration.InSeconds(), 0); 196 197 // Advance clock two seconds and we should get 2 sec and then 0 sec. 198 fake_clock.SetMonotonicTime(base::Time::FromInternalValue(4000000)); 199 EXPECT_TRUE(metrics_utils::MonotonicDurationHelper(&fake_system_state, 200 &storage, 201 &duration)); 202 EXPECT_EQ(duration.InSeconds(), 2); 203 EXPECT_TRUE(metrics_utils::MonotonicDurationHelper(&fake_system_state, 204 &storage, 205 &duration)); 206 EXPECT_EQ(duration.InSeconds(), 0); 207 } 208 209 } // namespace metrics_utils 210 } // namespace chromeos_update_engine 211