)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"3c3dd24be3a326d74ad0424ed383bca16b577dee","unresolved":false,"context_lines":[{"line_number":7,"context_line":"Fix incorrect instance state after build failure"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"The primary purpose of this change was to add a regression test for"},{"line_number":10,"context_line":"bug 1831771. However, this regression test highlighted another bug in"},{"line_number":11,"context_line":"cleanup after build failure which is therefore fixed in this change."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"It is possible that the instance object was in an inconsistent state"},{"line_number":14,"context_line":"at the point in the build process where an exception was raised,"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"3fa7e38b_419b9565","line":11,"range":{"start_line":10,"start_character":55,"end_line":11,"end_character":27},"updated":"2019-10-17 21:56:40.000000000","message":"Skimming the compute manager delta, it seems like this bit should have its own bug report (with Closes-Bug here) for backportability.","commit_id":"9bb3b864320e739635bd8db7ae4cdaccef86bb8e"}],"nova/tests/functional/libvirt/test_delete.py":[{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"3c0951fd93e7803f8c7f4ace3bfd872bd441f3e0","unresolved":false,"context_lines":[{"line_number":23,"context_line":"from nova.tests.functional.libvirt import base"},{"line_number":24,"context_line":""},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"class TestDelete(base.IntegratedTestBase):"},{"line_number":27,"context_line":"    def test_delete_during_create(self):"},{"line_number":28,"context_line":"        self.start_compute(\u0027compute1\u0027)"},{"line_number":29,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"3fa7e38b_7e92caa1","line":26,"range":{"start_line":26,"start_character":22,"end_line":26,"end_character":40},"updated":"2019-10-21 15:47:27.000000000","message":"This is new as of https://review.opendev.org/#/c/689186/ and it would be nice if we didn\u0027t have to depend on that for this since I\u0027m assuming you\u0027ll want to backport the fix at the top of this stack of changes.","commit_id":"de9f8602024136ba5f899151e2c12d384429726b"},{"author":{"_account_id":9555,"name":"Matthew Booth","email":"mbooth@redhat.com","username":"MatthewBooth"},"change_message_id":"a2897f7219924d2247aa9bc2e0787938b1db2489","unresolved":false,"context_lines":[{"line_number":23,"context_line":"from nova.tests.functional.libvirt import base"},{"line_number":24,"context_line":""},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"class TestDelete(base.IntegratedTestBase):"},{"line_number":27,"context_line":"    def test_delete_during_create(self):"},{"line_number":28,"context_line":"        self.start_compute(\u0027compute1\u0027)"},{"line_number":29,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"3fa7e38b_e07134e0","line":26,"range":{"start_line":26,"start_character":22,"end_line":26,"end_character":40},"in_reply_to":"3fa7e38b_7e92caa1","updated":"2019-10-21 21:37:37.000000000","message":"I don\u0027t think that\u0027s an issue in itself as the top change is well isolated. I\u0027ll look into the alternative approach you mentioned and see if it\u0027s better, though.","commit_id":"de9f8602024136ba5f899151e2c12d384429726b"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"e6ee4fc350418fcf5fc4285f9a56b78fd47fc153","unresolved":false,"context_lines":[{"line_number":23,"context_line":"from nova.tests.functional.libvirt import base"},{"line_number":24,"context_line":""},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"class TestDelete(base.IntegratedTestBase):"},{"line_number":27,"context_line":"    def test_delete_during_create(self):"},{"line_number":28,"context_line":"        self.start_compute(\u0027compute1\u0027)"},{"line_number":29,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"3fa7e38b_e6594135","line":26,"range":{"start_line":26,"start_character":22,"end_line":26,"end_character":40},"in_reply_to":"3fa7e38b_e07134e0","updated":"2019-10-22 14:18:34.000000000","message":"\u003e I don\u0027t think that\u0027s an issue in itself as the top change is well\n \u003e isolated. I\u0027ll look into the alternative approach you mentioned and\n \u003e see if it\u0027s better, though.\n\nPresumably you guys (Red Hat) are going to want to backport the fix as far back as possible though, which upstream right now is stable/queens. I really don\u0027t want to have to deal with backporting refactors of functional tests if it\u0027s not necessary and this is not a libvirt-specific issue.","commit_id":"de9f8602024136ba5f899151e2c12d384429726b"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"c5b44e572a5563625316f2bdca5dedc617ef36b1","unresolved":false,"context_lines":[{"line_number":44,"context_line":"                    # instance save happens."},{"line_number":45,"context_line":"                    self.api.delete_server(instance.uuid)"},{"line_number":46,"context_line":"                except Exception:"},{"line_number":47,"context_line":"                    # This is going to fail because of the"},{"line_number":48,"context_line":"                    # MessagingTimeout we raised."},{"line_number":49,"context_line":"                    pass"},{"line_number":50,"context_line":"                else:"},{"line_number":51,"context_line":"                    self.fail(\u0027Expected delete to raise exception\u0027)"},{"line_number":52,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"3fa7e38b_9e3ea689","line":49,"range":{"start_line":47,"start_character":20,"end_line":49,"end_character":24},"updated":"2019-10-21 15:49:47.000000000","message":"It wouldn\u0027t if you were not using the IntegratedTestBase stuff which uses the CastAsCall fixture and is therefore not realistic. Normally you\u0027d just delete and wait for the server to be gone, like this regression test that does something similar:\n\nhttps://review.opendev.org/#/c/688980/","commit_id":"de9f8602024136ba5f899151e2c12d384429726b"},{"author":{"_account_id":9555,"name":"Matthew Booth","email":"mbooth@redhat.com","username":"MatthewBooth"},"change_message_id":"a2897f7219924d2247aa9bc2e0787938b1db2489","unresolved":false,"context_lines":[{"line_number":50,"context_line":"                else:"},{"line_number":51,"context_line":"                    self.fail(\u0027Expected delete to raise exception\u0027)"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":"        orig_save \u003d objects.Instance.save"},{"line_number":54,"context_line":""},{"line_number":55,"context_line":"        # A wrapper round instance.save() which allows us to inject a race"},{"line_number":56,"context_line":"        # under specific conditions before calling the original instance.save()"}],"source_content_type":"text/x-python","patch_set":3,"id":"3fa7e38b_e01ff46d","line":53,"updated":"2019-10-21 21:37:37.000000000","message":"This also looks like a potential user of Eric/Gibi\u0027s spy interface. I\u0027ve wanted one of those several times.\n\nhttps://review.opendev.org/#/c/686207/","commit_id":"de9f8602024136ba5f899151e2c12d384429726b"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"e6ee4fc350418fcf5fc4285f9a56b78fd47fc153","unresolved":false,"context_lines":[{"line_number":50,"context_line":"                else:"},{"line_number":51,"context_line":"                    self.fail(\u0027Expected delete to raise exception\u0027)"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":"        orig_save \u003d objects.Instance.save"},{"line_number":54,"context_line":""},{"line_number":55,"context_line":"        # A wrapper round instance.save() which allows us to inject a race"},{"line_number":56,"context_line":"        # under specific conditions before calling the original instance.save()"}],"source_content_type":"text/x-python","patch_set":3,"id":"3fa7e38b_4648555b","line":53,"in_reply_to":"3fa7e38b_e01ff46d","updated":"2019-10-22 14:18:34.000000000","message":"Don\u0027t rely on something like that which is not in stable branches since it would mean having to either (1) backport the spy stuff before it\u0027s fully baked and soaked in master or (2) re-writing the test to not rely on it for backports.","commit_id":"de9f8602024136ba5f899151e2c12d384429726b"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"3c0951fd93e7803f8c7f4ace3bfd872bd441f3e0","unresolved":false,"context_lines":[{"line_number":73,"context_line":""},{"line_number":74,"context_line":"            orig_save(instance, *wrap_args, **wrap_kwargs)"},{"line_number":75,"context_line":""},{"line_number":76,"context_line":"        _driver \u003d \u0027nova.virt.libvirt.driver.LibvirtDriver\u0027"},{"line_number":77,"context_line":"        with mock.patch(\u0027nova.objects.Instance.save\u0027, wrap_save), \\"},{"line_number":78,"context_line":"             mock.patch(_driver + \u0027.plug_vifs\u0027) as mock_plug_vifs, \\"},{"line_number":79,"context_line":"             mock.patch(_driver + \u0027.unplug_vifs\u0027) as mock_unplug_vifs:"}],"source_content_type":"text/x-python","patch_set":3,"id":"3fa7e38b_7ed72a51","line":76,"updated":"2019-10-21 15:47:27.000000000","message":"Does this really need to be a libvirt-based functional test? If you\u0027re stubbing out the driver methods what is the point? IOW, couldn\u0027t we decouple this from the libvirt functional test base tree and just add a new fake virt driver that tracks calls to plug_vifs/unplug_vifs or whatever is needed to assert in this test? It just seems like basing on the libvirt stuff is shoe-horning this when we don\u0027t need to.","commit_id":"de9f8602024136ba5f899151e2c12d384429726b"},{"author":{"_account_id":9555,"name":"Matthew Booth","email":"mbooth@redhat.com","username":"MatthewBooth"},"change_message_id":"a2897f7219924d2247aa9bc2e0787938b1db2489","unresolved":false,"context_lines":[{"line_number":73,"context_line":""},{"line_number":74,"context_line":"            orig_save(instance, *wrap_args, **wrap_kwargs)"},{"line_number":75,"context_line":""},{"line_number":76,"context_line":"        _driver \u003d \u0027nova.virt.libvirt.driver.LibvirtDriver\u0027"},{"line_number":77,"context_line":"        with mock.patch(\u0027nova.objects.Instance.save\u0027, wrap_save), \\"},{"line_number":78,"context_line":"             mock.patch(_driver + \u0027.plug_vifs\u0027) as mock_plug_vifs, \\"},{"line_number":79,"context_line":"             mock.patch(_driver + \u0027.unplug_vifs\u0027) as mock_unplug_vifs:"}],"source_content_type":"text/x-python","patch_set":3,"id":"3fa7e38b_e08374a8","line":76,"in_reply_to":"3fa7e38b_7ed72a51","updated":"2019-10-21 21:37:37.000000000","message":"Well it\u0027s the driver that calls plug_vifs. If I was going to use a fake driver I\u0027d simply check the call to spawn rather than have fake spawn call fake plug_vifs.","commit_id":"de9f8602024136ba5f899151e2c12d384429726b"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"e6ee4fc350418fcf5fc4285f9a56b78fd47fc153","unresolved":false,"context_lines":[{"line_number":73,"context_line":""},{"line_number":74,"context_line":"            orig_save(instance, *wrap_args, **wrap_kwargs)"},{"line_number":75,"context_line":""},{"line_number":76,"context_line":"        _driver \u003d \u0027nova.virt.libvirt.driver.LibvirtDriver\u0027"},{"line_number":77,"context_line":"        with mock.patch(\u0027nova.objects.Instance.save\u0027, wrap_save), \\"},{"line_number":78,"context_line":"             mock.patch(_driver + \u0027.plug_vifs\u0027) as mock_plug_vifs, \\"},{"line_number":79,"context_line":"             mock.patch(_driver + \u0027.unplug_vifs\u0027) as mock_unplug_vifs:"}],"source_content_type":"text/x-python","patch_set":3,"id":"3fa7e38b_0699fdce","line":76,"in_reply_to":"3fa7e38b_e08374a8","updated":"2019-10-22 14:18:34.000000000","message":"plug_vifs is on the base driver interface, not just for libvirt, so this isn\u0027t libvirt-specific since the ComputeManager is just calling the driver interface:\n\nhttps://review.opendev.org/#/c/663382/12/nova/compute/manager.py","commit_id":"de9f8602024136ba5f899151e2c12d384429726b"}],"nova/tests/functional/regressions/test_bug_1831771.py":[{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"8aab4b50efe1eac13adf0cb412285bb26cda0c95","unresolved":false,"context_lines":[{"line_number":23,"context_line":"from nova.tests.functional import integrated_helpers"},{"line_number":24,"context_line":""},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"class TestDelete(integrated_helpers.ProviderUsageBaseTestCase):"},{"line_number":27,"context_line":"    compute_driver \u003d \u0027fake.MediumFakeDriver\u0027"},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"    def test_delete_during_create(self):"}],"source_content_type":"text/x-python","patch_set":5,"id":"1fa4df85_fb4c9377","line":26,"range":{"start_line":26,"start_character":6,"end_line":26,"end_character":16},"updated":"2020-02-25 15:19:18.000000000","message":"This could use a docstring summarizing the bug and describing what the test is going to do.","commit_id":"10434bd229973b37647741e58aff3ac90b3a0a6c"},{"author":{"_account_id":10135,"name":"Lee Yarwood","display_name":"Lee Yarwood","email":"lyarwood@redhat.com","username":"lyarwood"},"change_message_id":"2645a644fc52085c38e151c192d09ca3a98a06da","unresolved":false,"context_lines":[{"line_number":32,"context_line":"        def delete_race(instance):"},{"line_number":33,"context_line":"            self.api.delete_server(instance.uuid)"},{"line_number":34,"context_line":"            self._wait_for_server_parameter("},{"line_number":35,"context_line":"                self.api,"},{"line_number":36,"context_line":"                {\u0027id\u0027: instance.uuid},"},{"line_number":37,"context_line":"                {\u0027OS-EXT-STS:task_state\u0027: task_states.DELETING},"},{"line_number":38,"context_line":"            )"}],"source_content_type":"text/x-python","patch_set":5,"id":"1fa4df85_5df0c4fe","line":35,"range":{"start_line":35,"start_character":16,"end_line":35,"end_character":25},"updated":"2020-03-04 12:01:50.000000000","message":"I don\u0027t understand how this doesn\u0027t always fail given I8c96b337f32148f8f5899c9b87af331b1fa41424.","commit_id":"10434bd229973b37647741e58aff3ac90b3a0a6c"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"c0df904d393ca089c2d48cdbe5f35c31bb1f97f7","unresolved":false,"context_lines":[{"line_number":87,"context_line":"        ) as (_, mock_spawn, mock_unplug_vifs):"},{"line_number":88,"context_line":"            # the compute manager doesn\u0027t set the ERROR state in cleanup since"},{"line_number":89,"context_line":"            # it might race with delete, therefore we\u0027ll be left in BUILDING"},{"line_number":90,"context_line":"            server_req \u003d self._build_server(networks\u003d\u0027none\u0027)"},{"line_number":91,"context_line":"            created_server \u003d self.api.post_server({\u0027server\u0027: server_req})"},{"line_number":92,"context_line":"            self._wait_until_deleted(created_server)"},{"line_number":93,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"1fa4df85_d7e175d2","line":90,"range":{"start_line":90,"start_character":44,"end_line":90,"end_character":59},"updated":"2020-02-25 08:41:09.000000000","message":"networks\u003dnone is confusing as we also excepts that the vifs are unplugged but we did not ask for any vifs.  (I know that that unplug_vifs should be called unconditionally by the cleanup but it is implementation specific information)\n\nMaybe a code comment would be helpful for the future reader.","commit_id":"10434bd229973b37647741e58aff3ac90b3a0a6c"}],"nova/tests/functional/test_servers.py":[{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"345c8ad0dd2d870e287b829f41954fc458706457","unresolved":false,"context_lines":[{"line_number":1430,"context_line":"        # Now update the image metadata to be something that won\u0027t work with"},{"line_number":1431,"context_line":"        # the fake compute driver we\u0027re using since the fake driver has an"},{"line_number":1432,"context_line":"        # \"x86_64\" architecture."},{"line_number":1433,"context_line":"        rebuild_image_ref \u003d fake_image.AUTO_DISK_CONFIG_ENABLED_IMAGE_UUID"},{"line_number":1434,"context_line":"        self.api.put_image_meta_key("},{"line_number":1435,"context_line":"            rebuild_image_ref, \u0027hw_architecture\u0027, \u0027unicore32\u0027)"},{"line_number":1436,"context_line":"        # Now rebuild the server with that updated image and it should result"}],"source_content_type":"text/x-python","patch_set":4,"id":"3fa7e38b_a1124cb3","line":1433,"updated":"2019-10-22 20:25:19.000000000","message":"This is unrelated to the new test.","commit_id":"33df3db78605754379d13a3c76610ede24bb8732"},{"author":{"_account_id":9555,"name":"Matthew Booth","email":"mbooth@redhat.com","username":"MatthewBooth"},"change_message_id":"e198e58145dfa2376b6224b2081942013ac3fc08","unresolved":false,"context_lines":[{"line_number":1430,"context_line":"        # Now update the image metadata to be something that won\u0027t work with"},{"line_number":1431,"context_line":"        # the fake compute driver we\u0027re using since the fake driver has an"},{"line_number":1432,"context_line":"        # \"x86_64\" architecture."},{"line_number":1433,"context_line":"        rebuild_image_ref \u003d fake_image.AUTO_DISK_CONFIG_ENABLED_IMAGE_UUID"},{"line_number":1434,"context_line":"        self.api.put_image_meta_key("},{"line_number":1435,"context_line":"            rebuild_image_ref, \u0027hw_architecture\u0027, \u0027unicore32\u0027)"},{"line_number":1436,"context_line":"        # Now rebuild the server with that updated image and it should result"}],"source_content_type":"text/x-python","patch_set":4,"id":"3fa7e38b_41d4b8bb","line":1433,"in_reply_to":"3fa7e38b_a1124cb3","updated":"2019-10-22 20:37:28.000000000","message":"It\u0027s not, actually. I changed the name of the fake_image import because I use it below and it\u0027s currently a bit mad. Consequently I had to update these, too.","commit_id":"33df3db78605754379d13a3c76610ede24bb8732"},{"author":{"_account_id":9555,"name":"Matthew Booth","email":"mbooth@redhat.com","username":"MatthewBooth"},"change_message_id":"e198e58145dfa2376b6224b2081942013ac3fc08","unresolved":false,"context_lines":[{"line_number":3924,"context_line":"        return body[\u0027flavor\u0027][\u0027id\u0027]"},{"line_number":3925,"context_line":""},{"line_number":3926,"context_line":"    def _create_server(self):"},{"line_number":3927,"context_line":"        with nova_utils.temporary_mutation(self.api, microversion\u003d\u00272.35\u0027):"},{"line_number":3928,"context_line":"            image_id \u003d self.api.get_images()[0][\u0027id\u0027]"},{"line_number":3929,"context_line":"        server_req \u003d self._build_minimal_create_server_request("},{"line_number":3930,"context_line":"            self.api, \u0027trait-based-server\u0027,"}],"source_content_type":"text/x-python","patch_set":4,"id":"3fa7e38b_e1e284a0","line":3927,"updated":"2019-10-22 20:37:28.000000000","message":"Ditto. nova seems to have been implicitly imported when importing nova.foo.bar.baz.from.image.fake. When I gave the image fake a sensible name this was caught in the crossfire.","commit_id":"33df3db78605754379d13a3c76610ede24bb8732"},{"author":{"_account_id":9555,"name":"Matthew Booth","email":"mbooth@redhat.com","username":"MatthewBooth"},"change_message_id":"e198e58145dfa2376b6224b2081942013ac3fc08","unresolved":false,"context_lines":[{"line_number":6517,"context_line":"            qos_normal_port, qos_sriov_port, self.flavor_with_group_policy)"},{"line_number":6518,"context_line":""},{"line_number":6519,"context_line":"        orig_get_service \u003d objects.Service.get_by_host_and_binary"},{"line_number":6520,"context_line":""},{"line_number":6521,"context_line":"        def fake_get_service(context, host, binary):"},{"line_number":6522,"context_line":"            # host2 is the only migration target, let\u0027s make it too old so the"},{"line_number":6523,"context_line":"            # migration will fail"}],"source_content_type":"text/x-python","patch_set":4,"id":"3fa7e38b_a1eecc88","line":6520,"updated":"2019-10-22 20:37:28.000000000","message":"Ditto, and I\u0027m now explicitly importing objects.","commit_id":"33df3db78605754379d13a3c76610ede24bb8732"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"345c8ad0dd2d870e287b829f41954fc458706457","unresolved":false,"context_lines":[{"line_number":7107,"context_line":"        self.assertNotIn(\u0027allocation\u0027, binding_profile)"},{"line_number":7108,"context_line":""},{"line_number":7109,"context_line":""},{"line_number":7110,"context_line":"class TestDelete(integrated_helpers.SimpleTestBase):"},{"line_number":7111,"context_line":"    compute_driver \u003d \u0027fake.MediumFakeDriver\u0027"},{"line_number":7112,"context_line":""},{"line_number":7113,"context_line":"    def test_delete_during_create(self):"}],"source_content_type":"text/x-python","patch_set":4,"id":"3fa7e38b_610c5494","line":7110,"range":{"start_line":7110,"start_character":17,"end_line":7110,"end_character":50},"updated":"2019-10-22 20:25:19.000000000","message":"This won\u0027t exist in stable branches unless we backport the refactor you\u0027ve got before this in the series, which I\u0027d rather not do. I don\u0027t know why the test can\u0027t just use ProviderUsageBaseTestCase.","commit_id":"33df3db78605754379d13a3c76610ede24bb8732"},{"author":{"_account_id":9555,"name":"Matthew Booth","email":"mbooth@redhat.com","username":"MatthewBooth"},"change_message_id":"e198e58145dfa2376b6224b2081942013ac3fc08","unresolved":false,"context_lines":[{"line_number":7107,"context_line":"        self.assertNotIn(\u0027allocation\u0027, binding_profile)"},{"line_number":7108,"context_line":""},{"line_number":7109,"context_line":""},{"line_number":7110,"context_line":"class TestDelete(integrated_helpers.SimpleTestBase):"},{"line_number":7111,"context_line":"    compute_driver \u003d \u0027fake.MediumFakeDriver\u0027"},{"line_number":7112,"context_line":""},{"line_number":7113,"context_line":"    def test_delete_during_create(self):"}],"source_content_type":"text/x-python","patch_set":4,"id":"3fa7e38b_e1a92424","line":7110,"range":{"start_line":7110,"start_character":17,"end_line":7110,"end_character":50},"in_reply_to":"3fa7e38b_610c5494","updated":"2019-10-22 20:37:28.000000000","message":"Lets use ProviderUsageBaseTestCase in the backport to avoid backporting the code motion. However, this is better here.\n\nI don\u0027t want to use it here because this test has nothing to do with providers. The provider-specific test code in that class isn\u0027t relevant, and the name is confusing in this context (Why is this using a provider base? What\u0027s the provider connection? What am I missing? Cue 2 hours of wasted spelunking).","commit_id":"33df3db78605754379d13a3c76610ede24bb8732"}]}
