Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[JENKINS-39284] Set build description to failure cause #72

Open
wants to merge 40 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
bc8430f
JENKINS-39284_Set_build_description_to_failure_cause
TreverW Aug 2, 2017
82fa462
Add a setter for the enableBuildDescription option.
TreverW Aug 11, 2017
cae89da
Refactor with a method specific to creating the build description usi…
TreverW Aug 11, 2017
c6a005c
Add unit tests for the enableBuildDescription option. The tests are …
TreverW Aug 11, 2017
764d9f3
Fix how BFA description gets concatenated to existing build description.
TreverW Aug 17, 2017
f4ebd34
Change tests to include a pre-set build description.
TreverW Aug 17, 2017
7412511
JENKINS-39284_Set_build_description_to_failure_cause
TreverW Aug 2, 2017
f57029d
Add a setter for the enableBuildDescription option.
TreverW Aug 11, 2017
f3b2cab
Refactor with a method specific to creating the build description usi…
TreverW Aug 11, 2017
2c4ab5e
Add unit tests for the enableBuildDescription option. The tests are …
TreverW Aug 11, 2017
9d86903
Fix how BFA description gets concatenated to existing build description.
TreverW Aug 17, 2017
03e03c7
Change tests to include a pre-set build description.
TreverW Aug 17, 2017
2550584
Merge remote-tracking branch 'origin/JENKINS-39284_Set_build_descript…
TreverW Mar 22, 2018
81ab7df
Merge branch 'master' into JENKINS-39284_Set_build_description_to_fai…
TreverW May 31, 2018
f0125a0
Merge remote-tracking branch 'upstream/master'
TreverW Jan 7, 2020
cf6104f
Merge master upstream into working branch.
TreverW Jan 7, 2020
1bd3035
Change tests to include a pre-set build description.
TreverW Feb 20, 2020
ca1223e
Merge branch 'master' of https://github.com/jenkinsci/build-failure-a…
TreverW Mar 9, 2020
1e3912a
Fix test expected files.
TreverW Mar 9, 2020
554f8a1
Update Javadocs per checkstyle recommendations.
TreverW Mar 9, 2020
f1a693a
Merge branch 'master' of https://github.com/jenkinsci/build-failure-a…
TreverW Mar 9, 2020
d6cb396
Merge branch 'JENKINS-39284_Set_build_description_to_failure_cause'
TreverW Mar 10, 2020
9a5ba06
Refactored naming to be consistent with rest of code.
TreverW Mar 10, 2020
8b89b0e
Merge remote-tracking branch 'upstream/master' into master
TreverW Sep 5, 2020
b36d19e
Merge branch 'master' into JENKINS-39284_Set_build_description_to_fai…
TreverW Sep 5, 2020
782c996
Add suppression for MagicNumber Checkstyle check in test file.
TreverW Sep 7, 2020
8d7b3fd
Refactor Boolean to boolean
TreverW Sep 7, 2020
848b9d1
Test for null.
TreverW Sep 7, 2020
de4785f
Change type of test builder to QueueTaskFuture
TreverW Sep 7, 2020
e483810
Update src/main/java/com/sonyericsson/jenkins/plugins/bfa/PluginImpl.…
TreverW Sep 7, 2020
bf9461c
Update src/main/java/com/sonyericsson/jenkins/plugins/bfa/BuildFailur…
TreverW Sep 7, 2020
9740cac
Merge remote-tracking branch 'origin/JENKINS-39284_Set_build_descript…
TreverW Sep 7, 2020
8df48d5
Add suppression for MagicNumber Checkstyle check in test file. Remov…
TreverW Sep 7, 2020
2d3e9ac
Change to StringUtils
TreverW Sep 7, 2020
7dbb571
Removing unnecessary items per feedback to pull request.
TreverW Sep 7, 2020
7977487
Enable parsing test results in test method. Results are required in …
TreverW Sep 9, 2020
9673b47
Refactor string concatenation to eliminate spotbugs issue.
TreverW Sep 9, 2020
3ac164f
Add space to fix another SpotBug isssue.
TreverW Sep 9, 2020
d7868b7
Merge remote-tracking branch 'upstream/master' into master
TreverW Sep 5, 2020
8716adf
Merge branch 'master' into JENKINS-39284_Set_build_description_to_fai…
TreverW Sep 16, 2020
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 @@ -240,6 +240,10 @@ public static void scan(Run build, PrintStream scanLog) {
printDownstream(scanLog, downstreamFailureCauses);
}

if (PluginImpl.getInstance().isBuildDescriptionEnabled() && !foundCauseList.isEmpty()) {
build.setDescription(generateDescriptionString(build, foundCauseList));
}

StatisticsLogger.getInstance().log(build, foundCauseListToLog);
} catch (Exception e) {
logger.log(Level.SEVERE, "Could not scan build " + build, e);
Expand Down Expand Up @@ -534,4 +538,43 @@ private static List<FoundFailureCause> findFailedTests(final Run build, final Pr

return failedTestList;
}

/**
* Generate text that can be used for the build description using categories and failure causes.
*
* @param build to get current build description
* @param foundCauseList list of failure causes
* @return A String of the BFA categories and causes appended to the build's description.
*/
public static String generateDescriptionString(Run build, List<FoundFailureCause> foundCauseList) {
String buildDescription = "<mark>";
// Append all of the categories.
if (foundCauseList.get(0) != null) {
for (int j = 0; j < foundCauseList.get(0).getCategories().size(); j++) {
buildDescription += "<b>";
buildDescription += foundCauseList.get(0).getCategories().get(j).toString();
buildDescription += "</b> ";
}
if (foundCauseList.get(0).getCategories().size() > 0) {
buildDescription += ": ";
}
}

// Append all failure causes.
for (int i = 0; i < foundCauseList.size(); i++) {
buildDescription = buildDescription.concat("<i>");
buildDescription = buildDescription.concat(foundCauseList.get(i).getDescription());
TreverW marked this conversation as resolved.
Show resolved Hide resolved
buildDescription = buildDescription.concat("</i>");
if (i < (foundCauseList.size() - 1)) {
buildDescription += " ";
}
}
buildDescription = buildDescription.concat("</mark>");

// Append this build description to any pre-existing build description
if (!(build.getDescription() == null) && !build.getDescription().isEmpty()) {
TreverW marked this conversation as resolved.
Show resolved Hide resolved
buildDescription = build.getDescription().concat("<br>\n").concat(buildDescription);
}
return buildDescription;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ public class PluginImpl extends GlobalConfiguration {

private int nrOfScanThreads;
private int maxLogSize;
private Boolean buildDescriptionEnabled;

private Boolean graphsEnabled;

Expand Down Expand Up @@ -594,6 +595,28 @@ public int getMaxLogSize() {
}


/**
* Set option to append failure causes to job's build description.
*
* @param buildDescriptionEnabled should build description option be turned on
*/
public void setBuildDescriptionEnabled(Boolean buildDescriptionEnabled) {
TreverW marked this conversation as resolved.
Show resolved Hide resolved
this.buildDescriptionEnabled = buildDescriptionEnabled;
}

/**
* If buildDescriptionEnabled is enabled or not. Build Descriptions will be set to a concatenated
* list of the failure descriptions as a convenience.
* @return True if enabled.
*/
public boolean isBuildDescriptionEnabled() {
if (buildDescriptionEnabled == null) {
return false;
} else {
return buildDescriptionEnabled;
}
}

/**
* Checks if the build with certain result should be analyzed or not.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,5 +87,10 @@
<f:entry title="${%Max size of log file}" description="${%maxLogSize}">
<f:textbox field="maxLogSize" />
</f:entry>
<f:entry title="${%Set job description to failure description}"
description="${%Enabling this option will set the build's description to the failure descriptions as a convenience.}">
<f:checkbox name="buildDescriptionEnabled" checked="${it.buildDescriptionEnabled}"
default="false"/>
</f:entry>
TreverW marked this conversation as resolved.
Show resolved Hide resolved
</f:advanced>
</j:jelly>
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ public class BuildFailureScannerHudsonTest {

private static final String BUILD_LOG = "ERROR: brief\n detail\n";
private static final String BUILD_LOG_FIRST_LINE = "ERROR: brief";
private static final String BUILD_DESCRIPTION = "This is a build description.";
private static final String DESCRIPTION = "The error was: ${1,1}${2,1}";
private static final String REGEX = "ERROR: (.*?)$";
private static final String MULTILINE_REGEX = "ERROR: (.*?)$.*? detail";
Expand Down Expand Up @@ -695,6 +696,126 @@ public boolean perform(AbstractBuild<?, ?> build, Launcher launcher,
assertEquals("Amount of failure causes does not match.", 0, causeListFromAction.size());
}

/**
* Test buildDescriptionEnabled = false does not append failure cause to build description.
*
* @throws Exception if a build description is appended when the setting is set to false.
*/
@Test
public void testTestBuildDescriptionEnabledIfDisabled() throws Exception {
PluginImpl.getInstance().setTestResultParsingEnabled(true);
TreverW marked this conversation as resolved.
Show resolved Hide resolved
PluginImpl.getInstance().setBuildDescriptionEnabled(false);
FreeStyleProject project = jenkins.createFreeStyleProject();

project.getBuildersList().add(new PrintToLogBuilder(BUILD_LOG));
project.getBuildersList().add(new TestBuilder() {
public boolean perform(AbstractBuild<?, ?> build, Launcher launcher,
BuildListener listener) throws InterruptedException, IOException {
build.getWorkspace().child("junit.xml").copyFrom(
this.getClass().getResource("junit.xml"));
return true;
}
});

project.getPublishersList().add(new JUnitResultArchiver("junit.xml", false, null));

Future<FreeStyleBuild> future = project.scheduleBuild2(0, new Cause.UserIdCause());
FreeStyleBuild build = future.get(10, TimeUnit.SECONDS);
jenkins.assertBuildStatus(Result.UNSTABLE, build);

FailureCauseBuildAction action = build.getAction(FailureCauseBuildAction.class);
assertNotNull(action);

List<FoundFailureCause> causeListFromAction = action.getFoundFailureCauses();
assertEquals("Amount of failure causes does not match.", 2, causeListFromAction.size());

// Start with some build description not assigned by BFA and run another scan.
action.getFoundFailureCauses();
assertEquals(build.getDescription(), null);
}

/**
* Test buildDescriptionEnabled = true does append failure cause to existing build description
* without categories set.
*
* @throws Exception if the build description is not appended when the setting is true.
*/
@Test
public void testTestBuildDescriptionEnabledWithoutCategoriesIfEnabled() throws Exception {
PluginImpl.getInstance().setTestResultParsingEnabled(true);
PluginImpl.getInstance().setBuildDescriptionEnabled(true);
FreeStyleProject project = jenkins.createFreeStyleProject();

// Test with a preset build description
project.getBuildersList().add(new PrintToLogBuilder(BUILD_LOG));
project.getBuildersList().add(new TestBuilder() {
public boolean perform(AbstractBuild<?, ?> build, Launcher launcher,
BuildListener listener) throws InterruptedException, IOException {
build.getWorkspace().child("junit.xml").copyFrom(this.getClass().getResource("junit.xml"));
TreverW marked this conversation as resolved.
Show resolved Hide resolved
build.setDescription("Hello World");
return true;
}
});

project.getPublishersList().add(new JUnitResultArchiver("junit.xml", false, null));

Future<FreeStyleBuild> future = project.scheduleBuild2(0, new Cause.UserIdCause());
FreeStyleBuild build = future.get(120, TimeUnit.SECONDS);
jenkins.assertBuildStatus(Result.UNSTABLE, build);

FailureCauseBuildAction action = build.getAction(FailureCauseBuildAction.class);
assertNotNull(action);

List<FoundFailureCause> causeListFromAction = action.getFoundFailureCauses();
assertEquals("Amount of failure causes does not match.", 2, causeListFromAction.size());
String testDescription = "Hello World<br>\n"
+ "<mark><i>Here are details of the failure...</i> <i>More details</i></mark>";

assertEquals(testDescription, build.getDescription());
TreverW marked this conversation as resolved.
Show resolved Hide resolved
}

/**
* Test buildDescriptionEnabled = true does append failure cause to existing build description.
* with categories set
*
* @throws Exception if description is not appended correctly.
*/
@Test
public void testTestBuildDescriptionEnabledWithCategoriesIfEnabled() throws Exception {
PluginImpl.getInstance().setTestResultParsingEnabled(true);
PluginImpl.getInstance().setBuildDescriptionEnabled(true);
String categories = "foo bar";
PluginImpl.getInstance().setTestResultCategories(categories);
FreeStyleProject project = jenkins.createFreeStyleProject();

// Test with a preset build description
project.getBuildersList().add(new PrintToLogBuilder(BUILD_LOG));
project.getBuildersList().add(new TestBuilder() {
public boolean perform(AbstractBuild<?, ?> build, Launcher launcher,
BuildListener listener) throws InterruptedException, IOException {
build.getWorkspace().child("junit.xml").copyFrom(this.getClass().getResource("junit.xml"));
build.setDescription("Hello World");
return true;
}
});

project.getPublishersList().add(new JUnitResultArchiver("junit.xml", false, null));

Future<FreeStyleBuild> future = project.scheduleBuild2(0, new Cause.UserIdCause());
FreeStyleBuild build = future.get(10, TimeUnit.SECONDS);
jenkins.assertBuildStatus(Result.UNSTABLE, build);

FailureCauseBuildAction action = build.getAction(FailureCauseBuildAction.class);
assertNotNull(action);

List<FoundFailureCause> causeListFromAction = action.getFoundFailureCauses();
assertEquals("Amount of failure causes does not match.", 2, causeListFromAction.size());

String testDescription = "Hello World<br>\n"
+ "<mark><b>foo</b> <b>bar</b> : <i>Here are details of the failure...</i> <i>More details</i></mark>";
assertEquals(build.getDescription(), testDescription);
}

/**
* ArgumentMatcher for a Statistics object.
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
buildDescriptionEnabled: false
doNotAnalyzeAbortedJob: true
gerritTriggerEnabled: true
globalEnabled: true
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
buildDescriptionEnabled: false
doNotAnalyzeAbortedJob: true
gerritTriggerEnabled: true
globalEnabled: true
Expand Down