@@ -2853,3 +2853,134 @@ def test_twisterrunner_get_cmake_filter_stages(filter, expected_result):
2853
2853
result = TwisterRunner .get_cmake_filter_stages (filter , ['not' , 'and' ])
2854
2854
2855
2855
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