[shill] Back property storage in Service objects with Entry objects

Much of Shill Service state is persisted to disk, by creating an Entry
in a Profile.  We should store this info just once, so that we don't
have to worry about keeping multiple data stores in sync.  This is a
first step in that direction.

BUG=chromium-os:17436
TEST=unit tests

Change-Id: If94db2a38a7d79c56e2c746b2f069cfd7ab4bf65
Reviewed-on: http://gerrit.chromium.org/gerrit/3876
Tested-by: Chris Masone <cmasone@chromium.org>
Reviewed-by: Darin Petkov <petkov@chromium.org>
diff --git a/service_unittest.cc b/service_unittest.cc
index 9c38938..a67d56f 100644
--- a/service_unittest.cc
+++ b/service_unittest.cc
@@ -14,10 +14,12 @@
 #include <gmock/gmock.h>
 
 #include "shill/dbus_adaptor.h"
+#include "shill/entry.h"
 #include "shill/ethernet_service.h"
 #include "shill/manager.h"
 #include "shill/mock_adaptors.h"
 #include "shill/mock_control.h"
+#include "shill/mock_profile.h"
 #include "shill/mock_service.h"
 #include "shill/property_store_unittest.h"
 #include "shill/shill_event.h"
@@ -36,10 +38,14 @@
  public:
   static const char kMockServiceName[];
   static const char kMockDeviceRpcId[];
+  static const char kEntryName[];
+  static const char kProfileName[];
 
   ServiceTest()
       : service_(new MockService(&control_interface_,
                                  &dispatcher_,
+                                 new MockProfile(&control_interface_, &glib_),
+                                 new Entry(kEntryName),
                                  kMockServiceName)) {
   }
 
@@ -53,6 +59,10 @@
 
 const char ServiceTest::kMockDeviceRpcId[] = "mock-device-rpc";
 
+const char ServiceTest::kEntryName[] = "entry";
+
+const char ServiceTest::kProfileName[] = "profile";
+
 TEST_F(ServiceTest, GetProperties) {
   EXPECT_CALL(*service_.get(), CalculateState()).WillRepeatedly(Return(""));
   EXPECT_CALL(*service_.get(), GetDeviceRpcId())
@@ -140,4 +150,40 @@
   }
 }
 
+TEST_F(ServiceTest, MoveEntry) {
+  // Create a Profile with an Entry in it that should back our Service.
+  EntryRefPtr entry(new Entry(kProfileName));
+  ProfileRefPtr profile(new Profile(&control_interface_, &glib_));
+  profile->entries_[kEntryName] = entry;
+
+  scoped_refptr<MockService> service(new MockService(&control_interface_,
+                                                     &dispatcher_,
+                                                     profile,
+                                                     entry,
+                                                     kMockServiceName));
+  // Now, move the entry to another profile.
+  ProfileRefPtr profile2(new Profile(&control_interface_, &glib_));
+  map<string, EntryRefPtr>::iterator it = profile->entries_.find(kEntryName);
+  ASSERT_TRUE(it != profile->entries_.end());
+
+  profile2->AdoptEntry(it->first, it->second);
+  profile->entries_.erase(it);
+  // Force destruction of the original Profile, to ensure that the Entry
+  // is kept alive and populated with data.
+  profile = NULL;
+  {
+    Error error(Error::kInvalidProperty, "");
+    ::DBus::Error dbus_error;
+    map<string, ::DBus::Variant> props;
+    bool expected = true;
+    service->store()->SetBoolProperty(flimflam::kAutoConnectProperty,
+                                      expected,
+                                      &error);
+    DBusAdaptor::GetProperties(service->store(), &props, &dbus_error);
+    ASSERT_FALSE(props.find(flimflam::kAutoConnectProperty) == props.end());
+    EXPECT_EQ(props[flimflam::kAutoConnectProperty].reader().get_bool(),
+              expected);
+  }
+}
+
 }  // namespace shill