• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 "odr_metrics.h"
18 
19 #include <unistd.h>
20 
21 #include <chrono>
22 #include <cstdint>
23 #include <fstream>
24 #include <memory>
25 #include <string>
26 #include <thread>
27 
28 #include "base/casts.h"
29 #include "base/common_art_test.h"
30 #include "odr_metrics_record.h"
31 
32 namespace art {
33 namespace odrefresh {
34 
35 using std::chrono_literals::operator""ms;  // NOLINT
36 
37 class OdrMetricsTest : public CommonArtTest {
38  public:
SetUp()39   void SetUp() override {
40     CommonArtTest::SetUp();
41 
42     scratch_dir_ = std::make_unique<ScratchDir>();
43     metrics_file_path_ = scratch_dir_->GetPath() + "/metrics.xml";
44     cache_directory_ = scratch_dir_->GetPath() + "/dir";
45     mkdir(cache_directory_.c_str(), S_IRWXU);
46   }
47 
TearDown()48   void TearDown() override {
49     scratch_dir_.reset();
50   }
51 
MetricsFileExists() const52   bool MetricsFileExists() const {
53     const char* path = metrics_file_path_.c_str();
54     return OS::FileExists(path);
55   }
56 
GetCacheDirectory() const57   const std::string GetCacheDirectory() const { return cache_directory_; }
GetMetricsFilePath() const58   const std::string GetMetricsFilePath() const { return metrics_file_path_; }
59 
60  protected:
61   std::unique_ptr<ScratchDir> scratch_dir_;
62   std::string metrics_file_path_;
63   std::string cache_directory_;
64 };
65 
TEST_F(OdrMetricsTest,MetricsFileIsNotCreatedIfNotEnabled)66 TEST_F(OdrMetricsTest, MetricsFileIsNotCreatedIfNotEnabled) {
67   // Metrics file is (potentially) written in OdrMetrics destructor.
68   {
69     OdrMetrics metrics(GetCacheDirectory(), GetMetricsFilePath());
70     metrics.SetArtApexVersion(99);
71     metrics.SetTrigger(OdrMetrics::Trigger::kApexVersionMismatch);
72     metrics.SetStage(OdrMetrics::Stage::kCheck);
73     metrics.SetStatus(OdrMetrics::Status::kNoSpace);
74   }
75   EXPECT_FALSE(MetricsFileExists());
76 }
77 
TEST_F(OdrMetricsTest,MetricsFileIsCreatedIfEnabled)78 TEST_F(OdrMetricsTest, MetricsFileIsCreatedIfEnabled) {
79   // Metrics file is (potentially) written in OdrMetrics destructor.
80   {
81     OdrMetrics metrics(GetCacheDirectory(), GetMetricsFilePath());
82     metrics.SetEnabled(true);
83     metrics.SetArtApexVersion(101);
84     metrics.SetTrigger(OdrMetrics::Trigger::kDexFilesChanged);
85     metrics.SetStage(OdrMetrics::Stage::kCheck);
86     metrics.SetStatus(OdrMetrics::Status::kNoSpace);
87   }
88   EXPECT_TRUE(MetricsFileExists());
89 }
90 
TEST_F(OdrMetricsTest,CacheSpaceValuesAreUpdated)91 TEST_F(OdrMetricsTest, CacheSpaceValuesAreUpdated) {
92   OdrMetrics metrics(GetCacheDirectory(), GetMetricsFilePath());
93   metrics.CaptureSpaceFreeEnd();
94   OdrMetricsRecord record = metrics.ToRecord();
95   EXPECT_GT(record.cache_space_free_start_mib, 0);
96   EXPECT_GT(record.cache_space_free_end_mib, 0);
97 }
98 
TEST_F(OdrMetricsTest,PrimaryBcpResultWithValue)99 TEST_F(OdrMetricsTest, PrimaryBcpResultWithValue) {
100   OdrMetrics metrics(GetCacheDirectory(), GetMetricsFilePath());
101   metrics.SetDex2OatResult(
102       OdrMetrics::Stage::kPrimaryBootClasspath,
103       100,
104       ExecResult{.status = ExecResult::Status::kExited, .exit_code = 0, .signal = 0});
105   metrics.SetBcpCompilationType(OdrMetrics::Stage::kPrimaryBootClasspath,
106                                 OdrMetrics::BcpCompilationType::kMainline);
107   OdrMetricsRecord record = metrics.ToRecord();
108 
109   EXPECT_EQ(record.primary_bcp_compilation_millis, 100);
110   EXPECT_EQ(record.primary_bcp_dex2oat_result.status, ExecResult::Status::kExited);
111   EXPECT_EQ(record.primary_bcp_dex2oat_result.exit_code, 0);
112   EXPECT_EQ(record.primary_bcp_dex2oat_result.signal, 0);
113   EXPECT_EQ(record.primary_bcp_compilation_type,
114             static_cast<int32_t>(OdrMetrics::BcpCompilationType::kMainline));
115 
116   EXPECT_EQ(record.secondary_bcp_compilation_millis, 0);
117   EXPECT_EQ(record.secondary_bcp_dex2oat_result.status, kExecResultNotRun);
118   EXPECT_EQ(record.secondary_bcp_compilation_type,
119             static_cast<int32_t>(OdrMetrics::BcpCompilationType::kUnknown));
120 
121   EXPECT_EQ(record.system_server_compilation_millis, 0);
122   EXPECT_EQ(record.system_server_dex2oat_result.status, kExecResultNotRun);
123 }
124 
TEST_F(OdrMetricsTest,PrimaryBcpResultWithoutValue)125 TEST_F(OdrMetricsTest, PrimaryBcpResultWithoutValue) {
126   OdrMetrics metrics(GetCacheDirectory(), GetMetricsFilePath());
127 
128   OdrMetricsRecord record = metrics.ToRecord();
129   EXPECT_EQ(record.primary_bcp_dex2oat_result.status, kExecResultNotRun);
130   EXPECT_EQ(record.primary_bcp_dex2oat_result.exit_code, -1);
131   EXPECT_EQ(record.primary_bcp_dex2oat_result.signal, 0);
132 }
133 
TEST_F(OdrMetricsTest,SecondaryBcpResultWithValue)134 TEST_F(OdrMetricsTest, SecondaryBcpResultWithValue) {
135   OdrMetrics metrics(GetCacheDirectory(), GetMetricsFilePath());
136   metrics.SetDex2OatResult(
137       OdrMetrics::Stage::kPrimaryBootClasspath,
138       100,
139       ExecResult{.status = ExecResult::Status::kExited, .exit_code = 0, .signal = 0});
140   metrics.SetBcpCompilationType(OdrMetrics::Stage::kPrimaryBootClasspath,
141                                 OdrMetrics::BcpCompilationType::kMainline);
142   metrics.SetDex2OatResult(
143       OdrMetrics::Stage::kSecondaryBootClasspath,
144       200,
145       ExecResult{.status = ExecResult::Status::kTimedOut, .exit_code = 3, .signal = 0});
146   metrics.SetBcpCompilationType(OdrMetrics::Stage::kSecondaryBootClasspath,
147                                 OdrMetrics::BcpCompilationType::kPrimaryAndMainline);
148   OdrMetricsRecord record = metrics.ToRecord();
149 
150   EXPECT_EQ(record.primary_bcp_compilation_millis, 100);
151   EXPECT_EQ(record.primary_bcp_dex2oat_result.status, ExecResult::Status::kExited);
152   EXPECT_EQ(record.primary_bcp_dex2oat_result.exit_code, 0);
153   EXPECT_EQ(record.primary_bcp_dex2oat_result.signal, 0);
154   EXPECT_EQ(record.primary_bcp_compilation_type,
155             static_cast<int32_t>(OdrMetrics::BcpCompilationType::kMainline));
156 
157   EXPECT_EQ(record.secondary_bcp_compilation_millis, 200);
158   EXPECT_EQ(record.secondary_bcp_dex2oat_result.status, ExecResult::Status::kTimedOut);
159   EXPECT_EQ(record.secondary_bcp_dex2oat_result.exit_code, 3);
160   EXPECT_EQ(record.secondary_bcp_dex2oat_result.signal, 0);
161   EXPECT_EQ(record.secondary_bcp_compilation_type,
162             static_cast<int32_t>(OdrMetrics::BcpCompilationType::kPrimaryAndMainline));
163 
164   EXPECT_EQ(record.system_server_compilation_millis, 0);
165   EXPECT_EQ(record.system_server_dex2oat_result.status, kExecResultNotRun);
166 }
167 
TEST_F(OdrMetricsTest,SystemServerResultWithValue)168 TEST_F(OdrMetricsTest, SystemServerResultWithValue) {
169   OdrMetrics metrics(GetCacheDirectory(), GetMetricsFilePath());
170   metrics.SetDex2OatResult(
171       OdrMetrics::Stage::kPrimaryBootClasspath,
172       100,
173       ExecResult{.status = ExecResult::Status::kExited, .exit_code = 0, .signal = 0});
174   metrics.SetDex2OatResult(
175       OdrMetrics::Stage::kSecondaryBootClasspath,
176       200,
177       ExecResult{.status = ExecResult::Status::kTimedOut, .exit_code = 3, .signal = 0});
178   metrics.SetDex2OatResult(
179       OdrMetrics::Stage::kSystemServerClasspath,
180       300,
181       ExecResult{.status = ExecResult::Status::kSignaled, .exit_code = 2, .signal = 9});
182   OdrMetricsRecord record = metrics.ToRecord();
183 
184   EXPECT_EQ(record.primary_bcp_compilation_millis, 100);
185   EXPECT_EQ(record.primary_bcp_dex2oat_result.status, ExecResult::Status::kExited);
186   EXPECT_EQ(record.primary_bcp_dex2oat_result.exit_code, 0);
187   EXPECT_EQ(record.primary_bcp_dex2oat_result.signal, 0);
188 
189   EXPECT_EQ(record.secondary_bcp_compilation_millis, 200);
190   EXPECT_EQ(record.secondary_bcp_dex2oat_result.status, ExecResult::Status::kTimedOut);
191   EXPECT_EQ(record.secondary_bcp_dex2oat_result.exit_code, 3);
192   EXPECT_EQ(record.secondary_bcp_dex2oat_result.signal, 0);
193 
194   EXPECT_EQ(record.system_server_compilation_millis, 300);
195   EXPECT_EQ(record.system_server_dex2oat_result.status, ExecResult::Status::kSignaled);
196   EXPECT_EQ(record.system_server_dex2oat_result.exit_code, 2);
197   EXPECT_EQ(record.system_server_dex2oat_result.signal, 9);
198 }
199 
200 }  // namespace odrefresh
201 }  // namespace art
202