Commit 022ed8ae authored by Elad Alon's avatar Elad Alon Committed by Commit Bot

RenderProcessHost exiting is an implicit PeerConnection removal

When a RenderProcessHost exits clearly or crashes, all of its
PeerConnections should be considered as removed.

Bug: 775415, 805398, 808402
Change-Id: I223e6e867758ef05d896608fbdcc3bc824238dd8
Reviewed-on: https://chromium-review.googlesource.com/899348
Commit-Queue: Elad Alon <eladalon@chromium.org>
Reviewed-by: default avatarGuido Urdaneta <guidou@chromium.org>
Cr-Commit-Position: refs/heads/master@{#534840}
parent 4982f7ba
......@@ -96,6 +96,11 @@ WebRtcEventLogManager::WebRtcEventLogManager()
WebRtcEventLogManager::~WebRtcEventLogManager() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
for (RenderProcessHost* host : observed_render_process_hosts_) {
host->RemoveObserver(this);
}
DCHECK(g_webrtc_event_log_manager);
g_webrtc_event_log_manager = nullptr;
}
......@@ -105,6 +110,7 @@ void WebRtcEventLogManager::EnableForBrowserContext(
base::OnceClosure reply) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
CHECK(!browser_context->IsOffTheRecord());
// Posting to task queue owned by the unretained object - unretained is safe.
task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&WebRtcEventLogManager::EnableForBrowserContextInternal,
......@@ -117,6 +123,7 @@ void WebRtcEventLogManager::DisableForBrowserContext(
BrowserContextId browser_context_id,
base::OnceClosure reply) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
// Posting to task queue owned by the unretained object - unretained is safe.
task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&WebRtcEventLogManager::DisableForBrowserContextInternal,
......@@ -129,6 +136,17 @@ void WebRtcEventLogManager::PeerConnectionAdded(
int lid,
base::OnceCallback<void(bool)> reply) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
RenderProcessHost* host = RenderProcessHost::FromID(render_process_id);
auto it = observed_render_process_hosts_.find(host);
if (it == observed_render_process_hosts_.end()) {
// This is the first PeerConnection which we see that's associated
// with this RPH.
host->AddObserver(this);
observed_render_process_hosts_.insert(host);
}
// Posting to task queue owned by the unretained object - unretained is safe.
task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&WebRtcEventLogManager::PeerConnectionAddedInternal,
......@@ -156,6 +174,7 @@ void WebRtcEventLogManager::PeerConnectionRemoved(
}
const BrowserContext* browser_context = host->GetBrowserContext();
// Posting to task queue owned by the unretained object - unretained is safe.
task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&WebRtcEventLogManager::PeerConnectionRemovedInternal,
......@@ -169,6 +188,7 @@ void WebRtcEventLogManager::EnableLocalLogging(
base::OnceCallback<void(bool)> reply) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK(!base_path.empty());
// Posting to task queue owned by the unretained object - unretained is safe.
task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&WebRtcEventLogManager::EnableLocalLoggingInternal,
......@@ -179,6 +199,7 @@ void WebRtcEventLogManager::EnableLocalLogging(
void WebRtcEventLogManager::DisableLocalLogging(
base::OnceCallback<void(bool)> reply) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
// Posting to task queue owned by the unretained object - unretained is safe.
task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&WebRtcEventLogManager::DisableLocalLoggingInternal,
......@@ -198,6 +219,7 @@ void WebRtcEventLogManager::StartRemoteLogging(
browser_context_id = GetBrowserContextId(browser_context);
}
// Posting to task queue owned by the unretained object - unretained is safe.
task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&WebRtcEventLogManager::StartRemoteLoggingInternal,
......@@ -213,6 +235,7 @@ void WebRtcEventLogManager::OnWebRtcEventLogWrite(
base::OnceCallback<void(std::pair<bool, bool>)> reply) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
const BrowserContext* browser_context = GetBrowserContext(render_process_id);
// Posting to task queue owned by the unretained object - unretained is safe.
task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&WebRtcEventLogManager::OnWebRtcEventLogWriteInternal,
......@@ -225,6 +248,7 @@ void WebRtcEventLogManager::SetLocalLogsObserver(
WebRtcLocalEventLogsObserver* observer,
base::OnceClosure reply) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
// Posting to task queue owned by the unretained object - unretained is safe.
task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&WebRtcEventLogManager::SetLocalLogsObserverInternal,
......@@ -235,6 +259,7 @@ void WebRtcEventLogManager::SetRemoteLogsObserver(
WebRtcRemoteEventLogsObserver* observer,
base::OnceClosure reply) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
// Posting to task queue owned by the unretained object - unretained is safe.
task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&WebRtcEventLogManager::SetRemoteLogsObserverInternal,
......@@ -253,6 +278,38 @@ WebRtcEventLogManager::GetTaskRunnerForTesting() {
return task_runner_;
}
void WebRtcEventLogManager::RenderProcessExited(RenderProcessHost* host,
base::TerminationStatus status,
int exit_code) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
RenderProcessHostExitedDestroyed(host);
}
void WebRtcEventLogManager::RenderProcessHostDestroyed(
RenderProcessHost* host) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
RenderProcessHostExitedDestroyed(host);
}
void WebRtcEventLogManager::RenderProcessHostExitedDestroyed(
RenderProcessHost* host) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK(host);
auto it = observed_render_process_hosts_.find(host);
if (it == observed_render_process_hosts_.end()) {
return; // We've never seen PeerConnections associated with this RPH.
}
host->RemoveObserver(this);
observed_render_process_hosts_.erase(host);
// Posting to task queue owned by the unretained object - unretained is safe.
task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&WebRtcEventLogManager::RenderProcessExitedInternal,
base::Unretained(this), host->GetID()));
}
void WebRtcEventLogManager::OnLocalLogStarted(PeerConnectionKey peer_connection,
const base::FilePath& file_path) {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
......@@ -450,6 +507,12 @@ void WebRtcEventLogManager::OnWebRtcEventLogWriteInternal(
}
}
void WebRtcEventLogManager::RenderProcessExitedInternal(int render_process_id) {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
local_logs_manager_.RenderProcessHostExitedDestroyed(render_process_id);
remote_logs_manager_.RenderProcessHostExitedDestroyed(render_process_id);
}
void WebRtcEventLogManager::SetLocalLogsObserverInternal(
WebRtcLocalEventLogsObserver* observer,
base::OnceClosure reply) {
......
......@@ -11,6 +11,7 @@
#include <utility>
#include "base/callback.h"
#include "base/containers/flat_set.h"
#include "base/files/file_path.h"
#include "base/memory/scoped_refptr.h"
#include "base/optional.h"
......@@ -20,6 +21,7 @@
#include "content/browser/webrtc/webrtc_local_event_log_manager.h"
#include "content/browser/webrtc/webrtc_remote_event_log_manager.h"
#include "content/common/content_export.h"
#include "content/public/browser/render_process_host_observer.h"
namespace content {
......@@ -32,7 +34,8 @@ class BrowserContext;
// user from the WebRTCIntenals. (A log may simulatenously be written to both,
// either, or none.)
class CONTENT_EXPORT WebRtcEventLogManager
: public WebRtcLocalEventLogsObserver,
: public RenderProcessHostObserver,
public WebRtcLocalEventLogsObserver,
public WebRtcRemoteEventLogsObserver {
public:
using BrowserContextId = WebRtcRemoteEventLogManager::BrowserContextId;
......@@ -209,6 +212,16 @@ class CONTENT_EXPORT WebRtcEventLogManager
static WebRtcEventLogManager* g_webrtc_event_log_manager;
// RenderProcessHostObserver implementation.
void RenderProcessExited(RenderProcessHost* host,
base::TerminationStatus status,
int exit_code) override;
void RenderProcessHostDestroyed(RenderProcessHost* host) override;
// RenderProcessExited() and RenderProcessHostDestroyed() treated similarly
// by this function.
void RenderProcessHostExitedDestroyed(RenderProcessHost* host);
// WebRtcLocalEventLogsObserver implementation:
void OnLocalLogStarted(PeerConnectionKey peer_connection,
const base::FilePath& file_path) override;
......@@ -257,6 +270,8 @@ class CONTENT_EXPORT WebRtcEventLogManager
const std::string& message,
base::OnceCallback<void(std::pair<bool, bool>)> reply);
void RenderProcessExitedInternal(int render_process_id);
void SetLocalLogsObserverInternal(WebRtcLocalEventLogsObserver* observer,
base::OnceClosure reply);
......@@ -294,6 +309,12 @@ class CONTENT_EXPORT WebRtcEventLogManager
std::map<PeerConnectionKey, LoggingTargetBitmap>
peer_connections_with_event_logging_enabled_;
// The set of RenderProcessHosts with which the manager is registered for
// observation. Allows us to register for each RPH only once, and get notified
// when it exits (cleanly or due to a crash).
// This object is only to be accessed on the UI thread.
base::flat_set<RenderProcessHost*> observed_render_process_hosts_;
// In production, this holds a small object that just tells WebRTC (via
// PeerConnectionTracker) to start/stop producing event logs for a specific
// peer connection. In (relevant) unit tests, a mock will be injected.
......
......@@ -80,6 +80,22 @@ class NullWebRtcEventLogUploader : public WebRtcEventLogUploader {
};
};
class MockWebRtcLocalEventLogsObserver : public WebRtcLocalEventLogsObserver {
public:
~MockWebRtcLocalEventLogsObserver() override = default;
MOCK_METHOD2(OnLocalLogStarted,
void(PeerConnectionKey, const base::FilePath&));
MOCK_METHOD1(OnLocalLogStopped, void(PeerConnectionKey));
};
class MockWebRtcRemoteEventLogsObserver : public WebRtcRemoteEventLogsObserver {
public:
~MockWebRtcRemoteEventLogsObserver() override = default;
MOCK_METHOD2(OnRemoteLogStarted,
void(PeerConnectionKey, const base::FilePath&));
MOCK_METHOD1(OnRemoteLogStopped, void(PeerConnectionKey));
};
} // namespace
class WebRtcEventLogManagerTest : public ::testing::TestWithParam<bool> {
......@@ -104,6 +120,9 @@ class WebRtcEventLogManagerTest : public ::testing::TestWithParam<bool> {
std::make_unique<NullWebRtcEventLogUploader::Factory>());
browser_context_ = CreateBrowserContext();
rph_ = std::make_unique<MockRenderProcessHost>(browser_context_.get());
SetLocalLogsObserver(&local_observer_);
SetRemoteLogsObserver(&remote_observer_);
}
~WebRtcEventLogManagerTest() override {
......@@ -121,7 +140,6 @@ class WebRtcEventLogManagerTest : public ::testing::TestWithParam<bool> {
}
void DestroyUnitUnderTest() {
SetLocalLogsObserver(nullptr);
manager_.reset();
}
......@@ -382,6 +400,15 @@ class WebRtcEventLogManagerTest : public ::testing::TestWithParam<bool> {
bool enabled;
};
std::queue<WebRtcStateChangeInstruction> webrtc_state_change_instructions_;
// Observers for local/remote logging being started/stopped. By having them
// here, we achieve two goals:
// 1. Reduce boilerplate in the tests themselves.
// 2. Avoid lifetime issues, where the observer might be deallocated before
// a RenderProcessHost is deallocated (which can potentially trigger a
// callback on the observer).
NiceMock<MockWebRtcLocalEventLogsObserver> local_observer_;
NiceMock<MockWebRtcRemoteEventLogsObserver> remote_observer_;
};
namespace {
......@@ -389,30 +416,6 @@ namespace {
// Common default/arbitrary values.
static constexpr int kPeerConnectionId = 478;
class MockWebRtcLocalEventLogsObserver : public WebRtcLocalEventLogsObserver {
public:
~MockWebRtcLocalEventLogsObserver() override = default;
MOCK_METHOD2(OnLocalLogStarted,
void(PeerConnectionKey, const base::FilePath&));
MOCK_METHOD1(OnLocalLogStopped, void(PeerConnectionKey));
};
class MockWebRtcRemoteEventLogsObserver : public WebRtcRemoteEventLogsObserver {
public:
~MockWebRtcRemoteEventLogsObserver() override = default;
MOCK_METHOD2(OnRemoteLogStarted,
void(PeerConnectionKey, const base::FilePath&));
MOCK_METHOD1(OnRemoteLogStopped, void(PeerConnectionKey));
};
class MockWebRtcEventLogUploaderObserver
: public WebRtcEventLogUploaderObserver {
public:
~MockWebRtcEventLogUploaderObserver() override = default;
MOCK_METHOD2(OnWebRtcEventLogUploadComplete,
void(const base::FilePath&, bool));
};
auto SaveFilePathTo(base::Optional<base::FilePath>* output) {
return [output](PeerConnectionKey ignored_key, base::FilePath file_path) {
*output = file_path;
......@@ -642,47 +645,37 @@ TEST_F(WebRtcEventLogManagerTest,
TEST_F(WebRtcEventLogManagerTest,
OnLocalLogStartedNotCalledIfLocalLoggingEnabledWithoutPeerConnections) {
MockWebRtcLocalEventLogsObserver observer;
EXPECT_CALL(observer, OnLocalLogStarted(_, _)).Times(0);
SetLocalLogsObserver(&observer);
EXPECT_CALL(local_observer_, OnLocalLogStarted(_, _)).Times(0);
ASSERT_TRUE(EnableLocalLogging());
}
TEST_F(WebRtcEventLogManagerTest,
OnLocalLogStoppedNotCalledIfLocalLoggingDisabledWithoutPeerConnections) {
MockWebRtcLocalEventLogsObserver observer;
EXPECT_CALL(observer, OnLocalLogStopped(_)).Times(0);
SetLocalLogsObserver(&observer);
EXPECT_CALL(local_observer_, OnLocalLogStopped(_)).Times(0);
ASSERT_TRUE(EnableLocalLogging());
ASSERT_TRUE(DisableLocalLogging());
}
TEST_F(WebRtcEventLogManagerTest,
OnLocalLogStartedCalledForPeerConnectionAddedAndLocalLoggingEnabled) {
MockWebRtcLocalEventLogsObserver observer;
PeerConnectionKey peer_connection(rph_->GetID(), kPeerConnectionId);
EXPECT_CALL(observer, OnLocalLogStarted(peer_connection, _)).Times(1);
SetLocalLogsObserver(&observer);
EXPECT_CALL(local_observer_, OnLocalLogStarted(peer_connection, _)).Times(1);
ASSERT_TRUE(PeerConnectionAdded(rph_->GetID(), kPeerConnectionId));
ASSERT_TRUE(EnableLocalLogging());
}
TEST_F(WebRtcEventLogManagerTest,
OnLocalLogStartedCalledForLocalLoggingEnabledAndPeerConnectionAdded) {
MockWebRtcLocalEventLogsObserver observer;
PeerConnectionKey peer_connection(rph_->GetID(), kPeerConnectionId);
EXPECT_CALL(observer, OnLocalLogStarted(peer_connection, _)).Times(1);
SetLocalLogsObserver(&observer);
EXPECT_CALL(local_observer_, OnLocalLogStarted(peer_connection, _)).Times(1);
ASSERT_TRUE(EnableLocalLogging());
ASSERT_TRUE(PeerConnectionAdded(rph_->GetID(), kPeerConnectionId));
}
TEST_F(WebRtcEventLogManagerTest,
OnLocalLogStoppedCalledAfterLocalLoggingDisabled) {
NiceMock<MockWebRtcLocalEventLogsObserver> observer;
PeerConnectionKey peer_connection(rph_->GetID(), kPeerConnectionId);
EXPECT_CALL(observer, OnLocalLogStopped(peer_connection)).Times(1);
SetLocalLogsObserver(&observer);
EXPECT_CALL(local_observer_, OnLocalLogStopped(peer_connection)).Times(1);
ASSERT_TRUE(PeerConnectionAdded(rph_->GetID(), kPeerConnectionId));
ASSERT_TRUE(EnableLocalLogging());
ASSERT_TRUE(DisableLocalLogging());
......@@ -690,33 +683,17 @@ TEST_F(WebRtcEventLogManagerTest,
TEST_F(WebRtcEventLogManagerTest,
OnLocalLogStoppedCalledAfterPeerConnectionRemoved) {
NiceMock<MockWebRtcLocalEventLogsObserver> observer;
PeerConnectionKey peer_connection(rph_->GetID(), kPeerConnectionId);
EXPECT_CALL(observer, OnLocalLogStopped(peer_connection)).Times(1);
SetLocalLogsObserver(&observer);
EXPECT_CALL(local_observer_, OnLocalLogStopped(peer_connection)).Times(1);
ASSERT_TRUE(PeerConnectionAdded(rph_->GetID(), kPeerConnectionId));
ASSERT_TRUE(EnableLocalLogging());
ASSERT_TRUE(PeerConnectionRemoved(rph_->GetID(), kPeerConnectionId));
}
TEST_F(WebRtcEventLogManagerTest, RemovedLocalLogsObserverReceivesNoCalls) {
StrictMock<MockWebRtcLocalEventLogsObserver> observer;
EXPECT_CALL(observer, OnLocalLogStarted(_, _)).Times(0);
EXPECT_CALL(observer, OnLocalLogStopped(_)).Times(0);
SetLocalLogsObserver(&observer);
SetLocalLogsObserver(nullptr);
ASSERT_TRUE(EnableLocalLogging());
ASSERT_TRUE(PeerConnectionAdded(rph_->GetID(), kPeerConnectionId));
ASSERT_TRUE(PeerConnectionRemoved(rph_->GetID(), kPeerConnectionId));
}
TEST_F(WebRtcEventLogManagerTest, LocalLogCreatesEmptyFileWhenStarted) {
NiceMock<MockWebRtcLocalEventLogsObserver> observer;
SetLocalLogsObserver(&observer);
const PeerConnectionKey key(rph_->GetID(), kPeerConnectionId);
base::Optional<base::FilePath> file_path;
ON_CALL(observer, OnLocalLogStarted(key, _))
ON_CALL(local_observer_, OnLocalLogStarted(key, _))
.WillByDefault(Invoke(SaveFilePathTo(&file_path)));
ASSERT_TRUE(EnableLocalLogging());
......@@ -731,13 +708,10 @@ TEST_F(WebRtcEventLogManagerTest, LocalLogCreatesEmptyFileWhenStarted) {
}
TEST_F(WebRtcEventLogManagerTest, LocalLogCreateAndWriteToFile) {
NiceMock<MockWebRtcLocalEventLogsObserver> observer;
SetLocalLogsObserver(&observer);
const PeerConnectionKey key(rph_->GetID(), kPeerConnectionId);
base::Optional<base::FilePath> file_path;
ON_CALL(observer, OnLocalLogStarted(key, _))
ON_CALL(local_observer_, OnLocalLogStarted(key, _))
.WillByDefault(Invoke(SaveFilePathTo(&file_path)));
ASSERT_TRUE(EnableLocalLogging());
......@@ -756,13 +730,10 @@ TEST_F(WebRtcEventLogManagerTest, LocalLogCreateAndWriteToFile) {
}
TEST_F(WebRtcEventLogManagerTest, LocalLogMultipleWritesToSameFile) {
NiceMock<MockWebRtcLocalEventLogsObserver> observer;
SetLocalLogsObserver(&observer);
const PeerConnectionKey key(rph_->GetID(), kPeerConnectionId);
base::Optional<base::FilePath> file_path;
ON_CALL(observer, OnLocalLogStarted(key, _))
ON_CALL(local_observer_, OnLocalLogStarted(key, _))
.WillByDefault(Invoke(SaveFilePathTo(&file_path)));
ASSERT_TRUE(EnableLocalLogging());
......@@ -788,13 +759,10 @@ TEST_F(WebRtcEventLogManagerTest, LocalLogMultipleWritesToSameFile) {
}
TEST_F(WebRtcEventLogManagerTest, LocalLogFileSizeLimitNotExceeded) {
NiceMock<MockWebRtcLocalEventLogsObserver> observer;
SetLocalLogsObserver(&observer);
const PeerConnectionKey key(rph_->GetID(), kPeerConnectionId);
base::Optional<base::FilePath> file_path;
ON_CALL(observer, OnLocalLogStarted(key, _))
ON_CALL(local_observer_, OnLocalLogStarted(key, _))
.WillByDefault(Invoke(SaveFilePathTo(&file_path)));
const std::string log = "There lies the port; the vessel puffs her sail:";
......@@ -808,7 +776,7 @@ TEST_F(WebRtcEventLogManagerTest, LocalLogFileSizeLimitNotExceeded) {
// A failure is reported, because not everything could be written. The file
// will also be closed.
const auto pc = PeerConnectionKey(key.render_process_id, key.lid);
EXPECT_CALL(observer, OnLocalLogStopped(pc)).Times(1);
EXPECT_CALL(local_observer_, OnLocalLogStopped(pc)).Times(1);
ASSERT_EQ(OnWebRtcEventLogWrite(key.render_process_id, key.lid, log),
std::make_pair(false, false));
......@@ -820,13 +788,10 @@ TEST_F(WebRtcEventLogManagerTest, LocalLogFileSizeLimitNotExceeded) {
}
TEST_F(WebRtcEventLogManagerTest, LocalLogSanityOverUnlimitedFileSizes) {
NiceMock<MockWebRtcLocalEventLogsObserver> observer;
SetLocalLogsObserver(&observer);
const PeerConnectionKey key(rph_->GetID(), kPeerConnectionId);
base::Optional<base::FilePath> file_path;
ON_CALL(observer, OnLocalLogStarted(key, _))
ON_CALL(local_observer_, OnLocalLogStarted(key, _))
.WillByDefault(Invoke(SaveFilePathTo(&file_path)));
ASSERT_TRUE(EnableLocalLogging(kWebRtcEventLogManagerUnlimitedFileSize));
......@@ -848,13 +813,10 @@ TEST_F(WebRtcEventLogManagerTest, LocalLogSanityOverUnlimitedFileSizes) {
}
TEST_F(WebRtcEventLogManagerTest, LocalLogNoWriteAfterLogStopped) {
NiceMock<MockWebRtcLocalEventLogsObserver> observer;
SetLocalLogsObserver(&observer);
const PeerConnectionKey key(rph_->GetID(), kPeerConnectionId);
base::Optional<base::FilePath> file_path;
ON_CALL(observer, OnLocalLogStarted(key, _))
ON_CALL(local_observer_, OnLocalLogStarted(key, _))
.WillByDefault(Invoke(SaveFilePathTo(&file_path)));
ASSERT_TRUE(EnableLocalLogging());
......@@ -865,7 +827,7 @@ TEST_F(WebRtcEventLogManagerTest, LocalLogNoWriteAfterLogStopped) {
const std::string log_before = "log_before_stop";
ASSERT_EQ(OnWebRtcEventLogWrite(key.render_process_id, key.lid, log_before),
std::make_pair(true, false));
EXPECT_CALL(observer, OnLocalLogStopped(key)).Times(1);
EXPECT_CALL(local_observer_, OnLocalLogStopped(key)).Times(1);
ASSERT_TRUE(PeerConnectionRemoved(key.render_process_id, key.lid));
const std::string log_after = "log_after_stop";
......@@ -876,20 +838,17 @@ TEST_F(WebRtcEventLogManagerTest, LocalLogNoWriteAfterLogStopped) {
}
TEST_F(WebRtcEventLogManagerTest, LocalLogOnlyWritesTheLogsAfterStarted) {
NiceMock<MockWebRtcLocalEventLogsObserver> observer;
SetLocalLogsObserver(&observer);
const PeerConnectionKey key(rph_->GetID(), kPeerConnectionId);
// Calls to Write() before the log was started are ignored.
EXPECT_CALL(observer, OnLocalLogStarted(_, _)).Times(0);
EXPECT_CALL(local_observer_, OnLocalLogStarted(_, _)).Times(0);
const std::string log1 = "The lights begin to twinkle from the rocks:";
ASSERT_EQ(OnWebRtcEventLogWrite(key.render_process_id, key.lid, log1),
std::make_pair(false, false));
ASSERT_TRUE(base::IsDirectoryEmpty(local_logs_base_dir_));
base::Optional<base::FilePath> file_path;
EXPECT_CALL(observer, OnLocalLogStarted(key, _))
EXPECT_CALL(local_observer_, OnLocalLogStarted(key, _))
.Times(1)
.WillOnce(Invoke(SaveFilePathTo(&file_path)));
......@@ -913,9 +872,6 @@ TEST_F(WebRtcEventLogManagerTest, LocalLogOnlyWritesTheLogsAfterStarted) {
// Note: This test also covers the scenario LocalLogExistingFilesNotOverwritten,
// which is therefore not explicitly tested.
TEST_F(WebRtcEventLogManagerTest, LocalLoggingRestartCreatesNewFile) {
NiceMock<MockWebRtcLocalEventLogsObserver> observer;
SetLocalLogsObserver(&observer);
const std::vector<std::string> logs = {"<setup>", "<punchline>", "<encore>"};
std::vector<base::Optional<PeerConnectionKey>> keys(logs.size());
std::vector<base::Optional<base::FilePath>> file_paths(logs.size());
......@@ -923,7 +879,7 @@ TEST_F(WebRtcEventLogManagerTest, LocalLoggingRestartCreatesNewFile) {
ASSERT_TRUE(PeerConnectionAdded(rph_->GetID(), kPeerConnectionId));
for (size_t i = 0; i < logs.size(); i++) {
ON_CALL(observer, OnLocalLogStarted(_, _))
ON_CALL(local_observer_, OnLocalLogStarted(_, _))
.WillByDefault(Invoke(SaveKeyAndFilePathTo(&keys[i], &file_paths[i])));
ASSERT_TRUE(EnableLocalLogging());
ASSERT_TRUE(keys[i]);
......@@ -941,9 +897,6 @@ TEST_F(WebRtcEventLogManagerTest, LocalLoggingRestartCreatesNewFile) {
}
TEST_F(WebRtcEventLogManagerTest, LocalLogMultipleActiveFiles) {
NiceMock<MockWebRtcLocalEventLogsObserver> observer;
SetLocalLogsObserver(&observer);
ASSERT_TRUE(EnableLocalLogging());
std::list<MockRenderProcessHost> rphs;
......@@ -958,7 +911,7 @@ TEST_F(WebRtcEventLogManagerTest, LocalLogMultipleActiveFiles) {
std::vector<base::Optional<base::FilePath>> file_paths(keys.size());
for (size_t i = 0; i < keys.size(); i++) {
ON_CALL(observer, OnLocalLogStarted(keys[i], _))
ON_CALL(local_observer_, OnLocalLogStarted(keys[i], _))
.WillByDefault(Invoke(SaveFilePathTo(&file_paths[i])));
ASSERT_TRUE(PeerConnectionAdded(keys[i].render_process_id, keys[i].lid));
ASSERT_TRUE(file_paths[i]);
......@@ -983,29 +936,23 @@ TEST_F(WebRtcEventLogManagerTest, LocalLogMultipleActiveFiles) {
}
TEST_F(WebRtcEventLogManagerTest, LocalLogLimitActiveLocalLogFiles) {
NiceMock<MockWebRtcLocalEventLogsObserver> observer;
SetLocalLogsObserver(&observer);
ASSERT_TRUE(EnableLocalLogging());
const int kMaxLocalLogFiles =
static_cast<int>(kMaxNumberLocalWebRtcEventLogFiles);
for (int i = 0; i < kMaxLocalLogFiles; i++) {
const PeerConnectionKey key(rph_->GetID(), i);
EXPECT_CALL(observer, OnLocalLogStarted(key, _)).Times(1);
EXPECT_CALL(local_observer_, OnLocalLogStarted(key, _)).Times(1);
ASSERT_TRUE(PeerConnectionAdded(rph_->GetID(), i));
}
EXPECT_CALL(observer, OnLocalLogStarted(_, _)).Times(0);
EXPECT_CALL(local_observer_, OnLocalLogStarted(_, _)).Times(0);
ASSERT_TRUE(PeerConnectionAdded(rph_->GetID(), kMaxLocalLogFiles));
}
// When a log reaches its maximum size limit, it is closed, and no longer
// counted towards the limit.
TEST_F(WebRtcEventLogManagerTest, LocalLogFilledLogNotCountedTowardsLogsLimit) {
NiceMock<MockWebRtcLocalEventLogsObserver> observer;
SetLocalLogsObserver(&observer);
const std::string log = "very_short_log";
ASSERT_TRUE(EnableLocalLogging(log.size()));
......@@ -1013,7 +960,7 @@ TEST_F(WebRtcEventLogManagerTest, LocalLogFilledLogNotCountedTowardsLogsLimit) {
static_cast<int>(kMaxNumberLocalWebRtcEventLogFiles);
for (int i = 0; i < kMaxLocalLogFiles; i++) {
const PeerConnectionKey key(rph_->GetID(), i);
EXPECT_CALL(observer, OnLocalLogStarted(key, _)).Times(1);
EXPECT_CALL(local_observer_, OnLocalLogStarted(key, _)).Times(1);
ASSERT_TRUE(PeerConnectionAdded(key.render_process_id, key.lid));
}
......@@ -1024,34 +971,32 @@ TEST_F(WebRtcEventLogManagerTest, LocalLogFilledLogNotCountedTowardsLogsLimit) {
// We now have room for one additional log.
const PeerConnectionKey last_key(rph_->GetID(), kMaxLocalLogFiles);
EXPECT_CALL(observer, OnLocalLogStarted(last_key, _)).Times(1);
EXPECT_CALL(local_observer_, OnLocalLogStarted(last_key, _)).Times(1);
ASSERT_TRUE(PeerConnectionAdded(last_key.render_process_id, last_key.lid));
}
TEST_F(WebRtcEventLogManagerTest,
LocalLogForRemovedPeerConnectionNotCountedTowardsLogsLimit) {
NiceMock<MockWebRtcLocalEventLogsObserver> observer;
SetLocalLogsObserver(&observer);
ASSERT_TRUE(EnableLocalLogging());
const int kMaxLocalLogFiles =
static_cast<int>(kMaxNumberLocalWebRtcEventLogFiles);
for (int i = 0; i < kMaxLocalLogFiles; i++) {
const PeerConnectionKey key(rph_->GetID(), i);
EXPECT_CALL(observer, OnLocalLogStarted(key, _)).Times(1);
EXPECT_CALL(local_observer_, OnLocalLogStarted(key, _)).Times(1);
ASSERT_TRUE(PeerConnectionAdded(key.render_process_id, key.lid));
}
// When one peer connection is removed, one log is stopped, thereby allowing
// an additional log to be opened.
EXPECT_CALL(observer, OnLocalLogStopped(PeerConnectionKey(rph_->GetID(), 0)))
EXPECT_CALL(local_observer_,
OnLocalLogStopped(PeerConnectionKey(rph_->GetID(), 0)))
.Times(1);
ASSERT_TRUE(PeerConnectionRemoved(rph_->GetID(), 0));
// We now have room for one additional log.
const PeerConnectionKey last_key(rph_->GetID(), kMaxLocalLogFiles);
EXPECT_CALL(observer, OnLocalLogStarted(last_key, _)).Times(1);
EXPECT_CALL(local_observer_, OnLocalLogStarted(last_key, _)).Times(1);
ASSERT_TRUE(PeerConnectionAdded(last_key.render_process_id, last_key.lid));
}
......@@ -1065,12 +1010,9 @@ TEST_F(WebRtcEventLogManagerTest, LocalLogSanityDestructorWithActiveFile) {
}
TEST_F(WebRtcEventLogManagerTest, LocalLogIllegalPath) {
StrictMock<MockWebRtcLocalEventLogsObserver> observer;
SetLocalLogsObserver(&observer);
// Since the log file won't be properly opened, these will not be called.
EXPECT_CALL(observer, OnLocalLogStarted(_, _)).Times(0);
EXPECT_CALL(observer, OnLocalLogStopped(_)).Times(0);
EXPECT_CALL(local_observer_, OnLocalLogStarted(_, _)).Times(0);
EXPECT_CALL(local_observer_, OnLocalLogStopped(_)).Times(0);
ASSERT_TRUE(PeerConnectionAdded(rph_->GetID(), kPeerConnectionId));
......@@ -1086,12 +1028,9 @@ TEST_F(WebRtcEventLogManagerTest, LocalLogIllegalPath) {
TEST_F(WebRtcEventLogManagerTest, LocalLogLegalPathWithoutPermissionsSanity) {
RemoveWritePermissionsFromDirectory(local_logs_base_dir_);
StrictMock<MockWebRtcLocalEventLogsObserver> observer;
SetLocalLogsObserver(&observer);
// Since the log file won't be properly opened, these will not be called.
EXPECT_CALL(observer, OnLocalLogStarted(_, _)).Times(0);
EXPECT_CALL(observer, OnLocalLogStopped(_)).Times(0);
EXPECT_CALL(local_observer_, OnLocalLogStarted(_, _)).Times(0);
EXPECT_CALL(local_observer_, OnLocalLogStopped(_)).Times(0);
ASSERT_TRUE(PeerConnectionAdded(rph_->GetID(), kPeerConnectionId));
......@@ -1115,9 +1054,6 @@ TEST_F(WebRtcEventLogManagerTest, LocalLogLegalPathWithoutPermissionsSanity) {
#endif // defined(OS_POSIX) && !defined(OS_FUCHSIA)
TEST_F(WebRtcEventLogManagerTest, LocalLogEmptyStringHandledGracefully) {
NiceMock<MockWebRtcLocalEventLogsObserver> observer;
SetLocalLogsObserver(&observer);
const PeerConnectionKey key(rph_->GetID(), kPeerConnectionId);
// By writing a log after the empty string, we show that no odd behavior is
......@@ -1126,7 +1062,7 @@ TEST_F(WebRtcEventLogManagerTest, LocalLogEmptyStringHandledGracefully) {
base::Optional<base::FilePath> file_path;
ON_CALL(observer, OnLocalLogStarted(key, _))
ON_CALL(local_observer_, OnLocalLogStarted(key, _))
.WillByDefault(Invoke(SaveFilePathTo(&file_path)));
ASSERT_TRUE(EnableLocalLogging());
ASSERT_TRUE(PeerConnectionAdded(key.render_process_id, key.lid));
......@@ -1147,13 +1083,10 @@ TEST_F(WebRtcEventLogManagerTest, LocalLogEmptyStringHandledGracefully) {
TEST_F(WebRtcEventLogManagerTest, LocalLogFilenameMatchesExpectedFormat) {
using StringType = base::FilePath::StringType;
NiceMock<MockWebRtcLocalEventLogsObserver> observer;
SetLocalLogsObserver(&observer);
const PeerConnectionKey key(rph_->GetID(), kPeerConnectionId);
base::Optional<base::FilePath> file_path;
ON_CALL(observer, OnLocalLogStarted(key, _))
ON_CALL(local_observer_, OnLocalLogStarted(key, _))
.WillByDefault(Invoke(SaveFilePathTo(&file_path)));
const base::Time::Exploded frozen_time_exploded{
......@@ -1195,14 +1128,11 @@ TEST_F(WebRtcEventLogManagerTest,
LocalLogFilenameMatchesExpectedFormatRepeatedFilename) {
using StringType = base::FilePath::StringType;
NiceMock<MockWebRtcLocalEventLogsObserver> observer;
SetLocalLogsObserver(&observer);
const PeerConnectionKey key(rph_->GetID(), kPeerConnectionId);
base::Optional<base::FilePath> file_path_1;
base::Optional<base::FilePath> file_path_2;
EXPECT_CALL(observer, OnLocalLogStarted(key, _))
EXPECT_CALL(local_observer_, OnLocalLogStarted(key, _))
.WillOnce(Invoke(SaveFilePathTo(&file_path_1)))
.WillOnce(Invoke(SaveFilePathTo(&file_path_2)));
......@@ -1255,17 +1185,13 @@ TEST_F(WebRtcEventLogManagerTest,
TEST_F(WebRtcEventLogManagerTest,
OnRemoteLogStartedNotCalledIfRemoteLoggingNotEnabled) {
MockWebRtcRemoteEventLogsObserver observer;
EXPECT_CALL(observer, OnRemoteLogStarted(_, _)).Times(0);
SetRemoteLogsObserver(&observer);
EXPECT_CALL(remote_observer_, OnRemoteLogStarted(_, _)).Times(0);
ASSERT_TRUE(PeerConnectionAdded(rph_->GetID(), kPeerConnectionId));
}
TEST_F(WebRtcEventLogManagerTest,
OnRemoteLogStoppedNotCalledIfRemoteLoggingNotEnabled) {
MockWebRtcRemoteEventLogsObserver observer;
EXPECT_CALL(observer, OnRemoteLogStopped(_)).Times(0);
SetRemoteLogsObserver(&observer);
EXPECT_CALL(remote_observer_, OnRemoteLogStopped(_)).Times(0);
const PeerConnectionKey key(rph_->GetID(), kPeerConnectionId);
ASSERT_TRUE(PeerConnectionAdded(key.render_process_id, key.lid));
ASSERT_TRUE(PeerConnectionRemoved(key.render_process_id, key.lid));
......@@ -1273,20 +1199,16 @@ TEST_F(WebRtcEventLogManagerTest,
TEST_F(WebRtcEventLogManagerTest,
OnRemoteLogStartedCalledIfRemoteLoggingEnabled) {
MockWebRtcRemoteEventLogsObserver observer;
const PeerConnectionKey key(rph_->GetID(), kPeerConnectionId);
EXPECT_CALL(observer, OnRemoteLogStarted(key, _)).Times(1);
SetRemoteLogsObserver(&observer);
EXPECT_CALL(remote_observer_, OnRemoteLogStarted(key, _)).Times(1);
ASSERT_TRUE(PeerConnectionAdded(key.render_process_id, key.lid));
ASSERT_TRUE(StartRemoteLogging(key.render_process_id, key.lid));
}
TEST_F(WebRtcEventLogManagerTest,
OnRemoteLogStoppedCalledIfRemoteLoggingEnabledThenPcRemoved) {
NiceMock<MockWebRtcRemoteEventLogsObserver> observer;
const PeerConnectionKey key(rph_->GetID(), kPeerConnectionId);
EXPECT_CALL(observer, OnRemoteLogStopped(key)).Times(1);
SetRemoteLogsObserver(&observer);
EXPECT_CALL(remote_observer_, OnRemoteLogStopped(key)).Times(1);
ASSERT_TRUE(PeerConnectionAdded(key.render_process_id, key.lid));
ASSERT_TRUE(StartRemoteLogging(key.render_process_id, key.lid));
ASSERT_TRUE(PeerConnectionRemoved(key.render_process_id, key.lid));
......@@ -1334,13 +1256,11 @@ TEST_F(WebRtcEventLogManagerTest,
}
TEST_F(WebRtcEventLogManagerTest, StartRemoteLoggingCreatesEmptyFile) {
NiceMock<MockWebRtcRemoteEventLogsObserver> observer;
base::Optional<base::FilePath> file_path;
const PeerConnectionKey key(rph_->GetID(), kPeerConnectionId);
EXPECT_CALL(observer, OnRemoteLogStarted(key, _))
EXPECT_CALL(remote_observer_, OnRemoteLogStarted(key, _))
.Times(1)
.WillOnce(Invoke(SaveFilePathTo(&file_path)));
SetRemoteLogsObserver(&observer);
ASSERT_TRUE(PeerConnectionAdded(rph_->GetID(), kPeerConnectionId));
ASSERT_TRUE(StartRemoteLogging(rph_->GetID(), kPeerConnectionId));
......@@ -1361,14 +1281,12 @@ TEST_F(WebRtcEventLogManagerTest, RemoteLogFileCreatedInCorrectDirectory) {
// Prepare to store the logs' paths in distinct memory locations.
base::Optional<base::FilePath> file_paths[kLogsNum];
NiceMock<MockWebRtcRemoteEventLogsObserver> observer;
for (size_t i = 0; i < kLogsNum; i++) {
const PeerConnectionKey key(rphs[i]->GetID(), kPeerConnectionId);
EXPECT_CALL(observer, OnRemoteLogStarted(key, _))
EXPECT_CALL(remote_observer_, OnRemoteLogStarted(key, _))
.Times(1)
.WillOnce(Invoke(SaveFilePathTo(&file_paths[i])));
}
SetRemoteLogsObserver(&observer);
// Start one log for each browser context.
for (const auto& rph : rphs) {
......@@ -1385,13 +1303,11 @@ TEST_F(WebRtcEventLogManagerTest, RemoteLogFileCreatedInCorrectDirectory) {
TEST_F(WebRtcEventLogManagerTest,
OnWebRtcEventLogWriteWritesToTheRemoteBoundFile) {
NiceMock<MockWebRtcRemoteEventLogsObserver> observer;
base::Optional<base::FilePath> file_path;
const PeerConnectionKey key(rph_->GetID(), kPeerConnectionId);
EXPECT_CALL(observer, OnRemoteLogStarted(key, _))
EXPECT_CALL(remote_observer_, OnRemoteLogStarted(key, _))
.Times(1)
.WillOnce(Invoke(SaveFilePathTo(&file_path)));
SetRemoteLogsObserver(&observer);
ASSERT_TRUE(PeerConnectionAdded(rph_->GetID(), kPeerConnectionId));
ASSERT_TRUE(StartRemoteLogging(rph_->GetID(), kPeerConnectionId));
......@@ -1407,19 +1323,15 @@ TEST_F(WebRtcEventLogManagerTest, WriteToBothLocalAndRemoteFiles) {
const PeerConnectionKey key(rph_->GetID(), kPeerConnectionId);
ASSERT_TRUE(PeerConnectionAdded(key.render_process_id, key.lid));
NiceMock<MockWebRtcLocalEventLogsObserver> local_observer;
base::Optional<base::FilePath> local_path;
EXPECT_CALL(local_observer, OnLocalLogStarted(key, _))
EXPECT_CALL(local_observer_, OnLocalLogStarted(key, _))
.Times(1)
.WillOnce(Invoke(SaveFilePathTo(&local_path)));
SetLocalLogsObserver(&local_observer);
NiceMock<MockWebRtcRemoteEventLogsObserver> remote_observer;
base::Optional<base::FilePath> remote_path;
EXPECT_CALL(remote_observer, OnRemoteLogStarted(key, _))
EXPECT_CALL(remote_observer_, OnRemoteLogStarted(key, _))
.Times(1)
.WillOnce(Invoke(SaveFilePathTo(&remote_path)));
SetRemoteLogsObserver(&remote_observer);
ASSERT_TRUE(EnableLocalLogging());
ASSERT_TRUE(StartRemoteLogging(key.render_process_id, key.lid));
......@@ -1442,13 +1354,10 @@ TEST_F(WebRtcEventLogManagerTest, WriteToBothLocalAndRemoteFiles) {
}
TEST_F(WebRtcEventLogManagerTest, MultipleWritesToSameRemoteBoundLogfile) {
NiceMock<MockWebRtcRemoteEventLogsObserver> observer;
SetRemoteLogsObserver(&observer);
const PeerConnectionKey key(rph_->GetID(), kPeerConnectionId);
base::Optional<base::FilePath> file_path;
ON_CALL(observer, OnRemoteLogStarted(key, _))
ON_CALL(remote_observer_, OnRemoteLogStarted(key, _))
.WillByDefault(Invoke(SaveFilePathTo(&file_path)));
ASSERT_TRUE(PeerConnectionAdded(key.render_process_id, key.lid));
......@@ -1471,12 +1380,9 @@ TEST_F(WebRtcEventLogManagerTest, MultipleWritesToSameRemoteBoundLogfile) {
}
TEST_F(WebRtcEventLogManagerTest, RemoteLogFileSizeLimitNotExceeded) {
NiceMock<MockWebRtcRemoteEventLogsObserver> observer;
SetRemoteLogsObserver(&observer);
const PeerConnectionKey key(rph_->GetID(), kPeerConnectionId);
base::Optional<base::FilePath> file_path;
ON_CALL(observer, OnRemoteLogStarted(key, _))
ON_CALL(remote_observer_, OnRemoteLogStarted(key, _))
.WillByDefault(Invoke(SaveFilePathTo(&file_path)));
const std::string log = "tpyo";
......@@ -1488,7 +1394,7 @@ TEST_F(WebRtcEventLogManagerTest, RemoteLogFileSizeLimitNotExceeded) {
// A failure is reported, because not everything could be written. The file
// will also be closed.
EXPECT_CALL(observer, OnRemoteLogStopped(key)).Times(1);
EXPECT_CALL(remote_observer_, OnRemoteLogStopped(key)).Times(1);
ASSERT_EQ(OnWebRtcEventLogWrite(key.render_process_id, key.lid, log),
std::make_pair(false, false));
......@@ -1501,16 +1407,13 @@ TEST_F(WebRtcEventLogManagerTest, RemoteLogFileSizeLimitNotExceeded) {
TEST_F(WebRtcEventLogManagerTest,
LogMultipleActiveRemoteLogsSameBrowserContext) {
NiceMock<MockWebRtcRemoteEventLogsObserver> observer;
SetRemoteLogsObserver(&observer);
const std::vector<PeerConnectionKey> keys = {
PeerConnectionKey(rph_->GetID(), 0), PeerConnectionKey(rph_->GetID(), 1),
PeerConnectionKey(rph_->GetID(), 2)};
std::vector<base::Optional<base::FilePath>> file_paths(keys.size());
for (size_t i = 0; i < keys.size(); i++) {
ON_CALL(observer, OnRemoteLogStarted(keys[i], _))
ON_CALL(remote_observer_, OnRemoteLogStarted(keys[i], _))
.WillByDefault(Invoke(SaveFilePathTo(&file_paths[i])));
ASSERT_TRUE(PeerConnectionAdded(keys[i].render_process_id, keys[i].lid));
ASSERT_TRUE(StartRemoteLogging(keys[i].render_process_id, keys[i].lid));
......@@ -1538,9 +1441,6 @@ TEST_F(WebRtcEventLogManagerTest,
TEST_F(WebRtcEventLogManagerTest,
LogMultipleActiveRemoteLogsDifferentBrowserContexts) {
NiceMock<MockWebRtcRemoteEventLogsObserver> observer;
SetRemoteLogsObserver(&observer);
constexpr size_t kLogsNum = 3;
std::unique_ptr<TestBrowserContext> browser_contexts[kLogsNum] = {
CreateBrowserContext(), CreateBrowserContext(), CreateBrowserContext()};
......@@ -1557,7 +1457,7 @@ TEST_F(WebRtcEventLogManagerTest,
std::vector<base::Optional<base::FilePath>> file_paths(keys.size());
for (size_t i = 0; i < keys.size(); i++) {
ON_CALL(observer, OnRemoteLogStarted(keys[i], _))
ON_CALL(remote_observer_, OnRemoteLogStarted(keys[i], _))
.WillByDefault(Invoke(SaveFilePathTo(&file_paths[i])));
ASSERT_TRUE(PeerConnectionAdded(keys[i].render_process_id, keys[i].lid));
ASSERT_TRUE(StartRemoteLogging(keys[i].render_process_id, keys[i].lid));
......@@ -1584,14 +1484,11 @@ TEST_F(WebRtcEventLogManagerTest,
}
TEST_F(WebRtcEventLogManagerTest, DifferentRemoteLogsMayHaveDifferentMaximums) {
NiceMock<MockWebRtcRemoteEventLogsObserver> observer;
SetRemoteLogsObserver(&observer);
const std::vector<PeerConnectionKey> keys = {
PeerConnectionKey(rph_->GetID(), 0), PeerConnectionKey(rph_->GetID(), 1)};
std::vector<base::Optional<base::FilePath>> file_paths(keys.size());
for (size_t i = 0; i < keys.size(); i++) {
ON_CALL(observer, OnRemoteLogStarted(keys[i], _))
ON_CALL(remote_observer_, OnRemoteLogStarted(keys[i], _))
.WillByDefault(Invoke(SaveFilePathTo(&file_paths[i])));
}
......@@ -1621,12 +1518,9 @@ TEST_F(WebRtcEventLogManagerTest, DifferentRemoteLogsMayHaveDifferentMaximums) {
}
TEST_F(WebRtcEventLogManagerTest, RemoteLogFileClosedWhenCapacityReached) {
NiceMock<MockWebRtcRemoteEventLogsObserver> observer;
SetRemoteLogsObserver(&observer);
const PeerConnectionKey key(rph_->GetID(), kPeerConnectionId);
base::Optional<base::FilePath> file_path;
ON_CALL(observer, OnRemoteLogStarted(key, _))
ON_CALL(remote_observer_, OnRemoteLogStarted(key, _))
.WillByDefault(Invoke(SaveFilePathTo(&file_path)));
const std::string log = "Let X equal X.";
......@@ -1635,7 +1529,7 @@ TEST_F(WebRtcEventLogManagerTest, RemoteLogFileClosedWhenCapacityReached) {
ASSERT_TRUE(StartRemoteLogging(key.render_process_id, key.lid, log.length()));
ASSERT_TRUE(file_path);
EXPECT_CALL(observer, OnRemoteLogStopped(key)).Times(1);
EXPECT_CALL(remote_observer_, OnRemoteLogStopped(key)).Times(1);
EXPECT_EQ(OnWebRtcEventLogWrite(key.render_process_id, key.lid, log),
std::make_pair(false, true));
}
......@@ -1679,8 +1573,9 @@ TEST_F(WebRtcEventLogManagerTest,
}
TEST_F(WebRtcEventLogManagerTest, GracefullyHandleFailureToStartRemoteLogFile) {
StrictMock<MockWebRtcRemoteEventLogsObserver> observer;
SetRemoteLogsObserver(&observer); // WebRTC logging will not be turned on.
// WebRTC logging will not be turned on.
EXPECT_CALL(remote_observer_, OnRemoteLogStarted(_, _)).Times(0);
EXPECT_CALL(remote_observer_, OnRemoteLogStopped(_)).Times(0);
// Set up a BrowserContext whose directory we know, so that we would be
// able to manipulate it.
......@@ -1706,36 +1601,30 @@ TEST_F(WebRtcEventLogManagerTest, GracefullyHandleFailureToStartRemoteLogFile) {
#endif // defined(OS_POSIX) && !defined(OS_FUCHSIA)
TEST_F(WebRtcEventLogManagerTest, RemoteLogLimitActiveLogFiles) {
NiceMock<MockWebRtcRemoteEventLogsObserver> observer;
SetRemoteLogsObserver(&observer);
for (int i = 0; i < kMaxActiveRemoteLogFiles + 1; i++) {
ASSERT_TRUE(PeerConnectionAdded(rph_->GetID(), i));
}
int i;
for (i = 0; i < kMaxActiveRemoteLogFiles; i++) {
EXPECT_CALL(observer,
EXPECT_CALL(remote_observer_,
OnRemoteLogStarted(PeerConnectionKey(rph_->GetID(), i), _))
.Times(1);
ASSERT_TRUE(StartRemoteLogging(rph_->GetID(), i));
}
EXPECT_CALL(observer, OnRemoteLogStarted(_, _)).Times(0);
EXPECT_CALL(remote_observer_, OnRemoteLogStarted(_, _)).Times(0);
EXPECT_FALSE(StartRemoteLogging(rph_->GetID(), i));
}
TEST_F(WebRtcEventLogManagerTest,
RemoteLogFilledLogNotCountedTowardsLogsLimit) {
NiceMock<MockWebRtcRemoteEventLogsObserver> observer;
SetRemoteLogsObserver(&observer);
const std::string log = "very_short_log";
int i;
for (i = 0; i < kMaxActiveRemoteLogFiles; i++) {
ASSERT_TRUE(PeerConnectionAdded(rph_->GetID(), i));
EXPECT_CALL(observer,
EXPECT_CALL(remote_observer_,
OnRemoteLogStarted(PeerConnectionKey(rph_->GetID(), i), _))
.Times(1);
ASSERT_TRUE(StartRemoteLogging(rph_->GetID(), i, log.length()));
......@@ -1748,7 +1637,7 @@ TEST_F(WebRtcEventLogManagerTest,
// We now have room for one additional log.
++i;
EXPECT_CALL(observer,
EXPECT_CALL(remote_observer_,
OnRemoteLogStarted(PeerConnectionKey(rph_->GetID(), i), _))
.Times(1);
ASSERT_TRUE(PeerConnectionAdded(rph_->GetID(), i));
......@@ -1757,13 +1646,10 @@ TEST_F(WebRtcEventLogManagerTest,
TEST_F(WebRtcEventLogManagerTest,
RemoteLogForRemovedPeerConnectionNotCountedTowardsLogsLimit) {
NiceMock<MockWebRtcRemoteEventLogsObserver> observer;
SetRemoteLogsObserver(&observer);
for (int i = 0; i < kMaxActiveRemoteLogFiles; i++) {
const PeerConnectionKey key(rph_->GetID(), i);
ASSERT_TRUE(PeerConnectionAdded(key.render_process_id, key.lid));
EXPECT_CALL(observer, OnRemoteLogStarted(key, _)).Times(1);
EXPECT_CALL(remote_observer_, OnRemoteLogStarted(key, _)).Times(1);
ASSERT_TRUE(StartRemoteLogging(key.render_process_id, key.lid));
}
......@@ -1773,7 +1659,7 @@ TEST_F(WebRtcEventLogManagerTest,
// We now have room for one additional log.
const PeerConnectionKey last_key(rph_->GetID(), kMaxActiveRemoteLogFiles);
EXPECT_CALL(observer, OnRemoteLogStarted(last_key, _)).Times(1);
EXPECT_CALL(remote_observer_, OnRemoteLogStarted(last_key, _)).Times(1);
ASSERT_TRUE(PeerConnectionAdded(last_key.render_process_id, last_key.lid));
ASSERT_TRUE(StartRemoteLogging(last_key.render_process_id, last_key.lid));
}
......@@ -1873,12 +1759,9 @@ TEST_P(WebRtcEventLogManagerTest, FinishedRemoteLogsUploadedAndFileDeleted) {
// upload's success / failure.
const bool upload_result = GetParam();
NiceMock<MockWebRtcRemoteEventLogsObserver> observer;
SetRemoteLogsObserver(&observer);
const PeerConnectionKey key(rph_->GetID(), 1);
base::Optional<base::FilePath> log_file;
ON_CALL(observer, OnRemoteLogStarted(key, _))
ON_CALL(remote_observer_, OnRemoteLogStarted(key, _))
.WillByDefault(Invoke(SaveFilePathTo(&log_file)));
ASSERT_TRUE(PeerConnectionAdded(key.render_process_id, key.lid));
ASSERT_TRUE(StartRemoteLogging(key.render_process_id, key.lid));
......@@ -1900,9 +1783,6 @@ TEST_P(WebRtcEventLogManagerTest, FinishedRemoteLogsUploadedAndFileDeleted) {
// Note that SuppressUploading() and UnSuppressUploading() use the behavior
// guaranteed by this test.
TEST_F(WebRtcEventLogManagerTest, UploadOnlyWhenNoActivePeerConnections) {
NiceMock<MockWebRtcRemoteEventLogsObserver> observer;
SetRemoteLogsObserver(&observer);
const PeerConnectionKey untracked(rph_->GetID(), 0);
const PeerConnectionKey tracked(rph_->GetID(), 1);
......@@ -1912,7 +1792,7 @@ TEST_F(WebRtcEventLogManagerTest, UploadOnlyWhenNoActivePeerConnections) {
// The tracked peer connection's log is not uploaded when finished, because
// another peer connection is still active.
base::Optional<base::FilePath> log_file;
ON_CALL(observer, OnRemoteLogStarted(tracked, _))
ON_CALL(remote_observer_, OnRemoteLogStarted(tracked, _))
.WillByDefault(Invoke(SaveFilePathTo(&log_file)));
ASSERT_TRUE(PeerConnectionAdded(tracked.render_process_id, tracked.lid));
ASSERT_TRUE(StartRemoteLogging(tracked.render_process_id, tracked.lid));
......@@ -2075,9 +1955,6 @@ TEST_F(WebRtcEventLogManagerTest, RemoteLogSanityDestructorWithActiveFile) {
}
TEST_F(WebRtcEventLogManagerTest, RemoteLogEmptyStringHandledGracefully) {
NiceMock<MockWebRtcRemoteEventLogsObserver> observer;
SetRemoteLogsObserver(&observer);
const PeerConnectionKey key(rph_->GetID(), kPeerConnectionId);
// By writing a log after the empty string, we show that no odd behavior is
......@@ -2086,7 +1963,7 @@ TEST_F(WebRtcEventLogManagerTest, RemoteLogEmptyStringHandledGracefully) {
base::Optional<base::FilePath> file_path;
ON_CALL(observer, OnRemoteLogStarted(key, _))
ON_CALL(remote_observer_, OnRemoteLogStarted(key, _))
.WillByDefault(Invoke(SaveFilePathTo(&file_path)));
ASSERT_TRUE(PeerConnectionAdded(key.render_process_id, key.lid));
ASSERT_TRUE(StartRemoteLogging(key.render_process_id, key.lid));
......@@ -2311,16 +2188,12 @@ TEST_F(WebRtcEventLogManagerTest, SanityOverRecreatingTheSamePeerConnection) {
TEST_F(WebRtcEventLogManagerTest, LogAllPossibleCharacters) {
const PeerConnectionKey key(rph_->GetID(), kPeerConnectionId);
NiceMock<MockWebRtcLocalEventLogsObserver> local_observer;
SetLocalLogsObserver(&local_observer);
base::Optional<base::FilePath> local_log_file_path;
ON_CALL(local_observer, OnLocalLogStarted(key, _))
ON_CALL(local_observer_, OnLocalLogStarted(key, _))
.WillByDefault(Invoke(SaveFilePathTo(&local_log_file_path)));
NiceMock<MockWebRtcRemoteEventLogsObserver> remote_observer;
SetRemoteLogsObserver(&remote_observer);
base::Optional<base::FilePath> remote_log_file_path;
ON_CALL(remote_observer, OnRemoteLogStarted(key, _))
ON_CALL(remote_observer_, OnRemoteLogStarted(key, _))
.WillByDefault(Invoke(SaveFilePathTo(&remote_log_file_path)));
ASSERT_TRUE(EnableLocalLogging());
......@@ -2345,6 +2218,63 @@ TEST_F(WebRtcEventLogManagerTest, LogAllPossibleCharacters) {
ExpectFileContents(*remote_log_file_path, all_chars);
}
TEST_F(WebRtcEventLogManagerTest, LocalLogsClosedWhenRenderProcessHostExits) {
const PeerConnectionKey key(rph_->GetID(), kPeerConnectionId);
ASSERT_TRUE(PeerConnectionAdded(key.render_process_id, key.lid));
ASSERT_TRUE(EnableLocalLogging());
// The expectation for OnLocalLogStopped() will be saturated by this
// destruction of the RenderProcessHost, which triggers an implicit
// removal of all PeerConnections associated with it.
EXPECT_CALL(local_observer_, OnLocalLogStopped(key)).Times(1);
rph_.reset();
}
TEST_F(WebRtcEventLogManagerTest, RemoteLogsClosedWhenRenderProcessHostExits) {
const PeerConnectionKey key(rph_->GetID(), kPeerConnectionId);
ASSERT_TRUE(PeerConnectionAdded(key.render_process_id, key.lid));
ASSERT_TRUE(StartRemoteLogging(key.render_process_id, key.lid));
// The expectation for OnRemoteLogStopped() will be saturated by this
// destruction of the RenderProcessHost, which triggers an implicit
// removal of all PeerConnections associated with it.
EXPECT_CALL(remote_observer_, OnRemoteLogStopped(key)).Times(1);
rph_.reset();
}
// Once a RenderProcessHost exits/crashes, its PeerConnections are removed,
// which means that they can no longer suppress an upload.
TEST_F(WebRtcEventLogManagerTest,
RenderProcessHostExitCanRemoveUploadSuppression) {
SuppressUploading();
const PeerConnectionKey key(rph_->GetID(), kPeerConnectionId);
base::Optional<base::FilePath> file_path;
ON_CALL(remote_observer_, OnRemoteLogStarted(key, _))
.WillByDefault(Invoke(SaveFilePathTo(&file_path)));
ASSERT_TRUE(PeerConnectionAdded(key.render_process_id, key.lid));
ASSERT_TRUE(StartRemoteLogging(key.render_process_id, key.lid));
ASSERT_TRUE(PeerConnectionRemoved(key.render_process_id, key.lid));
ASSERT_TRUE(file_path);
ASSERT_FALSE(file_path->empty());
// The above removal is not sufficient to trigger an upload (so the test will
// not be flaky). It's only once we destroy the RPH with which the suppressing
// PeerConnection is associated, that upload will take place.
base::RunLoop run_loop;
std::list<base::FilePath> expected_files = {*file_path};
SetWebRtcEventLogUploaderFactoryForTesting(
std::make_unique<FileListExpectingWebRtcEventLogUploader::Factory>(
&expected_files, true, &run_loop));
// We destroy the RPH without explicitly removing its PeerConnection (unlike
// a call to UnsuppressUploading()).
upload_suppressing_rph_.reset();
WaitForPendingTasks(&run_loop);
}
INSTANTIATE_TEST_CASE_P(UploadCompleteResult,
WebRtcEventLogManagerTest,
::testing::Values(false, true));
......
......@@ -121,6 +121,30 @@ bool WebRtcLocalEventLogManager::EventLogWrite(int render_process_id,
return WriteToLogFile(it, message);
}
void WebRtcLocalEventLogManager::RenderProcessHostExitedDestroyed(
int render_process_id) {
// Remove all of the peer connections associated with this render process.
auto pc_it = active_peer_connections_.begin();
while (pc_it != active_peer_connections_.end()) {
if (pc_it->render_process_id == render_process_id) {
pc_it = active_peer_connections_.erase(pc_it);
} else {
++pc_it;
}
}
// Close all of the files that were associated with peer connections which
// belonged to this render process.
auto log_it = log_files_.begin();
while (log_it != log_files_.end()) {
if (log_it->first.render_process_id == render_process_id) {
log_it = CloseLogFile(log_it);
} else {
++log_it;
}
}
}
void WebRtcLocalEventLogManager::SetClockForTesting(base::Clock* clock) {
clock_for_testing_ = clock;
}
......
......@@ -32,6 +32,8 @@ class WebRtcLocalEventLogManager final : public LogFileWriter {
int lid,
const std::string& message);
void RenderProcessHostExitedDestroyed(int render_process_id);
// This function is public, but this entire class is a protected
// implementation detail of WebRtcEventLogManager, which hides this
// function from everybody except its own unit tests.
......
......@@ -158,6 +158,41 @@ bool WebRtcRemoteEventLogManager::EventLogWrite(int render_process_id,
return WriteToLogFile(it, message);
}
void WebRtcRemoteEventLogManager::RenderProcessHostExitedDestroyed(
int render_process_id) {
// Closing files will call MaybeStartUploading(). Avoid letting that upload
// any recently expired files.
PrunePendingLogs();
// Remove all of the peer connections associated with this render process.
// It's important to do this before closing the actual files, because closing
// files can trigger a new upload if no active peer connections are present.
auto pc_it = active_peer_connections_.begin();
while (pc_it != active_peer_connections_.end()) {
if (pc_it->render_process_id == render_process_id) {
pc_it = active_peer_connections_.erase(pc_it);
} else {
++pc_it;
}
}
// Close all of the files that were associated with peer connections which
// belonged to this render process.
auto log_it = active_logs_.begin();
while (log_it != active_logs_.end()) {
if (log_it->first.render_process_id == render_process_id) {
log_it = CloseLogFile(log_it);
} else {
++log_it;
}
}
// Though CloseLogFile() calls this, it's important to also do this
// explicitly, since it could be that no files were closed, but some
// active PeerConnections that were suppressing uploading are now gone.
MaybeStartUploading();
}
void WebRtcRemoteEventLogManager::OnWebRtcEventLogUploadComplete(
const base::FilePath& file_path,
bool upload_successful) {
......
......@@ -83,6 +83,10 @@ class CONTENT_EXPORT WebRtcRemoteEventLogManager final
int lid,
const std::string& message);
// An implicit PeerConnectionRemoved() on all of the peer connections that
// were associated with the renderer process.
void RenderProcessHostExitedDestroyed(int render_process_id);
// WebRtcEventLogUploaderObserver implementation.
void OnWebRtcEventLogUploadComplete(const base::FilePath& file_path,
bool upload_successful) override;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment