// This test verifies that the pending future returned by // 'Authenticator::authenticate()' is properly failed when the Authenticator is // destructed in the middle of authentication. TYPED_TEST(CRAMMD5Authentication, AuthenticatorDestructionRace) { // Launch a dummy process (somebody to send the AuthenticateMessage). UPID pid = spawn(new ProcessBase(), true); Credential credential1; credential1.set_principal("benh"); credential1.set_secret("secret"); Credentials credentials; Credential* credential2 = credentials.add_credentials(); credential2->set_principal(credential1.principal()); credential2->set_secret(credential1.secret()); secrets::load(credentials); Future<Message> message = FUTURE_MESSAGE(Eq(AuthenticateMessage().GetTypeName()), _, _); Try<Authenticatee*> authenticatee = TypeParam::TypeAuthenticatee::create(); CHECK_SOME(authenticatee); Future<bool> client = authenticatee.get()->authenticate(pid, UPID(), credential1); AWAIT_READY(message); Try<Authenticator*> authenticator = TypeParam::TypeAuthenticator::create(); CHECK_SOME(authenticator); authenticator.get()->initialize(message.get().from); // Drop the AuthenticationStepMessage from authenticator to keep // the authentication from getting completed. Future<AuthenticationStepMessage> authenticationStepMessage = DROP_PROTOBUF(AuthenticationStepMessage(), _, _); Future<Option<string>> principal = authenticator.get()->authenticate(); AWAIT_READY(authenticationStepMessage); // At this point 'AuthenticatorProcess::authenticate()' has been // executed and its promise associated with the promise returned // by 'Authenticator::authenticate()'. // Authentication should be pending. ASSERT_TRUE(principal.isPending()); // Now delete the authenticator. delete authenticator.get(); // The future should be failed at this point. AWAIT_FAILED(principal); terminate(pid); delete authenticatee.get(); }
// 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); }
// Negative test case that tests CopyFetcher plugin for a non-exiting file. TEST_F(CopyFetcherPluginTest, FetchNonExistingFile) { const URI uri = uri::file(path::join(os::getcwd(), "non-exist")); // Use the file fetcher to fetch the URI. Try<Owned<uri::Fetcher>> fetcher = uri::fetcher::create(); ASSERT_SOME(fetcher); const string dir = path::join(os::getcwd(), "dir"); // Validate that the fetch failed. AWAIT_FAILED(fetcher.get()->fetch(uri, dir)); }
TEST_F(HadoopFetcherPluginTest, FetchNonExistingFile) { URI uri = uri::hdfs(path::join(os::getcwd(), "non-exist")); uri::fetcher::Flags flags; flags.hadoop_client = hadoop; Try<Owned<uri::Fetcher>> fetcher = uri::fetcher::create(flags); ASSERT_SOME(fetcher); string dir = path::join(os::getcwd(), "dir"); AWAIT_FAILED(fetcher.get()->fetch(uri, dir)); }
TEST_F(CurlFetcherPluginTest, CURL_InvalidUri) { URI uri = uri::http( stringify(server.self().address.ip), "/TestHttpServer/test", server.self().address.port); EXPECT_CALL(server, test(_)) .WillOnce(Return(http::NotFound())); Try<Owned<uri::Fetcher>> fetcher = uri::fetcher::create(); ASSERT_SOME(fetcher); AWAIT_FAILED(fetcher.get()->fetch(uri, os::getcwd())); }
// 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); }