utility/timer: Make movable

Now that we can update the callbacks of our sources, we can move the
timer object freely by updating the callback when moved.

Tested:
    Unit tests pass, and we no longer see any valgrind issues when
    moving the timer object.

Change-Id: I15baf97538459ca8b9c48b75dba77d09b7b5075b
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/test/utility/timer.cpp b/test/utility/timer.cpp
index 6d5dff0..6c04e87 100644
--- a/test/utility/timer.cpp
+++ b/test/utility/timer.cpp
@@ -47,8 +47,11 @@
     sd_event* const expected_event = reinterpret_cast<sd_event*>(1234);
     sd_event_source* const expected_source =
         reinterpret_cast<sd_event_source*>(2345);
+    sd_event_source* const expected_source2 =
+        reinterpret_cast<sd_event_source*>(3456);
     const milliseconds interval{134};
     const milliseconds starting_time{10};
+    const milliseconds starting_time2{30};
     sd_event_time_handler_t handler = nullptr;
     void* handler_userdata;
     std::unique_ptr<Event> event;
@@ -340,6 +343,44 @@
     EXPECT_THROW(timer->setEnabled(true), std::runtime_error);
 }
 
+TEST_F(TimerTest, CallbackMove)
+{
+    size_t called = 0;
+    callback = [&]() { ++called; };
+
+    expectNow(starting_time2);
+    EXPECT_CALL(mock,
+                sd_event_source_set_userdata(expected_source2, testing::_))
+        .WillOnce(Return(nullptr));
+    EXPECT_CALL(mock, sd_event_add_time(expected_event, testing::_,
+                                        static_cast<clockid_t>(testClock),
+                                        microseconds(starting_time2).count(),
+                                        1000, testing::_, nullptr))
+        .WillOnce(DoAll(SetArgPointee<1>(expected_source2), Return(0)));
+    EXPECT_CALL(mock, sd_event_source_unref(expected_source2))
+        .WillOnce(Return(nullptr));
+    EXPECT_CALL(mock,
+                sd_event_source_set_enabled(
+                    expected_source2, static_cast<int>(source::Enabled::Off)))
+        .WillOnce(Return(0))
+        .WillOnce(Return(0));
+    TestTimer local_timer(*event, nullptr);
+
+    // Move assign
+    local_timer = std::move(*timer);
+    timer.reset();
+
+    // Move construct
+    timer = std::make_unique<TestTimer>(std::move(local_timer));
+
+    // handler_userdata should have been updated and the callback should work
+    const milliseconds new_time(90);
+    expectNow(new_time);
+    expectSetTime(new_time + interval);
+    EXPECT_EQ(0, handler(nullptr, 0, handler_userdata));
+    EXPECT_EQ(1, called);
+}
+
 TEST_F(TimerTest, SetValuesExpiredTimer)
 {
     const milliseconds new_time(90);