shill: cellular: mock proxy objects fail DBus calls synchronously by default.

This CL introduces a new mock action to pick out the (shill::Error *) argument
passed to mock DBus proxy objects, and set it to a particular error type.

This mock action is used to set default behaviour of all cellular related mock
proxies to fail DBus method calls synchronously. This is the only sensible
default behaviour because a successful DBus calls requires a continuation in the
form of a callback to report result.

Before this CL, the error argument was left untouched by default, i.e., the
error returned was Error::kSuccess. This behaviour has now changed to return
Error::kOperatorFailed.

BUG=chromium:409386
TEST=Run shill unittests.
CQ-DEPEND=CL:215791
Change-Id: I9f00f9fa4b70936ed1ff697a8e8524f389882433
Reviewed-on: https://chromium-review.googlesource.com/215790
Tested-by: Prathmesh Prabhu <pprabhu@chromium.org>
Reviewed-by: Ben Chan <benchan@chromium.org>
Commit-Queue: Prathmesh Prabhu <pprabhu@chromium.org>
diff --git a/mock_mm1_modem_modem3gpp_proxy.cc b/mock_mm1_modem_modem3gpp_proxy.cc
index 16272a8..83a4c9d 100644
--- a/mock_mm1_modem_modem3gpp_proxy.cc
+++ b/mock_mm1_modem_modem3gpp_proxy.cc
@@ -4,10 +4,19 @@
 
 #include "shill/mock_mm1_modem_modem3gpp_proxy.h"
 
+#include "shill/testing.h"
+
+using testing::_;
+
 namespace shill {
 namespace mm1 {
 
-MockModemModem3gppProxy::MockModemModem3gppProxy() {}
+MockModemModem3gppProxy::MockModemModem3gppProxy() {
+  ON_CALL(*this, Register(_, _, _, _))
+      .WillByDefault(SetOperationFailedInArgumentAndWarn<1>());
+  ON_CALL(*this, Scan(_, _, _))
+      .WillByDefault(SetOperationFailedInArgumentAndWarn<0>());
+}
 
 MockModemModem3gppProxy::~MockModemModem3gppProxy() {}
 
diff --git a/mock_mm1_modem_proxy.cc b/mock_mm1_modem_proxy.cc
index fb8403c..3ac4c6c 100644
--- a/mock_mm1_modem_proxy.cc
+++ b/mock_mm1_modem_proxy.cc
@@ -4,10 +4,33 @@
 
 #include "shill/mock_mm1_modem_proxy.h"
 
+#include "shill/testing.h"
+
+using testing::_;
+
 namespace shill {
 namespace mm1 {
 
-MockModemProxy::MockModemProxy() {}
+MockModemProxy::MockModemProxy() {
+  ON_CALL(*this, Enable(_, _, _, _))
+      .WillByDefault(SetOperationFailedInArgumentAndWarn<1>());
+  ON_CALL(*this, CreateBearer(_, _, _, _))
+      .WillByDefault(SetOperationFailedInArgumentAndWarn<1>());
+  ON_CALL(*this, DeleteBearer(_, _, _, _))
+      .WillByDefault(SetOperationFailedInArgumentAndWarn<1>());
+  ON_CALL(*this, Reset(_, _, _))
+      .WillByDefault(SetOperationFailedInArgumentAndWarn<0>());
+  ON_CALL(*this, FactoryReset(_, _, _, _))
+      .WillByDefault(SetOperationFailedInArgumentAndWarn<1>());
+  ON_CALL(*this, SetCurrentCapabilities(_, _, _, _))
+      .WillByDefault(SetOperationFailedInArgumentAndWarn<1>());
+  ON_CALL(*this, SetCurrentModes(_, _, _, _))
+      .WillByDefault(SetOperationFailedInArgumentAndWarn<1>());
+  ON_CALL(*this, Command(_, _, _, _, _))
+      .WillByDefault(SetOperationFailedInArgumentAndWarn<2>());
+  ON_CALL(*this, SetPowerState(_, _, _, _))
+      .WillByDefault(SetOperationFailedInArgumentAndWarn<1>());
+}
 
 MockModemProxy::~MockModemProxy() {}
 
diff --git a/mock_mm1_modem_simple_proxy.cc b/mock_mm1_modem_simple_proxy.cc
index 42ecb0f..b39113b 100644
--- a/mock_mm1_modem_simple_proxy.cc
+++ b/mock_mm1_modem_simple_proxy.cc
@@ -4,10 +4,21 @@
 
 #include "shill/mock_mm1_modem_simple_proxy.h"
 
+#include "shill/testing.h"
+
+using testing::_;
+
 namespace shill {
 namespace mm1 {
 
-MockModemSimpleProxy::MockModemSimpleProxy() {}
+MockModemSimpleProxy::MockModemSimpleProxy() {
+  ON_CALL(*this, Connect(_, _, _, _))
+      .WillByDefault(SetOperationFailedInArgumentAndWarn<1>());
+  ON_CALL(*this, Disconnect(_, _, _, _))
+      .WillByDefault(SetOperationFailedInArgumentAndWarn<1>());
+  ON_CALL(*this, GetStatus(_, _, _))
+      .WillByDefault(SetOperationFailedInArgumentAndWarn<0>());
+}
 
 MockModemSimpleProxy::~MockModemSimpleProxy() {}
 
diff --git a/mock_modem_cdma_proxy.cc b/mock_modem_cdma_proxy.cc
index c27d685..6871380 100644
--- a/mock_modem_cdma_proxy.cc
+++ b/mock_modem_cdma_proxy.cc
@@ -4,9 +4,20 @@
 
 #include "shill/mock_modem_cdma_proxy.h"
 
+#include "shill/testing.h"
+
+using testing::_;
+
 namespace shill {
 
-MockModemCDMAProxy::MockModemCDMAProxy() {}
+MockModemCDMAProxy::MockModemCDMAProxy() {
+  ON_CALL(*this, Activate(_, _, _, _))
+      .WillByDefault(SetOperationFailedInArgumentAndWarn<1>());
+  ON_CALL(*this, GetRegistrationState(_, _, _))
+      .WillByDefault(SetOperationFailedInArgumentAndWarn<0>());
+  ON_CALL(*this, GetSignalQuality(_, _, _))
+      .WillByDefault(SetOperationFailedInArgumentAndWarn<0>());
+}
 
 MockModemCDMAProxy::~MockModemCDMAProxy() {}
 
diff --git a/mock_modem_gsm_card_proxy.cc b/mock_modem_gsm_card_proxy.cc
index a65a289..8aac6d2 100644
--- a/mock_modem_gsm_card_proxy.cc
+++ b/mock_modem_gsm_card_proxy.cc
@@ -4,9 +4,30 @@
 
 #include "shill/mock_modem_gsm_card_proxy.h"
 
+#include "shill/testing.h"
+
+using testing::_;
+
 namespace shill {
 
-MockModemGSMCardProxy::MockModemGSMCardProxy() {}
+MockModemGSMCardProxy::MockModemGSMCardProxy() {
+  ON_CALL(*this, GetIMEI(_, _, _))
+      .WillByDefault(SetOperationFailedInArgumentAndWarn<0>());
+  ON_CALL(*this, GetIMSI(_, _, _))
+      .WillByDefault(SetOperationFailedInArgumentAndWarn<0>());
+  ON_CALL(*this, GetSPN(_, _, _))
+      .WillByDefault(SetOperationFailedInArgumentAndWarn<0>());
+  ON_CALL(*this, GetMSISDN(_, _, _))
+      .WillByDefault(SetOperationFailedInArgumentAndWarn<0>());
+  ON_CALL(*this, EnablePIN(_, _, _, _, _))
+      .WillByDefault(SetOperationFailedInArgumentAndWarn<2>());
+  ON_CALL(*this, SendPIN(_, _, _, _))
+      .WillByDefault(SetOperationFailedInArgumentAndWarn<1>());
+  ON_CALL(*this, SendPUK(_, _, _, _, _))
+      .WillByDefault(SetOperationFailedInArgumentAndWarn<2>());
+  ON_CALL(*this, ChangePIN(_, _, _, _, _))
+      .WillByDefault(SetOperationFailedInArgumentAndWarn<2>());
+}
 
 MockModemGSMCardProxy::~MockModemGSMCardProxy() {}
 
diff --git a/mock_modem_gsm_network_proxy.cc b/mock_modem_gsm_network_proxy.cc
index 1e3676f..bd5f4ab 100644
--- a/mock_modem_gsm_network_proxy.cc
+++ b/mock_modem_gsm_network_proxy.cc
@@ -4,9 +4,22 @@
 
 #include "shill/mock_modem_gsm_network_proxy.h"
 
+#include "shill/testing.h"
+
+using testing::_;
+
 namespace shill {
 
-MockModemGSMNetworkProxy::MockModemGSMNetworkProxy() {}
+MockModemGSMNetworkProxy::MockModemGSMNetworkProxy() {
+  ON_CALL(*this, GetRegistrationInfo(_, _, _))
+      .WillByDefault(SetOperationFailedInArgumentAndWarn<0>());
+  ON_CALL(*this, GetSignalQuality(_, _, _))
+      .WillByDefault(SetOperationFailedInArgumentAndWarn<0>());
+  ON_CALL(*this, Register(_, _, _, _))
+      .WillByDefault(SetOperationFailedInArgumentAndWarn<1>());
+  ON_CALL(*this, Scan(_, _, _))
+      .WillByDefault(SetOperationFailedInArgumentAndWarn<0>());
+}
 
 MockModemGSMNetworkProxy::~MockModemGSMNetworkProxy() {}
 
diff --git a/mock_modem_proxy.cc b/mock_modem_proxy.cc
index 97923db..9045c41 100644
--- a/mock_modem_proxy.cc
+++ b/mock_modem_proxy.cc
@@ -4,9 +4,20 @@
 
 #include "shill/mock_modem_proxy.h"
 
+#include "shill/testing.h"
+
+using testing::_;
+
 namespace shill {
 
-MockModemProxy::MockModemProxy() {}
+MockModemProxy::MockModemProxy() {
+  ON_CALL(*this, Enable(_, _, _, _))
+      .WillByDefault(SetOperationFailedInArgumentAndWarn<1>());
+  ON_CALL(*this, Disconnect(_, _, _))
+      .WillByDefault(SetOperationFailedInArgumentAndWarn<0>());
+  ON_CALL(*this, GetModemInfo(_, _, _))
+      .WillByDefault(SetOperationFailedInArgumentAndWarn<0>());
+}
 
 MockModemProxy::~MockModemProxy() {}
 
diff --git a/mock_modem_simple_proxy.cc b/mock_modem_simple_proxy.cc
index e76c500..e3b0404 100644
--- a/mock_modem_simple_proxy.cc
+++ b/mock_modem_simple_proxy.cc
@@ -4,9 +4,18 @@
 
 #include "shill/mock_modem_simple_proxy.h"
 
+#include "shill/testing.h"
+
+using testing::_;
+
 namespace shill {
 
-MockModemSimpleProxy::MockModemSimpleProxy() {}
+MockModemSimpleProxy::MockModemSimpleProxy() {
+  ON_CALL(*this, GetModemStatus(_, _, _))
+      .WillByDefault(SetOperationFailedInArgumentAndWarn<0>());
+  ON_CALL(*this, Connect(_, _, _, _))
+      .WillByDefault(SetOperationFailedInArgumentAndWarn<1>());
+}
 
 MockModemSimpleProxy::~MockModemSimpleProxy() {}
 
diff --git a/testing.h b/testing.h
index f03bccc..cdc8353 100644
--- a/testing.h
+++ b/testing.h
@@ -8,6 +8,9 @@
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
 
+#include "shill/error.h"
+#include "shill/logging.h"
+
 namespace shill {
 
 // A Google Mock action (similar to testing::ReturnPointee) that takes a pointer
@@ -58,6 +61,59 @@
   return arg.get() == ref_address;
 }
 
+template<int error_argument_index>
+class SetErrorTypeInArgumentAction {
+ public:
+  SetErrorTypeInArgumentAction(Error::Type error_type, bool warn_default)
+      : error_type_(error_type),
+        warn_default_(warn_default) {}
+
+  template <typename Result, typename ArgumentTuple>
+  Result Perform(const ArgumentTuple& args) const {
+    Error *error_arg = ::std::tr1::get<error_argument_index>(args);
+    if (error_arg)
+      error_arg->Populate(error_type_);
+
+    // You should be careful if you see this warning in your log messages: it is
+    // likely that you want to instead set a non-default expectation on this
+    // mock, to test the success code-paths.
+    if (warn_default_)
+      LOG(WARNING) << "Default action taken: set error to "
+                   << error_type_
+                   << "(" << (error_arg ? error_arg->message() : "") << ")";
+  }
+
+ private:
+  Error::Type error_type_;
+  bool warn_default_;
+};
+
+// Many functions in the the DBus proxy classes take a (shill::Error *) output
+// argument that is set to shill::Error::kOperationFailed to notify the caller
+// synchronously of error conditions.
+//
+// If an error is not returned synchronously, a callback (passed as another
+// argument to the function) must eventually be called with the result/error.
+// Mock classes for these proxies should by default return failure synchronously
+// so that callers do not expect the callback to be called.
+template<int error_argument_index>
+::testing::PolymorphicAction<SetErrorTypeInArgumentAction<error_argument_index>>
+SetOperationFailedInArgumentAndWarn() {
+  return ::testing::MakePolymorphicAction(
+      SetErrorTypeInArgumentAction<error_argument_index>(
+          Error::kOperationFailed,
+          true));
+}
+
+// Use this action to set the (shill::Error *) output argument to any
+// shill::Error value on mock DBus proxy method calls.
+template<int error_argument_index>
+::testing::PolymorphicAction<SetErrorTypeInArgumentAction<error_argument_index>>
+SetErrorTypeInArgument(Error::Type error_type) {
+  return ::testing::MakePolymorphicAction(
+      SetErrorTypeInArgumentAction<error_argument_index>(error_type, false));
+}
+
 }  // namespace shill
 
 #endif  // SHILL_TESTING_H_