)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"65e64b1d703041d5ae0fae1e2100c863b3e9d7aa","unresolved":false,"context_lines":[{"line_number":27,"context_line":"As a result, we\u0027re forced to treat Glance as yet another \"special\""},{"line_number":28,"context_line":"service when it comes to pagination. The first step of this is to look"},{"line_number":29,"context_line":"for the \u0027next\u0027 field and grab the value. As you can see, this value"},{"line_number":30,"context_line":"also includes the version prefix, which we don\u0027t want this since"},{"line_number":31,"context_line":"keystoneauth1 already appends the version prefix when generating"},{"line_number":32,"context_line":"absolute URLs from information in the service catalog. This means our"},{"line_number":33,"context_line":"next step is to strip this version filter, which we have done since"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":9,"id":"77566a32_74d4c9ae","line":30,"range":{"start_line":30,"start_character":54,"end_line":30,"end_character":58},"updated":"2022-09-07 10:01:08.000000000","message":"~strike~ this","commit_id":"0529c30ae2958338aa8c0d56066b762eb412adcc"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"65e64b1d703041d5ae0fae1e2100c863b3e9d7aa","unresolved":false,"context_lines":[{"line_number":39,"context_line":"upper limit on the size of URLs, it\u0027s important that we don\u0027t constantly"},{"line_number":40,"context_line":"append our query parameters to the request URL for each page. Instead,"},{"line_number":41,"context_line":"we parse the query parameters present in the \u0027next\u0027 URL and munge them"},{"line_number":42,"context_line":"with our our parameters. The way we do this is using"},{"line_number":43,"context_line":"\u0027urllib.parse.urljoin\u0027 method with this pattern:"},{"line_number":44,"context_line":""},{"line_number":45,"context_line":"  urljoin(url, urlparse(url).path)"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":9,"id":"ca504871_34bd53f0","line":42,"range":{"start_line":42,"start_character":9,"end_line":42,"end_character":12},"updated":"2022-09-07 10:01:08.000000000","message":"own","commit_id":"0529c30ae2958338aa8c0d56066b762eb412adcc"}],"/PATCHSET_LEVEL":[{"author":{"_account_id":27900,"name":"Artem Goncharov","email":"artem.goncharov@gmail.com","username":"gtema"},"change_message_id":"83dc300c16167c21ac30aac0cb7dd26fab25a43a","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"22c3f4ba_4f16e1d3","updated":"2022-08-18 13:26:27.000000000","message":"For such a change please provide test cases proving it works properly and verifying that current pagination is not working.\nAlso you rely on some private (or not really public) method from side library. This should always be avoided (and actually forbidden) or at least every time provable with the relevant test case","commit_id":"afc02b37e8189110154b2e23fc41038a4ffa42ca"},{"author":{"_account_id":7953,"name":"Ulrich Schwickerath","email":"Ulrich.Schwickerath@cern.ch","username":"schwicke"},"change_message_id":"5feb380fb8a30d578378ad23c1ce37b5f812b480","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"3b0cb633_9d47e552","in_reply_to":"22c3f4ba_4f16e1d3","updated":"2022-08-19 13:25:13.000000000","message":"Many thanks for the quick review! All very valid points.\nWe\u0027ve submitted 2 additional patch sets now:\n\nPatch set 3: contains only additional tests for base_urls with a sub structure. This patch set will fail in the tests, with the symptom that the url expected is of the form a/b while what is returned by the existing code is a/a/b. \n\nPatch set 4: contains our actual bug fix. This has been redone to avoid using an any private functions. This patch set is supposed to pass all tests, including the new one submitted by patch set 3.","commit_id":"afc02b37e8189110154b2e23fc41038a4ffa42ca"},{"author":{"_account_id":20498,"name":"Spyros Trigazis","email":"spyridon.trigazis@cern.ch","username":"strigazi"},"change_message_id":"6554c17d9ab59be5c99625154f320651c42dc603","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"c0e617f2_5e340485","updated":"2022-08-23 11:51:08.000000000","message":"Areg, can you submit the code from patch 3 again and let the CI run to see the expected failure?\n\nOnly then, push the code from patch 4. ","commit_id":"a8a7b056daeb02fdc1955696cb47736e48e1e331"},{"author":{"_account_id":20498,"name":"Spyros Trigazis","email":"spyridon.trigazis@cern.ch","username":"strigazi"},"change_message_id":"710fdc7e220328bd30b0031bcca4e81de9ab44ef","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"55dc3418_d275dfdc","in_reply_to":"c0e617f2_5e340485","updated":"2022-08-23 14:14:36.000000000","message":"Thanks!\n\nHere is the expected failure:\n2022-08-23 12:05:47.692946 | ubuntu-focal | \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\n2022-08-23 12:05:47.692952 | ubuntu-focal | Failed 1 tests - output below:\n2022-08-23 12:05:47.692957 | ubuntu-focal | \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\n2022-08-23 12:05:47.692961 | ubuntu-focal |\n2022-08-23 12:05:47.692965 | ubuntu-focal | openstack.tests.unit.test_resource.TestResourceActionsComplex.test_list_multi_page_header_count\n2022-08-23 12:05:47.692970 | ubuntu-focal | -----------------------------------------------------------------------------------------------\n2022-08-23 12:05:47.692974 | ubuntu-focal |\n2022-08-23 12:05:47.692978 | ubuntu-focal | Captured traceback:\n2022-08-23 12:05:47.692982 | ubuntu-focal | ~~~~~~~~~~~~~~~~~~~\n2022-08-23 12:05:47.692996 | ubuntu-focal |     Traceback (most recent call last):\n2022-08-23 12:05:47.693003 | ubuntu-focal |\n2022-08-23 12:05:47.693009 | ubuntu-focal |       File \"/home/zuul/src/opendev.org/openstack/openstacksdk/openstack/tests/unit/test_resource.py\", line 3905, in test_list_multi_page_header_count\n2022-08-23 12:05:47.693015 | ubuntu-focal |     self.session.get.assert_called_with(\n2022-08-23 12:05:47.693020 | ubuntu-focal |\n2022-08-23 12:05:47.693024 | ubuntu-focal |       File \"/usr/lib/python3.8/unittest/mock.py\", line 913, in assert_called_with\n2022-08-23 12:05:47.693033 | ubuntu-focal |     raise AssertionError(_error_message()) from cause\n2022-08-23 12:05:47.693038 | ubuntu-focal |\n2022-08-23 12:05:47.693042 | ubuntu-focal |     AssertionError: expected call not found.\n2022-08-23 12:05:47.693046 | ubuntu-focal | Expected: get(\u0027base_path/something\u0027, headers\u003d{\u0027Accept\u0027: \u0027application/json\u0027}, params\u003d{\u0027marker\u0027: 2}, microversion\u003dNone)\n2022-08-23 12:05:47.693050 | ubuntu-focal | Actual: get(\u0027base_path/base_path/something\u0027, headers\u003d{\u0027Accept\u0027: \u0027application/json\u0027}, params\u003d{\u0027marker\u0027: 2}, microversion\u003dNone)","commit_id":"a8a7b056daeb02fdc1955696cb47736e48e1e331"},{"author":{"_account_id":7953,"name":"Ulrich Schwickerath","email":"Ulrich.Schwickerath@cern.ch","username":"schwicke"},"change_message_id":"ffa776157a9fdbee34d6f91036c8f4f6c69e3686","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":6,"id":"b2d1be17_45b865aa","updated":"2022-08-24 12:59:59.000000000","message":"I think the new sequence of patch sets (thanks for re-uploading to see the actual failure) shows quite nicely the impact of that bug.","commit_id":"63f53569528c6afa0015b03aed264f4e23c1e187"},{"author":{"_account_id":7953,"name":"Ulrich Schwickerath","email":"Ulrich.Schwickerath@cern.ch","username":"schwicke"},"change_message_id":"6c9c653675a9125f656132f2392d50f49a20629f","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":7,"id":"ae0b8af7_c8006f56","updated":"2022-09-02 09:53:25.000000000","message":"I suppose this one should have some release notes as well.","commit_id":"4b3991b1b1b8145a7d1d17dccabd0b8d8b764bfc"},{"author":{"_account_id":7953,"name":"Ulrich Schwickerath","email":"Ulrich.Schwickerath@cern.ch","username":"schwicke"},"change_message_id":"d56da0436d1a30a8eed5f1dfe4f815bef175c752","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":7,"id":"adce78d8_be3e923c","in_reply_to":"ae0b8af7_c8006f56","updated":"2022-09-06 12:01:56.000000000","message":"added a note for the bug referencing https://storyboard.openstack.org/#!/story/2010273","commit_id":"4b3991b1b1b8145a7d1d17dccabd0b8d8b764bfc"},{"author":{"_account_id":7953,"name":"Ulrich Schwickerath","email":"Ulrich.Schwickerath@cern.ch","username":"schwicke"},"change_message_id":"d56da0436d1a30a8eed5f1dfe4f815bef175c752","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":8,"id":"d27a4815_8a50000b","updated":"2022-09-06 12:01:56.000000000","message":"Added a note on the change.","commit_id":"0579fc953b5bfc56672b3437dc90efa4e4ba62e3"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"30e6d43388c5dfe38656cc644431f9114f3ebacd","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":8,"id":"9759c6c9_d6a00934","updated":"2022-09-06 17:17:44.000000000","message":"Okay, figured this out. I hope you don\u0027t mind but I\u0027m going to push up a fix that addresses the root cause of this issue (and includes a lengthy message explaining what\u0027s going on)","commit_id":"0579fc953b5bfc56672b3437dc90efa4e4ba62e3"},{"author":{"_account_id":7953,"name":"Ulrich Schwickerath","email":"Ulrich.Schwickerath@cern.ch","username":"schwicke"},"change_message_id":"bb76f2d85f0f2c99286bba738b35798391ad59b3","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":9,"id":"c73cd043_f7e280f2","updated":"2022-09-07 08:25:49.000000000","message":"Many thanks for the excellent explanation! I very much like the proposed functional test.\n\nPlease take a look at my inline comments. ","commit_id":"0529c30ae2958338aa8c0d56066b762eb412adcc"},{"author":{"_account_id":7953,"name":"Ulrich Schwickerath","email":"Ulrich.Schwickerath@cern.ch","username":"schwicke"},"change_message_id":"553d1ec7dfb150fdb03aca7467abcf0aa6c0963e","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":9,"id":"d81f7d93_c12ddd8c","updated":"2022-09-07 11:23:37.000000000","message":"Nice, this seems to be sorted out.","commit_id":"0529c30ae2958338aa8c0d56066b762eb412adcc"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"b92f4fae7c26ba83536a4cc29b9e5275ab8f4f4d","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":9,"id":"496951e6_aca7d930","updated":"2022-09-09 13:38:56.000000000","message":"This has a test and a length explanation. I doubt we\u0027re going to get a second reviewer so let\u0027s go with the one we have.","commit_id":"0529c30ae2958338aa8c0d56066b762eb412adcc"},{"author":{"_account_id":27900,"name":"Artem Goncharov","email":"artem.goncharov@gmail.com","username":"gtema"},"change_message_id":"37adde255132ae35ce16cd2aa213a520f3990f63","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":9,"id":"f4eb1525_ead3261a","updated":"2022-09-09 15:52:43.000000000","message":"recheck devstack failure","commit_id":"0529c30ae2958338aa8c0d56066b762eb412adcc"}],"openstack/resource.py":[{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"f921223ba97919e4e6edc495162fbd9d40992157","unresolved":true,"context_lines":[{"line_number":2040,"context_line":"            parts \u003d urllib.parse.urlparse(next_link)"},{"line_number":2041,"context_line":"            query_params \u003d urllib.parse.parse_qs(parts.query)"},{"line_number":2042,"context_line":"            params.update(query_params)"},{"line_number":2043,"context_line":"            next_link \u003d urllib.parse.urljoin(next_link, parts.path)"},{"line_number":2044,"context_line":""},{"line_number":2045,"context_line":"        # If we still have no link, and limit was given and is non-zero,"},{"line_number":2046,"context_line":"        # and the number of records yielded equals the limit, then the user"}],"source_content_type":"text/x-python","patch_set":7,"id":"2273d667_ac1b4966","side":"PARENT","line":2043,"updated":"2022-09-06 16:54:07.000000000","message":"Looking at this, I suspect the author was trying to do [1] and indeed after playing around with it locally it looks like should work:\n\n  \u003e\u003e\u003e from urllib.parse import urljoin, urlparse\n  \u003e\u003e\u003e url \u003d \u0027http://example.com/foo/bar?a\u003dtext\u0026q2\u003dtext2\u0026q3\u003dtext3\u0026q2\u003dtext4\u0027\n  \u003e\u003e\u003e urljoin(url, urlparse(url).path)\n  \u0027http://example.com/foo/bar\u0027\n\nSo I wonder why this is not working...\n\n[1] https://stackoverflow.com/a/32214777","commit_id":"3f81d0001dd994cde990d38f6e2671ee0694d7d5"},{"author":{"_account_id":7953,"name":"Ulrich Schwickerath","email":"Ulrich.Schwickerath@cern.ch","username":"schwicke"},"change_message_id":"bb76f2d85f0f2c99286bba738b35798391ad59b3","unresolved":true,"context_lines":[{"line_number":2040,"context_line":"            parts \u003d urllib.parse.urlparse(next_link)"},{"line_number":2041,"context_line":"            query_params \u003d urllib.parse.parse_qs(parts.query)"},{"line_number":2042,"context_line":"            params.update(query_params)"},{"line_number":2043,"context_line":"            next_link \u003d urllib.parse.urljoin(next_link, parts.path)"},{"line_number":2044,"context_line":""},{"line_number":2045,"context_line":"        # If we still have no link, and limit was given and is non-zero,"},{"line_number":2046,"context_line":"        # and the number of records yielded equals the limit, then the user"}],"source_content_type":"text/x-python","patch_set":7,"id":"3e7dbbf1_c4b0442f","side":"PARENT","line":2043,"in_reply_to":"2273d667_ac1b4966","updated":"2022-09-07 08:25:49.000000000","message":"As you nicely described in patchset9, it works fine for absolute paths, starting with a leading /. It fails for relatives path, which are missing that:\n\u003e\u003e\u003e next_link\u003d\"foo/bar\"\n\u003e\u003e\u003e urljoin(next_link, urlparse(next_link).path)\n\u0027foo/foo/bar\u0027\n\u003e\u003e\u003e next_link\u003d\"/foo/bar\"\n\u003e\u003e\u003e urljoin(next_link, urlparse(next_link).path)\n\u0027/foo/bar\u0027\n\nThe method proposed by us in the original patch gives the correct answer in both cases:\n\n\u003e\u003e\u003e next_link\u003d\"/foo/bar\"\n\u003e\u003e\u003e parts \u003d urlparse(next_link)\n\u003e\u003e\u003e noquery \u003d (parts.scheme, parts.netloc,parts.path, parts.params, \u0027\u0027, parts.fragment)\n\u003e\u003e\u003e urlunparse(noquery)\n\u0027/foo/bar\u0027\n\u003e\u003e\u003e next_link\u003d\"foo/bar\"\n\u003e\u003e\u003e parts \u003d urlparse(next_link)\n\u003e\u003e\u003e noquery \u003d (parts.scheme, parts.netloc,parts.path, parts.params, \u0027\u0027, parts.fragment)\n\u003e\u003e\u003e urlunparse(noquery)\n\u0027foo/bar\u0027\n\u003e\u003e\u003e next_link \u003d \u0027http://example.com/foo/bar?a\u003dtext\u0026q2\u003dtext2\u0026q3\u003dtext3\u0026q2\u003dtext4\u0027\n\u003e\u003e\u003e parts \u003d urlparse(next_link)\n\u003e\u003e\u003e noquery \u003d (parts.scheme, parts.netloc,parts.path, parts.params, \u0027\u0027, parts.fragment)\n\u003e\u003e\u003e urlunparse(noquery)\n\u0027http://example.com/foo/bar\u0027\n\nNot removing the leading / for glance would solve the issue for this special case. I just wonder if it was not better to correct that function and make it work for both cases.","commit_id":"3f81d0001dd994cde990d38f6e2671ee0694d7d5"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"b8315245173696e759fdb974098c49bd66b19f59","unresolved":true,"context_lines":[{"line_number":2040,"context_line":"            parts \u003d urllib.parse.urlparse(next_link)"},{"line_number":2041,"context_line":"            query_params \u003d urllib.parse.parse_qs(parts.query)"},{"line_number":2042,"context_line":"            params.update(query_params)"},{"line_number":2043,"context_line":"            next_link \u003d urllib.parse.urljoin(next_link, parts.path)"},{"line_number":2044,"context_line":""},{"line_number":2045,"context_line":"        # If we still have no link, and limit was given and is non-zero,"},{"line_number":2046,"context_line":"        # and the number of records yielded equals the limit, then the user"}],"source_content_type":"text/x-python","patch_set":7,"id":"e2d1178f_5d912cd1","side":"PARENT","line":2043,"in_reply_to":"3e7dbbf1_c4b0442f","updated":"2022-09-07 09:35:24.000000000","message":"\u003e As you nicely described in patchset9, it works fine for absolute paths, starting with a leading /.\n\nI think we might be mixing up terminology here. An absolute path in a Linux context is one that starts *with* a leading forward slash. However, an absolute URL is one that starts *without* a leading forward slash: instead, it starts with the (optional) scheme, the hostname, and (optional) the port. Consider this very URL. First, an absolute URL:\n\n  review.opendev.org/c/openstack/openstacksdk/+/853656/\n\nNow a relative URL:\n\n  /c/openstack/openstacksdk/+/853656/\n\nYou need the leading slash to distinguish these. Consider the following perfectly legitimate URL:\n\n  example.com/openstack.org/data/image.png\n\nA \"relative\" URL without the leading slash would be indistinguishable from an absolute URL:\n\n  openstack.org/data/image.png\n\nAs such, I don\u0027t think relative URLs without a leading slash are valid, at least not for our use cases here.\n\n\u003e It fails for relatives path, which are missing that:\n\u003e \u003e\u003e\u003e next_link\u003d\"foo/bar\"\n\u003e \u003e\u003e\u003e urljoin(next_link, urlparse(next_link).path)\n\u003e \u0027foo/foo/bar\u0027\n\u003e \u003e\u003e\u003e next_link\u003d\"/foo/bar\"\n\u003e \u003e\u003e\u003e urljoin(next_link, urlparse(next_link).path)\n\u003e \u0027/foo/bar\u0027\n\nAs above, I don\u0027t think these are valid. Almost as importantly though, does anything actually return this style of URL? Glance certainly doesn\u0027t...\n\n\u003e The method proposed by us in the original patch gives the correct answer in both cases:\n\u003e \n\u003e \u003e\u003e\u003e next_link\u003d\"/foo/bar\"\n\u003e \u003e\u003e\u003e parts \u003d urlparse(next_link)\n\u003e \u003e\u003e\u003e noquery \u003d (parts.scheme, parts.netloc,parts.path, parts.params, \u0027\u0027, parts.fragment)\n\u003e \u003e\u003e\u003e urlunparse(noquery)\n\u003e \u0027/foo/bar\u0027\n\u003e \u003e\u003e\u003e next_link\u003d\"foo/bar\"\n\u003e \u003e\u003e\u003e parts \u003d urlparse(next_link)\n\u003e \u003e\u003e\u003e noquery \u003d (parts.scheme, parts.netloc,parts.path, parts.params, \u0027\u0027, parts.fragment)\n\u003e \u003e\u003e\u003e urlunparse(noquery)\n\u003e \u0027foo/bar\u0027\n\u003e \u003e\u003e\u003e next_link \u003d \u0027http://example.com/foo/bar?a\u003dtext\u0026q2\u003dtext2\u0026q3\u003dtext3\u0026q2\u003dtext4\u0027\n\u003e \u003e\u003e\u003e parts \u003d urlparse(next_link)\n\u003e \u003e\u003e\u003e noquery \u003d (parts.scheme, parts.netloc,parts.path, parts.params, \u0027\u0027, parts.fragment)\n\u003e \u003e\u003e\u003e urlunparse(noquery)\n\u003e \u0027http://example.com/foo/bar\u0027\n\u003e \n\u003e Not removing the leading / for glance would solve the issue for this special case. I just wonder if it was not better to correct that function and make it work for both cases.\n\nGiven these aren\u0027t valid (IMO), I don\u0027t think we should make the code more complicated to address them. If you insist then we can but there is value in keeping things simple (KISS principle)","commit_id":"3f81d0001dd994cde990d38f6e2671ee0694d7d5"},{"author":{"_account_id":7953,"name":"Ulrich Schwickerath","email":"Ulrich.Schwickerath@cern.ch","username":"schwicke"},"change_message_id":"553d1ec7dfb150fdb03aca7467abcf0aa6c0963e","unresolved":false,"context_lines":[{"line_number":2040,"context_line":"            parts \u003d urllib.parse.urlparse(next_link)"},{"line_number":2041,"context_line":"            query_params \u003d urllib.parse.parse_qs(parts.query)"},{"line_number":2042,"context_line":"            params.update(query_params)"},{"line_number":2043,"context_line":"            next_link \u003d urllib.parse.urljoin(next_link, parts.path)"},{"line_number":2044,"context_line":""},{"line_number":2045,"context_line":"        # If we still have no link, and limit was given and is non-zero,"},{"line_number":2046,"context_line":"        # and the number of records yielded equals the limit, then the user"}],"source_content_type":"text/x-python","patch_set":7,"id":"f795ea37_4ca08ccd","side":"PARENT","line":2043,"in_reply_to":"e2d1178f_5d912cd1","updated":"2022-09-07 11:23:37.000000000","message":"Ack. +1 for the KISS principle (involving minimal changes).","commit_id":"3f81d0001dd994cde990d38f6e2671ee0694d7d5"}],"openstack/tests/unit/test_resource.py":[{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"f921223ba97919e4e6edc495162fbd9d40992157","unresolved":true,"context_lines":[{"line_number":4090,"context_line":"        response.reason \u003d \u0027Bad Request\u0027"},{"line_number":4091,"context_line":"        self.session.post.return_value \u003d response"},{"line_number":4092,"context_line":"        self.assertRaises(exceptions.ConflictException, Test.bulk_create,"},{"line_number":4093,"context_line":"                          self.session, [{\u0027name\u0027: \u0027name\u0027}])"},{"line_number":4094,"context_line":""},{"line_number":4095,"context_line":""},{"line_number":4096,"context_line":"class TestResourceFind(base.TestCase):"}],"source_content_type":"text/x-python","patch_set":7,"id":"afacdb61_d86766dc","line":4093,"updated":"2022-09-06 16:54:07.000000000","message":"I\u0027m guess for most of these you copied the previous test class and modified the base Test resource used in each to use a more complex base_path? That works, but it\u0027s rather wasteful. Instead of doing that, why not test the function that we\u0027re using to find the next link directly? Alternatively, could we have a single test in the main test case that works with a slightly different \u0027base_path\u0027?","commit_id":"4b3991b1b1b8145a7d1d17dccabd0b8d8b764bfc"},{"author":{"_account_id":7953,"name":"Ulrich Schwickerath","email":"Ulrich.Schwickerath@cern.ch","username":"schwicke"},"change_message_id":"bb76f2d85f0f2c99286bba738b35798391ad59b3","unresolved":false,"context_lines":[{"line_number":4090,"context_line":"        response.reason \u003d \u0027Bad Request\u0027"},{"line_number":4091,"context_line":"        self.session.post.return_value \u003d response"},{"line_number":4092,"context_line":"        self.assertRaises(exceptions.ConflictException, Test.bulk_create,"},{"line_number":4093,"context_line":"                          self.session, [{\u0027name\u0027: \u0027name\u0027}])"},{"line_number":4094,"context_line":""},{"line_number":4095,"context_line":""},{"line_number":4096,"context_line":"class TestResourceFind(base.TestCase):"}],"source_content_type":"text/x-python","patch_set":7,"id":"e6b18da0_b649d8e1","line":4093,"in_reply_to":"afacdb61_d86766dc","updated":"2022-09-07 08:25:49.000000000","message":"Yes, the idea was to have a full test not only for glance but also all the other services. I like the idea of patchset9. Looks fine to me.","commit_id":"4b3991b1b1b8145a7d1d17dccabd0b8d8b764bfc"}]}
