Add end-to-end browser tests for PluginVm setup flow
Adds end-to-end setup flow browser tests.
This CL also adds DCHECKs that check that UI related calls made in the
UI thread.
Test: browser_tests --gtest_filter="PluginVm*"
Bug: 920988
Change-Id: Ia3ae225f44f05cde4468b72f49a7ecbaa250c42c
Reviewed-on: https://chromium-review.googlesource.com/c/1494881
Commit-Queue: Olya Kalitova <okalitova@chromium.org>
Reviewed-by: Igor <igorcov@chromium.org>
Cr-Commit-Position: refs/heads/master@{#637253}
diff --git a/chrome/browser/ui/views/plugin_vm/plugin_vm_launcher_view.cc b/chrome/browser/ui/views/plugin_vm/plugin_vm_launcher_view.cc
index fc072af..e37149a 100644
--- a/chrome/browser/ui/views/plugin_vm/plugin_vm_launcher_view.cc
+++ b/chrome/browser/ui/views/plugin_vm/plugin_vm_launcher_view.cc
@@ -14,6 +14,7 @@
#include "chrome/browser/ui/views/chrome_layout_provider.h"
#include "chrome/grit/chrome_unscaled_resources.h"
#include "chrome/grit/generated_resources.h"
+#include "content/public/browser/browser_thread.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/text/bytes_formatting.h"
@@ -158,15 +159,13 @@
GetLayoutManager()->GetPreferredHeightForWidth(this, width));
}
-PluginVmLauncherView::~PluginVmLauncherView() {
- plugin_vm_image_manager_->RemoveObserver();
- g_plugin_vm_launcher_view = nullptr;
+void PluginVmLauncherView::OnDownloadStarted() {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
}
-void PluginVmLauncherView::OnDownloadStarted() {}
-
void PluginVmLauncherView::OnDownloadProgressUpdated(uint64_t bytes_downloaded,
int64_t content_length) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
DCHECK_EQ(state_, State::DOWNLOADING);
base::Optional<double> fraction_complete =
@@ -178,6 +177,7 @@
}
void PluginVmLauncherView::OnDownloadCompleted() {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
DCHECK_EQ(state_, State::DOWNLOADING);
plugin_vm_image_manager_->StartUnzipping();
@@ -185,9 +185,12 @@
OnStateUpdated();
}
-void PluginVmLauncherView::OnDownloadCancelled() {}
+void PluginVmLauncherView::OnDownloadCancelled() {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+}
void PluginVmLauncherView::OnDownloadFailed() {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
state_ = State::ERROR;
OnStateUpdated();
}
@@ -195,6 +198,7 @@
void PluginVmLauncherView::OnUnzippingProgressUpdated(
int64_t bytes_unzipped,
int64_t plugin_vm_image_size) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
DCHECK_EQ(state_, State::UNZIPPING);
base::Optional<double> fraction_complete =
GetFractionComplete(bytes_unzipped, plugin_vm_image_size);
@@ -205,21 +209,18 @@
}
void PluginVmLauncherView::OnUnzipped() {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
DCHECK_EQ(state_, State::UNZIPPING);
state_ = State::FINISHED;
OnStateUpdated();
}
void PluginVmLauncherView::OnUnzippingFailed() {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
state_ = State::ERROR;
OnStateUpdated();
}
-plugin_vm::PluginVmImageManager*
-PluginVmLauncherView::GetPluginVmImageManagerForTesting() {
- return plugin_vm_image_manager_;
-}
-
base::string16 PluginVmLauncherView::GetBigMessage() {
switch (state_) {
case State::START_DOWNLOADING:
@@ -234,10 +235,30 @@
}
}
+PluginVmLauncherView::~PluginVmLauncherView() {
+ plugin_vm_image_manager_->RemoveObserver();
+ g_plugin_vm_launcher_view = nullptr;
+}
+
void PluginVmLauncherView::AddedToWidget() {
StartPluginVmImageDownload();
}
+void PluginVmLauncherView::OnStateUpdated() {
+ DialogModelChanged();
+ SetBigMessageLabel();
+ SetMessageLabel();
+ SetBigImage();
+
+ const bool progress_bar_visible =
+ state_ == State::DOWNLOADING || state_ == State::UNZIPPING;
+ progress_bar_->SetVisible(progress_bar_visible);
+ // Values outside the range [0,1] display an infinite loading animation.
+ progress_bar_->SetValue(-1);
+
+ GetWidget()->SetSize(GetWidget()->non_client_view()->GetPreferredSize());
+}
+
base::string16 PluginVmLauncherView::GetMessage() const {
switch (state_) {
case State::START_DOWNLOADING:
@@ -278,21 +299,6 @@
IDR_PLUGIN_VM_LAUNCHER));
}
-void PluginVmLauncherView::OnStateUpdated() {
- DialogModelChanged();
- SetBigMessageLabel();
- SetMessageLabel();
- SetBigImage();
-
- const bool progress_bar_visible =
- state_ == State::DOWNLOADING || state_ == State::UNZIPPING;
- progress_bar_->SetVisible(progress_bar_visible);
- // Values outside the range [0,1] display an infinite loading animation.
- progress_bar_->SetValue(-1);
-
- GetWidget()->SetSize(GetWidget()->non_client_view()->GetPreferredSize());
-}
-
void PluginVmLauncherView::StartPluginVmImageDownload() {
plugin_vm_image_manager_->SetObserver(this);
plugin_vm_image_manager_->StartDownload();
diff --git a/chrome/browser/ui/views/plugin_vm/plugin_vm_launcher_view.h b/chrome/browser/ui/views/plugin_vm/plugin_vm_launcher_view.h
index f8b8cc7..bda4520 100644
--- a/chrome/browser/ui/views/plugin_vm/plugin_vm_launcher_view.h
+++ b/chrome/browser/ui/views/plugin_vm/plugin_vm_launcher_view.h
@@ -47,24 +47,9 @@
void OnUnzippingFailed() override;
// Public for testing purposes.
- plugin_vm::PluginVmImageManager* GetPluginVmImageManagerForTesting();
base::string16 GetBigMessage();
protected:
- // views::BubbleDialogDelegateView implementation.
- void AddedToWidget() override;
-
- private:
- ~PluginVmLauncherView() override;
-
- base::string16 GetMessage() const;
- void SetBigMessageLabel();
- void SetMessageLabel();
- void SetBigImage();
- void OnStateUpdated();
-
- void StartPluginVmImageDownload();
-
enum class State {
START_DOWNLOADING, // PluginVm image downloading should be started.
DOWNLOADING, // PluginVm image downloading is in progress.
@@ -74,6 +59,20 @@
};
State state_ = State::START_DOWNLOADING;
+
+ ~PluginVmLauncherView() override;
+ virtual void OnStateUpdated();
+ // views::BubbleDialogDelegateView implementation.
+ void AddedToWidget() override;
+
+ private:
+ base::string16 GetMessage() const;
+ void SetBigMessageLabel();
+ void SetMessageLabel();
+ void SetBigImage();
+
+ void StartPluginVmImageDownload();
+
plugin_vm::PluginVmImageManager* plugin_vm_image_manager_ = nullptr;
views::Label* big_message_label_ = nullptr;
views::Label* message_label_ = nullptr;
diff --git a/chrome/browser/ui/views/plugin_vm/plugin_vm_launcher_view_browsertest.cc b/chrome/browser/ui/views/plugin_vm/plugin_vm_launcher_view_browsertest.cc
index fa6442f..d11e36f 100644
--- a/chrome/browser/ui/views/plugin_vm/plugin_vm_launcher_view_browsertest.cc
+++ b/chrome/browser/ui/views/plugin_vm/plugin_vm_launcher_view_browsertest.cc
@@ -4,26 +4,100 @@
#include "chrome/browser/ui/views/plugin_vm/plugin_vm_launcher_view.h"
+#include "base/bind.h"
+#include "base/files/file_util.h"
+#include "base/threading/thread_restrictions.h"
+#include "chrome/browser/chromeos/plugin_vm/plugin_vm_pref_names.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/test/test_browser_dialog.h"
#include "chrome/grit/generated_resources.h"
#include "components/download/public/background_service/download_metadata.h"
+#include "components/prefs/pref_service.h"
+#include "components/prefs/scoped_user_pref_update.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/views/window/dialog_client_view.h"
+namespace {
+
+const char kZipFile[] = "/downloads/a_zip_file.zip";
+const char kZippedFile[] = "a_file.txt";
+const char kZipFileHash[] =
+ "bb077522e6c6fec07cf863ca44d5701935c4bc36ed12ef154f4cc22df70aec18";
+const char kNonMatchingHash[] =
+ "842841a4c75a55ad050d686f4ea5f77e83ae059877fe9b6946aa63d3d057ed32";
+const char kJpgFile[] = "/downloads/image.jpg";
+const char kJpgFileHash[] =
+ "01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b";
+
+} // namespace
+
+class PluginVmLauncherViewForTesting : public PluginVmLauncherView {
+ public:
+ explicit PluginVmLauncherViewForTesting(Profile* profile)
+ : PluginVmLauncherView(profile) {}
+
+ void AddSetupIsFinishedCallbackForTesting(base::RepeatingClosure callback) {
+ setup_is_finished_callback_for_testing_ = callback;
+ }
+
+ private:
+ base::RepeatingClosure setup_is_finished_callback_for_testing_;
+
+ void OnStateUpdated() override {
+ PluginVmLauncherView::OnStateUpdated();
+
+ if (state_ == State::FINISHED || state_ == State::ERROR) {
+ if (setup_is_finished_callback_for_testing_)
+ setup_is_finished_callback_for_testing_.Run();
+ }
+ }
+};
+
class PluginVmLauncherViewBrowserTest : public DialogBrowserTest {
public:
+ class SetupObserver {
+ public:
+ void OnSetupFinished() {
+ if (closure_) {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
+ std::move(closure_));
+ }
+ }
+
+ void WaitForSetupToFinish() {
+ base::RunLoop run_loop;
+ closure_ = run_loop.QuitClosure();
+ run_loop.Run();
+ }
+
+ private:
+ base::OnceClosure closure_;
+ };
+
PluginVmLauncherViewBrowserTest() {}
void SetUp() override { DialogBrowserTest::SetUp(); }
+ void SetUpOnMainThread() override {
+ embedded_test_server()->ServeFilesFromSourceDirectory("chrome/test/data");
+ ASSERT_TRUE(embedded_test_server()->Start());
+ }
+
// DialogBrowserTest:
void ShowUi(const std::string& name) override {
- view_ = new PluginVmLauncherView(browser()->profile());
+ view_ = new PluginVmLauncherViewForTesting(browser()->profile());
+ setup_observer_ = new SetupObserver();
+ view_->AddSetupIsFinishedCallbackForTesting(base::BindRepeating(
+ &SetupObserver::OnSetupFinished, base::Unretained(setup_observer_)));
views::DialogDelegate::CreateDialogWidget(view_, nullptr, nullptr);
}
+ protected:
+ PluginVmLauncherViewForTesting* view_;
+ SetupObserver* setup_observer_;
+
bool HasAcceptButton() {
return view_->GetDialogClientView()->ok_button() != nullptr;
}
@@ -32,14 +106,6 @@
return view_->GetDialogClientView()->cancel_button() != nullptr;
}
- void CheckSetupIsInProgress() {
- EXPECT_TRUE(HasCancelButton());
- EXPECT_FALSE(HasAcceptButton());
- EXPECT_EQ(view_->GetBigMessage(),
- l10n_util::GetStringUTF16(
- IDS_PLUGIN_VM_LAUNCHER_ENVIRONMENT_SETTING_TITLE));
- }
-
void CheckSetupFailed() {
EXPECT_TRUE(HasAcceptButton());
EXPECT_TRUE(HasCancelButton());
@@ -47,19 +113,45 @@
l10n_util::GetStringUTF16(IDS_PLUGIN_VM_LAUNCHER_RETRY_BUTTON));
EXPECT_EQ(view_->GetBigMessage(),
l10n_util::GetStringUTF16(IDS_PLUGIN_VM_LAUNCHER_ERROR_TITLE));
+
+ base::FilePath plugin_vm_image_dir =
+ browser()
+ ->profile()
+ ->GetPath()
+ .AppendASCII(plugin_vm::kCrosvmDir)
+ .AppendASCII(plugin_vm::kPvmDir)
+ .AppendASCII(plugin_vm::kPluginVmImageDir);
+ base::ScopedAllowBlockingForTesting allow_blocking;
+ EXPECT_FALSE(base::DirectoryExists(plugin_vm_image_dir));
}
- void CheckSetupIsCompleted() {
+ void CheckSetupIsFinishedSuccessfully() {
EXPECT_TRUE(HasAcceptButton());
EXPECT_FALSE(HasCancelButton());
EXPECT_EQ(view_->GetDialogButtonLabel(ui::DIALOG_BUTTON_OK),
l10n_util::GetStringUTF16(IDS_PLUGIN_VM_LAUNCHER_LAUNCH_BUTTON));
EXPECT_EQ(view_->GetBigMessage(),
l10n_util::GetStringUTF16(IDS_PLUGIN_VM_LAUNCHER_FINISHED_TITLE));
+
+ base::FilePath plugin_vm_image_dir =
+ browser()
+ ->profile()
+ ->GetPath()
+ .AppendASCII(plugin_vm::kCrosvmDir)
+ .AppendASCII(plugin_vm::kPvmDir)
+ .AppendASCII(plugin_vm::kPluginVmImageDir);
+ base::ScopedAllowBlockingForTesting allow_blocking;
+ EXPECT_TRUE(base::DirectoryExists(plugin_vm_image_dir));
+ EXPECT_TRUE(base::PathExists(plugin_vm_image_dir.AppendASCII(kZippedFile)));
}
- protected:
- PluginVmLauncherView* view_;
+ void SetPluginVmImagePref(std::string url, std::string hash) {
+ DictionaryPrefUpdate update(browser()->profile()->GetPrefs(),
+ plugin_vm::prefs::kPluginVmImage);
+ base::DictionaryValue* plugin_vm_image = update.Get();
+ plugin_vm_image->SetKey("url", base::Value(url));
+ plugin_vm_image->SetKey("hash", base::Value(hash));
+ }
private:
DISALLOW_COPY_AND_ASSIGN(PluginVmLauncherViewBrowserTest);
@@ -70,65 +162,64 @@
ShowAndVerifyUi();
}
-IN_PROC_BROWSER_TEST_F(PluginVmLauncherViewBrowserTest, SetupCompleted) {
- // TODO(https://crbug.com/904852): Add a proper end-to-end test that
- // checks that file specified by PluginVmImage user policy is being
- // downloaded and unzipped to the specified location.
+IN_PROC_BROWSER_TEST_F(PluginVmLauncherViewBrowserTest,
+ SetupShouldFinishSuccessfully) {
+ SetPluginVmImagePref(embedded_test_server()->GetURL(kZipFile).spec(),
+ kZipFileHash);
ShowUi("default");
EXPECT_NE(nullptr, view_);
- CheckSetupIsInProgress();
+ setup_observer_->WaitForSetupToFinish();
- view_->GetPluginVmImageManagerForTesting()->OnDownloadCompleted(
- download::CompletionInfo());
-
- CheckSetupIsInProgress();
-
- view_->GetPluginVmImageManagerForTesting()->OnUnzipped(true /* success */);
-
- CheckSetupIsCompleted();
-
- view_->GetDialogClientView()->AcceptWindow();
-
- EXPECT_TRUE(view_->GetWidget()->IsClosed());
+ CheckSetupIsFinishedSuccessfully();
}
IN_PROC_BROWSER_TEST_F(PluginVmLauncherViewBrowserTest,
- RetryAfterDownloadFailed) {
+ SetupShouldFailAsHashesDoNotMatch) {
+ SetPluginVmImagePref(embedded_test_server()->GetURL(kZipFile).spec(),
+ kNonMatchingHash);
+
ShowUi("default");
EXPECT_NE(nullptr, view_);
- CheckSetupIsInProgress();
-
- view_->GetPluginVmImageManagerForTesting()->OnDownloadFailed();
+ setup_observer_->WaitForSetupToFinish();
CheckSetupFailed();
+}
+
+IN_PROC_BROWSER_TEST_F(PluginVmLauncherViewBrowserTest,
+ SetupShouldFailAsUnzippingFails) {
+ SetPluginVmImagePref(embedded_test_server()->GetURL(kJpgFile).spec(),
+ kJpgFileHash);
+
+ ShowUi("default");
+ EXPECT_NE(nullptr, view_);
+
+ setup_observer_->WaitForSetupToFinish();
+
+ CheckSetupFailed();
+}
+
+IN_PROC_BROWSER_TEST_F(PluginVmLauncherViewBrowserTest,
+ CouldRetryAfterFailedSetup) {
+ SetPluginVmImagePref(embedded_test_server()->GetURL(kZipFile).spec(),
+ kNonMatchingHash);
+
+ ShowUi("default");
+ EXPECT_NE(nullptr, view_);
+
+ setup_observer_->WaitForSetupToFinish();
+
+ CheckSetupFailed();
+
+ SetPluginVmImagePref(embedded_test_server()->GetURL(kZipFile).spec(),
+ kZipFileHash);
// Retry button clicked to retry the download.
view_->GetDialogClientView()->AcceptWindow();
- CheckSetupIsInProgress();
-}
+ setup_observer_->WaitForSetupToFinish();
-IN_PROC_BROWSER_TEST_F(PluginVmLauncherViewBrowserTest,
- RetryAfterUnzippingFailed) {
- ShowUi("default");
- EXPECT_NE(nullptr, view_);
-
- CheckSetupIsInProgress();
-
- view_->GetPluginVmImageManagerForTesting()->OnDownloadCompleted(
- download::CompletionInfo());
-
- CheckSetupIsInProgress();
-
- view_->GetPluginVmImageManagerForTesting()->OnUnzipped(false /* success */);
-
- CheckSetupFailed();
-
- // Retry button clicked to retry the download.
- view_->GetDialogClientView()->AcceptWindow();
-
- CheckSetupIsInProgress();
+ CheckSetupIsFinishedSuccessfully();
}