CliMain { static void run(CliContext cliContext, String... args) { run(cliContext, ImmutableList.copyOf(args)); } private  CliMain(
      StyxCliParser parser,
      Namespace namespace,
      String apiHost,
      CliOutput cliOutput,
      CliContext cliContext,
      boolean debug); static void main(String... args);  }
@Test public void testWorkflowCreateInvalidStructure() throws Exception { final Path workflowsFile = fileFromResource("wf-missing-schedule.yaml"); try { CliMain.run(cliContext, "workflow", "create", "-f", workflowsFile.toString(), "foo"); fail(); } catch (CliExitException e) { assertThat(e.status(), is(ExitStatus.InputError)); } verify(cliOutput).printError( "Workflow configuration doesn't conform to the expected structure, problem: " + "schedule\n at [Source: (File); line: 4, column: 1]\n" + "Minimal valid example: \n" + "========================\n" + "id: bar\n" + "schedule: DAYS\n" + "docker_image: busybox\n" + "docker_args: [echo, bar]\n" + "========================\n"); }
@Test public void testWorkflowCreateBadInput() throws Exception { final Path workflowsFile = fileFromResource("bad-content.yaml"); try { CliMain.run(cliContext, "workflow", "create", "-f", workflowsFile.toString(), "foo"); fail(); } catch (CliExitException e) { assertThat(e.status(), is(ExitStatus.InputError)); } verify(cliOutput).printError(contains( "Workflow configuration doesn't conform to the expected structure, ")); }
@Test public void testWorkflowCreateInvalid() throws Exception { final String component = "quux"; final Path workflowsFile = fileFromResource("workflows.yaml"); final List<WorkflowConfiguration> expected = Json.YAML_MAPPER .reader().forType(WorkflowConfiguration.class) .<WorkflowConfiguration>readValues(workflowsFile.toFile()) .readAll(); assertThat(expected, is(not(Matchers.empty()))); for (WorkflowConfiguration configuration : expected) { var workflow = Workflow.create(component, configuration); when(validator.validateWorkflow(workflow)).thenReturn( List.of("bad-" + configuration.id(), "cfg-" + configuration.id())); } try { CliMain.run(cliContext, "workflow", "create", component, "-f", workflowsFile.toString()); fail(); } catch (CliExitException e) { assertThat(e.status(), is(ExitStatus.ArgumentError)); } for (WorkflowConfiguration configuration : expected) { verify(cliOutput).printError("Invalid workflow configuration: " + configuration.id()); verify(cliOutput).printError(" error: bad-" + configuration.id()); verify(cliOutput).printError(" error: cfg-" + configuration.id()); } verify(client, never()).createOrUpdateWorkflow(any(), any()); }
@Test public void testBackfillCreateWithInvalidEnv() { final String component = "quux"; try { CliMain.run(cliContext, "backfill", "create", "-e", "FOO=foo", component, "foo", "2017-01-01", "2017-01-30", "1", "-e", "BAR=bar", "--env", "BAZ=baz", "-e", "FOOBAR"); fail(); } catch (CliExitException e) { assertThat(e.status(), is(ExitStatus.UnknownError)); } }
@Test public void testBackfillShowTruncating() { final String backfillId = "backfill-2"; final Backfill backfill = Backfill.newBuilder() .id(backfillId) .start(Instant.parse("2017-01-01T00:00:00Z")) .end(Instant.parse("2017-01-30T00:00:00Z")) .workflowId(WorkflowId.create("quux", backfillId)) .concurrency(1) .description("Description") .nextTrigger(Instant.parse("2017-01-01T00:00:00Z")) .schedule(Schedule.DAYS) .created(currentTime) .lastModified(currentTime) .build(); final BackfillPayload backfillPayload = BackfillPayload.create(backfill, Optional.empty()); when(client.backfill(backfillId, true)) .thenReturn(CompletableFuture.completedFuture(backfillPayload)); CliMain.run(cliContext, "backfill", "show", backfillId); verify(client).backfill(backfillId, true); verify(cliOutput).printBackfillPayload(backfillPayload, false); }
@Test @Parameters({ "n", "N", "Y", "", " ", "dfgdfgd", }) public void testWorkflowDeleteInteractiveNo(String reply) { when(cliContext.hasConsole()).thenReturn(true); when(cliContext.consoleReadLine(any())).thenReturn(reply); try { CliMain.run(cliContext, "workflow", "delete", "quux", "foo", "bar"); fail(); } catch (CliExitException e) { assertThat(e.status(), is(ExitStatus.UnknownError)); } verify(cliContext).consoleReadLine( "Sure you want to delete the workflows foo, bar in component quux? [y/N] "); }
@Test @Parameters({ "y", " y", "y ", " y ", }) public void testWorkflowDeleteInteractiveYes(String reply) { final String component = "quux"; when(cliContext.hasConsole()).thenReturn(true); when(cliContext.consoleReadLine(any())).thenReturn(reply); when(client.deleteWorkflow(any(), any())).thenReturn(CompletableFuture.completedFuture(null)); CliMain.run(cliContext, "workflow", "delete", component, "foo", "bar"); verify(cliContext).consoleReadLine( "Sure you want to delete the workflows foo, bar in component quux? [y/N] "); verify(client).deleteWorkflow(component, "foo"); verify(client).deleteWorkflow(component, "bar"); verify(cliOutput).printMessage("Workflow foo in component " + component + " deleted."); verify(cliOutput).printMessage("Workflow bar in component " + component + " deleted."); }
@Test public void testWorkflowDeleteInteractiveForce() { final String component = "quux"; when(cliContext.hasConsole()).thenReturn(true); when(client.deleteWorkflow(any(), any())).thenReturn(CompletableFuture.completedFuture(null)); CliMain.run(cliContext, "workflow", "delete", component, "foo", "bar", "--force"); verify(cliContext, never()).consoleReadLine(any()); verify(client).deleteWorkflow(component, "foo"); verify(client).deleteWorkflow(component, "bar"); verify(cliOutput).printMessage("Workflow foo in component " + component + " deleted."); verify(cliOutput).printMessage("Workflow bar in component " + component + " deleted."); }
@Test public void shouldHandleWorkflowNotFoundWhenEnabling() { final String component = "quux"; final WorkflowState workflowState = WorkflowState.builder() .enabled(true) .build(); final ApiErrorException exception = new ApiErrorException("not found", 404, true, requestId); when(client.updateWorkflowState(any(), any(), eq(workflowState))) .thenReturn(exceptionallyCompletedFuture(exception)); CliMain.run(cliContext, "workflow", "enable", component, "foo", "bar"); verify(cliOutput).printMessage("Workflow foo in component " + component + " not found."); verify(cliOutput).printMessage("Workflow bar in component " + component + " not found."); }
@Test public void shouldHandleWorkflowNotFoundWhenDisabling() { final String component = "quux"; final WorkflowState workflowState = WorkflowState.builder() .enabled(false) .build(); final ApiErrorException exception = new ApiErrorException("not found", 404, true, requestId); when(client.updateWorkflowState(any(), any(), eq(workflowState))) .thenReturn(exceptionallyCompletedFuture(exception)); CliMain.run(cliContext, "workflow", "disable", component, "foo", "bar"); verify(cliOutput).printMessage("Workflow foo in component " + component + " not found."); verify(cliOutput).printMessage("Workflow bar in component " + component + " not found."); }
@Test public void testHelp() { try { CliMain.run(cliContext, "--help"); fail(); } catch (CliExitException e) { assertThat(e.status(), is(ExitStatus.Success)); } try { CliMain.run(cliContext); fail(); } catch (CliExitException e) { assertThat(e.status(), is(ExitStatus.Success)); } verifyZeroInteractions(client); }
@Test public void testArgumentError() { try { CliMain.run(cliContext, "foozbarz"); fail(); } catch (CliExitException e) { assertThat(e.status(), is(ExitStatus.ArgumentError)); } verifyZeroInteractions(client); }
@Test @Parameters({ "--json workflow ls", "workflow --json ls", "workflow ls --json", }) public void testJsonOptionIsGlobal(final String argLine) { when(client.workflows()).thenReturn(CompletableFuture.completedFuture(Collections.emptyList())); CliMain.run(cliContext, argLine.split(" ")); verify(cliContext).output(Output.JSON); }
@Test @Parameters({ "--plain workflow ls", "workflow --plain ls", "workflow ls --plain", }) public void testPlainOptionIsGlobal(final String argLine) { when(client.workflows()).thenReturn(CompletableFuture.completedFuture(Collections.emptyList())); CliMain.run(cliContext, argLine.split(" ")); verify(cliContext).output(Output.PLAIN); }
@Test @Parameters({ "--debug workflow ls", "workflow --debug ls", "workflow ls --debug", }) public void testDebugOptionIsGlobal(final String argLine) { when(client.workflows()).thenReturn(CompletableFuture.completedFuture(Collections.emptyList())); assertThat(Try.run(() -> CliMain.run(cliContext, argLine.split(" "))).isSuccess(), is(true)); }
@Test @Parameters({ "--host https: "workflow --host https: "workflow ls --host https: }) public void testHostOptionIsGlobal(final String argLine) { when(client.workflows()).thenReturn(CompletableFuture.completedFuture(Collections.emptyList())); CliMain.run(cliContext, argLine.split(" ")); verify(cliContext).createClient("https: }
@Test public void testAuthTestServiceAccountUsageSuccess() { final String serviceAccount = "foo@bar.iam.gserviceaccount.com"; final String principal = "baz@example.com"; final TestServiceAccountUsageAuthorizationResponse response = TestServiceAccountUsageAuthorizationResponse.builder() .authorized(true) .serviceAccount(serviceAccount) .principal(principal) .message("foobar") .build(); when(client.testServiceAccountUsageAuthorization(serviceAccount, principal)) .thenReturn(CompletableFuture.completedFuture(response)); CliMain.run(cliContext, "auth", "test", "--service-account", serviceAccount, "--principal", principal); verify(client).testServiceAccountUsageAuthorization(serviceAccount, principal); verify(cliOutput).printMessage("The principal " + principal + " is authorized to use the service account " + serviceAccount + ". " + response.message().get()); }
@Test public void testAuthTestServiceAccountUsageFailure() { final String serviceAccount = "foo@bar.iam.gserviceaccount.com"; final String principal = "baz@example.com"; final TestServiceAccountUsageAuthorizationResponse response = TestServiceAccountUsageAuthorizationResponse.builder() .authorized(false) .serviceAccount(serviceAccount) .principal(principal) .message("foobar") .build(); when(client.testServiceAccountUsageAuthorization(serviceAccount, principal)) .thenReturn(CompletableFuture.completedFuture(response)); try { CliMain.run(cliContext, "auth", "test", "--service-account", serviceAccount, "--principal", principal); fail(); } catch (CliExitException e) { assertThat(e.status(), is(ExitStatus.UnknownError)); } verify(client).testServiceAccountUsageAuthorization(serviceAccount, principal); verify(cliOutput).printMessage("The principal " + principal + " is not authorized to use the service account " + serviceAccount + ". " + response.message().orElse("")); }
@Test @Parameters({ "auth test --service-account foo@bar.iam.gserviceaccount.com", "auth test --principal baz@example.com", "auth test" }) public void testAuthTestServiceAccountUsageMissingRequiredArgument(final String argLine) { when(client.workflows()).thenReturn(CompletableFuture.completedFuture(Collections.emptyList())); try { CliMain.run(cliContext, argLine.split(" ")); fail(); } catch (CliExitException e) { assertThat(e.status(), is(ExitStatus.ArgumentError)); } }