TEST(Statistics, truncate) { Clock::pause(); Statistics statistics(Days(1)); statistics.set("test", "statistic", 3.0); Future<map<Seconds, double> > values = statistics.timeseries("test", "statistic"); values.await(); ASSERT_TRUE(values.isReady()); EXPECT_EQ(1, values.get().size()); EXPECT_GE(Clock::now(), values.get().begin()->first.secs()); EXPECT_DOUBLE_EQ(3.0, values.get().begin()->second); Clock::advance((60*60*24) + 1); statistics.increment("test", "statistic"); values = statistics.timeseries("test", "statistic"); values.await(); ASSERT_TRUE(values.isReady()); EXPECT_EQ(1, values.get().size()); EXPECT_GE(Clock::now(), values.get().begin()->first.secs()); EXPECT_DOUBLE_EQ(4.0, values.get().begin()->second); Clock::resume(); }
TEST(Statistics, truncate) { Clock::pause(); Statistics statistics(seconds(60*60*24)); statistics.set("statistic", 3.14); Future<map<seconds, double> > values = statistics.get("statistic"); values.await(); ASSERT_TRUE(values.isReady()); EXPECT_EQ(1, values.get().size()); EXPECT_GE(Clock::now(), values.get().begin()->first.value); EXPECT_DOUBLE_EQ(3.14, values.get().begin()->second); Clock::advance((60*60*24) + 1); statistics.increment("statistic"); values = statistics.get("statistic"); values.await(); ASSERT_TRUE(values.isReady()); EXPECT_EQ(1, values.get().size()); EXPECT_GE(Clock::now(), values.get().begin()->first.value); EXPECT_DOUBLE_EQ(4.14, values.get().begin()->second); Clock::resume(); }
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); }
TEST(ProcessTest, Defer2) { ASSERT_TRUE(GTEST_IS_THREADSAFE); DeferProcess process; PID<DeferProcess> pid = spawn(process); Future<string> f = dispatch(pid, &DeferProcess::func1, 41); f.await(); ASSERT_TRUE(f.isReady()); EXPECT_EQ("41", f.get()); f = dispatch(pid, &DeferProcess::func2, 41); f.await(); ASSERT_TRUE(f.isReady()); EXPECT_EQ("42", f.get()); terminate(pid); wait(pid); }
TEST(CoordinatorTest, Truncate) { const std::string path1 = utils::os::getcwd() + "/.log1"; const std::string path2 = utils::os::getcwd() + "/.log2"; utils::os::rmdir(path1); utils::os::rmdir(path2); Replica replica1(path1); Replica replica2(path2); Network network; network.add(replica1.pid()); network.add(replica2.pid()); Coordinator coord(2, &replica1, &network); { Result<uint64_t> result = coord.elect(Timeout(1.0)); ASSERT_TRUE(result.isSome()); EXPECT_EQ(0, result.get()); } for (uint64_t position = 1; position <= 10; position++) { Result<uint64_t> result = coord.append(utils::stringify(position), Timeout(1.0)); ASSERT_TRUE(result.isSome()); EXPECT_EQ(position, result.get()); } { Result<uint64_t> result = coord.truncate(7, Timeout(1.0)); ASSERT_TRUE(result.isSome()); EXPECT_EQ(11, result.get()); } { Future<std::list<Action> > actions = replica1.read(6, 10); ASSERT_TRUE(actions.await(2.0)); ASSERT_TRUE(actions.isFailed()); EXPECT_EQ("Bad read range (truncated position)", actions.failure()); } { Future<std::list<Action> > actions = replica1.read(7, 10); ASSERT_TRUE(actions.await(2.0)); ASSERT_TRUE(actions.isReady()); EXPECT_EQ(4, actions.get().size()); foreach (const Action& action, actions.get()) { ASSERT_TRUE(action.has_type()); ASSERT_EQ(Action::APPEND, action.type()); EXPECT_EQ(utils::stringify(action.position()), action.append().bytes()); } } utils::os::rmdir(path1); utils::os::rmdir(path2); }
TEST(ReplicaTest, Promise) { const std::string path = utils::os::getcwd() + "/.log"; utils::os::rmdir(path); Replica replica(path); PromiseRequest request; PromiseResponse response; Future<PromiseResponse> future; request.set_id(2); future = protocol::promise(replica.pid(), request); future.await(2.0); ASSERT_TRUE(future.isReady()); response = future.get(); EXPECT_TRUE(response.okay()); EXPECT_EQ(2, response.id()); EXPECT_TRUE(response.has_position()); EXPECT_EQ(0, response.position()); EXPECT_FALSE(response.has_action()); request.set_id(1); future = protocol::promise(replica.pid(), request); future.await(2.0); ASSERT_TRUE(future.isReady()); response = future.get(); EXPECT_FALSE(response.okay()); EXPECT_EQ(1, response.id()); EXPECT_FALSE(response.has_position()); EXPECT_FALSE(response.has_action()); request.set_id(3); future = protocol::promise(replica.pid(), request); future.await(2.0); ASSERT_TRUE(future.isReady()); response = future.get(); EXPECT_TRUE(response.okay()); EXPECT_EQ(3, response.id()); EXPECT_TRUE(response.has_position()); EXPECT_EQ(0, response.position()); EXPECT_FALSE(response.has_action()); utils::os::rmdir(path); }
TEST(Statistics, set) { Statistics statistics(Days(1)); // Set one using Clock::now() implicitly. statistics.set("test", "statistic", 3.0); // Set one using Clock::now() explicitly. Seconds now(Clock::now()); statistics.set("test", "statistic", 4.0, now); Future<map<Seconds, double> > values = statistics.timeseries("test", "statistic"); values.await(); ASSERT_TRUE(values.isReady()); EXPECT_EQ(2, values.get().size()); EXPECT_GE(Clock::now(), values.get().begin()->first.secs()); EXPECT_DOUBLE_EQ(3.0, values.get().begin()->second); EXPECT_EQ(1, values.get().count(now)); EXPECT_DOUBLE_EQ(4.0, values.get()[now]); }
TEST(Process, collect) { ASSERT_TRUE(GTEST_IS_THREADSAFE); Promise<int> promise1; Promise<int> promise2; Promise<int> promise3; Promise<int> promise4; std::list<Future<int> > futures; futures.push_back(promise1.future()); futures.push_back(promise2.future()); futures.push_back(promise3.future()); futures.push_back(promise4.future()); promise1.set(1); promise2.set(2); promise3.set(3); promise4.set(4); Future<std::list<int> > future = collect(futures); EXPECT_TRUE(future.await()); EXPECT_TRUE(future.isReady()); std::list<int> values; values.push_back(1); values.push_back(2); values.push_back(3); values.push_back(4); EXPECT_EQ(values, future.get()); }
bool SlavesManager::remove(const string& hostname, uint16_t port) { // Make sure the slave is currently activated or deactivated. if (!active.contains(hostname, port) && !inactive.contains(hostname, port)) { LOG(WARNING) << "Attempted to remove unknown slave!"; return false; } // Get the storage system to persist the removal. Future<bool> removed = process::dispatch(storage->self(), &SlavesManagerStorage::remove, hostname, port); removed.await(); if (removed.isReady() && removed.get()) { active.remove(hostname, port); inactive.remove(hostname, port); // Tell the master that this slave is now deactivated. process::dispatch(master, &Master::deactivatedSlaveHostnamePort, hostname, port); return true; } return false; }
/* * Class: org_apache_mesos_state_ZooKeeperState * Method: __expunge_get * Signature: (J)Ljava/lang/Boolean; */ JNIEXPORT jobject JNICALL Java_org_apache_mesos_state_ZooKeeperState__1_1expunge_1get (JNIEnv* env, jobject thiz, jlong jfuture) { Future<bool>* future = (Future<bool>*) jfuture; future->await(); if (future->isFailed()) { jclass clazz = env->FindClass("java/util/concurrent/ExecutionException"); env->ThrowNew(clazz, future->failure().c_str()); return NULL; } else if (future->isDiscarded()) { jclass clazz = env->FindClass("java/util/concurrent/CancellationException"); env->ThrowNew(clazz, "Future was discarded"); return NULL; } CHECK(future->isReady()); if (future->get()) { jclass clazz = env->FindClass("java/lang/Boolean"); return env->GetStaticObjectField( clazz, env->GetStaticFieldID(clazz, "TRUE", "Ljava/lang/Boolean;")); } jclass clazz = env->FindClass("java/lang/Boolean"); return env->GetStaticObjectField( clazz, env->GetStaticFieldID(clazz, "FALSE", "Ljava/lang/Boolean;")); }
/* * Class: org_apache_mesos_state_AbstractState * Method: __fetch_get * Signature: (J)Lorg/apache/mesos/state/Variable; */ JNIEXPORT jobject JNICALL Java_org_apache_mesos_state_AbstractState__1_1fetch_1get (JNIEnv* env, jobject thiz, jlong jfuture) { Future<Variable>* future = (Future<Variable>*) jfuture; future->await(); if (future->isFailed()) { jclass clazz = env->FindClass("java/util/concurrent/ExecutionException"); env->ThrowNew(clazz, future->failure().c_str()); return nullptr; } else if (future->isDiscarded()) { // TODO(benh): Consider throwing an ExecutionException since we // never return true for 'isCancelled'. jclass clazz = env->FindClass("java/util/concurrent/CancellationException"); env->ThrowNew(clazz, "Future was discarded"); return nullptr; } CHECK_READY(*future); Variable* variable = new Variable(future->get()); // Variable variable = new Variable(); jclass clazz = env->FindClass("org/apache/mesos/state/Variable"); jmethodID _init_ = env->GetMethodID(clazz, "<init>", "()V"); jobject jvariable = env->NewObject(clazz, _init_); jfieldID __variable = env->GetFieldID(clazz, "__variable", "J"); env->SetLongField(jvariable, __variable, (jlong) variable); return jvariable; }
// This hook locates the file created by environment decorator hook // and deletes it. virtual Try<Nothing> slaveRemoveExecutorHook( const FrameworkInfo& frameworkInfo, const ExecutorInfo& executorInfo) { LOG(INFO) << "Executing 'slaveRemoveExecutorHook'"; // Send a HookExecuted message to ourself. The hook test // "VerifySlaveLaunchExecutorHook" will wait for the testing // infrastructure to intercept this message. The intercepted message // indicates successful execution of this hook. HookProcess hookProcess; process::spawn(&hookProcess); Future<Nothing> future = process::dispatch(hookProcess, &HookProcess::await); process::dispatch(hookProcess, &HookProcess::signal); // Make sure we don't terminate the process before the message self-send has // completed. future.await(); process::terminate(hookProcess); process::wait(hookProcess); return Nothing(); }
TEST(CoordinatorTest, Failover) { const std::string path1 = utils::os::getcwd() + "/.log1"; const std::string path2 = utils::os::getcwd() + "/.log2"; utils::os::rmdir(path1); utils::os::rmdir(path2); Replica replica1(path1); Replica replica2(path2); Network network1; network1.add(replica1.pid()); network1.add(replica2.pid()); Coordinator coord1(2, &replica1, &network1); { Result<uint64_t> result = coord1.elect(Timeout(1.0)); ASSERT_TRUE(result.isSome()); EXPECT_EQ(0, result.get()); } uint64_t position; { Result<uint64_t> result = coord1.append("hello world", Timeout(1.0)); ASSERT_TRUE(result.isSome()); position = result.get(); EXPECT_EQ(1, position); } Network network2; network2.add(replica1.pid()); network2.add(replica2.pid()); Coordinator coord2(2, &replica2, &network2); { Result<uint64_t> result = coord2.elect(Timeout(1.0)); ASSERT_TRUE(result.isSome()); EXPECT_EQ(position, result.get()); } { Future<std::list<Action> > actions = replica2.read(position, position); ASSERT_TRUE(actions.await(2.0)); ASSERT_TRUE(actions.isReady()); ASSERT_EQ(1, actions.get().size()); EXPECT_EQ(position, actions.get().front().position()); ASSERT_TRUE(actions.get().front().has_type()); ASSERT_EQ(Action::APPEND, actions.get().front().type()); EXPECT_EQ("hello world", actions.get().front().append().bytes()); } utils::os::rmdir(path1); utils::os::rmdir(path2); }
virtual Try<Nothing> masterSlaveLostHook(const SlaveInfo& slaveInfo) { LOG(INFO) << "Executing 'masterSlaveLostHook' in agent '" << slaveInfo.id() << "'"; // TODO(nnielsen): Add argument to signal(), so we can filter messages from // the `masterSlaveLostHook` from `slaveRemoveExecutorHook`. // NOTE: Will not be a problem **as long as** the test doesn't start any // tasks. HookProcess hookProcess; process::spawn(&hookProcess); Future<Nothing> future = process::dispatch(hookProcess, &HookProcess::await); process::dispatch(hookProcess, &HookProcess::signal); // Make sure we don't terminate the process before the message self-send has // completed. future.await(); process::terminate(hookProcess); process::wait(hookProcess); return Nothing(); }
bool SlavesManager::deactivate(const string& hostname, uint16_t port) { // Make sure the slave is currently activated. if (active.contains(hostname, port)) { // Get the storage system to persist the deactivation. Future<bool> deactivated = process::dispatch(storage->self(), &SlavesManagerStorage::deactivate, hostname, port); deactivated.await(); if (deactivated.isReady() && deactivated.get()) { active.remove(hostname, port); inactive.put(hostname, port); // Tell the master that this slave is now deactivated. process::dispatch(master, &Master::deactivatedSlaveHostnamePort, hostname, port); return true; } } return false; }
bool SlavesManager::add(const string& hostname, uint16_t port) { // Ignore request if slave is already active. if (active.contains(hostname, port)) { LOG(WARNING) << "Attempted to add an already added slave!"; return false; } // Make sure this slave is not currently deactivated. if (inactive.contains(hostname, port)) { LOG(WARNING) << "Attempted to add a deactivated slave, " << "try activating it instead!"; return false; } // Ask the storage system to persist the addition. Future<bool> added = process::dispatch(storage->self(), &SlavesManagerStorage::add, hostname, port); added.await(); if (added.isReady() && added.get()) { active.put(hostname, port); // Tell the master that this slave is now active. process::dispatch(master, &Master::activatedSlaveHostnamePort, hostname, port); return true; } return false; }
/* * Class: org_apache_mesos_state_AbstractState * Method: __expunge_get * Signature: (J)Ljava/lang/Boolean; */ JNIEXPORT jobject JNICALL Java_org_apache_mesos_state_AbstractState__1_1expunge_1get (JNIEnv* env, jobject thiz, jlong jfuture) { Future<bool>* future = (Future<bool>*) jfuture; future->await(); if (future->isFailed()) { jclass clazz = env->FindClass("java/util/concurrent/ExecutionException"); env->ThrowNew(clazz, future->failure().c_str()); return NULL; } else if (future->isDiscarded()) { // TODO(benh): Consider throwing an ExecutionException since we // never return true for 'isCancelled'. jclass clazz = env->FindClass("java/util/concurrent/CancellationException"); env->ThrowNew(clazz, "Future was discarded"); return NULL; } CHECK_READY(*future); if (future->get()) { jclass clazz = env->FindClass("java/lang/Boolean"); return env->GetStaticObjectField( clazz, env->GetStaticFieldID(clazz, "TRUE", "Ljava/lang/Boolean;")); } jclass clazz = env->FindClass("java/lang/Boolean"); return env->GetStaticObjectField( clazz, env->GetStaticFieldID(clazz, "FALSE", "Ljava/lang/Boolean;")); }
/* * Class: org_apache_mesos_state_ZooKeeperState * Method: __fetch_get * Signature: (J)Lorg/apache/mesos/state/Variable; */ JNIEXPORT jobject JNICALL Java_org_apache_mesos_state_ZooKeeperState__1_1fetch_1get (JNIEnv* env, jobject thiz, jlong jfuture) { Future<Variable>* future = (Future<Variable>*) jfuture; future->await(); if (future->isFailed()) { jclass clazz = env->FindClass("java/util/concurrent/ExecutionException"); env->ThrowNew(clazz, future->failure().c_str()); return NULL; } else if (future->isDiscarded()) { jclass clazz = env->FindClass("java/util/concurrent/CancellationException"); env->ThrowNew(clazz, "Future was discarded"); return NULL; } CHECK(future->isReady()); Variable* variable = new Variable(future->get()); // Variable variable = new Variable(); jclass clazz = env->FindClass("org/apache/mesos/state/Variable"); jmethodID _init_ = env->GetMethodID(clazz, "<init>", "()V"); jobject jvariable = env->NewObject(clazz, _init_); jfieldID __variable = env->GetFieldID(clazz, "__variable", "J"); env->SetLongField(jvariable, __variable, (jlong) variable); return jvariable; }
TEST(Statistics, meter) { Statistics statistics(Days(1)); // Set up a meter, and ensure it captures the expected time rate. Future<Try<Nothing> > meter = statistics.meter("test", "statistic", new meters::TimeRate("metered")); meter.await(); ASSERT_TRUE(meter.isReady()); ASSERT_TRUE(meter.get().isSome()); Seconds now(Clock::now()); statistics.set("test", "statistic", 1.0, now); statistics.set("test", "statistic", 2.0, Seconds(now.secs() + 1.0)); statistics.set("test", "statistic", 4.0, Seconds(now.secs() + 2.0)); // Check the raw statistic values. Future<map<Seconds, double> > values = statistics.timeseries("test", "statistic"); values.await(); ASSERT_TRUE(values.isReady()); EXPECT_EQ(3, values.get().size()); EXPECT_EQ(1, values.get().count(now)); EXPECT_EQ(1, values.get().count(Seconds(now.secs() + 1.0))); EXPECT_EQ(1, values.get().count(Seconds(now.secs() + 2.0))); EXPECT_EQ(1.0, values.get()[now]); EXPECT_EQ(2.0, values.get()[Seconds(now.secs() + 1.0)]); EXPECT_EQ(4.0, values.get()[Seconds(now.secs() + 2.0)]); // Now check the metered values. values = statistics.timeseries("test", "metered"); values.await(); ASSERT_TRUE(values.isReady()); EXPECT_EQ(2, values.get().size()); EXPECT_EQ(1, values.get().count(Seconds(now.secs() + 1.0))); EXPECT_EQ(1, values.get().count(Seconds(now.secs() + 2.0))); EXPECT_EQ(0., values.get()[now]); EXPECT_EQ(1.0, values.get()[Seconds(now.secs() + 1.0)]); // 100%. EXPECT_EQ(2.0, values.get()[Seconds(now.secs() + 2.0)]); // 200%. }
void _healthCheck() { if (check.has_http()) { promise.fail("HTTP health check is not supported"); } else if (check.has_command()) { const CommandInfo& command = check.command(); map<string, string> environment; foreach (const Environment_Variable& variable, command.environment().variables()) { environment[variable.name()] = variable.value(); } VLOG(2) << "Launching health command: " << command.value(); Try<Subprocess> external = process::subprocess( command.value(), // Reading from STDIN instead of PIPE because scripts // seeing an open STDIN pipe might behave differently // and we do not expect to pass any value from STDIN // or PIPE. Subprocess::FD(STDIN_FILENO), Subprocess::FD(STDERR_FILENO), Subprocess::FD(STDERR_FILENO), environment); if (external.isError()) { promise.fail("Error creating subprocess for healthcheck"); } else { Future<Option<int> > status = external.get().status(); status.await(Seconds(check.timeout_seconds())); if (!status.isReady()) { string msg = "Shell command check failed with reason: "; if (status.isFailed()) { msg += "failed with error: " + status.failure(); } else if (status.isDiscarded()) { msg += "status future discarded"; } else { msg += "status still pending after timeout " + stringify(Seconds(check.timeout_seconds())); } promise.fail(msg); return; } int statusCode = status.get().get(); if (statusCode != 0) { string message = "Health command check " + WSTRINGIFY(statusCode); failure(message); } else { success(); } } } else {
/* * Class: org_apache_mesos_state_AbstractState * Method: __names_get_timeout * Signature: (JJLjava/util/concurrent/TimeUnit;)Ljava/util/Iterator; */ JNIEXPORT jobject JNICALL Java_org_apache_mesos_state_AbstractState__1_1names_1get_1timeout (JNIEnv* env, jobject thiz, jlong jfuture, jlong jtimeout, jobject junit) { Future<set<string> >* future = (Future<set<string> >*) jfuture; jclass clazz = env->GetObjectClass(junit); // long seconds = unit.toSeconds(time); jmethodID toSeconds = env->GetMethodID(clazz, "toSeconds", "(J)J"); jlong jseconds = env->CallLongMethod(junit, toSeconds, jtimeout); Seconds seconds(jseconds); if (future->await(seconds)) { if (future->isFailed()) { clazz = env->FindClass("java/util/concurrent/ExecutionException"); env->ThrowNew(clazz, future->failure().c_str()); return NULL; } else if (future->isDiscarded()) { // TODO(benh): Consider throwing an ExecutionException since we // never return true for 'isCancelled'. clazz = env->FindClass("java/util/concurrent/CancellationException"); env->ThrowNew(clazz, "Future was discarded"); return NULL; } CHECK_READY(*future); // List names = new ArrayList(); clazz = env->FindClass("java/util/ArrayList"); jmethodID _init_ = env->GetMethodID(clazz, "<init>", "()V"); jobject jnames = env->NewObject(clazz, _init_); jmethodID add = env->GetMethodID(clazz, "add", "(Ljava/lang/Object;)Z"); foreach (const string& name, future->get()) { jobject jname = convert<string>(env, name); env->CallBooleanMethod(jnames, add, jname); } // Iterator iterator = jnames.iterator(); jmethodID iterator = env->GetMethodID(clazz, "iterator", "()Ljava/util/Iterator;"); jobject jiterator = env->CallObjectMethod(jnames, iterator); return jiterator; } clazz = env->FindClass("java/util/concurrent/TimeoutException"); env->ThrowNew(clazz, "Failed to wait for future within timeout"); return NULL; }
/* * Class: org_apache_mesos_state_AbstractState * Method: __store_get_timeout * Signature: (JJLjava/util/concurrent/TimeUnit;)Lorg/apache/mesos/state/Variable; */ JNIEXPORT jobject JNICALL Java_org_apache_mesos_state_AbstractState__1_1store_1get_1timeout (JNIEnv* env, jobject thiz, jlong jfuture, jlong jtimeout, jobject junit) { Future<Option<Variable> >* future = (Future<Option<Variable> >*) jfuture; jclass clazz = env->GetObjectClass(junit); // long seconds = unit.toSeconds(time); jmethodID toSeconds = env->GetMethodID(clazz, "toSeconds", "(J)J"); jlong jseconds = env->CallLongMethod(junit, toSeconds, jtimeout); Seconds seconds(jseconds); if (future->await(seconds)) { if (future->isFailed()) { clazz = env->FindClass("java/util/concurrent/ExecutionException"); env->ThrowNew(clazz, future->failure().c_str()); return NULL; } else if (future->isDiscarded()) { // TODO(benh): Consider throwing an ExecutionException since we // never return true for 'isCancelled'. clazz = env->FindClass("java/util/concurrent/CancellationException"); env->ThrowNew(clazz, "Future was discarded"); return NULL; } CHECK_READY(*future); if (future->get().isSome()) { Variable* variable = new Variable(future->get().get()); // Variable variable = new Variable(); clazz = env->FindClass("org/apache/mesos/state/Variable"); jmethodID _init_ = env->GetMethodID(clazz, "<init>", "()V"); jobject jvariable = env->NewObject(clazz, _init_); jfieldID __variable = env->GetFieldID(clazz, "__variable", "J"); env->SetLongField(jvariable, __variable, (jlong) variable); return jvariable; } return NULL; } clazz = env->FindClass("java/util/concurrent/TimeoutException"); env->ThrowNew(clazz, "Failed to wait for future within timeout"); return NULL; }
// Find out how large a potential download from the given URI is. static Try<Bytes> fetchSize( const string& uri, const Option<string>& frameworksHome) { VLOG(1) << "Fetching size for URI: " << uri; Result<string> path = Fetcher::uriToLocalPath(uri, frameworksHome); if (path.isError()) { return Error(path.error()); } if (path.isSome()) { Try<Bytes> size = os::stat::size(path.get(), os::stat::FOLLOW_SYMLINK); if (size.isError()) { return Error("Could not determine file size for: '" + path.get() + "', error: " + size.error()); } return size.get(); } if (Fetcher::isNetUri(uri)) { Try<Bytes> size = net::contentLength(uri); if (size.isError()) { return Error(size.error()); } if (size.get() == 0) { return Error("URI reported content-length 0: " + uri); } return size.get(); } // TODO(hausdorff): (MESOS-5460) Explore adding support for fetching from // HDFS. #ifndef __WINDOWS__ Try<Owned<HDFS>> hdfs = HDFS::create(); if (hdfs.isError()) { return Error("Failed to create HDFS client: " + hdfs.error()); } Future<Bytes> size = hdfs.get()->du(uri); size.await(); if (!size.isReady()) { return Error("Hadoop client could not determine size: " + (size.isFailed() ? size.failure() : "discarded")); } return size.get(); #else return Error("Windows currently does not support fetching files from HDFS"); #endif // __WINDOWS__ }
TEST(Statistics, set) { Statistics statistics(seconds(60*60*24)); statistics.set("statistic", 3.14); Future<map<seconds, double> > values = statistics.get("statistic"); values.await(); ASSERT_TRUE(values.isReady()); EXPECT_EQ(1, values.get().size()); EXPECT_GE(Clock::now(), values.get().begin()->first.value); EXPECT_DOUBLE_EQ(3.14, values.get().begin()->second); }
// Find out how large a potential download from the given URI is. static Try<Bytes> fetchSize( const string& uri, const Option<string>& frameworksHome) { VLOG(1) << "Fetching size for URI: " << uri; Result<string> path = Fetcher::uriToLocalPath(uri, frameworksHome); if (path.isError()) { return Error(path.error()); } if (path.isSome()) { Try<Bytes> size = os::stat::size(path.get(), os::stat::FOLLOW_SYMLINK); if (size.isError()) { return Error("Could not determine file size for: '" + path.get() + "', error: " + size.error()); } return size.get(); } if (Fetcher::isNetUri(uri)) { Try<Bytes> size = net::contentLength(uri); if (size.isError()) { return Error(size.error()); } if (size.get() == 0) { return Error("URI reported content-length 0: " + uri); } return size.get(); } Try<Owned<HDFS>> hdfs = HDFS::create(); if (hdfs.isError()) { return Error("Failed to create HDFS client: " + hdfs.error()); } Future<Bytes> size = hdfs.get()->du(uri); size.await(); if (!size.isReady()) { return Error("Hadoop client could not determine size: " + (size.isFailed() ? size.failure() : "discarded")); } return size.get(); }
/* * Class: org_apache_mesos_state_ZooKeeperState * Method: __fetch_get_timeout * Signature: (JJLjava/util/concurrent/TimeUnit;)Lorg/apache/mesos/state/Variable; */ JNIEXPORT jobject JNICALL Java_org_apache_mesos_state_ZooKeeperState__1_1fetch_1get_1timeout (JNIEnv* env, jobject thiz, jlong jfuture, jlong jtimeout, jobject junit) { Future<Variable>* future = (Future<Variable>*) jfuture; jclass clazz = env->GetObjectClass(junit); // long seconds = unit.toSeconds(time); jmethodID toSeconds = env->GetMethodID(clazz, "toSeconds", "(J)J"); jlong jseconds = env->CallLongMethod(junit, toSeconds, jtimeout); Seconds seconds(jseconds); if (future->await(seconds)) { if (future->isFailed()) { clazz = env->FindClass("java/util/concurrent/ExecutionException"); env->ThrowNew(clazz, future->failure().c_str()); return NULL; } else if (future->isDiscarded()) { clazz = env->FindClass("java/util/concurrent/CancellationException"); env->ThrowNew(clazz, "Future was discarded"); return NULL; } CHECK(future->isReady()); Variable* variable = new Variable(future->get()); // Variable variable = new Variable(); clazz = env->FindClass("org/apache/mesos/state/Variable"); jmethodID _init_ = env->GetMethodID(clazz, "<init>", "()V"); jobject jvariable = env->NewObject(clazz, _init_); jfieldID __variable = env->GetFieldID(clazz, "__variable", "J"); env->SetLongField(jvariable, __variable, (jlong) variable); return jvariable; } clazz = env->FindClass("java/util/concurrent/TimeoutException"); env->ThrowNew(clazz, "Failed to wait for future within timeout"); return NULL; }
/* * Class: org_apache_mesos_state_AbstractState * Method: __expunge_get_timeout * Signature: (JJLjava/util/concurrent/TimeUnit;)Ljava/lang/Boolean; */ JNIEXPORT jobject JNICALL Java_org_apache_mesos_state_AbstractState__1_1expunge_1get_1timeout (JNIEnv* env, jobject thiz, jlong jfuture, jlong jtimeout, jobject junit) { Future<bool>* future = (Future<bool>*) jfuture; jclass clazz = env->GetObjectClass(junit); // long seconds = unit.toSeconds(time); jmethodID toSeconds = env->GetMethodID(clazz, "toSeconds", "(J)J"); jlong jseconds = env->CallLongMethod(junit, toSeconds, jtimeout); Seconds seconds(jseconds); if (future->await(seconds)) { if (future->isFailed()) { clazz = env->FindClass("java/util/concurrent/ExecutionException"); env->ThrowNew(clazz, future->failure().c_str()); return NULL; } else if (future->isDiscarded()) { // TODO(benh): Consider throwing an ExecutionException since we // never return true for 'isCancelled'. clazz = env->FindClass("java/util/concurrent/CancellationException"); env->ThrowNew(clazz, "Future was discarded"); return NULL; } CHECK_READY(*future); if (future->get()) { jclass clazz = env->FindClass("java/lang/Boolean"); return env->GetStaticObjectField( clazz, env->GetStaticFieldID(clazz, "TRUE", "Ljava/lang/Boolean;")); } jclass clazz = env->FindClass("java/lang/Boolean"); return env->GetStaticObjectField( clazz, env->GetStaticFieldID(clazz, "FALSE", "Ljava/lang/Boolean;")); } clazz = env->FindClass("java/util/concurrent/TimeoutException"); env->ThrowNew(clazz, "Failed to wait for future within timeout"); return NULL; }
TEST(CoordinatorTest, AppendReadError) { const std::string path1 = utils::os::getcwd() + "/.log1"; const std::string path2 = utils::os::getcwd() + "/.log2"; utils::os::rmdir(path1); utils::os::rmdir(path2); Replica replica1(path1); Replica replica2(path2); Network network; network.add(replica1.pid()); network.add(replica2.pid()); Coordinator coord(2, &replica1, &network); { Result<uint64_t> result = coord.elect(Timeout(1.0)); ASSERT_TRUE(result.isSome()); EXPECT_EQ(0, result.get()); } uint64_t position; { Result<uint64_t> result2 = coord.append("hello world", Timeout(1.0)); ASSERT_TRUE(result2.isSome()); position = result2.get(); EXPECT_EQ(1, position); } { position += 1; Future<std::list<Action> > actions = replica1.read(position, position); ASSERT_TRUE(actions.await(2.0)); ASSERT_TRUE(actions.isFailed()); EXPECT_EQ("Bad read range (past end of log)", actions.failure()); } utils::os::rmdir(path1); utils::os::rmdir(path2); }
TEST_F(FrameworksManagerTestFixture, AddFramework) { // Test if initially FM returns empty list. Future<Result<map<FrameworkID, FrameworkInfo> > > future = process::dispatch(manager, &FrameworksManager::list); ASSERT_TRUE(future.await(2.0)); EXPECT_TRUE(future.get().get().empty()); // Add a dummy framework. FrameworkID id; id.set_value("id"); FrameworkInfo info; info.set_name("test name"); info.set_user("test user"); // Add the framework. Future<Result<bool> > future2 = process::dispatch(manager, &FrameworksManager::add, id, info); ASSERT_TRUE(future2.await(2.0)); EXPECT_TRUE(future2.get().get()); // Check if framework manager returns the added framework. Future<Result<map<FrameworkID, FrameworkInfo> > > future3 = process::dispatch(manager, &FrameworksManager::list); ASSERT_TRUE(future3.await(2.0)); map<FrameworkID, FrameworkInfo> result = future3.get().get(); ASSERT_EQ(1, result.count(id)); EXPECT_EQ("test name", result[id].name()); EXPECT_EQ("test user", result[id].user()); // Check if the framework exists. Future<Result<bool> > future4 = process::dispatch(manager, &FrameworksManager::exists, id); ASSERT_TRUE(future4.await(2.0)); EXPECT_TRUE(future4.get().get()); }
TEST(Process, poll) { ASSERT_TRUE(GTEST_IS_THREADSAFE); int pipes[2]; pipe(pipes); Future<short> future = io::poll(pipes[0], io::READ); EXPECT_FALSE(future.isReady()); ASSERT_EQ(3, write(pipes[1], "hi", 3)); future.await(); ASSERT_TRUE(future.isReady()); EXPECT_EQ(io::READ, future.get()); close(pipes[0]); close(pipes[1]); }