Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import io.jenkins.plugins.forensics.delta.FileEditType;
import io.jenkins.plugins.forensics.git.reference.GitReferenceRecorder;
import io.jenkins.plugins.forensics.git.util.GitITest;
import io.jenkins.plugins.forensics.reference.ReferenceBuild;

import static io.jenkins.plugins.forensics.assertions.Assertions.*;
import static org.mockito.Mockito.*;
Expand All @@ -48,7 +49,61 @@
\\ No newline at end of file
""";

@Test @Issue("JENKINS-73297")
/**
* Creates a pipeline that checks if the delta computation works as expected when the main is one commit and build
* ahead of the feature branch.
*
* <pre>
* {@code
* M: [M1]#1 - [M2]#2
* \
* F: [F1]#1}
* </pre>
*/
@Test
void shouldFindDeltaEvenWhenTheMainBranchEvolves() {
var mainBranch = createPipeline(MAIN);
mainBranch.setDefinition(asStage(createLocalGitCheckout(MAIN)));

Run<?, ?> mainBuild = buildSuccessfully(mainBranch);

var mainHash = getHead();
var featureHash = createFeatureBranchAndAddCommits();
addAdditionalFileTo(MAIN);

buildAgain(mainBranch);

var featureBranch = createPipeline(FEATURE);
featureBranch.setDefinition(asStage(createLocalGitCheckout(FEATURE),
"discoverGitReferenceBuild(referenceJob: '" + MAIN + "')"));

Run<?, ?> featureBuild = buildSuccessfully(featureBranch);
assertThat(featureBuild.getNumber()).isEqualTo(1);

assertThat(featureBuild.getAction(ReferenceBuild.class)).isNotNull()
.hasOwner(featureBuild)
.hasReferenceBuildId(mainBuild.getExternalizableId())
.hasReferenceBuild(Optional.of(mainBuild))
.hasMessages("Configured reference job: 'main'",
"Found reference build '#1' for target branch");

Check warning on line 88 in plugin/src/test/java/io/jenkins/plugins/forensics/git/delta/GitDeltaCalculatorITest.java

View check run for this annotation

ci.jenkins.io / CPD

CPD

LOW: Found duplicated code.
Raw output
<pre><code>var featureHash &#61; createFeatureBranchAndAddCommits(); addAdditionalFileTo(MAIN); buildAgain(mainBranch); var featureBranch &#61; createPipeline(FEATURE); featureBranch.setDefinition(asStage(createLocalGitCheckout(FEATURE), &#34;discoverGitReferenceBuild(referenceJob: &#39;&#34; &#43; MAIN &#43; &#34;&#39;)&#34;)); Run&lt;?, ?&gt; featureBuild &#61; buildSuccessfully(featureBranch); assertThat(featureBuild.getNumber()).isEqualTo(1); assertThat(featureBuild.getAction(ReferenceBuild.class)).isNotNull() .hasOwner(featureBuild) .hasReferenceBuildId(mainBuild.getExternalizableId()) .hasReferenceBuild(Optional.of(mainBuild)) .hasMessages(&#34;Configured reference job: &#39;main&#39;&#34;, &#34;Found reference build &#39;#1&#39; for target branch&#34;);</code></pre>

var log = createLog();
var deltaCalculator = createDeltaCalculator();
deltaCalculator.calculateDelta(featureBuild, mainBuild, EMPTY_SCM_KEY, log);
assertThat(log.getErrorMessages()).isEmpty();
assertThat(log.getInfoMessages()).contains(String.format(
"-> Using commit '%7.7s' as latest commit for build 'main #1'", mainHash));
assertThat(log.getInfoMessages()).contains(String.format(
"-> Using commit '%7.7s' as latest commit for build 'feature #1'", featureHash));
assertThat(log.getInfoMessages()).contains(
"-> 1 files contain changes",
"-> Creating the Git diff file",
"-> Git code delta successfully calculated"
);
}

@Test
@Issue("JENKINS-73297")
void shouldShowErrorIfCommitIsNotFound() {
var job = createPipeline();
job.setDefinition(asStage("checkout([$class: 'GitSCM', "
Expand All @@ -65,7 +120,8 @@
assertThat(result).isNotEmpty();

assertThat(log.getInfoMessages()).anyMatch(s ->
s.contains("-> Invoking Git delta calculator for determining the changes between commits '86503e8' and '86503e8'"));
s.contains(
"-> Invoking Git delta calculator for determining the changes between commits '86503e8' and '86503e8'"));
assertThat(log.getErrorMessages())
.contains("Could not find the specified commit - is the SCM parameter correctly set?",
"org.eclipse.jgit.errors.MissingObjectException: Missing unknown 86503e8bc0374e05e2cd32ed3bb8b4435d5fd757");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,7 @@

import com.cloudbees.hudson.plugins.folder.computed.FolderComputation;

import edu.hm.hafner.util.PathUtil;

import java.io.IOException;
import java.util.Arrays;
import java.util.Locale;
import java.util.Objects;
import java.util.Optional;
Expand Down Expand Up @@ -53,11 +50,6 @@
class GitReferenceRecorderITest extends GitITest {
private static final String FORENSICS_API_URL = "https://github.com/jenkinsci/forensics-api-plugin.git";

private static final String JENKINS_FILE = "Jenkinsfile";
private static final String SOURCE_FILE = "file";
private static final String FEATURE = "feature";
private static final String MAIN = "main";
private static final String ADDITIONAL_SOURCE_FILE = "test.txt";
private static final String CHANGED_CONTENT = "changed content";
private static final GitCommitTextDecorator DECORATOR = new GitCommitTextDecorator();

Expand Down Expand Up @@ -136,24 +128,24 @@

Run<?, ?> mainBuild = buildSuccessfully(mainBranch);

createFeatureBranchAndAddCommits();

addAdditionalFileTo(MAIN);

buildAgain(mainBranch);

var featureBranch = createPipeline(FEATURE);
featureBranch.setDefinition(asStage(createLocalGitCheckout(FEATURE),
"discoverGitReferenceBuild(referenceJob: '" + MAIN + "')"));

Run<?, ?> featureBuild = buildSuccessfully(featureBranch);
assertThat(featureBuild.getNumber()).isEqualTo(1);

assertThat(featureBuild.getAction(ReferenceBuild.class)).isNotNull()
.hasOwner(featureBuild)
.hasReferenceBuildId(mainBuild.getExternalizableId())
.hasReferenceBuild(Optional.of(mainBuild))
.hasMessages("Configured reference job: 'main'",

Check warning on line 148 in plugin/src/test/java/io/jenkins/plugins/forensics/git/reference/GitReferenceRecorderITest.java

View check run for this annotation

ci.jenkins.io / CPD

CPD

LOW: Found duplicated code.
Raw output
<pre><code>var featureHash &#61; createFeatureBranchAndAddCommits(); addAdditionalFileTo(MAIN); buildAgain(mainBranch); var featureBranch &#61; createPipeline(FEATURE); featureBranch.setDefinition(asStage(createLocalGitCheckout(FEATURE), &#34;discoverGitReferenceBuild(referenceJob: &#39;&#34; &#43; MAIN &#43; &#34;&#39;)&#34;)); Run&lt;?, ?&gt; featureBuild &#61; buildSuccessfully(featureBranch); assertThat(featureBuild.getNumber()).isEqualTo(1); assertThat(featureBuild.getAction(ReferenceBuild.class)).isNotNull() .hasOwner(featureBuild) .hasReferenceBuildId(mainBuild.getExternalizableId()) .hasReferenceBuild(Optional.of(mainBuild)) .hasMessages(&#34;Configured reference job: &#39;main&#39;&#34;, &#34;Found reference build &#39;#1&#39; for target branch&#34;);</code></pre>
"Found reference build '#1' for target branch");
}

Expand Down Expand Up @@ -399,14 +391,6 @@
verifyPipelineResult(mainBuild, featureBranch);
}

private String createLocalGitCheckout(final String branch) {
return "checkout([$class: 'GitSCM', "
+ "branches: [[name: '" + branch + "' ]],\n"
+ getUrl()
+ "extensions: [[$class: 'RelativeTargetDirectory', \n"
+ " relativeTargetDir: 'forensics-api']]])\n";
}

private String createForensicsCheckoutStep() {
return "checkout([$class: 'GitSCM', "
+ "branches: [[name: 'a6d0ef09ab3c418e370449a884da99b8190ae950' ]],\n"
Expand Down Expand Up @@ -434,10 +418,6 @@
"Found reference build '#1' for target branch");
}

private String getUrl() {
return "userRemoteConfigs: [[url: 'file://" + new PathUtil().getAbsolutePath(getGitRepositoryPath()) + "']],\n";
}

/**
* Creates a multibranch pipelines (similar to the manual pipelines in {@link #shouldFindCorrectBuildInPipelines()}).
* <pre>
Expand Down Expand Up @@ -912,42 +892,6 @@
}
}

private String createFeatureBranchAndAddCommits(final String... parameters) {
String[] actual = Arrays.copyOf(parameters, parameters.length + 1);
actual[parameters.length] = "targetBranch: '" + MAIN + "'";
return createBranchAndAddCommits(FEATURE, actual);
}

private String createBranchAndAddCommits(final String branch, final String... parameters) {
try {
checkoutNewBranch(branch);
writeFile(JENKINS_FILE,
String.format("echo \"branch=${env.BRANCH_NAME}\";"
+ "node {checkout scm; echo readFile('file').toUpperCase(); "
+ "echo \"GitForensics\"; "
+ "discoverGitReferenceBuild(%s);"
+ "gitDiffStat()}", String.join(",", parameters)));
writeFile(SOURCE_FILE, branch + " content");
commit(branch + " changes");
return getHead();
}
catch (Exception exception) {
throw new AssertionError(exception);
}
}

private String addAdditionalFileTo(final String branch) {
return changeContentOfAdditionalFile(branch, "test");
}

private String changeContentOfAdditionalFile(final String branch, final String content) {
checkout(branch);
writeFile(ADDITIONAL_SOURCE_FILE, content);
addFile(ADDITIONAL_SOURCE_FILE);
commit("Add additional file");
return getHead();
}

private void delete(final String toDeleteId) {
try {
Objects.requireNonNull(Run.fromExternalizableId(toDeleteId)).delete();
Expand Down Expand Up @@ -990,15 +934,6 @@
getJenkins().assertLogContains(value, build);
}

private WorkflowRun buildAgain(final WorkflowJob build) {
try {
return Objects.requireNonNull(build.scheduleBuild2(0)).get();
}
catch (Exception exception) {
throw new AssertionError(exception);
}
}

private void buildProject(final WorkflowMultiBranchProject project) {
try {
Objects.requireNonNull(project.scheduleBuild2(0)).getFuture().get();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.io.TempDir;

import edu.hm.hafner.util.PathUtil;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;

import java.io.File;
Expand All @@ -19,10 +20,13 @@
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.UUID;

import org.jenkinsci.plugins.gitclient.GitClient;
import org.jenkinsci.plugins.gitclient.RepositoryCallback;
import org.jenkinsci.plugins.workflow.job.WorkflowJob;
import org.jenkinsci.plugins.workflow.job.WorkflowRun;
import hudson.EnvVars;
import hudson.FilePath;
import hudson.Launcher;
Expand Down Expand Up @@ -62,6 +66,11 @@

/** Initial branch used in Git repository. */
protected static final String INITIAL_BRANCH = "main";
protected static final String FEATURE = "feature";

Check warning on line 69 in plugin/src/test/java/io/jenkins/plugins/forensics/git/util/GitITest.java

View check run for this annotation

ci.jenkins.io / CheckStyle

JavadocVariableCheck

NORMAL: Missing a Javadoc comment.
Raw output
<p>Since Checkstyle 3.0</p><p> Checks that variables have Javadoc comments. Ignores <code>serialVersionUID</code> fields. </p>
protected static final String MAIN = "main";

Check warning on line 70 in plugin/src/test/java/io/jenkins/plugins/forensics/git/util/GitITest.java

View check run for this annotation

ci.jenkins.io / CheckStyle

JavadocVariableCheck

NORMAL: Missing a Javadoc comment.
Raw output
<p>Since Checkstyle 3.0</p><p> Checks that variables have Javadoc comments. Ignores <code>serialVersionUID</code> fields. </p>
protected static final String JENKINS_FILE = "Jenkinsfile";

Check warning on line 71 in plugin/src/test/java/io/jenkins/plugins/forensics/git/util/GitITest.java

View check run for this annotation

ci.jenkins.io / CheckStyle

JavadocVariableCheck

NORMAL: Missing a Javadoc comment.
Raw output
<p>Since Checkstyle 3.0</p><p> Checks that variables have Javadoc comments. Ignores <code>serialVersionUID</code> fields. </p>
protected static final String SOURCE_FILE = "file";

Check warning on line 72 in plugin/src/test/java/io/jenkins/plugins/forensics/git/util/GitITest.java

View check run for this annotation

ci.jenkins.io / CheckStyle

JavadocVariableCheck

NORMAL: Missing a Javadoc comment.
Raw output
<p>Since Checkstyle 3.0</p><p> Checks that variables have Javadoc comments. Ignores <code>serialVersionUID</code> fields. </p>
private static final String ADDITIONAL_SOURCE_FILE = "test.txt";

private GitRepository gitRepository;

Expand Down Expand Up @@ -280,6 +289,63 @@
return getGitRepository().getBaseDirectory().getAbsolutePath();
}

protected String createLocalGitCheckout(final String branch) {
return "checkout([$class: 'GitSCM', "
+ "branches: [[name: '" + branch + "' ]],\n"
+ getUrl()
+ "extensions: [[$class: 'RelativeTargetDirectory', \n"
+ " relativeTargetDir: 'forensics-api']]])\n";
}

private String getUrl() {
return "userRemoteConfigs: [[url: 'file://" + new PathUtil().getAbsolutePath(getGitRepositoryPath()) + "']],\n";
}

protected String createFeatureBranchAndAddCommits(final String... parameters) {
String[] actual = Arrays.copyOf(parameters, parameters.length + 1);
actual[parameters.length] = "targetBranch: '" + MAIN + "'";
return createBranchAndAddCommits(FEATURE, actual);
}

protected String createBranchAndAddCommits(final String branch, final String... parameters) {
try {
checkoutNewBranch(branch);
writeFile(JENKINS_FILE,
String.format("echo \"branch=${env.BRANCH_NAME}\";"
+ "node {checkout scm; echo readFile('file').toUpperCase(); "
+ "echo \"GitForensics\"; "
+ "discoverGitReferenceBuild(%s);"
+ "gitDiffStat()}", String.join(",", parameters)));
writeFile(SOURCE_FILE, branch + " content");
commit(branch + " changes");
return getHead();
}
catch (Exception exception) {
throw new AssertionError(exception);
}
}

protected String addAdditionalFileTo(final String branch) {
return changeContentOfAdditionalFile(branch, "test");
}

protected String changeContentOfAdditionalFile(final String branch, final String content) {
checkout(branch);
writeFile(ADDITIONAL_SOURCE_FILE, content);
addFile(ADDITIONAL_SOURCE_FILE);
commit("Add additional file");
return getHead();
}

protected WorkflowRun buildAgain(final WorkflowJob build) {
try {
return Objects.requireNonNull(build.scheduleBuild2(0)).get();
}
catch (Exception exception) {
throw new AssertionError(exception);
}
}

/**
* A test case that runs in the preconfigured Git repository of this integration test.
*/
Expand Down
Loading