)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"3e2851edb01fde5dffd4dbb7605fef150953a469","unresolved":false,"context_lines":[{"line_number":4,"context_line":"Commit:     Tim Burke \u003ctim.burke@gmail.com\u003e"},{"line_number":5,"context_line":"CommitDate: 2018-01-16 10:01:26 -0800"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"expirer: don\u0027t retry 404, 409, or 412 failures"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Related-Change: Icd63c80c73f864d2561e745c3154fbfda02bd0cc"},{"line_number":10,"context_line":"Change-Id: Ie5f2d3824e040bbc76d511a54d1316c4c2503732"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"7f96bb07_957cda83","line":7,"updated":"2018-01-16 20:29:13.000000000","message":"OH, don\u0027t retry *in* make_request","commit_id":"acb6f2082e540e5db6dfdeb605fbd57559c1ea9d"}],"swift/common/internal_client.py":[{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"d4f2b8c278368f25ece3de6e9a1561182453a259","unresolved":false,"context_lines":[{"line_number":202,"context_line":"                elif server_handled_successfully(resp.status_int):"},{"line_number":203,"context_line":"                    # No sense retrying when we expect the same result"},{"line_number":204,"context_line":"                    break"},{"line_number":205,"context_line":"                elif resp.status_int \u003d\u003d HTTP_CONFLICT and \u0027x-timestamp\u0027 in ["},{"line_number":206,"context_line":"                        header.lower() for header in headers]:"},{"line_number":207,"context_line":"                    break"},{"line_number":208,"context_line":"            # sleep only between tries, not after each one"}],"source_content_type":"text/x-python","patch_set":2,"id":"7f96bb07_e39b1615","line":205,"updated":"2018-01-17 09:02:21.000000000","message":"nits) i like to add inline comment picked from the commit message why we can handle the HTTP_CONFLICT as enough response to break.","commit_id":"49f47c6a18758e21acdb2a25e7be8d6ad8d9257a"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"77ecb40bf2bdb88bf6426797dde62c02c9ccfe4a","unresolved":false,"context_lines":[{"line_number":202,"context_line":"                elif server_handled_successfully(resp.status_int):"},{"line_number":203,"context_line":"                    # No sense retrying when we expect the same result"},{"line_number":204,"context_line":"                    break"},{"line_number":205,"context_line":"                elif resp.status_int \u003d\u003d HTTP_CONFLICT and \u0027x-timestamp\u0027 in ["},{"line_number":206,"context_line":"                        header.lower() for header in headers]:"},{"line_number":207,"context_line":"                    break"},{"line_number":208,"context_line":"            # sleep only between tries, not after each one"}],"source_content_type":"text/x-python","patch_set":2,"id":"7f96bb07_d0cd6985","line":205,"in_reply_to":"7f96bb07_e39b1615","updated":"2018-01-17 20:37:51.000000000","message":"Done","commit_id":"49f47c6a18758e21acdb2a25e7be8d6ad8d9257a"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"ce92862a03f7e2a1dd6638fd369c6af13922a247","unresolved":false,"context_lines":[{"line_number":203,"context_line":"                    # No sense retrying when we expect the same result"},{"line_number":204,"context_line":"                    break"},{"line_number":205,"context_line":"                elif resp.status_int \u003d\u003d HTTP_CONFLICT and \u0027x-timestamp\u0027 in ["},{"line_number":206,"context_line":"                        header.lower() for header in headers]:"},{"line_number":207,"context_line":"                    # Since the caller provided the timestamp, retrying won\u0027t"},{"line_number":208,"context_line":"                    # change the result"},{"line_number":209,"context_line":"                    break"}],"source_content_type":"text/x-python","patch_set":5,"id":"7f96bb07_5878708e","line":206,"updated":"2018-01-19 02:35:35.000000000","message":"this seems fairly domain specific to have in the internal_client - I agree we shouldn\u0027t *need* to retry on 409... *sometimes* retrying on 409 because self.app calls time.time seems a little too inscrutable","commit_id":"cd2c73fd955317a3f40758cef45ee48bef8fbc79"}],"swift/container/reconciler.py":[{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"d4f2b8c278368f25ece3de6e9a1561182453a259","unresolved":false,"context_lines":[{"line_number":417,"context_line":"        success \u003d False"},{"line_number":418,"context_line":"        try:"},{"line_number":419,"context_line":"            self.swift.delete_object(account, container, obj,"},{"line_number":420,"context_line":"                                     acceptable_statuses\u003d(2, 404, 409),"},{"line_number":421,"context_line":"                                     headers\u003dheaders)"},{"line_number":422,"context_line":"        except UnexpectedResponse as err:"},{"line_number":423,"context_line":"            self.stats_log(\u0027cleanup_failed\u0027, \u0027%r (%f) was not cleaned up \u0027"}],"source_content_type":"text/x-python","patch_set":2,"id":"7f96bb07_208d74d2","line":420,"range":{"start_line":420,"start_character":66,"end_line":420,"end_character":69},"updated":"2018-01-17 09:02:21.000000000","message":"This change seems correct - if the throw_tombstone to the object in the old policy container comes 409 unfortunately, we could pop the task from queue and expecting to happen re-reconcile (actually check the diff and push the task into the queue) again by container-replicator.\n\nSo... I think this 409 is affected for handling if it\u0027s succeeded or not and it\u0027s worth.\n\nHowever, *I\u0027m worried* about no tests failed if i stash this change to be the original (i.e. w/o 409 as acceptable response).\n\nIf it\u0027s intended to decrease the number of retries, the change in internal client seems enough because it can handle 409 w/ x-timestamp.\n\nSo imo, I like either to add tests for the change above or to separate the change to be one mean per commit.","commit_id":"49f47c6a18758e21acdb2a25e7be8d6ad8d9257a"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"77ecb40bf2bdb88bf6426797dde62c02c9ccfe4a","unresolved":false,"context_lines":[{"line_number":417,"context_line":"        success \u003d False"},{"line_number":418,"context_line":"        try:"},{"line_number":419,"context_line":"            self.swift.delete_object(account, container, obj,"},{"line_number":420,"context_line":"                                     acceptable_statuses\u003d(2, 404, 409),"},{"line_number":421,"context_line":"                                     headers\u003dheaders)"},{"line_number":422,"context_line":"        except UnexpectedResponse as err:"},{"line_number":423,"context_line":"            self.stats_log(\u0027cleanup_failed\u0027, \u0027%r (%f) was not cleaned up \u0027"}],"source_content_type":"text/x-python","patch_set":2,"id":"7f96bb07_507cf981","line":420,"range":{"start_line":420,"start_character":66,"end_line":420,"end_character":69},"in_reply_to":"7f96bb07_208d74d2","updated":"2018-01-17 20:37:51.000000000","message":"Dropped. The one test that fails if I remove 404 from the list of acceptable responses doesn\u0027t seem to translate well to a 409. I\u0027m going to need to know a lot more about how the reconciler works to feel confident in any test I write for this change...","commit_id":"49f47c6a18758e21acdb2a25e7be8d6ad8d9257a"}],"swift/obj/expirer.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"5fe033dca734da3d99e6c2a40ee5b9ee47e9fe42","unresolved":false,"context_lines":[{"line_number":306,"context_line":"            \u0027DELETE\u0027, path,"},{"line_number":307,"context_line":"            {\u0027X-If-Delete-At\u0027: str(timestamp),"},{"line_number":308,"context_line":"             \u0027X-Timestamp\u0027: str(timestamp)},"},{"line_number":309,"context_line":"            (2, HTTP_NOT_FOUND, HTTP_CONFLICT, HTTP_PRECONDITION_FAILED))"},{"line_number":310,"context_line":"        if resp and not is_success(resp.status_int):"},{"line_number":311,"context_line":"            raise UnexpectedResponse("},{"line_number":312,"context_line":"                _(\u0027Unexpected response: %s\u0027) % resp.status, resp)"}],"source_content_type":"text/x-python","patch_set":1,"id":"7f96bb07_d28b5865","line":309,"updated":"2018-01-16 19:55:10.000000000","message":"I don\u0027t think we can ignore 404 and 412 wholesale - a DELETE might 404/412 could happen if the object that corresponds to this row is stuck on handoffs.  I don\u0027t believe the object-server will write tombstones in all the cases we care about (I think x-delete-at might short circuit this behavior).","commit_id":"acb6f2082e540e5db6dfdeb605fbd57559c1ea9d"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"480fbcc7af5bdd18cb8d22bf2c03ced66e2a8903","unresolved":false,"context_lines":[{"line_number":306,"context_line":"            \u0027DELETE\u0027, path,"},{"line_number":307,"context_line":"            {\u0027X-If-Delete-At\u0027: str(timestamp),"},{"line_number":308,"context_line":"             \u0027X-Timestamp\u0027: str(timestamp)},"},{"line_number":309,"context_line":"            (2, HTTP_NOT_FOUND, HTTP_CONFLICT, HTTP_PRECONDITION_FAILED))"},{"line_number":310,"context_line":"        if resp and not is_success(resp.status_int):"},{"line_number":311,"context_line":"            raise UnexpectedResponse("},{"line_number":312,"context_line":"                _(\u0027Unexpected response: %s\u0027) % resp.status, resp)"}],"source_content_type":"text/x-python","patch_set":1,"id":"7f96bb07_72904444","line":309,"in_reply_to":"7f96bb07_d28b5865","updated":"2018-01-16 20:05:01.000000000","message":"we\u0027re not ignoring -- that\u0027s what the manual raise is about. We want this to keep retrying, but we want to wait a while between retries.\n\n\u003e (I think x-delete-at might short circuit this behavior)\n\nX-If-Delete-At totally *does* short circuit this, and with good reason.","commit_id":"acb6f2082e540e5db6dfdeb605fbd57559c1ea9d"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"3e2851edb01fde5dffd4dbb7605fef150953a469","unresolved":false,"context_lines":[{"line_number":309,"context_line":"            (2, HTTP_NOT_FOUND, HTTP_CONFLICT, HTTP_PRECONDITION_FAILED))"},{"line_number":310,"context_line":"        if resp and not is_success(resp.status_int):"},{"line_number":311,"context_line":"            raise UnexpectedResponse("},{"line_number":312,"context_line":"                _(\u0027Unexpected response: %s\u0027) % resp.status, resp)"}],"source_content_type":"text/x-python","patch_set":1,"id":"7f96bb07_f56afeb0","line":312,"updated":"2018-01-16 20:29:13.000000000","message":"sorry, I think I imagined this was just a log line or something... pattern-matching/poor-reading on my part","commit_id":"acb6f2082e540e5db6dfdeb605fbd57559c1ea9d"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"d4f2b8c278368f25ece3de6e9a1561182453a259","unresolved":false,"context_lines":[{"line_number":305,"context_line":"        self.swift.make_request(\u0027DELETE\u0027, path,"},{"line_number":306,"context_line":"                                {\u0027X-If-Delete-At\u0027: str(timestamp),"},{"line_number":307,"context_line":"                                 \u0027X-Timestamp\u0027: str(timestamp)},"},{"line_number":308,"context_line":"                                (2,))"}],"source_content_type":"text/x-python","patch_set":2,"id":"7f96bb07_833812ee","line":308,"updated":"2018-01-17 09:02:21.000000000","message":"If it\u0027s same logic with container-reconciler, we could ignore 409 Conflict, here to pop the task from the queue? That is because 409 Conflicted should be obviously overwritten by another PUT...\n\nAh, ok. I got the answer, delete request with X-If-Delete-At will never respond 409 Conflict. Instead either 404 or 412. [1]\n\nThat makes me sense we don\u0027t have to set the 409 as acceptable here.\n\n1: https://github.com/openstack/swift/blob/master/swift/obj/server.py#L1057-L1078","commit_id":"49f47c6a18758e21acdb2a25e7be8d6ad8d9257a"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"77ecb40bf2bdb88bf6426797dde62c02c9ccfe4a","unresolved":false,"context_lines":[{"line_number":305,"context_line":"        self.swift.make_request(\u0027DELETE\u0027, path,"},{"line_number":306,"context_line":"                                {\u0027X-If-Delete-At\u0027: str(timestamp),"},{"line_number":307,"context_line":"                                 \u0027X-Timestamp\u0027: str(timestamp)},"},{"line_number":308,"context_line":"                                (2,))"}],"source_content_type":"text/x-python","patch_set":2,"id":"7f96bb07_5b53bfe2","line":308,"in_reply_to":"7f96bb07_833812ee","updated":"2018-01-17 20:37:51.000000000","message":"\u003e delete request with X-If-Delete-At will never respond 409 Conflict. Instead either 404 or 412\n\nYeah, I really want to fix that. 412 doesn\u0027t seem appropriate if 409 would be appropriate without the X-If-Delete-At... but that\u0027ll be a separate change...","commit_id":"49f47c6a18758e21acdb2a25e7be8d6ad8d9257a"}],"test/unit/common/test_internal_client.py":[{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"dfa800388abade94c0d5256579dd251470dd0d54","unresolved":false,"context_lines":[{"line_number":463,"context_line":"            client.make_request(\u0027DELETE\u0027, \u0027/container\u0027, {}, (200,))"},{"line_number":464,"context_line":""},{"line_number":465,"context_line":"        # Since we didn\u0027t provide an X-Timestamp, retrying gives us a chance to"},{"line_number":466,"context_line":"        # succeed (assuming the failure was due to clock skew between servers)"},{"line_number":467,"context_line":"        expected \u003d (\u0027 HTTP/1.0 409 \u0027, \u0027 HTTP/1.0 409 \u0027, \u0027 HTTP/1.0 409 \u0027, )"},{"line_number":468,"context_line":"        loglines \u003d client.logger.get_lines_for_level(\u0027info\u0027)"},{"line_number":469,"context_line":"        for expected, logline in izip_longest(expected, loglines):"}],"source_content_type":"text/x-python","patch_set":5,"id":"7f96bb07_d8dec06b","line":466,"updated":"2018-01-19 02:35:06.000000000","message":"Nice.","commit_id":"cd2c73fd955317a3f40758cef45ee48bef8fbc79"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"ce92862a03f7e2a1dd6638fd369c6af13922a247","unresolved":false,"context_lines":[{"line_number":469,"context_line":"        for expected, logline in izip_longest(expected, loglines):"},{"line_number":470,"context_line":"            if not expected:"},{"line_number":471,"context_line":"                self.fail(\u0027Unexpected extra log line: %r\u0027 % logline)"},{"line_number":472,"context_line":"            self.assertIn(expected, logline)"},{"line_number":473,"context_line":""},{"line_number":474,"context_line":"    def test_make_request_acceptable_status_not_2xx(self):"},{"line_number":475,"context_line":"        class InternalClient(internal_client.InternalClient):"}],"source_content_type":"text/x-python","patch_set":5,"id":"7f96bb07_f52145b5","line":472,"updated":"2018-01-19 02:35:35.000000000","message":"desirable or not, i\u0027m not sure it\u0027s internal_client\u0027s job to codify and test something so domain specific.  It\u0027s not obvious to me that it\u0027s internal_client\u0027s job to retry 409s","commit_id":"cd2c73fd955317a3f40758cef45ee48bef8fbc79"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"ce92862a03f7e2a1dd6638fd369c6af13922a247","unresolved":false,"context_lines":[{"line_number":487,"context_line":"                body \u003d \u0027fake error response\u0027"},{"line_number":488,"context_line":"                start_response(self.resp_status,"},{"line_number":489,"context_line":"                               [(\u0027Content-Length\u0027, str(len(body)))])"},{"line_number":490,"context_line":"                return LeakTrackingIter(body, self.closed_paths.append,"},{"line_number":491,"context_line":"                                        env[\u0027PATH_INFO\u0027])"},{"line_number":492,"context_line":""},{"line_number":493,"context_line":"        def do_test(resp_status):"}],"source_content_type":"text/x-python","patch_set":5,"id":"7f96bb07_551cb976","line":490,"updated":"2018-01-19 02:35:35.000000000","message":"passing in the builtin as the mark_closed callback it super sexy - kudos","commit_id":"cd2c73fd955317a3f40758cef45ee48bef8fbc79"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"ce92862a03f7e2a1dd6638fd369c6af13922a247","unresolved":false,"context_lines":[{"line_number":513,"context_line":"        for expected, logline in izip_longest(expected, loglines):"},{"line_number":514,"context_line":"            if not expected:"},{"line_number":515,"context_line":"                self.fail(\u0027Unexpected extra log line: %r\u0027 % logline)"},{"line_number":516,"context_line":"            self.assertIn(expected, logline)"},{"line_number":517,"context_line":""},{"line_number":518,"context_line":"        closed_paths, resp, loglines \u003d do_test(\u0027503 Service Unavailable\u0027)"},{"line_number":519,"context_line":"        # But since 5xx is neither \"properly handled\" not likely to include"}],"source_content_type":"text/x-python","patch_set":5,"id":"7f96bb07_380a441f","line":516,"updated":"2018-01-19 02:35:35.000000000","message":"seems reasonable to me, if the caller wants to \"retry a 2xx\" they can write their own retry loop.","commit_id":"cd2c73fd955317a3f40758cef45ee48bef8fbc79"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"ce92862a03f7e2a1dd6638fd369c6af13922a247","unresolved":false,"context_lines":[{"line_number":520,"context_line":"        # a large body, it will be retried and responses will already be closed"},{"line_number":521,"context_line":"        self.assertEqual(closed_paths, [\u0027/cont/obj\u0027] * 3)"},{"line_number":522,"context_line":""},{"line_number":523,"context_line":"        expected \u003d (\u0027 HTTP/1.0 503 \u0027, \u0027 HTTP/1.0 503 \u0027, \u0027 HTTP/1.0 503 \u0027, )"},{"line_number":524,"context_line":"        for expected, logline in izip_longest(expected, loglines):"},{"line_number":525,"context_line":"            if not expected:"},{"line_number":526,"context_line":"                self.fail(\u0027Unexpected extra log line: %r\u0027 % logline)"}],"source_content_type":"text/x-python","patch_set":5,"id":"7f96bb07_f80ffc2a","line":523,"updated":"2018-01-19 02:35:35.000000000","message":"LGTM","commit_id":"cd2c73fd955317a3f40758cef45ee48bef8fbc79"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"ce92862a03f7e2a1dd6638fd369c6af13922a247","unresolved":false,"context_lines":[{"line_number":605,"context_line":"            self.assertEqual(client.call_count, expected_calls)"},{"line_number":606,"context_line":""},{"line_number":607,"context_line":"        do_test(\u0027404 Not Found\u0027, 1)"},{"line_number":608,"context_line":"        do_test(\u0027503 Service Unavailable\u0027, 3)"},{"line_number":609,"context_line":""},{"line_number":610,"context_line":"    def test_make_request_request_exception(self):"},{"line_number":611,"context_line":"        class InternalClient(internal_client.InternalClient):"}],"source_content_type":"text/x-python","patch_set":5,"id":"7f96bb07_b815f43e","line":608,"updated":"2018-01-19 02:35:35.000000000","message":"cool!","commit_id":"cd2c73fd955317a3f40758cef45ee48bef8fbc79"}],"test/unit/obj/test_expirer.py":[{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"d4f2b8c278368f25ece3de6e9a1561182453a259","unresolved":false,"context_lines":[{"line_number":755,"context_line":"        # object was deleted and tombstone reaped"},{"line_number":756,"context_line":"        do_test(\u0027404 Not Found\u0027)"},{"line_number":757,"context_line":"        # object was overwritten *after* the original expiration"},{"line_number":758,"context_line":"        do_test(\u0027409 Conflict\u0027)"},{"line_number":759,"context_line":"        # object was deleted but tombstone still exists, or"},{"line_number":760,"context_line":"        # object was overwritten ahead of the original expiration, or"},{"line_number":761,"context_line":"        # object was POSTed to with a new (or no) expiration, or ..."}],"source_content_type":"text/x-python","patch_set":2,"id":"7f96bb07_86b3400a","line":758,"updated":"2018-01-17 09:02:21.000000000","message":"Regarding to my comment at [1], this test is weird because the request with x-if-delete-at doesn\u0027t return 409 Conflicted if i understand correctly. In my idea, object-server will 404 NotFound when a newer object found (i.e. overwritten after the original expiration) ...\n\n1: https://review.openstack.org/#/c/534399/2/swift/obj/expirer.py@308","commit_id":"49f47c6a18758e21acdb2a25e7be8d6ad8d9257a"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"77ecb40bf2bdb88bf6426797dde62c02c9ccfe4a","unresolved":false,"context_lines":[{"line_number":755,"context_line":"        # object was deleted and tombstone reaped"},{"line_number":756,"context_line":"        do_test(\u0027404 Not Found\u0027)"},{"line_number":757,"context_line":"        # object was overwritten *after* the original expiration"},{"line_number":758,"context_line":"        do_test(\u0027409 Conflict\u0027)"},{"line_number":759,"context_line":"        # object was deleted but tombstone still exists, or"},{"line_number":760,"context_line":"        # object was overwritten ahead of the original expiration, or"},{"line_number":761,"context_line":"        # object was POSTed to with a new (or no) expiration, or ..."}],"source_content_type":"text/x-python","patch_set":2,"id":"7f96bb07_f0266568","line":758,"in_reply_to":"7f96bb07_86b3400a","updated":"2018-01-17 20:37:51.000000000","message":"Dropped until we actually start returning 409s.","commit_id":"49f47c6a18758e21acdb2a25e7be8d6ad8d9257a"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"7799d7f773392e137cf17d1e1bf50b505078421d","unresolved":false,"context_lines":[{"line_number":754,"context_line":""},{"line_number":755,"context_line":"        # object was deleted and tombstone reaped"},{"line_number":756,"context_line":"        do_test(\u0027404 Not Found\u0027)"},{"line_number":757,"context_line":"        # object was overwritten *after* the original expiration, or"},{"line_number":758,"context_line":"        # object was deleted but tombstone still exists, or"},{"line_number":759,"context_line":"        # object was overwritten ahead of the original expiration, or"},{"line_number":760,"context_line":"        # object was POSTed to with a new (or no) expiration, or ..."}],"source_content_type":"text/x-python","patch_set":4,"id":"7f96bb07_6ac80ea5","line":757,"range":{"start_line":757,"start_character":8,"end_line":757,"end_character":65},"updated":"2018-01-18 09:46:28.000000000","message":"perhaps, the overwritten will be 404 but okay, no big problem for understanding for us.","commit_id":"98bfcc8b474fd0b12a0fc655fe581753462779ac"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"ce92862a03f7e2a1dd6638fd369c6af13922a247","unresolved":false,"context_lines":[{"line_number":764,"context_line":"        # object was deleted but tombstone still exists, or"},{"line_number":765,"context_line":"        # object was overwritten ahead of the original expiration, or"},{"line_number":766,"context_line":"        # object was POSTed to with a new (or no) expiration, or ..."},{"line_number":767,"context_line":"        do_test(\u0027412 Precondition Failed\u0027)"},{"line_number":768,"context_line":""},{"line_number":769,"context_line":"    def test_delete_actual_object_does_not_handle_odd_stuff(self):"},{"line_number":770,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"7f96bb07_b82e5489","line":767,"updated":"2018-01-19 02:35:35.000000000","message":"consolidation","commit_id":"cd2c73fd955317a3f40758cef45ee48bef8fbc79"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"ce92862a03f7e2a1dd6638fd369c6af13922a247","unresolved":false,"context_lines":[{"line_number":791,"context_line":"        timestamp \u003d \u00271366063156.863045\u0027"},{"line_number":792,"context_line":"        x \u003d expirer.ObjectExpirer({})"},{"line_number":793,"context_line":"        x.swift.make_request \u003d mock.Mock()"},{"line_number":794,"context_line":"        x.swift.make_request.return_value.status_int \u003d 204"},{"line_number":795,"context_line":"        x.delete_actual_object(name, timestamp)"},{"line_number":796,"context_line":"        self.assertEqual(x.swift.make_request.call_count, 1)"},{"line_number":797,"context_line":"        self.assertEqual(x.swift.make_request.call_args[0][1],"}],"source_content_type":"text/x-python","patch_set":5,"id":"7f96bb07_584f106a","line":794,"updated":"2018-01-19 02:35:35.000000000","message":"cleanup","commit_id":"cd2c73fd955317a3f40758cef45ee48bef8fbc79"}]}
