@@ -33,6 +33,7 @@ def test_find_upstream_visits(
3333 upstream_data_dirs = {}
3434 for n in range (10 ):
3535 upstream_instrument = f"{ instrument_name } { str (n ).zfill (2 )} "
36+ # Create path to visit
3637 upstream_visit = (
3738 tmp_path / f"{ upstream_instrument } /data/2020/{ visit_name_root } -{ n } "
3839 )
@@ -49,6 +50,14 @@ def test_find_upstream_visits(
4950 upstream_visit .parent .mkdir (parents = True , exist_ok = True )
5051 upstream_visit .touch (exist_ok = True )
5152
53+ # Create junk directories with multiple levels to test recursion logic with
54+ junk_directories = [
55+ tmp_path / f"{ upstream_instrument } /data/junk/directory/number/{ n } "
56+ for n in range (5 )
57+ ]
58+ for dirpath in junk_directories :
59+ dirpath .mkdir (parents = True , exist_ok = True )
60+
5261 # Mock the MachineConfig for this instrument
5362 mock_machine_config = MagicMock (spec = MachineConfig )
5463 mock_machine_config .upstream_data_directories = upstream_data_dirs
@@ -57,10 +66,66 @@ def test_find_upstream_visits(
5766 )
5867 mock_get_machine_config .return_value = {instrument_name : mock_machine_config }
5968
60- # Run the function:
69+ # Run the function
6170 result = find_upstream_visits (session_id = session_id , db = mock_murfey_db )
6271
72+ # Check that the expected directories are returned
73+ assert result == upstream_visits
74+
75+
76+ def test_find_upstream_visits_permission_error (
77+ mocker : MockerFixture ,
78+ tmp_path : Path ,
79+ ):
80+ # Get the visit, instrument name, and session ID
81+ visit_name_root = f"{ ExampleVisit .proposal_code } { ExampleVisit .proposal_number } "
82+ visit_name = f"{ visit_name_root } -{ ExampleVisit .visit_number } "
83+ instrument_name = ExampleVisit .instrument_name
84+ session_id = ExampleVisit .murfey_session_id
85+
6386 # Mock the database call
87+ mock_murfey_session_row = MagicMock ()
88+ mock_murfey_session_row .visit = visit_name
89+ mock_murfey_session_row .instrument_name = instrument_name
90+ mock_murfey_db = MagicMock ()
91+ mock_murfey_db .exec .return_value .one .return_value = mock_murfey_session_row
92+
93+ # Create mock upstream visit directories and necessary data structures
94+ upstream_visits : dict [str , dict ] = {}
95+ upstream_data_dirs = {}
96+ for n in range (10 ):
97+ upstream_instrument = f"{ instrument_name } { str (n ).zfill (2 )} "
98+ upstream_visit = (
99+ tmp_path / f"{ upstream_instrument } /data/2020/{ visit_name_root } -{ n } "
100+ )
101+ # Create some as directories, and some as files
102+ if n % 2 :
103+ upstream_visit .mkdir (parents = True , exist_ok = True )
104+ upstream_data_dirs [upstream_instrument ] = upstream_visit .parent .parent
105+ # With os.scandir set to raise PermissionError, dictionaries should be empty
106+ upstream_visits [upstream_instrument ] = {}
107+ else :
108+ upstream_visit .parent .mkdir (parents = True , exist_ok = True )
109+ upstream_visit .touch (exist_ok = True )
110+
111+ # Mock the MachineConfig for this instrument
112+ mock_machine_config = MagicMock (spec = MachineConfig )
113+ mock_machine_config .upstream_data_directories = upstream_data_dirs
114+ mock_get_machine_config = mocker .patch (
115+ "murfey.server.api.session_shared.get_machine_config" ,
116+ )
117+ mock_get_machine_config .return_value = {instrument_name : mock_machine_config }
118+
119+ # Mock the 'os.scandir' function used
120+ mocker .patch (
121+ "murfey.server.api.session_shared.os.scandir" ,
122+ side_effect = PermissionError (),
123+ )
124+
125+ # Run the function:
126+ result = find_upstream_visits (session_id = session_id , db = mock_murfey_db )
127+
128+ # With 'os.scandir' mocked to raise PermissionError, no entries should be returned
64129 assert result == upstream_visits
65130
66131
0 commit comments