blob: 6aaa8ed6d24dca9001025f7ba77d4f5278b3adfb [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
46 // Whether the caller has already started profiling with the given mode.
47 // TODO(erikchen): Implement and test the case where this member is false.
48 // Starting profiling is an asynchronous operation, so this requires adding
49 // some more plumbing. https://crbug.com/753218.
50 bool profiling_already_started;
51 };
52
53 ProfilingTestDriver();
54 ~ProfilingTestDriver();
55
56 // If this is called on the content::BrowserThread::UI thread, then the
57 // platform must support nested message loops. [This is currently not
58 // supported on Android].
59 //
60 // Returns whether the test run was successful. Expectation/Assertion failures
61 // will be printed via LOG(ERROR).
62 bool RunTest(const Options& options);
63
64 private:
65 // Populates |initialization_success_| with the result of
66 // |RunInitializationOnUIThread|, and then signals |wait_for_ui_thread_|.
67 void RunInitializationOnUIThreadAndSignal();
68
69 // Starts profiling. Makes allocations.
70 bool RunInitializationOnUIThread();
71
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
94 Options options_;
95
96 // Allocations made by this class. Intentionally leaked, since deallocating
97 // them would trigger a large number of IPCs, which is slow.
98 std::vector<char*> leaks_;
99
100 // Sum of size of all variadic allocations.
101 size_t total_variadic_allocations_ = 0;
102
103 // Use to make PA allocations, which should also be shimmed.
104 base::PartitionAllocatorGeneric partition_allocator_;
105
106 // Contains nothing until |CollectResults| has been called.
erikchen872446d2017-11-29 00:34:40107 std::string serialized_trace_;
Erik Chen9d81094d2017-11-20 17:40:09108
109 // Whether the test was invoked on the ui thread.
110 bool running_on_ui_thread_ = true;
111
112 // Whether an error has occurred.
113 bool initialization_success_ = false;
114
115 base::WaitableEvent wait_for_ui_thread_;
116
117 DISALLOW_COPY_AND_ASSIGN(ProfilingTestDriver);
118};
119
120} // namespace profiling
121
122#endif // CHROME_BROWSER_PROFILING_HOST_PROFILING_TEST_DRIVER_H_