/** Scenario: loads on one label shouldn't translate to load on another label. */
  public void testLabels() throws Exception {
    BulkChange bc = new BulkChange(hudson);
    try {
      DummyCloudImpl cloud = initHudson(0);
      Label blue = hudson.getLabel("blue");
      Label red = hudson.getLabel("red");
      cloud.label = red;

      // red jobs
      List<FreeStyleProject> redJobs = create5SlowJobs(new Latch(5));
      for (FreeStyleProject p : redJobs) p.setAssignedLabel(red);

      // blue jobs
      List<FreeStyleProject> blueJobs = create5SlowJobs(new Latch(5));
      for (FreeStyleProject p : blueJobs) p.setAssignedLabel(blue);

      // build all
      List<Future<FreeStyleBuild>> blueBuilds = buildAll(blueJobs);
      verifySuccessfulCompletion(buildAll(redJobs));

      // cloud should only give us 5 nodes for 5 red jobs
      assertEquals(5, cloud.numProvisioned);

      // and all blue jobs should be still stuck in the queue
      for (Future<FreeStyleBuild> bb : blueBuilds) assertFalse(bb.isDone());
    } finally {
      bc.abort();
    }
  }
  /** Scenario: we got a lot of jobs all of the sudden, and we need to fire up a few nodes. */
  public void testLoadSpike() throws Exception {
    BulkChange bc = new BulkChange(hudson);
    try {
      DummyCloudImpl cloud = initHudson(0);

      verifySuccessfulCompletion(buildAll(create5SlowJobs(new Latch(5))));

      // the time it takes to complete a job is eternally long compared to the time it takes to
      // launch
      // a new slave, so in this scenario we end up allocating 5 slaves for 5 jobs.
      assertEquals(5, cloud.numProvisioned);
    } finally {
      bc.abort();
    }
  }
  /** Scenario: schedule a build and see if one slave is provisioned. */
  public void testAutoProvision() throws Exception {
    BulkChange bc = new BulkChange(hudson);
    try {
      DummyCloudImpl cloud = initHudson(10);

      FreeStyleProject p = createJob(new SleepBuilder(10));

      Future<FreeStyleBuild> f = p.scheduleBuild2(0);
      f.get(30, TimeUnit.SECONDS); // if it's taking too long, abort.

      // since there's only one job, we expect there to be just one slave
      assertEquals(1, cloud.numProvisioned);
    } finally {
      bc.abort();
    }
  }
  /** Scenario: make sure we take advantage of statically configured slaves. */
  public void testBaselineSlaveUsage() throws Exception {
    BulkChange bc = new BulkChange(hudson);
    try {
      DummyCloudImpl cloud = initHudson(0);
      // add slaves statically upfront
      createSlave().toComputer().connect(false).get();
      createSlave().toComputer().connect(false).get();

      verifySuccessfulCompletion(buildAll(create5SlowJobs(new Latch(5))));

      // we should have used two static slaves, thus only 3 slaves should have been provisioned
      assertEquals(3, cloud.numProvisioned);
    } finally {
      bc.abort();
    }
  }