1 // 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 #include "chrome/browser/media/webrtc/webrtc_event_log_manager.h"
6
7 #include <algorithm>
8 #include <list>
9 #include <map>
10 #include <memory>
11 #include <numeric>
12 #include <queue>
13 #include <string>
14 #include <tuple>
15 #include <utility>
16 #include <vector>
17
18 #include "base/big_endian.h"
19 #include "base/bind.h"
20 #include "base/files/file.h"
21 #include "base/files/file_path.h"
22 #include "base/files/file_util.h"
23 #include "base/files/scoped_temp_dir.h"
24 #include "base/memory/ptr_util.h"
25 #include "base/memory/scoped_refptr.h"
26 #include "base/optional.h"
27 #include "base/run_loop.h"
28 #include "base/stl_util.h"
29 #include "base/strings/string_number_conversions.h"
30 #include "base/strings/string_util.h"
31 #include "base/synchronization/waitable_event.h"
32 #include "base/test/gtest_util.h"
33 #include "base/test/scoped_command_line.h"
34 #include "base/test/scoped_feature_list.h"
35 #include "base/test/simple_test_clock.h"
36 #include "base/threading/sequenced_task_runner_handle.h"
37 #include "base/time/time.h"
38 #include "build/build_config.h"
39 #include "chrome/browser/media/webrtc/webrtc_event_log_manager_common.h"
40 #include "chrome/browser/media/webrtc/webrtc_event_log_manager_unittest_helpers.h"
41 #include "chrome/browser/policy/profile_policy_connector.h"
42 #include "chrome/browser/prefs/browser_prefs.h"
43 #include "chrome/common/chrome_features.h"
44 #include "chrome/common/chrome_switches.h"
45 #include "chrome/common/pref_names.h"
46 #include "chrome/test/base/testing_browser_process.h"
47 #include "chrome/test/base/testing_profile.h"
48 #include "components/pref_registry/pref_registry_syncable.h"
49 #include "components/prefs/testing_pref_store.h"
50 #include "components/sync_preferences/pref_service_mock_factory.h"
51 #include "components/sync_preferences/pref_service_syncable.h"
52 #include "content/public/browser/network_service_instance.h"
53 #include "content/public/test/browser_task_environment.h"
54 #include "content/public/test/mock_render_process_host.h"
55 #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
56 #include "services/network/test/test_network_connection_tracker.h"
57 #include "services/network/test/test_url_loader_factory.h"
58 #include "testing/gmock/include/gmock/gmock.h"
59 #include "testing/gtest/include/gtest/gtest.h"
60 #include "third_party/zlib/google/compression_utils.h"
61
62 #if !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
63 #include "chrome/browser/policy/chrome_browser_policy_connector.h"
64 #include "components/policy/core/common/mock_configuration_policy_provider.h"
65 #include "components/policy/core/common/policy_map.h"
66 #include "components/policy/core/common/policy_types.h"
67 #endif
68
69 #if defined(OS_CHROMEOS)
70 #include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h"
71 #include "chrome/browser/chromeos/profiles/profile_helper.h"
72 #include "components/account_id/account_id.h"
73 #include "components/user_manager/scoped_user_manager.h"
74 #endif
75
76 namespace webrtc_event_logging {
77
78 #if defined(OS_WIN)
79 #define NumberToStringType base::NumberToString16
80 #else
81 #define NumberToStringType base::NumberToString
82 #endif
83
84 using ::testing::_;
85 using ::testing::Invoke;
86 using ::testing::NiceMock;
87
88 using BrowserContext = content::BrowserContext;
89 using BrowserContextId = WebRtcEventLogPeerConnectionKey::BrowserContextId;
90 using MockRenderProcessHost = content::MockRenderProcessHost;
91 using PeerConnectionKey = WebRtcEventLogPeerConnectionKey;
92 using RenderProcessHost = content::RenderProcessHost;
93
94 using Compression = WebRtcEventLogCompression;
95
96 namespace {
97
98 #if !defined(OS_ANDROID)
99
SaveFilePathTo(base::Optional<base::FilePath> * output)100 auto SaveFilePathTo(base::Optional<base::FilePath>* output) {
101 return [output](PeerConnectionKey ignored_key, base::FilePath file_path,
102 int output_period_ms = 0) { *output = file_path; };
103 }
104
SaveKeyAndFilePathTo(base::Optional<PeerConnectionKey> * key_output,base::Optional<base::FilePath> * file_path_output)105 auto SaveKeyAndFilePathTo(base::Optional<PeerConnectionKey>* key_output,
106 base::Optional<base::FilePath>* file_path_output) {
107 return [key_output, file_path_output](PeerConnectionKey key,
108 base::FilePath file_path) {
109 *key_output = key;
110 *file_path_output = file_path;
111 };
112 }
113
114 const int kMaxActiveRemoteLogFiles =
115 static_cast<int>(kMaxActiveRemoteBoundWebRtcEventLogs);
116 const int kMaxPendingRemoteLogFiles =
117 static_cast<int>(kMaxPendingRemoteBoundWebRtcEventLogs);
118 const char kSessionId[] = "session_id";
119
GetLastModificationTime(const base::FilePath & file_path)120 base::Time GetLastModificationTime(const base::FilePath& file_path) {
121 base::File::Info file_info;
122 if (!base::GetFileInfo(file_path, &file_info)) {
123 EXPECT_TRUE(false);
124 return base::Time();
125 }
126 return file_info.last_modified;
127 }
128
129 #endif
130
131 // Common default/arbitrary values.
132 constexpr int kLid = 478;
133 constexpr size_t kWebAppId = 42;
134
GetPeerConnectionKey(RenderProcessHost * rph,int lid)135 PeerConnectionKey GetPeerConnectionKey(RenderProcessHost* rph, int lid) {
136 const BrowserContext* browser_context = rph->GetBrowserContext();
137 const auto browser_context_id = GetBrowserContextId(browser_context);
138 return PeerConnectionKey(rph->GetID(), lid, browser_context_id);
139 }
140
CreateRemoteBoundLogFile(const base::FilePath & dir,size_t web_app_id,const base::FilePath::StringPieceType & extension,base::Time capture_time,base::FilePath * file_path,base::File * file)141 bool CreateRemoteBoundLogFile(const base::FilePath& dir,
142 size_t web_app_id,
143 const base::FilePath::StringPieceType& extension,
144 base::Time capture_time,
145 base::FilePath* file_path,
146 base::File* file) {
147 *file_path =
148 dir.AsEndingWithSeparator()
149 .InsertBeforeExtensionASCII(kRemoteBoundWebRtcEventLogFileNamePrefix)
150 .InsertBeforeExtensionASCII("_")
151 .InsertBeforeExtensionASCII(std::to_string(web_app_id))
152 .InsertBeforeExtensionASCII("_")
153 .InsertBeforeExtensionASCII(CreateWebRtcEventLogId())
154 .AddExtension(extension);
155
156 constexpr int file_flags = base::File::FLAG_CREATE | base::File::FLAG_WRITE |
157 base::File::FLAG_EXCLUSIVE_WRITE;
158 file->Initialize(*file_path, file_flags);
159 if (!file->IsValid() || !file->created()) {
160 return false;
161 }
162
163 if (!base::TouchFile(*file_path, capture_time, capture_time)) {
164 return false;
165 }
166
167 return true;
168 }
169
170 // This implementation does not upload files, nor pretends to have finished an
171 // upload. Most importantly, it does not get rid of the locally-stored log file
172 // after finishing a simulated upload; this is useful because it keeps the file
173 // on disk, where unit tests may inspect it.
174 // This class enforces an expectation over the upload being cancelled or not.
175 class NullWebRtcEventLogUploader : public WebRtcEventLogUploader {
176 public:
NullWebRtcEventLogUploader(const WebRtcLogFileInfo & log_file,UploadResultCallback callback,bool cancellation_expected)177 NullWebRtcEventLogUploader(const WebRtcLogFileInfo& log_file,
178 UploadResultCallback callback,
179 bool cancellation_expected)
180 : log_file_(log_file),
181 callback_(std::move(callback)),
182 cancellation_expected_(cancellation_expected),
183 was_cancelled_(false) {}
184
~NullWebRtcEventLogUploader()185 ~NullWebRtcEventLogUploader() override {
186 EXPECT_EQ(was_cancelled_, cancellation_expected_);
187 }
188
GetWebRtcLogFileInfo() const189 const WebRtcLogFileInfo& GetWebRtcLogFileInfo() const override {
190 return log_file_;
191 }
192
Cancel()193 void Cancel() override {
194 EXPECT_TRUE(cancellation_expected_);
195 was_cancelled_ = true;
196 if (callback_) {
197 base::SequencedTaskRunnerHandle::Get()->PostTask(
198 FROM_HERE,
199 base::BindOnce(std::move(callback_), log_file_.path, false));
200 }
201 }
202
203 class Factory : public WebRtcEventLogUploader::Factory {
204 public:
Factory(bool cancellation_expected,base::Optional<size_t> expected_instance_count=base::nullopt)205 Factory(bool cancellation_expected,
206 base::Optional<size_t> expected_instance_count = base::nullopt)
207 : cancellation_expected_(cancellation_expected),
208 expected_instance_count_(expected_instance_count),
209 instance_count_(0) {}
210
~Factory()211 ~Factory() override {
212 if (expected_instance_count_.has_value()) {
213 EXPECT_EQ(instance_count_, expected_instance_count_.value());
214 }
215 }
216
Create(const WebRtcLogFileInfo & log_file,UploadResultCallback callback)217 std::unique_ptr<WebRtcEventLogUploader> Create(
218 const WebRtcLogFileInfo& log_file,
219 UploadResultCallback callback) override {
220 if (expected_instance_count_.has_value()) {
221 EXPECT_LE(++instance_count_, expected_instance_count_.value());
222 }
223 return std::make_unique<NullWebRtcEventLogUploader>(
224 log_file, std::move(callback), cancellation_expected_);
225 }
226
227 private:
228 const bool cancellation_expected_;
229 const base::Optional<size_t> expected_instance_count_;
230 size_t instance_count_;
231 };
232
233 private:
234 const WebRtcLogFileInfo log_file_;
235 UploadResultCallback callback_;
236 const bool cancellation_expected_;
237 bool was_cancelled_;
238 };
239
240 class MockWebRtcLocalEventLogsObserver : public WebRtcLocalEventLogsObserver {
241 public:
242 ~MockWebRtcLocalEventLogsObserver() override = default;
243 MOCK_METHOD2(OnLocalLogStarted,
244 void(PeerConnectionKey, const base::FilePath&));
245 MOCK_METHOD1(OnLocalLogStopped, void(PeerConnectionKey));
246 };
247
248 class MockWebRtcRemoteEventLogsObserver : public WebRtcRemoteEventLogsObserver {
249 public:
250 ~MockWebRtcRemoteEventLogsObserver() override = default;
251 MOCK_METHOD3(OnRemoteLogStarted,
252 void(PeerConnectionKey, const base::FilePath&, int));
253 MOCK_METHOD1(OnRemoteLogStopped, void(PeerConnectionKey));
254 };
255
256 } // namespace
257
258 class WebRtcEventLogManagerTestBase : public ::testing::Test {
259 public:
WebRtcEventLogManagerTestBase()260 WebRtcEventLogManagerTestBase()
261 : test_shared_url_loader_factory_(
262 base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
263 &test_url_loader_factory_)),
264 run_loop_(std::make_unique<base::RunLoop>()),
265 uploader_run_loop_(std::make_unique<base::RunLoop>()),
266 browser_context_(nullptr),
267 browser_context_id_(GetBrowserContextId(browser_context_.get())) {
268 TestingBrowserProcess::GetGlobal()->SetSharedURLLoaderFactory(
269 test_shared_url_loader_factory_);
270
271 // Avoid proactive pruning; it has the potential to mess up tests, as well
272 // as keep pendings tasks around with a dangling reference to the unit
273 // under test. (Zero is a sentinel value for disabling proactive pruning.)
274 scoped_command_line_.GetProcessCommandLine()->AppendSwitchASCII(
275 ::switches::kWebRtcRemoteEventLogProactivePruningDelta, "0");
276
277 EXPECT_TRUE(local_logs_base_dir_.CreateUniqueTempDir());
278 local_logs_base_path_ = local_logs_base_dir_.GetPath().Append(
279 FILE_PATH_LITERAL("local_event_logs"));
280
281 EXPECT_TRUE(profiles_dir_.CreateUniqueTempDir());
282 }
283
~WebRtcEventLogManagerTestBase()284 ~WebRtcEventLogManagerTestBase() override {
285 WaitForPendingTasks();
286
287 base::RunLoop run_loop;
288 event_log_manager_->ShutDownForTesting(run_loop.QuitClosure());
289 run_loop.Run();
290
291 // We do not want to satisfy any unsatisfied expectations by destroying
292 // |rph_|, |browser_context_|, etc., at the end of the test, before we
293 // destroy |event_log_manager_|. However, we must also make sure that their
294 // destructors do not attempt to access |event_log_manager_|, which in
295 // normal code lives forever, but not in the unit tests.
296 event_log_manager_.reset();
297
298 // Guard against unexpected state changes.
299 EXPECT_TRUE(webrtc_state_change_instructions_.empty());
300 }
301
SetUp()302 void SetUp() override {
303 SetUpNetworkConnection(true,
304 network::mojom::ConnectionType::CONNECTION_ETHERNET);
305 SetLocalLogsObserver(&local_observer_);
306 SetRemoteLogsObserver(&remote_observer_);
307 LoadMainTestProfile();
308 #if !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
309 policy::BrowserPolicyConnectorBase::SetPolicyProviderForTesting(&provider_);
310 #endif
311 }
312
TearDown()313 void TearDown() override {
314 #if !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
315 TestingBrowserProcess::GetGlobal()->ShutdownBrowserPolicyConnector();
316 #endif
317 }
318
SetUpNetworkConnection(bool respond_synchronously,network::mojom::ConnectionType connection_type)319 void SetUpNetworkConnection(bool respond_synchronously,
320 network::mojom::ConnectionType connection_type) {
321 auto* tracker = network::TestNetworkConnectionTracker::GetInstance();
322 tracker->SetRespondSynchronously(respond_synchronously);
323 tracker->SetConnectionType(connection_type);
324 }
325
SetConnectionType(network::mojom::ConnectionType connection_type)326 void SetConnectionType(network::mojom::ConnectionType connection_type) {
327 network::TestNetworkConnectionTracker::GetInstance()->SetConnectionType(
328 connection_type);
329 }
330
CreateWebRtcEventLogManager(base::Optional<Compression> remote=base::nullopt)331 void CreateWebRtcEventLogManager(
332 base::Optional<Compression> remote = base::nullopt) {
333 DCHECK(!event_log_manager_);
334
335 event_log_manager_ = WebRtcEventLogManager::CreateSingletonInstance();
336
337 local_log_extension_ = kWebRtcEventLogUncompressedExtension;
338
339 if (remote.has_value()) {
340 auto factory = CreateLogFileWriterFactory(remote.value());
341 remote_log_extension_ = factory->Extension();
342 event_log_manager_->SetRemoteLogFileWriterFactoryForTesting(
343 std::move(factory));
344 } else {
345 // kWebRtcRemoteEventLogGzipped is turned on by default.
346 remote_log_extension_ = kWebRtcEventLogGzippedExtension;
347 }
348 }
349
LoadMainTestProfile()350 void LoadMainTestProfile() {
351 browser_context_ = CreateBrowserContext("browser_context_");
352 browser_context_id_ = GetBrowserContextId(browser_context_.get());
353 rph_ = std::make_unique<MockRenderProcessHost>(browser_context_.get());
354 }
355
UnloadMainTestProfile()356 void UnloadMainTestProfile() {
357 rph_.reset();
358 browser_context_.reset();
359 browser_context_id_ = GetBrowserContextId(browser_context_.get());
360 }
361
WaitForReply()362 void WaitForReply() {
363 run_loop_->Run();
364 run_loop_.reset(new base::RunLoop); // Allow re-blocking.
365 }
366
Reply()367 void Reply() { run_loop_->QuitWhenIdle(); }
368
ReplyClosure()369 base::OnceClosure ReplyClosure() {
370 // Intermediary pointer used to help the compiler distinguish between
371 // the overloaded Reply() functions.
372 void (WebRtcEventLogManagerTestBase::*function)() =
373 &WebRtcEventLogManagerTestBase::Reply;
374 return base::BindOnce(function, base::Unretained(this));
375 }
376
377 template <typename T>
Reply(T * output,T val)378 void Reply(T* output, T val) {
379 *output = val;
380 run_loop_->QuitWhenIdle();
381 }
382
383 template <typename T>
ReplyClosure(T * output)384 base::OnceCallback<void(T)> ReplyClosure(T* output) {
385 // Intermediary pointer used to help the compiler distinguish between
386 // the overloaded Reply() functions.
387 void (WebRtcEventLogManagerTestBase::*function)(T*, T) =
388 &WebRtcEventLogManagerTestBase::Reply;
389 return base::BindOnce(function, base::Unretained(this), output);
390 }
391
Reply(bool * output_bool,std::string * output_str1,std::string * output_str2,bool bool_val,const std::string & str1_val,const std::string & str2_val)392 void Reply(bool* output_bool,
393 std::string* output_str1,
394 std::string* output_str2,
395 bool bool_val,
396 const std::string& str1_val,
397 const std::string& str2_val) {
398 *output_bool = bool_val;
399 *output_str1 = str1_val;
400 *output_str2 = str2_val;
401 run_loop_->QuitWhenIdle();
402 }
403
404 base::OnceCallback<void(bool, const std::string&, const std::string&)>
ReplyClosure(bool * output_bool,std::string * output_str1,std::string * output_str2)405 ReplyClosure(bool* output_bool,
406 std::string* output_str1,
407 std::string* output_str2) {
408 // Intermediary pointer used to help the compiler distinguish between
409 // the overloaded Reply() functions.
410 void (WebRtcEventLogManagerTestBase::*function)(
411 bool*, std::string*, std::string*, bool, const std::string&,
412 const std::string&) = &WebRtcEventLogManagerTestBase::Reply;
413 return base::BindOnce(function, base::Unretained(this), output_bool,
414 output_str1, output_str2);
415 }
416
PeerConnectionAdded(const PeerConnectionKey & key)417 bool PeerConnectionAdded(const PeerConnectionKey& key) {
418 bool result;
419 event_log_manager_->PeerConnectionAdded(key.render_process_id, key.lid,
420 ReplyClosure(&result));
421 WaitForReply();
422 return result;
423 }
424
PeerConnectionRemoved(const PeerConnectionKey & key)425 bool PeerConnectionRemoved(const PeerConnectionKey& key) {
426 bool result;
427 event_log_manager_->PeerConnectionRemoved(key.render_process_id, key.lid,
428 ReplyClosure(&result));
429 WaitForReply();
430 return result;
431 }
432
PeerConnectionSessionIdSet(const PeerConnectionKey & key,const std::string & session_id)433 bool PeerConnectionSessionIdSet(const PeerConnectionKey& key,
434 const std::string& session_id) {
435 bool result;
436 event_log_manager_->PeerConnectionSessionIdSet(
437 key.render_process_id, key.lid, session_id, ReplyClosure(&result));
438 WaitForReply();
439 return result;
440 }
441
PeerConnectionSessionIdSet(const PeerConnectionKey & key)442 bool PeerConnectionSessionIdSet(const PeerConnectionKey& key) {
443 return PeerConnectionSessionIdSet(key, GetUniqueId(key));
444 }
445
PeerConnectionStopped(const PeerConnectionKey & key)446 bool PeerConnectionStopped(const PeerConnectionKey& key) {
447 bool result;
448 event_log_manager_->PeerConnectionStopped(key.render_process_id, key.lid,
449 ReplyClosure(&result));
450 WaitForReply();
451 return result;
452 }
453
EnableLocalLogging(size_t max_size_bytes=kWebRtcEventLogManagerUnlimitedFileSize)454 bool EnableLocalLogging(
455 size_t max_size_bytes = kWebRtcEventLogManagerUnlimitedFileSize) {
456 return EnableLocalLogging(local_logs_base_path_, max_size_bytes);
457 }
458
EnableLocalLogging(base::FilePath local_logs_base_path,size_t max_size_bytes=kWebRtcEventLogManagerUnlimitedFileSize)459 bool EnableLocalLogging(
460 base::FilePath local_logs_base_path,
461 size_t max_size_bytes = kWebRtcEventLogManagerUnlimitedFileSize) {
462 bool result;
463 event_log_manager_->EnableLocalLogging(local_logs_base_path, max_size_bytes,
464 ReplyClosure(&result));
465 WaitForReply();
466 return result;
467 }
468
DisableLocalLogging()469 bool DisableLocalLogging() {
470 bool result;
471 event_log_manager_->DisableLocalLogging(ReplyClosure(&result));
472 WaitForReply();
473 return result;
474 }
475
StartRemoteLogging(const PeerConnectionKey & key,const std::string & session_id,size_t max_size_bytes,int output_period_ms,size_t web_app_id,std::string * log_id_output=nullptr,std::string * error_message_output=nullptr)476 bool StartRemoteLogging(const PeerConnectionKey& key,
477 const std::string& session_id,
478 size_t max_size_bytes,
479 int output_period_ms,
480 size_t web_app_id,
481 std::string* log_id_output = nullptr,
482 std::string* error_message_output = nullptr) {
483 bool result;
484 std::string log_id;
485 std::string error_message;
486
487 event_log_manager_->StartRemoteLogging(
488 key.render_process_id, session_id, max_size_bytes, output_period_ms,
489 web_app_id, ReplyClosure(&result, &log_id, &error_message));
490
491 WaitForReply();
492
493 // If successful, only |log_id|. If unsuccessful, only |error_message| set.
494 DCHECK_EQ(result, !log_id.empty());
495 DCHECK_EQ(!result, !error_message.empty());
496
497 if (log_id_output) {
498 *log_id_output = log_id;
499 }
500
501 if (error_message_output) {
502 *error_message_output = error_message;
503 }
504
505 return result;
506 }
507
StartRemoteLogging(const PeerConnectionKey & key,const std::string & session_id,std::string * log_id_output=nullptr,std::string * error_message_output=nullptr)508 bool StartRemoteLogging(const PeerConnectionKey& key,
509 const std::string& session_id,
510 std::string* log_id_output = nullptr,
511 std::string* error_message_output = nullptr) {
512 return StartRemoteLogging(key, session_id, kMaxRemoteLogFileSizeBytes, 0,
513 kWebAppId, log_id_output, error_message_output);
514 }
515
StartRemoteLogging(const PeerConnectionKey & key,std::string * log_id_output=nullptr,std::string * error_message_output=nullptr)516 bool StartRemoteLogging(const PeerConnectionKey& key,
517 std::string* log_id_output = nullptr,
518 std::string* error_message_output = nullptr) {
519 return StartRemoteLogging(key, GetUniqueId(key), kMaxRemoteLogFileSizeBytes,
520 0, kWebAppId, log_id_output,
521 error_message_output);
522 }
523
ClearCacheForBrowserContext(const content::BrowserContext * browser_context,const base::Time & delete_begin,const base::Time & delete_end)524 void ClearCacheForBrowserContext(
525 const content::BrowserContext* browser_context,
526 const base::Time& delete_begin,
527 const base::Time& delete_end) {
528 event_log_manager_->ClearCacheForBrowserContext(
529 browser_context, delete_begin, delete_end, ReplyClosure());
530 WaitForReply();
531 }
532
GetHistory(BrowserContextId browser_context_id)533 std::vector<UploadList::UploadInfo> GetHistory(
534 BrowserContextId browser_context_id) {
535 std::vector<UploadList::UploadInfo> result;
536
537 base::RunLoop run_loop;
538
539 auto reply = [](base::RunLoop* run_loop,
540 std::vector<UploadList::UploadInfo>* output,
541 const std::vector<UploadList::UploadInfo>& input) {
542 *output = input;
543 run_loop->Quit();
544 };
545 event_log_manager_->GetHistory(browser_context_id,
546 base::BindOnce(reply, &run_loop, &result));
547 run_loop.Run();
548
549 return result;
550 }
551
SetLocalLogsObserver(WebRtcLocalEventLogsObserver * observer)552 void SetLocalLogsObserver(WebRtcLocalEventLogsObserver* observer) {
553 event_log_manager_->SetLocalLogsObserver(observer, ReplyClosure());
554 WaitForReply();
555 }
556
SetRemoteLogsObserver(WebRtcRemoteEventLogsObserver * observer)557 void SetRemoteLogsObserver(WebRtcRemoteEventLogsObserver* observer) {
558 event_log_manager_->SetRemoteLogsObserver(observer, ReplyClosure());
559 WaitForReply();
560 }
561
SetWebRtcEventLogUploaderFactoryForTesting(std::unique_ptr<WebRtcEventLogUploader::Factory> factory)562 void SetWebRtcEventLogUploaderFactoryForTesting(
563 std::unique_ptr<WebRtcEventLogUploader::Factory> factory) {
564 event_log_manager_->SetWebRtcEventLogUploaderFactoryForTesting(
565 std::move(factory), ReplyClosure());
566 WaitForReply();
567 }
568
OnWebRtcEventLogWrite(const PeerConnectionKey & key,const std::string & message)569 std::pair<bool, bool> OnWebRtcEventLogWrite(const PeerConnectionKey& key,
570 const std::string& message) {
571 std::pair<bool, bool> result;
572 event_log_manager_->OnWebRtcEventLogWrite(key.render_process_id, key.lid,
573 message, ReplyClosure(&result));
574 WaitForReply();
575 return result;
576 }
577
FreezeClockAt(const base::Time::Exploded & frozen_time_exploded)578 void FreezeClockAt(const base::Time::Exploded& frozen_time_exploded) {
579 base::Time frozen_time;
580 ASSERT_TRUE(
581 base::Time::FromLocalExploded(frozen_time_exploded, &frozen_time));
582 frozen_clock_.SetNow(frozen_time);
583 event_log_manager_->SetClockForTesting(&frozen_clock_, ReplyClosure());
584 WaitForReply();
585 }
586
SetWebRtcEventLoggingState(const PeerConnectionKey & key,bool event_logging_enabled)587 void SetWebRtcEventLoggingState(const PeerConnectionKey& key,
588 bool event_logging_enabled) {
589 webrtc_state_change_instructions_.emplace(key, event_logging_enabled);
590 }
591
ExpectWebRtcStateChangeInstruction(const PeerConnectionKey & key,bool enabled)592 void ExpectWebRtcStateChangeInstruction(const PeerConnectionKey& key,
593 bool enabled) {
594 ASSERT_FALSE(webrtc_state_change_instructions_.empty());
595 auto& instruction = webrtc_state_change_instructions_.front();
596 EXPECT_EQ(instruction.key.render_process_id, key.render_process_id);
597 EXPECT_EQ(instruction.key.lid, key.lid);
598 EXPECT_EQ(instruction.enabled, enabled);
599 webrtc_state_change_instructions_.pop();
600 }
601
SetPeerConnectionTrackerProxyForTesting(std::unique_ptr<WebRtcEventLogManager::PeerConnectionTrackerProxy> pc_tracker_proxy)602 void SetPeerConnectionTrackerProxyForTesting(
603 std::unique_ptr<WebRtcEventLogManager::PeerConnectionTrackerProxy>
604 pc_tracker_proxy) {
605 event_log_manager_->SetPeerConnectionTrackerProxyForTesting(
606 std::move(pc_tracker_proxy), ReplyClosure());
607 WaitForReply();
608 }
609
610 // Allows either creating a TestingProfile with a predetermined name
611 // (useful when trying to "reload" a profile), or one with an arbitrary name.
CreateBrowserContext()612 virtual std::unique_ptr<TestingProfile> CreateBrowserContext() {
613 return CreateBrowserContext(std::string());
614 }
CreateBrowserContext(std::string profile_name)615 virtual std::unique_ptr<TestingProfile> CreateBrowserContext(
616 std::string profile_name) {
617 return CreateBrowserContext(profile_name, true /* is_managed_profile */,
618 false /* has_device_level_policies */,
619 true /* policy_allows_remote_logging */);
620 }
CreateBrowserContext(std::string profile_name,bool is_managed_profile,bool has_device_level_policies,base::Optional<bool> policy_allows_remote_logging)621 virtual std::unique_ptr<TestingProfile> CreateBrowserContext(
622 std::string profile_name,
623 bool is_managed_profile,
624 bool has_device_level_policies,
625 base::Optional<bool> policy_allows_remote_logging) {
626 return CreateBrowserContextWithCustomSupervision(
627 profile_name, is_managed_profile, has_device_level_policies,
628 false /* is_supervised */, policy_allows_remote_logging);
629 }
630 virtual std::unique_ptr<TestingProfile>
CreateBrowserContextWithCustomSupervision(std::string profile_name,bool is_managed_profile,bool has_device_level_policies,bool is_supervised,base::Optional<bool> policy_allows_remote_logging)631 CreateBrowserContextWithCustomSupervision(
632 std::string profile_name,
633 bool is_managed_profile,
634 bool has_device_level_policies,
635 bool is_supervised,
636 base::Optional<bool> policy_allows_remote_logging) {
637 // If profile name not specified, select a unique name.
638 if (profile_name.empty()) {
639 static size_t index = 0;
640 profile_name = std::to_string(++index);
641 }
642
643 // Set a directory for the profile, derived from its name, so that
644 // recreating the profile will get the same directory.
645 const base::FilePath profile_path =
646 profiles_dir_.GetPath().AppendASCII(profile_name);
647 if (base::PathExists(profile_path)) {
648 EXPECT_TRUE(base::DirectoryExists(profile_path));
649 } else {
650 EXPECT_TRUE(base::CreateDirectory(profile_path));
651 }
652
653 // Prepare to specify preferences for the profile.
654 sync_preferences::PrefServiceMockFactory factory;
655 factory.set_user_prefs(base::WrapRefCounted(new TestingPrefStore()));
656 scoped_refptr<user_prefs::PrefRegistrySyncable> registry(
657 new user_prefs::PrefRegistrySyncable);
658 sync_preferences::PrefServiceSyncable* regular_prefs =
659 factory.CreateSyncable(registry.get()).release();
660
661 // Set the preference associated with the policy for WebRTC remote-bound
662 // event logging.
663 RegisterUserProfilePrefs(registry.get());
664 if (policy_allows_remote_logging.has_value()) {
665 regular_prefs->SetBoolean(prefs::kWebRtcEventLogCollectionAllowed,
666 policy_allows_remote_logging.value());
667 }
668
669 #if !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
670 policy::PolicyMap policy_map;
671 if (has_device_level_policies) {
672 policy_map.Set("test-policy", policy::POLICY_LEVEL_MANDATORY,
673 policy::POLICY_SCOPE_MACHINE,
674 policy::POLICY_SOURCE_PLATFORM, base::Value("test"),
675 nullptr);
676 }
677 provider_.UpdateChromePolicy(policy_map);
678 #else
679 if (has_device_level_policies) {
680 ADD_FAILURE() << "Invalid test setup. Chrome platform policies cannot be "
681 "set on Chrome OS and Android.";
682 }
683 #endif
684
685 // Build the profile.
686 TestingProfile::Builder profile_builder;
687 profile_builder.SetProfileName(profile_name);
688 profile_builder.SetPath(profile_path);
689 profile_builder.SetPrefService(base::WrapUnique(regular_prefs));
690 profile_builder.OverridePolicyConnectorIsManagedForTesting(
691 is_managed_profile);
692 if (is_supervised) {
693 profile_builder.SetSupervisedUserId("id");
694 }
695 std::unique_ptr<TestingProfile> profile = profile_builder.Build();
696
697 // Blocks on the unit under test's task runner, so that we won't proceed
698 // with the test (e.g. check that files were created) before finished
699 // processing this even (which is signaled to it from
700 // BrowserContext::EnableForBrowserContext).
701 WaitForPendingTasks();
702
703 return profile;
704 }
705
RemoteBoundLogsDir(BrowserContext * browser_context) const706 base::FilePath RemoteBoundLogsDir(BrowserContext* browser_context) const {
707 return RemoteBoundLogsDir(browser_context->GetPath());
708 }
709
RemoteBoundLogsDir(const base::FilePath & browser_context_base_dir) const710 base::FilePath RemoteBoundLogsDir(
711 const base::FilePath& browser_context_base_dir) const {
712 return GetRemoteBoundWebRtcEventLogsDir(browser_context_base_dir);
713 }
714
715 // Initiate an arbitrary synchronous operation, allowing any tasks pending
716 // on the manager's internal task queue to be completed.
717 // If given a RunLoop, we first block on it. The reason to do both is that
718 // with the RunLoop we wait on some tasks which we know also post additional
719 // tasks, then, after that chain is completed, we also wait for any potential
720 // leftovers. For example, the run loop could wait for n-1 files to be
721 // uploaded, then it is released when the last one's upload is initiated,
722 // then we wait for the last file's upload to be completed.
WaitForPendingTasks(base::RunLoop * run_loop=nullptr)723 void WaitForPendingTasks(base::RunLoop* run_loop = nullptr) {
724 if (run_loop) {
725 run_loop->Run();
726 }
727
728 base::WaitableEvent event(base::WaitableEvent::ResetPolicy::MANUAL,
729 base::WaitableEvent::InitialState::NOT_SIGNALED);
730 event_log_manager_->GetTaskRunnerForTesting()->PostTask(
731 FROM_HERE,
732 base::BindOnce([](base::WaitableEvent* event) { event->Signal(); },
733 &event));
734 event.Wait();
735 }
736
SuppressUploading()737 void SuppressUploading() {
738 if (!upload_suppressing_browser_context_) { // First suppression.
739 upload_suppressing_browser_context_ = CreateBrowserContext();
740 }
741 DCHECK(!upload_suppressing_rph_) << "Uploading already suppressed.";
742 upload_suppressing_rph_ = std::make_unique<MockRenderProcessHost>(
743 upload_suppressing_browser_context_.get());
744 const auto key = GetPeerConnectionKey(upload_suppressing_rph_.get(), 0);
745 ASSERT_TRUE(PeerConnectionAdded(key));
746 }
747
UnsuppressUploading()748 void UnsuppressUploading() {
749 DCHECK(upload_suppressing_rph_) << "Uploading not suppressed.";
750 const auto key = GetPeerConnectionKey(upload_suppressing_rph_.get(), 0);
751 ASSERT_TRUE(PeerConnectionRemoved(key));
752 upload_suppressing_rph_.reset();
753 }
754
ExpectLocalFileContents(const base::FilePath & file_path,const std::string & expected_contents)755 void ExpectLocalFileContents(const base::FilePath& file_path,
756 const std::string& expected_contents) {
757 std::string file_contents;
758 ASSERT_TRUE(base::ReadFileToString(file_path, &file_contents));
759 EXPECT_EQ(file_contents, expected_contents);
760 }
761
ExpectRemoteFileContents(const base::FilePath & file_path,const std::string & expected_event_log)762 void ExpectRemoteFileContents(const base::FilePath& file_path,
763 const std::string& expected_event_log) {
764 std::string file_contents;
765 ASSERT_TRUE(base::ReadFileToString(file_path, &file_contents));
766
767 if (remote_log_extension_ == kWebRtcEventLogUncompressedExtension) {
768 EXPECT_EQ(file_contents, expected_event_log);
769 } else if (remote_log_extension_ == kWebRtcEventLogGzippedExtension) {
770 std::string uncompressed_log;
771 ASSERT_TRUE(
772 compression::GzipUncompress(file_contents, &uncompressed_log));
773 EXPECT_EQ(uncompressed_log, expected_event_log);
774 } else {
775 NOTREACHED();
776 }
777 }
778
779 // When the peer connection's ID is not the focus of the test, this allows
780 // us to conveniently assign unique IDs to peer connections.
GetUniqueId(int render_process_id,int lid)781 std::string GetUniqueId(int render_process_id, int lid) {
782 return std::to_string(render_process_id) + "_" + std::to_string(lid);
783 }
GetUniqueId(const PeerConnectionKey & key)784 std::string GetUniqueId(const PeerConnectionKey& key) {
785 return GetUniqueId(key.render_process_id, key.lid);
786 }
787
UploadConditionsHold()788 bool UploadConditionsHold() {
789 base::RunLoop run_loop;
790 bool result;
791
792 auto callback = [](base::RunLoop* run_loop, bool* result_out, bool result) {
793 *result_out = result;
794 run_loop->QuitWhenIdle();
795 };
796
797 event_log_manager_->UploadConditionsHoldForTesting(
798 base::BindOnce(callback, &run_loop, &result));
799 run_loop.Run();
800
801 return result;
802 }
803
804 // Testing utilities.
805 content::BrowserTaskEnvironment task_environment_;
806 base::test::ScopedFeatureList scoped_feature_list_;
807 base::test::ScopedCommandLine scoped_command_line_;
808 base::SimpleTestClock frozen_clock_;
809 network::TestURLLoaderFactory test_url_loader_factory_;
810 scoped_refptr<network::SharedURLLoaderFactory>
811 test_shared_url_loader_factory_;
812
813 #if !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
814 policy::MockConfigurationPolicyProvider provider_;
815 #endif
816
817 // The main loop, which allows waiting for the operations invoked on the
818 // unit-under-test to be completed. Do not use this object directly from the
819 // tests, since that would be error-prone. (Specifically, one must not produce
820 // two events that could produce replies, without waiting on the first reply
821 // in between.)
822 std::unique_ptr<base::RunLoop> run_loop_;
823
824 // Allows waiting for upload operations.
825 std::unique_ptr<base::RunLoop> uploader_run_loop_;
826
827 // Unit under test.
828 std::unique_ptr<WebRtcEventLogManager> event_log_manager_;
829
830 // Extensions associated with local/remote-bound event logs. Depends on
831 // whether they're compressed.
832 base::FilePath::StringPieceType local_log_extension_;
833 base::FilePath::StringPieceType remote_log_extension_;
834
835 // The directory which will contain all profiles.
836 base::ScopedTempDir profiles_dir_;
837
838 // Default BrowserContext and RenderProcessHost, to be used by tests which
839 // do not require anything fancy (such as seeding the BrowserContext with
840 // pre-existing logs files from a previous session, or working with multiple
841 // BrowserContext objects).
842
843 std::unique_ptr<TestingProfile> browser_context_;
844 BrowserContextId browser_context_id_;
845 std::unique_ptr<MockRenderProcessHost> rph_;
846
847 // Used for suppressing the upload of finished files, by creating an active
848 // remote-bound log associated with an independent BrowserContext which
849 // does not otherwise interfere with the test.
850 std::unique_ptr<TestingProfile> upload_suppressing_browser_context_;
851 std::unique_ptr<MockRenderProcessHost> upload_suppressing_rph_;
852
853 // The directory where we'll save local log files.
854 base::ScopedTempDir local_logs_base_dir_;
855 // local_logs_base_dir_ + log files' name prefix.
856 base::FilePath local_logs_base_path_;
857
858 // WebRtcEventLogManager instructs WebRTC, via PeerConnectionTracker, to
859 // only send WebRTC messages for certain peer connections. Some tests make
860 // sure that this is done correctly, by waiting for these notifications, then
861 // testing them.
862 // Because a single action - disabling of local logging - could crease a
863 // series of such instructions, we keep a queue of them. However, were one
864 // to actually test that scenario, one would have to account for the lack
865 // of a guarantee over the order in which these instructions are produced.
866 struct WebRtcStateChangeInstruction {
WebRtcStateChangeInstructionwebrtc_event_logging::WebRtcEventLogManagerTestBase::WebRtcStateChangeInstruction867 WebRtcStateChangeInstruction(PeerConnectionKey key, bool enabled)
868 : key(key), enabled(enabled) {}
869 PeerConnectionKey key;
870 bool enabled;
871 };
872 std::queue<WebRtcStateChangeInstruction> webrtc_state_change_instructions_;
873
874 // Observers for local/remote logging being started/stopped. By having them
875 // here, we achieve two goals:
876 // 1. Reduce boilerplate in the tests themselves.
877 // 2. Avoid lifetime issues, where the observer might be deallocated before
878 // a RenderProcessHost is deallocated (which can potentially trigger a
879 // callback on the observer).
880 NiceMock<MockWebRtcLocalEventLogsObserver> local_observer_;
881 NiceMock<MockWebRtcRemoteEventLogsObserver> remote_observer_;
882
883 DISALLOW_COPY_AND_ASSIGN(WebRtcEventLogManagerTestBase);
884 };
885
886 #if !defined(OS_ANDROID)
887
888 class WebRtcEventLogManagerTest : public WebRtcEventLogManagerTestBase,
889 public ::testing::WithParamInterface<bool> {
890 public:
WebRtcEventLogManagerTest()891 WebRtcEventLogManagerTest() {
892 scoped_feature_list_.InitAndEnableFeature(features::kWebRtcRemoteEventLog);
893
894 // Use a low delay, or the tests would run for quite a long time.
895 scoped_command_line_.GetProcessCommandLine()->AppendSwitchASCII(
896 ::switches::kWebRtcRemoteEventLogUploadDelayMs, "100");
897 }
898
899 ~WebRtcEventLogManagerTest() override = default;
900
SetUp()901 void SetUp() override {
902 CreateWebRtcEventLogManager(Compression::GZIP_PERFECT_ESTIMATION);
903
904 WebRtcEventLogManagerTestBase::SetUp();
905
906 SetWebRtcEventLogUploaderFactoryForTesting(
907 std::make_unique<NullWebRtcEventLogUploader::Factory>(false));
908 }
909 };
910
911 class WebRtcEventLogManagerTestCacheClearing
912 : public WebRtcEventLogManagerTest {
913 public:
914 ~WebRtcEventLogManagerTestCacheClearing() override = default;
915
CreatePendingLogFiles(BrowserContext * browser_context)916 void CreatePendingLogFiles(BrowserContext* browser_context) {
917 ASSERT_TRUE(pending_logs_.find(browser_context) == pending_logs_.end());
918 auto& elements = pending_logs_[browser_context];
919 elements = std::make_unique<BrowserContextAssociatedElements>();
920
921 for (size_t i = 0; i < kMaxActiveRemoteBoundWebRtcEventLogs; ++i) {
922 elements->rphs.push_back(
923 std::make_unique<MockRenderProcessHost>(browser_context));
924 const auto key = GetPeerConnectionKey(elements->rphs[i].get(), kLid);
925 elements->file_paths.push_back(CreatePendingRemoteLogFile(key));
926 ASSERT_TRUE(elements->file_paths[i]);
927 ASSERT_TRUE(base::PathExists(*elements->file_paths[i]));
928
929 pending_latest_mod_ = GetLastModificationTime(*elements->file_paths[i]);
930 if (pending_earliest_mod_.is_null()) { // First file.
931 pending_earliest_mod_ = pending_latest_mod_;
932 }
933 }
934 }
935
ClearPendingLogFiles()936 void ClearPendingLogFiles() { pending_logs_.clear(); }
937
CreateRemoteLogFile(const PeerConnectionKey & key,bool pending)938 base::Optional<base::FilePath> CreateRemoteLogFile(
939 const PeerConnectionKey& key,
940 bool pending) {
941 base::Optional<base::FilePath> file_path;
942 ON_CALL(remote_observer_, OnRemoteLogStarted(key, _, _))
943 .WillByDefault(Invoke(SaveFilePathTo(&file_path)));
944 EXPECT_TRUE(PeerConnectionAdded(key));
945 EXPECT_TRUE(PeerConnectionSessionIdSet(key));
946 EXPECT_TRUE(StartRemoteLogging(key));
947 if (pending) {
948 // Transition from ACTIVE to PENDING.
949 EXPECT_TRUE(PeerConnectionRemoved(key));
950 }
951 return file_path;
952 }
953
CreateActiveRemoteLogFile(const PeerConnectionKey & key)954 base::Optional<base::FilePath> CreateActiveRemoteLogFile(
955 const PeerConnectionKey& key) {
956 return CreateRemoteLogFile(key, false);
957 }
958
CreatePendingRemoteLogFile(const PeerConnectionKey & key)959 base::Optional<base::FilePath> CreatePendingRemoteLogFile(
960 const PeerConnectionKey& key) {
961 return CreateRemoteLogFile(key, true);
962 }
963
964 protected:
965 // When closing a file, rather than check its last modification date, which
966 // is potentially expensive, WebRtcRemoteEventLogManager reads the system
967 // clock, which should be close enough. For tests, however, the difference
968 // could be enough to flake the tests, if not for this epsilon. Given the
969 // focus of the tests that use this, this epsilon can be arbitrarily large.
970 static const base::TimeDelta kEpsion;
971
972 struct BrowserContextAssociatedElements {
973 std::vector<std::unique_ptr<MockRenderProcessHost>> rphs;
974 std::vector<base::Optional<base::FilePath>> file_paths;
975 };
976
977 std::map<const BrowserContext*,
978 std::unique_ptr<BrowserContextAssociatedElements>>
979 pending_logs_;
980
981 // Latest modification times of earliest and latest pending log files.
982 base::Time pending_earliest_mod_;
983 base::Time pending_latest_mod_;
984 };
985
986 const base::TimeDelta WebRtcEventLogManagerTestCacheClearing::kEpsion =
987 base::TimeDelta::FromHours(1);
988
989 class WebRtcEventLogManagerTestWithRemoteLoggingDisabled
990 : public WebRtcEventLogManagerTestBase,
991 public ::testing::WithParamInterface<bool> {
992 public:
WebRtcEventLogManagerTestWithRemoteLoggingDisabled()993 WebRtcEventLogManagerTestWithRemoteLoggingDisabled()
994 : feature_enabled_(GetParam()), policy_enabled_(!feature_enabled_) {
995 if (feature_enabled_) {
996 scoped_feature_list_.InitAndEnableFeature(
997 features::kWebRtcRemoteEventLog);
998 } else {
999 scoped_feature_list_.InitAndDisableFeature(
1000 features::kWebRtcRemoteEventLog);
1001 }
1002 CreateWebRtcEventLogManager();
1003 }
1004
1005 ~WebRtcEventLogManagerTestWithRemoteLoggingDisabled() override = default;
1006
1007 // Override CreateBrowserContext() to use policy_enabled_.
CreateBrowserContext()1008 std::unique_ptr<TestingProfile> CreateBrowserContext() override {
1009 return CreateBrowserContext(std::string());
1010 }
CreateBrowserContext(std::string profile_name)1011 std::unique_ptr<TestingProfile> CreateBrowserContext(
1012 std::string profile_name) override {
1013 return CreateBrowserContext(profile_name, policy_enabled_,
1014 false /* has_device_level_policies */,
1015 policy_enabled_);
1016 }
CreateBrowserContext(std::string profile_name,bool is_managed_profile,bool has_device_level_policies,base::Optional<bool> policy_allows_remote_logging)1017 std::unique_ptr<TestingProfile> CreateBrowserContext(
1018 std::string profile_name,
1019 bool is_managed_profile,
1020 bool has_device_level_policies,
1021 base::Optional<bool> policy_allows_remote_logging) override {
1022 DCHECK_EQ(policy_enabled_, policy_allows_remote_logging.value());
1023 return WebRtcEventLogManagerTestBase::CreateBrowserContext(
1024 profile_name, is_managed_profile, has_device_level_policies,
1025 policy_allows_remote_logging);
1026 }
1027
1028 private:
1029 const bool feature_enabled_; // Whether the Finch kill-switch is engaged.
1030 const bool policy_enabled_; // Whether the policy is enabled for the profile.
1031 };
1032
1033 class WebRtcEventLogManagerTestPolicy : public WebRtcEventLogManagerTestBase {
1034 public:
1035 ~WebRtcEventLogManagerTestPolicy() override = default;
1036
1037 // Defer to setup from the body.
SetUp()1038 void SetUp() override {}
1039
SetUp(bool feature_enabled)1040 void SetUp(bool feature_enabled) {
1041 if (feature_enabled) {
1042 scoped_feature_list_.InitAndEnableFeature(
1043 features::kWebRtcRemoteEventLog);
1044 } else {
1045 scoped_feature_list_.InitAndDisableFeature(
1046 features::kWebRtcRemoteEventLog);
1047 }
1048
1049 scoped_command_line_.GetProcessCommandLine()->AppendSwitchASCII(
1050 ::switches::kWebRtcRemoteEventLogUploadDelayMs, "0");
1051
1052 CreateWebRtcEventLogManager(Compression::GZIP_PERFECT_ESTIMATION);
1053
1054 WebRtcEventLogManagerTestBase::SetUp();
1055 }
1056
1057 #if defined(OS_CHROMEOS)
1058 std::unique_ptr<user_manager::ScopedUserManager> GetScopedUserManager(
1059 user_manager::UserType user_type);
1060 #endif
1061
1062 void TestManagedProfileAfterBeingExplicitlySet(bool explicitly_set_value);
1063 };
1064
1065 class WebRtcEventLogManagerTestUploadSuppressionDisablingFlag
1066 : public WebRtcEventLogManagerTestBase {
1067 public:
WebRtcEventLogManagerTestUploadSuppressionDisablingFlag()1068 WebRtcEventLogManagerTestUploadSuppressionDisablingFlag() {
1069 scoped_feature_list_.InitAndEnableFeature(features::kWebRtcRemoteEventLog);
1070
1071 scoped_command_line_.GetProcessCommandLine()->AppendSwitch(
1072 ::switches::kWebRtcRemoteEventLogUploadNoSuppression);
1073
1074 // Use a low delay, or the tests would run for quite a long time.
1075 scoped_command_line_.GetProcessCommandLine()->AppendSwitchASCII(
1076 ::switches::kWebRtcRemoteEventLogUploadDelayMs, "100");
1077
1078 CreateWebRtcEventLogManager();
1079 }
1080
1081 ~WebRtcEventLogManagerTestUploadSuppressionDisablingFlag() override = default;
1082 };
1083
1084 class WebRtcEventLogManagerTestForNetworkConnectivity
1085 : public WebRtcEventLogManagerTestBase,
1086 public ::testing::WithParamInterface<
1087 std::tuple<bool,
1088 network::mojom::ConnectionType,
1089 network::mojom::ConnectionType>> {
1090 public:
WebRtcEventLogManagerTestForNetworkConnectivity()1091 WebRtcEventLogManagerTestForNetworkConnectivity()
1092 : get_conn_type_is_sync_(std::get<0>(GetParam())),
1093 supported_type_(std::get<1>(GetParam())),
1094 unsupported_type_(std::get<2>(GetParam())) {
1095 scoped_feature_list_.InitAndEnableFeature(features::kWebRtcRemoteEventLog);
1096
1097 // Use a low delay, or the tests would run for quite a long time.
1098 scoped_command_line_.GetProcessCommandLine()->AppendSwitchASCII(
1099 ::switches::kWebRtcRemoteEventLogUploadDelayMs, "100");
1100
1101 CreateWebRtcEventLogManager();
1102 }
1103
1104 ~WebRtcEventLogManagerTestForNetworkConnectivity() override = default;
1105
UnloadProfileAndSeedPendingLog()1106 void UnloadProfileAndSeedPendingLog() {
1107 DCHECK(browser_context_path_.empty()) << "Not expected to be called twice.";
1108
1109 // Unload the profile, but remember where it stores its files (for sanity).
1110 browser_context_path_ = browser_context_->GetPath();
1111 const base::FilePath remote_logs_dir =
1112 RemoteBoundLogsDir(browser_context_.get());
1113 UnloadMainTestProfile();
1114
1115 // Seed the remote logs' directory with one log file, simulating the
1116 // creation of logs in a previous session.
1117 ASSERT_TRUE(base::CreateDirectory(remote_logs_dir));
1118
1119 base::FilePath file_path;
1120 ASSERT_TRUE(CreateRemoteBoundLogFile(
1121 remote_logs_dir, kWebAppId, remote_log_extension_, base::Time::Now(),
1122 &file_path, &file_));
1123
1124 expected_files_.emplace_back(browser_context_id_, file_path,
1125 GetLastModificationTime(file_path));
1126 }
1127
1128 const bool get_conn_type_is_sync_;
1129 const network::mojom::ConnectionType supported_type_;
1130 const network::mojom::ConnectionType unsupported_type_;
1131
1132 base::FilePath browser_context_path_; // For sanity over the test itself.
1133 std::list<WebRtcLogFileInfo> expected_files_;
1134 base::File file_;
1135 };
1136
1137 class WebRtcEventLogManagerTestUploadDelay
1138 : public WebRtcEventLogManagerTestBase {
1139 public:
1140 ~WebRtcEventLogManagerTestUploadDelay() override = default;
1141
SetUp()1142 void SetUp() override {
1143 // Intercept and block the call to SetUp(). The test body will call
1144 // the version that sets an upload delay instead.
1145 }
1146
SetUp(size_t upload_delay_ms)1147 void SetUp(size_t upload_delay_ms) {
1148 scoped_feature_list_.InitAndEnableFeature(features::kWebRtcRemoteEventLog);
1149
1150 scoped_command_line_.GetProcessCommandLine()->AppendSwitchASCII(
1151 ::switches::kWebRtcRemoteEventLogUploadDelayMs,
1152 std::to_string(upload_delay_ms));
1153
1154 CreateWebRtcEventLogManager();
1155
1156 WebRtcEventLogManagerTestBase::SetUp();
1157 }
1158
1159 // There's a trade-off between the test runtime and the likelihood of a
1160 // false-positive (lowered when the time is increased).
1161 // Since false-positives can be caught handled even if only manifesting
1162 // occasionally, this value should be enough.
1163 static const size_t kDefaultUploadDelayMs = 500;
1164
1165 // For tests where we don't intend to wait, prevent flakiness by setting
1166 // an unrealistically long delay.
1167 static const size_t kIntentionallyExcessiveDelayMs = 1000 * 1000 * 1000;
1168 };
1169
1170 // For testing compression issues.
1171 class WebRtcEventLogManagerTestCompression
1172 : public WebRtcEventLogManagerTestBase {
1173 public:
WebRtcEventLogManagerTestCompression()1174 WebRtcEventLogManagerTestCompression() {
1175 scoped_feature_list_.InitAndEnableFeature(features::kWebRtcRemoteEventLog);
1176
1177 scoped_command_line_.GetProcessCommandLine()->AppendSwitchASCII(
1178 ::switches::kWebRtcRemoteEventLogUploadDelayMs, "0");
1179 }
1180
1181 ~WebRtcEventLogManagerTestCompression() override = default;
1182
SetUp()1183 void SetUp() override {
1184 // Defer until Init(), which will allow the test body more control.
1185 }
1186
Init(base::Optional<WebRtcEventLogCompression> remote_compression=base::Optional<WebRtcEventLogCompression> ())1187 void Init(base::Optional<WebRtcEventLogCompression> remote_compression =
1188 base::Optional<WebRtcEventLogCompression>()) {
1189 CreateWebRtcEventLogManager(remote_compression);
1190
1191 WebRtcEventLogManagerTestBase::SetUp();
1192 }
1193 };
1194
1195 class WebRtcEventLogManagerTestIncognito
1196 : public WebRtcEventLogManagerTestBase {
1197 public:
WebRtcEventLogManagerTestIncognito()1198 WebRtcEventLogManagerTestIncognito() : incognito_profile_(nullptr) {
1199 scoped_feature_list_.InitAndEnableFeature(features::kWebRtcRemoteEventLog);
1200 CreateWebRtcEventLogManager();
1201 }
1202
~WebRtcEventLogManagerTestIncognito()1203 ~WebRtcEventLogManagerTestIncognito() override {
1204 incognito_rph_.reset();
1205 if (incognito_profile_) {
1206 DCHECK(browser_context_);
1207 browser_context_->DestroyOffTheRecordProfile(incognito_profile_);
1208 }
1209 }
1210
SetUp()1211 void SetUp() override {
1212 WebRtcEventLogManagerTestBase::SetUp();
1213
1214 incognito_profile_ = browser_context_->GetPrimaryOTRProfile();
1215 incognito_rph_ =
1216 std::make_unique<MockRenderProcessHost>(incognito_profile_);
1217 }
1218
1219 Profile* incognito_profile_;
1220 std::unique_ptr<MockRenderProcessHost> incognito_rph_;
1221 };
1222
1223 class WebRtcEventLogManagerTestHistory : public WebRtcEventLogManagerTestBase {
1224 public:
WebRtcEventLogManagerTestHistory()1225 WebRtcEventLogManagerTestHistory() {
1226 scoped_command_line_.GetProcessCommandLine()->AppendSwitchASCII(
1227 ::switches::kWebRtcRemoteEventLogUploadDelayMs, "0");
1228
1229 CreateWebRtcEventLogManager();
1230 }
1231
1232 ~WebRtcEventLogManagerTestHistory() override = default;
1233
1234 // Allows us to test that a time is as expected, down to UNIX time's
1235 // lower resolution than our clock.
IsSameTimeWhenTruncatedToSeconds(base::Time a,base::Time b)1236 static bool IsSameTimeWhenTruncatedToSeconds(base::Time a, base::Time b) {
1237 if (a.is_null() || b.is_null()) {
1238 return false;
1239 }
1240 const base::TimeDelta delta = std::max(a, b) - std::min(a, b);
1241 return delta.InSeconds() == 0;
1242 }
1243
1244 // Allows us to check that the timestamps are roughly what we expect.
1245 // Doing better than this would require too much effort.
IsSmallTimeDelta(base::Time a,base::Time b)1246 static bool IsSmallTimeDelta(base::Time a, base::Time b) {
1247 if (a.is_null() || b.is_null()) {
1248 return false;
1249 }
1250
1251 // Way more than is "small", to make sure tests don't become flaky.
1252 // If the timestamp is ever off, it's likely to be off by more than this,
1253 // though, or the problem would not truly be severe enough to worry about.
1254 const base::TimeDelta small_delta = base::TimeDelta::FromMinutes(15);
1255
1256 return (std::max(a, b) - std::min(a, b) <= small_delta);
1257 }
1258 };
1259
1260 namespace {
1261
1262 class PeerConnectionTrackerProxyForTesting
1263 : public WebRtcEventLogManager::PeerConnectionTrackerProxy {
1264 public:
PeerConnectionTrackerProxyForTesting(WebRtcEventLogManagerTestBase * test)1265 explicit PeerConnectionTrackerProxyForTesting(
1266 WebRtcEventLogManagerTestBase* test)
1267 : test_(test) {}
1268
1269 ~PeerConnectionTrackerProxyForTesting() override = default;
1270
EnableWebRtcEventLogging(const PeerConnectionKey & key,int output_period_ms)1271 void EnableWebRtcEventLogging(const PeerConnectionKey& key,
1272 int output_period_ms) override {
1273 test_->SetWebRtcEventLoggingState(key, true);
1274 }
DisableWebRtcEventLogging(const PeerConnectionKey & key)1275 void DisableWebRtcEventLogging(const PeerConnectionKey& key) override {
1276 test_->SetWebRtcEventLoggingState(key, false);
1277 }
1278
1279 private:
1280 WebRtcEventLogManagerTestBase* const test_;
1281 };
1282
1283 // The factory for the following fake uploader produces a sequence of
1284 // uploaders which fail the test if given a file other than that which they
1285 // expect. The factory itself likewise fails the test if destroyed before
1286 // producing all expected uploaders, or if it's asked for more uploaders than
1287 // it expects to create. This allows us to test for sequences of uploads.
1288 class FileListExpectingWebRtcEventLogUploader : public WebRtcEventLogUploader {
1289 public:
1290 class Factory : public WebRtcEventLogUploader::Factory {
1291 public:
Factory(std::list<WebRtcLogFileInfo> * expected_files,bool result,base::RunLoop * run_loop)1292 Factory(std::list<WebRtcLogFileInfo>* expected_files,
1293 bool result,
1294 base::RunLoop* run_loop)
1295 : result_(result), run_loop_(run_loop) {
1296 expected_files_.swap(*expected_files);
1297 if (expected_files_.empty()) {
1298 run_loop_->QuitWhenIdle();
1299 }
1300 }
1301
~Factory()1302 ~Factory() override { EXPECT_TRUE(expected_files_.empty()); }
1303
Create(const WebRtcLogFileInfo & log_file,UploadResultCallback callback)1304 std::unique_ptr<WebRtcEventLogUploader> Create(
1305 const WebRtcLogFileInfo& log_file,
1306 UploadResultCallback callback) override {
1307 if (expected_files_.empty()) {
1308 EXPECT_FALSE(true); // More files uploaded than expected.
1309 } else {
1310 EXPECT_EQ(log_file.path, expected_files_.front().path);
1311 // Because LoadMainTestProfile() and UnloadMainTestProfile() mess up the
1312 // BrowserContextId in ways that would not happen in production,
1313 // we cannot verify |log_file.browser_context_id| is correct.
1314 // This is unimportant to the test.
1315
1316 base::DeleteFile(log_file.path);
1317 expected_files_.pop_front();
1318 }
1319
1320 if (expected_files_.empty()) {
1321 run_loop_->QuitWhenIdle();
1322 }
1323
1324 return std::make_unique<FileListExpectingWebRtcEventLogUploader>(
1325 log_file, result_, std::move(callback));
1326 }
1327
1328 private:
1329 std::list<WebRtcLogFileInfo> expected_files_;
1330 const bool result_;
1331 base::RunLoop* const run_loop_;
1332 };
1333
1334 // The logic is in the factory; the uploader just reports success so that the
1335 // next file may become eligible for uploading.
FileListExpectingWebRtcEventLogUploader(const WebRtcLogFileInfo & log_file,bool result,UploadResultCallback callback)1336 FileListExpectingWebRtcEventLogUploader(const WebRtcLogFileInfo& log_file,
1337 bool result,
1338 UploadResultCallback callback)
1339 : log_file_(log_file) {
1340 base::SequencedTaskRunnerHandle::Get()->PostTask(
1341 FROM_HERE, base::BindOnce(std::move(callback), log_file_.path, result));
1342 }
1343
1344 ~FileListExpectingWebRtcEventLogUploader() override = default;
1345
GetWebRtcLogFileInfo() const1346 const WebRtcLogFileInfo& GetWebRtcLogFileInfo() const override {
1347 return log_file_;
1348 }
1349
Cancel()1350 void Cancel() override {
1351 NOTREACHED() << "Incompatible with this kind of test.";
1352 }
1353
1354 private:
1355 const WebRtcLogFileInfo log_file_;
1356 };
1357
1358 } // namespace
1359
TEST_F(WebRtcEventLogManagerTest,PeerConnectionAddedReturnsTrue)1360 TEST_F(WebRtcEventLogManagerTest, PeerConnectionAddedReturnsTrue) {
1361 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
1362 EXPECT_TRUE(PeerConnectionAdded(key));
1363 }
1364
TEST_F(WebRtcEventLogManagerTest,PeerConnectionAddedReturnsFalseIfAlreadyAdded)1365 TEST_F(WebRtcEventLogManagerTest,
1366 PeerConnectionAddedReturnsFalseIfAlreadyAdded) {
1367 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
1368 ASSERT_TRUE(PeerConnectionAdded(key));
1369 EXPECT_FALSE(PeerConnectionAdded(key));
1370 }
1371
TEST_F(WebRtcEventLogManagerTest,PeerConnectionRemovedReturnsTrue)1372 TEST_F(WebRtcEventLogManagerTest, PeerConnectionRemovedReturnsTrue) {
1373 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
1374 ASSERT_TRUE(PeerConnectionAdded(key));
1375 EXPECT_TRUE(PeerConnectionRemoved(key));
1376 }
1377
TEST_F(WebRtcEventLogManagerTest,PeerConnectionRemovedReturnsFalseIfNeverAdded)1378 TEST_F(WebRtcEventLogManagerTest,
1379 PeerConnectionRemovedReturnsFalseIfNeverAdded) {
1380 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
1381 EXPECT_FALSE(PeerConnectionRemoved(key));
1382 }
1383
TEST_F(WebRtcEventLogManagerTest,PeerConnectionRemovedReturnsFalseIfAlreadyRemoved)1384 TEST_F(WebRtcEventLogManagerTest,
1385 PeerConnectionRemovedReturnsFalseIfAlreadyRemoved) {
1386 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
1387 ASSERT_TRUE(PeerConnectionAdded(key));
1388 ASSERT_TRUE(PeerConnectionRemoved(key));
1389 EXPECT_FALSE(PeerConnectionRemoved(key));
1390 }
1391
TEST_F(WebRtcEventLogManagerTest,PeerConnectionSessionIdSetReturnsTrue)1392 TEST_F(WebRtcEventLogManagerTest, PeerConnectionSessionIdSetReturnsTrue) {
1393 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
1394 ASSERT_TRUE(PeerConnectionAdded(key));
1395 EXPECT_TRUE(PeerConnectionSessionIdSet(key));
1396 }
1397
TEST_F(WebRtcEventLogManagerTest,PeerConnectionSessionIdSetReturnsFalseIfEmptyString)1398 TEST_F(WebRtcEventLogManagerTest,
1399 PeerConnectionSessionIdSetReturnsFalseIfEmptyString) {
1400 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
1401 ASSERT_TRUE(PeerConnectionAdded(key));
1402 EXPECT_FALSE(PeerConnectionSessionIdSet(key, ""));
1403 }
1404
TEST_F(WebRtcEventLogManagerTest,PeerConnectionSessionIdSetReturnsFalseIfPeerConnectionNeverAdded)1405 TEST_F(WebRtcEventLogManagerTest,
1406 PeerConnectionSessionIdSetReturnsFalseIfPeerConnectionNeverAdded) {
1407 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
1408 EXPECT_FALSE(PeerConnectionSessionIdSet(key, kSessionId));
1409 }
1410
TEST_F(WebRtcEventLogManagerTest,PeerConnectionSessionIdSetReturnsFalseIfPeerConnectionAlreadyRemoved)1411 TEST_F(WebRtcEventLogManagerTest,
1412 PeerConnectionSessionIdSetReturnsFalseIfPeerConnectionAlreadyRemoved) {
1413 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
1414 ASSERT_TRUE(PeerConnectionAdded(key));
1415 ASSERT_TRUE(PeerConnectionRemoved(key));
1416 EXPECT_FALSE(PeerConnectionSessionIdSet(key, kSessionId));
1417 }
1418
TEST_F(WebRtcEventLogManagerTest,PeerConnectionSessionIdSetReturnsTrueIfAlreadyCalledSameId)1419 TEST_F(WebRtcEventLogManagerTest,
1420 PeerConnectionSessionIdSetReturnsTrueIfAlreadyCalledSameId) {
1421 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
1422 ASSERT_TRUE(PeerConnectionAdded(key));
1423 ASSERT_TRUE(PeerConnectionSessionIdSet(key, kSessionId));
1424 EXPECT_TRUE(PeerConnectionSessionIdSet(key, kSessionId));
1425 }
1426
TEST_F(WebRtcEventLogManagerTest,PeerConnectionSessionIdSetReturnsFalseIfAlreadyCalledDifferentId)1427 TEST_F(WebRtcEventLogManagerTest,
1428 PeerConnectionSessionIdSetReturnsFalseIfAlreadyCalledDifferentId) {
1429 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
1430 ASSERT_TRUE(PeerConnectionAdded(key));
1431 ASSERT_TRUE(PeerConnectionSessionIdSet(key, "id1"));
1432 EXPECT_FALSE(PeerConnectionSessionIdSet(key, "id2"));
1433 }
1434
TEST_F(WebRtcEventLogManagerTest,PeerConnectionSessionIdSetCalledOnRecreatedPeerConnectionSanity)1435 TEST_F(WebRtcEventLogManagerTest,
1436 PeerConnectionSessionIdSetCalledOnRecreatedPeerConnectionSanity) {
1437 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
1438 ASSERT_TRUE(PeerConnectionAdded(key));
1439 ASSERT_TRUE(PeerConnectionSessionIdSet(key, kSessionId));
1440 ASSERT_TRUE(PeerConnectionRemoved(key));
1441 ASSERT_TRUE(PeerConnectionAdded(key));
1442 EXPECT_TRUE(PeerConnectionSessionIdSet(key, kSessionId));
1443 }
1444
TEST_F(WebRtcEventLogManagerTest,EnableLocalLoggingReturnsTrue)1445 TEST_F(WebRtcEventLogManagerTest, EnableLocalLoggingReturnsTrue) {
1446 EXPECT_TRUE(EnableLocalLogging());
1447 }
1448
TEST_F(WebRtcEventLogManagerTest,EnableLocalLoggingReturnsFalseIfCalledWhenAlreadyEnabled)1449 TEST_F(WebRtcEventLogManagerTest,
1450 EnableLocalLoggingReturnsFalseIfCalledWhenAlreadyEnabled) {
1451 ASSERT_TRUE(EnableLocalLogging());
1452 EXPECT_FALSE(EnableLocalLogging());
1453 }
1454
TEST_F(WebRtcEventLogManagerTest,DisableLocalLoggingReturnsTrue)1455 TEST_F(WebRtcEventLogManagerTest, DisableLocalLoggingReturnsTrue) {
1456 ASSERT_TRUE(EnableLocalLogging());
1457 EXPECT_TRUE(DisableLocalLogging());
1458 }
1459
TEST_F(WebRtcEventLogManagerTest,DisableLocalLoggingReturnsIfNeverEnabled)1460 TEST_F(WebRtcEventLogManagerTest, DisableLocalLoggingReturnsIfNeverEnabled) {
1461 EXPECT_FALSE(DisableLocalLogging());
1462 }
1463
TEST_F(WebRtcEventLogManagerTest,DisableLocalLoggingReturnsIfAlreadyDisabled)1464 TEST_F(WebRtcEventLogManagerTest, DisableLocalLoggingReturnsIfAlreadyDisabled) {
1465 ASSERT_TRUE(EnableLocalLogging());
1466 ASSERT_TRUE(DisableLocalLogging());
1467 EXPECT_FALSE(DisableLocalLogging());
1468 }
1469
TEST_F(WebRtcEventLogManagerTest,OnWebRtcEventLogWriteReturnsFalseAndFalseWhenAllLoggingDisabled)1470 TEST_F(WebRtcEventLogManagerTest,
1471 OnWebRtcEventLogWriteReturnsFalseAndFalseWhenAllLoggingDisabled) {
1472 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
1473 // Note that EnableLocalLogging() and StartRemoteLogging() weren't called.
1474 ASSERT_TRUE(PeerConnectionAdded(key));
1475 EXPECT_EQ(OnWebRtcEventLogWrite(key, "log"), std::make_pair(false, false));
1476 }
1477
TEST_F(WebRtcEventLogManagerTest,OnWebRtcEventLogWriteReturnsFalseAndFalseForUnknownPeerConnection)1478 TEST_F(WebRtcEventLogManagerTest,
1479 OnWebRtcEventLogWriteReturnsFalseAndFalseForUnknownPeerConnection) {
1480 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
1481 ASSERT_TRUE(EnableLocalLogging());
1482 // Note that PeerConnectionAdded() wasn't called.
1483 EXPECT_EQ(OnWebRtcEventLogWrite(key, "log"), std::make_pair(false, false));
1484 }
1485
TEST_F(WebRtcEventLogManagerTest,OnWebRtcEventLogWriteReturnsLocalTrueWhenPcKnownAndLocalLoggingOn)1486 TEST_F(WebRtcEventLogManagerTest,
1487 OnWebRtcEventLogWriteReturnsLocalTrueWhenPcKnownAndLocalLoggingOn) {
1488 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
1489 ASSERT_TRUE(EnableLocalLogging());
1490 ASSERT_TRUE(PeerConnectionAdded(key));
1491 EXPECT_EQ(OnWebRtcEventLogWrite(key, "log"), std::make_pair(true, false));
1492 }
1493
TEST_F(WebRtcEventLogManagerTest,OnWebRtcEventLogWriteReturnsRemoteTrueWhenPcKnownAndRemoteLogging)1494 TEST_F(WebRtcEventLogManagerTest,
1495 OnWebRtcEventLogWriteReturnsRemoteTrueWhenPcKnownAndRemoteLogging) {
1496 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
1497 ASSERT_TRUE(PeerConnectionAdded(key));
1498 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
1499 ASSERT_TRUE(StartRemoteLogging(key));
1500 EXPECT_EQ(OnWebRtcEventLogWrite(key, "log"), std::make_pair(false, true));
1501 }
1502
TEST_F(WebRtcEventLogManagerTest,OnWebRtcEventLogWriteReturnsTrueAndTrueeWhenAllLoggingEnabled)1503 TEST_F(WebRtcEventLogManagerTest,
1504 OnWebRtcEventLogWriteReturnsTrueAndTrueeWhenAllLoggingEnabled) {
1505 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
1506 ASSERT_TRUE(PeerConnectionAdded(key));
1507 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
1508 ASSERT_TRUE(EnableLocalLogging());
1509 ASSERT_TRUE(StartRemoteLogging(key));
1510 EXPECT_EQ(OnWebRtcEventLogWrite(key, "log"), std::make_pair(true, true));
1511 }
1512
TEST_F(WebRtcEventLogManagerTest,OnLocalLogStartedNotCalledIfLocalLoggingEnabledWithoutPeerConnections)1513 TEST_F(WebRtcEventLogManagerTest,
1514 OnLocalLogStartedNotCalledIfLocalLoggingEnabledWithoutPeerConnections) {
1515 EXPECT_CALL(local_observer_, OnLocalLogStarted(_, _)).Times(0);
1516 ASSERT_TRUE(EnableLocalLogging());
1517 }
1518
TEST_F(WebRtcEventLogManagerTest,OnLocalLogStoppedNotCalledIfLocalLoggingDisabledWithoutPeerConnections)1519 TEST_F(WebRtcEventLogManagerTest,
1520 OnLocalLogStoppedNotCalledIfLocalLoggingDisabledWithoutPeerConnections) {
1521 EXPECT_CALL(local_observer_, OnLocalLogStopped(_)).Times(0);
1522 ASSERT_TRUE(EnableLocalLogging());
1523 ASSERT_TRUE(DisableLocalLogging());
1524 }
1525
TEST_F(WebRtcEventLogManagerTest,OnLocalLogStartedCalledForPeerConnectionAddedAndLocalLoggingEnabled)1526 TEST_F(WebRtcEventLogManagerTest,
1527 OnLocalLogStartedCalledForPeerConnectionAddedAndLocalLoggingEnabled) {
1528 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
1529 EXPECT_CALL(local_observer_, OnLocalLogStarted(key, _)).Times(1);
1530 ASSERT_TRUE(PeerConnectionAdded(key));
1531 ASSERT_TRUE(EnableLocalLogging());
1532 }
1533
TEST_F(WebRtcEventLogManagerTest,OnLocalLogStartedCalledForLocalLoggingEnabledAndPeerConnectionAdded)1534 TEST_F(WebRtcEventLogManagerTest,
1535 OnLocalLogStartedCalledForLocalLoggingEnabledAndPeerConnectionAdded) {
1536 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
1537 EXPECT_CALL(local_observer_, OnLocalLogStarted(key, _)).Times(1);
1538 ASSERT_TRUE(EnableLocalLogging());
1539 ASSERT_TRUE(PeerConnectionAdded(key));
1540 }
1541
TEST_F(WebRtcEventLogManagerTest,OnLocalLogStoppedCalledAfterLocalLoggingDisabled)1542 TEST_F(WebRtcEventLogManagerTest,
1543 OnLocalLogStoppedCalledAfterLocalLoggingDisabled) {
1544 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
1545 EXPECT_CALL(local_observer_, OnLocalLogStopped(key)).Times(1);
1546 ASSERT_TRUE(PeerConnectionAdded(key));
1547 ASSERT_TRUE(EnableLocalLogging());
1548 ASSERT_TRUE(DisableLocalLogging());
1549 }
1550
TEST_F(WebRtcEventLogManagerTest,OnLocalLogStoppedCalledAfterPeerConnectionRemoved)1551 TEST_F(WebRtcEventLogManagerTest,
1552 OnLocalLogStoppedCalledAfterPeerConnectionRemoved) {
1553 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
1554 EXPECT_CALL(local_observer_, OnLocalLogStopped(key)).Times(1);
1555 ASSERT_TRUE(PeerConnectionAdded(key));
1556 ASSERT_TRUE(EnableLocalLogging());
1557 ASSERT_TRUE(PeerConnectionRemoved(key));
1558 }
1559
TEST_F(WebRtcEventLogManagerTest,LocalLogCreatesEmptyFileWhenStarted)1560 TEST_F(WebRtcEventLogManagerTest, LocalLogCreatesEmptyFileWhenStarted) {
1561 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
1562 base::Optional<base::FilePath> file_path;
1563 ON_CALL(local_observer_, OnLocalLogStarted(key, _))
1564 .WillByDefault(Invoke(SaveFilePathTo(&file_path)));
1565
1566 ASSERT_TRUE(EnableLocalLogging());
1567 ASSERT_TRUE(PeerConnectionAdded(key));
1568 ASSERT_TRUE(file_path);
1569 ASSERT_FALSE(file_path->empty());
1570
1571 // Make sure the file would be closed, so that we could safely read it.
1572 ASSERT_TRUE(PeerConnectionRemoved(key));
1573
1574 ExpectLocalFileContents(*file_path, std::string());
1575 }
1576
TEST_F(WebRtcEventLogManagerTest,LocalLogCreateAndWriteToFile)1577 TEST_F(WebRtcEventLogManagerTest, LocalLogCreateAndWriteToFile) {
1578 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
1579
1580 base::Optional<base::FilePath> file_path;
1581 ON_CALL(local_observer_, OnLocalLogStarted(key, _))
1582 .WillByDefault(Invoke(SaveFilePathTo(&file_path)));
1583
1584 ASSERT_TRUE(EnableLocalLogging());
1585 ASSERT_TRUE(PeerConnectionAdded(key));
1586 ASSERT_TRUE(file_path);
1587 ASSERT_FALSE(file_path->empty());
1588
1589 const std::string log = "To strive, to seek, to find, and not to yield.";
1590 ASSERT_EQ(OnWebRtcEventLogWrite(key, log), std::make_pair(true, false));
1591
1592 // Make sure the file would be closed, so that we could safely read it.
1593 ASSERT_TRUE(PeerConnectionRemoved(key));
1594
1595 ExpectLocalFileContents(*file_path, log);
1596 }
1597
TEST_F(WebRtcEventLogManagerTest,LocalLogMultipleWritesToSameFile)1598 TEST_F(WebRtcEventLogManagerTest, LocalLogMultipleWritesToSameFile) {
1599 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
1600
1601 base::Optional<base::FilePath> file_path;
1602 ON_CALL(local_observer_, OnLocalLogStarted(key, _))
1603 .WillByDefault(Invoke(SaveFilePathTo(&file_path)));
1604
1605 ASSERT_TRUE(EnableLocalLogging());
1606 ASSERT_TRUE(PeerConnectionAdded(key));
1607 ASSERT_TRUE(file_path);
1608 ASSERT_FALSE(file_path->empty());
1609
1610 const std::string logs[] = {"Old age hath yet his honour and his toil;",
1611 "Death closes all: but something ere the end,",
1612 "Some work of noble note, may yet be done,",
1613 "Not unbecoming men that strove with Gods."};
1614 for (const std::string& log : logs) {
1615 ASSERT_EQ(OnWebRtcEventLogWrite(key, log), std::make_pair(true, false));
1616 }
1617
1618 // Make sure the file would be closed, so that we could safely read it.
1619 ASSERT_TRUE(PeerConnectionRemoved(key));
1620
1621 ExpectLocalFileContents(
1622 *file_path,
1623 std::accumulate(std::begin(logs), std::end(logs), std::string()));
1624 }
1625
TEST_F(WebRtcEventLogManagerTest,LocalLogFileSizeLimitNotExceeded)1626 TEST_F(WebRtcEventLogManagerTest, LocalLogFileSizeLimitNotExceeded) {
1627 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
1628
1629 base::Optional<base::FilePath> file_path;
1630 ON_CALL(local_observer_, OnLocalLogStarted(key, _))
1631 .WillByDefault(Invoke(SaveFilePathTo(&file_path)));
1632
1633 const std::string log = "There lies the port; the vessel puffs her sail:";
1634 const size_t file_size_limit_bytes = log.length() / 2;
1635
1636 ASSERT_TRUE(EnableLocalLogging(file_size_limit_bytes));
1637 ASSERT_TRUE(PeerConnectionAdded(key));
1638 ASSERT_TRUE(file_path);
1639 ASSERT_FALSE(file_path->empty());
1640
1641 // Failure is reported, because not everything could be written. The file
1642 // will also be closed.
1643 EXPECT_CALL(local_observer_, OnLocalLogStopped(key)).Times(1);
1644 ASSERT_EQ(OnWebRtcEventLogWrite(key, log), std::make_pair(false, false));
1645
1646 // Additional calls to Write() have no effect.
1647 ASSERT_EQ(OnWebRtcEventLogWrite(key, "ignored"),
1648 std::make_pair(false, false));
1649
1650 ExpectLocalFileContents(*file_path, std::string());
1651 }
1652
TEST_F(WebRtcEventLogManagerTest,LocalLogSanityOverUnlimitedFileSizes)1653 TEST_F(WebRtcEventLogManagerTest, LocalLogSanityOverUnlimitedFileSizes) {
1654 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
1655
1656 base::Optional<base::FilePath> file_path;
1657 ON_CALL(local_observer_, OnLocalLogStarted(key, _))
1658 .WillByDefault(Invoke(SaveFilePathTo(&file_path)));
1659
1660 ASSERT_TRUE(EnableLocalLogging(kWebRtcEventLogManagerUnlimitedFileSize));
1661 ASSERT_TRUE(PeerConnectionAdded(key));
1662 ASSERT_TRUE(file_path);
1663 ASSERT_FALSE(file_path->empty());
1664
1665 const std::string log1 = "Who let the dogs out?";
1666 const std::string log2 = "Woof, woof, woof, woof, woof!";
1667 ASSERT_EQ(OnWebRtcEventLogWrite(key, log1), std::make_pair(true, false));
1668 ASSERT_EQ(OnWebRtcEventLogWrite(key, log2), std::make_pair(true, false));
1669
1670 // Make sure the file would be closed, so that we could safely read it.
1671 ASSERT_TRUE(PeerConnectionRemoved(key));
1672
1673 ExpectLocalFileContents(*file_path, log1 + log2);
1674 }
1675
TEST_F(WebRtcEventLogManagerTest,LocalLogNoWriteAfterLogStopped)1676 TEST_F(WebRtcEventLogManagerTest, LocalLogNoWriteAfterLogStopped) {
1677 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
1678
1679 base::Optional<base::FilePath> file_path;
1680 ON_CALL(local_observer_, OnLocalLogStarted(key, _))
1681 .WillByDefault(Invoke(SaveFilePathTo(&file_path)));
1682
1683 ASSERT_TRUE(EnableLocalLogging());
1684 ASSERT_TRUE(PeerConnectionAdded(key));
1685 ASSERT_TRUE(file_path);
1686 ASSERT_FALSE(file_path->empty());
1687
1688 const std::string log_before = "log_before_stop";
1689 ASSERT_EQ(OnWebRtcEventLogWrite(key, log_before),
1690 std::make_pair(true, false));
1691 EXPECT_CALL(local_observer_, OnLocalLogStopped(key)).Times(1);
1692 ASSERT_TRUE(PeerConnectionRemoved(key));
1693
1694 const std::string log_after = "log_after_stop";
1695 ASSERT_EQ(OnWebRtcEventLogWrite(key, log_after),
1696 std::make_pair(false, false));
1697
1698 ExpectLocalFileContents(*file_path, log_before);
1699 }
1700
TEST_F(WebRtcEventLogManagerTest,LocalLogOnlyWritesTheLogsAfterStarted)1701 TEST_F(WebRtcEventLogManagerTest, LocalLogOnlyWritesTheLogsAfterStarted) {
1702 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
1703
1704 // Calls to Write() before the log was started are ignored.
1705 EXPECT_CALL(local_observer_, OnLocalLogStarted(_, _)).Times(0);
1706 const std::string log1 = "The lights begin to twinkle from the rocks:";
1707 ASSERT_EQ(OnWebRtcEventLogWrite(key, log1), std::make_pair(false, false));
1708 ASSERT_TRUE(base::IsDirectoryEmpty(local_logs_base_dir_.GetPath()));
1709
1710 base::Optional<base::FilePath> file_path;
1711 EXPECT_CALL(local_observer_, OnLocalLogStarted(key, _))
1712 .Times(1)
1713 .WillOnce(Invoke(SaveFilePathTo(&file_path)));
1714
1715 ASSERT_TRUE(EnableLocalLogging());
1716 ASSERT_TRUE(PeerConnectionAdded(key));
1717 ASSERT_TRUE(file_path);
1718 ASSERT_FALSE(file_path->empty());
1719
1720 // Calls after the log started have an effect. The calls to Write() from
1721 // before the log started are not remembered.
1722 const std::string log2 = "The long day wanes: the slow moon climbs: the deep";
1723 ASSERT_EQ(OnWebRtcEventLogWrite(key, log2), std::make_pair(true, false));
1724
1725 // Make sure the file would be closed, so that we could safely read it.
1726 ASSERT_TRUE(PeerConnectionRemoved(key));
1727
1728 ExpectLocalFileContents(*file_path, log2);
1729 }
1730
1731 // Note: This test also covers the scenario LocalLogExistingFilesNotOverwritten,
1732 // which is therefore not explicitly tested.
TEST_F(WebRtcEventLogManagerTest,LocalLoggingRestartCreatesNewFile)1733 TEST_F(WebRtcEventLogManagerTest, LocalLoggingRestartCreatesNewFile) {
1734 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
1735
1736 const std::vector<std::string> logs = {"<setup>", "<punchline>", "<encore>"};
1737 std::vector<base::Optional<PeerConnectionKey>> keys(logs.size());
1738 std::vector<base::Optional<base::FilePath>> file_paths(logs.size());
1739
1740 ASSERT_TRUE(PeerConnectionAdded(key));
1741
1742 for (size_t i = 0; i < logs.size(); ++i) {
1743 ON_CALL(local_observer_, OnLocalLogStarted(_, _))
1744 .WillByDefault(Invoke(SaveKeyAndFilePathTo(&keys[i], &file_paths[i])));
1745 ASSERT_TRUE(EnableLocalLogging());
1746 ASSERT_TRUE(keys[i]);
1747 ASSERT_EQ(*keys[i], key);
1748 ASSERT_TRUE(file_paths[i]);
1749 ASSERT_FALSE(file_paths[i]->empty());
1750 ASSERT_EQ(OnWebRtcEventLogWrite(key, logs[i]), std::make_pair(true, false));
1751 ASSERT_TRUE(DisableLocalLogging());
1752 }
1753
1754 for (size_t i = 0; i < logs.size(); ++i) {
1755 ExpectLocalFileContents(*file_paths[i], logs[i]);
1756 }
1757 }
1758
TEST_F(WebRtcEventLogManagerTest,LocalLogMultipleActiveFiles)1759 TEST_F(WebRtcEventLogManagerTest, LocalLogMultipleActiveFiles) {
1760 ASSERT_TRUE(EnableLocalLogging());
1761
1762 std::list<MockRenderProcessHost> rphs;
1763 for (size_t i = 0; i < 3; ++i) {
1764 rphs.emplace_back(browser_context_.get()); // (MockRenderProcessHost ctor)
1765 }
1766
1767 std::vector<PeerConnectionKey> keys;
1768 for (auto& rph : rphs) {
1769 keys.push_back(GetPeerConnectionKey(&rph, kLid));
1770 }
1771
1772 std::vector<base::Optional<base::FilePath>> file_paths(keys.size());
1773 for (size_t i = 0; i < keys.size(); ++i) {
1774 ON_CALL(local_observer_, OnLocalLogStarted(keys[i], _))
1775 .WillByDefault(Invoke(SaveFilePathTo(&file_paths[i])));
1776 ASSERT_TRUE(PeerConnectionAdded(keys[i]));
1777 ASSERT_TRUE(file_paths[i]);
1778 ASSERT_FALSE(file_paths[i]->empty());
1779 }
1780
1781 std::vector<std::string> logs;
1782 for (size_t i = 0; i < keys.size(); ++i) {
1783 logs.emplace_back(std::to_string(rph_->GetID()) + std::to_string(kLid));
1784 ASSERT_EQ(OnWebRtcEventLogWrite(keys[i], logs[i]),
1785 std::make_pair(true, false));
1786 }
1787
1788 // Make sure the file woulds be closed, so that we could safely read them.
1789 ASSERT_TRUE(DisableLocalLogging());
1790
1791 for (size_t i = 0; i < keys.size(); ++i) {
1792 ExpectLocalFileContents(*file_paths[i], logs[i]);
1793 }
1794 }
1795
TEST_F(WebRtcEventLogManagerTest,LocalLogLimitActiveLocalLogFiles)1796 TEST_F(WebRtcEventLogManagerTest, LocalLogLimitActiveLocalLogFiles) {
1797 ASSERT_TRUE(EnableLocalLogging());
1798
1799 const int kMaxLocalLogFiles =
1800 static_cast<int>(kMaxNumberLocalWebRtcEventLogFiles);
1801 for (int i = 0; i < kMaxLocalLogFiles; ++i) {
1802 const auto key = GetPeerConnectionKey(rph_.get(), i);
1803 EXPECT_CALL(local_observer_, OnLocalLogStarted(key, _)).Times(1);
1804 ASSERT_TRUE(PeerConnectionAdded(key));
1805 }
1806
1807 EXPECT_CALL(local_observer_, OnLocalLogStarted(_, _)).Times(0);
1808 const auto last_key = GetPeerConnectionKey(rph_.get(), kMaxLocalLogFiles);
1809 ASSERT_TRUE(PeerConnectionAdded(last_key));
1810 }
1811
1812 // When a log reaches its maximum size limit, it is closed, and no longer
1813 // counted towards the limit.
TEST_F(WebRtcEventLogManagerTest,LocalLogFilledLogNotCountedTowardsLogsLimit)1814 TEST_F(WebRtcEventLogManagerTest, LocalLogFilledLogNotCountedTowardsLogsLimit) {
1815 const std::string log = "very_short_log";
1816 ASSERT_TRUE(EnableLocalLogging(log.size()));
1817
1818 const int kMaxLocalLogFiles =
1819 static_cast<int>(kMaxNumberLocalWebRtcEventLogFiles);
1820 for (int i = 0; i < kMaxLocalLogFiles; ++i) {
1821 const auto key = GetPeerConnectionKey(rph_.get(), i);
1822 EXPECT_CALL(local_observer_, OnLocalLogStarted(key, _)).Times(1);
1823 ASSERT_TRUE(PeerConnectionAdded(key));
1824 }
1825
1826 // By writing to one of the logs, we fill it and end up closing it, allowing
1827 // an additional log to be written.
1828 const auto removed_key = GetPeerConnectionKey(rph_.get(), 0);
1829 EXPECT_EQ(OnWebRtcEventLogWrite(removed_key, log),
1830 std::make_pair(true, false));
1831
1832 // We now have room for one additional log.
1833 const auto last_key = GetPeerConnectionKey(rph_.get(), kMaxLocalLogFiles);
1834 EXPECT_CALL(local_observer_, OnLocalLogStarted(last_key, _)).Times(1);
1835 ASSERT_TRUE(PeerConnectionAdded(last_key));
1836 }
1837
TEST_F(WebRtcEventLogManagerTest,LocalLogForRemovedPeerConnectionNotCountedTowardsLogsLimit)1838 TEST_F(WebRtcEventLogManagerTest,
1839 LocalLogForRemovedPeerConnectionNotCountedTowardsLogsLimit) {
1840 ASSERT_TRUE(EnableLocalLogging());
1841
1842 const int kMaxLocalLogFiles =
1843 static_cast<int>(kMaxNumberLocalWebRtcEventLogFiles);
1844 for (int i = 0; i < kMaxLocalLogFiles; ++i) {
1845 const auto key = GetPeerConnectionKey(rph_.get(), i);
1846 EXPECT_CALL(local_observer_, OnLocalLogStarted(key, _)).Times(1);
1847 ASSERT_TRUE(PeerConnectionAdded(key));
1848 }
1849
1850 // When one peer connection is removed, one log is stopped, thereby allowing
1851 // an additional log to be opened.
1852 const auto removed_key = GetPeerConnectionKey(rph_.get(), 0);
1853 EXPECT_CALL(local_observer_, OnLocalLogStopped(removed_key)).Times(1);
1854 ASSERT_TRUE(PeerConnectionRemoved(removed_key));
1855
1856 // We now have room for one additional log.
1857 const auto last_key = GetPeerConnectionKey(rph_.get(), kMaxLocalLogFiles);
1858 EXPECT_CALL(local_observer_, OnLocalLogStarted(last_key, _)).Times(1);
1859 ASSERT_TRUE(PeerConnectionAdded(last_key));
1860 }
1861
TEST_F(WebRtcEventLogManagerTest,LocalLogIllegalPath)1862 TEST_F(WebRtcEventLogManagerTest, LocalLogIllegalPath) {
1863 // Since the log file won't be properly opened, these will not be called.
1864 EXPECT_CALL(local_observer_, OnLocalLogStarted(_, _)).Times(0);
1865 EXPECT_CALL(local_observer_, OnLocalLogStopped(_)).Times(0);
1866
1867 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
1868 ASSERT_TRUE(PeerConnectionAdded(key));
1869
1870 // See the documentation of the function for why |true| is expected despite
1871 // the path being illegal.
1872 const base::FilePath illegal_path(FILE_PATH_LITERAL(":!@#$%|`^&*\\/"));
1873 EXPECT_TRUE(EnableLocalLogging(illegal_path));
1874
1875 EXPECT_TRUE(base::IsDirectoryEmpty(local_logs_base_dir_.GetPath()));
1876 }
1877
1878 #if defined(OS_POSIX)
TEST_F(WebRtcEventLogManagerTest,LocalLogLegalPathWithoutPermissionsSanity)1879 TEST_F(WebRtcEventLogManagerTest, LocalLogLegalPathWithoutPermissionsSanity) {
1880 RemoveWritePermissions(local_logs_base_dir_.GetPath());
1881
1882 // Since the log file won't be properly opened, these will not be called.
1883 EXPECT_CALL(local_observer_, OnLocalLogStarted(_, _)).Times(0);
1884 EXPECT_CALL(local_observer_, OnLocalLogStopped(_)).Times(0);
1885
1886 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
1887 ASSERT_TRUE(PeerConnectionAdded(key));
1888
1889 // See the documentation of the function for why |true| is expected despite
1890 // the path being illegal.
1891 EXPECT_TRUE(EnableLocalLogging(local_logs_base_path_));
1892
1893 EXPECT_TRUE(base::IsDirectoryEmpty(local_logs_base_dir_.GetPath()));
1894
1895 // Write() has no effect (but is handled gracefully).
1896 EXPECT_EQ(OnWebRtcEventLogWrite(key, "Why did the chicken cross the road?"),
1897 std::make_pair(false, false));
1898 EXPECT_TRUE(base::IsDirectoryEmpty(local_logs_base_dir_.GetPath()));
1899
1900 // Logging was enabled, even if it had no effect because of the lacking
1901 // permissions; therefore, the operation of disabling it makes sense.
1902 EXPECT_TRUE(DisableLocalLogging());
1903 EXPECT_TRUE(base::IsDirectoryEmpty(local_logs_base_dir_.GetPath()));
1904 }
1905 #endif // defined(OS_POSIX)
1906
TEST_F(WebRtcEventLogManagerTest,LocalLogEmptyStringHandledGracefully)1907 TEST_F(WebRtcEventLogManagerTest, LocalLogEmptyStringHandledGracefully) {
1908 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
1909
1910 // By writing a log after the empty string, we show that no odd behavior is
1911 // encountered, such as closing the file (an actual bug from WebRTC).
1912 const std::vector<std::string> logs = {"<setup>", "", "<encore>"};
1913
1914 base::Optional<base::FilePath> file_path;
1915
1916 ON_CALL(local_observer_, OnLocalLogStarted(key, _))
1917 .WillByDefault(Invoke(SaveFilePathTo(&file_path)));
1918 ASSERT_TRUE(EnableLocalLogging());
1919 ASSERT_TRUE(PeerConnectionAdded(key));
1920 ASSERT_TRUE(file_path);
1921 ASSERT_FALSE(file_path->empty());
1922
1923 for (size_t i = 0; i < logs.size(); ++i) {
1924 ASSERT_EQ(OnWebRtcEventLogWrite(key, logs[i]), std::make_pair(true, false));
1925 }
1926 ASSERT_TRUE(DisableLocalLogging());
1927
1928 ExpectLocalFileContents(
1929 *file_path,
1930 std::accumulate(std::begin(logs), std::end(logs), std::string()));
1931 }
1932
TEST_F(WebRtcEventLogManagerTest,LocalLogFilenameMatchesExpectedFormat)1933 TEST_F(WebRtcEventLogManagerTest, LocalLogFilenameMatchesExpectedFormat) {
1934 using StringType = base::FilePath::StringType;
1935
1936 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
1937
1938 base::Optional<base::FilePath> file_path;
1939 ON_CALL(local_observer_, OnLocalLogStarted(key, _))
1940 .WillByDefault(Invoke(SaveFilePathTo(&file_path)));
1941
1942 const base::Time::Exploded frozen_time_exploded{
1943 2017, // Four digit year "2007"
1944 9, // 1-based month (values 1 = January, etc.)
1945 3, // 0-based day of week (0 = Sunday, etc.)
1946 6, // 1-based day of month (1-31)
1947 10, // Hour within the current day (0-23)
1948 43, // Minute within the current hour (0-59)
1949 29, // Second within the current minute.
1950 0 // Milliseconds within the current second (0-999)
1951 };
1952 ASSERT_TRUE(frozen_time_exploded.HasValidValues());
1953 FreezeClockAt(frozen_time_exploded);
1954
1955 const StringType user_defined = FILE_PATH_LITERAL("user_defined");
1956 const base::FilePath local_logs_base_path =
1957 local_logs_base_dir_.GetPath().Append(user_defined);
1958
1959 ASSERT_TRUE(EnableLocalLogging(local_logs_base_path));
1960 ASSERT_TRUE(PeerConnectionAdded(key));
1961 ASSERT_TRUE(file_path);
1962 ASSERT_FALSE(file_path->empty());
1963
1964 // [user_defined]_[date]_[time]_[render_process_id]_[lid].[extension]
1965 const StringType date = FILE_PATH_LITERAL("20170906");
1966 const StringType time = FILE_PATH_LITERAL("1043");
1967 base::FilePath expected_path = local_logs_base_path;
1968 expected_path = local_logs_base_path.InsertBeforeExtension(
1969 FILE_PATH_LITERAL("_") + date + FILE_PATH_LITERAL("_") + time +
1970 FILE_PATH_LITERAL("_") + NumberToStringType(rph_->GetID()) +
1971 FILE_PATH_LITERAL("_") + NumberToStringType(kLid));
1972 expected_path = expected_path.AddExtension(local_log_extension_);
1973
1974 EXPECT_EQ(file_path, expected_path);
1975 }
1976
TEST_F(WebRtcEventLogManagerTest,LocalLogFilenameMatchesExpectedFormatRepeatedFilename)1977 TEST_F(WebRtcEventLogManagerTest,
1978 LocalLogFilenameMatchesExpectedFormatRepeatedFilename) {
1979 using StringType = base::FilePath::StringType;
1980
1981 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
1982
1983 base::Optional<base::FilePath> file_path_1;
1984 base::Optional<base::FilePath> file_path_2;
1985 EXPECT_CALL(local_observer_, OnLocalLogStarted(key, _))
1986 .WillOnce(Invoke(SaveFilePathTo(&file_path_1)))
1987 .WillOnce(Invoke(SaveFilePathTo(&file_path_2)));
1988
1989 const base::Time::Exploded frozen_time_exploded{
1990 2017, // Four digit year "2007"
1991 9, // 1-based month (values 1 = January, etc.)
1992 3, // 0-based day of week (0 = Sunday, etc.)
1993 6, // 1-based day of month (1-31)
1994 10, // Hour within the current day (0-23)
1995 43, // Minute within the current hour (0-59)
1996 29, // Second within the current minute.
1997 0 // Milliseconds within the current second (0-999)
1998 };
1999 ASSERT_TRUE(frozen_time_exploded.HasValidValues());
2000 FreezeClockAt(frozen_time_exploded);
2001
2002 const StringType user_defined_portion = FILE_PATH_LITERAL("user_defined");
2003 const base::FilePath local_logs_base_path =
2004 local_logs_base_dir_.GetPath().Append(user_defined_portion);
2005
2006 ASSERT_TRUE(EnableLocalLogging(local_logs_base_path));
2007 ASSERT_TRUE(PeerConnectionAdded(key));
2008 ASSERT_TRUE(file_path_1);
2009 ASSERT_FALSE(file_path_1->empty());
2010
2011 // [user_defined]_[date]_[time]_[render_process_id]_[lid].[extension]
2012 const StringType date = FILE_PATH_LITERAL("20170906");
2013 const StringType time = FILE_PATH_LITERAL("1043");
2014 base::FilePath expected_path_1 = local_logs_base_path;
2015 expected_path_1 = local_logs_base_path.InsertBeforeExtension(
2016 FILE_PATH_LITERAL("_") + date + FILE_PATH_LITERAL("_") + time +
2017 FILE_PATH_LITERAL("_") + NumberToStringType(rph_->GetID()) +
2018 FILE_PATH_LITERAL("_") + NumberToStringType(kLid));
2019 expected_path_1 = expected_path_1.AddExtension(local_log_extension_);
2020
2021 ASSERT_EQ(file_path_1, expected_path_1);
2022
2023 ASSERT_TRUE(DisableLocalLogging());
2024 ASSERT_TRUE(EnableLocalLogging(local_logs_base_path));
2025 ASSERT_TRUE(file_path_2);
2026 ASSERT_FALSE(file_path_2->empty());
2027
2028 const base::FilePath expected_path_2 =
2029 expected_path_1.InsertBeforeExtension(FILE_PATH_LITERAL(" (1)"));
2030
2031 // Focus of the test - starting the same log again produces a new file,
2032 // with an expected new filename.
2033 ASSERT_EQ(file_path_2, expected_path_2);
2034 }
2035
TEST_F(WebRtcEventLogManagerTest,OnRemoteLogStartedNotCalledIfRemoteLoggingNotEnabled)2036 TEST_F(WebRtcEventLogManagerTest,
2037 OnRemoteLogStartedNotCalledIfRemoteLoggingNotEnabled) {
2038 EXPECT_CALL(remote_observer_, OnRemoteLogStarted(_, _, _)).Times(0);
2039 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
2040 ASSERT_TRUE(PeerConnectionAdded(key));
2041 EXPECT_TRUE(PeerConnectionSessionIdSet(key));
2042 }
2043
TEST_F(WebRtcEventLogManagerTest,OnRemoteLogStoppedNotCalledIfRemoteLoggingNotEnabled)2044 TEST_F(WebRtcEventLogManagerTest,
2045 OnRemoteLogStoppedNotCalledIfRemoteLoggingNotEnabled) {
2046 EXPECT_CALL(remote_observer_, OnRemoteLogStopped(_)).Times(0);
2047 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
2048 ASSERT_TRUE(PeerConnectionAdded(key));
2049 EXPECT_TRUE(PeerConnectionSessionIdSet(key));
2050 ASSERT_TRUE(PeerConnectionRemoved(key));
2051 }
2052
TEST_F(WebRtcEventLogManagerTest,OnRemoteLogStartedCalledIfRemoteLoggingEnabled)2053 TEST_F(WebRtcEventLogManagerTest,
2054 OnRemoteLogStartedCalledIfRemoteLoggingEnabled) {
2055 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
2056 EXPECT_CALL(remote_observer_, OnRemoteLogStarted(key, _, _)).Times(1);
2057 ASSERT_TRUE(PeerConnectionAdded(key));
2058 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
2059 ASSERT_TRUE(StartRemoteLogging(key));
2060 }
2061
TEST_F(WebRtcEventLogManagerTest,OnRemoteLogStoppedCalledIfRemoteLoggingEnabledThenPcRemoved)2062 TEST_F(WebRtcEventLogManagerTest,
2063 OnRemoteLogStoppedCalledIfRemoteLoggingEnabledThenPcRemoved) {
2064 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
2065 EXPECT_CALL(remote_observer_, OnRemoteLogStopped(key)).Times(1);
2066 ASSERT_TRUE(PeerConnectionAdded(key));
2067 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
2068 ASSERT_TRUE(StartRemoteLogging(key));
2069 ASSERT_TRUE(PeerConnectionRemoved(key));
2070 }
2071
TEST_F(WebRtcEventLogManagerTest,BrowserContextInitializationCreatesDirectoryForRemoteLogs)2072 TEST_F(WebRtcEventLogManagerTest,
2073 BrowserContextInitializationCreatesDirectoryForRemoteLogs) {
2074 auto browser_context = CreateBrowserContext();
2075 const base::FilePath remote_logs_path =
2076 RemoteBoundLogsDir(browser_context.get());
2077 EXPECT_TRUE(base::DirectoryExists(remote_logs_path));
2078 EXPECT_TRUE(base::IsDirectoryEmpty(remote_logs_path));
2079 }
2080
TEST_F(WebRtcEventLogManagerTest,StartRemoteLoggingReturnsFalseIfUnknownPeerConnection)2081 TEST_F(WebRtcEventLogManagerTest,
2082 StartRemoteLoggingReturnsFalseIfUnknownPeerConnection) {
2083 const auto key = GetPeerConnectionKey(rph_.get(), 0);
2084 std::string error_message;
2085 EXPECT_FALSE(StartRemoteLogging(key, "id", nullptr, &error_message));
2086 EXPECT_EQ(error_message,
2087 kStartRemoteLoggingFailureUnknownOrInactivePeerConnection);
2088 }
2089
TEST_F(WebRtcEventLogManagerTest,StartRemoteLoggingReturnsFalseIfUnknownSessionId)2090 TEST_F(WebRtcEventLogManagerTest,
2091 StartRemoteLoggingReturnsFalseIfUnknownSessionId) {
2092 const auto key = GetPeerConnectionKey(rph_.get(), 0);
2093 ASSERT_TRUE(PeerConnectionAdded(key));
2094 ASSERT_TRUE(PeerConnectionSessionIdSet(key, kSessionId));
2095 std::string error_message;
2096 EXPECT_FALSE(StartRemoteLogging(key, "wrong_id", nullptr, &error_message));
2097 EXPECT_EQ(error_message,
2098 kStartRemoteLoggingFailureUnknownOrInactivePeerConnection);
2099 }
2100
TEST_F(WebRtcEventLogManagerTest,StartRemoteLoggingReturnsTrueIfKnownSessionId)2101 TEST_F(WebRtcEventLogManagerTest,
2102 StartRemoteLoggingReturnsTrueIfKnownSessionId) {
2103 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
2104 ASSERT_TRUE(PeerConnectionAdded(key));
2105 ASSERT_TRUE(PeerConnectionSessionIdSet(key, kSessionId));
2106 EXPECT_TRUE(StartRemoteLogging(key, kSessionId));
2107 }
2108
TEST_F(WebRtcEventLogManagerTest,StartRemoteLoggingReturnsFalseIfRestartAttempt)2109 TEST_F(WebRtcEventLogManagerTest,
2110 StartRemoteLoggingReturnsFalseIfRestartAttempt) {
2111 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
2112 ASSERT_TRUE(PeerConnectionAdded(key));
2113 ASSERT_TRUE(PeerConnectionSessionIdSet(key, kSessionId));
2114 ASSERT_TRUE(StartRemoteLogging(key, kSessionId));
2115 std::string error_message;
2116 EXPECT_FALSE(StartRemoteLogging(key, kSessionId, nullptr, &error_message));
2117 EXPECT_EQ(error_message, kStartRemoteLoggingFailureAlreadyLogging);
2118 }
2119
TEST_F(WebRtcEventLogManagerTest,StartRemoteLoggingReturnsFalseIfUnlimitedFileSize)2120 TEST_F(WebRtcEventLogManagerTest,
2121 StartRemoteLoggingReturnsFalseIfUnlimitedFileSize) {
2122 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
2123 ASSERT_TRUE(PeerConnectionAdded(key));
2124 ASSERT_TRUE(PeerConnectionSessionIdSet(key, kSessionId));
2125 std::string error_message;
2126 EXPECT_FALSE(StartRemoteLogging(key, kSessionId,
2127 kWebRtcEventLogManagerUnlimitedFileSize, 0,
2128 kWebAppId, nullptr, &error_message));
2129 EXPECT_EQ(error_message, kStartRemoteLoggingFailureUnlimitedSizeDisallowed);
2130 }
2131
TEST_F(WebRtcEventLogManagerTest,StartRemoteLoggingReturnsTrueIfFileSizeAtOrBelowLimit)2132 TEST_F(WebRtcEventLogManagerTest,
2133 StartRemoteLoggingReturnsTrueIfFileSizeAtOrBelowLimit) {
2134 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
2135 ASSERT_TRUE(PeerConnectionAdded(key));
2136 ASSERT_TRUE(PeerConnectionSessionIdSet(key, kSessionId));
2137 EXPECT_TRUE(StartRemoteLogging(key, kSessionId, kMaxRemoteLogFileSizeBytes, 0,
2138 kWebAppId));
2139 }
2140
TEST_F(WebRtcEventLogManagerTest,StartRemoteLoggingReturnsFalseIfFileSizeToSmall)2141 TEST_F(WebRtcEventLogManagerTest,
2142 StartRemoteLoggingReturnsFalseIfFileSizeToSmall) {
2143 const size_t min_size =
2144 CreateLogFileWriterFactory(Compression::GZIP_NULL_ESTIMATION)
2145 ->MinFileSizeBytes();
2146
2147 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
2148 ASSERT_TRUE(PeerConnectionAdded(key));
2149 ASSERT_TRUE(PeerConnectionSessionIdSet(key, kSessionId));
2150 std::string error_message;
2151 EXPECT_FALSE(StartRemoteLogging(key, kSessionId, min_size - 1, 0, kWebAppId,
2152 nullptr, &error_message));
2153 EXPECT_EQ(error_message, kStartRemoteLoggingFailureMaxSizeTooSmall);
2154 }
2155
TEST_F(WebRtcEventLogManagerTest,StartRemoteLoggingReturnsFalseIfExcessivelyLargeFileSize)2156 TEST_F(WebRtcEventLogManagerTest,
2157 StartRemoteLoggingReturnsFalseIfExcessivelyLargeFileSize) {
2158 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
2159 ASSERT_TRUE(PeerConnectionAdded(key));
2160 ASSERT_TRUE(PeerConnectionSessionIdSet(key, kSessionId));
2161 std::string error_message;
2162 EXPECT_FALSE(StartRemoteLogging(key, kSessionId,
2163 kMaxRemoteLogFileSizeBytes + 1, 0, kWebAppId,
2164 nullptr, &error_message));
2165 EXPECT_EQ(error_message, kStartRemoteLoggingFailureMaxSizeTooLarge);
2166 }
2167
TEST_F(WebRtcEventLogManagerTest,StartRemoteLoggingReturnsFalseIfExcessivelyLargeOutputPeriodMs)2168 TEST_F(WebRtcEventLogManagerTest,
2169 StartRemoteLoggingReturnsFalseIfExcessivelyLargeOutputPeriodMs) {
2170 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
2171 ASSERT_TRUE(PeerConnectionAdded(key));
2172 ASSERT_TRUE(PeerConnectionSessionIdSet(key, kSessionId));
2173 std::string error_message;
2174 EXPECT_FALSE(StartRemoteLogging(key, kSessionId, kMaxRemoteLogFileSizeBytes,
2175 kMaxOutputPeriodMs + 1, kWebAppId, nullptr,
2176 &error_message));
2177 EXPECT_EQ(error_message, kStartRemoteLoggingFailureOutputPeriodMsTooLarge);
2178 }
2179
TEST_F(WebRtcEventLogManagerTest,StartRemoteLoggingReturnsFalseIfPeerConnectionAlreadyClosed)2180 TEST_F(WebRtcEventLogManagerTest,
2181 StartRemoteLoggingReturnsFalseIfPeerConnectionAlreadyClosed) {
2182 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
2183 ASSERT_TRUE(PeerConnectionAdded(key));
2184 ASSERT_TRUE(PeerConnectionSessionIdSet(key, kSessionId));
2185 ASSERT_TRUE(PeerConnectionRemoved(key));
2186 std::string error_message;
2187 EXPECT_FALSE(StartRemoteLogging(key, kSessionId, nullptr, &error_message));
2188 EXPECT_EQ(error_message,
2189 kStartRemoteLoggingFailureUnknownOrInactivePeerConnection);
2190 }
2191
TEST_F(WebRtcEventLogManagerTest,StartRemoteLoggingDoesNotReturnIdWhenUnsuccessful)2192 TEST_F(WebRtcEventLogManagerTest,
2193 StartRemoteLoggingDoesNotReturnIdWhenUnsuccessful) {
2194 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
2195 ASSERT_TRUE(PeerConnectionAdded(key));
2196 ASSERT_TRUE(PeerConnectionSessionIdSet(key, kSessionId));
2197 ASSERT_TRUE(PeerConnectionRemoved(key));
2198
2199 std::string log_id;
2200 ASSERT_FALSE(StartRemoteLogging(key, kSessionId, &log_id));
2201
2202 EXPECT_TRUE(log_id.empty());
2203 }
2204
TEST_F(WebRtcEventLogManagerTest,StartRemoteLoggingReturnsLegalIdWhenSuccessful)2205 TEST_F(WebRtcEventLogManagerTest,
2206 StartRemoteLoggingReturnsLegalIdWhenSuccessful) {
2207 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
2208 ASSERT_TRUE(PeerConnectionAdded(key));
2209 ASSERT_TRUE(PeerConnectionSessionIdSet(key, kSessionId));
2210
2211 std::string log_id;
2212 ASSERT_TRUE(StartRemoteLogging(key, kSessionId, &log_id));
2213
2214 EXPECT_EQ(log_id.size(), 32u);
2215 EXPECT_EQ(log_id.find_first_not_of("0123456789ABCDEF"), std::string::npos);
2216 }
2217
TEST_F(WebRtcEventLogManagerTest,StartRemoteLoggingSavesToFileWithCorrectFileNameFormat)2218 TEST_F(WebRtcEventLogManagerTest,
2219 StartRemoteLoggingSavesToFileWithCorrectFileNameFormat) {
2220 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
2221
2222 base::Optional<base::FilePath> file_path;
2223 ON_CALL(remote_observer_, OnRemoteLogStarted(key, _, _))
2224 .WillByDefault(Invoke(SaveFilePathTo(&file_path)));
2225
2226 ASSERT_TRUE(PeerConnectionAdded(key));
2227 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
2228
2229 std::string log_id;
2230 ASSERT_TRUE(StartRemoteLogging(key, &log_id));
2231
2232 // Compare filename (without extension).
2233 const std::string filename =
2234 file_path->BaseName().RemoveExtension().MaybeAsASCII();
2235 ASSERT_FALSE(filename.empty());
2236
2237 const std::string expected_filename =
2238 std::string(kRemoteBoundWebRtcEventLogFileNamePrefix) + "_" +
2239 std::to_string(kWebAppId) + "_" + log_id;
2240 EXPECT_EQ(filename, expected_filename);
2241
2242 // Compare extension.
2243 EXPECT_EQ(base::FilePath::kExtensionSeparator +
2244 base::FilePath::StringType(remote_log_extension_),
2245 file_path->Extension());
2246 }
2247
TEST_F(WebRtcEventLogManagerTest,StartRemoteLoggingCreatesEmptyFile)2248 TEST_F(WebRtcEventLogManagerTest, StartRemoteLoggingCreatesEmptyFile) {
2249 base::Optional<base::FilePath> file_path;
2250 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
2251 EXPECT_CALL(remote_observer_, OnRemoteLogStarted(key, _, _))
2252 .Times(1)
2253 .WillOnce(Invoke(SaveFilePathTo(&file_path)));
2254
2255 ASSERT_TRUE(PeerConnectionAdded(key));
2256 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
2257 ASSERT_TRUE(StartRemoteLogging(key));
2258
2259 // Close file before examining its contents.
2260 ASSERT_TRUE(PeerConnectionRemoved(key));
2261
2262 ExpectRemoteFileContents(*file_path, std::string());
2263 }
2264
TEST_F(WebRtcEventLogManagerTest,RemoteLogFileCreatedInCorrectDirectory)2265 TEST_F(WebRtcEventLogManagerTest, RemoteLogFileCreatedInCorrectDirectory) {
2266 // Set up separate browser contexts; each one will get one log.
2267 constexpr size_t kLogsNum = 3;
2268 std::unique_ptr<TestingProfile> browser_contexts[kLogsNum];
2269 std::vector<std::unique_ptr<MockRenderProcessHost>> rphs;
2270 for (size_t i = 0; i < kLogsNum; ++i) {
2271 browser_contexts[i] = CreateBrowserContext();
2272 rphs.emplace_back(
2273 std::make_unique<MockRenderProcessHost>(browser_contexts[i].get()));
2274 }
2275
2276 // Prepare to store the logs' paths in distinct memory locations.
2277 base::Optional<base::FilePath> file_paths[kLogsNum];
2278 for (size_t i = 0; i < kLogsNum; ++i) {
2279 const auto key = GetPeerConnectionKey(rphs[i].get(), kLid);
2280 EXPECT_CALL(remote_observer_, OnRemoteLogStarted(key, _, _))
2281 .Times(1)
2282 .WillOnce(Invoke(SaveFilePathTo(&file_paths[i])));
2283 }
2284
2285 // Start one log for each browser context.
2286 for (const auto& rph : rphs) {
2287 const auto key = GetPeerConnectionKey(&*rph, kLid);
2288 ASSERT_TRUE(PeerConnectionAdded(key));
2289 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
2290 ASSERT_TRUE(StartRemoteLogging(key));
2291 }
2292
2293 // All log files must be created in their own context's directory.
2294 for (size_t i = 0; i < base::size(browser_contexts); ++i) {
2295 ASSERT_TRUE(file_paths[i]);
2296 EXPECT_TRUE(browser_contexts[i]->GetPath().IsParent(*file_paths[i]));
2297 }
2298 }
2299
TEST_F(WebRtcEventLogManagerTest,StartRemoteLoggingSanityIfDuplicateIdsInDifferentRendererProcesses)2300 TEST_F(WebRtcEventLogManagerTest,
2301 StartRemoteLoggingSanityIfDuplicateIdsInDifferentRendererProcesses) {
2302 std::unique_ptr<MockRenderProcessHost> rphs[2] = {
2303 std::make_unique<MockRenderProcessHost>(browser_context_.get()),
2304 std::make_unique<MockRenderProcessHost>(browser_context_.get()),
2305 };
2306
2307 PeerConnectionKey keys[2] = {GetPeerConnectionKey(rphs[0].get(), 0),
2308 GetPeerConnectionKey(rphs[1].get(), 0)};
2309
2310 // The ID is shared, but that's not a problem, because the renderer process
2311 // are different.
2312 const std::string id = "shared_id";
2313 ASSERT_TRUE(PeerConnectionAdded(keys[0]));
2314 PeerConnectionSessionIdSet(keys[0], id);
2315 ASSERT_TRUE(PeerConnectionAdded(keys[1]));
2316 PeerConnectionSessionIdSet(keys[1], id);
2317
2318 // Make sure the logs get written to separate files.
2319 base::Optional<base::FilePath> file_paths[2];
2320 for (size_t i = 0; i < 2; ++i) {
2321 EXPECT_CALL(remote_observer_, OnRemoteLogStarted(keys[i], _, _))
2322 .Times(1)
2323 .WillOnce(Invoke(SaveFilePathTo(&file_paths[i])));
2324 }
2325
2326 EXPECT_TRUE(StartRemoteLogging(keys[0], id));
2327 EXPECT_TRUE(StartRemoteLogging(keys[1], id));
2328
2329 EXPECT_TRUE(file_paths[0]);
2330 EXPECT_TRUE(file_paths[1]);
2331 EXPECT_NE(file_paths[0], file_paths[1]);
2332 }
2333
TEST_F(WebRtcEventLogManagerTest,OnWebRtcEventLogWriteWritesToTheRemoteBoundFile)2334 TEST_F(WebRtcEventLogManagerTest,
2335 OnWebRtcEventLogWriteWritesToTheRemoteBoundFile) {
2336 base::Optional<base::FilePath> file_path;
2337 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
2338 EXPECT_CALL(remote_observer_, OnRemoteLogStarted(key, _, _))
2339 .Times(1)
2340 .WillOnce(Invoke(SaveFilePathTo(&file_path)));
2341
2342 ASSERT_TRUE(PeerConnectionAdded(key));
2343 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
2344 ASSERT_TRUE(StartRemoteLogging(key));
2345
2346 const char* const log = "1 + 1 = 3";
2347 EXPECT_EQ(OnWebRtcEventLogWrite(key, log), std::make_pair(false, true));
2348
2349 // Close file before examining its contents.
2350 ASSERT_TRUE(PeerConnectionRemoved(key));
2351
2352 ExpectRemoteFileContents(*file_path, log);
2353 }
2354
TEST_F(WebRtcEventLogManagerTest,WriteToBothLocalAndRemoteFiles)2355 TEST_F(WebRtcEventLogManagerTest, WriteToBothLocalAndRemoteFiles) {
2356 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
2357 ASSERT_TRUE(PeerConnectionAdded(key));
2358 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
2359
2360 base::Optional<base::FilePath> local_path;
2361 EXPECT_CALL(local_observer_, OnLocalLogStarted(key, _))
2362 .Times(1)
2363 .WillOnce(Invoke(SaveFilePathTo(&local_path)));
2364
2365 base::Optional<base::FilePath> remote_path;
2366 EXPECT_CALL(remote_observer_, OnRemoteLogStarted(key, _, _))
2367 .Times(1)
2368 .WillOnce(Invoke(SaveFilePathTo(&remote_path)));
2369
2370 ASSERT_TRUE(EnableLocalLogging());
2371 ASSERT_TRUE(StartRemoteLogging(key));
2372
2373 ASSERT_TRUE(local_path);
2374 ASSERT_FALSE(local_path->empty());
2375 ASSERT_TRUE(remote_path);
2376 ASSERT_FALSE(remote_path->empty());
2377
2378 const char* const log = "logloglog";
2379 ASSERT_EQ(OnWebRtcEventLogWrite(key, log), std::make_pair(true, true));
2380
2381 // Ensure the flushing of the file to disk before attempting to read them.
2382 ASSERT_TRUE(PeerConnectionRemoved(key));
2383
2384 ExpectLocalFileContents(*local_path, log);
2385 ExpectRemoteFileContents(*remote_path, log);
2386 }
2387
TEST_F(WebRtcEventLogManagerTest,MultipleWritesToSameRemoteBoundLogfile)2388 TEST_F(WebRtcEventLogManagerTest, MultipleWritesToSameRemoteBoundLogfile) {
2389 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
2390
2391 base::Optional<base::FilePath> file_path;
2392 ON_CALL(remote_observer_, OnRemoteLogStarted(key, _, _))
2393 .WillByDefault(Invoke(SaveFilePathTo(&file_path)));
2394
2395 ASSERT_TRUE(PeerConnectionAdded(key));
2396 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
2397 ASSERT_TRUE(StartRemoteLogging(key));
2398 ASSERT_TRUE(file_path);
2399 ASSERT_FALSE(file_path->empty());
2400
2401 const std::string logs[] = {"ABC", "DEF", "XYZ"};
2402 for (const std::string& log : logs) {
2403 ASSERT_EQ(OnWebRtcEventLogWrite(key, log), std::make_pair(false, true));
2404 }
2405
2406 // Make sure the file would be closed, so that we could safely read it.
2407 ASSERT_TRUE(PeerConnectionRemoved(key));
2408
2409 ExpectRemoteFileContents(
2410 *file_path,
2411 std::accumulate(std::begin(logs), std::end(logs), std::string()));
2412 }
2413
TEST_F(WebRtcEventLogManagerTest,RemoteLogFileSizeLimitNotExceededSingleWrite)2414 TEST_F(WebRtcEventLogManagerTest,
2415 RemoteLogFileSizeLimitNotExceededSingleWrite) {
2416 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
2417 base::Optional<base::FilePath> file_path;
2418 ON_CALL(remote_observer_, OnRemoteLogStarted(key, _, _))
2419 .WillByDefault(Invoke(SaveFilePathTo(&file_path)));
2420
2421 const std::string log = "tpyo";
2422
2423 ASSERT_TRUE(PeerConnectionAdded(key));
2424 ASSERT_TRUE(PeerConnectionSessionIdSet(key, kSessionId));
2425 ASSERT_TRUE(
2426 StartRemoteLogging(key, kSessionId, GzippedSize(log) - 1, 0, kWebAppId));
2427
2428 // Failure is reported, because not everything could be written. The file
2429 // will also be closed.
2430 EXPECT_CALL(remote_observer_, OnRemoteLogStopped(key)).Times(1);
2431 ASSERT_EQ(OnWebRtcEventLogWrite(key, log), std::make_pair(false, false));
2432
2433 // Make sure the file would be closed, so that we could safely read it.
2434 ASSERT_TRUE(PeerConnectionRemoved(key));
2435
2436 // No partial writes occurred.
2437 ExpectRemoteFileContents(*file_path, std::string());
2438 }
2439
TEST_F(WebRtcEventLogManagerTest,RemoteLogFileSizeLimitNotExceededMultipleWrites)2440 TEST_F(WebRtcEventLogManagerTest,
2441 RemoteLogFileSizeLimitNotExceededMultipleWrites) {
2442 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
2443 base::Optional<base::FilePath> file_path;
2444 ON_CALL(remote_observer_, OnRemoteLogStarted(key, _, _))
2445 .WillByDefault(Invoke(SaveFilePathTo(&file_path)));
2446
2447 const std::string log1 = "abcabc";
2448 const std::string log2 = "defghijklmnopqrstuvwxyz";
2449
2450 ASSERT_TRUE(PeerConnectionAdded(key));
2451 ASSERT_TRUE(PeerConnectionSessionIdSet(key, kSessionId));
2452 ASSERT_TRUE(
2453 StartRemoteLogging(key, kSessionId, 1 + GzippedSize(log1), 0, kWebAppId));
2454
2455 // First write works.
2456 ASSERT_EQ(OnWebRtcEventLogWrite(key, log1), std::make_pair(false, true));
2457
2458 // On the second write, failure is reported, because not everything could be
2459 // written. The file will also be closed.
2460 EXPECT_CALL(remote_observer_, OnRemoteLogStopped(key)).Times(1);
2461 ASSERT_EQ(OnWebRtcEventLogWrite(key, log2), std::make_pair(false, false));
2462
2463 ExpectRemoteFileContents(*file_path, log1);
2464 }
2465
TEST_F(WebRtcEventLogManagerTest,LogMultipleActiveRemoteLogsSameBrowserContext)2466 TEST_F(WebRtcEventLogManagerTest,
2467 LogMultipleActiveRemoteLogsSameBrowserContext) {
2468 const std::vector<PeerConnectionKey> keys = {
2469 GetPeerConnectionKey(rph_.get(), 0), GetPeerConnectionKey(rph_.get(), 1),
2470 GetPeerConnectionKey(rph_.get(), 2)};
2471
2472 std::vector<base::Optional<base::FilePath>> file_paths(keys.size());
2473 for (size_t i = 0; i < keys.size(); ++i) {
2474 ON_CALL(remote_observer_, OnRemoteLogStarted(keys[i], _, _))
2475 .WillByDefault(Invoke(SaveFilePathTo(&file_paths[i])));
2476 ASSERT_TRUE(PeerConnectionAdded(keys[i]));
2477 ASSERT_TRUE(PeerConnectionSessionIdSet(keys[i]));
2478 ASSERT_TRUE(StartRemoteLogging(keys[i]));
2479 ASSERT_TRUE(file_paths[i]);
2480 ASSERT_FALSE(file_paths[i]->empty());
2481 }
2482
2483 std::vector<std::string> logs;
2484 for (size_t i = 0; i < keys.size(); ++i) {
2485 logs.emplace_back(std::to_string(rph_->GetID()) + std::to_string(i));
2486 ASSERT_EQ(OnWebRtcEventLogWrite(keys[i], logs[i]),
2487 std::make_pair(false, true));
2488 }
2489
2490 // Make sure the file woulds be closed, so that we could safely read them.
2491 for (auto& key : keys) {
2492 ASSERT_TRUE(PeerConnectionRemoved(key));
2493 }
2494
2495 for (size_t i = 0; i < keys.size(); ++i) {
2496 ExpectRemoteFileContents(*file_paths[i], logs[i]);
2497 }
2498 }
2499
TEST_F(WebRtcEventLogManagerTest,LogMultipleActiveRemoteLogsDifferentBrowserContexts)2500 TEST_F(WebRtcEventLogManagerTest,
2501 LogMultipleActiveRemoteLogsDifferentBrowserContexts) {
2502 constexpr size_t kLogsNum = 3;
2503 std::unique_ptr<TestingProfile> browser_contexts[kLogsNum];
2504 std::vector<std::unique_ptr<MockRenderProcessHost>> rphs;
2505 for (size_t i = 0; i < kLogsNum; ++i) {
2506 browser_contexts[i] = CreateBrowserContext();
2507 rphs.emplace_back(
2508 std::make_unique<MockRenderProcessHost>(browser_contexts[i].get()));
2509 }
2510
2511 std::vector<PeerConnectionKey> keys;
2512 for (auto& rph : rphs) {
2513 keys.push_back(GetPeerConnectionKey(rph.get(), kLid));
2514 }
2515
2516 std::vector<base::Optional<base::FilePath>> file_paths(keys.size());
2517 for (size_t i = 0; i < keys.size(); ++i) {
2518 ON_CALL(remote_observer_, OnRemoteLogStarted(keys[i], _, _))
2519 .WillByDefault(Invoke(SaveFilePathTo(&file_paths[i])));
2520 ASSERT_TRUE(PeerConnectionAdded(keys[i]));
2521 ASSERT_TRUE(PeerConnectionSessionIdSet(keys[i]));
2522 ASSERT_TRUE(StartRemoteLogging(keys[i]));
2523 ASSERT_TRUE(file_paths[i]);
2524 ASSERT_FALSE(file_paths[i]->empty());
2525 }
2526
2527 std::vector<std::string> logs;
2528 for (size_t i = 0; i < keys.size(); ++i) {
2529 logs.emplace_back(std::to_string(rph_->GetID()) + std::to_string(i));
2530 ASSERT_EQ(OnWebRtcEventLogWrite(keys[i], logs[i]),
2531 std::make_pair(false, true));
2532 }
2533
2534 // Make sure the file woulds be closed, so that we could safely read them.
2535 for (auto& key : keys) {
2536 ASSERT_TRUE(PeerConnectionRemoved(key));
2537 }
2538
2539 for (size_t i = 0; i < keys.size(); ++i) {
2540 ExpectRemoteFileContents(*file_paths[i], logs[i]);
2541 }
2542 }
2543
TEST_F(WebRtcEventLogManagerTest,DifferentRemoteLogsMayHaveDifferentMaximums)2544 TEST_F(WebRtcEventLogManagerTest, DifferentRemoteLogsMayHaveDifferentMaximums) {
2545 const std::string logs[2] = {"abra", "cadabra"};
2546 std::vector<base::Optional<base::FilePath>> file_paths(base::size(logs));
2547 std::vector<PeerConnectionKey> keys;
2548 for (size_t i = 0; i < base::size(logs); ++i) {
2549 keys.push_back(GetPeerConnectionKey(rph_.get(), i));
2550 ON_CALL(remote_observer_, OnRemoteLogStarted(keys[i], _, _))
2551 .WillByDefault(Invoke(SaveFilePathTo(&file_paths[i])));
2552 }
2553
2554 for (size_t i = 0; i < keys.size(); ++i) {
2555 ASSERT_TRUE(PeerConnectionAdded(keys[i]));
2556 const std::string session_id = GetUniqueId(keys[i]);
2557 ASSERT_TRUE(PeerConnectionSessionIdSet(keys[i], session_id));
2558 ASSERT_TRUE(StartRemoteLogging(keys[i], session_id, GzippedSize(logs[i]), 0,
2559 kWebAppId));
2560 }
2561
2562 for (size_t i = 0; i < keys.size(); ++i) {
2563 // The write is successful, but the file closed, indicating that the
2564 // maximum file size has been reached.
2565 EXPECT_CALL(remote_observer_, OnRemoteLogStopped(keys[i])).Times(1);
2566 ASSERT_EQ(OnWebRtcEventLogWrite(keys[i], logs[i]),
2567 std::make_pair(false, true));
2568 ASSERT_TRUE(file_paths[i]);
2569 ExpectRemoteFileContents(*file_paths[i], logs[i]);
2570 }
2571 }
2572
TEST_F(WebRtcEventLogManagerTest,RemoteLogFileClosedWhenCapacityReached)2573 TEST_F(WebRtcEventLogManagerTest, RemoteLogFileClosedWhenCapacityReached) {
2574 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
2575 base::Optional<base::FilePath> file_path;
2576 ON_CALL(remote_observer_, OnRemoteLogStarted(key, _, _))
2577 .WillByDefault(Invoke(SaveFilePathTo(&file_path)));
2578
2579 const std::string log = "Let X equal X.";
2580
2581 ASSERT_TRUE(PeerConnectionAdded(key));
2582 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
2583 ASSERT_TRUE(StartRemoteLogging(key, GetUniqueId(key), GzippedSize(log), 0,
2584 kWebAppId));
2585 ASSERT_TRUE(file_path);
2586
2587 EXPECT_CALL(remote_observer_, OnRemoteLogStopped(key)).Times(1);
2588 EXPECT_EQ(OnWebRtcEventLogWrite(key, log), std::make_pair(false, true));
2589 }
2590
2591 #if defined(OS_POSIX)
2592 // TODO(crbug.com/775415): Add unit tests for lacking read permissions when
2593 // looking to upload the file.
TEST_F(WebRtcEventLogManagerTest,FailureToCreateRemoteLogsDirHandledGracefully)2594 TEST_F(WebRtcEventLogManagerTest,
2595 FailureToCreateRemoteLogsDirHandledGracefully) {
2596 const base::FilePath browser_context_dir = browser_context_->GetPath();
2597 const base::FilePath remote_logs_path =
2598 RemoteBoundLogsDir(browser_context_.get());
2599
2600 // Unload the profile, delete its remove logs directory, and remove write
2601 // permissions from it, thereby preventing it from being created again.
2602 UnloadMainTestProfile();
2603 ASSERT_TRUE(base::DeletePathRecursively(remote_logs_path));
2604 RemoveWritePermissions(browser_context_dir);
2605
2606 // Graceful handling by BrowserContext::EnableForBrowserContext, despite
2607 // failing to create the remote logs' directory..
2608 LoadMainTestProfile();
2609 EXPECT_FALSE(base::DirectoryExists(remote_logs_path));
2610
2611 // Graceful handling of PeerConnectionAdded: True returned because the
2612 // remote-logs' manager can still safely reason about the state of peer
2613 // connections even if one of its browser contexts is defective.)
2614 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
2615 EXPECT_TRUE(PeerConnectionAdded(key));
2616 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
2617
2618 // Graceful handling of StartRemoteLogging: False returned because it's
2619 // impossible to write the log to a file.
2620 std::string error_message;
2621 EXPECT_FALSE(StartRemoteLogging(key, nullptr, &error_message));
2622 EXPECT_EQ(error_message,
2623 kStartRemoteLoggingFailureLoggingDisabledBrowserContext);
2624
2625 // Graceful handling of OnWebRtcEventLogWrite: False returned because the
2626 // log could not be written at all, let alone in its entirety.
2627 const char* const log = "This is not a log.";
2628 EXPECT_EQ(OnWebRtcEventLogWrite(key, log), std::make_pair(false, false));
2629
2630 // Graceful handling of PeerConnectionRemoved: True returned because the
2631 // remote-logs' manager can still safely reason about the state of peer
2632 // connections even if one of its browser contexts is defective.
2633 EXPECT_TRUE(PeerConnectionRemoved(key));
2634 }
2635
TEST_F(WebRtcEventLogManagerTest,GracefullyHandleFailureToStartRemoteLogFile)2636 TEST_F(WebRtcEventLogManagerTest, GracefullyHandleFailureToStartRemoteLogFile) {
2637 // WebRTC logging will not be turned on.
2638 EXPECT_CALL(remote_observer_, OnRemoteLogStarted(_, _, _)).Times(0);
2639 EXPECT_CALL(remote_observer_, OnRemoteLogStopped(_)).Times(0);
2640
2641 // Remove write permissions from the directory.
2642 const base::FilePath remote_logs_path =
2643 RemoteBoundLogsDir(browser_context_.get());
2644 ASSERT_TRUE(base::DirectoryExists(remote_logs_path));
2645 RemoveWritePermissions(remote_logs_path);
2646
2647 // StartRemoteLogging() will now fail.
2648 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
2649 ASSERT_TRUE(PeerConnectionAdded(key));
2650 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
2651 std::string error_message;
2652 EXPECT_FALSE(StartRemoteLogging(key, nullptr, &error_message));
2653 EXPECT_EQ(error_message, kStartRemoteLoggingFailureFileCreationError);
2654 EXPECT_EQ(OnWebRtcEventLogWrite(key, "abc"), std::make_pair(false, false));
2655 EXPECT_TRUE(base::IsDirectoryEmpty(remote_logs_path));
2656 }
2657 #endif // defined(OS_POSIX)
2658
TEST_F(WebRtcEventLogManagerTest,RemoteLogLimitActiveLogFiles)2659 TEST_F(WebRtcEventLogManagerTest, RemoteLogLimitActiveLogFiles) {
2660 for (int i = 0; i < kMaxActiveRemoteLogFiles + 1; ++i) {
2661 const auto key = GetPeerConnectionKey(rph_.get(), i);
2662 ASSERT_TRUE(PeerConnectionAdded(key));
2663 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
2664 }
2665
2666 for (int i = 0; i < kMaxActiveRemoteLogFiles; ++i) {
2667 const auto key = GetPeerConnectionKey(rph_.get(), i);
2668 EXPECT_CALL(remote_observer_, OnRemoteLogStarted(key, _, _)).Times(1);
2669 ASSERT_TRUE(StartRemoteLogging(key));
2670 }
2671
2672 EXPECT_CALL(remote_observer_, OnRemoteLogStarted(_, _, _)).Times(0);
2673 const auto new_key =
2674 GetPeerConnectionKey(rph_.get(), kMaxActiveRemoteLogFiles);
2675 EXPECT_FALSE(StartRemoteLogging(new_key));
2676 }
2677
TEST_F(WebRtcEventLogManagerTest,RemoteLogFilledLogNotCountedTowardsLogsLimit)2678 TEST_F(WebRtcEventLogManagerTest,
2679 RemoteLogFilledLogNotCountedTowardsLogsLimit) {
2680 const std::string log = "very_short_log";
2681
2682 for (int i = 0; i < kMaxActiveRemoteLogFiles; ++i) {
2683 const auto key = GetPeerConnectionKey(rph_.get(), i);
2684 ASSERT_TRUE(PeerConnectionAdded(key));
2685 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
2686 EXPECT_CALL(remote_observer_, OnRemoteLogStarted(key, _, _)).Times(1);
2687 ASSERT_TRUE(StartRemoteLogging(key, GetUniqueId(key), GzippedSize(log), 0,
2688 kWebAppId));
2689 }
2690
2691 // By writing to one of the logs until it reaches capacity, we fill it,
2692 // causing it to close, therefore allowing an additional log.
2693 const auto removed_key = GetPeerConnectionKey(rph_.get(), 0);
2694 EXPECT_EQ(OnWebRtcEventLogWrite(removed_key, log),
2695 std::make_pair(false, true));
2696
2697 // We now have room for one additional log.
2698 const auto new_key =
2699 GetPeerConnectionKey(rph_.get(), kMaxActiveRemoteLogFiles);
2700 EXPECT_CALL(remote_observer_, OnRemoteLogStarted(new_key, _, _)).Times(1);
2701 ASSERT_TRUE(PeerConnectionAdded(new_key));
2702 ASSERT_TRUE(PeerConnectionSessionIdSet(new_key));
2703 ASSERT_TRUE(StartRemoteLogging(new_key));
2704 }
2705
TEST_F(WebRtcEventLogManagerTest,RemoteLogForRemovedPeerConnectionNotCountedTowardsLogsLimit)2706 TEST_F(WebRtcEventLogManagerTest,
2707 RemoteLogForRemovedPeerConnectionNotCountedTowardsLogsLimit) {
2708 for (int i = 0; i < kMaxActiveRemoteLogFiles; ++i) {
2709 const auto key = GetPeerConnectionKey(rph_.get(), i);
2710 ASSERT_TRUE(PeerConnectionAdded(key));
2711 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
2712 EXPECT_CALL(remote_observer_, OnRemoteLogStarted(key, _, _)).Times(1);
2713 ASSERT_TRUE(StartRemoteLogging(key));
2714 }
2715
2716 // By removing a peer connection associated with one of the logs, we allow
2717 // an additional log.
2718 const auto removed_key = GetPeerConnectionKey(rph_.get(), 0);
2719 ASSERT_TRUE(PeerConnectionRemoved(removed_key));
2720
2721 // We now have room for one additional log.
2722 const auto last_key =
2723 GetPeerConnectionKey(rph_.get(), kMaxActiveRemoteLogFiles);
2724 EXPECT_CALL(remote_observer_, OnRemoteLogStarted(last_key, _, _)).Times(1);
2725 ASSERT_TRUE(PeerConnectionAdded(last_key));
2726 ASSERT_TRUE(PeerConnectionSessionIdSet(last_key));
2727 ASSERT_TRUE(StartRemoteLogging(last_key));
2728 }
2729
TEST_F(WebRtcEventLogManagerTest,ActiveLogsForBrowserContextCountedTowardsItsPendingsLogsLimit)2730 TEST_F(WebRtcEventLogManagerTest,
2731 ActiveLogsForBrowserContextCountedTowardsItsPendingsLogsLimit) {
2732 SuppressUploading();
2733
2734 // Produce kMaxPendingRemoteLogFiles pending logs.
2735 for (int i = 0; i < kMaxPendingRemoteLogFiles; ++i) {
2736 const auto key = GetPeerConnectionKey(rph_.get(), i);
2737 ASSERT_TRUE(PeerConnectionAdded(key));
2738 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
2739 ASSERT_TRUE(StartRemoteLogging(key));
2740 ASSERT_TRUE(PeerConnectionRemoved(key));
2741 }
2742
2743 // It is now impossible to start another *active* log for that BrowserContext,
2744 // because we have too many pending logs (and active logs become pending
2745 // once completed).
2746 const auto forbidden =
2747 GetPeerConnectionKey(rph_.get(), kMaxPendingRemoteLogFiles);
2748 ASSERT_TRUE(PeerConnectionAdded(forbidden));
2749 ASSERT_TRUE(PeerConnectionSessionIdSet(forbidden));
2750 std::string error_message;
2751 EXPECT_FALSE(StartRemoteLogging(forbidden, nullptr, &error_message));
2752 EXPECT_EQ(error_message,
2753 kStartRemoteLoggingFailureNoAdditionalActiveLogsAllowed);
2754 }
2755
TEST_F(WebRtcEventLogManagerTest,ObserveLimitOnMaximumPendingLogsPerBrowserContext)2756 TEST_F(WebRtcEventLogManagerTest,
2757 ObserveLimitOnMaximumPendingLogsPerBrowserContext) {
2758 SuppressUploading();
2759
2760 // Create additional BrowserContexts for the test.
2761 std::unique_ptr<TestingProfile> browser_contexts[2] = {
2762 CreateBrowserContext(), CreateBrowserContext()};
2763 std::unique_ptr<MockRenderProcessHost> rphs[2] = {
2764 std::make_unique<MockRenderProcessHost>(browser_contexts[0].get()),
2765 std::make_unique<MockRenderProcessHost>(browser_contexts[1].get())};
2766
2767 // Allowed to start kMaxPendingRemoteLogFiles for each BrowserContext.
2768 // Specifically, we can do it for the first BrowserContext.
2769 for (int i = 0; i < kMaxPendingRemoteLogFiles; ++i) {
2770 const auto key = GetPeerConnectionKey(rphs[0].get(), i);
2771 // The log could be opened:
2772 ASSERT_TRUE(PeerConnectionAdded(key));
2773 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
2774 ASSERT_TRUE(StartRemoteLogging(key));
2775 // The log changes state from ACTIVE to PENDING:
2776 EXPECT_TRUE(PeerConnectionRemoved(key));
2777 }
2778
2779 // Not allowed to start any more remote-bound logs for the BrowserContext on
2780 // which the limit was reached.
2781 const auto key0 =
2782 GetPeerConnectionKey(rphs[0].get(), kMaxPendingRemoteLogFiles);
2783 ASSERT_TRUE(PeerConnectionAdded(key0));
2784 ASSERT_TRUE(PeerConnectionSessionIdSet(key0));
2785 std::string error_message;
2786 EXPECT_FALSE(StartRemoteLogging(key0, nullptr, &error_message));
2787 EXPECT_EQ(error_message,
2788 kStartRemoteLoggingFailureNoAdditionalActiveLogsAllowed);
2789
2790 // Other BrowserContexts aren't limit by the previous one's limit.
2791 const auto key1 = GetPeerConnectionKey(rphs[1].get(), 0);
2792 ASSERT_TRUE(PeerConnectionAdded(key1));
2793 ASSERT_TRUE(PeerConnectionSessionIdSet(key1));
2794 EXPECT_TRUE(StartRemoteLogging(key1));
2795 }
2796
2797 // This also tests the scenario UploadOrderDependsOnLastModificationTime.
TEST_F(WebRtcEventLogManagerTest,LogsFromPreviousSessionBecomePendingLogsWhenBrowserContextInitialized)2798 TEST_F(WebRtcEventLogManagerTest,
2799 LogsFromPreviousSessionBecomePendingLogsWhenBrowserContextInitialized) {
2800 // Unload the profile, but remember where it stores its files.
2801 const base::FilePath browser_context_path = browser_context_->GetPath();
2802 const base::FilePath remote_logs_dir =
2803 RemoteBoundLogsDir(browser_context_.get());
2804 UnloadMainTestProfile();
2805
2806 // Seed the remote logs' directory with log files, simulating the
2807 // creation of logs in a previous session.
2808 std::list<WebRtcLogFileInfo> expected_files;
2809 ASSERT_TRUE(base::CreateDirectory(remote_logs_dir));
2810
2811 // Avoid arbitrary ordering due to files being created in the same second.
2812 // This is OK in production, but can confuse the test, which expects a
2813 // specific order.
2814 base::Time time =
2815 base::Time::Now() -
2816 base::TimeDelta::FromSeconds(kMaxPendingRemoteBoundWebRtcEventLogs);
2817
2818 for (size_t i = 0; i < kMaxPendingRemoteBoundWebRtcEventLogs; ++i) {
2819 time += base::TimeDelta::FromSeconds(1);
2820
2821 base::FilePath file_path;
2822 base::File file;
2823 ASSERT_TRUE(CreateRemoteBoundLogFile(remote_logs_dir, kWebAppId,
2824 remote_log_extension_, time,
2825 &file_path, &file));
2826
2827 expected_files.emplace_back(browser_context_id_, file_path, time);
2828 }
2829
2830 // This factory enforces the expectation that the files will be uploaded,
2831 // all of them, only them, and in the order expected.
2832 base::RunLoop run_loop;
2833 SetWebRtcEventLogUploaderFactoryForTesting(
2834 std::make_unique<FileListExpectingWebRtcEventLogUploader::Factory>(
2835 &expected_files, true, &run_loop));
2836
2837 LoadMainTestProfile();
2838 ASSERT_EQ(browser_context_->GetPath(), browser_context_path);
2839
2840 WaitForPendingTasks(&run_loop);
2841 }
2842
2843 // It is possible for remote-bound logs to be compressed or uncompressed.
2844 // We show that logs from a previous session are captured even if they are
2845 // different, with regards to compression, compared to last time.
TEST_F(WebRtcEventLogManagerTest,LogsCapturedPreviouslyMadePendingEvenIfDifferentExtensionsUsed)2846 TEST_F(WebRtcEventLogManagerTest,
2847 LogsCapturedPreviouslyMadePendingEvenIfDifferentExtensionsUsed) {
2848 // Unload the profile, but remember where it stores its files.
2849 const base::FilePath browser_context_path = browser_context_->GetPath();
2850 const base::FilePath remote_logs_dir =
2851 RemoteBoundLogsDir(browser_context_.get());
2852 UnloadMainTestProfile();
2853
2854 // Seed the remote logs' directory with log files, simulating the
2855 // creation of logs in a previous session.
2856 std::list<WebRtcLogFileInfo> expected_files;
2857 ASSERT_TRUE(base::CreateDirectory(remote_logs_dir));
2858
2859 base::FilePath::StringPieceType extensions[] = {
2860 kWebRtcEventLogUncompressedExtension, kWebRtcEventLogGzippedExtension};
2861 ASSERT_LE(base::size(extensions), kMaxPendingRemoteBoundWebRtcEventLogs)
2862 << "Lacking test coverage.";
2863
2864 // Avoid arbitrary ordering due to files being created in the same second.
2865 // This is OK in production, but can confuse the test, which expects a
2866 // specific order.
2867 base::Time time =
2868 base::Time::Now() -
2869 base::TimeDelta::FromSeconds(kMaxPendingRemoteBoundWebRtcEventLogs);
2870
2871 for (size_t i = 0, ext = 0; i < kMaxPendingRemoteBoundWebRtcEventLogs; ++i) {
2872 time += base::TimeDelta::FromSeconds(1);
2873
2874 const auto& extension = extensions[ext];
2875 ext = (ext + 1) % base::size(extensions);
2876
2877 base::FilePath file_path;
2878 base::File file;
2879 ASSERT_TRUE(CreateRemoteBoundLogFile(remote_logs_dir, kWebAppId, extension,
2880 time, &file_path, &file));
2881
2882 expected_files.emplace_back(browser_context_id_, file_path, time);
2883 }
2884
2885 // This factory enforces the expectation that the files will be uploaded,
2886 // all of them, only them, and in the order expected.
2887 base::RunLoop run_loop;
2888 SetWebRtcEventLogUploaderFactoryForTesting(
2889 std::make_unique<FileListExpectingWebRtcEventLogUploader::Factory>(
2890 &expected_files, true, &run_loop));
2891
2892 LoadMainTestProfile();
2893 ASSERT_EQ(browser_context_->GetPath(), browser_context_path);
2894
2895 WaitForPendingTasks(&run_loop);
2896 }
2897
TEST_P(WebRtcEventLogManagerTest,WhenPeerConnectionRemovedFinishedRemoteLogUploadedAndFileDeleted)2898 TEST_P(WebRtcEventLogManagerTest,
2899 WhenPeerConnectionRemovedFinishedRemoteLogUploadedAndFileDeleted) {
2900 // |upload_result| show that the files are deleted independent of the
2901 // upload's success / failure.
2902 const bool upload_result = GetParam();
2903
2904 const auto key = GetPeerConnectionKey(rph_.get(), 1);
2905 base::Optional<base::FilePath> log_file;
2906 ON_CALL(remote_observer_, OnRemoteLogStarted(key, _, _))
2907 .WillByDefault(Invoke(SaveFilePathTo(&log_file)));
2908 ASSERT_TRUE(PeerConnectionAdded(key));
2909 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
2910 ASSERT_TRUE(StartRemoteLogging(key));
2911 ASSERT_TRUE(log_file);
2912
2913 base::RunLoop run_loop;
2914 std::list<WebRtcLogFileInfo> expected_files = {WebRtcLogFileInfo(
2915 browser_context_id_, *log_file, GetLastModificationTime(*log_file))};
2916 SetWebRtcEventLogUploaderFactoryForTesting(
2917 std::make_unique<FileListExpectingWebRtcEventLogUploader::Factory>(
2918 &expected_files, upload_result, &run_loop));
2919
2920 // Peer connection removal triggers next upload.
2921 ASSERT_TRUE(PeerConnectionRemoved(key));
2922
2923 WaitForPendingTasks(&run_loop);
2924
2925 EXPECT_TRUE(
2926 base::IsDirectoryEmpty(RemoteBoundLogsDir(browser_context_.get())));
2927 }
2928
TEST_P(WebRtcEventLogManagerTest,DestroyedRphTriggersLogUpload)2929 TEST_P(WebRtcEventLogManagerTest, DestroyedRphTriggersLogUpload) {
2930 // |upload_result| show that the files are deleted independent of the
2931 // upload's success / failure.
2932 const bool upload_result = GetParam();
2933
2934 const auto key = GetPeerConnectionKey(rph_.get(), 1);
2935 base::Optional<base::FilePath> log_file;
2936 ON_CALL(remote_observer_, OnRemoteLogStarted(key, _, _))
2937 .WillByDefault(Invoke(SaveFilePathTo(&log_file)));
2938 ASSERT_TRUE(PeerConnectionAdded(key));
2939 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
2940 ASSERT_TRUE(StartRemoteLogging(key));
2941 ASSERT_TRUE(log_file);
2942
2943 base::RunLoop run_loop;
2944 std::list<WebRtcLogFileInfo> expected_files = {WebRtcLogFileInfo(
2945 browser_context_id_, *log_file, GetLastModificationTime(*log_file))};
2946 SetWebRtcEventLogUploaderFactoryForTesting(
2947 std::make_unique<FileListExpectingWebRtcEventLogUploader::Factory>(
2948 &expected_files, upload_result, &run_loop));
2949
2950 // RPH destruction stops all active logs and triggers next upload.
2951 rph_.reset();
2952
2953 WaitForPendingTasks(&run_loop);
2954
2955 EXPECT_TRUE(
2956 base::IsDirectoryEmpty(RemoteBoundLogsDir(browser_context_.get())));
2957 }
2958
2959 // Note that SuppressUploading() and UnSuppressUploading() use the behavior
2960 // guaranteed by this test.
TEST_F(WebRtcEventLogManagerTest,UploadOnlyWhenNoActivePeerConnections)2961 TEST_F(WebRtcEventLogManagerTest, UploadOnlyWhenNoActivePeerConnections) {
2962 const auto untracked = GetPeerConnectionKey(rph_.get(), 0);
2963 const auto tracked = GetPeerConnectionKey(rph_.get(), 1);
2964
2965 // Suppresses the uploading of the "tracked" peer connection's log.
2966 ASSERT_TRUE(PeerConnectionAdded(untracked));
2967 ASSERT_TRUE(PeerConnectionSessionIdSet(untracked));
2968
2969 // The tracked peer connection's log is not uploaded when finished, because
2970 // another peer connection is still active.
2971 base::Optional<base::FilePath> log_file;
2972 ON_CALL(remote_observer_, OnRemoteLogStarted(tracked, _, _))
2973 .WillByDefault(Invoke(SaveFilePathTo(&log_file)));
2974 ASSERT_TRUE(PeerConnectionAdded(tracked));
2975 ASSERT_TRUE(PeerConnectionSessionIdSet(tracked));
2976 ASSERT_TRUE(StartRemoteLogging(tracked));
2977 ASSERT_TRUE(log_file);
2978 ASSERT_TRUE(PeerConnectionRemoved(tracked));
2979
2980 // Perform another action synchronously, so that we may be assured that the
2981 // observer's lack of callbacks was not a timing fluke.
2982 OnWebRtcEventLogWrite(untracked, "Ook!");
2983
2984 // Having been convinced that |tracked|'s log was not uploded while
2985 // |untracked| was active, close |untracked| and see that |tracked|'s log
2986 // is now uploaded.
2987 base::RunLoop run_loop;
2988 std::list<WebRtcLogFileInfo> expected_uploads = {WebRtcLogFileInfo(
2989 browser_context_id_, *log_file, GetLastModificationTime(*log_file))};
2990 SetWebRtcEventLogUploaderFactoryForTesting(
2991 std::make_unique<FileListExpectingWebRtcEventLogUploader::Factory>(
2992 &expected_uploads, true, &run_loop));
2993 ASSERT_TRUE(PeerConnectionRemoved(untracked));
2994
2995 WaitForPendingTasks(&run_loop);
2996 }
2997
TEST_F(WebRtcEventLogManagerTest,ExpiredFilesArePrunedRatherThanUploaded)2998 TEST_F(WebRtcEventLogManagerTest, ExpiredFilesArePrunedRatherThanUploaded) {
2999 constexpr size_t kExpired = 0;
3000 constexpr size_t kFresh = 1;
3001 DCHECK_GE(kMaxPendingRemoteBoundWebRtcEventLogs, 2u)
3002 << "Please restructure the test to use separate browser contexts.";
3003
3004 const base::FilePath remote_logs_dir =
3005 RemoteBoundLogsDir(browser_context_.get());
3006
3007 UnloadMainTestProfile();
3008
3009 base::FilePath file_paths[2];
3010 for (size_t i = 0; i < 2; ++i) {
3011 base::File file;
3012 ASSERT_TRUE(CreateRemoteBoundLogFile(
3013 remote_logs_dir, kWebAppId, remote_log_extension_, base::Time::Now(),
3014 &file_paths[i], &file));
3015 }
3016
3017 // Touch() requires setting the last access time as well. Keep it current,
3018 // showing that only the last modification time matters.
3019 base::File::Info file_info;
3020 ASSERT_TRUE(base::GetFileInfo(file_paths[0], &file_info));
3021
3022 // Set the expired file's last modification time to past max retention.
3023 const base::Time expired_mod_time = base::Time::Now() -
3024 kRemoteBoundWebRtcEventLogsMaxRetention -
3025 base::TimeDelta::FromSeconds(1);
3026 ASSERT_TRUE(base::TouchFile(file_paths[kExpired], file_info.last_accessed,
3027 expired_mod_time));
3028
3029 // Show that the expired file is not uploaded.
3030 base::RunLoop run_loop;
3031 std::list<WebRtcLogFileInfo> expected_files = {
3032 WebRtcLogFileInfo(browser_context_id_, file_paths[kFresh],
3033 GetLastModificationTime(file_paths[kFresh]))};
3034 SetWebRtcEventLogUploaderFactoryForTesting(
3035 std::make_unique<FileListExpectingWebRtcEventLogUploader::Factory>(
3036 &expected_files, true, &run_loop));
3037
3038 // Recognize the files as pending by initializing their BrowserContext.
3039 LoadMainTestProfile();
3040
3041 WaitForPendingTasks(&run_loop);
3042
3043 // Both the uploaded file as well as the expired file have no been removed
3044 // from local disk.
3045 for (const base::FilePath& file_path : file_paths) {
3046 EXPECT_FALSE(base::PathExists(file_path));
3047 }
3048 }
3049
3050 // TODO(crbug.com/775415): Add a test showing that a file expiring while another
3051 // is being uploaded, is not uploaded after the current upload is completed.
3052 // This is significant because Chrome might stay up for a long time.
3053
TEST_F(WebRtcEventLogManagerTest,RemoteLogEmptyStringHandledGracefully)3054 TEST_F(WebRtcEventLogManagerTest, RemoteLogEmptyStringHandledGracefully) {
3055 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
3056
3057 // By writing a log after the empty string, we show that no odd behavior is
3058 // encountered, such as closing the file (an actual bug from WebRTC).
3059 const std::vector<std::string> logs = {"<setup>", "", "<encore>"};
3060
3061 base::Optional<base::FilePath> file_path;
3062
3063 ON_CALL(remote_observer_, OnRemoteLogStarted(key, _, _))
3064 .WillByDefault(Invoke(SaveFilePathTo(&file_path)));
3065 ASSERT_TRUE(PeerConnectionAdded(key));
3066 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
3067 ASSERT_TRUE(StartRemoteLogging(key));
3068 ASSERT_TRUE(file_path);
3069 ASSERT_FALSE(file_path->empty());
3070
3071 for (size_t i = 0; i < logs.size(); ++i) {
3072 ASSERT_EQ(OnWebRtcEventLogWrite(key, logs[i]), std::make_pair(false, true));
3073 }
3074 ASSERT_TRUE(PeerConnectionRemoved(key));
3075
3076 ExpectRemoteFileContents(
3077 *file_path,
3078 std::accumulate(std::begin(logs), std::end(logs), std::string()));
3079 }
3080
3081 #if defined(OS_POSIX)
TEST_F(WebRtcEventLogManagerTest,UnopenedRemoteLogFilesNotCountedTowardsActiveLogsLimit)3082 TEST_F(WebRtcEventLogManagerTest,
3083 UnopenedRemoteLogFilesNotCountedTowardsActiveLogsLimit) {
3084 std::unique_ptr<TestingProfile> browser_contexts[2];
3085 std::unique_ptr<MockRenderProcessHost> rphs[2];
3086 for (size_t i = 0; i < 2; ++i) {
3087 browser_contexts[i] = CreateBrowserContext();
3088 rphs[i] =
3089 std::make_unique<MockRenderProcessHost>(browser_contexts[i].get());
3090 }
3091
3092 constexpr size_t without_permissions = 0;
3093 constexpr size_t with_permissions = 1;
3094
3095 // Remove write permissions from one directory.
3096 const base::FilePath permissions_lacking_remote_logs_path =
3097 RemoteBoundLogsDir(browser_contexts[without_permissions].get());
3098 ASSERT_TRUE(base::DirectoryExists(permissions_lacking_remote_logs_path));
3099 RemoveWritePermissions(permissions_lacking_remote_logs_path);
3100
3101 // Fail to start a log associated with the permission-lacking directory.
3102 const auto without_permissions_key =
3103 GetPeerConnectionKey(rphs[without_permissions].get(), 0);
3104 ASSERT_TRUE(PeerConnectionAdded(without_permissions_key));
3105 ASSERT_TRUE(PeerConnectionSessionIdSet(without_permissions_key));
3106 std::string error;
3107 ASSERT_FALSE(StartRemoteLogging(without_permissions_key, nullptr, &error));
3108 EXPECT_EQ(error, kStartRemoteLoggingFailureFileCreationError);
3109
3110 // Show that this was not counted towards the limit of active files.
3111 for (int i = 0; i < kMaxActiveRemoteLogFiles; ++i) {
3112 const auto with_permissions_key =
3113 GetPeerConnectionKey(rphs[with_permissions].get(), i);
3114 ASSERT_TRUE(PeerConnectionAdded(with_permissions_key));
3115 ASSERT_TRUE(PeerConnectionSessionIdSet(with_permissions_key));
3116 EXPECT_TRUE(StartRemoteLogging(with_permissions_key));
3117 }
3118 }
3119 #endif // defined(OS_POSIX)
3120
TEST_F(WebRtcEventLogManagerTest,NoStartWebRtcSendingEventLogsWhenLocalEnabledWithoutPeerConnection)3121 TEST_F(WebRtcEventLogManagerTest,
3122 NoStartWebRtcSendingEventLogsWhenLocalEnabledWithoutPeerConnection) {
3123 SetPeerConnectionTrackerProxyForTesting(
3124 std::make_unique<PeerConnectionTrackerProxyForTesting>(this));
3125 ASSERT_TRUE(EnableLocalLogging());
3126 EXPECT_TRUE(webrtc_state_change_instructions_.empty());
3127 }
3128
TEST_F(WebRtcEventLogManagerTest,NoStartWebRtcSendingEventLogsWhenPeerConnectionButNoLoggingEnabled)3129 TEST_F(WebRtcEventLogManagerTest,
3130 NoStartWebRtcSendingEventLogsWhenPeerConnectionButNoLoggingEnabled) {
3131 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
3132 SetPeerConnectionTrackerProxyForTesting(
3133 std::make_unique<PeerConnectionTrackerProxyForTesting>(this));
3134 ASSERT_TRUE(PeerConnectionAdded(key));
3135 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
3136 EXPECT_TRUE(webrtc_state_change_instructions_.empty());
3137 }
3138
TEST_F(WebRtcEventLogManagerTest,StartWebRtcSendingEventLogsWhenLocalEnabledThenPeerConnectionAdded)3139 TEST_F(WebRtcEventLogManagerTest,
3140 StartWebRtcSendingEventLogsWhenLocalEnabledThenPeerConnectionAdded) {
3141 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
3142 SetPeerConnectionTrackerProxyForTesting(
3143 std::make_unique<PeerConnectionTrackerProxyForTesting>(this));
3144 ASSERT_TRUE(EnableLocalLogging());
3145 ASSERT_TRUE(PeerConnectionAdded(key));
3146 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
3147 ExpectWebRtcStateChangeInstruction(key, true);
3148 }
3149
TEST_F(WebRtcEventLogManagerTest,StartWebRtcSendingEventLogsWhenPeerConnectionAddedThenLocalEnabled)3150 TEST_F(WebRtcEventLogManagerTest,
3151 StartWebRtcSendingEventLogsWhenPeerConnectionAddedThenLocalEnabled) {
3152 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
3153 SetPeerConnectionTrackerProxyForTesting(
3154 std::make_unique<PeerConnectionTrackerProxyForTesting>(this));
3155 ASSERT_TRUE(PeerConnectionAdded(key));
3156 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
3157 ASSERT_TRUE(EnableLocalLogging());
3158 ExpectWebRtcStateChangeInstruction(key, true);
3159 }
3160
TEST_F(WebRtcEventLogManagerTest,StartWebRtcSendingEventLogsWhenRemoteLoggingEnabled)3161 TEST_F(WebRtcEventLogManagerTest,
3162 StartWebRtcSendingEventLogsWhenRemoteLoggingEnabled) {
3163 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
3164 SetPeerConnectionTrackerProxyForTesting(
3165 std::make_unique<PeerConnectionTrackerProxyForTesting>(this));
3166 ASSERT_TRUE(PeerConnectionAdded(key));
3167 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
3168 ASSERT_TRUE(StartRemoteLogging(key));
3169 ExpectWebRtcStateChangeInstruction(key, true);
3170 }
3171
TEST_F(WebRtcEventLogManagerTest,InstructWebRtcToStopSendingEventLogsWhenLocalLoggingStopped)3172 TEST_F(WebRtcEventLogManagerTest,
3173 InstructWebRtcToStopSendingEventLogsWhenLocalLoggingStopped) {
3174 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
3175
3176 // Setup
3177 SetPeerConnectionTrackerProxyForTesting(
3178 std::make_unique<PeerConnectionTrackerProxyForTesting>(this));
3179 ASSERT_TRUE(PeerConnectionAdded(key));
3180 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
3181 ASSERT_TRUE(EnableLocalLogging());
3182 ExpectWebRtcStateChangeInstruction(key, true);
3183
3184 // Test
3185 ASSERT_TRUE(DisableLocalLogging());
3186 ExpectWebRtcStateChangeInstruction(key, false);
3187 }
3188
3189 // #1 - Local logging was the cause of the logs.
TEST_F(WebRtcEventLogManagerTest,InstructWebRtcToStopSendingEventLogsWhenPeerConnectionRemoved1)3190 TEST_F(WebRtcEventLogManagerTest,
3191 InstructWebRtcToStopSendingEventLogsWhenPeerConnectionRemoved1) {
3192 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
3193
3194 // Setup
3195 SetPeerConnectionTrackerProxyForTesting(
3196 std::make_unique<PeerConnectionTrackerProxyForTesting>(this));
3197 ASSERT_TRUE(PeerConnectionAdded(key));
3198 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
3199 ASSERT_TRUE(EnableLocalLogging());
3200 ExpectWebRtcStateChangeInstruction(key, true);
3201
3202 // Test
3203 ASSERT_TRUE(PeerConnectionRemoved(key));
3204 ExpectWebRtcStateChangeInstruction(key, false);
3205 }
3206
3207 // #2 - Remote logging was the cause of the logs.
TEST_F(WebRtcEventLogManagerTest,InstructWebRtcToStopSendingEventLogsWhenPeerConnectionRemoved2)3208 TEST_F(WebRtcEventLogManagerTest,
3209 InstructWebRtcToStopSendingEventLogsWhenPeerConnectionRemoved2) {
3210 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
3211
3212 // Setup
3213 SetPeerConnectionTrackerProxyForTesting(
3214 std::make_unique<PeerConnectionTrackerProxyForTesting>(this));
3215 ASSERT_TRUE(PeerConnectionAdded(key));
3216 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
3217 ASSERT_TRUE(StartRemoteLogging(key));
3218 ExpectWebRtcStateChangeInstruction(key, true);
3219
3220 // Test
3221 ASSERT_TRUE(PeerConnectionRemoved(key));
3222 ExpectWebRtcStateChangeInstruction(key, false);
3223 }
3224
3225 // #1 - Local logging added first.
TEST_F(WebRtcEventLogManagerTest,SecondLoggingTargetDoesNotInitiateWebRtcLogging1)3226 TEST_F(WebRtcEventLogManagerTest,
3227 SecondLoggingTargetDoesNotInitiateWebRtcLogging1) {
3228 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
3229
3230 // Setup
3231 SetPeerConnectionTrackerProxyForTesting(
3232 std::make_unique<PeerConnectionTrackerProxyForTesting>(this));
3233 ASSERT_TRUE(PeerConnectionAdded(key));
3234 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
3235 ASSERT_TRUE(EnableLocalLogging());
3236 ExpectWebRtcStateChangeInstruction(key, true);
3237
3238 // Test
3239 ASSERT_TRUE(StartRemoteLogging(key));
3240 EXPECT_TRUE(webrtc_state_change_instructions_.empty());
3241 }
3242
3243 // #2 - Remote logging added first.
TEST_F(WebRtcEventLogManagerTest,SecondLoggingTargetDoesNotInitiateWebRtcLogging2)3244 TEST_F(WebRtcEventLogManagerTest,
3245 SecondLoggingTargetDoesNotInitiateWebRtcLogging2) {
3246 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
3247
3248 // Setup
3249 SetPeerConnectionTrackerProxyForTesting(
3250 std::make_unique<PeerConnectionTrackerProxyForTesting>(this));
3251 ASSERT_TRUE(PeerConnectionAdded(key));
3252 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
3253 ASSERT_TRUE(StartRemoteLogging(key));
3254 ExpectWebRtcStateChangeInstruction(key, true);
3255
3256 // Test
3257 ASSERT_TRUE(EnableLocalLogging());
3258 EXPECT_TRUE(webrtc_state_change_instructions_.empty());
3259 }
3260
TEST_F(WebRtcEventLogManagerTest,DisablingLocalLoggingWhenRemoteLoggingEnabledDoesNotStopWebRtcLogging)3261 TEST_F(WebRtcEventLogManagerTest,
3262 DisablingLocalLoggingWhenRemoteLoggingEnabledDoesNotStopWebRtcLogging) {
3263 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
3264
3265 // Setup
3266 SetPeerConnectionTrackerProxyForTesting(
3267 std::make_unique<PeerConnectionTrackerProxyForTesting>(this));
3268 ASSERT_TRUE(PeerConnectionAdded(key));
3269 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
3270 ASSERT_TRUE(EnableLocalLogging());
3271 ASSERT_TRUE(StartRemoteLogging(key));
3272 ExpectWebRtcStateChangeInstruction(key, true);
3273
3274 // Test
3275 ASSERT_TRUE(DisableLocalLogging());
3276 EXPECT_TRUE(webrtc_state_change_instructions_.empty());
3277
3278 // Cleanup
3279 ASSERT_TRUE(PeerConnectionRemoved(key));
3280 ExpectWebRtcStateChangeInstruction(key, false);
3281 }
3282
TEST_F(WebRtcEventLogManagerTest,DisablingLocalLoggingAfterPcRemovalHasNoEffectOnWebRtcLogging)3283 TEST_F(WebRtcEventLogManagerTest,
3284 DisablingLocalLoggingAfterPcRemovalHasNoEffectOnWebRtcLogging) {
3285 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
3286
3287 // Setup
3288 SetPeerConnectionTrackerProxyForTesting(
3289 std::make_unique<PeerConnectionTrackerProxyForTesting>(this));
3290 ASSERT_TRUE(PeerConnectionAdded(key));
3291 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
3292 ASSERT_TRUE(EnableLocalLogging());
3293 ASSERT_TRUE(StartRemoteLogging(key));
3294 ExpectWebRtcStateChangeInstruction(key, true);
3295
3296 // Test
3297 ASSERT_TRUE(PeerConnectionRemoved(key));
3298 ExpectWebRtcStateChangeInstruction(key, false);
3299 ASSERT_TRUE(DisableLocalLogging());
3300 EXPECT_TRUE(webrtc_state_change_instructions_.empty());
3301 }
3302
3303 // Once a peer connection with a given key was removed, it may not again be
3304 // added. But, if this impossible case occurs, WebRtcEventLogManager will
3305 // not crash.
TEST_F(WebRtcEventLogManagerTest,SanityOverRecreatingTheSamePeerConnection)3306 TEST_F(WebRtcEventLogManagerTest, SanityOverRecreatingTheSamePeerConnection) {
3307 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
3308 ASSERT_TRUE(EnableLocalLogging());
3309 ASSERT_TRUE(PeerConnectionAdded(key));
3310 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
3311 ASSERT_TRUE(StartRemoteLogging(key));
3312 OnWebRtcEventLogWrite(key, "log1");
3313 ASSERT_TRUE(PeerConnectionRemoved(key));
3314 ASSERT_TRUE(PeerConnectionAdded(key));
3315 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
3316 OnWebRtcEventLogWrite(key, "log2");
3317 }
3318
3319 // The logs would typically be binary. However, the other tests only cover ASCII
3320 // characters, for readability. This test shows that this is not a problem.
TEST_F(WebRtcEventLogManagerTest,LogAllPossibleCharacters)3321 TEST_F(WebRtcEventLogManagerTest, LogAllPossibleCharacters) {
3322 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
3323
3324 base::Optional<base::FilePath> local_log_file_path;
3325 ON_CALL(local_observer_, OnLocalLogStarted(key, _))
3326 .WillByDefault(Invoke(SaveFilePathTo(&local_log_file_path)));
3327
3328 base::Optional<base::FilePath> remote_log_file_path;
3329 ON_CALL(remote_observer_, OnRemoteLogStarted(key, _, _))
3330 .WillByDefault(Invoke(SaveFilePathTo(&remote_log_file_path)));
3331
3332 ASSERT_TRUE(EnableLocalLogging());
3333 ASSERT_TRUE(PeerConnectionAdded(key));
3334 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
3335 ASSERT_TRUE(StartRemoteLogging(key));
3336 ASSERT_TRUE(local_log_file_path);
3337 ASSERT_FALSE(local_log_file_path->empty());
3338 ASSERT_TRUE(remote_log_file_path);
3339 ASSERT_FALSE(remote_log_file_path->empty());
3340
3341 std::string all_chars;
3342 for (size_t i = 0; i < 256; ++i) {
3343 all_chars += static_cast<uint8_t>(i);
3344 }
3345 ASSERT_EQ(OnWebRtcEventLogWrite(key, all_chars), std::make_pair(true, true));
3346
3347 // Make sure the file would be closed, so that we could safely read it.
3348 ASSERT_TRUE(PeerConnectionRemoved(key));
3349
3350 ExpectLocalFileContents(*local_log_file_path, all_chars);
3351 ExpectRemoteFileContents(*remote_log_file_path, all_chars);
3352 }
3353
TEST_F(WebRtcEventLogManagerTest,LocalLogsClosedWhenRenderProcessHostExits)3354 TEST_F(WebRtcEventLogManagerTest, LocalLogsClosedWhenRenderProcessHostExits) {
3355 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
3356 ASSERT_TRUE(PeerConnectionAdded(key));
3357 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
3358 ASSERT_TRUE(EnableLocalLogging());
3359
3360 // The expectation for OnLocalLogStopped() will be saturated by this
3361 // destruction of the RenderProcessHost, which triggers an implicit
3362 // removal of all PeerConnections associated with it.
3363 EXPECT_CALL(local_observer_, OnLocalLogStopped(key)).Times(1);
3364 rph_.reset();
3365 }
3366
TEST_F(WebRtcEventLogManagerTest,RemoteLogsClosedWhenRenderProcessHostExits)3367 TEST_F(WebRtcEventLogManagerTest, RemoteLogsClosedWhenRenderProcessHostExits) {
3368 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
3369 ASSERT_TRUE(PeerConnectionAdded(key));
3370 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
3371 ASSERT_TRUE(StartRemoteLogging(key));
3372
3373 // The expectation for OnRemoteLogStopped() will be saturated by this
3374 // destruction of the RenderProcessHost, which triggers an implicit
3375 // removal of all PeerConnections associated with it.
3376 EXPECT_CALL(remote_observer_, OnRemoteLogStopped(key)).Times(1);
3377 rph_.reset();
3378 }
3379
3380 // Once a RenderProcessHost exits/crashes, its PeerConnections are removed,
3381 // which means that they can no longer suppress an upload.
TEST_F(WebRtcEventLogManagerTest,RenderProcessHostExitCanRemoveUploadSuppression)3382 TEST_F(WebRtcEventLogManagerTest,
3383 RenderProcessHostExitCanRemoveUploadSuppression) {
3384 SuppressUploading();
3385
3386 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
3387 base::Optional<base::FilePath> file_path;
3388 ON_CALL(remote_observer_, OnRemoteLogStarted(key, _, _))
3389 .WillByDefault(Invoke(SaveFilePathTo(&file_path)));
3390
3391 ASSERT_TRUE(PeerConnectionAdded(key));
3392 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
3393 ASSERT_TRUE(StartRemoteLogging(key));
3394 ASSERT_TRUE(PeerConnectionRemoved(key));
3395 ASSERT_TRUE(file_path);
3396 ASSERT_FALSE(file_path->empty());
3397
3398 // The above removal is not sufficient to trigger an upload (so the test will
3399 // not be flaky). It's only once we destroy the RPH with which the suppressing
3400 // PeerConnection is associated, that upload will take place.
3401 base::RunLoop run_loop;
3402 std::list<WebRtcLogFileInfo> expected_files = {WebRtcLogFileInfo(
3403 browser_context_id_, *file_path, GetLastModificationTime(*file_path))};
3404 SetWebRtcEventLogUploaderFactoryForTesting(
3405 std::make_unique<FileListExpectingWebRtcEventLogUploader::Factory>(
3406 &expected_files, true, &run_loop));
3407
3408 // We destroy the RPH without explicitly removing its PeerConnection (unlike
3409 // a call to UnsuppressUploading()).
3410 upload_suppressing_rph_.reset();
3411
3412 WaitForPendingTasks(&run_loop);
3413 }
3414
TEST_F(WebRtcEventLogManagerTest,PeerConnectionAddedOverDestroyedRphReturnsFalse)3415 TEST_F(WebRtcEventLogManagerTest,
3416 PeerConnectionAddedOverDestroyedRphReturnsFalse) {
3417 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
3418 rph_.reset();
3419 EXPECT_FALSE(PeerConnectionAdded(key));
3420 }
3421
TEST_F(WebRtcEventLogManagerTest,PeerConnectionRemovedOverDestroyedRphReturnsFalse)3422 TEST_F(WebRtcEventLogManagerTest,
3423 PeerConnectionRemovedOverDestroyedRphReturnsFalse) {
3424 // Setup - make sure the |false| returned by the function being tested is
3425 // related to the RPH being dead, and not due other restrictions.
3426 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
3427 ASSERT_TRUE(PeerConnectionAdded(key));
3428 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
3429
3430 // Test
3431 rph_.reset();
3432 EXPECT_FALSE(PeerConnectionRemoved(key));
3433 }
3434
TEST_F(WebRtcEventLogManagerTest,PeerConnectionStoppedOverDestroyedRphReturnsFalse)3435 TEST_F(WebRtcEventLogManagerTest,
3436 PeerConnectionStoppedOverDestroyedRphReturnsFalse) {
3437 // Setup - make sure the |false| returned by the function being tested is
3438 // related to the RPH being dead, and not due other restrictions.
3439 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
3440 ASSERT_TRUE(PeerConnectionAdded(key));
3441 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
3442
3443 // Test
3444 rph_.reset();
3445 EXPECT_FALSE(PeerConnectionStopped(key));
3446 }
3447
TEST_F(WebRtcEventLogManagerTest,StartRemoteLoggingOverDestroyedRphReturnsFalse)3448 TEST_F(WebRtcEventLogManagerTest,
3449 StartRemoteLoggingOverDestroyedRphReturnsFalse) {
3450 // Setup - make sure the |false| returned by the function being tested is
3451 // related to the RPH being dead, and not due other restrictions.
3452 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
3453 ASSERT_TRUE(PeerConnectionAdded(key));
3454 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
3455
3456 // Test
3457 rph_.reset();
3458 std::string error_message;
3459 EXPECT_FALSE(StartRemoteLogging(key, nullptr, &error_message));
3460 EXPECT_EQ(error_message, kStartRemoteLoggingFailureDeadRenderProcessHost);
3461 }
3462
TEST_F(WebRtcEventLogManagerTest,OnWebRtcEventLogWriteOverDestroyedRphReturnsFalseAndFalse)3463 TEST_F(WebRtcEventLogManagerTest,
3464 OnWebRtcEventLogWriteOverDestroyedRphReturnsFalseAndFalse) {
3465 // Setup - make sure the |false| returned by the function being tested is
3466 // related to the RPH being dead, and not due other restrictions.
3467 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
3468 ASSERT_TRUE(PeerConnectionAdded(key));
3469 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
3470 ASSERT_TRUE(EnableLocalLogging());
3471
3472 // Test
3473 rph_.reset();
3474 EXPECT_EQ(OnWebRtcEventLogWrite(key, "log"), std::make_pair(false, false));
3475 }
3476
TEST_F(WebRtcEventLogManagerTest,DifferentProfilesCanHaveDifferentPolicies)3477 TEST_F(WebRtcEventLogManagerTest, DifferentProfilesCanHaveDifferentPolicies) {
3478 auto policy_disabled_profile =
3479 CreateBrowserContext("disabled", true /* is_managed_profile */,
3480 false /* has_device_level_policies */,
3481 false /* policy_allows_remote_logging */);
3482 auto policy_disabled_rph =
3483 std::make_unique<MockRenderProcessHost>(policy_disabled_profile.get());
3484 const auto disabled_key =
3485 GetPeerConnectionKey(policy_disabled_rph.get(), kLid);
3486
3487 auto policy_enabled_profile =
3488 CreateBrowserContext("enabled", true /* is_managed_profile */,
3489 false /* has_device_level_policies */,
3490 true /* policy_allows_remote_logging */);
3491 auto policy_enabled_rph =
3492 std::make_unique<MockRenderProcessHost>(policy_enabled_profile.get());
3493 const auto enabled_key = GetPeerConnectionKey(policy_enabled_rph.get(), kLid);
3494
3495 ASSERT_TRUE(PeerConnectionAdded(disabled_key));
3496 ASSERT_TRUE(PeerConnectionSessionIdSet(disabled_key));
3497
3498 ASSERT_TRUE(PeerConnectionAdded(enabled_key));
3499 ASSERT_TRUE(PeerConnectionSessionIdSet(enabled_key));
3500
3501 EXPECT_FALSE(StartRemoteLogging(disabled_key));
3502 EXPECT_TRUE(StartRemoteLogging(enabled_key));
3503 }
3504
TEST_F(WebRtcEventLogManagerTest,StartRemoteLoggingWithTooLowWebAppIdRejected)3505 TEST_F(WebRtcEventLogManagerTest,
3506 StartRemoteLoggingWithTooLowWebAppIdRejected) {
3507 const size_t web_app_id = kMinWebRtcEventLogWebAppId - 1;
3508 ASSERT_LT(web_app_id, kMinWebRtcEventLogWebAppId); // Avoid wrap-around.
3509
3510 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
3511 ASSERT_TRUE(PeerConnectionAdded(key));
3512 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
3513 EXPECT_FALSE(StartRemoteLogging(key, GetUniqueId(key),
3514 kMaxRemoteLogFileSizeBytes, 0, web_app_id));
3515 }
3516
TEST_F(WebRtcEventLogManagerTest,StartRemoteLoggingWithTooHighWebAppIdRejected)3517 TEST_F(WebRtcEventLogManagerTest,
3518 StartRemoteLoggingWithTooHighWebAppIdRejected) {
3519 const size_t web_app_id = kMaxWebRtcEventLogWebAppId + 1;
3520 ASSERT_GT(web_app_id, kMaxWebRtcEventLogWebAppId); // Avoid wrap-around.
3521
3522 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
3523 ASSERT_TRUE(PeerConnectionAdded(key));
3524 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
3525 EXPECT_FALSE(StartRemoteLogging(key, GetUniqueId(key),
3526 kMaxRemoteLogFileSizeBytes, 0, web_app_id));
3527 }
3528
TEST_F(WebRtcEventLogManagerTest,StartRemoteLoggingWithInRangeWebAppIdAllowedMin)3529 TEST_F(WebRtcEventLogManagerTest,
3530 StartRemoteLoggingWithInRangeWebAppIdAllowedMin) {
3531 const size_t web_app_id = kMinWebRtcEventLogWebAppId;
3532 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
3533 ASSERT_TRUE(PeerConnectionAdded(key));
3534 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
3535 EXPECT_TRUE(StartRemoteLogging(key, GetUniqueId(key),
3536 kMaxRemoteLogFileSizeBytes, 0, web_app_id));
3537 }
3538
TEST_F(WebRtcEventLogManagerTest,StartRemoteLoggingWithInRangeWebAppIdAllowedMax)3539 TEST_F(WebRtcEventLogManagerTest,
3540 StartRemoteLoggingWithInRangeWebAppIdAllowedMax) {
3541 const size_t web_app_id = kMaxWebRtcEventLogWebAppId;
3542 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
3543 ASSERT_TRUE(PeerConnectionAdded(key));
3544 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
3545 EXPECT_TRUE(StartRemoteLogging(key, GetUniqueId(key),
3546 kMaxRemoteLogFileSizeBytes, 0, web_app_id));
3547 }
3548
3549 // Only one remote-bound event log allowed per
TEST_F(WebRtcEventLogManagerTest,StartRemoteLoggingOverMultipleWebAppsDisallowed)3550 TEST_F(WebRtcEventLogManagerTest,
3551 StartRemoteLoggingOverMultipleWebAppsDisallowed) {
3552 // Test assumes there are at least two legal web-app IDs.
3553 ASSERT_NE(kMinWebRtcEventLogWebAppId, kMaxWebRtcEventLogWebAppId);
3554 const size_t web_app_ids[2] = {kMinWebRtcEventLogWebAppId,
3555 kMaxWebRtcEventLogWebAppId};
3556
3557 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
3558 ASSERT_TRUE(PeerConnectionAdded(key));
3559 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
3560 EXPECT_TRUE(StartRemoteLogging(
3561 key, GetUniqueId(key), kMaxRemoteLogFileSizeBytes, 0, web_app_ids[0]));
3562 EXPECT_FALSE(StartRemoteLogging(
3563 key, GetUniqueId(key), kMaxRemoteLogFileSizeBytes, 0, web_app_ids[1]));
3564 }
3565
TEST_F(WebRtcEventLogManagerTest,StartRemoteLoggingWebAppIdIncorporatedIntoFileName)3566 TEST_F(WebRtcEventLogManagerTest,
3567 StartRemoteLoggingWebAppIdIncorporatedIntoFileName) {
3568 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
3569
3570 base::Optional<base::FilePath> file_path;
3571 ON_CALL(remote_observer_, OnRemoteLogStarted(key, _, _))
3572 .WillByDefault(Invoke(SaveFilePathTo(&file_path)));
3573
3574 ASSERT_TRUE(PeerConnectionAdded(key));
3575 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
3576 const size_t expected_web_app_id = kWebAppId;
3577 ASSERT_TRUE(StartRemoteLogging(key, GetUniqueId(key),
3578 kMaxRemoteLogFileSizeBytes, 0,
3579 expected_web_app_id));
3580 ASSERT_TRUE(file_path);
3581
3582 const size_t written_web_app_id =
3583 ExtractRemoteBoundWebRtcEventLogWebAppIdFromPath(*file_path);
3584 EXPECT_EQ(written_web_app_id, expected_web_app_id);
3585 }
3586
3587 INSTANTIATE_TEST_SUITE_P(UploadCompleteResult,
3588 WebRtcEventLogManagerTest,
3589 ::testing::Bool());
3590
TEST_F(WebRtcEventLogManagerTestCacheClearing,ClearCacheForBrowserContextRemovesPendingFilesInRange)3591 TEST_F(WebRtcEventLogManagerTestCacheClearing,
3592 ClearCacheForBrowserContextRemovesPendingFilesInRange) {
3593 SuppressUploading();
3594
3595 auto browser_context = CreateBrowserContext("name");
3596 CreatePendingLogFiles(browser_context.get());
3597 auto& elements = *(pending_logs_[browser_context.get()]);
3598
3599 const base::Time earliest_mod = pending_earliest_mod_ - kEpsion;
3600 const base::Time latest_mod = pending_latest_mod_ + kEpsion;
3601
3602 // Test - ClearCacheForBrowserContext() removed all of the files in the range.
3603 ClearCacheForBrowserContext(browser_context.get(), earliest_mod, latest_mod);
3604 for (size_t i = 0; i < elements.file_paths.size(); ++i) {
3605 EXPECT_FALSE(base::PathExists(*elements.file_paths[i]));
3606 }
3607
3608 ClearPendingLogFiles();
3609 }
3610
TEST_F(WebRtcEventLogManagerTestCacheClearing,ClearCacheForBrowserContextCancelsActiveLogFilesIfInRange)3611 TEST_F(WebRtcEventLogManagerTestCacheClearing,
3612 ClearCacheForBrowserContextCancelsActiveLogFilesIfInRange) {
3613 SuppressUploading();
3614
3615 // Setup
3616 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
3617 ASSERT_TRUE(PeerConnectionAdded(key));
3618 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
3619 base::Optional<base::FilePath> file_path;
3620 EXPECT_CALL(remote_observer_, OnRemoteLogStarted(key, _, _))
3621 .Times(1)
3622 .WillOnce(Invoke(SaveFilePathTo(&file_path)));
3623 ASSERT_TRUE(StartRemoteLogging(key));
3624 ASSERT_TRUE(file_path);
3625 ASSERT_TRUE(base::PathExists(*file_path));
3626
3627 // Test
3628 EXPECT_CALL(remote_observer_, OnRemoteLogStopped(key)).Times(1);
3629 ClearCacheForBrowserContext(
3630 browser_context_.get(), base::Time::Now() - base::TimeDelta::FromHours(1),
3631 base::Time::Now() + base::TimeDelta::FromHours(1));
3632 EXPECT_FALSE(base::PathExists(*file_path));
3633 }
3634
TEST_F(WebRtcEventLogManagerTestCacheClearing,ClearCacheForBrowserContextCancelsFileUploadIfInRange)3635 TEST_F(WebRtcEventLogManagerTestCacheClearing,
3636 ClearCacheForBrowserContextCancelsFileUploadIfInRange) {
3637 // This factory will enforce the expectation that the upload is cancelled.
3638 // WebRtcEventLogUploaderImplTest.CancelOnOngoingUploadDeletesFile is in
3639 // charge of making sure that when the upload is cancelled, the file is
3640 // removed from disk.
3641 SetWebRtcEventLogUploaderFactoryForTesting(
3642 std::make_unique<NullWebRtcEventLogUploader::Factory>(true));
3643
3644 // Set up and trigger the uploading of a file.
3645 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
3646 base::Optional<base::FilePath> file_path = CreatePendingRemoteLogFile(key);
3647
3648 ASSERT_TRUE(file_path);
3649 ASSERT_TRUE(base::PathExists(*file_path));
3650 const base::Time mod_time = GetLastModificationTime(*file_path);
3651
3652 // Main part of test - the expectation set up in the the uploader factory
3653 // should now be satisfied.
3654 ClearCacheForBrowserContext(browser_context_.get(), mod_time - kEpsion,
3655 mod_time + kEpsion);
3656 }
3657
TEST_F(WebRtcEventLogManagerTestCacheClearing,ClearCacheForBrowserContextDoesNotRemovePendingFilesOutOfRange)3658 TEST_F(WebRtcEventLogManagerTestCacheClearing,
3659 ClearCacheForBrowserContextDoesNotRemovePendingFilesOutOfRange) {
3660 SuppressUploading();
3661
3662 auto browser_context = CreateBrowserContext("name");
3663 CreatePendingLogFiles(browser_context.get());
3664 auto& elements = *(pending_logs_[browser_context.get()]);
3665
3666 // Get a range whose intersection with the files' range is empty.
3667 const base::Time earliest_mod =
3668 pending_earliest_mod_ - base::TimeDelta::FromHours(2);
3669 const base::Time latest_mod =
3670 pending_earliest_mod_ - base::TimeDelta::FromHours(1);
3671 ASSERT_LT(latest_mod, pending_latest_mod_);
3672
3673 // Test - ClearCacheForBrowserContext() does not remove files not in range.
3674 // (Range chosen to be earlier than the oldest file
3675 ClearCacheForBrowserContext(browser_context.get(), earliest_mod, latest_mod);
3676 for (size_t i = 0; i < elements.file_paths.size(); ++i) {
3677 EXPECT_TRUE(base::PathExists(*elements.file_paths[i]));
3678 }
3679
3680 ClearPendingLogFiles();
3681 }
3682
TEST_F(WebRtcEventLogManagerTestCacheClearing,ClearCacheForBrowserContextDoesNotCancelActiveLogFilesIfOutOfRange)3683 TEST_F(WebRtcEventLogManagerTestCacheClearing,
3684 ClearCacheForBrowserContextDoesNotCancelActiveLogFilesIfOutOfRange) {
3685 SuppressUploading();
3686
3687 // Setup
3688 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
3689 ASSERT_TRUE(PeerConnectionAdded(key));
3690 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
3691 base::Optional<base::FilePath> file_path;
3692 EXPECT_CALL(remote_observer_, OnRemoteLogStarted(key, _, _))
3693 .Times(1)
3694 .WillOnce(Invoke(SaveFilePathTo(&file_path)));
3695 ASSERT_TRUE(StartRemoteLogging(key));
3696 ASSERT_TRUE(file_path);
3697 ASSERT_TRUE(base::PathExists(*file_path));
3698
3699 // Test
3700 EXPECT_CALL(remote_observer_, OnRemoteLogStopped(_)).Times(0);
3701 ClearCacheForBrowserContext(
3702 browser_context_.get(), base::Time::Now() - base::TimeDelta::FromHours(2),
3703 base::Time::Now() - base::TimeDelta::FromHours(1));
3704 EXPECT_TRUE(base::PathExists(*file_path));
3705 }
3706
TEST_F(WebRtcEventLogManagerTestCacheClearing,ClearCacheForBrowserContextDoesNotCancelFileUploadIfOutOfRange)3707 TEST_F(WebRtcEventLogManagerTestCacheClearing,
3708 ClearCacheForBrowserContextDoesNotCancelFileUploadIfOutOfRange) {
3709 // This factory will enforce the expectation that the upload is not cancelled.
3710 SetWebRtcEventLogUploaderFactoryForTesting(
3711 std::make_unique<NullWebRtcEventLogUploader::Factory>(false));
3712
3713 // Set up and trigger the uploading of a file.
3714 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
3715 base::Optional<base::FilePath> file_path = CreatePendingRemoteLogFile(key);
3716
3717 ASSERT_TRUE(file_path);
3718 ASSERT_TRUE(base::PathExists(*file_path));
3719 const base::Time mod_time = GetLastModificationTime(*file_path);
3720
3721 // Main part of test - the expectation set up in the the uploader factory,
3722 // that the upload will not be cancelled, should be shown to hold true.
3723 // should now be satisfied.
3724 ClearCacheForBrowserContext(browser_context_.get(), mod_time + kEpsion,
3725 mod_time + 2 * kEpsion);
3726 }
3727
TEST_F(WebRtcEventLogManagerTestCacheClearing,ClearCacheForBrowserContextDoesNotRemovePendingFilesFromOtherProfiles)3728 TEST_F(WebRtcEventLogManagerTestCacheClearing,
3729 ClearCacheForBrowserContextDoesNotRemovePendingFilesFromOtherProfiles) {
3730 SuppressUploading();
3731
3732 auto cleared_browser_context = CreateBrowserContext("cleared");
3733 CreatePendingLogFiles(cleared_browser_context.get());
3734 auto& cleared_elements = *(pending_logs_[cleared_browser_context.get()]);
3735
3736 auto const uncleared_browser_context = CreateBrowserContext("pristine");
3737 CreatePendingLogFiles(uncleared_browser_context.get());
3738 auto& uncleared_elements = *(pending_logs_[uncleared_browser_context.get()]);
3739
3740 ASSERT_EQ(cleared_elements.file_paths.size(),
3741 uncleared_elements.file_paths.size());
3742 const size_t kFileCount = cleared_elements.file_paths.size();
3743
3744 const base::Time earliest_mod = pending_earliest_mod_ - kEpsion;
3745 const base::Time latest_mod = pending_latest_mod_ + kEpsion;
3746
3747 // Test - ClearCacheForBrowserContext() only removes the files which belong
3748 // to the cleared context.
3749 ClearCacheForBrowserContext(cleared_browser_context.get(), earliest_mod,
3750 latest_mod);
3751 for (size_t i = 0; i < kFileCount; ++i) {
3752 EXPECT_FALSE(base::PathExists(*cleared_elements.file_paths[i]));
3753 EXPECT_TRUE(base::PathExists(*uncleared_elements.file_paths[i]));
3754 }
3755
3756 ClearPendingLogFiles();
3757 }
3758
TEST_F(WebRtcEventLogManagerTestCacheClearing,ClearCacheForBrowserContextDoesNotCancelActiveLogsFromOtherProfiles)3759 TEST_F(WebRtcEventLogManagerTestCacheClearing,
3760 ClearCacheForBrowserContextDoesNotCancelActiveLogsFromOtherProfiles) {
3761 SuppressUploading();
3762
3763 // Remote-bound active log file that *will* be cleared.
3764 auto cleared_browser_context = CreateBrowserContext("cleared");
3765 auto cleared_rph =
3766 std::make_unique<MockRenderProcessHost>(cleared_browser_context.get());
3767 const auto cleared_key = GetPeerConnectionKey(cleared_rph.get(), kLid);
3768 base::Optional<base::FilePath> cleared_file_path =
3769 CreateActiveRemoteLogFile(cleared_key);
3770
3771 // Remote-bound active log file that will *not* be cleared.
3772 auto uncleared_browser_context = CreateBrowserContext("pristine");
3773 auto uncleared_rph =
3774 std::make_unique<MockRenderProcessHost>(uncleared_browser_context.get());
3775 const auto uncleared_key = GetPeerConnectionKey(uncleared_rph.get(), kLid);
3776 base::Optional<base::FilePath> uncleared_file_path =
3777 CreateActiveRemoteLogFile(uncleared_key);
3778
3779 // Test - ClearCacheForBrowserContext() only removes the files which belong
3780 // to the cleared context.
3781 EXPECT_CALL(remote_observer_, OnRemoteLogStopped(cleared_key)).Times(1);
3782 EXPECT_CALL(remote_observer_, OnRemoteLogStopped(uncleared_key)).Times(0);
3783 ClearCacheForBrowserContext(cleared_browser_context.get(), base::Time::Min(),
3784 base::Time::Max());
3785 EXPECT_FALSE(base::PathExists(*cleared_file_path));
3786 EXPECT_TRUE(base::PathExists(*uncleared_file_path));
3787
3788 // Cleanup - uncleared_file_path will be closed as part of the shutdown. It
3789 // is time to clear its expectation.
3790 testing::Mock::VerifyAndClearExpectations(&remote_observer_);
3791 }
3792
TEST_F(WebRtcEventLogManagerTestCacheClearing,ClearCacheForBrowserContextDoesNotCancelFileUploadFromOtherProfiles)3793 TEST_F(WebRtcEventLogManagerTestCacheClearing,
3794 ClearCacheForBrowserContextDoesNotCancelFileUploadFromOtherProfiles) {
3795 // This factory will enforce the expectation that the upload is not cancelled.
3796 SetWebRtcEventLogUploaderFactoryForTesting(
3797 std::make_unique<NullWebRtcEventLogUploader::Factory>(false));
3798
3799 // Set up and trigger the uploading of a file.
3800 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
3801 base::Optional<base::FilePath> file_path = CreatePendingRemoteLogFile(key);
3802
3803 ASSERT_TRUE(file_path);
3804 ASSERT_TRUE(base::PathExists(*file_path));
3805 const base::Time mod_time = GetLastModificationTime(*file_path);
3806
3807 // Main part of test - the expectation set up in the the uploader factory,
3808 // that the upload will not be cancelled, should be shown to hold true.
3809 // should now be satisfied.
3810 auto const different_browser_context = CreateBrowserContext();
3811 ClearCacheForBrowserContext(different_browser_context.get(),
3812 mod_time - kEpsion, mod_time + kEpsion);
3813 }
3814
3815 // Show that clearing browser cache, while it removes remote-bound logs, does
3816 // not interfere with local-bound logging, even if that happens on the same PC.
TEST_F(WebRtcEventLogManagerTestCacheClearing,ClearCacheForBrowserContextDoesNotInterfereWithLocalLogs)3817 TEST_F(WebRtcEventLogManagerTestCacheClearing,
3818 ClearCacheForBrowserContextDoesNotInterfereWithLocalLogs) {
3819 SuppressUploading();
3820
3821 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
3822
3823 base::Optional<base::FilePath> local_log;
3824 ON_CALL(local_observer_, OnLocalLogStarted(key, _))
3825 .WillByDefault(Invoke(SaveFilePathTo(&local_log)));
3826 ASSERT_TRUE(EnableLocalLogging());
3827
3828 // This adds a peer connection for |key|, which also triggers
3829 // OnLocalLogStarted() on |local_observer_|.
3830 auto pending_remote_log = CreatePendingRemoteLogFile(key);
3831
3832 // Test focus - local logging is uninterrupted.
3833 EXPECT_CALL(local_observer_, OnLocalLogStopped(_)).Times(0);
3834 ClearCacheForBrowserContext(browser_context_.get(), base::Time::Min(),
3835 base::Time::Max());
3836 EXPECT_TRUE(base::PathExists(*local_log));
3837
3838 // Sanity on the test itself; the remote log should have been cleared.
3839 ASSERT_FALSE(base::PathExists(*pending_remote_log));
3840 }
3841
3842 // When cache clearing cancels the active upload, the next (non-deleted) pending
3843 // file becomes eligible for upload.
TEST_F(WebRtcEventLogManagerTestCacheClearing,UploadCancellationTriggersUploadOfNextPendingFile)3844 TEST_F(WebRtcEventLogManagerTestCacheClearing,
3845 UploadCancellationTriggersUploadOfNextPendingFile) {
3846 // The first created file will start being uploaded, but then cancelled.
3847 // The second file will never be uploaded (deleted while pending).
3848 SetWebRtcEventLogUploaderFactoryForTesting(
3849 std::make_unique<NullWebRtcEventLogUploader::Factory>(true));
3850
3851 // Create the files that will be deleted when cache is cleared.
3852 CreatePendingRemoteLogFile(GetPeerConnectionKey(rph_.get(), 0));
3853 CreatePendingRemoteLogFile(GetPeerConnectionKey(rph_.get(), 1));
3854
3855 // Create the not-deleted file under a different profile, to easily make sure
3856 // it does not fit in the ClearCacheForBrowserContext range (less fiddly than
3857 // a time range).
3858 auto other_browser_context = CreateBrowserContext();
3859 auto other_rph =
3860 std::make_unique<MockRenderProcessHost>(other_browser_context.get());
3861 const auto key = GetPeerConnectionKey(other_rph.get(), kLid);
3862 base::Optional<base::FilePath> other_file = CreatePendingRemoteLogFile(key);
3863 ASSERT_TRUE(other_file);
3864
3865 // Switch the uploader factory to one that will allow us to ensure that the
3866 // new file, which is not deleted, is uploaded.
3867 base::RunLoop run_loop;
3868 std::list<WebRtcLogFileInfo> expected_files = {
3869 WebRtcLogFileInfo(GetBrowserContextId(other_browser_context.get()),
3870 *other_file, GetLastModificationTime(*other_file))};
3871 SetWebRtcEventLogUploaderFactoryForTesting(
3872 std::make_unique<FileListExpectingWebRtcEventLogUploader::Factory>(
3873 &expected_files, true, &run_loop));
3874
3875 // Clearing the cache for the first profile, should now trigger the upload
3876 // of the last remaining unclear pending log file - |other_file|.
3877 ClearCacheForBrowserContext(browser_context_.get(), base::Time::Min(),
3878 base::Time::Max());
3879 WaitForPendingTasks(&run_loop);
3880 }
3881
TEST_P(WebRtcEventLogManagerTestWithRemoteLoggingDisabled,SanityPeerConnectionAdded)3882 TEST_P(WebRtcEventLogManagerTestWithRemoteLoggingDisabled,
3883 SanityPeerConnectionAdded) {
3884 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
3885 EXPECT_TRUE(PeerConnectionAdded(key));
3886 }
3887
TEST_P(WebRtcEventLogManagerTestWithRemoteLoggingDisabled,SanityPeerConnectionRemoved)3888 TEST_P(WebRtcEventLogManagerTestWithRemoteLoggingDisabled,
3889 SanityPeerConnectionRemoved) {
3890 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
3891 ASSERT_TRUE(PeerConnectionAdded(key));
3892 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
3893 EXPECT_TRUE(PeerConnectionRemoved(key));
3894 }
3895
TEST_P(WebRtcEventLogManagerTestWithRemoteLoggingDisabled,SanityPeerConnectionStopped)3896 TEST_P(WebRtcEventLogManagerTestWithRemoteLoggingDisabled,
3897 SanityPeerConnectionStopped) {
3898 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
3899 PeerConnectionStopped(key); // No crash.
3900 }
3901
TEST_P(WebRtcEventLogManagerTestWithRemoteLoggingDisabled,SanityEnableLocalLogging)3902 TEST_P(WebRtcEventLogManagerTestWithRemoteLoggingDisabled,
3903 SanityEnableLocalLogging) {
3904 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
3905 ASSERT_TRUE(PeerConnectionAdded(key));
3906 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
3907 ASSERT_TRUE(EnableLocalLogging());
3908 }
3909
TEST_P(WebRtcEventLogManagerTestWithRemoteLoggingDisabled,SanityDisableLocalLogging)3910 TEST_P(WebRtcEventLogManagerTestWithRemoteLoggingDisabled,
3911 SanityDisableLocalLogging) {
3912 ASSERT_TRUE(EnableLocalLogging());
3913 EXPECT_TRUE(DisableLocalLogging());
3914 }
3915
TEST_P(WebRtcEventLogManagerTestWithRemoteLoggingDisabled,SanityStartRemoteLogging)3916 TEST_P(WebRtcEventLogManagerTestWithRemoteLoggingDisabled,
3917 SanityStartRemoteLogging) {
3918 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
3919 ASSERT_TRUE(PeerConnectionAdded(key));
3920 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
3921 std::string error_message;
3922 EXPECT_FALSE(StartRemoteLogging(key, nullptr, &error_message));
3923 EXPECT_EQ(error_message, kStartRemoteLoggingFailureFeatureDisabled);
3924 }
3925
TEST_P(WebRtcEventLogManagerTestWithRemoteLoggingDisabled,SanityOnWebRtcEventLogWrite)3926 TEST_P(WebRtcEventLogManagerTestWithRemoteLoggingDisabled,
3927 SanityOnWebRtcEventLogWrite) {
3928 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
3929 ASSERT_TRUE(PeerConnectionAdded(key));
3930 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
3931 ASSERT_FALSE(StartRemoteLogging(key));
3932 EXPECT_EQ(OnWebRtcEventLogWrite(key, "log"), std::make_pair(false, false));
3933 }
3934
3935 INSTANTIATE_TEST_SUITE_P(All,
3936 WebRtcEventLogManagerTestWithRemoteLoggingDisabled,
3937 ::testing::Bool());
3938
3939 // This test is redundant; it is provided for completeness; see following tests.
TEST_F(WebRtcEventLogManagerTestPolicy,StartsEnabledAllowsRemoteLogging)3940 TEST_F(WebRtcEventLogManagerTestPolicy, StartsEnabledAllowsRemoteLogging) {
3941 SetUp(true); // Feature generally enabled (kill-switch not engaged).
3942
3943 const bool allow_remote_logging = true;
3944 auto browser_context = CreateBrowserContext(
3945 "name", true /* is_managed_profile */,
3946 false /* has_device_level_policies */, allow_remote_logging);
3947
3948 auto rph = std::make_unique<MockRenderProcessHost>(browser_context.get());
3949 const auto key = GetPeerConnectionKey(rph.get(), kLid);
3950
3951 ASSERT_TRUE(PeerConnectionAdded(key));
3952 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
3953 EXPECT_EQ(StartRemoteLogging(key), allow_remote_logging);
3954 }
3955
3956 // This test is redundant; it is provided for completeness; see following tests.
TEST_F(WebRtcEventLogManagerTestPolicy,StartsDisabledRejectsRemoteLogging)3957 TEST_F(WebRtcEventLogManagerTestPolicy, StartsDisabledRejectsRemoteLogging) {
3958 SetUp(true); // Feature generally enabled (kill-switch not engaged).
3959
3960 const bool allow_remote_logging = false;
3961 auto browser_context = CreateBrowserContext(
3962 "name", true /* is_managed_profile */,
3963 false /* has_device_level_policies */, allow_remote_logging);
3964
3965 auto rph = std::make_unique<MockRenderProcessHost>(browser_context.get());
3966 const auto key = GetPeerConnectionKey(rph.get(), kLid);
3967
3968 ASSERT_TRUE(PeerConnectionAdded(key));
3969 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
3970 EXPECT_EQ(StartRemoteLogging(key), allow_remote_logging);
3971 }
3972
TEST_F(WebRtcEventLogManagerTestPolicy,NotManagedRejectsRemoteLogging)3973 TEST_F(WebRtcEventLogManagerTestPolicy, NotManagedRejectsRemoteLogging) {
3974 SetUp(true); // Feature generally enabled (kill-switch not engaged).
3975
3976 const bool allow_remote_logging = false;
3977 auto browser_context = CreateBrowserContext(
3978 "name", false /* is_managed_profile */,
3979 false /* has_device_level_policies */, base::nullopt);
3980
3981 auto rph = std::make_unique<MockRenderProcessHost>(browser_context.get());
3982 const auto key = GetPeerConnectionKey(rph.get(), kLid);
3983
3984 ASSERT_TRUE(PeerConnectionAdded(key));
3985 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
3986 EXPECT_EQ(StartRemoteLogging(key), allow_remote_logging);
3987 }
3988
3989 #if defined(OS_CHROMEOS)
3990 std::unique_ptr<user_manager::ScopedUserManager>
GetScopedUserManager(user_manager::UserType user_type)3991 WebRtcEventLogManagerTestPolicy::GetScopedUserManager(
3992 user_manager::UserType user_type) {
3993 const AccountId kAccountId = AccountId::FromUserEmailGaiaId("name", "id");
3994 auto mock_user_manager =
3995 std::make_unique<testing::NiceMock<chromeos::FakeChromeUserManager>>();
3996 // On Chrome OS, there are different user types, some of which can be
3997 // affiliated with the device if the device is enterprise-enrolled, i.e. the
3998 // logged in account belongs to the org that owns the device. For our
3999 // purposes here, affiliation does not matter for the determination of the
4000 // policy default, so we can set it to false here. We do not need a user
4001 // to profile mapping either, so profile can be a nullptr.
4002 mock_user_manager->AddUserWithAffiliationAndTypeAndProfile(
4003 kAccountId, /*is_affiliated*/ false, user_type, /*profile*/ nullptr);
4004 return std::make_unique<user_manager::ScopedUserManager>(
4005 std::move(mock_user_manager));
4006 }
4007 #endif
4008
TEST_F(WebRtcEventLogManagerTestPolicy,ManagedProfileAllowsRemoteLoggingByDefault)4009 TEST_F(WebRtcEventLogManagerTestPolicy,
4010 ManagedProfileAllowsRemoteLoggingByDefault) {
4011 SetUp(true); // Feature generally enabled (kill-switch not engaged).
4012
4013 const bool allow_remote_logging = true;
4014
4015 #if defined(OS_CHROMEOS)
4016 std::unique_ptr<user_manager::ScopedUserManager> scoped_user_manager =
4017 GetScopedUserManager(user_manager::USER_TYPE_REGULAR);
4018 #endif
4019
4020 auto browser_context = CreateBrowserContext(
4021 "name", true /* is_managed_profile */,
4022 false /* has_device_level_policies */, base::nullopt);
4023
4024 auto rph = std::make_unique<MockRenderProcessHost>(browser_context.get());
4025 const auto key = GetPeerConnectionKey(rph.get(), kLid);
4026
4027 ASSERT_TRUE(PeerConnectionAdded(key));
4028 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
4029 EXPECT_EQ(StartRemoteLogging(key), allow_remote_logging);
4030 }
4031
4032 // Currently we only test the case of supervised child profiles for Chrome OS
4033 // here. Other user types for Chrome OS are tested in the unit test for
4034 // ProfileDefaultsToLoggingEnabledTestCase in
4035 // webrtc_event_log_manager_common_unittest because the test setup in this
4036 // class currently does not seem to allow for an easy setup of some user types.
4037 // TODO(crbug.com/1035829): Figure out whether this can be resolved by tweaking
4038 // the test setup or whether the Active Directory services need to be adapted
4039 // for easy testing.
TEST_F(WebRtcEventLogManagerTestPolicy,ManagedProfileDoesNotAllowRemoteLoggingForSupervisedProfiles)4040 TEST_F(WebRtcEventLogManagerTestPolicy,
4041 ManagedProfileDoesNotAllowRemoteLoggingForSupervisedProfiles) {
4042 SetUp(true); // Feature generally enabled (kill-switch not engaged).
4043
4044 const bool allow_remote_logging = false;
4045
4046 #if defined(OS_CHROMEOS)
4047 std::unique_ptr<user_manager::ScopedUserManager> scoped_user_manager =
4048 GetScopedUserManager(user_manager::USER_TYPE_CHILD);
4049 #endif
4050
4051 auto browser_context = CreateBrowserContextWithCustomSupervision(
4052 "name", true /* is_managed_profile */,
4053 false /* has_device_level_policies */, true /* is_supervised */,
4054 base::nullopt);
4055
4056 auto rph = std::make_unique<MockRenderProcessHost>(browser_context.get());
4057 const auto key = GetPeerConnectionKey(rph.get(), kLid);
4058
4059 ASSERT_TRUE(PeerConnectionAdded(key));
4060 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
4061 EXPECT_EQ(StartRemoteLogging(key), allow_remote_logging);
4062 }
4063
4064 #if !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
TEST_F(WebRtcEventLogManagerTestPolicy,OnlyManagedByPlatformPoliciesDoesNotAllowRemoteLoggingByDefault)4065 TEST_F(WebRtcEventLogManagerTestPolicy,
4066 OnlyManagedByPlatformPoliciesDoesNotAllowRemoteLoggingByDefault) {
4067 SetUp(true); // Feature generally enabled (kill-switch not engaged).
4068
4069 const bool allow_remote_logging = false;
4070 auto browser_context =
4071 CreateBrowserContext("name", false /* is_managed_profile */,
4072 true /* has_device_level_policies */, base::nullopt);
4073
4074 auto rph = std::make_unique<MockRenderProcessHost>(browser_context.get());
4075 const auto key = GetPeerConnectionKey(rph.get(), kLid);
4076
4077 ASSERT_TRUE(PeerConnectionAdded(key));
4078 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
4079 EXPECT_EQ(StartRemoteLogging(key), allow_remote_logging);
4080 }
4081 #endif
4082
TestManagedProfileAfterBeingExplicitlySet(bool explicitly_set_value)4083 void WebRtcEventLogManagerTestPolicy::TestManagedProfileAfterBeingExplicitlySet(
4084 bool explicitly_set_value) {
4085 SetUp(true); // Feature generally enabled (kill-switch not engaged).
4086
4087 auto profile = CreateBrowserContext("name", true /* is_managed_profile */,
4088 false /* has_device_level_policies */,
4089 base::nullopt);
4090
4091 auto rph = std::make_unique<MockRenderProcessHost>(profile.get());
4092 const auto key = GetPeerConnectionKey(rph.get(), kLid);
4093
4094 ASSERT_TRUE(PeerConnectionAdded(key));
4095 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
4096
4097 profile->GetPrefs()->SetBoolean(prefs::kWebRtcEventLogCollectionAllowed,
4098 explicitly_set_value);
4099 EXPECT_EQ(StartRemoteLogging(key), explicitly_set_value);
4100 }
4101
TEST_F(WebRtcEventLogManagerTestPolicy,ManagedProfileAllowsRemoteLoggingAfterBeingExplicitlyEnabled)4102 TEST_F(WebRtcEventLogManagerTestPolicy,
4103 ManagedProfileAllowsRemoteLoggingAfterBeingExplicitlyEnabled) {
4104 TestManagedProfileAfterBeingExplicitlySet(true);
4105 }
4106
TEST_F(WebRtcEventLogManagerTestPolicy,ManagedProfileDisallowsRemoteLoggingAfterBeingDisabled)4107 TEST_F(WebRtcEventLogManagerTestPolicy,
4108 ManagedProfileDisallowsRemoteLoggingAfterBeingDisabled) {
4109 TestManagedProfileAfterBeingExplicitlySet(false);
4110 }
4111
4112 // #1 and #2 differ in the order of AddPeerConnection and the changing of
4113 // the pref value.
TEST_F(WebRtcEventLogManagerTestPolicy,StartsEnabledThenDisabledRejectsRemoteLogging1)4114 TEST_F(WebRtcEventLogManagerTestPolicy,
4115 StartsEnabledThenDisabledRejectsRemoteLogging1) {
4116 SetUp(true); // Feature generally enabled (kill-switch not engaged).
4117
4118 bool allow_remote_logging = true;
4119 auto profile = CreateBrowserContext("name", true /* is_managed_profile */,
4120 false /* has_device_level_policies */,
4121 allow_remote_logging);
4122
4123 auto rph = std::make_unique<MockRenderProcessHost>(profile.get());
4124 const auto key = GetPeerConnectionKey(rph.get(), kLid);
4125
4126 ASSERT_TRUE(PeerConnectionAdded(key));
4127 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
4128
4129 allow_remote_logging = !allow_remote_logging;
4130 profile->GetPrefs()->SetBoolean(prefs::kWebRtcEventLogCollectionAllowed,
4131 allow_remote_logging);
4132
4133 EXPECT_EQ(StartRemoteLogging(key), allow_remote_logging);
4134 }
4135
4136 // #1 and #2 differ in the order of AddPeerConnection and the changing of
4137 // the pref value.
TEST_F(WebRtcEventLogManagerTestPolicy,StartsEnabledThenDisabledRejectsRemoteLogging2)4138 TEST_F(WebRtcEventLogManagerTestPolicy,
4139 StartsEnabledThenDisabledRejectsRemoteLogging2) {
4140 SetUp(true); // Feature generally enabled (kill-switch not engaged).
4141
4142 bool allow_remote_logging = true;
4143 auto profile = CreateBrowserContext("name", true /* is_managed_profile */,
4144 false /* has_device_level_policies */,
4145 allow_remote_logging);
4146
4147 auto rph = std::make_unique<MockRenderProcessHost>(profile.get());
4148 const auto key = GetPeerConnectionKey(rph.get(), kLid);
4149
4150 allow_remote_logging = !allow_remote_logging;
4151 profile->GetPrefs()->SetBoolean(prefs::kWebRtcEventLogCollectionAllowed,
4152 allow_remote_logging);
4153
4154 ASSERT_TRUE(PeerConnectionAdded(key));
4155 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
4156
4157 EXPECT_EQ(StartRemoteLogging(key), allow_remote_logging);
4158 }
4159
4160 // #1 and #2 differ in the order of AddPeerConnection and the changing of
4161 // the pref value.
TEST_F(WebRtcEventLogManagerTestPolicy,StartsDisabledThenEnabledAllowsRemoteLogging1)4162 TEST_F(WebRtcEventLogManagerTestPolicy,
4163 StartsDisabledThenEnabledAllowsRemoteLogging1) {
4164 SetUp(true); // Feature generally enabled (kill-switch not engaged).
4165
4166 bool allow_remote_logging = false;
4167 auto profile = CreateBrowserContext("name", true /* is_managed_profile */,
4168 false /* has_device_level_policies */,
4169 allow_remote_logging);
4170
4171 auto rph = std::make_unique<MockRenderProcessHost>(profile.get());
4172 const auto key = GetPeerConnectionKey(rph.get(), kLid);
4173
4174 ASSERT_TRUE(PeerConnectionAdded(key));
4175 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
4176
4177 allow_remote_logging = !allow_remote_logging;
4178 profile->GetPrefs()->SetBoolean(prefs::kWebRtcEventLogCollectionAllowed,
4179 allow_remote_logging);
4180
4181 EXPECT_EQ(StartRemoteLogging(key), allow_remote_logging);
4182 }
4183
4184 // #1 and #2 differ in the order of AddPeerConnection and the changing of
4185 // the pref value.
TEST_F(WebRtcEventLogManagerTestPolicy,StartsDisabledThenEnabledAllowsRemoteLogging2)4186 TEST_F(WebRtcEventLogManagerTestPolicy,
4187 StartsDisabledThenEnabledAllowsRemoteLogging2) {
4188 SetUp(true); // Feature generally enabled (kill-switch not engaged).
4189
4190 bool allow_remote_logging = false;
4191 auto profile = CreateBrowserContext("name", true /* is_managed_profile */,
4192 false /* has_device_level_policies */,
4193 allow_remote_logging);
4194
4195 auto rph = std::make_unique<MockRenderProcessHost>(profile.get());
4196 const auto key = GetPeerConnectionKey(rph.get(), kLid);
4197
4198 allow_remote_logging = !allow_remote_logging;
4199 profile->GetPrefs()->SetBoolean(prefs::kWebRtcEventLogCollectionAllowed,
4200 allow_remote_logging);
4201
4202 ASSERT_TRUE(PeerConnectionAdded(key));
4203 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
4204
4205 EXPECT_EQ(StartRemoteLogging(key), allow_remote_logging);
4206 }
4207
TEST_F(WebRtcEventLogManagerTestPolicy,StartsDisabledThenEnabledUploadsPendingLogFiles)4208 TEST_F(WebRtcEventLogManagerTestPolicy,
4209 StartsDisabledThenEnabledUploadsPendingLogFiles) {
4210 SetUp(true); // Feature generally enabled (kill-switch not engaged).
4211
4212 bool allow_remote_logging = false;
4213 auto profile = CreateBrowserContext("name", true /* is_managed_profile */,
4214 false /* has_device_level_policies */,
4215 allow_remote_logging);
4216
4217 auto rph = std::make_unique<MockRenderProcessHost>(profile.get());
4218 const auto key = GetPeerConnectionKey(rph.get(), kLid);
4219
4220 allow_remote_logging = !allow_remote_logging;
4221 profile->GetPrefs()->SetBoolean(prefs::kWebRtcEventLogCollectionAllowed,
4222 allow_remote_logging);
4223
4224 base::Optional<base::FilePath> log_file;
4225 ON_CALL(remote_observer_, OnRemoteLogStarted(key, _, _))
4226 .WillByDefault(Invoke(SaveFilePathTo(&log_file)));
4227 ASSERT_TRUE(PeerConnectionAdded(key));
4228 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
4229 ASSERT_TRUE(allow_remote_logging)
4230 << "Must turn on before StartRemoteLogging, to test the right thing.";
4231 ASSERT_EQ(StartRemoteLogging(key), allow_remote_logging);
4232 ASSERT_TRUE(log_file);
4233
4234 base::RunLoop run_loop;
4235 std::list<WebRtcLogFileInfo> expected_files = {WebRtcLogFileInfo(
4236 browser_context_id_, *log_file, GetLastModificationTime(*log_file))};
4237 SetWebRtcEventLogUploaderFactoryForTesting(
4238 std::make_unique<FileListExpectingWebRtcEventLogUploader::Factory>(
4239 &expected_files, true, &run_loop));
4240
4241 ASSERT_TRUE(PeerConnectionRemoved(key));
4242
4243 WaitForPendingTasks(&run_loop);
4244 }
4245
TEST_F(WebRtcEventLogManagerTestPolicy,StartsEnabledThenDisabledDoesNotUploadPendingLogFiles)4246 TEST_F(WebRtcEventLogManagerTestPolicy,
4247 StartsEnabledThenDisabledDoesNotUploadPendingLogFiles) {
4248 SetUp(true); // Feature generally enabled (kill-switch not engaged).
4249
4250 SuppressUploading();
4251
4252 std::list<WebRtcLogFileInfo> empty_list;
4253 base::RunLoop run_loop;
4254 SetWebRtcEventLogUploaderFactoryForTesting(
4255 std::make_unique<FileListExpectingWebRtcEventLogUploader::Factory>(
4256 &empty_list, true, &run_loop));
4257
4258 bool allow_remote_logging = true;
4259 auto profile = CreateBrowserContext("name", true /* is_managed_profile */,
4260 false /* has_device_level_policies */,
4261 allow_remote_logging);
4262
4263 auto rph = std::make_unique<MockRenderProcessHost>(profile.get());
4264 const auto key = GetPeerConnectionKey(rph.get(), kLid);
4265
4266 ASSERT_TRUE(PeerConnectionAdded(key));
4267 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
4268 ASSERT_TRUE(allow_remote_logging)
4269 << "Must turn off after StartRemoteLogging, to test the right thing.";
4270 ASSERT_EQ(StartRemoteLogging(key), allow_remote_logging);
4271 ASSERT_TRUE(PeerConnectionRemoved(key));
4272
4273 allow_remote_logging = !allow_remote_logging;
4274 profile->GetPrefs()->SetBoolean(prefs::kWebRtcEventLogCollectionAllowed,
4275 allow_remote_logging);
4276
4277 UnsuppressUploading();
4278
4279 WaitForPendingTasks(&run_loop);
4280 }
4281
TEST_F(WebRtcEventLogManagerTestPolicy,StartsEnabledThenDisabledDeletesPendingLogFiles)4282 TEST_F(WebRtcEventLogManagerTestPolicy,
4283 StartsEnabledThenDisabledDeletesPendingLogFiles) {
4284 SetUp(true); // Feature generally enabled (kill-switch not engaged).
4285
4286 SuppressUploading();
4287
4288 std::list<WebRtcLogFileInfo> empty_list;
4289 base::RunLoop run_loop;
4290 SetWebRtcEventLogUploaderFactoryForTesting(
4291 std::make_unique<FileListExpectingWebRtcEventLogUploader::Factory>(
4292 &empty_list, true, &run_loop));
4293
4294 bool allow_remote_logging = true;
4295 auto profile = CreateBrowserContext("name", true /* is_managed_profile */,
4296 false /* has_device_level_policies */,
4297 allow_remote_logging);
4298
4299 auto rph = std::make_unique<MockRenderProcessHost>(profile.get());
4300 const auto key = GetPeerConnectionKey(rph.get(), kLid);
4301
4302 base::Optional<base::FilePath> log_file;
4303 ON_CALL(remote_observer_, OnRemoteLogStarted(key, _, _))
4304 .WillByDefault(Invoke(SaveFilePathTo(&log_file)));
4305 ASSERT_TRUE(PeerConnectionAdded(key));
4306 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
4307 ASSERT_TRUE(allow_remote_logging)
4308 << "Must turn off after StartRemoteLogging, to test the right thing.";
4309 ASSERT_EQ(StartRemoteLogging(key), allow_remote_logging);
4310 ASSERT_TRUE(log_file);
4311
4312 // Make the file PENDING.
4313 ASSERT_TRUE(PeerConnectionRemoved(key));
4314 ASSERT_TRUE(base::PathExists(*log_file)); // Test sanity; exists before.
4315
4316 allow_remote_logging = !allow_remote_logging;
4317 profile->GetPrefs()->SetBoolean(prefs::kWebRtcEventLogCollectionAllowed,
4318 allow_remote_logging);
4319
4320 WaitForPendingTasks(&run_loop);
4321
4322 // Test focus - file deleted without being uploaded.
4323 EXPECT_FALSE(base::PathExists(*log_file));
4324
4325 // Still not uploaded.
4326 UnsuppressUploading();
4327 WaitForPendingTasks();
4328 }
4329
TEST_F(WebRtcEventLogManagerTestPolicy,StartsEnabledThenDisabledCancelsAndDeletesCurrentlyUploadedLogFile)4330 TEST_F(WebRtcEventLogManagerTestPolicy,
4331 StartsEnabledThenDisabledCancelsAndDeletesCurrentlyUploadedLogFile) {
4332 SetUp(true); // Feature generally enabled (kill-switch not engaged).
4333
4334 // This factory expects exactly one log to be uploaded, then cancelled.
4335 SetWebRtcEventLogUploaderFactoryForTesting(
4336 std::make_unique<NullWebRtcEventLogUploader::Factory>(true, 1));
4337
4338 bool allow_remote_logging = true;
4339 auto profile = CreateBrowserContext("name", true /* is_managed_profile */,
4340 false /* has_device_level_policies */,
4341 allow_remote_logging);
4342
4343 auto rph = std::make_unique<MockRenderProcessHost>(profile.get());
4344 const auto key = GetPeerConnectionKey(rph.get(), kLid);
4345
4346 base::Optional<base::FilePath> log_file;
4347 ON_CALL(remote_observer_, OnRemoteLogStarted(key, _, _))
4348 .WillByDefault(Invoke(SaveFilePathTo(&log_file)));
4349 ASSERT_TRUE(PeerConnectionAdded(key));
4350 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
4351 ASSERT_TRUE(allow_remote_logging)
4352 << "Must turn off after StartRemoteLogging, to test the right thing.";
4353 ASSERT_EQ(StartRemoteLogging(key), allow_remote_logging);
4354 ASSERT_TRUE(log_file);
4355
4356 // Log file's upload commences.
4357 ASSERT_TRUE(PeerConnectionRemoved(key));
4358
4359 ASSERT_TRUE(base::PathExists(*log_file)); // Test sanity; exists before.
4360
4361 allow_remote_logging = false;
4362 profile->GetPrefs()->SetBoolean(prefs::kWebRtcEventLogCollectionAllowed,
4363 allow_remote_logging);
4364
4365 WaitForPendingTasks();
4366
4367 // Test focus - file deleted without being uploaded.
4368 // When the test terminates, the NullWebRtcEventLogUploader::Factory's
4369 // expectation that one log file was uploaded, and that the upload was
4370 // cancelled, is enforced.
4371 // Deletion of the file not performed by NullWebRtcEventLogUploader; instead,
4372 // WebRtcEventLogUploaderImplTest.CancelOnOngoingUploadDeletesFile tests that.
4373 }
4374
4375 // This test makes sure that if the policy was enabled in the past, but was
4376 // disabled while Chrome was not running, pending logs created during the
4377 // earlier session will be deleted from disk.
TEST_F(WebRtcEventLogManagerTestPolicy,PendingLogsFromPreviousSessionRemovedIfPolicyDisabledAtNewSessionStart)4378 TEST_F(WebRtcEventLogManagerTestPolicy,
4379 PendingLogsFromPreviousSessionRemovedIfPolicyDisabledAtNewSessionStart) {
4380 SetUp(true); // Feature generally enabled (kill-switch not engaged).
4381
4382 SuppressUploading();
4383
4384 SetWebRtcEventLogUploaderFactoryForTesting(
4385 std::make_unique<NullWebRtcEventLogUploader::Factory>(true, 0));
4386
4387 bool allow_remote_logging = true;
4388 auto browser_context = CreateBrowserContext(
4389 "name", true /* is_managed_profile */,
4390 false /* has_device_level_policies */, allow_remote_logging);
4391
4392 const base::FilePath browser_context_dir =
4393 RemoteBoundLogsDir(browser_context.get());
4394 ASSERT_TRUE(base::DirectoryExists(browser_context_dir));
4395
4396 auto rph = std::make_unique<MockRenderProcessHost>(browser_context.get());
4397 const auto key = GetPeerConnectionKey(rph.get(), kLid);
4398
4399 // Produce an empty log file in the BrowserContext. It's not uploaded
4400 // because uploading is suppressed.
4401 ASSERT_TRUE(PeerConnectionAdded(key));
4402 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
4403 ASSERT_TRUE(allow_remote_logging)
4404 << "Must turn off after StartRemoteLogging, to test the right thing.";
4405 ASSERT_EQ(StartRemoteLogging(key), allow_remote_logging);
4406 ASSERT_TRUE(PeerConnectionRemoved(key));
4407
4408 // Reload the BrowserContext, but this time with the policy disabling
4409 // the feature.
4410 rph.reset();
4411 browser_context.reset();
4412 ASSERT_TRUE(base::DirectoryExists(browser_context_dir)); // Test sanity
4413 allow_remote_logging = false;
4414 browser_context = CreateBrowserContext("name", true /* is_managed_profile */,
4415 false /* has_device_level_policies */,
4416 allow_remote_logging);
4417
4418 // Test focus - pending log files removed, as well as any potential metadata
4419 // associated with remote-bound logging for |browser_context|.
4420 ASSERT_FALSE(base::DirectoryExists(browser_context_dir));
4421
4422 // When NullWebRtcEventLogUploader::Factory is destroyed, it will show that
4423 // the deleted log file was never uploaded.
4424 UnsuppressUploading();
4425 WaitForPendingTasks();
4426 }
4427
TEST_F(WebRtcEventLogManagerTestPolicy,PendingLogsFromPreviousSessionRemovedIfRemoteLoggingKillSwitchEngaged)4428 TEST_F(WebRtcEventLogManagerTestPolicy,
4429 PendingLogsFromPreviousSessionRemovedIfRemoteLoggingKillSwitchEngaged) {
4430 SetUp(false); // Feature generally disabled (kill-switch engaged).
4431
4432 SetWebRtcEventLogUploaderFactoryForTesting(
4433 std::make_unique<NullWebRtcEventLogUploader::Factory>(true, 0));
4434
4435 const std::string name = "name";
4436 const base::FilePath browser_context_dir =
4437 profiles_dir_.GetPath().AppendASCII(name);
4438 const base::FilePath remote_bound_dir =
4439 RemoteBoundLogsDir(browser_context_dir);
4440 ASSERT_FALSE(base::PathExists(remote_bound_dir));
4441
4442 base::FilePath file_path;
4443 base::File file;
4444 ASSERT_TRUE(base::CreateDirectory(remote_bound_dir));
4445 ASSERT_TRUE(CreateRemoteBoundLogFile(remote_bound_dir, kWebAppId,
4446 remote_log_extension_, base::Time::Now(),
4447 &file_path, &file));
4448 file.Close();
4449
4450 const bool allow_remote_logging = true;
4451 auto browser_context = CreateBrowserContext(
4452 "name", true /* is_managed_profile */,
4453 false /* has_device_level_policies */, allow_remote_logging);
4454 ASSERT_EQ(browser_context->GetPath(), browser_context_dir); // Test sanity
4455
4456 WaitForPendingTasks();
4457
4458 EXPECT_FALSE(base::PathExists(remote_bound_dir));
4459 }
4460
TEST_F(WebRtcEventLogManagerTestUploadSuppressionDisablingFlag,UploadingNotSuppressedByActivePeerConnections)4461 TEST_F(WebRtcEventLogManagerTestUploadSuppressionDisablingFlag,
4462 UploadingNotSuppressedByActivePeerConnections) {
4463 SuppressUploading();
4464
4465 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
4466 ASSERT_TRUE(PeerConnectionAdded(key));
4467 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
4468
4469 base::Optional<base::FilePath> log_file;
4470 ON_CALL(remote_observer_, OnRemoteLogStarted(key, _, _))
4471 .WillByDefault(Invoke(SaveFilePathTo(&log_file)));
4472 ASSERT_TRUE(StartRemoteLogging(key));
4473 ASSERT_TRUE(log_file);
4474
4475 base::RunLoop run_loop;
4476 std::list<WebRtcLogFileInfo> expected_files = {WebRtcLogFileInfo(
4477 browser_context_id_, *log_file, GetLastModificationTime(*log_file))};
4478 SetWebRtcEventLogUploaderFactoryForTesting(
4479 std::make_unique<FileListExpectingWebRtcEventLogUploader::Factory>(
4480 &expected_files, true, &run_loop));
4481
4482 ASSERT_TRUE(PeerConnectionRemoved(key));
4483 WaitForPendingTasks(&run_loop);
4484 }
4485
TEST_P(WebRtcEventLogManagerTestForNetworkConnectivity,DoNotUploadPendingLogsIfConnectedToUnsupportedNetworkType)4486 TEST_P(WebRtcEventLogManagerTestForNetworkConnectivity,
4487 DoNotUploadPendingLogsIfConnectedToUnsupportedNetworkType) {
4488 SetUpNetworkConnection(get_conn_type_is_sync_, unsupported_type_);
4489
4490 const auto key = GetPeerConnectionKey(rph_.get(), 1);
4491 base::Optional<base::FilePath> log_file;
4492 ON_CALL(remote_observer_, OnRemoteLogStarted(key, _, _))
4493 .WillByDefault(Invoke(SaveFilePathTo(&log_file)));
4494 ASSERT_TRUE(PeerConnectionAdded(key));
4495 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
4496 ASSERT_TRUE(StartRemoteLogging(key));
4497 ASSERT_TRUE(log_file);
4498
4499 std::list<WebRtcLogFileInfo> empty_expected_files_list;
4500 base::RunLoop run_loop;
4501 SetWebRtcEventLogUploaderFactoryForTesting(
4502 std::make_unique<FileListExpectingWebRtcEventLogUploader::Factory>(
4503 &empty_expected_files_list, true, &run_loop));
4504
4505 // Peer connection removal MAY trigger upload, depending on network.
4506 ASSERT_TRUE(PeerConnectionRemoved(key));
4507
4508 WaitForPendingTasks(&run_loop);
4509 }
4510
TEST_P(WebRtcEventLogManagerTestForNetworkConnectivity,UploadPendingLogsIfConnectedToSupportedNetworkType)4511 TEST_P(WebRtcEventLogManagerTestForNetworkConnectivity,
4512 UploadPendingLogsIfConnectedToSupportedNetworkType) {
4513 SetUpNetworkConnection(get_conn_type_is_sync_, supported_type_);
4514
4515 const auto key = GetPeerConnectionKey(rph_.get(), 1);
4516 base::Optional<base::FilePath> log_file;
4517 ON_CALL(remote_observer_, OnRemoteLogStarted(key, _, _))
4518 .WillByDefault(Invoke(SaveFilePathTo(&log_file)));
4519 ASSERT_TRUE(PeerConnectionAdded(key));
4520 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
4521 ASSERT_TRUE(StartRemoteLogging(key));
4522 ASSERT_TRUE(log_file);
4523
4524 base::RunLoop run_loop;
4525 std::list<WebRtcLogFileInfo> expected_files = {WebRtcLogFileInfo(
4526 browser_context_id_, *log_file, GetLastModificationTime(*log_file))};
4527 SetWebRtcEventLogUploaderFactoryForTesting(
4528 std::make_unique<FileListExpectingWebRtcEventLogUploader::Factory>(
4529 &expected_files, true, &run_loop));
4530
4531 // Peer connection removal MAY trigger upload, depending on network.
4532 ASSERT_TRUE(PeerConnectionRemoved(key));
4533
4534 WaitForPendingTasks(&run_loop);
4535 }
4536
TEST_P(WebRtcEventLogManagerTestForNetworkConnectivity,UploadPendingLogsIfConnectionTypeChangesFromUnsupportedToSupported)4537 TEST_P(WebRtcEventLogManagerTestForNetworkConnectivity,
4538 UploadPendingLogsIfConnectionTypeChangesFromUnsupportedToSupported) {
4539 SetUpNetworkConnection(get_conn_type_is_sync_, unsupported_type_);
4540
4541 const auto key = GetPeerConnectionKey(rph_.get(), 1);
4542 base::Optional<base::FilePath> log_file;
4543 ON_CALL(remote_observer_, OnRemoteLogStarted(key, _, _))
4544 .WillByDefault(Invoke(SaveFilePathTo(&log_file)));
4545 ASSERT_TRUE(PeerConnectionAdded(key));
4546 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
4547 ASSERT_TRUE(StartRemoteLogging(key));
4548 ASSERT_TRUE(log_file);
4549
4550 // That a peer connection upload is not initiated by this point, is verified
4551 // by previous tests.
4552 ASSERT_TRUE(PeerConnectionRemoved(key));
4553 WaitForPendingTasks();
4554
4555 // Test focus - an upload will be initiated after changing the network type.
4556 base::RunLoop run_loop;
4557 std::list<WebRtcLogFileInfo> expected_files = {WebRtcLogFileInfo(
4558 browser_context_id_, *log_file, GetLastModificationTime(*log_file))};
4559 SetWebRtcEventLogUploaderFactoryForTesting(
4560 std::make_unique<FileListExpectingWebRtcEventLogUploader::Factory>(
4561 &expected_files, true, &run_loop));
4562 SetConnectionType(supported_type_);
4563
4564 WaitForPendingTasks(&run_loop);
4565 }
4566
TEST_P(WebRtcEventLogManagerTestForNetworkConnectivity,DoNotUploadPendingLogsAtStartupIfConnectedToUnsupportedNetworkType)4567 TEST_P(WebRtcEventLogManagerTestForNetworkConnectivity,
4568 DoNotUploadPendingLogsAtStartupIfConnectedToUnsupportedNetworkType) {
4569 SetUpNetworkConnection(get_conn_type_is_sync_, unsupported_type_);
4570
4571 UnloadProfileAndSeedPendingLog();
4572
4573 // This factory enforces the expectation that the files will be uploaded,
4574 // all of them, only them, and in the order expected.
4575 std::list<WebRtcLogFileInfo> empty_expected_files_list;
4576 base::RunLoop run_loop;
4577 SetWebRtcEventLogUploaderFactoryForTesting(
4578 std::make_unique<FileListExpectingWebRtcEventLogUploader::Factory>(
4579 &empty_expected_files_list, true, &run_loop));
4580
4581 LoadMainTestProfile();
4582 ASSERT_EQ(browser_context_->GetPath(), browser_context_path_);
4583
4584 WaitForPendingTasks(&run_loop);
4585 }
4586
TEST_P(WebRtcEventLogManagerTestForNetworkConnectivity,UploadPendingLogsAtStartupIfConnectedToSupportedNetworkType)4587 TEST_P(WebRtcEventLogManagerTestForNetworkConnectivity,
4588 UploadPendingLogsAtStartupIfConnectedToSupportedNetworkType) {
4589 SetUpNetworkConnection(get_conn_type_is_sync_, supported_type_);
4590
4591 UnloadProfileAndSeedPendingLog();
4592
4593 // This factory enforces the expectation that the files will be uploaded,
4594 // all of them, only them, and in the order expected.
4595 base::RunLoop run_loop;
4596 SetWebRtcEventLogUploaderFactoryForTesting(
4597 std::make_unique<FileListExpectingWebRtcEventLogUploader::Factory>(
4598 &expected_files_, true, &run_loop));
4599
4600 LoadMainTestProfile();
4601 ASSERT_EQ(browser_context_->GetPath(), browser_context_path_);
4602
4603 WaitForPendingTasks(&run_loop);
4604 }
4605
4606 INSTANTIATE_TEST_SUITE_P(
4607 UploadSupportingConnectionTypes,
4608 WebRtcEventLogManagerTestForNetworkConnectivity,
4609 ::testing::Combine(
4610 // Wehther GetConnectionType() responds synchronously.
4611 ::testing::Bool(),
4612 // The upload-supporting network type to be used.
4613 ::testing::Values(network::mojom::ConnectionType::CONNECTION_ETHERNET,
4614 network::mojom::ConnectionType::CONNECTION_WIFI,
4615 network::mojom::ConnectionType::CONNECTION_UNKNOWN),
4616 // The upload-unsupporting network type to be used.
4617 ::testing::Values(network::mojom::ConnectionType::CONNECTION_NONE,
4618 network::mojom::ConnectionType::CONNECTION_4G)));
4619
TEST_F(WebRtcEventLogManagerTestUploadDelay,DoNotInitiateUploadBeforeDelay)4620 TEST_F(WebRtcEventLogManagerTestUploadDelay, DoNotInitiateUploadBeforeDelay) {
4621 SetUp(kIntentionallyExcessiveDelayMs);
4622
4623 const auto key = GetPeerConnectionKey(rph_.get(), 1);
4624 ASSERT_TRUE(PeerConnectionAdded(key));
4625 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
4626 ASSERT_TRUE(StartRemoteLogging(key));
4627
4628 std::list<WebRtcLogFileInfo> empty_list;
4629 base::RunLoop run_loop;
4630 SetWebRtcEventLogUploaderFactoryForTesting(
4631 std::make_unique<FileListExpectingWebRtcEventLogUploader::Factory>(
4632 &empty_list, true, &run_loop));
4633
4634 // Change log file from ACTIVE to PENDING.
4635 ASSERT_TRUE(PeerConnectionRemoved(key));
4636
4637 // Wait a bit and see that the upload was not initiated. (Due to technical
4638 // constraints, we cannot wait forever.)
4639 base::WaitableEvent event(base::WaitableEvent::ResetPolicy::MANUAL,
4640 base::WaitableEvent::InitialState::NOT_SIGNALED);
4641 event.TimedWait(base::TimeDelta::FromMilliseconds(500));
4642
4643 WaitForPendingTasks(&run_loop);
4644 }
4645
4646 // WhenPeerConnectionRemovedFinishedRemoteLogUploadedAndFileDeleted has some
4647 // overlap with this, but we still include this test for explicitness and
4648 // clarity.
TEST_F(WebRtcEventLogManagerTestUploadDelay,InitiateUploadAfterDelay)4649 TEST_F(WebRtcEventLogManagerTestUploadDelay, InitiateUploadAfterDelay) {
4650 SetUp(kDefaultUploadDelayMs);
4651
4652 const auto key = GetPeerConnectionKey(rph_.get(), 1);
4653 base::Optional<base::FilePath> log_file;
4654 ON_CALL(remote_observer_, OnRemoteLogStarted(key, _, _))
4655 .WillByDefault(Invoke(SaveFilePathTo(&log_file)));
4656 ASSERT_TRUE(PeerConnectionAdded(key));
4657 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
4658 ASSERT_TRUE(StartRemoteLogging(key));
4659 ASSERT_TRUE(log_file);
4660
4661 base::RunLoop run_loop;
4662 std::list<WebRtcLogFileInfo> expected_files = {WebRtcLogFileInfo(
4663 browser_context_id_, *log_file, GetLastModificationTime(*log_file))};
4664 SetWebRtcEventLogUploaderFactoryForTesting(
4665 std::make_unique<FileListExpectingWebRtcEventLogUploader::Factory>(
4666 &expected_files, true, &run_loop));
4667
4668 // Change log file from ACTIVE to PENDING.
4669 ASSERT_TRUE(PeerConnectionRemoved(key));
4670
4671 WaitForPendingTasks(&run_loop);
4672 }
4673
TEST_F(WebRtcEventLogManagerTestUploadDelay,PeerConnectionAddedDuringDelaySuppressesUpload)4674 TEST_F(WebRtcEventLogManagerTestUploadDelay,
4675 PeerConnectionAddedDuringDelaySuppressesUpload) {
4676 SetUp(kIntentionallyExcessiveDelayMs);
4677
4678 const auto key1 = GetPeerConnectionKey(rph_.get(), 1);
4679 const auto key2 = GetPeerConnectionKey(rph_.get(), 2);
4680
4681 ASSERT_TRUE(PeerConnectionAdded(key1));
4682 ASSERT_TRUE(PeerConnectionSessionIdSet(key1));
4683 ASSERT_TRUE(StartRemoteLogging(key1));
4684
4685 std::list<WebRtcLogFileInfo> empty_list;
4686 base::RunLoop run_loop;
4687 SetWebRtcEventLogUploaderFactoryForTesting(
4688 std::make_unique<FileListExpectingWebRtcEventLogUploader::Factory>(
4689 &empty_list, true, &run_loop));
4690
4691 // Change log file from ACTIVE to PENDING.
4692 ASSERT_TRUE(PeerConnectionRemoved(key1));
4693
4694 // Test focus - after adding a peer connection, the conditions for the upload
4695 // are no longer considered to hold.
4696 // (Test implemented with a glimpse into the black box due to technical
4697 // limitations and the desire to avoid flakiness.)
4698 ASSERT_TRUE(PeerConnectionAdded(key2));
4699 ASSERT_TRUE(PeerConnectionSessionIdSet(key2));
4700 EXPECT_FALSE(UploadConditionsHold());
4701
4702 WaitForPendingTasks(&run_loop);
4703 }
4704
TEST_F(WebRtcEventLogManagerTestUploadDelay,ClearCacheForBrowserContextDuringDelayCancelsItsUpload)4705 TEST_F(WebRtcEventLogManagerTestUploadDelay,
4706 ClearCacheForBrowserContextDuringDelayCancelsItsUpload) {
4707 SetUp(kIntentionallyExcessiveDelayMs);
4708
4709 const auto key = GetPeerConnectionKey(rph_.get(), 1);
4710
4711 ASSERT_TRUE(PeerConnectionAdded(key));
4712 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
4713 ASSERT_TRUE(StartRemoteLogging(key));
4714
4715 std::list<WebRtcLogFileInfo> empty_list;
4716 base::RunLoop run_loop;
4717 SetWebRtcEventLogUploaderFactoryForTesting(
4718 std::make_unique<FileListExpectingWebRtcEventLogUploader::Factory>(
4719 &empty_list, true, &run_loop));
4720
4721 // Change log file from ACTIVE to PENDING.
4722 ASSERT_TRUE(PeerConnectionRemoved(key));
4723
4724 // Test focus - after clearing browser cache, the conditions for the upload
4725 // are no longer considered to hold, because the file about to be uploaded
4726 // was deleted.
4727 // (Test implemented with a glimpse into the black box due to technical
4728 // limitations and the desire to avoid flakiness.)
4729 ClearCacheForBrowserContext(browser_context_.get(), base::Time::Min(),
4730 base::Time::Max());
4731 EXPECT_FALSE(UploadConditionsHold());
4732
4733 WaitForPendingTasks(&run_loop);
4734 }
4735
TEST_F(WebRtcEventLogManagerTestCompression,ErroredFilesDueToBadEstimationDeletedRatherThanUploaded)4736 TEST_F(WebRtcEventLogManagerTestCompression,
4737 ErroredFilesDueToBadEstimationDeletedRatherThanUploaded) {
4738 Init(Compression::GZIP_NULL_ESTIMATION);
4739
4740 const std::string log = "It's better than bad; it's good.";
4741
4742 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
4743 base::Optional<base::FilePath> log_file;
4744 ON_CALL(remote_observer_, OnRemoteLogStarted(key, _, _))
4745 .WillByDefault(Invoke(SaveFilePathTo(&log_file)));
4746 ASSERT_TRUE(PeerConnectionAdded(key));
4747 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
4748 ASSERT_TRUE(StartRemoteLogging(key, GetUniqueId(key), GzippedSize(log) - 1, 0,
4749 kWebAppId));
4750 ASSERT_TRUE(log_file);
4751
4752 std::list<WebRtcLogFileInfo> empty_list;
4753 base::RunLoop run_loop;
4754 SetWebRtcEventLogUploaderFactoryForTesting(
4755 std::make_unique<FileListExpectingWebRtcEventLogUploader::Factory>(
4756 &empty_list, true, &run_loop));
4757
4758 // Writing fails because the budget is exceeded.
4759 EXPECT_EQ(OnWebRtcEventLogWrite(key, log), std::make_pair(false, false));
4760
4761 // The file was deleted due to the error we've instigated (by using an
4762 // intentionally over-optimistic estimation).
4763 EXPECT_FALSE(base::PathExists(*log_file));
4764
4765 // If the file is incorrectly still eligible for an upload, this will trigger
4766 // the upload (which will be a test failure).
4767 ASSERT_TRUE(PeerConnectionRemoved(key));
4768
4769 WaitForPendingTasks(&run_loop);
4770 }
4771
TEST_F(WebRtcEventLogManagerTestIncognito,NoRemoteBoundLogsDirectoryCreatedWhenProfileLoaded)4772 TEST_F(WebRtcEventLogManagerTestIncognito,
4773 NoRemoteBoundLogsDirectoryCreatedWhenProfileLoaded) {
4774 const base::FilePath remote_logs_path =
4775 RemoteBoundLogsDir(incognito_profile_);
4776 EXPECT_FALSE(base::DirectoryExists(remote_logs_path));
4777 }
4778
TEST_F(WebRtcEventLogManagerTestIncognito,StartRemoteLoggingFails)4779 TEST_F(WebRtcEventLogManagerTestIncognito, StartRemoteLoggingFails) {
4780 const auto key = GetPeerConnectionKey(incognito_rph_.get(), kLid);
4781 ASSERT_TRUE(PeerConnectionAdded(key));
4782 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
4783 EXPECT_FALSE(StartRemoteLogging(key));
4784 }
4785
TEST_F(WebRtcEventLogManagerTestIncognito,StartRemoteLoggingDoesNotCreateDirectoryOrFiles)4786 TEST_F(WebRtcEventLogManagerTestIncognito,
4787 StartRemoteLoggingDoesNotCreateDirectoryOrFiles) {
4788 const auto key = GetPeerConnectionKey(incognito_rph_.get(), kLid);
4789 ASSERT_TRUE(PeerConnectionAdded(key));
4790 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
4791 ASSERT_FALSE(StartRemoteLogging(key));
4792
4793 const base::FilePath remote_logs_path =
4794 RemoteBoundLogsDir(incognito_profile_);
4795 EXPECT_FALSE(base::DirectoryExists(remote_logs_path));
4796 }
4797
TEST_F(WebRtcEventLogManagerTestIncognito,OnWebRtcEventLogWriteReturnsFalseForRemotePart)4798 TEST_F(WebRtcEventLogManagerTestIncognito,
4799 OnWebRtcEventLogWriteReturnsFalseForRemotePart) {
4800 const auto key = GetPeerConnectionKey(incognito_rph_.get(), kLid);
4801 ASSERT_TRUE(PeerConnectionAdded(key));
4802 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
4803 ASSERT_FALSE(StartRemoteLogging(key));
4804 EXPECT_EQ(OnWebRtcEventLogWrite(key, "log"), std::make_pair(false, false));
4805 }
4806
TEST_F(WebRtcEventLogManagerTestHistory,CorrectHistoryReturnedForActivelyWrittenLog)4807 TEST_F(WebRtcEventLogManagerTestHistory,
4808 CorrectHistoryReturnedForActivelyWrittenLog) {
4809 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
4810 ASSERT_TRUE(PeerConnectionAdded(key));
4811 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
4812
4813 base::Optional<base::FilePath> path;
4814 EXPECT_CALL(remote_observer_, OnRemoteLogStarted(key, _, _))
4815 .Times(1)
4816 .WillOnce(Invoke(SaveFilePathTo(&path)));
4817 ASSERT_TRUE(StartRemoteLogging(key));
4818 ASSERT_TRUE(path);
4819 ASSERT_FALSE(path->BaseName().MaybeAsASCII().empty());
4820
4821 const auto history = GetHistory(browser_context_id_);
4822 ASSERT_EQ(history.size(), 1u);
4823 const auto history_entry = history[0];
4824
4825 EXPECT_EQ(history_entry.state, UploadList::UploadInfo::State::Pending);
4826 EXPECT_TRUE(IsSmallTimeDelta(history_entry.capture_time, base::Time::Now()));
4827 EXPECT_EQ(history_entry.local_id, path->BaseName().MaybeAsASCII());
4828 EXPECT_TRUE(history_entry.upload_id.empty());
4829 EXPECT_TRUE(history_entry.upload_time.is_null());
4830 }
4831
TEST_F(WebRtcEventLogManagerTestHistory,CorrectHistoryReturnedForPendingLog)4832 TEST_F(WebRtcEventLogManagerTestHistory, CorrectHistoryReturnedForPendingLog) {
4833 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
4834 ASSERT_TRUE(PeerConnectionAdded(key));
4835 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
4836
4837 base::Optional<base::FilePath> path;
4838 EXPECT_CALL(remote_observer_, OnRemoteLogStarted(key, _, _))
4839 .Times(1)
4840 .WillOnce(Invoke(SaveFilePathTo(&path)));
4841 ASSERT_TRUE(StartRemoteLogging(key));
4842 ASSERT_TRUE(path);
4843 ASSERT_FALSE(path->BaseName().MaybeAsASCII().empty());
4844
4845 SuppressUploading();
4846 ASSERT_TRUE(PeerConnectionRemoved(key));
4847
4848 const auto history = GetHistory(browser_context_id_);
4849 ASSERT_EQ(history.size(), 1u);
4850 const auto history_entry = history[0];
4851
4852 EXPECT_EQ(history_entry.state, UploadList::UploadInfo::State::Pending);
4853 EXPECT_TRUE(IsSmallTimeDelta(history_entry.capture_time, base::Time::Now()));
4854 EXPECT_EQ(history_entry.local_id, path->BaseName().MaybeAsASCII());
4855 EXPECT_TRUE(history_entry.upload_id.empty());
4856 EXPECT_TRUE(history_entry.upload_time.is_null());
4857 }
4858
TEST_F(WebRtcEventLogManagerTestHistory,CorrectHistoryReturnedForActivelyUploadedLog)4859 TEST_F(WebRtcEventLogManagerTestHistory,
4860 CorrectHistoryReturnedForActivelyUploadedLog) {
4861 // This factory expects exactly one log to be uploaded; cancellation is
4862 // expected during tear-down.
4863 SetWebRtcEventLogUploaderFactoryForTesting(
4864 std::make_unique<NullWebRtcEventLogUploader::Factory>(true, 1));
4865
4866 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
4867 ASSERT_TRUE(PeerConnectionAdded(key));
4868 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
4869
4870 base::Optional<base::FilePath> path;
4871 EXPECT_CALL(remote_observer_, OnRemoteLogStarted(key, _, _))
4872 .Times(1)
4873 .WillOnce(Invoke(SaveFilePathTo(&path)));
4874 ASSERT_TRUE(StartRemoteLogging(key));
4875 ASSERT_TRUE(path);
4876 ASSERT_FALSE(path->BaseName().MaybeAsASCII().empty());
4877
4878 ASSERT_TRUE(PeerConnectionRemoved(key));
4879
4880 const auto history = GetHistory(browser_context_id_);
4881 ASSERT_EQ(history.size(), 1u);
4882 const auto history_entry = history[0];
4883
4884 EXPECT_EQ(history_entry.state, UploadList::UploadInfo::State::Pending);
4885 EXPECT_TRUE(IsSmallTimeDelta(history_entry.capture_time, base::Time::Now()));
4886 EXPECT_EQ(history_entry.local_id, path->BaseName().MaybeAsASCII());
4887 EXPECT_TRUE(history_entry.upload_id.empty());
4888 EXPECT_TRUE(IsSmallTimeDelta(history_entry.upload_time, base::Time::Now()));
4889 EXPECT_LE(history_entry.capture_time, history_entry.upload_time);
4890
4891 // Test tear down - trigger uploader cancellation.
4892 ClearCacheForBrowserContext(browser_context_.get(), base::Time::Min(),
4893 base::Time::Max());
4894 }
4895
4896 // See ExpiredLogFilesAreReplacedByHistoryFiles for verification of the
4897 // creation of history files of this type.
TEST_F(WebRtcEventLogManagerTestHistory,ExpiredLogFilesReplacedByHistoryFilesAndGetHistoryReportsAccordingly)4898 TEST_F(WebRtcEventLogManagerTestHistory,
4899 ExpiredLogFilesReplacedByHistoryFilesAndGetHistoryReportsAccordingly) {
4900 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
4901 ASSERT_TRUE(PeerConnectionAdded(key));
4902 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
4903
4904 base::Optional<base::FilePath> log_path;
4905 EXPECT_CALL(remote_observer_, OnRemoteLogStarted(key, _, _))
4906 .Times(1)
4907 .WillOnce(Invoke(SaveFilePathTo(&log_path)));
4908 ASSERT_TRUE(StartRemoteLogging(key));
4909 ASSERT_TRUE(log_path);
4910 ASSERT_FALSE(log_path->BaseName().MaybeAsASCII().empty());
4911
4912 SuppressUploading();
4913 ASSERT_TRUE(PeerConnectionRemoved(key));
4914
4915 UnloadMainTestProfile();
4916
4917 // Test sanity.
4918 ASSERT_TRUE(base::PathExists(*log_path));
4919
4920 // Pretend more time than kRemoteBoundWebRtcEventLogsMaxRetention has passed.
4921 const base::TimeDelta elapsed_time =
4922 kRemoteBoundWebRtcEventLogsMaxRetention + base::TimeDelta::FromHours(1);
4923 base::File::Info file_info;
4924 ASSERT_TRUE(base::GetFileInfo(*log_path, &file_info));
4925
4926 const auto modified_capture_time = file_info.last_modified - elapsed_time;
4927 ASSERT_TRUE(base::TouchFile(*log_path, file_info.last_accessed - elapsed_time,
4928 modified_capture_time));
4929
4930 LoadMainTestProfile();
4931
4932 ASSERT_FALSE(base::PathExists(*log_path));
4933
4934 const auto history = GetHistory(browser_context_id_);
4935 ASSERT_EQ(history.size(), 1u);
4936 const auto history_entry = history[0];
4937
4938 EXPECT_EQ(history_entry.state, UploadList::UploadInfo::State::NotUploaded);
4939 EXPECT_TRUE(IsSameTimeWhenTruncatedToSeconds(history_entry.capture_time,
4940 modified_capture_time));
4941 EXPECT_EQ(history_entry.local_id,
4942 ExtractRemoteBoundWebRtcEventLogLocalIdFromPath(*log_path));
4943 EXPECT_TRUE(history_entry.upload_id.empty());
4944 EXPECT_TRUE(history_entry.upload_time.is_null());
4945 }
4946
4947 // Since the uploader mocks do not write the history files, it is not easy
4948 // to check that the correct result is returned for GetHistory() for either
4949 // a successful or an unsuccessful upload from the WebRtcEventLogManager level.
4950 // Instead, this is checked by WebRtcEventLogUploaderImplTest.
4951 // TODO(crbug.com/775415): Add the tests mention in the comment above.
4952
TEST_F(WebRtcEventLogManagerTestHistory,ClearingCacheRemovesHistoryFiles)4953 TEST_F(WebRtcEventLogManagerTestHistory, ClearingCacheRemovesHistoryFiles) {
4954 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
4955 ASSERT_TRUE(PeerConnectionAdded(key));
4956 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
4957
4958 base::Optional<base::FilePath> log_path;
4959 EXPECT_CALL(remote_observer_, OnRemoteLogStarted(key, _, _))
4960 .Times(1)
4961 .WillOnce(Invoke(SaveFilePathTo(&log_path)));
4962 ASSERT_TRUE(StartRemoteLogging(key));
4963 ASSERT_TRUE(log_path);
4964 ASSERT_FALSE(log_path->BaseName().MaybeAsASCII().empty());
4965
4966 SuppressUploading();
4967 ASSERT_TRUE(PeerConnectionRemoved(key));
4968
4969 UnloadMainTestProfile();
4970
4971 // Test sanity.
4972 ASSERT_TRUE(base::PathExists(*log_path));
4973
4974 // Pretend more time than kRemoteBoundWebRtcEventLogsMaxRetention has passed.
4975 const base::TimeDelta elapsed_time =
4976 kRemoteBoundWebRtcEventLogsMaxRetention + base::TimeDelta::FromHours(1);
4977 base::File::Info file_info;
4978 ASSERT_TRUE(base::GetFileInfo(*log_path, &file_info));
4979
4980 const auto modified_capture_time = file_info.last_modified - elapsed_time;
4981 ASSERT_TRUE(base::TouchFile(*log_path, file_info.last_accessed - elapsed_time,
4982 modified_capture_time));
4983
4984 LoadMainTestProfile();
4985
4986 ASSERT_FALSE(base::PathExists(*log_path));
4987
4988 // Setup complete; we now have a history file on disk. Time to see that it is
4989 // removed when cache is cleared.
4990
4991 // Sanity.
4992 const auto history_path = GetWebRtcEventLogHistoryFilePath(*log_path);
4993 ASSERT_TRUE(base::PathExists(history_path));
4994 ASSERT_EQ(GetHistory(browser_context_id_).size(), 1u);
4995
4996 // Test.
4997 ClearCacheForBrowserContext(browser_context_.get(), base::Time::Min(),
4998 base::Time::Max());
4999 ASSERT_FALSE(base::PathExists(history_path));
5000 ASSERT_EQ(GetHistory(browser_context_id_).size(), 0u);
5001 }
5002
TEST_F(WebRtcEventLogManagerTestHistory,ClearingCacheDoesNotLeaveBehindHistoryForRemovedLogs)5003 TEST_F(WebRtcEventLogManagerTestHistory,
5004 ClearingCacheDoesNotLeaveBehindHistoryForRemovedLogs) {
5005 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
5006 ASSERT_TRUE(PeerConnectionAdded(key));
5007 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
5008
5009 base::Optional<base::FilePath> log_path;
5010 EXPECT_CALL(remote_observer_, OnRemoteLogStarted(key, _, _))
5011 .Times(1)
5012 .WillOnce(Invoke(SaveFilePathTo(&log_path)));
5013 ASSERT_TRUE(StartRemoteLogging(key));
5014 ASSERT_TRUE(log_path);
5015 ASSERT_FALSE(log_path->BaseName().MaybeAsASCII().empty());
5016
5017 ASSERT_TRUE(base::PathExists(*log_path));
5018 ClearCacheForBrowserContext(browser_context_.get(), base::Time::Min(),
5019 base::Time::Max());
5020 ASSERT_FALSE(base::PathExists(*log_path));
5021
5022 const auto history = GetHistory(browser_context_id_);
5023 EXPECT_EQ(history.size(), 0u);
5024 }
5025
5026 // TODO(crbug.com/775415): Add a test for the limit on the number of history
5027 // files allowed to remain on disk.
5028
5029 #else // defined(OS_ANDROID)
5030
5031 class WebRtcEventLogManagerTestOnMobileDevices
5032 : public WebRtcEventLogManagerTestBase {
5033 public:
WebRtcEventLogManagerTestOnMobileDevices()5034 WebRtcEventLogManagerTestOnMobileDevices() {
5035 // features::kWebRtcRemoteEventLog not defined on mobile, and can therefore
5036 // not be forced on. This test is here to make sure that when the feature
5037 // is changed to be on by default, it will still be off for mobile devices.
5038 CreateWebRtcEventLogManager();
5039 }
5040 };
5041
TEST_F(WebRtcEventLogManagerTestOnMobileDevices,RemoteBoundLoggingDisabled)5042 TEST_F(WebRtcEventLogManagerTestOnMobileDevices, RemoteBoundLoggingDisabled) {
5043 const auto key = GetPeerConnectionKey(rph_.get(), kLid);
5044 ASSERT_TRUE(PeerConnectionAdded(key));
5045 ASSERT_TRUE(PeerConnectionSessionIdSet(key));
5046 EXPECT_FALSE(StartRemoteLogging(key));
5047 }
5048
5049 #endif
5050
5051 } // namespace webrtc_event_logging
5052