shill: Create mockable ModemManagerProxy on appearance of new ModemManagers.
BUG=chromium-os:17649
TEST=unit tests, tested on device
Change-Id: Id9e6500168d63493eb94bd7939e379b964bef063
Reviewed-on: http://gerrit.chromium.org/gerrit/4269
Tested-by: Darin Petkov <petkov@chromium.org>
Reviewed-by: Chris Masone <cmasone@chromium.org>
diff --git a/Makefile b/Makefile
index 855a094..fc2cbeb 100644
--- a/Makefile
+++ b/Makefile
@@ -8,7 +8,6 @@
# disable some errors, which occur repeateadly the dbus-c++ headers.
CXXFLAGS += -Wno-ignored-qualifiers -Wno-unused
CPPFLAGS ?= -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
-AR ?= ar
PKG_CONFIG ?= pkg-config
DBUSXX_XML2CPP = dbusxx-xml2cpp
@@ -25,7 +24,6 @@
gdk-2.0 gtk+-2.0)
TEST_LIBS = $(BASE_LIBS) -lgmock -lgtest
-TEST_INCLUDE_DIRS = $(INCLUDE_DIRS)
TEST_LIB_DIRS = $(LIB_DIRS)
DBUS_ADAPTOR_HEADERS = \
@@ -37,6 +35,7 @@
DBUS_PROXY_HEADERS = \
dhcpcd.h \
+ mm.h \
supplicant-bss.h \
supplicant-interface.h \
supplicant-network.h \
@@ -75,9 +74,11 @@
manager_dbus_adaptor.o \
modem_info.o \
modem_manager.o \
+ modem_manager_proxy.o \
profile.o \
profile_dbus_adaptor.o \
property_store.o \
+ proxy_factory.o \
rtnl_handler.o \
rtnl_listener.o \
service.o \
@@ -129,8 +130,13 @@
testrunner.o \
wifi_unittest.o
+.PHONY: all clean
+
all: $(SHILL_BIN) $(TEST_BIN)
+mm.xml: $(SYSROOT)/usr/share/dbus-1/interfaces/org.freedesktop.ModemManager.xml
+ cat $< > $@
+
$(DBUS_PROXY_HEADERS): %.h: %.xml
$(DBUSXX_XML2CPP) $< --proxy=$@
@@ -148,8 +154,7 @@
$(TEST_BIN): CXXFLAGS += -DUNIT_TEST
$(TEST_BIN): $(TEST_OBJS) $(SHILL_OBJS)
- $(CXX) $(CXXFLAGS) $(TEST_INCLUDE_DIRS) $(TEST_LIB_DIRS) $(LDFLAGS) $^ \
- $(TEST_LIBS) -o $@
+ $(CXX) $(CXXFLAGS) $(TEST_LIB_DIRS) $(LDFLAGS) $^ $(TEST_LIBS) -o $@
clean:
- rm -rf *.o $(DBUS_HEADERS) $(SHILL_BIN) $(TEST_BIN)
+ rm -rf *.o mm.xml $(DBUS_HEADERS) $(SHILL_BIN) $(TEST_BIN)
diff --git a/dhcpcd_proxy.h b/dhcpcd_proxy.h
index ebb61b5..672411a 100644
--- a/dhcpcd_proxy.h
+++ b/dhcpcd_proxy.h
@@ -15,6 +15,8 @@
class DHCPProvider;
+// TODO(petkov): Convert this to match ModemManagerProxy model.
+
// The DHCPCD listener is a singleton proxy that listens to signals from all
// DHCP clients and dispatches them through the DHCP provider to the appropriate
// client based on the PID.
diff --git a/mock_modem_manager_proxy.h b/mock_modem_manager_proxy.h
new file mode 100644
index 0000000..0810a8d
--- /dev/null
+++ b/mock_modem_manager_proxy.h
@@ -0,0 +1,21 @@
+// Copyright (c) 2011 The Chromium OS 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 SHILL_MOCK_MODEM_MANAGER_PROXY_H_
+#define SHILL_MOCK_MODEM_MANAGER_PROXY_H_
+
+#include <gmock/gmock.h>
+
+#include "shill/modem_manager_proxy_interface.h"
+
+namespace shill {
+
+class MockModemManagerProxy : public ModemManagerProxyInterface {
+ public:
+ MOCK_METHOD0(EnumerateDevices, std::vector<DBus::Path>());
+};
+
+} // namespace shill
+
+#endif // SHILL_MOCK_MODEM_MANAGER_PROXY_H_
diff --git a/modem_manager.cc b/modem_manager.cc
index df4c4ae..94536fb 100644
--- a/modem_manager.cc
+++ b/modem_manager.cc
@@ -6,6 +6,9 @@
#include <base/logging.h>
+#include "shill/modem_manager_proxy.h"
+#include "shill/proxy_factory.h"
+
using std::string;
namespace shill {
@@ -30,6 +33,7 @@
void ModemManager::Start() {
LOG(INFO) << "Start watching modem manager service: " << service_;
CHECK_EQ(0, watcher_id_);
+ // TODO(petkov): Implement DBus name watching through dbus-c++.
watcher_id_ = glib_->BusWatchName(G_BUS_TYPE_SYSTEM,
service_.c_str(),
G_BUS_NAME_WATCHER_FLAGS_NONE,
@@ -50,12 +54,13 @@
void ModemManager::Connect(const string &owner) {
owner_ = owner;
- // TODO(petkov): Create a proxy to the manager and enumerate its devices.
+ proxy_.reset(
+ ProxyFactory::factory()->CreateModemManagerProxy(this, path_, owner_));
}
void ModemManager::Disconnect() {
owner_.clear();
- // TODO(petkov): Destroy manager's proxy and its devices.
+ proxy_.reset();
}
void ModemManager::OnAppear(GDBusConnection *connection,
diff --git a/modem_manager.h b/modem_manager.h
index 96d18ef..14d3a4f 100644
--- a/modem_manager.h
+++ b/modem_manager.h
@@ -6,6 +6,7 @@
#define SHILL_MODEM_MANAGER_
#include <base/basictypes.h>
+#include <base/memory/scoped_ptr.h>
#include <gtest/gtest_prod.h> // for FRIEND_TEST
#include "shill/glib.h"
@@ -15,6 +16,7 @@
class ControlInterface;
class EventDispatcher;
class Manager;
+class ModemManagerProxyInterface;
// Handles a modem manager service and creates and destroys cellular devices.
class ModemManager {
@@ -63,8 +65,8 @@
const std::string path_;
guint watcher_id_;
- // DBus service owner.
- std::string owner_;
+ std::string owner_; // DBus service owner.
+ scoped_ptr<ModemManagerProxyInterface> proxy_; // DBus service proxy.
ControlInterface *control_interface_;
EventDispatcher *dispatcher_;
diff --git a/modem_manager_proxy.cc b/modem_manager_proxy.cc
new file mode 100644
index 0000000..21a0a93
--- /dev/null
+++ b/modem_manager_proxy.cc
@@ -0,0 +1,43 @@
+// Copyright (c) 2011 The Chromium OS 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 "shill/modem_manager_proxy.h"
+
+#include <base/logging.h>
+
+using std::string;
+using std::vector;
+
+namespace shill {
+
+ModemManagerProxy::ModemManagerProxy(ModemManager *manager,
+ const string &path,
+ const string &service)
+ : connection_(DBus::Connection::SystemBus()),
+ proxy_(manager, &connection_, path, service) {}
+
+ModemManagerProxy::~ModemManagerProxy() {}
+
+vector<DBus::Path> ModemManagerProxy::EnumerateDevices() {
+ return proxy_.EnumerateDevices();
+}
+
+ModemManagerProxy::Proxy::Proxy(ModemManager *manager,
+ DBus::Connection *connection,
+ const string &path,
+ const string &service)
+ : DBus::ObjectProxy(*connection, path, service.c_str()),
+ manager_(manager) {}
+
+ModemManagerProxy::Proxy::~Proxy() {}
+
+void ModemManagerProxy::Proxy::DeviceAdded(const DBus::Path &device) {
+ LOG(INFO) << "Modem device added: " << device;
+}
+
+void ModemManagerProxy::Proxy::DeviceRemoved(const DBus::Path &device) {
+ LOG(INFO) << "Modem device removed: " << device;
+}
+
+} // namespace shill
diff --git a/modem_manager_proxy.h b/modem_manager_proxy.h
new file mode 100644
index 0000000..b782267
--- /dev/null
+++ b/modem_manager_proxy.h
@@ -0,0 +1,58 @@
+// Copyright (c) 2011 The Chromium OS 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 SHILL_MODEM_MANAGER_PROXY_
+#define SHILL_MODEM_MANAGER_PROXY_
+
+#include <base/basictypes.h>
+
+#include "shill/mm.h"
+#include "shill/modem_manager_proxy_interface.h"
+
+namespace shill {
+
+class ModemManager;
+
+// There's a single proxy per ModemManager service identified by its DBus |path|
+// and owner name |service|.
+class ModemManagerProxy : public ModemManagerProxyInterface {
+ public:
+ ModemManagerProxy(ModemManager *manager,
+ const std::string &path,
+ const std::string &service);
+ virtual ~ModemManagerProxy();
+
+ // Inherited from ModemManagerProxyInterface.
+ virtual std::vector<DBus::Path> EnumerateDevices();
+
+ private:
+ class Proxy : public org::freedesktop::ModemManager_proxy,
+ public DBus::ObjectProxy {
+ public:
+ Proxy(ModemManager *manager,
+ DBus::Connection *connection,
+ const std::string &path,
+ const std::string &service);
+ virtual ~Proxy();
+
+ private:
+ // Signal callbacks inherited from ModemManager_proxy.
+ virtual void DeviceAdded(const DBus::Path &device);
+ virtual void DeviceRemoved(const DBus::Path &device);
+
+ // The owner of this proxy.
+ ModemManager *manager_;
+
+ DISALLOW_COPY_AND_ASSIGN(Proxy);
+ };
+
+ DBus::Connection connection_;
+ Proxy proxy_;
+
+ DISALLOW_COPY_AND_ASSIGN(ModemManagerProxy);
+};
+
+} // namespace shill
+
+#endif // SHILL_MODEM_MANAGER_PROXY_
diff --git a/modem_manager_proxy_interface.h b/modem_manager_proxy_interface.h
new file mode 100644
index 0000000..e294eea
--- /dev/null
+++ b/modem_manager_proxy_interface.h
@@ -0,0 +1,25 @@
+// Copyright (c) 2011 The Chromium OS 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 SHILL_MODEM_MANAGER_PROXY_INTERFACE_
+#define SHILL_MODEM_MANAGER_PROXY_INTERFACE_
+
+#include <vector>
+
+#include <dbus-c++/types.h>
+
+namespace shill {
+
+// These are the methods that a ModemManager proxy must support. The interface
+// is provided so that it can be mocked in tests.
+class ModemManagerProxyInterface {
+ public:
+ virtual ~ModemManagerProxyInterface() {}
+
+ virtual std::vector<DBus::Path> EnumerateDevices() = 0;
+};
+
+} // namespace shill
+
+#endif // SHILL_MODEM_MANAGER_PROXY_INTERFACE_
diff --git a/modem_manager_unittest.cc b/modem_manager_unittest.cc
index c7c83d0..89362f7 100644
--- a/modem_manager_unittest.cc
+++ b/modem_manager_unittest.cc
@@ -7,8 +7,11 @@
#include "shill/manager.h"
#include "shill/mock_control.h"
#include "shill/mock_glib.h"
+#include "shill/mock_modem_manager_proxy.h"
#include "shill/modem_manager.h"
+#include "shill/proxy_factory.h"
+using std::string;
using testing::_;
using testing::Return;
using testing::StrEq;
@@ -25,13 +28,34 @@
&control_interface_,
&dispatcher_,
&manager_,
- &glib_) {}
+ &glib_),
+ proxy_factory_(&proxy_) {
+ ProxyFactory::set_factory(&proxy_factory_);
+ }
virtual void TearDown() {
modem_manager_.watcher_id_ = 0;
+ ModemManagerProxyInterface *proxy = modem_manager_.proxy_.release();
+ EXPECT_TRUE(proxy == NULL || proxy == &proxy_);
+ ProxyFactory::set_factory(NULL);
}
protected:
+ class TestProxyFactory : public ProxyFactory {
+ public:
+ TestProxyFactory(ModemManagerProxyInterface *proxy) : proxy_(proxy) {}
+
+ virtual ModemManagerProxyInterface *CreateModemManagerProxy(
+ ModemManager *manager,
+ const string &path,
+ const string &service) {
+ return proxy_;
+ }
+
+ private:
+ ModemManagerProxyInterface *proxy_;
+ };
+
static const char kService[];
static const char kPath[];
@@ -40,6 +64,8 @@
EventDispatcher dispatcher_;
Manager manager_;
ModemManager modem_manager_;
+ MockModemManagerProxy proxy_;
+ TestProxyFactory proxy_factory_;
};
const char ModemManagerTest::kService[] = "test.dbus.service";
diff --git a/proxy_factory.cc b/proxy_factory.cc
new file mode 100644
index 0000000..f2092e9
--- /dev/null
+++ b/proxy_factory.cc
@@ -0,0 +1,24 @@
+// Copyright (c) 2011 The Chromium OS 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 "shill/proxy_factory.h"
+
+#include "shill/modem_manager_proxy.h"
+
+namespace shill {
+
+ProxyFactory *ProxyFactory::factory_ = NULL;
+
+ProxyFactory::ProxyFactory() {}
+
+ProxyFactory::~ProxyFactory() {}
+
+ModemManagerProxyInterface *ProxyFactory::CreateModemManagerProxy(
+ ModemManager *manager,
+ const std::string &path,
+ const std::string &service) {
+ return new ModemManagerProxy(manager, path, service);
+}
+
+} // namespace shill
diff --git a/proxy_factory.h b/proxy_factory.h
new file mode 100644
index 0000000..fffcd05
--- /dev/null
+++ b/proxy_factory.h
@@ -0,0 +1,41 @@
+// Copyright (c) 2011 The Chromium OS 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 SHILL_PROXY_FACTORY_
+#define SHILL_PROXY_FACTORY_
+
+#include <string>
+
+#include <base/basictypes.h>
+
+namespace shill {
+
+class ModemManager;
+class ModemManagerProxyInterface;
+
+// TODO(petkov): Merge supplicant proxy factory into this one.
+
+// Global DBus proxy factory that can be mocked out in tests.
+class ProxyFactory {
+ public:
+ ProxyFactory();
+ virtual ~ProxyFactory();
+
+ virtual ModemManagerProxyInterface *CreateModemManagerProxy(
+ ModemManager *manager,
+ const std::string &path,
+ const std::string &service);
+
+ static ProxyFactory *factory() { return factory_; }
+ static void set_factory(ProxyFactory *factory) { factory_ = factory; }
+
+ private:
+ static ProxyFactory *factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(ProxyFactory);
+};
+
+} // namespace shill
+
+#endif // SHILL_PROXY_FACTORY_
diff --git a/shill_main.cc b/shill_main.cc
index 16703cd..ded1341 100644
--- a/shill_main.cc
+++ b/shill_main.cc
@@ -15,6 +15,7 @@
#include "shill/dbus_control.h"
#include "shill/dhcp_provider.h"
#include "shill/glib.h"
+#include "shill/proxy_factory.h"
#include "shill/shill_config.h"
#include "shill/shill_daemon.h"
#include "shill/supplicant_proxy_factory.h"
@@ -98,6 +99,9 @@
shill::SupplicantProxyFactory live_proxy_factory;
shill::WiFi::set_proxy_factory(&live_proxy_factory);
+ shill::ProxyFactory proxy_factory;
+ shill::ProxyFactory::set_factory(&proxy_factory);
+
// TODO(pstew): This should be chosen based on config
shill::DBusControl *dbus_control = new shill::DBusControl();
dbus_control->Init();