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