)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"77795ac7ceb81f35b146d085d9ff3aee7e3afb2c","unresolved":true,"context_lines":[{"line_number":4,"context_line":"Commit:     ashnair \u003cashnair@nvidia.com\u003e"},{"line_number":5,"context_line":"CommitDate: 2024-10-22 13:56:19 -0700"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"refactor test for x-delete-at w/t part_num and x-open-expired"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Change-Id: Ia1d8d9085bad5c6df744a4551eef9dcf56e6e261"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":2,"id":"a1b9a4cd_e0ee1b60","line":7,"updated":"2024-10-22 21:28:11.000000000","message":"Why are we refactoring? What\u0027s the issue with the test as it stands now?\n\n(I know, we\u0027ve been talking about it out of band -- but it\u0027ll be helpful for future-us to have some of the reasoning written down in the commit message.)","commit_id":"051b0294ad884b10cebafbd0d53db0fd9eb7e10a"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"4d276be18006210b1034acb840db3c41ea8772c0","unresolved":false,"context_lines":[{"line_number":4,"context_line":"Commit:     ashnair \u003cashnair@nvidia.com\u003e"},{"line_number":5,"context_line":"CommitDate: 2024-10-22 13:56:19 -0700"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"refactor test for x-delete-at w/t part_num and x-open-expired"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Change-Id: Ia1d8d9085bad5c6df744a4551eef9dcf56e6e261"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":2,"id":"17840802_46a48b09","line":7,"in_reply_to":"a1b9a4cd_e0ee1b60","updated":"2024-10-23 22:00:23.000000000","message":"Done","commit_id":"051b0294ad884b10cebafbd0d53db0fd9eb7e10a"}],"/PATCHSET_LEVEL":[{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"29b8c6e2090d78859016d73e34e8ffc7cf324470","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":9,"id":"449641a5_ec307c36","updated":"2025-02-13 19:01:15.000000000","message":"Waiting on tests to pass","commit_id":"1f3eb1e7949bd0c311806936972907ae5868988e"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"ef7972daeb067d163b89034a92d1c517a95fe876","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":12,"id":"cc930767_27cac17c","updated":"2025-02-14 17:52:38.000000000","message":"i had some left over drafts I didn\u0027t push yesterday because I was planning to retest but then it started to look like it wasn\u0027t actually doing what we set out to do so I pulled back...\n\nmaybe look int the zuul errors and let me know if you need another review!","commit_id":"480698152a5518cd7f6fcda091525eabe20edf00"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"04e2adede0970b8b74ecbc941ed914b2ab0797c6","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":14,"id":"03440fa9_6804f445","updated":"2025-02-18 20:01:58.000000000","message":"This works!","commit_id":"c3237aba14a87b78f63721fbf92fd07e770cda97"}],"test/functional/test_slo.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"77795ac7ceb81f35b146d085d9ff3aee7e3afb2c","unresolved":true,"context_lines":[{"line_number":496,"context_line":"                body\u003djson.dumps(manifest_data),"},{"line_number":497,"context_line":"                headers\u003d{"},{"line_number":498,"context_line":"                    \u0027X-Auth-Token\u0027: token,"},{"line_number":499,"context_line":"                    \u0027X-Delete-At\u0027: delete_time,"},{"line_number":500,"context_line":"                    \u0027X-Static-Large-Object\u0027: \u0027true\u0027,"},{"line_number":501,"context_line":"                    \u0027Content-Type\u0027: \u0027application/json\u0027"},{"line_number":502,"context_line":"                }"}],"source_content_type":"text/x-python","patch_set":2,"id":"52ccb93f_4be2e10c","line":499,"updated":"2024-10-22 21:28:11.000000000","message":"We might want to use `X-Delete-After` so we don\u0027t have to rely on client/server clock synchronization at all here.","commit_id":"051b0294ad884b10cebafbd0d53db0fd9eb7e10a"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"57343600889d65e6c9a70fd3672178aef9a45310","unresolved":false,"context_lines":[{"line_number":496,"context_line":"                body\u003djson.dumps(manifest_data),"},{"line_number":497,"context_line":"                headers\u003d{"},{"line_number":498,"context_line":"                    \u0027X-Auth-Token\u0027: token,"},{"line_number":499,"context_line":"                    \u0027X-Delete-At\u0027: delete_time,"},{"line_number":500,"context_line":"                    \u0027X-Static-Large-Object\u0027: \u0027true\u0027,"},{"line_number":501,"context_line":"                    \u0027Content-Type\u0027: \u0027application/json\u0027"},{"line_number":502,"context_line":"                }"}],"source_content_type":"text/x-python","patch_set":2,"id":"2ff35acb_136a793c","line":499,"in_reply_to":"52ccb93f_4be2e10c","updated":"2024-10-23 21:59:58.000000000","message":"Acknowledged","commit_id":"051b0294ad884b10cebafbd0d53db0fd9eb7e10a"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"77795ac7ceb81f35b146d085d9ff3aee7e3afb2c","unresolved":true,"context_lines":[{"line_number":518,"context_line":"                    body\u003dobject_segments[objnum],"},{"line_number":519,"context_line":"                    headers\u003d{"},{"line_number":520,"context_line":"                        \u0027X-Auth-Token\u0027: token,"},{"line_number":521,"context_line":"                        \u0027X-Delete-At\u0027: delete_time})"},{"line_number":522,"context_line":"                resp \u003d check_response(conn)"},{"line_number":523,"context_line":"                body \u003d resp.read()"},{"line_number":524,"context_line":"                self.assertEqual(resp.status, 201,"}],"source_content_type":"text/x-python","patch_set":2,"id":"0d25bf59_4b5ae348","line":521,"updated":"2024-10-22 21:28:11.000000000","message":"This one\u0027s more annoying, though, since we want all of the segments to expire at the same time...","commit_id":"051b0294ad884b10cebafbd0d53db0fd9eb7e10a"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"dc6f41862b603c3347ca6e92d437df78ebeba4b9","unresolved":true,"context_lines":[{"line_number":518,"context_line":"                    body\u003dobject_segments[objnum],"},{"line_number":519,"context_line":"                    headers\u003d{"},{"line_number":520,"context_line":"                        \u0027X-Auth-Token\u0027: token,"},{"line_number":521,"context_line":"                        \u0027X-Delete-At\u0027: delete_time})"},{"line_number":522,"context_line":"                resp \u003d check_response(conn)"},{"line_number":523,"context_line":"                body \u003d resp.read()"},{"line_number":524,"context_line":"                self.assertEqual(resp.status, 201,"}],"source_content_type":"text/x-python","patch_set":2,"id":"66feb8c2_abe9535e","line":521,"in_reply_to":"0d25bf59_4b5ae348","updated":"2024-10-30 19:11:30.000000000","message":"Correct, which is why `delete_time`is set outside of the for loop","commit_id":"051b0294ad884b10cebafbd0d53db0fd9eb7e10a"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"29b8c6e2090d78859016d73e34e8ffc7cf324470","unresolved":false,"context_lines":[{"line_number":518,"context_line":"                    body\u003dobject_segments[objnum],"},{"line_number":519,"context_line":"                    headers\u003d{"},{"line_number":520,"context_line":"                        \u0027X-Auth-Token\u0027: token,"},{"line_number":521,"context_line":"                        \u0027X-Delete-At\u0027: delete_time})"},{"line_number":522,"context_line":"                resp \u003d check_response(conn)"},{"line_number":523,"context_line":"                body \u003d resp.read()"},{"line_number":524,"context_line":"                self.assertEqual(resp.status, 201,"}],"source_content_type":"text/x-python","patch_set":2,"id":"653e48fe_4eb7d6af","line":521,"in_reply_to":"66feb8c2_abe9535e","updated":"2025-02-13 19:01:15.000000000","message":"Done","commit_id":"051b0294ad884b10cebafbd0d53db0fd9eb7e10a"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"77795ac7ceb81f35b146d085d9ff3aee7e3afb2c","unresolved":true,"context_lines":[{"line_number":591,"context_line":"                resp \u003d retry(get_or_head_part, method\u003d\u0027HEAD\u0027,"},{"line_number":592,"context_line":"                             part_number\u003dpart_num)"},{"line_number":593,"context_line":"                resp.read()"},{"line_number":594,"context_line":"                if resp.status \u003d\u003d 404:"},{"line_number":595,"context_line":"                    break"},{"line_number":596,"context_line":"                time.sleep(1)  # wait for 1 second before retrying"},{"line_number":597,"context_line":"            self.assertEqual(resp.status, 404)"}],"source_content_type":"text/x-python","patch_set":2,"id":"a47d1085_0ca5cda5","line":594,"updated":"2024-10-22 21:28:11.000000000","message":"There\u0027s a lot of things it could be besides 204 and 404 (401, 503, 500) -- should we care?","commit_id":"051b0294ad884b10cebafbd0d53db0fd9eb7e10a"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"2a4efaa565cd8b70748bf743397b1cf72cbe1b76","unresolved":false,"context_lines":[{"line_number":591,"context_line":"                resp \u003d retry(get_or_head_part, method\u003d\u0027HEAD\u0027,"},{"line_number":592,"context_line":"                             part_number\u003dpart_num)"},{"line_number":593,"context_line":"                resp.read()"},{"line_number":594,"context_line":"                if resp.status \u003d\u003d 404:"},{"line_number":595,"context_line":"                    break"},{"line_number":596,"context_line":"                time.sleep(1)  # wait for 1 second before retrying"},{"line_number":597,"context_line":"            self.assertEqual(resp.status, 404)"}],"source_content_type":"text/x-python","patch_set":2,"id":"1b8ab7af_b73844da","line":594,"in_reply_to":"a47d1085_0ca5cda5","updated":"2024-10-23 22:00:12.000000000","message":"Acknowledged","commit_id":"051b0294ad884b10cebafbd0d53db0fd9eb7e10a"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"ef7972daeb067d163b89034a92d1c517a95fe876","unresolved":true,"context_lines":[{"line_number":492,"context_line":"                body\u003djson.dumps(manifest_data),"},{"line_number":493,"context_line":"                headers\u003d{"},{"line_number":494,"context_line":"                    \u0027X-Auth-Token\u0027: token,"},{"line_number":495,"context_line":"                    \u0027X-Delete-After\u0027: \u00272\u0027,"},{"line_number":496,"context_line":"                    \u0027X-Static-Large-Object\u0027: \u0027true\u0027,"},{"line_number":497,"context_line":"                    \u0027Content-Type\u0027: \u0027application/json\u0027"},{"line_number":498,"context_line":"                }"}],"source_content_type":"text/x-python","patch_set":11,"id":"3d4e5319_7e60359d","line":495,"updated":"2025-02-14 17:52:38.000000000","message":"if feels like this should either be a parameter or part of the function name.","commit_id":"e480a0364894802db0a5cff4be2b32b6575efff5"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"04e2adede0970b8b74ecbc941ed914b2ab0797c6","unresolved":false,"context_lines":[{"line_number":492,"context_line":"                body\u003djson.dumps(manifest_data),"},{"line_number":493,"context_line":"                headers\u003d{"},{"line_number":494,"context_line":"                    \u0027X-Auth-Token\u0027: token,"},{"line_number":495,"context_line":"                    \u0027X-Delete-After\u0027: \u00272\u0027,"},{"line_number":496,"context_line":"                    \u0027X-Static-Large-Object\u0027: \u0027true\u0027,"},{"line_number":497,"context_line":"                    \u0027Content-Type\u0027: \u0027application/json\u0027"},{"line_number":498,"context_line":"                }"}],"source_content_type":"text/x-python","patch_set":11,"id":"776fa6a6_4ab3194c","line":495,"in_reply_to":"3d4e5319_7e60359d","updated":"2025-02-18 20:01:58.000000000","message":"Done","commit_id":"e480a0364894802db0a5cff4be2b32b6575efff5"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"ef7972daeb067d163b89034a92d1c517a95fe876","unresolved":true,"context_lines":[{"line_number":540,"context_line":"        # wait for the manifest to expire"},{"line_number":541,"context_line":"        # the objects will also have expired at the same time"},{"line_number":542,"context_line":"        # since their x-delete-at times are the same"},{"line_number":543,"context_line":"        time.sleep(2)"},{"line_number":544,"context_line":"        resp \u003d retry(get_manifest)"},{"line_number":545,"context_line":"        resp.read()"},{"line_number":546,"context_line":"        # check to see manifest has expired"}],"source_content_type":"text/x-python","patch_set":11,"id":"82abfe68_040bbb2c","line":543,"updated":"2025-02-14 17:52:38.000000000","message":"if this test has truly resolved the requirement for time syncronization with the server we should be able to remove this sleep.  This sleep indicates that we expect the server time to not expire the object until after our client time has passed 2s; although it\u0027s POSSIBLE if the server is running slow it might take longer, or fast that it may be done sooner!","commit_id":"e480a0364894802db0a5cff4be2b32b6575efff5"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"04e2adede0970b8b74ecbc941ed914b2ab0797c6","unresolved":false,"context_lines":[{"line_number":540,"context_line":"        # wait for the manifest to expire"},{"line_number":541,"context_line":"        # the objects will also have expired at the same time"},{"line_number":542,"context_line":"        # since their x-delete-at times are the same"},{"line_number":543,"context_line":"        time.sleep(2)"},{"line_number":544,"context_line":"        resp \u003d retry(get_manifest)"},{"line_number":545,"context_line":"        resp.read()"},{"line_number":546,"context_line":"        # check to see manifest has expired"}],"source_content_type":"text/x-python","patch_set":11,"id":"0f17e809_03e462af","line":543,"in_reply_to":"82abfe68_040bbb2c","updated":"2025-02-18 20:01:58.000000000","message":"Done","commit_id":"e480a0364894802db0a5cff4be2b32b6575efff5"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"04e2adede0970b8b74ecbc941ed914b2ab0797c6","unresolved":true,"context_lines":[{"line_number":503,"context_line":""},{"line_number":504,"context_line":"        def put_segments(url, token, parsed, conn, object_segments):"},{"line_number":505,"context_line":"            now \u003d int(time.time())"},{"line_number":506,"context_line":"            delete_time \u003d now + 2"},{"line_number":507,"context_line":""},{"line_number":508,"context_line":"            for objnum in range(len(object_segments)):"},{"line_number":509,"context_line":"                conn.request(\u0027PUT\u0027, \u0027%s/%s/segments/%s\u0027 % ("}],"source_content_type":"text/x-python","patch_set":14,"id":"5acdee72_a921e725","line":506,"updated":"2025-02-18 20:01:58.000000000","message":"maybe a little confusing that the segments don\u0027t expire at the same time as manifest - they might actually expire *before* except this is hard-coded to `2s` and the manifest is uploaded with `delete-after: 1`","commit_id":"c3237aba14a87b78f63721fbf92fd07e770cda97"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"04e2adede0970b8b74ecbc941ed914b2ab0797c6","unresolved":true,"context_lines":[{"line_number":529,"context_line":"                headers.update(extra_headers)"},{"line_number":530,"context_line":"            conn.request("},{"line_number":531,"context_line":"                \u0027GET\u0027,"},{"line_number":532,"context_line":"                \u0027%s/%s/manifest?multipart-manifest\u003dget\u0027 %"},{"line_number":533,"context_line":"                (parsed.path, cont_name),"},{"line_number":534,"context_line":"                \u0027\u0027, headers)"},{"line_number":535,"context_line":"            return check_response(conn)"}],"source_content_type":"text/x-python","patch_set":14,"id":"51f014b0_51a74507","line":532,"updated":"2025-02-18 20:01:58.000000000","message":"I had missed that `get_manifest` is actually getting the *manifest* (it\u0027s not trying to download the segments) - so it doesn\u0027t get a 409 if they expire before the manifest does.","commit_id":"c3237aba14a87b78f63721fbf92fd07e770cda97"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"04e2adede0970b8b74ecbc941ed914b2ab0797c6","unresolved":true,"context_lines":[{"line_number":551,"context_line":"                self.fail("},{"line_number":552,"context_line":"                    f\u0027manifest still returns {resp.status} after \u0027"},{"line_number":553,"context_line":"                    f\u0027we set x-delete-after to 2s post object \u0027"},{"line_number":554,"context_line":"                    f\u0027creation\u0027)"},{"line_number":555,"context_line":""},{"line_number":556,"context_line":"            self.assertEqual(resp.status, 404,"},{"line_number":557,"context_line":"                             resp.headers.get(\u0027x-trans-id\u0027))"}],"source_content_type":"text/x-python","patch_set":14,"id":"f9c7cef2_c7d003b0","line":554,"updated":"2025-02-18 20:01:58.000000000","message":"this looks not bad; after I increase the x_delete_after param for put_manifest to 100 I get a failure like:\n\n```\nswift/test/functional/test_slo.py:551: in get_manifest_still_expired\n    self.fail(\nE   AssertionError: manifest still returns 200 after we set x-delete-after to 2s post object creation\n```\n\nthere\u0027s some coupling between this error message and the value we pass to put_manifest - since everything in here is a closure we might just use a variable scoped at the same level as say ... \"cont_name\"","commit_id":"c3237aba14a87b78f63721fbf92fd07e770cda97"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"04e2adede0970b8b74ecbc941ed914b2ab0797c6","unresolved":true,"context_lines":[{"line_number":563,"context_line":"            self.assertEqual(resp.status, 200)"},{"line_number":564,"context_line":"            resp.read()"},{"line_number":565,"context_line":""},{"line_number":566,"context_line":"        get_manifest_with_open_expire()"},{"line_number":567,"context_line":""},{"line_number":568,"context_line":"        def get_or_head_part(url, token, parsed, conn,"},{"line_number":569,"context_line":"                             extra_headers\u003dNone, method\u003d\u0027GET\u0027,"}],"source_content_type":"text/x-python","patch_set":14,"id":"3ed9c78c_c130a702","line":566,"updated":"2025-02-18 20:01:58.000000000","message":"I\u0027m not sure the closure adds much here; using an iterative/declarative style when possible is probably normally best.","commit_id":"c3237aba14a87b78f63721fbf92fd07e770cda97"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"04e2adede0970b8b74ecbc941ed914b2ab0797c6","unresolved":true,"context_lines":[{"line_number":599,"context_line":"            for objnum, segment in enumerate(segments):"},{"line_number":600,"context_line":"                part_num \u003d str(objnum + 1)"},{"line_number":601,"context_line":"                start_time \u003d time.time()"},{"line_number":602,"context_line":"                while time.time() - start_time \u003c timeout:"},{"line_number":603,"context_line":"                    resp \u003d retry(get_or_head_part, method\u003dmethod,"},{"line_number":604,"context_line":"                                 part_number\u003dpart_num)"},{"line_number":605,"context_line":"                    resp.read()"}],"source_content_type":"text/x-python","patch_set":14,"id":"c0e4a37d_b3d9b562","line":602,"updated":"2025-02-18 20:01:58.000000000","message":"the timeout probably isn\u0027t helping much here and could potentially be hiding an inconsistency - I would believe that as soon as the manifest is expired the part-num requests should also start returning 404\n\nBut it turns out we\u0027re setting *different* x-delete-at on the segments and manifest - and while *this* check is actually trying to read the expired manifest and fetch the potentially expired segments - the test \"with out part-num\" is actually just fetching the manifest directly (and so NOT trying to read the potentially expired segments).  Since we wait for the manifest to expire before we start making these part-num requests there\u0027s no situation to encounter an unexpired manifest trying to fetch an expired segment.  These requests always 404 because the manifest is already expired (regardless if you extend the x-delete-at of the segments)\n\nI think having expiration set on the segments is probably confusing `test_x_delete_at_with_part_number_and_open_expired` which is really just trying to verify that after the manifest expires you can still make part-num reqeusts with x-open-expired\n\nIf we want to test what happens when you set expiration on segments it might be better to not set an expiration on the manifest at all.  In my testing you get a 409 if you try to get whole SLO and a 404 if you try to get a specific part - but all of it works if you send x-open-expired (which is just getting forward to the segment GET requests regardless of the expiration status of the manifest)","commit_id":"c3237aba14a87b78f63721fbf92fd07e770cda97"}]}
