1 /*
2  * Copyright (C) 2020 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 "src/traced/probes/common/cpu_freq_info_for_testing.h"
18 
19 #include <algorithm>
20 #include <memory>
21 
22 #include "perfetto/ext/base/file_utils.h"
23 #include "perfetto/ext/base/scoped_file.h"
24 #include "perfetto/ext/base/temp_file.h"
25 
26 namespace perfetto {
27 
28 namespace {
29 
30 const char kCpuFrequenciesAndroidLittleCore[] =
31     "300000 576000 748800 998400 1209600 1324800 1516800 1612800 1708800 \n";
32 
33 const char kCpuBoostFrequenciesAndroidLittleCore[] = "\n";
34 
35 const char kCpuFrequenciesAndroidBigCore[] =
36     "300000 652800 825600 979200 1132800 1363200 1536000 1747200 1843200 "
37     "1996800 \n";
38 
39 const char kCpuBoostFrequenciesAndroidBigCore[] = "2803200 \n";
40 
41 }  // namespace
42 
CpuFreqInfoForTesting()43 CpuFreqInfoForTesting::CpuFreqInfoForTesting()
44     : fake_cpu_dir_(base::TempDir::Create()) {
45   // Create a subset of /sys/devices/system/cpu.
46   AddDir("cpuidle");
47   AddDir("cpu0");
48   AddDir("cpu0/cpufreq");
49   AddFile("cpu0/cpufreq/scaling_available_frequencies",
50           kCpuFrequenciesAndroidLittleCore);
51   AddFile("cpu0/cpufreq/scaling_boost_frequencies",
52           kCpuBoostFrequenciesAndroidLittleCore);
53   AddDir("cpufreq");
54   AddDir("cpu1");
55   AddDir("cpu1/cpufreq");
56   AddFile("cpu1/cpufreq/scaling_available_frequencies",
57           kCpuFrequenciesAndroidBigCore);
58   AddFile("cpu1/cpufreq/scaling_boost_frequencies",
59           kCpuBoostFrequenciesAndroidBigCore);
60   AddDir("power");
61 }
62 
~CpuFreqInfoForTesting()63 CpuFreqInfoForTesting::~CpuFreqInfoForTesting() {
64   for (auto path : files_to_remove_)
65     PERFETTO_CHECK(remove(AbsolutePath(path).c_str()) == 0);
66   std::reverse(dirs_to_remove_.begin(), dirs_to_remove_.end());
67   for (auto path : dirs_to_remove_)
68     base::Rmdir(AbsolutePath(path));
69 }
70 
GetInstance()71 std::unique_ptr<CpuFreqInfo> CpuFreqInfoForTesting::GetInstance() {
72   return std::unique_ptr<CpuFreqInfo>(new CpuFreqInfo(fake_cpu_dir_.path()));
73 }
74 
AddDir(std::string path)75 void CpuFreqInfoForTesting::AddDir(std::string path) {
76   dirs_to_remove_.push_back(path);
77   base::Mkdir(AbsolutePath(path).c_str());
78 }
79 
AddFile(std::string path,std::string content)80 void CpuFreqInfoForTesting::AddFile(std::string path, std::string content) {
81   files_to_remove_.push_back(path);
82   base::ScopedFile fd(
83       base::OpenFile(AbsolutePath(path), O_WRONLY | O_CREAT | O_TRUNC, 0600));
84   PERFETTO_CHECK(base::WriteAll(fd.get(), content.c_str(), content.size()) ==
85                  static_cast<ssize_t>(content.size()));
86 }
87 
AbsolutePath(std::string path)88 std::string CpuFreqInfoForTesting::AbsolutePath(std::string path) {
89   return fake_cpu_dir_.path() + "/" + path;
90 }
91 
92 }  // namespace perfetto
93