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