blob: 8d842434441d5f01752316172a183ad234606835 [file] [log] [blame]
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/extensions/policy_extension_reinstaller.h"
#include "base/test/simple_test_tick_clock.h"
#include "base/threading/thread_task_runner_handle.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_service_test_base.h"
#include "chrome/test/base/testing_profile.h"
namespace extensions {
namespace {
const char kDummyExtensionId[] = "whatever";
}
class TestReinstallerTracker {
public:
TestReinstallerTracker()
: action_(base::Bind(&TestReinstallerTracker::ReinstallAction,
base::Unretained(this))) {
PolicyExtensionReinstaller::set_policy_reinstall_action_for_test(&action_);
}
~TestReinstallerTracker() {
PolicyExtensionReinstaller::set_policy_reinstall_action_for_test(nullptr);
}
void ReinstallAction(const base::Closure& callback,
base::TimeDelta reinstall_delay) {
++call_count_;
saved_callback_ = callback;
}
void Proceed() {
DCHECK(saved_callback_);
DCHECK(!saved_callback_->is_null());
// Run() will set |saved_callback_| again, so use a temporary.
base::Closure callback = saved_callback_.value();
saved_callback_.reset();
callback.Run();
}
int call_count() { return call_count_; }
private:
int call_count_ = 0;
base::Optional<base::Closure> saved_callback_;
PolicyExtensionReinstaller::ReinstallCallback action_;
DISALLOW_COPY_AND_ASSIGN(TestReinstallerTracker);
};
using PolicyExtensionReinstallerUnittest = ExtensionServiceTestBase;
// Tests that a single extension corruption will keep retrying reinstallation.
TEST_F(PolicyExtensionReinstallerUnittest, Retry) {
InitializeEmptyExtensionService();
service()->pending_extension_manager()->ExpectPolicyReinstallForCorruption(
kDummyExtensionId);
PolicyExtensionReinstaller reinstaller(profile_.get());
TestReinstallerTracker tracker;
reinstaller.NotifyExtensionDisabledDueToCorruption();
EXPECT_EQ(1, tracker.call_count());
tracker.Proceed();
EXPECT_EQ(2, tracker.call_count());
tracker.Proceed();
EXPECT_EQ(3, tracker.call_count());
}
// Tests that PolicyExtensionReinstaller doesn't schedule a
// CheckForExternalUpdates() when one is already in-flight through PostTask.
TEST_F(PolicyExtensionReinstallerUnittest, DoNotScheduleWhenAlreadyInflight) {
InitializeEmptyExtensionService();
service()->pending_extension_manager()->ExpectPolicyReinstallForCorruption(
kDummyExtensionId);
PolicyExtensionReinstaller reinstaller(profile_.get());
TestReinstallerTracker tracker;
reinstaller.NotifyExtensionDisabledDueToCorruption();
EXPECT_EQ(1, tracker.call_count());
reinstaller.NotifyExtensionDisabledDueToCorruption();
// Resolve the reinstall attempt.
tracker.Proceed();
EXPECT_EQ(2, tracker.call_count());
reinstaller.NotifyExtensionDisabledDueToCorruption();
// Not resolving the pending attempt will not produce further calls.
EXPECT_EQ(2, tracker.call_count());
}
} // namespace extensions