/**
   * When a build is marked as NOT_BUILD And more builds are started And there are no changes Then
   * all following builds should also be marked NOT_BUILD
   */
  public void testShouldMarkBuildsAsNotBuilt() throws Exception {
    setup();
    File dir = createTempDirectory();
    MercurialBridge plugin = new MercurialBridge(false, "test", "default");
    plugin.setWorkingDirectory(new FilePath(dir));

    hg(dir, "init");
    shell(dir, "touch", "foo");
    hg(dir, "add", "foo");
    hg(dir, "commit", "-m", "\"added foo\"");
    // String rev = hg(dir,"tip","--template","{node}").toString();
    hg(dir, "branch", "test");
    shell(dir, "touch", "bar");
    hg(dir, "add", "bar");
    hg(dir, "commit", "-m", "\"added bar\"");

    MercurialSCM scm =
        new MercurialSCM(null, dir.getAbsolutePath(), "test", null, null, null, true);
    FreeStyleProject project =
        Hudson.getInstance().createProject(FreeStyleProject.class, "testproject");
    project.setScm(scm);
    project.getBuildWrappersList().add(new PretestedIntegrationBuildWrapper(plugin));

    Future<FreeStyleBuild> f = project.scheduleBuild2(0);
    FreeStyleBuild build = f.get();
    assertEquals(Result.SUCCESS, build.getResult());
    f = project.scheduleBuild2(0);
    build = f.get();
    assertEquals(Result.NOT_BUILT, build.getResult());
    f = project.scheduleBuild2(0);
    build = f.get();
    assertEquals(Result.NOT_BUILT, build.getResult());
    cleanup(dir);
  }
  /**
   * Given that there are uncomitted changes in the integration branch And that the build is marked
   * successful When handlePostBuild has been invoked Then there should be no more changes on the
   * integration branch And the integration branch has a new commit with the changes
   *
   * @throws Exception
   */
  public void testShouldCommitChanges() throws Exception {
    setup();
    File dir = createTempDirectory();
    System.out.println("Creating test repository at repository: " + dir.getAbsolutePath());

    MercurialBridge plugin = new MercurialBridge(false, "test", "default");
    plugin.setWorkingDirectory(new FilePath(dir));

    hg(dir, "init");
    shell(dir, "touch", "foo");
    hg(dir, "add", "foo");
    hg(dir, "commit", "-m", "added foo");
    hg(dir, "branch", "test");
    String revision = hg(dir, "tip", "--template", "{node}").toString();
    shell(dir, "touch", "bar");
    hg(dir, "add", "bar");
    hg(dir, "commit", "-m", "added bar");
    hg(dir, "update", "default");
    hg(dir, "merge", "test");

    MercurialSCM scm =
        new MercurialSCM(null, dir.getAbsolutePath(), "test", null, null, null, true);
    FreeStyleProject project =
        Hudson.getInstance().createProject(FreeStyleProject.class, "testproject");
    project.setScm(scm);

    Future<FreeStyleBuild> b = project.scheduleBuild2(0);
    FreeStyleBuild build = spy(b.get());
    when(build.getResult()).thenReturn(Result.SUCCESS);

    OutputStream out = new ByteArrayOutputStream();
    BuildListener bListener = new StreamBuildListener(out);
    assertTrue(hg(dir, "branch").toString().startsWith("default"));
    assertTrue(hg(dir, "status").toString().startsWith("M bar"));
    assertNotNull(build.getResult());

    plugin.nextCommit(build, launcher, bListener, null);

    plugin.handlePostBuild(build, launcher, bListener);

    assertTrue(hg(dir, "branch").toString().startsWith("default"));
    assertTrue(hg(dir, "status").toString().isEmpty());

    assertTrue(
        hg(dir, "log", "-rtip", "--template", "{desc}").toString().startsWith("Merge of revision"));

    cleanup(dir);
  }
  /**
   * Tests to trigger a build with the same patch set twice, one is a manual event and the other a
   * normal. Expecting one build to be scheduled with two causes of different type..
   *
   * @throws Exception if so.
   */
  @LocalData
  public void testDoubleTriggeredBuildOfDifferentType() throws Exception {
    FreeStyleProject project = DuplicatesUtil.createGerritTriggeredJob(this, "projectX");
    server.waitForCommand(GERRIT_STREAM_EVENTS, 2000);
    PatchsetCreated patchsetCreated = Setup.createPatchsetCreated();
    ManualPatchsetCreated mpc = new ManualPatchsetCreated();
    mpc.setChange(patchsetCreated.getChange());
    mpc.setPatchset(patchsetCreated.getPatchSet());
    mpc.setUploader(patchsetCreated.getUploader());
    mpc.setUserName("bobby");
    PluginImpl.getInstance().triggerEvent(Setup.createPatchsetCreated());
    PluginImpl.getInstance().triggerEvent(mpc);

    RunList<FreeStyleBuild> builds = waitForBuilds(project, 1, 5000);
    FreeStyleBuild build = builds.get(0);
    assertSame(Result.SUCCESS, build.getResult());
    assertEquals(1, builds.size());

    int count = 0;
    for (Cause cause : build.getCauses()) {
      if (cause instanceof GerritCause) {
        count++;
        assertNotNull(((GerritCause) cause).getContext());
        assertNotNull(((GerritCause) cause).getContext().getThisBuild());
        assertNotNull(((GerritCause) cause).getEvent());
      }
    }
    assertEquals(2, count);
  }
  @Test
  public void testParameterisedJobShouldSaveAllParameters() throws Exception {
    final FreeStyleProject project = createFreeStyleProject("ParameterisedJob");

    // set parameters
    final ParameterDefinition param1 =
        new StringParameterDefinition("myStringParam", "myStringValue", "My String Parameter");
    final ParameterDefinition param2 =
        new BooleanParameterDefinition("myBooleanParam", false, "My Boolean Parameter");
    project.addProperty(new ParametersDefinitionProperty(param1, param2));

    // enable audit2db plugin
    final DbAuditPublisher plugin = getPlugin();
    project.getPublishersList().add((Publisher) plugin);

    // build now
    final Future<FreeStyleBuild> futureBuild = project.scheduleBuild2(0);
    final FreeStyleBuild build = futureBuild.get();
    Assert.assertNotNull(build);
    Assert.assertEquals("Unexpected build result", Result.SUCCESS, build.getResult());

    // check data persistence
    final BuildDetailsRepository repository = plugin.getRepository();
    final BuildDetails actual = repository.getBuildDetailsForBuild(build);
    final BuildDetails expected = new BuildDetailsImpl(build);
    Assert.assertEquals("Unexpected build details", expected, actual);
    Assert.assertNotNull("Unexpected null end date", actual.getEndDate());
    Assert.assertTrue("Unexpected duration", actual.getDuration() > 0L);
    Assert.assertEquals("Unexpected number of params", 2, actual.getParameters().size());
  }
  /**
   * Tests to trigger a build with the same patch set twice. Expecting one build to be scheduled
   * with one cause.
   *
   * @throws Exception if so.
   */
  @LocalData
  public void testDoubleTriggeredBuild() throws Exception {
    FreeStyleProject project = DuplicatesUtil.createGerritTriggeredJob(this, "projectX");
    server.waitForCommand(GERRIT_STREAM_EVENTS, 2000);
    PluginImpl.getInstance().triggerEvent(Setup.createPatchsetCreated());
    PluginImpl.getInstance().triggerEvent(Setup.createPatchsetCreated());

    RunList<FreeStyleBuild> builds = waitForBuilds(project, 1, 5000);
    FreeStyleBuild build = builds.get(0);
    assertSame(Result.SUCCESS, build.getResult());
    assertEquals(1, project.getBuilds().size());

    int count = 0;
    for (Cause cause : build.getCauses()) {
      if (cause instanceof GerritCause) {
        count++;
        assertNotNull(((GerritCause) cause).getContext());
        assertNotNull(((GerritCause) cause).getEvent());
      }
    }
    assertEquals(1, count);
  }
  @Test
  public void testPlainJobShouldSaveNoParameters() throws Exception {
    final FreeStyleProject project = createFreeStyleProject("PlainJob");

    // enable audit2db plugin
    final DbAuditPublisher plugin = getPlugin();
    project.getPublishersList().add((Publisher) plugin);

    // build now
    final Future<FreeStyleBuild> futureBuild = project.scheduleBuild2(0);
    final FreeStyleBuild build = futureBuild.get();
    Assert.assertNotNull(build);
    Assert.assertEquals("Unexpected build result", Result.SUCCESS, build.getResult());

    // check data persistence
    final BuildDetailsRepository repository = plugin.getRepository();
    final BuildDetails actual = repository.getBuildDetailsForBuild(build);
    final BuildDetails expected = new BuildDetailsImpl(build);
    Assert.assertEquals("Unexpected build details", expected, actual);
    Assert.assertNotNull("Unexpected null end date", actual.getEndDate());
    Assert.assertTrue("Unexpected duration", actual.getDuration() > 0L);
    Assert.assertEquals("Unexpected number of params", 0, actual.getParameters().size());
  }