1
1
import { describe , test , expect , beforeAll , afterAll } from '@jest/globals' ;
2
2
import ExperimentClient from '../src/tracking/ExperimentClient' ;
3
3
import { ApiError } from '../src/utils/apiError' ;
4
- import { Experiment } from '../src/utils/interface' ;
4
+ import {
5
+ createTestExperiment ,
6
+ deleteTestExperiments ,
7
+ experimentProperties ,
8
+ ExpSearchResults ,
9
+ TRACKING_SERVER_URI ,
10
+ } from './testUtils' ;
5
11
6
12
describe ( 'ExperimentClient' , ( ) => {
7
13
let experimentClient : ExperimentClient ;
8
- let experimentId : string ;
9
- let experimentName : string ;
10
14
const testIds : string [ ] = [ ] ;
11
15
12
16
beforeAll ( async ( ) => {
13
17
// Add a small delay to ensure MLflow is fully ready
14
18
await new Promise ( ( resolve ) => setTimeout ( resolve , 2000 ) ) ;
15
- experimentClient = new ExperimentClient ( 'http://127.0.0.1:5002' ) ;
16
-
17
- // Generate the experiment ID to be used generically in later tests
18
- const timestamp = Date . now ( ) ;
19
- experimentName = `Testing ${ timestamp } ` ;
20
- experimentId = await experimentClient . createExperiment ( experimentName ) ;
21
- testIds . push ( experimentId ) ;
19
+ experimentClient = new ExperimentClient ( TRACKING_SERVER_URI ) ;
22
20
} ) ;
23
21
24
22
describe ( 'createExperiment' , ( ) => {
25
23
test ( 'should create an experiment and return the experiment ID' , async ( ) => {
26
- const timestamp = Date . now ( ) ;
27
- const testExperimentId = await experimentClient . createExperiment (
28
- `Test experiment ${ timestamp } `
29
- ) ;
24
+ const testExperimentId : string = await createTestExperiment ( ) ;
30
25
testIds . push ( testExperimentId ) ;
31
26
expect ( typeof testExperimentId ) . toBe ( 'string' ) ;
32
27
expect ( testExperimentId ) . toBeTruthy ( ) ;
@@ -44,6 +39,8 @@ describe('ExperimentClient', () => {
44
39
} ) ;
45
40
46
41
test ( 'should throw error if name is already in use' , async ( ) => {
42
+ const experimentName : string = `Test experiment ${ Date . now ( ) } ` ;
43
+ testIds . push ( await experimentClient . createExperiment ( experimentName ) ) ;
47
44
await expect (
48
45
experimentClient . createExperiment ( experimentName )
49
46
) . rejects . toThrow ( ApiError ) ;
@@ -53,18 +50,15 @@ describe('ExperimentClient', () => {
53
50
describe ( 'searchExperiment' , ( ) => {
54
51
beforeAll ( async ( ) => {
55
52
for ( let i = 0 ; i < 5 ; i ++ ) {
56
- const num = Math . random ( ) . toString ( ) . slice ( 2 , 11 ) ;
57
- const name = `Search test ${ num } ` ;
58
- const search = await experimentClient . createExperiment ( name ) ;
53
+ const search : string = await experimentClient . createExperiment (
54
+ `Search test ${ Date . now ( ) } `
55
+ ) ;
59
56
testIds . push ( search ) ;
60
57
}
61
58
} ) ;
62
59
63
60
test ( 'should return valid search results' , async ( ) => {
64
- const results : {
65
- experiments ?: Experiment [ ] ;
66
- next_page_token ?: string ;
67
- } = await experimentClient . searchExperiment (
61
+ const results : ExpSearchResults = await experimentClient . searchExperiment (
68
62
"name LIKE 'Search test%'" ,
69
63
4
70
64
) ;
@@ -73,26 +67,22 @@ describe('ExperimentClient', () => {
73
67
expect ( results . next_page_token ) . toBeDefined ( ) ;
74
68
expect ( results . experiments ) . toHaveLength ( 4 ) ;
75
69
results . experiments ?. forEach ( ( result ) => {
76
- expect ( result ) . toHaveProperty ( 'experiment_id' ) ;
77
- expect ( result ) . toHaveProperty ( 'name' ) ;
78
- expect ( result ) . toHaveProperty ( 'artifact_location' ) ;
79
- expect ( result ) . toHaveProperty ( 'lifecycle_stage' ) ;
80
- expect ( result ) . toHaveProperty ( 'last_update_time' ) ;
81
- expect ( result ) . toHaveProperty ( 'creation_time' ) ;
70
+ for ( const property of experimentProperties ) {
71
+ expect ( result ) . toHaveProperty ( property ) ;
72
+ }
82
73
} ) ;
83
74
expect ( typeof results . next_page_token ) . toBe ( 'string' ) ;
84
75
} ) ;
85
76
} ) ;
86
77
87
78
describe ( 'getExperiment' , ( ) => {
88
79
test ( 'should return experiment information' , async ( ) => {
89
- const experiment = await experimentClient . getExperiment ( experimentId ) ;
90
- expect ( experiment ) . toHaveProperty ( 'experiment_id' ) ;
91
- expect ( experiment ) . toHaveProperty ( 'name' ) ;
92
- expect ( experiment ) . toHaveProperty ( 'artifact_location' ) ;
93
- expect ( experiment ) . toHaveProperty ( 'lifecycle_stage' ) ;
94
- expect ( experiment ) . toHaveProperty ( 'last_update_time' ) ;
95
- expect ( experiment ) . toHaveProperty ( 'creation_time' ) ;
80
+ const expId : string = await createTestExperiment ( ) ;
81
+ const experiment = await experimentClient . getExperiment ( expId ) ;
82
+ testIds . push ( expId ) ;
83
+ for ( const property of experimentProperties ) {
84
+ expect ( experiment ) . toHaveProperty ( property ) ;
85
+ }
96
86
} ) ;
97
87
98
88
test ( 'should throw error if experiment ID is missing' , async ( ) => {
@@ -103,54 +93,49 @@ describe('ExperimentClient', () => {
103
93
104
94
describe ( 'getExperimentByName' , ( ) => {
105
95
test ( 'should return experiment information' , async ( ) => {
106
- const experiment = await experimentClient . getExperimentByName ( experimentName ) ;
107
- expect ( experiment ) . toHaveProperty ( 'experiment_id' ) ;
108
- expect ( experiment ) . toHaveProperty ( 'name' ) ;
109
- expect ( experiment ) . toHaveProperty ( 'artifact_location' ) ;
110
- expect ( experiment ) . toHaveProperty ( 'lifecycle_stage' ) ;
111
- expect ( experiment ) . toHaveProperty ( 'last_update_time' ) ;
112
- expect ( experiment ) . toHaveProperty ( 'creation_time' ) ;
96
+ const name : string = `Test experiment ${ Date . now ( ) } ` ;
97
+ testIds . push ( await experimentClient . createExperiment ( name ) ) ;
98
+ const experiment = await experimentClient . getExperimentByName ( name ) ;
99
+ for ( const property of experimentProperties ) {
100
+ expect ( experiment ) . toHaveProperty ( property ) ;
101
+ }
113
102
} ) ;
114
103
115
104
test ( 'should throw error if experiment name is missing' , async ( ) => {
116
105
// @ts -expect-error: testing for missing arguments
117
- await expect ( experimentClient . getExperimentByName ( ) ) . rejects . toThrow ( ApiError ) ;
106
+ await expect ( experimentClient . getExperimentByName ( ) ) . rejects . toThrow (
107
+ ApiError
108
+ ) ;
118
109
} ) ;
119
110
} ) ;
120
111
121
112
describe ( 'deleteExperiment' , ( ) => {
122
113
test ( 'should delete an experiment' , async ( ) => {
123
- const num = Math . random ( ) . toString ( ) . slice ( 2 , 11 ) ;
124
- const name = `Test experiment ${ num } ` ;
125
- const idToDelete = await experimentClient . createExperiment ( name ) ;
114
+ const name : string = `Test experiment ${ Date . now ( ) } ` ;
115
+ const idToDelete : string = await experimentClient . createExperiment ( name ) ;
126
116
await experimentClient . deleteExperiment ( idToDelete ) ;
127
- const results : {
128
- experiments ?: Experiment [ ] ;
129
- next_page_token ?: string ;
130
- } = await experimentClient . searchExperiment (
131
- `name LIKE '${ idToDelete } '` ,
117
+ const results : ExpSearchResults = await experimentClient . searchExperiment (
118
+ `name LIKE '${ name } '` ,
132
119
4
133
120
) ;
134
121
expect ( results ) . toEqual ( { } ) ;
135
122
} ) ;
136
123
137
124
test ( 'should throw error if invalid experiment ID is passed in' , async ( ) => {
138
- await expect ( experimentClient . deleteExperiment ( 'invalidExperimentId' ) ) . rejects . toThrow ( ApiError ) ;
125
+ await expect (
126
+ experimentClient . deleteExperiment ( 'invalidExperimentId' )
127
+ ) . rejects . toThrow ( ApiError ) ;
139
128
} ) ;
140
129
} ) ;
141
130
142
131
describe ( 'restoreExperiment' , ( ) => {
143
132
test ( 'should restore a deleted experiment' , async ( ) => {
144
- const num = Math . random ( ) . toString ( ) . slice ( 2 , 11 ) ;
145
- const name = `Test experiment ${ num } ` ;
146
- const idToDelete = await experimentClient . createExperiment ( name ) ;
133
+ const name : string = `Test experiment ${ Date . now ( ) } ` ;
134
+ const idToDelete : string = await experimentClient . createExperiment ( name ) ;
147
135
testIds . push ( idToDelete ) ;
148
136
await experimentClient . deleteExperiment ( idToDelete ) ;
149
137
await experimentClient . restoreExperiment ( idToDelete ) ;
150
- const results : {
151
- experiments ?: Experiment [ ] ;
152
- next_page_token ?: string ;
153
- } = await experimentClient . searchExperiment (
138
+ const results : ExpSearchResults = await experimentClient . searchExperiment (
154
139
`name LIKE '${ name } '` ,
155
140
4
156
141
) ;
@@ -159,22 +144,20 @@ describe('ExperimentClient', () => {
159
144
} ) ;
160
145
161
146
test ( 'should throw error if invalid experiment ID is passed in' , async ( ) => {
162
- await expect ( experimentClient . restoreExperiment ( 'invalidExperimentId' ) ) . rejects . toThrow ( ApiError ) ;
147
+ await expect (
148
+ experimentClient . restoreExperiment ( 'invalidExperimentId' )
149
+ ) . rejects . toThrow ( ApiError ) ;
163
150
} ) ;
164
151
} ) ;
165
152
166
153
describe ( 'updateExperiment' , ( ) => {
167
- test ( 'should update an experiment\'s name' , async ( ) => {
168
- const num = Math . random ( ) . toString ( ) . slice ( 2 , 11 ) ;
169
- const name = `Test experiment ${ num } ` ;
170
- const exp = await experimentClient . createExperiment ( name ) ;
154
+ test ( "should update an experiment's name" , async ( ) => {
155
+ const name : string = `Test experiment ${ Date . now ( ) } ` ;
156
+ const exp : string = await experimentClient . createExperiment ( name ) ;
171
157
testIds . push ( exp ) ;
172
- const updatedName = `${ name } _UPDATE`
158
+ const updatedName : string = `${ name } _UPDATE` ;
173
159
await experimentClient . updateExperiment ( exp , updatedName ) ;
174
- const results : {
175
- experiments ?: Experiment [ ] ;
176
- next_page_token ?: string ;
177
- } = await experimentClient . searchExperiment (
160
+ const results : ExpSearchResults = await experimentClient . searchExperiment (
178
161
`name LIKE '${ updatedName } '` ,
179
162
4
180
163
) ;
@@ -184,22 +167,24 @@ describe('ExperimentClient', () => {
184
167
} ) ;
185
168
186
169
test ( 'should throw error if invalid experiment ID is passed in' , async ( ) => {
187
- await expect ( experimentClient . updateExperiment ( 'invalidExperimentId' , 'invalidExperimentIdUpdate' ) ) . rejects . toThrow ( ApiError ) ;
170
+ await expect (
171
+ experimentClient . updateExperiment (
172
+ 'invalidExperimentId' ,
173
+ 'invalidExperimentIdUpdate'
174
+ )
175
+ ) . rejects . toThrow ( ApiError ) ;
188
176
} ) ;
189
177
} ) ;
190
178
191
179
describe ( 'setExperimentTag' , ( ) => {
192
180
test ( 'should set a tag on an experiment' , async ( ) => {
193
- const num = Math . random ( ) . toString ( ) . slice ( 2 , 11 ) ;
194
- const name = `Test experiment ${ num } ` ;
195
- const exp = await experimentClient . createExperiment ( name ) ;
181
+ const date : number = Date . now ( ) ;
182
+ const name : string = `Test experiment ${ date } ` ;
183
+ const exp : string = await experimentClient . createExperiment ( name ) ;
196
184
testIds . push ( exp ) ;
197
- await experimentClient . setExperimentTag ( exp , 'tag1' , `value${ num } ` ) ;
198
- const results : {
199
- experiments ?: Experiment [ ] ;
200
- next_page_token ?: string ;
201
- } = await experimentClient . searchExperiment (
202
- `tags.tag1 = "value${ num } "` ,
185
+ await experimentClient . setExperimentTag ( exp , 'tag1' , `value${ date } ` ) ;
186
+ const results : ExpSearchResults = await experimentClient . searchExperiment (
187
+ `tags.tag1 = "value${ date } "` ,
203
188
4
204
189
) ;
205
190
expect ( results . experiments ) . toBeDefined ( ) ;
@@ -208,16 +193,15 @@ describe('ExperimentClient', () => {
208
193
} ) ;
209
194
210
195
test ( 'should throw error if invalid experiment ID is passed in' , async ( ) => {
211
- await expect ( experimentClient . setExperimentTag ( 'invalidExperimentId' , 'tag1' , 'value1' ) ) . rejects . toThrow ( ApiError ) ;
196
+ await expect (
197
+ experimentClient . setExperimentTag (
198
+ 'invalidExperimentId' ,
199
+ 'tag1' ,
200
+ 'value1'
201
+ )
202
+ ) . rejects . toThrow ( ApiError ) ;
212
203
} ) ;
213
204
} ) ;
214
205
215
- afterAll ( async ( ) => {
216
- while ( testIds . length > 0 ) {
217
- const id = testIds . pop ( ) ;
218
- if ( id ) {
219
- await experimentClient . deleteExperiment ( id ) ;
220
- }
221
- }
222
- } ) ;
206
+ afterAll ( async ( ) => await deleteTestExperiments ( testIds ) ) ;
223
207
} ) ;
0 commit comments