blob: 88478e699a93bd1830eac35f3ddc8b8ab448067d [file] [log] [blame]
Erik Chen9d81094d2017-11-20 17:40:091// Copyright 2017 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CHROME_BROWSER_PROFILING_HOST_PROFILING_TEST_DRIVER_H_
6#define CHROME_BROWSER_PROFILING_HOST_PROFILING_TEST_DRIVER_H_
7
8#include <vector>
9
10#include "base/allocator/partition_allocator/partition_alloc.h"
11#include "base/macros.h"
12#include "base/memory/ref_counted_memory.h"
13#include "base/synchronization/waitable_event.h"
14#include "chrome/browser/profiling_host/profiling_process_host.h"
15
16namespace base {
17class Value;
18} // namespace base
19
20namespace profiling {
21
22// This class runs tests for the profiling service, a cross-platform,
23// multi-process component. Chrome on Android does not support browser_tests. It
24// does support content_browsertests, but those are not multi-process tests. On
25// Android, processes have to be started via the Activity mechanism, and the
26// test infrastructure does not support this.
27//
28// To avoid test-code duplication, all tests are pulled into this class.
29// browser_tests will directly call this class. The android
30// chrome_public_test_apk will invoke this class via a JNI shim. Since the
31// latter is not running within the gtest framework, this class cannot use
32// EXPECT* and ASSERT* macros. Instead, this class will return a bool indicating
33// success of the entire test. On failure, errors will be output via LOG(ERROR).
34// These will show up in the browser_tests output stream, and will be captured
35// by logcat [the Android logging facility]. The latter is already the canonical
36// mechanism for investigating test failures.
37//
38// Note: Outputting to stderr will not have the desired effect, since that is
39// not captured by logcat.
40class ProfilingTestDriver {
41 public:
42 struct Options {
43 // The profiling mode to test.
44 ProfilingProcessHost::Mode mode;
45
Erik Chen3303fd0232018-01-11 20:29:0546 // The stack profiling mode to test.
47 profiling::mojom::StackMode stack_mode;
48
Erik Chen9d81094d2017-11-20 17:40:0949 // Whether the caller has already started profiling with the given mode.
50 // TODO(erikchen): Implement and test the case where this member is false.
51 // Starting profiling is an asynchronous operation, so this requires adding
52 // some more plumbing. https://crbug.com/753218.
53 bool profiling_already_started;
54 };
55
56 ProfilingTestDriver();
57 ~ProfilingTestDriver();
58
59 // If this is called on the content::BrowserThread::UI thread, then the
60 // platform must support nested message loops. [This is currently not
61 // supported on Android].
62 //
63 // Returns whether the test run was successful. Expectation/Assertion failures
64 // will be printed via LOG(ERROR).
65 bool RunTest(const Options& options);
66
67 private:
68 // Populates |initialization_success_| with the result of
69 // |RunInitializationOnUIThread|, and then signals |wait_for_ui_thread_|.
Erik Chen3303fd0232018-01-11 20:29:0570 void CheckOrStartProfilingOnUIThreadAndSignal();
Erik Chen9d81094d2017-11-20 17:40:0971
72 // If profiling is expected to already be started, confirm it.
73 // Otherwise, start profiling with the given mode.
74 bool CheckOrStartProfiling();
75
76 // Performs allocations. These are expected to be profiled.
77 void MakeTestAllocations();
78
79 // Collects a trace that contains a heap dump. The result is stored in
80 // |serialized_trace_|.
81 //
82 // When |synchronous| is true, this method spins a nested message loop. When
83 // |synchronous| is false, this method posts some tasks that will eventually
84 // signal |wait_for_ui_thread_|.
85 void CollectResults(bool synchronous);
86
erikchen872446d2017-11-29 00:34:4087 void TraceFinished(base::Closure closure,
88 bool success,
89 std::string trace_json);
90
Erik Chen9d81094d2017-11-20 17:40:0991 bool ValidateBrowserAllocations(base::Value* dump_json);
92 bool ValidateRendererAllocations(base::Value* dump_json);
93
Erik Chen3303fd0232018-01-11 20:29:0594 bool ShouldProfileBrowser();
95 bool HasPseudoFrames();
96
Erik Chen9d81094d2017-11-20 17:40:0997 Options options_;
98
99 // Allocations made by this class. Intentionally leaked, since deallocating
100 // them would trigger a large number of IPCs, which is slow.
101 std::vector<char*> leaks_;
102
103 // Sum of size of all variadic allocations.
104 size_t total_variadic_allocations_ = 0;
105
106 // Use to make PA allocations, which should also be shimmed.
107 base::PartitionAllocatorGeneric partition_allocator_;
108
109 // Contains nothing until |CollectResults| has been called.
erikchen872446d2017-11-29 00:34:40110 std::string serialized_trace_;
Erik Chen9d81094d2017-11-20 17:40:09111
112 // Whether the test was invoked on the ui thread.
113 bool running_on_ui_thread_ = true;
114
115 // Whether an error has occurred.
116 bool initialization_success_ = false;
117
Erik Chen3303fd0232018-01-11 20:29:05118 // When |true|, initialization will wait for the allocator shim to enable
119 // before continuing.
120 bool wait_for_profiling_to_start_ = false;
121
Erik Chen9d81094d2017-11-20 17:40:09122 base::WaitableEvent wait_for_ui_thread_;
123
124 DISALLOW_COPY_AND_ASSIGN(ProfilingTestDriver);
125};
126
127} // namespace profiling
128
129#endif // CHROME_BROWSER_PROFILING_HOST_PROFILING_TEST_DRIVER_H_