11from http import HTTPStatus
22from logging import Logger
33from pathlib import Path
4+ from typing import Union
45
56from flask import Request
67import pytest
@@ -87,13 +88,16 @@ def test_missing_authorization_header(self, client, server_config):
8788 assert response .status_code == HTTPStatus .UNAUTHORIZED
8889 assert not self .cachemanager_created
8990
90- @responses .activate
9191 @pytest .mark .freeze_time ("2023-07-01" )
92- def test_relay (self , client , server_config , pbench_drb_token , tarball ):
92+ @pytest .mark .parametrize ("delete" , ("false" , "true" , None ))
93+ @responses .activate
94+ def test_relay (self , client , server_config , pbench_drb_token , tarball , delete ):
9395 """Verify the success path
9496
9597 Ensure successful completion when the primary relay URI returns a valid
9698 relay manifest referencing a secondary relay URI containing a tarball.
99+
100+ Also check that the DELETE requests happen when `?delete` is specified.
97101 """
98102 file , md5file , md5 = tarball
99103 name = Dataset .stem (file )
@@ -117,22 +121,34 @@ def test_relay(self, client, server_config, pbench_drb_token, tarball):
117121 headers = {"content-length" : f"{ file .stat ().st_size } " },
118122 content_type = "application/octet-stream" ,
119123 )
124+ if delete == "true" :
125+ responses .add (
126+ responses .DELETE , "https://relay.example.com/uri1" , status = HTTPStatus .OK
127+ )
128+ responses .add (
129+ responses .DELETE , "https://relay.example.com/uri2" , status = HTTPStatus .OK
130+ )
120131 response = client .post (
121132 self .gen_uri (server_config , "https://relay.example.com/uri1" ),
133+ query_string = {"delete" : delete } if delete else None ,
122134 headers = self .gen_headers (pbench_drb_token ),
123135 )
124136 assert (
125137 response .status_code == HTTPStatus .CREATED
126138 ), f"Unexpected result, { response .text } "
139+ expected_notes = [
140+ "Identified benchmark workload 'unknown'." ,
141+ "Expected expiration date is 2025-06-30." ,
142+ ]
143+ if delete == "true" :
144+ expected_notes .append ("Relay files were successfully removed." )
127145 assert response .json == {
128146 "message" : "File successfully uploaded" ,
129147 "name" : name ,
130148 "resource_id" : md5 ,
131- "notes" : [
132- "Identified benchmark workload 'unknown'." ,
133- "Expected expiration date is 2025-06-30." ,
134- ],
149+ "notes" : expected_notes ,
135150 }
151+ assert len (responses .calls ) == 4 if delete == "true" else 2
136152 assert (
137153 response .headers ["location" ]
138154 == f"https://localhost/api/v1/datasets/{ md5 } /inventory/"
@@ -162,23 +178,21 @@ def test_relay(self, client, server_config, pbench_drb_token, tarball):
162178 assert audit [1 ].name == "relay"
163179 assert audit [1 ].object_type == AuditType .DATASET
164180 assert audit [1 ].object_id == md5
165- assert audit [1 ].object_name == Dataset . stem ( file )
181+ assert audit [1 ].object_name == name
166182 assert audit [1 ].user_id == DRB_USER_ID
167183 assert audit [1 ].user_name == "drb"
168184 assert audit [1 ].reason is None
169185 assert audit [1 ].attributes == {
170186 "access" : "private" ,
171187 "metadata" : {"global.pbench.test" : "data" },
172- "notes" : [
173- "Identified benchmark workload 'unknown'." ,
174- "Expected expiration date is 2025-06-30." ,
175- ],
188+ "notes" : expected_notes ,
176189 }
177190
178191 @responses .activate
179192 def test_relay_tar_fail (self , client , server_config , pbench_drb_token , tarball ):
180193 """Verify failure when secondary relay URI is not found"""
181194 file , md5file , md5 = tarball
195+ name = Dataset .stem (file )
182196 responses .add (
183197 responses .GET ,
184198 "https://relay.example.com/uri1" ,
@@ -211,7 +225,7 @@ def test_relay_tar_fail(self, client, server_config, pbench_drb_token, tarball):
211225 assert audit [0 ].name == "relay"
212226 assert audit [0 ].object_type == AuditType .DATASET
213227 assert audit [0 ].object_id == md5
214- assert audit [0 ].object_name == Dataset . stem ( file )
228+ assert audit [0 ].object_name == name
215229 assert audit [0 ].user_id == DRB_USER_ID
216230 assert audit [0 ].user_name == "drb"
217231 assert audit [0 ].reason is None
@@ -226,7 +240,7 @@ def test_relay_tar_fail(self, client, server_config, pbench_drb_token, tarball):
226240 assert audit [1 ].name == "relay"
227241 assert audit [1 ].object_type == AuditType .DATASET
228242 assert audit [1 ].object_id == md5
229- assert audit [1 ].object_name == Dataset . stem ( file )
243+ assert audit [1 ].object_name == name
230244 assert audit [1 ].user_id == DRB_USER_ID
231245 assert audit [1 ].user_name == "drb"
232246 assert audit [1 ].reason == AuditReason .CONSISTENCY
@@ -392,3 +406,140 @@ def test_relay_tarball_connection(
392406 assert (
393407 response .json ["message" ] == "Unable to connect to results URI: 'leaky wire'"
394408 )
409+
410+ @pytest .mark .freeze_time ("2023-07-01" )
411+ @pytest .mark .parametrize (
412+ "status1,status2" ,
413+ (
414+ ((HTTPStatus .OK , None ), ((HTTPStatus .BAD_REQUEST , "Bad Request" ))),
415+ ((HTTPStatus .BAD_REQUEST , "Bad Request" ), (HTTPStatus .OK , None )),
416+ (
417+ (HTTPStatus .BAD_REQUEST , "Bad Request" ),
418+ (HTTPStatus .BAD_REQUEST , "Bad Request" ),
419+ ),
420+ ((ConnectionError ("testing" ), "testing" ), (HTTPStatus .OK , None )),
421+ ((HTTPStatus .OK , None ), (ConnectionError ("testing" ), "testing" )),
422+ (
423+ (ConnectionError ("testing1" ), "testing1" ),
424+ (ConnectionError ("testing2" ), "testing2" ),
425+ ),
426+ ),
427+ )
428+ @responses .activate
429+ def test_delete_failures (
430+ self ,
431+ client ,
432+ server_config ,
433+ pbench_drb_token ,
434+ tarball ,
435+ status1 : tuple [Union [HTTPStatus , Exception ], str ],
436+ status2 : tuple [Union [HTTPStatus , Exception ], str ],
437+ ):
438+ """Verify reporting of delete failures
439+
440+ Ensure successful completion with appropriate notes when deletion of
441+ the relay files fails.
442+ """
443+ file , md5file , md5 = tarball
444+ name = Dataset .stem (file )
445+ responses .add (
446+ responses .GET ,
447+ "https://relay.example.com/uri1" ,
448+ status = HTTPStatus .OK ,
449+ json = {
450+ "uri" : "https://relay.example.com/uri2" ,
451+ "name" : file .name ,
452+ "md5" : md5 ,
453+ "access" : "private" ,
454+ "metadata" : ["global.pbench.test:data" ],
455+ },
456+ )
457+ responses .add (
458+ responses .GET ,
459+ "https://relay.example.com/uri2" ,
460+ status = HTTPStatus .OK ,
461+ body = file .open ("rb" ),
462+ headers = {"content-length" : f"{ file .stat ().st_size } " },
463+ content_type = "application/octet-stream" ,
464+ )
465+ responses .add (
466+ responses .DELETE ,
467+ "https://relay.example.com/uri1" ,
468+ status = status1 [0 ]
469+ if isinstance (status1 [0 ], int )
470+ else HTTPStatus .ALREADY_REPORTED ,
471+ body = status1 [0 ] if isinstance (status1 [0 ], Exception ) else None ,
472+ )
473+ responses .add (
474+ responses .DELETE ,
475+ "https://relay.example.com/uri2" ,
476+ status = status2 [0 ]
477+ if isinstance (status2 [0 ], int )
478+ else HTTPStatus .ALREADY_REPORTED ,
479+ body = status2 [0 ] if isinstance (status2 [0 ], Exception ) else None ,
480+ )
481+ response = client .post (
482+ self .gen_uri (server_config , "https://relay.example.com/uri1" ),
483+ query_string = {"delete" : "true" },
484+ headers = self .gen_headers (pbench_drb_token ),
485+ )
486+ assert (
487+ response .status_code == HTTPStatus .CREATED
488+ ), f"Unexpected result, { response .text } "
489+ expected_notes = [
490+ "Identified benchmark workload 'unknown'." ,
491+ "Expected expiration date is 2025-06-30." ,
492+ ]
493+ if status1 [0 ] != HTTPStatus .OK :
494+ expected_notes .append (
495+ f"Unable to remove relay file https://relay.example.com/uri1: '{ status1 [1 ]} '"
496+ )
497+ if status2 [0 ] != HTTPStatus .OK :
498+ expected_notes .append (
499+ f"Unable to remove relay file https://relay.example.com/uri2: '{ status2 [1 ]} '"
500+ )
501+ assert response .json == {
502+ "message" : "File successfully uploaded" ,
503+ "name" : name ,
504+ "resource_id" : md5 ,
505+ "notes" : expected_notes ,
506+ }
507+ assert len (responses .calls ) == 4
508+ assert (
509+ response .headers ["location" ]
510+ == f"https://localhost/api/v1/datasets/{ md5 } /inventory/"
511+ )
512+
513+ audit = Audit .query ()
514+ assert len (audit ) == 2
515+ assert audit [0 ].id == 1
516+ assert audit [0 ].root_id is None
517+ assert audit [0 ].operation == OperationCode .CREATE
518+ assert audit [0 ].status == AuditStatus .BEGIN
519+ assert audit [0 ].name == "relay"
520+ assert audit [0 ].object_type == AuditType .DATASET
521+ assert audit [0 ].object_id == md5
522+ assert audit [0 ].object_name == name
523+ assert audit [0 ].user_id == DRB_USER_ID
524+ assert audit [0 ].user_name == "drb"
525+ assert audit [0 ].reason is None
526+ assert audit [0 ].attributes == {
527+ "access" : "private" ,
528+ "metadata" : {"global.pbench.test" : "data" },
529+ }
530+ assert audit [1 ].id == 2
531+ assert audit [1 ].root_id == 1
532+ assert audit [1 ].operation == OperationCode .CREATE
533+ assert audit [1 ].status == AuditStatus .SUCCESS
534+ assert audit [1 ].name == "relay"
535+ assert audit [1 ].object_type == AuditType .DATASET
536+ assert audit [1 ].object_id == md5
537+ assert audit [1 ].object_name == name
538+ assert audit [1 ].user_id == DRB_USER_ID
539+ assert audit [1 ].user_name == "drb"
540+ assert audit [1 ].reason is None
541+ assert audit [1 ].attributes == {
542+ "access" : "private" ,
543+ "metadata" : {"global.pbench.test" : "data" },
544+ "notes" : expected_notes ,
545+ }
0 commit comments