@@ -258,6 +258,109 @@ def test_write_metrics_log(self, mock_gna):
258
258
self .assertEqual (tmp .read (), expected_output )
259
259
260
260
261
+ class TestWriteMetricsByClasses (TestCase ):
262
+
263
+ @mock .patch ('openshift_metrics.utils.get_namespace_attributes' )
264
+ def test_write_metrics_log (self , mock_gna ):
265
+ mock_gna .return_value = {
266
+ 'namespace1' : {
267
+ 'cf_pi' : 'PI1' ,
268
+ 'cf_project_id' : '123' ,
269
+ 'institution_code' : '76'
270
+ },
271
+ 'namespace2' : {
272
+ 'cf_pi' : 'PI2' ,
273
+ 'cf_project_id' : '456' ,
274
+ }
275
+ }
276
+ test_metrics_dict = {
277
+ "namespace1" : { # namespace is ignored entirely from the report
278
+ "pod1" : {
279
+ "metrics" : {
280
+ 0 : {
281
+ "cpu_request" : 2 ,
282
+ "memory_request" : 4 * 2 ** 30 ,
283
+ "duration" : 43200
284
+ },
285
+ }
286
+ },
287
+ },
288
+ "namespace2" : {
289
+ "pod2" : { # pod which doesn't belong to a class
290
+ "metrics" : {
291
+ 0 : {
292
+ "cpu_request" : 1 ,
293
+ "memory_request" : 8 * 2 ** 30 ,
294
+ "duration" : 172800
295
+ },
296
+ }
297
+ },
298
+ "pod3" : {
299
+ "label_nerc_mghpcc_org_class" : "math-201" ,
300
+ "metrics" : {
301
+ 0 : {
302
+ "cpu_request" : 1 ,
303
+ "memory_request" : 8 * 2 ** 30 ,
304
+ "duration" : 86400
305
+ },
306
+ }
307
+ },
308
+ "pod4" : {
309
+ "label_nerc_mghpcc_org_class" : "math-201" ,
310
+ "metrics" : {
311
+ 0 : {
312
+ "cpu_request" : 2 ,
313
+ "memory_request" : 8 * 2 ** 30 ,
314
+ "duration" : 86400
315
+ },
316
+ }
317
+ },
318
+ "pod5" : {
319
+ "label_nerc_mghpcc_org_class" : "math-201" ,
320
+ "metrics" : {
321
+ 0 : {
322
+ "cpu_request" : 1 ,
323
+ "memory_request" : 8 * 2 ** 30 ,
324
+ "gpu_request" : 1 ,
325
+ "gpu_type" : invoice .GPU_A100 ,
326
+ "gpu_resource" : invoice .WHOLE_GPU ,
327
+ "duration" : 86400
328
+ },
329
+ }
330
+ },
331
+ "pod6" : {
332
+ "label_nerc_mghpcc_org_class" : "cs-101" ,
333
+ "gpu_type" : invoice .GPU_A100_SXM4 ,
334
+ "metrics" : {
335
+ 0 : {
336
+ "cpu_request" : 24 ,
337
+ "memory_request" : 8 * 2 ** 30 ,
338
+ "gpu_request" : 1 ,
339
+ "gpu_type" : invoice .GPU_A100_SXM4 ,
340
+ "gpu_resource" : invoice .WHOLE_GPU ,
341
+ "duration" : 172800
342
+ },
343
+ }
344
+ },
345
+ }
346
+ }
347
+
348
+ expected_output = ("Invoice Month,Project - Allocation,Project - Allocation ID,Manager (PI),Invoice Email,Invoice Address,Institution,Institution - Specific Code,SU Hours (GBhr or SUhr),SU Type,Rate,Cost\n "
349
+ "2023-01,namespace2:noclass,namespace2:noclass,,,,,,96,OpenShift CPU,0.013,1.25\n "
350
+ "2023-01,namespace2:math-201,namespace2:math-201,,,,,,96,OpenShift CPU,0.013,1.25\n "
351
+ "2023-01,namespace2:math-201,namespace2:math-201,,,,,,24,OpenShift GPUA100,1.803,43.27\n "
352
+ "2023-01,namespace2:cs-101,namespace2:cs-101,,,,,,48,OpenShift GPUA100SXM4,2.078,99.74\n " )
353
+
354
+ with tempfile .NamedTemporaryFile (mode = "w+" ) as tmp :
355
+ utils .write_metrics_by_classes (
356
+ condensed_metrics_dict = test_metrics_dict ,
357
+ file_name = tmp .name ,
358
+ report_month = "2023-01" ,
359
+ rates = RATES ,
360
+ namespaces_with_classes = ["namespace2" ]
361
+ )
362
+ self .assertEqual (tmp .read (), expected_output )
363
+
261
364
@mock .patch ('openshift_metrics.utils.get_namespace_attributes' )
262
365
def test_write_metrics_by_namespace_decimal (self , mock_gna ):
263
366
"""This tests the inaccurate result we get when using floating
0 commit comments