15
15
16
16
package software .amazon .awssdk .benchmark ;
17
17
18
- import com .fasterxml .jackson .core .JsonProcessingException ;
18
+ import static software .amazon .awssdk .benchmark .utils .BenchmarkConstant .OBJECT_MAPPER ;
19
+
20
+ import java .io .IOException ;
21
+ import java .io .OutputStream ;
22
+ import java .nio .file .Files ;
23
+ import java .nio .file .Path ;
24
+ import java .nio .file .Paths ;
19
25
import java .util .ArrayList ;
20
26
import java .util .Arrays ;
21
27
import java .util .Collection ;
22
28
import java .util .List ;
29
+ import java .util .stream .Collectors ;
30
+ import org .apache .commons .cli .CommandLine ;
31
+ import org .apache .commons .cli .CommandLineParser ;
32
+ import org .apache .commons .cli .DefaultParser ;
33
+ import org .apache .commons .cli .Options ;
34
+ import org .apache .commons .cli .ParseException ;
23
35
import org .openjdk .jmh .results .RunResult ;
24
36
import org .openjdk .jmh .runner .Runner ;
25
37
import org .openjdk .jmh .runner .RunnerException ;
45
57
import software .amazon .awssdk .benchmark .enhanced .dynamodb .EnhancedClientQueryV1MapperComparisonBenchmark ;
46
58
import software .amazon .awssdk .benchmark .enhanced .dynamodb .EnhancedClientScanV1MapperComparisonBenchmark ;
47
59
import software .amazon .awssdk .benchmark .enhanced .dynamodb .EnhancedClientUpdateV1MapperComparisonBenchmark ;
60
+ import software .amazon .awssdk .benchmark .stats .SdkBenchmarkResult ;
61
+ import software .amazon .awssdk .benchmark .utils .BenchmarkProcessorOutput ;
48
62
import software .amazon .awssdk .utils .Logger ;
49
63
50
64
@@ -84,13 +98,15 @@ public class BenchmarkRunner {
84
98
85
99
private final List <String > benchmarksToRun ;
86
100
private final BenchmarkResultProcessor resultProcessor ;
101
+ private final BenchmarkRunnerOptions options ;
87
102
88
- private BenchmarkRunner (List <String > benchmarksToRun ) {
103
+ private BenchmarkRunner (List <String > benchmarksToRun , BenchmarkRunnerOptions options ) {
89
104
this .benchmarksToRun = benchmarksToRun ;
90
105
this .resultProcessor = new BenchmarkResultProcessor ();
106
+ this .options = options ;
91
107
}
92
108
93
- public static void main (String ... args ) throws RunnerException , JsonProcessingException {
109
+ public static void main (String ... args ) throws Exception {
94
110
List <String > benchmarksToRun = new ArrayList <>();
95
111
benchmarksToRun .addAll (SYNC_BENCHMARKS );
96
112
benchmarksToRun .addAll (ASYNC_BENCHMARKS );
@@ -99,13 +115,14 @@ public static void main(String... args) throws RunnerException, JsonProcessingEx
99
115
100
116
log .info (() -> "Skipping tests, to reduce benchmark times: \n " + MAPPER_BENCHMARKS + "\n " + METRIC_BENCHMARKS );
101
117
102
-
103
- BenchmarkRunner runner = new BenchmarkRunner (benchmarksToRun );
118
+ BenchmarkRunner runner = new BenchmarkRunner (benchmarksToRun , parseOptions (args ));
104
119
105
120
runner .runBenchmark ();
106
121
}
107
122
108
123
private void runBenchmark () throws RunnerException {
124
+ log .info (() -> "Running with options: " + options );
125
+
109
126
ChainedOptionsBuilder optionsBuilder = new OptionsBuilder ();
110
127
111
128
benchmarksToRun .forEach (optionsBuilder ::include );
@@ -114,11 +131,70 @@ private void runBenchmark() throws RunnerException {
114
131
115
132
Collection <RunResult > results = new Runner (optionsBuilder .build ()).run ();
116
133
117
- List <String > failedResult = resultProcessor .processBenchmarkResult (results );
134
+ BenchmarkProcessorOutput processedResults = resultProcessor .processBenchmarkResult (results );
135
+ List <String > failedResults = processedResults .getFailedBenchmarks ();
136
+
137
+ if (options .outputPath != null ) {
138
+ log .info (() -> "Writing results to " + options .outputPath );
139
+ writeResults (processedResults , options .outputPath );
140
+ }
141
+
142
+ if (options .check && !failedResults .isEmpty ()) {
143
+ log .info (() -> "Failed perf regression tests: " + failedResults );
144
+ throw new RuntimeException ("Perf regression tests failed: " + failedResults );
145
+ }
146
+ }
147
+
148
+ private static BenchmarkRunnerOptions parseOptions (String [] args ) throws ParseException {
149
+ Options cliOptions = new Options ();
150
+ cliOptions .addOption ("o" , "output" , true ,
151
+ "The path to write the benchmark results to." );
152
+ cliOptions .addOption ("c" , "check" , false ,
153
+ "If specified, exit with error code 1 if the results are not within the baseline." );
154
+
155
+ CommandLineParser parser = new DefaultParser ();
156
+ CommandLine cmdLine = parser .parse (cliOptions , args );
157
+
158
+ BenchmarkRunnerOptions options = new BenchmarkRunnerOptions ()
159
+ .check (cmdLine .hasOption ("c" ));
160
+
161
+ if (cmdLine .hasOption ("o" )) {
162
+ options .outputPath (Paths .get (cmdLine .getOptionValue ("o" )));
163
+ }
164
+
165
+ return options ;
166
+ }
167
+
168
+ private static void writeResults (BenchmarkProcessorOutput output , Path outputPath ) {
169
+ List <SdkBenchmarkResult > results = output .getBenchmarkResults ().values ().stream ().collect (Collectors .toList ());
170
+ try (OutputStream os = Files .newOutputStream (outputPath )) {
171
+ OBJECT_MAPPER .writeValue (os , results );
172
+ } catch (IOException e ) {
173
+ log .error (() -> "Failed to write the results to " + outputPath , e );
174
+ throw new RuntimeException (e );
175
+ }
176
+ }
177
+
178
+ private static class BenchmarkRunnerOptions {
179
+ private Path outputPath ;
180
+ private boolean check ;
181
+
182
+ public BenchmarkRunnerOptions outputPath (Path outputPath ) {
183
+ this .outputPath = outputPath ;
184
+ return this ;
185
+ }
186
+
187
+ public BenchmarkRunnerOptions check (boolean check ) {
188
+ this .check = check ;
189
+ return this ;
190
+ }
118
191
119
- if (!failedResult .isEmpty ()) {
120
- log .info (() -> "Failed perf regression tests: " + failedResult );
121
- throw new RuntimeException ("Perf regression tests failed: " + failedResult );
192
+ @ Override
193
+ public String toString () {
194
+ return "BenchmarkRunnerOptions{" +
195
+ "outputPath=" + outputPath +
196
+ ", check=" + check +
197
+ '}' ;
122
198
}
123
199
}
124
200
}
0 commit comments