@@ -51,4 +51,88 @@ public void shouldReturnNullWhenDisplayNameHasNoBuildNumber() {
5151
5252 assertThat (runIdentity == null , is (true ));
5353 }
54+
55+ @ Test
56+ public void shouldReturnNullWhenDisplayNameIsNull () {
57+ assertThat (AnkaCloudComputer .parseRunIdentityFromDisplayName (null ) == null , is (true ));
58+ }
59+
60+ @ Test
61+ public void shouldReturnNullWhenDisplayNameIsEmpty () {
62+ assertThat (AnkaCloudComputer .parseRunIdentityFromDisplayName ("" ) == null , is (true ));
63+ }
64+
65+ @ Test
66+ public void shouldReturnNullWhenBuildNumberIsNotNumeric () {
67+ assertThat (AnkaCloudComputer .parseRunIdentityFromDisplayName ("folder/job-name #abc" ) == null , is (true ));
68+ }
69+
70+ @ Test
71+ public void shouldReturnNullWhenBuildNumberIsZero () {
72+ assertThat (AnkaCloudComputer .parseRunIdentityFromDisplayName ("folder/job-name #0" ) == null , is (true ));
73+ }
74+
75+ @ Test
76+ public void shouldReturnNullWhenBuildNumberIsNegative () {
77+ assertThat (AnkaCloudComputer .parseRunIdentityFromDisplayName ("folder/job-name #-1" ) == null , is (true ));
78+ }
79+
80+ @ Test
81+ public void shouldReturnNullWhenNoSpaceBeforeHash () {
82+ // "name#42" lacks the Jenkins-standard " #" separator and must be rejected so
83+ // we do not misattribute outcomes to a spurious job name. This directly protects
84+ // the run-once cleanup from picking the wrong build.
85+ assertThat (AnkaCloudComputer .parseRunIdentityFromDisplayName ("name#42" ) == null , is (true ));
86+ }
87+
88+ @ Test
89+ public void shouldReturnNullWhenJobNameIsBlank () {
90+ assertThat (AnkaCloudComputer .parseRunIdentityFromDisplayName (" #42" ) == null , is (true ));
91+ }
92+
93+ @ Test
94+ public void shouldParseIdentityWhenJobNameContainsNestedFolders () {
95+ AnkaCloudComputer .RunIdentity runIdentity =
96+ AnkaCloudComputer .parseRunIdentityFromDisplayName ("top-folder/mid-folder/leaf-job #7" );
97+
98+ assertThat (runIdentity .getJobFullName (), is ("top-folder/mid-folder/leaf-job" ));
99+ assertThat (runIdentity .getBuildNumber (), is (7 ));
100+ }
101+
102+ @ Test
103+ public void shouldParseIdentityAndTrimTrailingWhitespace () {
104+ AnkaCloudComputer .RunIdentity runIdentity =
105+ AnkaCloudComputer .parseRunIdentityFromDisplayName ("job-name #42 " );
106+
107+ assertThat (runIdentity .getJobFullName (), is ("job-name" ));
108+ assertThat (runIdentity .getBuildNumber (), is (42 ));
109+ }
110+
111+ @ Test
112+ public void shouldParseIdentityUsingLastHashSeparator () {
113+ // Job names can legally contain '#', so we anchor on the last " #" to locate
114+ // the build number segment.
115+ AnkaCloudComputer .RunIdentity runIdentity =
116+ AnkaCloudComputer .parseRunIdentityFromDisplayName ("weird #name #99" );
117+
118+ assertThat (runIdentity .getJobFullName (), is ("weird #name" ));
119+ assertThat (runIdentity .getBuildNumber (), is (99 ));
120+ }
121+
122+ @ Test
123+ public void shouldResolveAbortedResultToFailureOutcome () {
124+ assertThat (AnkaCloudComputer .resolveBuildOutcome (Result .ABORTED ), is (AnkaCloudComputer .BuildOutcome .FAILURE ));
125+ }
126+
127+ @ Test
128+ public void shouldResolveNotBuiltResultToFailureOutcome () {
129+ assertThat (AnkaCloudComputer .resolveBuildOutcome (Result .NOT_BUILT ), is (AnkaCloudComputer .BuildOutcome .FAILURE ));
130+ }
131+
132+ @ Test
133+ public void shouldNotMarkUnknownOutcomeAsKeepAliveError () {
134+ // UNKNOWN outcomes must not flip hadErrorsOnBuild, otherwise keepAliveOnError
135+ // could hold a run-once agent alive and let a pending task pick it up.
136+ assertThat (AnkaCloudComputer .shouldMarkBuildAsErrorForKeepAlive (AnkaCloudComputer .BuildOutcome .UNKNOWN ), is (false ));
137+ }
54138}
0 commit comments