/**
   * Should not cause a fatal error even for an empty selector.
   *
   * @throws Exception
   */
  @Test
  public void testEmptySelector() throws Exception {
    FreeStyleProject copiee = j.createFreeStyleProject();
    FreeStyleProject copier = j.createFreeStyleProject();

    ParameterizedBuildSelector pbs = new ParameterizedBuildSelector("SELECTOR");
    copier
        .getBuildersList()
        .add(
            CopyArtifactUtil.createCopyArtifact(
                copiee.getFullName(),
                null, // parameters
                pbs,
                "**/*", // filter
                "", // excludes
                false, // flatten
                true, // optional
                false // finterprintArtifacts
                ));
    FreeStyleBuild b =
        (FreeStyleBuild)
            copier
                .scheduleBuild2(0, new ParametersAction(new StringParameterValue("SELECTOR", "")))
                .get();
    j.assertBuildStatusSuccess(b);
  }
  @Test
  public void testRestInterfaceSuccess() throws Exception {
    prepareSecurity();

    FreeStyleProject srcProject = j.createFreeStyleProject();
    srcProject.addProperty(
        new AuthorizeProjectProperty(new SpecificUsersAuthorizationStrategy("test1", false)));
    srcProject.save();

    WebClient wc = j.createWebClient();
    wc.login("test1", "test1");

    // GET config.xml of srcProject (userid is set to test1)
    String configXml =
        getConfigXml(wc.goToXml(String.format("%s/config.xml", srcProject.getUrl())));

    // POST config.xml of srcProject (userid is set to test1) to a new project.
    // This should success.
    FreeStyleProject destProject = j.createFreeStyleProject();
    destProject.save();
    String projectName = destProject.getFullName();

    WebRequestSettings req =
        new WebRequestSettings(
            wc.createCrumbedUrl(String.format("%s/config.xml", destProject.getUrl())),
            HttpMethod.POST);
    req.setRequestBody(configXml);
    wc.getPage(req);

    {
      FreeStyleProject p = j.jenkins.getItemByFullName(projectName, FreeStyleProject.class);
      assertNotNull(p);
      AuthorizeProjectProperty prop = p.getProperty(AuthorizeProjectProperty.class);
      assertNotNull(prop);
      assertEquals(SpecificUsersAuthorizationStrategy.class, prop.getStrategy().getClass());
      SpecificUsersAuthorizationStrategy strategy =
          (SpecificUsersAuthorizationStrategy) prop.getStrategy();
      assertEquals("test1", strategy.getUserid());
    }

    j.jenkins.reload();

    {
      FreeStyleProject p = j.jenkins.getItemByFullName(projectName, FreeStyleProject.class);
      assertNotNull(p);
      AuthorizeProjectProperty prop = p.getProperty(AuthorizeProjectProperty.class);
      assertNotNull(prop);
      assertEquals(SpecificUsersAuthorizationStrategy.class, prop.getStrategy().getClass());
      SpecificUsersAuthorizationStrategy strategy =
          (SpecificUsersAuthorizationStrategy) prop.getStrategy();
      assertEquals("test1", strategy.getUserid());
    }
  }
  @Test
  public void testRestInterfaceFailure() throws Exception {
    prepareSecurity();

    FreeStyleProject srcProject = j.createFreeStyleProject();
    srcProject.addProperty(
        new AuthorizeProjectProperty(new SpecificUsersAuthorizationStrategy("admin", false)));
    srcProject.save();

    WebClient wc = j.createWebClient();
    wc.login("test1", "test1");

    // GET config.xml of srcProject (userid is set to admin)
    String configXml =
        getConfigXml(wc.goToXml(String.format("%s/config.xml", srcProject.getUrl())));

    // POST config.xml of srcProject (userid is set to admin) to a new project.
    // This should fail.
    FreeStyleProject destProject = j.createFreeStyleProject();
    destProject.save();
    String projectName = destProject.getFullName();

    WebRequestSettings req =
        new WebRequestSettings(
            wc.createCrumbedUrl(String.format("%s/config.xml", destProject.getUrl())),
            HttpMethod.POST);
    req.setRequestBody(configXml);

    try {
      wc.getPage(req);
      fail();
    } catch (FailingHttpStatusCodeException e) {
    }

    {
      FreeStyleProject p = j.jenkins.getItemByFullName(projectName, FreeStyleProject.class);
      assertNotNull(p);
      AuthorizeProjectProperty prop = p.getProperty(AuthorizeProjectProperty.class);
      assertTrue(prop == null || prop.getStrategy() == null);
    }

    j.jenkins.reload();

    {
      FreeStyleProject p = j.jenkins.getItemByFullName(projectName, FreeStyleProject.class);
      assertNotNull(p);
      AuthorizeProjectProperty prop = p.getProperty(AuthorizeProjectProperty.class);
      assertTrue(prop == null || prop.getStrategy() == null);
    }
  }
  @Test
  public void doNothingIfItWillNotShortenThePath() throws Exception {
    DumbSlave s = j.createOnlineSlave();

    // Would be turned into 'short_project...XXXXXXXX' which is in fact longer than the original
    FreeStyleProject p = j.createFreeStyleProject("short_project_name");
    p.setAssignedNode(s);

    // Not enough for anything
    setMaxPathLength(s, 1);

    FreeStyleBuild b = p.scheduleBuild2(0).get();
    assertThat(
        b.getWorkspace().getRemote(),
        equalTo(s.getRootPath() + DS + "workspace" + DS + p.getFullName().replace("/", DS)));
  }
  @Test
  public void doNothingIfThereIsEnoughRoom() throws Exception {
    DumbSlave s = j.createOnlineSlave();

    MockFolder f = j.createFolder("this_is_my_folder_alright");
    FreeStyleProject p = f.createProject(FreeStyleProject.class, "and_a_project_in_it");
    p.setAssignedNode(s);

    // Enough for the test - even on windows
    setMaxPathLength(s, 4096);

    FreeStyleBuild b = p.scheduleBuild2(0).get();
    assertThat(
        b.getWorkspace().getRemote(),
        equalTo(s.getRootPath() + DS + "workspace" + DS + p.getFullName().replace("/", DS)));
  }
  /**
   * Should not cause a fatal error even for an undefined variable.
   *
   * @throws Exception
   */
  @Issue("JENKINS-30357")
  @Test
  public void testUndefinedParameter() throws Exception {
    FreeStyleProject copiee = j.createFreeStyleProject();
    FreeStyleProject copier = j.createFreeStyleProject();

    ParameterizedBuildSelector pbs = new ParameterizedBuildSelector("NosuchVariable");
    copier
        .getBuildersList()
        .add(
            CopyArtifactUtil.createCopyArtifact(
                copiee.getFullName(),
                null, // parameters
                pbs,
                "**/*", // filter
                "", // excludes
                false, // flatten
                true, // optional
                false // finterprintArtifacts
                ));
    FreeStyleBuild b = copier.scheduleBuild2(0).get();
    j.assertBuildStatusSuccess(b);
  }
  /**
   * Also applicable for workflow jobs.
   *
   * @throws Exception
   */
  @Issue("JENKINS-30357")
  @Test
  public void testWorkflow() throws Exception {
    // Prepare an artifact to be copied.
    FreeStyleProject copiee = j.createFreeStyleProject();
    copiee.getBuildersList().add(new FileWriteBuilder("artifact.txt", "foobar"));
    copiee.getPublishersList().add(new ArtifactArchiver("artifact.txt"));
    j.assertBuildStatusSuccess(copiee.scheduleBuild2(0));

    WorkflowJob copier = createWorkflowJob();
    copier.setDefinition(
        new CpsFlowDefinition(
            String.format(
                "node {"
                    + "step([$class: 'CopyArtifact',"
                    + "projectName: '%1$s',"
                    + "filter: '**/*',"
                    + "selector: [$class: 'ParameterizedBuildSelector', parameterName: 'SELECTOR'],"
                    + "]);"
                    + "step([$class: 'ArtifactArchiver', artifacts: '**/*']);"
                    + "}",
                copiee.getFullName()),
            true));

    WorkflowRun b =
        j.assertBuildStatusSuccess(
            copier.scheduleBuild2(
                0,
                null,
                new ParametersAction(
                    new StringParameterValue(
                        "SELECTOR",
                        "<StatusBuildSelector><stable>true</stable></StatusBuildSelector>"))));

    VirtualFile vf = b.getArtifactManager().root().child("artifact.txt");
    assertEquals("foobar", IOUtils.toString(vf.open()));
  }
  /**
   * Also accepts variable expression.
   *
   * @throws Exception
   */
  @Test
  public void testVariableExpression() throws Exception {
    // Prepare an artifact to be copied.
    FreeStyleProject copiee = j.createFreeStyleProject();
    copiee.getBuildersList().add(new FileWriteBuilder("artifact.txt", "foobar"));
    copiee.getPublishersList().add(new ArtifactArchiver("artifact.txt"));
    j.assertBuildStatusSuccess(copiee.scheduleBuild2(0));

    FreeStyleProject copier = j.createFreeStyleProject();
    ParameterizedBuildSelector pbs = new ParameterizedBuildSelector("${SELECTOR}");
    copier
        .getBuildersList()
        .add(
            CopyArtifactUtil.createCopyArtifact(
                copiee.getFullName(),
                null, // parameters
                pbs,
                "**/*", // filter
                "", // excludes
                false, // flatten
                false, // optional
                false // finterprintArtifacts
                ));
    FreeStyleBuild b =
        j.assertBuildStatusSuccess(
            (FreeStyleBuild)
                copier
                    .scheduleBuild2(
                        0,
                        new ParametersAction(
                            new StringParameterValue(
                                "SELECTOR",
                                "<StatusBuildSelector><stable>true</stable></StatusBuildSelector>")))
                    .get());

    assertEquals("foobar", b.getWorkspace().child("artifact.txt").readToString());
  }
  @Test
  public void testCliFailure() throws Exception {
    prepareSecurity();

    FreeStyleProject srcProject = j.createFreeStyleProject();
    srcProject.addProperty(
        new AuthorizeProjectProperty(new SpecificUsersAuthorizationStrategy("admin", false)));
    srcProject.save();

    WebClient wc = j.createWebClient();
    wc.login("test1", "test1");

    // GET config.xml of srcProject (userid is set to admin)
    String configXml = null;
    {
      CLI cli = new CLI(j.getURL());
      ByteArrayOutputStream stdout = new ByteArrayOutputStream();
      ByteArrayOutputStream stderr = new ByteArrayOutputStream();
      int ret =
          cli.execute(
              Arrays.asList(
                  "get-job",
                  srcProject.getFullName(),
                  "--username",
                  "test1",
                  "--password",
                  "test1"),
              new NullInputStream(0),
              stdout,
              stderr);
      assertEquals(stderr.toString(), 0, ret);
      configXml = stdout.toString();
    }

    // POST config.xml of srcProject (userid is set to admin) to a new project.
    // This should fail.
    FreeStyleProject destProject = j.createFreeStyleProject();
    destProject.save();
    String projectName = destProject.getFullName();

    {
      CLI cli = new CLI(j.getURL());
      ByteArrayOutputStream stdout = new ByteArrayOutputStream();
      ByteArrayOutputStream stderr = new ByteArrayOutputStream();
      int ret =
          cli.execute(
              Arrays.asList(
                  "update-job",
                  destProject.getFullName(),
                  "--username",
                  "test1",
                  "--password",
                  "test1"),
              new ByteArrayInputStream(configXml.getBytes()),
              stdout,
              stderr);
      assertNotEquals(0, ret);
    }

    {
      FreeStyleProject p = j.jenkins.getItemByFullName(projectName, FreeStyleProject.class);
      assertNotNull(p);
      AuthorizeProjectProperty prop = p.getProperty(AuthorizeProjectProperty.class);
      assertTrue(prop == null || prop.getStrategy() == null);
    }

    j.jenkins.reload();

    {
      FreeStyleProject p = j.jenkins.getItemByFullName(projectName, FreeStyleProject.class);
      assertNotNull(p);
      AuthorizeProjectProperty prop = p.getProperty(AuthorizeProjectProperty.class);
      assertTrue(prop == null || prop.getStrategy() == null);
    }
  }