void FetchAndStoreAndExpungeAndFetch(State* state) { Future<Variable<Slaves> > future1 = state->fetch<Slaves>("slaves"); AWAIT_READY(future1); Variable<Slaves> variable = future1.get(); Slaves slaves1 = variable.get(); ASSERT_EQ(0, slaves1.slaves().size()); Slave* slave = slaves1.add_slaves(); slave->mutable_info()->set_hostname("localhost"); variable = variable.mutate(slaves1); Future<Option<Variable<Slaves> > > future2 = state->store(variable); AWAIT_READY(future2); ASSERT_SOME(future2.get()); variable = future2.get().get(); Future<bool> future3 = state->expunge(variable); AWAIT_READY(future3); ASSERT_TRUE(future3.get()); future1 = state->fetch<Slaves>("slaves"); AWAIT_READY(future1); variable = future1.get(); Slaves slaves2 = variable.get(); ASSERT_EQ(0, slaves2.slaves().size()); }
static void set_flags(Variable& var, VarFlags flags, std::shared_ptr<Function> grad_fn, bool inplace=false, int output_nr = 0) { if (grad_fn) { grad_fn->num_inputs = 1; } if (inplace) { var.rebase_history(flags, output_nr, std::move(grad_fn)); } else { // TODO: combine this code path with the Variable construction var.get()->requires_grad = flags.requires_grad; var.get()->is_volatile = flags.is_volatile; var.get()->output_nr = output_nr; var.get()->_grad_fn = std::move(grad_fn); } }
TEST_F(LogStateTest, Timeout) { Clock::pause(); Future<Variable<Slaves> > future1 = state->fetch<Slaves>("slaves"); AWAIT_READY(future1); Variable<Slaves> variable = future1.get(); Slaves slaves1 = variable.get(); ASSERT_EQ(0, slaves1.slaves().size()); Slave* slave = slaves1.add_slaves(); slave->mutable_info()->set_hostname("localhost"); variable = variable.mutate(slaves1); // Now terminate the replica so the store will timeout. terminate(replica2->pid()); wait(replica2->pid()); Future<Option<Variable<Slaves> > > future2 = state->store(variable); Future<Option<Variable<Slaves> > > future3 = future2.after(Seconds(5), lambda::bind(&timeout, lambda::_1)); ASSERT_TRUE(future2.isPending()); ASSERT_TRUE(future3.isPending()); Clock::advance(Seconds(5)); AWAIT_DISCARDED(future2); AWAIT_FAILED(future3); Clock::resume(); }
void Names(State* state) { Future<Variable<Slaves> > future1 = state->fetch<Slaves>("slaves"); AWAIT_READY(future1); Variable<Slaves> variable = future1.get(); Slaves slaves1 = variable.get(); ASSERT_EQ(0, slaves1.slaves().size()); Slave* slave = slaves1.add_slaves(); slave->mutable_info()->set_hostname("localhost"); variable = variable.mutate(slaves1); Future<Option<Variable<Slaves> > > future2 = state->store(variable); AWAIT_READY(future2); ASSERT_SOME(future2.get()); Future<set<string> > names = state->names(); AWAIT_READY(names); ASSERT_EQ(1u, names.get().size()); EXPECT_NE(names.get().find("slaves"), names.get().end()); }
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()); }