/** * Exercises the service's packaging and resulting Service Specification YAML file without running any simulation * afterwards. * * @return a {@link ServiceTestResult} containing the resulting scheduler environment and spec information * @throws Exception if the test failed */ public ServiceTestResult run() throws Exception { return run(Collections.emptyList()); }
/** * Validates the default service spec. */ @Test public void testDefaultSpec() throws Exception { new ServiceTestRunner().run(); }
@Test public void testSpec() throws Exception { getDefaultRunner().run(); }
@Test public void testSpec() throws Exception { getDefaultRunner().run(); }
@Test(expected = IllegalStateException.class) public void testInvalidStep() throws Exception { new ServiceTestRunner("custom_steps.yml") .setSchedulerEnv( "DEPLOY_STRATEGY", "serial", "DEPLOY_STEPS", "[[foo, bar]]") .run(Collections.emptyList()); }
@Test public void testSwitchToInvalidPlacementConstraint() throws Exception { ServiceTestResult initial = new ServiceTestRunner() .setSchedulerEnv("HELLO_PLACEMENT", VALID_HOSTNAME_CONSTRAINT) .run(getDefaultDeploymentTicks()); Collection<SimulationTick> ticks = new ArrayList<>(); ticks.add(Send.register()); ticks.add(Expect.planStatus("deploy", Status.ERROR)); new ServiceTestRunner() .setState(initial) .setSchedulerEnv("HELLO_PLACEMENT", INVALID_HOSTNAME_CONSTRAINT) .run(ticks); }
@Test public void testRegionAwareness() throws Exception { ServiceTestResult result = getDefaultRunner() .setOptions("service.region", "Europe") .run(); Assert.assertEquals(result.getSchedulerEnvironment().get("SERVICE_REGION"), "Europe"); }
@Test public void testRegionAwareness() throws Exception { ServiceTestResult result = getDefaultRunner() .setOptions("service.region", "Europe") .run(); Assert.assertEquals(result.getSchedulerEnvironment().get("SERVICE_REGION"), "Europe"); }
@Test(expected = IllegalStateException.class) public void testInvalidPlacementConstraint() throws Exception { new ServiceTestRunner() .setSchedulerEnv("HELLO_PLACEMENT", INVALID_HOSTNAME_CONSTRAINT) .run(getDefaultDeploymentTicks()); }
@Test public void testValidPlacementConstraint() throws Exception { new ServiceTestRunner() .setSchedulerEnv("HELLO_PLACEMENT", VALID_HOSTNAME_CONSTRAINT) .run(getDefaultDeploymentTicks()); }
@Test public void testSpec() throws Exception { new ServiceTestRunner().setPodEnv("node", getDefaultNodeEnv()).run(); }
public CassandraRecoveryPlanOverriderTest() throws Exception { ServiceTestResult result = new ServiceTestRunner() .setPodEnv("node", "LOCAL_SEEDS", "foo,bar") .run(); rawSpec = result.getRawServiceSpec(); serviceSpec = result.getServiceSpec(); }
@Test public void testSpecSSL() throws Exception { ServiceTestResult result = new ServiceTestRunner() .setOptions("service.security.transport_encryption.enabled", "true") .setPodEnv("node", getDefaultNodeEnv()) .run(); Assert.assertTrue(result.getTaskConfig("node", "server", "cassandra").contains("internode_encryption: all")); Assert.assertTrue(result.getTaskConfig("node", "server", "cassandra").contains( "client_encryption_options:\n enabled: true\n optional: false")); }
@Test public void testRegionAwareness() throws Exception { ServiceTestResult result = new ServiceTestRunner() .setOptions("service.region", "Europe") .setPodEnv("node", getDefaultNodeEnv()) .run(); Assert.assertEquals(result.getSchedulerEnvironment().get("SERVICE_REGION"), "Europe"); }
/** * Checks that unexpected Tasks are killed. */ @Test public void testZombieTaskKilling() throws Exception { Collection<SimulationTick> ticks = new ArrayList<>(); ticks.add(Send.register()); ticks.add(Expect.reconciledImplicitly()); // Verify that service launches 1 hello pod. ticks.add(Send.offerBuilder("hello").build()); ticks.add(Expect.launchedTasks("hello-0-server")); // Running, no readiness check is applicable: ticks.add(Send.taskStatus("hello-0-server", Protos.TaskState.TASK_RUNNING).build()); String taskId = CommonIdUtils.toTaskId("bogus", "taskid").getValue(); ticks.add(Send.taskStatus("hello-0-server", Protos.TaskState.TASK_RUNNING) .setTaskId(taskId) .build()); // Unknown task that we made up above was killed, but the launched task was not killed: ticks.add(Expect.taskIdKilled(taskId)); ticks.add(Expect.taskNameNotKilled("hello-0-server")); new ServiceTestRunner("simple.yml").run(ticks); }
@Test public void testSpecCustomUserAndSeeds() throws Exception { Map<String, String> nodeEnv = getDefaultNodeEnv(); nodeEnv.put("REMOTE_SEEDS", "baz"); ServiceTestResult result = new ServiceTestRunner() .setOptions("service.user", "foo") .setPodEnv("node", nodeEnv) .run(); Assert.assertEquals("foo", result.getServiceSpec().getUser()); Assert.assertEquals("foo", result.getServiceSpec().getPods().get(0).getUser().get()); Assert.assertTrue(result.getTaskConfig("node", "server", "cassandra").contains("- seeds: \"foo,bar,baz\"")); }
@Test public void testParallelStrategyParallelSteps() throws Exception { Collection<SimulationTick> ticks = new ArrayList<>(); ticks.add(Send.register()); ticks.add(Expect.reconciledImplicitly()); // Service should launch all of hello-0/1-first/second using the provided offers: ticks.add(Send.offerBuilder("hello").setCount(3).build()); // Launches will end up being split across two offers/agents: ticks.add(Expect.launchedTasks(2, "hello-0-first", "hello-0-second", "hello-1-first", "hello-1-second")); ticks.add(Send.taskStatus("hello-0-first", Protos.TaskState.TASK_RUNNING).build()); ticks.add(Send.taskStatus("hello-0-second", Protos.TaskState.TASK_RUNNING).build()); ticks.add(Send.taskStatus("hello-1-first", Protos.TaskState.TASK_RUNNING).build()); ticks.add(Send.taskStatus("hello-1-second", Protos.TaskState.TASK_RUNNING).build()); ticks.add(Expect.samePod("hello-0-first", "hello-0-second")); ticks.add(Expect.samePod("hello-1-first", "hello-1-second")); // No more hellos to launch: ticks.add(Send.offerBuilder("hello").setCount(3).build()); ticks.add(Expect.declinedLastOffer()); ticks.add(Expect.allPlansComplete()); new ServiceTestRunner("custom_steps.yml") .setSchedulerEnv( "DEPLOY_STRATEGY", "parallel", "DEPLOY_STEPS", "[[first, second]]") .run(ticks); }
@Test public void testSerialStrategyParallelSteps() throws Exception { Collection<SimulationTick> ticks = new ArrayList<>(); ticks.add(Send.register()); ticks.add(Expect.reconciledImplicitly()); // Service should launch hello-0-first and hello-0-second at the same time. ticks.add(Send.offerBuilder("hello").setCount(3).build()); ticks.add(Expect.launchedTasks("hello-0-first", "hello-0-second")); ticks.add(Send.taskStatus("hello-0-first", Protos.TaskState.TASK_RUNNING).build()); // New offer declined since hello-0-second isn't RUNNING yet: ticks.add(Send.offerBuilder("hello").setCount(3).build()); ticks.add(Expect.declinedLastOffer()); ticks.add(Send.taskStatus("hello-0-second", Protos.TaskState.TASK_RUNNING).build()); ticks.add(Expect.samePod("hello-0-first", "hello-0-second")); // Now hello-1 may be deployed: ticks.add(Send.offerBuilder("hello").setCount(3).build()); ticks.add(Expect.launchedTasks("hello-1-first", "hello-1-second")); ticks.add(Send.taskStatus("hello-1-first", Protos.TaskState.TASK_RUNNING).build()); ticks.add(Send.taskStatus("hello-1-second", Protos.TaskState.TASK_RUNNING).build()); ticks.add(Expect.samePod("hello-1-first", "hello-1-second")); // No more hellos to launch: ticks.add(Send.offerBuilder("hello").setCount(3).build()); ticks.add(Expect.declinedLastOffer()); ticks.add(Expect.allPlansComplete()); new ServiceTestRunner("custom_steps.yml") .setSchedulerEnv( "DEPLOY_STRATEGY", "serial", "DEPLOY_STEPS", "[[first, second]]") .run(ticks); }
/** * Validates service deployment in the default configuration case. */ @Test public void testDefaultDeployment() throws Exception { ServiceTestResult result = new ServiceTestRunner().run(getDefaultDeploymentTicks()); // After deployment completed, service should have stored that fact to ZK: Assert.assertTrue(StateStoreUtils.getDeploymentWasCompleted(new StateStore(result.getPersister()))); }