Esempio n. 1
0
TEST(FutureTest, Future)
{
  Promise<bool> promise;
  promise.set(true);
  ASSERT_TRUE(promise.future().isReady());
  EXPECT_TRUE(promise.future().get());
}
Esempio n. 2
0
TEST(AwaitTest, AwaitSingleDiscard)
{
  Promise<int> promise;

  auto bar = [&]() {
    return promise.future();
  };

  auto foo = [&]() {
    return await(bar())
      .then([](const Future<int>& f) {
        return f
          .then([](int i) {
            return stringify(i);
          });
      });
  };

  Future<string> future = foo();

  future.discard();

  AWAIT_DISCARDED(future);

  EXPECT_TRUE(promise.future().hasDiscard());
}
Esempio n. 3
0
	void futureCanDowncastToVoid()
	{
		Promise<int> promise;
		Future<int> future1 = promise.future();
		Future<void> future2 = promise.future();
		Future<void> future3 = future1;
	}
// This test ensures that destroy can be called at the end of the
// launch loop. The composing containerizer still calls the
// underlying containerizer's destroy (because it's not sure
// if the containerizer can handle the type of container being
// launched). If the launch is not supported by any containerizers
// both the launch and destroy futures should be false.
TEST_F(ComposingContainerizerTest, DestroyAfterLaunchLoop)
{
  vector<Containerizer*> containerizers;

  MockContainerizer* mockContainerizer1 = new MockContainerizer();
  containerizers.push_back(mockContainerizer1);

  ComposingContainerizer containerizer(containerizers);
  ContainerID containerId;
  containerId.set_value("container");
  TaskInfo taskInfo;
  ExecutorInfo executorInfo;
  SlaveID slaveId;
  std::map<std::string, std::string> environment;

  Promise<bool> launchPromise;

  EXPECT_CALL(*mockContainerizer1, launch(_, _, _, _, _, _, _, _))
    .WillOnce(Return(launchPromise.future()));

  Future<Nothing> destroy;
  Promise<bool> destroyPromise;
  EXPECT_CALL(*mockContainerizer1, destroy(_))
    .WillOnce(DoAll(FutureSatisfy(&destroy),
                    Return(destroyPromise.future())));

  Future<bool> launched = containerizer.launch(
      containerId,
      taskInfo,
      executorInfo,
      "dir",
      "user",
      slaveId,
      environment,
      false);

  Resources resources = Resources::parse("cpus:1;mem:256").get();

  EXPECT_TRUE(launched.isPending());

  Future<bool> destroyed = containerizer.destroy(containerId);

  // We make sure the destroy is being called on the containerizer.
  AWAIT_READY(destroy);

  launchPromise.set(false);
  destroyPromise.set(false);

  // `launch` should return false and `destroyed` should return false
  // because none of the containerizers support the launch.
  AWAIT_EXPECT_EQ(false, launched);
  AWAIT_EXPECT_EQ(false, destroyed);
}
Esempio n. 5
0
  Future<Option<MasterInfo>> detect(
      const Option<MasterInfo>& previous = None())
  {
    if (leader != previous) {
      return leader;
    }

    Promise<Option<MasterInfo>>* promise = new Promise<Option<MasterInfo>>();

    promise->future()
      .onDiscard(defer(self(), &Self::discard, promise->future()));

    promises.insert(promise);
    return promise->future();
  }
Esempio n. 6
0
TEST(FutureTest, UndiscardableFuture)
{
  Promise<int> promise;

  Future<int> f = undiscardable(promise.future());

  f.discard();

  EXPECT_TRUE(f.hasDiscard());
  EXPECT_FALSE(promise.future().hasDiscard());

  promise.set(42);

  AWAIT_ASSERT_EQ(42, f);
}
Esempio n. 7
0
  Future<int> create(
      const string& path,
      const string& data,
      const ACL_vector& acl,
      int flags,
      string* result)
  {
    Promise<int>* promise = new Promise<int>();

    Future<int> future = promise->future();

    tuple<Promise<int>*, string*>* args =
      new tuple<Promise<int>*, string*>(promise, result);

    int ret = zoo_acreate(
        zh,
        path.c_str(),
        data.data(),
        data.size(),
        &acl,
        flags,
        stringCompletion,
        args);

    if (ret != ZOK) {
      delete promise;
      delete args;
      return ret;
    }

    return future;
  }
Esempio n. 8
0
  Future<int> set(const string& path, const string& data, int version)
  {
    Promise<int>* promise = new Promise<int>();

    Future<int> future = promise->future();

    tuple<Promise<int>*, Stat*>* args =
      new tuple<Promise<int>*, Stat*>(promise, nullptr);

    int ret = zoo_aset(
        zh,
        path.c_str(),
        data.data(),
        data.size(),
        version,
        statCompletion,
        args);

    if (ret != ZOK) {
      delete promise;
      delete args;
      return ret;
    }

    return future;
  }
Esempio n. 9
0
FutureSync<void> TransportSocketCache::disconnect(MessageSocketPtr socket)
{
  Promise<void> promiseSocketRemoved;
  {
    auto syncDisconnectInfos = _disconnectInfos.synchronize();
    // TODO: Remove Promise<void>{} when get rid of VS2013.
    syncDisconnectInfos->push_back(DisconnectInfo{socket, Promise<void>{}});
    promiseSocketRemoved = syncDisconnectInfos->back().promiseSocketRemoved;
  }
  // We wait that the socket has been disconnected _and_ the `disconnected`
  // signal has been received by the cache.
  FutureBarrier<void> barrier;
  barrier.addFuture(promiseSocketRemoved.future());
  barrier.addFuture(socket->disconnect());
  Promise<void> promise;
  return barrier.future().then([=](const std::vector<Future<void>>& v) mutable {
    const auto isInError = [](const Future<void>& f) {
      return f.hasError();
    };
    if (std::any_of(begin(v), end(v), isInError))
    {
      promise.setError("disconnect error");
      return;
    }
    promise.setValue(0);
  });
}
Esempio n. 10
0
TEST(FutureTest, Chain)
{
  Future<string> s = readyFuture()
    .then(lambda::bind(&second, lambda::_1))
    .then(lambda::bind(&third, lambda::_1));

  s.await();

  ASSERT_TRUE(s.isReady());
  EXPECT_EQ("true", s.get());

  s = failedFuture()
    .then(lambda::bind(&second, lambda::_1))
    .then(lambda::bind(&third, lambda::_1));

  s.await();

  ASSERT_TRUE(s.isFailed());

  Promise<bool> promise;

  s = pendingFuture(promise.future())
    .then(lambda::bind(&second, lambda::_1))
    .then(lambda::bind(&third, lambda::_1));

  ASSERT_TRUE(s.isPending());

  promise.discard();

  AWAIT_DISCARDED(s);
}
Esempio n. 11
0
TEST(FutureTest, CallableOnce)
{
  Promise<Nothing> promise;
  promise.set(Nothing());

  Future<int> future = promise.future()
    .then(lambda::partial(
        [](std::unique_ptr<int>&& o) {
          return *o;
        },
        std::unique_ptr<int>(new int(42))));

  ASSERT_TRUE(future.isReady());
  EXPECT_EQ(42, future.get());

  int n = 0;
  future = promise.future()
    .onReady(lambda::partial(
        [&n](std::unique_ptr<int> o) {
          n += *o;
        },
        std::unique_ptr<int>(new int(1))))
    .onAny(lambda::partial(
        [&n](std::unique_ptr<int>&& o) {
          n += *o;
        },
        std::unique_ptr<int>(new int(10))))
    .onFailed(lambda::partial(
        [&n](const std::unique_ptr<int>& o) {
          n += *o;
        },
        std::unique_ptr<int>(new int(100))))
    .onDiscard(lambda::partial(
        [&n](std::unique_ptr<int>&& o) {
          n += *o;
        },
        std::unique_ptr<int>(new int(1000))))
    .onDiscarded(lambda::partial(
        [&n](std::unique_ptr<int>&& o) {
          n += *o;
        },
        std::unique_ptr<int>(new int(10000))))
    .then([&n]() { return n; });

  ASSERT_TRUE(future.isReady());
  EXPECT_EQ(11, future.get());
}
Esempio n. 12
0
inline Future<std::list<T> > collect(
    std::list<Future<T> >& futures,
    const Option<Timeout>& timeout)
{
    Promise<std::list<T> >* promise = new Promise<std::list<T> >();
    Future<std::list<T> > future = promise->future();
    spawn(new internal::CollectProcess<T>(futures, timeout, promise), true);
    return future;
}
// This test checks if destroy is called while container is being
// launched, the composing containerizer still calls the underlying
// containerizer's destroy and skip calling the rest of the
// containerizers.
TEST_F(ComposingContainerizerTest, DestroyWhileLaunching)
{
  vector<Containerizer*> containerizers;

  MockContainerizer* mockContainerizer = new MockContainerizer();
  MockContainerizer* mockContainerizer2 = new MockContainerizer();

  containerizers.push_back(mockContainerizer);
  containerizers.push_back(mockContainerizer2);

  ComposingContainerizer containerizer(containerizers);
  ContainerID containerId;
  containerId.set_value("container");
  TaskInfo taskInfo;
  ExecutorInfo executorInfo;
  SlaveID slaveId;
  std::map<std::string, std::string> environment;

  Promise<bool> launchPromise;

  EXPECT_CALL(*mockContainerizer, launch(_, _, _, _, _, _, _, _))
    .WillOnce(Return(launchPromise.future()));

  Future<Nothing> destroy;

  EXPECT_CALL(*mockContainerizer, destroy(_))
    .WillOnce(FutureSatisfy(&destroy));

  Future<bool> launch = containerizer.launch(
      containerId,
      taskInfo,
      executorInfo,
      "dir",
      "user",
      slaveId,
      environment,
      false);

  Resources resources = Resources::parse("cpus:1;mem:256").get();

  EXPECT_TRUE(launch.isPending());

  containerizer.destroy(containerId);

  EXPECT_CALL(*mockContainerizer2, launch(_, _, _, _, _, _, _, _))
    .Times(0);

  // We make sure the destroy is being called on the first containerizer.
  // The second containerizer shouldn't be called as well since the
  // container is already destroyed.
  AWAIT_READY(destroy);

  launchPromise.set(false);
  AWAIT_FAILED(launch);
}
Esempio n. 14
0
TEST(Process, then)
{
  Promise<int*> promise;

  int i = 42;

  promise.set(&i);

  Future<std::string> future = promise.future()
    .then(std::tr1::bind(&itoa1, std::tr1::placeholders::_1));

  ASSERT_TRUE(future.isReady());
  EXPECT_EQ("42", future.get());

  future = promise.future()
    .then(std::tr1::bind(&itoa2, std::tr1::placeholders::_1));

  ASSERT_TRUE(future.isReady());
  EXPECT_EQ("42", future.get());
}
Esempio n. 15
0
TEST(FutureTest, Then)
{
  Promise<int*> promise;

  int i = 42;

  promise.set(&i);

  Future<string> future = promise.future()
    .then(lambda::bind(&itoa1, lambda::_1));

  ASSERT_TRUE(future.isReady());
  EXPECT_EQ("42", future.get());

  future = promise.future()
    .then(lambda::bind(&itoa2, lambda::_1));

  ASSERT_TRUE(future.isReady());
  EXPECT_EQ("42", future.get());
}
Esempio n. 16
0
TEST(FutureTest, UndiscardableLambda)
{
  Promise<int> promise;

  Future<int> f = Future<int>(2)
    .then(undiscardable([&](int multiplier) {
      return promise.future()
        .then([=](int i) {
          return i * multiplier;
        });
    }));

  f.discard();

  EXPECT_TRUE(f.hasDiscard());
  EXPECT_FALSE(promise.future().hasDiscard());

  promise.set(42);

  AWAIT_ASSERT_EQ(84, f);
}
Esempio n. 17
0
TEST(LoopTest, DiscardIterate)
{
  Promise<int> promise;

  promise.future().onDiscard([&]() { promise.discard(); });

  Future<Nothing> future = loop(
      [&]() {
        return promise.future();
      },
      [&](int i) -> ControlFlow<Nothing> {
        return Break();
      });

  EXPECT_TRUE(future.isPending());

  future.discard();

  AWAIT_DISCARDED(future);
  EXPECT_TRUE(promise.future().hasDiscard());
}
Esempio n. 18
0
Future<Option<int64_t> > GroupProcess::session()
{
    if (error.isSome()) {
        Promise<Option<int64_t> > promise;
        promise.fail(error.get());
        return promise.future();
    } else if (state != CONNECTED) {
        return None();
    }

    return Option<int64_t>::some(zk->getSessionId());
}
Esempio n. 19
0
    Future<Nothing> acquire()
    {
        if (!promises.empty()) {
            // Need to wait for others to get permits first.
            Promise<Nothing>* promise = new Promise<Nothing>();
            promises.push_back(promise);
            return promise->future()
                   .onDiscard(defer(self(), &Self::discard, promise->future()));
        }

        if (timeout.remaining() > Seconds(0)) {
            // Need to wait a bit longer, but first one in the queue.
            Promise<Nothing>* promise = new Promise<Nothing>();
            promises.push_back(promise);
            delay(timeout.remaining(), self(), &Self::_acquire);
            return promise->future()
                   .onDiscard(defer(self(), &Self::discard, promise->future()));
        }

        // No need to wait!
        timeout = Seconds(1) / permitsPerSecond;
        return Nothing();
    }
Esempio n. 20
0
Future<Option<Group::Membership> > LeaderDetectorProcess::detect(
    const Option<Group::Membership>& previous)
{
  // Return immediately if the incumbent leader is different from the
  // expected.
  if (leader != previous) {
    return leader;
  }

  // Otherwise wait for the next election result.
  Promise<Option<Group::Membership> >* promise =
    new Promise<Option<Group::Membership> >();
  promises.insert(promise);
  return promise->future();
}
Esempio n. 21
0
TEST(FutureTest, RecoverFailed)
{
  Promise<int> promise;

  Future<string> future = promise.future()
    .then([]() -> string {
      return "hello";
    })
    .recover([](const Future<string>&) -> string {
      return "world";
    });

  promise.fail("Failure");

  AWAIT_EQ("world", future);
}
// This test ensures that a framework that is removed while
// authorization for registration is in progress is properly handled.
TEST_F(MasterAuthorizationTest, FrameworkRemovedBeforeRegistration)
{
  MockAuthorizer authorizer;
  Try<PID<Master> > master = StartMaster(&authorizer);
  ASSERT_SOME(master);

  MockScheduler sched;
  MesosSchedulerDriver driver(
      &sched, DEFAULT_FRAMEWORK_INFO, master.get(), DEFAULT_CREDENTIAL);

  // Return a pending future from authorizer.
  Future<Nothing> future;
  Promise<bool> promise;
  EXPECT_CALL(authorizer, authorize(An<const mesos::ACL::ReceiveOffers&>()))
    .WillOnce(DoAll(FutureSatisfy(&future),
                    Return(promise.future())));

  driver.start();

  // Wait until authorization is in progress.
  AWAIT_READY(future);

  // Stop the framework.
  // At this point the framework is disconnected but the master does
  // not take any action because the framework is not in its map yet.
  driver.stop();
  driver.join();

  // Settle the clock here to ensure master handles the framework
  // 'exited' event.
  Clock::pause();
  Clock::settle();
  Clock::resume();

  Future<Nothing> frameworkRemoved =
    FUTURE_DISPATCH(_, &AllocatorProcess::frameworkRemoved);

  // Now complete authorization.
  promise.set(true);

  // When the master tries to link to a non-existent framework PID
  // it should realize the framework is gone and remove it.
  AWAIT_READY(frameworkRemoved);

  Shutdown();
}
Esempio n. 23
0
  Future<int> remove(const string& path, int version)
  {
    Promise<int>* promise = new Promise<int>();

    Future<int> future = promise->future();

    tuple<Promise<int>*>* args = new tuple<Promise<int>*>(promise);

    int ret = zoo_adelete(zh, path.c_str(), version, voidCompletion, args);

    if (ret != ZOK) {
      delete promise;
      delete args;
      return ret;
    }

    return future;
  }
Esempio n. 24
0
  Future<int> get(const string& path, bool watch, string* result, Stat* stat)
  {
    Promise<int>* promise = new Promise<int>();

    Future<int> future = promise->future();

    tuple<Promise<int>*, string*, Stat*>* args =
      new tuple<Promise<int>*, string*, Stat*>(promise, result, stat);

    int ret = zoo_aget(zh, path.c_str(), watch, dataCompletion, args);

    if (ret != ZOK) {
      delete promise;
      delete args;
      return ret;
    }

    return future;
  }
Esempio n. 25
0
  Future<int> authenticate(const string& scheme, const string& credentials)
  {
    Promise<int>* promise = new Promise<int>();

    Future<int> future = promise->future();

    tuple<Promise<int>*>* args = new tuple<Promise<int>*>(promise);

    int ret = zoo_add_auth(zh, scheme.c_str(), credentials.data(),
                           credentials.size(), voidCompletion, args);

    if (ret != ZOK) {
      delete promise;
      delete args;
      return ret;
    }

    return future;
  }
Esempio n. 26
0
    Future<Option<Group::Membership> > LeaderDetectorProcess::detect(
            const Option<Group::Membership> &previous) {
        // Return immediately if the detector is no longer operational due
        // to the non-retryable error.
        if (error.isSome()) {
            return Failure(error.get().message);
        }

        // Return immediately if the incumbent leader is different from the
        // expected.
        if (leader != previous) {
            return leader;
        }

        // Otherwise wait for the next election result.
        Promise < Option<Group::Membership> > *promise =
                new Promise <Option<Group::Membership>>();
        promises.insert(promise);
        return promise->future();
    }
Esempio n. 27
0
  Future<int> getChildren(const string& path,
                          bool watch,
                          vector<string>* results)
  {
    Promise<int>* promise = new Promise<int>();

    Future<int> future = promise->future();

    tuple<Promise<int>*, vector<string>*>* args =
      new tuple<Promise<int>*, vector<string>*>(promise, results);

    int ret = zoo_aget_children(zh, path.c_str(), watch, stringsCompletion,
                                args);

    if (ret != ZOK) {
      delete promise;
      delete args;
      return ret;
    }

    return future;
  }
Esempio n. 28
0
TEST(FutureTest, FromTryFuture)
{
  Try<Future<int>> t = 1;
  Future<int> future = t;

  ASSERT_TRUE(future.isReady());
  EXPECT_EQ(1, future.get());

  Promise<int> p;
  t = p.future();
  future = t;

  ASSERT_TRUE(future.isPending());
  p.set(1);
  ASSERT_TRUE(future.isReady());
  EXPECT_EQ(1, future.get());

  t = Error("error");
  future = t;

  ASSERT_TRUE(future.isFailed());
  EXPECT_EQ(t.error(), future.failure());
}
Esempio n. 29
0
// Checks that completing a promise will keep the 'after' callback
// from executing.
TEST(FutureTest, After2)
{
  Clock::pause();

  std::atomic_bool executed(false);

  Promise<Nothing> promise;

  Future<Nothing> future = promise.future()
    .after(Hours(42), lambda::bind(&after, &executed, lambda::_1));

  EXPECT_TRUE(future.isPending());

  // Only advanced halfway, future should remain pending.
  Clock::advance(Hours(21));

  EXPECT_TRUE(future.isPending());

  // Even doing a discard on the future should keep it pending.
  future.discard();

  EXPECT_TRUE(future.isPending());

  // Now set the promise, the 'after' timer should be cancelled and
  // the pending future should be completed.
  promise.set(Nothing());

  AWAIT_READY(future);

  // Advancing time the rest of the way should not cause the 'after'
  // callback to execute.
  Clock::advance(Hours(21));

  EXPECT_FALSE(executed.load());

  Clock::resume();
}
// This test ensures that destroy can be called while in the
// launch loop. The composing containerizer still calls the
// underlying containerizer's destroy (because it's not sure
// if the containerizer can handle the type of container being
// launched). If the launch is not supported by the 1st containerizer,
// the composing containerizer should stop the launch loop and
// set the value of destroy future to true.
TEST_F(ComposingContainerizerTest, DestroyDuringUnsupportedLaunchLoop)
{
  vector<Containerizer*> containerizers;

  MockContainerizer* mockContainerizer1 = new MockContainerizer();
  MockContainerizer* mockContainerizer2 = new MockContainerizer();

  containerizers.push_back(mockContainerizer1);
  containerizers.push_back(mockContainerizer2);

  ComposingContainerizer containerizer(containerizers);
  ContainerID containerId;
  containerId.set_value("container");
  TaskInfo taskInfo;
  ExecutorInfo executorInfo;
  SlaveID slaveId;
  std::map<std::string, std::string> environment;

  Promise<bool> launchPromise;

  EXPECT_CALL(*mockContainerizer1, launch(_, _, _, _, _, _, _, _))
    .WillOnce(Return(launchPromise.future()));

  Future<Nothing> destroy;
  Promise<bool> destroyPromise;
  EXPECT_CALL(*mockContainerizer1, destroy(_))
    .WillOnce(DoAll(FutureSatisfy(&destroy),
                    Return(destroyPromise.future())));

  Future<bool> launched = containerizer.launch(
      containerId,
      taskInfo,
      executorInfo,
      "dir",
      "user",
      slaveId,
      environment,
      false);

  Resources resources = Resources::parse("cpus:1;mem:256").get();

  EXPECT_TRUE(launched.isPending());

  Future<bool> destroyed = containerizer.destroy(containerId);

  EXPECT_CALL(*mockContainerizer2, launch(_, _, _, _, _, _, _, _))
    .Times(0);

  // We make sure the destroy is being called on the first containerizer.
  // The second containerizer shouldn't be called as well since the
  // container is already destroyed.
  AWAIT_READY(destroy);

  launchPromise.set(false);
  destroyPromise.set(false);

  // `launched` should be a failure and `destroyed` should be true
  // because the launch was stopped from being tried on the 2nd
  // containerizer because of the destroy.
  AWAIT_FAILED(launched);
  AWAIT_EXPECT_EQ(true, destroyed);
}