@@ -29,6 +29,7 @@ import (
29
29
"os"
30
30
"path"
31
31
"regexp"
32
+ "slices"
32
33
"strings"
33
34
"sync"
34
35
"testing"
@@ -207,9 +208,9 @@ var (
207
208
}
208
209
)
209
210
210
- var UseTestingLog * bool
211
- var PerfSchedulingLabelFilter * string
212
- var TestSchedulingLabelFilter * string
211
+ var UseTestingLog bool
212
+ var PerfSchedulingLabelFilter string
213
+ var TestSchedulingLabelFilter string
213
214
214
215
// InitTests should be called in a TestMain in each config subdirectory.
215
216
func InitTests () error {
@@ -235,9 +236,9 @@ func InitTests() error {
235
236
"A set of key=value pairs that describe feature gates for alpha/experimental features. " +
236
237
"Options are:\n " + strings .Join (LoggingFeatureGate .KnownFeatures (), "\n " ))
237
238
238
- UseTestingLog = flag .Bool ( "use-testing-log" , false , "Write log entries with testing.TB.Log. This is more suitable for unit testing and debugging, but less realistic in real benchmarks." )
239
- PerfSchedulingLabelFilter = flag .String ( "perf-scheduling-label-filter" , "performance" , "comma-separated list of labels which a testcase must have (no prefix or +) or must not have (-), used by BenchmarkPerfScheduling" )
240
- TestSchedulingLabelFilter = flag .String ( "test-scheduling-label-filter" , "integration-test,-performance" , "comma-separated list of labels which a testcase must have (no prefix or +) or must not have (-), used by TestScheduling" )
239
+ flag .BoolVar ( & UseTestingLog , "use-testing-log" , false , "Write log entries with testing.TB.Log. This is more suitable for unit testing and debugging, but less realistic in real benchmarks." )
240
+ flag .StringVar ( & PerfSchedulingLabelFilter , "perf-scheduling-label-filter" , "performance" , "comma-separated list of labels which a testcase must have (no prefix or +) or must not have (-), used by BenchmarkPerfScheduling" )
241
+ flag .StringVar ( & TestSchedulingLabelFilter , "test-scheduling-label-filter" , "integration-test,-performance" , "comma-separated list of labels which a testcase must have (no prefix or +) or must not have (-), used by TestScheduling" )
241
242
242
243
// This would fail if we hadn't removed the logging flags above.
243
244
logsapi .AddGoFlags (LoggingConfig , flag .CommandLine )
@@ -988,7 +989,7 @@ func (scm stopCollectingMetricsOp) patchParams(_ *workload) (realOp, error) {
988
989
989
990
func initTestOutput (tb testing.TB ) io.Writer {
990
991
var output io.Writer
991
- if * UseTestingLog {
992
+ if UseTestingLog {
992
993
output = framework .NewTBWriter (tb )
993
994
} else {
994
995
tmpDir := tb .TempDir ()
@@ -1020,9 +1021,9 @@ func initTestOutput(tb testing.TB) io.Writer {
1020
1021
var specialFilenameChars = regexp .MustCompile (`[^a-zA-Z0-9-_]` )
1021
1022
1022
1023
func setupTestCase (t testing.TB , tc * testCase , featureGates map [featuregate.Feature ]bool , output io.Writer , outOfTreePluginRegistry frameworkruntime.Registry ) (informers.SharedInformerFactory , ktesting.TContext ) {
1023
- tCtx := ktesting .Init (t , initoption .PerTestOutput (* UseTestingLog ))
1024
+ tCtx := ktesting .Init (t , initoption .PerTestOutput (UseTestingLog ))
1024
1025
artifacts , doArtifacts := os .LookupEnv ("ARTIFACTS" )
1025
- if ! * UseTestingLog && doArtifacts {
1026
+ if ! UseTestingLog && doArtifacts {
1026
1027
// Reconfigure logging so that it goes to a separate file per
1027
1028
// test instead of stderr. If the test passes, the file gets
1028
1029
// deleted. The overall output can be very large (> 200 MB for
@@ -1115,6 +1116,32 @@ func featureGatesMerge(src map[featuregate.Feature]bool, overrides map[featurega
1115
1116
return result
1116
1117
}
1117
1118
1119
+ // fixJSONOutput works around Go not emitting a "pass" action for
1120
+ // sub-benchmarks
1121
+ // (https://github.com/golang/go/issues/66825#issuecomment-2343229005), which
1122
+ // causes gotestsum to report a successful benchmark run as failed
1123
+ // (https://github.com/gotestyourself/gotestsum/issues/413#issuecomment-2343206787).
1124
+ //
1125
+ // It does this by printing the missing "PASS" output line that test2json
1126
+ // then converts into the "pass" action.
1127
+ func fixJSONOutput (b * testing.B ) {
1128
+ if ! slices .Contains (os .Args , "-test.v=test2json" ) {
1129
+ // Not printing JSON.
1130
+ return
1131
+ }
1132
+
1133
+ start := time .Now ()
1134
+ b .Cleanup (func () {
1135
+ if b .Failed () {
1136
+ // Really has failed, do nothing.
1137
+ return
1138
+ }
1139
+ // SYN gets injected when using -test.v=test2json, see
1140
+ // https://cs.opensource.google/go/go/+/refs/tags/go1.23.3:src/testing/testing.go;drc=87ec2c959c73e62bfae230ef7efca11ec2a90804;l=527
1141
+ fmt .Fprintf (os .Stderr , "%c--- PASS: %s (%.2fs)\n " , 22 /* SYN */ , b .Name (), time .Since (start ).Seconds ())
1142
+ })
1143
+ }
1144
+
1118
1145
// RunBenchmarkPerfScheduling runs the scheduler performance benchmark tests.
1119
1146
//
1120
1147
// You can pass your own scheduler plugins via outOfTreePluginRegistry.
@@ -1128,11 +1155,12 @@ func RunBenchmarkPerfScheduling(b *testing.B, configFile string, topicName strin
1128
1155
if err = validateTestCases (testCases ); err != nil {
1129
1156
b .Fatal (err )
1130
1157
}
1158
+ fixJSONOutput (b )
1131
1159
1132
1160
if testing .Short () {
1133
- * PerfSchedulingLabelFilter += ",+short"
1161
+ PerfSchedulingLabelFilter += ",+short"
1134
1162
}
1135
- testcaseLabelSelectors := strings .Split (* PerfSchedulingLabelFilter , "," )
1163
+ testcaseLabelSelectors := strings .Split (PerfSchedulingLabelFilter , "," )
1136
1164
1137
1165
output := initTestOutput (b )
1138
1166
@@ -1147,11 +1175,13 @@ func RunBenchmarkPerfScheduling(b *testing.B, configFile string, topicName strin
1147
1175
dataItems := DataItems {Version : "v1" }
1148
1176
for _ , tc := range testCases {
1149
1177
b .Run (tc .Name , func (b * testing.B ) {
1178
+ fixJSONOutput (b )
1150
1179
for _ , w := range tc .Workloads {
1151
1180
b .Run (w .Name , func (b * testing.B ) {
1152
1181
if ! enabled (testcaseLabelSelectors , append (tc .Labels , w .Labels ... )... ) {
1153
- b .Skipf ("disabled by label filter %v " , PerfSchedulingLabelFilter )
1182
+ b .Skipf ("disabled by label filter %q " , PerfSchedulingLabelFilter )
1154
1183
}
1184
+ fixJSONOutput (b )
1155
1185
1156
1186
featureGates := featureGatesMerge (tc .FeatureGates , w .FeatureGates )
1157
1187
informerFactory , tCtx := setupTestCase (b , tc , featureGates , output , outOfTreePluginRegistry )
@@ -1244,16 +1274,16 @@ func RunIntegrationPerfScheduling(t *testing.T, configFile string) {
1244
1274
}
1245
1275
1246
1276
if testing .Short () {
1247
- * TestSchedulingLabelFilter += ",+short"
1277
+ TestSchedulingLabelFilter += ",+short"
1248
1278
}
1249
- testcaseLabelSelectors := strings .Split (* TestSchedulingLabelFilter , "," )
1279
+ testcaseLabelSelectors := strings .Split (TestSchedulingLabelFilter , "," )
1250
1280
1251
1281
for _ , tc := range testCases {
1252
1282
t .Run (tc .Name , func (t * testing.T ) {
1253
1283
for _ , w := range tc .Workloads {
1254
1284
t .Run (w .Name , func (t * testing.T ) {
1255
1285
if ! enabled (testcaseLabelSelectors , append (tc .Labels , w .Labels ... )... ) {
1256
- t .Skipf ("disabled by label filter %q" , * TestSchedulingLabelFilter )
1286
+ t .Skipf ("disabled by label filter %q" , TestSchedulingLabelFilter )
1257
1287
}
1258
1288
featureGates := featureGatesMerge (tc .FeatureGates , w .FeatureGates )
1259
1289
informerFactory , tCtx := setupTestCase (t , tc , featureGates , nil , nil )
0 commit comments