• 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 "compiler/compiler.h"
19 #include "inode2filename/inode_resolver.h"
20 
21 #include <cstdio>
22 #include <fstream>
23 #include <string>
24 #include <vector>
25 
26 #include <android-base/file.h>
27 #include <gtest/gtest.h>
28 
29 namespace iorap::compiler {
30 
GetTestDataPath(const std::string & fn)31 static std::string GetTestDataPath(const std::string& fn) {
32   static std::string exec_dir = android::base::GetExecutableDirectory();
33   return exec_dir + "/tests/src/compiler/testdata/" + fn;
34 }
35 
36 class CompilerTest: public ::testing::Test{
37  protected:
SetUp()38   void SetUp() override {
39     ir_dependencies.data_source = inode2filename::DataSourceKind::kTextCache;
40     ir_dependencies.text_cache_filename = GetTestDataPath("common_textcache");
41     ir_dependencies.verify = inode2filename::VerifyKind::kNone;  // required for determinism.
42     ir_dependencies.root_directories.push_back("/system");
43     ir_dependencies.root_directories.push_back("/apex");
44     ir_dependencies.root_directories.push_back("/data");
45     ir_dependencies.root_directories.push_back("/vendor");
46     ir_dependencies.root_directories.push_back("/product");
47     ir_dependencies.root_directories.push_back("/metadata");
48   }
49 
50   inode2filename::InodeResolverDependencies ir_dependencies;
51 };
52 
TEST_F(CompilerTest,SingleTraceDuration)53 TEST_F(CompilerTest, SingleTraceDuration) {
54   std::vector<std::string> input_file_names{GetTestDataPath("common_perfetto_trace.pb")};
55   std::vector<uint64_t> timestamp_limit_ns{260390390018596UL};
56   TemporaryFile tmp_file;
57   char* output_file_name = tmp_file.path;
58   bool output_proto = false;
59 
60 
61   std::vector<CompilationInput> perfetto_traces =
62       MakeCompilationInputs(input_file_names, timestamp_limit_ns);
63   bool result = PerformCompilation(perfetto_traces,
64                                    output_file_name,
65                                    output_proto,
66                                    /*blacklist_filter*/std::nullopt,
67                                    ir_dependencies);
68   std::ifstream ifs(output_file_name);
69 
70   // The extra paren is needed to avoid compilation error:
71   // "parentheses were disambiguated as a function declaration".
72   std::string content{std::istreambuf_iterator<char>(ifs),
73     std::istreambuf_iterator<char>()};
74 
75   EXPECT_EQ(result, true);
76   EXPECT_EQ(content, "{filename:\"/product/app/CalculatorGooglePrebuilt/"
77             "CalculatorGooglePrebuilt.apk\","
78             "timestamp:7641303,"
79             "add_to_page_cache:1,"
80             "index:540}\n");
81 }
82 
TEST_F(CompilerTest,MultiTraceDuration)83 TEST_F(CompilerTest, MultiTraceDuration) {
84   std::vector<std::string> input_file_names{GetTestDataPath("common_perfetto_trace.pb"),
85     GetTestDataPath("common_perfetto_trace2.pb")};
86   std::vector<uint64_t> timestamp_limit_ns{260390390018596UL, 333215840452006UL};
87   TemporaryFile tmp_file;
88   char* output_file_name = tmp_file.path;
89   bool output_proto = false;
90 
91   std::vector<CompilationInput> perfetto_traces =
92       MakeCompilationInputs(input_file_names, timestamp_limit_ns);
93   bool result = PerformCompilation(perfetto_traces,
94                                    output_file_name,
95                                    output_proto,
96                                    /*blacklist_filter*/std::nullopt,
97                                    ir_dependencies);
98   std::ifstream ifs(output_file_name);
99   std::string content{std::istreambuf_iterator<char>(ifs),
100     std::istreambuf_iterator<char>()};
101 
102   EXPECT_EQ(result, true);
103   EXPECT_EQ(content, "{filename:\"/apex/com.android.art/lib64/libperfetto_hprof.so\","
104             "timestamp:4388958,"
105             "add_to_page_cache:1,"
106             "index:227}\n"
107             "{filename:\"/product/app/CalculatorGooglePrebuilt/"
108             "CalculatorGooglePrebuilt.apk\","
109             "timestamp:7641303,"
110             "add_to_page_cache:1,"
111             "index:540}\n");
112 }
113 
TEST_F(CompilerTest,NoTraceDuration)114 TEST_F(CompilerTest, NoTraceDuration) {
115   std::vector<std::string> input_file_names{GetTestDataPath("common_perfetto_trace.pb")};
116   TemporaryFile tmp_file;
117   char* output_file_name = tmp_file.path;
118   bool output_proto = false;
119 
120   std::vector<CompilationInput> perfetto_traces =
121       MakeCompilationInputs(input_file_names, /* timestamp_limit_ns= */{});
122   bool result = PerformCompilation(perfetto_traces,
123                                    output_file_name,
124                                    output_proto,
125                                    /*blacklist_filter*/std::nullopt,
126                                    ir_dependencies);
127   std::ifstream ifs(output_file_name);
128   size_t line_num = std::count((std::istreambuf_iterator<char>(ifs)),
129                                (std::istreambuf_iterator<char>()),
130                                '\n');
131 
132   EXPECT_EQ(result, true);
133   EXPECT_EQ(line_num, 1675UL);
134 }
135 
TEST_F(CompilerTest,BlacklistFilterArtFiles)136 TEST_F(CompilerTest, BlacklistFilterArtFiles) {
137   std::vector<std::string> input_file_names{GetTestDataPath("common_perfetto_trace.pb")};
138   TemporaryFile tmp_file;
139   char* output_file_name = tmp_file.path;
140   bool output_proto = false;
141 
142   std::string blacklist_filter = "[.](art|oat|odex|vdex|dex)$";
143 
144   // iorap.cmd.compiler -op output.pb -it common_textcache -ot
145   //                    --blacklist-filter "[.](art|oat|odex|vdex|dex)$" common_perfetto_trace.pb
146 
147   std::vector<CompilationInput> perfetto_traces =
148       MakeCompilationInputs(input_file_names, /* timestamp_limit_ns= */{});
149   bool result = PerformCompilation(perfetto_traces,
150                                    output_file_name,
151                                    output_proto,
152                                      blacklist_filter,
153                                    ir_dependencies);
154   std::ifstream ifs(output_file_name);
155   size_t line_num = std::count((std::istreambuf_iterator<char>(ifs)),
156                                (std::istreambuf_iterator<char>()),
157                                '\n');
158 
159   EXPECT_EQ(result, true);
160   EXPECT_EQ(line_num, 1617UL);
161 }
162 }  // namespace iorap::compiler
163