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