• 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 "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