@@ -2853,3 +2853,134 @@ def test_twisterrunner_get_cmake_filter_stages(filter, expected_result):
28532853 result = TwisterRunner .get_cmake_filter_stages (filter , ['not' , 'and' ])
28542854
28552855 assert sorted (result ) == sorted (expected_result )
2856+
2857+
2858+ @pytest .mark .parametrize (
2859+ 'required_apps, processing_ready_keys, expected_result' ,
2860+ [
2861+ (['app1' , 'app2' ], ['app1' , 'app2' ], True ), # all apps ready
2862+ (['app1' , 'app2' , 'app3' ], ['app1' , 'app2' ], False ), # some apps missing
2863+ ([], [], True ), # no required apps
2864+ (['app1' ], [], False ), # single app missing
2865+ ],
2866+ ids = ['all_ready' , 'some_missing' , 'no_apps' , 'single_missing' ]
2867+ )
2868+ def test_twisterrunner_are_required_apps_ready (required_apps , processing_ready_keys , expected_result ):
2869+ """Test _are_required_apps_ready method with various scenarios"""
2870+ instances = {}
2871+ suites = []
2872+ env_mock = mock .Mock ()
2873+ tr = TwisterRunner (instances , suites , env = env_mock )
2874+
2875+ instance_mock = mock .Mock ()
2876+ instance_mock .required_applications = required_apps
2877+
2878+ processing_ready = {key : mock .Mock () for key in processing_ready_keys }
2879+
2880+ result = tr ._are_required_apps_ready (instance_mock , processing_ready )
2881+
2882+ assert result is expected_result
2883+
2884+
2885+ @pytest .mark .parametrize (
2886+ 'app_statuses, expected_result' ,
2887+ [
2888+ ([TwisterStatus .PASS , TwisterStatus .PASS ], True ), # all passed
2889+ ([TwisterStatus .NOTRUN , TwisterStatus .NOTRUN ], True ), # all notrun
2890+ ([TwisterStatus .PASS , TwisterStatus .NOTRUN ], True ), # mixed pass/notrun
2891+ ([TwisterStatus .PASS , TwisterStatus .FAIL ], False ), # one failed
2892+ ([TwisterStatus .ERROR ], False ), # single error
2893+ ],
2894+ ids = ['all_pass' , 'all_notrun' , 'mixed_pass_notrun' , 'one_fail' , 'single_error' ]
2895+ )
2896+ def test_twisterrunner_are_all_required_apps_success (app_statuses , expected_result ):
2897+ """Test _are_all_required_apps_success method with various app statuses"""
2898+ instances = {}
2899+ suites = []
2900+ env_mock = mock .Mock ()
2901+ tr = TwisterRunner (instances , suites , env = env_mock )
2902+
2903+ instance_mock = mock .Mock ()
2904+ required_apps = [f'app{ i + 1 } ' for i in range (len (app_statuses ))]
2905+ instance_mock .required_applications = required_apps
2906+
2907+ processing_ready = {}
2908+ for i , status in enumerate (app_statuses ):
2909+ app_instance = mock .Mock ()
2910+ app_instance .status = status
2911+ app_instance .reason = f"Reason for app{ i + 1 } "
2912+ processing_ready [f'app{ i + 1 } ' ] = app_instance
2913+
2914+ result = tr ._are_all_required_apps_success (instance_mock , processing_ready )
2915+ assert result is expected_result
2916+
2917+
2918+ @pytest .mark .parametrize (
2919+ 'required_apps, ready_apps, expected_result, expected_actions' ,
2920+ [
2921+ ([], {}, True ,
2922+ {'requeue' : False , 'skip' : False , 'build_dirs' : 0 }),
2923+ (['app1' ], {}, False ,
2924+ {'requeue' : True , 'skip' : False , 'build_dirs' : 0 }),
2925+ (['app1' , 'app2' ], {'app1' : TwisterStatus .PASS }, False ,
2926+ {'requeue' : True , 'skip' : False , 'build_dirs' : 0 }),
2927+ (['app1' ], {'app1' : TwisterStatus .FAIL }, False ,
2928+ {'requeue' : False , 'skip' : True , 'build_dirs' : 0 }),
2929+ (['app1' , 'app2' ], {'app1' : TwisterStatus .PASS , 'app2' : TwisterStatus .NOTRUN }, True ,
2930+ {'requeue' : False , 'skip' : False , 'build_dirs' : 2 }),
2931+ ],
2932+ ids = ['no_apps' , 'not_ready_single_job' , 'not_ready_multi_job' ,
2933+ 'apps_failed' , 'apps_success' ]
2934+ )
2935+ def test_twisterrunner_are_required_apps_processed (required_apps , ready_apps ,
2936+ expected_result , expected_actions ):
2937+ """Test are_required_apps_processed method with various scenarios"""
2938+ # Setup TwisterRunner instances dict
2939+ tr_instances = {}
2940+ for app_name in required_apps :
2941+ tr_instances [app_name ] = mock .Mock (build_dir = f'/path/to/{ app_name } ' )
2942+
2943+ env_mock = mock .Mock ()
2944+ tr = TwisterRunner (tr_instances , [], env = env_mock )
2945+ tr .jobs = 1
2946+
2947+ instance_mock = mock .Mock ()
2948+ instance_mock .required_applications = required_apps [:]
2949+ instance_mock .required_build_dirs = []
2950+
2951+ # Setup testcases for skip scenarios
2952+ if expected_actions ['skip' ]:
2953+ testcase_mock = mock .Mock ()
2954+ instance_mock .testcases = [testcase_mock ]
2955+
2956+ # Setup processing_ready with app instances
2957+ processing_ready = {}
2958+ for app_name , status in ready_apps .items ():
2959+ app_instance = mock .Mock ()
2960+ app_instance .status = status
2961+ app_instance .reason = f"Reason for { app_name } "
2962+ app_instance .build_dir = f'/path/to/{ app_name } '
2963+ processing_ready [app_name ] = app_instance
2964+
2965+ processing_queue = deque ()
2966+ task = {'test' : instance_mock }
2967+
2968+ result = tr .are_required_apps_processed (instance_mock , processing_queue , processing_ready , task )
2969+
2970+ assert result is expected_result
2971+
2972+ if expected_actions ['requeue' ]:
2973+ assert len (processing_queue ) == 1
2974+ assert processing_queue [0 ] == task
2975+
2976+ if expected_actions ['skip' ]:
2977+ assert instance_mock .status == TwisterStatus .SKIP
2978+ assert instance_mock .reason == "Required application failed"
2979+ assert instance_mock .required_applications == []
2980+ assert instance_mock .testcases [0 ].status == TwisterStatus .SKIP
2981+ # Check for report task in queue
2982+ assert any (item .get ('op' ) == 'report' for item in processing_queue )
2983+
2984+ assert len (instance_mock .required_build_dirs ) == expected_actions ['build_dirs' ]
2985+ if expected_actions ['build_dirs' ] > 0 :
2986+ assert instance_mock .required_applications == []
0 commit comments