4949 "framework_version" : "1.9.0" ,
5050 "py_version" : "py3" ,
5151 },
52- "hosting_artifact_uri " : "pytorch-infer/infer-pytorch-ic-mobilenet-v2.tar.gz" ,
53- "training_artifact_uri " : "pytorch-training/train-pytorch-ic-mobilenet-v2.tar.gz" ,
54- "hosting_script_uri " : "source-directory-tarballs/pytorch/inference/ic/v1.0.0/sourcedir.tar.gz" ,
55- "training_script_uri " : "source-directory-tarballs/pytorch/transfer_learning/ic/v1.0.0/sourcedir.tar.gz" ,
52+ "hosting_artifact_key " : "pytorch-infer/infer-pytorch-ic-mobilenet-v2.tar.gz" ,
53+ "training_artifact_key " : "pytorch-training/train-pytorch-ic-mobilenet-v2.tar.gz" ,
54+ "hosting_script_key " : "source-directory-tarballs/pytorch/inference/ic/v1.0.0/sourcedir.tar.gz" ,
55+ "training_script_key " : "source-directory-tarballs/pytorch/transfer_learning/ic/v1.0.0/sourcedir.tar.gz" ,
5656 "hyperparameters" : {
5757 "adam-learning-rate" : {"type" : "float" , "default" : 0.05 , "min" : 1e-08 , "max" : 1 },
5858 "epochs" : {"type" : "int" , "default" : 3 , "min" : 1 , "max" : 1000 },
@@ -334,30 +334,100 @@ def test_jumpstart_cache_gets_cleared_when_params_are_set(mock_boto3_client):
334334
335335
336336def test_jumpstart_cache_handles_boto3_client_errors ():
337+ # Testing get_object
337338 cache = JumpStartModelsCache (s3_bucket_name = "some_bucket" )
338339 stubbed_s3_client = Stubber (cache ._s3_client )
339- stubbed_s3_client .add_client_error ("head_object" , http_status_code = 404 )
340340 stubbed_s3_client .add_client_error ("get_object" , http_status_code = 404 )
341341 stubbed_s3_client .activate ()
342342 with pytest .raises (botocore .exceptions .ClientError ):
343343 cache .get_header (model_id = "tensorflow-ic-imagenet-inception-v3-classification-4" )
344344
345345 cache = JumpStartModelsCache (s3_bucket_name = "some_bucket" )
346346 stubbed_s3_client = Stubber (cache ._s3_client )
347- stubbed_s3_client .add_client_error ("head_object" , service_error_code = "AccessDenied" )
348347 stubbed_s3_client .add_client_error ("get_object" , service_error_code = "AccessDenied" )
349348 stubbed_s3_client .activate ()
350349 with pytest .raises (botocore .exceptions .ClientError ):
351350 cache .get_header (model_id = "tensorflow-ic-imagenet-inception-v3-classification-4" )
352351
353352 cache = JumpStartModelsCache (s3_bucket_name = "some_bucket" )
354353 stubbed_s3_client = Stubber (cache ._s3_client )
355- stubbed_s3_client .add_client_error ("head_object" , service_error_code = "EndpointConnectionError" )
356354 stubbed_s3_client .add_client_error ("get_object" , service_error_code = "EndpointConnectionError" )
357355 stubbed_s3_client .activate ()
358356 with pytest .raises (botocore .exceptions .ClientError ):
359357 cache .get_header (model_id = "tensorflow-ic-imagenet-inception-v3-classification-4" )
360358
359+ # Testing head_object:
360+ mock_now = datetime .datetime .fromtimestamp (1636730651.079551 )
361+ with patch ("datetime.datetime" ) as mock_datetime :
362+ mock_manifest_json = json .dumps (
363+ [
364+ {
365+ "model_id" : "pytorch-ic-imagenet-inception-v3-classification-4" ,
366+ "version" : "2.0.0" ,
367+ "min_version" : "2.49.0" ,
368+ "spec_key" : "community_models_specs/pytorch-ic-"
369+ "imagenet-inception-v3-classification-4/specs_v2.0.0.json" ,
370+ }
371+ ]
372+ )
373+
374+ get_object_mocked_response = {
375+ "Body" : botocore .response .StreamingBody (
376+ io .BytesIO (bytes (mock_manifest_json , "utf-8" )),
377+ content_length = len (mock_manifest_json ),
378+ ),
379+ "ETag" : "etag" ,
380+ }
381+
382+ mock_datetime .now .return_value = mock_now
383+
384+ cache1 = JumpStartModelsCache (
385+ s3_bucket_name = "some_bucket" , s3_cache_expiration_horizon = datetime .timedelta (hours = 1 )
386+ )
387+ stubbed_s3_client1 = Stubber (cache1 ._s3_client )
388+
389+ stubbed_s3_client1 .add_response ("get_object" , copy .deepcopy (get_object_mocked_response ))
390+ stubbed_s3_client1 .activate ()
391+ cache1 .get_header (model_id = "pytorch-ic-imagenet-inception-v3-classification-4" )
392+
393+ mock_datetime .now .return_value += datetime .timedelta (weeks = 1 )
394+
395+ stubbed_s3_client1 .add_client_error ("head_object" , http_status_code = 404 )
396+ with pytest .raises (botocore .exceptions .ClientError ):
397+ cache1 .get_header (model_id = "pytorch-ic-imagenet-inception-v3-classification-4" )
398+
399+ cache2 = JumpStartModelsCache (
400+ s3_bucket_name = "some_bucket" , s3_cache_expiration_horizon = datetime .timedelta (hours = 1 )
401+ )
402+ stubbed_s3_client2 = Stubber (cache2 ._s3_client )
403+
404+ stubbed_s3_client2 .add_response ("get_object" , copy .deepcopy (get_object_mocked_response ))
405+ stubbed_s3_client2 .activate ()
406+ cache2 .get_header (model_id = "pytorch-ic-imagenet-inception-v3-classification-4" )
407+
408+ mock_datetime .now .return_value += datetime .timedelta (weeks = 1 )
409+
410+ stubbed_s3_client2 .add_client_error ("head_object" , service_error_code = "AccessDenied" )
411+ with pytest .raises (botocore .exceptions .ClientError ):
412+ cache2 .get_header (model_id = "pytorch-ic-imagenet-inception-v3-classification-4" )
413+
414+ cache3 = JumpStartModelsCache (
415+ s3_bucket_name = "some_bucket" , s3_cache_expiration_horizon = datetime .timedelta (hours = 1 )
416+ )
417+ stubbed_s3_client3 = Stubber (cache3 ._s3_client )
418+
419+ stubbed_s3_client3 .add_response ("get_object" , copy .deepcopy (get_object_mocked_response ))
420+ stubbed_s3_client3 .activate ()
421+ cache3 .get_header (model_id = "pytorch-ic-imagenet-inception-v3-classification-4" )
422+
423+ mock_datetime .now .return_value += datetime .timedelta (weeks = 1 )
424+
425+ stubbed_s3_client3 .add_client_error (
426+ "head_object" , service_error_code = "EndpointConnectionError"
427+ )
428+ with pytest .raises (botocore .exceptions .ClientError ):
429+ cache3 .get_header (model_id = "pytorch-ic-imagenet-inception-v3-classification-4" )
430+
361431
362432def test_jumpstart_cache_accepts_input_parameters ():
363433
@@ -422,19 +492,18 @@ def test_jumpstart_cache_evaluates_md5_hash(mock_boto3_client):
422492 mock_boto3_client .return_value .get_object .return_value = {
423493 "Body" : botocore .response .StreamingBody (
424494 io .BytesIO (bytes (mock_json , "utf-8" )), content_length = len (mock_json )
425- )
495+ ),
496+ "ETag" : "hash1" ,
426497 }
427498 mock_boto3_client .return_value .head_object .return_value = {"ETag" : "hash1" }
428499
429500 cache .get_header (model_id = "pytorch-ic-imagenet-inception-v3-classification-4" )
430501
431- # first time accessing cache should involve get_object and head_object
502+ # first time accessing cache should just involve get_object
432503 mock_boto3_client .return_value .get_object .assert_called_with (
433504 Bucket = bucket_name , Key = JUMPSTART_DEFAULT_MANIFEST_FILE_S3_KEY
434505 )
435- mock_boto3_client .return_value .head_object .assert_called_with (
436- Bucket = bucket_name , Key = JUMPSTART_DEFAULT_MANIFEST_FILE_S3_KEY
437- )
506+ mock_boto3_client .return_value .head_object .assert_not_called ()
438507
439508 mock_boto3_client .return_value .get_object .reset_mock ()
440509 mock_boto3_client .return_value .head_object .reset_mock ()
@@ -443,7 +512,8 @@ def test_jumpstart_cache_evaluates_md5_hash(mock_boto3_client):
443512 mock_boto3_client .return_value .get_object .return_value = {
444513 "Body" : botocore .response .StreamingBody (
445514 io .BytesIO (bytes (mock_json , "utf-8" )), content_length = len (mock_json )
446- )
515+ ),
516+ "ETag" : "hash1" ,
447517 }
448518 mock_boto3_client .return_value .head_object .return_value = {"ETag" : "hash1" }
449519
@@ -465,7 +535,8 @@ def test_jumpstart_cache_evaluates_md5_hash(mock_boto3_client):
465535 mock_boto3_client .return_value .get_object .return_value = {
466536 "Body" : botocore .response .StreamingBody (
467537 io .BytesIO (bytes (mock_json , "utf-8" )), content_length = len (mock_json )
468- )
538+ ),
539+ "ETag" : "hash2" ,
469540 }
470541
471542 # invalidate cache
@@ -499,7 +570,8 @@ def test_jumpstart_cache_makes_correct_s3_calls(mock_boto3_client):
499570 mock_boto3_client .return_value .get_object .return_value = {
500571 "Body" : botocore .response .StreamingBody (
501572 io .BytesIO (bytes (mock_json , "utf-8" )), content_length = len (mock_json )
502- )
573+ ),
574+ "ETag" : "etag" ,
503575 }
504576
505577 mock_boto3_client .return_value .head_object .return_value = {"ETag" : "some-hash" }
@@ -514,9 +586,8 @@ def test_jumpstart_cache_makes_correct_s3_calls(mock_boto3_client):
514586 mock_boto3_client .return_value .get_object .assert_called_with (
515587 Bucket = bucket_name , Key = JUMPSTART_DEFAULT_MANIFEST_FILE_S3_KEY
516588 )
517- mock_boto3_client .return_value .head_object .assert_called_with (
518- Bucket = bucket_name , Key = JUMPSTART_DEFAULT_MANIFEST_FILE_S3_KEY
519- )
589+ mock_boto3_client .return_value .head_object .assert_not_called ()
590+
520591 mock_boto3_client .assert_called_with ("s3" , region_name = "my_region" , config = client_config )
521592
522593 # test get_specs. manifest already in cache, so only s3 call will be to get specs.
@@ -527,7 +598,8 @@ def test_jumpstart_cache_makes_correct_s3_calls(mock_boto3_client):
527598 mock_boto3_client .return_value .get_object .return_value = {
528599 "Body" : botocore .response .StreamingBody (
529600 io .BytesIO (bytes (mock_json , "utf-8" )), content_length = len (mock_json )
530- )
601+ ),
602+ "ETag" : "etag" ,
531603 }
532604 cache .get_specs (model_id = "pytorch-ic-imagenet-inception-v3-classification-4" )
533605
0 commit comments