Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in / Register
Toggle navigation
S
spring-boot
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
DEMO
spring-boot
Commits
29bbbc3b
Commit
29bbbc3b
authored
Feb 24, 2021
by
Andy Wilkinson
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch '2.3.x' into 2.4.x
Closes gh-25406
parents
999c36b6
11b77037
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
109 additions
and
77 deletions
+109
-77
TestFailuresPlugin.java
...pringframework/boot/build/testing/TestFailuresPlugin.java
+12
-75
TestResultsOverview.java
...ringframework/boot/build/testing/TestResultsOverview.java
+95
-0
TestFailuresPluginIntegrationTests.java
...oot/build/testing/TestFailuresPluginIntegrationTests.java
+2
-2
No files found.
buildSrc/src/main/java/org/springframework/boot/build/testing/TestFailuresPlugin.java
View file @
29bbbc3b
/*
* Copyright 2012-202
0
the original author or authors.
* Copyright 2012-202
1
the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
...
...
@@ -17,14 +17,11 @@
package
org
.
springframework
.
boot
.
build
.
testing
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.TreeMap
;
import
org.gradle.BuildResult
;
import
org.gradle.api.Plugin
;
import
org.gradle.api.Project
;
import
org.gradle.api.provider.Provider
;
import
org.gradle.api.tasks.testing.Test
;
import
org.gradle.api.tasks.testing.TestDescriptor
;
import
org.gradle.api.tasks.testing.TestListener
;
...
...
@@ -39,46 +36,37 @@ public class TestFailuresPlugin implements Plugin<Project> {
@Override
public
void
apply
(
Project
project
)
{
TestResultsExtension
testResults
=
getOrCreateTestResults
(
project
);
Provider
<
TestResultsOverview
>
testResultsOverview
=
project
.
getGradle
().
getSharedServices
()
.
registerIfAbsent
(
"testResultsOverview"
,
TestResultsOverview
.
class
,
(
spec
)
->
{
});
project
.
getTasks
().
withType
(
Test
.
class
,
(
test
)
->
test
.
addTestListener
(
new
FailureRecordingTestListener
(
testResults
,
test
)));
}
private
TestResultsExtension
getOrCreateTestResults
(
Project
project
)
{
TestResultsExtension
testResults
=
project
.
getRootProject
().
getExtensions
()
.
findByType
(
TestResultsExtension
.
class
);
if
(
testResults
==
null
)
{
testResults
=
project
.
getRootProject
().
getExtensions
().
create
(
"testResults"
,
TestResultsExtension
.
class
);
project
.
getRootProject
().
getGradle
().
buildFinished
(
testResults:
:
buildFinished
);
}
return
testResults
;
(
test
)
->
test
.
addTestListener
(
new
FailureRecordingTestListener
(
testResultsOverview
,
test
)));
}
private
final
class
FailureRecordingTestListener
implements
TestListener
{
private
final
List
<
Test
Failure
>
failures
=
new
ArrayList
<>();
private
final
List
<
Test
Descriptor
>
failures
=
new
ArrayList
<>();
private
final
TestResultsExtension
testResults
;
private
final
Provider
<
TestResultsOverview
>
testResultsOverview
;
private
final
Test
test
;
private
FailureRecordingTestListener
(
TestResultsExtension
testResults
,
Test
test
)
{
this
.
testResults
=
testResults
;
private
FailureRecordingTestListener
(
Provider
<
TestResultsOverview
>
testResultOverview
,
Test
test
)
{
this
.
testResults
Overview
=
testResultOverview
;
this
.
test
=
test
;
}
@Override
public
void
afterSuite
(
TestDescriptor
descriptor
,
TestResult
result
)
{
if
(!
this
.
failures
.
isEmpty
())
{
Collections
.
sort
(
this
.
failures
);
this
.
testResults
.
addFailures
(
this
.
test
,
this
.
failures
);
this
.
testResultsOverview
.
get
().
addFailures
(
this
.
test
,
this
.
failures
);
}
}
@Override
public
void
afterTest
(
TestDescriptor
descriptor
,
TestResult
result
)
{
if
(
result
.
getFailedTestCount
()
>
0
)
{
this
.
failures
.
add
(
new
TestFailure
(
descriptor
)
);
this
.
failures
.
add
(
descriptor
);
}
}
...
...
@@ -94,55 +82,4 @@ public class TestFailuresPlugin implements Plugin<Project> {
}
private
static
final
class
TestFailure
implements
Comparable
<
TestFailure
>
{
private
final
TestDescriptor
descriptor
;
private
TestFailure
(
TestDescriptor
descriptor
)
{
this
.
descriptor
=
descriptor
;
}
@Override
public
int
compareTo
(
TestFailure
other
)
{
int
comparison
=
this
.
descriptor
.
getClassName
().
compareTo
(
other
.
descriptor
.
getClassName
());
if
(
comparison
==
0
)
{
comparison
=
this
.
descriptor
.
getName
().
compareTo
(
other
.
descriptor
.
getName
());
}
return
comparison
;
}
}
public
static
class
TestResultsExtension
{
private
final
Map
<
Test
,
List
<
TestFailure
>>
testFailures
=
new
TreeMap
<>(
(
one
,
two
)
->
one
.
getPath
().
compareTo
(
two
.
getPath
()));
private
final
Object
monitor
=
new
Object
();
void
addFailures
(
Test
test
,
List
<
TestFailure
>
testFailures
)
{
synchronized
(
this
.
monitor
)
{
this
.
testFailures
.
put
(
test
,
testFailures
);
}
}
public
void
buildFinished
(
BuildResult
result
)
{
synchronized
(
this
.
monitor
)
{
if
(
this
.
testFailures
.
isEmpty
())
{
return
;
}
System
.
err
.
println
();
System
.
err
.
println
(
"Found test failures in "
+
this
.
testFailures
.
size
()
+
" test task"
+
((
this
.
testFailures
.
size
()
==
1
)
?
":"
:
"s:"
));
this
.
testFailures
.
forEach
((
task
,
failures
)
->
{
System
.
err
.
println
();
System
.
err
.
println
(
task
.
getPath
());
failures
.
forEach
((
failure
)
->
System
.
err
.
println
(
" "
+
failure
.
descriptor
.
getClassName
()
+
" > "
+
failure
.
descriptor
.
getName
()));
});
}
}
}
}
buildSrc/src/main/java/org/springframework/boot/build/testing/TestResultsOverview.java
0 → 100644
View file @
29bbbc3b
/*
* Copyright 2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
org
.
springframework
.
boot
.
build
.
testing
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.TreeMap
;
import
java.util.stream.Collectors
;
import
org.gradle.api.services.BuildService
;
import
org.gradle.api.services.BuildServiceParameters
;
import
org.gradle.api.tasks.testing.Test
;
import
org.gradle.api.tasks.testing.TestDescriptor
;
import
org.gradle.tooling.events.FinishEvent
;
import
org.gradle.tooling.events.OperationCompletionListener
;
/**
* {@link BuildService} that provides an overview of all of the test failures in the
* build.
*
* @author Andy Wilkinson
*/
public
abstract
class
TestResultsOverview
implements
BuildService
<
BuildServiceParameters
.
None
>,
OperationCompletionListener
,
AutoCloseable
{
private
final
Map
<
Test
,
List
<
TestFailure
>>
testFailures
=
new
TreeMap
<>(
(
one
,
two
)
->
one
.
getPath
().
compareTo
(
two
.
getPath
()));
private
final
Object
monitor
=
new
Object
();
void
addFailures
(
Test
test
,
List
<
TestDescriptor
>
failureDescriptors
)
{
List
<
TestFailure
>
testFailures
=
failureDescriptors
.
stream
().
map
(
TestFailure:
:
new
).
sorted
()
.
collect
(
Collectors
.
toList
());
synchronized
(
this
.
monitor
)
{
this
.
testFailures
.
put
(
test
,
testFailures
);
}
}
@Override
public
void
onFinish
(
FinishEvent
event
)
{
// OperationCompletionListener is implemented to defer close until the build ends
}
@Override
public
void
close
()
{
synchronized
(
this
.
monitor
)
{
if
(
this
.
testFailures
.
isEmpty
())
{
return
;
}
System
.
err
.
println
();
System
.
err
.
println
(
"Found test failures in "
+
this
.
testFailures
.
size
()
+
" test task"
+
((
this
.
testFailures
.
size
()
==
1
)
?
":"
:
"s:"
));
this
.
testFailures
.
forEach
((
task
,
failures
)
->
{
System
.
err
.
println
();
System
.
err
.
println
(
task
.
getPath
());
failures
.
forEach
((
failure
)
->
System
.
err
.
println
(
" "
+
failure
.
descriptor
.
getClassName
()
+
" > "
+
failure
.
descriptor
.
getName
()));
});
}
}
private
static
final
class
TestFailure
implements
Comparable
<
TestFailure
>
{
private
final
TestDescriptor
descriptor
;
private
TestFailure
(
TestDescriptor
descriptor
)
{
this
.
descriptor
=
descriptor
;
}
@Override
public
int
compareTo
(
TestFailure
other
)
{
int
comparison
=
this
.
descriptor
.
getClassName
().
compareTo
(
other
.
descriptor
.
getClassName
());
if
(
comparison
==
0
)
{
comparison
=
this
.
descriptor
.
getName
().
compareTo
(
other
.
descriptor
.
getName
());
}
return
comparison
;
}
}
}
buildSrc/src/test/java/org/springframework/boot/build/testing/TestFailuresPluginIntegrationTests.java
View file @
29bbbc3b
/*
* Copyright 2012-202
0
the original author or authors.
* Copyright 2012-202
1
the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
...
...
@@ -84,7 +84,7 @@ class TestFailuresPluginIntegrationTests {
void
multiProjectParallel
()
throws
IOException
{
createMultiProjectBuild
();
BuildResult
result
=
GradleRunner
.
create
().
withDebug
(
true
).
withProjectDir
(
this
.
projectDir
)
.
withArguments
(
"build"
,
"--parallel"
).
withPluginClasspath
().
buildAndFail
();
.
withArguments
(
"build"
,
"--parallel"
,
"--stacktrace"
).
withPluginClasspath
().
buildAndFail
();
assertThat
(
readLines
(
result
.
getOutput
())).
containsSequence
(
"Found test failures in 2 test tasks:"
,
""
,
":project-one:test"
,
" example.ExampleTests > bad()"
,
" example.ExampleTests > fail()"
,
" example.MoreTests > bad()"
,
" example.MoreTests > fail()"
,
""
,
":project-two:test"
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment