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