public boolean run()
      throws ExecutionException, InterruptedException, ScanningWorkflowException, IOException {
    String logId = mainCliOptions.getLogId();
    // TODO(b/171405612): Find a way to print the log ID at every log line.
    logger.atInfo().log("%sTsunamiCli starting...", logId);

    ImmutableList<Process> languageServerProcesses = remoteServerLoader.runServerProcesses();
    ScanResults scanResults = scanningWorkflow.run(buildScanTarget());
    languageServerProcesses.forEach(Process::destroy);

    logger.atInfo().log("Tsunami scan finished, saving results.");
    saveResults(scanResults);

    if (hasSuccessfulResults(scanResults)) {
      logger.atInfo().log("TsunamiCli finished...");
      return true;
    } else {
      logger.atInfo().log(
          "Tsunami scan has failed status, message = %s.", scanResults.getStatusMessage());
      return false;
    }
  }
@Test
  public void run_whenScanFailed_generatesFailedScanResults()
      throws InterruptedException, ExecutionException, IOException {

    try (ScanResult scanResult = new ClassGraph().enableAllInfo().scan()) {
      Guice.createInjector(
              new AbstractModule() {
                @Override
                protected void configure() {
                  bind(ScanResultsArchiver.class).toInstance(scanResultsArchiver);
                  install(
                      new ConfigModule(scanResult, TsunamiConfig.fromYamlData(ImmutableMap.of())));
                  install(
                      new CliOptionsModule(
                          scanResult,
                          "TsunamiCliTest",
                          new String[] {
                            "--ip-v4-target=" + IP_TARGET, "--hostname-target=" + HOSTNAME_TARGET
                          }));
                  install(new FakeUtcClockModule());
                  install(new FakePluginExecutionModule());
                  install(new FakePortScannerBootstrapModule());
                  install(new FailedVulnDetectorBootstrapModule());
                  install(new RemoteServerLoaderModule(ImmutableList.of()));
                }
              })
          .injectMembers(this);

      boolean scanSucceeded = tsunamiCli.run();

      assertThat(scanSucceeded).isFalse();

      verify(scanResultsArchiver, times(1)).archive(scanResultsCaptor.capture());
      ScanResults storedScanResult = scanResultsCaptor.getValue();
      assertThat(storedScanResult.getScanStatus()).isEqualTo(ScanStatus.FAILED);
      assertThat(storedScanResult.getStatusMessage()).isEqualTo("All VulnDetectors failed.");
    }
  }