source/*: Allow copies to be made

Sources are now just reference holders so we can copy them freely.

Change-Id: I263219de83341473c333a29cf651ae82428a208a
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/test/source/base.cpp b/test/source/base.cpp
index 3673e24..43e70ff 100644
--- a/test/source/base.cpp
+++ b/test/source/base.cpp
@@ -207,6 +207,37 @@
     destroy(userdata);
 }
 
+TEST_F(BaseTest, CopyCorrectness)
+{
+    std::unique_ptr<BaseImpl> base1, base2;
+    std::function<void()> destroy;
+    std::tie(base1, destroy) = make_base(*event, expected_source);
+    set_prepare_placeholder(*base1);
+    EXPECT_TRUE(base1->get_prepare());
+
+    EXPECT_CALL(mock, sd_event_ref(expected_event))
+        .WillOnce(Return(expected_event));
+    EXPECT_CALL(mock, sd_event_source_ref(expected_source))
+        .WillOnce(Return(expected_source));
+    base2 = std::make_unique<BaseImpl>(*base1);
+    EXPECT_EQ(&base1->get_prepare(), &base2->get_prepare());
+
+    empty_base(std::move(*base1));
+    EXPECT_THROW(base1->get_prepare(), std::bad_optional_access);
+    EXPECT_CALL(mock, sd_event_ref(expected_event))
+        .WillOnce(Return(expected_event));
+    EXPECT_CALL(mock, sd_event_source_ref(expected_source))
+        .WillOnce(Return(expected_source));
+    *base1 = *base2;
+    EXPECT_EQ(&base1->get_prepare(), &base2->get_prepare());
+
+    expect_base_destruct(*event, expected_source);
+    base2.reset();
+    expect_base_destruct(*event, expected_source);
+    base1.reset();
+    destroy();
+}
+
 class BaseMethodTest : public BaseTest
 {
   protected:
diff --git a/test/source/child.cpp b/test/source/child.cpp
index 5dc06b9..71a8789 100644
--- a/test/source/child.cpp
+++ b/test/source/child.cpp
@@ -162,6 +162,39 @@
     }
 };
 
+TEST_F(ChildMethodTest, Copy)
+{
+    EXPECT_CALL(mock, sd_event_ref(expected_event))
+        .WillOnce(Return(expected_event));
+    EXPECT_CALL(mock, sd_event_source_ref(expected_source))
+        .WillOnce(Return(expected_source));
+    auto child2 = std::make_unique<Child>(*child);
+    {
+        EXPECT_CALL(mock, sd_event_ref(expected_event))
+            .WillOnce(Return(expected_event));
+        EXPECT_CALL(mock, sd_event_source_ref(expected_source))
+            .WillOnce(Return(expected_source));
+        Child child3(*child);
+
+        expect_destruct();
+        EXPECT_CALL(mock, sd_event_ref(expected_event))
+            .WillOnce(Return(expected_event));
+        EXPECT_CALL(mock, sd_event_source_ref(expected_source))
+            .WillOnce(Return(expected_source));
+        *child2 = child3;
+
+        expect_destruct();
+    }
+
+    // Delete the original child
+    child2.swap(child);
+    expect_destruct();
+    child2.reset();
+
+    // Make sure our new copy can still access data
+    child->set_callback(nullptr);
+}
+
 TEST_F(ChildMethodTest, GetPidSuccess)
 {
     const pid_t pid = 32;
diff --git a/test/source/event.cpp b/test/source/event.cpp
index 1d5a877..0d86617 100644
--- a/test/source/event.cpp
+++ b/test/source/event.cpp
@@ -186,6 +186,63 @@
     EXPECT_EQ(0, completions);
 }
 
+TEST_F(EventTest, CopyConstruct)
+{
+    EXPECT_CALL(mock, sd_event_ref(expected_event))
+        .WillOnce(Return(expected_event));
+    sd_event_destroy_t destroy;
+    void* userdata;
+    {
+        testing::InSequence seq;
+        EXPECT_CALL(mock, sd_event_source_set_destroy_callback(expected_source,
+                                                               testing::_))
+            .WillOnce(DoAll(SaveArg<1>(&destroy), Return(0)));
+        EXPECT_CALL(mock,
+                    sd_event_source_set_userdata(expected_source, testing::_))
+            .WillOnce(DoAll(SaveArg<1>(&userdata), Return(nullptr)));
+        EXPECT_CALL(mock, sd_event_source_get_userdata(expected_source))
+            .WillRepeatedly(ReturnPointee(&userdata));
+    }
+    sd_event_handler_t handler;
+    EXPECT_CALL(mock, sd_event_add_exit(expected_event, testing::_, testing::_,
+                                        nullptr))
+        .WillOnce(DoAll(SetArgPointee<1>(expected_source), SaveArg<2>(&handler),
+                        Return(0)));
+    auto exit = std::make_unique<Exit>(*event, [](EventBase&) {});
+
+    EXPECT_CALL(mock, sd_event_ref(expected_event))
+        .WillOnce(Return(expected_event));
+    EXPECT_CALL(mock, sd_event_source_ref(expected_source))
+        .WillOnce(Return(expected_source));
+    auto exit2 = std::make_unique<Exit>(*exit);
+    {
+        EXPECT_CALL(mock, sd_event_ref(expected_event))
+            .WillOnce(Return(expected_event));
+        EXPECT_CALL(mock, sd_event_source_ref(expected_source))
+            .WillOnce(Return(expected_source));
+        Exit exit3(*exit);
+
+        expect_destruct();
+        EXPECT_CALL(mock, sd_event_ref(expected_event))
+            .WillOnce(Return(expected_event));
+        EXPECT_CALL(mock, sd_event_source_ref(expected_source))
+            .WillOnce(Return(expected_source));
+        *exit2 = exit3;
+
+        expect_destruct();
+    }
+
+    // Delete the original exit
+    expect_destruct();
+    exit.reset();
+
+    // Make sure our new copy can still access data
+    exit2->set_callback(nullptr);
+    expect_destruct();
+    exit2.reset();
+    destroy(userdata);
+}
+
 } // namespace
 } // namespace source
 } // namespace sdeventplus
diff --git a/test/source/io.cpp b/test/source/io.cpp
index bafdeb8..e8abb82 100644
--- a/test/source/io.cpp
+++ b/test/source/io.cpp
@@ -162,6 +162,39 @@
     }
 };
 
+TEST_F(IOMethodTest, Copy)
+{
+    EXPECT_CALL(mock, sd_event_ref(expected_event))
+        .WillOnce(Return(expected_event));
+    EXPECT_CALL(mock, sd_event_source_ref(expected_source))
+        .WillOnce(Return(expected_source));
+    auto io2 = std::make_unique<IO>(*io);
+    {
+        EXPECT_CALL(mock, sd_event_ref(expected_event))
+            .WillOnce(Return(expected_event));
+        EXPECT_CALL(mock, sd_event_source_ref(expected_source))
+            .WillOnce(Return(expected_source));
+        IO io3(*io);
+
+        expect_destruct();
+        EXPECT_CALL(mock, sd_event_ref(expected_event))
+            .WillOnce(Return(expected_event));
+        EXPECT_CALL(mock, sd_event_source_ref(expected_source))
+            .WillOnce(Return(expected_source));
+        *io2 = io3;
+
+        expect_destruct();
+    }
+
+    // Delete the original IO
+    io2.swap(io);
+    expect_destruct();
+    io2.reset();
+
+    // Make sure our new copy can still access data
+    io->set_callback(nullptr);
+}
+
 TEST_F(IOMethodTest, GetFdSuccess)
 {
     const int fd = 5;
diff --git a/test/source/signal.cpp b/test/source/signal.cpp
index 209f2a7..9ac0f67 100644
--- a/test/source/signal.cpp
+++ b/test/source/signal.cpp
@@ -161,6 +161,39 @@
     }
 };
 
+TEST_F(SignalMethodTest, Copy)
+{
+    EXPECT_CALL(mock, sd_event_ref(expected_event))
+        .WillOnce(Return(expected_event));
+    EXPECT_CALL(mock, sd_event_source_ref(expected_source))
+        .WillOnce(Return(expected_source));
+    auto signal2 = std::make_unique<Signal>(*signal);
+    {
+        EXPECT_CALL(mock, sd_event_ref(expected_event))
+            .WillOnce(Return(expected_event));
+        EXPECT_CALL(mock, sd_event_source_ref(expected_source))
+            .WillOnce(Return(expected_source));
+        Signal signal3(*signal);
+
+        expect_destruct();
+        EXPECT_CALL(mock, sd_event_ref(expected_event))
+            .WillOnce(Return(expected_event));
+        EXPECT_CALL(mock, sd_event_source_ref(expected_source))
+            .WillOnce(Return(expected_source));
+        *signal2 = signal3;
+
+        expect_destruct();
+    }
+
+    // Delete the original signal
+    signal2.swap(signal);
+    expect_destruct();
+    signal2.reset();
+
+    // Make sure our new copy can still access data
+    signal->set_callback(nullptr);
+}
+
 TEST_F(SignalMethodTest, GetSignalSuccess)
 {
     const int sig = SIGTERM;
diff --git a/test/source/time.cpp b/test/source/time.cpp
index 569d2c0..01d4ae2 100644
--- a/test/source/time.cpp
+++ b/test/source/time.cpp
@@ -164,6 +164,39 @@
     }
 };
 
+TEST_F(TimeMethodTest, Copy)
+{
+    EXPECT_CALL(mock, sd_event_ref(expected_event))
+        .WillOnce(Return(expected_event));
+    EXPECT_CALL(mock, sd_event_source_ref(expected_source))
+        .WillOnce(Return(expected_source));
+    auto time2 = std::make_unique<Time<id>>(*time);
+    {
+        EXPECT_CALL(mock, sd_event_ref(expected_event))
+            .WillOnce(Return(expected_event));
+        EXPECT_CALL(mock, sd_event_source_ref(expected_source))
+            .WillOnce(Return(expected_source));
+        Time<id> time3(*time);
+
+        expect_time_destroy(expected_event, expected_source);
+        EXPECT_CALL(mock, sd_event_ref(expected_event))
+            .WillOnce(Return(expected_event));
+        EXPECT_CALL(mock, sd_event_source_ref(expected_source))
+            .WillOnce(Return(expected_source));
+        *time2 = time3;
+
+        expect_time_destroy(expected_event, expected_source);
+    }
+
+    // Delete the original time
+    time2.swap(time);
+    expect_time_destroy(expected_event, expected_source);
+    time2.reset();
+
+    // Make sure our new copy can still access data
+    time->set_callback(nullptr);
+}
+
 TEST_F(TimeMethodTest, SetTimeSuccess)
 {
     EXPECT_CALL(mock, sd_event_source_set_time(expected_source, 1000000))