• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 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 "common/debug.h"
18 #include "maintenance/controller.h"
19 
20 #include "db/file_models.h"
21 #include "db/models.h"
22 
23 #include <cstdio>
24 #include <filesystem>
25 #include <fstream>
26 #include <string>
27 #include <vector>
28 
29 #include <android-base/file.h>
30 #include <gtest/gtest.h>
31 #include <gmock/gmock.h>
32 
33 using ::testing::Return;
34 using ::testing::_;
35 using ::testing::SaveArg;
36 using ::testing::SaveArgPointee;
37 
38 namespace iorap::maintenance {
39 
GetTestDataPath(const std::string & fn)40 static std::string GetTestDataPath(const std::string& fn) {
41   static std::string exec_dir = android::base::GetExecutableDirectory();
42   return exec_dir + "/tests/src/maintenance/testdata/" + fn;
43 }
44 
45 class MockExec : public IExec {
46  public:
47   MOCK_METHOD(int,
48               Execve,
49               (const std::string& pathname, std::vector<std::string>& argv_vec, char *const envp[]),
50               (override));
51 
52   MOCK_METHOD(pid_t, Fork, (), (override));
53 };
54 
55 class ControllerTest: public ::testing::Test {
56  protected:
SetUp()57   void SetUp() override {
58     // The db is a fake db with the following tables:
59     //
60     // packages:
61     // id, name, version
62     // 1, com.android.settings, 1
63     // 2, com.yawanng, 1
64     //
65     // activities:
66     // id, name
67     // 1, Setting
68     // 2, yawanng
69     //
70     // app_launch_histories:
71     // id, activity_id, temperature, trace_enabled, readahead_enabled, intent_start_ns, total_time_ns, report_fully_drawn_ns
72     // 1, 1, 1, 1, 1, 1, 2, NULL
73     // 2, 1, 1, 1, 1, NULL, 4, 5
74     // 3, 1, 1, 1, 1, 3, NULL, NULL
75     // 4, 1, 1, 1, 1, 3, 7, 8
76     // 5, 1, 1, 0, 1, 4, 9, 10
77     // 6, 1, 2, 1, 1, 5, 11, 12
78     // 7, 2, 1, 1, 1, 6, 21, 22
79     // 8, 2, 1, 1, 1, 7, 22, 23
80     //
81     // raw_traces:
82     // id, history_id, file_path
83     // 1, 1, 1.txt
84     // 2, 3, 3.txt
85     // 3, 4, 4.txt
86     // 4, 5, 5.txt
87     // 5, 6, 6.txt
88     // 6, 7, 7.txt
89     // 7, 8, 8.txt
90     db_path = GetTestDataPath("test_sqlite.db");
91   }
92 
93   std::string db_path;
94   TemporaryDir root_path;
95 };
96 
97 MATCHER_P(AreArgsExpected, compiled_trace_path, "") {
98   std::vector<std::string> expect =
99     { "1.txt",
100       "3.txt",
101       "4.txt",
102       "--timestamp_limit_ns", "2",
103       "--timestamp_limit_ns", "18446744073709551615",
104       "--timestamp_limit_ns", "8",
105       "--output-text",
106       "--output-proto", compiled_trace_path,
107       "--verbose" };
108   return arg == expect;
109 }
110 
TEST_F(ControllerTest,CompilationController)111 TEST_F(ControllerTest, CompilationController) {
112   auto mock_exec = std::make_shared<MockExec>();
113   iorap::db::SchemaModel db_schema = db::SchemaModel::GetOrCreate(db_path);
114   db::DbHandle db{db_schema.db()};
115 
116   setenv("IORAPD_ROOT_DIR", root_path.path ,1);
117   std::string compiled_trace_path = std::string(root_path.path) +
118       "/com.android.settings/1/Setting/compiled_traces/compiled_trace.pb";
119 
120   // No recompile
121   ControllerParameters params{
122     /*output_text=*/true,
123     /*inode_textcache=*/std::nullopt,
124     /*verbose=*/true,
125     /*recompile=*/false,
126     /*min_traces=*/3,
127     mock_exec};
128 
129   ON_CALL(*mock_exec, Fork())
130       .WillByDefault(Return(-2));
131 
132   EXPECT_CALL(*mock_exec,
133               Execve("/system/bin/iorap.cmd.compiler",
134                      AreArgsExpected(compiled_trace_path),
135                      nullptr))
136       .Times(2);
137 
138   CompileAppsOnDevice(db, params);
139 
140   // Recompile
141   ControllerParameters params2{
142     /*output_text=*/true,
143     /*inode_textcache=*/std::nullopt,
144     /*verbose=*/true,
145     /*recompile=*/true,
146     /*min_traces=*/3,
147     mock_exec};
148 
149   // Create a fake compiled trace file to test recompile.
150   std::ofstream tmp_file;
151   tmp_file.open(compiled_trace_path);
152   tmp_file.close();
153 
154   CompileAppsOnDevice(db, params2);
155 }
156 
157 }  // namespace iorap::maintenance
158