summaryrefslogtreecommitdiffstats
path: root/chrome/browser/diagnostics
diff options
context:
space:
mode:
authorcpu@chromium.org <cpu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-11-19 04:50:58 +0000
committercpu@chromium.org <cpu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-11-19 04:50:58 +0000
commitaedc9960f80930f1c5ed1059660f822533792bb9 (patch)
treeaeff6028eefc73c5c88dd02a73f6ce821197ba66 /chrome/browser/diagnostics
parent74cda952e5725e71f2294d741ecde4424e760f48 (diff)
downloadchromium_src-aedc9960f80930f1c5ed1059660f822533792bb9.zip
chromium_src-aedc9960f80930f1c5ed1059660f822533792bb9.tar.gz
chromium_src-aedc9960f80930f1c5ed1059660f822533792bb9.tar.bz2
Introducing the diagnostic model classes
Chrome diagnostics wants to be a MVC, this is the classes that compose the model part. BUG=27885 TEST=included unit tests Review URL: http://codereview.chromium.org/385144 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@32494 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/diagnostics')
-rw-r--r--chrome/browser/diagnostics/diagnostics_model.cc149
-rw-r--r--chrome/browser/diagnostics/diagnostics_model.h75
-rw-r--r--chrome/browser/diagnostics/diagnostics_model_unittest.cc76
-rw-r--r--chrome/browser/diagnostics/diagnostics_test.h80
4 files changed, 380 insertions, 0 deletions
diff --git a/chrome/browser/diagnostics/diagnostics_model.cc b/chrome/browser/diagnostics/diagnostics_model.cc
new file mode 100644
index 0000000..82168e0
--- /dev/null
+++ b/chrome/browser/diagnostics/diagnostics_model.cc
@@ -0,0 +1,149 @@
+// Copyright (c) 2009 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/diagnostics/diagnostics_model.h"
+
+#include <algorithm>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/file_util.h"
+#include "base/stl_util-inl.h"
+#include "base/string_util.h"
+#include "base/path_service.h"
+#include "chrome/browser/diagnostics/diagnostics_test.h"
+#include "chrome/common/chrome_paths.h"
+
+namespace {
+
+// Embodies the commonalities of the model across platforms. It manages the
+// list of tests and can loop over them. The main job of the platform specific
+// code becomes:
+// 1- Inserting the appropiate tests into |tests_|
+// 2- Overriding RunTest() to wrap it with the appropiate fatal exception
+// handler for the OS.
+// This class owns the all the tests and will only delete them upon
+// destruction.
+class DiagnosticsModelImpl : public DiagnosticsModel {
+ public:
+ DiagnosticsModelImpl() : tests_run_(0) {
+ }
+
+ ~DiagnosticsModelImpl() {
+ STLDeleteElements(&tests_);
+ }
+
+ virtual int GetTestRunCount() {
+ return tests_run_;
+ }
+
+ virtual int GetTestAvailableCount() {
+ return tests_.size();
+ }
+
+ virtual void RunAll(DiagnosticsModel::Observer* observer) {
+ size_t test_count = tests_.size();
+ for (size_t ix = 0; ix != test_count; ++ix) {
+ bool do_next = RunTest(tests_[ix], observer);
+ ++tests_run_;
+ if (!do_next)
+ break;
+ }
+ observer->OnDoneAll(this);
+ }
+
+ virtual TestInfo& GetTest(size_t id) {
+ return *tests_[id];
+ }
+
+ protected:
+ // Run a particular test. Return false if no other tests should be run.
+ virtual bool RunTest(DiagnosticTest* test, Observer* observer) {
+ return test->Execute(observer, this);
+ }
+
+ typedef std::vector<DiagnosticTest*> TestArray;
+ TestArray tests_;
+ int tests_run_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(DiagnosticsModelImpl);
+};
+
+// Simple basic diagnostic test. Check that the user's data directory
+// exists. This test works for all platforms.
+// TODO(cpu): Move to its final place.
+// TODO(cpu): Localize strings.
+class UserPathsTest : public DiagnosticTest {
+ public:
+ UserPathsTest() : DiagnosticTest(ASCIIToUTF16("User Directory")) {}
+
+ // Not used at the moment but it allows one test to query the status
+ // of another test so we can build test dependencies.
+ virtual int GetId() { return 0; }
+
+ virtual bool ExecuteImpl(DiagnosticsModel::Observer* observer) {
+ FilePath data_dir;
+ if (!PathService::Get(chrome::DIR_USER_DATA, &data_dir)) {
+ RecordStopFailure(ASCIIToUTF16("Path provider failure"));
+ return false;
+ }
+ if (!file_util::PathExists(data_dir)) {
+ RecordFailure(ASCIIToUTF16("No user data dir found"));
+ return true;
+ }
+ RecordSuccess(ASCIIToUTF16("Directory found"));
+ return true;
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(UserPathsTest);
+};
+
+// Each platform can have their own tests. For the time being there is only
+// one test that works on all platforms.
+#if defined(OS_WIN)
+class DiagnosticsModelWin : public DiagnosticsModelImpl {
+ public:
+ DiagnosticsModelWin() {
+ tests_.push_back(new UserPathsTest());
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(DiagnosticsModelWin);
+};
+
+#elif defined(OS_MACOSX)
+class DiagnosticsModelMac : public DiagnosticsModelImpl {
+ public:
+ DiagnosticsModelMac() {
+ tests_.push_back(new UserPathsTest());
+ }
+ private:
+ DISALLOW_COPY_AND_ASSIGN(DiagnosticsModelMac);
+};
+
+#elif defined(OS_LINUX)
+class DiagnosticsModelLinux : public DiagnosticsModelImpl {
+ public:
+ DiagnosticsModelLinux() {
+ tests_.push_back(new UserPathsTest());
+ }
+ private:
+ DISALLOW_COPY_AND_ASSIGN(DiagnosticsModelLinux);
+};
+
+#endif
+
+} // namespace
+
+DiagnosticsModel* MakeDiagnosticsModel() {
+#if defined(OS_WIN)
+ return new DiagnosticsModelWin();
+#elif defined(OS_MACOSX)
+ return new DiagnosticsModelMac();
+#elif defined(OS_LINUX)
+ return new DiagnosticsModelLinux();
+#endif
+}
diff --git a/chrome/browser/diagnostics/diagnostics_model.h b/chrome/browser/diagnostics/diagnostics_model.h
new file mode 100644
index 0000000..bb977ef
--- /dev/null
+++ b/chrome/browser/diagnostics/diagnostics_model.h
@@ -0,0 +1,75 @@
+// Copyright (c) 2009 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.
+
+#ifndef CHROME_BROWSER_DIAGNOSTICS_DIAGNOSTICS_MODEL_H_
+#define CHROME_BROWSER_DIAGNOSTICS_DIAGNOSTICS_MODEL_H_
+
+#include "base/string16.h"
+
+// The chrome diagnostics system is a model-view-controller system. The Model
+// responsible for holding and running the individual tests and providing a
+// uniform interface for quering the outcome.
+// TODO (CPU): The view and the controller are not yet built.
+class DiagnosticsModel {
+ public:
+ // A particular test can be in one of the following states.
+ enum TestResult {
+ TEST_NOT_RUN,
+ TEST_RUNNING,
+ TEST_OK,
+ TEST_FAIL_CONTINUE,
+ TEST_FAIL_STOP,
+ };
+
+ // Observer derived form this class which provides a way to be notified of
+ // changes to the model as the tests are run. For all the callbacks |id|
+ // is the index of the test in question and information can be obtained by
+ // calling model->GetTest(id).
+ class Observer {
+ public:
+ virtual ~Observer() {}
+ // Called once upon test start with |percent| = 0 and periodically as the
+ // test progresses. There is no cancelation method.
+ virtual void OnProgress(int id, int percent, DiagnosticsModel* model) = 0;
+ // Called if the test in question cannot be run.
+ virtual void OnSkipped(int id, DiagnosticsModel* model) = 0;
+ // Called when the test has finished regardless of outcome.
+ virtual void OnFinished(int id, DiagnosticsModel* model) = 0;
+ // Called once all the test are run.
+ virtual void OnDoneAll(DiagnosticsModel* model) = 0;
+ };
+
+ // Encapsulates what you can know about a given test.
+ class TestInfo {
+ public:
+ virtual ~TestInfo() {}
+ // A human readable, localized string that tells you what is being tested.
+ virtual string16 GetTitle() = 0;
+ // The result of running the test. If called before the test is ran the
+ // answer is TEST_NOT_RUN.
+ virtual TestResult GetResult() = 0;
+ // A human readable, localized string that tells you what happened. If
+ // called before the test is run it returns the empty string.
+ virtual string16 GetAdditionalInfo() = 0;
+ };
+
+ virtual ~DiagnosticsModel() {}
+ // Returns how many tests have been run.
+ virtual int GetTestRunCount() = 0;
+ // Returns how many tests are available. This value never changes.
+ virtual int GetTestAvailableCount() =0;
+ // Runs all the availabe tests, the |observer| callbacks will be called as
+ // the test progress and thus cannot be null.
+ virtual void RunAll(DiagnosticsModel::Observer* observer) = 0;
+ // Get the information for a particular test. Do not keep a pointer to the
+ // returned object.
+ virtual TestInfo& GetTest(size_t id) = 0;
+};
+
+// The factory for the model. The main purpose is to hide the creation of
+// different models for different platforms.
+DiagnosticsModel* MakeDiagnosticsModel();
+
+
+#endif // CHROME_BROWSER_DIAGNOSTICS_DIAGNOSTICS_MODEL_H_
diff --git a/chrome/browser/diagnostics/diagnostics_model_unittest.cc b/chrome/browser/diagnostics/diagnostics_model_unittest.cc
new file mode 100644
index 0000000..f6a7697
--- /dev/null
+++ b/chrome/browser/diagnostics/diagnostics_model_unittest.cc
@@ -0,0 +1,76 @@
+// Copyright (c) 2009 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/diagnostics/diagnostics_model.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+// Basic harness to adquire and release the Diagnostic model object.
+class DiagnosticsModelTest : public testing::Test {
+ protected:
+ DiagnosticsModelTest() : model_(NULL) { }
+
+ virtual ~DiagnosticsModelTest() { }
+
+ virtual void SetUp() {
+ model_ = MakeDiagnosticsModel();
+ ASSERT_TRUE(model_ != NULL);
+ }
+
+ virtual void TearDown() {
+ delete model_;
+ }
+
+ DiagnosticsModel* model_;
+};
+
+// The test observer is used to know if the callbacks are being called.
+class UTObserver: public DiagnosticsModel::Observer {
+ public:
+ UTObserver() : done_(false), progress_called_(0) {}
+
+ virtual void OnProgress(int id, int percent, DiagnosticsModel* model) {
+ EXPECT_TRUE(model != NULL);
+ ++progress_called_;
+ }
+
+ virtual void OnSkipped(int id, DiagnosticsModel* model) {
+ EXPECT_TRUE(model != NULL);
+ }
+
+ virtual void OnFinished(int id, DiagnosticsModel* model) {
+ EXPECT_TRUE(model != NULL);
+ }
+
+ virtual void OnDoneAll(DiagnosticsModel* model) {
+ done_ = true;
+ EXPECT_TRUE(model != NULL);
+ }
+
+ bool done() const { return done_; }
+
+ int progress_called() const { return progress_called_; }
+
+ private:
+ bool done_;
+ int progress_called_;
+};
+
+// Test that the initial state is correct. We only have one test
+TEST_F(DiagnosticsModelTest, BeforeRun) {
+ int available = model_->GetTestAvailableCount();
+ EXPECT_EQ(1, available);
+ EXPECT_EQ(0, model_->GetTestRunCount());
+ EXPECT_EQ(DiagnosticsModel::TEST_NOT_RUN, model_->GetTest(0).GetResult());
+}
+
+// Run all the tests, verify that the basic callbacks are run and that the
+// final state is correct.
+TEST_F(DiagnosticsModelTest, RunAll) {
+ UTObserver observer;
+ EXPECT_FALSE(observer.done());
+ model_->RunAll(&observer);
+ EXPECT_TRUE(observer.done());
+ EXPECT_GT(observer.progress_called(), 0);
+ EXPECT_EQ(1, model_->GetTestRunCount());
+}
diff --git a/chrome/browser/diagnostics/diagnostics_test.h b/chrome/browser/diagnostics/diagnostics_test.h
new file mode 100644
index 0000000..8d12bc5
--- /dev/null
+++ b/chrome/browser/diagnostics/diagnostics_test.h
@@ -0,0 +1,80 @@
+// Copyright (c) 2009 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.
+
+#ifndef CHROME_BROWSER_DIAGNOSTICS_DIAGNOSTICS_TEST_H_
+#define CHROME_BROWSER_DIAGNOSTICS_DIAGNOSTICS_TEST_H_
+
+#include "base/string16.h"
+#include "chrome/browser/diagnostics/diagnostics_model.h"
+
+// Represents a single diagnostic test and encapsulates the common
+// functionality across platforms as well.
+// It also Implements the TestInfo interface providing the storage
+// for the outcome of the test.
+// Specific tests need (minimally) only to:
+// 1- override ExecuteImpl() to imnplement the test.
+// 2- call RecordStopFailure() or RecordFailure() or RecordSuccess()
+// at the end of the test.
+// 3- Optionally call observer->OnProgress() if the test is long.
+// 4- Optionally call observer->OnSkipped() if the test cannot be run.
+class DiagnosticTest : public DiagnosticsModel::TestInfo {
+ public:
+ // |title| is the human readable, localized string that says that
+ // the objective of the test is.
+ explicit DiagnosticTest(const string16& title)
+ : title_(title), result_(DiagnosticsModel::TEST_NOT_RUN) {}
+
+ virtual ~DiagnosticTest() {}
+
+ // Runs the test. Returning false signals that no more tests should be run.
+ // The actual outcome of the test should be set using the RecordXX functions.
+ bool Execute(DiagnosticsModel::Observer* observer, DiagnosticsModel* model) {
+ result_ = DiagnosticsModel::TEST_RUNNING;
+ observer->OnProgress(GetId(), 0, model);
+ return ExecuteImpl(observer);
+ }
+
+ virtual string16 GetTitle() {
+ return title_;
+ }
+
+ virtual DiagnosticsModel::TestResult GetResult() {
+ return result_;
+ }
+
+ virtual string16 GetAdditionalInfo() {
+ return additional_info_;
+ }
+
+ void RecordStopFailure(const string16& additional_info) {
+ RecordOutcome(additional_info, DiagnosticsModel::TEST_FAIL_STOP);
+ }
+
+ void RecordFailure(const string16& additional_info) {
+ RecordOutcome(additional_info, DiagnosticsModel::TEST_FAIL_CONTINUE);
+ }
+
+ void RecordSuccess(const string16& additional_info) {
+ RecordOutcome(additional_info, DiagnosticsModel::TEST_OK);
+ }
+
+ void RecordOutcome(const string16& additional_info,
+ DiagnosticsModel::TestResult result) {
+ additional_info_ = additional_info;
+ result_ = result;
+ }
+
+ protected:
+ // The id needs to be overriden by derived classes and must uniquely
+ // identify this test so other test can refer to it.
+ virtual int GetId() = 0;
+ // Derived classes override this method do perform the actual test.
+ virtual bool ExecuteImpl(DiagnosticsModel::Observer* observer) = 0;
+
+ string16 title_;
+ string16 additional_info_;
+ DiagnosticsModel::TestResult result_;
+};
+
+#endif // CHROME_BROWSER_DIAGNOSTICS_DIAGNOSTICS_TEST_H_