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 "src/tracing/test/api_test_support.h"
18
19 #include "perfetto/base/proc_utils.h"
20 #include "perfetto/base/time.h"
21 #include "perfetto/ext/base/temp_file.h"
22 #include "src/tracing/internal/tracing_muxer_impl.h"
23
24 #include <sstream>
25
26 #if PERFETTO_BUILDFLAG(PERFETTO_IPC)
27 #include "test/test_helper.h"
28 #endif
29
30 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
31 #include <Windows.h>
32 #endif
33
34 namespace perfetto {
35 namespace test {
36
37 #if PERFETTO_BUILDFLAG(PERFETTO_IPC)
38 namespace {
39
40 class InProcessSystemService {
41 public:
InProcessSystemService()42 InProcessSystemService()
43 : test_helper_(&task_runner_, TestHelper::Mode::kStartDaemons) {
44 // Will always start service because we explicitly set kStartDaemons.
45 test_helper_.StartServiceIfRequired();
46 }
47
48 private:
49 perfetto::base::TestTaskRunner task_runner_;
50 perfetto::TestHelper test_helper_;
51 };
52
53 } // namespace
54
StartSystemService()55 bool StartSystemService() {
56 static InProcessSystemService* system_service;
57
58 // If there already was a system service running, make sure the new one is
59 // running before tearing down the old one. This avoids a 1 second
60 // reconnection delay between each test since the connection to the new
61 // service succeeds immediately.
62 std::unique_ptr<InProcessSystemService> old_service(system_service);
63 system_service = new InProcessSystemService();
64
65 // Tear down the service at process exit to make sure temporary files get
66 // deleted.
67 static bool cleanup_registered;
68 if (!cleanup_registered) {
69 atexit([] { delete system_service; });
70 cleanup_registered = true;
71 }
72 return true;
73 }
74 #else // !PERFETTO_BUILDFLAG(PERFETTO_IPC)
75 bool StartSystemService() {
76 return false;
77 }
78 #endif // !PERFETTO_BUILDFLAG(PERFETTO_IPC)
79
GetCurrentProcessId()80 int32_t GetCurrentProcessId() {
81 return static_cast<int32_t>(base::GetProcessId());
82 }
83
SyncProducers()84 void SyncProducers() {
85 auto* muxer = reinterpret_cast<perfetto::internal::TracingMuxerImpl*>(
86 perfetto::internal::TracingMuxer::Get());
87 muxer->SyncProducersForTesting();
88 }
89
SetBatchCommitsDuration(uint32_t batch_commits_duration_ms,BackendType backend_type)90 void SetBatchCommitsDuration(uint32_t batch_commits_duration_ms,
91 BackendType backend_type) {
92 auto* muxer = reinterpret_cast<perfetto::internal::TracingMuxerImpl*>(
93 perfetto::internal::TracingMuxer::Get());
94 muxer->SetBatchCommitsDurationForTesting(batch_commits_duration_ms,
95 backend_type);
96 }
97
DisableReconnectLimit()98 void DisableReconnectLimit() {
99 auto* muxer = reinterpret_cast<perfetto::internal::TracingMuxerImpl*>(
100 perfetto::internal::TracingMuxer::Get());
101 muxer->SetMaxProducerReconnectionsForTesting(
102 std::numeric_limits<uint32_t>::max());
103 }
104
EnableDirectSMBPatching(BackendType backend_type)105 bool EnableDirectSMBPatching(BackendType backend_type) {
106 auto* muxer = reinterpret_cast<perfetto::internal::TracingMuxerImpl*>(
107 perfetto::internal::TracingMuxer::Get());
108 return muxer->EnableDirectSMBPatchingForTesting(backend_type);
109 }
110
CreateTempFile()111 TestTempFile CreateTempFile() {
112 TestTempFile res{};
113 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
114 char temp_file[255]{};
115 sprintf(temp_file, "%s\\perfetto-XXXXXX", getenv("TMP"));
116 PERFETTO_CHECK(_mktemp_s(temp_file, strlen(temp_file) + 1) == 0);
117 HANDLE handle =
118 ::CreateFileA(temp_file, GENERIC_READ | GENERIC_WRITE,
119 FILE_SHARE_DELETE | FILE_SHARE_READ, nullptr, CREATE_ALWAYS,
120 FILE_ATTRIBUTE_TEMPORARY, nullptr);
121 PERFETTO_CHECK(handle && handle != INVALID_HANDLE_VALUE);
122 res.fd = _open_osfhandle(reinterpret_cast<intptr_t>(handle), 0);
123 #elif PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
124 char temp_file[] = "/data/local/tmp/perfetto-XXXXXXXX";
125 res.fd = mkstemp(temp_file);
126 #else
127 char temp_file[] = "/tmp/perfetto-XXXXXXXX";
128 res.fd = mkstemp(temp_file);
129 #endif
130 res.path = temp_file;
131 PERFETTO_CHECK(res.fd > 0);
132 return res;
133 }
134
135 } // namespace test
136 } // namespace perfetto
137