crash: Remove glib from crash_reporter

As part of the minimization effort, refactor crash_reporter code to
not depend directly on glib.

BUG=brillo:87, brillo:88, chromium:435314
TEST=`FEATURES=test emerge-panther libchromeos debugd crash-reporter`
TEST=Enabled crash reports; Browsed to chrome://crash; crash files \
     generated; `FORCE_OFFICIAL=1 SECONDS_SEND_SPREAD=1 crash_sender` \
     /var/log/messages shows crash id, report shows all expected files
TEST=`cbuildbot --remote -p chromiumos/platform2 amd64-generic-full`
CQ-DEPEND=I00331e0bf29195b41cd84d4495ab47738a5a41de
CQ-DEPEND=I9df752d8995773adb56fab34dd97626f3ddf1765

Change-Id: I48b366198a7f89ca55259603cf8470e4d59321bf
Reviewed-on: https://chromium-review.googlesource.com/246441
Reviewed-by: Dan Erat <derat@chromium.org>
Tested-by: Steve Fung <stevefung@chromium.org>
Commit-Queue: Steve Fung <stevefung@chromium.org>
diff --git a/crash_reporter/chrome_collector.cc b/crash_reporter/chrome_collector.cc
index 8dd56fb..e32ef56 100644
--- a/crash_reporter/chrome_collector.cc
+++ b/crash_reporter/chrome_collector.cc
@@ -4,10 +4,10 @@
 
 #include "crash-reporter/chrome_collector.h"
 
-#include <glib.h>
 #include <pcrecpp.h>
 #include <stdint.h>
 
+#include <map>
 #include <string>
 #include <vector>
 
@@ -15,6 +15,7 @@
 #include <base/logging.h>
 #include <base/strings/string_number_conversions.h>
 #include <base/strings/string_util.h>
+#include <chromeos/data_encoding.h>
 #include <chromeos/dbus/dbus.h>
 #include <chromeos/dbus/service_constants.h>
 #include <chromeos/process.h>
@@ -51,39 +52,20 @@
 
 // Gets the GPU's error state from debugd and writes it to |error_state_path|.
 // Returns true on success.
-bool GetDriErrorState(const FilePath &error_state_path) {
-  chromeos::dbus::BusConnection dbus = chromeos::dbus::GetSystemBusConnection();
-  if (!dbus.HasConnection()) {
-    LOG(ERROR) << "Error connecting to system D-Bus";
+bool GetDriErrorState(const FilePath &error_state_path,
+                      org::chromium::debugdProxy *proxy) {
+  chromeos::ErrorPtr error;
+  std::string error_state_str;
+
+  proxy->GetLog("i915_error_state", &error_state_str, &error);
+
+  if (error) {
+    LOG(ERROR) << "Error calling D-Bus proxy call to interface "
+               << "'" << proxy->GetObjectPath().value() << "':"
+               << error->GetMessage();
     return false;
   }
 
-  chromeos::dbus::Proxy proxy(dbus,
-                              debugd::kDebugdServiceName,
-                              debugd::kDebugdServicePath,
-                              debugd::kDebugdInterface);
-  if (!proxy) {
-    LOG(ERROR) << "Error creating D-Bus proxy to interface "
-               << "'" << debugd::kDebugdServiceName << "'";
-    return false;
-  }
-
-  chromeos::glib::ScopedError error;
-  gchar *error_state = nullptr;
-  if (!dbus_g_proxy_call(proxy.gproxy(), debugd::kGetLog,
-                         &chromeos::Resetter(&error).lvalue(),
-                         G_TYPE_STRING, "i915_error_state", G_TYPE_INVALID,
-                         G_TYPE_STRING, &error_state, G_TYPE_INVALID)) {
-    LOG(ERROR) << "Error performing D-Bus proxy call "
-               << "'" << debugd::kGetLog << "'"
-               << ": " << (error ? error->message : "");
-    g_free(error_state);
-    return false;
-  }
-
-  std::string error_state_str(error_state);
-  g_free(error_state);
-
   if (error_state_str == "<empty>")
     return false;
 
@@ -94,17 +76,23 @@
     return false;
   }
 
-  gsize len;
-  guchar *decoded_error_state =
-      g_base64_decode(error_state_str.c_str() + kBase64HeaderLength, &len);
+  std::string decoded_error_state;
 
-  int written =
-      base::WriteFile(error_state_path,
-                      reinterpret_cast<const char *>(decoded_error_state), len);
-  g_free(decoded_error_state);
+  if (!chromeos::data_encoding::Base64Decode(
+      error_state_str.c_str() + kBase64HeaderLength,
+      &decoded_error_state)) {
+    LOG(ERROR) << "Could not decode i915_error_state";
+    return false;
+  }
 
-  if (written < 0 || (gsize)written != len) {
-    LOG(ERROR) << "Could not write file " << error_state_path.value();
+  int written = base::WriteFile(error_state_path,
+                                decoded_error_state.c_str(),
+                                decoded_error_state.length());
+  if (written < 0 ||
+      static_cast<size_t>(written) != decoded_error_state.length()) {
+    LOG(ERROR) << "Could not write file " << error_state_path.value()
+               << " Written: " << written << " Len: "
+               << decoded_error_state.length();
     base::DeleteFile(error_state_path, false);
     return false;
   }
@@ -208,6 +196,13 @@
   return true;
 }
 
+void ChromeCollector::SetUpDBus() {
+  CrashCollector::SetUpDBus();
+
+  debugd_proxy_.reset(
+      new org::chromium::debugdProxy(bus_, debugd::kDebugdServiceName));
+}
+
 bool ChromeCollector::ParseCrashLog(const std::string &data,
                                     const FilePath &dir,
                                     const FilePath &minidump,
@@ -325,11 +320,14 @@
       base::DeleteFile(chrome_log_path, false /* recursive */);
   }
 
-  // Now get the GPU state from debugd.
-  const FilePath dri_error_state_path =
-      GetCrashPath(dir, basename, kGpuStateFilename);
-  if (GetDriErrorState(dri_error_state_path))
-    logs[kGpuStateFilename] = dri_error_state_path;
+  // For unit testing, debugd_proxy_ isn't initialized, so skip attempting to
+  // get the GPU error state from debugd.
+  if (debugd_proxy_) {
+    const FilePath dri_error_state_path =
+        GetCrashPath(dir, basename, kGpuStateFilename);
+    if (GetDriErrorState(dri_error_state_path, debugd_proxy_.get()))
+      logs[kGpuStateFilename] = dri_error_state_path;
+  }
 
   return logs;
 }
diff --git a/crash_reporter/chrome_collector.h b/crash_reporter/chrome_collector.h
index 566b5a8..0b58c19 100644
--- a/crash_reporter/chrome_collector.h
+++ b/crash_reporter/chrome_collector.h
@@ -5,6 +5,7 @@
 #ifndef CRASH_REPORTER_CHROME_COLLECTOR_H_
 #define CRASH_REPORTER_CHROME_COLLECTOR_H_
 
+#include <map>
 #include <string>
 
 #include <base/files/file_path.h>
@@ -12,6 +13,7 @@
 #include <gtest/gtest_prod.h>  // for FRIEND_TEST
 
 #include "crash-reporter/crash_collector.h"
+#include "debugd/dbus-proxies.h"
 
 class SystemLogging;
 
@@ -30,6 +32,9 @@
                    const std::string &uid_string,
                    const std::string &exe_name);
 
+ protected:
+  void SetUpDBus() override;
+
  private:
   friend class ChromeCollectorTest;
   FRIEND_TEST(ChromeCollectorTest, GoodValues);
@@ -58,6 +63,9 @@
 
   FILE *output_file_ptr_;
 
+  // D-Bus proxy for debugd interface.  Unset in unit tests.
+  std::unique_ptr<org::chromium::debugdProxy> debugd_proxy_;
+
   DISALLOW_COPY_AND_ASSIGN(ChromeCollector);
 };
 
diff --git a/crash_reporter/chrome_collector_test.cc b/crash_reporter/chrome_collector_test.cc
index d44c82c..0d6a7ce 100644
--- a/crash_reporter/chrome_collector_test.cc
+++ b/crash_reporter/chrome_collector_test.cc
@@ -10,6 +10,7 @@
 #include <base/files/file_util.h>
 #include <base/files/scoped_temp_dir.h>
 #include <chromeos/syslog_logging.h>
+#include <gmock/gmock.h>
 #include <gtest/gtest.h>
 
 using base::FilePath;
@@ -40,6 +41,11 @@
 
 }  // namespace
 
+class ChromeCollectorMock : public ChromeCollector {
+ public:
+  MOCK_METHOD0(SetUpDBus, void());
+};
+
 class ChromeCollectorTest : public ::testing::Test {
  protected:
   void ExpectFileEquals(const char *golden,
@@ -49,10 +55,12 @@
     EXPECT_EQ(golden, contents);
   }
 
-  ChromeCollector collector_;
+  ChromeCollectorMock collector_;
 
  private:
   void SetUp() override {
+    EXPECT_CALL(collector_, SetUpDBus()).WillRepeatedly(testing::Return());
+
     collector_.Initialize(CountCrash, IsMetrics);
     chromeos::ClearLog();
   }
diff --git a/crash_reporter/crash-reporter.gyp b/crash_reporter/crash-reporter.gyp
index b42657b..6e1ceac 100644
--- a/crash_reporter/crash-reporter.gyp
+++ b/crash_reporter/crash-reporter.gyp
@@ -39,6 +39,28 @@
         'unclean_shutdown_collector.cc',
         'user_collector.cc',
       ],
+      'actions': [
+        {
+          'action_name': 'generate-session-manager-proxies',
+          'variables': {
+            'proxy_output_file': 'include/session_manager/dbus-proxies.h'
+          },
+          'sources': [
+            '../login_manager/dbus_bindings/org.chromium.SessionManager.xml',
+          ],
+          'includes': ['../common-mk/generate-dbus-proxies.gypi'],
+        },
+        {
+          'action_name': 'generate-debugd-proxies',
+          'variables': {
+            'proxy_output_file': 'include/debugd/dbus-proxies.h'
+          },
+          'sources': [
+            '../debugd/share/org.chromium.debugd.xml',
+          ],
+          'includes': ['../common-mk/generate-dbus-proxies.gypi'],
+        },
+      ],
     },
     {
       'target_name': 'crash_reporter',
diff --git a/crash_reporter/crash_collector.cc b/crash_reporter/crash_collector.cc
index a53bff9..d67356d 100644
--- a/crash_reporter/crash_collector.cc
+++ b/crash_reporter/crash_collector.cc
@@ -18,9 +18,6 @@
 #include <utility>
 #include <vector>
 
-#include <dbus/dbus-glib-lowlevel.h>
-#include <glib.h>
-
 #include <base/files/file_util.h>
 #include <base/logging.h>
 #include <base/posix/eintr_wrapper.h>
@@ -92,6 +89,8 @@
 }
 
 CrashCollector::~CrashCollector() {
+  if (bus_)
+    bus_->ShutdownAndBlock();
 }
 
 void CrashCollector::Initialize(
@@ -102,6 +101,21 @@
 
   count_crash_function_ = count_crash_function;
   is_feedback_allowed_function_ = is_feedback_allowed_function;
+
+  SetUpDBus();
+}
+
+void CrashCollector::SetUpDBus() {
+  dbus::Bus::Options options;
+  options.bus_type = dbus::Bus::SYSTEM;
+
+  bus_ = new dbus::Bus(options);
+  CHECK(bus_->Connect());
+
+  session_manager_proxy_.reset(
+      new org::chromium::SessionManagerInterfaceProxy(
+          bus_,
+          login_manager::kSessionManagerInterface));
 }
 
 int CrashCollector::WriteNewFile(const FilePath &filename,
@@ -154,49 +168,19 @@
                                              extension.c_str()));
 }
 
-namespace {
+bool CrashCollector::GetActiveUserSessions(
+    std::map<std::string, std::string> *sessions) {
+  chromeos::ErrorPtr error;
+  session_manager_proxy_->RetrieveActiveSessions(sessions, &error);
 
-const char *GetGErrorMessage(const GError *error) {
-  if (!error)
-    return "Unknown error.";
-  return error->message;
-}
-
-}
-
-GHashTable *CrashCollector::GetActiveUserSessions() {
-  GHashTable *active_sessions = nullptr;
-
-  chromeos::dbus::BusConnection dbus = chromeos::dbus::GetSystemBusConnection();
-  if (!dbus.HasConnection()) {
-    LOG(ERROR) << "Error connecting to system D-Bus";
-    return active_sessions;
-  }
-  chromeos::dbus::Proxy proxy(dbus,
-                              login_manager::kSessionManagerServiceName,
-                              login_manager::kSessionManagerServicePath,
-                              login_manager::kSessionManagerInterface);
-  if (!proxy) {
-    LOG(ERROR) << "Error creating D-Bus proxy to interface "
-               << "'" << login_manager::kSessionManagerServiceName << "'";
-    return active_sessions;
+  if (error) {
+    LOG(ERROR) << "Error calling D-Bus proxy call to interface "
+               << "'" << session_manager_proxy_->GetObjectPath().value() << "':"
+               << error->GetMessage();
+    return false;
   }
 
-  // Request all the active sessions.
-  GError *gerror = nullptr;
-  if (!dbus_g_proxy_call(proxy.gproxy(),
-                         login_manager::kSessionManagerRetrieveActiveSessions,
-                         &gerror, G_TYPE_INVALID,
-                         DBUS_TYPE_G_STRING_STRING_HASHTABLE, &active_sessions,
-                         G_TYPE_INVALID)) {
-    LOG(ERROR) << "Error performing D-Bus proxy call "
-               << "'"
-               << login_manager::kSessionManagerRetrieveActiveSessions << "'"
-               << ": " << GetGErrorMessage(gerror);
-    return active_sessions;
-  }
-
-  return active_sessions;
+  return true;
 }
 
 FilePath CrashCollector::GetUserCrashPath() {
@@ -204,19 +188,14 @@
   // Ask the session manager for the active ones, then just run with the
   // first result we get back.
   FilePath user_path = FilePath(kFallbackUserCrashPath);
-  GHashTable *active_sessions = GetActiveUserSessions();
-  if (!active_sessions)
+  std::map<std::string, std::string> active_sessions;
+  if (!GetActiveUserSessions(&active_sessions)) {
+    LOG(ERROR) << "Could not get active user sessions, using default.";
     return user_path;
-
-  GList *list = g_hash_table_get_values(active_sessions);
-  if (list) {
-    const char *salted_path = static_cast<const char *>(list->data);
-    user_path = chromeos::cryptohome::home::GetHashedUserPath(salted_path)
-        .Append("crash");
-    g_list_free(list);
   }
 
-  g_hash_table_destroy(active_sessions);
+  user_path = chromeos::cryptohome::home::GetHashedUserPath(
+      active_sessions.begin()->second).Append("crash");
 
   return user_path;
 }
diff --git a/crash_reporter/crash_collector.h b/crash_reporter/crash_collector.h
index 68806d9..ef443d3 100644
--- a/crash_reporter/crash_collector.h
+++ b/crash_reporter/crash_collector.h
@@ -10,12 +10,13 @@
 #include <map>
 #include <string>
 
-#include <glib.h>
-
 #include <base/files/file_path.h>
 #include <base/macros.h>
+#include <base/memory/scoped_ptr.h>
 #include <gtest/gtest_prod.h>  // for FRIEND_TEST
 
+#include "session_manager/dbus-proxies.h"
+
 // User crash collector.
 class CrashCollector {
  public:
@@ -60,6 +61,9 @@
   // Set maximum enqueued crashes in a crash directory.
   static const int kMaxCrashDirectorySize;
 
+  // Set up D-Bus.
+  virtual void SetUpDBus();
+
   // Writes |data| of |size| to |filename|, which must be a new file.
   // If the file already exists or writing fails, return a negative value.
   // Otherwise returns the number of bytes written.
@@ -75,7 +79,8 @@
     forced_crash_directory_ = forced_directory;
   }
 
-  virtual GHashTable *GetActiveUserSessions();
+  virtual bool GetActiveUserSessions(
+      std::map<std::string, std::string> *sessions);
   base::FilePath GetUserCrashPath();
   base::FilePath GetCrashDirectoryInfo(uid_t process_euid,
                                  uid_t default_user_id,
@@ -161,7 +166,13 @@
   std::string lsb_release_;
   base::FilePath log_config_path_;
 
+  scoped_refptr<dbus::Bus> bus_;
+
  private:
+  // D-Bus proxy for session manager interface.
+  std::unique_ptr<org::chromium::SessionManagerInterfaceProxy>
+      session_manager_proxy_;
+
   DISALLOW_COPY_AND_ASSIGN(CrashCollector);
 };
 
diff --git a/crash_reporter/crash_collector_test.cc b/crash_reporter/crash_collector_test.cc
index 0ca3792..ce9af2b 100644
--- a/crash_reporter/crash_collector_test.cc
+++ b/crash_reporter/crash_collector_test.cc
@@ -5,8 +5,7 @@
 #include "crash-reporter/crash_collector_test.h"
 
 #include <unistd.h>
-
-#include <glib.h>
+#include <utility>
 
 #include <base/files/file_util.h>
 #include <base/strings/string_util.h>
@@ -19,6 +18,7 @@
 using base::FilePath;
 using base::StringPrintf;
 using chromeos::FindLog;
+using ::testing::Invoke;
 using ::testing::Return;
 
 namespace {
@@ -32,11 +32,20 @@
   return false;
 }
 
+bool GetActiveUserSessionsImpl(std::map<std::string, std::string> *sessions) {
+  char kUser[] = "chicken@butt.com";
+  char kHash[] = "hashcakes";
+  sessions->insert(std::pair<std::string, std::string>(kUser, kHash));
+  return true;
+}
+
 }  // namespace
 
 class CrashCollectorTest : public ::testing::Test {
  public:
   void SetUp() {
+    EXPECT_CALL(collector_, SetUpDBus()).WillRepeatedly(Return());
+
     collector_.Initialize(CountCrash, IsMetrics);
     test_dir_ = FilePath("test");
     base::CreateDirectory(test_dir_);
@@ -117,15 +126,8 @@
   EXPECT_EQ(kRootUid, directory_owner);
   EXPECT_EQ(kRootGid, directory_group);
 
-  // No need to destroy the hash as GetCrashDirectoryInfo() will do it for us.
-  GHashTable *active_sessions = g_hash_table_new(g_str_hash, g_str_equal);
-  char kUser[] = "chicken@butt.com";
-  char kHash[] = "hashcakes";
-  g_hash_table_insert(active_sessions,
-                      static_cast<gpointer>(kUser),
-                      static_cast<gpointer>(kHash));
-  EXPECT_CALL(collector_, GetActiveUserSessions())
-      .WillOnce(Return(active_sessions));
+  EXPECT_CALL(collector_, GetActiveUserSessions(testing::_))
+      .WillOnce(Invoke(&GetActiveUserSessionsImpl));
 
   EXPECT_EQ(collector_.IsUserSpecificDirectoryEnabled(), true);
 
diff --git a/crash_reporter/crash_collector_test.h b/crash_reporter/crash_collector_test.h
index 28811b0..8339fa0 100644
--- a/crash_reporter/crash_collector_test.h
+++ b/crash_reporter/crash_collector_test.h
@@ -7,14 +7,17 @@
 
 #include "crash-reporter/crash_collector.h"
 
-#include <glib.h>
+#include <map>
+#include <string>
 
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
 
 class CrashCollectorMock : public CrashCollector {
  public:
-  MOCK_METHOD0(GetActiveUserSessions, GHashTable*());
+  MOCK_METHOD0(SetUpDBus, void());
+  MOCK_METHOD1(GetActiveUserSessions,
+               bool(std::map<std::string, std::string> *sessions));
 };
 
 #endif  // CRASH_REPORTER_CRASH_COLLECTOR_TEST_H_
diff --git a/crash_reporter/crash_reporter.cc b/crash_reporter/crash_reporter.cc
index c5824aa..1528b3f 100644
--- a/crash_reporter/crash_reporter.cc
+++ b/crash_reporter/crash_reporter.cc
@@ -3,7 +3,6 @@
 // found in the LICENSE file.
 
 #include <fcntl.h>  // for open
-#include <glib-object.h>
 
 #include <string>
 #include <vector>
@@ -275,8 +274,6 @@
   chromeos::OpenLog(my_path.BaseName().value().c_str(), true);
   chromeos::InitLog(chromeos::kLogToSyslog);
 
-  ::g_type_init();
-
   KernelCollector kernel_collector;
   kernel_collector.Initialize(CountKernelCrash, IsFeedbackAllowed);
   UserCollector user_collector;
diff --git a/crash_reporter/kernel_collector_test.cc b/crash_reporter/kernel_collector_test.cc
index b067afd..48d94ea 100644
--- a/crash_reporter/kernel_collector_test.cc
+++ b/crash_reporter/kernel_collector_test.cc
@@ -52,6 +52,9 @@
   void SetUp() override {
     s_crashes = 0;
     s_metrics = true;
+
+    EXPECT_CALL(collector_, SetUpDBus()).WillRepeatedly(testing::Return());
+
     collector_.Initialize(CountCrash, IsMetrics);
     ASSERT_TRUE(scoped_temp_dir_.CreateUniqueTempDir());
     test_kcrash_ = scoped_temp_dir_.path().Append("kcrash");
diff --git a/crash_reporter/kernel_collector_test.h b/crash_reporter/kernel_collector_test.h
index 3219324..75ac01e 100644
--- a/crash_reporter/kernel_collector_test.h
+++ b/crash_reporter/kernel_collector_test.h
@@ -13,6 +13,7 @@
 class KernelCollectorMock : public KernelCollector {
  public:
   MOCK_METHOD0(DumpDirMounted, bool());
+  MOCK_METHOD0(SetUpDBus, void());
 };
 
 #endif  // CRASH_REPORTER_KERNEL_COLLECTOR_TEST_H_
diff --git a/crash_reporter/testrunner.cc b/crash_reporter/testrunner.cc
index 24e2329..d45bbf8 100644
--- a/crash_reporter/testrunner.cc
+++ b/crash_reporter/testrunner.cc
@@ -3,11 +3,9 @@
 // found in the LICENSE file.
 
 #include <chromeos/test_helpers.h>
-#include <glib-object.h>
 #include <gtest/gtest.h>
 
 int main(int argc, char** argv) {
-  ::g_type_init();
   SetUpTests(&argc, argv, true);
   return RUN_ALL_TESTS();
 }
diff --git a/crash_reporter/udev_collector_test.cc b/crash_reporter/udev_collector_test.cc
index f41b06f..1705a6d 100644
--- a/crash_reporter/udev_collector_test.cc
+++ b/crash_reporter/udev_collector_test.cc
@@ -6,6 +6,7 @@
 #include <base/files/file_util.h>
 #include <base/files/scoped_temp_dir.h>
 #include <chromeos/syslog_logging.h>
+#include <gmock/gmock.h>
 #include <gtest/gtest.h>
 
 #include "crash-reporter/udev_collector.h"
@@ -46,6 +47,11 @@
 
 }  // namespace
 
+class UdevCollectorMock : public UdevCollector {
+ public:
+  MOCK_METHOD0(SetUpDBus, void());
+};
+
 class UdevCollectorTest : public ::testing::Test {
  protected:
   base::ScopedTempDir temp_dir_generator_;
@@ -58,6 +64,8 @@
   void SetUp() override {
     s_consent_given = true;
 
+    EXPECT_CALL(collector_, SetUpDBus()).WillRepeatedly(testing::Return());
+
     collector_.Initialize(CountCrash, IsMetrics);
 
     ASSERT_TRUE(temp_dir_generator_.CreateUniqueTempDir());
@@ -76,7 +84,7 @@
     chromeos::ClearLog();
   }
 
-  UdevCollector collector_;
+  UdevCollectorMock collector_;
 };
 
 TEST_F(UdevCollectorTest, TestNoConsent) {
diff --git a/crash_reporter/unclean_shutdown_collector_test.cc b/crash_reporter/unclean_shutdown_collector_test.cc
index 859b881..f5e1b32 100644
--- a/crash_reporter/unclean_shutdown_collector_test.cc
+++ b/crash_reporter/unclean_shutdown_collector_test.cc
@@ -9,6 +9,7 @@
 #include <base/files/file_util.h>
 #include <base/strings/string_util.h>
 #include <chromeos/syslog_logging.h>
+#include <gmock/gmock.h>
 #include <gtest/gtest.h>
 
 using base::FilePath;
@@ -33,9 +34,17 @@
 
 }  // namespace
 
+class UncleanShutdownCollectorMock : public UncleanShutdownCollector {
+ public:
+  MOCK_METHOD0(SetUpDBus, void());
+};
+
 class UncleanShutdownCollectorTest : public ::testing::Test {
   void SetUp() {
     s_crashes = 0;
+
+    EXPECT_CALL(collector_, SetUpDBus()).WillRepeatedly(testing::Return());
+
     collector_.Initialize(CountCrash,
                           IsMetrics);
     rmdir(kTestDirectory);
@@ -46,13 +55,14 @@
     collector_.powerd_suspended_file_ = FilePath(kTestSuspended);
     chromeos::ClearLog();
   }
+
  protected:
   void WriteStringToFile(const FilePath &file_path,
                          const char *data) {
     ASSERT_EQ(strlen(data), base::WriteFile(file_path, data, strlen(data)));
   }
 
-  UncleanShutdownCollector collector_;
+  UncleanShutdownCollectorMock collector_;
   FilePath test_unclean_;
 };
 
diff --git a/crash_reporter/user_collector_test.cc b/crash_reporter/user_collector_test.cc
index 5a5bb0c..823d8b4 100644
--- a/crash_reporter/user_collector_test.cc
+++ b/crash_reporter/user_collector_test.cc
@@ -12,6 +12,7 @@
 #include <base/files/scoped_temp_dir.h>
 #include <base/strings/string_split.h>
 #include <chromeos/syslog_logging.h>
+#include <gmock/gmock.h>
 #include <gtest/gtest.h>
 
 using base::FilePath;
@@ -39,9 +40,17 @@
 
 }  // namespace
 
+class UserCollectorMock : public UserCollector {
+ public:
+  MOCK_METHOD0(SetUpDBus, void());
+};
+
 class UserCollectorTest : public ::testing::Test {
   void SetUp() {
     s_crashes = 0;
+
+    EXPECT_CALL(collector_, SetUpDBus()).WillRepeatedly(testing::Return());
+
     collector_.Initialize(CountCrash,
                           kFilePath,
                           IsMetrics,
@@ -71,7 +80,7 @@
     return result;
   }
 
-  UserCollector collector_;
+  UserCollectorMock collector_;
   pid_t pid_;
 };