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

Default checks name to be ' / '-joined enclosing blocks names #211

Conversation

mrginglymus
Copy link
Contributor

@mrginglymus mrginglymus commented Nov 18, 2020

This hopefully goes some way to address @jglick's concerns over the current behaviour (#210).

The default now (hopefully!) is that checks are published per junit invocation with a name derived from the enclosing blocks, unless otherwise overridden. This means that, assuming the idiom of one junit invocation per stage is followed, checks will not be overwritten losing data.

// If we haven't been provided with a checks name, and we have pipeline test details, set the checks name
// to be a ' / '-joined string of the enclosing blocks names. JUnitChecksPublisher will handle defaults if
// checksName ends up being empty or null
String checksName = task.getChecksName() != null || pipelineTestDetails == null ? task.getChecksName() :
Copy link
Member

@timja timja Nov 18, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

example PR where this has been tested? both custom checks name and no override

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm going to spend some quality time with mockito to see if I can get the checks tests testing more of the implementation of parseAndSummarize.

// to be a ' / '-joined string of the enclosing blocks names. JUnitChecksPublisher will handle defaults if
// checksName ends up being empty or null
String checksName = task.getChecksName() != null || pipelineTestDetails == null ? task.getChecksName() :
StringUtils.join(new ReverseListIterator(pipelineTestDetails.getEnclosingBlockNames()), " / ");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are the spaces around the slash conventional?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I took my inspiration from

return StringUtils.join(new ReverseListIterator(getEnclosingFlowNodeNames()), " / ") + " / " + rawName;

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right…this is a display name for rendering in an HTML GUI, though, whereas a check name is in a somewhat different category because it is used as a key in the REST API, requested in branch protection settings, etc.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've been using slashes in my own custom checks without issue; nothing seems to mind.

used as a key in the REST API

As in in Githubs REST API?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've been using slashes in my own custom checks without issue

Yes of course, I am just asking if there is a convention for using strings that look more like display names (Tests / Branch / Stage) or more like file paths or URIs (tests/branch/stage).

As in in Githubs REST API?

Yes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes.

I'm not sure I see where.

file paths or URIs (tests/branch/stage).

ahh, to look more like this?

image

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer display name. something like Tests / Unit

src/main/java/hudson/tasks/junit/JUnitResultArchiver.java Outdated Show resolved Hide resolved
@mrginglymus mrginglymus marked this pull request as ready for review November 18, 2020 12:49
@jglick jglick linked an issue Nov 18, 2020 that may be closed by this pull request
Copy link
Member

@jglick jglick left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good!

String checksName = task.getChecksName() != null || pipelineTestDetails == null ? task.getChecksName() :
StringUtils.join(new ReverseListIterator(pipelineTestDetails.getEnclosingBlockNames()), " / ");
// to be a ' / '-joined string of the enclosing blocks names. If all of that ends up being empty or null,
// set a default of 'Test'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// set a default of 'Test'
// set a default of 'Tests'

Comment on lines 61 to 64
@After
public void clearDetails() {
InterceptingChecksPublisherFactory.publisher.details.clear();
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assuming @Rule JenkinsRule (rather than @ClassRule), every test case gets its own Jenkins session, thus a new copy of every @TestExtension, so this would be unnecessary if you just make publisher an instance field rather than static. To find the current InterceptingChecksPublisherFactory instance, use ExtensionList.lookupSingleton.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh, thanks! I figured there must be something like that.

// If we haven't been provided with a checks name, and we have pipeline test details, set the checks name
// to be a ' / '-joined string of the enclosing blocks names. If all of that ends up being empty or null,
// set a default of 'Tests'
String checksName = task.getChecksName();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't we still include tests in the check ?

image

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, yes. For context I'm working mostly on python/js environments, where our stages are dedicated to test generation...

stage('JS Tests') {
    sh 'yarn test'
    junit 'js_tests.xml'
}

stage('Python Tests') {
    sh 'pytest tests/'
    junit 'python_tests.xml'
}

...as opposed to maven where tests are a bit more of a 'side effect' of the build

stage('Build') {
    sh 'mvn install'
    junit 'results.xml'
    archiveArticfcats(...)
    recordIssues(...)
    // etc...
}

So we'd end up with JS Tests / Tests etc. OTOH, I'm already setting a custom name (and will be using withChecks when it's ready) so I think meeting the 'mvn' use case possibly makes more sense?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I think so

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made the change locally,

+
+    private static final String DEFAULT_CHECKS_NAME = "Tests";

     /**
      * {@link FileSet} "includes" string, like "foo/bar/*.xml"
@@ -290,10 +294,12 @@ public class JUnitResultArchiver extends Recorder implements SimpleBuildStep, JU
                 // set a default of 'Tests'
                 String checksName = task.getChecksName();
                 if (checksName == null && pipelineTestDetails != null) {
-                    checksName = StringUtils.join(new ReverseListIterator(pipelineTestDetails.getEnclosingBlockNames()), " / ");
+                    List<String> checksComponents = new ArrayList<>(pipelineTestDetails.getEnclosingBlockNames());
+                    checksComponents.add(DEFAULT_CHECKS_NAME);
+                    checksName = StringUtils.join(new ReverseListIterator(checksComponents), " / ");
                 }
                 if (Util.fixEmpty(checksName) == null) {
-                    checksName = "Tests";
+                    checksName = DEFAULT_CHECKS_NAME;
                 }

Requires tests changes but that gives what I expected

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, will get that done

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ugh, sorry, you meant Tests at the beginning...

@mrginglymus mrginglymus force-pushed the use-enclosing-blocks-for-default-checks-name branch from a2e7710 to c227039 Compare December 3, 2020 10:12
@mrginglymus mrginglymus force-pushed the use-enclosing-blocks-for-default-checks-name branch from c227039 to db58881 Compare December 3, 2020 11:38
@timja timja merged commit 3c18200 into jenkinsci:master Dec 3, 2020
@mrginglymus mrginglymus deleted the use-enclosing-blocks-for-default-checks-name branch December 3, 2020 12:23
@timja
Copy link
Member

timja commented Dec 4, 2020

@mrginglymus

🎉 jenkinsci/bom#374

image

@timja
Copy link
Member

timja commented Dec 4, 2020

#221 May be related, I didn’t do any complex testing in my setup

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Remove/deprecate checksName parameter to junit step
3 participants