TEST_F(LogStateTest, Diff) { Future<Variable<Slaves>> future1 = state->fetch<Slaves>("slaves"); AWAIT_READY(future1); Variable<Slaves> variable = future1.get(); Slaves slaves = variable.get(); ASSERT_EQ(0, slaves.slaves().size()); for (size_t i = 0; i < 1024; i++) { Slave* slave = slaves.add_slaves(); slave->mutable_info()->set_hostname("localhost" + stringify(i)); } variable = variable.mutate(slaves); Future<Option<Variable<Slaves>>> future2 = state->store(variable); AWAIT_READY(future2); ASSERT_SOME(future2.get()); variable = future2.get().get(); Slave* slave = slaves.add_slaves(); slave->mutable_info()->set_hostname("localhost1024"); variable = variable.mutate(slaves); future2 = state->store(variable); AWAIT_READY(future2); ASSERT_SOME(future2.get()); // It's possible that we're doing truncation asynchronously which // will cause the test to fail because we'll end up getting a // pending position from Log::Reader::ending which will cause // Log::Reader::read to fail. To remedy this, we pause the clock and // wait for all executing processe to settle. Clock::pause(); Clock::settle(); Clock::resume(); Log::Reader reader(log); Future<Log::Position> beginning = reader.beginning(); Future<Log::Position> ending = reader.ending(); AWAIT_READY(beginning); AWAIT_READY(ending); Future<list<Log::Entry>> entries = reader.read(beginning.get(), ending.get()); AWAIT_READY(entries); // Convert each Log::Entry to a Operation. vector<Operation> operations; foreach (const Log::Entry& entry, entries.get()) { // Parse the Operation from the Log::Entry. Operation operation; google::protobuf::io::ArrayInputStream stream( entry.data.data(), entry.data.size()); ASSERT_TRUE(operation.ParseFromZeroCopyStream(&stream)); operations.push_back(operation); } ASSERT_EQ(2u, operations.size()); EXPECT_EQ(Operation::SNAPSHOT, operations[0].type()); EXPECT_EQ(Operation::DIFF, operations[1].type()); }
TEST_F(LogStateTest, Diff) { Future<Variable<Slaves>> future1 = state->fetch<Slaves>("slaves"); AWAIT_READY(future1); Variable<Slaves> variable = future1.get(); Slaves slaves = variable.get(); ASSERT_EQ(0, slaves.slaves().size()); for (size_t i = 0; i < 1024; i++) { Slave* slave = slaves.add_slaves(); slave->mutable_info()->set_hostname("localhost" + stringify(i)); } variable = variable.mutate(slaves); Future<Option<Variable<Slaves>>> future2 = state->store(variable); AWAIT_READY(future2); ASSERT_SOME(future2.get()); variable = future2.get().get(); Slave* slave = slaves.add_slaves(); slave->mutable_info()->set_hostname("localhost1024"); variable = variable.mutate(slaves); future2 = state->store(variable); AWAIT_READY(future2); ASSERT_SOME(future2.get()); Log::Reader reader(log); Future<Log::Position> beginning = reader.beginning(); Future<Log::Position> ending = reader.ending(); AWAIT_READY(beginning); AWAIT_READY(ending); Future<list<Log::Entry>> entries = reader.read(beginning.get(), ending.get()); AWAIT_READY(entries); // Convert each Log::Entry to a Operation. vector<Operation> operations; foreach (const Log::Entry& entry, entries.get()) { // Parse the Operation from the Log::Entry. Operation operation; google::protobuf::io::ArrayInputStream stream( entry.data.data(), entry.data.size()); ASSERT_TRUE(operation.ParseFromZeroCopyStream(&stream)); operations.push_back(operation); } ASSERT_EQ(2u, operations.size()); EXPECT_EQ(Operation::SNAPSHOT, operations[0].type()); EXPECT_EQ(Operation::DIFF, operations[1].type()); }