11"""Tests methods in codeocean_bucket_indexer module"""
22
3- import json
43import os
54import unittest
65from datetime import datetime , timezone
76from pathlib import Path
87from unittest .mock import MagicMock , call , patch
98
9+ from codeocean import CodeOcean
10+ from codeocean .data_asset import (
11+ DataAsset ,
12+ DataAssetOrigin ,
13+ DataAssetState ,
14+ DataAssetType ,
15+ SourceBucket ,
16+ )
1017from pymongo .operations import UpdateOne
11- from requests import Response
12- from requests .exceptions import ReadTimeout
1318
1419from aind_data_asset_indexer .codeocean_bucket_indexer import (
1520 CodeOceanIndexBucketJob ,
@@ -102,54 +107,85 @@ def setUpClass(cls) -> None:
102107 },
103108 ]
104109
105- cls .example_temp_endpoint_response = [
106- {"id" : "abc-123" , "source" : "s3://bucket/prefix1" },
107- {"id" : "def-456" , "source" : "s3://bucket/prefix1" },
108- {"id" : "ghi-789" , "source" : "s3://bucket/prefix2" },
110+ cls .example_search_iterator_response = [
111+ DataAsset (
112+ id = "abc-123" ,
113+ created = 0 ,
114+ name = "prefix1" ,
115+ mount = "prefix1" ,
116+ state = DataAssetState .Ready ,
117+ type = DataAssetType .Dataset ,
118+ last_used = 0 ,
119+ source_bucket = SourceBucket (
120+ bucket = "bucket" ,
121+ prefix = "prefix1" ,
122+ origin = DataAssetOrigin .AWS ,
123+ ),
124+ ),
125+ DataAsset (
126+ id = "def-456" ,
127+ created = 0 ,
128+ name = "prefix1" ,
129+ mount = "prefix1" ,
130+ state = DataAssetState .Ready ,
131+ type = DataAssetType .Dataset ,
132+ last_used = 0 ,
133+ source_bucket = SourceBucket (
134+ bucket = "bucket" ,
135+ prefix = "prefix1" ,
136+ origin = DataAssetOrigin .AWS ,
137+ ),
138+ ),
139+ DataAsset (
140+ id = "ghi-789" ,
141+ created = 0 ,
142+ name = "prefix2" ,
143+ mount = "prefix2" ,
144+ state = DataAssetState .Ready ,
145+ type = DataAssetType .Dataset ,
146+ last_used = 0 ,
147+ source_bucket = SourceBucket (
148+ bucket = "bucket" ,
149+ prefix = "prefix2" ,
150+ origin = DataAssetOrigin .AWS ,
151+ ),
152+ ),
109153 ]
110154
111- @patch ("requests.get " )
112- def test_get_external_data_asset_records (self , mock_get : MagicMock ):
155+ @patch ("codeocean.data_asset.DataAssets.search_data_assets_iterator " )
156+ def test_get_external_data_asset_records (self , mock_search : MagicMock ):
113157 """Tests the _get_external_data_asset_records method"""
114- example_response = self .example_temp_endpoint_response
115- mock_get_response = Response ()
116- mock_get_response .status_code = 200
117- mock_get_response ._content = json .dumps (example_response ).encode (
118- "utf-8"
158+ mock_search .return_value = self .example_search_iterator_response
159+ response = self .basic_job ._get_external_data_asset_records (
160+ co_client = CodeOcean (domain = "www.example.com" , token = "" )
119161 )
120- mock_get .return_value = mock_get_response
121- response = self .basic_job ._get_external_data_asset_records ()
122- self .assertEqual (example_response , response )
162+ expected_response = [
163+ {"id" : "abc-123" , "location" : "s3://bucket/prefix1" },
164+ {"id" : "def-456" , "location" : "s3://bucket/prefix1" },
165+ {"id" : "ghi-789" , "location" : "s3://bucket/prefix2" },
166+ ]
167+ self .assertEqual (expected_response , response )
123168
124- @patch ("requests.get " )
125- def test_get_external_data_asset_records_error (self , mock_get : MagicMock ):
169+ @patch ("codeocean.data_asset.DataAssets.search_data_assets_iterator " )
170+ def test_get_external_data_asset_records_err (self , mock_search : MagicMock ):
126171 """Tests the _get_external_data_asset_records method when an error
127172 response is returned"""
128- mock_get_response = Response ()
129- mock_get_response .status_code = 500
130- mock_get .return_value = mock_get_response
131- response = self .basic_job ._get_external_data_asset_records ()
132- self .assertIsNone (response )
133-
134- @patch ("requests.get" )
135- def test_get_external_data_asset_records_read_timeout (
136- self , mock_get : MagicMock
137- ):
138- """Tests the _get_external_data_asset_records method when the read
139- times out."""
140- mock_get .side_effect = ReadTimeout ()
173+ mock_search .side_effect = Exception ("Something went wrong!" )
141174 with self .assertLogs (level = "DEBUG" ) as captured :
142- response = self .basic_job ._get_external_data_asset_records ()
143- expected_log_messages = [
144- "ERROR:root:Read timed out at http://some_url:8080/created_after/0"
145- ]
146- self .assertEqual (expected_log_messages , captured .output )
175+ response = self .basic_job ._get_external_data_asset_records (
176+ co_client = CodeOcean (domain = "www.example.com" , token = "" )
177+ )
147178 self .assertIsNone (response )
179+ self .assertIsNotNone (captured .output )
148180
149181 def test_map_external_list_to_dict (self ):
150182 """Tests _map_external_list_to_dict method"""
151183 mapped_response = self .basic_job ._map_external_list_to_dict (
152- self .example_temp_endpoint_response
184+ [
185+ {"id" : "abc-123" , "location" : "s3://bucket/prefix1" },
186+ {"id" : "def-456" , "location" : "s3://bucket/prefix1" },
187+ {"id" : "ghi-789" , "location" : "s3://bucket/prefix2" },
188+ ]
153189 )
154190 expected_response = {
155191 "s3://bucket/prefix1" : {"abc-123" , "def-456" },
@@ -185,27 +221,21 @@ def test_get_co_links_from_record_legacy(self):
185221 self .assertEqual (["abc-123" , "def-456" ], output )
186222
187223 @patch ("aind_data_asset_indexer.codeocean_bucket_indexer.MongoClient" )
188- @patch ("requests.get " )
224+ @patch ("codeocean.data_asset.DataAssets.search_data_assets_iterator " )
189225 @patch ("aind_data_asset_indexer.codeocean_bucket_indexer.paginate_docdb" )
190226 @patch ("aind_data_asset_indexer.codeocean_bucket_indexer.datetime" )
191227 def test_update_external_links_in_docdb (
192228 self ,
193229 mock_datetime : MagicMock ,
194230 mock_paginate : MagicMock ,
195- mock_get : MagicMock ,
231+ mock_search : MagicMock ,
196232 mock_docdb_client : MagicMock ,
197233 ):
198234 """Tests _update_external_links_in_docdb method."""
199235 mock_datetime .utcnow .return_value = datetime (2024 , 9 , 5 )
200236
201- # Mock requests get response
202- example_response = self .example_temp_endpoint_response
203- mock_get_response = Response ()
204- mock_get_response .status_code = 200
205- mock_get_response ._content = json .dumps (example_response ).encode (
206- "utf-8"
207- )
208- mock_get .return_value = mock_get_response
237+ # Mock code ocean search response
238+ mock_search .return_value = self .example_search_iterator_response
209239
210240 # Mock bulk_write
211241 mock_db = MagicMock ()
@@ -237,7 +267,8 @@ def test_update_external_links_in_docdb(
237267
238268 with self .assertLogs (level = "DEBUG" ) as captured :
239269 self .basic_job ._update_external_links_in_docdb (
240- docdb_client = mock_docdb_client
270+ docdb_client = mock_docdb_client ,
271+ co_client = CodeOcean (domain = "www.example.com" , token = "" ),
241272 )
242273 expected_log_messages = [
243274 "INFO:root:No code ocean data asset ids found for "
@@ -284,31 +315,31 @@ def test_update_external_links_in_docdb(
284315 mock_collection .bulk_write .assert_has_calls (expected_bulk_write_calls )
285316
286317 @patch ("aind_data_asset_indexer.codeocean_bucket_indexer.MongoClient" )
287- @patch ("requests.get " )
318+ @patch ("codeocean.data_asset.DataAssets.search_data_assets_iterator " )
288319 @patch ("aind_data_asset_indexer.codeocean_bucket_indexer.paginate_docdb" )
289320 def test_update_external_links_in_docdb_error (
290321 self ,
291322 mock_paginate : MagicMock ,
292- mock_get : MagicMock ,
323+ mock_search : MagicMock ,
293324 mock_docdb_client : MagicMock ,
294325 ):
295326 """Tests _update_external_links_in_docdb method when there is an
296327 error retrieving info from the temp endpoint."""
297- # Mock requests get response
298- mock_get_response = Response ()
299- mock_get_response .status_code = 500
300- mock_get .return_value = mock_get_response
328+ # Mock search response
329+ mock_search .side_effect = Exception ("Something went wrong!" )
301330
302331 mock_db = MagicMock ()
303332 mock_docdb_client .__getitem__ .return_value = mock_db
304333 with self .assertLogs (level = "DEBUG" ) as captured :
305334 self .basic_job ._update_external_links_in_docdb (
306- docdb_client = mock_docdb_client
335+ docdb_client = mock_docdb_client ,
336+ co_client = CodeOcean (domain = "www.example.com" , token = "" ),
307337 )
308- expected_log_messages = [
338+ expected_log_message = (
309339 "ERROR:root:There was an error retrieving external links!"
310- ]
311- self .assertEqual (expected_log_messages , captured .output )
340+ )
341+ self .assertEqual (2 , len (captured .output ))
342+ self .assertEqual (expected_log_message , captured .output [1 ])
312343 mock_paginate .assert_not_called ()
313344
314345 @patch ("aind_data_asset_indexer.codeocean_bucket_indexer.MongoClient" )
@@ -568,8 +599,10 @@ def test_delete_records_from_docdb(
568599 "aind_data_asset_indexer.codeocean_bucket_indexer."
569600 "get_all_processed_codeocean_asset_records"
570601 )
602+ @patch ("aind_data_asset_indexer.codeocean_bucket_indexer.CodeOcean" )
571603 def test_run_job (
572604 self ,
605+ mock_codeocean_client : MagicMock ,
573606 mock_get_all_co_records : MagicMock ,
574607 mock_docdb_client : MagicMock ,
575608 mock_paginate_docdb : MagicMock ,
@@ -581,6 +614,8 @@ def test_run_job(
581614 one record, add one record, and delete one record."""
582615 mock_mongo_client = MagicMock ()
583616 mock_docdb_client .return_value = mock_mongo_client
617+ mock_co_client = MagicMock ()
618+ mock_codeocean_client .return_value = mock_co_client
584619 mock_get_all_co_records .return_value = dict (
585620 [(r ["location" ], r ) for r in self .example_codeocean_records ]
586621 )
@@ -602,7 +637,7 @@ def test_run_job(
602637 self .assertEqual (expected_log_messages , captured .output )
603638
604639 mock_update_external_links_in_docdb .assert_called_once_with (
605- docdb_client = mock_mongo_client
640+ docdb_client = mock_mongo_client , co_client = mock_co_client
606641 )
607642 mock_process_codeocean_records .assert_called_once_with (
608643 records = [self .example_codeocean_records [0 ]]
0 commit comments