TEST_F(FilesTest, DownloadTest) { Files files; process::UPID upid("files", process::address()); // This is a one-pixel black gif image. const unsigned char gifData[] = { 0x47, 0x49, 0x46, 0x38, 0x37, 0x61, 0x01, 0x00, 0x01, 0x00, 0x91, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x02, 0x02, 0x4c, 0x01, 0x00, 0x3b, 0x00 }; string data((const char*) gifData, sizeof(gifData)); ASSERT_SOME(os::write("binary", "no file extension")); ASSERT_SOME(os::write("black.gif", data)); AWAIT_EXPECT_READY(files.attach("binary", "binary")); AWAIT_EXPECT_READY(files.attach("black.gif", "black.gif")); Future<Response> response = process::http::get(upid, "download.json", "path=binary"); AWAIT_EXPECT_RESPONSE_STATUS_EQ(OK().status, response); AWAIT_EXPECT_RESPONSE_HEADER_EQ( "application/octet-stream", "Content-Type", response); AWAIT_EXPECT_RESPONSE_BODY_EQ("no file extension", response); response = process::http::get(upid, "download.json", "path=black.gif"); AWAIT_EXPECT_RESPONSE_STATUS_EQ(OK().status, response); AWAIT_EXPECT_RESPONSE_HEADER_EQ("image/gif", "Content-Type", response); AWAIT_EXPECT_RESPONSE_BODY_EQ(data, response); }
TEST_F(FilesTest, ReadTest) { Files files; process::UPID upid("files", process::address()); Future<Response> response = process::http::get(upid, "read.json"); AWAIT_EXPECT_RESPONSE_STATUS_EQ(BadRequest().status, response); AWAIT_EXPECT_RESPONSE_BODY_EQ( "Expecting 'path=value' in query.\n", response); response = process::http::get(upid, "read.json", "path=none&offset=hello"); AWAIT_EXPECT_RESPONSE_STATUS_EQ(BadRequest().status, response); AWAIT_EXPECT_RESPONSE_BODY_EQ( "Failed to parse offset: Failed to convert 'hello' to number.\n", response); response = process::http::get(upid, "read.json", "path=none&length=hello"); AWAIT_EXPECT_RESPONSE_STATUS_EQ(BadRequest().status, response); AWAIT_EXPECT_RESPONSE_BODY_EQ( "Failed to parse length: Failed to convert 'hello' to number.\n", response); // Now write a file. ASSERT_SOME(os::write("file", "body")); AWAIT_EXPECT_READY(files.attach("file", "/myname")); AWAIT_EXPECT_READY(files.attach("file", "myname")); // Read a valid file. JSON::Object expected; expected.values["offset"] = 0; expected.values["data"] = "body"; response = process::http::get(upid, "read.json", "path=/myname&offset=0"); AWAIT_EXPECT_RESPONSE_STATUS_EQ(OK().status, response); AWAIT_EXPECT_RESPONSE_BODY_EQ(stringify(expected), response); response = process::http::get(upid, "read.json", "path=myname&offset=0"); AWAIT_EXPECT_RESPONSE_STATUS_EQ(OK().status, response); AWAIT_EXPECT_RESPONSE_BODY_EQ(stringify(expected), response); // Missing file. AWAIT_EXPECT_RESPONSE_STATUS_EQ( NotFound().status, process::http::get(upid, "read.json", "path=missing")); }
TEST_F(FilesTest, BrowseTest) { Files files; process::UPID upid("files", process::address()); ASSERT_SOME(os::mkdir("1/2")); ASSERT_SOME(os::mkdir("1/3")); ASSERT_SOME(os::write("1/two", "two")); ASSERT_SOME(os::write("1/three", "three")); AWAIT_EXPECT_READY(files.attach("1", "one")); // Get the listing. struct stat s; JSON::Array expected; ASSERT_EQ(0, stat("1/2", &s)); expected.values.push_back(jsonFileInfo("one/2", s)); ASSERT_EQ(0, stat("1/3", &s)); expected.values.push_back(jsonFileInfo("one/3", s)); ASSERT_EQ(0, stat("1/three", &s)); expected.values.push_back(jsonFileInfo("one/three", s)); ASSERT_EQ(0, stat("1/two", &s)); expected.values.push_back(jsonFileInfo("one/two", s)); Future<Response> response = process::http::get(upid, "browse.json", "path=one/"); AWAIT_EXPECT_RESPONSE_STATUS_EQ(OK().status, response); AWAIT_EXPECT_RESPONSE_BODY_EQ(stringify(expected), response); response = process::http::get(upid, "browse.json", "path=one%2F"); AWAIT_EXPECT_RESPONSE_STATUS_EQ(OK().status, response); AWAIT_EXPECT_RESPONSE_BODY_EQ(stringify(expected), response); response = process::http::get(upid, "browse.json", "path=one"); AWAIT_EXPECT_RESPONSE_STATUS_EQ(OK().status, response); AWAIT_EXPECT_RESPONSE_BODY_EQ(stringify(expected), response); // Empty listing. response = process::http::get(upid, "browse.json", "path=one/2"); AWAIT_EXPECT_RESPONSE_STATUS_EQ(OK().status, response); AWAIT_EXPECT_RESPONSE_BODY_EQ(stringify(JSON::Array()), response); // Missing dir. AWAIT_EXPECT_RESPONSE_STATUS_EQ( NotFound().status, process::http::get(upid, "browse.json", "path=missing")); }
// This test verifies the correct handling of the statistics // endpoint when there is no executor running. TEST(MonitorTest, NoExecutor) { ResourceMonitor monitor([]() -> Future<ResourceUsage> { return ResourceUsage(); }); UPID upid("monitor", process::address()); Future<http::Response> response = http::get(upid, "statistics"); AWAIT_READY(response); AWAIT_EXPECT_RESPONSE_STATUS_EQ(http::OK().status, response); AWAIT_EXPECT_RESPONSE_HEADER_EQ( "application/json", "Content-Type", response); AWAIT_EXPECT_RESPONSE_BODY_EQ("[]", response); }
// This test verifies the correct handling of the statistics // endpoint when statistics is missing in ResourceUsage. TEST(MonitorTest, MissingStatistics) { ResourceMonitor monitor([]() -> Future<ResourceUsage> { FrameworkID frameworkId; frameworkId.set_value("framework"); ExecutorID executorId; executorId.set_value("executor"); ExecutorInfo executorInfo; executorInfo.mutable_executor_id()->CopyFrom(executorId); executorInfo.mutable_framework_id()->CopyFrom(frameworkId); executorInfo.set_name("name"); executorInfo.set_source("source"); Resources resources = Resources::parse("cpus:1;mem:2").get(); ResourceUsage usage; ResourceUsage::Executor* executor = usage.add_executors(); executor->mutable_executor_info()->CopyFrom(executorInfo); executor->mutable_allocated()->CopyFrom(resources); return usage; }); UPID upid("monitor", process::address()); Future<http::Response> response = http::get(upid, "statistics"); AWAIT_READY(response); AWAIT_EXPECT_RESPONSE_STATUS_EQ(http::OK().status, response); AWAIT_EXPECT_RESPONSE_HEADER_EQ( "application/json", "Content-Type", response); AWAIT_EXPECT_RESPONSE_BODY_EQ("[]", response); }
// This test verifies that the scheduler will receive a `BadRequest` response // when it tries to acknowledge a status update with a malformed UUID. TEST_P(SchedulerHttpApiTest, MalformedUUID) { Try<Owned<cluster::Master>> master = StartMaster(); ASSERT_SOME(master); // Retrieve the parameter passed as content type to this test. const string contentType = GetParam(); process::http::Headers headers = createBasicAuthHeaders(DEFAULT_CREDENTIAL); headers["Accept"] = contentType; v1::FrameworkID frameworkId; string streamId; // Subscribe once to get a valid stream ID. { Call call; call.set_type(Call::SUBSCRIBE); Call::Subscribe* subscribe = call.mutable_subscribe(); subscribe->mutable_framework_info()->CopyFrom(v1::DEFAULT_FRAMEWORK_INFO); Future<Response> response = process::http::streaming::post( master.get()->pid, "api/v1/scheduler", headers, serialize(call, contentType), contentType); AWAIT_EXPECT_RESPONSE_STATUS_EQ(OK().status, response); ASSERT_EQ(Response::PIPE, response.get().type); ASSERT_TRUE(response.get().headers.contains("Mesos-Stream-Id")); streamId = response.get().headers.at("Mesos-Stream-Id"); Option<Pipe::Reader> reader = response.get().reader; ASSERT_SOME(reader); auto deserializer = lambda::bind( &SchedulerHttpApiTest::deserialize, this, contentType, lambda::_1); Reader<Event> responseDecoder(Decoder<Event>(deserializer), reader.get()); Future<Result<Event>> event = responseDecoder.read(); AWAIT_READY(event); ASSERT_SOME(event.get()); // Check that the event type is subscribed and the framework ID is set. ASSERT_EQ(Event::SUBSCRIBED, event.get().get().type()); frameworkId = event.get().get().subscribed().framework_id(); EXPECT_NE("", frameworkId.value()); } // Make an acknowledge call with a malformed UUID. This should result in a // `BadResponse`. { headers["Mesos-Stream-Id"] = streamId; Call call; call.set_type(Call::ACKNOWLEDGE); // Set the framework ID in the subscribe call. call.mutable_framework_id()->CopyFrom(frameworkId); Call::Acknowledge* acknowledge = call.mutable_acknowledge(); acknowledge->mutable_task_id()->set_value("task-id"); acknowledge->mutable_agent_id()->set_value("agent-id"); // Set a malformed uuid. acknowledge->set_uuid("bad-uuid"); Future<Response> response = process::http::post( master.get()->pid, "api/v1/scheduler", headers, serialize(call, contentType), contentType); AWAIT_EXPECT_RESPONSE_STATUS_EQ(BadRequest().status, response); AWAIT_EXPECT_RESPONSE_BODY_EQ( "Failed to validate scheduler::Call: Not a valid UUID", response); } }
TEST_F(FilesTest, ResolveTest) { Files files; process::UPID upid("files", process::address()); // Test the directory / file resolution. ASSERT_SOME(os::mkdir("1/2")); ASSERT_SOME(os::write("1/two", "two")); ASSERT_SOME(os::write("1/2/three", "three")); // Attach some paths. AWAIT_EXPECT_READY(files.attach("1", "one")); AWAIT_EXPECT_READY(files.attach("1", "/one/")); AWAIT_EXPECT_READY(files.attach("1/2", "two")); AWAIT_EXPECT_READY(files.attach("1/2", "one/two")); // Resolve 1/2/3 via each attached path. JSON::Object expected; expected.values["offset"] = 0; expected.values["data"] = "three"; Future<Response> response = process::http::get(upid, "read.json", "path=one/2/three&offset=0"); AWAIT_EXPECT_RESPONSE_STATUS_EQ(OK().status, response); AWAIT_EXPECT_RESPONSE_BODY_EQ(stringify(expected), response); response = process::http::get(upid, "read.json", "path=/one/2/three&offset=0"); AWAIT_EXPECT_RESPONSE_STATUS_EQ(OK().status, response); AWAIT_EXPECT_RESPONSE_BODY_EQ(stringify(expected), response); response = process::http::get(upid, "read.json", "path=two/three&offset=0"); AWAIT_EXPECT_RESPONSE_STATUS_EQ(OK().status, response); AWAIT_EXPECT_RESPONSE_BODY_EQ(stringify(expected), response); response = process::http::get(upid, "read.json", "path=one/two/three&offset=0"); AWAIT_EXPECT_RESPONSE_STATUS_EQ(OK().status, response); AWAIT_EXPECT_RESPONSE_BODY_EQ(stringify(expected), response); // Percent encoded '/' urls. response = process::http::get(upid, "read.json", "path=%2Fone%2F2%2Fthree&offset=0"); AWAIT_EXPECT_RESPONSE_STATUS_EQ(OK().status, response); AWAIT_EXPECT_RESPONSE_BODY_EQ(stringify(expected), response); response = process::http::get(upid, "read.json", "path=one%2Ftwo%2Fthree&offset=0"); AWAIT_EXPECT_RESPONSE_STATUS_EQ(OK().status, response); AWAIT_EXPECT_RESPONSE_BODY_EQ(stringify(expected), response); // Reading dirs not allowed. AWAIT_EXPECT_RESPONSE_STATUS_EQ( BadRequest().status, process::http::get(upid, "read.json", "path=one/2")); AWAIT_EXPECT_RESPONSE_STATUS_EQ( BadRequest().status, process::http::get(upid, "read.json", "path=one")); AWAIT_EXPECT_RESPONSE_STATUS_EQ( BadRequest().status, process::http::get(upid, "read.json", "path=one/")); // Breaking out of sandbox. AWAIT_EXPECT_RESPONSE_STATUS_EQ( BadRequest().status, process::http::get(upid, "read.json", "path=two/../two")); }