@@ -23,52 +23,29 @@ import (
23
23
"time"
24
24
25
25
"github.com/google/go-cmp/cmp"
26
+ "github.com/google/go-cmp/cmp/cmpopts"
26
27
commonv1beta1 "github.com/kubeflow/katib/pkg/apis/controller/common/v1beta1"
27
28
v1beta1 "github.com/kubeflow/katib/pkg/apis/manager/v1beta1"
28
29
"github.com/kubeflow/katib/pkg/controller.v1beta1/consts"
29
30
)
30
31
31
- const (
32
- validJSONTestFile = "good.json"
33
- invalidFormatJSONTestFile = "invalid-format.json"
34
- invalidTimestampJSONTestFile = "invalid-timestamp.json"
35
- missingMetricJSONTestFile = "missing-objective-metric.json"
36
-
37
- validTEXTTestFile = "good.log"
38
- invalidValueTEXTTestFile = "invalid-value.log"
39
- invalidFormatTEXTTestFile = "invalid-format.log"
40
- invalidTimestampTEXTTestFile = "invalid-timestamp.log"
41
- missingMetricTEXTTestFile = "missing-objective-metric.log"
42
- )
43
-
44
- var (
45
- testDir = "testdata"
46
- testJsonDataPath = filepath .Join (testDir , "JSON" )
47
- testTextDataPath = filepath .Join (testDir , "TEXT" )
48
- )
49
-
50
32
func TestCollectObservationLog (t * testing.T ) {
51
- if err := generateTestDirs (); err != nil {
52
- t .Fatal (err )
53
- }
54
- if err := generateJSONTestFiles (); err != nil {
55
- t .Fatal (err )
56
- }
57
- if err := generateTEXTTestFiles (); err != nil {
58
- t .Fatal (err )
59
- }
60
- defer os .RemoveAll (testDir )
61
-
62
33
testCases := map [string ]struct {
63
- filePath string
34
+ fileName string
35
+ testData string
64
36
metrics []string
65
37
filters []string
66
38
fileFormat commonv1beta1.FileFormat
67
- err bool
39
+ wantError error
68
40
expected * v1beta1.ObservationLog
69
41
}{
70
42
"Positive case for logs in JSON format" : {
71
- filePath : filepath .Join (testJsonDataPath , validJSONTestFile ),
43
+ fileName : "good.json" ,
44
+ testData : `{"checkpoint_path": "", "global_step": "0", "loss": "0.22082142531871796", "timestamp": 1638422847.28721, "trial": "0"}
45
+ {"acc": "0.9349666833877563", "checkpoint_path": "", "global_step": "0", "timestamp": 1638422847.287801, "trial": "0"}
46
+ {"checkpoint_path": "", "global_step": "1", "loss": "0.1414974331855774", "timestamp": "2021-12-02T14:27:50.000035161Z", "trial": "0"}
47
+ {"acc": "0.9586416482925415", "checkpoint_path": "", "global_step": "1", "timestamp": "2021-12-02T14:27:50.000037459Z", "trial": "0"}
48
+ {"checkpoint_path": "", "global_step": "2", "loss": "0.10683439671993256", "trial": "0"}` ,
72
49
metrics : []string {"acc" , "loss" },
73
50
fileFormat : commonv1beta1 .JsonFormat ,
74
51
expected : & v1beta1.ObservationLog {
@@ -112,7 +89,14 @@ func TestCollectObservationLog(t *testing.T) {
112
89
},
113
90
},
114
91
"Positive case for logs in TEXT format" : {
115
- filePath : filepath .Join (testTextDataPath , validTEXTTestFile ),
92
+ fileName : "good.log" ,
93
+ testData : `2024-03-04T17:55:08Z INFO {metricName: accuracy, metricValue: 0.8078};{metricName: loss, metricValue: 0.5183}
94
+ 2024-03-04T17:55:08Z INFO {metricName: accuracy, metricValue: 0.6752}
95
+ 2024-03-04T17:55:08Z INFO {metricName: loss, metricValue: 0.3634}
96
+ 2024-03-04T17:55:08Z INFO {metricName: accuracy, metricValue: 100}
97
+ 2024-03-04T17:55:08Z INFO {metricName: accuracy, metricValue: 888.333}
98
+ 2024-03-04T17:55:08Z INFO {metricName: accuracy, metricValue: -0.4759}
99
+ {metricName: loss, metricValue: 0.8671}` ,
116
100
metrics : []string {"accuracy" , "loss" },
117
101
filters : []string {"{metricName: ([\\ w|-]+), metricValue: ((-?\\ d+)(\\ .\\ d+)?)}" },
118
102
fileFormat : commonv1beta1 .TextFormat ,
@@ -178,7 +162,11 @@ func TestCollectObservationLog(t *testing.T) {
178
162
},
179
163
},
180
164
"Invalid case for logs in TEXT format" : {
181
- filePath : filepath .Join (testTextDataPath , invalidValueTEXTTestFile ),
165
+ fileName : "invalid-value.log" ,
166
+ testData : `2024-03-04T17:55:08Z INFO {metricName: accuracy, metricValue: .333}
167
+ 2024-03-04T17:55:08Z INFO {metricName: accuracy, metricValue: -.333}
168
+ 2024-03-04T17:55:08Z INFO {metricName: accuracy, metricValue: - 345.333}
169
+ 2024-03-04T17:55:08Z INFO {metricName: accuracy, metricValue: 888.}` ,
182
170
filters : []string {"{metricName: ([\\ w|-]+), metricValue: ((-?\\ d+)(\\ .\\ d+)?)}" },
183
171
metrics : []string {"accuracy" , "loss" },
184
172
fileFormat : commonv1beta1 .TextFormat ,
@@ -195,21 +183,26 @@ func TestCollectObservationLog(t *testing.T) {
195
183
},
196
184
},
197
185
"Invalid file name" : {
198
- filePath : "invalid" ,
199
- err : true ,
186
+ fileName : "invalid" ,
187
+ fileFormat : commonv1beta1 .JsonFormat ,
188
+ wantError : errOpenFile ,
200
189
},
201
190
"Invalid file format" : {
202
- filePath : filepath . Join ( testTextDataPath , validTEXTTestFile ) ,
191
+ fileName : "good.log" ,
203
192
fileFormat : "invalid" ,
204
- err : true ,
193
+ wantError : errFileFormat ,
205
194
},
206
195
"Invalid formatted file for logs in JSON format" : {
207
- filePath : filepath .Join (testJsonDataPath , invalidFormatJSONTestFile ),
196
+ fileName : "invalid-format.json" ,
197
+ testData : `"checkpoint_path": "", "global_step": "0", "loss": "0.22082142531871796", "timestamp": 1638422847.28721, "trial": "0"
198
+ {"acc": "0.9349666833877563", "checkpoint_path": "", "global_step": "0", "timestamp": 1638422847.287801, "trial": "0` ,
208
199
fileFormat : commonv1beta1 .JsonFormat ,
209
- err : true ,
200
+ wantError : errParseJson ,
210
201
},
211
202
"Invalid formatted file for logs in TEXT format" : {
212
- filePath : filepath .Join (testTextDataPath , invalidFormatTEXTTestFile ),
203
+ fileName : "invalid-format.log" ,
204
+ testData : `2024-03-04T17:55:08Z INFO {metricName: accuracy, metricValue: 0.6752
205
+ 2024-03-04T17:55:08Z INFO {metricName: loss, metricValue: 0.3634}` ,
213
206
filters : []string {"{metricName: ([\\ w|-]+), metricValue: ((-?\\ d+)(\\ .\\ d+)?)}" },
214
207
metrics : []string {"accuracy" , "loss" },
215
208
fileFormat : commonv1beta1 .TextFormat ,
@@ -226,7 +219,9 @@ func TestCollectObservationLog(t *testing.T) {
226
219
},
227
220
},
228
221
"Invalid timestamp for logs in JSON format" : {
229
- filePath : filepath .Join (testJsonDataPath , invalidTimestampJSONTestFile ),
222
+ fileName : "invalid-timestamp.json" ,
223
+ testData : `{"checkpoint_path": "", "global_step": "0", "loss": "0.22082142531871796", "timestamp": "invalid", "trial": "0"}
224
+ {"acc": "0.9349666833877563", "checkpoint_path": "", "global_step": "0", "timestamp": 1638422847, "trial": "0"}` ,
230
225
fileFormat : commonv1beta1 .JsonFormat ,
231
226
metrics : []string {"acc" , "loss" },
232
227
expected : & v1beta1.ObservationLog {
@@ -249,7 +244,9 @@ func TestCollectObservationLog(t *testing.T) {
249
244
},
250
245
},
251
246
"Invalid timestamp for logs in TEXT format" : {
252
- filePath : filepath .Join (testTextDataPath , invalidTimestampTEXTTestFile ),
247
+ fileName : "invalid-timestamp.log" ,
248
+ testData : `2024-03-04T17:55:08Z INFO {metricName: accuracy, metricValue: 0.6752}
249
+ invalid INFO {metricName: loss, metricValue: 0.3634}` ,
253
250
metrics : []string {"accuracy" , "loss" },
254
251
filters : []string {"{metricName: ([\\ w|-]+), metricValue: ((-?\\ d+)(\\ .\\ d+)?)}" },
255
252
fileFormat : commonv1beta1 .TextFormat ,
@@ -273,7 +270,10 @@ func TestCollectObservationLog(t *testing.T) {
273
270
},
274
271
},
275
272
"Missing objective metric in JSON training logs" : {
276
- filePath : filepath .Join (testJsonDataPath , missingMetricJSONTestFile ),
273
+ fileName : "missing-objective-metric.json" ,
274
+ testData : `{"checkpoint_path": "", "global_step": "0", "loss": "0.22082142531871796", "timestamp": 1638422847.28721, "trial": "0"}
275
+ {"checkpoint_path": "", "global_step": "1", "loss": "0.1414974331855774", "timestamp": "2021-12-02T14:27:50.000035161+09:00", "trial": "0"}
276
+ {"checkpoint_path": "", "global_step": "2", "loss": "0.10683439671993256", "trial": "0"}` ,
277
277
fileFormat : commonv1beta1 .JsonFormat ,
278
278
metrics : []string {"acc" , "loss" },
279
279
expected : & v1beta1.ObservationLog {
@@ -289,7 +289,9 @@ func TestCollectObservationLog(t *testing.T) {
289
289
},
290
290
},
291
291
"Missing objective metric in TEXT training logs" : {
292
- filePath : filepath .Join (testTextDataPath , missingMetricTEXTTestFile ),
292
+ fileName : "missing-objective-metric.log" ,
293
+ testData : `2024-03-04T17:55:08Z INFO {metricName: loss, metricValue: 0.3634}
294
+ 2024-03-04T17:55:08Z INFO {metricName: loss, metricValue: 0.8671}` ,
293
295
fileFormat : commonv1beta1 .TextFormat ,
294
296
metrics : []string {"accuracy" , "loss" },
295
297
expected : & v1beta1.ObservationLog {
@@ -306,126 +308,21 @@ func TestCollectObservationLog(t *testing.T) {
306
308
},
307
309
}
308
310
311
+ tmpDir := t .TempDir ()
309
312
for name , test := range testCases {
310
313
t .Run (name , func (t * testing.T ) {
311
- actual , err := CollectObservationLog (test .filePath , test .metrics , test .filters , test .fileFormat )
312
- if (err != nil ) != test .err {
313
- t .Errorf ("\n GOT: \n %v\n WANT: %v\n " , err , test .err )
314
- } else {
315
- if diff := cmp .Diff (test .expected , actual ); diff != "" {
316
- t .Errorf ("Unexpected parsed result (-want,+got):\n %s" , diff )
314
+ if test .testData != "" {
315
+ if err := os .WriteFile (filepath .Join (tmpDir , test .fileName ), []byte (test .testData ), 0600 ); err != nil {
316
+ t .Fatalf ("failed to write test data: %v" , err )
317
317
}
318
318
}
319
+ actual , err := CollectObservationLog (filepath .Join (tmpDir , test .fileName ), test .metrics , test .filters , test .fileFormat )
320
+ if diff := cmp .Diff (test .wantError , err , cmpopts .EquateErrors ()); len (diff ) != 0 {
321
+ t .Errorf ("Unexpected error (-want,+got):\n %s" , diff )
322
+ }
323
+ if diff := cmp .Diff (test .expected , actual ); len (diff ) != 0 {
324
+ t .Errorf ("Unexpected parsed result (-want,+got):\n %s" , diff )
325
+ }
319
326
})
320
327
}
321
328
}
322
-
323
- func generateTestDirs () error {
324
- // Generate JSON files' dir
325
- if _ , err := os .Stat (testJsonDataPath ); err != nil {
326
- if err = os .MkdirAll (testJsonDataPath , 0700 ); err != nil {
327
- return err
328
- }
329
- }
330
-
331
- // Generate TEXT files' dir
332
- if _ , err := os .Stat (testTextDataPath ); err != nil {
333
- if err = os .MkdirAll (testTextDataPath , 0700 ); err != nil {
334
- return err
335
- }
336
- }
337
-
338
- return nil
339
- }
340
-
341
- func generateJSONTestFiles () error {
342
- testData := []struct {
343
- fileName string
344
- data string
345
- }{
346
- {
347
- fileName : validJSONTestFile ,
348
- data : `{"checkpoint_path": "", "global_step": "0", "loss": "0.22082142531871796", "timestamp": 1638422847.28721, "trial": "0"}
349
- {"acc": "0.9349666833877563", "checkpoint_path": "", "global_step": "0", "timestamp": 1638422847.287801, "trial": "0"}
350
- {"checkpoint_path": "", "global_step": "1", "loss": "0.1414974331855774", "timestamp": "2021-12-02T14:27:50.000035161Z", "trial": "0"}
351
- {"acc": "0.9586416482925415", "checkpoint_path": "", "global_step": "1", "timestamp": "2021-12-02T14:27:50.000037459Z", "trial": "0"}
352
- {"checkpoint_path": "", "global_step": "2", "loss": "0.10683439671993256", "trial": "0"}
353
- ` ,
354
- },
355
- {
356
- fileName : invalidFormatJSONTestFile ,
357
- data : `"checkpoint_path": "", "global_step": "0", "loss": "0.22082142531871796", "timestamp": 1638422847.28721, "trial": "0"
358
- {"acc": "0.9349666833877563", "checkpoint_path": "", "global_step": "0", "timestamp": 1638422847.287801, "trial": "0
359
- ` ,
360
- },
361
- {
362
- fileName : invalidTimestampJSONTestFile ,
363
- data : `{"checkpoint_path": "", "global_step": "0", "loss": "0.22082142531871796", "timestamp": "invalid", "trial": "0"}
364
- {"acc": "0.9349666833877563", "checkpoint_path": "", "global_step": "0", "timestamp": 1638422847, "trial": "0"}
365
- ` ,
366
- }, {
367
- fileName : missingMetricJSONTestFile ,
368
- data : `{"checkpoint_path": "", "global_step": "0", "loss": "0.22082142531871796", "timestamp": 1638422847.28721, "trial": "0"}
369
- {"checkpoint_path": "", "global_step": "1", "loss": "0.1414974331855774", "timestamp": "2021-12-02T14:27:50.000035161+09:00", "trial": "0"}
370
- {"checkpoint_path": "", "global_step": "2", "loss": "0.10683439671993256", "trial": "0"}` ,
371
- },
372
- }
373
-
374
- for _ , td := range testData {
375
- filePath := filepath .Join (testJsonDataPath , td .fileName )
376
- if err := os .WriteFile (filePath , []byte (td .data ), 0600 ); err != nil {
377
- return err
378
- }
379
- }
380
-
381
- return nil
382
- }
383
-
384
- func generateTEXTTestFiles () error {
385
- testData := []struct {
386
- fileName string
387
- data string
388
- }{
389
- {
390
- fileName : validTEXTTestFile ,
391
- data : `2024-03-04T17:55:08Z INFO {metricName: accuracy, metricValue: 0.8078};{metricName: loss, metricValue: 0.5183}
392
- 2024-03-04T17:55:08Z INFO {metricName: accuracy, metricValue: 0.6752}
393
- 2024-03-04T17:55:08Z INFO {metricName: loss, metricValue: 0.3634}
394
- 2024-03-04T17:55:08Z INFO {metricName: accuracy, metricValue: 100}
395
- 2024-03-04T17:55:08Z INFO {metricName: accuracy, metricValue: 888.333}
396
- 2024-03-04T17:55:08Z INFO {metricName: accuracy, metricValue: -0.4759}
397
- {metricName: loss, metricValue: 0.8671}` ,
398
- },
399
- {
400
- fileName : invalidValueTEXTTestFile ,
401
- data : `2024-03-04T17:55:08Z INFO {metricName: accuracy, metricValue: .333}
402
- 2024-03-04T17:55:08Z INFO {metricName: accuracy, metricValue: -.333}
403
- 2024-03-04T17:55:08Z INFO {metricName: accuracy, metricValue: - 345.333}
404
- 2024-03-04T17:55:08Z INFO {metricName: accuracy, metricValue: 888.}` ,
405
- },
406
- {
407
- fileName : invalidFormatTEXTTestFile ,
408
- data : `2024-03-04T17:55:08Z INFO {metricName: accuracy, metricValue: 0.6752
409
- 2024-03-04T17:55:08Z INFO {metricName: loss, metricValue: 0.3634}` ,
410
- },
411
- {
412
- fileName : invalidTimestampTEXTTestFile ,
413
- data : `2024-03-04T17:55:08Z INFO {metricName: accuracy, metricValue: 0.6752}
414
- invalid INFO {metricName: loss, metricValue: 0.3634}` ,
415
- },
416
- {
417
- fileName : missingMetricTEXTTestFile ,
418
- data : `2024-03-04T17:55:08Z INFO {metricName: loss, metricValue: 0.3634}
419
- 2024-03-04T17:55:08Z INFO {metricName: loss, metricValue: 0.8671}` ,
420
- },
421
- }
422
-
423
- for _ , td := range testData {
424
- filePath := filepath .Join (testTextDataPath , td .fileName )
425
- if err := os .WriteFile (filePath , []byte (td .data ), 0600 ); err != nil {
426
- return err
427
- }
428
- }
429
-
430
- return nil
431
- }
0 commit comments