138429cf76aaac8c499004b6f537229a26b381602Alex Deymo//
238429cf76aaac8c499004b6f537229a26b381602Alex Deymo// Copyright (C) 2015 The Android Open Source Project
338429cf76aaac8c499004b6f537229a26b381602Alex Deymo//
438429cf76aaac8c499004b6f537229a26b381602Alex Deymo// Licensed under the Apache License, Version 2.0 (the "License");
538429cf76aaac8c499004b6f537229a26b381602Alex Deymo// you may not use this file except in compliance with the License.
638429cf76aaac8c499004b6f537229a26b381602Alex Deymo// You may obtain a copy of the License at
738429cf76aaac8c499004b6f537229a26b381602Alex Deymo//
838429cf76aaac8c499004b6f537229a26b381602Alex Deymo//      http://www.apache.org/licenses/LICENSE-2.0
938429cf76aaac8c499004b6f537229a26b381602Alex Deymo//
1038429cf76aaac8c499004b6f537229a26b381602Alex Deymo// Unless required by applicable law or agreed to in writing, software
1138429cf76aaac8c499004b6f537229a26b381602Alex Deymo// distributed under the License is distributed on an "AS IS" BASIS,
1238429cf76aaac8c499004b6f537229a26b381602Alex Deymo// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1338429cf76aaac8c499004b6f537229a26b381602Alex Deymo// See the License for the specific language governing permissions and
1438429cf76aaac8c499004b6f537229a26b381602Alex Deymo// limitations under the License.
1538429cf76aaac8c499004b6f537229a26b381602Alex Deymo//
1638429cf76aaac8c499004b6f537229a26b381602Alex Deymo
1738429cf76aaac8c499004b6f537229a26b381602Alex Deymo#include "update_engine/metrics_utils.h"
1838429cf76aaac8c499004b6f537229a26b381602Alex Deymo
1938429cf76aaac8c499004b6f537229a26b381602Alex Deymo#include <gtest/gtest.h>
2038429cf76aaac8c499004b6f537229a26b381602Alex Deymo
21a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo#include "update_engine/common/fake_clock.h"
22a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo#include "update_engine/common/fake_prefs.h"
23a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo#include "update_engine/fake_system_state.h"
24a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo
2538429cf76aaac8c499004b6f537229a26b381602Alex Deymonamespace chromeos_update_engine {
2638429cf76aaac8c499004b6f537229a26b381602Alex Deymonamespace metrics_utils {
2738429cf76aaac8c499004b6f537229a26b381602Alex Deymo
2838429cf76aaac8c499004b6f537229a26b381602Alex Deymoclass MetricsUtilsTest : public ::testing::Test {};
2938429cf76aaac8c499004b6f537229a26b381602Alex Deymo
3038429cf76aaac8c499004b6f537229a26b381602Alex DeymoTEST(MetricsUtilsTest, GetConnectionType) {
3138429cf76aaac8c499004b6f537229a26b381602Alex Deymo  // Check that expected combinations map to the right value.
3238429cf76aaac8c499004b6f537229a26b381602Alex Deymo  EXPECT_EQ(metrics::ConnectionType::kUnknown,
33255e22b82af3a52218eaea66acc734ec25cfeab6Sen Jiang            GetConnectionType(ConnectionType::kUnknown,
34255e22b82af3a52218eaea66acc734ec25cfeab6Sen Jiang                              ConnectionTethering::kUnknown));
3538429cf76aaac8c499004b6f537229a26b381602Alex Deymo  EXPECT_EQ(metrics::ConnectionType::kEthernet,
36255e22b82af3a52218eaea66acc734ec25cfeab6Sen Jiang            GetConnectionType(ConnectionType::kEthernet,
37255e22b82af3a52218eaea66acc734ec25cfeab6Sen Jiang                              ConnectionTethering::kUnknown));
3838429cf76aaac8c499004b6f537229a26b381602Alex Deymo  EXPECT_EQ(metrics::ConnectionType::kWifi,
39255e22b82af3a52218eaea66acc734ec25cfeab6Sen Jiang            GetConnectionType(ConnectionType::kWifi,
40255e22b82af3a52218eaea66acc734ec25cfeab6Sen Jiang                              ConnectionTethering::kUnknown));
4138429cf76aaac8c499004b6f537229a26b381602Alex Deymo  EXPECT_EQ(metrics::ConnectionType::kWimax,
42255e22b82af3a52218eaea66acc734ec25cfeab6Sen Jiang            GetConnectionType(ConnectionType::kWimax,
43255e22b82af3a52218eaea66acc734ec25cfeab6Sen Jiang                              ConnectionTethering::kUnknown));
4438429cf76aaac8c499004b6f537229a26b381602Alex Deymo  EXPECT_EQ(metrics::ConnectionType::kBluetooth,
45255e22b82af3a52218eaea66acc734ec25cfeab6Sen Jiang            GetConnectionType(ConnectionType::kBluetooth,
46255e22b82af3a52218eaea66acc734ec25cfeab6Sen Jiang                              ConnectionTethering::kUnknown));
4738429cf76aaac8c499004b6f537229a26b381602Alex Deymo  EXPECT_EQ(metrics::ConnectionType::kCellular,
48255e22b82af3a52218eaea66acc734ec25cfeab6Sen Jiang            GetConnectionType(ConnectionType::kCellular,
49255e22b82af3a52218eaea66acc734ec25cfeab6Sen Jiang                              ConnectionTethering::kUnknown));
5038429cf76aaac8c499004b6f537229a26b381602Alex Deymo  EXPECT_EQ(metrics::ConnectionType::kTetheredEthernet,
51255e22b82af3a52218eaea66acc734ec25cfeab6Sen Jiang            GetConnectionType(ConnectionType::kEthernet,
52255e22b82af3a52218eaea66acc734ec25cfeab6Sen Jiang                              ConnectionTethering::kConfirmed));
5338429cf76aaac8c499004b6f537229a26b381602Alex Deymo  EXPECT_EQ(metrics::ConnectionType::kTetheredWifi,
54255e22b82af3a52218eaea66acc734ec25cfeab6Sen Jiang            GetConnectionType(ConnectionType::kWifi,
55255e22b82af3a52218eaea66acc734ec25cfeab6Sen Jiang                              ConnectionTethering::kConfirmed));
5638429cf76aaac8c499004b6f537229a26b381602Alex Deymo
5738429cf76aaac8c499004b6f537229a26b381602Alex Deymo  // Ensure that we don't report tethered ethernet unless it's confirmed.
5838429cf76aaac8c499004b6f537229a26b381602Alex Deymo  EXPECT_EQ(metrics::ConnectionType::kEthernet,
59255e22b82af3a52218eaea66acc734ec25cfeab6Sen Jiang            GetConnectionType(ConnectionType::kEthernet,
60255e22b82af3a52218eaea66acc734ec25cfeab6Sen Jiang                              ConnectionTethering::kNotDetected));
6138429cf76aaac8c499004b6f537229a26b381602Alex Deymo  EXPECT_EQ(metrics::ConnectionType::kEthernet,
62255e22b82af3a52218eaea66acc734ec25cfeab6Sen Jiang            GetConnectionType(ConnectionType::kEthernet,
63255e22b82af3a52218eaea66acc734ec25cfeab6Sen Jiang                              ConnectionTethering::kSuspected));
6438429cf76aaac8c499004b6f537229a26b381602Alex Deymo  EXPECT_EQ(metrics::ConnectionType::kEthernet,
65255e22b82af3a52218eaea66acc734ec25cfeab6Sen Jiang            GetConnectionType(ConnectionType::kEthernet,
66255e22b82af3a52218eaea66acc734ec25cfeab6Sen Jiang                              ConnectionTethering::kUnknown));
6738429cf76aaac8c499004b6f537229a26b381602Alex Deymo
6838429cf76aaac8c499004b6f537229a26b381602Alex Deymo  // Ditto for tethered wifi.
6938429cf76aaac8c499004b6f537229a26b381602Alex Deymo  EXPECT_EQ(metrics::ConnectionType::kWifi,
70255e22b82af3a52218eaea66acc734ec25cfeab6Sen Jiang            GetConnectionType(ConnectionType::kWifi,
71255e22b82af3a52218eaea66acc734ec25cfeab6Sen Jiang                              ConnectionTethering::kNotDetected));
7238429cf76aaac8c499004b6f537229a26b381602Alex Deymo  EXPECT_EQ(metrics::ConnectionType::kWifi,
73255e22b82af3a52218eaea66acc734ec25cfeab6Sen Jiang            GetConnectionType(ConnectionType::kWifi,
74255e22b82af3a52218eaea66acc734ec25cfeab6Sen Jiang                              ConnectionTethering::kSuspected));
7538429cf76aaac8c499004b6f537229a26b381602Alex Deymo  EXPECT_EQ(metrics::ConnectionType::kWifi,
76255e22b82af3a52218eaea66acc734ec25cfeab6Sen Jiang            GetConnectionType(ConnectionType::kWifi,
77255e22b82af3a52218eaea66acc734ec25cfeab6Sen Jiang                              ConnectionTethering::kUnknown));
7838429cf76aaac8c499004b6f537229a26b381602Alex Deymo}
7938429cf76aaac8c499004b6f537229a26b381602Alex Deymo
80a2591795edb1a4f4c751347daab16c70daad1274Alex DeymoTEST(MetricsUtilsTest, WallclockDurationHelper) {
81a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  FakeSystemState fake_system_state;
82a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  FakeClock fake_clock;
83a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  base::TimeDelta duration;
84a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  const std::string state_variable_key = "test-prefs";
85a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  FakePrefs fake_prefs;
86a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo
87a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  fake_system_state.set_clock(&fake_clock);
88a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  fake_system_state.set_prefs(&fake_prefs);
89a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo
90a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  // Initialize wallclock to 1 sec.
91a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  fake_clock.SetWallclockTime(base::Time::FromInternalValue(1000000));
92a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo
93a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  // First time called so no previous measurement available.
94a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  EXPECT_FALSE(metrics_utils::WallclockDurationHelper(&fake_system_state,
95a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo                                                      state_variable_key,
96a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo                                                      &duration));
97a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo
98a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  // Next time, we should get zero since the clock didn't advance.
99a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  EXPECT_TRUE(metrics_utils::WallclockDurationHelper(&fake_system_state,
100a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo                                                     state_variable_key,
101a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo                                                     &duration));
102a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  EXPECT_EQ(duration.InSeconds(), 0);
103a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo
104a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  // We can also call it as many times as we want with it being
105a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  // considered a failure.
106a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  EXPECT_TRUE(metrics_utils::WallclockDurationHelper(&fake_system_state,
107a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo                                                     state_variable_key,
108a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo                                                     &duration));
109a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  EXPECT_EQ(duration.InSeconds(), 0);
110a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  EXPECT_TRUE(metrics_utils::WallclockDurationHelper(&fake_system_state,
111a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo                                                     state_variable_key,
112a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo                                                     &duration));
113a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  EXPECT_EQ(duration.InSeconds(), 0);
114a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo
115a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  // Advance the clock one second, then we should get 1 sec on the
116a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  // next call and 0 sec on the subsequent call.
117a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  fake_clock.SetWallclockTime(base::Time::FromInternalValue(2000000));
118a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  EXPECT_TRUE(metrics_utils::WallclockDurationHelper(&fake_system_state,
119a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo                                                     state_variable_key,
120a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo                                                     &duration));
121a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  EXPECT_EQ(duration.InSeconds(), 1);
122a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  EXPECT_TRUE(metrics_utils::WallclockDurationHelper(&fake_system_state,
123a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo                                                     state_variable_key,
124a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo                                                     &duration));
125a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  EXPECT_EQ(duration.InSeconds(), 0);
126a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo
127a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  // Advance clock two seconds and we should get 2 sec and then 0 sec.
128a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  fake_clock.SetWallclockTime(base::Time::FromInternalValue(4000000));
129a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  EXPECT_TRUE(metrics_utils::WallclockDurationHelper(&fake_system_state,
130a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo                                                     state_variable_key,
131a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo                                                     &duration));
132a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  EXPECT_EQ(duration.InSeconds(), 2);
133a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  EXPECT_TRUE(metrics_utils::WallclockDurationHelper(&fake_system_state,
134a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo                                                     state_variable_key,
135a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo                                                     &duration));
136a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  EXPECT_EQ(duration.InSeconds(), 0);
137a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo
138a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  // There's a possibility that the wallclock can go backwards (NTP
139a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  // adjustments, for example) so check that we properly handle this
140a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  // case.
141a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  fake_clock.SetWallclockTime(base::Time::FromInternalValue(3000000));
142a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  EXPECT_FALSE(metrics_utils::WallclockDurationHelper(&fake_system_state,
143a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo                                                      state_variable_key,
144a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo                                                      &duration));
145a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  fake_clock.SetWallclockTime(base::Time::FromInternalValue(4000000));
146a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  EXPECT_TRUE(metrics_utils::WallclockDurationHelper(&fake_system_state,
147a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo                                                     state_variable_key,
148a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo                                                     &duration));
149a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  EXPECT_EQ(duration.InSeconds(), 1);
150a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo}
151a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo
152a2591795edb1a4f4c751347daab16c70daad1274Alex DeymoTEST(MetricsUtilsTest, MonotonicDurationHelper) {
153a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  int64_t storage = 0;
154a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  FakeSystemState fake_system_state;
155a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  FakeClock fake_clock;
156a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  base::TimeDelta duration;
157a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo
158a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  fake_system_state.set_clock(&fake_clock);
159a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo
160a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  // Initialize monotonic clock to 1 sec.
161a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  fake_clock.SetMonotonicTime(base::Time::FromInternalValue(1000000));
162a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo
163a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  // First time called so no previous measurement available.
164a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  EXPECT_FALSE(metrics_utils::MonotonicDurationHelper(&fake_system_state,
165a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo                                                      &storage,
166a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo                                                      &duration));
167a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo
168a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  // Next time, we should get zero since the clock didn't advance.
169a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  EXPECT_TRUE(metrics_utils::MonotonicDurationHelper(&fake_system_state,
170a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo                                                     &storage,
171a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo                                                     &duration));
172a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  EXPECT_EQ(duration.InSeconds(), 0);
173a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo
174a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  // We can also call it as many times as we want with it being
175a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  // considered a failure.
176a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  EXPECT_TRUE(metrics_utils::MonotonicDurationHelper(&fake_system_state,
177a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo                                                     &storage,
178a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo                                                     &duration));
179a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  EXPECT_EQ(duration.InSeconds(), 0);
180a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  EXPECT_TRUE(metrics_utils::MonotonicDurationHelper(&fake_system_state,
181a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo                                                     &storage,
182a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo                                                     &duration));
183a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  EXPECT_EQ(duration.InSeconds(), 0);
184a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo
185a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  // Advance the clock one second, then we should get 1 sec on the
186a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  // next call and 0 sec on the subsequent call.
187a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  fake_clock.SetMonotonicTime(base::Time::FromInternalValue(2000000));
188a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  EXPECT_TRUE(metrics_utils::MonotonicDurationHelper(&fake_system_state,
189a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo                                                     &storage,
190a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo                                                     &duration));
191a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  EXPECT_EQ(duration.InSeconds(), 1);
192a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  EXPECT_TRUE(metrics_utils::MonotonicDurationHelper(&fake_system_state,
193a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo                                                     &storage,
194a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo                                                     &duration));
195a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  EXPECT_EQ(duration.InSeconds(), 0);
196a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo
197a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  // Advance clock two seconds and we should get 2 sec and then 0 sec.
198a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  fake_clock.SetMonotonicTime(base::Time::FromInternalValue(4000000));
199a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  EXPECT_TRUE(metrics_utils::MonotonicDurationHelper(&fake_system_state,
200a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo                                                     &storage,
201a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo                                                     &duration));
202a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  EXPECT_EQ(duration.InSeconds(), 2);
203a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  EXPECT_TRUE(metrics_utils::MonotonicDurationHelper(&fake_system_state,
204a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo                                                     &storage,
205a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo                                                     &duration));
206a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo  EXPECT_EQ(duration.InSeconds(), 0);
207a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo}
208a2591795edb1a4f4c751347daab16c70daad1274Alex Deymo
20938429cf76aaac8c499004b6f537229a26b381602Alex Deymo}  // namespace metrics_utils
21038429cf76aaac8c499004b6f537229a26b381602Alex Deymo}  // namespace chromeos_update_engine
211