gtest_main.cpp revision dec43c18d06415a955b8f32355bca925be901905
1323e945313b190373b3fcfe578e25ee8390a76d3Yabin Cui/*
2323e945313b190373b3fcfe578e25ee8390a76d3Yabin Cui * Copyright (C) 2015 The Android Open Source Project
3323e945313b190373b3fcfe578e25ee8390a76d3Yabin Cui *
4323e945313b190373b3fcfe578e25ee8390a76d3Yabin Cui * Licensed under the Apache License, Version 2.0 (the "License");
5323e945313b190373b3fcfe578e25ee8390a76d3Yabin Cui * you may not use this file except in compliance with the License.
6323e945313b190373b3fcfe578e25ee8390a76d3Yabin Cui * You may obtain a copy of the License at
7323e945313b190373b3fcfe578e25ee8390a76d3Yabin Cui *
8323e945313b190373b3fcfe578e25ee8390a76d3Yabin Cui *      http://www.apache.org/licenses/LICENSE-2.0
9323e945313b190373b3fcfe578e25ee8390a76d3Yabin Cui *
10323e945313b190373b3fcfe578e25ee8390a76d3Yabin Cui * Unless required by applicable law or agreed to in writing, software
11323e945313b190373b3fcfe578e25ee8390a76d3Yabin Cui * distributed under the License is distributed on an "AS IS" BASIS,
12323e945313b190373b3fcfe578e25ee8390a76d3Yabin Cui * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13323e945313b190373b3fcfe578e25ee8390a76d3Yabin Cui * See the License for the specific language governing permissions and
14323e945313b190373b3fcfe578e25ee8390a76d3Yabin Cui * limitations under the License.
15323e945313b190373b3fcfe578e25ee8390a76d3Yabin Cui */
16323e945313b190373b3fcfe578e25ee8390a76d3Yabin Cui
17323e945313b190373b3fcfe578e25ee8390a76d3Yabin Cui#include <gtest/gtest.h>
18323e945313b190373b3fcfe578e25ee8390a76d3Yabin Cui
19be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui#include <memory>
20be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui
21be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui#include <android-base/file.h>
2266dd09e8e2407082ce93bf0784de641298131912Elliott Hughes#include <android-base/logging.h>
23be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui#include <android-base/test_utils.h>
24be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui#include <ziparchive/zip_archive.h>
25323e945313b190373b3fcfe578e25ee8390a76d3Yabin Cui
265896132e00c7e49d2468d7ebd5372654df29b872Yabin Cui#if defined(__ANDROID__)
275896132e00c7e49d2468d7ebd5372654df29b872Yabin Cui#include <sys/system_properties.h>
285896132e00c7e49d2468d7ebd5372654df29b872Yabin Cui#endif
295896132e00c7e49d2468d7ebd5372654df29b872Yabin Cui
30569f64afd3db2b43003978765b833669f99477d2Yabin Cui#include "get_test_data.h"
31be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui#include "read_elf.h"
32569f64afd3db2b43003978765b833669f99477d2Yabin Cui#include "utils.h"
33569f64afd3db2b43003978765b833669f99477d2Yabin Cui
34569f64afd3db2b43003978765b833669f99477d2Yabin Cuistatic std::string testdata_dir;
35569f64afd3db2b43003978765b833669f99477d2Yabin Cui
366acf8c67e949bb5a4642ff0035a49a459bca9022Yabin Cui#if defined(__ANDROID__)
37be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cuistatic const std::string testdata_section = ".testzipdata";
38be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui
39be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cuistatic bool ExtractTestDataFromElfSection() {
40be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui  if (!MkdirWithParents(testdata_dir)) {
41be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui    PLOG(ERROR) << "failed to create testdata_dir " << testdata_dir;
42be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui    return false;
43be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui  }
44be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui  std::string content;
45dec43c18d06415a955b8f32355bca925be901905Yabin Cui  ElfStatus result = ReadSectionFromElfFile("/proc/self/exe", testdata_section, &content);
46dec43c18d06415a955b8f32355bca925be901905Yabin Cui  if (result != ElfStatus::NO_ERROR) {
47dec43c18d06415a955b8f32355bca925be901905Yabin Cui    LOG(ERROR) << "failed to read section " << testdata_section
48dec43c18d06415a955b8f32355bca925be901905Yabin Cui               << ": " << result;
49be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui    return false;
50be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui  }
51be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui  TemporaryFile tmp_file;
52be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui  if (!android::base::WriteStringToFile(content, tmp_file.path)) {
53be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui    PLOG(ERROR) << "failed to write file " << tmp_file.path;
54be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui    return false;
55be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui  }
56be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui  ArchiveHelper ahelper(tmp_file.fd, tmp_file.path);
57be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui  if (!ahelper) {
58be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui    LOG(ERROR) << "failed to open archive " << tmp_file.path;
59be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui    return false;
60be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui  }
61be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui  ZipArchiveHandle& handle = ahelper.archive_handle();
62be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui  void* cookie;
63be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui  int ret = StartIteration(handle, &cookie, nullptr, nullptr);
64be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui  if (ret != 0) {
65be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui    LOG(ERROR) << "failed to start iterating zip entries";
66be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui    return false;
67be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui  }
688f680f60dc800bec880c5c35bfbc1ac36165e1f3Yabin Cui  std::unique_ptr<void, decltype(&EndIteration)> guard(cookie, EndIteration);
69be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui  ZipEntry entry;
70be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui  ZipString name;
71be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui  while (Next(cookie, &entry, &name) == 0) {
72be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui    std::string entry_name(name.name, name.name + name.name_length);
73be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui    std::string path = testdata_dir + entry_name;
74be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui    // Skip dir.
75be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui    if (path.back() == '/') {
76be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui      continue;
77be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui    }
78be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui    if (!MkdirWithParents(path)) {
79be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui      LOG(ERROR) << "failed to create dir for " << path;
80be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui      return false;
81be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui    }
82be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui    FileHelper fhelper = FileHelper::OpenWriteOnly(path);
83be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui    if (!fhelper) {
84be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui      PLOG(ERROR) << "failed to create file " << path;
85be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui      return false;
86be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui    }
87be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui    std::vector<uint8_t> data(entry.uncompressed_length);
88be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui    if (ExtractToMemory(handle, &entry, data.data(), data.size()) != 0) {
89be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui      LOG(ERROR) << "failed to extract entry " << entry_name;
90be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui      return false;
91be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui    }
92be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui    if (!android::base::WriteFully(fhelper.fd(), data.data(), data.size())) {
93be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui      LOG(ERROR) << "failed to write file " << path;
94be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui      return false;
95be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui    }
96be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui  }
97be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui  return true;
98be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui}
995896132e00c7e49d2468d7ebd5372654df29b872Yabin Cui
1005896132e00c7e49d2468d7ebd5372654df29b872Yabin Cuiclass SavedPerfHardenProperty {
1015896132e00c7e49d2468d7ebd5372654df29b872Yabin Cui public:
1025896132e00c7e49d2468d7ebd5372654df29b872Yabin Cui  SavedPerfHardenProperty() {
1035896132e00c7e49d2468d7ebd5372654df29b872Yabin Cui    __system_property_get("security.perf_harden", prop_value_);
1045896132e00c7e49d2468d7ebd5372654df29b872Yabin Cui    if (!android::base::ReadFileToString("/proc/sys/kernel/perf_event_paranoid",
1055896132e00c7e49d2468d7ebd5372654df29b872Yabin Cui                                    &paranoid_value_)) {
1065896132e00c7e49d2468d7ebd5372654df29b872Yabin Cui      PLOG(ERROR) << "failed to read /proc/sys/kernel/perf_event_paranoid";
1075896132e00c7e49d2468d7ebd5372654df29b872Yabin Cui    }
1085896132e00c7e49d2468d7ebd5372654df29b872Yabin Cui  }
1095896132e00c7e49d2468d7ebd5372654df29b872Yabin Cui
1105896132e00c7e49d2468d7ebd5372654df29b872Yabin Cui  ~SavedPerfHardenProperty() {
1115896132e00c7e49d2468d7ebd5372654df29b872Yabin Cui    if (strlen(prop_value_) != 0) {
1125896132e00c7e49d2468d7ebd5372654df29b872Yabin Cui      __system_property_set("security.perf_harden", prop_value_);
1135896132e00c7e49d2468d7ebd5372654df29b872Yabin Cui      // Sleep one second to wait for security.perf_harden changing
1145896132e00c7e49d2468d7ebd5372654df29b872Yabin Cui      // /proc/sys/kernel/perf_event_paranoid.
1155896132e00c7e49d2468d7ebd5372654df29b872Yabin Cui      sleep(1);
1165896132e00c7e49d2468d7ebd5372654df29b872Yabin Cui      std::string paranoid_value;
1175896132e00c7e49d2468d7ebd5372654df29b872Yabin Cui      if (!android::base::ReadFileToString("/proc/sys/kernel/perf_event_paranoid",
1185896132e00c7e49d2468d7ebd5372654df29b872Yabin Cui                                           &paranoid_value)) {
1195896132e00c7e49d2468d7ebd5372654df29b872Yabin Cui        PLOG(ERROR) << "failed to read /proc/sys/kernel/perf_event_paranoid";
1205896132e00c7e49d2468d7ebd5372654df29b872Yabin Cui        return;
1215896132e00c7e49d2468d7ebd5372654df29b872Yabin Cui      }
1225896132e00c7e49d2468d7ebd5372654df29b872Yabin Cui      if (paranoid_value_ != paranoid_value) {
1235896132e00c7e49d2468d7ebd5372654df29b872Yabin Cui        LOG(ERROR) << "failed to restore /proc/sys/kernel/perf_event_paranoid";
1245896132e00c7e49d2468d7ebd5372654df29b872Yabin Cui      }
1255896132e00c7e49d2468d7ebd5372654df29b872Yabin Cui    }
1265896132e00c7e49d2468d7ebd5372654df29b872Yabin Cui  }
1275896132e00c7e49d2468d7ebd5372654df29b872Yabin Cui
1285896132e00c7e49d2468d7ebd5372654df29b872Yabin Cui private:
1295896132e00c7e49d2468d7ebd5372654df29b872Yabin Cui  char prop_value_[PROP_VALUE_MAX];
1305896132e00c7e49d2468d7ebd5372654df29b872Yabin Cui  std::string paranoid_value_;
1315896132e00c7e49d2468d7ebd5372654df29b872Yabin Cui};
1325896132e00c7e49d2468d7ebd5372654df29b872Yabin Cui
1336acf8c67e949bb5a4642ff0035a49a459bca9022Yabin Cui#endif  // defined(__ANDROID__)
134be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui
135323e945313b190373b3fcfe578e25ee8390a76d3Yabin Cuiint main(int argc, char** argv) {
136323e945313b190373b3fcfe578e25ee8390a76d3Yabin Cui  InitLogging(argv, android::base::StderrLogger);
137323e945313b190373b3fcfe578e25ee8390a76d3Yabin Cui  testing::InitGoogleTest(&argc, argv);
1388f680f60dc800bec880c5c35bfbc1ac36165e1f3Yabin Cui  android::base::LogSeverity log_severity = android::base::WARNING;
139be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui
140569f64afd3db2b43003978765b833669f99477d2Yabin Cui  for (int i = 1; i < argc; ++i) {
141569f64afd3db2b43003978765b833669f99477d2Yabin Cui    if (strcmp(argv[i], "-t") == 0 && i + 1 < argc) {
142569f64afd3db2b43003978765b833669f99477d2Yabin Cui      testdata_dir = argv[i + 1];
143be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui      i++;
1448f680f60dc800bec880c5c35bfbc1ac36165e1f3Yabin Cui    } else if (strcmp(argv[i], "--log") == 0) {
1458f680f60dc800bec880c5c35bfbc1ac36165e1f3Yabin Cui      if (i + 1 < argc) {
1468f680f60dc800bec880c5c35bfbc1ac36165e1f3Yabin Cui        ++i;
1478f680f60dc800bec880c5c35bfbc1ac36165e1f3Yabin Cui        if (!GetLogSeverity(argv[i], &log_severity)) {
1488f680f60dc800bec880c5c35bfbc1ac36165e1f3Yabin Cui          LOG(ERROR) << "Unknown log severity: " << argv[i];
1498f680f60dc800bec880c5c35bfbc1ac36165e1f3Yabin Cui          return 1;
1508f680f60dc800bec880c5c35bfbc1ac36165e1f3Yabin Cui        }
1518f680f60dc800bec880c5c35bfbc1ac36165e1f3Yabin Cui      } else {
1528f680f60dc800bec880c5c35bfbc1ac36165e1f3Yabin Cui        LOG(ERROR) << "Missing argument for --log option.\n";
1538f680f60dc800bec880c5c35bfbc1ac36165e1f3Yabin Cui        return 1;
1548f680f60dc800bec880c5c35bfbc1ac36165e1f3Yabin Cui      }
155569f64afd3db2b43003978765b833669f99477d2Yabin Cui    }
156569f64afd3db2b43003978765b833669f99477d2Yabin Cui  }
1578f680f60dc800bec880c5c35bfbc1ac36165e1f3Yabin Cui  android::base::ScopedLogSeverity severity(log_severity);
158be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui
1596acf8c67e949bb5a4642ff0035a49a459bca9022Yabin Cui#if defined(__ANDROID__)
160be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui  std::unique_ptr<TemporaryDir> tmp_dir;
161be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui  if (!::testing::GTEST_FLAG(list_tests) && testdata_dir.empty()) {
162be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui    tmp_dir.reset(new TemporaryDir);
163be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui    testdata_dir = std::string(tmp_dir->path) + "/";
164be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui    if (!ExtractTestDataFromElfSection()) {
165be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui      LOG(ERROR) << "failed to extract test data from elf section";
166be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui      return 1;
167be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui    }
168be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui  }
1695896132e00c7e49d2468d7ebd5372654df29b872Yabin Cui
1705896132e00c7e49d2468d7ebd5372654df29b872Yabin Cui  // A cts test PerfEventParanoidTest.java is testing if
1715896132e00c7e49d2468d7ebd5372654df29b872Yabin Cui  // /proc/sys/kernel/perf_event_paranoid is 3, so restore perf_harden
1725896132e00c7e49d2468d7ebd5372654df29b872Yabin Cui  // value after current test to not break that test.
1735896132e00c7e49d2468d7ebd5372654df29b872Yabin Cui  SavedPerfHardenProperty saved_perf_harden;
174be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui#endif
1756acf8c67e949bb5a4642ff0035a49a459bca9022Yabin Cui
176be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui  if (!::testing::GTEST_FLAG(list_tests) && testdata_dir.empty()) {
177be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui    printf("Usage: %s -t <testdata_dir>\n", argv[0]);
178569f64afd3db2b43003978765b833669f99477d2Yabin Cui    return 1;
179569f64afd3db2b43003978765b833669f99477d2Yabin Cui  }
180569f64afd3db2b43003978765b833669f99477d2Yabin Cui  if (testdata_dir.back() != '/') {
181569f64afd3db2b43003978765b833669f99477d2Yabin Cui    testdata_dir.push_back('/');
182569f64afd3db2b43003978765b833669f99477d2Yabin Cui  }
183be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui  LOG(INFO) << "testdata is in " << testdata_dir;
184323e945313b190373b3fcfe578e25ee8390a76d3Yabin Cui  return RUN_ALL_TESTS();
185323e945313b190373b3fcfe578e25ee8390a76d3Yabin Cui}
186569f64afd3db2b43003978765b833669f99477d2Yabin Cui
187569f64afd3db2b43003978765b833669f99477d2Yabin Cuistd::string GetTestData(const std::string& filename) {
188569f64afd3db2b43003978765b833669f99477d2Yabin Cui  return testdata_dir + filename;
189569f64afd3db2b43003978765b833669f99477d2Yabin Cui}
190b1a885b014540a2f7798b5a35ea0f0ec150d93eeYabin Cui
191b1a885b014540a2f7798b5a35ea0f0ec150d93eeYabin Cuiconst std::string& GetTestDataDir() {
192b1a885b014540a2f7798b5a35ea0f0ec150d93eeYabin Cui  return testdata_dir;
193b1a885b014540a2f7798b5a35ea0f0ec150d93eeYabin Cui}
194