49
49
"framework_version" : "1.9.0" ,
50
50
"py_version" : "py3" ,
51
51
},
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" ,
56
56
"hyperparameters" : {
57
57
"adam-learning-rate" : {"type" : "float" , "default" : 0.05 , "min" : 1e-08 , "max" : 1 },
58
58
"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):
334
334
335
335
336
336
def test_jumpstart_cache_handles_boto3_client_errors ():
337
+ # Testing get_object
337
338
cache = JumpStartModelsCache (s3_bucket_name = "some_bucket" )
338
339
stubbed_s3_client = Stubber (cache ._s3_client )
339
- stubbed_s3_client .add_client_error ("head_object" , http_status_code = 404 )
340
340
stubbed_s3_client .add_client_error ("get_object" , http_status_code = 404 )
341
341
stubbed_s3_client .activate ()
342
342
with pytest .raises (botocore .exceptions .ClientError ):
343
343
cache .get_header (model_id = "tensorflow-ic-imagenet-inception-v3-classification-4" )
344
344
345
345
cache = JumpStartModelsCache (s3_bucket_name = "some_bucket" )
346
346
stubbed_s3_client = Stubber (cache ._s3_client )
347
- stubbed_s3_client .add_client_error ("head_object" , service_error_code = "AccessDenied" )
348
347
stubbed_s3_client .add_client_error ("get_object" , service_error_code = "AccessDenied" )
349
348
stubbed_s3_client .activate ()
350
349
with pytest .raises (botocore .exceptions .ClientError ):
351
350
cache .get_header (model_id = "tensorflow-ic-imagenet-inception-v3-classification-4" )
352
351
353
352
cache = JumpStartModelsCache (s3_bucket_name = "some_bucket" )
354
353
stubbed_s3_client = Stubber (cache ._s3_client )
355
- stubbed_s3_client .add_client_error ("head_object" , service_error_code = "EndpointConnectionError" )
356
354
stubbed_s3_client .add_client_error ("get_object" , service_error_code = "EndpointConnectionError" )
357
355
stubbed_s3_client .activate ()
358
356
with pytest .raises (botocore .exceptions .ClientError ):
359
357
cache .get_header (model_id = "tensorflow-ic-imagenet-inception-v3-classification-4" )
360
358
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
+
361
431
362
432
def test_jumpstart_cache_accepts_input_parameters ():
363
433
@@ -422,19 +492,18 @@ def test_jumpstart_cache_evaluates_md5_hash(mock_boto3_client):
422
492
mock_boto3_client .return_value .get_object .return_value = {
423
493
"Body" : botocore .response .StreamingBody (
424
494
io .BytesIO (bytes (mock_json , "utf-8" )), content_length = len (mock_json )
425
- )
495
+ ),
496
+ "ETag" : "hash1" ,
426
497
}
427
498
mock_boto3_client .return_value .head_object .return_value = {"ETag" : "hash1" }
428
499
429
500
cache .get_header (model_id = "pytorch-ic-imagenet-inception-v3-classification-4" )
430
501
431
- # first time accessing cache should involve get_object and head_object
502
+ # first time accessing cache should just involve get_object
432
503
mock_boto3_client .return_value .get_object .assert_called_with (
433
504
Bucket = bucket_name , Key = JUMPSTART_DEFAULT_MANIFEST_FILE_S3_KEY
434
505
)
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 ()
438
507
439
508
mock_boto3_client .return_value .get_object .reset_mock ()
440
509
mock_boto3_client .return_value .head_object .reset_mock ()
@@ -443,7 +512,8 @@ def test_jumpstart_cache_evaluates_md5_hash(mock_boto3_client):
443
512
mock_boto3_client .return_value .get_object .return_value = {
444
513
"Body" : botocore .response .StreamingBody (
445
514
io .BytesIO (bytes (mock_json , "utf-8" )), content_length = len (mock_json )
446
- )
515
+ ),
516
+ "ETag" : "hash1" ,
447
517
}
448
518
mock_boto3_client .return_value .head_object .return_value = {"ETag" : "hash1" }
449
519
@@ -465,7 +535,8 @@ def test_jumpstart_cache_evaluates_md5_hash(mock_boto3_client):
465
535
mock_boto3_client .return_value .get_object .return_value = {
466
536
"Body" : botocore .response .StreamingBody (
467
537
io .BytesIO (bytes (mock_json , "utf-8" )), content_length = len (mock_json )
468
- )
538
+ ),
539
+ "ETag" : "hash2" ,
469
540
}
470
541
471
542
# invalidate cache
@@ -499,7 +570,8 @@ def test_jumpstart_cache_makes_correct_s3_calls(mock_boto3_client):
499
570
mock_boto3_client .return_value .get_object .return_value = {
500
571
"Body" : botocore .response .StreamingBody (
501
572
io .BytesIO (bytes (mock_json , "utf-8" )), content_length = len (mock_json )
502
- )
573
+ ),
574
+ "ETag" : "etag" ,
503
575
}
504
576
505
577
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):
514
586
mock_boto3_client .return_value .get_object .assert_called_with (
515
587
Bucket = bucket_name , Key = JUMPSTART_DEFAULT_MANIFEST_FILE_S3_KEY
516
588
)
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
+
520
591
mock_boto3_client .assert_called_with ("s3" , region_name = "my_region" , config = client_config )
521
592
522
593
# 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):
527
598
mock_boto3_client .return_value .get_object .return_value = {
528
599
"Body" : botocore .response .StreamingBody (
529
600
io .BytesIO (bytes (mock_json , "utf-8" )), content_length = len (mock_json )
530
- )
601
+ ),
602
+ "ETag" : "etag" ,
531
603
}
532
604
cache .get_specs (model_id = "pytorch-ic-imagenet-inception-v3-classification-4" )
533
605
0 commit comments