@@ -306,5 +306,150 @@ def test_process_terraform_logs_with_all_retries_failed(self, mock_open_file, mo
306306 mock_open_file .assert_called_once_with ('/fake/path/terraform_apply.log' , 'r' , encoding = 'utf-8' )
307307 mock_isfile .assert_called_once_with ("/fake/path/terraform_apply.log" )
308308
309+ @patch ("os.path.isfile" , return_value = True )
310+ @patch ("builtins.open" , new_callable = mock_open , read_data = (
311+ 'module.azapi["ccp-provisioning-H2"].azapi_resource.aks_cluster: Destroying... [id=/subscriptions/b8ceb4e5-f05b-4562-a9f5-14acb1f24219/resourceGroups/59393-51f48219/providers/Microsoft.ContainerService/managedClusters/ccp-provisioning-H2]\n '
312+ 'module.azapi["ccp-provisioning-H2"].azapi_resource.aks_cluster: Still destroying... [id=/subscriptions/b8ceb4e5-f05b-4562-a9f5-...ce/managedClusters/ccp-provisioning-H2, 00m10s elapsed]\n '
313+ ))
314+ def test_process_terraform_logs_still_destroying_with_id_prefix (self , mock_open_file , mock_isfile ):
315+ """Verify metadata record is created when 'Still destroying' line contains id= prefix before elapsed time."""
316+ os .environ ["RUN_ID" ] = "4455667788"
317+
318+ results = process_terraform_logs (
319+ log_path = "/fake/path" ,
320+ _command_type = "destroy" ,
321+ _scenario_type = "ccp" ,
322+ _scenario_name = "provisioning" ,
323+ )
324+
325+ self .assertEqual (len (results ), 1 )
326+ self .assertEqual (results [0 ]["run_id" ], "4455667788" )
327+ self .assertEqual (results [0 ]["module_name" ], 'azapi["ccp-provisioning-H2"]' )
328+ self .assertEqual (results [0 ]["submodule_name" ], "azapi_resource" )
329+ self .assertEqual (results [0 ]["resource_name" ], "aks_cluster" )
330+ self .assertEqual (results [0 ]["action" ], "destroy" )
331+ self .assertEqual (results [0 ]["time_taken_seconds" ], 10 )
332+ self .assertEqual (results [0 ]["result" ], {"success" : False , "timed_out" : False })
333+ mock_open_file .assert_called_once_with ('/fake/path/terraform_destroy.log' , 'r' , encoding = 'utf-8' )
334+ mock_isfile .assert_called_once_with ("/fake/path/terraform_destroy.log" )
335+
336+ @patch ("os.path.isfile" , return_value = True )
337+ @patch ("builtins.open" , new_callable = mock_open , read_data = (
338+ 'module.azapi["ccp-provisioning-H2"].azapi_resource.aks_cluster: Creating... [id=/subscriptions/b8ceb4e5-f05b-4562-a9f5-14acb1f24219/resourceGroups/59393-51f48219/providers/Microsoft.ContainerService/managedClusters/ccp-provisioning-H2]\n '
339+ 'module.azapi["ccp-provisioning-H2"].azapi_resource.aks_cluster: Still creating... [id=/subscriptions/b8ceb4e5-f05b-4562-a9f5-...ce/managedClusters/ccp-provisioning-H2, 10m0s elapsed]\n '
340+ 'module.azapi["ccp-provisioning-H2"].azapi_resource.aks_cluster: Still creating... [id=/subscriptions/b8ceb4e5-f05b-4562-a9f5-...ce/managedClusters/ccp-provisioning-H2, 20m0s elapsed]\n '
341+ 'module.azapi["ccp-provisioning-H2"].azapi_resource.aks_cluster: Creation complete after 25m30s [id=/subscriptions/b8ceb4e5-f05b-4562-a9f5-14acb1f24219/resourceGroups/59393-51f48219/providers/Microsoft.ContainerService/managedClusters/ccp-provisioning-H2]\n '
342+ ))
343+ def test_process_terraform_logs_still_creating_with_id_prefix_then_complete (self , mock_open_file , mock_isfile ):
344+ """Verify that 'Still creating' lines with id= prefix are parsed and final completion record is used."""
345+ os .environ ["RUN_ID" ] = "5566778899"
346+
347+ results = process_terraform_logs (
348+ log_path = "/fake/path" ,
349+ _command_type = "apply" ,
350+ _scenario_type = "ccp" ,
351+ _scenario_name = "provisioning" ,
352+ )
353+
354+ self .assertEqual (len (results ), 1 )
355+ self .assertEqual (results [0 ]["run_id" ], "5566778899" )
356+ self .assertEqual (results [0 ]["module_name" ], 'azapi["ccp-provisioning-H2"]' )
357+ self .assertEqual (results [0 ]["submodule_name" ], "azapi_resource" )
358+ self .assertEqual (results [0 ]["resource_name" ], "aks_cluster" )
359+ self .assertEqual (results [0 ]["action" ], "apply" )
360+ self .assertEqual (results [0 ]["time_taken_seconds" ], 1530 )
361+ self .assertEqual (results [0 ]["result" ], {"success" : True , "timed_out" : False })
362+ mock_open_file .assert_called_once_with ('/fake/path/terraform_apply.log' , 'r' , encoding = 'utf-8' )
363+ mock_isfile .assert_called_once_with ("/fake/path/terraform_apply.log" )
364+
365+ @patch ("os.path.isfile" , return_value = True )
366+ @patch ("builtins.open" , new_callable = mock_open , read_data = (
367+ 'module.azapi["ccp"].azapi_resource.aks_cluster: Destroying... [id=/subscriptions/b8ceb4e5/resourceGroups/59393/providers/Microsoft.ContainerService/managedClusters/ccp-H2]\n '
368+ '│ Error: deleting Resource: unexpected status 409\n '
369+ ))
370+ def test_process_terraform_logs_failure_without_elapsed_line (self , mock_open_file , mock_isfile ):
371+ """Verify a failure record with 0s elapsed is created when there is no 'Still destroying' line."""
372+ os .environ ["RUN_ID" ] = "6677889900"
373+
374+ results = process_terraform_logs (
375+ log_path = "/fake/path" ,
376+ _command_type = "destroy" ,
377+ _scenario_type = "ccp" ,
378+ _scenario_name = "provisioning" ,
379+ )
380+
381+ self .assertEqual (len (results ), 1 )
382+ self .assertEqual (results [0 ]["run_id" ], "6677889900" )
383+ self .assertEqual (results [0 ]["module_name" ], 'azapi["ccp"]' )
384+ self .assertEqual (results [0 ]["submodule_name" ], "azapi_resource" )
385+ self .assertEqual (results [0 ]["resource_name" ], "aks_cluster" )
386+ self .assertEqual (results [0 ]["action" ], "destroy" )
387+ self .assertEqual (results [0 ]["time_taken_seconds" ], 0 )
388+ self .assertEqual (results [0 ]["result" ], {"success" : False , "timed_out" : False })
389+ mock_open_file .assert_called_once_with ('/fake/path/terraform_destroy.log' , 'r' , encoding = 'utf-8' )
390+ mock_isfile .assert_called_once_with ("/fake/path/terraform_destroy.log" )
391+
392+ @patch ("os.path.isfile" , return_value = True )
393+ @patch ("builtins.open" , new_callable = mock_open , read_data = (
394+ 'module.azapi["ccp"].azapi_resource.aks_cluster: Creating...\n '
395+ '│ Error: creating Resource: context deadline exceeded\n '
396+ ))
397+ def test_process_terraform_logs_timeout_without_elapsed_line (self , mock_open_file , mock_isfile ):
398+ """Verify a failure record with timed_out=True and 0s elapsed is created when timeout occurs without elapsed lines."""
399+ os .environ ["RUN_ID" ] = "7788990011"
400+
401+ results = process_terraform_logs (
402+ log_path = "/fake/path" ,
403+ _command_type = "apply" ,
404+ _scenario_type = "ccp" ,
405+ _scenario_name = "provisioning" ,
406+ )
407+
408+ self .assertEqual (len (results ), 1 )
409+ self .assertEqual (results [0 ]["run_id" ], "7788990011" )
410+ self .assertEqual (results [0 ]["module_name" ], 'azapi["ccp"]' )
411+ self .assertEqual (results [0 ]["resource_name" ], "aks_cluster" )
412+ self .assertEqual (results [0 ]["action" ], "apply" )
413+ self .assertEqual (results [0 ]["time_taken_seconds" ], 0 )
414+ self .assertEqual (results [0 ]["result" ], {"success" : False , "timed_out" : True })
415+ mock_open_file .assert_called_once_with ('/fake/path/terraform_apply.log' , 'r' , encoding = 'utf-8' )
416+ mock_isfile .assert_called_once_with ("/fake/path/terraform_apply.log" )
417+
418+ @patch ("os.path.isfile" , return_value = True )
419+ @patch ("builtins.open" , new_callable = mock_open , read_data = (
420+ 'module.azapi["ccp"].azapi_resource.aks_cluster: Creating...\n '
421+ '│ Error: creating Resource: unexpected status 409\n '
422+ 'module.azapi["ccp"].azapi_resource.aks_cluster: Creating...\n '
423+ 'module.azapi["ccp"].azapi_resource.aks_cluster: Still creating... [5m0s elapsed]\n '
424+ 'module.azapi["ccp"].azapi_resource.aks_cluster: Creation complete after 8m30s [id=/subscriptions/b8ceb4e5/resourceGroups/59393/providers/Microsoft.ContainerService/managedClusters/ccp-H2]\n '
425+ ))
426+ def test_process_terraform_logs_retry_after_immediate_failure (self , mock_open_file , mock_isfile ):
427+ """Verify first run records 0s failure when it fails immediately, and retry succeeds normally."""
428+ os .environ ["RUN_ID" ] = "8899001122"
429+
430+ results = process_terraform_logs (
431+ log_path = "/fake/path" ,
432+ _command_type = "apply" ,
433+ _scenario_type = "ccp" ,
434+ _scenario_name = "provisioning" ,
435+ )
436+
437+ self .assertEqual (len (results ), 2 )
438+
439+ # First run failed immediately - no elapsed time
440+ self .assertEqual (results [0 ]["module_name" ], 'azapi["ccp"]' )
441+ self .assertEqual (results [0 ]["resource_name" ], "aks_cluster" )
442+ self .assertEqual (results [0 ]["time_taken_seconds" ], 0 )
443+ self .assertEqual (results [0 ]["result" ], {"success" : False , "timed_out" : False })
444+
445+ # Retry succeeded
446+ self .assertEqual (results [1 ]["module_name" ], 'azapi["ccp"]' )
447+ self .assertEqual (results [1 ]["resource_name" ], "aks_cluster" )
448+ self .assertEqual (results [1 ]["time_taken_seconds" ], 510 )
449+ self .assertEqual (results [1 ]["result" ], {"success" : True , "timed_out" : False })
450+
451+ mock_open_file .assert_called_once_with ('/fake/path/terraform_apply.log' , 'r' , encoding = 'utf-8' )
452+ mock_isfile .assert_called_once_with ("/fake/path/terraform_apply.log" )
453+
309454if __name__ == "__main__" :
310455 unittest .main ()
0 commit comments