@Test public void testJobStatusHostFilter() throws Exception { startDefaultMaster(); final HeliosClient client = defaultClient(); startDefaultAgent(testHost()); // Create a job final Job job = Job.newBuilder() .setName(testJobName) .setVersion(testJobVersion) .setImage(BUSYBOX) .setCommand(IDLE_COMMAND) .setPorts(EMPTY_PORTS) .build(); final CreateJobResponse created = client.createJob(job).get(); assertEquals(CreateJobResponse.Status.OK, created.getStatus()); final String result = cli("status", "--host", "framazama"); assertThat(result, containsString("There are no jobs deployed to hosts with the host pattern")); } }
/** * Verify that the Helios master generates and returns a hash if the submitted job creation * request does not include one. */ @Test public void testHashLessJobCreation() throws Exception { startDefaultMaster(); final Job job = Job.newBuilder() .setName(testJobName) .setVersion(testJobVersion) .setImage(BUSYBOX) .setCommand(IDLE_COMMAND) .setCreatingUser(TEST_USER) .build(); // Remove the hash from the id in the json serialized job final ObjectNode json = (ObjectNode) Json.reader().readTree(Json.asString(job)); json.set("id", TextNode.valueOf(testJobName + ":" + testJobVersion)); final HttpURLConnection req = post("/jobs?user=" + TEST_USER, Json.asBytes(json)); assertEquals(req.getResponseCode(), 200); final CreateJobResponse res = Json.read(toByteArray(req.getInputStream()), CreateJobResponse.class); assertEquals(OK, res.getStatus()); assertTrue(res.getErrors().isEmpty()); assertEquals(job.getId().toString(), res.getId()); }
.setName(testJobName) .setVersion(testJobVersion) .setImage(BUSYBOX) .setCommand(IDLE_COMMAND) .setPorts(ImmutableMap.of("foo", PortMapping.of(4711),
@Test public void testTermOnExit() throws Exception { startDefaultMaster(); final String host = testHost(); startDefaultAgent(host); final HeliosClient client = defaultClient(); awaitHostStatus(client, host, UP, LONG_WAIT_SECONDS, SECONDS); // Note: signal 15 is SIGTERM final Job jobToInterrupt = Job.newBuilder() .setName(testJobName) .setVersion(testJobVersion) .setImage(BUSYBOX) .setCommand(asList("/bin/sh", "-c", "trap handle 15; handle() { echo term; exit 0; }; " + "while true; do sleep 1; done")) .build(); final JobId jobId = createJob(jobToInterrupt); deployJob(jobId, host); awaitTaskState(jobId, host, RUNNING); client.setGoal(new Deployment(jobId, Goal.STOP, Deployment.EMTPY_DEPLOYER_USER, Deployment.EMPTY_DEPLOYER_MASTER, Deployment.EMPTY_DEPLOYMENT_GROUP_NAME), host); final TaskStatus taskStatus = awaitTaskState(jobId, host, STOPPED); final String log; try (final DockerClient dockerClient = getNewDockerClient(); LogStream logs = dockerClient.logs(taskStatus.getContainerId(), stdout())) { log = logs.readFully(); } // Message expected, because the SIGTERM handler in the script should have run assertEquals("term\n", log); }
return builder.setImage(image) .setHostname(hostname) .setCreated(created)
.setName(testTag + "foo") .setVersion("1") .setImage(BUSYBOX) .setCommand(IDLE_COMMAND) .setPorts(ImmutableMap.of("foo", PortMapping.of(10001, externalPort))) .setName(testTag + "bar") .setVersion("1") .setImage(BUSYBOX) .setCommand(IDLE_COMMAND) .setPorts(ImmutableMap.of("foo", PortMapping.of(10002, externalPort)))
@Test public void testNoIntOnExit() throws Exception { startDefaultMaster(); final String host = testHost(); startDefaultAgent(host); final HeliosClient client = defaultClient(); awaitHostStatus(client, host, UP, LONG_WAIT_SECONDS, SECONDS); // Note: signal 2 is SIGINT final Job jobToInterrupt = Job.newBuilder() .setName(testJobName) .setVersion(testJobVersion) .setImage(BUSYBOX) .setCommand(asList("/bin/sh", "-c", "trap handle 2; handle() { echo int; exit 0; }; " + "while true; do sleep 1; done")) .build(); final JobId jobId = createJob(jobToInterrupt); deployJob(jobId, host); awaitTaskState(jobId, host, RUNNING); client.setGoal(new Deployment(jobId, Goal.STOP, Deployment.EMTPY_DEPLOYER_USER, Deployment.EMPTY_DEPLOYER_MASTER, Deployment.EMPTY_DEPLOYMENT_GROUP_NAME), host); final TaskStatus taskStatus = awaitTaskState(jobId, host, STOPPED); final String log; try (final DockerClient dockerClient = getNewDockerClient(); LogStream logs = dockerClient.logs(taskStatus.getContainerId(), stdout())) { log = logs.readFully(); } // No message expected, since SIGINT should not be sent assertEquals("", log); }
.setName(testJobName) .setVersion(testJobVersion) .setImage(BUSYBOX) .setHostname(testHost()) .setCommand(command)
@Test public void testRollingUpdateWithToken() throws Exception { final String host = testHost(); startDefaultAgent(host, "--labels", TEST_LABEL); // Wait for agent to come up final HeliosClient client = defaultClient(); awaitHostStatus(client, testHost(), UP, LONG_WAIT_SECONDS, SECONDS); // Manually deploy a job with a token on the host (i.e. a job not part of the deployment group) final Job job = Job.newBuilder() .setName(testJobName) .setVersion(testJobVersion) .setImage(BUSYBOX) .setCommand(IDLE_COMMAND) .setToken(TOKEN) .build(); final JobId jobId = createJob(job); // Create a deployment-group and trigger a migration rolling-update cli("create-deployment-group", "--json", TEST_GROUP, TEST_LABEL); cli("rolling-update", "--async", "--token", TOKEN, testJobNameAndVersion, TEST_GROUP); // rolling-update should succeed & job should be running awaitDeploymentGroupStatus(defaultClient(), TEST_GROUP, DeploymentGroupStatus.State.DONE); awaitTaskState(jobId, host, TaskStatus.State.RUNNING); // Check that we cannot manually undeploy the job with a token final String output = cli("undeploy", jobId.toString(), host); assertThat(output, containsString("FORBIDDEN")); awaitDeploymentGroupStatus(defaultClient(), TEST_GROUP, DeploymentGroupStatus.State.DONE); awaitTaskState(jobId, host, TaskStatus.State.RUNNING); }
protected JobId createJob(final String name, final String version, final String image, final String hostname, final List<String> command, final Map<String, String> env, final Map<String, PortMapping> ports, final Map<ServiceEndpoint, ServicePorts> registration, final Integer gracePeriod, final Map<String, String> volumes, final Date expires) throws Exception { return createJob(Job.newBuilder() .setName(name) .setVersion(version) .setImage(image) .setHostname(hostname) .setCommand(command) .setEnv(env) .setPorts(ports) .setRegistration(registration) .setGracePeriod(gracePeriod) .setVolumes(volumes) .setExpires(expires) .build()); }
@Before public void setup() throws Exception { startDefaultMaster(); client = defaultClient(); startDefaultAgent(testHost()); job = Job.newBuilder() .setName(testJobName) .setVersion(testJobVersion) .setImage(BUSYBOX) .addVolume("/random-vol") .addVolume("/named-vol", "my-volume") .addVolume("/hostname", "/etc/hostname") .setCommand(asList("sh", "-c", "echo foo > /random-vol/foo; " + "echo foo > /named-vol/foo;" + "nc -p 4711 -le dd if=/random-vol/foo;" + "nc -p 4712 -le dd if=/named-vol/foo;" + "nc -p 4713 -le dd if=/hostname")) .addPort("random", PortMapping.of(4711)) .addPort("named", PortMapping.of(4712)) .addPort("hostname", PortMapping.of(4713)) .setCreatingUser(TEST_USER) .build(); }
@Test public void testPortMappingWithBadIp() throws Exception { startDefaultMaster(); startDefaultAgent(testHost()); awaitHostStatus(testHost(), UP, LONG_WAIT_SECONDS, SECONDS); expectedException.expect(IllegalArgumentException.class); expectedException.expectMessage("foobar is not a valid IP address."); // Create job with a portmapping that has a bad IP. Check it throws. createJobRawOutput(Job.newBuilder() .setName(testJobName) .setVersion(testJobVersion) .setImage(BUSYBOX) .setPorts(Collections.singletonMap("foo", PortMapping.builder() .ip("foobar") .internalPort(80) .externalPort(80) .build() )).build()); } }
@Test public void testHttp() throws Exception { startDefaultMaster(); final HeliosClient client = defaultClient(); startDefaultAgent(testHost(), "--service-registry=" + registryAddress); awaitHostStatus(client, testHost(), UP, LONG_WAIT_SECONDS, SECONDS); final HealthCheck healthCheck = HttpHealthCheck.of("http", "/"); // start a container that listens on a poke port, and once poked runs a web server final Job job = Job.newBuilder() .setName(testJobName) .setVersion(testJobVersion) .setImage(NGINX) .setCommand(asList("sh", "-c", "nc -l -p 4711 && nginx -g 'daemon off;'")) .addPort("poke", PortMapping.of(4711)) .addPort("http", PortMapping.of(80)) .addRegistration(ServiceEndpoint.of("foo_service", "foo_proto"), ServicePorts.of("http")) .setHealthCheck(healthCheck) .build(); assertContainerRegistersAfterPoke(client, job); }
@Test public void testPortMappingWithIp() throws Exception { startDefaultMaster(); startDefaultAgent(testHost()); awaitHostStatus(testHost(), UP, LONG_WAIT_SECONDS, SECONDS); // Create job with a portmapping that has an IP. Check it doesn't throw. createJobRawOutput(Job.newBuilder() .setName(testJobName) .setVersion(testJobVersion) .setImage(BUSYBOX) .setPorts(Collections.singletonMap("foo", PortMapping.builder() .ip("127.0.0.1") .internalPort(80) .externalPort(80) .build() )).build()); }
/** * Starts a container that listens on a poke port, and once poked listens on the healthcheck * port. */ private Job pokeJob(final HealthCheck healthCheck) { return Job.newBuilder() .setName(testJobName) .setVersion(testJobVersion) .setImage(ALPINE) .setCommand(asList("sh", "-c", "nc -l -p 4711 && nc -lk -p 4712 -e hostname")) .addPort("poke", PortMapping.of(4711)) .addPort("health", PortMapping.of(4712)) .addRegistration(ServiceEndpoint.of("foo_service", "foo_proto"), ServicePorts.of("health")) .setHealthCheck(healthCheck) .build(); }
@Before public void setup() throws Exception { startDefaultMaster(); client = defaultClient(); startDefaultAgent(testHost()); job = Job.newBuilder() .setName(testJobName) .setVersion(testJobVersion) .setImage(BUSYBOX) .addRamdisk("/much-volatile", "rw,noexec,nosuid,size=1") .setCommand(asList("sh", "-c", "nc -p 4711 -lle sh -c \"df | grep much-volatile\"")) .addPort("df", PortMapping.of(4711)) .setCreatingUser(TEST_USER) .build(); }
@Test public void testInvalidHostname() throws Exception { startDefaultMaster(); startDefaultAgent(testHost()); awaitHostStatus(testHost(), UP, LONG_WAIT_SECONDS, SECONDS); // Create job final String output = createJobRawOutput(Job.newBuilder() .setName(testJobName) .setVersion(testJobVersion) .setImage(BUSYBOX) .setHostname("$%^&") .build()); assertThat(output, Matchers.containsString("Invalid hostname ")); }
@Before public void setup() throws Exception { startDefaultMaster(); client = defaultClient(); startDefaultAgent(testHost()); job = Job.newBuilder() .setName(testJobName) .setVersion(testJobVersion) .setImage(BUSYBOX) .setResources(new Resources(MEMORY, MEMORY_SWAP, CPU_SHARES, CPUSET_CPUS)) .setCommand(IDLE_COMMAND) .setCreatingUser(TEST_USER) .build(); }
@Before public void setup() throws Exception { startDefaultMaster(); client = defaultClient(); startDefaultAgent(testHost()); job = Job.newBuilder() .setName(testJobName) .setVersion(testJobVersion) .setImage(BUSYBOX) .setNetworkMode("host") .setCommand(IDLE_COMMAND) .build(); }