From 4a9860c5445af675a9fa9530c8607547ef833e8c Mon Sep 17 00:00:00 2001 From: kayrus Date: Tue, 9 Jul 2024 21:18:32 +0200 Subject: [PATCH 001/353] [neutron]: introduce Description argument for the portforwarding --- .../networking/v2/extensions/layer3/layer3.go | 2 ++ .../extensions/layer3/portforwardings_test.go | 3 +++ .../layer3/portforwarding/requests.go | 20 +++++++++---------- .../layer3/portforwarding/results.go | 4 ++++ 4 files changed, 18 insertions(+), 11 deletions(-) diff --git a/internal/acceptance/openstack/networking/v2/extensions/layer3/layer3.go b/internal/acceptance/openstack/networking/v2/extensions/layer3/layer3.go index 1edc2d0cc8..c45bb08069 100644 --- a/internal/acceptance/openstack/networking/v2/extensions/layer3/layer3.go +++ b/internal/acceptance/openstack/networking/v2/extensions/layer3/layer3.go @@ -75,7 +75,9 @@ func CreatePortForwarding(t *testing.T, client *gophercloud.ServiceClient, fipID fixedIP := portFixedIPs[0] internalIP := fixedIP.IPAddress + pfDescription := "Test description" createOpts := &portforwarding.CreateOpts{ + Description: pfDescription, Protocol: "tcp", InternalPort: 25, ExternalPort: 2230, diff --git a/internal/acceptance/openstack/networking/v2/extensions/layer3/portforwardings_test.go b/internal/acceptance/openstack/networking/v2/extensions/layer3/portforwardings_test.go index bd9ccf3ad4..3d3f208529 100644 --- a/internal/acceptance/openstack/networking/v2/extensions/layer3/portforwardings_test.go +++ b/internal/acceptance/openstack/networking/v2/extensions/layer3/portforwardings_test.go @@ -56,6 +56,7 @@ func TestLayer3PortForwardingsCreateDelete(t *testing.T) { pf, err := CreatePortForwarding(t, client, fip.ID, port.ID, port.FixedIPs) th.AssertNoErr(t, err) + th.AssertEquals(t, pf.Description, "Test description") defer DeletePortForwarding(t, client, fip.ID, pf.ID) tools.PrintResource(t, pf) @@ -63,6 +64,7 @@ func TestLayer3PortForwardingsCreateDelete(t *testing.T) { th.AssertNoErr(t, err) updateOpts := portforwarding.UpdateOpts{ + Description: new(string), Protocol: "udp", InternalPort: 30, ExternalPort: 678, @@ -73,6 +75,7 @@ func TestLayer3PortForwardingsCreateDelete(t *testing.T) { newPf, err = portforwarding.Get(context.TODO(), client, fip.ID, pf.ID).Extract() th.AssertNoErr(t, err) + th.AssertEquals(t, newPf.Description, "") allPages, err := portforwarding.List(client, portforwarding.ListOpts{}, fip.ID).AllPages(context.TODO()) th.AssertNoErr(t, err) diff --git a/openstack/networking/v2/extensions/layer3/portforwarding/requests.go b/openstack/networking/v2/extensions/layer3/portforwarding/requests.go index 42f90332ac..1b07b6b7c9 100644 --- a/openstack/networking/v2/extensions/layer3/portforwarding/requests.go +++ b/openstack/networking/v2/extensions/layer3/portforwarding/requests.go @@ -18,6 +18,7 @@ type ListOptsBuilder interface { // either `asc' or `desc'. Marker and Limit are used for pagination. type ListOpts struct { ID string `q:"id"` + Description string `q:"description"` InternalPortID string `q:"internal_port_id"` ExternalPort string `q:"external_port"` InternalIPAddress string `q:"internal_ip_address"` @@ -63,6 +64,7 @@ func Get(ctx context.Context, c *gophercloud.ServiceClient, floatingIpId string, // CreateOpts contains all the values needed to create a new port forwarding // resource. All attributes are required. type CreateOpts struct { + Description string `json:"description,omitempty"` InternalPortID string `json:"internal_port_id"` InternalIPAddress string `json:"internal_ip_address"` InternalPort int `json:"internal_port"` @@ -97,22 +99,18 @@ func Create(ctx context.Context, c *gophercloud.ServiceClient, floatingIpId stri // UpdateOpts contains the values used when updating a port forwarding resource. type UpdateOpts struct { - InternalPortID string `json:"internal_port_id,omitempty"` - InternalIPAddress string `json:"internal_ip_address,omitempty"` - InternalPort int `json:"internal_port,omitempty"` - ExternalPort int `json:"external_port,omitempty"` - Protocol string `json:"protocol,omitempty"` + Description *string `json:"description,omitempty"` + InternalPortID string `json:"internal_port_id,omitempty"` + InternalIPAddress string `json:"internal_ip_address,omitempty"` + InternalPort int `json:"internal_port,omitempty"` + ExternalPort int `json:"external_port,omitempty"` + Protocol string `json:"protocol,omitempty"` } // ToPortForwardingUpdateMap allows UpdateOpts to satisfy the UpdateOptsBuilder // interface func (opts UpdateOpts) ToPortForwardingUpdateMap() (map[string]any, error) { - b, err := gophercloud.BuildRequestBody(opts, "port_forwarding") - if err != nil { - return nil, err - } - - return b, nil + return gophercloud.BuildRequestBody(opts, "port_forwarding") } // UpdateOptsBuilder allows extensions to add additional parameters to the diff --git a/openstack/networking/v2/extensions/layer3/portforwarding/results.go b/openstack/networking/v2/extensions/layer3/portforwarding/results.go index 17c5281acc..89e71efd0e 100644 --- a/openstack/networking/v2/extensions/layer3/portforwarding/results.go +++ b/openstack/networking/v2/extensions/layer3/portforwarding/results.go @@ -9,6 +9,10 @@ type PortForwarding struct { // The ID of the floating IP port forwarding ID string `json:"id"` + // A text describing the rule, which helps users to manage/find easily + // theirs rules. + Description string `json:"description"` + // The ID of the Neutron port associated to the floating IP port forwarding. InternalPortID string `json:"internal_port_id"` From ffe4285f70574d914e843b5113085ef38c86c624 Mon Sep 17 00:00:00 2001 From: kayrus Date: Mon, 15 Jul 2024 14:31:48 +0200 Subject: [PATCH 002/353] [tests]: bump golang to 1.22 --- .github/workflows/functional-baremetal.yaml | 2 +- .github/workflows/functional-basic.yaml | 2 +- .github/workflows/functional-blockstorage.yaml | 2 +- .github/workflows/functional-compute.yaml | 2 +- .github/workflows/functional-containerinfra.yaml | 2 +- .github/workflows/functional-dns.yaml | 2 +- .github/workflows/functional-fwaas_v2.yaml | 2 +- .github/workflows/functional-identity.yaml | 2 +- .github/workflows/functional-image.yaml | 2 +- .github/workflows/functional-keymanager.yaml | 2 +- .github/workflows/functional-loadbalancer.yaml | 2 +- .github/workflows/functional-messaging.yaml | 2 +- .github/workflows/functional-networking.yaml | 2 +- .github/workflows/functional-objectstorage.yaml | 2 +- .github/workflows/functional-orchestration.yaml | 2 +- .github/workflows/functional-placement.yaml | 2 +- .github/workflows/functional-sharedfilesystems.yaml | 2 +- 17 files changed, 17 insertions(+), 17 deletions(-) diff --git a/.github/workflows/functional-baremetal.yaml b/.github/workflows/functional-baremetal.yaml index ddaeb1fd14..c4aa44d8f5 100644 --- a/.github/workflows/functional-baremetal.yaml +++ b/.github/workflows/functional-baremetal.yaml @@ -91,7 +91,7 @@ jobs: - name: Checkout go uses: actions/setup-go@v5 with: - go-version: '^1.20' + go-version: '^1.22' - name: Run Gophercloud acceptance tests run: ./script/acceptancetest env: diff --git a/.github/workflows/functional-basic.yaml b/.github/workflows/functional-basic.yaml index cc134dfb91..8157156702 100644 --- a/.github/workflows/functional-basic.yaml +++ b/.github/workflows/functional-basic.yaml @@ -43,7 +43,7 @@ jobs: - name: Checkout go uses: actions/setup-go@v5 with: - go-version: '^1.20' + go-version: '^1.22' - name: Run Gophercloud acceptance tests run: ./script/acceptancetest env: diff --git a/.github/workflows/functional-blockstorage.yaml b/.github/workflows/functional-blockstorage.yaml index daf2bb31ce..dceb7596a3 100644 --- a/.github/workflows/functional-blockstorage.yaml +++ b/.github/workflows/functional-blockstorage.yaml @@ -42,7 +42,7 @@ jobs: - name: Checkout go uses: actions/setup-go@v5 with: - go-version: '^1.20' + go-version: '^1.22' - name: Run Gophercloud acceptance tests run: ./script/acceptancetest env: diff --git a/.github/workflows/functional-compute.yaml b/.github/workflows/functional-compute.yaml index 0065891bdb..0e1bab61e9 100644 --- a/.github/workflows/functional-compute.yaml +++ b/.github/workflows/functional-compute.yaml @@ -42,7 +42,7 @@ jobs: - name: Checkout go uses: actions/setup-go@v5 with: - go-version: '^1.20' + go-version: '^1.22' - name: Run Gophercloud acceptance tests run: ./script/acceptancetest env: diff --git a/.github/workflows/functional-containerinfra.yaml b/.github/workflows/functional-containerinfra.yaml index d42add38cb..df45bae93e 100644 --- a/.github/workflows/functional-containerinfra.yaml +++ b/.github/workflows/functional-containerinfra.yaml @@ -59,7 +59,7 @@ jobs: - name: Checkout go uses: actions/setup-go@v5 with: - go-version: '^1.20' + go-version: '^1.22' - name: Run Gophercloud acceptance tests run: ./script/acceptancetest env: diff --git a/.github/workflows/functional-dns.yaml b/.github/workflows/functional-dns.yaml index 9145ae0198..a20d5c1f85 100644 --- a/.github/workflows/functional-dns.yaml +++ b/.github/workflows/functional-dns.yaml @@ -43,7 +43,7 @@ jobs: - name: Checkout go uses: actions/setup-go@v5 with: - go-version: '^1.20' + go-version: '^1.22' - name: Run Gophercloud acceptance tests run: ./script/acceptancetest env: diff --git a/.github/workflows/functional-fwaas_v2.yaml b/.github/workflows/functional-fwaas_v2.yaml index 6accf2828c..09d03db28b 100644 --- a/.github/workflows/functional-fwaas_v2.yaml +++ b/.github/workflows/functional-fwaas_v2.yaml @@ -47,7 +47,7 @@ jobs: - name: Checkout go uses: actions/setup-go@v5 with: - go-version: '^1.20' + go-version: '^1.22' - name: Run Gophercloud acceptance tests run: ./script/acceptancetest env: diff --git a/.github/workflows/functional-identity.yaml b/.github/workflows/functional-identity.yaml index ebe76b40a0..f6f083bc62 100644 --- a/.github/workflows/functional-identity.yaml +++ b/.github/workflows/functional-identity.yaml @@ -40,7 +40,7 @@ jobs: - name: Checkout go uses: actions/setup-go@v5 with: - go-version: '^1.20' + go-version: '^1.22' - name: Run Gophercloud acceptance tests run: ./script/acceptancetest env: diff --git a/.github/workflows/functional-image.yaml b/.github/workflows/functional-image.yaml index 70ab27eeef..554c89fcc3 100644 --- a/.github/workflows/functional-image.yaml +++ b/.github/workflows/functional-image.yaml @@ -40,7 +40,7 @@ jobs: - name: Checkout go uses: actions/setup-go@v5 with: - go-version: '^1.20' + go-version: '^1.22' - name: Run Gophercloud acceptance tests run: ./script/acceptancetest env: diff --git a/.github/workflows/functional-keymanager.yaml b/.github/workflows/functional-keymanager.yaml index de2c95c503..9cdd3cbdf1 100644 --- a/.github/workflows/functional-keymanager.yaml +++ b/.github/workflows/functional-keymanager.yaml @@ -42,7 +42,7 @@ jobs: - name: Checkout go uses: actions/setup-go@v5 with: - go-version: '^1.20' + go-version: '^1.22' - name: Run Gophercloud acceptance tests run: ./script/acceptancetest env: diff --git a/.github/workflows/functional-loadbalancer.yaml b/.github/workflows/functional-loadbalancer.yaml index b93014dadd..c40e8ee2c4 100644 --- a/.github/workflows/functional-loadbalancer.yaml +++ b/.github/workflows/functional-loadbalancer.yaml @@ -43,7 +43,7 @@ jobs: - name: Checkout go uses: actions/setup-go@v5 with: - go-version: '^1.20' + go-version: '^1.22' - name: Run Gophercloud acceptance tests run: ./script/acceptancetest env: diff --git a/.github/workflows/functional-messaging.yaml b/.github/workflows/functional-messaging.yaml index 6703dbb835..db990e0d81 100644 --- a/.github/workflows/functional-messaging.yaml +++ b/.github/workflows/functional-messaging.yaml @@ -43,7 +43,7 @@ jobs: - name: Checkout go uses: actions/setup-go@v5 with: - go-version: '^1.20' + go-version: '^1.22' - name: Run Gophercloud acceptance tests run: ./script/acceptancetest env: diff --git a/.github/workflows/functional-networking.yaml b/.github/workflows/functional-networking.yaml index feb896eb45..480a493d88 100644 --- a/.github/workflows/functional-networking.yaml +++ b/.github/workflows/functional-networking.yaml @@ -57,7 +57,7 @@ jobs: - name: Checkout go uses: actions/setup-go@v5 with: - go-version: '^1.20' + go-version: '^1.22' - name: Run Gophercloud acceptance tests run: ./script/acceptancetest env: diff --git a/.github/workflows/functional-objectstorage.yaml b/.github/workflows/functional-objectstorage.yaml index ebb63e8a41..c0b204a1b4 100644 --- a/.github/workflows/functional-objectstorage.yaml +++ b/.github/workflows/functional-objectstorage.yaml @@ -46,7 +46,7 @@ jobs: - name: Checkout go uses: actions/setup-go@v5 with: - go-version: '^1.20' + go-version: '^1.22' - name: Run Gophercloud acceptance tests run: ./script/acceptancetest env: diff --git a/.github/workflows/functional-orchestration.yaml b/.github/workflows/functional-orchestration.yaml index 8e7bc6b8aa..0f627474b5 100644 --- a/.github/workflows/functional-orchestration.yaml +++ b/.github/workflows/functional-orchestration.yaml @@ -42,7 +42,7 @@ jobs: - name: Checkout go uses: actions/setup-go@v5 with: - go-version: '^1.20' + go-version: '^1.22' - name: Run Gophercloud acceptance tests run: ./script/acceptancetest env: diff --git a/.github/workflows/functional-placement.yaml b/.github/workflows/functional-placement.yaml index d407413ac0..640df2c1d5 100644 --- a/.github/workflows/functional-placement.yaml +++ b/.github/workflows/functional-placement.yaml @@ -40,7 +40,7 @@ jobs: - name: Checkout go uses: actions/setup-go@v5 with: - go-version: '^1.20' + go-version: '^1.22' - name: Run Gophercloud acceptance tests run: ./script/acceptancetest env: diff --git a/.github/workflows/functional-sharedfilesystems.yaml b/.github/workflows/functional-sharedfilesystems.yaml index e46a39f0ee..e4d8bbea39 100644 --- a/.github/workflows/functional-sharedfilesystems.yaml +++ b/.github/workflows/functional-sharedfilesystems.yaml @@ -56,7 +56,7 @@ jobs: - name: Checkout go uses: actions/setup-go@v5 with: - go-version: '^1.20' + go-version: '^1.22' - name: Run Gophercloud acceptance tests run: ./script/acceptancetest env: From 65470e335580473093b65da9c182640f820a9f7d Mon Sep 17 00:00:00 2001 From: Pablo COLSON Date: Mon, 8 Jul 2024 20:21:49 +0200 Subject: [PATCH 003/353] [networking]: subnet add field dns_publish_fixed_ip --- openstack/networking/v2/subnets/requests.go | 49 +- openstack/networking/v2/subnets/results.go | 3 + .../v2/subnets/testing/fixtures_test.go | 795 +++++++++--------- 3 files changed, 435 insertions(+), 412 deletions(-) diff --git a/openstack/networking/v2/subnets/requests.go b/openstack/networking/v2/subnets/requests.go index 20f747b5a9..db597d6864 100644 --- a/openstack/networking/v2/subnets/requests.go +++ b/openstack/networking/v2/subnets/requests.go @@ -20,27 +20,28 @@ type ListOptsBuilder interface { // by a particular subnet attribute. SortDir sets the direction, and is either // `asc' or `desc'. Marker and Limit are used for pagination. type ListOpts struct { - Name string `q:"name"` - Description string `q:"description"` - EnableDHCP *bool `q:"enable_dhcp"` - NetworkID string `q:"network_id"` - TenantID string `q:"tenant_id"` - ProjectID string `q:"project_id"` - IPVersion int `q:"ip_version"` - GatewayIP string `q:"gateway_ip"` - CIDR string `q:"cidr"` - IPv6AddressMode string `q:"ipv6_address_mode"` - IPv6RAMode string `q:"ipv6_ra_mode"` - ID string `q:"id"` - SubnetPoolID string `q:"subnetpool_id"` - Limit int `q:"limit"` - Marker string `q:"marker"` - SortKey string `q:"sort_key"` - SortDir string `q:"sort_dir"` - Tags string `q:"tags"` - TagsAny string `q:"tags-any"` - NotTags string `q:"not-tags"` - NotTagsAny string `q:"not-tags-any"` + Name string `q:"name"` + Description string `q:"description"` + DNSPublishFixedIP *bool `q:"dns_publish_fixed_ip"` + EnableDHCP *bool `q:"enable_dhcp"` + NetworkID string `q:"network_id"` + TenantID string `q:"tenant_id"` + ProjectID string `q:"project_id"` + IPVersion int `q:"ip_version"` + GatewayIP string `q:"gateway_ip"` + CIDR string `q:"cidr"` + IPv6AddressMode string `q:"ipv6_address_mode"` + IPv6RAMode string `q:"ipv6_ra_mode"` + ID string `q:"id"` + SubnetPoolID string `q:"subnetpool_id"` + Limit int `q:"limit"` + Marker string `q:"marker"` + SortKey string `q:"sort_key"` + SortDir string `q:"sort_dir"` + Tags string `q:"tags"` + TagsAny string `q:"tags-any"` + NotTags string `q:"not-tags"` + NotTagsAny string `q:"not-tags-any"` } // ToSubnetListQuery formats a ListOpts into a query string. @@ -123,6 +124,9 @@ type CreateOpts struct { // DNSNameservers are the nameservers to be set via DHCP. DNSNameservers []string `json:"dns_nameservers,omitempty"` + // DNSPublishFixedIP will either enable or disable the publication of fixed IPs to the DNS + DNSPublishFixedIP *bool `json:"dns_publish_fixed_ip,omitempty"` + // ServiceTypes are the service types associated with the subnet. ServiceTypes []string `json:"service_types,omitempty"` @@ -198,6 +202,9 @@ type UpdateOpts struct { // DNSNameservers are the nameservers to be set via DHCP. DNSNameservers *[]string `json:"dns_nameservers,omitempty"` + // DNSPublishFixedIP will either enable or disable the publication of fixed IPs to the DNS + DNSPublishFixedIP *bool `json:"dns_publish_fixed_ip,omitempty"` + // ServiceTypes are the service types associated with the subnet. ServiceTypes *[]string `json:"service_types,omitempty"` diff --git a/openstack/networking/v2/subnets/results.go b/openstack/networking/v2/subnets/results.go index a105c75015..cab10623e0 100644 --- a/openstack/networking/v2/subnets/results.go +++ b/openstack/networking/v2/subnets/results.go @@ -83,6 +83,9 @@ type Subnet struct { // DNS name servers used by hosts in this subnet. DNSNameservers []string `json:"dns_nameservers"` + // Specifies whether the fixed IP addresses are published to the DNS. + DNSPublishFixedIP bool `json:"dns_publish_fixed_ip,omitempty"` + // Service types associated with the subnet. ServiceTypes []string `json:"service_types"` diff --git a/openstack/networking/v2/subnets/testing/fixtures_test.go b/openstack/networking/v2/subnets/testing/fixtures_test.go index e6079975ec..a44f1cc77e 100644 --- a/openstack/networking/v2/subnets/testing/fixtures_test.go +++ b/openstack/networking/v2/subnets/testing/fixtures_test.go @@ -6,90 +6,94 @@ import ( const SubnetListResult = ` { - "subnets": [ - { - "name": "private-subnet", - "enable_dhcp": true, - "network_id": "db193ab3-96e3-4cb3-8fc5-05f4296d0324", - "tenant_id": "26a7980765d0414dbc1fc1f88cdb7e6e", - "dns_nameservers": [], - "allocation_pools": [ - { - "start": "10.0.0.2", - "end": "10.0.0.254" - } - ], - "host_routes": [], - "ip_version": 4, - "gateway_ip": "10.0.0.1", - "cidr": "10.0.0.0/24", - "id": "08eae331-0402-425a-923c-34f7cfe39c1b" - }, - { - "name": "my_subnet", - "enable_dhcp": true, - "network_id": "d32019d3-bc6e-4319-9c1d-6722fc136a22", - "tenant_id": "4fd44f30292945e481c7b8a0c8908869", - "dns_nameservers": [], - "allocation_pools": [ - { - "start": "192.0.0.2", - "end": "192.255.255.254" - } - ], - "host_routes": [], - "ip_version": 4, - "gateway_ip": "192.0.0.1", - "cidr": "192.0.0.0/8", - "id": "54d6f61d-db07-451c-9ab3-b9609b6b6f0b" - }, - { - "name": "my_gatewayless_subnet", - "enable_dhcp": true, - "network_id": "d32019d3-bc6e-4319-9c1d-6722fc136a23", - "tenant_id": "4fd44f30292945e481c7b8a0c8908869", - "dns_nameservers": [], - "allocation_pools": [ - { - "start": "192.168.1.2", - "end": "192.168.1.254" - } - ], - "host_routes": [], - "ip_version": 4, - "gateway_ip": null, - "cidr": "192.168.1.0/24", - "id": "54d6f61d-db07-451c-9ab3-b9609b6b6f0c" - }, - { - "name": "my_subnet_with_subnetpool", - "enable_dhcp": false, - "network_id": "d32019d3-bc6e-4319-9c1d-6722fc136a23", - "tenant_id": "4fd44f30292945e481c7b8a0c8908869", - "dns_nameservers": [], - "allocation_pools": [ - { - "start": "10.11.12.2", - "end": "10.11.12.254" - } - ], - "host_routes": [], - "ip_version": 4, - "gateway_ip": null, - "cidr": "10.11.12.0/24", - "id": "38186a51-f373-4bbc-838b-6eaa1aa13eac", - "subnetpool_id": "b80340c7-9960-4f67-a99c-02501656284b" - } - ] + "subnets": [ + { + "name": "private-subnet", + "enable_dhcp": true, + "dns_publish_fixed_ip": true, + "network_id": "db193ab3-96e3-4cb3-8fc5-05f4296d0324", + "tenant_id": "26a7980765d0414dbc1fc1f88cdb7e6e", + "dns_nameservers": [], + "allocation_pools": [ + { + "start": "10.0.0.2", + "end": "10.0.0.254" + } + ], + "host_routes": [], + "ip_version": 4, + "gateway_ip": "10.0.0.1", + "cidr": "10.0.0.0/24", + "id": "08eae331-0402-425a-923c-34f7cfe39c1b" + }, + { + "name": "my_subnet", + "enable_dhcp": true, + "dns_publish_fixed_ip": true, + "network_id": "d32019d3-bc6e-4319-9c1d-6722fc136a22", + "tenant_id": "4fd44f30292945e481c7b8a0c8908869", + "dns_nameservers": [], + "allocation_pools": [ + { + "start": "192.0.0.2", + "end": "192.255.255.254" + } + ], + "host_routes": [], + "ip_version": 4, + "gateway_ip": "192.0.0.1", + "cidr": "192.0.0.0/8", + "id": "54d6f61d-db07-451c-9ab3-b9609b6b6f0b" + }, + { + "name": "my_gatewayless_subnet", + "enable_dhcp": true, + "dns_publish_fixed_ip": true, + "network_id": "d32019d3-bc6e-4319-9c1d-6722fc136a23", + "tenant_id": "4fd44f30292945e481c7b8a0c8908869", + "dns_nameservers": [], + "allocation_pools": [ + { + "start": "192.168.1.2", + "end": "192.168.1.254" + } + ], + "host_routes": [], + "ip_version": 4, + "gateway_ip": null, + "cidr": "192.168.1.0/24", + "id": "54d6f61d-db07-451c-9ab3-b9609b6b6f0c" + }, + { + "name": "my_subnet_with_subnetpool", + "enable_dhcp": false, + "network_id": "d32019d3-bc6e-4319-9c1d-6722fc136a23", + "tenant_id": "4fd44f30292945e481c7b8a0c8908869", + "dns_nameservers": [], + "allocation_pools": [ + { + "start": "10.11.12.2", + "end": "10.11.12.254" + } + ], + "host_routes": [], + "ip_version": 4, + "gateway_ip": null, + "cidr": "10.11.12.0/24", + "id": "38186a51-f373-4bbc-838b-6eaa1aa13eac", + "subnetpool_id": "b80340c7-9960-4f67-a99c-02501656284b" + } + ] } ` var Subnet1 = subnets.Subnet{ - Name: "private-subnet", - EnableDHCP: true, - NetworkID: "db193ab3-96e3-4cb3-8fc5-05f4296d0324", - TenantID: "26a7980765d0414dbc1fc1f88cdb7e6e", - DNSNameservers: []string{}, + Name: "private-subnet", + EnableDHCP: true, + NetworkID: "db193ab3-96e3-4cb3-8fc5-05f4296d0324", + TenantID: "26a7980765d0414dbc1fc1f88cdb7e6e", + DNSNameservers: []string{}, + DNSPublishFixedIP: true, AllocationPools: []subnets.AllocationPool{ { Start: "10.0.0.2", @@ -104,11 +108,13 @@ var Subnet1 = subnets.Subnet{ } var Subnet2 = subnets.Subnet{ - Name: "my_subnet", - EnableDHCP: true, - NetworkID: "d32019d3-bc6e-4319-9c1d-6722fc136a22", - TenantID: "4fd44f30292945e481c7b8a0c8908869", - DNSNameservers: []string{}, + Name: "my_subnet", + EnableDHCP: true, + + NetworkID: "d32019d3-bc6e-4319-9c1d-6722fc136a22", + TenantID: "4fd44f30292945e481c7b8a0c8908869", + DNSNameservers: []string{}, + DNSPublishFixedIP: true, AllocationPools: []subnets.AllocationPool{ { Start: "192.0.0.2", @@ -123,11 +129,12 @@ var Subnet2 = subnets.Subnet{ } var Subnet3 = subnets.Subnet{ - Name: "my_gatewayless_subnet", - EnableDHCP: true, - NetworkID: "d32019d3-bc6e-4319-9c1d-6722fc136a23", - TenantID: "4fd44f30292945e481c7b8a0c8908869", - DNSNameservers: []string{}, + Name: "my_gatewayless_subnet", + EnableDHCP: true, + NetworkID: "d32019d3-bc6e-4319-9c1d-6722fc136a23", + TenantID: "4fd44f30292945e481c7b8a0c8908869", + DNSNameservers: []string{}, + DNSPublishFixedIP: true, AllocationPools: []subnets.AllocationPool{ { Start: "192.168.1.2", @@ -142,11 +149,12 @@ var Subnet3 = subnets.Subnet{ } var Subnet4 = subnets.Subnet{ - Name: "my_subnet_with_subnetpool", - EnableDHCP: false, - NetworkID: "d32019d3-bc6e-4319-9c1d-6722fc136a23", - TenantID: "4fd44f30292945e481c7b8a0c8908869", - DNSNameservers: []string{}, + Name: "my_subnet_with_subnetpool", + EnableDHCP: false, + NetworkID: "d32019d3-bc6e-4319-9c1d-6722fc136a23", + TenantID: "4fd44f30292945e481c7b8a0c8908869", + DNSNameservers: []string{}, + DNSPublishFixedIP: false, AllocationPools: []subnets.AllocationPool{ { Start: "10.11.12.2", @@ -163,409 +171,414 @@ var Subnet4 = subnets.Subnet{ const SubnetGetResult = ` { - "subnet": { - "name": "my_subnet", - "enable_dhcp": true, - "network_id": "d32019d3-bc6e-4319-9c1d-6722fc136a22", - "tenant_id": "4fd44f30292945e481c7b8a0c8908869", - "dns_nameservers": [], - "allocation_pools": [ - { - "start": "192.0.0.2", - "end": "192.255.255.254" - } - ], - "host_routes": [], - "ip_version": 4, - "gateway_ip": "192.0.0.1", - "cidr": "192.0.0.0/8", - "id": "54d6f61d-db07-451c-9ab3-b9609b6b6f0b", - "subnetpool_id": "b80340c7-9960-4f67-a99c-02501656284b" - } + "subnet": { + "name": "my_subnet", + "enable_dhcp": true, + "dns_publish_fixed_ip": true, + "network_id": "d32019d3-bc6e-4319-9c1d-6722fc136a22", + "tenant_id": "4fd44f30292945e481c7b8a0c8908869", + "dns_nameservers": [], + "allocation_pools": [ + { + "start": "192.0.0.2", + "end": "192.255.255.254" + } + ], + "host_routes": [], + "ip_version": 4, + "gateway_ip": "192.0.0.1", + "cidr": "192.0.0.0/8", + "id": "54d6f61d-db07-451c-9ab3-b9609b6b6f0b", + "subnetpool_id": "b80340c7-9960-4f67-a99c-02501656284b" + } } ` const SubnetCreateRequest = ` { - "subnet": { - "network_id": "d32019d3-bc6e-4319-9c1d-6722fc136a22", - "ip_version": 4, - "gateway_ip": "192.168.199.1", - "cidr": "192.168.199.0/24", - "dns_nameservers": ["foo"], - "service_types": ["network:routed"], - "allocation_pools": [ - { - "start": "192.168.199.2", - "end": "192.168.199.254" - } - ], - "host_routes": [{"destination":"","nexthop": "bar"}], - "subnetpool_id": "b80340c7-9960-4f67-a99c-02501656284b" - } + "subnet": { + "network_id": "d32019d3-bc6e-4319-9c1d-6722fc136a22", + "ip_version": 4, + "dns_publish_fixed_ip": true, + "gateway_ip": "192.168.199.1", + "cidr": "192.168.199.0/24", + "dns_nameservers": ["foo"], + "service_types": ["network:routed"], + "allocation_pools": [ + { + "start": "192.168.199.2", + "end": "192.168.199.254" + } + ], + "host_routes": [{"destination":"","nexthop": "bar"}], + "subnetpool_id": "b80340c7-9960-4f67-a99c-02501656284b" + } } ` const SubnetCreateResult = ` { - "subnet": { - "name": "", - "enable_dhcp": true, - "network_id": "d32019d3-bc6e-4319-9c1d-6722fc136a22", - "tenant_id": "4fd44f30292945e481c7b8a0c8908869", - "dns_nameservers": ["foo"], - "service_types": ["network:routed"], - "allocation_pools": [ - { - "start": "192.168.199.2", - "end": "192.168.199.254" - } - ], - "host_routes": [], - "ip_version": 4, - "gateway_ip": "192.168.199.1", - "cidr": "192.168.199.0/24", - "id": "3b80198d-4f7b-4f77-9ef5-774d54e17126", - "subnetpool_id": "b80340c7-9960-4f67-a99c-02501656284b" - } + "subnet": { + "name": "", + "enable_dhcp": true, + "dns_publish_fixed_ip": true, + "network_id": "d32019d3-bc6e-4319-9c1d-6722fc136a22", + "tenant_id": "4fd44f30292945e481c7b8a0c8908869", + "dns_nameservers": ["foo"], + "service_types": ["network:routed"], + "allocation_pools": [ + { + "start": "192.168.199.2", + "end": "192.168.199.254" + } + ], + "host_routes": [], + "ip_version": 4, + "gateway_ip": "192.168.199.1", + "cidr": "192.168.199.0/24", + "id": "3b80198d-4f7b-4f77-9ef5-774d54e17126", + "subnetpool_id": "b80340c7-9960-4f67-a99c-02501656284b" + } } ` const SubnetCreateWithNoGatewayRequest = ` { - "subnet": { - "network_id": "d32019d3-bc6e-4319-9c1d-6722fc136a23", - "ip_version": 4, - "cidr": "192.168.1.0/24", - "gateway_ip": null, - "allocation_pools": [ - { - "start": "192.168.1.2", - "end": "192.168.1.254" - } - ] - } + "subnet": { + "network_id": "d32019d3-bc6e-4319-9c1d-6722fc136a23", + "ip_version": 4, + "cidr": "192.168.1.0/24", + "gateway_ip": null, + "allocation_pools": [ + { + "start": "192.168.1.2", + "end": "192.168.1.254" + } + ] + } } ` const SubnetCreateWithNoGatewayResponse = ` { - "subnet": { - "name": "", - "enable_dhcp": true, - "network_id": "d32019d3-bc6e-4319-9c1d-6722fc136a23", - "tenant_id": "4fd44f30292945e481c7b8a0c8908869", - "allocation_pools": [ - { - "start": "192.168.1.2", - "end": "192.168.1.254" - } - ], - "host_routes": [], - "ip_version": 4, - "gateway_ip": null, - "cidr": "192.168.1.0/24", - "id": "54d6f61d-db07-451c-9ab3-b9609b6b6f0c" - } + "subnet": { + "name": "", + "enable_dhcp": true, + "dns_publish_fixed_ip": true, + "network_id": "d32019d3-bc6e-4319-9c1d-6722fc136a23", + "tenant_id": "4fd44f30292945e481c7b8a0c8908869", + "allocation_pools": [ + { + "start": "192.168.1.2", + "end": "192.168.1.254" + } + ], + "host_routes": [], + "ip_version": 4, + "gateway_ip": null, + "cidr": "192.168.1.0/24", + "id": "54d6f61d-db07-451c-9ab3-b9609b6b6f0c" + } } ` const SubnetCreateWithDefaultGatewayRequest = ` { - "subnet": { - "network_id": "d32019d3-bc6e-4319-9c1d-6722fc136a23", - "ip_version": 4, - "cidr": "192.168.1.0/24", - "allocation_pools": [ - { - "start": "192.168.1.2", - "end": "192.168.1.254" - } - ] - } + "subnet": { + "network_id": "d32019d3-bc6e-4319-9c1d-6722fc136a23", + "ip_version": 4, + "cidr": "192.168.1.0/24", + "allocation_pools": [ + { + "start": "192.168.1.2", + "end": "192.168.1.254" + } + ] + } } ` const SubnetCreateWithDefaultGatewayResponse = ` { - "subnet": { - "name": "", - "enable_dhcp": true, - "network_id": "d32019d3-bc6e-4319-9c1d-6722fc136a23", - "tenant_id": "4fd44f30292945e481c7b8a0c8908869", - "allocation_pools": [ - { - "start": "192.168.1.2", - "end": "192.168.1.254" - } - ], - "host_routes": [], - "ip_version": 4, - "gateway_ip": "192.168.1.1", - "cidr": "192.168.1.0/24", - "id": "54d6f61d-db07-451c-9ab3-b9609b6b6f0c" - } + "subnet": { + "name": "", + "enable_dhcp": true, + "dns_publish_fixed_ip": true, + "network_id": "d32019d3-bc6e-4319-9c1d-6722fc136a23", + "tenant_id": "4fd44f30292945e481c7b8a0c8908869", + "allocation_pools": [ + { + "start": "192.168.1.2", + "end": "192.168.1.254" + } + ], + "host_routes": [], + "ip_version": 4, + "gateway_ip": "192.168.1.1", + "cidr": "192.168.1.0/24", + "id": "54d6f61d-db07-451c-9ab3-b9609b6b6f0c" + } } ` const SubnetCreateWithIPv6RaAddressModeRequest = ` { - "subnet": { - "network_id": "d32019d3-bc6e-4319-9c1d-6722fc136a22", - "ip_version": 6, - "gateway_ip": "2001:db8:0:a::1", - "cidr": "2001:db8:0:a:0:0:0:0/64", - "ipv6_address_mode": "slaac", - "ipv6_ra_mode": "slaac" - } + "subnet": { + "network_id": "d32019d3-bc6e-4319-9c1d-6722fc136a22", + "ip_version": 6, + "gateway_ip": "2001:db8:0:a::1", + "cidr": "2001:db8:0:a:0:0:0:0/64", + "ipv6_address_mode": "slaac", + "ipv6_ra_mode": "slaac" + } } ` const SubnetCreateWithIPv6RaAddressModeResponse = ` { - "subnet": { - "name": "", - "enable_dhcp": true, - "network_id": "d32019d3-bc6e-4319-9c1d-6722fc136a22", - "tenant_id": "4fd44f30292945e481c7b8a0c8908869", - "dns_nameservers": [], - "host_routes": [], - "ip_version": 6, - "gateway_ip": "2001:db8:0:a::1", - "cidr": "2001:db8:0:a:0:0:0:0/64", - "id": "3b80198d-4f7b-4f77-9ef5-774d54e17126", - "ipv6_address_mode": "slaac", - "ipv6_ra_mode": "slaac" - } + "subnet": { + "name": "", + "enable_dhcp": true, + "network_id": "d32019d3-bc6e-4319-9c1d-6722fc136a22", + "tenant_id": "4fd44f30292945e481c7b8a0c8908869", + "dns_nameservers": [], + "host_routes": [], + "ip_version": 6, + "gateway_ip": "2001:db8:0:a::1", + "cidr": "2001:db8:0:a:0:0:0:0/64", + "id": "3b80198d-4f7b-4f77-9ef5-774d54e17126", + "ipv6_address_mode": "slaac", + "ipv6_ra_mode": "slaac" + } } ` const SubnetCreateRequestWithNoCIDR = ` { - "subnet": { - "network_id": "d32019d3-bc6e-4319-9c1d-6722fc136a22", - "ip_version": 4, - "dns_nameservers": ["foo"], - "host_routes": [{"destination":"","nexthop": "bar"}], - "subnetpool_id": "b80340c7-9960-4f67-a99c-02501656284b" - } + "subnet": { + "network_id": "d32019d3-bc6e-4319-9c1d-6722fc136a22", + "ip_version": 4, + "dns_nameservers": ["foo"], + "host_routes": [{"destination":"","nexthop": "bar"}], + "subnetpool_id": "b80340c7-9960-4f67-a99c-02501656284b" + } } ` const SubnetCreateRequestWithPrefixlen = ` { - "subnet": { - "network_id": "d32019d3-bc6e-4319-9c1d-6722fc136a22", - "ip_version": 4, - "dns_nameservers": ["foo"], - "host_routes": [{"destination":"","nexthop": "bar"}], - "subnetpool_id": "b80340c7-9960-4f67-a99c-02501656284b", - "prefixlen": 12 - } + "subnet": { + "network_id": "d32019d3-bc6e-4319-9c1d-6722fc136a22", + "ip_version": 4, + "dns_nameservers": ["foo"], + "host_routes": [{"destination":"","nexthop": "bar"}], + "subnetpool_id": "b80340c7-9960-4f67-a99c-02501656284b", + "prefixlen": 12 + } } ` const SubnetUpdateRequest = ` { - "subnet": { - "name": "my_new_subnet", - "dns_nameservers": ["foo"], - "host_routes": [{"destination":"","nexthop": "bar"}] - } + "subnet": { + "name": "my_new_subnet", + "dns_nameservers": ["foo"], + "host_routes": [{"destination":"","nexthop": "bar"}] + } } ` const SubnetUpdateResponse = ` { - "subnet": { - "name": "my_new_subnet", - "enable_dhcp": true, - "network_id": "db193ab3-96e3-4cb3-8fc5-05f4296d0324", - "tenant_id": "26a7980765d0414dbc1fc1f88cdb7e6e", - "dns_nameservers": [], - "allocation_pools": [ - { - "start": "10.0.0.2", - "end": "10.0.0.254" - } - ], - "host_routes": [], - "ip_version": 4, - "gateway_ip": "10.0.0.1", - "cidr": "10.0.0.0/24", - "id": "08eae331-0402-425a-923c-34f7cfe39c1b" - } + "subnet": { + "name": "my_new_subnet", + "enable_dhcp": true, + "network_id": "db193ab3-96e3-4cb3-8fc5-05f4296d0324", + "tenant_id": "26a7980765d0414dbc1fc1f88cdb7e6e", + "dns_nameservers": [], + "allocation_pools": [ + { + "start": "10.0.0.2", + "end": "10.0.0.254" + } + ], + "host_routes": [], + "ip_version": 4, + "gateway_ip": "10.0.0.1", + "cidr": "10.0.0.0/24", + "id": "08eae331-0402-425a-923c-34f7cfe39c1b" + } } ` const SubnetUpdateGatewayRequest = ` { - "subnet": { - "name": "my_new_subnet", - "gateway_ip": "10.0.0.1" - } + "subnet": { + "name": "my_new_subnet", + "gateway_ip": "10.0.0.1" + } } ` const SubnetUpdateGatewayResponse = ` { - "subnet": { - "name": "my_new_subnet", - "enable_dhcp": true, - "network_id": "db193ab3-96e3-4cb3-8fc5-05f4296d0324", - "tenant_id": "26a7980765d0414dbc1fc1f88cdb7e6e", - "dns_nameservers": [], - "allocation_pools": [ - { - "start": "10.0.0.2", - "end": "10.0.0.254" - } - ], - "host_routes": [], - "ip_version": 4, - "gateway_ip": "10.0.0.1", - "cidr": "10.0.0.0/24", - "id": "08eae331-0402-425a-923c-34f7cfe39c1b" - } + "subnet": { + "name": "my_new_subnet", + "enable_dhcp": true, + "network_id": "db193ab3-96e3-4cb3-8fc5-05f4296d0324", + "tenant_id": "26a7980765d0414dbc1fc1f88cdb7e6e", + "dns_nameservers": [], + "allocation_pools": [ + { + "start": "10.0.0.2", + "end": "10.0.0.254" + } + ], + "host_routes": [], + "ip_version": 4, + "gateway_ip": "10.0.0.1", + "cidr": "10.0.0.0/24", + "id": "08eae331-0402-425a-923c-34f7cfe39c1b" + } } ` const SubnetUpdateRemoveGatewayRequest = ` { - "subnet": { - "name": "my_new_subnet", - "gateway_ip": null - } + "subnet": { + "name": "my_new_subnet", + "gateway_ip": null + } } ` const SubnetUpdateRemoveGatewayResponse = ` { - "subnet": { - "name": "my_new_subnet", - "enable_dhcp": true, - "network_id": "db193ab3-96e3-4cb3-8fc5-05f4296d0324", - "tenant_id": "26a7980765d0414dbc1fc1f88cdb7e6e", - "dns_nameservers": [], - "allocation_pools": [ - { - "start": "10.0.0.2", - "end": "10.0.0.254" - } - ], - "host_routes": [], - "ip_version": 4, - "gateway_ip": null, - "cidr": "10.0.0.0/24", - "id": "08eae331-0402-425a-923c-34f7cfe39c1b" - } + "subnet": { + "name": "my_new_subnet", + "enable_dhcp": true, + "network_id": "db193ab3-96e3-4cb3-8fc5-05f4296d0324", + "tenant_id": "26a7980765d0414dbc1fc1f88cdb7e6e", + "dns_nameservers": [], + "allocation_pools": [ + { + "start": "10.0.0.2", + "end": "10.0.0.254" + } + ], + "host_routes": [], + "ip_version": 4, + "gateway_ip": null, + "cidr": "10.0.0.0/24", + "id": "08eae331-0402-425a-923c-34f7cfe39c1b" + } } ` const SubnetUpdateHostRoutesRequest = ` { - "subnet": { - "name": "my_new_subnet", - "host_routes": [ - { - "destination": "192.168.1.1/24", - "nexthop": "bar" - } - ] - } + "subnet": { + "name": "my_new_subnet", + "host_routes": [ + { + "destination": "192.168.1.1/24", + "nexthop": "bar" + } + ] + } } ` const SubnetUpdateHostRoutesResponse = ` { - "subnet": { - "name": "my_new_subnet", - "enable_dhcp": true, - "network_id": "db193ab3-96e3-4cb3-8fc5-05f4296d0324", - "tenant_id": "26a7980765d0414dbc1fc1f88cdb7e6e", - "dns_nameservers": [], - "allocation_pools": [ - { - "start": "10.0.0.2", - "end": "10.0.0.254" - } - ], - "ip_version": 4, - "gateway_ip": "10.0.0.1", - "host_routes": [ - { - "destination": "192.168.1.1/24", - "nexthop": "bar" - } - ], - "cidr": "10.0.0.0/24", - "id": "08eae331-0402-425a-923c-34f7cfe39c1b" - } + "subnet": { + "name": "my_new_subnet", + "enable_dhcp": true, + "network_id": "db193ab3-96e3-4cb3-8fc5-05f4296d0324", + "tenant_id": "26a7980765d0414dbc1fc1f88cdb7e6e", + "dns_nameservers": [], + "allocation_pools": [ + { + "start": "10.0.0.2", + "end": "10.0.0.254" + } + ], + "ip_version": 4, + "gateway_ip": "10.0.0.1", + "host_routes": [ + { + "destination": "192.168.1.1/24", + "nexthop": "bar" + } + ], + "cidr": "10.0.0.0/24", + "id": "08eae331-0402-425a-923c-34f7cfe39c1b" + } } ` const SubnetUpdateRemoveHostRoutesRequest = ` { - "subnet": { - "host_routes": [] - } + "subnet": { + "host_routes": [] + } } ` const SubnetUpdateRemoveHostRoutesResponse = ` { - "subnet": { - "name": "my_new_subnet", - "enable_dhcp": true, - "network_id": "db193ab3-96e3-4cb3-8fc5-05f4296d0324", - "tenant_id": "26a7980765d0414dbc1fc1f88cdb7e6e", - "dns_nameservers": [], - "allocation_pools": [ - { - "start": "10.0.0.2", - "end": "10.0.0.254" - } - ], - "host_routes": [], - "ip_version": 4, - "gateway_ip": null, - "cidr": "10.0.0.0/24", - "id": "08eae331-0402-425a-923c-34f7cfe39c1b" - } + "subnet": { + "name": "my_new_subnet", + "enable_dhcp": true, + "network_id": "db193ab3-96e3-4cb3-8fc5-05f4296d0324", + "tenant_id": "26a7980765d0414dbc1fc1f88cdb7e6e", + "dns_nameservers": [], + "allocation_pools": [ + { + "start": "10.0.0.2", + "end": "10.0.0.254" + } + ], + "host_routes": [], + "ip_version": 4, + "gateway_ip": null, + "cidr": "10.0.0.0/24", + "id": "08eae331-0402-425a-923c-34f7cfe39c1b" + } } ` const SubnetUpdateAllocationPoolRequest = ` { - "subnet": { - "name": "my_new_subnet", - "allocation_pools": [ - { - "start": "10.1.0.2", - "end": "10.1.0.254" - } - ] - } + "subnet": { + "name": "my_new_subnet", + "allocation_pools": [ + { + "start": "10.1.0.2", + "end": "10.1.0.254" + } + ] + } } ` const SubnetUpdateAllocationPoolResponse = ` { - "subnet": { - "name": "my_new_subnet", - "enable_dhcp": true, - "network_id": "db193ab3-96e3-4cb3-8fc5-05f4296d0324", - "tenant_id": "26a7980765d0414dbc1fc1f88cdb7e6e", - "dns_nameservers": [], - "allocation_pools": [ - { - "start": "10.1.0.2", - "end": "10.1.0.254" - } - ], - "host_routes": [], - "ip_version": 4, - "gateway_ip": "10.0.0.1", - "cidr": "10.0.0.0/24", - "id": "08eae331-0402-425a-923c-34f7cfe39c1b" - } + "subnet": { + "name": "my_new_subnet", + "enable_dhcp": true, + "network_id": "db193ab3-96e3-4cb3-8fc5-05f4296d0324", + "tenant_id": "26a7980765d0414dbc1fc1f88cdb7e6e", + "dns_nameservers": [], + "allocation_pools": [ + { + "start": "10.1.0.2", + "end": "10.1.0.254" + } + ], + "host_routes": [], + "ip_version": 4, + "gateway_ip": "10.0.0.1", + "cidr": "10.0.0.0/24", + "id": "08eae331-0402-425a-923c-34f7cfe39c1b" + } } ` From fffa63d53e7de89aad7f0a10e771154ae9dd0572 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?p=C3=BDrus?= Date: Wed, 10 Jul 2024 10:17:02 +0200 Subject: [PATCH 004/353] Update openstack/networking/v2/subnets/results.go --- openstack/networking/v2/subnets/results.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openstack/networking/v2/subnets/results.go b/openstack/networking/v2/subnets/results.go index cab10623e0..7d5ba13cc5 100644 --- a/openstack/networking/v2/subnets/results.go +++ b/openstack/networking/v2/subnets/results.go @@ -84,7 +84,7 @@ type Subnet struct { DNSNameservers []string `json:"dns_nameservers"` // Specifies whether the fixed IP addresses are published to the DNS. - DNSPublishFixedIP bool `json:"dns_publish_fixed_ip,omitempty"` + DNSPublishFixedIP bool `json:"dns_publish_fixed_ip"` // Service types associated with the subnet. ServiceTypes []string `json:"service_types"` From e5980af6c4fd681dcd9e7ee456801482e83adaf6 Mon Sep 17 00:00:00 2001 From: Pablo COLSON Date: Wed, 10 Jul 2024 14:34:18 +0200 Subject: [PATCH 005/353] fix(tests): forgot to set DNSPublishFixedIP in requests_test.go --- openstack/networking/v2/subnets/testing/requests_test.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/openstack/networking/v2/subnets/testing/requests_test.go b/openstack/networking/v2/subnets/testing/requests_test.go index c4bac8dc0c..e6f140ebe4 100644 --- a/openstack/networking/v2/subnets/testing/requests_test.go +++ b/openstack/networking/v2/subnets/testing/requests_test.go @@ -108,6 +108,7 @@ func TestCreate(t *testing.T) { }) var gatewayIP = "192.168.199.1" + var dnsPublishFixedIP = true opts := subnets.CreateOpts{ NetworkID: "d32019d3-bc6e-4319-9c1d-6722fc136a22", IPVersion: 4, @@ -120,6 +121,7 @@ func TestCreate(t *testing.T) { }, }, DNSNameservers: []string{"foo"}, + DNSPublishFixedIP: &dnsPublishFixedIP, ServiceTypes: []string{"network:routed"}, HostRoutes: []subnets.HostRoute{ {NextHop: "bar"}, @@ -130,6 +132,7 @@ func TestCreate(t *testing.T) { th.AssertNoErr(t, err) th.AssertEquals(t, s.Name, "") + th.AssertEquals(t, s.DNSPublishFixedIP, true) th.AssertEquals(t, s.EnableDHCP, true) th.AssertEquals(t, s.NetworkID, "d32019d3-bc6e-4319-9c1d-6722fc136a22") th.AssertEquals(t, s.TenantID, "4fd44f30292945e481c7b8a0c8908869") @@ -320,6 +323,7 @@ func TestCreateWithNoCIDR(t *testing.T) { th.AssertNoErr(t, err) th.AssertEquals(t, s.Name, "") + th.AssertEquals(t, s.DNSPublishFixedIP, true) th.AssertEquals(t, s.EnableDHCP, true) th.AssertEquals(t, s.NetworkID, "d32019d3-bc6e-4319-9c1d-6722fc136a22") th.AssertEquals(t, s.TenantID, "4fd44f30292945e481c7b8a0c8908869") @@ -369,6 +373,7 @@ func TestCreateWithPrefixlen(t *testing.T) { th.AssertNoErr(t, err) th.AssertEquals(t, s.Name, "") + th.AssertEquals(t, s.DNSPublishFixedIP, true) th.AssertEquals(t, s.EnableDHCP, true) th.AssertEquals(t, s.NetworkID, "d32019d3-bc6e-4319-9c1d-6722fc136a22") th.AssertEquals(t, s.TenantID, "4fd44f30292945e481c7b8a0c8908869") From e2325092f62ffbe7ad1120c4f6c8012bc69ba451 Mon Sep 17 00:00:00 2001 From: Pablo COLSON Date: Wed, 10 Jul 2024 14:47:39 +0200 Subject: [PATCH 006/353] fix: formating --- openstack/networking/v2/subnets/testing/requests_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openstack/networking/v2/subnets/testing/requests_test.go b/openstack/networking/v2/subnets/testing/requests_test.go index e6f140ebe4..1df6fd1ce3 100644 --- a/openstack/networking/v2/subnets/testing/requests_test.go +++ b/openstack/networking/v2/subnets/testing/requests_test.go @@ -120,9 +120,9 @@ func TestCreate(t *testing.T) { End: "192.168.199.254", }, }, - DNSNameservers: []string{"foo"}, + DNSNameservers: []string{"foo"}, DNSPublishFixedIP: &dnsPublishFixedIP, - ServiceTypes: []string{"network:routed"}, + ServiceTypes: []string{"network:routed"}, HostRoutes: []subnets.HostRoute{ {NextHop: "bar"}, }, @@ -373,7 +373,7 @@ func TestCreateWithPrefixlen(t *testing.T) { th.AssertNoErr(t, err) th.AssertEquals(t, s.Name, "") - th.AssertEquals(t, s.DNSPublishFixedIP, true) + th.AssertEquals(t, s.DNSPublishFixedIP, true) th.AssertEquals(t, s.EnableDHCP, true) th.AssertEquals(t, s.NetworkID, "d32019d3-bc6e-4319-9c1d-6722fc136a22") th.AssertEquals(t, s.TenantID, "4fd44f30292945e481c7b8a0c8908869") From fe584850a4c20fca7edcca9d3f89a903c0131768 Mon Sep 17 00:00:00 2001 From: Pierre Prinetti Date: Tue, 16 Jul 2024 15:39:40 +0200 Subject: [PATCH 007/353] clouds: Parse trust_id from clouds.yaml --- openstack/config/clouds/clouds.go | 20 ++++++++++++++------ openstack/config/clouds/types.go | 3 +++ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/openstack/config/clouds/clouds.go b/openstack/config/clouds/clouds.go index e890b5b5ce..e2310fbc10 100644 --- a/openstack/config/clouds/clouds.go +++ b/openstack/config/clouds/clouds.go @@ -148,6 +148,13 @@ func Parse(opts ...ParseOption) (gophercloud.AuthOptions, gophercloud.EndpointOp endpointType := coalesce(options.endpointType, cloud.EndpointType, cloud.Interface) + var scope *gophercloud.AuthScope + if trustID := cloud.AuthInfo.TrustID; trustID != "" { + scope = &gophercloud.AuthScope{ + TrustID: trustID, + } + } + return gophercloud.AuthOptions{ IdentityEndpoint: coalesce(options.authURL, cloud.AuthInfo.AuthURL), Username: coalesce(options.username, cloud.AuthInfo.Username), @@ -158,7 +165,7 @@ func Parse(opts ...ParseOption) (gophercloud.AuthOptions, gophercloud.EndpointOp TenantID: coalesce(options.projectID, cloud.AuthInfo.ProjectID), TenantName: coalesce(options.projectName, cloud.AuthInfo.ProjectName), TokenID: coalesce(options.token, cloud.AuthInfo.Token), - Scope: options.scope, + Scope: coalesce(options.scope, scope), ApplicationCredentialID: coalesce(options.applicationCredentialID, cloud.AuthInfo.ApplicationCredentialID), ApplicationCredentialName: coalesce(options.applicationCredentialName, cloud.AuthInfo.ApplicationCredentialName), ApplicationCredentialSecret: coalesce(options.applicationCredentialSecret, cloud.AuthInfo.ApplicationCredentialSecret), @@ -182,15 +189,16 @@ func computeAvailability(endpointType string) gophercloud.Availability { return gophercloud.AvailabilityPublic } -// coalesce returns the first argument that is not the empty string, or the -// empty string. -func coalesce(items ...string) string { +// coalesce returns the first argument that is not the zero value for its type, +// or the zero value for its type. +func coalesce[T comparable](items ...T) T { + var t T for _, item := range items { - if item != "" { + if item != t { return item } } - return "" + return t } // mergeClouds merges two Clouds recursively (the AuthInfo also gets merged). diff --git a/openstack/config/clouds/types.go b/openstack/config/clouds/types.go index fc2da75925..93fc093268 100644 --- a/openstack/config/clouds/types.go +++ b/openstack/config/clouds/types.go @@ -123,6 +123,9 @@ type AuthInfo struct { // been specified and a domain is required for scope. DefaultDomain string `yaml:"default_domain,omitempty" json:"default_domain,omitempty"` + // TrustID is the ID of the trust to use as a trustee. + TrustID string `yaml:"trust_id,omitempty" json:"trust_id,omitempty"` + // AllowReauth should be set to true if you grant permission for Gophercloud to // cache your credentials in memory, and to allow Gophercloud to attempt to // re-authenticate automatically if/when your token expires. If you set it to From f4c6a8e44cc6f9c8d9a775e5f852a5975ebcd467 Mon Sep 17 00:00:00 2001 From: kayrus Date: Tue, 9 Jul 2024 21:05:40 +0200 Subject: [PATCH 008/353] [neutron]: introduce Stateful argument for the security groups --- .../openstack/networking/v2/extensions/security_test.go | 3 +++ .../networking/v2/extensions/security/groups/requests.go | 7 +++++++ .../networking/v2/extensions/security/groups/results.go | 3 +++ 3 files changed, 13 insertions(+) diff --git a/internal/acceptance/openstack/networking/v2/extensions/security_test.go b/internal/acceptance/openstack/networking/v2/extensions/security_test.go index 7d0d967e46..670735ec5e 100644 --- a/internal/acceptance/openstack/networking/v2/extensions/security_test.go +++ b/internal/acceptance/openstack/networking/v2/extensions/security_test.go @@ -20,6 +20,7 @@ func TestSecurityGroupsCreateUpdateDelete(t *testing.T) { group, err := CreateSecurityGroup(t, client) th.AssertNoErr(t, err) defer DeleteSecurityGroup(t, client, group.ID) + th.AssertEquals(t, group.Stateful, true) rule, err := CreateSecurityGroupRule(t, client, group.ID) th.AssertNoErr(t, err) @@ -32,6 +33,7 @@ func TestSecurityGroupsCreateUpdateDelete(t *testing.T) { updateOpts := groups.UpdateOpts{ Name: name, Description: &description, + Stateful: new(bool), } newGroup, err := groups.Update(context.TODO(), client, group.ID, updateOpts).Extract() @@ -40,6 +42,7 @@ func TestSecurityGroupsCreateUpdateDelete(t *testing.T) { tools.PrintResource(t, newGroup) th.AssertEquals(t, newGroup.Name, name) th.AssertEquals(t, newGroup.Description, description) + th.AssertEquals(t, newGroup.Stateful, false) listOpts := groups.ListOpts{} allPages, err := groups.List(client, listOpts).AllPages(context.TODO()) diff --git a/openstack/networking/v2/extensions/security/groups/requests.go b/openstack/networking/v2/extensions/security/groups/requests.go index a45403f13b..fabb744114 100644 --- a/openstack/networking/v2/extensions/security/groups/requests.go +++ b/openstack/networking/v2/extensions/security/groups/requests.go @@ -16,6 +16,7 @@ type ListOpts struct { ID string `q:"id"` Name string `q:"name"` Description string `q:"description"` + Stateful *bool `q:"stateful"` TenantID string `q:"tenant_id"` ProjectID string `q:"project_id"` Limit int `q:"limit"` @@ -63,6 +64,9 @@ type CreateOpts struct { // Describes the security group. Description string `json:"description,omitempty"` + + // Stateful indicates if the security group is stateful or stateless. + Stateful *bool `json:"stateful,omitempty"` } // ToSecGroupCreateMap builds a request body from CreateOpts. @@ -97,6 +101,9 @@ type UpdateOpts struct { // Describes the security group. Description *string `json:"description,omitempty"` + + // Stateful indicates if the security group is stateful or stateless. + Stateful *bool `json:"stateful,omitempty"` } // ToSecGroupUpdateMap builds a request body from UpdateOpts. diff --git a/openstack/networking/v2/extensions/security/groups/results.go b/openstack/networking/v2/extensions/security/groups/results.go index 6f1a4e1620..b3aa2efb48 100644 --- a/openstack/networking/v2/extensions/security/groups/results.go +++ b/openstack/networking/v2/extensions/security/groups/results.go @@ -25,6 +25,9 @@ type SecGroup struct { // traffic entering and leaving the group. Rules []rules.SecGroupRule `json:"security_group_rules"` + // Indicates if the security group is stateful or stateless. + Stateful bool `json:"stateful"` + // TenantID is the project owner of the security group. TenantID string `json:"tenant_id"` From efdc1af20eb906ddc24acac4cbc56d8c1f599fbc Mon Sep 17 00:00:00 2001 From: Pierre Prinetti Date: Wed, 17 Jul 2024 12:23:07 +0200 Subject: [PATCH 009/353] actions: Add a label to hold merging Create the label 'hold' and add a check that fails when the PR has that label. --- .github/labels.yaml | 3 +++ .github/workflows/check-pr-labels.yaml | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 .github/workflows/check-pr-labels.yaml diff --git a/.github/labels.yaml b/.github/labels.yaml index 8a908009e2..ecf74f57ac 100644 --- a/.github/labels.yaml +++ b/.github/labels.yaml @@ -22,3 +22,6 @@ - color: 'EC0101' description: Unable to figure out the semver type name: semver:unknown +- color: 'D73A4A' + description: Do not merge + name: hold diff --git a/.github/workflows/check-pr-labels.yaml b/.github/workflows/check-pr-labels.yaml new file mode 100644 index 0000000000..ea8068f602 --- /dev/null +++ b/.github/workflows/check-pr-labels.yaml @@ -0,0 +1,18 @@ +name: Ready +on: + pull_request_target: + types: + - opened + - labeled + +jobs: + hold: + if: github.event.pull_request.merged == false + runs-on: ubuntu-latest + steps: + - if: > + contains(github.event.pull_request.labels.*.name, 'hold') + run: 'false' + - if: > + !contains(github.event.pull_request.labels.*.name, 'hold') + run: 'true' From 4945aeadcb7c439bb1ae9cba07490bd0995ba101 Mon Sep 17 00:00:00 2001 From: Pierre Prinetti Date: Thu, 18 Jul 2024 10:34:03 +0200 Subject: [PATCH 010/353] actions: Correctly refresh hold state Before adding these trigger types, the `hold` job was often skipped, unnecessarily blocking the Pull request. --- .github/workflows/check-pr-labels.yaml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/check-pr-labels.yaml b/.github/workflows/check-pr-labels.yaml index ea8068f602..4fbb7fc0b8 100644 --- a/.github/workflows/check-pr-labels.yaml +++ b/.github/workflows/check-pr-labels.yaml @@ -2,8 +2,11 @@ name: Ready on: pull_request_target: types: - - opened - labeled + - opened + - reopened + - synchronize + - unlabeled jobs: hold: From 594708a595fc1c29d8c3da864bd5adbf1ef5d857 Mon Sep 17 00:00:00 2001 From: Pierre Prinetti Date: Fri, 5 Jul 2024 16:29:27 +0200 Subject: [PATCH 011/353] MIGRATING.md: Provide a migration script Some steps in the migration from Gophercloud v1 to v2 can be automated. Provide a script that can take out some of the pain. --- docs/MIGRATING.md | 134 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) diff --git a/docs/MIGRATING.md b/docs/MIGRATING.md index a507820bf5..c398cf0e65 100644 --- a/docs/MIGRATING.md +++ b/docs/MIGRATING.md @@ -493,3 +493,137 @@ Users that still rely on theses old services should continue using Gophercloud v (`openstack/networking/v2/extensions/fwaas`) - Poppy (CDNaaS) service (`openstack/cdn`) - Senlin (Clustering) service (`openstack/clustering`) + +### Script-assisted migration + +#### Expected outcome + +After running the script, your code may not compile. The idea is that at this point, you're only left with a few changes that can't reasonably be automated. + +#### What it does + +* Add `/v2` to all Gophercloud imports, except to the packages that have been removed without replacement +* Adjust the import path of moved packages +* Adjust the package identifier in the code where possible +* Add `context.TODO()` where required + +#### Limitations + +* it doesn't fix the use of removed extensions. For example, if you used `openstack/blockstorage/extensions/availabilityzones`, you will have to manually put that back into e.g. `servers.CreateOpts` +* it will just put `context.TODO()` where a context is required to satisfy the function signature. It's up to you to actually replace that with a variable and provide proper cancellation +* it will add `context.TODO()` to `blockstorage/v1` calls, even though that package only exists in Gophercloud v1 + +```bash +# Adjust the blockstorage version appropriately +blockstorageversion=v3 + +openstack='github.com/gophercloud/gophercloud/openstack' +openstack_utils='github.com/gophercloud/utils/openstack' +find . -type f -name '*.go' -exec sed -i ' + /^import ($/,/^)$/ { + + # 1: These packages have been removed and their functionality moved into the main module for the corresponding service. + /\(\/openstack\/blockstorage\/v1\|\/openstack\/networking\/v2\/extensions\/lbaas\|\/openstack\/networking\/v2\/extensions\/lbaas_v2\|\/openstack\/networking\/v2\/extensions\/fwaas\|\/openstack\/cdn\|\/openstack\/clustering\)/! { + /\/openstack\/blockstorage\/extensions\/volumehost/d + /\/openstack\/blockstorage\/extensions\/volumetenants/d + /\/openstack\/compute\/v2\/extensions\/bootfromvolume/d + /\/openstack\/compute\/v2\/extensions\/diskconfig/d + /\/openstack\/compute\/v2\/extensions\/extendedserverattributes/d + /\/openstack\/compute\/v2\/extensions\/extendedstatus/d + /\/openstack\/compute\/v2\/extensions\/schedulerhints/d + /\/openstack\/compute\/v2\/extensions\/serverusage/d + /\/openstack\/compute\/v2\/extensions\/availabilityzones/d + /\/openstack\/identity\/v3\/extensions\/trusts/d + } + + '" + # 2: Functions and supporting structs and interfaces of these packages have been moved to an existing package + s|${openstack}/blockstorage/extensions/schedulerhints|${openstack}/blockstorage/${blockstorageversion}/volumes|g + s|${openstack}/blockstorage/extensions/volumeactions|${openstack}/blockstorage/${blockstorageversion}/volumes|g + s|${openstack}/compute/v2/extensions/evacuate|${openstack}/compute/v2/servers|g + s|${openstack}/compute/v2/extensions/injectnetworkinfo|${openstack}/compute/v2/servers|g + s|${openstack}/compute/v2/extensions/lockunlock|${openstack}/compute/v2/servers|g + s|${openstack}/compute/v2/extensions/migrate|${openstack}/compute/v2/servers|g + s|${openstack}/compute/v2/extensions/pauseunpause|${openstack}/compute/v2/servers|g + s|${openstack}/compute/v2/extensions/rescueunrescue|${openstack}/compute/v2/servers|g + s|${openstack}/compute/v2/extensions/resetnetwork|${openstack}/compute/v2/servers|g + s|${openstack}/compute/v2/extensions/resetstate|${openstack}/compute/v2/servers|g + s|${openstack}/compute/v2/extensions/shelveunshelve|${openstack}/compute/v2/servers|g + s|${openstack}/compute/v2/extensions/startstop|${openstack}/compute/v2/servers|g + s|${openstack}/compute/v2/extensions/suspendresume|${openstack}/compute/v2/servers|g + + # 3: These packages have been renamed + s|${openstack}/imageservice|${openstack}/image|g + s|${openstack_utils}/imageservice|${openstack_utils}/image|g + s|${openstack}/blockstorage/extensions/availabilityzones|${openstack}/blockstorage/${blockstorageversion}/availabilityzones|g + s|${openstack}/blockstorage/extensions/backups|${openstack}/blockstorage/${blockstorageversion}/backups|g + s|${openstack}/blockstorage/extensions/limits|${openstack}/blockstorage/${blockstorageversion}/limits|g + s|${openstack}/blockstorage/extensions/quotasets|${openstack}/blockstorage/${blockstorageversion}/quotasets|g + s|${openstack}/blockstorage/extensions/schedulerstats|${openstack}/blockstorage/${blockstorageversion}/schedulerstats|g + s|${openstack}/blockstorage/extensions/services|${openstack}/blockstorage/${blockstorageversion}/services|g + s|${openstack}/blockstorage/extensions/volumetransfers|${openstack}/blockstorage/${blockstorageversion}/transfers|g + s|${openstack}/compute/v2/extensions/aggregates|${openstack}/compute/v2/aggregates|g + s|${openstack}/compute/v2/extensions/attachinterfaces|${openstack}/compute/v2/attachinterfaces|g + s|${openstack}/compute/v2/extensions/diagnostics|${openstack}/compute/v2/diagnostics|g + s|${openstack}/compute/v2/extensions/hypervisors|${openstack}/compute/v2/hypervisors|g + s|${openstack}/compute/v2/extensions/instanceactions|${openstack}/compute/v2/instanceactions|g + s|${openstack}/compute/v2/extensions/keypairs|${openstack}/compute/v2/keypairs|g + s|${openstack}/compute/v2/extensions/limits|${openstack}/compute/v2/limits|g + s|${openstack}/compute/v2/extensions/quotasets|${openstack}/compute/v2/quotasets|g + s|${openstack}/compute/v2/extensions/remoteconsoles|${openstack}/compute/v2/remoteconsoles|g + s|${openstack}/compute/v2/extensions/secgroups|${openstack}/compute/v2/secgroups|g + s|${openstack}/compute/v2/extensions/servergroups|${openstack}/compute/v2/servergroups|g + s|${openstack}/compute/v2/extensions/services|${openstack}/compute/v2/services|g + s|${openstack}/compute/v2/extensions/tags|${openstack}/compute/v2/tags|g + s|${openstack}/compute/v2/extensions/usage|${openstack}/compute/v2/usage|g + s|${openstack}/compute/v2/extensions/volumeattach|${openstack}/compute/v2/volumeattach|g + s|${openstack}/identity/v2/extensions/admin/roles|${openstack}/identity/v2/roles|g + s|${openstack}/identity/v3/extensions/ec2credentials|${openstack}/identity/v3/ec2credentials|g + s|${openstack}/identity/v3/extensions/ec2tokens|${openstack}/identity/v3/ec2tokens|g + s|${openstack}/identity/v3/extensions/federation|${openstack}/identity/v3/federation|g + s|${openstack}/identity/v3/extensions/oauth1|${openstack}/identity/v3/oauth1|g + s|${openstack}/identity/v3/extensions/projectendpoints|${openstack}/identity/v3/projectendpoints|g + + # 4: These removed packages existed as proxies of others + s|${openstack}/compute/v2/extensions/defsecrules|${openstack}/networking/v2/extensions/security/groups|g + s|${openstack}/compute/v2/extensions/floatingips|${openstack}/networking/v2/extensions/layer3/floatingips|g + s|${openstack}/compute/v2/extensions/images|${openstack}/image/v2/images|g + s|${openstack}/compute/v2/extensions/networks|${openstack}/networking/v2/networks|g + s|${openstack}/compute/v2/extensions/tenantnetworks|${openstack}/networking/v2/networks|g + "' + + # 5: Update to v2, except for packages that were removed without replacement + s|github.com/gophercloud/utils|github.com/gophercloud/utils/v2|g + /\(\/openstack\/blockstorage\/v1\|\/openstack\/networking\/v2\/extensions\/lbaas\|\/openstack\/networking\/v2\/extensions\/lbaas_v2\|\/openstack\/networking\/v2\/extensions\/fwaas\|\/openstack\/cdn\|\/openstack\/clustering\)/! s|github.com/gophercloud/gophercloud|github.com/gophercloud/gophercloud/v2|g + } + + /^)$/,$ { + + # 6: Rename identifiers of items of step 2 above + s#\(schedulerhints\|volumeactions\)\.\([A-Z][A-Z_a-z_0-9]*\)#volumes.\2#g + s#\(evacuate\|injectnetworkinfo\|lockunlock\|migrate\|pauseunpause\|rescueunrescue\|resetnetwork\|resetstate\|shelveunshelve\|startstop\|suspendresume\)\.\([A-Z][A-Z_a-z_0-9]*\)#servers.\2#g + + # 7: Add context.TODO() + s#\(accept\.Create\|accept\.Get\|accounts\.Get\|accounts\.Update\|acls\.DeleteContainerACL\|acls\.DeleteSecretACL\|acls\.GetContainerACL\|acls\.GetSecretACL\|acls\.SetContainerACL\|acls\.SetSecretACL\|acls\.UpdateContainerACL\|acls\.UpdateSecretACL\|addressscopes\.Create\|addressscopes\.Delete\|addressscopes\.Get\|addressscopes\.Update\|agents\.Delete\|agents\.Get\|agents\.ListDHCPNetworks\|agents\.ListL3Routers\|agents\.RemoveBGPSpeaker\|agents\.RemoveDHCPNetwork\|agents\.RemoveL3Router\|agents\.ScheduleBGPSpeaker\|agents\.ScheduleDHCPNetwork\|agents\.ScheduleL3Router\|agents\.Update\|aggregates\.AddHost\|aggregates\.Create\|aggregates\.Delete\|aggregates\.Get\|aggregates\.RemoveHost\|aggregates\.SetMetadata\|aggregates\.Update\|allocations\.Create\|allocations\.Delete\|allocations\.Get\|amphorae\.Failover\|amphorae\.Get\|apiversions\.Get\|apiversions\.List\|applicationcredentials\.Create\|applicationcredentials\.Delete\|applicationcredentials\.DeleteAccessRule\|applicationcredentials\.Get\|applicationcredentials\.GetAccessRule\|attachinterfaces\.Create\|attachinterfaces\.Delete\|attachinterfaces\.Get\|attachments\.Complete\|attachments\.Create\|attachments\.Delete\|attachments\.Get\|attachments\.Update\|attachments\.WaitForStatus\|backups\.Create\|backups\.Delete\|backups\.Export\|backups\.ForceDelete\|backups\.Get\|backups\.Import\|backups\.ResetStatus\|backups\.RestoreFromBackup\|backups\.Update\|bgpvpns\.Create\|bgpvpns\.CreateNetworkAssociation\|bgpvpns\.CreatePortAssociation\|bgpvpns\.CreateRouterAssociation\|bgpvpns\.Delete\|bgpvpns\.DeleteNetworkAssociation\|bgpvpns\.DeletePortAssociation\|bgpvpns\.DeleteRouterAssociation\|bgpvpns\.Get\|bgpvpns\.GetNetworkAssociation\|bgpvpns\.GetPortAssociation\|bgpvpns\.GetRouterAssociation\|bgpvpns\.Update\|bgpvpns\.UpdatePortAssociation\|bgpvpns\.UpdateRouterAssociation\|buildinfo\.Get\|capsules\.Create\|capsules\.Delete\|capsules\.Get\|certificates\.Create\|certificates\.Get\|certificates\.Update\|claims\.Create\|claims\.Delete\|claims\.Get\|claims\.Update\|clusters\.Create\|clusters\.Delete\|clusters\.Get\|clusters\.Resize\|clusters\.Update\|clusters\.Upgrade\|clustertemplates\.Create\|clustertemplates\.Delete\|clustertemplates\.Get\|clustertemplates\.Update\|conductors\.Get\|config\.NewProviderClient\|configurations\.Create\|configurations\.Delete\|configurations\.Get\|configurations\.GetDatastoreParam\|configurations\.GetGlobalParam\|configurations\.Replace\|configurations\.Update\|containers\.BulkDelete\|containers\.Create\|containers\.CreateConsumer\|containers\.CreateSecretRef\|containers\.Delete\|containers\.DeleteConsumer\|containers\.DeleteSecretRef\|containers\.Get\|containers\.Update\|credentials\.Create\|credentials\.Delete\|credentials\.Get\|credentials\.Update\|crontriggers\.Create\|crontriggers\.Delete\|crontriggers\.Get\|databases\.Create\|databases\.Delete\|datastores\.Get\|datastores\.GetVersion\|diagnostics\.Get\|domains\.Create\|domains\.Delete\|domains\.Get\|domains\.Update\|drivers\.GetDriverDetails\|drivers\.GetDriverDiskProperties\|drivers\.GetDriverProperties\|ec2credentials\.Create\|ec2credentials\.Delete\|ec2credentials\.Get\|ec2tokens\.Create\|ec2tokens\.ValidateS3Token\|endpointgroups\.Create\|endpointgroups\.Delete\|endpointgroups\.Get\|endpointgroups\.Update\|endpoints\.Create\|endpoints\.Delete\|endpoints\.Update\|executions\.Create\|executions\.Delete\|executions\.Get\|extensions\.Get\|extraroutes\.Add\|extraroutes\.Remove\|federation\.CreateMapping\|federation\.DeleteMapping\|federation\.GetMapping\|federation\.UpdateMapping\|flavorprofiles\.Create\|flavorprofiles\.Delete\|flavorprofiles\.Get\|flavorprofiles\.Update\|flavors\.AddAccess\|flavors\.Create\|flavors\.CreateExtraSpecs\|flavors\.Delete\|flavors\.DeleteExtraSpec\|flavors\.Get\|flavors\.GetExtraSpec\|flavors\.ListExtraSpecs\|flavors\.RemoveAccess\|flavors\.Update\|flavors\.UpdateExtraSpec\|floatingips\.Create\|floatingips\.Delete\|floatingips\.Get\|floatingips\.Update\|gophercloud\.WaitFor\|groups\.Create\|groups\.Delete\|groups\.Get\|groups\.RemoveEgressPolicy\|groups\.RemoveIngressPolicy\|groups\.Update\|hypervisors\.Get\|hypervisors\.GetStatistics\|hypervisors\.GetUptime\|ikepolicies\.Create\|ikepolicies\.Delete\|ikepolicies\.Get\|ikepolicies\.Update\|imagedata\.Download\|imagedata\.Stage\|imagedata\.Upload\|imageimport\.Create\|imageimport\.Get\|images\.Create\|images\.Delete\|images\.Get\|images\.Update\|instanceactions\.Get\|instances\.AttachConfigurationGroup\|instances\.Create\|instances\.Delete\|instances\.DetachConfigurationGroup\|instances\.EnableRootUser\|instances\.Get\|instances\.IsRootEnabled\|instances\.Resize\|instances\.ResizeVolume\|instances\.Restart\|introspection\.AbortIntrospection\|introspection\.GetIntrospectionData\|introspection\.GetIntrospectionStatus\|introspection\.ReApplyIntrospection\|introspection\.StartIntrospection\|ipsecpolicies\.Create\|ipsecpolicies\.Delete\|ipsecpolicies\.Get\|ipsecpolicies\.Update\|keypairs\.Create\|keypairs\.Delete\|keypairs\.Get\|l7policies\.Create\|l7policies\.CreateRule\|l7policies\.Delete\|l7policies\.DeleteRule\|l7policies\.Get\|l7policies\.GetRule\|l7policies\.Update\|l7policies\.UpdateRule\|limits\.BatchCreate\|limits\.Delete\|limits\.Get\|limits\.GetEnforcementModel\|limits\.Update\|listeners\.Create\|listeners\.Delete\|listeners\.Get\|listeners\.GetStats\|listeners\.Update\|loadbalancers\.Create\|loadbalancers\.Delete\|loadbalancers\.Failover\|loadbalancers\.Get\|loadbalancers\.GetStats\|loadbalancers\.GetStatuses\|loadbalancers\.Update\|members\.Create\|members\.Delete\|members\.Get\|members\.Update\|messages\.Create\|messages\.Delete\|messages\.DeleteMessages\|messages\.Get\|messages\.GetMessages\|messages\.PopMessages\|monitors\.Create\|monitors\.Delete\|monitors\.Get\|monitors\.Update\|networkipavailabilities\.Get\|networks\.Create\|networks\.Delete\|networks\.Get\|networks\.Update\|nodegroups\.Create\|nodegroups\.Delete\|nodegroups\.Get\|nodegroups\.Update\|nodes\.AttachVirtualMedia\|nodes\.ChangePowerState\|nodes\.ChangeProvisionState\|nodes\.Create\|nodes\.CreateSubscription\|nodes\.Delete\|nodes\.DeleteSubscription\|nodes\.DetachVirtualMedia\|nodes\.Get\|nodes\.GetAllSubscriptions\|nodes\.GetBIOSSetting\|nodes\.GetBootDevice\|nodes\.GetInventory\|nodes\.GetSubscription\|nodes\.GetSupportedBootDevices\|nodes\.GetVendorPassthruMethods\|nodes\.InjectNMI\|nodes\.ListBIOSSettings\|nodes\.ListFirmware\|nodes\.SetBootDevice\|nodes\.SetMaintenance\|nodes\.SetRAIDConfig\|nodes\.UnsetMaintenance\|nodes\.Update\|nodes\.Validate\|nodes\.WaitForProvisionState\|oauth1\.AuthorizeToken\|oauth1\.Create\|oauth1\.CreateAccessToken\|oauth1\.CreateConsumer\|oauth1\.DeleteConsumer\|oauth1\.GetAccessToken\|oauth1\.GetAccessTokenRole\|oauth1\.GetConsumer\|oauth1\.RequestToken\|oauth1\.RevokeAccessToken\|oauth1\.UpdateConsumer\|objects\.BulkDelete\|objects\.Copy\|objects\.Create\|objects\.CreateTempURL\|objects\.Delete\|objects\.Download\|objects\.Get\|objects\.Update\|openstack\.Authenticate\|openstack\.AuthenticatedClient\|openstack\.AuthenticateV2\|openstack\.AuthenticateV3\|orders\.Create\|orders\.Delete\|orders\.Get\|osinherit\.Assign\|osinherit\.Unassign\|osinherit\.Validate\|pagination\.Request\|peers\.Create\|peers\.Delete\|peers\.Get\|peers\.Update\|policies\.Create\|policies\.Delete\|policies\.Get\|policies\.InsertRule\|policies\.RemoveRule\|policies\.Update\|pools\.BatchUpdateMembers\|pools\.Create\|pools\.CreateMember\|pools\.Delete\|pools\.DeleteMember\|pools\.Get\|pools\.GetMember\|pools\.Update\|pools\.UpdateMember\|portforwarding\.Create\|portforwarding\.Delete\|portforwarding\.Get\|portforwarding\.Update\|ports\.Create\|ports\.Delete\|ports\.Get\|ports\.Update\|projectendpoints\.Create\|projectendpoints\.Delete\|projects\.Create\|projects\.Delete\|projects\.DeleteTags\|projects\.Get\|projects\.ListTags\|projects\.ModifyTags\|projects\.Update\|qos\.Associate\|qos\.Create\|qos\.Delete\|qos\.DeleteKeys\|qos\.Disassociate\|qos\.DisassociateAll\|qos\.Get\|qos\.Update\|queues\.Create\|queues\.Delete\|queues\.Get\|queues\.GetStats\|queues\.Purge\|queues\.Share\|queues\.Update\|quotas\.Create\|quotasets\.Delete\|quotasets\.Get\|quotasets\.GetDefaults\|quotasets\.GetDetail\|quotasets\.GetUsage\|quotasets\.Update\|quotas\.Get\|quotas\.GetDetail\|quotas\.Update\|rbacpolicies\.Create\|rbacpolicies\.Delete\|rbacpolicies\.Get\|rbacpolicies\.Update\|recordsets\.Create\|recordsets\.Delete\|recordsets\.Get\|recordsets\.Update\|regions\.Create\|regions\.Delete\|regions\.Get\|regions\.Update\|registeredlimits\.BatchCreate\|registeredlimits\.Delete\|registeredlimits\.Get\|registeredlimits\.Update\|remoteconsoles\.Create\|replicas\.Create\|replicas\.Delete\|replicas\.ForceDelete\|replicas\.Get\|replicas\.GetExportLocation\|replicas\.ListExportLocations\|replicas\.Promote\|replicas\.ResetState\|replicas\.ResetStatus\|replicas\.Resync\|request\.Create\|request\.Delete\|request\.Get\|request\.Update\|resourceproviders\.Create\|resourceproviders\.Delete\|resourceproviders\.Get\|resourceproviders\.GetAllocations\|resourceproviders\.GetInventories\|resourceproviders\.GetTraits\|resourceproviders\.GetUsages\|resourceproviders\.Update\|resourcetypes\.GenerateTemplate\|resourcetypes\.GetSchema\|resourcetypes\.List\|roles\.AddUser\|roles\.Assign\|roles\.Create\|roles\.CreateRoleInferenceRule\|roles\.Delete\|roles\.DeleteRoleInferenceRule\|roles\.DeleteUser\|roles\.Get\|roles\.GetRoleInferenceRule\|roles\.ListRoleInferenceRules\|roles\.Unassign\|roles\.Update\|routers\.AddInterface\|routers\.Create\|routers\.Delete\|routers\.Get\|routers\.RemoveInterface\|routers\.Update\|rules\.Create\|rules\.CreateBandwidthLimitRule\|rules\.CreateDSCPMarkingRule\|rules\.CreateMinimumBandwidthRule\|rules\.Delete\|rules\.DeleteBandwidthLimitRule\|rules\.DeleteDSCPMarkingRule\|rules\.DeleteMinimumBandwidthRule\|rules\.Get\|rules\.GetBandwidthLimitRule\|rules\.GetDSCPMarkingRule\|rules\.GetMinimumBandwidthRule\|rules\.Update\|rules\.UpdateBandwidthLimitRule\|rules\.UpdateDSCPMarkingRule\|rules\.UpdateMinimumBandwidthRule\|ruletypes\.GetRuleType\|secgroups\.AddServer\|secgroups\.Create\|secgroups\.CreateRule\|secgroups\.Delete\|secgroups\.DeleteRule\|secgroups\.Get\|secgroups\.RemoveServer\|secgroups\.Update\|secrets\.Create\|secrets\.CreateMetadata\|secrets\.CreateMetadatum\|secrets\.Delete\|secrets\.DeleteMetadatum\|secrets\.Get\|secrets\.GetMetadata\|secrets\.GetMetadatum\|secrets\.GetPayload\|secrets\.Update\|secrets\.UpdateMetadatum\|securityservices\.Create\|securityservices\.Delete\|securityservices\.Get\|securityservices\.Update\|servergroups\.Create\|servergroups\.Delete\|servergroups\.Get\|servers\.ChangeAdminPassword\|servers\.ConfirmResize\|servers\.Create\|servers\.CreateImage\|servers\.CreateMetadatum\|servers\.Delete\|servers\.DeleteMetadatum\|servers\.Evacuate\|servers\.ForceDelete\|servers\.Get\|servers\.GetPassword\|servers\.InjectNetworkInfo\|servers\.LiveMigrate\|servers\.Lock\|servers\.Metadata\|servers\.Metadatum\|servers\.Migrate\|servers\.Pause\|servers\.Reboot\|servers\.Rebuild\|servers\.Rescue\|servers\.ResetMetadata\|servers\.ResetNetwork\|servers\.ResetState\|servers\.Resize\|servers\.Resume\|servers\.RevertResize\|servers\.Shelve\|servers\.ShelveOffload\|servers\.ShowConsoleOutput\|servers\.Start\|servers\.Stop\|servers\.Suspend\|servers\.Unlock\|servers\.Unpause\|servers\.Unrescue\|servers\.Unshelve\|servers\.Update\|servers\.UpdateMetadata\|servers\.WaitForStatus\|services\.Create\|services\.Delete\|services\.Get\|services\.Update\|shareaccessrules\.Get\|shareaccessrules\.List\|sharenetworks\.AddSecurityService\|sharenetworks\.Create\|sharenetworks\.Delete\|sharenetworks\.Get\|sharenetworks\.RemoveSecurityService\|sharenetworks\.Update\|shares\.Create\|shares\.Delete\|shares\.DeleteMetadatum\|shares\.Extend\|shares\.ForceDelete\|shares\.Get\|shares\.GetExportLocation\|shares\.GetMetadata\|shares\.GetMetadatum\|shares\.GrantAccess\|shares\.ListAccessRights\|shares\.ListExportLocations\|shares\.ResetStatus\|shares\.Revert\|shares\.RevokeAccess\|shares\.SetMetadata\|shares\.Shrink\|shares\.Unmanage\|shares\.Update\|shares\.UpdateMetadata\|sharetransfers\.Accept\|sharetransfers\.Create\|sharetransfers\.Delete\|sharetransfers\.Get\|sharetypes\.AddAccess\|sharetypes\.Create\|sharetypes\.Delete\|sharetypes\.GetDefault\|sharetypes\.GetExtraSpecs\|sharetypes\.RemoveAccess\|sharetypes\.SetExtraSpecs\|sharetypes\.ShowAccess\|sharetypes\.UnsetExtraSpecs\|siteconnections\.Create\|siteconnections\.Delete\|siteconnections\.Get\|siteconnections\.Update\|snapshots\.Create\|snapshots\.Delete\|snapshots\.ForceDelete\|snapshots\.Get\|snapshots\.ResetStatus\|snapshots\.Update\|snapshots\.UpdateMetadata\|snapshots\.UpdateStatus\|snapshots\.WaitForStatus\|speakers\.AddBGPPeer\|speakers\.AddGatewayNetwork\|speakers\.Create\|speakers\.Delete\|speakers\.Get\|speakers\.RemoveBGPPeer\|speakers\.RemoveGatewayNetwork\|speakers\.Update\|stackevents\.Find\|stackevents\.Get\|stackresources\.Find\|stackresources\.Get\|stackresources\.MarkUnhealthy\|stackresources\.Metadata\|stackresources\.Schema\|stackresources\.Template\|stacks\.Abandon\|stacks\.Adopt\|stacks\.Create\|stacks\.Delete\|stacks\.Find\|stacks\.Get\|stacks\.Preview\|stacks\.Update\|stacks\.UpdatePatch\|stacktemplates\.Get\|stacktemplates\.Validate\|subnetpools\.Create\|subnetpools\.Delete\|subnetpools\.Get\|subnetpools\.Update\|subnets\.Create\|subnets\.Delete\|subnets\.Get\|subnets\.Update\|swauth\.Auth\|swauth\.NewObjectStorageV1\|tags\.Add\|tags\.Check\|tags\.Delete\|tags\.DeleteAll\|tags\.List\|tags\.ReplaceAll\|tasks\.Create\|tasks\.Get\|tenants\.Create\|tenants\.Delete\|tenants\.Get\|tenants\.Update\|tokens\.Create\|tokens\.Get\|tokens\.Revoke\|tokens\.Validate\|transfers\.Accept\|transfers\.Create\|transfers\.Delete\|transfers\.Get\|trunks\.AddSubports\|trunks\.Create\|trunks\.Delete\|trunks\.Get\|trunks\.GetSubports\|trunks\.RemoveSubports\|trunks\.Update\|trusts\.CheckRole\|trusts\.Create\|trusts\.Delete\|trusts\.Get\|trusts\.GetRole\|users\.AddToGroup\|users\.ChangePassword\|users\.Create\|users\.Delete\|users\.Get\|users\.IsMemberOfGroup\|users\.RemoveFromGroup\|users\.Update\|utils\.ChooseVersion\|utils\.GetSupportedMicroversions\|utils\.RequireMicroversion\|volumeattach\.Create\|volumeattach\.Delete\|volumeattach\.Get\|volumes\.Attach\|volumes\.BeginDetaching\|volumes\.ChangeType\|volumes\.Create\|volumes\.Delete\|volumes\.Detach\|volumes\.ExtendSize\|volumes\.ForceDelete\|volumes\.Get\|volumes\.InitializeConnection\|volumes\.ReImage\|volumes\.Reserve\|volumes\.ResetStatus\|volumes\.SetBootable\|volumes\.SetImageMetadata\|volumes\.TerminateConnection\|volumes\.Unreserve\|volumes\.Update\|volumes\.UploadImage\|volumes\.WaitForStatus\|volumetypes\.AddAccess\|volumetypes\.Create\|volumetypes\.CreateEncryption\|volumetypes\.CreateExtraSpecs\|volumetypes\.Delete\|volumetypes\.DeleteEncryption\|volumetypes\.DeleteExtraSpec\|volumetypes\.Get\|volumetypes\.GetEncryption\|volumetypes\.GetEncryptionSpec\|volumetypes\.GetExtraSpec\|volumetypes\.ListExtraSpecs\|volumetypes\.RemoveAccess\|volumetypes\.Update\|volumetypes\.UpdateEncryption\|volumetypes\.UpdateExtraSpec\|workflows\.Create\|workflows\.Delete\|workflows\.Get\|zones\.Create\|zones\.Delete\|zones\.Get\|zones\.Update\)(#\1(context.TODO(), #g + s#\(\.AllPages(\)#\1context.TODO(), #g + s#\(\.EachPage(\)\(func(\)#\1context.TODO(), \2ctx context.Context, #g + + # 8: Rename identifiers that were changed in v2 + s#\(\(volumes\|servers\)\.SchedulerHint\)s#\2.SchedulerHintOpts#g + + # 9: Tentatively replace error handling for 404s + s#\(\t\+\)if _, ok := err.(gophercloud.ErrDefault404); \(!\?\)ok {#\1if \2gophercloud.ResponseCodeIs(err, http.StatusNotFound) {#g + } + ' {} \; + +grep -r -l 'context\.TODO' | xargs -r sed -i ' + /^import ($/ a "context" + ' + +grep -r -l 'http\.Status' | xargs -r sed -i ' + /^import ($/ a "net/http" + ' + +goimports -format-only -w . +go mod tidy +``` From 3cc29318d19fa1b71d8c6736038f355bd2699cf4 Mon Sep 17 00:00:00 2001 From: Pierre Prinetti Date: Thu, 18 Jul 2024 15:05:33 +0200 Subject: [PATCH 012/353] actions: Refactor the semver assessment Using `gh` lets us drop two external dependencies, and condensate the steps a bit. After this change: * new pushes in the PR won't trigger relabeling if the assessment is unchanged * failures in the workflow will be notified as comments in the PR rather than via the `semver:unknown` label The next natural step is to set this job as mandatory, to that a failure to assess semver will block merging. --- .github/labels.yaml | 3 -- .github/workflows/semver-auto.yaml | 71 ++++++++++++++++-------------- 2 files changed, 37 insertions(+), 37 deletions(-) diff --git a/.github/labels.yaml b/.github/labels.yaml index ecf74f57ac..72d8730f8e 100644 --- a/.github/labels.yaml +++ b/.github/labels.yaml @@ -19,9 +19,6 @@ - color: '6E7624' description: No API change name: semver:patch -- color: 'EC0101' - description: Unable to figure out the semver type - name: semver:unknown - color: 'D73A4A' description: Do not merge name: hold diff --git a/.github/workflows/semver-auto.yaml b/.github/workflows/semver-auto.yaml index c042be134a..eb92701452 100644 --- a/.github/workflows/semver-auto.yaml +++ b/.github/workflows/semver-auto.yaml @@ -1,21 +1,15 @@ -name: Add PR semver labels +name: Add semver labels on: pull_request_target: - types: [opened, synchronize, reopened] + types: + - opened + - synchronize + - reopened + jobs: go-apidiff: runs-on: ubuntu-latest steps: - - name: Remove the semver labels - uses: actions-ecosystem/action-remove-labels@2ce5d41b4b6aa8503e285553f75ed56e0a40bae0 - with: - labels: | - semver:patch - semver:minor - semver:major - semver:unknown - github_token: ${{ secrets.GITHUB_TOKEN }} - - uses: actions/checkout@v4 with: fetch-depth: 0 @@ -30,13 +24,6 @@ jobs: env: GIT_SEQUENCE_EDITOR: '/usr/bin/true' - - name: Add semver:unknown label - if: failure() - uses: actions-ecosystem/action-add-labels@18f1af5e3544586314bbe15c0273249c770b2daf - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - labels: semver:unknown - - uses: actions/setup-go@v5 with: go-version: '1' @@ -54,23 +41,39 @@ jobs: if: steps.go-apidiff.outcome != 'success' && steps.go-apidiff.outputs.semver-type != 'major' run: exit 1 - - name: Add semver:patch label + - name: Add label semver:patch if: steps.go-apidiff.outputs.semver-type == 'patch' - uses: actions-ecosystem/action-add-labels@18f1af5e3544586314bbe15c0273249c770b2daf - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - labels: semver:patch + run: gh pr edit "$NUMBER" --add-label "semver:patch" --remove-label "semver:major,semver:minor" + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_REPO: ${{ github.repository }} + NUMBER: ${{ github.event.pull_request.number }} - - name: Add semver:minor label + - name: Add label semver:minor if: steps.go-apidiff.outputs.semver-type == 'minor' - uses: actions-ecosystem/action-add-labels@18f1af5e3544586314bbe15c0273249c770b2daf - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - labels: semver:minor + run: gh pr edit "$NUMBER" --add-label "semver:minor" --remove-label "semver:major,semver:patch" + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_REPO: ${{ github.repository }} + NUMBER: ${{ github.event.pull_request.number }} - - name: Add semver:major label + - name: Add label semver:major if: steps.go-apidiff.outputs.semver-type == 'major' - uses: actions-ecosystem/action-add-labels@18f1af5e3544586314bbe15c0273249c770b2daf - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - labels: semver:major + run: gh pr edit "$NUMBER" --add-label "semver:major" --remove-label "semver:minor,semver:patch" + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_REPO: ${{ github.repository }} + NUMBER: ${{ github.event.pull_request.number }} + + - name: Report failure + if: failure() + run: | + gh pr edit "$NUMBER" --remove-label "semver:major,semver:minor,semver:patch" + gh issue comment "$NUMBER" --body "$BODY" + exit 1 + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_REPO: ${{ github.repository }} + NUMBER: ${{ github.event.pull_request.number }} + BODY: > + Failed to assess the semver bump. See [logs](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) for details. From 33ec4e9f95cb3f5c7e890a47c5a2a60113331e34 Mon Sep 17 00:00:00 2001 From: Przemyslaw Szczerbik Date: Tue, 16 Jul 2024 00:36:22 -0700 Subject: [PATCH 013/353] Align ServiceFail provisioning state value with Ironic There is a mismatch between ServiceFail values used by Gophercloud and Ironic. Ironic uses "service failed" value [1], rather than "service fail". This commit addresses this discrepancy. [1] https://github.com/openstack/ironic/blob/stable/2024.1/ironic/common/states.py#L248 Signed-off-by: Przemyslaw Szczerbik --- openstack/baremetal/v1/nodes/requests.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openstack/baremetal/v1/nodes/requests.go b/openstack/baremetal/v1/nodes/requests.go index f79721b4e7..8cb0de9e05 100644 --- a/openstack/baremetal/v1/nodes/requests.go +++ b/openstack/baremetal/v1/nodes/requests.go @@ -50,7 +50,7 @@ const ( Unrescuing ProvisionState = "unrescuing" Servicing ProvisionState = "servicing" ServiceWait ProvisionState = "service wait" - ServiceFail ProvisionState = "service fail" + ServiceFail ProvisionState = "service failed" ServiceHold ProvisionState = "service hold" ) From dc780086862d2fd1d0c59e4e0de1e4dd25d4e9fe Mon Sep 17 00:00:00 2001 From: Pierre Prinetti Date: Mon, 22 Jul 2024 10:15:35 +0200 Subject: [PATCH 014/353] Add needinfo label Includes a Github action that automatically removes the `needinfo` label when the original author adds a comment. --- .github/labels.yaml | 3 +++ .github/workflows/label-issue.yaml | 17 +++++++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 .github/workflows/label-issue.yaml diff --git a/.github/labels.yaml b/.github/labels.yaml index 72d8730f8e..bcd8e6c453 100644 --- a/.github/labels.yaml +++ b/.github/labels.yaml @@ -22,3 +22,6 @@ - color: 'D73A4A' description: Do not merge name: hold +- color: 'F9D0C4' + description: Additional information requested + name: needinfo diff --git a/.github/workflows/label-issue.yaml b/.github/workflows/label-issue.yaml new file mode 100644 index 0000000000..723f4cd04e --- /dev/null +++ b/.github/workflows/label-issue.yaml @@ -0,0 +1,17 @@ +name: Label issue +on: + issue_comment: + types: + - created + +jobs: + clear_needinfo: + name: Clear needinfo + if: ${{ github.event.issue.user.login }} == ${{ github.event.comment.user.login }} + runs-on: ubuntu-latest + steps: + - run: gh pr edit "$NUMBER" --remove-label "needinfo" + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_REPO: ${{ github.repository }} + NUMBER: ${{ github.event.pull_request.number }} From 343fc1a2d23474ba89c194231e0f6ccedd7f9444 Mon Sep 17 00:00:00 2001 From: Pierre Prinetti Date: Tue, 23 Jul 2024 14:35:22 +0200 Subject: [PATCH 015/353] chore: Sync labels with master --- .github/labels.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/labels.yaml b/.github/labels.yaml index bcd8e6c453..a266cf1678 100644 --- a/.github/labels.yaml +++ b/.github/labels.yaml @@ -1,6 +1,9 @@ - color: '30ABB9' description: This PR will be backported to v1 name: backport-v1 +- color: 'E99695' + description: This PR will be backported to v2 + name: backport-v2 - color: '0366d6' description: Pull requests that update a dependency file name: dependencies From b789a5a71d44d1e4ba35a8129ecc8feaa59b1209 Mon Sep 17 00:00:00 2001 From: Pierre Prinetti Date: Fri, 19 Jul 2024 12:07:37 +0200 Subject: [PATCH 016/353] actions: Label PRs based on the paths of files being changed To facilitate PR assignment and ultimately reviews, label the PRs based on what they touch. --- .github/labeler.yml | 144 ++++++++++++++++++ .github/labels.yaml | 95 +++++++++++- .../{semver-auto.yaml => label-pr.yaml} | 12 +- 3 files changed, 243 insertions(+), 8 deletions(-) create mode 100644 .github/labeler.yml rename .github/workflows/{semver-auto.yaml => label-pr.yaml} (94%) diff --git a/.github/labeler.yml b/.github/labeler.yml new file mode 100644 index 0000000000..a07b39fe3e --- /dev/null +++ b/.github/labeler.yml @@ -0,0 +1,144 @@ +edit:dependencies: +- changed-files: + - any-glob-to-any-file: + - 'go.mod' + - 'go.sum' + - '.github/dependabot.yml' +edit:actions: +- changed-files: + - any-glob-to-any-file: + - '.github/**' +edit:gophercloud: +- changed-files: + - any-glob-to-any-file: + - '*.go' + - 'testing/**' + - 'pagination/**' +edit:openstack: +- changed-files: + - any-glob-to-any-file: + - 'openstack/*' + - 'openstack/testing/**' +edit:baremetal: +- changed-files: + - any-glob-to-any-file: + - 'openstack/baremetal/**' + - 'internal/acceptance/openstack/baremetal/**' +edit:baremetalintrospection: +- changed-files: + - any-glob-to-any-file: + - 'openstack/baremetalintrospection/**' +edit:blockstorage: +- changed-files: + - any-glob-to-any-file: + - 'openstack/blockstorage/**' + - 'internal/acceptance/openstack/blockstorage/**' +edit:common: +- changed-files: + - any-glob-to-any-file: + - 'openstack/common/**' +edit:compute: +- changed-files: + - any-glob-to-any-file: + - 'openstack/compute/**' + - 'internal/acceptance/openstack/compute/**' +edit:config: +- changed-files: + - any-glob-to-any-file: + - 'openstack/config/**' +edit:container: +- changed-files: + - any-glob-to-any-file: + - 'openstack/container/**' + - 'internal/acceptance/openstack/container/**' +edit:containerinfra: +- changed-files: + - any-glob-to-any-file: + - 'openstack/containerinfra/**' + - 'internal/acceptance/openstack/containerinfra/**' +edit:db: +- changed-files: + - any-glob-to-any-file: + - 'openstack/db/**' + - 'internal/acceptance/openstack/db/**' +edit:dns: +- changed-files: + - any-glob-to-any-file: + - 'openstack/dns/**' + - 'internal/acceptance/openstack/dns/**' +edit:identity: +- changed-files: + - any-glob-to-any-file: + - 'openstack/identity/**' + - 'internal/acceptance/openstack/identity/**' +edit:image: +- changed-files: + - any-glob-to-any-file: + - 'openstack/image/**' + - 'internal/acceptance/openstack/image/**' +edit:keymanager: +- changed-files: + - any-glob-to-any-file: + - 'openstack/keymanager/**' + - 'internal/acceptance/openstack/keymanager/**' +edit:loadbalancer: +- changed-files: + - any-glob-to-any-file: + - 'openstack/loadbalancer/**' + - 'internal/acceptance/openstack/loadbalancer/**' +edit:messaging: +- changed-files: + - any-glob-to-any-file: + - 'openstack/messaging/**' + - 'internal/acceptance/openstack/messaging/**' +edit:networking: +- changed-files: + - any-glob-to-any-file: + - 'openstack/networking/**' + - 'internal/acceptance/openstack/networking/**' +edit:objectstorage: +- changed-files: + - any-glob-to-any-file: + - 'openstack/objectstorage/**' + - 'internal/acceptance/openstack/objectstorage/**' +edit:orchestration: +- changed-files: + - any-glob-to-any-file: + - 'openstack/orchestration/**' + - 'internal/acceptance/openstack/orchestration/**' +edit:placement: +- changed-files: + - any-glob-to-any-file: + - 'openstack/placement/**' + - 'internal/acceptance/openstack/placement/**' +edit:sharedfilesystems: +- changed-files: + - any-glob-to-any-file: + - 'openstack/sharedfilesystems/**' + - 'internal/acceptance/openstack/sharedfilesystems/**' +edit:testinfra: +- changed-files: + - any-glob-to-any-file: + - 'testhelper/**' + - 'internal/acceptance/*' + - 'internal/acceptance/openstack/*' + - 'internal/acceptance/clients/**' + - 'internal/acceptance/tools/**' + - '.github/workflows/functional-*.yaml' + - '.github/workflows/unit.yaml' + - '.github/workflows/lint.yaml' + - 'script/**' +edit:utils: +- changed-files: + - any-glob-to-any-file: + - 'openstack/utils/**' +edit:workflow: +- changed-files: + - any-glob-to-any-file: + - 'openstack/workflow/**' + - 'internal/acceptance/openstack/workflow/**' + +v1: +- base-branch: 'v1' +v2: +- base-branch: 'v2' diff --git a/.github/labels.yaml b/.github/labels.yaml index a266cf1678..4f888b4d4f 100644 --- a/.github/labels.yaml +++ b/.github/labels.yaml @@ -4,12 +4,6 @@ - color: 'E99695' description: This PR will be backported to v2 name: backport-v2 -- color: '0366d6' - description: Pull requests that update a dependency file - name: dependencies -- color: '000000' - description: Pull requests that update GitHub Actions code - name: github_actions - color: 'BCF611' description: A good issue for first-time contributors name: good first issue @@ -28,3 +22,92 @@ - color: 'F9D0C4' description: Additional information requested name: needinfo + +- color: '30ABB9' + description: This PR targets v1 + name: v1 +- color: 'E99695' + description: This PR targets v2 + name: v2 + +- color: '000000' + description: This PR updates dependencies + name: edit:dependencies +- color: '000000' + description: This PR updates GitHub Actions code + name: edit:actions +- color: '000000' + description: This PR updates common Gophercloud code + name: edit:gophercloud +- color: '000000' + description: This PR updates common OpenStack code + name: edit:openstack +- color: '000000' + description: This PR updates baremetal code + name: edit:baremetal +- color: '000000' + description: This PR updates baremetalintrospection code + name: edit:baremetalintrospection +- color: '000000' + description: This PR updates blockstorage code + name: edit:blockstorage +- color: '000000' + description: This PR updates common code + name: edit:common +- color: '000000' + description: This PR updates compute code + name: edit:compute +- color: '000000' + description: This PR updates config code + name: edit:config +- color: '000000' + description: This PR updates container code + name: edit:container +- color: '000000' + description: This PR updates containerinfra code + name: edit:containerinfra +- color: '000000' + description: This PR updates db code + name: edit:db +- color: '000000' + description: This PR updates dns code + name: edit:dns +- color: '000000' + description: This PR updates identity code + name: edit:identity +- color: '000000' + description: This PR updates image code + name: edit:image +- color: '000000' + description: This PR updates keymanager code + name: edit:keymanager +- color: '000000' + description: This PR updates loadbalancer code + name: edit:loadbalancer +- color: '000000' + description: This PR updates messaging code + name: edit:messaging +- color: '000000' + description: This PR updates networking code + name: edit:networking +- color: '000000' + description: This PR updates objectstorage code + name: edit:objectstorage +- color: '000000' + description: This PR updates orchestration code + name: edit:orchestration +- color: '000000' + description: This PR updates placement code + name: edit:placement +- color: '000000' + description: This PR updates sharedfilesystems code + name: edit:sharedfilesystems +- color: '000000' + description: This PR updates testing code + name: edit:testing +- color: '000000' + description: This PR updates utils code + name: edit:utils +- color: '000000' + description: This PR updates workflow code + name: edit:workflow diff --git a/.github/workflows/semver-auto.yaml b/.github/workflows/label-pr.yaml similarity index 94% rename from .github/workflows/semver-auto.yaml rename to .github/workflows/label-pr.yaml index eb92701452..44d46b0e15 100644 --- a/.github/workflows/semver-auto.yaml +++ b/.github/workflows/label-pr.yaml @@ -1,4 +1,4 @@ -name: Add semver labels +name: Label PR on: pull_request_target: types: @@ -7,7 +7,7 @@ on: - reopened jobs: - go-apidiff: + semver: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -77,3 +77,11 @@ jobs: NUMBER: ${{ github.event.pull_request.number }} BODY: > Failed to assess the semver bump. See [logs](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) for details. + + edits: + permissions: + contents: read + pull-requests: write + runs-on: ubuntu-latest + steps: + - uses: actions/labeler@v5 From 1c3733d6346bbf38836c5af313e5e13f1a208eab Mon Sep 17 00:00:00 2001 From: Sharpz7 Date: Fri, 19 Jul 2024 11:43:51 +0000 Subject: [PATCH 017/353] Added node.Retired --- openstack/baremetal/v1/nodes/results.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/openstack/baremetal/v1/nodes/results.go b/openstack/baremetal/v1/nodes/results.go index 0602add768..5c6eb5c190 100644 --- a/openstack/baremetal/v1/nodes/results.go +++ b/openstack/baremetal/v1/nodes/results.go @@ -261,6 +261,13 @@ type Node struct { // The UTC date and time when the last inspection was finished, ISO 8601 format. May be “null” if inspection hasn't been finished yet. InspectionFinishedAt *time.Time `json:"inspection_finished_at"` + + // Whether the node is retired. A Node tagged as retired will prevent any further + // scheduling of instances, but will still allow for other operations, such as cleaning, to happen + Retired bool `json:"retired"` + + // Reason the node is marked as retired. + RetiredReason string `json:"retired_reason"` } // NodePage abstracts the raw results of making a List() request against From e33a181a00c323dfeae9c86769383e465759afb2 Mon Sep 17 00:00:00 2001 From: Sharpz7 Date: Fri, 19 Jul 2024 14:51:12 +0000 Subject: [PATCH 018/353] Added tests --- .../v1/nodes/testing/fixtures_test.go | 24 +++++++++++++++---- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/openstack/baremetal/v1/nodes/testing/fixtures_test.go b/openstack/baremetal/v1/nodes/testing/fixtures_test.go index 8ab570b54d..d47d70b13c 100644 --- a/openstack/baremetal/v1/nodes/testing/fixtures_test.go +++ b/openstack/baremetal/v1/nodes/testing/fixtures_test.go @@ -149,6 +149,8 @@ const NodeListDetailBody = ` "provision_updated_at": "2019-02-15T17:21:29+00:00", "raid_config": {}, "raid_interface": "no-raid", + "retired": false, + "retired_reason": "No longer needed", "rescue_interface": "no-rescue", "reservation": null, "resource_class": null, @@ -247,6 +249,8 @@ const NodeListDetailBody = ` "provision_updated_at": null, "raid_config": {}, "raid_interface": "no-raid", + "retired": false, + "retired_reason": "No longer needed", "rescue_interface": "no-rescue", "reservation": null, "resource_class": null, @@ -345,6 +349,8 @@ const NodeListDetailBody = ` "provision_updated_at": null, "raid_config": {}, "raid_interface": "no-raid", + "retired": false, + "retired_reason": "No longer needed", "rescue_interface": "no-rescue", "reservation": null, "resource_class": null, @@ -456,6 +462,8 @@ const SingleNodeBody = ` "provision_updated_at": "2019-02-15T17:21:29+00:00", "raid_config": {}, "raid_interface": "no-raid", + "retired": false, + "retired_reason": "No longer needed", "rescue_interface": "no-rescue", "reservation": null, "resource_class": null, @@ -855,7 +863,7 @@ const NodeFirmwareListBody = ` { "firmware": [ { - "created_at": "2023-10-03T18:30:00+00:00", + "created_at": "2023-10-03T18:30:00+00:00", "updated_at": null, "component": "bios", "initial_version": "U30 v2.36 (07/16/2020)", @@ -864,10 +872,10 @@ const NodeFirmwareListBody = ` }, { "created_at": "2023-10-03T18:30:00+00:00", - "updated_at": "2023-10-03T18:45:54+00:00", - "component": "bmc", - "initial_version": "iLO 5 v2.78", - "current_version": "iLO 5 v2.81", + "updated_at": "2023-10-03T18:45:54+00:00", + "component": "bmc", + "initial_version": "iLO 5 v2.78", + "current_version": "iLO 5 v2.81", "last_version_flashed": "iLO 5 v2.81" } ] @@ -949,6 +957,8 @@ var ( CreatedAt: createdAtFoo, UpdatedAt: updatedAt, ProvisionUpdatedAt: provisonUpdatedAt, + Retired: false, + RetiredReason: "No longer needed", } NodeFooValidation = nodes.NodeValidation{ @@ -1058,6 +1068,8 @@ var ( UpdatedAt: updatedAt, InspectionStartedAt: &InspectionStartedAt, InspectionFinishedAt: &InspectionFinishedAt, + Retired: false, + RetiredReason: "No longer needed", } NodeBaz = nodes.Node{ @@ -1105,6 +1117,8 @@ var ( ProtectedReason: "", CreatedAt: createdAtBaz, UpdatedAt: updatedAt, + Retired: false, + RetiredReason: "No longer needed", } ConfigDriveMap = nodes.ConfigDrive{ From 93b24a5b595c564122f55f75a84384516340a276 Mon Sep 17 00:00:00 2001 From: Pierre Prinetti Date: Tue, 23 Jul 2024 14:57:53 +0200 Subject: [PATCH 019/353] Prepare v2.1.0 --- CHANGELOG.md | 10 ++++++++++ provider_client.go | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d7dfbc469..4e4d1c854e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +## v2.1.0 + +* [GH-3078](https://github.com/gophercloud/gophercloud/pull/3078) [networking]: add BGP VPNs support +* [GH-3086](https://github.com/gophercloud/gophercloud/pull/3086) build(deps): bump golang.org/x/crypto from 0.24.0 to 0.25.0 +* [GH-3090](https://github.com/gophercloud/gophercloud/pull/3090) Adding support for field dns_publish_fixed_ip in a subnet +* [GH-3092](https://github.com/gophercloud/gophercloud/pull/3092) [neutron]: introduce Stateful argument for the security groups +* [GH-3094](https://github.com/gophercloud/gophercloud/pull/3094) [neutron]: introduce Description argument for the portforwarding +* [GH-3106](https://github.com/gophercloud/gophercloud/pull/3106) clouds: Parse trust_id from clouds.yaml +* [GH-3131](https://github.com/gophercloud/gophercloud/pull/3131) Align ServiceFail provisioning state value with Ironic + ## v2.0.0 (2024-05-27) MAIN BREAKING CHANGES: diff --git a/provider_client.go b/provider_client.go index f8c4928cbd..a4a8dce51d 100644 --- a/provider_client.go +++ b/provider_client.go @@ -13,7 +13,7 @@ import ( // DefaultUserAgent is the default User-Agent string set in the request header. const ( - DefaultUserAgent = "gophercloud/v2.0.0" + DefaultUserAgent = "gophercloud/v2.1.0" DefaultMaxBackoffRetries = 60 ) From c208b4bf89c2215afe889dc7b628845bfb8136d1 Mon Sep 17 00:00:00 2001 From: Pierre Prinetti Date: Tue, 23 Jul 2024 14:57:53 +0200 Subject: [PATCH 020/353] Prepare v2.1.0 --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e4d1c854e..bae5109cfe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -## v2.1.0 +## v2.1.0 (2024-07-24) * [GH-3078](https://github.com/gophercloud/gophercloud/pull/3078) [networking]: add BGP VPNs support * [GH-3086](https://github.com/gophercloud/gophercloud/pull/3086) build(deps): bump golang.org/x/crypto from 0.24.0 to 0.25.0 @@ -7,6 +7,7 @@ * [GH-3094](https://github.com/gophercloud/gophercloud/pull/3094) [neutron]: introduce Description argument for the portforwarding * [GH-3106](https://github.com/gophercloud/gophercloud/pull/3106) clouds: Parse trust_id from clouds.yaml * [GH-3131](https://github.com/gophercloud/gophercloud/pull/3131) Align ServiceFail provisioning state value with Ironic +* [GH-3136](https://github.com/gophercloud/gophercloud/pull/3136) Added node.Retired ## v2.0.0 (2024-05-27) From b743cca31d7b26d4996167a4bf88011eaf88213e Mon Sep 17 00:00:00 2001 From: whitefox Date: Wed, 24 Jul 2024 20:55:42 +0500 Subject: [PATCH 021/353] fix: create security group rule with any protocol https://github.com/gophercloud/gophercloud/issues/2442 --- .../v2/extensions/security/rules/requests.go | 5 ++ .../security/rules/testing/requests_test.go | 60 +++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/openstack/networking/v2/extensions/security/rules/requests.go b/openstack/networking/v2/extensions/security/rules/requests.go index 78b67b0df0..d9079dd96a 100644 --- a/openstack/networking/v2/extensions/security/rules/requests.go +++ b/openstack/networking/v2/extensions/security/rules/requests.go @@ -145,6 +145,11 @@ func Create(ctx context.Context, c *gophercloud.ServiceClient, opts CreateOptsBu r.Err = err return } + if m, mOk := b["security_group_rule"].(map[string]any); mOk { + if p, ok := m["protocol"]; ok && p == "any" { + m["protocol"] = nil + } + } resp, err := c.Post(ctx, rootURL(c), b, &r.Body, nil) _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) return diff --git a/openstack/networking/v2/extensions/security/rules/testing/requests_test.go b/openstack/networking/v2/extensions/security/rules/testing/requests_test.go index 454399f306..7d9ceefdff 100644 --- a/openstack/networking/v2/extensions/security/rules/testing/requests_test.go +++ b/openstack/networking/v2/extensions/security/rules/testing/requests_test.go @@ -164,6 +164,66 @@ func TestCreate(t *testing.T) { th.AssertNoErr(t, err) } +func TestCreateAnyProtocol(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + + th.Mux.HandleFunc("/v2.0/security-group-rules", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "POST") + th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "Content-Type", "application/json") + th.TestHeader(t, r, "Accept", "application/json") + th.TestJSONRequest(t, r, ` +{ + "security_group_rule": { + "description": "test description of rule", + "direction": "ingress", + "port_range_min": 80, + "ethertype": "IPv4", + "port_range_max": 80, + "protocol": null, + "remote_group_id": "85cc3048-abc3-43cc-89b3-377341426ac5", + "security_group_id": "a7734e61-b545-452d-a3cd-0189cbd9747a" + } +} + `) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusCreated) + + fmt.Fprintf(w, ` +{ + "security_group_rule": { + "description": "test description of rule", + "direction": "ingress", + "ethertype": "IPv4", + "id": "2bc0accf-312e-429a-956e-e4407625eb62", + "port_range_max": 80, + "port_range_min": 80, + "protocol": null, + "remote_group_id": "85cc3048-abc3-43cc-89b3-377341426ac5", + "remote_ip_prefix": null, + "security_group_id": "a7734e61-b545-452d-a3cd-0189cbd9747a", + "tenant_id": "e4f50856753b4dc6afee5fa6b9b6c550" + } +} + `) + }) + + opts := rules.CreateOpts{ + Description: "test description of rule", + Direction: "ingress", + PortRangeMin: 80, + EtherType: rules.EtherType4, + PortRangeMax: 80, + Protocol: "any", + RemoteGroupID: "85cc3048-abc3-43cc-89b3-377341426ac5", + SecGroupID: "a7734e61-b545-452d-a3cd-0189cbd9747a", + } + _, err := rules.Create(context.TODO(), fake.ServiceClient(), opts).Extract() + th.AssertNoErr(t, err) +} + func TestRequiredCreateOpts(t *testing.T) { res := rules.Create(context.TODO(), fake.ServiceClient(), rules.CreateOpts{Direction: rules.DirIngress}) if res.Err == nil { From d3a0124321fb3feb3d97fce3f8bf8adf94f0d30f Mon Sep 17 00:00:00 2001 From: whitefox Date: Wed, 24 Jul 2024 21:07:47 +0500 Subject: [PATCH 022/353] use const --- openstack/networking/v2/extensions/security/rules/requests.go | 2 +- .../v2/extensions/security/rules/testing/requests_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/openstack/networking/v2/extensions/security/rules/requests.go b/openstack/networking/v2/extensions/security/rules/requests.go index d9079dd96a..8fa5d9ee83 100644 --- a/openstack/networking/v2/extensions/security/rules/requests.go +++ b/openstack/networking/v2/extensions/security/rules/requests.go @@ -146,7 +146,7 @@ func Create(ctx context.Context, c *gophercloud.ServiceClient, opts CreateOptsBu return } if m, mOk := b["security_group_rule"].(map[string]any); mOk { - if p, ok := m["protocol"]; ok && p == "any" { + if p, ok := m["protocol"]; ok && p == string(ProtocolAny) { m["protocol"] = nil } } diff --git a/openstack/networking/v2/extensions/security/rules/testing/requests_test.go b/openstack/networking/v2/extensions/security/rules/testing/requests_test.go index 7d9ceefdff..3b44db3837 100644 --- a/openstack/networking/v2/extensions/security/rules/testing/requests_test.go +++ b/openstack/networking/v2/extensions/security/rules/testing/requests_test.go @@ -216,7 +216,7 @@ func TestCreateAnyProtocol(t *testing.T) { PortRangeMin: 80, EtherType: rules.EtherType4, PortRangeMax: 80, - Protocol: "any", + Protocol: rules.ProtocolAny, RemoteGroupID: "85cc3048-abc3-43cc-89b3-377341426ac5", SecGroupID: "a7734e61-b545-452d-a3cd-0189cbd9747a", } From 91bbaa36262372a92eeea8b74ceb941b6f092374 Mon Sep 17 00:00:00 2001 From: whitefox Date: Wed, 24 Jul 2024 23:11:12 +0500 Subject: [PATCH 023/353] move to ToSecGroupRuleCreateMap --- .../v2/extensions/security/rules/requests.go | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/openstack/networking/v2/extensions/security/rules/requests.go b/openstack/networking/v2/extensions/security/rules/requests.go index 8fa5d9ee83..cad532bd93 100644 --- a/openstack/networking/v2/extensions/security/rules/requests.go +++ b/openstack/networking/v2/extensions/security/rules/requests.go @@ -134,7 +134,16 @@ type CreateOpts struct { // ToSecGroupRuleCreateMap builds a request body from CreateOpts. func (opts CreateOpts) ToSecGroupRuleCreateMap() (map[string]any, error) { - return gophercloud.BuildRequestBody(opts, "security_group_rule") + b, err := gophercloud.BuildRequestBody(opts, "security_group_rule") + if err != nil { + return nil, err + } + if m, mOk := b["security_group_rule"].(map[string]any); mOk { + if p, ok := m["protocol"]; ok && p == string(ProtocolAny) { + m["protocol"] = nil + } + } + return b, err } // Create is an operation which adds a new security group rule and associates it @@ -145,11 +154,6 @@ func Create(ctx context.Context, c *gophercloud.ServiceClient, opts CreateOptsBu r.Err = err return } - if m, mOk := b["security_group_rule"].(map[string]any); mOk { - if p, ok := m["protocol"]; ok && p == string(ProtocolAny) { - m["protocol"] = nil - } - } resp, err := c.Post(ctx, rootURL(c), b, &r.Body, nil) _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) return From 4cd0309af736a14151adcba13ddfa243ae0688ff Mon Sep 17 00:00:00 2001 From: whitefox Date: Wed, 24 Jul 2024 23:44:21 +0500 Subject: [PATCH 024/353] emoved redundant key check --- .../networking/v2/extensions/security/rules/requests.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/openstack/networking/v2/extensions/security/rules/requests.go b/openstack/networking/v2/extensions/security/rules/requests.go index cad532bd93..55a6cde88f 100644 --- a/openstack/networking/v2/extensions/security/rules/requests.go +++ b/openstack/networking/v2/extensions/security/rules/requests.go @@ -2,6 +2,7 @@ package rules import ( "context" + "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/extensions/fwaas_v2/rules" "github.com/gophercloud/gophercloud/v2" "github.com/gophercloud/gophercloud/v2/pagination" @@ -138,10 +139,8 @@ func (opts CreateOpts) ToSecGroupRuleCreateMap() (map[string]any, error) { if err != nil { return nil, err } - if m, mOk := b["security_group_rule"].(map[string]any); mOk { - if p, ok := m["protocol"]; ok && p == string(ProtocolAny) { - m["protocol"] = nil - } + if m := b["security_group_rule"].(map[string]any); m["protocol"] == string(rules.ProtocolAny) { + m["protocol"] = nil } return b, err } From fc5f4178fc797b46b6c5b9ace78ff7a14d9ca6ff Mon Sep 17 00:00:00 2001 From: whitefox Date: Thu, 25 Jul 2024 00:34:18 +0500 Subject: [PATCH 025/353] extract ProtocolAny --- openstack/networking/v2/extensions/security/rules/results.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openstack/networking/v2/extensions/security/rules/results.go b/openstack/networking/v2/extensions/security/rules/results.go index cfdb27fa17..bcaea974ce 100644 --- a/openstack/networking/v2/extensions/security/rules/results.go +++ b/openstack/networking/v2/extensions/security/rules/results.go @@ -109,6 +109,9 @@ func (r commonResult) Extract() (*SecGroupRule, error) { SecGroupRule *SecGroupRule `json:"security_group_rule"` } err := r.ExtractInto(&s) + if err == nil && len(s.SecGroupRule.Protocol) == 0 { + s.SecGroupRule.Protocol = string(ProtocolAny) + } return s.SecGroupRule, err } From ab9a11ea83bb84c6e4d5a45cf5ef9f338f23a46f Mon Sep 17 00:00:00 2001 From: whitefox Date: Fri, 26 Jul 2024 22:57:11 +0500 Subject: [PATCH 026/353] protocol any to empty string --- .../v2/extensions/security/rules/requests.go | 13 ++----------- .../v2/extensions/security/rules/results.go | 3 --- .../security/rules/testing/requests_test.go | 2 -- 3 files changed, 2 insertions(+), 16 deletions(-) diff --git a/openstack/networking/v2/extensions/security/rules/requests.go b/openstack/networking/v2/extensions/security/rules/requests.go index 55a6cde88f..eaf6deab80 100644 --- a/openstack/networking/v2/extensions/security/rules/requests.go +++ b/openstack/networking/v2/extensions/security/rules/requests.go @@ -2,8 +2,6 @@ package rules import ( "context" - "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/extensions/fwaas_v2/rules" - "github.com/gophercloud/gophercloud/v2" "github.com/gophercloud/gophercloud/v2/pagination" ) @@ -78,7 +76,7 @@ const ( ProtocolUDP RuleProtocol = "udp" ProtocolUDPLite RuleProtocol = "udplite" ProtocolVRRP RuleProtocol = "vrrp" - ProtocolAny RuleProtocol = "any" + ProtocolAny RuleProtocol = "" ) // CreateOptsBuilder allows extensions to add additional parameters to the @@ -135,14 +133,7 @@ type CreateOpts struct { // ToSecGroupRuleCreateMap builds a request body from CreateOpts. func (opts CreateOpts) ToSecGroupRuleCreateMap() (map[string]any, error) { - b, err := gophercloud.BuildRequestBody(opts, "security_group_rule") - if err != nil { - return nil, err - } - if m := b["security_group_rule"].(map[string]any); m["protocol"] == string(rules.ProtocolAny) { - m["protocol"] = nil - } - return b, err + return gophercloud.BuildRequestBody(opts, "security_group_rule") } // Create is an operation which adds a new security group rule and associates it diff --git a/openstack/networking/v2/extensions/security/rules/results.go b/openstack/networking/v2/extensions/security/rules/results.go index bcaea974ce..cfdb27fa17 100644 --- a/openstack/networking/v2/extensions/security/rules/results.go +++ b/openstack/networking/v2/extensions/security/rules/results.go @@ -109,9 +109,6 @@ func (r commonResult) Extract() (*SecGroupRule, error) { SecGroupRule *SecGroupRule `json:"security_group_rule"` } err := r.ExtractInto(&s) - if err == nil && len(s.SecGroupRule.Protocol) == 0 { - s.SecGroupRule.Protocol = string(ProtocolAny) - } return s.SecGroupRule, err } diff --git a/openstack/networking/v2/extensions/security/rules/testing/requests_test.go b/openstack/networking/v2/extensions/security/rules/testing/requests_test.go index 3b44db3837..40372c298a 100644 --- a/openstack/networking/v2/extensions/security/rules/testing/requests_test.go +++ b/openstack/networking/v2/extensions/security/rules/testing/requests_test.go @@ -181,7 +181,6 @@ func TestCreateAnyProtocol(t *testing.T) { "port_range_min": 80, "ethertype": "IPv4", "port_range_max": 80, - "protocol": null, "remote_group_id": "85cc3048-abc3-43cc-89b3-377341426ac5", "security_group_id": "a7734e61-b545-452d-a3cd-0189cbd9747a" } @@ -200,7 +199,6 @@ func TestCreateAnyProtocol(t *testing.T) { "id": "2bc0accf-312e-429a-956e-e4407625eb62", "port_range_max": 80, "port_range_min": 80, - "protocol": null, "remote_group_id": "85cc3048-abc3-43cc-89b3-377341426ac5", "remote_ip_prefix": null, "security_group_id": "a7734e61-b545-452d-a3cd-0189cbd9747a", From 17ab1a6bc8daa4abee25c26de8c39e5c9868f817 Mon Sep 17 00:00:00 2001 From: whitefox Date: Fri, 26 Jul 2024 23:52:25 +0500 Subject: [PATCH 027/353] revert newline --- openstack/networking/v2/extensions/security/rules/requests.go | 1 + 1 file changed, 1 insertion(+) diff --git a/openstack/networking/v2/extensions/security/rules/requests.go b/openstack/networking/v2/extensions/security/rules/requests.go index eaf6deab80..f2ea9f2d16 100644 --- a/openstack/networking/v2/extensions/security/rules/requests.go +++ b/openstack/networking/v2/extensions/security/rules/requests.go @@ -2,6 +2,7 @@ package rules import ( "context" + "github.com/gophercloud/gophercloud/v2" "github.com/gophercloud/gophercloud/v2/pagination" ) From f38fcef442834685d024f1422b20719f021e3705 Mon Sep 17 00:00:00 2001 From: Pierre Prinetti Date: Wed, 18 Sep 2024 13:46:49 +0200 Subject: [PATCH 028/353] Prepare v2.1.1 --- CHANGELOG.md | 4 ++++ provider_client.go | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bae5109cfe..41f9017aa9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## v2.1.1 (2024-09-18) + +* [GH-3161](https://github.com/gophercloud/gophercloud/pull/3161) [v2] fix: create security group rule with any protocol + ## v2.1.0 (2024-07-24) * [GH-3078](https://github.com/gophercloud/gophercloud/pull/3078) [networking]: add BGP VPNs support diff --git a/provider_client.go b/provider_client.go index a4a8dce51d..e2cd3c2dad 100644 --- a/provider_client.go +++ b/provider_client.go @@ -13,7 +13,7 @@ import ( // DefaultUserAgent is the default User-Agent string set in the request header. const ( - DefaultUserAgent = "gophercloud/v2.1.0" + DefaultUserAgent = "gophercloud/v2.1.1" DefaultMaxBackoffRetries = 60 ) From 757ad867295a7ab7c0bd904fa7faf7cf70f8a0a3 Mon Sep 17 00:00:00 2001 From: kayrus Date: Sat, 27 Jul 2024 12:15:17 +0200 Subject: [PATCH 029/353] [containerinfra]: add "MasterLBEnabled" in Cluster results --- .../acceptance/openstack/containerinfra/v1/clusters_test.go | 1 + openstack/containerinfra/v1/clusters/results.go | 1 + .../containerinfra/v1/clusters/testing/fixtures_test.go | 5 +++++ 3 files changed, 7 insertions(+) diff --git a/internal/acceptance/openstack/containerinfra/v1/clusters_test.go b/internal/acceptance/openstack/containerinfra/v1/clusters_test.go index 7a277b318a..d12c31bf4a 100644 --- a/internal/acceptance/openstack/containerinfra/v1/clusters_test.go +++ b/internal/acceptance/openstack/containerinfra/v1/clusters_test.go @@ -63,6 +63,7 @@ func TestClustersCRUD(t *testing.T) { newCluster, err := clusters.Get(context.TODO(), client, clusterID).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, newCluster.UUID, clusterID) + th.AssertEquals(t, newCluster.MasterLBEnabled, false) allPagesDetail, err := clusters.ListDetail(client, nil).AllPages(context.TODO()) th.AssertNoErr(t, err) diff --git a/openstack/containerinfra/v1/clusters/results.go b/openstack/containerinfra/v1/clusters/results.go index 6c235dcd23..04adc8ea48 100644 --- a/openstack/containerinfra/v1/clusters/results.go +++ b/openstack/containerinfra/v1/clusters/results.go @@ -112,6 +112,7 @@ type Cluster struct { UpdatedAt time.Time `json:"updated_at"` UserID string `json:"user_id"` FloatingIPEnabled bool `json:"floating_ip_enabled"` + MasterLBEnabled bool `json:"master_lb_enabled"` FixedNetwork string `json:"fixed_network"` FixedSubnet string `json:"fixed_subnet"` HealthStatus string `json:"health_status"` diff --git a/openstack/containerinfra/v1/clusters/testing/fixtures_test.go b/openstack/containerinfra/v1/clusters/testing/fixtures_test.go index 640533e2c8..ccbfddfc6d 100644 --- a/openstack/containerinfra/v1/clusters/testing/fixtures_test.go +++ b/openstack/containerinfra/v1/clusters/testing/fixtures_test.go @@ -50,6 +50,7 @@ var ExpectedCluster = clusters.Cluster{ UpdatedAt: time.Date(2016, 8, 29, 6, 53, 24, 0, time.UTC), UUID: clusterUUID, FloatingIPEnabled: true, + MasterLBEnabled: true, FixedNetwork: "private_network", FixedSubnet: "private_subnet", HealthStatus: "HEALTHY", @@ -85,6 +86,7 @@ var ExpectedCluster2 = clusters.Cluster{ UpdatedAt: time.Date(2016, 8, 29, 6, 53, 24, 0, time.UTC), UUID: clusterUUID2, FloatingIPEnabled: true, + MasterLBEnabled: true, FixedNetwork: "private_network", FixedSubnet: "private_subnet", HealthStatus: "HEALTHY", @@ -152,6 +154,7 @@ var ClusterGetResponse = fmt.Sprintf(` "create_timeout":60, "name":"k8s", "floating_ip_enabled": true, + "master_lb_enabled": true, "fixed_network": "private_network", "fixed_subnet": "private_subnet", "health_status": "HEALTHY", @@ -194,6 +197,7 @@ var ClusterListResponse = fmt.Sprintf(` "updated_at":"2016-08-29T06:53:24+00:00", "uuid":"%s", "floating_ip_enabled": true, + "master_lb_enabled": true, "fixed_network": "private_network", "fixed_subnet": "private_subnet", "health_status": "HEALTHY", @@ -232,6 +236,7 @@ var ClusterListResponse = fmt.Sprintf(` "updated_at":null, "uuid":"%s", "floating_ip_enabled": true, + "master_lb_enabled": true, "fixed_network": "private_network", "fixed_subnet": "private_subnet", "health_status": "HEALTHY", From 8e1a5babca470170b99f0f1276a817d4002a3cdb Mon Sep 17 00:00:00 2001 From: kayrus Date: Tue, 24 Sep 2024 02:40:00 +0200 Subject: [PATCH 030/353] octavia: add new options to health monitors --- openstack/loadbalancer/v2/monitors/requests.go | 16 ++++++++++++++++ openstack/loadbalancer/v2/monitors/results.go | 6 ++++++ 2 files changed, 22 insertions(+) diff --git a/openstack/loadbalancer/v2/monitors/requests.go b/openstack/loadbalancer/v2/monitors/requests.go index 5667955add..be5701c5f4 100644 --- a/openstack/loadbalancer/v2/monitors/requests.go +++ b/openstack/loadbalancer/v2/monitors/requests.go @@ -119,6 +119,10 @@ type CreateOpts struct { // is not specified, it defaults to "GET". Required for HTTP(S) types. HTTPMethod string `json:"http_method,omitempty"` + // The HTTP version. One of 1.0 or 1.1. The default is 1.0. New in + // version 2.10. + HTTPVersion string `json:"http_version,omitempty"` + // Expected HTTP codes for a passing HTTP(S) Monitor. You can either specify // a single status like "200", a range like "200-202", or a combination like // "200-202, 401". @@ -139,6 +143,10 @@ type CreateOpts struct { // or false (DOWN). AdminStateUp *bool `json:"admin_state_up,omitempty"` + // The domain name, which be injected into the HTTP Host Header to the + // backend server for HTTP health check. New in version 2.10 + DomainName string `json:"domain_name,omitempty"` + // Tags is a set of resource tags. New in version 2.5 Tags []string `json:"tags,omitempty"` } @@ -213,6 +221,10 @@ type UpdateOpts struct { // is not specified, it defaults to "GET". Required for HTTP(S) types. HTTPMethod string `json:"http_method,omitempty"` + // The HTTP version. One of 1.0 or 1.1. The default is 1.0. New in + // version 2.10. + HTTPVersion *string `json:"http_version,omitempty"` + // Expected HTTP codes for a passing HTTP(S) Monitor. You can either specify // a single status like "200", or a range like "200-202". Required for HTTP(S) // types. @@ -221,6 +233,10 @@ type UpdateOpts struct { // The Name of the Monitor. Name *string `json:"name,omitempty"` + // The domain name, which be injected into the HTTP Host Header to the + // backend server for HTTP health check. New in version 2.10 + DomainName *string `json:"domain_name,omitempty"` + // The administrative state of the Monitor. A valid value is true (UP) // or false (DOWN). AdminStateUp *bool `json:"admin_state_up,omitempty"` diff --git a/openstack/loadbalancer/v2/monitors/results.go b/openstack/loadbalancer/v2/monitors/results.go index 3a29da9f40..644ef18700 100644 --- a/openstack/loadbalancer/v2/monitors/results.go +++ b/openstack/loadbalancer/v2/monitors/results.go @@ -60,6 +60,9 @@ type Monitor struct { // The HTTP method that the monitor uses for requests. HTTPMethod string `json:"http_method"` + // The HTTP version that the monitor uses for requests. + HTTPVersion string `json:"http_version"` + // The HTTP path of the request sent by the monitor to test the health of a // member. Must be a string beginning with a forward slash (/). URLPath string `json:"url_path" ` @@ -67,6 +70,9 @@ type Monitor struct { // Expected HTTP codes for a passing HTTP(S) monitor. ExpectedCodes string `json:"expected_codes"` + // The HTTP host header that the monitor uses for requests. + DomainName string `json:"domain_name"` + // The administrative state of the health monitor, which is up (true) or // down (false). AdminStateUp bool `json:"admin_state_up"` From 2765b1ff1f8ed85038aaf4b75a3fcda54327cea7 Mon Sep 17 00:00:00 2001 From: kayrus Date: Mon, 23 Sep 2024 23:00:36 +0200 Subject: [PATCH 031/353] octavia: add new security options to pools and listeners --- .../loadbalancer/v2/listeners/requests.go | 80 +++++++++++++++++++ .../loadbalancer/v2/listeners/results.go | 18 +++++ openstack/loadbalancer/v2/pools/requests.go | 62 ++++++++++++++ openstack/loadbalancer/v2/pools/results.go | 31 +++++++ 4 files changed, 191 insertions(+) diff --git a/openstack/loadbalancer/v2/listeners/requests.go b/openstack/loadbalancer/v2/listeners/requests.go index ea5b10dd2f..5c66db23be 100644 --- a/openstack/loadbalancer/v2/listeners/requests.go +++ b/openstack/loadbalancer/v2/listeners/requests.go @@ -170,6 +170,46 @@ type CreateOpts struct { // A list of IPv4, IPv6 or mix of both CIDRs AllowedCIDRs []string `json:"allowed_cidrs,omitempty"` + // A list of ALPN protocols. Available protocols: http/1.0, http/1.1, + // h2. Available from microversion 2.20. + ALPNProtocols []string `json:"alpn_protocols,omitempty"` + + // The TLS client authentication mode. One of the options NONE, + // OPTIONAL or MANDATORY. Available from microversion 2.8. + ClientAuthentication string `json:"client_authentication,omitempty"` + + // The ref of the key manager service secret containing a PEM format + // client CA certificate bundle for TERMINATED_HTTPS listeners. + // Available from microversion 2.8. + ClientCATLSContainerRef string `json:"client_ca_tls_container_ref,omitempty"` + + // The URI of the key manager service secret containing a PEM format CA + // revocation list file for TERMINATED_HTTPS listeners. Available from + // microversion 2.8. + ClientCRLContainerRef string `json:"client_crl_container_ref,omitempty"` + + // Defines whether the includeSubDomains directive should be added to + // the Strict-Transport-Security HTTP response header. This requires + // setting the hsts_max_age option as well in order to become + // effective. Available from microversion 2.27. + HSTSIncludeSubdomains bool `json:"hsts_include_subdomains,omitempty"` + + // The value of the max_age directive for the Strict-Transport-Security + // HTTP response header. Setting this enables HTTP Strict Transport + // Security (HSTS) for the TLS-terminated listener. Available from + // microversion 2.27. + HSTSMaxAge int `json:"hsts_max_age,omitempty"` + + // Defines whether the preload directive should be added to the + // Strict-Transport-Security HTTP response header. This requires + // setting the hsts_max_age option as well in order to become + // effective. Available from microversion 2.27. + HSTSPreload bool `json:"hsts_preload,omitempty"` + + // List of ciphers in OpenSSL format (colon-separated). Available from + // microversion 2.15. + TLSCiphers string `json:"tls_ciphers,omitempty"` + // A list of TLS protocol versions. Available from microversion 2.17 TLSVersions []TLSVersion `json:"tls_versions,omitempty"` @@ -255,6 +295,46 @@ type UpdateOpts struct { // A list of IPv4, IPv6 or mix of both CIDRs AllowedCIDRs *[]string `json:"allowed_cidrs,omitempty"` + // A list of ALPN protocols. Available protocols: http/1.0, http/1.1, + // h2. Available from microversion 2.20. + ALPNProtocols *[]string `json:"alpn_protocols,omitempty"` + + // The TLS client authentication mode. One of the options NONE, + // OPTIONAL or MANDATORY. Available from microversion 2.8. + ClientAuthentication *string `json:"client_authentication,omitempty"` + + // The ref of the key manager service secret containing a PEM format + // client CA certificate bundle for TERMINATED_HTTPS listeners. + // Available from microversion 2.8. + ClientCATLSContainerRef *string `json:"client_ca_tls_container_ref,omitempty"` + + // The URI of the key manager service secret containing a PEM format CA + // revocation list file for TERMINATED_HTTPS listeners. Available from + // microversion 2.8. + ClientCRLContainerRef *string `json:"client_crl_container_ref,omitempty"` + + // Defines whether the includeSubDomains directive should be added to + // the Strict-Transport-Security HTTP response header. This requires + // setting the hsts_max_age option as well in order to become + // effective. Available from microversion 2.27. + HSTSIncludeSubdomains *bool `json:"hsts_include_subdomains,omitempty"` + + // The value of the max_age directive for the Strict-Transport-Security + // HTTP response header. Setting this enables HTTP Strict Transport + // Security (HSTS) for the TLS-terminated listener. Available from + // microversion 2.27. + HSTSMaxAge *int `json:"hsts_max_age,omitempty"` + + // Defines whether the preload directive should be added to the + // Strict-Transport-Security HTTP response header. This requires + // setting the hsts_max_age option as well in order to become + // effective. Available from microversion 2.27. + HSTSPreload *bool `json:"hsts_preload,omitempty"` + + // List of ciphers in OpenSSL format (colon-separated). Available from + // microversion 2.15. + TLSCiphers *string `json:"tls_ciphers,omitempty"` + // A list of TLS protocol versions. Available from microversion 2.17 TLSVersions *[]TLSVersion `json:"tls_versions,omitempty"` diff --git a/openstack/loadbalancer/v2/listeners/results.go b/openstack/loadbalancer/v2/listeners/results.go index 562a7618dd..0bd08f783a 100644 --- a/openstack/loadbalancer/v2/listeners/results.go +++ b/openstack/loadbalancer/v2/listeners/results.go @@ -114,6 +114,24 @@ type Listener struct { // New in version 2.8 ClientCRLContainerRef string `json:"client_crl_container_ref"` + // Defines whether the includeSubDomains directive should be added to + // the Strict-Transport-Security HTTP response header. This requires + // setting the hsts_max_age option as well in order to become + // effective. Available from microversion 2.27. + HSTSIncludeSubdomains bool `json:"hsts_include_subdomains"` + + // The value of the max_age directive for the Strict-Transport-Security + // HTTP response header. Setting this enables HTTP Strict Transport + // Security (HSTS) for the TLS-terminated listener. Available from + // microversion 2.27. + HSTSMaxAge int `json:"hsts_max_age"` + + // Defines whether the preload directive should be added to the + // Strict-Transport-Security HTTP response header. This requires + // setting the hsts_max_age option as well in order to become + // effective. Available from microversion 2.27. + HSTSPreload bool `json:"hsts_preload"` + // The operating status of the resource OperatingStatus string `json:"operating_status"` } diff --git a/openstack/loadbalancer/v2/pools/requests.go b/openstack/loadbalancer/v2/pools/requests.go index 452bfaddb9..60d1132eba 100644 --- a/openstack/loadbalancer/v2/pools/requests.go +++ b/openstack/loadbalancer/v2/pools/requests.go @@ -122,6 +122,37 @@ type CreateOpts struct { // Omit this field to prevent session persistence. Persistence *SessionPersistence `json:"session_persistence,omitempty"` + // A list of ALPN protocols. Available protocols: http/1.0, http/1.1, + // h2. Available from microversion 2.24. + ALPNProtocols []string `json:"alpn_protocols,omitempty"` + + // The reference of the key manager service secret containing a PEM + // format CA certificate bundle for tls_enabled pools. Available from + // microversion 2.8. + CATLSContainerRef string `json:"ca_tls_container_ref,omitempty"` + + // The reference of the key manager service secret containing a PEM + // format CA revocation list file for tls_enabled pools. Available from + // microversion 2.8. + CRLContainerRef string `json:"crl_container_ref,omitempty"` + + // When true connections to backend member servers will use TLS + // encryption. Default is false. Available from microversion 2.8. + TLSEnabled bool `json:"tls_enabled,omitempty"` + + // List of ciphers in OpenSSL format (colon-separated). Available from + // microversion 2.15. + TLSCiphers string `json:"tls_ciphers,omitempty"` + + // The reference to the key manager service secret containing a PKCS12 + // format certificate/key bundle for tls_enabled pools for TLS client + // authentication to the member servers. Available from microversion 2.8. + TLSContainerRef string `json:"tls_container_ref,omitempty"` + + // A list of TLS protocol versions. Available versions: SSLv3, TLSv1, + // TLSv1.1, TLSv1.2, TLSv1.3. Available from microversion 2.17. + TLSVersions []string `json:"tls_versions,omitempty"` + // The administrative state of the Pool. A valid value is true (UP) // or false (DOWN). AdminStateUp *bool `json:"admin_state_up,omitempty"` @@ -196,6 +227,37 @@ type UpdateOpts struct { // Persistence is the session persistence of the pool. Persistence *SessionPersistence `json:"session_persistence,omitempty"` + // A list of ALPN protocols. Available protocols: http/1.0, http/1.1, + // h2. Available from microversion 2.24. + ALPNProtocols *[]string `json:"alpn_protocols,omitempty"` + + // The reference of the key manager service secret containing a PEM + // format CA certificate bundle for tls_enabled pools. Available from + // microversion 2.8. + CATLSContainerRef *string `json:"ca_tls_container_ref,omitempty"` + + // The reference of the key manager service secret containing a PEM + // format CA revocation list file for tls_enabled pools. Available from + // microversion 2.8. + CRLContainerRef *string `json:"crl_container_ref,omitempty"` + + // When true connections to backend member servers will use TLS + // encryption. Default is false. Available from microversion 2.8. + TLSEnabled *bool `json:"tls_enabled,omitempty"` + + // List of ciphers in OpenSSL format (colon-separated). Available from + // microversion 2.15. + TLSCiphers *string `json:"tls_ciphers,omitempty"` + + // The reference to the key manager service secret containing a PKCS12 + // format certificate/key bundle for tls_enabled pools for TLS client + // authentication to the member servers. Available from microversion 2.8. + TLSContainerRef *string `json:"tls_container_ref,omitempty"` + + // A list of TLS protocol versions. Available versions: SSLv3, TLSv1, + // TLSv1.1, TLSv1.2, TLSv1.3. Available from microversion 2.17. + TLSVersions *[]string `json:"tls_versions,omitempty"` + // Tags is a set of resource tags. New in version 2.5 Tags *[]string `json:"tags,omitempty"` } diff --git a/openstack/loadbalancer/v2/pools/results.go b/openstack/loadbalancer/v2/pools/results.go index 1f27752e0d..bff336ea4a 100644 --- a/openstack/loadbalancer/v2/pools/results.go +++ b/openstack/loadbalancer/v2/pools/results.go @@ -95,6 +95,37 @@ type Pool struct { // same Pool member or not. Persistence SessionPersistence `json:"session_persistence"` + // A list of ALPN protocols. Available protocols: http/1.0, http/1.1, + // h2. Available from microversion 2.24. + ALPNProtocols []string `json:"alpn_protocols"` + + // The reference of the key manager service secret containing a PEM + // format CA certificate bundle for tls_enabled pools. Available from + // microversion 2.8. + CATLSContainerRef string `json:"ca_tls_container_ref"` + + // The reference of the key manager service secret containing a PEM + // format CA revocation list file for tls_enabled pools. Available from + // microversion 2.8. + CRLContainerRef string `json:"crl_container_ref"` + + // When true connections to backend member servers will use TLS + // encryption. Default is false. Available from microversion 2.8. + TLSEnabled bool `json:"tls_enabled"` + + // List of ciphers in OpenSSL format (colon-separated). Available from + // microversion 2.15. + TLSCiphers string `json:"tls_ciphers"` + + // The reference to the key manager service secret containing a PKCS12 + // format certificate/key bundle for tls_enabled pools for TLS client + // authentication to the member servers. Available from microversion 2.8. + TLSContainerRef string `json:"tls_container_ref"` + + // A list of TLS protocol versions. Available versions: SSLv3, TLSv1, + // TLSv1.1, TLSv1.2, TLSv1.3. Available from microversion 2.17. + TLSVersions []string `json:"tls_versions"` + // The load balancer provider. Provider string `json:"provider"` From b31521943016f60db5d22c5d77731b5d0878a361 Mon Sep 17 00:00:00 2001 From: kayrus Date: Tue, 24 Sep 2024 01:54:02 +0200 Subject: [PATCH 032/353] Allow unsetting certain parameters --- .../loadbalancer/v2/listeners/requests.go | 28 +++++++++++-- openstack/loadbalancer/v2/pools/requests.go | 39 +++++++++++++++++-- 2 files changed, 61 insertions(+), 6 deletions(-) diff --git a/openstack/loadbalancer/v2/listeners/requests.go b/openstack/loadbalancer/v2/listeners/requests.go index 5c66db23be..3216fbddd0 100644 --- a/openstack/loadbalancer/v2/listeners/requests.go +++ b/openstack/loadbalancer/v2/listeners/requests.go @@ -37,6 +37,15 @@ const ( TLSVersionTLSv1_3 TLSVersion = "TLSv1.3" ) +// ClientAuthentication represents the TLS client authentication mode. +type ClientAuthentication string + +const ( + ClientAuthenticationNone ClientAuthentication = "NONE" + ClientAuthenticationOptional ClientAuthentication = "OPTIONAL" + ClientAuthenticationMandatory ClientAuthentication = "MANDATORY" +) + // ListOptsBuilder allows extensions to add additional parameters to the // List request. type ListOptsBuilder interface { @@ -176,7 +185,7 @@ type CreateOpts struct { // The TLS client authentication mode. One of the options NONE, // OPTIONAL or MANDATORY. Available from microversion 2.8. - ClientAuthentication string `json:"client_authentication,omitempty"` + ClientAuthentication ClientAuthentication `json:"client_authentication,omitempty"` // The ref of the key manager service secret containing a PEM format // client CA certificate bundle for TERMINATED_HTTPS listeners. @@ -301,7 +310,7 @@ type UpdateOpts struct { // The TLS client authentication mode. One of the options NONE, // OPTIONAL or MANDATORY. Available from microversion 2.8. - ClientAuthentication *string `json:"client_authentication,omitempty"` + ClientAuthentication *ClientAuthentication `json:"client_authentication,omitempty"` // The ref of the key manager service secret containing a PEM format // client CA certificate bundle for TERMINATED_HTTPS listeners. @@ -349,10 +358,23 @@ func (opts UpdateOpts) ToListenerUpdateMap() (map[string]any, error) { return nil, err } - if m := b["listener"].(map[string]any); m["default_pool_id"] == "" { + m := b["listener"].(map[string]any) + + // allow to unset default_pool_id on empty string + if m["default_pool_id"] == "" { m["default_pool_id"] = nil } + // allow to unset alpn_protocols on empty slice + if opts.ALPNProtocols != nil && len(*opts.ALPNProtocols) == 0 { + m["alpn_protocols"] = nil + } + + // allow to unset tls_versions on empty slice + if opts.TLSVersions != nil && len(*opts.TLSVersions) == 0 { + m["tls_versions"] = nil + } + return b, nil } diff --git a/openstack/loadbalancer/v2/pools/requests.go b/openstack/loadbalancer/v2/pools/requests.go index 60d1132eba..3443686370 100644 --- a/openstack/loadbalancer/v2/pools/requests.go +++ b/openstack/loadbalancer/v2/pools/requests.go @@ -8,6 +8,17 @@ import ( "github.com/gophercloud/gophercloud/v2/pagination" ) +// Type TLSVersion represents a tls version +type TLSVersion string + +const ( + TLSVersionSSLv3 TLSVersion = "SSLv3" + TLSVersionTLSv1 TLSVersion = "TLSv1" + TLSVersionTLSv1_1 TLSVersion = "TLSv1.1" + TLSVersionTLSv1_2 TLSVersion = "TLSv1.2" + TLSVersionTLSv1_3 TLSVersion = "TLSv1.3" +) + // ListOptsBuilder allows extensions to add additional parameters to the // List request. type ListOptsBuilder interface { @@ -151,7 +162,7 @@ type CreateOpts struct { // A list of TLS protocol versions. Available versions: SSLv3, TLSv1, // TLSv1.1, TLSv1.2, TLSv1.3. Available from microversion 2.17. - TLSVersions []string `json:"tls_versions,omitempty"` + TLSVersions []TLSVersion `json:"tls_versions,omitempty"` // The administrative state of the Pool. A valid value is true (UP) // or false (DOWN). @@ -256,7 +267,7 @@ type UpdateOpts struct { // A list of TLS protocol versions. Available versions: SSLv3, TLSv1, // TLSv1.1, TLSv1.2, TLSv1.3. Available from microversion 2.17. - TLSVersions *[]string `json:"tls_versions,omitempty"` + TLSVersions *[]TLSVersion `json:"tls_versions,omitempty"` // Tags is a set of resource tags. New in version 2.5 Tags *[]string `json:"tags,omitempty"` @@ -264,7 +275,29 @@ type UpdateOpts struct { // ToPoolUpdateMap builds a request body from UpdateOpts. func (opts UpdateOpts) ToPoolUpdateMap() (map[string]any, error) { - return gophercloud.BuildRequestBody(opts, "pool") + b, err := gophercloud.BuildRequestBody(opts, "pool") + if err != nil { + return nil, err + } + + m := b["pool"].(map[string]any) + + // allow to unset session_persistence on empty SessionPersistence struct + if opts.Persistence != nil && *opts.Persistence == (SessionPersistence{}) { + m["session_persistence"] = nil + } + + // allow to unset alpn_protocols on empty slice + if opts.ALPNProtocols != nil && len(*opts.ALPNProtocols) == 0 { + m["alpn_protocols"] = nil + } + + // allow to unset tls_versions on empty slice + if opts.TLSVersions != nil && len(*opts.TLSVersions) == 0 { + m["tls_versions"] = nil + } + + return b, nil } // Update allows pools to be updated. From 113e3c4aaae04f064e1fd71aafb10d1d40abf11d Mon Sep 17 00:00:00 2001 From: kayrus Date: Thu, 26 Sep 2024 22:09:13 +0200 Subject: [PATCH 033/353] [core]: handle empty response body --- openstack/networking/v2/extensions/bgp/speakers/requests.go | 4 ++-- .../v2/extensions/bgp/speakers/testing/requests_test.go | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/openstack/networking/v2/extensions/bgp/speakers/requests.go b/openstack/networking/v2/extensions/bgp/speakers/requests.go index 4c352c2cc3..b6dd26d909 100644 --- a/openstack/networking/v2/extensions/bgp/speakers/requests.go +++ b/openstack/networking/v2/extensions/bgp/speakers/requests.go @@ -142,7 +142,7 @@ func RemoveBGPPeer(ctx context.Context, c *gophercloud.ServiceClient, bgpSpeaker r.Err = err return } - resp, err := c.Put(ctx, removeBGPPeerURL(c, bgpSpeakerID), b, &r.Body, &gophercloud.RequestOpts{ + resp, err := c.Put(ctx, removeBGPPeerURL(c, bgpSpeakerID), b, nil, &gophercloud.RequestOpts{ OkCodes: []int{200}, }) _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) @@ -207,7 +207,7 @@ func RemoveGatewayNetwork(ctx context.Context, c *gophercloud.ServiceClient, bgp r.Err = err return } - resp, err := c.Put(ctx, removeGatewayNetworkURL(c, bgpSpeakerID), b, &r.Body, &gophercloud.RequestOpts{ + resp, err := c.Put(ctx, removeGatewayNetworkURL(c, bgpSpeakerID), b, nil, &gophercloud.RequestOpts{ OkCodes: []int{200}, }) _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) diff --git a/openstack/networking/v2/extensions/bgp/speakers/testing/requests_test.go b/openstack/networking/v2/extensions/bgp/speakers/testing/requests_test.go index 9e8df52b0c..d163086a8a 100644 --- a/openstack/networking/v2/extensions/bgp/speakers/testing/requests_test.go +++ b/openstack/networking/v2/extensions/bgp/speakers/testing/requests_test.go @@ -3,7 +3,6 @@ package testing import ( "context" "fmt" - "io" "net/http" "testing" @@ -195,7 +194,7 @@ func TestRemoveBGPPeer(t *testing.T) { opts := speakers.RemoveBGPPeerOpts{BGPPeerID: bgpPeerID} err := speakers.RemoveBGPPeer(context.TODO(), fake.ServiceClient(), bgpSpeakerID, opts).ExtractErr() - th.AssertEquals(t, err, io.EOF) + th.AssertNoErr(t, err) } func TestGetAdvertisedRoutes(t *testing.T) { @@ -279,5 +278,5 @@ func TestRemoveGatewayNetwork(t *testing.T) { opts := speakers.RemoveGatewayNetworkOpts{NetworkID: networkID} err := speakers.RemoveGatewayNetwork(context.TODO(), fake.ServiceClient(), bgpSpeakerID, opts).ExtractErr() - th.AssertEquals(t, err, io.EOF) + th.AssertNoErr(t, err) } From 02cff14569bfdaa94ff8da80f87f715133a0958e Mon Sep 17 00:00:00 2001 From: kayrus Date: Thu, 26 Sep 2024 23:52:53 +0200 Subject: [PATCH 034/353] [core]: proper ParseResponse handling --- .../v2/extensions/fwaas_v2/groups/requests.go | 18 ++++++++++++------ .../extensions/fwaas_v2/policies/requests.go | 18 ++++++++++++------ 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/openstack/networking/v2/extensions/fwaas_v2/groups/requests.go b/openstack/networking/v2/extensions/fwaas_v2/groups/requests.go index 9b12c62842..856e21548f 100644 --- a/openstack/networking/v2/extensions/fwaas_v2/groups/requests.go +++ b/openstack/networking/v2/extensions/fwaas_v2/groups/requests.go @@ -69,7 +69,8 @@ func List(c *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { // Get retrieves a particular firewall group based on its unique ID. func Get(ctx context.Context, c *gophercloud.ServiceClient, id string) (r GetResult) { - _, r.Err = c.Get(ctx, resourceURL(c, id), &r.Body, nil) + resp, err := c.Get(ctx, resourceURL(c, id), &r.Body, nil) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) return } @@ -107,7 +108,8 @@ func Create(ctx context.Context, c *gophercloud.ServiceClient, opts CreateOptsBu r.Err = err return } - _, r.Err = c.Post(ctx, rootURL(c), b, &r.Body, nil) + resp, err := c.Post(ctx, rootURL(c), b, &r.Body, nil) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) return } @@ -142,9 +144,10 @@ func Update(ctx context.Context, c *gophercloud.ServiceClient, id string, opts U r.Err = err return } - _, r.Err = c.Put(ctx, resourceURL(c, id), b, &r.Body, &gophercloud.RequestOpts{ + resp, err := c.Put(ctx, resourceURL(c, id), b, &r.Body, &gophercloud.RequestOpts{ OkCodes: []int{200}, }) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) return } @@ -165,9 +168,10 @@ func RemoveIngressPolicy(ctx context.Context, c *gophercloud.ServiceClient, id s r.Err = err return } - _, r.Err = c.Put(ctx, resourceURL(c, id), b, &r.Body, &gophercloud.RequestOpts{ + resp, err := c.Put(ctx, resourceURL(c, id), b, &r.Body, &gophercloud.RequestOpts{ OkCodes: []int{200}, }) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) return } @@ -181,14 +185,16 @@ func RemoveEgressPolicy(ctx context.Context, c *gophercloud.ServiceClient, id st r.Err = err return } - _, r.Err = c.Put(ctx, resourceURL(c, id), b, &r.Body, &gophercloud.RequestOpts{ + resp, err := c.Put(ctx, resourceURL(c, id), b, &r.Body, &gophercloud.RequestOpts{ OkCodes: []int{200}, }) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) return } // Delete will permanently delete a particular firewall group based on its unique ID. func Delete(ctx context.Context, c *gophercloud.ServiceClient, id string) (r DeleteResult) { - _, r.Err = c.Delete(ctx, resourceURL(c, id), nil) + resp, err := c.Delete(ctx, resourceURL(c, id), nil) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) return } diff --git a/openstack/networking/v2/extensions/fwaas_v2/policies/requests.go b/openstack/networking/v2/extensions/fwaas_v2/policies/requests.go index 57d25a6726..476360dbb3 100644 --- a/openstack/networking/v2/extensions/fwaas_v2/policies/requests.go +++ b/openstack/networking/v2/extensions/fwaas_v2/policies/requests.go @@ -91,13 +91,15 @@ func Create(ctx context.Context, c *gophercloud.ServiceClient, opts CreateOptsBu r.Err = err return } - _, r.Err = c.Post(ctx, rootURL(c), b, &r.Body, nil) + resp, err := c.Post(ctx, rootURL(c), b, &r.Body, nil) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) return } // Get retrieves a particular firewall policy based on its unique ID. func Get(ctx context.Context, c *gophercloud.ServiceClient, id string) (r GetResult) { - _, r.Err = c.Get(ctx, resourceURL(c, id), &r.Body, nil) + resp, err := c.Get(ctx, resourceURL(c, id), &r.Body, nil) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) return } @@ -130,15 +132,17 @@ func Update(ctx context.Context, c *gophercloud.ServiceClient, id string, opts U r.Err = err return } - _, r.Err = c.Put(ctx, resourceURL(c, id), b, &r.Body, &gophercloud.RequestOpts{ + resp, err := c.Put(ctx, resourceURL(c, id), b, &r.Body, &gophercloud.RequestOpts{ OkCodes: []int{200}, }) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) return } // Delete will permanently delete a particular firewall policy based on its unique ID. func Delete(ctx context.Context, c *gophercloud.ServiceClient, id string) (r DeleteResult) { - _, r.Err = c.Delete(ctx, resourceURL(c, id), nil) + resp, err := c.Delete(ctx, resourceURL(c, id), nil) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) return } @@ -162,16 +166,18 @@ func InsertRule(ctx context.Context, c *gophercloud.ServiceClient, id string, op r.Err = err return } - _, r.Err = c.Put(ctx, insertURL(c, id), b, &r.Body, &gophercloud.RequestOpts{ + resp, err := c.Put(ctx, insertURL(c, id), b, &r.Body, &gophercloud.RequestOpts{ OkCodes: []int{200}, }) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) return } func RemoveRule(ctx context.Context, c *gophercloud.ServiceClient, id, ruleID string) (r RemoveRuleResult) { b := map[string]any{"firewall_rule_id": ruleID} - _, r.Err = c.Put(ctx, removeURL(c, id), b, &r.Body, &gophercloud.RequestOpts{ + resp, err := c.Put(ctx, removeURL(c, id), b, &r.Body, &gophercloud.RequestOpts{ OkCodes: []int{200}, }) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) return } From a253e3965d81dddf5003badac613f0710dc39c6b Mon Sep 17 00:00:00 2001 From: Pierre Prinetti Date: Fri, 4 Oct 2024 12:09:02 +0200 Subject: [PATCH 035/353] compute: Fix expected and actual test results Our test convenience function `AssertEquals` accept the expected value first, then the actual value. Many tests in Compute were using it the other way around, thus potentially returning confusing error messages. --- .../compute/v2/attachinterfaces_test.go | 2 +- .../compute/v2/availabilityzones_test.go | 4 +- .../compute/v2/bootfromvolume_test.go | 20 ++--- .../openstack/compute/v2/compute.go | 84 +++++++++---------- .../openstack/compute/v2/extension_test.go | 4 +- .../openstack/compute/v2/flavors_test.go | 34 ++++---- .../compute/v2/instance_actions_test.go | 6 +- .../openstack/compute/v2/keypairs_test.go | 6 +- .../openstack/compute/v2/limits_test.go | 4 +- .../openstack/compute/v2/quotaset_test.go | 2 +- .../openstack/compute/v2/secgroup_test.go | 12 +-- .../openstack/compute/v2/servergroup_test.go | 4 +- .../openstack/compute/v2/servers_test.go | 40 ++++----- .../openstack/compute/v2/services_test.go | 6 +- .../openstack/compute/v2/volumeattach_test.go | 2 +- 15 files changed, 115 insertions(+), 115 deletions(-) diff --git a/internal/acceptance/openstack/compute/v2/attachinterfaces_test.go b/internal/acceptance/openstack/compute/v2/attachinterfaces_test.go index cf9b1a973e..95ad0ebf2d 100644 --- a/internal/acceptance/openstack/compute/v2/attachinterfaces_test.go +++ b/internal/acceptance/openstack/compute/v2/attachinterfaces_test.go @@ -48,5 +48,5 @@ func TestAttachDetachInterface(t *testing.T) { } } - th.AssertEquals(t, found, true) + th.AssertEquals(t, true, found) } diff --git a/internal/acceptance/openstack/compute/v2/availabilityzones_test.go b/internal/acceptance/openstack/compute/v2/availabilityzones_test.go index b3af24b0a1..3b37db49b0 100644 --- a/internal/acceptance/openstack/compute/v2/availabilityzones_test.go +++ b/internal/acceptance/openstack/compute/v2/availabilityzones_test.go @@ -31,7 +31,7 @@ func TestAvailabilityZonesList(t *testing.T) { } } - th.AssertEquals(t, found, true) + th.AssertEquals(t, true, found) } func TestAvailabilityZonesListDetail(t *testing.T) { @@ -55,5 +55,5 @@ func TestAvailabilityZonesListDetail(t *testing.T) { } } - th.AssertEquals(t, found, true) + th.AssertEquals(t, true, found) } diff --git a/internal/acceptance/openstack/compute/v2/bootfromvolume_test.go b/internal/acceptance/openstack/compute/v2/bootfromvolume_test.go index 5bf7f75e13..4b7082ab3a 100644 --- a/internal/acceptance/openstack/compute/v2/bootfromvolume_test.go +++ b/internal/acceptance/openstack/compute/v2/bootfromvolume_test.go @@ -39,7 +39,7 @@ func TestBootFromImage(t *testing.T) { tools.PrintResource(t, server) - th.AssertEquals(t, server.Image["id"], choices.ImageID) + th.AssertEquals(t, choices.ImageID, server.Image["id"]) } func TestBootFromNewVolume(t *testing.T) { @@ -80,13 +80,13 @@ func TestBootFromNewVolume(t *testing.T) { tools.PrintResource(t, server) tools.PrintResource(t, attachments) attachmentTag := *attachments[0].Tag - th.AssertEquals(t, attachmentTag, tagName) + th.AssertEquals(t, tagName, attachmentTag) if server.Image != nil { t.Fatalf("server image should be nil") } - th.AssertEquals(t, len(attachments), 1) + th.AssertEquals(t, 1, len(attachments)) // TODO: volumes_attached extension } @@ -131,8 +131,8 @@ func TestBootFromExistingVolume(t *testing.T) { t.Fatalf("server image should be nil") } - th.AssertEquals(t, len(attachments), 1) - th.AssertEquals(t, attachments[0].VolumeID, volume.ID) + th.AssertEquals(t, 1, len(attachments)) + th.AssertEquals(t, volume.ID, attachments[0].VolumeID) // TODO: volumes_attached extension } @@ -218,8 +218,8 @@ func TestAttachNewVolume(t *testing.T) { tools.PrintResource(t, server) tools.PrintResource(t, attachments) - th.AssertEquals(t, server.Image["id"], choices.ImageID) - th.AssertEquals(t, len(attachments), 1) + th.AssertEquals(t, choices.ImageID, server.Image["id"]) + th.AssertEquals(t, 1, len(attachments)) // TODO: volumes_attached extension } @@ -269,9 +269,9 @@ func TestAttachExistingVolume(t *testing.T) { tools.PrintResource(t, server) tools.PrintResource(t, attachments) - th.AssertEquals(t, server.Image["id"], choices.ImageID) - th.AssertEquals(t, len(attachments), 1) - th.AssertEquals(t, attachments[0].VolumeID, volume.ID) + th.AssertEquals(t, choices.ImageID, server.Image["id"]) + th.AssertEquals(t, 1, len(attachments)) + th.AssertEquals(t, volume.ID, attachments[0].VolumeID) // TODO: volumes_attached extension } diff --git a/internal/acceptance/openstack/compute/v2/compute.go b/internal/acceptance/openstack/compute/v2/compute.go index 513344082f..4a5ec655a2 100644 --- a/internal/acceptance/openstack/compute/v2/compute.go +++ b/internal/acceptance/openstack/compute/v2/compute.go @@ -84,8 +84,8 @@ func CreateAggregate(t *testing.T, client *gophercloud.ServiceClient) (*aggregat return nil, err } - th.AssertEquals(t, aggregate.Name, aggregateName) - th.AssertEquals(t, aggregate.AvailabilityZone, availabilityZone) + th.AssertEquals(t, aggregateName, aggregate.Name) + th.AssertEquals(t, availabilityZone, aggregate.AvailabilityZone) return aggregate, nil } @@ -137,7 +137,7 @@ func CreateBootableVolumeServer(t *testing.T, client *gophercloud.ServiceClient, return nil, err } - th.AssertEquals(t, newServer.Name, name) + th.AssertEquals(t, name, newServer.Name) return newServer, nil } @@ -169,12 +169,12 @@ func CreateFlavor(t *testing.T, client *gophercloud.ServiceClient) (*flavors.Fla t.Logf("Successfully created flavor %s", flavor.ID) - th.AssertEquals(t, flavor.Name, flavorName) - th.AssertEquals(t, flavor.RAM, 1) - th.AssertEquals(t, flavor.Disk, 1) - th.AssertEquals(t, flavor.VCPUs, 1) - th.AssertEquals(t, flavor.IsPublic, true) - th.AssertEquals(t, flavor.Description, flavorDescription) + th.AssertEquals(t, flavorName, flavor.Name) + th.AssertEquals(t, 1, flavor.RAM) + th.AssertEquals(t, 1, flavor.Disk) + th.AssertEquals(t, 1, flavor.VCPUs) + th.AssertEquals(t, true, flavor.IsPublic) + th.AssertEquals(t, flavorDescription, flavor.Description) return flavor, nil } @@ -213,7 +213,7 @@ func CreateKeyPair(t *testing.T, client *gophercloud.ServiceClient) (*keypairs.K t.Logf("Created keypair: %s", keyPairName) - th.AssertEquals(t, keyPair.Name, keyPairName) + th.AssertEquals(t, keyPairName, keyPair.Name) return keyPair, nil } @@ -263,9 +263,9 @@ func CreateMultiEphemeralServer(t *testing.T, client *gophercloud.ServiceClient, if err != nil { return server, err } - th.AssertEquals(t, newServer.Name, name) - th.AssertEquals(t, newServer.Flavor["id"], choices.FlavorID) - th.AssertEquals(t, newServer.Image["id"], choices.ImageID) + th.AssertEquals(t, name, newServer.Name) + th.AssertEquals(t, choices.FlavorID, newServer.Flavor["id"]) + th.AssertEquals(t, choices.ImageID, newServer.Image["id"]) return newServer, nil } @@ -292,11 +292,11 @@ func CreatePrivateFlavor(t *testing.T, client *gophercloud.ServiceClient) (*flav t.Logf("Successfully created flavor %s", flavor.ID) - th.AssertEquals(t, flavor.Name, flavorName) - th.AssertEquals(t, flavor.RAM, 1) - th.AssertEquals(t, flavor.Disk, 1) - th.AssertEquals(t, flavor.VCPUs, 1) - th.AssertEquals(t, flavor.IsPublic, false) + th.AssertEquals(t, flavorName, flavor.Name) + th.AssertEquals(t, 1, flavor.RAM) + th.AssertEquals(t, 1, flavor.Disk) + th.AssertEquals(t, 1, flavor.VCPUs) + th.AssertEquals(t, false, flavor.IsPublic) return flavor, nil } @@ -318,7 +318,7 @@ func CreateSecurityGroup(t *testing.T, client *gophercloud.ServiceClient) (*secg t.Logf("Created security group: %s", securityGroup.ID) - th.AssertEquals(t, securityGroup.Name, name) + th.AssertEquals(t, name, securityGroup.Name) return securityGroup, nil } @@ -344,9 +344,9 @@ func CreateSecurityGroupRule(t *testing.T, client *gophercloud.ServiceClient, se t.Logf("Created security group rule: %s", rule.ID) - th.AssertEquals(t, rule.FromPort, fromPort) - th.AssertEquals(t, rule.ToPort, toPort) - th.AssertEquals(t, rule.ParentGroupID, securityGroupID) + th.AssertEquals(t, fromPort, rule.FromPort) + th.AssertEquals(t, toPort, rule.ToPort) + th.AssertEquals(t, securityGroupID, rule.ParentGroupID) return rule, nil } @@ -403,9 +403,9 @@ func CreateServer(t *testing.T, client *gophercloud.ServiceClient) (*servers.Ser return nil, err } - th.AssertEquals(t, newServer.Name, name) - th.AssertEquals(t, newServer.Flavor["id"], choices.FlavorID) - th.AssertEquals(t, newServer.Image["id"], choices.ImageID) + th.AssertEquals(t, name, newServer.Name) + th.AssertEquals(t, choices.FlavorID, newServer.Flavor["id"]) + th.AssertEquals(t, choices.ImageID, newServer.Image["id"]) return newServer, nil } @@ -457,8 +457,8 @@ func CreateMicroversionServer(t *testing.T, client *gophercloud.ServiceClient) ( return nil, err } - th.AssertEquals(t, newServer.Name, name) - th.AssertEquals(t, newServer.Image["id"], choices.ImageID) + th.AssertEquals(t, name, newServer.Name) + th.AssertEquals(t, choices.ImageID, newServer.Image["id"]) return newServer, nil } @@ -560,8 +560,8 @@ func CreateServerWithTags(t *testing.T, client *gophercloud.ServiceClient, netwo newServer, err := res.Extract() th.AssertNoErr(t, err) - th.AssertEquals(t, newServer.Name, name) - th.AssertDeepEquals(t, *newServer.Tags, []string{"tag1", "tag2"}) + th.AssertEquals(t, name, newServer.Name) + th.AssertDeepEquals(t, []string{"tag1", "tag2"}, *newServer.Tags) return newServer, nil } @@ -584,7 +584,7 @@ func CreateServerGroup(t *testing.T, client *gophercloud.ServiceClient, policy s t.Logf("Successfully created server group %s", name) - th.AssertEquals(t, sg.Name, name) + th.AssertEquals(t, name, sg.Name) return sg, nil } @@ -612,7 +612,7 @@ func CreateServerGroupMicroversion(t *testing.T, client *gophercloud.ServiceClie t.Logf("Successfully created server group %s", name) - th.AssertEquals(t, sg.Name, name) + th.AssertEquals(t, name, sg.Name) return sg, nil } @@ -662,9 +662,9 @@ func CreateServerInServerGroup(t *testing.T, client *gophercloud.ServiceClient, return nil, err } - th.AssertEquals(t, newServer.Name, name) - th.AssertEquals(t, newServer.Flavor["id"], choices.FlavorID) - th.AssertEquals(t, newServer.Image["id"], choices.ImageID) + th.AssertEquals(t, name, newServer.Name) + th.AssertEquals(t, choices.FlavorID, newServer.Flavor["id"]) + th.AssertEquals(t, choices.ImageID, newServer.Image["id"]) return newServer, nil } @@ -711,9 +711,9 @@ func CreateServerWithPublicKey(t *testing.T, client *gophercloud.ServiceClient, return nil, err } - th.AssertEquals(t, newServer.Name, name) - th.AssertEquals(t, newServer.Flavor["id"], choices.FlavorID) - th.AssertEquals(t, newServer.Image["id"], choices.ImageID) + th.AssertEquals(t, name, newServer.Name) + th.AssertEquals(t, choices.FlavorID, newServer.Flavor["id"]) + th.AssertEquals(t, choices.ImageID, newServer.Image["id"]) return newServer, nil } @@ -910,8 +910,8 @@ func ImportPublicKey(t *testing.T, client *gophercloud.ServiceClient, publicKey t.Logf("Created keypair: %s", keyPairName) - th.AssertEquals(t, keyPair.Name, keyPairName) - th.AssertEquals(t, keyPair.PublicKey, publicKey) + th.AssertEquals(t, keyPairName, keyPair.Name) + th.AssertEquals(t, publicKey, keyPair.PublicKey) return keyPair, nil } @@ -1070,9 +1070,9 @@ func CreateServerNoNetwork(t *testing.T, client *gophercloud.ServiceClient) (*se return nil, err } - th.AssertEquals(t, newServer.Name, name) - th.AssertEquals(t, newServer.Flavor["id"], choices.FlavorID) - th.AssertEquals(t, newServer.Image["id"], choices.ImageID) + th.AssertEquals(t, name, newServer.Name) + th.AssertEquals(t, choices.FlavorID, newServer.Flavor["id"]) + th.AssertEquals(t, choices.ImageID, newServer.Image["id"]) return newServer, nil } diff --git a/internal/acceptance/openstack/compute/v2/extension_test.go b/internal/acceptance/openstack/compute/v2/extension_test.go index 0339b251fb..8040282289 100644 --- a/internal/acceptance/openstack/compute/v2/extension_test.go +++ b/internal/acceptance/openstack/compute/v2/extension_test.go @@ -31,7 +31,7 @@ func TestExtensionsList(t *testing.T) { } } - th.AssertEquals(t, found, true) + th.AssertEquals(t, true, found) } func TestExtensionsGet(t *testing.T) { @@ -43,5 +43,5 @@ func TestExtensionsGet(t *testing.T) { tools.PrintResource(t, extension) - th.AssertEquals(t, extension.Name, "AdminActions") + th.AssertEquals(t, "AdminActions", extension.Name) } diff --git a/internal/acceptance/openstack/compute/v2/flavors_test.go b/internal/acceptance/openstack/compute/v2/flavors_test.go index cb6bd319a1..412149adfe 100644 --- a/internal/acceptance/openstack/compute/v2/flavors_test.go +++ b/internal/acceptance/openstack/compute/v2/flavors_test.go @@ -35,7 +35,7 @@ func TestFlavorsList(t *testing.T) { } } - th.AssertEquals(t, found, true) + th.AssertEquals(t, true, found) } func TestFlavorsAccessTypeList(t *testing.T) { @@ -74,7 +74,7 @@ func TestFlavorsGet(t *testing.T) { tools.PrintResource(t, flavor) - th.AssertEquals(t, flavor.ID, choices.FlavorID) + th.AssertEquals(t, choices.FlavorID, flavor.ID) } func TestFlavorExtraSpecsGet(t *testing.T) { @@ -103,9 +103,9 @@ func TestFlavorExtraSpecsGet(t *testing.T) { th.AssertNoErr(t, err) tools.PrintResource(t, flavor) - th.AssertEquals(t, len(flavor.ExtraSpecs), 2) - th.AssertEquals(t, flavor.ExtraSpecs["hw:cpu_policy"], "CPU-POLICY") - th.AssertEquals(t, flavor.ExtraSpecs["hw:cpu_thread_policy"], "CPU-THREAD-POLICY") + th.AssertEquals(t, 2, len(flavor.ExtraSpecs)) + th.AssertEquals(t, "CPU-POLICY", flavor.ExtraSpecs["hw:cpu_policy"]) + th.AssertEquals(t, "CPU-THREAD-POLICY", flavor.ExtraSpecs["hw:cpu_thread_policy"]) } func TestFlavorsCreateDelete(t *testing.T) { @@ -140,7 +140,7 @@ func TestFlavorsCreateUpdateDelete(t *testing.T) { flavor, err = flavors.Update(context.TODO(), client, flavor.ID, updateOpts).Extract() th.AssertNoErr(t, err) - th.AssertEquals(t, flavor.Description, newFlavorDescription) + th.AssertEquals(t, newFlavorDescription, flavor.Description) tools.PrintResource(t, flavor) } @@ -161,7 +161,7 @@ func TestFlavorsAccessesList(t *testing.T) { allAccesses, err := flavors.ExtractAccesses(allPages) th.AssertNoErr(t, err) - th.AssertEquals(t, len(allAccesses), 0) + th.AssertEquals(t, 0, len(allAccesses)) } func TestFlavorsAccessCRUD(t *testing.T) { @@ -188,9 +188,9 @@ func TestFlavorsAccessCRUD(t *testing.T) { accessList, err := flavors.AddAccess(context.TODO(), client, flavor.ID, addAccessOpts).Extract() th.AssertNoErr(t, err) - th.AssertEquals(t, len(accessList), 1) - th.AssertEquals(t, accessList[0].TenantID, project.ID) - th.AssertEquals(t, accessList[0].FlavorID, flavor.ID) + th.AssertEquals(t, 1, len(accessList)) + th.AssertEquals(t, project.ID, accessList[0].TenantID) + th.AssertEquals(t, flavor.ID, accessList[0].FlavorID) for _, access := range accessList { tools.PrintResource(t, access) @@ -203,7 +203,7 @@ func TestFlavorsAccessCRUD(t *testing.T) { accessList, err = flavors.RemoveAccess(context.TODO(), client, flavor.ID, removeAccessOpts).Extract() th.AssertNoErr(t, err) - th.AssertEquals(t, len(accessList), 0) + th.AssertEquals(t, 0, len(accessList)) } func TestFlavorsExtraSpecsCRUD(t *testing.T) { @@ -225,9 +225,9 @@ func TestFlavorsExtraSpecsCRUD(t *testing.T) { tools.PrintResource(t, createdExtraSpecs) - th.AssertEquals(t, len(createdExtraSpecs), 2) - th.AssertEquals(t, createdExtraSpecs["hw:cpu_policy"], "CPU-POLICY") - th.AssertEquals(t, createdExtraSpecs["hw:cpu_thread_policy"], "CPU-THREAD-POLICY") + th.AssertEquals(t, 2, len(createdExtraSpecs)) + th.AssertEquals(t, "CPU-POLICY", createdExtraSpecs["hw:cpu_policy"]) + th.AssertEquals(t, "CPU-THREAD-POLICY", createdExtraSpecs["hw:cpu_thread_policy"]) err = flavors.DeleteExtraSpec(context.TODO(), client, flavor.ID, "hw:cpu_policy").ExtractErr() th.AssertNoErr(t, err) @@ -245,13 +245,13 @@ func TestFlavorsExtraSpecsCRUD(t *testing.T) { tools.PrintResource(t, allExtraSpecs) - th.AssertEquals(t, len(allExtraSpecs), 1) - th.AssertEquals(t, allExtraSpecs["hw:cpu_thread_policy"], "CPU-THREAD-POLICY-BETTER") + th.AssertEquals(t, 1, len(allExtraSpecs)) + th.AssertEquals(t, "CPU-THREAD-POLICY-BETTER", allExtraSpecs["hw:cpu_thread_policy"]) spec, err := flavors.GetExtraSpec(context.TODO(), client, flavor.ID, "hw:cpu_thread_policy").Extract() th.AssertNoErr(t, err) tools.PrintResource(t, spec) - th.AssertEquals(t, spec["hw:cpu_thread_policy"], "CPU-THREAD-POLICY-BETTER") + th.AssertEquals(t, "CPU-THREAD-POLICY-BETTER", spec["hw:cpu_thread_policy"]) } diff --git a/internal/acceptance/openstack/compute/v2/instance_actions_test.go b/internal/acceptance/openstack/compute/v2/instance_actions_test.go index fb43cd72d6..01dd9fc72c 100644 --- a/internal/acceptance/openstack/compute/v2/instance_actions_test.go +++ b/internal/acceptance/openstack/compute/v2/instance_actions_test.go @@ -39,7 +39,7 @@ func TestInstanceActions(t *testing.T) { } } - th.AssertEquals(t, found, true) + th.AssertEquals(t, true, found) } func TestInstanceActionsMicroversions(t *testing.T) { @@ -88,7 +88,7 @@ func TestInstanceActionsMicroversions(t *testing.T) { } } - th.AssertEquals(t, found, true) + th.AssertEquals(t, true, found) listOpts = instanceactions.ListOpts{ Limit: 1, @@ -101,5 +101,5 @@ func TestInstanceActionsMicroversions(t *testing.T) { allActions, err = instanceactions.ExtractInstanceActions(allPages) th.AssertNoErr(t, err) - th.AssertEquals(t, len(allActions), 0) + th.AssertEquals(t, 0, len(allActions)) } diff --git a/internal/acceptance/openstack/compute/v2/keypairs_test.go b/internal/acceptance/openstack/compute/v2/keypairs_test.go index f3a0ac7e32..09d28f24f5 100644 --- a/internal/acceptance/openstack/compute/v2/keypairs_test.go +++ b/internal/acceptance/openstack/compute/v2/keypairs_test.go @@ -57,7 +57,7 @@ func TestKeyPairsCreateDelete(t *testing.T) { } } - th.AssertEquals(t, found, true) + th.AssertEquals(t, true, found) } func TestKeyPairsImportPublicKey(t *testing.T) { @@ -94,7 +94,7 @@ func TestKeyPairsServerCreateWithKey(t *testing.T) { server, err = servers.Get(context.TODO(), client, server.ID).Extract() th.AssertNoErr(t, err) - th.AssertEquals(t, server.KeyName, keyPair.Name) + th.AssertEquals(t, keyPair.Name, server.KeyName) } func TestKeyPairsCreateDeleteByID(t *testing.T) { @@ -146,7 +146,7 @@ func TestKeyPairsCreateDeleteByID(t *testing.T) { } } - th.AssertEquals(t, found, true) + th.AssertEquals(t, true, found) deleteOpts := keypairs.DeleteOpts{ UserID: user.ID, diff --git a/internal/acceptance/openstack/compute/v2/limits_test.go b/internal/acceptance/openstack/compute/v2/limits_test.go index 55ef2854f2..a4240ee5e0 100644 --- a/internal/acceptance/openstack/compute/v2/limits_test.go +++ b/internal/acceptance/openstack/compute/v2/limits_test.go @@ -22,7 +22,7 @@ func TestLimits(t *testing.T) { tools.PrintResource(t, limits) - th.AssertEquals(t, limits.Absolute.MaxPersonalitySize, 10240) + th.AssertEquals(t, 10240, limits.Absolute.MaxPersonalitySize) } func TestLimitsForTenant(t *testing.T) { @@ -47,5 +47,5 @@ func TestLimitsForTenant(t *testing.T) { tools.PrintResource(t, limits) - th.AssertEquals(t, limits.Absolute.MaxPersonalitySize, 10240) + th.AssertEquals(t, 10240, limits.Absolute.MaxPersonalitySize) } diff --git a/internal/acceptance/openstack/compute/v2/quotaset_test.go b/internal/acceptance/openstack/compute/v2/quotaset_test.go index 78ebbae2f0..53d94b538e 100644 --- a/internal/acceptance/openstack/compute/v2/quotaset_test.go +++ b/internal/acceptance/openstack/compute/v2/quotaset_test.go @@ -31,7 +31,7 @@ func TestQuotasetGet(t *testing.T) { tools.PrintResource(t, quotaSet) - th.AssertEquals(t, quotaSet.FixedIPs, -1) + th.AssertEquals(t, -1, quotaSet.FixedIPs) } func getProjectID(t *testing.T, client *gophercloud.ServiceClient) (string, error) { diff --git a/internal/acceptance/openstack/compute/v2/secgroup_test.go b/internal/acceptance/openstack/compute/v2/secgroup_test.go index 0809bb0dda..dd6b6dd85e 100644 --- a/internal/acceptance/openstack/compute/v2/secgroup_test.go +++ b/internal/acceptance/openstack/compute/v2/secgroup_test.go @@ -32,7 +32,7 @@ func TestSecGroupsList(t *testing.T) { } } - th.AssertEquals(t, found, true) + th.AssertEquals(t, true, found) } func TestSecGroupsCRUD(t *testing.T) { @@ -58,8 +58,8 @@ func TestSecGroupsCRUD(t *testing.T) { t.Logf("Updated %s's name to %s", updatedSecurityGroup.ID, updatedSecurityGroup.Name) - th.AssertEquals(t, updatedSecurityGroup.Name, newName) - th.AssertEquals(t, updatedSecurityGroup.Description, description) + th.AssertEquals(t, newName, updatedSecurityGroup.Name) + th.AssertEquals(t, description, updatedSecurityGroup.Description) } func TestSecGroupsRuleCreate(t *testing.T) { @@ -83,7 +83,7 @@ func TestSecGroupsRuleCreate(t *testing.T) { tools.PrintResource(t, newSecurityGroup) - th.AssertEquals(t, len(newSecurityGroup.Rules), 1) + th.AssertEquals(t, 1, len(newSecurityGroup.Rules)) } func TestSecGroupsAddGroupToServer(t *testing.T) { @@ -120,7 +120,7 @@ func TestSecGroupsAddGroupToServer(t *testing.T) { } } - th.AssertEquals(t, found, true) + th.AssertEquals(t, true, found) t.Logf("Removing group %s from server %s", securityGroup.ID, server.ID) err = secgroups.RemoveServer(context.TODO(), client, server.ID, securityGroup.Name).ExtractErr() @@ -139,5 +139,5 @@ func TestSecGroupsAddGroupToServer(t *testing.T) { } } - th.AssertEquals(t, found, false) + th.AssertEquals(t, false, found) } diff --git a/internal/acceptance/openstack/compute/v2/servergroup_test.go b/internal/acceptance/openstack/compute/v2/servergroup_test.go index 8d23ea8135..09d351a7b4 100644 --- a/internal/acceptance/openstack/compute/v2/servergroup_test.go +++ b/internal/acceptance/openstack/compute/v2/servergroup_test.go @@ -41,7 +41,7 @@ func TestServergroupsCreateDelete(t *testing.T) { } } - th.AssertEquals(t, found, true) + th.AssertEquals(t, true, found) } func TestServergroupsAffinityPolicy(t *testing.T) { @@ -100,5 +100,5 @@ func TestServergroupsMicroversionCreateDelete(t *testing.T) { } } - th.AssertEquals(t, found, true) + th.AssertEquals(t, true, found) } diff --git a/internal/acceptance/openstack/compute/v2/servers_test.go b/internal/acceptance/openstack/compute/v2/servers_test.go index 9aa8133de9..5934805ba2 100644 --- a/internal/acceptance/openstack/compute/v2/servers_test.go +++ b/internal/acceptance/openstack/compute/v2/servers_test.go @@ -45,7 +45,7 @@ func TestServersCreateDestroy(t *testing.T) { } } - th.AssertEquals(t, found, true) + th.AssertEquals(t, true, found) allAddressPages, err := servers.ListAddresses(client, server.ID).AllPages(context.TODO()) th.AssertNoErr(t, err) @@ -93,12 +93,12 @@ func TestServersWithExtensionsCreateDestroy(t *testing.T) { th.AssertNoErr(t, err) tools.PrintResource(t, created) - th.AssertEquals(t, created.AvailabilityZone, "nova") - th.AssertEquals(t, int(created.PowerState), servers.RUNNING) - th.AssertEquals(t, created.TaskState, "") - th.AssertEquals(t, created.VmState, "active") - th.AssertEquals(t, created.LaunchedAt.IsZero(), false) - th.AssertEquals(t, created.TerminatedAt.IsZero(), true) + th.AssertEquals(t, "nova", created.AvailabilityZone) + th.AssertEquals(t, servers.RUNNING, int(created.PowerState)) + th.AssertEquals(t, "", created.TaskState) + th.AssertEquals(t, "active", created.VmState) + th.AssertEquals(t, false, created.LaunchedAt.IsZero()) + th.AssertEquals(t, true, created.TerminatedAt.IsZero()) } func TestServersWithoutImageRef(t *testing.T) { @@ -139,7 +139,7 @@ func TestServersUpdate(t *testing.T) { updated, err := servers.Update(context.TODO(), client, server.ID, updateOpts).Extract() th.AssertNoErr(t, err) - th.AssertEquals(t, updated.ID, server.ID) + th.AssertEquals(t, server.ID, updated.ID) err = tools.WaitFor(func(ctx context.Context) (bool, error) { latest, err := servers.Get(ctx, client, updated.ID).Extract() @@ -307,7 +307,7 @@ func TestServersActionRebuild(t *testing.T) { rebuilt, err := servers.Rebuild(context.TODO(), client, server.ID, rebuildOpts).Extract() th.AssertNoErr(t, err) - th.AssertEquals(t, rebuilt.ID, server.ID) + th.AssertEquals(t, server.ID, rebuilt.ID) if err = WaitForComputeStatus(client, rebuilt, "REBUILD"); err != nil { t.Fatal(err) @@ -347,7 +347,7 @@ func TestServersActionResizeConfirm(t *testing.T) { server, err = servers.Get(context.TODO(), client, server.ID).Extract() th.AssertNoErr(t, err) - th.AssertEquals(t, server.Flavor["id"], choices.FlavorIDResize) + th.AssertEquals(t, choices.FlavorIDResize, server.Flavor["id"]) } func TestServersActionResizeRevert(t *testing.T) { @@ -379,7 +379,7 @@ func TestServersActionResizeRevert(t *testing.T) { server, err = servers.Get(context.TODO(), client, server.ID).Extract() th.AssertNoErr(t, err) - th.AssertEquals(t, server.Flavor["id"], choices.FlavorID) + th.AssertEquals(t, choices.FlavorID, server.Flavor["id"]) } func TestServersActionPause(t *testing.T) { @@ -447,7 +447,7 @@ func TestServersActionLock(t *testing.T) { t.Logf("Attempting to delete locked server %s", server.ID) err = servers.Delete(context.TODO(), client, server.ID).ExtractErr() - th.AssertEquals(t, err != nil, true) + th.AssertEquals(t, true, err != nil) t.Logf("Attempting to unlock server %s", server.ID) err = servers.Unlock(context.TODO(), client, server.ID).ExtractErr() @@ -565,13 +565,13 @@ func TestServersWithExtendedAttributesCreateDestroy(t *testing.T) { t.Logf("Server With Extended Attributes: %#v", created) - th.AssertEquals(t, *created.ReservationID != "", true) - th.AssertEquals(t, *created.LaunchIndex, 0) - th.AssertEquals(t, *created.RAMDiskID == "", true) - th.AssertEquals(t, *created.KernelID == "", true) - th.AssertEquals(t, *created.Hostname != "", true) - th.AssertEquals(t, *created.RootDeviceName != "", true) - th.AssertEquals(t, created.Userdata == nil, true) + th.AssertEquals(t, true, *created.ReservationID != "") + th.AssertEquals(t, 0, *created.LaunchIndex) + th.AssertEquals(t, true, *created.RAMDiskID == "") + th.AssertEquals(t, true, *created.KernelID == "") + th.AssertEquals(t, true, *created.Hostname != "") + th.AssertEquals(t, true, *created.RootDeviceName != "") + th.AssertEquals(t, true, created.Userdata == nil) } func TestServerNoNetworkCreateDestroy(t *testing.T) { @@ -604,7 +604,7 @@ func TestServerNoNetworkCreateDestroy(t *testing.T) { } } - th.AssertEquals(t, found, true) + th.AssertEquals(t, true, found) allAddressPages, err := servers.ListAddresses(client, server.ID).AllPages(context.TODO()) th.AssertNoErr(t, err) diff --git a/internal/acceptance/openstack/compute/v2/services_test.go b/internal/acceptance/openstack/compute/v2/services_test.go index 155255fb43..d913173810 100644 --- a/internal/acceptance/openstack/compute/v2/services_test.go +++ b/internal/acceptance/openstack/compute/v2/services_test.go @@ -33,7 +33,7 @@ func TestServicesList(t *testing.T) { } } - th.AssertEquals(t, found, true) + th.AssertEquals(t, true, found) } func TestServicesListWithOpts(t *testing.T) { @@ -55,14 +55,14 @@ func TestServicesListWithOpts(t *testing.T) { var found bool for _, service := range allServices { tools.PrintResource(t, service) - th.AssertEquals(t, service.Binary, "nova-scheduler") + th.AssertEquals(t, "nova-scheduler", service.Binary) if service.Binary == "nova-scheduler" { found = true } } - th.AssertEquals(t, found, true) + th.AssertEquals(t, true, found) } func TestServicesUpdate(t *testing.T) { diff --git a/internal/acceptance/openstack/compute/v2/volumeattach_test.go b/internal/acceptance/openstack/compute/v2/volumeattach_test.go index d4cce8d700..157f97c4c0 100644 --- a/internal/acceptance/openstack/compute/v2/volumeattach_test.go +++ b/internal/acceptance/openstack/compute/v2/volumeattach_test.go @@ -35,5 +35,5 @@ func TestVolumeAttachAttachment(t *testing.T) { tools.PrintResource(t, volumeAttachment) - th.AssertEquals(t, volumeAttachment.ServerID, server.ID) + th.AssertEquals(t, server.ID, volumeAttachment.ServerID) } From 7970f4435d9a8f607cba9b3e21ebba47534e6764 Mon Sep 17 00:00:00 2001 From: kayrus Date: Fri, 27 Sep 2024 16:30:28 +0200 Subject: [PATCH 036/353] [octavia] add an ability to filter flavors and flavorprofiles --- .../v2/flavorprofiles/requests.go | 4 ++ openstack/loadbalancer/v2/flavors/requests.go | 6 +++ .../v2/flavors/testing/requests_test.go | 47 +++++++++++++++++++ 3 files changed, 57 insertions(+) diff --git a/openstack/loadbalancer/v2/flavorprofiles/requests.go b/openstack/loadbalancer/v2/flavorprofiles/requests.go index 594b79739a..e51b9d99e6 100644 --- a/openstack/loadbalancer/v2/flavorprofiles/requests.go +++ b/openstack/loadbalancer/v2/flavorprofiles/requests.go @@ -15,6 +15,10 @@ type ListOptsBuilder interface { // ListOpts allows to manage the output of the request. type ListOpts struct { + // The name of the flavor profile to filter by. + Name string `q:"name"` + // The provider name of the flavor profile to filter by. + ProviderName string `q:"provider_name"` // The fields that you want the server to return Fields []string `q:"fields"` } diff --git a/openstack/loadbalancer/v2/flavors/requests.go b/openstack/loadbalancer/v2/flavors/requests.go index 6c4859116c..cba77c1d78 100644 --- a/openstack/loadbalancer/v2/flavors/requests.go +++ b/openstack/loadbalancer/v2/flavors/requests.go @@ -15,6 +15,12 @@ type ListOptsBuilder interface { // ListOpts allows to manage the output of the request. type ListOpts struct { + // The name of the flavor to filter by. + Name string `q:"name"` + // The flavor profile id to filter by. + FlavorProfileId string `q:"flavor_profile_id"` + // The enabled status of the flavor to filter by. + Enabled *bool `q:"enabled"` // The fields that you want the server to return Fields []string `q:"fields"` } diff --git a/openstack/loadbalancer/v2/flavors/testing/requests_test.go b/openstack/loadbalancer/v2/flavors/testing/requests_test.go index 14a74dbe45..fd668a2134 100644 --- a/openstack/loadbalancer/v2/flavors/testing/requests_test.go +++ b/openstack/loadbalancer/v2/flavors/testing/requests_test.go @@ -2,6 +2,8 @@ package testing import ( "context" + "fmt" + "net/http" "testing" "github.com/gophercloud/gophercloud/v2/openstack/loadbalancer/v2/flavors" @@ -9,6 +11,7 @@ import ( fake "github.com/gophercloud/gophercloud/v2/openstack/loadbalancer/v2/testhelper" th "github.com/gophercloud/gophercloud/v2/testhelper" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) func TestListFlavors(t *testing.T) { @@ -41,6 +44,50 @@ func TestListFlavors(t *testing.T) { } } +func TestListFlavorsEnabled(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + + func() { + testCases := []string{ + "true", + "false", + "", + } + + cases := 0 + th.Mux.HandleFunc("/v2.0/lbaas/flavors", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.Header().Add("Content-Type", "application/json") + if err := r.ParseForm(); err != nil { + t.Errorf("Failed to parse request form %v", err) + } + enabled := r.Form.Get("enabled") + if enabled != testCases[cases] { + t.Errorf("Expected enabled=%s got %q", testCases[cases], enabled) + } + cases++ + fmt.Fprintf(w, `{"flavorprofiles":[]}`) + }) + }() + + var nilBool *bool + enabled := true + filters := []*bool{ + &enabled, + new(bool), + nilBool, + } + for _, filter := range filters { + allPages, err := flavors.List(fake.ServiceClient(), flavors.ListOpts{Enabled: filter}).AllPages(context.TODO()) + th.AssertNoErr(t, err) + _, err = flavors.ExtractFlavors(allPages) + th.AssertNoErr(t, err) + } +} + func TestListAllFlavors(t *testing.T) { th.SetupHTTP() defer th.TeardownHTTP() From 260409965feacf42a5a0da581daa4fe832d243a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?p=C3=BDrus?= Date: Fri, 4 Oct 2024 09:05:35 +0200 Subject: [PATCH 037/353] Update openstack/loadbalancer/v2/flavors/requests.go Co-authored-by: Emilien Macchi --- openstack/loadbalancer/v2/flavors/requests.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openstack/loadbalancer/v2/flavors/requests.go b/openstack/loadbalancer/v2/flavors/requests.go index cba77c1d78..710a6edf5b 100644 --- a/openstack/loadbalancer/v2/flavors/requests.go +++ b/openstack/loadbalancer/v2/flavors/requests.go @@ -18,7 +18,7 @@ type ListOpts struct { // The name of the flavor to filter by. Name string `q:"name"` // The flavor profile id to filter by. - FlavorProfileId string `q:"flavor_profile_id"` + FlavorProfileID string `q:"flavor_profile_id"` // The enabled status of the flavor to filter by. Enabled *bool `q:"enabled"` // The fields that you want the server to return From 5bab9013acd2fbd7ee6c74a8d1539a1a24478e5b Mon Sep 17 00:00:00 2001 From: Samuel Allan Date: Wed, 10 Apr 2024 13:52:52 +0930 Subject: [PATCH 038/353] Handle nova api version > 2.87 for hypervisor fixes: #3026 --- openstack/compute/v2/hypervisors/results.go | 76 ++++++++++++--------- 1 file changed, 43 insertions(+), 33 deletions(-) diff --git a/openstack/compute/v2/hypervisors/results.go b/openstack/compute/v2/hypervisors/results.go index 2e8d244763..ee6046c6c0 100644 --- a/openstack/compute/v2/hypervisors/results.go +++ b/openstack/compute/v2/hypervisors/results.go @@ -158,27 +158,31 @@ func (r *Hypervisor) UnmarshalJSON(b []byte) error { *r = Hypervisor(s.tmp) - // Newer versions return the CPU info as the correct type. - // Older versions return the CPU info as a string and need to be - // unmarshalled by the json parser. - var tmpb []byte - - switch t := s.CPUInfo.(type) { - case string: - tmpb = []byte(t) - case map[string]any: - tmpb, err = json.Marshal(t) - if err != nil { - return err + // cpu_info doesn't exist after api version 2.87, + // see https://docs.openstack.org/api-ref/compute/#id288 + if s.CPUInfo != nil { + // api versions 2.28 to 2.87 return the CPU info as the correct type. + // api versions < 2.28 return the CPU info as a string and need to be + // unmarshalled by the json parser. + var tmpb []byte + + switch t := s.CPUInfo.(type) { + case string: + tmpb = []byte(t) + case map[string]any: + tmpb, err = json.Marshal(t) + if err != nil { + return err + } + default: + return fmt.Errorf("CPUInfo has unexpected type: %T", t) } - default: - return fmt.Errorf("CPUInfo has unexpected type: %T", t) - } - if len(tmpb) != 0 { - err = json.Unmarshal(tmpb, &r.CPUInfo) - if err != nil { - return err + if len(tmpb) != 0 { + err = json.Unmarshal(tmpb, &r.CPUInfo) + if err != nil { + return err + } } } @@ -193,22 +197,28 @@ func (r *Hypervisor) UnmarshalJSON(b []byte) error { return fmt.Errorf("Hypervisor version has unexpected type: %T", t) } - switch t := s.FreeDiskGB.(type) { - case int: - r.FreeDiskGB = t - case float64: - r.FreeDiskGB = int(t) - default: - return fmt.Errorf("Free disk GB has unexpected type: %T", t) + // free_disk_gb doesn't exist after api version 2.87 + if s.FreeDiskGB != nil { + switch t := s.FreeDiskGB.(type) { + case int: + r.FreeDiskGB = t + case float64: + r.FreeDiskGB = int(t) + default: + return fmt.Errorf("Free disk GB has unexpected type: %T", t) + } } - switch t := s.LocalGB.(type) { - case int: - r.LocalGB = t - case float64: - r.LocalGB = int(t) - default: - return fmt.Errorf("Local GB has unexpected type: %T", t) + // local_gb doesn't exist after api version 2.87 + if s.LocalGB != nil { + switch t := s.LocalGB.(type) { + case int: + r.LocalGB = t + case float64: + r.LocalGB = int(t) + default: + return fmt.Errorf("Local GB has unexpected type: %T", t) + } } // OpenStack Compute service returns ID in string representation since From 91f66ee37be7f7b2a0386881e8091d829640db66 Mon Sep 17 00:00:00 2001 From: Samuel Allan Date: Thu, 18 Jul 2024 07:35:37 +0930 Subject: [PATCH 039/353] Add unit test --- .../v2/hypervisors/testing/fixtures_test.go | 68 +++++++++++++++++++ .../v2/hypervisors/testing/requests_test.go | 12 ++++ 2 files changed, 80 insertions(+) diff --git a/openstack/compute/v2/hypervisors/testing/fixtures_test.go b/openstack/compute/v2/hypervisors/testing/fixtures_test.go index 1942c842e0..a969f1f825 100644 --- a/openstack/compute/v2/hypervisors/testing/fixtures_test.go +++ b/openstack/compute/v2/hypervisors/testing/fixtures_test.go @@ -346,6 +346,36 @@ const HypervisorGetEmptyCPUInfoBody = ` } ` +// HypervisorAfterV287ResponseBody represents a raw hypervisor GET result with +// missing cpu_info, free_disk_gb, local_gb as seen after v2.87 +const HypervisorAfterV287ResponseBody = ` +{ + "hypervisor":{ + "current_workload":0, + "status":"enabled", + "state":"up", + "disk_available_least":0, + "host_ip":"1.1.1.1", + "free_ram_mb":7680, + "hypervisor_hostname":"fake-mini", + "hypervisor_type":"fake", + "hypervisor_version":2002000, + "id":"c48f6247-abe4-4a24-824e-ea39e108874f", + "local_gb_used":0, + "memory_mb":8192, + "memory_mb_used":512, + "running_vms":0, + "service":{ + "host":"e6a37ee802d74863ab8b91ade8f12a67", + "id":"9c2566e7-7a54-4777-a1ae-c2662f0c407c", + "disabled_reason":null + }, + "vcpus":1, + "vcpus_used":0 + } +} +` + // HypervisorUptimeBody represents a raw hypervisor uptime request result with // Pike+ release. const HypervisorUptimeBody = ` @@ -492,6 +522,7 @@ var ( } HypervisorEmptyCPUInfo = hypervisors.Hypervisor{ + CPUInfo: hypervisors.CPUInfo{}, CurrentWorkload: 0, Status: "enabled", State: "up", @@ -517,6 +548,33 @@ var ( VCPUsUsed: 0, } + HypervisorAfterV287Response = hypervisors.Hypervisor{ + CPUInfo: hypervisors.CPUInfo{}, + CurrentWorkload: 0, + Status: "enabled", + State: "up", + DiskAvailableLeast: 0, + HostIP: "1.1.1.1", + FreeDiskGB: 0, + FreeRamMB: 7680, + HypervisorHostname: "fake-mini", + HypervisorType: "fake", + HypervisorVersion: 2002000, + ID: "c48f6247-abe4-4a24-824e-ea39e108874f", + LocalGB: 0, + LocalGBUsed: 0, + MemoryMB: 8192, + MemoryMBUsed: 512, + RunningVMs: 0, + Service: hypervisors.Service{ + Host: "e6a37ee802d74863ab8b91ade8f12a67", + ID: "9c2566e7-7a54-4777-a1ae-c2662f0c407c", + DisabledReason: "", + }, + VCPUs: 1, + VCPUsUsed: 0, + } + HypervisorsStatisticsExpected = hypervisors.Statistics{ Count: 1, CurrentWorkload: 0, @@ -604,6 +662,16 @@ func HandleHypervisorGetEmptyCPUInfoSuccessfully(t *testing.T) { }) } +func HandleHypervisorAfterV287ResponseSuccessfully(t *testing.T) { + testhelper.Mux.HandleFunc("/os-hypervisors/"+HypervisorFake.ID, func(w http.ResponseWriter, r *http.Request) { + testhelper.TestMethod(t, r, "GET") + testhelper.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.Header().Add("Content-Type", "application/json") + fmt.Fprintf(w, HypervisorAfterV287ResponseBody) + }) +} + func HandleHypervisorUptimeSuccessfully(t *testing.T) { testhelper.Mux.HandleFunc("/os-hypervisors/"+HypervisorFake.ID+"/uptime", func(w http.ResponseWriter, r *http.Request) { testhelper.TestMethod(t, r, "GET") diff --git a/openstack/compute/v2/hypervisors/testing/requests_test.go b/openstack/compute/v2/hypervisors/testing/requests_test.go index 900eadc78b..493e8138d1 100644 --- a/openstack/compute/v2/hypervisors/testing/requests_test.go +++ b/openstack/compute/v2/hypervisors/testing/requests_test.go @@ -148,6 +148,18 @@ func TestGetHypervisorEmptyCPUInfo(t *testing.T) { testhelper.CheckDeepEquals(t, &expected, actual) } +func TestGetHypervisorAfterV287Response(t *testing.T) { + testhelper.SetupHTTP() + defer testhelper.TeardownHTTP() + HandleHypervisorAfterV287ResponseSuccessfully(t) + + expected := HypervisorAfterV287Response + + actual, err := hypervisors.Get(context.TODO(), client.ServiceClient(), expected.ID).Extract() + testhelper.AssertNoErr(t, err) + testhelper.CheckDeepEquals(t, &expected, actual) +} + func TestHypervisorsUptime(t *testing.T) { testhelper.SetupHTTP() defer testhelper.TeardownHTTP() From 9c67060f0a2f37e89b22344c4e6d11c44bb41482 Mon Sep 17 00:00:00 2001 From: kayrus Date: Thu, 10 Oct 2024 18:02:04 +0200 Subject: [PATCH 040/353] [manila] add scheduler_hints to the shares CreateOpts --- .../sharedfilesystems/v2/shares/requests.go | 19 +++++++++++++++++++ .../v2/shares/testing/fixtures_test.go | 10 ++++++++-- .../v2/shares/testing/request_test.go | 12 +++++++++++- 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/openstack/sharedfilesystems/v2/shares/requests.go b/openstack/sharedfilesystems/v2/shares/requests.go index d228f6a36c..8c111b4837 100644 --- a/openstack/sharedfilesystems/v2/shares/requests.go +++ b/openstack/sharedfilesystems/v2/shares/requests.go @@ -7,6 +7,22 @@ import ( "github.com/gophercloud/gophercloud/v2/pagination" ) +// SchedulerHints contains options for providing scheduler hints when creating +// a Share. +type SchedulerHints struct { + // DifferentHost will place the share on a different back-end that does not + // host the given shares. + DifferentHost string `json:"different_host,omitempty"` + + // SameHost will place the share on a back-end that hosts the given shares. + SameHost string `json:"same_host,omitempty"` + + // OnlyHost value must be a manage-share service host in + // host@backend#POOL format (admin only). Only available in and beyond + // API version 2.67 + OnlyHost string `json:"only_host,omitempty"` +} + // CreateOptsBuilder allows extensions to add additional parameters to the // Create request. type CreateOptsBuilder interface { @@ -48,6 +64,9 @@ type CreateOpts struct { ConsistencyGroupID string `json:"consistency_group_id,omitempty"` // The availability zone of the share AvailabilityZone string `json:"availability_zone,omitempty"` + // SchedulerHints are hints for the scheduler to select the share backend + // Only available in and beyond API version 2.65 + SchedulerHints *SchedulerHints `json:"scheduler_hints,omitempty"` } // ToShareCreateMap assembles a request body based on the contents of a diff --git a/openstack/sharedfilesystems/v2/shares/testing/fixtures_test.go b/openstack/sharedfilesystems/v2/shares/testing/fixtures_test.go index 89a2c5461e..cfb9e73d2e 100644 --- a/openstack/sharedfilesystems/v2/shares/testing/fixtures_test.go +++ b/openstack/sharedfilesystems/v2/shares/testing/fixtures_test.go @@ -18,7 +18,11 @@ var createRequest = `{ "share": { "name": "my_test_share", "size": 1, - "share_proto": "NFS" + "share_proto": "NFS", + "scheduler_hints": { + "same_host": "e268f4aa-d571-43dd-9ab3-f49ad06ffaef", + "different_host": "e268f4aa-d571-43dd-9ab3-f49ad06ffaef" + } } }` @@ -61,7 +65,9 @@ var createResponse = `{ "is_public": true, "metadata": { "project": "my_app", - "aim": "doc" + "aim": "doc", + "__affinity_same_host": "e268f4aa-d571-43dd-9ab3-f49ad06ffaef", + "__affinity_different_host": "e268f4aa-d571-43dd-9ab3-f49ad06ffaef" }, "id": "011d21e2-fbc3-4e4a-9993-9ea223f73264", "description": "My custom share London" diff --git a/openstack/sharedfilesystems/v2/shares/testing/request_test.go b/openstack/sharedfilesystems/v2/shares/testing/request_test.go index f9af3da84b..396c73a795 100644 --- a/openstack/sharedfilesystems/v2/shares/testing/request_test.go +++ b/openstack/sharedfilesystems/v2/shares/testing/request_test.go @@ -16,13 +16,23 @@ func TestCreate(t *testing.T) { MockCreateResponse(t) - options := &shares.CreateOpts{Size: 1, Name: "my_test_share", ShareProto: "NFS"} + options := &shares.CreateOpts{ + Size: 1, + Name: "my_test_share", + ShareProto: "NFS", + SchedulerHints: &shares.SchedulerHints{ + SameHost: "e268f4aa-d571-43dd-9ab3-f49ad06ffaef", + DifferentHost: "e268f4aa-d571-43dd-9ab3-f49ad06ffaef", + }, + } n, err := shares.Create(context.TODO(), client.ServiceClient(), options).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, n.Name, "my_test_share") th.AssertEquals(t, n.Size, 1) th.AssertEquals(t, n.ShareProto, "NFS") + th.AssertEquals(t, n.Metadata["__affinity_same_host"], "e268f4aa-d571-43dd-9ab3-f49ad06ffaef") + th.AssertEquals(t, n.Metadata["__affinity_different_host"], "e268f4aa-d571-43dd-9ab3-f49ad06ffaef") } func TestUpdate(t *testing.T) { From 7401f48fddced7aee332bf2c5565da2f87c903ea Mon Sep 17 00:00:00 2001 From: kayrus Date: Wed, 9 Oct 2024 13:51:57 +0200 Subject: [PATCH 041/353] [manila] add share_group_id to share's CreateOpts --- openstack/sharedfilesystems/v2/shares/requests.go | 2 ++ openstack/sharedfilesystems/v2/shares/results.go | 2 ++ 2 files changed, 4 insertions(+) diff --git a/openstack/sharedfilesystems/v2/shares/requests.go b/openstack/sharedfilesystems/v2/shares/requests.go index 8c111b4837..5d680a642b 100644 --- a/openstack/sharedfilesystems/v2/shares/requests.go +++ b/openstack/sharedfilesystems/v2/shares/requests.go @@ -56,6 +56,8 @@ type CreateOpts struct { SnapshotID string `json:"snapshot_id,omitempty"` // Determines whether or not the share is public IsPublic *bool `json:"is_public,omitempty"` + // The UUID of the share group. Available starting from the microversion 2.31 + ShareGroupID string `json:"share_group_id,omitempty"` // Key value pairs of user defined metadata Metadata map[string]string `json:"metadata,omitempty"` // The UUID of the share network to which the share belongs to diff --git a/openstack/sharedfilesystems/v2/shares/results.go b/openstack/sharedfilesystems/v2/shares/results.go index d3fe9d8437..7c1b621327 100644 --- a/openstack/sharedfilesystems/v2/shares/results.go +++ b/openstack/sharedfilesystems/v2/shares/results.go @@ -54,6 +54,8 @@ type Share struct { ShareType string `json:"share_type"` // The name of the share type. ShareTypeName string `json:"share_type_name"` + // The UUID of the share group. Available starting from the microversion 2.31 + ShareGroupID string `json:"share_group_id"` // Size of the share in GB Size int `json:"size"` // UUID of the snapshot from which to create the share From 0d1c2a0a6bece35ed9cd30f0574b1a4158837ea2 Mon Sep 17 00:00:00 2001 From: Pierre Prinetti Date: Thu, 17 Oct 2024 10:23:58 +0200 Subject: [PATCH 042/353] docs: Remove outdated godoc The `doc.go` file, and [go.dev](https://pkg.go.dev/github.com/gophercloud/gophercloud/v2) as a consequence, was still recommending to use utils for authentication. Since the automatically-generated documentation on the Go website already includes the README, we can delete doc.go and keep README.md as the canonical introduction to the module. --- README.md | 2 - doc.go | 148 ------------------------------------------------------ 2 files changed, 150 deletions(-) delete mode 100644 doc.go diff --git a/README.md b/README.md index e9ba39bb79..ca47f5b0ba 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,6 @@ # Gophercloud: an OpenStack SDK for Go [![Coverage Status](https://coveralls.io/repos/github/gophercloud/gophercloud/badge.svg?branch=master)](https://coveralls.io/github/gophercloud/gophercloud?branch=master) -[Reference documentation](http://godoc.org/github.com/gophercloud/gophercloud/v2) - Gophercloud is a Go SDK for OpenStack. Join us on kubernetes slack, on [#gophercloud](https://kubernetes.slack.com/archives/C05G4NJ6P6X). Visit [slack.k8s.io](https://slack.k8s.io) for an invitation. diff --git a/doc.go b/doc.go deleted file mode 100644 index a755ecb180..0000000000 --- a/doc.go +++ /dev/null @@ -1,148 +0,0 @@ -/* -Package gophercloud provides a multi-vendor interface to OpenStack-compatible -clouds. The library has a three-level hierarchy: providers, services, and -resources. - -# Authenticating with Providers - -Provider structs represent the cloud providers that offer and manage a -collection of services. You will generally want to create one Provider -client per OpenStack cloud. - - It is now recommended to use the `clientconfig` package found at - https://github.com/gophercloud/utils/tree/master/openstack/clientconfig - for all authentication purposes. - - The below documentation is still relevant. clientconfig simply implements - the below and presents it in an easier and more flexible way. - -Use your OpenStack credentials to create a Provider client. The -IdentityEndpoint is typically refered to as "auth_url" or "OS_AUTH_URL" in -information provided by the cloud operator. Additionally, the cloud may refer to -TenantID or TenantName as project_id and project_name. Credentials are -specified like so: - - opts := gophercloud.AuthOptions{ - IdentityEndpoint: "https://openstack.example.com:5000/v2.0", - Username: "{username}", - Password: "{password}", - TenantID: "{tenant_id}", - } - - provider, err := openstack.AuthenticatedClient(context.TODO(), opts) - -You can authenticate with a token by doing: - - opts := gophercloud.AuthOptions{ - IdentityEndpoint: "https://openstack.example.com:5000/v2.0", - TokenID: "{token_id}", - TenantID: "{tenant_id}", - } - - provider, err := openstack.AuthenticatedClient(context.TODO(), opts) - -You may also use the openstack.AuthOptionsFromEnv() helper function. This -function reads in standard environment variables frequently found in an -OpenStack `openrc` file. Again note that Gophercloud currently uses "tenant" -instead of "project". - - opts, err := openstack.AuthOptionsFromEnv() - provider, err := openstack.AuthenticatedClient(context.TODO(), opts) - -# Service Clients - -Service structs are specific to a provider and handle all of the logic and -operations for a particular OpenStack service. Examples of services include: -Compute, Object Storage, Block Storage. In order to define one, you need to -pass in the parent provider, like so: - - opts := gophercloud.EndpointOpts{Region: "RegionOne"} - - client, err := openstack.NewComputeV2(provider, opts) - -# Resources - -Resource structs are the domain models that services make use of in order -to work with and represent the state of API resources: - - server, err := servers.Get(context.TODO(), client, "{serverId}").Extract() - -Intermediate Result structs are returned for API operations, which allow -generic access to the HTTP headers, response body, and any errors associated -with the network transaction. To turn a result into a usable resource struct, -you must call the Extract method which is chained to the response, or an -Extract function from an applicable extension: - - result := servers.Get(context.TODO(), client, "{serverId}") - - // Attempt to extract the disk configuration from the OS-DCF disk config - // extension: - config, err := diskconfig.ExtractGet(result) - -All requests that enumerate a collection return a Pager struct that is used to -iterate through the results one page at a time. Use the EachPage method on that -Pager to handle each successive Page in a closure, then use the appropriate -extraction method from that request's package to interpret that Page as a slice -of results: - - err := servers.List(client, nil).EachPage(context.TODO(), func (_ context.Context, page pagination.Page) (bool, error) { - s, err := servers.ExtractServers(page) - if err != nil { - return false, err - } - - // Handle the []servers.Server slice. - - // Return "false" or an error to prematurely stop fetching new pages. - return true, nil - }) - -If you want to obtain the entire collection of pages without doing any -intermediary processing on each page, you can use the AllPages method: - - allPages, err := servers.List(client, nil).AllPages(context.TODO()) - allServers, err := servers.ExtractServers(allPages) - -This top-level package contains utility functions and data types that are used -throughout the provider and service packages. Of particular note for end users -are the AuthOptions and EndpointOpts structs. - -An example retry backoff function, which respects the 429 HTTP response code and a "Retry-After" header: - - endpoint := "http://localhost:5000" - provider, err := openstack.NewClient(endpoint) - if err != nil { - panic(err) - } - provider.MaxBackoffRetries = 3 // max three retries - provider.RetryBackoffFunc = func(ctx context.Context, respErr *ErrUnexpectedResponseCode, e error, retries uint) error { - retryAfter := respErr.ResponseHeader.Get("Retry-After") - if retryAfter == "" { - return e - } - - var sleep time.Duration - - // Parse delay seconds or HTTP date - if v, err := strconv.ParseUint(retryAfter, 10, 32); err == nil { - sleep = time.Duration(v) * time.Second - } else if v, err := time.Parse(http.TimeFormat, retryAfter); err == nil { - sleep = time.Until(v) - } else { - return e - } - - if ctx != nil { - select { - case <-time.After(sleep): - case <-ctx.Done(): - return e - } - } else { - time.Sleep(sleep) - } - - return nil - } -*/ -package gophercloud From 9f84b963d8c249bb4a4fb9ff9df388707e3f1afc Mon Sep 17 00:00:00 2001 From: Pierre Prinetti Date: Fri, 18 Oct 2024 13:42:59 +0200 Subject: [PATCH 043/353] Prepare v2.2.0 --- CHANGELOG.md | 13 +++++++++++++ provider_client.go | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 41f9017aa9..efe2d9f6af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,16 @@ +## v2.2.0 (2024-10-18) + +* [GH-3176](https://github.com/gophercloud/gophercloud/pull/3176) [v2] [containerinfra]: add "MasterLBEnabled" in Cluster results +* [GH-3181](https://github.com/gophercloud/gophercloud/pull/3181) [v2] octavia: add new options to health monitors +* [GH-3182](https://github.com/gophercloud/gophercloud/pull/3182) [v2] octavia: add new security options to pools and listeners +* [GH-3195](https://github.com/gophercloud/gophercloud/pull/3195) [v2] [core]: handle empty response body +* [GH-3196](https://github.com/gophercloud/gophercloud/pull/3196) [v2] [fwaas_v2]: proper ParseResponse handling +* [GH-3198](https://github.com/gophercloud/gophercloud/pull/3198) [v2] compute: Fix expected and actual test results +* [GH-3199](https://github.com/gophercloud/gophercloud/pull/3199) [v2] [octavia] add an ability to filter flavors and flavorprofiles +* [GH-3214](https://github.com/gophercloud/gophercloud/pull/3214) [v2] [manila] add scheduler_hints to the shares CreateOpts +* [GH-3215](https://github.com/gophercloud/gophercloud/pull/3215) [v2] [manila] add share_group_id to share's CreateOpts +* [GH-3219](https://github.com/gophercloud/gophercloud/pull/3219) [v2] docs: Remove outdated godoc + ## v2.1.1 (2024-09-18) * [GH-3161](https://github.com/gophercloud/gophercloud/pull/3161) [v2] fix: create security group rule with any protocol diff --git a/provider_client.go b/provider_client.go index e2cd3c2dad..007266f635 100644 --- a/provider_client.go +++ b/provider_client.go @@ -13,7 +13,7 @@ import ( // DefaultUserAgent is the default User-Agent string set in the request header. const ( - DefaultUserAgent = "gophercloud/v2.1.1" + DefaultUserAgent = "gophercloud/v2.2.0" DefaultMaxBackoffRetries = 60 ) From fbd7eb497d4347e58dda3e54c04677cc308d7bbc Mon Sep 17 00:00:00 2001 From: Pierre Prinetti Date: Mon, 21 Oct 2024 12:04:40 +0200 Subject: [PATCH 044/353] Fix clear-needinfo The gh tool must be set to operate on an issue rather than on a PR. --- .github/workflows/label-issue.yaml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/label-issue.yaml b/.github/workflows/label-issue.yaml index 723f4cd04e..a1fbff16e0 100644 --- a/.github/workflows/label-issue.yaml +++ b/.github/workflows/label-issue.yaml @@ -9,9 +9,11 @@ jobs: name: Clear needinfo if: ${{ github.event.issue.user.login }} == ${{ github.event.comment.user.login }} runs-on: ubuntu-latest + permissions: + issues: write steps: - - run: gh pr edit "$NUMBER" --remove-label "needinfo" + - run: gh issue edit "$NUMBER" --remove-label "needinfo" env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} GH_REPO: ${{ github.repository }} - NUMBER: ${{ github.event.pull_request.number }} + NUMBER: ${{ github.event.issue.number }} From 591cc7409bced4939a95198a723c62da77e9ad6e Mon Sep 17 00:00:00 2001 From: Sharpz7 Date: Wed, 30 Oct 2024 01:06:21 +0000 Subject: [PATCH 045/353] Added fields for Node API Parity --- openstack/baremetal/v1/nodes/results.go | 82 ++++++++--- .../v1/nodes/testing/fixtures_test.go | 133 +++++++++++++++--- 2 files changed, 177 insertions(+), 38 deletions(-) diff --git a/openstack/baremetal/v1/nodes/results.go b/openstack/baremetal/v1/nodes/results.go index 5c6eb5c190..22babe02d3 100644 --- a/openstack/baremetal/v1/nodes/results.go +++ b/openstack/baremetal/v1/nodes/results.go @@ -90,12 +90,19 @@ func (r SubscriptionVendorPassthruResult) Extract() (*SubscriptionVendorPassthru return &s, err } +// Link represents a hyperlink and its relationship to the current resource. +type Link struct { + // Href is the URL of the related resource. + Href string `json:"href"` + + // Rel describes the relationship of the resource to the current + // context (e.g., "self", "bookmark"). + Rel string `json:"rel"` +} + // Node represents a node in the OpenStack Bare Metal API. +// https://docs.openstack.org/api-ref/baremetal/#list-nodes-detailed type Node struct { - // Whether automated cleaning is enabled or disabled on this node. - // Requires microversion 1.47 or later. - AutomatedClean *bool `json:"automated_clean"` - // UUID for the resource. UUID string `json:"uuid"` @@ -183,8 +190,17 @@ type Node struct { // Current deploy step. DeployStep map[string]any `json:"deploy_step"` - // Current service step. - ServiceStep map[string]any `json:"service_step"` + // A list of relative links. Includes the self and bookmark links. + Links []Link `json:"links"` + + // Links to the collection of ports on this node + Ports []Link `json:"ports"` + + // Links to the collection of portgroups on this node. + PortGroups []Link `json:"portgroups"` + + // Links to the collection of states. Note that this resource is also used to request state transitions. + States []Link `json:"states"` // String which can be used by external schedulers to identify this Node as a unit of a specific type of resource. // For more details, see: https://docs.openstack.org/ironic/latest/install/configure-nova-flavors.html @@ -202,9 +218,6 @@ type Node struct { // Deploy interface for a node, e.g. “iscsi”. DeployInterface string `json:"deploy_interface"` - // Firmware interface for a node, e.g. “redfish”. - FirmwareInterface string `json:"firmware_interface"` - // Interface used for node inspection, e.g. “no-inspect”. InspectInterface string `json:"inspect_interface"` @@ -232,9 +245,15 @@ type Node struct { // For vendor-specific functionality on this node, e.g. “no-vendor”. VendorInterface string `json:"vendor_interface"` + // Links to the volume resources. + Volume []Link `json:"volume"` + // Conductor group for a node. Case-insensitive string up to 255 characters, containing a-z, 0-9, _, -, and .. ConductorGroup string `json:"conductor_group"` + // An optional UUID which can be used to denote the “parent” baremetal node. + ParentNode string `json:"parent_node"` + // The node is protected from undeploying, rebuilding and deletion. Protected bool `json:"protected"` @@ -244,14 +263,42 @@ type Node struct { // A string or UUID of the tenant who owns the baremetal node. Owner string `json:"owner"` + // A string or UUID of the tenant who is leasing the object. + Lessee string `json:"lessee"` + + // A string indicating the shard this node belongs to. + Shard string `json:"shard"` + + // Informational text about this node. + Description string `json:"description"` + + // The conductor currently servicing a node. This field is read-only. + Conductor string `json:"conductor"` + + // The UUID of the allocation associated with the node. If not null, will be the same as instance_uuid + // (the opposite is not always true). Unlike instance_uuid, this field is read-only. Please use the + // Allocation API to remove allocations. + AllocationUUID string `json:"allocation_uuid"` + + // Whether the node is retired. A Node tagged as retired will prevent any further + // scheduling of instances, but will still allow for other operations, such as cleaning, to happen + Retired bool `json:"retired"` + + // Reason the node is marked as retired. + RetiredReason string `json:"retired_reason"` + // Static network configuration to use during deployment and cleaning. NetworkData map[string]any `json:"network_data"` - // The UTC date and time when the resource was created, ISO 8601 format. - CreatedAt time.Time `json:"created_at"` + // Whether automated cleaning is enabled or disabled on this node. + // Requires microversion 1.47 or later. + AutomatedClean *bool `json:"automated_clean"` - // The UTC date and time when the resource was updated, ISO 8601 format. May be “null”. - UpdatedAt time.Time `json:"updated_at"` + // Current service step. + ServiceStep map[string]any `json:"service_step"` + + // Firmware interface for a node, e.g. “redfish”. + FirmwareInterface string `json:"firmware_interface"` // The UTC date and time when the provision state was updated, ISO 8601 format. May be “null”. ProvisionUpdatedAt time.Time `json:"provision_updated_at"` @@ -262,12 +309,11 @@ type Node struct { // The UTC date and time when the last inspection was finished, ISO 8601 format. May be “null” if inspection hasn't been finished yet. InspectionFinishedAt *time.Time `json:"inspection_finished_at"` - // Whether the node is retired. A Node tagged as retired will prevent any further - // scheduling of instances, but will still allow for other operations, such as cleaning, to happen - Retired bool `json:"retired"` + // The UTC date and time when the resource was created, ISO 8601 format. + CreatedAt time.Time `json:"created_at"` - // Reason the node is marked as retired. - RetiredReason string `json:"retired_reason"` + // The UTC date and time when the resource was updated, ISO 8601 format. May be “null”. + UpdatedAt time.Time `json:"updated_at"` } // NodePage abstracts the raw results of making a List() request against diff --git a/openstack/baremetal/v1/nodes/testing/fixtures_test.go b/openstack/baremetal/v1/nodes/testing/fixtures_test.go index d47d70b13c..d174edde2b 100644 --- a/openstack/baremetal/v1/nodes/testing/fixtures_test.go +++ b/openstack/baremetal/v1/nodes/testing/fixtures_test.go @@ -925,23 +925,57 @@ var ( "deploy_ramdisk": "http://172.22.0.1/images/tinyipa-stable-rocky.gz", "ipmi_password": "admin", }, - DriverInternalInfo: map[string]any{}, - Properties: map[string]any{}, - InstanceInfo: map[string]any{}, - InstanceUUID: "", - ChassisUUID: "", - Extra: map[string]any{}, - ConsoleEnabled: false, - RAIDConfig: map[string]any{}, - TargetRAIDConfig: map[string]any{}, - CleanStep: map[string]any{}, - DeployStep: map[string]any{}, + DriverInternalInfo: map[string]any{}, + Properties: map[string]any{}, + InstanceInfo: map[string]any{}, + InstanceUUID: "", + ChassisUUID: "", + Extra: map[string]any{}, + ConsoleEnabled: false, + RAIDConfig: map[string]any{}, + TargetRAIDConfig: map[string]any{}, + CleanStep: map[string]any{}, + DeployStep: map[string]any{}, + Links: []nodes.Link{ + { + Href: "http://ironic.example.com:6385/v1/nodes/d2630783-6ec8-4836-b556-ab427c4b581e", + Rel: "self", + }, + { + Href: "http://ironic.example.com:6385/nodes/d2630783-6ec8-4836-b556-ab427c4b581e", + Rel: "bookmark", + }, + }, + Ports: []nodes.Link{ + { + Href: "http://ironic.example.com:6385/v1/nodes/d2630783-6ec8-4836-b556-ab427c4b581e/ports", + Rel: "self", + }, + { + Href: "http://ironic.example.com:6385/nodes/d2630783-6ec8-4836-b556-ab427c4b581e/ports", + Rel: "bookmark", + }, + }, + PortGroups: []nodes.Link{ + { + Href: "http://ironic.example.com:6385/v1/nodes/d2630783-6ec8-4836-b556-ab427c4b581e/portgroups", + Rel: "self", + }, + { + Href: "http://ironic.example.com:6385/nodes/d2630783-6ec8-4836-b556-ab427c4b581e/portgroups", + Rel: "bookmark"}, + }, + States: []nodes.Link{ + { + Href: "http://ironic.example.com:6385/v1/nodes/d2630783-6ec8-4836-b556-ab427c4b581e/states", + Rel: "self", + }, + }, ResourceClass: "", BIOSInterface: "no-bios", BootInterface: "pxe", ConsoleInterface: "no-console", DeployInterface: "iscsi", - FirmwareInterface: "no-firmware", InspectInterface: "no-inspect", ManagementInterface: "ipmitool", NetworkInterface: "flat", @@ -951,14 +985,33 @@ var ( StorageInterface: "noop", Traits: []string{}, VendorInterface: "ipmitool", - ConductorGroup: "", - Protected: false, - ProtectedReason: "", - CreatedAt: createdAtFoo, - UpdatedAt: updatedAt, - ProvisionUpdatedAt: provisonUpdatedAt, - Retired: false, - RetiredReason: "No longer needed", + Volume: []nodes.Link{ + { + Href: "http://ironic.example.com:6385/v1/nodes/d2630783-6ec8-4836-b556-ab427c4b581e/volume", + Rel: "self", + }, + }, + ConductorGroup: "", + ParentNode: "", + Protected: false, + ProtectedReason: "", + Owner: "", + Lessee: "", + Shard: "", + Description: "", + Conductor: "", + AllocationUUID: "", + Retired: false, + RetiredReason: "No longer needed", + NetworkData: map[string]interface{}(nil), + AutomatedClean: nil, + ServiceStep: map[string]interface{}(nil), + FirmwareInterface: "no-firmware", + ProvisionUpdatedAt: provisonUpdatedAt, + InspectionStartedAt: nil, + InspectionFinishedAt: nil, + CreatedAt: createdAtFoo, + UpdatedAt: updatedAt, } NodeFooValidation = nodes.NodeValidation{ @@ -1070,6 +1123,26 @@ var ( InspectionFinishedAt: &InspectionFinishedAt, Retired: false, RetiredReason: "No longer needed", + Links: []nodes.Link{ + {Href: "http://ironic.example.com:6385/v1/nodes/08c84581-58f5-4ea2-a0c6-dd2e5d2b3662", Rel: "self"}, + {Href: "http://ironic.example.com:6385/nodes/08c84581-58f5-4ea2-a0c6-dd2e5d2b3662", Rel: "bookmark"}, + }, + Ports: []nodes.Link{ + {Href: "http://ironic.example.com:6385/v1/nodes/08c84581-58f5-4ea2-a0c6-dd2e5d2b3662/ports", Rel: "self"}, + {Href: "http://ironic.example.com:6385/nodes/08c84581-58f5-4ea2-a0c6-dd2e5d2b3662/ports", Rel: "bookmark"}, + }, + PortGroups: []nodes.Link{ + {Href: "http://ironic.example.com:6385/v1/nodes/08c84581-58f5-4ea2-a0c6-dd2e5d2b3662/portgroups", Rel: "self"}, + {Href: "http://ironic.example.com:6385/nodes/08c84581-58f5-4ea2-a0c6-dd2e5d2b3662/portgroups", Rel: "bookmark"}, + }, + States: []nodes.Link{ + {Href: "http://ironic.example.com:6385/v1/nodes/08c84581-58f5-4ea2-a0c6-dd2e5d2b3662/states", Rel: "self"}, + {Href: "http://ironic.example.com:6385/nodes/08c84581-58f5-4ea2-a0c6-dd2e5d2b3662/states", Rel: "bookmark"}, + }, + Volume: []nodes.Link{ + {Href: "http://ironic.example.com:6385/v1/nodes/08c84581-58f5-4ea2-a0c6-dd2e5d2b3662/volume", Rel: "self"}, + {Href: "http://ironic.example.com:6385/nodes/08c84581-58f5-4ea2-a0c6-dd2e5d2b3662/volume", Rel: "bookmark"}, + }, } NodeBaz = nodes.Node{ @@ -1119,6 +1192,26 @@ var ( UpdatedAt: updatedAt, Retired: false, RetiredReason: "No longer needed", + Links: []nodes.Link{ + {Href: "http://ironic.example.com:6385/v1/nodes/c9afd385-5d89-4ecb-9e1c-68194da6b474", Rel: "self"}, + {Href: "http://ironic.example.com:6385/nodes/c9afd385-5d89-4ecb-9e1c-68194da6b474", Rel: "bookmark"}, + }, + Ports: []nodes.Link{ + {Href: "http://ironic.example.com:6385/v1/nodes/c9afd385-5d89-4ecb-9e1c-68194da6b474/ports", Rel: "self"}, + {Href: "http://ironic.example.com:6385/nodes/c9afd385-5d89-4ecb-9e1c-68194da6b474/ports", Rel: "bookmark"}, + }, + PortGroups: []nodes.Link{ + {Href: "http://ironic.example.com:6385/v1/nodes/c9afd385-5d89-4ecb-9e1c-68194da6b474/portgroups", Rel: "self"}, + {Href: "http://ironic.example.com:6385/nodes/c9afd385-5d89-4ecb-9e1c-68194da6b474/portgroups", Rel: "bookmark"}, + }, + States: []nodes.Link{ + {Href: "http://ironic.example.com:6385/v1/nodes/c9afd385-5d89-4ecb-9e1c-68194da6b474/states", Rel: "self"}, + {Href: "http://ironic.example.com:6385/nodes/c9afd385-5d89-4ecb-9e1c-68194da6b474/states", Rel: "bookmark"}, + }, + Volume: []nodes.Link{ + {Href: "http://ironic.example.com:6385/v1/nodes/c9afd385-5d89-4ecb-9e1c-68194da6b474/volume", Rel: "self"}, + {Href: "http://ironic.example.com:6385/nodes/c9afd385-5d89-4ecb-9e1c-68194da6b474/volume", Rel: "bookmark"}, + }, } ConfigDriveMap = nodes.ConfigDrive{ From 968a33be6bee4f473c0545c74db1f49acfde73de Mon Sep 17 00:00:00 2001 From: Derek Higgins Date: Wed, 13 Nov 2024 10:28:17 +0000 Subject: [PATCH 046/353] Add support for disable_power_off Added in baremetal api v1.95 disable_power_off expcicitly prevents a node from being powered off by ironic. See https://specs.openstack.org/openstack/ironic-specs/specs/approved/nc-si.html --- openstack/baremetal/v1/nodes/requests.go | 4 ++++ openstack/baremetal/v1/nodes/results.go | 4 ++++ openstack/baremetal/v1/nodes/testing/fixtures_test.go | 5 +++++ 3 files changed, 13 insertions(+) diff --git a/openstack/baremetal/v1/nodes/requests.go b/openstack/baremetal/v1/nodes/requests.go index 8cb0de9e05..8b2eb4b218 100644 --- a/openstack/baremetal/v1/nodes/requests.go +++ b/openstack/baremetal/v1/nodes/requests.go @@ -274,6 +274,10 @@ type CreateOpts struct { // Static network configuration to use during deployment and cleaning. NetworkData map[string]any `json:"network_data,omitempty"` + + // Whether disable_power_off is enabled or disabled on this node. + // Requires microversion 1.95 or later. + DisablePowerOff *bool `json:"disable_power_off,omitempty"` } // ToNodeCreateMap assembles a request body based on the contents of a CreateOpts. diff --git a/openstack/baremetal/v1/nodes/results.go b/openstack/baremetal/v1/nodes/results.go index 22babe02d3..507e0d6a4f 100644 --- a/openstack/baremetal/v1/nodes/results.go +++ b/openstack/baremetal/v1/nodes/results.go @@ -314,6 +314,10 @@ type Node struct { // The UTC date and time when the resource was updated, ISO 8601 format. May be “null”. UpdatedAt time.Time `json:"updated_at"` + + // Whether disable_power_off is enabled or disabled on this node. + // Requires microversion 1.95 or later. + DisablePowerOff bool `json:"disable_power_off"` } // NodePage abstracts the raw results of making a List() request against diff --git a/openstack/baremetal/v1/nodes/testing/fixtures_test.go b/openstack/baremetal/v1/nodes/testing/fixtures_test.go index d174edde2b..7819111314 100644 --- a/openstack/baremetal/v1/nodes/testing/fixtures_test.go +++ b/openstack/baremetal/v1/nodes/testing/fixtures_test.go @@ -87,6 +87,7 @@ const NodeListDetailBody = ` "created_at": "2019-01-31T19:59:28+00:00", "deploy_interface": "iscsi", "deploy_step": {}, + "disable_power_off": false, "driver": "ipmi", "driver_info": { "ipmi_port": "6230", @@ -195,6 +196,7 @@ const NodeListDetailBody = ` "created_at": "2019-01-31T19:59:29+00:00", "deploy_interface": "iscsi", "deploy_step": {}, + "disable_power_off": false, "driver": "ipmi", "driver_info": {}, "driver_internal_info": {}, @@ -295,6 +297,7 @@ const NodeListDetailBody = ` "created_at": "2019-01-31T19:59:30+00:00", "deploy_interface": "iscsi", "deploy_step": {}, + "disable_power_off": true, "driver": "ipmi", "driver_info": {}, "driver_internal_info": {}, @@ -1123,6 +1126,7 @@ var ( InspectionFinishedAt: &InspectionFinishedAt, Retired: false, RetiredReason: "No longer needed", + DisablePowerOff: false, Links: []nodes.Link{ {Href: "http://ironic.example.com:6385/v1/nodes/08c84581-58f5-4ea2-a0c6-dd2e5d2b3662", Rel: "self"}, {Href: "http://ironic.example.com:6385/nodes/08c84581-58f5-4ea2-a0c6-dd2e5d2b3662", Rel: "bookmark"}, @@ -1192,6 +1196,7 @@ var ( UpdatedAt: updatedAt, Retired: false, RetiredReason: "No longer needed", + DisablePowerOff: true, Links: []nodes.Link{ {Href: "http://ironic.example.com:6385/v1/nodes/c9afd385-5d89-4ecb-9e1c-68194da6b474", Rel: "self"}, {Href: "http://ironic.example.com:6385/nodes/c9afd385-5d89-4ecb-9e1c-68194da6b474", Rel: "bookmark"}, From c5b4c8db118715050161bc014ad1c1e1f0325510 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Aug 2024 09:11:02 +0000 Subject: [PATCH 047/353] build(deps): bump golang.org/x/crypto from 0.25.0 to 0.26.0 Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.25.0 to 0.26.0. - [Commits](https://github.com/golang/crypto/compare/v0.25.0...v0.26.0) --- updated-dependencies: - dependency-name: golang.org/x/crypto dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 4 ++-- go.sum | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/go.mod b/go.mod index d4ac50a838..1a02e360ff 100644 --- a/go.mod +++ b/go.mod @@ -3,8 +3,8 @@ module github.com/gophercloud/gophercloud/v2 go 1.22 require ( - golang.org/x/crypto v0.25.0 + golang.org/x/crypto v0.26.0 gopkg.in/yaml.v2 v2.4.0 ) -require golang.org/x/sys v0.22.0 // indirect +require golang.org/x/sys v0.23.0 // indirect diff --git a/go.sum b/go.sum index 1e1f48a722..70de9bd3f3 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,9 @@ -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= -golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= +golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= +golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= +golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= From b7f6fc436624a37eb2a245907b174892d97dcb07 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Thu, 28 Nov 2024 17:58:30 +0000 Subject: [PATCH 048/353] Drop CI coverage for Antelope Antelope has entered the unmaintained [1] phase. We can no longer rely on this for testing. [1] https://docs.openstack.org/project-team-guide/stable-branches.html#unmaintained Signed-off-by: Stephen Finucane --- .github/workflows/functional-baremetal.yaml | 5 ----- .github/workflows/functional-basic.yaml | 4 ---- .github/workflows/functional-blockstorage.yaml | 4 ---- .github/workflows/functional-compute.yaml | 4 ---- .github/workflows/functional-containerinfra.yaml | 7 ------- .github/workflows/functional-dns.yaml | 4 ---- .github/workflows/functional-fwaas_v2.yaml | 4 ---- .github/workflows/functional-identity.yaml | 4 ---- .github/workflows/functional-image.yaml | 4 ---- .github/workflows/functional-keymanager.yaml | 4 ---- .github/workflows/functional-loadbalancer.yaml | 4 ---- .github/workflows/functional-messaging.yaml | 4 ---- .github/workflows/functional-networking.yaml | 4 ---- .github/workflows/functional-objectstorage.yaml | 4 ---- .github/workflows/functional-orchestration.yaml | 4 ---- .github/workflows/functional-placement.yaml | 4 ---- .github/workflows/functional-sharedfilesystems.yaml | 4 ---- 17 files changed, 72 deletions(-) diff --git a/.github/workflows/functional-baremetal.yaml b/.github/workflows/functional-baremetal.yaml index c4aa44d8f5..adfb726385 100644 --- a/.github/workflows/functional-baremetal.yaml +++ b/.github/workflows/functional-baremetal.yaml @@ -29,11 +29,6 @@ jobs: ubuntu_version: "22.04" use_system_scope: false additional_services: "" - - name: "antelope" - openstack_version: "stable/2023.1" - ubuntu_version: "22.04" - use_system_scope: false - additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Deploy OpenStack ${{ matrix.name }} with Ironic and run baremetal acceptance tests steps: diff --git a/.github/workflows/functional-basic.yaml b/.github/workflows/functional-basic.yaml index 8157156702..0cad444eac 100644 --- a/.github/workflows/functional-basic.yaml +++ b/.github/workflows/functional-basic.yaml @@ -26,10 +26,6 @@ jobs: openstack_version: "stable/2023.2" ubuntu_version: "22.04" additional_services: "" - - name: "antelope" - openstack_version: "stable/2023.1" - ubuntu_version: "22.04" - additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Deploy OpenStack ${{ matrix.name }} with defaults and run basic acceptance tests steps: diff --git a/.github/workflows/functional-blockstorage.yaml b/.github/workflows/functional-blockstorage.yaml index dceb7596a3..df08b64f9d 100644 --- a/.github/workflows/functional-blockstorage.yaml +++ b/.github/workflows/functional-blockstorage.yaml @@ -23,10 +23,6 @@ jobs: openstack_version: "stable/2023.2" ubuntu_version: "22.04" additional_services: "" - - name: "antelope" - openstack_version: "stable/2023.1" - ubuntu_version: "22.04" - additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Deploy OpenStack ${{ matrix.name }} with Cinder and run blockstorage acceptance tests steps: diff --git a/.github/workflows/functional-compute.yaml b/.github/workflows/functional-compute.yaml index 0e1bab61e9..6600138f96 100644 --- a/.github/workflows/functional-compute.yaml +++ b/.github/workflows/functional-compute.yaml @@ -23,10 +23,6 @@ jobs: openstack_version: "stable/2023.2" ubuntu_version: "22.04" additional_services: "" - - name: "antelope" - openstack_version: "stable/2023.1" - ubuntu_version: "22.04" - additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Deploy OpenStack ${{ matrix.name }} with Nova and run compute acceptance tests steps: diff --git a/.github/workflows/functional-containerinfra.yaml b/.github/workflows/functional-containerinfra.yaml index df45bae93e..e4f6d71444 100644 --- a/.github/workflows/functional-containerinfra.yaml +++ b/.github/workflows/functional-containerinfra.yaml @@ -32,13 +32,6 @@ jobs: enable_plugin magnum https://github.com/openstack/magnum stable/2023.2 MAGNUMCLIENT_BRANCH=stable/2023.2 additional_services: "" - - name: "antelope" - openstack_version: "stable/2023.1" - ubuntu_version: "22.04" - devstack_conf_overrides: | - enable_plugin magnum https://github.com/openstack/magnum stable/2023.1 - MAGNUMCLIENT_BRANCH=stable/2023.1 - additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Deploy OpenStack ${{ matrix.name }} with Magnum and run containerinfra acceptance tests steps: diff --git a/.github/workflows/functional-dns.yaml b/.github/workflows/functional-dns.yaml index a20d5c1f85..ffeac43918 100644 --- a/.github/workflows/functional-dns.yaml +++ b/.github/workflows/functional-dns.yaml @@ -24,10 +24,6 @@ jobs: openstack_version: "stable/2023.2" ubuntu_version: "22.04" additional_services: "" - - name: "antelope" - openstack_version: "stable/2023.1" - ubuntu_version: "22.04" - additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Deploy OpenStack ${{ matrix.name }} with Designate and run dns acceptance tests steps: diff --git a/.github/workflows/functional-fwaas_v2.yaml b/.github/workflows/functional-fwaas_v2.yaml index 09d03db28b..53a94d76c2 100644 --- a/.github/workflows/functional-fwaas_v2.yaml +++ b/.github/workflows/functional-fwaas_v2.yaml @@ -23,10 +23,6 @@ jobs: openstack_version: "stable/2023.2" ubuntu_version: "22.04" additional_services: "" - - name: "antelope" - openstack_version: "stable/2023.1" - ubuntu_version: "22.04" - additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Deploy OpenStack ${{ matrix.name }} with enabled FWaaS_v2 and run networking acceptance tests steps: diff --git a/.github/workflows/functional-identity.yaml b/.github/workflows/functional-identity.yaml index f6f083bc62..1b11132609 100644 --- a/.github/workflows/functional-identity.yaml +++ b/.github/workflows/functional-identity.yaml @@ -23,10 +23,6 @@ jobs: openstack_version: "stable/2023.2" ubuntu_version: "22.04" additional_services: "" - - name: "antelope" - openstack_version: "stable/2023.1" - ubuntu_version: "22.04" - additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Deploy OpenStack ${{ matrix.name }} with Keystone and run identity acceptance tests steps: diff --git a/.github/workflows/functional-image.yaml b/.github/workflows/functional-image.yaml index 554c89fcc3..0d9855d5f1 100644 --- a/.github/workflows/functional-image.yaml +++ b/.github/workflows/functional-image.yaml @@ -23,10 +23,6 @@ jobs: openstack_version: "stable/2023.2" ubuntu_version: "22.04" additional_services: "" - - name: "antelope" - openstack_version: "stable/2023.1" - ubuntu_version: "22.04" - additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Deploy OpenStack ${{ matrix.name }} with Glance and run image acceptance tests steps: diff --git a/.github/workflows/functional-keymanager.yaml b/.github/workflows/functional-keymanager.yaml index 9cdd3cbdf1..979227ae92 100644 --- a/.github/workflows/functional-keymanager.yaml +++ b/.github/workflows/functional-keymanager.yaml @@ -23,10 +23,6 @@ jobs: openstack_version: "stable/2023.2" ubuntu_version: "22.04" additional_services: "" - - name: "antelope" - openstack_version: "stable/2023.1" - ubuntu_version: "22.04" - additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Deploy OpenStack ${{ matrix.name }} with Barbican and run keymanager acceptance tests steps: diff --git a/.github/workflows/functional-loadbalancer.yaml b/.github/workflows/functional-loadbalancer.yaml index c40e8ee2c4..7a91c91e71 100644 --- a/.github/workflows/functional-loadbalancer.yaml +++ b/.github/workflows/functional-loadbalancer.yaml @@ -23,10 +23,6 @@ jobs: openstack_version: "stable/2023.2" ubuntu_version: "22.04" additional_services: "" - - name: "antelope" - openstack_version: "stable/2023.1" - ubuntu_version: "22.04" - additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Deploy OpenStack ${{ matrix.name }} with Octavia and run loadbalancer acceptance tests steps: diff --git a/.github/workflows/functional-messaging.yaml b/.github/workflows/functional-messaging.yaml index db990e0d81..98fe43d421 100644 --- a/.github/workflows/functional-messaging.yaml +++ b/.github/workflows/functional-messaging.yaml @@ -23,10 +23,6 @@ jobs: openstack_version: "stable/2023.2" ubuntu_version: "22.04" additional_services: "" - - name: "antelope" - openstack_version: "stable/2023.1" - ubuntu_version: "22.04" - additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Deploy OpenStack ${{ matrix.name }} with Zaqar and run messaging acceptance tests steps: diff --git a/.github/workflows/functional-networking.yaml b/.github/workflows/functional-networking.yaml index 480a493d88..fba964795a 100644 --- a/.github/workflows/functional-networking.yaml +++ b/.github/workflows/functional-networking.yaml @@ -23,10 +23,6 @@ jobs: openstack_version: "stable/2023.2" ubuntu_version: "22.04" additional_services: "" - - name: "antelope" - openstack_version: "stable/2023.1" - ubuntu_version: "22.04" - additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Deploy OpenStack ${{ matrix.name }} with Neutron and run networking acceptance tests steps: diff --git a/.github/workflows/functional-objectstorage.yaml b/.github/workflows/functional-objectstorage.yaml index c0b204a1b4..54e9b52bf2 100644 --- a/.github/workflows/functional-objectstorage.yaml +++ b/.github/workflows/functional-objectstorage.yaml @@ -23,10 +23,6 @@ jobs: openstack_version: "stable/2023.2" ubuntu_version: "22.04" additional_services: "" - - name: "antelope" - openstack_version: "stable/2023.1" - ubuntu_version: "22.04" - additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Deploy OpenStack ${{ matrix.name }} with Swift and run objectstorage acceptance tests steps: diff --git a/.github/workflows/functional-orchestration.yaml b/.github/workflows/functional-orchestration.yaml index 0f627474b5..1423d8f9af 100644 --- a/.github/workflows/functional-orchestration.yaml +++ b/.github/workflows/functional-orchestration.yaml @@ -23,10 +23,6 @@ jobs: openstack_version: "stable/2023.2" ubuntu_version: "22.04" additional_services: "" - - name: "antelope" - openstack_version: "stable/2023.1" - ubuntu_version: "22.04" - additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Deploy OpenStack ${{ matrix.name }} with Heat and run orchestration acceptance tests steps: diff --git a/.github/workflows/functional-placement.yaml b/.github/workflows/functional-placement.yaml index 640df2c1d5..d138a53175 100644 --- a/.github/workflows/functional-placement.yaml +++ b/.github/workflows/functional-placement.yaml @@ -23,10 +23,6 @@ jobs: openstack_version: "stable/2023.2" ubuntu_version: "22.04" additional_services: "" - - name: "antelope" - openstack_version: "stable/2023.1" - ubuntu_version: "22.04" - additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Deploy OpenStack ${{ matrix.name }} with Placement and run placement acceptance tests steps: diff --git a/.github/workflows/functional-sharedfilesystems.yaml b/.github/workflows/functional-sharedfilesystems.yaml index e4d8bbea39..c799250d7e 100644 --- a/.github/workflows/functional-sharedfilesystems.yaml +++ b/.github/workflows/functional-sharedfilesystems.yaml @@ -23,10 +23,6 @@ jobs: openstack_version: "stable/2023.2" ubuntu_version: "22.04" additional_services: "" - - name: "antelope" - openstack_version: "stable/2023.1" - ubuntu_version: "22.04" - additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Deploy OpenStack ${{ matrix.name }} with Manila and run sharedfilesystems acceptance tests steps: From d1b8a2413710b4ee40c78e979a846744923f22eb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 Sep 2024 09:58:44 +0000 Subject: [PATCH 049/353] build(deps): bump golang.org/x/crypto from 0.26.0 to 0.27.0 Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.26.0 to 0.27.0. - [Commits](https://github.com/golang/crypto/compare/v0.26.0...v0.27.0) --- updated-dependencies: - dependency-name: golang.org/x/crypto dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 4 ++-- go.sum | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/go.mod b/go.mod index 1a02e360ff..0f39082357 100644 --- a/go.mod +++ b/go.mod @@ -3,8 +3,8 @@ module github.com/gophercloud/gophercloud/v2 go 1.22 require ( - golang.org/x/crypto v0.26.0 + golang.org/x/crypto v0.27.0 gopkg.in/yaml.v2 v2.4.0 ) -require golang.org/x/sys v0.23.0 // indirect +require golang.org/x/sys v0.25.0 // indirect diff --git a/go.sum b/go.sum index 70de9bd3f3..77cbe99406 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,9 @@ -golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= -golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= -golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= +golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= +golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= +golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= +golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM= +golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= From 5e4e1e30759e0eaeefab92e366f5ce87f9a24ea7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Oct 2024 09:49:00 +0000 Subject: [PATCH 050/353] build(deps): bump golang.org/x/crypto from 0.27.0 to 0.28.0 Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.27.0 to 0.28.0. - [Commits](https://github.com/golang/crypto/compare/v0.27.0...v0.28.0) --- updated-dependencies: - dependency-name: golang.org/x/crypto dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 4 ++-- go.sum | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/go.mod b/go.mod index 0f39082357..8e527ec8e5 100644 --- a/go.mod +++ b/go.mod @@ -3,8 +3,8 @@ module github.com/gophercloud/gophercloud/v2 go 1.22 require ( - golang.org/x/crypto v0.27.0 + golang.org/x/crypto v0.28.0 gopkg.in/yaml.v2 v2.4.0 ) -require golang.org/x/sys v0.25.0 // indirect +require golang.org/x/sys v0.26.0 // indirect diff --git a/go.sum b/go.sum index 77cbe99406..7cc4cf43b5 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,9 @@ -golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= -golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= -golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= -golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM= -golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8= +golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= +golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= +golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= +golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24= +golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= From e5d9366136beb69d20a0f1c0dd4d2e0b2994051e Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Fri, 29 Nov 2024 11:13:38 +0000 Subject: [PATCH 051/353] make: Switch default test runner gotestsum provides far more readable output than the default runner. Signed-off-by: Stephen Finucane --- Makefile | 41 +++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/Makefile b/Makefile index 128beec005..2a7a9376d9 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,7 @@ undefine GOFLAGS GOLANGCI_LINT_VERSION?=v1.57.1 +GO_TEST?=go run gotest.tools/gotestsum@latest --format testname ifeq ($(shell command -v podman 2> /dev/null),) RUNNER=docker @@ -26,84 +27,84 @@ lint: .PHONY: lint unit: - go test ./... + $(GO_TEST) ./... .PHONY: unit coverage: - go test -covermode count -coverprofile cover.out -coverpkg=./... ./... + $(GO_TEST) -covermode count -coverprofile cover.out -coverpkg=./... ./... .PHONY: coverage acceptance: acceptance-baremetal acceptance-blockstorage acceptance-compute acceptance-container acceptance-containerinfra acceptance-db acceptance-dns acceptance-identity acceptance-imageservice acceptance-keymanager acceptance-loadbalancer acceptance-messaging acceptance-networking acceptance-objectstorage acceptance-orchestration acceptance-placement acceptance-sharedfilesystems acceptance-workflow .PHONY: acceptance acceptance-baremetal: - go test -tags "fixtures acceptance" ./internal/acceptance/openstack/baremetal/... + $(GO_TEST) -tags "fixtures acceptance" ./internal/acceptance/openstack/baremetal/... .PHONY: acceptance-baremetal acceptance-blockstorage: - go test -tags "fixtures acceptance" ./internal/acceptance/openstack/blockstorage/... + $(GO_TEST) -tags "fixtures acceptance" ./internal/acceptance/openstack/blockstorage/... .PHONY: acceptance-blockstorage acceptance-compute: - go test -tags "fixtures acceptance" ./internal/acceptance/openstack/compute/... + $(GO_TEST) -tags "fixtures acceptance" ./internal/acceptance/openstack/compute/... .PHONY: acceptance-compute acceptance-container: - go test -tags "fixtures acceptance" ./internal/acceptance/openstack/container/... + $(GO_TEST) -tags "fixtures acceptance" ./internal/acceptance/openstack/container/... .PHONY: acceptance-container acceptance-containerinfra: - go test -tags "fixtures acceptance" ./internal/acceptance/openstack/containerinfra/... + $(GO_TEST) -tags "fixtures acceptance" ./internal/acceptance/openstack/containerinfra/... .PHONY: acceptance-containerinfra acceptance-db: - go test -tags "fixtures acceptance" ./internal/acceptance/openstack/db/... + $(GO_TEST) -tags "fixtures acceptance" ./internal/acceptance/openstack/db/... .PHONY: acceptance-db acceptance-dns: - go test -tags "fixtures acceptance" ./internal/acceptance/openstack/dns/... + $(GO_TEST) -tags "fixtures acceptance" ./internal/acceptance/openstack/dns/... .PHONY: acceptance-dns acceptance-identity: - go test -tags "fixtures acceptance" ./internal/acceptance/openstack/identity/... + $(GO_TEST) -tags "fixtures acceptance" ./internal/acceptance/openstack/identity/... .PHONY: acceptance-identity acceptance-image: - go test -tags "fixtures acceptance" ./internal/acceptance/openstack/imageservice/... + $(GO_TEST) -tags "fixtures acceptance" ./internal/acceptance/openstack/imageservice/... .PHONY: acceptance-image acceptance-keymanager: - go test -tags "fixtures acceptance" ./internal/acceptance/openstack/keymanager/... + $(GO_TEST) -tags "fixtures acceptance" ./internal/acceptance/openstack/keymanager/... .PHONY: acceptance-keymanager acceptance-loadbalancer: - go test -tags "fixtures acceptance" ./internal/acceptance/openstack/loadbalancer/... + $(GO_TEST) -tags "fixtures acceptance" ./internal/acceptance/openstack/loadbalancer/... .PHONY: acceptance-loadbalancer acceptance-messaging: - go test -tags "fixtures acceptance" ./internal/acceptance/openstack/messaging/... + $(GO_TEST) -tags "fixtures acceptance" ./internal/acceptance/openstack/messaging/... .PHONY: acceptance-messaging acceptance-networking: - go test -tags "fixtures acceptance" ./internal/acceptance/openstack/networking/... + $(GO_TEST) -tags "fixtures acceptance" ./internal/acceptance/openstack/networking/... .PHONY: acceptance-networking acceptance-objectstorage: - go test -tags "fixtures acceptance" ./internal/acceptance/openstack/objectstorage/... + $(GO_TEST) -tags "fixtures acceptance" ./internal/acceptance/openstack/objectstorage/... .PHONY: acceptance-objectstorage acceptance-orchestration: - go test -tags "fixtures acceptance" ./internal/acceptance/openstack/orchestration/... + $(GO_TEST) -tags "fixtures acceptance" ./internal/acceptance/openstack/orchestration/... .PHONY: acceptance-orchestration acceptance-placement: - go test -tags "fixtures acceptance" ./internal/acceptance/openstack/placement/... + $(GO_TEST) -tags "fixtures acceptance" ./internal/acceptance/openstack/placement/... .PHONY: acceptance-placement acceptance-sharedfilesystems: - go test -tags "fixtures acceptance" ./internal/acceptance/openstack/sharedfilesystems/... + $(GO_TEST) -tags "fixtures acceptance" ./internal/acceptance/openstack/sharedfilesystems/... .PHONY: acceptance-sharefilesystems acceptance-workflow: - go test -tags "fixtures acceptance" ./internal/acceptance/openstack/workflow/... + $(GO_TEST) -tags "fixtures acceptance" ./internal/acceptance/openstack/workflow/... .PHONY: acceptance-workflow From 97705e979536f57c911fac3a6234489bbb7c157e Mon Sep 17 00:00:00 2001 From: Anthony ROUSSEL Date: Sat, 16 Nov 2024 21:19:52 +0100 Subject: [PATCH 052/353] Adding CI job for testing workflow (Mistral) --- .github/workflows/functional-workflow.yaml | 67 ++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 .github/workflows/functional-workflow.yaml diff --git a/.github/workflows/functional-workflow.yaml b/.github/workflows/functional-workflow.yaml new file mode 100644 index 0000000000..f124fc6412 --- /dev/null +++ b/.github/workflows/functional-workflow.yaml @@ -0,0 +1,67 @@ +name: functional-workflow +on: + pull_request: + paths: + - '**workflow**' + schedule: + - cron: '0 0 */3 * *' +jobs: + functional-workflow: + strategy: + fail-fast: false + matrix: + include: + - name: "master" + openstack_version: "master" + ubuntu_version: "22.04" + mistral_plugin_version: "master" + additional_services: "openstack-cli-server" + - name: "dalmatian" + openstack_version: "stable/2024.2" + ubuntu_version: "22.04" + mistral_plugin_version: "stable/2024.2" + additional_services: "openstack-cli-server" + - name: "caracal" + openstack_version: "stable/2024.1" + ubuntu_version: "22.04" + mistral_plugin_version: "stable/2024.1" + additional_services: "" + - name: "bobcat" + openstack_version: "stable/2023.2" + ubuntu_version: "22.04" + # Devstack support is broken with Mistral v2023.2, and requires 2 patches: + # * https://github.com/openstack/mistral/commit/e343ccb078d8ba261ac70afca93f4358589730d3 + # * https://github.com/openstack/mistral/commit/ecdeadeb7a1aa87cba2cdb0c1a2bb1ffc4aabf25 + mistral_plugin_version: "ecdeadeb7a1aa87cba2cdb0c1a2bb1ffc4aabf25" + additional_services: "" + runs-on: ubuntu-${{ matrix.ubuntu_version }} + name: Deploy OpenStack ${{ matrix.name }} with Mistral and run workflow acceptance tests + steps: + - name: Checkout Gophercloud + uses: actions/checkout@v4 + - name: Deploy devstack + uses: EmilienM/devstack-action@e82a9cbead099cba72f99537e82a360c3e319c69 + with: + branch: ${{ matrix.openstack_version }} + conf_overrides: | + enable_plugin mistral https://github.com/openstack/mistral ${{ matrix.mistral_plugin_version }} + enabled_services: "mistral,mistral-api,mistral-engine,mistral-executor,mistral-event-engine,${{ matrix.additional_services }}" + - name: Checkout go + uses: actions/setup-go@v5 + with: + go-version: '^1.22' + - name: Run Gophercloud acceptance tests + run: ./script/acceptancetest + env: + DEVSTACK_PATH: ${{ github.workspace }}/devstack + PACKAGE: "./internal/acceptance/openstack/workflow/..." + OS_BRANCH: ${{ matrix.openstack_version }} + - name: Generate logs on failure + run: ./script/collectlogs + if: failure() + - name: Upload logs artifacts on failure + if: failure() + uses: actions/upload-artifact@v4 + with: + name: functional-workflow-${{ matrix.name }}-${{ github.run_id }} + path: /tmp/devstack-logs/* From 391057892a7e50e03801278658d15e53cb84ae6b Mon Sep 17 00:00:00 2001 From: Emilien Macchi Date: Thu, 26 Sep 2024 11:57:07 -0400 Subject: [PATCH 053/353] Merge pull request #3187 from shiftstack/label-needs-tests Add label: just-needs-tests --- .github/labels.yaml | 3 +++ .github/workflows/functional-baremetal.yaml | 5 +++++ .github/workflows/functional-basic.yaml | 4 ++++ .github/workflows/functional-blockstorage.yaml | 4 ++++ .github/workflows/functional-compute.yaml | 4 ++++ .github/workflows/functional-containerinfra.yaml | 7 +++++++ .github/workflows/functional-dns.yaml | 4 ++++ .github/workflows/functional-fwaas_v2.yaml | 4 ++++ .github/workflows/functional-identity.yaml | 4 ++++ .github/workflows/functional-image.yaml | 4 ++++ .github/workflows/functional-keymanager.yaml | 4 ++++ .github/workflows/functional-loadbalancer.yaml | 4 ++++ .github/workflows/functional-messaging.yaml | 4 ++++ .github/workflows/functional-networking.yaml | 4 ++++ .github/workflows/functional-objectstorage.yaml | 4 ++++ .github/workflows/functional-orchestration.yaml | 4 ++++ .github/workflows/functional-placement.yaml | 4 ++++ .github/workflows/functional-sharedfilesystems.yaml | 4 ++++ 18 files changed, 75 insertions(+) diff --git a/.github/labels.yaml b/.github/labels.yaml index 4f888b4d4f..ad21863831 100644 --- a/.github/labels.yaml +++ b/.github/labels.yaml @@ -22,6 +22,9 @@ - color: 'F9D0C4' description: Additional information requested name: needinfo +- color: 'FEF2C0' + description: This PR lacks tests before it can be merged + name: just-needs-tests - color: '30ABB9' description: This PR targets v1 diff --git a/.github/workflows/functional-baremetal.yaml b/.github/workflows/functional-baremetal.yaml index adfb726385..e9ccef16ec 100644 --- a/.github/workflows/functional-baremetal.yaml +++ b/.github/workflows/functional-baremetal.yaml @@ -14,6 +14,11 @@ jobs: - name: "master" openstack_version: "master" ubuntu_version: "22.04" + use_system_scope: true + additional_services: "openstack-cli-server" + - name: "dalmatian" + openstack_version: "stable/2024.2" + ubuntu_version: "22.04" # NOTE(dtantsur): this forces running tests with a system scope # token, which is required for certain actions. Use it on versions # starting with 2024.1. diff --git a/.github/workflows/functional-basic.yaml b/.github/workflows/functional-basic.yaml index 0cad444eac..718e4eba57 100644 --- a/.github/workflows/functional-basic.yaml +++ b/.github/workflows/functional-basic.yaml @@ -18,6 +18,10 @@ jobs: openstack_version: "master" ubuntu_version: "22.04" additional_services: "openstack-cli-server" + - name: "dalmatian" + openstack_version: "stable/2024.2" + ubuntu_version: "22.04" + additional_services: "openstack-cli-server" - name: "caracal" openstack_version: "stable/2024.1" ubuntu_version: "22.04" diff --git a/.github/workflows/functional-blockstorage.yaml b/.github/workflows/functional-blockstorage.yaml index df08b64f9d..68e5832e39 100644 --- a/.github/workflows/functional-blockstorage.yaml +++ b/.github/workflows/functional-blockstorage.yaml @@ -15,6 +15,10 @@ jobs: openstack_version: "master" ubuntu_version: "22.04" additional_services: "openstack-cli-server" + - name: "dalmatian" + openstack_version: "stable/2024.2" + ubuntu_version: "22.04" + additional_services: "openstack-cli-server" - name: "caracal" openstack_version: "stable/2024.1" ubuntu_version: "22.04" diff --git a/.github/workflows/functional-compute.yaml b/.github/workflows/functional-compute.yaml index 6600138f96..2db1173327 100644 --- a/.github/workflows/functional-compute.yaml +++ b/.github/workflows/functional-compute.yaml @@ -15,6 +15,10 @@ jobs: openstack_version: "master" ubuntu_version: "22.04" additional_services: "openstack-cli-server" + - name: "dalmatian" + openstack_version: "stable/2024.2" + ubuntu_version: "22.04" + additional_services: "openstack-cli-server" - name: "caracal" openstack_version: "stable/2024.1" ubuntu_version: "22.04" diff --git a/.github/workflows/functional-containerinfra.yaml b/.github/workflows/functional-containerinfra.yaml index e4f6d71444..0cbb4b47da 100644 --- a/.github/workflows/functional-containerinfra.yaml +++ b/.github/workflows/functional-containerinfra.yaml @@ -18,6 +18,13 @@ jobs: enable_plugin magnum https://github.com/openstack/magnum master MAGNUMCLIENT_BRANCH=master additional_services: "openstack-cli-server" + - name: "dalmatian" + openstack_version: "stable/2024.2" + ubuntu_version: "22.04" + devstack_conf_overrides: | + enable_plugin magnum https://github.com/openstack/magnum stable/2024.2 + MAGNUMCLIENT_BRANCH=stable/2024.2 + additional_services: "openstack-cli-server" - name: "caracal" openstack_version: "stable/2024.1" ubuntu_version: "22.04" diff --git a/.github/workflows/functional-dns.yaml b/.github/workflows/functional-dns.yaml index ffeac43918..8fb1b24f9d 100644 --- a/.github/workflows/functional-dns.yaml +++ b/.github/workflows/functional-dns.yaml @@ -16,6 +16,10 @@ jobs: openstack_version: "master" ubuntu_version: "22.04" additional_services: "openstack-cli-server" + - name: "dalmatian" + openstack_version: "stable/2024.2" + ubuntu_version: "22.04" + additional_services: "openstack-cli-server" - name: "caracal" openstack_version: "stable/2024.1" ubuntu_version: "22.04" diff --git a/.github/workflows/functional-fwaas_v2.yaml b/.github/workflows/functional-fwaas_v2.yaml index 53a94d76c2..b741554451 100644 --- a/.github/workflows/functional-fwaas_v2.yaml +++ b/.github/workflows/functional-fwaas_v2.yaml @@ -15,6 +15,10 @@ jobs: openstack_version: "master" ubuntu_version: "22.04" additional_services: "openstack-cli-server" + - name: "dalmatian" + openstack_version: "stable/2024.2" + ubuntu_version: "22.04" + additional_services: "openstack-cli-server" - name: "caracal" openstack_version: "stable/2024.1" ubuntu_version: "22.04" diff --git a/.github/workflows/functional-identity.yaml b/.github/workflows/functional-identity.yaml index 1b11132609..e2ff7284ca 100644 --- a/.github/workflows/functional-identity.yaml +++ b/.github/workflows/functional-identity.yaml @@ -15,6 +15,10 @@ jobs: openstack_version: "master" ubuntu_version: "22.04" additional_services: "openstack-cli-server" + - name: "dalmatian" + openstack_version: "stable/2024.2" + ubuntu_version: "22.04" + additional_services: "openstack-cli-server" - name: "caracal" openstack_version: "stable/2024.1" ubuntu_version: "22.04" diff --git a/.github/workflows/functional-image.yaml b/.github/workflows/functional-image.yaml index 0d9855d5f1..410384cad7 100644 --- a/.github/workflows/functional-image.yaml +++ b/.github/workflows/functional-image.yaml @@ -15,6 +15,10 @@ jobs: openstack_version: "master" ubuntu_version: "22.04" additional_services: "openstack-cli-server" + - name: "dalmatian" + openstack_version: "stable/2024.2" + ubuntu_version: "22.04" + additional_services: "openstack-cli-server" - name: "caracal" openstack_version: "stable/2024.1" ubuntu_version: "22.04" diff --git a/.github/workflows/functional-keymanager.yaml b/.github/workflows/functional-keymanager.yaml index 979227ae92..06ddd57d3b 100644 --- a/.github/workflows/functional-keymanager.yaml +++ b/.github/workflows/functional-keymanager.yaml @@ -15,6 +15,10 @@ jobs: openstack_version: "master" ubuntu_version: "22.04" additional_services: "openstack-cli-server" + - name: "dalmatian" + openstack_version: "stable/2024.2" + ubuntu_version: "22.04" + additional_services: "openstack-cli-server" - name: "caracal" openstack_version: "stable/2024.1" ubuntu_version: "22.04" diff --git a/.github/workflows/functional-loadbalancer.yaml b/.github/workflows/functional-loadbalancer.yaml index 7a91c91e71..77a637375a 100644 --- a/.github/workflows/functional-loadbalancer.yaml +++ b/.github/workflows/functional-loadbalancer.yaml @@ -15,6 +15,10 @@ jobs: openstack_version: "master" ubuntu_version: "22.04" additional_services: "openstack-cli-server" + - name: "dalmatian" + openstack_version: "stable/2024.2" + ubuntu_version: "22.04" + additional_services: "openstack-cli-server" - name: "caracal" openstack_version: "stable/2024.1" ubuntu_version: "22.04" diff --git a/.github/workflows/functional-messaging.yaml b/.github/workflows/functional-messaging.yaml index 98fe43d421..8576e41a0d 100644 --- a/.github/workflows/functional-messaging.yaml +++ b/.github/workflows/functional-messaging.yaml @@ -15,6 +15,10 @@ jobs: openstack_version: "master" ubuntu_version: "22.04" additional_services: "openstack-cli-server" + - name: "dalmatian" + openstack_version: "stable/2024.2" + ubuntu_version: "22.04" + additional_services: "openstack-cli-server" - name: "caracal" openstack_version: "stable/2024.1" ubuntu_version: "22.04" diff --git a/.github/workflows/functional-networking.yaml b/.github/workflows/functional-networking.yaml index fba964795a..cba8fb2cc4 100644 --- a/.github/workflows/functional-networking.yaml +++ b/.github/workflows/functional-networking.yaml @@ -15,6 +15,10 @@ jobs: openstack_version: "master" ubuntu_version: "22.04" additional_services: "openstack-cli-server" + - name: "dalmatian" + openstack_version: "stable/2024.2" + ubuntu_version: "22.04" + additional_services: "openstack-cli-server" - name: "caracal" openstack_version: "stable/2024.1" ubuntu_version: "22.04" diff --git a/.github/workflows/functional-objectstorage.yaml b/.github/workflows/functional-objectstorage.yaml index 54e9b52bf2..f2d4a2d58c 100644 --- a/.github/workflows/functional-objectstorage.yaml +++ b/.github/workflows/functional-objectstorage.yaml @@ -15,6 +15,10 @@ jobs: openstack_version: "master" ubuntu_version: "22.04" additional_services: "openstack-cli-server" + - name: "dalmatian" + openstack_version: "stable/2024.2" + ubuntu_version: "22.04" + additional_services: "openstack-cli-server" - name: "caracal" openstack_version: "stable/2024.1" ubuntu_version: "22.04" diff --git a/.github/workflows/functional-orchestration.yaml b/.github/workflows/functional-orchestration.yaml index 1423d8f9af..fefc9b550e 100644 --- a/.github/workflows/functional-orchestration.yaml +++ b/.github/workflows/functional-orchestration.yaml @@ -15,6 +15,10 @@ jobs: openstack_version: "master" ubuntu_version: "22.04" additional_services: "openstack-cli-server" + - name: "dalmatian" + openstack_version: "stable/2024.2" + ubuntu_version: "22.04" + additional_services: "openstack-cli-server" - name: "caracal" openstack_version: "stable/2024.1" ubuntu_version: "22.04" diff --git a/.github/workflows/functional-placement.yaml b/.github/workflows/functional-placement.yaml index d138a53175..d8b31f2ad8 100644 --- a/.github/workflows/functional-placement.yaml +++ b/.github/workflows/functional-placement.yaml @@ -15,6 +15,10 @@ jobs: openstack_version: "master" ubuntu_version: "22.04" additional_services: "openstack-cli-server" + - name: "dalmatian" + openstack_version: "stable/2024.2" + ubuntu_version: "22.04" + additional_services: "openstack-cli-server" - name: "caracal" openstack_version: "stable/2024.1" ubuntu_version: "22.04" diff --git a/.github/workflows/functional-sharedfilesystems.yaml b/.github/workflows/functional-sharedfilesystems.yaml index c799250d7e..cca13e788c 100644 --- a/.github/workflows/functional-sharedfilesystems.yaml +++ b/.github/workflows/functional-sharedfilesystems.yaml @@ -15,6 +15,10 @@ jobs: openstack_version: "master" ubuntu_version: "22.04" additional_services: "openstack-cli-server" + - name: "dalmatian" + openstack_version: "stable/2024.2" + ubuntu_version: "22.04" + additional_services: "openstack-cli-server" - name: "caracal" openstack_version: "stable/2024.1" ubuntu_version: "22.04" From 9e952bb9cc3e8a5cc3fd6cf32ffc7a78a700cc52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Andr=C3=A9?= Date: Wed, 11 Sep 2024 17:16:00 +0200 Subject: [PATCH 054/353] migration.md: exclude vendor directory for automated script --- docs/MIGRATING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/MIGRATING.md b/docs/MIGRATING.md index c398cf0e65..75c4724a95 100644 --- a/docs/MIGRATING.md +++ b/docs/MIGRATING.md @@ -519,7 +519,7 @@ blockstorageversion=v3 openstack='github.com/gophercloud/gophercloud/openstack' openstack_utils='github.com/gophercloud/utils/openstack' -find . -type f -name '*.go' -exec sed -i ' +find . -type f -name '*.go' -not -path "*/vendor/*" -exec sed -i ' /^import ($/,/^)$/ { # 1: These packages have been removed and their functionality moved into the main module for the corresponding service. From f6b7b21db3e7cc578df5b1fc5ded9a8ab09b76a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Andr=C3=A9?= Date: Wed, 11 Sep 2024 17:18:03 +0200 Subject: [PATCH 055/353] migration.md: try converting more error types We should try converting all ErrDefaultXXX errors that existed in gophercloud v1 to their net/http equivalent. --- docs/MIGRATING.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/docs/MIGRATING.md b/docs/MIGRATING.md index 75c4724a95..7bf4ed9708 100644 --- a/docs/MIGRATING.md +++ b/docs/MIGRATING.md @@ -611,8 +611,19 @@ find . -type f -name '*.go' -not -path "*/vendor/*" -exec sed -i ' # 8: Rename identifiers that were changed in v2 s#\(\(volumes\|servers\)\.SchedulerHint\)s#\2.SchedulerHintOpts#g - # 9: Tentatively replace error handling for 404s + # 9: Tentatively replace error handling + s#\(\t\+\)if _, ok := err.(gophercloud.ErrDefault400); \(!\?\)ok {#\1if \2gophercloud.ResponseCodeIs(err, http.StatusBadRequest) {#g + s#\(\t\+\)if _, ok := err.(gophercloud.ErrDefault401); \(!\?\)ok {#\1if \2gophercloud.ResponseCodeIs(err, http.StatusUnauthorized) {#g + s#\(\t\+\)if _, ok := err.(gophercloud.ErrDefault403); \(!\?\)ok {#\1if \2gophercloud.ResponseCodeIs(err, http.StatusForbidden) {#g s#\(\t\+\)if _, ok := err.(gophercloud.ErrDefault404); \(!\?\)ok {#\1if \2gophercloud.ResponseCodeIs(err, http.StatusNotFound) {#g + s#\(\t\+\)if _, ok := err.(gophercloud.ErrDefault405); \(!\?\)ok {#\1if \2gophercloud.ResponseCodeIs(err, http.StatusMethodNotAllowed) {#g + s#\(\t\+\)if _, ok := err.(gophercloud.ErrDefault408); \(!\?\)ok {#\1if \2gophercloud.ResponseCodeIs(err, http.StatusRequestTimeout) {#g + s#\(\t\+\)if _, ok := err.(gophercloud.ErrDefault409); \(!\?\)ok {#\1if \2gophercloud.ResponseCodeIs(err, http.StatusConflict) {#g + s#\(\t\+\)if _, ok := err.(gophercloud.ErrDefault429); \(!\?\)ok {#\1if \2gophercloud.ResponseCodeIs(err, http.StatusTooManyRequests) {#g + s#\(\t\+\)if _, ok := err.(gophercloud.ErrDefault500); \(!\?\)ok {#\1if \2gophercloud.ResponseCodeIs(err, http.StatusInternalServerError) {#g + s#\(\t\+\)if _, ok := err.(gophercloud.ErrDefault502); \(!\?\)ok {#\1if \2gophercloud.ResponseCodeIs(err, http.StatusBadGateway) {#g + s#\(\t\+\)if _, ok := err.(gophercloud.ErrDefault503); \(!\?\)ok {#\1if \2gophercloud.ResponseCodeIs(err, http.StatusServiceUnavailable) {#g + s#\(\t\+\)if _, ok := err.(gophercloud.ErrDefault504); \(!\?\)ok {#\1if \2gophercloud.ResponseCodeIs(err, http.StatusGatewayTimeout) {#g } ' {} \; From 1a2d7e559323c3242ce109a930da47af2904cf1e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 8 Nov 2024 09:21:06 +0000 Subject: [PATCH 056/353] build(deps): bump golang.org/x/crypto from 0.28.0 to 0.29.0 Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.28.0 to 0.29.0. - [Commits](https://github.com/golang/crypto/compare/v0.28.0...v0.29.0) --- updated-dependencies: - dependency-name: golang.org/x/crypto dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 4 ++-- go.sum | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/go.mod b/go.mod index 8e527ec8e5..45961985de 100644 --- a/go.mod +++ b/go.mod @@ -3,8 +3,8 @@ module github.com/gophercloud/gophercloud/v2 go 1.22 require ( - golang.org/x/crypto v0.28.0 + golang.org/x/crypto v0.29.0 gopkg.in/yaml.v2 v2.4.0 ) -require golang.org/x/sys v0.26.0 // indirect +require golang.org/x/sys v0.27.0 // indirect diff --git a/go.sum b/go.sum index 7cc4cf43b5..a14f597436 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,9 @@ -golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= -golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= -golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= -golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24= -golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M= +golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ= +golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg= +golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= +golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.26.0 h1:WEQa6V3Gja/BhNxg540hBip/kkaYtRg3cxg4oXSw4AU= +golang.org/x/term v0.26.0/go.mod h1:Si5m1o57C5nBNQo5z1iq+XDijt21BDBDp2bK0QI8e3E= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= From 066e8d7a567b2b974041d7a75894d939dc62b5dc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 5 Dec 2024 10:00:56 +0000 Subject: [PATCH 057/353] build(deps): bump golang.org/x/crypto from 0.29.0 to 0.30.0 Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.29.0 to 0.30.0. - [Commits](https://github.com/golang/crypto/compare/v0.29.0...v0.30.0) --- updated-dependencies: - dependency-name: golang.org/x/crypto dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 4 ++-- go.sum | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/go.mod b/go.mod index 45961985de..dc5d92e323 100644 --- a/go.mod +++ b/go.mod @@ -3,8 +3,8 @@ module github.com/gophercloud/gophercloud/v2 go 1.22 require ( - golang.org/x/crypto v0.29.0 + golang.org/x/crypto v0.30.0 gopkg.in/yaml.v2 v2.4.0 ) -require golang.org/x/sys v0.27.0 // indirect +require golang.org/x/sys v0.28.0 // indirect diff --git a/go.sum b/go.sum index a14f597436..1812f7828d 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,9 @@ -golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ= -golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg= -golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= -golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.26.0 h1:WEQa6V3Gja/BhNxg540hBip/kkaYtRg3cxg4oXSw4AU= -golang.org/x/term v0.26.0/go.mod h1:Si5m1o57C5nBNQo5z1iq+XDijt21BDBDp2bK0QI8e3E= +golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY= +golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= +golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= From 301d0bdc62ffd4601edb396ccba6c3e9e7fe2010 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Tue, 16 Jul 2024 14:49:49 +0100 Subject: [PATCH 058/353] CI: Append job ID to artifact name Otherwise you end up with lots of duplicate 'functional-{service}-{branch}' tarballs when debugging. Signed-off-by: Stephen Finucane --- .github/workflows/functional-baremetal.yaml | 2 +- .github/workflows/functional-basic.yaml | 2 +- .github/workflows/functional-blockstorage.yaml | 2 +- .github/workflows/functional-compute.yaml | 2 +- .github/workflows/functional-containerinfra.yaml | 2 +- .github/workflows/functional-dns.yaml | 2 +- .github/workflows/functional-fwaas_v2.yaml | 2 +- .github/workflows/functional-identity.yaml | 2 +- .github/workflows/functional-image.yaml | 2 +- .github/workflows/functional-keymanager.yaml | 2 +- .github/workflows/functional-loadbalancer.yaml | 2 +- .github/workflows/functional-messaging.yaml | 2 +- .github/workflows/functional-networking.yaml | 2 +- .github/workflows/functional-objectstorage.yaml | 2 +- .github/workflows/functional-orchestration.yaml | 2 +- .github/workflows/functional-placement.yaml | 2 +- .github/workflows/functional-sharedfilesystems.yaml | 2 +- 17 files changed, 17 insertions(+), 17 deletions(-) diff --git a/.github/workflows/functional-baremetal.yaml b/.github/workflows/functional-baremetal.yaml index adfb726385..ac51bf0a82 100644 --- a/.github/workflows/functional-baremetal.yaml +++ b/.github/workflows/functional-baremetal.yaml @@ -102,5 +102,5 @@ jobs: if: failure() uses: actions/upload-artifact@v4 with: - name: functional-baremetal-${{ matrix.name }} + name: functional-baremetal-${{ matrix.name }}-${{ github.run_id }} path: /tmp/devstack-logs/* diff --git a/.github/workflows/functional-basic.yaml b/.github/workflows/functional-basic.yaml index 0cad444eac..91fa29ad65 100644 --- a/.github/workflows/functional-basic.yaml +++ b/.github/workflows/functional-basic.yaml @@ -53,5 +53,5 @@ jobs: if: failure() uses: actions/upload-artifact@v4 with: - name: functional-basic-${{ matrix.name }} + name: functional-basic-${{ matrix.name }}-${{ github.run_id }} path: /tmp/devstack-logs/* diff --git a/.github/workflows/functional-blockstorage.yaml b/.github/workflows/functional-blockstorage.yaml index df08b64f9d..9ef59a7e41 100644 --- a/.github/workflows/functional-blockstorage.yaml +++ b/.github/workflows/functional-blockstorage.yaml @@ -52,5 +52,5 @@ jobs: if: failure() uses: actions/upload-artifact@v4 with: - name: functional-blockstorage-${{ matrix.name }} + name: functional-blockstorage-${{ matrix.name }}-${{ github.run_id }} path: /tmp/devstack-logs/* diff --git a/.github/workflows/functional-compute.yaml b/.github/workflows/functional-compute.yaml index 6600138f96..f55363f3c1 100644 --- a/.github/workflows/functional-compute.yaml +++ b/.github/workflows/functional-compute.yaml @@ -52,5 +52,5 @@ jobs: if: failure() uses: actions/upload-artifact@v4 with: - name: functional-compute-${{ matrix.name }} + name: functional-compute-${{ matrix.name }}-${{ github.run_id }} path: /tmp/devstack-logs/* diff --git a/.github/workflows/functional-containerinfra.yaml b/.github/workflows/functional-containerinfra.yaml index e4f6d71444..d13cbac8dc 100644 --- a/.github/workflows/functional-containerinfra.yaml +++ b/.github/workflows/functional-containerinfra.yaml @@ -66,5 +66,5 @@ jobs: if: failure() uses: actions/upload-artifact@v4 with: - name: functional-containerinfra-${{ matrix.name }} + name: functional-containerinfra-${{ matrix.name }}-${{ github.run_id }} path: /tmp/devstack-logs/* diff --git a/.github/workflows/functional-dns.yaml b/.github/workflows/functional-dns.yaml index ffeac43918..0650723b4b 100644 --- a/.github/workflows/functional-dns.yaml +++ b/.github/workflows/functional-dns.yaml @@ -53,5 +53,5 @@ jobs: if: failure() uses: actions/upload-artifact@v4 with: - name: functional-dns-${{ matrix.name }} + name: functional-dns-${{ matrix.name }}-${{ github.run_id }} path: /tmp/devstack-logs/* diff --git a/.github/workflows/functional-fwaas_v2.yaml b/.github/workflows/functional-fwaas_v2.yaml index 53a94d76c2..cebce8e0af 100644 --- a/.github/workflows/functional-fwaas_v2.yaml +++ b/.github/workflows/functional-fwaas_v2.yaml @@ -57,5 +57,5 @@ jobs: if: failure() uses: actions/upload-artifact@v4 with: - name: functional-fwaas_v2-${{ matrix.name }} + name: functional-fwaas_v2-${{ matrix.name }}-${{ github.run_id }} path: /tmp/devstack-logs/* diff --git a/.github/workflows/functional-identity.yaml b/.github/workflows/functional-identity.yaml index 1b11132609..5d15245912 100644 --- a/.github/workflows/functional-identity.yaml +++ b/.github/workflows/functional-identity.yaml @@ -50,5 +50,5 @@ jobs: if: failure() uses: actions/upload-artifact@v4 with: - name: functional-identity-${{ matrix.name }} + name: functional-identity-${{ matrix.name }}-${{ github.run_id }} path: /tmp/devstack-logs/* diff --git a/.github/workflows/functional-image.yaml b/.github/workflows/functional-image.yaml index 0d9855d5f1..606b756d1c 100644 --- a/.github/workflows/functional-image.yaml +++ b/.github/workflows/functional-image.yaml @@ -50,5 +50,5 @@ jobs: if: failure() uses: actions/upload-artifact@v4 with: - name: functional-image-${{ matrix.name }} + name: functional-image-${{ matrix.name }}-${{ github.run_id }} path: /tmp/devstack-logs/* diff --git a/.github/workflows/functional-keymanager.yaml b/.github/workflows/functional-keymanager.yaml index 979227ae92..4af4af43f2 100644 --- a/.github/workflows/functional-keymanager.yaml +++ b/.github/workflows/functional-keymanager.yaml @@ -52,5 +52,5 @@ jobs: if: failure() uses: actions/upload-artifact@v4 with: - name: functional-keymanager-${{ matrix.name }} + name: functional-keymanager-${{ matrix.name }}-${{ github.run_id }} path: /tmp/devstack-logs/* diff --git a/.github/workflows/functional-loadbalancer.yaml b/.github/workflows/functional-loadbalancer.yaml index 7a91c91e71..3ce2c21e09 100644 --- a/.github/workflows/functional-loadbalancer.yaml +++ b/.github/workflows/functional-loadbalancer.yaml @@ -53,5 +53,5 @@ jobs: if: failure() uses: actions/upload-artifact@v4 with: - name: functional-loadbalancer-${{ matrix.name }} + name: functional-loadbalancer-${{ matrix.name }}-${{ github.run_id }} path: /tmp/devstack-logs/* diff --git a/.github/workflows/functional-messaging.yaml b/.github/workflows/functional-messaging.yaml index 98fe43d421..fa1dedb63f 100644 --- a/.github/workflows/functional-messaging.yaml +++ b/.github/workflows/functional-messaging.yaml @@ -53,5 +53,5 @@ jobs: if: failure() uses: actions/upload-artifact@v4 with: - name: functional-messaging-${{ matrix.name }} + name: functional-messaging-${{ matrix.name }}-${{ github.run_id }} path: /tmp/devstack-logs/* diff --git a/.github/workflows/functional-networking.yaml b/.github/workflows/functional-networking.yaml index fba964795a..e8526c7a9d 100644 --- a/.github/workflows/functional-networking.yaml +++ b/.github/workflows/functional-networking.yaml @@ -67,5 +67,5 @@ jobs: if: failure() uses: actions/upload-artifact@v4 with: - name: functional-networking-${{ matrix.name }} + name: functional-networking-${{ matrix.name }}-${{ github.run_id }} path: /tmp/devstack-logs/* diff --git a/.github/workflows/functional-objectstorage.yaml b/.github/workflows/functional-objectstorage.yaml index 54e9b52bf2..abd5738697 100644 --- a/.github/workflows/functional-objectstorage.yaml +++ b/.github/workflows/functional-objectstorage.yaml @@ -56,5 +56,5 @@ jobs: if: failure() uses: actions/upload-artifact@v4 with: - name: functional-objectstorage-${{ matrix.name }} + name: functional-objectstorage-${{ matrix.name }}-${{ github.run_id }} path: /tmp/devstack-logs/* diff --git a/.github/workflows/functional-orchestration.yaml b/.github/workflows/functional-orchestration.yaml index 1423d8f9af..a02f435cd2 100644 --- a/.github/workflows/functional-orchestration.yaml +++ b/.github/workflows/functional-orchestration.yaml @@ -52,5 +52,5 @@ jobs: if: failure() uses: actions/upload-artifact@v4 with: - name: functional-orchestration-${{ matrix.name }} + name: functional-orchestration-${{ matrix.name }}-${{ github.run_id }} path: /tmp/devstack-logs/* diff --git a/.github/workflows/functional-placement.yaml b/.github/workflows/functional-placement.yaml index d138a53175..4cca481f7d 100644 --- a/.github/workflows/functional-placement.yaml +++ b/.github/workflows/functional-placement.yaml @@ -50,5 +50,5 @@ jobs: if: failure() uses: actions/upload-artifact@v4 with: - name: functional-placement-${{ matrix.name }} + name: functional-placement-${{ matrix.name }}-${{ github.run_id }} path: /tmp/devstack-logs/* diff --git a/.github/workflows/functional-sharedfilesystems.yaml b/.github/workflows/functional-sharedfilesystems.yaml index c799250d7e..93822175a7 100644 --- a/.github/workflows/functional-sharedfilesystems.yaml +++ b/.github/workflows/functional-sharedfilesystems.yaml @@ -66,5 +66,5 @@ jobs: if: failure() uses: actions/upload-artifact@v4 with: - name: functional-sharedfilesystems-${{ matrix.name }} + name: functional-sharedfilesystems-${{ matrix.name }}-${{ github.run_id }} path: /tmp/devstack-logs/* From c09920f72767a08566c203d709d35ea8cad41058 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Wed, 29 May 2024 14:46:10 +0100 Subject: [PATCH 059/353] make: Add 'format' target Signed-off-by: Stephen Finucane --- Makefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Makefile b/Makefile index 2a7a9376d9..066946cf8d 100644 --- a/Makefile +++ b/Makefile @@ -26,6 +26,10 @@ lint: golangci/golangci-lint:$(GOLANGCI_LINT_VERSION) golangci-lint run .PHONY: lint +format: + gofmt -w -s $(shell pwd) +.PHONY: format + unit: $(GO_TEST) ./... .PHONY: unit From 5a5a01107676b08d31de71b34918459eaf37792b Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Thu, 28 Nov 2024 13:49:00 +0000 Subject: [PATCH 060/353] script: Remove unused bootstrap script This is not referenced or documented anywhere and it has not been touched in years. Remove it. Signed-off-by: Stephen Finucane --- script/bootstrap | 25 ------------------------- 1 file changed, 25 deletions(-) delete mode 100755 script/bootstrap diff --git a/script/bootstrap b/script/bootstrap deleted file mode 100755 index 78a195dcf7..0000000000 --- a/script/bootstrap +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/bash -# -# This script helps new contributors set up their local workstation for -# gophercloud development and contributions. - -# Create the environment -export GOPATH=$HOME/go/gophercloud -mkdir -p $GOPATH - -# Download gophercloud into that environment -go get github.com/gophercloud/gophercloud -cd $GOPATH/src/github.com/gophercloud/gophercloud -git checkout master - -# Write out the env.sh convenience file. -cd $GOPATH -cat <env.sh -#!/bin/bash -export GOPATH=$(pwd) -export GOPHERCLOUD=$GOPATH/src/github.com/gophercloud/gophercloud -EOF -chmod a+x env.sh - -# Make changes immediately available as a convenience. -. ./env.sh From 7225da7ad1289ca6c15465f0badf655b880d690e Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Wed, 20 Mar 2024 13:31:11 +0000 Subject: [PATCH 061/353] trivial: Consistent file extensions Signed-off-by: Stephen Finucane --- .github/{dependabot.yml => dependabot.yaml} | 0 .github/workflows/{codeql-analysis.yml => codeql-analysis.yaml} | 0 .github/workflows/{greetings.yml => greetings.yaml} | 0 .github/workflows/{unit.yml => unit.yaml} | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename .github/{dependabot.yml => dependabot.yaml} (100%) rename .github/workflows/{codeql-analysis.yml => codeql-analysis.yaml} (100%) rename .github/workflows/{greetings.yml => greetings.yaml} (100%) rename .github/workflows/{unit.yml => unit.yaml} (100%) diff --git a/.github/dependabot.yml b/.github/dependabot.yaml similarity index 100% rename from .github/dependabot.yml rename to .github/dependabot.yaml diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yaml similarity index 100% rename from .github/workflows/codeql-analysis.yml rename to .github/workflows/codeql-analysis.yaml diff --git a/.github/workflows/greetings.yml b/.github/workflows/greetings.yaml similarity index 100% rename from .github/workflows/greetings.yml rename to .github/workflows/greetings.yaml diff --git a/.github/workflows/unit.yml b/.github/workflows/unit.yaml similarity index 100% rename from .github/workflows/unit.yml rename to .github/workflows/unit.yaml From e57e4475cfd81137dd92495cedc57ad473fa6b21 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Thu, 21 Mar 2024 12:23:28 +0000 Subject: [PATCH 062/353] script: Address shellcheck warnings Signed-off-by: Stephen Finucane --- script/acceptancetest | 9 +++++---- script/coverage | 3 ++- script/test | 1 + script/unittest | 1 + script/vet | 2 +- 5 files changed, 10 insertions(+), 6 deletions(-) diff --git a/script/acceptancetest b/script/acceptancetest index 234f5b0bb6..7e223bae5e 100755 --- a/script/acceptancetest +++ b/script/acceptancetest @@ -7,19 +7,20 @@ # flags and things crash and burn *spectacularly* 🔥🔥🔥 set -xo pipefail -source $(dirname $0)/stackenv +# shellcheck disable=SC1091 +source "$(dirname "$0")/stackenv" # ...but we can do it after the fact set -eu timeout="60m" -failed= LOG_DIR=${LOG_DIR:-} if [[ -z "${LOG_DIR}" ]]; then echo "LOG_DIR not set, will set a temp directory" LOG_DIR=/tmp/devstack-logs fi -mkdir -p ${LOG_DIR} +mkdir -p "${LOG_DIR}" -go test -v -timeout $timeout -tags "fixtures acceptance" ${PACKAGE:-./internal/acceptance/openstack/...} $@ |& tee -a ${LOG_DIR}/acceptance_tests.log +# shellcheck disable=SC2068 +go test -v -timeout $timeout -tags "fixtures acceptance" "${PACKAGE:-./internal/acceptance/openstack/...}" $@ |& tee -a "${LOG_DIR}/acceptance_tests.log" diff --git a/script/coverage b/script/coverage index cd4dec06e5..ec5b2776b8 100755 --- a/script/coverage +++ b/script/coverage @@ -19,5 +19,6 @@ for path in $(find . -path '*/testing' -prune -o -path '*/internal' -prune -o -n n=$((n+1)) done -gocovmerge `ls *.coverprofile` > cover.out +# shellcheck disable=SC2046 +gocovmerge $(ls -- *.coverprofile) > cover.out rm ./*.coverprofile diff --git a/script/test b/script/test index 77f6af5017..e71e7514bb 100755 --- a/script/test +++ b/script/test @@ -4,4 +4,5 @@ set -euxo pipefail +# shellcheck disable=SC2068 go test -v -tags 'acceptance fixtures' ./... $@ diff --git a/script/unittest b/script/unittest index 2763e0efd9..1f1b1864f4 100755 --- a/script/unittest +++ b/script/unittest @@ -6,4 +6,5 @@ set -euxo pipefail # Do extra rounds of testing to help identify reauth concurrency issues. # All other packages are tested in the `coverage` tests. +# shellcheck disable=SC2068 go test -v -race -count=5 ./testing $@ diff --git a/script/vet b/script/vet index 4f3db40a28..ecb74ef37d 100755 --- a/script/vet +++ b/script/vet @@ -4,5 +4,5 @@ set -euxo pipefail -GOFLAGS="-tags=acceptance" +export GOFLAGS="-tags=acceptance" go vet ./... From 9490b5d314671e97953f1a39dead4456956532b0 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Thu, 30 May 2024 23:51:52 +0100 Subject: [PATCH 063/353] tests: Consist use of th alias testhelper is too long give how often these things are used. Signed-off-by: Stephen Finucane --- .../v1/nodes/testing/results_test.go | 50 +++---- .../schedulerstats/testing/fixtures_test.go | 8 +- .../schedulerstats/testing/requests_test.go | 14 +- .../v2/services/testing/requests_test.go | 14 +- .../schedulerstats/testing/fixtures_test.go | 8 +- .../schedulerstats/testing/requests_test.go | 14 +- .../v3/services/testing/requests_test.go | 14 +- .../v2/hypervisors/testing/fixtures_test.go | 52 +++---- .../v2/hypervisors/testing/requests_test.go | 98 ++++++------- .../v2/services/testing/requests_test.go | 42 +++--- .../v3/ec2tokens/testing/requests_test.go | 36 ++--- .../v3/oauth1/testing/fixtures_test.go | 136 +++++++++--------- .../identity/v3/tokens/testing/fixtures.go | 6 +- .../v3/tokens/testing/requests_test.go | 118 +++++++-------- .../v3/tokens/testing/results_test.go | 26 ++-- .../v3/trusts/testing/fixtures_test.go | 68 ++++----- .../schedulerstats/testing/fixtures_test.go | 14 +- .../schedulerstats/testing/requests_test.go | 30 ++-- .../v2/services/testing/requests_test.go | 12 +- .../utils/testing/choose_version_test.go | 66 ++++----- pagination/testing/linked_test.go | 26 ++-- pagination/testing/marker_test.go | 24 ++-- pagination/testing/pagination_test.go | 4 +- pagination/testing/single_test.go | 26 ++-- testhelper/client/fake.go | 4 +- 25 files changed, 455 insertions(+), 455 deletions(-) diff --git a/openstack/baremetal/v1/nodes/testing/results_test.go b/openstack/baremetal/v1/nodes/testing/results_test.go index 7c683ebecb..acdb59e774 100644 --- a/openstack/baremetal/v1/nodes/testing/results_test.go +++ b/openstack/baremetal/v1/nodes/testing/results_test.go @@ -8,68 +8,68 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/baremetal/v1/nodes" "github.com/gophercloud/gophercloud/v2/openstack/baremetalintrospection/v1/introspection" insptest "github.com/gophercloud/gophercloud/v2/openstack/baremetalintrospection/v1/introspection/testing" - "github.com/gophercloud/gophercloud/v2/testhelper" + th "github.com/gophercloud/gophercloud/v2/testhelper" ) func TestStandardPluginData(t *testing.T) { var pluginData nodes.PluginData err := pluginData.RawMessage.UnmarshalJSON([]byte(invtest.StandardPluginDataSample)) - testhelper.AssertNoErr(t, err) + th.AssertNoErr(t, err) parsedData, err := pluginData.AsStandardData() - testhelper.AssertNoErr(t, err) - testhelper.CheckDeepEquals(t, invtest.StandardPluginData, parsedData) + th.AssertNoErr(t, err) + th.CheckDeepEquals(t, invtest.StandardPluginData, parsedData) irData, inspData, err := pluginData.GuessFormat() - testhelper.AssertNoErr(t, err) - testhelper.CheckDeepEquals(t, invtest.StandardPluginData, *irData) - testhelper.CheckEquals(t, (*introspection.Data)(nil), inspData) + th.AssertNoErr(t, err) + th.CheckDeepEquals(t, invtest.StandardPluginData, *irData) + th.CheckEquals(t, (*introspection.Data)(nil), inspData) } func TestInspectorPluginData(t *testing.T) { var pluginData nodes.PluginData err := pluginData.RawMessage.UnmarshalJSON([]byte(insptest.IntrospectionDataJSONSample)) - testhelper.AssertNoErr(t, err) + th.AssertNoErr(t, err) parsedData, err := pluginData.AsInspectorData() - testhelper.AssertNoErr(t, err) - testhelper.CheckDeepEquals(t, insptest.IntrospectionDataRes, parsedData) + th.AssertNoErr(t, err) + th.CheckDeepEquals(t, insptest.IntrospectionDataRes, parsedData) irData, inspData, err := pluginData.GuessFormat() - testhelper.AssertNoErr(t, err) - testhelper.CheckEquals(t, (*inventory.StandardPluginData)(nil), irData) - testhelper.CheckDeepEquals(t, insptest.IntrospectionDataRes, *inspData) + th.AssertNoErr(t, err) + th.CheckEquals(t, (*inventory.StandardPluginData)(nil), irData) + th.CheckDeepEquals(t, insptest.IntrospectionDataRes, *inspData) } func TestGuessFormatUnknownDefaultsToIronic(t *testing.T) { var pluginData nodes.PluginData err := pluginData.RawMessage.UnmarshalJSON([]byte("{}")) - testhelper.AssertNoErr(t, err) + th.AssertNoErr(t, err) irData, inspData, err := pluginData.GuessFormat() - testhelper.CheckDeepEquals(t, inventory.StandardPluginData{}, *irData) - testhelper.CheckEquals(t, (*introspection.Data)(nil), inspData) - testhelper.AssertNoErr(t, err) + th.CheckDeepEquals(t, inventory.StandardPluginData{}, *irData) + th.CheckEquals(t, (*introspection.Data)(nil), inspData) + th.AssertNoErr(t, err) } func TestGuessFormatErrors(t *testing.T) { var pluginData nodes.PluginData err := pluginData.RawMessage.UnmarshalJSON([]byte("\"banana\"")) - testhelper.AssertNoErr(t, err) + th.AssertNoErr(t, err) irData, inspData, err := pluginData.GuessFormat() - testhelper.CheckEquals(t, (*inventory.StandardPluginData)(nil), irData) - testhelper.CheckEquals(t, (*introspection.Data)(nil), inspData) - testhelper.AssertErr(t, err) + th.CheckEquals(t, (*inventory.StandardPluginData)(nil), irData) + th.CheckEquals(t, (*introspection.Data)(nil), inspData) + th.AssertErr(t, err) failsInspectorConversion := `{ "interfaces": "banana" }` err = pluginData.RawMessage.UnmarshalJSON([]byte(failsInspectorConversion)) - testhelper.AssertNoErr(t, err) + th.AssertNoErr(t, err) irData, inspData, err = pluginData.GuessFormat() - testhelper.CheckEquals(t, (*inventory.StandardPluginData)(nil), irData) - testhelper.CheckEquals(t, (*introspection.Data)(nil), inspData) - testhelper.AssertErr(t, err) + th.CheckEquals(t, (*inventory.StandardPluginData)(nil), irData) + th.CheckEquals(t, (*introspection.Data)(nil), inspData) + th.AssertErr(t, err) } diff --git a/openstack/blockstorage/v2/schedulerstats/testing/fixtures_test.go b/openstack/blockstorage/v2/schedulerstats/testing/fixtures_test.go index 6f0317ef60..3a7fee8160 100644 --- a/openstack/blockstorage/v2/schedulerstats/testing/fixtures_test.go +++ b/openstack/blockstorage/v2/schedulerstats/testing/fixtures_test.go @@ -7,7 +7,7 @@ import ( "testing" "github.com/gophercloud/gophercloud/v2/openstack/blockstorage/v2/schedulerstats" - "github.com/gophercloud/gophercloud/v2/testhelper" + th "github.com/gophercloud/gophercloud/v2/testhelper" "github.com/gophercloud/gophercloud/v2/testhelper/client" ) @@ -94,9 +94,9 @@ var ( ) func HandleStoragePoolsListSuccessfully(t *testing.T) { - testhelper.Mux.HandleFunc("/scheduler-stats/get_pools", func(w http.ResponseWriter, r *http.Request) { - testhelper.TestMethod(t, r, "GET") - testhelper.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.Mux.HandleFunc("/scheduler-stats/get_pools", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") diff --git a/openstack/blockstorage/v2/schedulerstats/testing/requests_test.go b/openstack/blockstorage/v2/schedulerstats/testing/requests_test.go index 709ddeac58..7a6cb8b450 100644 --- a/openstack/blockstorage/v2/schedulerstats/testing/requests_test.go +++ b/openstack/blockstorage/v2/schedulerstats/testing/requests_test.go @@ -6,13 +6,13 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/blockstorage/v2/schedulerstats" "github.com/gophercloud/gophercloud/v2/pagination" - "github.com/gophercloud/gophercloud/v2/testhelper" + th "github.com/gophercloud/gophercloud/v2/testhelper" "github.com/gophercloud/gophercloud/v2/testhelper/client" ) func TestListStoragePoolsDetail(t *testing.T) { - testhelper.SetupHTTP() - defer testhelper.TeardownHTTP() + th.SetupHTTP() + defer th.TeardownHTTP() HandleStoragePoolsListSuccessfully(t) pages := 0 @@ -20,18 +20,18 @@ func TestListStoragePoolsDetail(t *testing.T) { pages++ actual, err := schedulerstats.ExtractStoragePools(page) - testhelper.AssertNoErr(t, err) + th.AssertNoErr(t, err) if len(actual) != 2 { t.Fatalf("Expected 2 backends, got %d", len(actual)) } - testhelper.CheckDeepEquals(t, StoragePoolFake1, actual[0]) - testhelper.CheckDeepEquals(t, StoragePoolFake2, actual[1]) + th.CheckDeepEquals(t, StoragePoolFake1, actual[0]) + th.CheckDeepEquals(t, StoragePoolFake2, actual[1]) return true, nil }) - testhelper.AssertNoErr(t, err) + th.AssertNoErr(t, err) if pages != 1 { t.Errorf("Expected 1 page, saw %d", pages) diff --git a/openstack/blockstorage/v2/services/testing/requests_test.go b/openstack/blockstorage/v2/services/testing/requests_test.go index 8ce1266d7e..d1277a99bf 100644 --- a/openstack/blockstorage/v2/services/testing/requests_test.go +++ b/openstack/blockstorage/v2/services/testing/requests_test.go @@ -6,13 +6,13 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/blockstorage/v2/services" "github.com/gophercloud/gophercloud/v2/pagination" - "github.com/gophercloud/gophercloud/v2/testhelper" + th "github.com/gophercloud/gophercloud/v2/testhelper" "github.com/gophercloud/gophercloud/v2/testhelper/client" ) func TestListServices(t *testing.T) { - testhelper.SetupHTTP() - defer testhelper.TeardownHTTP() + th.SetupHTTP() + defer th.TeardownHTTP() HandleListSuccessfully(t) pages := 0 @@ -27,14 +27,14 @@ func TestListServices(t *testing.T) { if len(actual) != 3 { t.Fatalf("Expected 3 services, got %d", len(actual)) } - testhelper.CheckDeepEquals(t, FirstFakeService, actual[0]) - testhelper.CheckDeepEquals(t, SecondFakeService, actual[1]) - testhelper.CheckDeepEquals(t, ThirdFakeService, actual[2]) + th.CheckDeepEquals(t, FirstFakeService, actual[0]) + th.CheckDeepEquals(t, SecondFakeService, actual[1]) + th.CheckDeepEquals(t, ThirdFakeService, actual[2]) return true, nil }) - testhelper.AssertNoErr(t, err) + th.AssertNoErr(t, err) if pages != 1 { t.Errorf("Expected 1 page, saw %d", pages) diff --git a/openstack/blockstorage/v3/schedulerstats/testing/fixtures_test.go b/openstack/blockstorage/v3/schedulerstats/testing/fixtures_test.go index df0ccaa7f5..0a1286e862 100644 --- a/openstack/blockstorage/v3/schedulerstats/testing/fixtures_test.go +++ b/openstack/blockstorage/v3/schedulerstats/testing/fixtures_test.go @@ -7,7 +7,7 @@ import ( "testing" "github.com/gophercloud/gophercloud/v2/openstack/blockstorage/v3/schedulerstats" - "github.com/gophercloud/gophercloud/v2/testhelper" + th "github.com/gophercloud/gophercloud/v2/testhelper" "github.com/gophercloud/gophercloud/v2/testhelper/client" ) @@ -94,9 +94,9 @@ var ( ) func HandleStoragePoolsListSuccessfully(t *testing.T) { - testhelper.Mux.HandleFunc("/scheduler-stats/get_pools", func(w http.ResponseWriter, r *http.Request) { - testhelper.TestMethod(t, r, "GET") - testhelper.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.Mux.HandleFunc("/scheduler-stats/get_pools", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") diff --git a/openstack/blockstorage/v3/schedulerstats/testing/requests_test.go b/openstack/blockstorage/v3/schedulerstats/testing/requests_test.go index b5e3f31ef6..c125763276 100644 --- a/openstack/blockstorage/v3/schedulerstats/testing/requests_test.go +++ b/openstack/blockstorage/v3/schedulerstats/testing/requests_test.go @@ -6,13 +6,13 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/blockstorage/v3/schedulerstats" "github.com/gophercloud/gophercloud/v2/pagination" - "github.com/gophercloud/gophercloud/v2/testhelper" + th "github.com/gophercloud/gophercloud/v2/testhelper" "github.com/gophercloud/gophercloud/v2/testhelper/client" ) func TestListStoragePoolsDetail(t *testing.T) { - testhelper.SetupHTTP() - defer testhelper.TeardownHTTP() + th.SetupHTTP() + defer th.TeardownHTTP() HandleStoragePoolsListSuccessfully(t) pages := 0 @@ -20,18 +20,18 @@ func TestListStoragePoolsDetail(t *testing.T) { pages++ actual, err := schedulerstats.ExtractStoragePools(page) - testhelper.AssertNoErr(t, err) + th.AssertNoErr(t, err) if len(actual) != 2 { t.Fatalf("Expected 2 backends, got %d", len(actual)) } - testhelper.CheckDeepEquals(t, StoragePoolFake1, actual[0]) - testhelper.CheckDeepEquals(t, StoragePoolFake2, actual[1]) + th.CheckDeepEquals(t, StoragePoolFake1, actual[0]) + th.CheckDeepEquals(t, StoragePoolFake2, actual[1]) return true, nil }) - testhelper.AssertNoErr(t, err) + th.AssertNoErr(t, err) if pages != 1 { t.Errorf("Expected 1 page, saw %d", pages) diff --git a/openstack/blockstorage/v3/services/testing/requests_test.go b/openstack/blockstorage/v3/services/testing/requests_test.go index 1fd5bcdd1e..4e291da96b 100644 --- a/openstack/blockstorage/v3/services/testing/requests_test.go +++ b/openstack/blockstorage/v3/services/testing/requests_test.go @@ -6,13 +6,13 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/blockstorage/v3/services" "github.com/gophercloud/gophercloud/v2/pagination" - "github.com/gophercloud/gophercloud/v2/testhelper" + th "github.com/gophercloud/gophercloud/v2/testhelper" "github.com/gophercloud/gophercloud/v2/testhelper/client" ) func TestListServices(t *testing.T) { - testhelper.SetupHTTP() - defer testhelper.TeardownHTTP() + th.SetupHTTP() + defer th.TeardownHTTP() HandleListSuccessfully(t) pages := 0 @@ -27,14 +27,14 @@ func TestListServices(t *testing.T) { if len(actual) != 3 { t.Fatalf("Expected 3 services, got %d", len(actual)) } - testhelper.CheckDeepEquals(t, FirstFakeService, actual[0]) - testhelper.CheckDeepEquals(t, SecondFakeService, actual[1]) - testhelper.CheckDeepEquals(t, ThirdFakeService, actual[2]) + th.CheckDeepEquals(t, FirstFakeService, actual[0]) + th.CheckDeepEquals(t, SecondFakeService, actual[1]) + th.CheckDeepEquals(t, ThirdFakeService, actual[2]) return true, nil }) - testhelper.AssertNoErr(t, err) + th.AssertNoErr(t, err) if pages != 1 { t.Errorf("Expected 1 page, saw %d", pages) diff --git a/openstack/compute/v2/hypervisors/testing/fixtures_test.go b/openstack/compute/v2/hypervisors/testing/fixtures_test.go index a969f1f825..6e4b2e4aff 100644 --- a/openstack/compute/v2/hypervisors/testing/fixtures_test.go +++ b/openstack/compute/v2/hypervisors/testing/fixtures_test.go @@ -6,7 +6,7 @@ import ( "testing" "github.com/gophercloud/gophercloud/v2/openstack/compute/v2/hypervisors" - "github.com/gophercloud/gophercloud/v2/testhelper" + th "github.com/gophercloud/gophercloud/v2/testhelper" "github.com/gophercloud/gophercloud/v2/testhelper/client" ) @@ -600,9 +600,9 @@ var ( ) func HandleHypervisorsStatisticsSuccessfully(t *testing.T) { - testhelper.Mux.HandleFunc("/os-hypervisors/statistics", func(w http.ResponseWriter, r *http.Request) { - testhelper.TestMethod(t, r, "GET") - testhelper.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.Mux.HandleFunc("/os-hypervisors/statistics", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") fmt.Fprintf(w, HypervisorsStatisticsBody) @@ -610,9 +610,9 @@ func HandleHypervisorsStatisticsSuccessfully(t *testing.T) { } func HandleHypervisorListPre253Successfully(t *testing.T) { - testhelper.Mux.HandleFunc("/os-hypervisors/detail", func(w http.ResponseWriter, r *http.Request) { - testhelper.TestMethod(t, r, "GET") - testhelper.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.Mux.HandleFunc("/os-hypervisors/detail", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") fmt.Fprintf(w, HypervisorListBodyPre253) @@ -620,9 +620,9 @@ func HandleHypervisorListPre253Successfully(t *testing.T) { } func HandleHypervisorListSuccessfully(t *testing.T) { - testhelper.Mux.HandleFunc("/os-hypervisors/detail", func(w http.ResponseWriter, r *http.Request) { - testhelper.TestMethod(t, r, "GET") - testhelper.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.Mux.HandleFunc("/os-hypervisors/detail", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") fmt.Fprintf(w, HypervisorListBody) @@ -630,10 +630,10 @@ func HandleHypervisorListSuccessfully(t *testing.T) { } func HandleHypervisorListWithParametersSuccessfully(t *testing.T) { - testhelper.Mux.HandleFunc("/os-hypervisors/detail", func(w http.ResponseWriter, r *http.Request) { - testhelper.TestMethod(t, r, "GET") - testhelper.TestHeader(t, r, "X-Auth-Token", client.TokenID) - testhelper.TestFormValues(t, r, map[string]string{ + th.Mux.HandleFunc("/os-hypervisors/detail", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.TestFormValues(t, r, map[string]string{ "with_servers": "true", }) @@ -643,9 +643,9 @@ func HandleHypervisorListWithParametersSuccessfully(t *testing.T) { } func HandleHypervisorGetSuccessfully(t *testing.T) { - testhelper.Mux.HandleFunc("/os-hypervisors/"+HypervisorFake.ID, func(w http.ResponseWriter, r *http.Request) { - testhelper.TestMethod(t, r, "GET") - testhelper.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.Mux.HandleFunc("/os-hypervisors/"+HypervisorFake.ID, func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") fmt.Fprintf(w, HypervisorGetBody) @@ -653,9 +653,9 @@ func HandleHypervisorGetSuccessfully(t *testing.T) { } func HandleHypervisorGetEmptyCPUInfoSuccessfully(t *testing.T) { - testhelper.Mux.HandleFunc("/os-hypervisors/"+HypervisorFake.ID, func(w http.ResponseWriter, r *http.Request) { - testhelper.TestMethod(t, r, "GET") - testhelper.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.Mux.HandleFunc("/os-hypervisors/"+HypervisorFake.ID, func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") fmt.Fprintf(w, HypervisorGetEmptyCPUInfoBody) @@ -663,9 +663,9 @@ func HandleHypervisorGetEmptyCPUInfoSuccessfully(t *testing.T) { } func HandleHypervisorAfterV287ResponseSuccessfully(t *testing.T) { - testhelper.Mux.HandleFunc("/os-hypervisors/"+HypervisorFake.ID, func(w http.ResponseWriter, r *http.Request) { - testhelper.TestMethod(t, r, "GET") - testhelper.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.Mux.HandleFunc("/os-hypervisors/"+HypervisorFake.ID, func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") fmt.Fprintf(w, HypervisorAfterV287ResponseBody) @@ -673,9 +673,9 @@ func HandleHypervisorAfterV287ResponseSuccessfully(t *testing.T) { } func HandleHypervisorUptimeSuccessfully(t *testing.T) { - testhelper.Mux.HandleFunc("/os-hypervisors/"+HypervisorFake.ID+"/uptime", func(w http.ResponseWriter, r *http.Request) { - testhelper.TestMethod(t, r, "GET") - testhelper.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.Mux.HandleFunc("/os-hypervisors/"+HypervisorFake.ID+"/uptime", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") fmt.Fprintf(w, HypervisorUptimeBody) diff --git a/openstack/compute/v2/hypervisors/testing/requests_test.go b/openstack/compute/v2/hypervisors/testing/requests_test.go index 493e8138d1..0303f7f1d0 100644 --- a/openstack/compute/v2/hypervisors/testing/requests_test.go +++ b/openstack/compute/v2/hypervisors/testing/requests_test.go @@ -6,13 +6,13 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/compute/v2/hypervisors" "github.com/gophercloud/gophercloud/v2/pagination" - "github.com/gophercloud/gophercloud/v2/testhelper" + th "github.com/gophercloud/gophercloud/v2/testhelper" "github.com/gophercloud/gophercloud/v2/testhelper/client" ) func TestListHypervisorsPre253(t *testing.T) { - testhelper.SetupHTTP() - defer testhelper.TeardownHTTP() + th.SetupHTTP() + defer th.TeardownHTTP() HandleHypervisorListPre253Successfully(t) pages := 0 @@ -28,13 +28,13 @@ func TestListHypervisorsPre253(t *testing.T) { if len(actual) != 2 { t.Fatalf("Expected 2 hypervisors, got %d", len(actual)) } - testhelper.CheckDeepEquals(t, HypervisorFakePre253, actual[0]) - testhelper.CheckDeepEquals(t, HypervisorFakePre253, actual[1]) + th.CheckDeepEquals(t, HypervisorFakePre253, actual[0]) + th.CheckDeepEquals(t, HypervisorFakePre253, actual[1]) return true, nil }) - testhelper.AssertNoErr(t, err) + th.AssertNoErr(t, err) if pages != 1 { t.Errorf("Expected 1 page, saw %d", pages) @@ -42,21 +42,21 @@ func TestListHypervisorsPre253(t *testing.T) { } func TestListAllHypervisorsPre253(t *testing.T) { - testhelper.SetupHTTP() - defer testhelper.TeardownHTTP() + th.SetupHTTP() + defer th.TeardownHTTP() HandleHypervisorListPre253Successfully(t) allPages, err := hypervisors.List(client.ServiceClient(), hypervisors.ListOpts{}).AllPages(context.TODO()) - testhelper.AssertNoErr(t, err) + th.AssertNoErr(t, err) actual, err := hypervisors.ExtractHypervisors(allPages) - testhelper.AssertNoErr(t, err) - testhelper.CheckDeepEquals(t, HypervisorFakePre253, actual[0]) - testhelper.CheckDeepEquals(t, HypervisorFakePre253, actual[1]) + th.AssertNoErr(t, err) + th.CheckDeepEquals(t, HypervisorFakePre253, actual[0]) + th.CheckDeepEquals(t, HypervisorFakePre253, actual[1]) } func TestListHypervisors(t *testing.T) { - testhelper.SetupHTTP() - defer testhelper.TeardownHTTP() + th.SetupHTTP() + defer th.TeardownHTTP() HandleHypervisorListSuccessfully(t) pages := 0 @@ -72,13 +72,13 @@ func TestListHypervisors(t *testing.T) { if len(actual) != 2 { t.Fatalf("Expected 2 hypervisors, got %d", len(actual)) } - testhelper.CheckDeepEquals(t, HypervisorFake, actual[0]) - testhelper.CheckDeepEquals(t, HypervisorFake, actual[1]) + th.CheckDeepEquals(t, HypervisorFake, actual[0]) + th.CheckDeepEquals(t, HypervisorFake, actual[1]) return true, nil }) - testhelper.AssertNoErr(t, err) + th.AssertNoErr(t, err) if pages != 1 { t.Errorf("Expected 1 page, saw %d", pages) @@ -86,88 +86,88 @@ func TestListHypervisors(t *testing.T) { } func TestListAllHypervisors(t *testing.T) { - testhelper.SetupHTTP() - defer testhelper.TeardownHTTP() + th.SetupHTTP() + defer th.TeardownHTTP() HandleHypervisorListSuccessfully(t) allPages, err := hypervisors.List(client.ServiceClient(), hypervisors.ListOpts{}).AllPages(context.TODO()) - testhelper.AssertNoErr(t, err) + th.AssertNoErr(t, err) actual, err := hypervisors.ExtractHypervisors(allPages) - testhelper.AssertNoErr(t, err) - testhelper.CheckDeepEquals(t, HypervisorFake, actual[0]) - testhelper.CheckDeepEquals(t, HypervisorFake, actual[1]) + th.AssertNoErr(t, err) + th.CheckDeepEquals(t, HypervisorFake, actual[0]) + th.CheckDeepEquals(t, HypervisorFake, actual[1]) } func TestListAllHypervisorsWithParameters(t *testing.T) { - testhelper.SetupHTTP() - defer testhelper.TeardownHTTP() + th.SetupHTTP() + defer th.TeardownHTTP() HandleHypervisorListWithParametersSuccessfully(t) with_servers := true allPages, err := hypervisors.List(client.ServiceClient(), hypervisors.ListOpts{WithServers: &with_servers}).AllPages(context.TODO()) - testhelper.AssertNoErr(t, err) + th.AssertNoErr(t, err) actual, err := hypervisors.ExtractHypervisors(allPages) - testhelper.AssertNoErr(t, err) - testhelper.CheckDeepEquals(t, HypervisorFakeWithParameters, actual[0]) - testhelper.CheckDeepEquals(t, HypervisorFakeWithParameters, actual[1]) + th.AssertNoErr(t, err) + th.CheckDeepEquals(t, HypervisorFakeWithParameters, actual[0]) + th.CheckDeepEquals(t, HypervisorFakeWithParameters, actual[1]) } func TestHypervisorsStatistics(t *testing.T) { - testhelper.SetupHTTP() - defer testhelper.TeardownHTTP() + th.SetupHTTP() + defer th.TeardownHTTP() HandleHypervisorsStatisticsSuccessfully(t) expected := HypervisorsStatisticsExpected actual, err := hypervisors.GetStatistics(context.TODO(), client.ServiceClient()).Extract() - testhelper.AssertNoErr(t, err) - testhelper.CheckDeepEquals(t, &expected, actual) + th.AssertNoErr(t, err) + th.CheckDeepEquals(t, &expected, actual) } func TestGetHypervisor(t *testing.T) { - testhelper.SetupHTTP() - defer testhelper.TeardownHTTP() + th.SetupHTTP() + defer th.TeardownHTTP() HandleHypervisorGetSuccessfully(t) expected := HypervisorFake actual, err := hypervisors.Get(context.TODO(), client.ServiceClient(), expected.ID).Extract() - testhelper.AssertNoErr(t, err) - testhelper.CheckDeepEquals(t, &expected, actual) + th.AssertNoErr(t, err) + th.CheckDeepEquals(t, &expected, actual) } func TestGetHypervisorEmptyCPUInfo(t *testing.T) { - testhelper.SetupHTTP() - defer testhelper.TeardownHTTP() + th.SetupHTTP() + defer th.TeardownHTTP() HandleHypervisorGetEmptyCPUInfoSuccessfully(t) expected := HypervisorEmptyCPUInfo actual, err := hypervisors.Get(context.TODO(), client.ServiceClient(), expected.ID).Extract() - testhelper.AssertNoErr(t, err) - testhelper.CheckDeepEquals(t, &expected, actual) + th.AssertNoErr(t, err) + th.CheckDeepEquals(t, &expected, actual) } func TestGetHypervisorAfterV287Response(t *testing.T) { - testhelper.SetupHTTP() - defer testhelper.TeardownHTTP() + th.SetupHTTP() + defer th.TeardownHTTP() HandleHypervisorAfterV287ResponseSuccessfully(t) expected := HypervisorAfterV287Response actual, err := hypervisors.Get(context.TODO(), client.ServiceClient(), expected.ID).Extract() - testhelper.AssertNoErr(t, err) - testhelper.CheckDeepEquals(t, &expected, actual) + th.AssertNoErr(t, err) + th.CheckDeepEquals(t, &expected, actual) } func TestHypervisorsUptime(t *testing.T) { - testhelper.SetupHTTP() - defer testhelper.TeardownHTTP() + th.SetupHTTP() + defer th.TeardownHTTP() HandleHypervisorUptimeSuccessfully(t) expected := HypervisorUptimeExpected actual, err := hypervisors.GetUptime(context.TODO(), client.ServiceClient(), HypervisorFake.ID).Extract() - testhelper.AssertNoErr(t, err) - testhelper.CheckDeepEquals(t, &expected, actual) + th.AssertNoErr(t, err) + th.CheckDeepEquals(t, &expected, actual) } diff --git a/openstack/compute/v2/services/testing/requests_test.go b/openstack/compute/v2/services/testing/requests_test.go index c201c9f4d6..df7a9e9a17 100644 --- a/openstack/compute/v2/services/testing/requests_test.go +++ b/openstack/compute/v2/services/testing/requests_test.go @@ -6,13 +6,13 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/compute/v2/services" "github.com/gophercloud/gophercloud/v2/pagination" - "github.com/gophercloud/gophercloud/v2/testhelper" + th "github.com/gophercloud/gophercloud/v2/testhelper" "github.com/gophercloud/gophercloud/v2/testhelper/client" ) func TestListServicesPre253(t *testing.T) { - testhelper.SetupHTTP() - defer testhelper.TeardownHTTP() + th.SetupHTTP() + defer th.TeardownHTTP() HandleListPre253Successfully(t) pages := 0 @@ -27,15 +27,15 @@ func TestListServicesPre253(t *testing.T) { if len(actual) != 4 { t.Fatalf("Expected 4 services, got %d", len(actual)) } - testhelper.CheckDeepEquals(t, FirstFakeServicePre253, actual[0]) - testhelper.CheckDeepEquals(t, SecondFakeServicePre253, actual[1]) - testhelper.CheckDeepEquals(t, ThirdFakeServicePre253, actual[2]) - testhelper.CheckDeepEquals(t, FourthFakeServicePre253, actual[3]) + th.CheckDeepEquals(t, FirstFakeServicePre253, actual[0]) + th.CheckDeepEquals(t, SecondFakeServicePre253, actual[1]) + th.CheckDeepEquals(t, ThirdFakeServicePre253, actual[2]) + th.CheckDeepEquals(t, FourthFakeServicePre253, actual[3]) return true, nil }) - testhelper.AssertNoErr(t, err) + th.AssertNoErr(t, err) if pages != 1 { t.Errorf("Expected 1 page, saw %d", pages) @@ -43,8 +43,8 @@ func TestListServicesPre253(t *testing.T) { } func TestListServices(t *testing.T) { - testhelper.SetupHTTP() - defer testhelper.TeardownHTTP() + th.SetupHTTP() + defer th.TeardownHTTP() HandleListSuccessfully(t) pages := 0 @@ -63,15 +63,15 @@ func TestListServices(t *testing.T) { if len(actual) != 4 { t.Fatalf("Expected 4 services, got %d", len(actual)) } - testhelper.CheckDeepEquals(t, FirstFakeService, actual[0]) - testhelper.CheckDeepEquals(t, SecondFakeService, actual[1]) - testhelper.CheckDeepEquals(t, ThirdFakeService, actual[2]) - testhelper.CheckDeepEquals(t, FourthFakeService, actual[3]) + th.CheckDeepEquals(t, FirstFakeService, actual[0]) + th.CheckDeepEquals(t, SecondFakeService, actual[1]) + th.CheckDeepEquals(t, ThirdFakeService, actual[2]) + th.CheckDeepEquals(t, FourthFakeService, actual[3]) return true, nil }) - testhelper.AssertNoErr(t, err) + th.AssertNoErr(t, err) if pages != 1 { t.Errorf("Expected 1 page, saw %d", pages) @@ -79,8 +79,8 @@ func TestListServices(t *testing.T) { } func TestUpdateService(t *testing.T) { - testhelper.SetupHTTP() - defer testhelper.TeardownHTTP() + th.SetupHTTP() + defer th.TeardownHTTP() HandleUpdateSuccessfully(t) client := client.ServiceClient() @@ -89,16 +89,16 @@ func TestUpdateService(t *testing.T) { t.Fatalf("Unexpected Update error: %v", err) } - testhelper.CheckDeepEquals(t, FakeServiceUpdateBody, *actual) + th.CheckDeepEquals(t, FakeServiceUpdateBody, *actual) } func TestDeleteService(t *testing.T) { - testhelper.SetupHTTP() - defer testhelper.TeardownHTTP() + th.SetupHTTP() + defer th.TeardownHTTP() HandleDeleteSuccessfully(t) client := client.ServiceClient() res := services.Delete(context.TODO(), client, "fake-service-id") - testhelper.AssertNoErr(t, res.Err) + th.AssertNoErr(t, res.Err) } diff --git a/openstack/identity/v3/ec2tokens/testing/requests_test.go b/openstack/identity/v3/ec2tokens/testing/requests_test.go index 188329daab..13239e2d91 100644 --- a/openstack/identity/v3/ec2tokens/testing/requests_test.go +++ b/openstack/identity/v3/ec2tokens/testing/requests_test.go @@ -12,24 +12,24 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/identity/v3/ec2tokens" "github.com/gophercloud/gophercloud/v2/openstack/identity/v3/tokens" tokens_testing "github.com/gophercloud/gophercloud/v2/openstack/identity/v3/tokens/testing" - "github.com/gophercloud/gophercloud/v2/testhelper" + th "github.com/gophercloud/gophercloud/v2/testhelper" ) // authTokenPost verifies that providing certain AuthOptions and Scope results in an expected JSON structure. func authTokenPost(t *testing.T, options ec2tokens.AuthOptions, requestJSON string) { - testhelper.SetupHTTP() - defer testhelper.TeardownHTTP() + th.SetupHTTP() + defer th.TeardownHTTP() client := gophercloud.ServiceClient{ ProviderClient: &gophercloud.ProviderClient{}, - Endpoint: testhelper.Endpoint(), + Endpoint: th.Endpoint(), } - testhelper.Mux.HandleFunc("/ec2tokens", func(w http.ResponseWriter, r *http.Request) { - testhelper.TestMethod(t, r, "POST") - testhelper.TestHeader(t, r, "Content-Type", "application/json") - testhelper.TestHeader(t, r, "Accept", "application/json") - testhelper.TestJSONRequest(t, r, requestJSON) + th.Mux.HandleFunc("/ec2tokens", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "POST") + th.TestHeader(t, r, "Content-Type", "application/json") + th.TestHeader(t, r, "Accept", "application/json") + th.TestJSONRequest(t, r, requestJSON) w.WriteHeader(http.StatusOK) fmt.Fprintf(w, tokens_testing.TokenOutput) @@ -40,8 +40,8 @@ func authTokenPost(t *testing.T, options ec2tokens.AuthOptions, requestJSON stri } actual, err := ec2tokens.Create(context.TODO(), &client, &options).Extract() - testhelper.AssertNoErr(t, err) - testhelper.CheckDeepEquals(t, expected, actual) + th.AssertNoErr(t, err) + th.CheckDeepEquals(t, expected, actual) } func TestCreateV2(t *testing.T) { @@ -224,7 +224,7 @@ func TestEC2CredentialsBuildCanonicalQueryStringV2(t *testing.T) { "Value": "bar", } expected := "Action=foo&Value=bar" - testhelper.CheckEquals(t, expected, ec2tokens.EC2CredentialsBuildCanonicalQueryStringV2(params)) + th.CheckEquals(t, expected, ec2tokens.EC2CredentialsBuildCanonicalQueryStringV2(params)) } func TestEC2CredentialsBuildStringToSignV2(t *testing.T) { @@ -238,7 +238,7 @@ func TestEC2CredentialsBuildStringToSignV2(t *testing.T) { }, } expected := []byte("GET\nlocalhost\n/\nAction=foo&Value=bar") - testhelper.CheckDeepEquals(t, expected, ec2tokens.EC2CredentialsBuildStringToSignV2(opts)) + th.CheckDeepEquals(t, expected, ec2tokens.EC2CredentialsBuildStringToSignV2(opts)) } func TestEC2CredentialsBuildCanonicalQueryStringV4(t *testing.T) { @@ -247,8 +247,8 @@ func TestEC2CredentialsBuildCanonicalQueryStringV4(t *testing.T) { "Value": "bar", } expected := "Action=foo&Value=bar" - testhelper.CheckEquals(t, expected, ec2tokens.EC2CredentialsBuildCanonicalQueryStringV4("foo", params)) - testhelper.CheckEquals(t, "", ec2tokens.EC2CredentialsBuildCanonicalQueryStringV4("POST", params)) + th.CheckEquals(t, expected, ec2tokens.EC2CredentialsBuildCanonicalQueryStringV4("foo", params)) + th.CheckEquals(t, "", ec2tokens.EC2CredentialsBuildCanonicalQueryStringV4("POST", params)) } func TestEC2CredentialsBuildCanonicalHeadersV4(t *testing.T) { @@ -258,12 +258,12 @@ func TestEC2CredentialsBuildCanonicalHeadersV4(t *testing.T) { } signedHeaders := "foo;baz" expected := "foo:bar\nbaz:qux\n" - testhelper.CheckEquals(t, expected, ec2tokens.EC2CredentialsBuildCanonicalHeadersV4(headers, signedHeaders)) + th.CheckEquals(t, expected, ec2tokens.EC2CredentialsBuildCanonicalHeadersV4(headers, signedHeaders)) } func TestEC2CredentialsBuildSignatureKeyV4(t *testing.T) { expected := "246626bd815b0a0cae4bedc3f4e124ca25e208cd75fd812d836aeae184de038a" - testhelper.CheckEquals(t, expected, hex.EncodeToString((ec2tokens.EC2CredentialsBuildSignatureKeyV4("foo", "bar", "baz", time.Time{})))) + th.CheckEquals(t, expected, hex.EncodeToString((ec2tokens.EC2CredentialsBuildSignatureKeyV4("foo", "bar", "baz", time.Time{})))) } func TestEC2CredentialsBuildSignatureV4(t *testing.T) { @@ -284,5 +284,5 @@ func TestEC2CredentialsBuildSignatureV4(t *testing.T) { stringToSign := ec2tokens.EC2CredentialsBuildStringToSignV4(opts, "host", "foo", date) key := ec2tokens.EC2CredentialsBuildSignatureKeyV4("", "", "", date) - testhelper.CheckEquals(t, expected, ec2tokens.EC2CredentialsBuildSignatureV4(key, stringToSign)) + th.CheckEquals(t, expected, ec2tokens.EC2CredentialsBuildSignatureV4(key, stringToSign)) } diff --git a/openstack/identity/v3/oauth1/testing/fixtures_test.go b/openstack/identity/v3/oauth1/testing/fixtures_test.go index 8a2bfe5cdb..3e8d144047 100644 --- a/openstack/identity/v3/oauth1/testing/fixtures_test.go +++ b/openstack/identity/v3/oauth1/testing/fixtures_test.go @@ -8,7 +8,7 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/identity/v3/oauth1" tokens "github.com/gophercloud/gophercloud/v2/openstack/identity/v3/tokens/testing" - "github.com/gophercloud/gophercloud/v2/testhelper" + th "github.com/gophercloud/gophercloud/v2/testhelper" "github.com/gophercloud/gophercloud/v2/testhelper/client" ) @@ -221,39 +221,39 @@ var ExpectedUserAccessTokenRolesSlice = []oauth1.AccessTokenRole{UserAccessToken // HandleCreateConsumer creates an HTTP handler at `/OS-OAUTH1/consumers` on the // test handler mux that tests consumer creation. func HandleCreateConsumer(t *testing.T) { - testhelper.Mux.HandleFunc("/OS-OAUTH1/consumers", func(w http.ResponseWriter, r *http.Request) { - testhelper.TestMethod(t, r, "POST") - testhelper.TestHeader(t, r, "Content-Type", "application/json") - testhelper.TestHeader(t, r, "Accept", "application/json") - testhelper.TestJSONRequest(t, r, CreateConsumerRequest) + th.Mux.HandleFunc("/OS-OAUTH1/consumers", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "POST") + th.TestHeader(t, r, "Content-Type", "application/json") + th.TestHeader(t, r, "Accept", "application/json") + th.TestJSONRequest(t, r, CreateConsumerRequest) w.WriteHeader(http.StatusCreated) _, err := fmt.Fprintf(w, CreateConsumerResponse) - testhelper.AssertNoErr(t, err) + th.AssertNoErr(t, err) }) } // HandleUpdateConsumer creates an HTTP handler at `/OS-OAUTH1/consumers/7fea2d` on the // test handler mux that tests consumer update. func HandleUpdateConsumer(t *testing.T) { - testhelper.Mux.HandleFunc("/OS-OAUTH1/consumers/7fea2d", func(w http.ResponseWriter, r *http.Request) { - testhelper.TestMethod(t, r, "PATCH") - testhelper.TestHeader(t, r, "Content-Type", "application/json") - testhelper.TestHeader(t, r, "Accept", "application/json") - testhelper.TestJSONRequest(t, r, UpdateConsumerRequest) + th.Mux.HandleFunc("/OS-OAUTH1/consumers/7fea2d", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "PATCH") + th.TestHeader(t, r, "Content-Type", "application/json") + th.TestHeader(t, r, "Accept", "application/json") + th.TestJSONRequest(t, r, UpdateConsumerRequest) w.WriteHeader(http.StatusOK) _, err := fmt.Fprintf(w, UpdateConsumerResponse) - testhelper.AssertNoErr(t, err) + th.AssertNoErr(t, err) }) } // HandleDeleteConsumer creates an HTTP handler at `/OS-OAUTH1/consumers/7fea2d` on the // test handler mux that tests consumer deletion. func HandleDeleteConsumer(t *testing.T) { - testhelper.Mux.HandleFunc("/OS-OAUTH1/consumers/7fea2d", func(w http.ResponseWriter, r *http.Request) { - testhelper.TestMethod(t, r, "DELETE") - testhelper.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.Mux.HandleFunc("/OS-OAUTH1/consumers/7fea2d", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "DELETE") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) @@ -262,10 +262,10 @@ func HandleDeleteConsumer(t *testing.T) { // HandleGetConsumer creates an HTTP handler at `/OS-OAUTH1/consumers/7fea2d` on the // test handler mux that responds with a single consumer. func HandleGetConsumer(t *testing.T) { - testhelper.Mux.HandleFunc("/OS-OAUTH1/consumers/7fea2d", func(w http.ResponseWriter, r *http.Request) { - testhelper.TestMethod(t, r, "GET") - testhelper.TestHeader(t, r, "Accept", "application/json") - testhelper.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.Mux.HandleFunc("/OS-OAUTH1/consumers/7fea2d", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "Accept", "application/json") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -299,10 +299,10 @@ var ExpectedConsumersSlice = []oauth1.Consumer{FirstConsumer, SecondConsumer} // HandleListConsumers creates an HTTP handler at `/OS-OAUTH1/consumers` on the // test handler mux that responds with a list of two consumers. func HandleListConsumers(t *testing.T) { - testhelper.Mux.HandleFunc("/OS-OAUTH1/consumers", func(w http.ResponseWriter, r *http.Request) { - testhelper.TestMethod(t, r, "GET") - testhelper.TestHeader(t, r, "Accept", "application/json") - testhelper.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.Mux.HandleFunc("/OS-OAUTH1/consumers", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "Accept", "application/json") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -319,13 +319,13 @@ var Token = oauth1.Token{ // HandleRequestToken creates an HTTP handler at `/OS-OAUTH1/request_token` on the // test handler mux that responds with a OAuth1 unauthorized token. func HandleRequestToken(t *testing.T) { - testhelper.Mux.HandleFunc("/OS-OAUTH1/request_token", func(w http.ResponseWriter, r *http.Request) { - testhelper.TestMethod(t, r, "POST") - testhelper.TestHeader(t, r, "Accept", "application/json") - testhelper.TestHeader(t, r, "X-Auth-Token", client.TokenID) - testhelper.TestHeader(t, r, "Authorization", `OAuth oauth_callback="oob", oauth_consumer_key="7fea2d", oauth_nonce="71416001758914252991586795052", oauth_signature_method="HMAC-SHA1", oauth_timestamp="0", oauth_version="1.0", oauth_signature="jCSPVryCYF52Ks0VNNmBmeKSGuw%3D"`) - testhelper.TestHeader(t, r, "Requested-Project-Id", "1df927e8a466498f98788ed73d3c8ab4") - testhelper.TestBody(t, r, "") + th.Mux.HandleFunc("/OS-OAUTH1/request_token", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "POST") + th.TestHeader(t, r, "Accept", "application/json") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.TestHeader(t, r, "Authorization", `OAuth oauth_callback="oob", oauth_consumer_key="7fea2d", oauth_nonce="71416001758914252991586795052", oauth_signature_method="HMAC-SHA1", oauth_timestamp="0", oauth_version="1.0", oauth_signature="jCSPVryCYF52Ks0VNNmBmeKSGuw%3D"`) + th.TestHeader(t, r, "Requested-Project-Id", "1df927e8a466498f98788ed73d3c8ab4") + th.TestBody(t, r, "") w.Header().Set("Content-Type", oauth1.OAuth1TokenContentType) w.WriteHeader(http.StatusCreated) @@ -336,15 +336,15 @@ func HandleRequestToken(t *testing.T) { // HandleAuthorizeToken creates an HTTP handler at `/OS-OAUTH1/authorize/29971f` on the // test handler mux that tests unauthorized token authorization. func HandleAuthorizeToken(t *testing.T) { - testhelper.Mux.HandleFunc("/OS-OAUTH1/authorize/29971f", func(w http.ResponseWriter, r *http.Request) { - testhelper.TestMethod(t, r, "PUT") - testhelper.TestHeader(t, r, "Content-Type", "application/json") - testhelper.TestHeader(t, r, "Accept", "application/json") - testhelper.TestJSONRequest(t, r, AuthorizeTokenRequest) + th.Mux.HandleFunc("/OS-OAUTH1/authorize/29971f", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "PUT") + th.TestHeader(t, r, "Content-Type", "application/json") + th.TestHeader(t, r, "Accept", "application/json") + th.TestJSONRequest(t, r, AuthorizeTokenRequest) w.WriteHeader(http.StatusOK) _, err := fmt.Fprintf(w, AuthorizeTokenResponse) - testhelper.AssertNoErr(t, err) + th.AssertNoErr(t, err) }) } @@ -357,12 +357,12 @@ var AccessToken = oauth1.Token{ // HandleCreateAccessToken creates an HTTP handler at `/OS-OAUTH1/access_token` on the // test handler mux that responds with a OAuth1 access token. func HandleCreateAccessToken(t *testing.T) { - testhelper.Mux.HandleFunc("/OS-OAUTH1/access_token", func(w http.ResponseWriter, r *http.Request) { - testhelper.TestMethod(t, r, "POST") - testhelper.TestHeader(t, r, "Accept", "application/json") - testhelper.TestHeader(t, r, "X-Auth-Token", client.TokenID) - testhelper.TestHeader(t, r, "Authorization", `OAuth oauth_consumer_key="7fea2d", oauth_nonce="66148873158553341551586804894", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1586804894", oauth_token="29971f", oauth_verifier="8171", oauth_version="1.0", oauth_signature="usQ89Y3IYG0IBE7%2Ft8aVsc8XgEk%3D"`) - testhelper.TestBody(t, r, "") + th.Mux.HandleFunc("/OS-OAUTH1/access_token", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "POST") + th.TestHeader(t, r, "Accept", "application/json") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.TestHeader(t, r, "Authorization", `OAuth oauth_consumer_key="7fea2d", oauth_nonce="66148873158553341551586804894", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1586804894", oauth_token="29971f", oauth_verifier="8171", oauth_version="1.0", oauth_signature="usQ89Y3IYG0IBE7%2Ft8aVsc8XgEk%3D"`) + th.TestBody(t, r, "") w.Header().Set("Content-Type", oauth1.OAuth1TokenContentType) w.WriteHeader(http.StatusCreated) @@ -373,10 +373,10 @@ func HandleCreateAccessToken(t *testing.T) { // HandleGetAccessToken creates an HTTP handler at `/users/ce9e07/OS-OAUTH1/access_tokens/6be26a` on the // test handler mux that responds with a single access token. func HandleGetAccessToken(t *testing.T) { - testhelper.Mux.HandleFunc("/users/ce9e07/OS-OAUTH1/access_tokens/6be26a", func(w http.ResponseWriter, r *http.Request) { - testhelper.TestMethod(t, r, "GET") - testhelper.TestHeader(t, r, "Accept", "application/json") - testhelper.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.Mux.HandleFunc("/users/ce9e07/OS-OAUTH1/access_tokens/6be26a", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "Accept", "application/json") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -387,9 +387,9 @@ func HandleGetAccessToken(t *testing.T) { // HandleRevokeAccessToken creates an HTTP handler at `/users/ce9e07/OS-OAUTH1/access_tokens/6be26a` on the // test handler mux that tests access token deletion. func HandleRevokeAccessToken(t *testing.T) { - testhelper.Mux.HandleFunc("/users/ce9e07/OS-OAUTH1/access_tokens/6be26a", func(w http.ResponseWriter, r *http.Request) { - testhelper.TestMethod(t, r, "DELETE") - testhelper.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.Mux.HandleFunc("/users/ce9e07/OS-OAUTH1/access_tokens/6be26a", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "DELETE") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) @@ -398,10 +398,10 @@ func HandleRevokeAccessToken(t *testing.T) { // HandleListAccessTokens creates an HTTP handler at `/users/ce9e07/OS-OAUTH1/access_tokens` on the // test handler mux that responds with a slice of access tokens. func HandleListAccessTokens(t *testing.T) { - testhelper.Mux.HandleFunc("/users/ce9e07/OS-OAUTH1/access_tokens", func(w http.ResponseWriter, r *http.Request) { - testhelper.TestMethod(t, r, "GET") - testhelper.TestHeader(t, r, "Accept", "application/json") - testhelper.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.Mux.HandleFunc("/users/ce9e07/OS-OAUTH1/access_tokens", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "Accept", "application/json") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -412,10 +412,10 @@ func HandleListAccessTokens(t *testing.T) { // HandleListAccessTokenRoles creates an HTTP handler at `/users/ce9e07/OS-OAUTH1/access_tokens/6be26a/roles` on the // test handler mux that responds with a slice of access token roles. func HandleListAccessTokenRoles(t *testing.T) { - testhelper.Mux.HandleFunc("/users/ce9e07/OS-OAUTH1/access_tokens/6be26a/roles", func(w http.ResponseWriter, r *http.Request) { - testhelper.TestMethod(t, r, "GET") - testhelper.TestHeader(t, r, "Accept", "application/json") - testhelper.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.Mux.HandleFunc("/users/ce9e07/OS-OAUTH1/access_tokens/6be26a/roles", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "Accept", "application/json") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -426,10 +426,10 @@ func HandleListAccessTokenRoles(t *testing.T) { // HandleGetAccessTokenRole creates an HTTP handler at `/users/ce9e07/OS-OAUTH1/access_tokens/6be26a/roles/5ad150` on the // test handler mux that responds with an access token role. func HandleGetAccessTokenRole(t *testing.T) { - testhelper.Mux.HandleFunc("/users/ce9e07/OS-OAUTH1/access_tokens/6be26a/roles/5ad150", func(w http.ResponseWriter, r *http.Request) { - testhelper.TestMethod(t, r, "GET") - testhelper.TestHeader(t, r, "Accept", "application/json") - testhelper.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.Mux.HandleFunc("/users/ce9e07/OS-OAUTH1/access_tokens/6be26a/roles/5ad150", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "Accept", "application/json") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -440,12 +440,12 @@ func HandleGetAccessTokenRole(t *testing.T) { // HandleAuthenticate creates an HTTP handler at `/auth/tokens` on the // test handler mux that responds with an OpenStack token. func HandleAuthenticate(t *testing.T) { - testhelper.Mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) { - testhelper.TestMethod(t, r, "POST") - testhelper.TestHeader(t, r, "Content-Type", "application/json") - testhelper.TestHeader(t, r, "Accept", "application/json") - testhelper.TestHeader(t, r, "Authorization", `OAuth oauth_consumer_key="7fea2d", oauth_nonce="66148873158553341551586804894", oauth_signature_method="HMAC-SHA1", oauth_timestamp="0", oauth_token="accd36", oauth_version="1.0", oauth_signature="JgMHu4e7rXGlqz3A%2FLhHDMvtjp8%3D"`) - testhelper.TestJSONRequest(t, r, `{"auth": {"identity": {"oauth1": {}, "methods": ["oauth1"]}}}`) + th.Mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "POST") + th.TestHeader(t, r, "Content-Type", "application/json") + th.TestHeader(t, r, "Accept", "application/json") + th.TestHeader(t, r, "Authorization", `OAuth oauth_consumer_key="7fea2d", oauth_nonce="66148873158553341551586804894", oauth_signature_method="HMAC-SHA1", oauth_timestamp="0", oauth_token="accd36", oauth_version="1.0", oauth_signature="JgMHu4e7rXGlqz3A%2FLhHDMvtjp8%3D"`) + th.TestJSONRequest(t, r, `{"auth": {"identity": {"oauth1": {}, "methods": ["oauth1"]}}}`) w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) diff --git a/openstack/identity/v3/tokens/testing/fixtures.go b/openstack/identity/v3/tokens/testing/fixtures.go index 0b4ccafa26..00797867c9 100644 --- a/openstack/identity/v3/tokens/testing/fixtures.go +++ b/openstack/identity/v3/tokens/testing/fixtures.go @@ -8,7 +8,7 @@ import ( "github.com/gophercloud/gophercloud/v2" "github.com/gophercloud/gophercloud/v2/openstack/identity/v3/tokens" - "github.com/gophercloud/gophercloud/v2/testhelper" + th "github.com/gophercloud/gophercloud/v2/testhelper" ) const testTokenID = "130f6c17-420e-4a0b-97b0-0c9cf2a05f30" @@ -310,7 +310,7 @@ func getGetResult(t *testing.T) tokens.GetResult { "X-Subject-Token": []string{testTokenID}, } err := json.Unmarshal([]byte(TokenOutput), &result.Body) - testhelper.AssertNoErr(t, err) + th.AssertNoErr(t, err) return result } @@ -320,6 +320,6 @@ func getGetDomainResult(t *testing.T) tokens.GetResult { "X-Subject-Token": []string{testTokenID}, } err := json.Unmarshal([]byte(DomainToken), &result.Body) - testhelper.AssertNoErr(t, err) + th.AssertNoErr(t, err) return result } diff --git a/openstack/identity/v3/tokens/testing/requests_test.go b/openstack/identity/v3/tokens/testing/requests_test.go index 9a9a59fc14..c0aafb9ad4 100644 --- a/openstack/identity/v3/tokens/testing/requests_test.go +++ b/openstack/identity/v3/tokens/testing/requests_test.go @@ -9,25 +9,25 @@ import ( "github.com/gophercloud/gophercloud/v2" "github.com/gophercloud/gophercloud/v2/openstack/identity/v3/tokens" - "github.com/gophercloud/gophercloud/v2/testhelper" + th "github.com/gophercloud/gophercloud/v2/testhelper" "github.com/gophercloud/gophercloud/v2/testhelper/client" ) // authTokenPost verifies that providing certain AuthOptions and Scope results in an expected JSON structure. func authTokenPost(t *testing.T, options tokens.AuthOptions, scope *tokens.Scope, requestJSON string) { - testhelper.SetupHTTP() - defer testhelper.TeardownHTTP() + th.SetupHTTP() + defer th.TeardownHTTP() client := gophercloud.ServiceClient{ ProviderClient: &gophercloud.ProviderClient{}, - Endpoint: testhelper.Endpoint(), + Endpoint: th.Endpoint(), } - testhelper.Mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) { - testhelper.TestMethod(t, r, "POST") - testhelper.TestHeader(t, r, "Content-Type", "application/json") - testhelper.TestHeader(t, r, "Accept", "application/json") - testhelper.TestJSONRequest(t, r, requestJSON) + th.Mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "POST") + th.TestHeader(t, r, "Content-Type", "application/json") + th.TestHeader(t, r, "Accept", "application/json") + th.TestJSONRequest(t, r, requestJSON) w.WriteHeader(http.StatusCreated) fmt.Fprintf(w, `{ @@ -45,17 +45,17 @@ func authTokenPost(t *testing.T, options tokens.AuthOptions, scope *tokens.Scope ExpiresAt: time.Date(2014, 10, 2, 13, 45, 0, 0, time.UTC), } actual, err := tokens.Create(context.TODO(), &client, &options).Extract() - testhelper.AssertNoErr(t, err) - testhelper.CheckDeepEquals(t, expected, actual) + th.AssertNoErr(t, err) + th.CheckDeepEquals(t, expected, actual) } func authTokenPostErr(t *testing.T, options tokens.AuthOptions, scope *tokens.Scope, includeToken bool, expectedErr error) { - testhelper.SetupHTTP() - defer testhelper.TeardownHTTP() + th.SetupHTTP() + defer th.TeardownHTTP() client := gophercloud.ServiceClient{ ProviderClient: &gophercloud.ProviderClient{}, - Endpoint: testhelper.Endpoint(), + Endpoint: th.Endpoint(), } if includeToken { client.TokenID = "abcdef123456" @@ -303,8 +303,8 @@ func TestCreateSystemScope(t *testing.T) { } func TestCreateUserIDPasswordTrustID(t *testing.T) { - testhelper.SetupHTTP() - defer testhelper.TeardownHTTP() + th.SetupHTTP() + defer th.TeardownHTTP() requestJSON := `{ "auth": { @@ -362,11 +362,11 @@ func TestCreateUserIDPasswordTrustID(t *testing.T) { } } }` - testhelper.Mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) { - testhelper.TestMethod(t, r, "POST") - testhelper.TestHeader(t, r, "Content-Type", "application/json") - testhelper.TestHeader(t, r, "Accept", "application/json") - testhelper.TestJSONRequest(t, r, requestJSON) + th.Mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "POST") + th.TestHeader(t, r, "Content-Type", "application/json") + th.TestHeader(t, r, "Accept", "application/json") + th.TestJSONRequest(t, r, requestJSON) w.WriteHeader(http.StatusCreated) fmt.Fprintf(w, responseJSON) @@ -389,7 +389,7 @@ func TestCreateUserIDPasswordTrustID(t *testing.T) { expectedToken := &tokens.Token{ ExpiresAt: time.Date(2024, 02, 28, 12, 10, 39, 0, time.UTC), } - testhelper.AssertDeepEquals(t, expectedToken, token) + th.AssertDeepEquals(t, expectedToken, token) trust, err := rsp.ExtractTrust() if err != nil { @@ -405,7 +405,7 @@ func TestCreateUserIDPasswordTrustID(t *testing.T) { ID: "c88693b7c81c408e9084ac1e51082bfb", }, } - testhelper.AssertDeepEquals(t, expectedTrust, trust) + th.AssertDeepEquals(t, expectedTrust, trust) } func TestCreateApplicationCredentialIDAndSecret(t *testing.T) { @@ -513,15 +513,15 @@ func TestCreatePasswordTOTPProjectNameAndDomainNameScope(t *testing.T) { } func TestCreateExtractsTokenFromResponse(t *testing.T) { - testhelper.SetupHTTP() - defer testhelper.TeardownHTTP() + th.SetupHTTP() + defer th.TeardownHTTP() client := gophercloud.ServiceClient{ ProviderClient: &gophercloud.ProviderClient{}, - Endpoint: testhelper.Endpoint(), + Endpoint: th.Endpoint(), } - testhelper.Mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) { + th.Mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) { w.Header().Add("X-Subject-Token", "aaa111") w.WriteHeader(http.StatusCreated) @@ -652,22 +652,22 @@ func TestCreateFailureEmptyScope(t *testing.T) { */ func TestGetRequest(t *testing.T) { - testhelper.SetupHTTP() - defer testhelper.TeardownHTTP() + th.SetupHTTP() + defer th.TeardownHTTP() client := gophercloud.ServiceClient{ ProviderClient: &gophercloud.ProviderClient{ TokenID: "12345abcdef", }, - Endpoint: testhelper.Endpoint(), + Endpoint: th.Endpoint(), } - testhelper.Mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) { - testhelper.TestMethod(t, r, "GET") - testhelper.TestHeaderUnset(t, r, "Content-Type") - testhelper.TestHeader(t, r, "Accept", "application/json") - testhelper.TestHeader(t, r, "X-Auth-Token", "12345abcdef") - testhelper.TestHeader(t, r, "X-Subject-Token", "abcdef12345") + th.Mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeaderUnset(t, r, "Content-Type") + th.TestHeader(t, r, "Accept", "application/json") + th.TestHeader(t, r, "X-Auth-Token", "12345abcdef") + th.TestHeader(t, r, "X-Subject-Token", "abcdef12345") w.WriteHeader(http.StatusOK) fmt.Fprintf(w, ` @@ -691,15 +691,15 @@ func prepareAuthTokenHandler(t *testing.T, expectedMethod string, status int) go ProviderClient: &gophercloud.ProviderClient{ TokenID: "12345abcdef", }, - Endpoint: testhelper.Endpoint(), + Endpoint: th.Endpoint(), } - testhelper.Mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) { - testhelper.TestMethod(t, r, expectedMethod) - testhelper.TestHeaderUnset(t, r, "Content-Type") - testhelper.TestHeader(t, r, "Accept", "application/json") - testhelper.TestHeader(t, r, "X-Auth-Token", "12345abcdef") - testhelper.TestHeader(t, r, "X-Subject-Token", "abcdef12345") + th.Mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, expectedMethod) + th.TestHeaderUnset(t, r, "Content-Type") + th.TestHeader(t, r, "Accept", "application/json") + th.TestHeader(t, r, "X-Auth-Token", "12345abcdef") + th.TestHeader(t, r, "X-Subject-Token", "abcdef12345") w.WriteHeader(status) }) @@ -708,8 +708,8 @@ func prepareAuthTokenHandler(t *testing.T, expectedMethod string, status int) go } func TestValidateRequestSuccessful(t *testing.T) { - testhelper.SetupHTTP() - defer testhelper.TeardownHTTP() + th.SetupHTTP() + defer th.TeardownHTTP() client := prepareAuthTokenHandler(t, "HEAD", http.StatusNoContent) ok, err := tokens.Validate(context.TODO(), &client, "abcdef12345") @@ -723,8 +723,8 @@ func TestValidateRequestSuccessful(t *testing.T) { } func TestValidateRequestFailure(t *testing.T) { - testhelper.SetupHTTP() - defer testhelper.TeardownHTTP() + th.SetupHTTP() + defer th.TeardownHTTP() client := prepareAuthTokenHandler(t, "HEAD", http.StatusNotFound) ok, err := tokens.Validate(context.TODO(), &client, "abcdef12345") @@ -738,8 +738,8 @@ func TestValidateRequestFailure(t *testing.T) { } func TestValidateRequestError(t *testing.T) { - testhelper.SetupHTTP() - defer testhelper.TeardownHTTP() + th.SetupHTTP() + defer th.TeardownHTTP() client := prepareAuthTokenHandler(t, "HEAD", http.StatusMethodNotAllowed) _, err := tokens.Validate(context.TODO(), &client, "abcdef12345") @@ -749,17 +749,17 @@ func TestValidateRequestError(t *testing.T) { } func TestRevokeRequestSuccessful(t *testing.T) { - testhelper.SetupHTTP() - defer testhelper.TeardownHTTP() + th.SetupHTTP() + defer th.TeardownHTTP() client := prepareAuthTokenHandler(t, "DELETE", http.StatusNoContent) res := tokens.Revoke(context.TODO(), &client, "abcdef12345") - testhelper.AssertNoErr(t, res.Err) + th.AssertNoErr(t, res.Err) } func TestRevokeRequestError(t *testing.T) { - testhelper.SetupHTTP() - defer testhelper.TeardownHTTP() + th.SetupHTTP() + defer th.TeardownHTTP() client := prepareAuthTokenHandler(t, "DELETE", http.StatusNotFound) res := tokens.Revoke(context.TODO(), &client, "abcdef12345") @@ -769,20 +769,20 @@ func TestRevokeRequestError(t *testing.T) { } func TestNoTokenInResponse(t *testing.T) { - testhelper.SetupHTTP() - defer testhelper.TeardownHTTP() + th.SetupHTTP() + defer th.TeardownHTTP() client := gophercloud.ServiceClient{ ProviderClient: &gophercloud.ProviderClient{}, - Endpoint: testhelper.Endpoint(), + Endpoint: th.Endpoint(), } - testhelper.Mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) { + th.Mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusCreated) fmt.Fprintf(w, `{}`) }) options := tokens.AuthOptions{UserID: "me", Password: "squirrel!"} _, err := tokens.Create(context.TODO(), &client, &options).Extract() - testhelper.AssertNoErr(t, err) + th.AssertNoErr(t, err) } diff --git a/openstack/identity/v3/tokens/testing/results_test.go b/openstack/identity/v3/tokens/testing/results_test.go index e142ac9c57..c45581ffde 100644 --- a/openstack/identity/v3/tokens/testing/results_test.go +++ b/openstack/identity/v3/tokens/testing/results_test.go @@ -3,59 +3,59 @@ package testing import ( "testing" - "github.com/gophercloud/gophercloud/v2/testhelper" + th "github.com/gophercloud/gophercloud/v2/testhelper" ) func TestExtractToken(t *testing.T) { result := getGetResult(t) token, err := result.ExtractToken() - testhelper.AssertNoErr(t, err) + th.AssertNoErr(t, err) - testhelper.CheckDeepEquals(t, &ExpectedToken, token) + th.CheckDeepEquals(t, &ExpectedToken, token) } func TestExtractCatalog(t *testing.T) { result := getGetResult(t) catalog, err := result.ExtractServiceCatalog() - testhelper.AssertNoErr(t, err) + th.AssertNoErr(t, err) - testhelper.CheckDeepEquals(t, &ExpectedServiceCatalog, catalog) + th.CheckDeepEquals(t, &ExpectedServiceCatalog, catalog) } func TestExtractUser(t *testing.T) { result := getGetResult(t) user, err := result.ExtractUser() - testhelper.AssertNoErr(t, err) + th.AssertNoErr(t, err) - testhelper.CheckDeepEquals(t, &ExpectedUser, user) + th.CheckDeepEquals(t, &ExpectedUser, user) } func TestExtractRoles(t *testing.T) { result := getGetResult(t) roles, err := result.ExtractRoles() - testhelper.AssertNoErr(t, err) + th.AssertNoErr(t, err) - testhelper.CheckDeepEquals(t, ExpectedRoles, roles) + th.CheckDeepEquals(t, ExpectedRoles, roles) } func TestExtractProject(t *testing.T) { result := getGetResult(t) project, err := result.ExtractProject() - testhelper.AssertNoErr(t, err) + th.AssertNoErr(t, err) - testhelper.CheckDeepEquals(t, &ExpectedProject, project) + th.CheckDeepEquals(t, &ExpectedProject, project) } func TestExtractDomain(t *testing.T) { result := getGetDomainResult(t) domain, err := result.ExtractDomain() - testhelper.AssertNoErr(t, err) + th.AssertNoErr(t, err) - testhelper.CheckDeepEquals(t, &ExpectedDomain, domain) + th.CheckDeepEquals(t, &ExpectedDomain, domain) } diff --git a/openstack/identity/v3/trusts/testing/fixtures_test.go b/openstack/identity/v3/trusts/testing/fixtures_test.go index 19ede76569..6cc9a8a7d1 100644 --- a/openstack/identity/v3/trusts/testing/fixtures_test.go +++ b/openstack/identity/v3/trusts/testing/fixtures_test.go @@ -7,7 +7,7 @@ import ( "time" "github.com/gophercloud/gophercloud/v2/openstack/identity/v3/trusts" - "github.com/gophercloud/gophercloud/v2/testhelper" + th "github.com/gophercloud/gophercloud/v2/testhelper" "github.com/gophercloud/gophercloud/v2/testhelper/client" ) @@ -201,37 +201,37 @@ var ExpectedTrustRolesSlice = []trusts.Role{FirstRole, SecondRole} // HandleCreateTrust creates an HTTP handler at `/OS-TRUST/trusts` on the // test handler mux that tests trust creation. func HandleCreateTrust(t *testing.T) { - testhelper.Mux.HandleFunc("/OS-TRUST/trusts", func(w http.ResponseWriter, r *http.Request) { - testhelper.TestMethod(t, r, "POST") - testhelper.TestHeader(t, r, "X-Auth-Token", client.TokenID) - testhelper.TestJSONRequest(t, r, CreateRequest) + th.Mux.HandleFunc("/OS-TRUST/trusts", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "POST") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.TestJSONRequest(t, r, CreateRequest) w.WriteHeader(http.StatusCreated) _, err := fmt.Fprintf(w, CreateResponse) - testhelper.AssertNoErr(t, err) + th.AssertNoErr(t, err) }) } // HandleCreateTrustNoExpire creates an HTTP handler at `/OS-TRUST/trusts` on the // test handler mux that tests trust creation. func HandleCreateTrustNoExpire(t *testing.T) { - testhelper.Mux.HandleFunc("/OS-TRUST/trusts", func(w http.ResponseWriter, r *http.Request) { - testhelper.TestMethod(t, r, "POST") - testhelper.TestHeader(t, r, "X-Auth-Token", client.TokenID) - testhelper.TestJSONRequest(t, r, CreateRequestNoExpire) + th.Mux.HandleFunc("/OS-TRUST/trusts", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "POST") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.TestJSONRequest(t, r, CreateRequestNoExpire) w.WriteHeader(http.StatusCreated) _, err := fmt.Fprintf(w, CreateResponseNoExpire) - testhelper.AssertNoErr(t, err) + th.AssertNoErr(t, err) }) } // HandleDeleteUserSuccessfully creates an HTTP handler at `/users` on the // test handler mux that tests user deletion. func HandleDeleteTrust(t *testing.T) { - testhelper.Mux.HandleFunc("/OS-TRUST/trusts/3422b7c113894f5d90665e1a79655e23", func(w http.ResponseWriter, r *http.Request) { - testhelper.TestMethod(t, r, "DELETE") - testhelper.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.Mux.HandleFunc("/OS-TRUST/trusts/3422b7c113894f5d90665e1a79655e23", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "DELETE") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) @@ -240,10 +240,10 @@ func HandleDeleteTrust(t *testing.T) { // HandleGetTrustSuccessfully creates an HTTP handler at `/OS-TRUST/trusts` on the // test handler mux that responds with a single trusts. func HandleGetTrustSuccessfully(t *testing.T) { - testhelper.Mux.HandleFunc("/OS-TRUST/trusts/987fe8", func(w http.ResponseWriter, r *http.Request) { - testhelper.TestMethod(t, r, "GET") - testhelper.TestHeader(t, r, "Accept", "application/json") - testhelper.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.Mux.HandleFunc("/OS-TRUST/trusts/987fe8", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "Accept", "application/json") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -310,10 +310,10 @@ var ExpectedTrustsSlice = []trusts.Trust{FirstTrust, SecondTrust} // HandleListTrustsSuccessfully creates an HTTP handler at `/OS-TRUST/trusts` on the // test handler mux that responds with a list of two trusts. func HandleListTrustsSuccessfully(t *testing.T) { - testhelper.Mux.HandleFunc("/OS-TRUST/trusts", func(w http.ResponseWriter, r *http.Request) { - testhelper.TestMethod(t, r, "GET") - testhelper.TestHeader(t, r, "Accept", "application/json") - testhelper.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.Mux.HandleFunc("/OS-TRUST/trusts", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "Accept", "application/json") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -324,10 +324,10 @@ func HandleListTrustsSuccessfully(t *testing.T) { // HandleListTrustRolesSuccessfully creates an HTTP handler at `/OS-TRUST/trusts/987fe8/roles` on the // test handler mux that responds with a list trust roles. func HandleListTrustRolesSuccessfully(t *testing.T) { - testhelper.Mux.HandleFunc("/OS-TRUST/trusts/987fe8/roles", func(w http.ResponseWriter, r *http.Request) { - testhelper.TestMethod(t, r, "GET") - testhelper.TestHeader(t, r, "Accept", "application/json") - testhelper.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.Mux.HandleFunc("/OS-TRUST/trusts/987fe8/roles", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "Accept", "application/json") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -338,10 +338,10 @@ func HandleListTrustRolesSuccessfully(t *testing.T) { // HandleGetTrustRoleSuccessfully creates an HTTP handler at `/OS-TRUST/trusts/987fe8/roles/c1648e` on the // test handler mux that responds with a trust role details. func HandleGetTrustRoleSuccessfully(t *testing.T) { - testhelper.Mux.HandleFunc("/OS-TRUST/trusts/987fe8/roles/c1648e", func(w http.ResponseWriter, r *http.Request) { - testhelper.TestMethod(t, r, "GET") - testhelper.TestHeader(t, r, "Accept", "application/json") - testhelper.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.Mux.HandleFunc("/OS-TRUST/trusts/987fe8/roles/c1648e", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "Accept", "application/json") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -352,10 +352,10 @@ func HandleGetTrustRoleSuccessfully(t *testing.T) { // HandleCheckTrustRoleSuccessfully creates an HTTP handler at `/OS-TRUST/trusts/987fe8/roles/c1648e` on the // test handler mux that responds with a list trust roles. func HandleCheckTrustRoleSuccessfully(t *testing.T) { - testhelper.Mux.HandleFunc("/OS-TRUST/trusts/987fe8/roles/c1648e", func(w http.ResponseWriter, r *http.Request) { - testhelper.TestMethod(t, r, "HEAD") - testhelper.TestHeader(t, r, "Accept", "application/json") - testhelper.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.Mux.HandleFunc("/OS-TRUST/trusts/987fe8/roles/c1648e", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "HEAD") + th.TestHeader(t, r, "Accept", "application/json") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusOK) }) diff --git a/openstack/sharedfilesystems/v2/schedulerstats/testing/fixtures_test.go b/openstack/sharedfilesystems/v2/schedulerstats/testing/fixtures_test.go index acdd04d53f..88c4b31203 100644 --- a/openstack/sharedfilesystems/v2/schedulerstats/testing/fixtures_test.go +++ b/openstack/sharedfilesystems/v2/schedulerstats/testing/fixtures_test.go @@ -6,7 +6,7 @@ import ( "testing" "github.com/gophercloud/gophercloud/v2/openstack/sharedfilesystems/v2/schedulerstats" - "github.com/gophercloud/gophercloud/v2/testhelper" + th "github.com/gophercloud/gophercloud/v2/testhelper" "github.com/gophercloud/gophercloud/v2/testhelper/client" ) @@ -265,9 +265,9 @@ var ( ) func HandlePoolsListSuccessfully(t *testing.T) { - testhelper.Mux.HandleFunc("/scheduler-stats/pools", func(w http.ResponseWriter, r *http.Request) { - testhelper.TestMethod(t, r, "GET") - testhelper.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.Mux.HandleFunc("/scheduler-stats/pools", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") @@ -277,9 +277,9 @@ func HandlePoolsListSuccessfully(t *testing.T) { fmt.Fprintf(w, PoolsListBody) }) - testhelper.Mux.HandleFunc("/scheduler-stats/pools/detail", func(w http.ResponseWriter, r *http.Request) { - testhelper.TestMethod(t, r, "GET") - testhelper.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.Mux.HandleFunc("/scheduler-stats/pools/detail", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") diff --git a/openstack/sharedfilesystems/v2/schedulerstats/testing/requests_test.go b/openstack/sharedfilesystems/v2/schedulerstats/testing/requests_test.go index 5c2ff36ad9..d6b826ed74 100644 --- a/openstack/sharedfilesystems/v2/schedulerstats/testing/requests_test.go +++ b/openstack/sharedfilesystems/v2/schedulerstats/testing/requests_test.go @@ -6,13 +6,13 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/sharedfilesystems/v2/schedulerstats" "github.com/gophercloud/gophercloud/v2/pagination" - "github.com/gophercloud/gophercloud/v2/testhelper" + th "github.com/gophercloud/gophercloud/v2/testhelper" "github.com/gophercloud/gophercloud/v2/testhelper/client" ) func TestListPoolsDetail(t *testing.T) { - testhelper.SetupHTTP() - defer testhelper.TeardownHTTP() + th.SetupHTTP() + defer th.TeardownHTTP() HandlePoolsListSuccessfully(t) pages := 0 @@ -20,20 +20,20 @@ func TestListPoolsDetail(t *testing.T) { pages++ actual, err := schedulerstats.ExtractPools(page) - testhelper.AssertNoErr(t, err) + th.AssertNoErr(t, err) if len(actual) != 4 { t.Fatalf("Expected 4 backends, got %d", len(actual)) } - testhelper.CheckDeepEquals(t, PoolFake1, actual[0]) - testhelper.CheckDeepEquals(t, PoolFake2, actual[1]) - testhelper.CheckDeepEquals(t, PoolFake3, actual[2]) - testhelper.CheckDeepEquals(t, PoolFake4, actual[3]) + th.CheckDeepEquals(t, PoolFake1, actual[0]) + th.CheckDeepEquals(t, PoolFake2, actual[1]) + th.CheckDeepEquals(t, PoolFake3, actual[2]) + th.CheckDeepEquals(t, PoolFake4, actual[3]) return true, nil }) - testhelper.AssertNoErr(t, err) + th.AssertNoErr(t, err) if pages != 1 { t.Errorf("Expected 1 page, saw %d", pages) @@ -44,20 +44,20 @@ func TestListPoolsDetail(t *testing.T) { pages++ actual, err := schedulerstats.ExtractPools(page) - testhelper.AssertNoErr(t, err) + th.AssertNoErr(t, err) if len(actual) != 4 { t.Fatalf("Expected 4 backends, got %d", len(actual)) } - testhelper.CheckDeepEquals(t, PoolDetailFake1, actual[0]) - testhelper.CheckDeepEquals(t, PoolDetailFake2, actual[1]) - testhelper.CheckDeepEquals(t, PoolDetailFake3, actual[2]) - testhelper.CheckDeepEquals(t, PoolDetailFake4, actual[3]) + th.CheckDeepEquals(t, PoolDetailFake1, actual[0]) + th.CheckDeepEquals(t, PoolDetailFake2, actual[1]) + th.CheckDeepEquals(t, PoolDetailFake3, actual[2]) + th.CheckDeepEquals(t, PoolDetailFake4, actual[3]) return true, nil }) - testhelper.AssertNoErr(t, err) + th.AssertNoErr(t, err) if pages != 1 { t.Errorf("Expected 1 page, saw %d", pages) diff --git a/openstack/sharedfilesystems/v2/services/testing/requests_test.go b/openstack/sharedfilesystems/v2/services/testing/requests_test.go index 16607415b6..d4845ca09e 100644 --- a/openstack/sharedfilesystems/v2/services/testing/requests_test.go +++ b/openstack/sharedfilesystems/v2/services/testing/requests_test.go @@ -6,13 +6,13 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/sharedfilesystems/v2/services" "github.com/gophercloud/gophercloud/v2/pagination" - "github.com/gophercloud/gophercloud/v2/testhelper" + th "github.com/gophercloud/gophercloud/v2/testhelper" "github.com/gophercloud/gophercloud/v2/testhelper/client" ) func TestListServices(t *testing.T) { - testhelper.SetupHTTP() - defer testhelper.TeardownHTTP() + th.SetupHTTP() + defer th.TeardownHTTP() HandleListSuccessfully(t) pages := 0 @@ -27,13 +27,13 @@ func TestListServices(t *testing.T) { if len(actual) != 2 { t.Fatalf("Expected 2 services, got %d", len(actual)) } - testhelper.CheckDeepEquals(t, FirstFakeService, actual[0]) - testhelper.CheckDeepEquals(t, SecondFakeService, actual[1]) + th.CheckDeepEquals(t, FirstFakeService, actual[0]) + th.CheckDeepEquals(t, SecondFakeService, actual[1]) return true, nil }) - testhelper.AssertNoErr(t, err) + th.AssertNoErr(t, err) if pages != 1 { t.Errorf("Expected 1 page, saw %d", pages) diff --git a/openstack/utils/testing/choose_version_test.go b/openstack/utils/testing/choose_version_test.go index 36d8ac37ec..c237e4e036 100644 --- a/openstack/utils/testing/choose_version_test.go +++ b/openstack/utils/testing/choose_version_test.go @@ -9,11 +9,11 @@ import ( "github.com/gophercloud/gophercloud/v2" "github.com/gophercloud/gophercloud/v2/openstack/utils" - "github.com/gophercloud/gophercloud/v2/testhelper" + th "github.com/gophercloud/gophercloud/v2/testhelper" ) func setupVersionHandler() { - testhelper.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + th.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, ` { "versions": { @@ -35,10 +35,10 @@ func setupVersionHandler() { ] } } - `, testhelper.Server.URL, testhelper.Server.URL) + `, th.Server.URL, th.Server.URL) }) // Compute v2.1 API - testhelper.Mux.HandleFunc("/compute/v2.1/", func(w http.ResponseWriter, r *http.Request) { + th.Mux.HandleFunc("/compute/v2.1/", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, ` { "version": { @@ -66,10 +66,10 @@ func setupVersionHandler() { ] } } - `, testhelper.Server.URL) + `, th.Server.URL) }) // Compute v2 API - testhelper.Mux.HandleFunc("/compute/v2/", func(w http.ResponseWriter, r *http.Request) { + th.Mux.HandleFunc("/compute/v2/", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, ` { "version": { @@ -97,10 +97,10 @@ func setupVersionHandler() { ] } } - `, testhelper.Server.URL) + `, th.Server.URL) }) // Ironic API - testhelper.Mux.HandleFunc("/ironic/v1/", func(w http.ResponseWriter, r *http.Request) { + th.Mux.HandleFunc("/ironic/v1/", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, ` { "name": "OpenStack Ironic API", @@ -132,10 +132,10 @@ func setupVersionHandler() { } ] } - `, testhelper.Server.URL, testhelper.Server.URL) + `, th.Server.URL, th.Server.URL) }) // Ironic multi-version - testhelper.Mux.HandleFunc("/ironic/v1.2/", func(w http.ResponseWriter, r *http.Request) { + th.Mux.HandleFunc("/ironic/v1.2/", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, ` { "name": "OpenStack Ironic API", @@ -179,20 +179,20 @@ func setupVersionHandler() { } ] } - `, testhelper.Server.URL, testhelper.Server.URL, testhelper.Server.URL) + `, th.Server.URL, th.Server.URL, th.Server.URL) }) } func TestChooseVersion(t *testing.T) { - testhelper.SetupHTTP() - defer testhelper.TeardownHTTP() + th.SetupHTTP() + defer th.TeardownHTTP() setupVersionHandler() v2 := &utils.Version{ID: "v2.0", Priority: 2, Suffix: "blarg"} v3 := &utils.Version{ID: "v3.0", Priority: 3, Suffix: "hargl"} c := &gophercloud.ProviderClient{ - IdentityBase: testhelper.Endpoint(), + IdentityBase: th.Endpoint(), IdentityEndpoint: "", } v, endpoint, err := utils.ChooseVersion(context.TODO(), c, []*utils.Version{v2, v3}) @@ -205,23 +205,23 @@ func TestChooseVersion(t *testing.T) { t.Errorf("Expected %#v to win, but %#v did instead", v3, v) } - expected := testhelper.Endpoint() + "v3.0/" + expected := th.Endpoint() + "v3.0/" if endpoint != expected { t.Errorf("Expected endpoint [%s], but was [%s] instead", expected, endpoint) } } func TestChooseVersionOpinionatedLink(t *testing.T) { - testhelper.SetupHTTP() - defer testhelper.TeardownHTTP() + th.SetupHTTP() + defer th.TeardownHTTP() setupVersionHandler() v2 := &utils.Version{ID: "v2.0", Priority: 2, Suffix: "nope"} v3 := &utils.Version{ID: "v3.0", Priority: 3, Suffix: "northis"} c := &gophercloud.ProviderClient{ - IdentityBase: testhelper.Endpoint(), - IdentityEndpoint: testhelper.Endpoint() + "v2.0/", + IdentityBase: th.Endpoint(), + IdentityEndpoint: th.Endpoint() + "v2.0/", } v, endpoint, err := utils.ChooseVersion(context.TODO(), c, []*utils.Version{v2, v3}) if err != nil { @@ -232,22 +232,22 @@ func TestChooseVersionOpinionatedLink(t *testing.T) { t.Errorf("Expected %#v to win, but %#v did instead", v2, v) } - expected := testhelper.Endpoint() + "v2.0/" + expected := th.Endpoint() + "v2.0/" if endpoint != expected { t.Errorf("Expected endpoint [%s], but was [%s] instead", expected, endpoint) } } func TestChooseVersionFromSuffix(t *testing.T) { - testhelper.SetupHTTP() - defer testhelper.TeardownHTTP() + th.SetupHTTP() + defer th.TeardownHTTP() v2 := &utils.Version{ID: "v2.0", Priority: 2, Suffix: "/v2.0/"} v3 := &utils.Version{ID: "v3.0", Priority: 3, Suffix: "/v3.0/"} c := &gophercloud.ProviderClient{ - IdentityBase: testhelper.Endpoint(), - IdentityEndpoint: testhelper.Endpoint() + "v2.0/", + IdentityBase: th.Endpoint(), + IdentityEndpoint: th.Endpoint() + "v2.0/", } v, endpoint, err := utils.ChooseVersion(context.TODO(), c, []*utils.Version{v2, v3}) if err != nil { @@ -258,7 +258,7 @@ func TestChooseVersionFromSuffix(t *testing.T) { t.Errorf("Expected %#v to win, but %#v did instead", v2, v) } - expected := testhelper.Endpoint() + "v2.0/" + expected := th.Endpoint() + "v2.0/" if endpoint != expected { t.Errorf("Expected endpoint [%s], but was [%s] instead", expected, endpoint) } @@ -272,33 +272,33 @@ type getSupportedServiceMicroversions struct { } func TestGetSupportedVersions(t *testing.T) { - testhelper.SetupHTTP() - defer testhelper.TeardownHTTP() + th.SetupHTTP() + defer th.TeardownHTTP() setupVersionHandler() tests := []getSupportedServiceMicroversions{ { // v2 does not support microversions and returns error - Endpoint: testhelper.Endpoint() + "compute/v2/", + Endpoint: th.Endpoint() + "compute/v2/", ExpectedMax: "", ExpectedMin: "", ExpectedErr: true, }, { - Endpoint: testhelper.Endpoint() + "compute/v2.1/", + Endpoint: th.Endpoint() + "compute/v2.1/", ExpectedMax: "2.90", ExpectedMin: "2.1", ExpectedErr: false, }, { - Endpoint: testhelper.Endpoint() + "ironic/v1/", + Endpoint: th.Endpoint() + "ironic/v1/", ExpectedMax: "1.87", ExpectedMin: "1.1", ExpectedErr: false, }, { // This endpoint returns multiple versions, which is not supported - Endpoint: testhelper.Endpoint() + "ironic/v1.2/", + Endpoint: th.Endpoint() + "ironic/v1.2/", ExpectedMax: "not-relevant", ExpectedMin: "not-relevant", ExpectedErr: true, @@ -307,8 +307,8 @@ func TestGetSupportedVersions(t *testing.T) { for _, test := range tests { c := &gophercloud.ProviderClient{ - IdentityBase: testhelper.Endpoint(), - IdentityEndpoint: testhelper.Endpoint() + "v2.0/", + IdentityBase: th.Endpoint(), + IdentityEndpoint: th.Endpoint() + "v2.0/", } client := &gophercloud.ServiceClient{ diff --git a/pagination/testing/linked_test.go b/pagination/testing/linked_test.go index 83673f19b8..25166ad861 100644 --- a/pagination/testing/linked_test.go +++ b/pagination/testing/linked_test.go @@ -8,7 +8,7 @@ import ( "testing" "github.com/gophercloud/gophercloud/v2/pagination" - "github.com/gophercloud/gophercloud/v2/testhelper" + th "github.com/gophercloud/gophercloud/v2/testhelper" ) // LinkedPager sample and test cases. @@ -31,19 +31,19 @@ func ExtractLinkedInts(r pagination.Page) ([]int, error) { } func createLinked() pagination.Pager { - testhelper.SetupHTTP() + th.SetupHTTP() - testhelper.Mux.HandleFunc("/page1", func(w http.ResponseWriter, r *http.Request) { + th.Mux.HandleFunc("/page1", func(w http.ResponseWriter, r *http.Request) { w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, `{ "ints": [1, 2, 3], "links": { "next": "%s/page2" } }`, testhelper.Server.URL) + fmt.Fprintf(w, `{ "ints": [1, 2, 3], "links": { "next": "%s/page2" } }`, th.Server.URL) }) - testhelper.Mux.HandleFunc("/page2", func(w http.ResponseWriter, r *http.Request) { + th.Mux.HandleFunc("/page2", func(w http.ResponseWriter, r *http.Request) { w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, `{ "ints": [4, 5, 6], "links": { "next": "%s/page3" } }`, testhelper.Server.URL) + fmt.Fprintf(w, `{ "ints": [4, 5, 6], "links": { "next": "%s/page3" } }`, th.Server.URL) }) - testhelper.Mux.HandleFunc("/page3", func(w http.ResponseWriter, r *http.Request) { + th.Mux.HandleFunc("/page3", func(w http.ResponseWriter, r *http.Request) { w.Header().Add("Content-Type", "application/json") fmt.Fprintf(w, `{ "ints": [7, 8, 9], "links": { "next": null } }`) }) @@ -54,12 +54,12 @@ func createLinked() pagination.Pager { return LinkedPageResult{pagination.LinkedPageBase{PageResult: r}} } - return pagination.NewPager(client, testhelper.Server.URL+"/page1", createPage) + return pagination.NewPager(client, th.Server.URL+"/page1", createPage) } func TestEnumerateLinked(t *testing.T) { pager := createLinked() - defer testhelper.TeardownHTTP() + defer th.TeardownHTTP() callCount := 0 err := pager.EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { @@ -101,13 +101,13 @@ func TestEnumerateLinked(t *testing.T) { func TestAllPagesLinked(t *testing.T) { pager := createLinked() - defer testhelper.TeardownHTTP() + defer th.TeardownHTTP() page, err := pager.AllPages(context.TODO()) - testhelper.AssertNoErr(t, err) + th.AssertNoErr(t, err) expected := []int{1, 2, 3, 4, 5, 6, 7, 8, 9} actual, err := ExtractLinkedInts(page) - testhelper.AssertNoErr(t, err) - testhelper.CheckDeepEquals(t, expected, actual) + th.AssertNoErr(t, err) + th.CheckDeepEquals(t, expected, actual) } diff --git a/pagination/testing/marker_test.go b/pagination/testing/marker_test.go index a1084ac12f..45c943e5b7 100644 --- a/pagination/testing/marker_test.go +++ b/pagination/testing/marker_test.go @@ -8,7 +8,7 @@ import ( "testing" "github.com/gophercloud/gophercloud/v2/pagination" - "github.com/gophercloud/gophercloud/v2/testhelper" + th "github.com/gophercloud/gophercloud/v2/testhelper" ) // MarkerPager sample and test cases. @@ -37,9 +37,9 @@ func (r MarkerPageResult) LastMarker() (string, error) { } func createMarkerPaged(t *testing.T) pagination.Pager { - testhelper.SetupHTTP() + th.SetupHTTP() - testhelper.Mux.HandleFunc("/page", func(w http.ResponseWriter, r *http.Request) { + th.Mux.HandleFunc("/page", func(w http.ResponseWriter, r *http.Request) { if err := r.ParseForm(); err != nil { t.Errorf("Failed to parse request form %v", err) } @@ -66,7 +66,7 @@ func createMarkerPaged(t *testing.T) pagination.Pager { return p } - return pagination.NewPager(client, testhelper.Server.URL+"/page", createPage) + return pagination.NewPager(client, th.Server.URL+"/page", createPage) } func ExtractMarkerStrings(page pagination.Page) ([]string, error) { @@ -83,7 +83,7 @@ func ExtractMarkerStrings(page pagination.Page) ([]string, error) { func TestEnumerateMarker(t *testing.T) { pager := createMarkerPaged(t) - defer testhelper.TeardownHTTP() + defer th.TeardownHTTP() callCount := 0 err := pager.EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { @@ -107,24 +107,24 @@ func TestEnumerateMarker(t *testing.T) { return false, nil } - testhelper.CheckDeepEquals(t, expected, actual) + th.CheckDeepEquals(t, expected, actual) callCount++ return true, nil }) - testhelper.AssertNoErr(t, err) - testhelper.AssertEquals(t, callCount, 3) + th.AssertNoErr(t, err) + th.AssertEquals(t, callCount, 3) } func TestAllPagesMarker(t *testing.T) { pager := createMarkerPaged(t) - defer testhelper.TeardownHTTP() + defer th.TeardownHTTP() page, err := pager.AllPages(context.TODO()) - testhelper.AssertNoErr(t, err) + th.AssertNoErr(t, err) expected := []string{"aaa", "bbb", "ccc", "ddd", "eee", "fff", "ggg", "hhh", "iii"} actual, err := ExtractMarkerStrings(page) - testhelper.AssertNoErr(t, err) - testhelper.CheckDeepEquals(t, expected, actual) + th.AssertNoErr(t, err) + th.CheckDeepEquals(t, expected, actual) } diff --git a/pagination/testing/pagination_test.go b/pagination/testing/pagination_test.go index b730676d4e..e10ef56847 100644 --- a/pagination/testing/pagination_test.go +++ b/pagination/testing/pagination_test.go @@ -2,12 +2,12 @@ package testing import ( "github.com/gophercloud/gophercloud/v2" - "github.com/gophercloud/gophercloud/v2/testhelper" + th "github.com/gophercloud/gophercloud/v2/testhelper" ) func createClient() *gophercloud.ServiceClient { return &gophercloud.ServiceClient{ ProviderClient: &gophercloud.ProviderClient{TokenID: "abc123"}, - Endpoint: testhelper.Endpoint(), + Endpoint: th.Endpoint(), } } diff --git a/pagination/testing/single_test.go b/pagination/testing/single_test.go index 21daedff0a..6bcd930cb2 100644 --- a/pagination/testing/single_test.go +++ b/pagination/testing/single_test.go @@ -7,7 +7,7 @@ import ( "testing" "github.com/gophercloud/gophercloud/v2/pagination" - "github.com/gophercloud/gophercloud/v2/testhelper" + th "github.com/gophercloud/gophercloud/v2/testhelper" ) // SinglePage sample and test cases. @@ -33,10 +33,10 @@ func ExtractSingleInts(r pagination.Page) ([]int, error) { } func setupSinglePaged() pagination.Pager { - testhelper.SetupHTTP() + th.SetupHTTP() client := createClient() - testhelper.Mux.HandleFunc("/only", func(w http.ResponseWriter, r *http.Request) { + th.Mux.HandleFunc("/only", func(w http.ResponseWriter, r *http.Request) { w.Header().Add("Content-Type", "application/json") fmt.Fprintf(w, `{ "ints": [1, 2, 3] }`) }) @@ -45,36 +45,36 @@ func setupSinglePaged() pagination.Pager { return SinglePageResult{pagination.SinglePageBase(r)} } - return pagination.NewPager(client, testhelper.Server.URL+"/only", createPage) + return pagination.NewPager(client, th.Server.URL+"/only", createPage) } func TestEnumerateSinglePaged(t *testing.T) { callCount := 0 pager := setupSinglePaged() - defer testhelper.TeardownHTTP() + defer th.TeardownHTTP() err := pager.EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { callCount++ expected := []int{1, 2, 3} actual, err := ExtractSingleInts(page) - testhelper.AssertNoErr(t, err) - testhelper.CheckDeepEquals(t, expected, actual) + th.AssertNoErr(t, err) + th.CheckDeepEquals(t, expected, actual) return true, nil }) - testhelper.CheckNoErr(t, err) - testhelper.CheckEquals(t, 1, callCount) + th.CheckNoErr(t, err) + th.CheckEquals(t, 1, callCount) } func TestAllPagesSingle(t *testing.T) { pager := setupSinglePaged() - defer testhelper.TeardownHTTP() + defer th.TeardownHTTP() page, err := pager.AllPages(context.TODO()) - testhelper.AssertNoErr(t, err) + th.AssertNoErr(t, err) expected := []int{1, 2, 3} actual, err := ExtractSingleInts(page) - testhelper.AssertNoErr(t, err) - testhelper.CheckDeepEquals(t, expected, actual) + th.AssertNoErr(t, err) + th.CheckDeepEquals(t, expected, actual) } diff --git a/testhelper/client/fake.go b/testhelper/client/fake.go index 6e25f759d7..29514b0a65 100644 --- a/testhelper/client/fake.go +++ b/testhelper/client/fake.go @@ -2,7 +2,7 @@ package client import ( "github.com/gophercloud/gophercloud/v2" - "github.com/gophercloud/gophercloud/v2/testhelper" + th "github.com/gophercloud/gophercloud/v2/testhelper" ) // Fake token to use. @@ -12,6 +12,6 @@ const TokenID = "cbc36478b0bd8e67e89469c7749d4127" func ServiceClient() *gophercloud.ServiceClient { return &gophercloud.ServiceClient{ ProviderClient: &gophercloud.ProviderClient{TokenID: TokenID}, - Endpoint: testhelper.Endpoint(), + Endpoint: th.Endpoint(), } } From fd05e46ab13c879b5171092a34a4f48d12fcde35 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Thu, 30 May 2024 23:54:21 +0100 Subject: [PATCH 064/353] tests: Add AssertTypeOf helper Better errors messages since we see the different types. Signed-off-by: Stephen Finucane --- testhelper/convenience.go | 10 ++++++++++ testing/auth_options_test.go | 3 +-- testing/params_test.go | 3 +-- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/testhelper/convenience.go b/testhelper/convenience.go index 3b3e63979d..1ea727045f 100644 --- a/testhelper/convenience.go +++ b/testhelper/convenience.go @@ -232,6 +232,16 @@ func CheckEquals(t *testing.T, expected, actual any) { } } +// AssertDeepEquals - like Equals - performs a comparison - but on more complex +// structures that requires deeper inspection +func AssertTypeEquals(t *testing.T, expected, actual any) { + t.Helper() + + if reflect.TypeOf(expected) != reflect.TypeOf(actual) { + logFatal(t, fmt.Sprintf("expected %s but got %s", green(expected), yellow(actual))) + } +} + // AssertDeepEquals - like Equals - performs a comparison - but on more complex // structures that requires deeper inspection func AssertDeepEquals(t *testing.T, expected, actual any) { diff --git a/testing/auth_options_test.go b/testing/auth_options_test.go index 1f9b230b50..fc2c936f89 100644 --- a/testing/auth_options_test.go +++ b/testing/auth_options_test.go @@ -1,7 +1,6 @@ package testing import ( - "reflect" "testing" "github.com/gophercloud/gophercloud/v2" @@ -199,6 +198,6 @@ func TestToTokenV3ScopeMap(t *testing.T) { } for _, failCase := range failCases { _, err := failCase.opts.ToTokenV3ScopeMap() - th.AssertDeepEquals(t, reflect.TypeOf(failCase.expected), reflect.TypeOf(err)) + th.AssertTypeEquals(t, failCase.expected, err) } } diff --git a/testing/params_test.go b/testing/params_test.go index 9e74bdd9ea..057a23b58a 100644 --- a/testing/params_test.go +++ b/testing/params_test.go @@ -2,7 +2,6 @@ package testing import ( "net/url" - "reflect" "testing" "time" @@ -255,7 +254,7 @@ func TestBuildRequestBody(t *testing.T) { for _, failCase := range failCases { _, err := gophercloud.BuildRequestBody(failCase.opts, "auth") - th.AssertDeepEquals(t, reflect.TypeOf(failCase.expected), reflect.TypeOf(err)) + th.AssertTypeEquals(t, failCase.expected, err) } createdAt := time.Date(2018, 1, 4, 10, 00, 12, 0, time.UTC) From 48356f113360f80f8e52660b6c2b7af80c25c307 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Fri, 31 May 2024 00:03:43 +0100 Subject: [PATCH 065/353] testing: Set test case names Make this a little easier to understand failures when they occur. Signed-off-by: Stephen Finucane --- testing/auth_options_test.go | 44 ++++++++++++++++++++---------------- testing/params_test.go | 22 ++++++++++++++---- 2 files changed, 42 insertions(+), 24 deletions(-) diff --git a/testing/auth_options_test.go b/testing/auth_options_test.go index fc2c936f89..67b06174e6 100644 --- a/testing/auth_options_test.go +++ b/testing/auth_options_test.go @@ -14,11 +14,12 @@ func TestToTokenV3ScopeMap(t *testing.T) { domainName := "Default" var successCases = []struct { + name string opts gophercloud.AuthOptions expected map[string]any }{ - // System-scoped { + "System-scoped", gophercloud.AuthOptions{ Scope: &gophercloud.AuthScope{ System: true, @@ -30,8 +31,8 @@ func TestToTokenV3ScopeMap(t *testing.T) { }, }, }, - // Trust-scoped { + "Trust-scoped", gophercloud.AuthOptions{ Scope: &gophercloud.AuthScope{ TrustID: "05144328-1f7d-46a9-a978-17eaad187077", @@ -43,8 +44,8 @@ func TestToTokenV3ScopeMap(t *testing.T) { }, }, }, - // Project-scoped (ID) { + "Project-scoped (ID)", gophercloud.AuthOptions{ Scope: &gophercloud.AuthScope{ ProjectID: projectID, @@ -56,8 +57,8 @@ func TestToTokenV3ScopeMap(t *testing.T) { }, }, }, - // Project-scoped (name) { + "Project-scoped (name)", gophercloud.AuthOptions{ Scope: &gophercloud.AuthScope{ ProjectName: projectName, @@ -73,8 +74,8 @@ func TestToTokenV3ScopeMap(t *testing.T) { }, }, }, - // Domain-scoped (ID) { + "Domain-scoped (ID)", gophercloud.AuthOptions{ Scope: &gophercloud.AuthScope{ DomainID: domainID, @@ -86,8 +87,8 @@ func TestToTokenV3ScopeMap(t *testing.T) { }, }, }, - // Domain-scoped (name) { + "Domain-scoped (name)", gophercloud.AuthOptions{ Scope: &gophercloud.AuthScope{ DomainName: domainName, @@ -99,8 +100,8 @@ func TestToTokenV3ScopeMap(t *testing.T) { }, }, }, - // Empty with project fallback (ID) { + "Empty with project fallback (ID)", gophercloud.AuthOptions{ TenantID: projectID, Scope: nil, @@ -111,8 +112,8 @@ func TestToTokenV3ScopeMap(t *testing.T) { }, }, }, - // Empty with project fallback (name) { + "Empty with project fallback (name)", gophercloud.AuthOptions{ TenantName: projectName, DomainName: domainName, @@ -127,8 +128,8 @@ func TestToTokenV3ScopeMap(t *testing.T) { }, }, }, - // Empty without fallback { + "Empty without fallback", gophercloud.AuthOptions{ Scope: nil, }, @@ -136,17 +137,20 @@ func TestToTokenV3ScopeMap(t *testing.T) { }, } for _, successCase := range successCases { - actual, err := successCase.opts.ToTokenV3ScopeMap() - th.AssertNoErr(t, err) - th.AssertDeepEquals(t, successCase.expected, actual) + t.Run(successCase.name, func(t *testing.T) { + actual, err := successCase.opts.ToTokenV3ScopeMap() + th.AssertNoErr(t, err) + th.AssertDeepEquals(t, successCase.expected, actual) + }) } var failCases = []struct { + name string opts gophercloud.AuthOptions expected error }{ - // Project-scoped with name but missing domain ID/name { + "Project-scoped with name but missing domain ID/name", gophercloud.AuthOptions{ Scope: &gophercloud.AuthScope{ ProjectName: "admin", @@ -154,8 +158,8 @@ func TestToTokenV3ScopeMap(t *testing.T) { }, gophercloud.ErrScopeDomainIDOrDomainName{}, }, - // Project-scoped with both project name and project ID { + "Project-scoped with both project name and project ID", gophercloud.AuthOptions{ Scope: &gophercloud.AuthScope{ ProjectName: "admin", @@ -165,8 +169,8 @@ func TestToTokenV3ScopeMap(t *testing.T) { }, gophercloud.ErrScopeProjectIDOrProjectName{}, }, - // Project-scoped with name and unnecessary domain ID { + "Project-scoped with name and unnecessary domain ID", gophercloud.AuthOptions{ Scope: &gophercloud.AuthScope{ ProjectID: "685038cd-3c25-4faf-8f9b-78c18e503190", @@ -175,8 +179,8 @@ func TestToTokenV3ScopeMap(t *testing.T) { }, gophercloud.ErrScopeProjectIDAlone{}, }, - // Project-scoped with name and unnecessary domain name { + "Project-scoped with name and unnecessary domain name", gophercloud.AuthOptions{ Scope: &gophercloud.AuthScope{ ProjectID: "685038cd-3c25-4faf-8f9b-78c18e503190", @@ -185,8 +189,8 @@ func TestToTokenV3ScopeMap(t *testing.T) { }, gophercloud.ErrScopeProjectIDAlone{}, }, - // Domain-scoped with both domain name and domain ID { + "Domain-scoped with both domain name and domain ID", gophercloud.AuthOptions{ Scope: &gophercloud.AuthScope{ DomainID: "e4b515b8-e453-49d8-9cce-4bec244fa84e", @@ -197,7 +201,9 @@ func TestToTokenV3ScopeMap(t *testing.T) { }, } for _, failCase := range failCases { - _, err := failCase.opts.ToTokenV3ScopeMap() - th.AssertTypeEquals(t, failCase.expected, err) + t.Run(failCase.name, func(t *testing.T) { + _, err := failCase.opts.ToTokenV3ScopeMap() + th.AssertTypeEquals(t, failCase.expected, err) + }) } } diff --git a/testing/params_test.go b/testing/params_test.go index 057a23b58a..146fc27025 100644 --- a/testing/params_test.go +++ b/testing/params_test.go @@ -166,10 +166,12 @@ func TestBuildRequestBody(t *testing.T) { } var successCases = []struct { + name string opts AuthOptions expected map[string]any }{ { + "Password", AuthOptions{ PasswordCredentials: &PasswordCredentials{ Username: "me", @@ -186,6 +188,7 @@ func TestBuildRequestBody(t *testing.T) { }, }, { + "Token", AuthOptions{ TokenCredentials: &TokenCredentials{ ID: "1234567", @@ -202,16 +205,20 @@ func TestBuildRequestBody(t *testing.T) { } for _, successCase := range successCases { - actual, err := gophercloud.BuildRequestBody(successCase.opts, "auth") - th.AssertNoErr(t, err) - th.AssertDeepEquals(t, successCase.expected, actual) + t.Run(successCase.name, func(t *testing.T) { + actual, err := gophercloud.BuildRequestBody(successCase.opts, "auth") + th.AssertNoErr(t, err) + th.AssertDeepEquals(t, successCase.expected, actual) + }) } var failCases = []struct { + name string opts AuthOptions expected error }{ { + "Conflicting tenant name and ID", AuthOptions{ TenantID: "987654321", TenantName: "me", @@ -219,6 +226,7 @@ func TestBuildRequestBody(t *testing.T) { gophercloud.ErrMissingInput{}, }, { + "Conflicting password and token auth", AuthOptions{ TokenCredentials: &TokenCredentials{ ID: "1234567", @@ -231,6 +239,7 @@ func TestBuildRequestBody(t *testing.T) { gophercloud.ErrMissingInput{}, }, { + "Missing Username or UserID", AuthOptions{ PasswordCredentials: &PasswordCredentials{ Password: "swordfish", @@ -239,6 +248,7 @@ func TestBuildRequestBody(t *testing.T) { gophercloud.ErrMissingInput{}, }, { + "Missing filler fields", AuthOptions{ PasswordCredentials: &PasswordCredentials{ Username: "me", @@ -253,8 +263,10 @@ func TestBuildRequestBody(t *testing.T) { } for _, failCase := range failCases { - _, err := gophercloud.BuildRequestBody(failCase.opts, "auth") - th.AssertTypeEquals(t, failCase.expected, err) + t.Run(failCase.name, func(t *testing.T) { + _, err := gophercloud.BuildRequestBody(failCase.opts, "auth") + th.AssertTypeEquals(t, failCase.expected, err) + }) } createdAt := time.Date(2018, 1, 4, 10, 00, 12, 0, time.UTC) From 596883b483733675d5a4cfefe1e4994169ad7e81 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Fri, 31 May 2024 15:25:54 +0100 Subject: [PATCH 066/353] tests: Be consistent in our generation of credentials We were not passing through user IDs, despite our test wrappers indicating you could user either user IDs or usernames. Similarly, we were not always setting scope, which could cause issues when using a project ID. Correct all issues. We should eventually move this to another test helper but that's a job for a later change. Signed-off-by: Stephen Finucane --- internal/acceptance/openstack/client_test.go | 2 +- .../identity/v3/applicationcredentials_test.go | 4 ++-- .../openstack/identity/v3/credentials_test.go | 4 ++-- .../openstack/identity/v3/ec2credentials_test.go | 2 +- .../acceptance/openstack/identity/v3/oauth1_test.go | 2 +- .../acceptance/openstack/identity/v3/token_test.go | 10 +++++++++- .../acceptance/openstack/identity/v3/trusts_test.go | 7 +++++++ 7 files changed, 23 insertions(+), 8 deletions(-) diff --git a/internal/acceptance/openstack/client_test.go b/internal/acceptance/openstack/client_test.go index 7902961c55..69e9a09367 100644 --- a/internal/acceptance/openstack/client_test.go +++ b/internal/acceptance/openstack/client_test.go @@ -56,10 +56,10 @@ func TestEC2AuthMethod(t *testing.T) { authOptions := tokens.AuthOptions{ Username: ao.Username, + UserID: ao.UserID, Password: ao.Password, DomainName: ao.DomainName, DomainID: ao.DomainID, - // We need a scope to get the token roles list Scope: tokens.Scope{ ProjectID: ao.TenantID, ProjectName: ao.TenantName, diff --git a/internal/acceptance/openstack/identity/v3/applicationcredentials_test.go b/internal/acceptance/openstack/identity/v3/applicationcredentials_test.go index 1390e284a9..7a4ad01e1c 100644 --- a/internal/acceptance/openstack/identity/v3/applicationcredentials_test.go +++ b/internal/acceptance/openstack/identity/v3/applicationcredentials_test.go @@ -34,10 +34,10 @@ func TestApplicationCredentialsCRD(t *testing.T) { authOptions := tokens.AuthOptions{ Username: ao.Username, + UserID: ao.UserID, Password: ao.Password, DomainName: ao.DomainName, DomainID: ao.DomainID, - // We need a scope to get the token roles list Scope: tokens.Scope{ ProjectID: ao.TenantID, ProjectName: ao.TenantName, @@ -178,10 +178,10 @@ func TestApplicationCredentialsAccessRules(t *testing.T) { authOptions := tokens.AuthOptions{ Username: ao.Username, + UserID: ao.UserID, Password: ao.Password, DomainName: ao.DomainName, DomainID: ao.DomainID, - // We need a scope to get the token roles list Scope: tokens.Scope{ ProjectID: ao.TenantID, ProjectName: ao.TenantName, diff --git a/internal/acceptance/openstack/identity/v3/credentials_test.go b/internal/acceptance/openstack/identity/v3/credentials_test.go index a1167ac647..ce0362abee 100644 --- a/internal/acceptance/openstack/identity/v3/credentials_test.go +++ b/internal/acceptance/openstack/identity/v3/credentials_test.go @@ -24,10 +24,10 @@ func TestCredentialsCRUD(t *testing.T) { authOptions := tokens.AuthOptions{ Username: ao.Username, + UserID: ao.UserID, Password: ao.Password, DomainName: ao.DomainName, DomainID: ao.DomainID, - // We need a scope to get the token roles list Scope: tokens.Scope{ ProjectID: ao.TenantID, ProjectName: ao.TenantName, @@ -101,10 +101,10 @@ func TestCredentialsValidateS3(t *testing.T) { authOptions := tokens.AuthOptions{ Username: ao.Username, + UserID: ao.UserID, Password: ao.Password, DomainName: ao.DomainName, DomainID: ao.DomainID, - // We need a scope to get the token roles list Scope: tokens.Scope{ ProjectID: ao.TenantID, ProjectName: ao.TenantName, diff --git a/internal/acceptance/openstack/identity/v3/ec2credentials_test.go b/internal/acceptance/openstack/identity/v3/ec2credentials_test.go index 6500aa6f0c..7f27f51ed4 100644 --- a/internal/acceptance/openstack/identity/v3/ec2credentials_test.go +++ b/internal/acceptance/openstack/identity/v3/ec2credentials_test.go @@ -23,10 +23,10 @@ func TestEC2CredentialsCRD(t *testing.T) { authOptions := tokens.AuthOptions{ Username: ao.Username, + UserID: ao.UserID, Password: ao.Password, DomainName: ao.DomainName, DomainID: ao.DomainID, - // We need a scope to get the token roles list Scope: tokens.Scope{ ProjectID: ao.TenantID, ProjectName: ao.TenantName, diff --git a/internal/acceptance/openstack/identity/v3/oauth1_test.go b/internal/acceptance/openstack/identity/v3/oauth1_test.go index da6c8be148..7a93d43fb4 100644 --- a/internal/acceptance/openstack/identity/v3/oauth1_test.go +++ b/internal/acceptance/openstack/identity/v3/oauth1_test.go @@ -24,10 +24,10 @@ func TestOAuth1CRUD(t *testing.T) { authOptions := tokens.AuthOptions{ Username: ao.Username, + UserID: ao.UserID, Password: ao.Password, DomainName: ao.DomainName, DomainID: ao.DomainID, - // We need a scope to get the token roles list Scope: tokens.Scope{ ProjectID: ao.TenantID, ProjectName: ao.TenantName, diff --git a/internal/acceptance/openstack/identity/v3/token_test.go b/internal/acceptance/openstack/identity/v3/token_test.go index d5274ff6b1..1bc436caa7 100644 --- a/internal/acceptance/openstack/identity/v3/token_test.go +++ b/internal/acceptance/openstack/identity/v3/token_test.go @@ -24,8 +24,16 @@ func TestTokensGet(t *testing.T) { authOptions := tokens.AuthOptions{ Username: ao.Username, + UserID: ao.UserID, Password: ao.Password, - DomainName: "default", + DomainName: ao.DomainName, + DomainID: ao.DomainID, + Scope: tokens.Scope{ + ProjectID: ao.TenantID, + ProjectName: ao.TenantName, + DomainID: ao.DomainID, + DomainName: ao.DomainName, + }, } token, err := tokens.Create(context.TODO(), client, &authOptions).Extract() diff --git a/internal/acceptance/openstack/identity/v3/trusts_test.go b/internal/acceptance/openstack/identity/v3/trusts_test.go index 39c7191eea..2eb659d55b 100644 --- a/internal/acceptance/openstack/identity/v3/trusts_test.go +++ b/internal/acceptance/openstack/identity/v3/trusts_test.go @@ -29,9 +29,16 @@ func TestTrustCRUD(t *testing.T) { authOptions := tokens.AuthOptions{ Username: ao.Username, + UserID: ao.UserID, Password: ao.Password, DomainName: ao.DomainName, DomainID: ao.DomainID, + Scope: tokens.Scope{ + ProjectID: ao.TenantID, + ProjectName: ao.TenantName, + DomainID: ao.DomainID, + DomainName: ao.DomainName, + }, } token, err := tokens.Create(context.TODO(), client, &authOptions).Extract() From 5d5024a243ce4271cc1f126c8fc39b869dd3b23b Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Fri, 31 May 2024 15:29:19 +0100 Subject: [PATCH 067/353] tests: Add missing RequireAdmin calls We're clearly not testing with non-admin credentials. That would be a good future test but for now we simply fix the issues. Signed-off-by: Stephen Finucane --- .../acceptance/openstack/identity/v3/federation_test.go | 6 ++++-- internal/acceptance/openstack/identity/v3/oauth1_test.go | 2 ++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/internal/acceptance/openstack/identity/v3/federation_test.go b/internal/acceptance/openstack/identity/v3/federation_test.go index b52d54cc30..35986dc15c 100644 --- a/internal/acceptance/openstack/identity/v3/federation_test.go +++ b/internal/acceptance/openstack/identity/v3/federation_test.go @@ -15,6 +15,8 @@ import ( ) func TestListMappings(t *testing.T) { + clients.RequireAdmin(t) + client, err := clients.NewIdentityV3Client() th.AssertNoErr(t, err) @@ -28,10 +30,10 @@ func TestListMappings(t *testing.T) { } func TestMappingsCRUD(t *testing.T) { - mappingName := tools.RandomString("TESTMAPPING-", 8) - clients.RequireAdmin(t) + mappingName := tools.RandomString("TESTMAPPING-", 8) + client, err := clients.NewIdentityV3Client() th.AssertNoErr(t, err) diff --git a/internal/acceptance/openstack/identity/v3/oauth1_test.go b/internal/acceptance/openstack/identity/v3/oauth1_test.go index 7a93d43fb4..125fdd0588 100644 --- a/internal/acceptance/openstack/identity/v3/oauth1_test.go +++ b/internal/acceptance/openstack/identity/v3/oauth1_test.go @@ -16,6 +16,8 @@ import ( ) func TestOAuth1CRUD(t *testing.T) { + clients.RequireAdmin(t) + client, err := clients.NewIdentityV3Client() th.AssertNoErr(t, err) From cfa40d7bcd21ff2e53f1ed36a35307a08cf69caa Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Fri, 31 May 2024 15:30:16 +0100 Subject: [PATCH 068/353] scripts: Add getenvvar tool Setting the necessary required environment variables has proven relatively tricky to do. Add a tool that will start doing this for us. Signed-off-by: Stephen Finucane --- script/getenvvar | 85 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100755 script/getenvvar diff --git a/script/getenvvar b/script/getenvvar new file mode 100755 index 0000000000..dbaa08f445 --- /dev/null +++ b/script/getenvvar @@ -0,0 +1,85 @@ +#!/usr/bin/env python3 + +""" +Set environment variables required for the CI jobs by inspection of the +clouds.yaml file. This is useful where you only have this file. + +To set variables: + + $ eval $(./script/getenvvar) + +To unset them: + + $ unset $(compgen -v | grep OS_) +""" + +import argparse +from pathlib import Path +import sys + +import yaml + +p = Path('~/.config/openstack/clouds.yaml').expanduser() +parser = argparse.ArgumentParser() +parser.add_argument( + 'cloud', + help="Cloud to export credentials for", +) + +args = parser.parse_args() + +with p.open() as fh: + data = yaml.safe_load(fh) + +if args.cloud not in data.get('clouds', {}) or {}: + print(f'Could not find cloud {args.cloud} in {str(p)}', file=sys.stderr) + sys.exit(1) + +cloud = data['clouds'][args.cloud] + +if 'auth' not in cloud: + print(f'Missing auth section for cloud {cloud}', file=sys.stderr) + sys.exit(1) + +auth = cloud['auth'] + +if 'username' not in auth or 'password' not in auth: + print('Only password authentication supported', file=sys.stderr) + sys.exit(1) + +# FIXME: This should work but does not, since the check for auth credentials +# is just 'OS_USERNAME == admin' + +# user_id = auth.get('user_id') +# project_id = auth.get('project_id') +# if not user_id or not project_id: +# import openstack +# conn = openstack.connect(args.cloud) +# auth_ref = conn.config.get_auth().get_auth_ref(conn.session) +# +# if not user_id: +# user_id = auth_ref.user_id +# +# if not project_id: +# project_id = auth_ref.project_id +# +# result = f""" +# unset OS_CLOUD +# export OS_AUTH_URL={auth['auth_url']} +# export OS_USERID={user_id} +# export OS_PASSWORD={auth['password']} +# export OS_PROJECT_ID={project_id} +# export OS_REGION_NAME={cloud['region_name']} +# """.strip() + +result = f""" +unset OS_CLOUD +export OS_AUTH_URL={auth['auth_url']} +export OS_USERNAME={auth['username']} +export OS_PASSWORD={auth['password']} +export OS_PROJECT_NAME={auth['project_name']} +export OS_DOMAIN_ID={auth['user_domain_id']} +export OS_REGION_NAME={cloud['region_name']} +""" + +print(result) From 49ee31a654a8c9999941a8db6225c70917d344f1 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Wed, 17 Jul 2024 12:41:23 +0100 Subject: [PATCH 069/353] lint: Address recent lint issues We really need to run golangci-lint in the gate but fix these issues for now. Signed-off-by: Stephen Finucane --- .../extensions/bgpvpns/testing/requests_test.go | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/openstack/networking/v2/extensions/bgpvpns/testing/requests_test.go b/openstack/networking/v2/extensions/bgpvpns/testing/requests_test.go index 859441f6f4..3b39e7cee0 100644 --- a/openstack/networking/v2/extensions/bgpvpns/testing/requests_test.go +++ b/openstack/networking/v2/extensions/bgpvpns/testing/requests_test.go @@ -27,7 +27,9 @@ func TestList(t *testing.T) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - r.ParseForm() + if err := r.ParseForm(); err != nil { + t.Errorf("Failed to parse request form %v", err) + } th.AssertDeepEquals(t, r.Form["fields"], fields) th.AssertDeepEquals(t, r.Form["project_id"], filterProjectID) @@ -177,7 +179,9 @@ func TestListNetworkAssociations(t *testing.T) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - r.ParseForm() + if err := r.ParseForm(); err != nil { + t.Errorf("Failed to parse request form %v", err) + } th.AssertDeepEquals(t, fields, r.Form["fields"]) w.Header().Add("Content-Type", "application/json") @@ -278,7 +282,9 @@ func TestListRouterAssociations(t *testing.T) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - r.ParseForm() + if err := r.ParseForm(); err != nil { + t.Errorf("Failed to parse request form %v", err) + } th.AssertDeepEquals(t, fields, r.Form["fields"]) w.Header().Add("Content-Type", "application/json") @@ -404,7 +410,9 @@ func TestListPortAssociations(t *testing.T) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - r.ParseForm() + if err := r.ParseForm(); err != nil { + t.Errorf("Failed to parse request form %v", err) + } th.AssertDeepEquals(t, fields, r.Form["fields"]) w.Header().Add("Content-Type", "application/json") From f26116ef60fd556173f14ff1272b3eac3416cca0 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Fri, 29 Nov 2024 14:39:32 +0000 Subject: [PATCH 070/353] lint: Remove non-constant format string in calls (govet) We were incorrectly using 'fmt.Printf', 'fmt.Errorf' and 't.Logf' with non-template strings/no arguments. The fix to this is replace these calls with the non-suffixed variants. There are many users of 'fmt.Fprint' - too many to do by hand - so this replacement was resolved using 'sed': sed 's/Fprintf/Fprint/g' -i $(ag fmt.Fprintf -l) We then manually fix the 25 cases where 'fmt.Fprintf' is actually warranted and manually replaced the errant users of 'fmt.Errorf' and 't.Logf'. We also rework 'internal/acceptance/clients/clients.go' slightly to make the code a bit clearer. PS: This is apparently going to be an issue in go 1.24 (specifically in 'go vet') [1] so this is not just golangci-lint being annoying. @PierrePrinetti, that's directed at you ;) [1] https://github.com/golang/go/issues/60529 Signed-off-by: Stephen Finucane --- internal/acceptance/clients/clients.go | 16 +++---- internal/acceptance/tools/tools.go | 2 +- .../apiversions/testing/fixtures_test.go | 4 +- .../v1/allocations/testing/fixtures_test.go | 8 ++-- .../v1/conductors/testing/fixtures_test.go | 8 ++-- .../v1/drivers/testing/fixtures_test.go | 8 ++-- .../v1/nodes/testing/fixtures_test.go | 38 +++++++-------- .../v1/ports/testing/fixtures_test.go | 12 ++--- .../v1/introspection/testing/fixtures.go | 8 ++-- .../apiversions/testing/fixtures_test.go | 4 +- .../testing/fixtures_test.go | 2 +- .../v2/backups/testing/fixtures_test.go | 14 +++--- .../v2/limits/testing/fixtures_test.go | 2 +- .../v2/quotasets/testing/fixtures_test.go | 2 +- .../schedulerstats/testing/fixtures_test.go | 4 +- .../v2/services/testing/fixtures_test.go | 2 +- .../v2/snapshots/testing/fixtures_test.go | 8 ++-- .../v2/transfers/testing/fixtures_test.go | 8 ++-- .../v2/volumes/testing/fixtures_test.go | 30 ++++++------ .../v3/attachments/testing/fixtures_test.go | 10 ++-- .../testing/fixtures_test.go | 2 +- .../v3/backups/testing/fixtures_test.go | 14 +++--- .../v3/limits/testing/fixtures_test.go | 2 +- .../v3/qos/testing/fixtures_test.go | 10 ++-- .../v3/quotasets/testing/fixtures_test.go | 2 +- .../schedulerstats/testing/fixtures_test.go | 4 +- .../v3/services/testing/fixtures_test.go | 2 +- .../v3/snapshots/testing/fixtures_test.go | 10 ++-- .../v3/transfers/testing/fixtures_test.go | 8 ++-- .../v3/volumes/testing/fixtures_test.go | 32 ++++++------- .../v3/volumetypes/testing/fixtures_test.go | 24 +++++----- .../v3/volumetypes/testing/requests_test.go | 2 +- .../common/extensions/testing/fixtures.go | 4 +- .../apiversions/testing/fixtures_test.go | 6 +-- .../v2/aggregates/testing/fixtures_test.go | 14 +++--- .../attachinterfaces/testing/fixtures_test.go | 6 +-- .../testing/fixtures_test.go | 4 +- .../v2/extensions/testing/fixtures_test.go | 4 +- .../v2/flavors/testing/fixtures_test.go | 8 ++-- .../v2/flavors/testing/requests_test.go | 14 +++--- .../v2/hypervisors/testing/fixtures_test.go | 16 +++---- .../instanceactions/testing/fixtures_test.go | 4 +- .../v2/keypairs/testing/fixtures_test.go | 12 ++--- .../v2/limits/testing/fixtures_test.go | 2 +- .../v2/quotasets/testing/fixtures_test.go | 8 ++-- .../remoteconsoles/testing/requests_test.go | 2 +- .../v2/secgroups/testing/fixtures_test.go | 14 +++--- .../v2/servergroups/testing/fixtures_test.go | 10 ++-- .../v2/servers/testing/fixtures_test.go | 46 +++++++++--------- .../v2/services/testing/fixtures_test.go | 6 +-- .../compute/v2/tags/testing/requests_test.go | 4 +- .../v2/volumeattach/testing/fixtures_test.go | 6 +-- .../v1/capsules/testing/fixtures_test.go | 10 ++-- .../apiversions/testing/fixtures_test.go | 4 +- .../v1/certificates/testing/fixtures_test.go | 2 +- .../v1/nodegroups/testing/fixtures_test.go | 22 ++++----- .../v2/recordsets/testing/fixtures_test.go | 12 ++--- .../transfer/accept/testing/fixtures_test.go | 8 ++-- .../transfer/request/testing/fixtures_test.go | 8 ++-- .../dns/v2/zones/testing/fixtures_test.go | 10 ++-- .../v2/extensions/testing/fixtures_test.go | 2 +- .../v2/roles/testing/fixtures_test.go | 2 +- .../v2/tenants/testing/fixtures_test.go | 8 ++-- .../v2/tokens/testing/fixtures_test.go | 4 +- .../v2/users/testing/fixtures_test.go | 10 ++-- .../testing/fixtures_test.go | 14 +++--- .../v3/catalog/testing/fixtures_test.go | 2 +- .../v3/credentials/testing/fixtures_test.go | 8 ++-- .../v3/domains/testing/fixtures_test.go | 10 ++-- .../ec2credentials/testing/fixtures_test.go | 6 +-- .../v3/ec2tokens/testing/requests_test.go | 2 +- .../v3/endpoints/testing/requests_test.go | 6 +-- .../v3/federation/testing/fixtures_test.go | 8 ++-- .../v3/groups/testing/fixtures_test.go | 8 ++-- .../v3/limits/testing/fixtures_test.go | 10 ++-- .../v3/oauth1/testing/fixtures_test.go | 24 +++++----- .../v3/policies/testing/fixtures_test.go | 10 ++-- .../projectendpoints/testing/requests_test.go | 2 +- .../v3/projects/testing/fixtures_test.go | 14 +++--- .../v3/regions/testing/fixtures_test.go | 8 ++-- .../registeredlimits/testing/fixtures_test.go | 8 ++-- .../v3/roles/testing/fixtures_test.go | 28 +++++------ .../v3/services/testing/fixtures_test.go | 8 ++-- .../v3/tokens/testing/requests_test.go | 10 ++-- .../v3/trusts/testing/fixtures_test.go | 12 ++--- .../v3/users/testing/fixtures_test.go | 16 +++---- .../v2/imageimport/testing/requests_test.go | 4 +- .../image/v2/images/testing/fixtures_test.go | 16 +++---- .../image/v2/members/testing/fixtures_test.go | 10 ++-- .../image/v2/tasks/testing/requests_test.go | 6 +-- .../v1/acls/testing/fixtures_test.go | 12 ++--- .../v1/containers/testing/fixtures_test.go | 12 ++--- .../v1/orders/testing/fixtures_test.go | 6 +-- .../v1/secrets/testing/fixtures_test.go | 18 +++---- .../v2/amphorae/testing/fixtures_test.go | 6 +-- .../v2/apiversions/testing/fixture.go | 2 +- .../v2/flavorprofiles/testing/fixtures.go | 10 ++-- .../v2/flavors/testing/fixtures.go | 10 ++-- .../v2/flavors/testing/requests_test.go | 2 +- .../v2/l7policies/testing/fixtures_test.go | 22 ++++----- .../v2/listeners/testing/fixtures_test.go | 12 ++--- .../v2/loadbalancers/testing/fixtures_test.go | 16 +++---- .../v2/monitors/testing/fixtures_test.go | 10 ++-- .../v2/pools/testing/fixtures_test.go | 20 ++++---- .../v2/providers/testing/fixtures_test.go | 2 +- .../v2/quotas/testing/requests_test.go | 8 ++-- .../v2/claims/testing/fixtures_test.go | 4 +- .../v2/messages/testing/fixtures_test.go | 10 ++-- .../v2/queues/testing/fixtures_test.go | 10 ++-- .../v2/apiversions/testing/requests_test.go | 4 +- .../agents/testing/requests_test.go | 14 +++--- .../attributestags/testing/requests_test.go | 4 +- .../bgp/peers/testing/requests_test.go | 8 ++-- .../bgp/speakers/testing/requests_test.go | 18 +++---- .../bgpvpns/testing/requests_test.go | 30 ++++++------ .../extensions/dns/testing/fixtures_test.go | 22 ++++----- .../external/testing/results_test.go | 8 ++-- .../fwaas_v2/groups/testing/requests_test.go | 12 ++--- .../policies/testing/requests_test.go | 12 ++--- .../fwaas_v2/rules/testing/requests_test.go | 10 ++-- .../addressscopes/testing/requests_test.go | 8 ++-- .../extraroutes/testing/requests_test.go | 4 +- .../floatingips/testing/requests_test.go | 16 +++---- .../portforwarding/testing/requests_test.go | 8 ++-- .../layer3/routers/testing/requests_test.go | 18 +++---- .../v2/extensions/mtu/testing/results_test.go | 8 ++-- .../testing/requests_test.go | 4 +- .../portsbinding/testing/fixtures_test.go | 8 ++-- .../provider/testing/results_test.go | 10 ++-- .../qos/policies/testing/requests_test.go | 24 +++++----- .../qos/rules/testing/requests_test.go | 24 +++++----- .../qos/ruletypes/testing/requests_test.go | 2 +- .../quotas/testing/requests_test.go | 6 +-- .../rbacpolicies/testing/requests_test.go | 10 ++-- .../security/groups/testing/requests_test.go | 8 ++-- .../security/rules/testing/requests_test.go | 8 ++-- .../subnetpools/testing/requests_test.go | 8 ++-- .../v2/extensions/testing/delegate_test.go | 4 +- .../trunks/testing/requests_test.go | 16 +++---- .../vlantransparent/testing/requests_test.go | 8 ++-- .../endpointgroups/testing/requests_test.go | 8 ++-- .../ikepolicies/testing/requests_test.go | 8 ++-- .../ipsecpolicies/testing/requests_test.go | 8 ++-- .../vpnaas/services/testing/requests_test.go | 8 ++-- .../siteconnections/testing/requests_test.go | 8 ++-- .../v2/networks/testing/requests_test.go | 22 ++++----- .../v2/ports/testing/requests_test.go | 48 +++++++++---------- .../v2/subnets/testing/requests_test.go | 32 ++++++------- .../v1/containers/testing/fixtures.go | 8 ++-- .../v1/objects/testing/fixtures_test.go | 12 ++--- .../v1/swauth/testing/fixtures_test.go | 2 +- .../v1/apiversions/testing/requests_test.go | 2 +- .../v1/buildinfo/testing/fixtures_test.go | 2 +- .../v1/stackevents/testing/fixtures_test.go | 12 ++--- .../stackresources/testing/fixtures_test.go | 16 +++---- .../v1/stacks/testing/fixtures_test.go | 14 +++--- .../orchestration/v1/stacks/utils_test.go | 2 +- .../stacktemplates/testing/fixtures_test.go | 4 +- .../testing/fixtures_test.go | 16 +++---- .../apiversions/testing/fixtures_test.go | 8 ++-- .../testing/fixtures_test.go | 2 +- .../v2/errors/testing/fixtures_test.go | 2 +- .../v2/messages/testing/fixtures_test.go | 6 +-- .../v2/replicas/testing/fixtures_test.go | 8 ++-- .../schedulerstats/testing/fixtures_test.go | 4 +- .../securityservices/testing/fixtures_test.go | 10 ++-- .../v2/services/testing/fixtures_test.go | 2 +- .../shareaccessrules/testing/fixtures_test.go | 2 +- .../shareaccessrules/testing/requests_test.go | 2 +- .../v2/sharenetworks/testing/fixtures_test.go | 24 +++++----- .../v2/shares/testing/fixtures_test.go | 14 +++--- .../sharetransfers/testing/fixtures_test.go | 8 ++-- .../v2/sharetypes/testing/fixtures_test.go | 12 ++--- .../v2/snapshots/testing/fixtures_test.go | 6 +-- openstack/testing/client_test.go | 6 +-- .../v2/crontriggers/testing/requests_test.go | 6 +-- .../v2/executions/testing/requests_test.go | 6 +-- .../v2/workflows/testing/requests_test.go | 10 ++-- pagination/testing/linked_test.go | 2 +- pagination/testing/marker_test.go | 6 +-- pagination/testing/single_test.go | 2 +- testhelper/fixture/helper.go | 2 +- testing/provider_client_test.go | 4 +- 183 files changed, 882 insertions(+), 884 deletions(-) diff --git a/internal/acceptance/clients/clients.go b/internal/acceptance/clients/clients.go index 21be9dbea2..f981ffcea2 100644 --- a/internal/acceptance/clients/clients.go +++ b/internal/acceptance/clients/clients.go @@ -107,16 +107,14 @@ func AcceptanceTestChoicesFromEnv() (*AcceptanceTestChoices, error) { notDistinct = "OS_FLAVOR_ID and OS_FLAVOR_ID_RESIZE must be distinct." } - if len(missing) > 0 || notDistinct != "" { - text := "You're missing some important setup:\n" - if len(missing) > 0 { - text += " * These environment variables must be provided: " + strings.Join(missing, ", ") + "\n" - } - if notDistinct != "" { - text += " * " + notDistinct + "\n" - } + if len(missing) > 0 { + text := "You're missing some important setup:\n * These environment variables must be provided: %s\n" + return nil, fmt.Errorf(text, strings.Join(missing, ", ")) + } - return nil, fmt.Errorf(text) + if notDistinct != "" { + text := "You're missing some important setup:\n * %s\n" + return nil, fmt.Errorf(text, notDistinct) } return &AcceptanceTestChoices{ diff --git a/internal/acceptance/tools/tools.go b/internal/acceptance/tools/tools.go index 8b0fad2ea6..75ac004473 100644 --- a/internal/acceptance/tools/tools.go +++ b/internal/acceptance/tools/tools.go @@ -81,5 +81,5 @@ func Elide(value string) string { // PrintResource returns a resource as a readable structure func PrintResource(t *testing.T, resource any) { b, _ := json.MarshalIndent(resource, "", " ") - t.Logf(string(b)) + t.Log(string(b)) } diff --git a/openstack/baremetal/apiversions/testing/fixtures_test.go b/openstack/baremetal/apiversions/testing/fixtures_test.go index 5e169d36fc..d0e11553c2 100644 --- a/openstack/baremetal/apiversions/testing/fixtures_test.go +++ b/openstack/baremetal/apiversions/testing/fixtures_test.go @@ -89,7 +89,7 @@ func MockListResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, IronicAPIAllVersionResponse) + fmt.Fprint(w, IronicAPIAllVersionResponse) }) } @@ -101,6 +101,6 @@ func MockGetResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, IronicAPIVersionResponse) + fmt.Fprint(w, IronicAPIVersionResponse) }) } diff --git a/openstack/baremetal/v1/allocations/testing/fixtures_test.go b/openstack/baremetal/v1/allocations/testing/fixtures_test.go index 6b8655169b..7ee9fa4834 100644 --- a/openstack/baremetal/v1/allocations/testing/fixtures_test.go +++ b/openstack/baremetal/v1/allocations/testing/fixtures_test.go @@ -120,10 +120,10 @@ func HandleAllocationListSuccessfully(t *testing.T) { marker := r.Form.Get("marker") switch marker { case "": - fmt.Fprintf(w, AllocationListBody) + fmt.Fprint(w, AllocationListBody) case "eff80f47-75f0-4d41-b1aa-cf07c201adac": - fmt.Fprintf(w, `{ "allocations": [] }`) + fmt.Fprint(w, `{ "allocations": [] }`) default: t.Fatalf("/allocations invoked with unexpected marker=[%s]", marker) } @@ -145,7 +145,7 @@ func HandleAllocationCreationSuccessfully(t *testing.T, response string) { w.WriteHeader(http.StatusAccepted) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, response) + fmt.Fprint(w, response) }) } @@ -165,6 +165,6 @@ func HandleAllocationGetSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") - fmt.Fprintf(w, SingleAllocationBody) + fmt.Fprint(w, SingleAllocationBody) }) } diff --git a/openstack/baremetal/v1/conductors/testing/fixtures_test.go b/openstack/baremetal/v1/conductors/testing/fixtures_test.go index 8e59ddaab4..fd66a34d4b 100644 --- a/openstack/baremetal/v1/conductors/testing/fixtures_test.go +++ b/openstack/baremetal/v1/conductors/testing/fixtures_test.go @@ -150,10 +150,10 @@ func HandleConductorListSuccessfully(t *testing.T) { marker := r.Form.Get("marker") switch marker { case "": - fmt.Fprintf(w, ConductorListBody) + fmt.Fprint(w, ConductorListBody) case "9e5476bd-a4ec-4653-93d6-72c93aa682ba": - fmt.Fprintf(w, `{ "servers": [] }`) + fmt.Fprint(w, `{ "servers": [] }`) default: t.Fatalf("/conductors invoked with unexpected marker=[%s]", marker) } @@ -170,7 +170,7 @@ func HandleConductorListDetailSuccessfully(t *testing.T) { t.Errorf("Failed to parse request form %v", err) } - fmt.Fprintf(w, ConductorListDetailBody) + fmt.Fprint(w, ConductorListDetailBody) }) } @@ -180,6 +180,6 @@ func HandleConductorGetSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") - fmt.Fprintf(w, SingleConductorBody) + fmt.Fprint(w, SingleConductorBody) }) } diff --git a/openstack/baremetal/v1/drivers/testing/fixtures_test.go b/openstack/baremetal/v1/drivers/testing/fixtures_test.go index a06bcee928..6c6d0fcc7e 100644 --- a/openstack/baremetal/v1/drivers/testing/fixtures_test.go +++ b/openstack/baremetal/v1/drivers/testing/fixtures_test.go @@ -377,7 +377,7 @@ func HandleListDriversSuccessfully(t *testing.T) { t.Errorf("Failed to parse request form %v", err) } - fmt.Fprintf(w, ListDriversBody) + fmt.Fprint(w, ListDriversBody) }) } @@ -388,7 +388,7 @@ func HandleGetDriverDetailsSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") - fmt.Fprintf(w, SingleDriverDetails) + fmt.Fprint(w, SingleDriverDetails) }) } @@ -399,7 +399,7 @@ func HandleGetDriverPropertiesSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") - fmt.Fprintf(w, SingleDriverProperties) + fmt.Fprint(w, SingleDriverProperties) }) } @@ -410,6 +410,6 @@ func HandleGetDriverDiskPropertiesSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") - fmt.Fprintf(w, SingleDriverDiskProperties) + fmt.Fprint(w, SingleDriverDiskProperties) }) } diff --git a/openstack/baremetal/v1/nodes/testing/fixtures_test.go b/openstack/baremetal/v1/nodes/testing/fixtures_test.go index 7819111314..88abebcebb 100644 --- a/openstack/baremetal/v1/nodes/testing/fixtures_test.go +++ b/openstack/baremetal/v1/nodes/testing/fixtures_test.go @@ -1409,10 +1409,10 @@ func HandleNodeListSuccessfully(t *testing.T) { marker := r.Form.Get("marker") switch marker { case "": - fmt.Fprintf(w, NodeListBody) + fmt.Fprint(w, NodeListBody) case "9e5476bd-a4ec-4653-93d6-72c93aa682ba": - fmt.Fprintf(w, `{ "servers": [] }`) + fmt.Fprint(w, `{ "servers": [] }`) default: t.Fatalf("/nodes invoked with unexpected marker=[%s]", marker) } @@ -1429,7 +1429,7 @@ func HandleNodeListDetailSuccessfully(t *testing.T) { t.Errorf("Failed to parse request form %v", err) } - fmt.Fprintf(w, NodeListDetailBody) + fmt.Fprint(w, NodeListDetailBody) }) } @@ -1456,7 +1456,7 @@ func HandleNodeCreationSuccessfully(t *testing.T, response string) { w.WriteHeader(http.StatusAccepted) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, response) + fmt.Fprint(w, response) }) } @@ -1476,7 +1476,7 @@ func HandleNodeGetSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") - fmt.Fprintf(w, SingleNodeBody) + fmt.Fprint(w, SingleNodeBody) }) } @@ -1488,7 +1488,7 @@ func HandleNodeUpdateSuccessfully(t *testing.T, response string) { th.TestHeader(t, r, "Content-Type", "application/json") th.TestJSONRequest(t, r, `[{"op": "replace", "path": "/properties", "value": {"root_gb": 25}}]`) - fmt.Fprintf(w, response) + fmt.Fprint(w, response) }) } @@ -1498,7 +1498,7 @@ func HandleNodeValidateSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") - fmt.Fprintf(w, NodeValidationBody) + fmt.Fprint(w, NodeValidationBody) }) } @@ -1530,7 +1530,7 @@ func HandleGetBootDeviceSuccessfully(t *testing.T) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, NodeBootDeviceBody) + fmt.Fprint(w, NodeBootDeviceBody) }) } @@ -1540,7 +1540,7 @@ func HandleGetSupportedBootDeviceSuccessfully(t *testing.T) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, NodeSupportedBootDeviceBody) + fmt.Fprint(w, NodeSupportedBootDeviceBody) }) } @@ -1672,7 +1672,7 @@ func HandleListBIOSSettingsSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") - fmt.Fprintf(w, NodeBIOSSettingsBody) + fmt.Fprint(w, NodeBIOSSettingsBody) }) } @@ -1682,7 +1682,7 @@ func HandleListDetailBIOSSettingsSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") - fmt.Fprintf(w, NodeDetailBIOSSettingsBody) + fmt.Fprint(w, NodeDetailBIOSSettingsBody) }) } @@ -1692,7 +1692,7 @@ func HandleGetBIOSSettingSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") - fmt.Fprintf(w, NodeSingleBIOSSettingBody) + fmt.Fprint(w, NodeSingleBIOSSettingBody) }) } @@ -1702,7 +1702,7 @@ func HandleGetVendorPassthruMethodsSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") - fmt.Fprintf(w, NodeVendorPassthruMethodsBody) + fmt.Fprint(w, NodeVendorPassthruMethodsBody) }) } @@ -1713,7 +1713,7 @@ func HandleGetAllSubscriptionsVendorPassthruSuccessfully(t *testing.T) { th.TestHeader(t, r, "Accept", "application/json") th.TestFormValues(t, r, map[string]string{"method": "get_all_subscriptions"}) - fmt.Fprintf(w, NodeGetAllSubscriptionsVnedorPassthruBody) + fmt.Fprint(w, NodeGetAllSubscriptionsVnedorPassthruBody) }) } @@ -1729,7 +1729,7 @@ func HandleGetSubscriptionVendorPassthruSuccessfully(t *testing.T) { } `) - fmt.Fprintf(w, NodeGetSubscriptionVendorPassthruBody) + fmt.Fprint(w, NodeGetSubscriptionVendorPassthruBody) }) } @@ -1749,7 +1749,7 @@ func HandleCreateSubscriptionVendorPassthruAllParametersSuccessfully(t *testing. } `) - fmt.Fprintf(w, NodeCreateSubscriptionVendorPassthruAllParametersBody) + fmt.Fprint(w, NodeCreateSubscriptionVendorPassthruAllParametersBody) }) } @@ -1765,7 +1765,7 @@ func HandleCreateSubscriptionVendorPassthruRequiredParametersSuccessfully(t *tes } `) - fmt.Fprintf(w, NodeCreateSubscriptionVendorPassthruRequiredParametersBody) + fmt.Fprint(w, NodeCreateSubscriptionVendorPassthruRequiredParametersBody) }) } @@ -1810,7 +1810,7 @@ func HandleGetInventorySuccessfully(t *testing.T) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, NodeInventoryBody) + fmt.Fprint(w, NodeInventoryBody) }) } @@ -1820,7 +1820,7 @@ func HandleListFirmwareSuccessfully(t *testing.T) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, NodeFirmwareListBody) + fmt.Fprint(w, NodeFirmwareListBody) }) } diff --git a/openstack/baremetal/v1/ports/testing/fixtures_test.go b/openstack/baremetal/v1/ports/testing/fixtures_test.go index 492aa42aa6..a6221ecd4a 100644 --- a/openstack/baremetal/v1/ports/testing/fixtures_test.go +++ b/openstack/baremetal/v1/ports/testing/fixtures_test.go @@ -181,10 +181,10 @@ func HandlePortListSuccessfully(t *testing.T) { marker := r.Form.Get("marker") switch marker { case "": - fmt.Fprintf(w, PortListBody) + fmt.Fprint(w, PortListBody) case "f2845e11-dbd4-4728-a8c0-30d19f48924a": - fmt.Fprintf(w, `{ "ports": [] }`) + fmt.Fprint(w, `{ "ports": [] }`) default: t.Fatalf("/ports invoked with unexpected marker=[%s]", marker) } @@ -201,7 +201,7 @@ func HandlePortListDetailSuccessfully(t *testing.T) { t.Errorf("Failed to parse request form %v", err) } - fmt.Fprintf(w, PortListDetailBody) + fmt.Fprint(w, PortListDetailBody) }) } @@ -219,7 +219,7 @@ func HandlePortCreationSuccessfully(t *testing.T, response string) { w.WriteHeader(http.StatusAccepted) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, response) + fmt.Fprint(w, response) }) } @@ -239,7 +239,7 @@ func HandlePortGetSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") - fmt.Fprintf(w, SinglePortBody) + fmt.Fprint(w, SinglePortBody) }) } @@ -251,6 +251,6 @@ func HandlePortUpdateSuccessfully(t *testing.T, response string) { th.TestHeader(t, r, "Content-Type", "application/json") th.TestJSONRequest(t, r, `[{"op": "replace", "path": "/address", "value": "22:22:22:22:22:22"}]`) - fmt.Fprintf(w, response) + fmt.Fprint(w, response) }) } diff --git a/openstack/baremetalintrospection/v1/introspection/testing/fixtures.go b/openstack/baremetalintrospection/v1/introspection/testing/fixtures.go index af2ad9e7f5..56a4299aef 100644 --- a/openstack/baremetalintrospection/v1/introspection/testing/fixtures.go +++ b/openstack/baremetalintrospection/v1/introspection/testing/fixtures.go @@ -467,10 +467,10 @@ func HandleListIntrospectionsSuccessfully(t *testing.T) { switch marker { case "": - fmt.Fprintf(w, IntrospectionListBody) + fmt.Fprint(w, IntrospectionListBody) case "c244557e-899f-46fa-a1ff-5b2c6718616b": - fmt.Fprintf(w, `{ "introspection": [] }`) + fmt.Fprint(w, `{ "introspection": [] }`) default: t.Fatalf("/introspection invoked with unexpected marker=[%s]", marker) @@ -484,7 +484,7 @@ func HandleGetIntrospectionStatusSuccessfully(t *testing.T) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") - fmt.Fprintf(w, IntrospectionStatus) + fmt.Fprint(w, IntrospectionStatus) }) } @@ -513,7 +513,7 @@ func HandleGetIntrospectionDataSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") - fmt.Fprintf(w, IntrospectionDataJSONSample) + fmt.Fprint(w, IntrospectionDataJSONSample) }) } diff --git a/openstack/blockstorage/apiversions/testing/fixtures_test.go b/openstack/blockstorage/apiversions/testing/fixtures_test.go index 4a368e9da9..ed78b1e472 100644 --- a/openstack/blockstorage/apiversions/testing/fixtures_test.go +++ b/openstack/blockstorage/apiversions/testing/fixtures_test.go @@ -124,7 +124,7 @@ func MockListResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, APIListResponse) + fmt.Fprint(w, APIListResponse) }) } @@ -136,6 +136,6 @@ func MockListOldResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, APIListOldResponse) + fmt.Fprint(w, APIListOldResponse) }) } diff --git a/openstack/blockstorage/v2/availabilityzones/testing/fixtures_test.go b/openstack/blockstorage/v2/availabilityzones/testing/fixtures_test.go index b13e464abb..5c48bdce2e 100644 --- a/openstack/blockstorage/v2/availabilityzones/testing/fixtures_test.go +++ b/openstack/blockstorage/v2/availabilityzones/testing/fixtures_test.go @@ -47,6 +47,6 @@ func HandleGetSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, GetOutput) + fmt.Fprint(w, GetOutput) }) } diff --git a/openstack/blockstorage/v2/backups/testing/fixtures_test.go b/openstack/blockstorage/v2/backups/testing/fixtures_test.go index 2f24173418..4f1f45c122 100644 --- a/openstack/blockstorage/v2/backups/testing/fixtures_test.go +++ b/openstack/blockstorage/v2/backups/testing/fixtures_test.go @@ -210,7 +210,7 @@ func MockListResponse(t *testing.T) { case "": fmt.Fprintf(w, ListResponse, th.Server.URL) case "1": - fmt.Fprintf(w, `{"backups": []}`) + fmt.Fprint(w, `{"backups": []}`) default: t.Fatalf("Unexpected marker: [%s]", marker) } @@ -233,7 +233,7 @@ func MockListDetailResponse(t *testing.T) { case "": fmt.Fprintf(w, ListDetailResponse, th.Server.URL) case "1": - fmt.Fprintf(w, `{"backups": []}`) + fmt.Fprint(w, `{"backups": []}`) default: t.Fatalf("Unexpected marker: [%s]", marker) } @@ -247,7 +247,7 @@ func MockGetResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, GetResponse) + fmt.Fprint(w, GetResponse) }) } @@ -262,7 +262,7 @@ func MockCreateResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusAccepted) - fmt.Fprintf(w, CreateResponse) + fmt.Fprint(w, CreateResponse) }) } @@ -277,7 +277,7 @@ func MockRestoreResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusAccepted) - fmt.Fprintf(w, RestoreResponse) + fmt.Fprint(w, RestoreResponse) }) } @@ -298,7 +298,7 @@ func MockExportResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ExportResponse) + fmt.Fprint(w, ExportResponse) }) } @@ -313,7 +313,7 @@ func MockImportResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, ImportResponse) + fmt.Fprint(w, ImportResponse) }) } diff --git a/openstack/blockstorage/v2/limits/testing/fixtures_test.go b/openstack/blockstorage/v2/limits/testing/fixtures_test.go index c3f8bf803d..bdd1308a17 100644 --- a/openstack/blockstorage/v2/limits/testing/fixtures_test.go +++ b/openstack/blockstorage/v2/limits/testing/fixtures_test.go @@ -124,6 +124,6 @@ func HandleGetSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, GetOutput) + fmt.Fprint(w, GetOutput) }) } diff --git a/openstack/blockstorage/v2/quotasets/testing/fixtures_test.go b/openstack/blockstorage/v2/quotasets/testing/fixtures_test.go index 066e1729c8..854ff08b63 100644 --- a/openstack/blockstorage/v2/quotasets/testing/fixtures_test.go +++ b/openstack/blockstorage/v2/quotasets/testing/fixtures_test.go @@ -164,7 +164,7 @@ func HandleSuccessfulRequest(t *testing.T, httpMethod, uriPath, jsonOutput strin th.TestFormValues(t, r, uriQueryParams) } - fmt.Fprintf(w, jsonOutput) + fmt.Fprint(w, jsonOutput) }) } diff --git a/openstack/blockstorage/v2/schedulerstats/testing/fixtures_test.go b/openstack/blockstorage/v2/schedulerstats/testing/fixtures_test.go index 3a7fee8160..05512dbf6d 100644 --- a/openstack/blockstorage/v2/schedulerstats/testing/fixtures_test.go +++ b/openstack/blockstorage/v2/schedulerstats/testing/fixtures_test.go @@ -104,9 +104,9 @@ func HandleStoragePoolsListSuccessfully(t *testing.T) { t.Errorf("Failed to parse request form %v", err) } if r.FormValue("detail") == "true" { - fmt.Fprintf(w, StoragePoolsListBodyDetail) + fmt.Fprint(w, StoragePoolsListBodyDetail) } else { - fmt.Fprintf(w, StoragePoolsListBody) + fmt.Fprint(w, StoragePoolsListBody) } }) } diff --git a/openstack/blockstorage/v2/services/testing/fixtures_test.go b/openstack/blockstorage/v2/services/testing/fixtures_test.go index a396abc39e..41fb5bc614 100644 --- a/openstack/blockstorage/v2/services/testing/fixtures_test.go +++ b/openstack/blockstorage/v2/services/testing/fixtures_test.go @@ -92,6 +92,6 @@ func HandleListSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, ServiceListBody) + fmt.Fprint(w, ServiceListBody) }) } diff --git a/openstack/blockstorage/v2/snapshots/testing/fixtures_test.go b/openstack/blockstorage/v2/snapshots/testing/fixtures_test.go index 2c00c8a05f..b2e5cf4c06 100644 --- a/openstack/blockstorage/v2/snapshots/testing/fixtures_test.go +++ b/openstack/blockstorage/v2/snapshots/testing/fixtures_test.go @@ -17,7 +17,7 @@ func MockListResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "snapshots": [ { @@ -51,7 +51,7 @@ func MockGetResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "snapshot": { "id": "d32019d3-bc6e-4319-9c1d-6722fc136a22", @@ -85,7 +85,7 @@ func MockCreateResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusAccepted) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "snapshot": { "volume_id": "1234", @@ -115,7 +115,7 @@ func MockUpdateMetadataResponse(t *testing.T) { } `) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "metadata": { "key": "v1" diff --git a/openstack/blockstorage/v2/transfers/testing/fixtures_test.go b/openstack/blockstorage/v2/transfers/testing/fixtures_test.go index 6a150508eb..866d5068fc 100644 --- a/openstack/blockstorage/v2/transfers/testing/fixtures_test.go +++ b/openstack/blockstorage/v2/transfers/testing/fixtures_test.go @@ -167,7 +167,7 @@ func HandleCreateTransfer(t *testing.T) { th.TestJSONRequest(t, r, CreateRequest) w.WriteHeader(http.StatusAccepted) - fmt.Fprintf(w, CreateResponse) + fmt.Fprint(w, CreateResponse) }) } @@ -179,7 +179,7 @@ func HandleAcceptTransfer(t *testing.T) { th.TestJSONRequest(t, r, AcceptTransferRequest) w.WriteHeader(http.StatusAccepted) - fmt.Fprintf(w, AcceptTransferResponse) + fmt.Fprint(w, AcceptTransferResponse) }) } @@ -200,7 +200,7 @@ func HandleListTransfers(t *testing.T) { th.TestFormValues(t, r, map[string]string{"all_tenants": "true"}) w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListOutput) + fmt.Fprint(w, ListOutput) }) } @@ -211,6 +211,6 @@ func HandleGetTransfer(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, GetOutput) + fmt.Fprint(w, GetOutput) }) } diff --git a/openstack/blockstorage/v2/volumes/testing/fixtures_test.go b/openstack/blockstorage/v2/volumes/testing/fixtures_test.go index 80677d2e40..d6688f7850 100644 --- a/openstack/blockstorage/v2/volumes/testing/fixtures_test.go +++ b/openstack/blockstorage/v2/volumes/testing/fixtures_test.go @@ -17,7 +17,7 @@ func MockListResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "volumes": [ { @@ -93,7 +93,7 @@ func MockGetResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "volume": { "volume_type": "lvmdriver-1", @@ -152,7 +152,7 @@ func MockCreateResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusAccepted) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "volume": { "size": 75, @@ -192,7 +192,7 @@ func MockUpdateResponse(t *testing.T) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "volume": { "name": "vol-002" @@ -223,7 +223,7 @@ func MockAttachResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusAccepted) - fmt.Fprintf(w, `{}`) + fmt.Fprint(w, `{}`) }) } @@ -243,7 +243,7 @@ func MockBeginDetachingResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusAccepted) - fmt.Fprintf(w, `{}`) + fmt.Fprint(w, `{}`) }) } @@ -263,7 +263,7 @@ func MockDetachResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusAccepted) - fmt.Fprintf(w, `{}`) + fmt.Fprint(w, `{}`) }) } @@ -288,7 +288,7 @@ func MockUploadImageResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusAccepted) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "os-volume_upload_image": { "container_format": "bare", @@ -335,7 +335,7 @@ func MockReserveResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusAccepted) - fmt.Fprintf(w, `{}`) + fmt.Fprint(w, `{}`) }) } @@ -355,7 +355,7 @@ func MockUnreserveResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusAccepted) - fmt.Fprintf(w, `{}`) + fmt.Fprint(w, `{}`) }) } @@ -386,7 +386,7 @@ func MockInitializeConnectionResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusAccepted) - fmt.Fprintf(w, `{ + fmt.Fprint(w, `{ "connection_info": { "data": { "target_portals": [ @@ -443,7 +443,7 @@ func MockTerminateConnectionResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusAccepted) - fmt.Fprintf(w, `{}`) + fmt.Fprint(w, `{}`) }) } @@ -466,7 +466,7 @@ func MockExtendSizeResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusAccepted) - fmt.Fprintf(w, `{}`) + fmt.Fprint(w, `{}`) }) } @@ -497,7 +497,7 @@ func MockSetImageMetadataResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, `{}`) + fmt.Fprint(w, `{}`) }) } @@ -560,7 +560,7 @@ func MockChangeTypeResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusAccepted) - fmt.Fprintf(w, `{}`) + fmt.Fprint(w, `{}`) }) } diff --git a/openstack/blockstorage/v3/attachments/testing/fixtures_test.go b/openstack/blockstorage/v3/attachments/testing/fixtures_test.go index d489ce16ef..18471c3b38 100644 --- a/openstack/blockstorage/v3/attachments/testing/fixtures_test.go +++ b/openstack/blockstorage/v3/attachments/testing/fixtures_test.go @@ -64,7 +64,7 @@ func MockListResponse(t *testing.T) { } `, th.Server.URL) case "1": - fmt.Fprintf(w, `{"volumes": []}`) + fmt.Fprint(w, `{"volumes": []}`) default: t.Fatalf("Unexpected marker: [%s]", marker) } @@ -78,7 +78,7 @@ func MockGetResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "attachment": { "status": "attaching", @@ -123,7 +123,7 @@ func MockCreateResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "attachment": { "status": "attaching", @@ -171,7 +171,7 @@ func MockUpdateResponse(t *testing.T) { `) w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "attachment": { "status": "attaching", @@ -202,7 +202,7 @@ func MockUpdateEmptyResponse(t *testing.T) { `) w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "attachment": { "status": "attaching", diff --git a/openstack/blockstorage/v3/availabilityzones/testing/fixtures_test.go b/openstack/blockstorage/v3/availabilityzones/testing/fixtures_test.go index 98f93db1d3..780c7dec26 100644 --- a/openstack/blockstorage/v3/availabilityzones/testing/fixtures_test.go +++ b/openstack/blockstorage/v3/availabilityzones/testing/fixtures_test.go @@ -47,6 +47,6 @@ func HandleGetSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, GetOutput) + fmt.Fprint(w, GetOutput) }) } diff --git a/openstack/blockstorage/v3/backups/testing/fixtures_test.go b/openstack/blockstorage/v3/backups/testing/fixtures_test.go index 13fc1d61d9..9bbaec87d4 100644 --- a/openstack/blockstorage/v3/backups/testing/fixtures_test.go +++ b/openstack/blockstorage/v3/backups/testing/fixtures_test.go @@ -210,7 +210,7 @@ func MockListResponse(t *testing.T) { case "": fmt.Fprintf(w, ListResponse, th.Server.URL) case "1": - fmt.Fprintf(w, `{"backups": []}`) + fmt.Fprint(w, `{"backups": []}`) default: t.Fatalf("Unexpected marker: [%s]", marker) } @@ -233,7 +233,7 @@ func MockListDetailResponse(t *testing.T) { case "": fmt.Fprintf(w, ListDetailResponse, th.Server.URL) case "1": - fmt.Fprintf(w, `{"backups": []}`) + fmt.Fprint(w, `{"backups": []}`) default: t.Fatalf("Unexpected marker: [%s]", marker) } @@ -247,7 +247,7 @@ func MockGetResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, GetResponse) + fmt.Fprint(w, GetResponse) }) } @@ -262,7 +262,7 @@ func MockCreateResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusAccepted) - fmt.Fprintf(w, CreateResponse) + fmt.Fprint(w, CreateResponse) }) } @@ -277,7 +277,7 @@ func MockRestoreResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusAccepted) - fmt.Fprintf(w, RestoreResponse) + fmt.Fprint(w, RestoreResponse) }) } @@ -298,7 +298,7 @@ func MockExportResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ExportResponse) + fmt.Fprint(w, ExportResponse) }) } @@ -313,7 +313,7 @@ func MockImportResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, ImportResponse) + fmt.Fprint(w, ImportResponse) }) } diff --git a/openstack/blockstorage/v3/limits/testing/fixtures_test.go b/openstack/blockstorage/v3/limits/testing/fixtures_test.go index 5d3b647427..68fe8ae833 100644 --- a/openstack/blockstorage/v3/limits/testing/fixtures_test.go +++ b/openstack/blockstorage/v3/limits/testing/fixtures_test.go @@ -124,6 +124,6 @@ func HandleGetSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, GetOutput) + fmt.Fprint(w, GetOutput) }) } diff --git a/openstack/blockstorage/v3/qos/testing/fixtures_test.go b/openstack/blockstorage/v3/qos/testing/fixtures_test.go index 8f9d2e2d51..e6cd002cea 100644 --- a/openstack/blockstorage/v3/qos/testing/fixtures_test.go +++ b/openstack/blockstorage/v3/qos/testing/fixtures_test.go @@ -47,7 +47,7 @@ func MockCreateResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "qos_specs": { "id": "d32019d3-bc6e-4319-9c1d-6722fc136a22", @@ -110,7 +110,7 @@ func MockListResponse(t *testing.T) { } `, th.Server.URL) case "2": - fmt.Fprintf(w, `{ "qos_specs": [] }`) + fmt.Fprint(w, `{ "qos_specs": [] }`) default: t.Fatalf("Unexpected marker: [%s]", marker) } @@ -124,7 +124,7 @@ func MockGetResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "qos_specs": { "id": "d32019d3-bc6e-4319-9c1d-6722fc136a22", @@ -172,7 +172,7 @@ func MockUpdateResponse(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, UpdateBody) + fmt.Fprint(w, UpdateBody) }) } @@ -219,7 +219,7 @@ func MockListAssociationsResponse(t *testing.T) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "qos_associations": [ { diff --git a/openstack/blockstorage/v3/quotasets/testing/fixtures_test.go b/openstack/blockstorage/v3/quotasets/testing/fixtures_test.go index df029ff8e1..103afef6ef 100644 --- a/openstack/blockstorage/v3/quotasets/testing/fixtures_test.go +++ b/openstack/blockstorage/v3/quotasets/testing/fixtures_test.go @@ -164,7 +164,7 @@ func HandleSuccessfulRequest(t *testing.T, httpMethod, uriPath, jsonOutput strin th.TestFormValues(t, r, uriQueryParams) } - fmt.Fprintf(w, jsonOutput) + fmt.Fprint(w, jsonOutput) }) } diff --git a/openstack/blockstorage/v3/schedulerstats/testing/fixtures_test.go b/openstack/blockstorage/v3/schedulerstats/testing/fixtures_test.go index 0a1286e862..18462bfb20 100644 --- a/openstack/blockstorage/v3/schedulerstats/testing/fixtures_test.go +++ b/openstack/blockstorage/v3/schedulerstats/testing/fixtures_test.go @@ -104,9 +104,9 @@ func HandleStoragePoolsListSuccessfully(t *testing.T) { t.Errorf("Failed to parse request form %v", err) } if r.FormValue("detail") == "true" { - fmt.Fprintf(w, StoragePoolsListBodyDetail) + fmt.Fprint(w, StoragePoolsListBodyDetail) } else { - fmt.Fprintf(w, StoragePoolsListBody) + fmt.Fprint(w, StoragePoolsListBody) } }) } diff --git a/openstack/blockstorage/v3/services/testing/fixtures_test.go b/openstack/blockstorage/v3/services/testing/fixtures_test.go index adf7993df7..63771ff032 100644 --- a/openstack/blockstorage/v3/services/testing/fixtures_test.go +++ b/openstack/blockstorage/v3/services/testing/fixtures_test.go @@ -92,6 +92,6 @@ func HandleListSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, ServiceListBody) + fmt.Fprint(w, ServiceListBody) }) } diff --git a/openstack/blockstorage/v3/snapshots/testing/fixtures_test.go b/openstack/blockstorage/v3/snapshots/testing/fixtures_test.go index 8bbc45e77d..25e54b9b3e 100644 --- a/openstack/blockstorage/v3/snapshots/testing/fixtures_test.go +++ b/openstack/blockstorage/v3/snapshots/testing/fixtures_test.go @@ -54,7 +54,7 @@ func MockListResponse(t *testing.T) { } `, th.Server.URL) case "1": - fmt.Fprintf(w, `{"snapshots": []}`) + fmt.Fprint(w, `{"snapshots": []}`) default: t.Fatalf("Unexpected marker: [%s]", marker) } @@ -69,7 +69,7 @@ func MockGetResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "snapshot": { "id": "d32019d3-bc6e-4319-9c1d-6722fc136a22", @@ -104,7 +104,7 @@ func MockCreateResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusAccepted) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "snapshot": { "volume_id": "1234", @@ -135,7 +135,7 @@ func MockUpdateMetadataResponse(t *testing.T) { } `) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "metadata": { "key": "v1" @@ -162,7 +162,7 @@ func MockUpdateResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "snapshot": { "id": "d32019d3-bc6e-4319-9c1d-6722fc136a22", diff --git a/openstack/blockstorage/v3/transfers/testing/fixtures_test.go b/openstack/blockstorage/v3/transfers/testing/fixtures_test.go index b2c11f60c7..859e454eca 100644 --- a/openstack/blockstorage/v3/transfers/testing/fixtures_test.go +++ b/openstack/blockstorage/v3/transfers/testing/fixtures_test.go @@ -167,7 +167,7 @@ func HandleCreateTransfer(t *testing.T) { th.TestJSONRequest(t, r, CreateRequest) w.WriteHeader(http.StatusAccepted) - fmt.Fprintf(w, CreateResponse) + fmt.Fprint(w, CreateResponse) }) } @@ -179,7 +179,7 @@ func HandleAcceptTransfer(t *testing.T) { th.TestJSONRequest(t, r, AcceptTransferRequest) w.WriteHeader(http.StatusAccepted) - fmt.Fprintf(w, AcceptTransferResponse) + fmt.Fprint(w, AcceptTransferResponse) }) } @@ -200,7 +200,7 @@ func HandleListTransfers(t *testing.T) { th.TestFormValues(t, r, map[string]string{"all_tenants": "true"}) w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListOutput) + fmt.Fprint(w, ListOutput) }) } @@ -211,6 +211,6 @@ func HandleGetTransfer(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, GetOutput) + fmt.Fprint(w, GetOutput) }) } diff --git a/openstack/blockstorage/v3/volumes/testing/fixtures_test.go b/openstack/blockstorage/v3/volumes/testing/fixtures_test.go index 4efb9e08f4..9b4630a978 100644 --- a/openstack/blockstorage/v3/volumes/testing/fixtures_test.go +++ b/openstack/blockstorage/v3/volumes/testing/fixtures_test.go @@ -95,7 +95,7 @@ func MockListResponse(t *testing.T) { } `, th.Server.URL) case "1": - fmt.Fprintf(w, `{"volumes": []}`) + fmt.Fprint(w, `{"volumes": []}`) default: t.Fatalf("Unexpected marker: [%s]", marker) } @@ -109,7 +109,7 @@ func MockGetResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "volume": { "volume_type": "lvmdriver-1", @@ -171,7 +171,7 @@ func MockCreateResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusAccepted) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "volume": { "size": 75, @@ -211,7 +211,7 @@ func MockUpdateResponse(t *testing.T) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "volume": { "name": "vol-002" @@ -239,7 +239,7 @@ func MockCreateVolumeFromBackupResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusAccepted) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "volume": { "size": 30, @@ -287,7 +287,7 @@ func MockAttachResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusAccepted) - fmt.Fprintf(w, `{}`) + fmt.Fprint(w, `{}`) }) } @@ -307,7 +307,7 @@ func MockBeginDetachingResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusAccepted) - fmt.Fprintf(w, `{}`) + fmt.Fprint(w, `{}`) }) } @@ -327,7 +327,7 @@ func MockDetachResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusAccepted) - fmt.Fprintf(w, `{}`) + fmt.Fprint(w, `{}`) }) } @@ -352,7 +352,7 @@ func MockUploadImageResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusAccepted) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "os-volume_upload_image": { "container_format": "bare", @@ -399,7 +399,7 @@ func MockReserveResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusAccepted) - fmt.Fprintf(w, `{}`) + fmt.Fprint(w, `{}`) }) } @@ -419,7 +419,7 @@ func MockUnreserveResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusAccepted) - fmt.Fprintf(w, `{}`) + fmt.Fprint(w, `{}`) }) } @@ -450,7 +450,7 @@ func MockInitializeConnectionResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusAccepted) - fmt.Fprintf(w, `{ + fmt.Fprint(w, `{ "connection_info": { "data": { "target_portals": [ @@ -507,7 +507,7 @@ func MockTerminateConnectionResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusAccepted) - fmt.Fprintf(w, `{}`) + fmt.Fprint(w, `{}`) }) } @@ -530,7 +530,7 @@ func MockExtendSizeResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusAccepted) - fmt.Fprintf(w, `{}`) + fmt.Fprint(w, `{}`) }) } @@ -561,7 +561,7 @@ func MockSetImageMetadataResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, `{}`) + fmt.Fprint(w, `{}`) }) } @@ -624,7 +624,7 @@ func MockChangeTypeResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusAccepted) - fmt.Fprintf(w, `{}`) + fmt.Fprint(w, `{}`) }) } diff --git a/openstack/blockstorage/v3/volumetypes/testing/fixtures_test.go b/openstack/blockstorage/v3/volumetypes/testing/fixtures_test.go index e1db5dfbd4..c7eb37893e 100644 --- a/openstack/blockstorage/v3/volumetypes/testing/fixtures_test.go +++ b/openstack/blockstorage/v3/volumetypes/testing/fixtures_test.go @@ -58,7 +58,7 @@ func MockListResponse(t *testing.T) { } `, th.Server.URL) case "1": - fmt.Fprintf(w, `{"volume_types": []}`) + fmt.Fprint(w, `{"volume_types": []}`) default: t.Fatalf("Unexpected marker: [%s]", marker) } @@ -72,7 +72,7 @@ func MockGetResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "volume_type": { "id": "d32019d3-bc6e-4319-9c1d-6722fc136a22", @@ -112,7 +112,7 @@ func MockCreateResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "volume_type": { "name": "test_type", @@ -143,7 +143,7 @@ func MockUpdateResponse(t *testing.T) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "volume_type": { "name": "vol-type-002", @@ -203,7 +203,7 @@ func HandleExtraSpecsListSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ExtraSpecsGetBody) + fmt.Fprint(w, ExtraSpecsGetBody) }) } @@ -215,7 +215,7 @@ func HandleExtraSpecGetSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, GetExtraSpecBody) + fmt.Fprint(w, GetExtraSpecBody) }) } @@ -233,7 +233,7 @@ func HandleExtraSpecsCreateSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ExtraSpecsGetBody) + fmt.Fprint(w, ExtraSpecsGetBody) }) } @@ -248,7 +248,7 @@ func HandleExtraSpecUpdateSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, UpdatedExtraSpecBody) + fmt.Fprint(w, UpdatedExtraSpecBody) }) } @@ -281,7 +281,7 @@ func MockEncryptionCreateResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "encryption": { "volume_type_id": "a5082c24-2a27-43a4-b48e-fcec1240e36b", @@ -324,7 +324,7 @@ func MockEncryptionUpdateResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "encryption": { "control_location": "front-end", @@ -345,7 +345,7 @@ func MockEncryptionGetResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "volume_type_id": "a5082c24-2a27-43a4-b48e-fcec1240e36b", "control_location": "front-end", @@ -370,7 +370,7 @@ func MockEncryptionGetSpecResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "cipher": "aes-xts-plain64" } diff --git a/openstack/blockstorage/v3/volumetypes/testing/requests_test.go b/openstack/blockstorage/v3/volumetypes/testing/requests_test.go index 56f22632f9..f222be2395 100644 --- a/openstack/blockstorage/v3/volumetypes/testing/requests_test.go +++ b/openstack/blockstorage/v3/volumetypes/testing/requests_test.go @@ -190,7 +190,7 @@ func TestVolumeTypeListAccesses(t *testing.T) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "volume_type_access": [ { diff --git a/openstack/common/extensions/testing/fixtures.go b/openstack/common/extensions/testing/fixtures.go index cfcdbe90e9..91f6a041b1 100644 --- a/openstack/common/extensions/testing/fixtures.go +++ b/openstack/common/extensions/testing/fixtures.go @@ -71,7 +71,7 @@ func HandleListExtensionsSuccessfully(t *testing.T) { w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, ListOutput) + fmt.Fprint(w, ListOutput) }) } @@ -85,6 +85,6 @@ func HandleGetExtensionSuccessfully(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, GetOutput) + fmt.Fprint(w, GetOutput) }) } diff --git a/openstack/compute/apiversions/testing/fixtures_test.go b/openstack/compute/apiversions/testing/fixtures_test.go index c7f4b1a977..49162c77ce 100644 --- a/openstack/compute/apiversions/testing/fixtures_test.go +++ b/openstack/compute/apiversions/testing/fixtures_test.go @@ -169,7 +169,7 @@ func MockListResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, NovaAllAPIVersionsResponse) + fmt.Fprint(w, NovaAllAPIVersionsResponse) }) } @@ -181,7 +181,7 @@ func MockGetResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, NovaAPIVersionResponse_21) + fmt.Fprint(w, NovaAPIVersionResponse_21) }) } @@ -193,6 +193,6 @@ func MockGetMultipleResponses(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, NovaAPIInvalidVersionResponse) + fmt.Fprint(w, NovaAPIInvalidVersionResponse) }) } diff --git a/openstack/compute/v2/aggregates/testing/fixtures_test.go b/openstack/compute/v2/aggregates/testing/fixtures_test.go index a67678404f..11cebc8915 100644 --- a/openstack/compute/v2/aggregates/testing/fixtures_test.go +++ b/openstack/compute/v2/aggregates/testing/fixtures_test.go @@ -264,7 +264,7 @@ func HandleListSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, AggregateListBody) + fmt.Fprint(w, AggregateListBody) }) } @@ -274,7 +274,7 @@ func HandleCreateSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, AggregateCreateBody) + fmt.Fprint(w, AggregateCreateBody) }) } @@ -295,7 +295,7 @@ func HandleGetSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, AggregateGetBody) + fmt.Fprint(w, AggregateGetBody) }) } @@ -306,7 +306,7 @@ func HandleUpdateSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, AggregateUpdateBody) + fmt.Fprint(w, AggregateUpdateBody) }) } @@ -317,7 +317,7 @@ func HandleAddHostSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, AggregateAddHostBody) + fmt.Fprint(w, AggregateAddHostBody) }) } @@ -328,7 +328,7 @@ func HandleRemoveHostSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, AggregateRemoveHostBody) + fmt.Fprint(w, AggregateRemoveHostBody) }) } @@ -339,6 +339,6 @@ func HandleSetMetadataSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, AggregateSetMetadataBody) + fmt.Fprint(w, AggregateSetMetadataBody) }) } diff --git a/openstack/compute/v2/attachinterfaces/testing/fixtures_test.go b/openstack/compute/v2/attachinterfaces/testing/fixtures_test.go index 77bc48f55e..59a03d57d2 100644 --- a/openstack/compute/v2/attachinterfaces/testing/fixtures_test.go +++ b/openstack/compute/v2/attachinterfaces/testing/fixtures_test.go @@ -69,7 +69,7 @@ func HandleInterfaceListSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, `{ + fmt.Fprint(w, `{ "interfaceAttachments": [ { "port_state":"ACTIVE", @@ -99,7 +99,7 @@ func HandleInterfaceGetSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, `{ + fmt.Fprint(w, `{ "interfaceAttachment": { "port_state":"ACTIVE", @@ -133,7 +133,7 @@ func HandleInterfaceCreateSuccessfully(t *testing.T) { }`) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, `{ + fmt.Fprint(w, `{ "interfaceAttachment": { "port_state":"ACTIVE", diff --git a/openstack/compute/v2/availabilityzones/testing/fixtures_test.go b/openstack/compute/v2/availabilityzones/testing/fixtures_test.go index 059364bcc0..a36c64649c 100644 --- a/openstack/compute/v2/availabilityzones/testing/fixtures_test.go +++ b/openstack/compute/v2/availabilityzones/testing/fixtures_test.go @@ -180,7 +180,7 @@ func HandleGetSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, GetOutput) + fmt.Fprint(w, GetOutput) }) } @@ -192,6 +192,6 @@ func HandleGetDetailSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, GetDetailOutput) + fmt.Fprint(w, GetDetailOutput) }) } diff --git a/openstack/compute/v2/extensions/testing/fixtures_test.go b/openstack/compute/v2/extensions/testing/fixtures_test.go index 6827dab20c..b1622af764 100644 --- a/openstack/compute/v2/extensions/testing/fixtures_test.go +++ b/openstack/compute/v2/extensions/testing/fixtures_test.go @@ -16,7 +16,7 @@ func HandleListExtensionsSuccessfully(t *testing.T) { w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "extensions": [ { @@ -41,7 +41,7 @@ func HandleGetExtensionsSuccessfully(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "extension": { "updated": "2013-02-03T10:00:00-00:00", diff --git a/openstack/compute/v2/flavors/testing/fixtures_test.go b/openstack/compute/v2/flavors/testing/fixtures_test.go index 94ac8c8a59..a92cdcd1d8 100644 --- a/openstack/compute/v2/flavors/testing/fixtures_test.go +++ b/openstack/compute/v2/flavors/testing/fixtures_test.go @@ -57,7 +57,7 @@ func HandleExtraSpecsListSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ExtraSpecsGetBody) + fmt.Fprint(w, ExtraSpecsGetBody) }) } @@ -69,7 +69,7 @@ func HandleExtraSpecGetSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, GetExtraSpecBody) + fmt.Fprint(w, GetExtraSpecBody) }) } @@ -87,7 +87,7 @@ func HandleExtraSpecsCreateSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ExtraSpecsGetBody) + fmt.Fprint(w, ExtraSpecsGetBody) }) } @@ -102,7 +102,7 @@ func HandleExtraSpecUpdateSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, UpdatedExtraSpecBody) + fmt.Fprint(w, UpdatedExtraSpecBody) }) } diff --git a/openstack/compute/v2/flavors/testing/requests_test.go b/openstack/compute/v2/flavors/testing/requests_test.go index d22e3dfa9c..efd6e4bcee 100644 --- a/openstack/compute/v2/flavors/testing/requests_test.go +++ b/openstack/compute/v2/flavors/testing/requests_test.go @@ -76,7 +76,7 @@ func TestListFlavors(t *testing.T) { } `, th.Server.URL) case "2": - fmt.Fprintf(w, `{ "flavors": [] }`) + fmt.Fprint(w, `{ "flavors": [] }`) default: t.Fatalf("Unexpected marker: [%s]", marker) } @@ -121,7 +121,7 @@ func TestGetFlavor(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "flavor": { "id": "1", @@ -170,7 +170,7 @@ func TestCreateFlavor(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "flavor": { "id": "1", @@ -225,7 +225,7 @@ func TestUpdateFlavor(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "flavor": { "id": "1", @@ -288,7 +288,7 @@ func TestFlavorAccessesList(t *testing.T) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "flavor_access": [ { @@ -336,7 +336,7 @@ func TestFlavorAccessAdd(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "flavor_access": [ { @@ -385,7 +385,7 @@ func TestFlavorAccessRemove(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "flavor_access": [] } diff --git a/openstack/compute/v2/hypervisors/testing/fixtures_test.go b/openstack/compute/v2/hypervisors/testing/fixtures_test.go index 6e4b2e4aff..fa0b93a3f8 100644 --- a/openstack/compute/v2/hypervisors/testing/fixtures_test.go +++ b/openstack/compute/v2/hypervisors/testing/fixtures_test.go @@ -605,7 +605,7 @@ func HandleHypervisorsStatisticsSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, HypervisorsStatisticsBody) + fmt.Fprint(w, HypervisorsStatisticsBody) }) } @@ -615,7 +615,7 @@ func HandleHypervisorListPre253Successfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, HypervisorListBodyPre253) + fmt.Fprint(w, HypervisorListBodyPre253) }) } @@ -625,7 +625,7 @@ func HandleHypervisorListSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, HypervisorListBody) + fmt.Fprint(w, HypervisorListBody) }) } @@ -638,7 +638,7 @@ func HandleHypervisorListWithParametersSuccessfully(t *testing.T) { }) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, HypervisorListWithParametersBody) + fmt.Fprint(w, HypervisorListWithParametersBody) }) } @@ -648,7 +648,7 @@ func HandleHypervisorGetSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, HypervisorGetBody) + fmt.Fprint(w, HypervisorGetBody) }) } @@ -658,7 +658,7 @@ func HandleHypervisorGetEmptyCPUInfoSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, HypervisorGetEmptyCPUInfoBody) + fmt.Fprint(w, HypervisorGetEmptyCPUInfoBody) }) } @@ -668,7 +668,7 @@ func HandleHypervisorAfterV287ResponseSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, HypervisorAfterV287ResponseBody) + fmt.Fprint(w, HypervisorAfterV287ResponseBody) }) } @@ -678,6 +678,6 @@ func HandleHypervisorUptimeSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, HypervisorUptimeBody) + fmt.Fprint(w, HypervisorUptimeBody) }) } diff --git a/openstack/compute/v2/instanceactions/testing/fixtures_test.go b/openstack/compute/v2/instanceactions/testing/fixtures_test.go index 3b24801c38..cbbf6def28 100644 --- a/openstack/compute/v2/instanceactions/testing/fixtures_test.go +++ b/openstack/compute/v2/instanceactions/testing/fixtures_test.go @@ -40,7 +40,7 @@ func HandleInstanceActionListSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, `{ + fmt.Fprint(w, `{ "instanceActions": [ { "action": "stop", @@ -100,7 +100,7 @@ func HandleInstanceActionGetSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, `{ + fmt.Fprint(w, `{ "instanceAction": { "action": "stop", diff --git a/openstack/compute/v2/keypairs/testing/fixtures_test.go b/openstack/compute/v2/keypairs/testing/fixtures_test.go index 41532c03cc..92460e9259 100644 --- a/openstack/compute/v2/keypairs/testing/fixtures_test.go +++ b/openstack/compute/v2/keypairs/testing/fixtures_test.go @@ -157,7 +157,7 @@ func HandleListSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, ListOutput) + fmt.Fprint(w, ListOutput) }) } @@ -169,11 +169,11 @@ func HandleGetSuccessfully(t *testing.T) { if r.URL.Query().Get("user_id") == "fake2" { w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, GetOutputOtherUser) + fmt.Fprint(w, GetOutputOtherUser) } else { w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, GetOutput) + fmt.Fprint(w, GetOutput) } }) @@ -188,7 +188,7 @@ func HandleCreateSuccessfully(t *testing.T) { th.TestJSONRequest(t, r, `{ "keypair": { "name": "createdkey" } }`) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, CreateOutput) + fmt.Fprint(w, CreateOutput) }) } @@ -201,7 +201,7 @@ func HandleCreateSuccessfullyOtherUser(t *testing.T) { th.TestJSONRequest(t, r, `{ "keypair": { "name": "createdkey", "user_id": "fake2" } }`) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, CreateOutputOtherUser) + fmt.Fprint(w, CreateOutputOtherUser) }) } @@ -221,7 +221,7 @@ func HandleImportSuccessfully(t *testing.T) { `) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, ImportOutput) + fmt.Fprint(w, ImportOutput) }) } diff --git a/openstack/compute/v2/limits/testing/fixtures_test.go b/openstack/compute/v2/limits/testing/fixtures_test.go index 3751c2d8b6..ee04c72442 100644 --- a/openstack/compute/v2/limits/testing/fixtures_test.go +++ b/openstack/compute/v2/limits/testing/fixtures_test.go @@ -75,6 +75,6 @@ func HandleGetSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, GetOutput) + fmt.Fprint(w, GetOutput) }) } diff --git a/openstack/compute/v2/quotasets/testing/fixtures_test.go b/openstack/compute/v2/quotasets/testing/fixtures_test.go index d1c714714b..5d0ef24931 100644 --- a/openstack/compute/v2/quotasets/testing/fixtures_test.go +++ b/openstack/compute/v2/quotasets/testing/fixtures_test.go @@ -167,7 +167,7 @@ func HandleGetSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, GetOutput) + fmt.Fprint(w, GetOutput) }) } @@ -177,7 +177,7 @@ func HandleGetDetailSuccessfully(t *testing.T) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, GetDetailsOutput) + fmt.Fprint(w, GetDetailsOutput) }) } @@ -188,7 +188,7 @@ func HandlePutSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, UpdateOutput) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, UpdateOutput) + fmt.Fprint(w, UpdateOutput) }) } @@ -199,7 +199,7 @@ func HandlePartialPutSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, PartialUpdateBody) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, UpdateOutput) + fmt.Fprint(w, UpdateOutput) }) } diff --git a/openstack/compute/v2/remoteconsoles/testing/requests_test.go b/openstack/compute/v2/remoteconsoles/testing/requests_test.go index e96b897d0f..3a49e4d46f 100644 --- a/openstack/compute/v2/remoteconsoles/testing/requests_test.go +++ b/openstack/compute/v2/remoteconsoles/testing/requests_test.go @@ -25,7 +25,7 @@ func TestCreate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, RemoteConsoleCreateResult) + fmt.Fprint(w, RemoteConsoleCreateResult) }) opts := remoteconsoles.CreateOpts{ diff --git a/openstack/compute/v2/secgroups/testing/fixtures_test.go b/openstack/compute/v2/secgroups/testing/fixtures_test.go index 0b35cc71d8..df3614b66b 100644 --- a/openstack/compute/v2/secgroups/testing/fixtures_test.go +++ b/openstack/compute/v2/secgroups/testing/fixtures_test.go @@ -33,7 +33,7 @@ func mockListGroupsResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, listGroupsJSON) + fmt.Fprint(w, listGroupsJSON) }) } @@ -46,7 +46,7 @@ func mockListGroupsByServerResponse(t *testing.T, serverID string) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, listGroupsJSON) + fmt.Fprint(w, listGroupsJSON) }) } @@ -67,7 +67,7 @@ func mockCreateGroupResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "security_group": { "description": "something", @@ -99,7 +99,7 @@ func mockUpdateGroupResponse(t *testing.T, groupID string) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "security_group": { "description": "something", @@ -122,7 +122,7 @@ func mockGetGroupsResponse(t *testing.T, groupID string) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "security_group": { "description": "default", @@ -224,7 +224,7 @@ func mockAddRuleResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "security_group_rule": { "from_port": 22, @@ -260,7 +260,7 @@ func mockAddRuleResponseICMPZero(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "security_group_rule": { "from_port": 0, diff --git a/openstack/compute/v2/servergroups/testing/fixtures_test.go b/openstack/compute/v2/servergroups/testing/fixtures_test.go index de36c3ff89..2ad519023a 100644 --- a/openstack/compute/v2/servergroups/testing/fixtures_test.go +++ b/openstack/compute/v2/servergroups/testing/fixtures_test.go @@ -148,7 +148,7 @@ func HandleListSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, ListOutput) + fmt.Fprint(w, ListOutput) }) } @@ -160,7 +160,7 @@ func HandleGetSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, GetOutput) + fmt.Fprint(w, GetOutput) }) } @@ -172,7 +172,7 @@ func HandleGetMicroversionSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, GetOutputMicroversion) + fmt.Fprint(w, GetOutputMicroversion) }) } @@ -194,7 +194,7 @@ func HandleCreateSuccessfully(t *testing.T) { `) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, CreateOutput) + fmt.Fprint(w, CreateOutput) }) } @@ -220,7 +220,7 @@ func HandleCreateMicroversionSuccessfully(t *testing.T) { `) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, CreateOutputMicroversion) + fmt.Fprint(w, CreateOutputMicroversion) }) } diff --git a/openstack/compute/v2/servers/testing/fixtures_test.go b/openstack/compute/v2/servers/testing/fixtures_test.go index 2ce6282b02..1c25b40074 100644 --- a/openstack/compute/v2/servers/testing/fixtures_test.go +++ b/openstack/compute/v2/servers/testing/fixtures_test.go @@ -741,7 +741,7 @@ func HandleServerNoNetworkCreationSuccessfully(t *testing.T, response string) { w.WriteHeader(http.StatusAccepted) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, response) + fmt.Fprint(w, response) }) } @@ -761,7 +761,7 @@ func HandleServerCreationSuccessfully(t *testing.T, response string) { w.WriteHeader(http.StatusAccepted) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, response) + fmt.Fprint(w, response) }) th.Mux.HandleFunc("/images/detail", func(w http.ResponseWriter, r *http.Request) { @@ -775,7 +775,7 @@ func HandleServerCreationSuccessfully(t *testing.T, response string) { marker := r.Form.Get("marker") switch marker { case "": - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "images": [ { @@ -804,7 +804,7 @@ func HandleServerCreationSuccessfully(t *testing.T, response string) { } `) case "2": - fmt.Fprintf(w, `{ "images": [] }`) + fmt.Fprint(w, `{ "images": [] }`) default: t.Fatalf("Unexpected marker: [%s]", marker) } @@ -850,7 +850,7 @@ func HandleServerCreationSuccessfully(t *testing.T, response string) { } `, th.Server.URL) case "2": - fmt.Fprintf(w, `{ "flavors": [] }`) + fmt.Fprint(w, `{ "flavors": [] }`) default: t.Fatalf("Unexpected marker: [%s]", marker) } @@ -875,7 +875,7 @@ func HandleServersCreationSuccessfully(t *testing.T, response string) { w.WriteHeader(http.StatusAccepted) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, response) + fmt.Fprint(w, response) }) } @@ -896,7 +896,7 @@ func HandleServerCreationWithCustomFieldSuccessfully(t *testing.T, response stri w.WriteHeader(http.StatusAccepted) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, response) + fmt.Fprint(w, response) }) } @@ -915,7 +915,7 @@ func HandleServerCreationWithHostname(t *testing.T, response string) { w.WriteHeader(http.StatusAccepted) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, response) + fmt.Fprint(w, response) }) } @@ -936,7 +936,7 @@ func HandleServerCreationWithUserdata(t *testing.T, response string) { w.WriteHeader(http.StatusAccepted) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, response) + fmt.Fprint(w, response) }) } @@ -959,7 +959,7 @@ func HandleServerCreationWithMetadata(t *testing.T, response string) { w.WriteHeader(http.StatusAccepted) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, response) + fmt.Fprint(w, response) }) } @@ -976,9 +976,9 @@ func HandleServerListSimpleSuccessfully(t *testing.T) { marker := r.Form.Get("marker") switch marker { case "": - fmt.Fprintf(w, ServerListBody) + fmt.Fprint(w, ServerListBody) case "9e5476bd-a4ec-4653-93d6-72c93aa682ba": - fmt.Fprintf(w, `{ "servers": [] }`) + fmt.Fprint(w, `{ "servers": [] }`) default: t.Fatalf("/servers invoked with unexpected marker=[%s]", marker) } @@ -998,9 +998,9 @@ func HandleServerListSuccessfully(t *testing.T) { marker := r.Form.Get("marker") switch marker { case "": - fmt.Fprintf(w, ServerListBody) + fmt.Fprint(w, ServerListBody) case "9e5476bd-a4ec-4653-93d6-72c93aa682ba": - fmt.Fprintf(w, `{ "servers": [] }`) + fmt.Fprint(w, `{ "servers": [] }`) default: t.Fatalf("/servers/detail invoked with unexpected marker=[%s]", marker) } @@ -1036,7 +1036,7 @@ func HandleServerGetSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") - fmt.Fprintf(w, SingleServerBody) + fmt.Fprint(w, SingleServerBody) }) } @@ -1048,7 +1048,7 @@ func HandleServerGetFaultSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") - fmt.Fprintf(w, FaultyServerBody) + fmt.Fprint(w, FaultyServerBody) }) } @@ -1061,7 +1061,7 @@ func HandleServerUpdateSuccessfully(t *testing.T) { th.TestHeader(t, r, "Content-Type", "application/json") th.TestJSONRequest(t, r, `{ "server": { "name": "new-name" } }`) - fmt.Fprintf(w, SingleServerBody) + fmt.Fprint(w, SingleServerBody) }) } @@ -1097,7 +1097,7 @@ func HandleShowConsoleOutputSuccessfully(t *testing.T, response string) { w.WriteHeader(http.StatusOK) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, response) + fmt.Fprint(w, response) }) } @@ -1119,7 +1119,7 @@ func HandleRebuildSuccessfully(t *testing.T, response string) { w.WriteHeader(http.StatusAccepted) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, response) + fmt.Fprint(w, response) }) } @@ -1243,7 +1243,7 @@ func HandleAddressListSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, `{ + fmt.Fprint(w, `{ "addresses": { "public": [ { @@ -1285,7 +1285,7 @@ func HandleNetworkAddressListSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, `{ + fmt.Fprint(w, `{ "public": [ { "version": 4, @@ -1317,7 +1317,7 @@ func HandlePasswordGetSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") - fmt.Fprintf(w, ServerPasswordBody) + fmt.Fprint(w, ServerPasswordBody) }) } @@ -1332,6 +1332,6 @@ func HandleServerWithTagsCreationSuccessfully(t *testing.T) { w.WriteHeader(http.StatusAccepted) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, SingleServerWithTagsBody) + fmt.Fprint(w, SingleServerWithTagsBody) }) } diff --git a/openstack/compute/v2/services/testing/fixtures_test.go b/openstack/compute/v2/services/testing/fixtures_test.go index 2104dc08cb..93b124df90 100644 --- a/openstack/compute/v2/services/testing/fixtures_test.go +++ b/openstack/compute/v2/services/testing/fixtures_test.go @@ -259,7 +259,7 @@ func HandleListPre253Successfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, ServiceListBodyPre253) + fmt.Fprint(w, ServiceListBodyPre253) }) } @@ -271,7 +271,7 @@ func HandleListSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, ServiceListBody) + fmt.Fprint(w, ServiceListBody) }) } @@ -285,7 +285,7 @@ func HandleUpdateSuccessfully(t *testing.T) { th.TestHeader(t, r, "Content-Type", "application/json") th.TestJSONRequest(t, r, `{"status": "disabled"}`) - fmt.Fprintf(w, ServiceUpdate) + fmt.Fprint(w, ServiceUpdate) }) } diff --git a/openstack/compute/v2/tags/testing/requests_test.go b/openstack/compute/v2/tags/testing/requests_test.go index 03f4260a7d..dc524a2306 100644 --- a/openstack/compute/v2/tags/testing/requests_test.go +++ b/openstack/compute/v2/tags/testing/requests_test.go @@ -22,7 +22,7 @@ func TestList(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - _, err := fmt.Fprintf(w, TagsListResponse) + _, err := fmt.Fprint(w, TagsListResponse) th.AssertNoErr(t, err) }) @@ -78,7 +78,7 @@ func TestReplaceAll(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - _, err := fmt.Fprintf(w, TagsReplaceAllResponse) + _, err := fmt.Fprint(w, TagsReplaceAllResponse) th.AssertNoErr(t, err) }) diff --git a/openstack/compute/v2/volumeattach/testing/fixtures_test.go b/openstack/compute/v2/volumeattach/testing/fixtures_test.go index c5f0435a96..d9ada1e8c1 100644 --- a/openstack/compute/v2/volumeattach/testing/fixtures_test.go +++ b/openstack/compute/v2/volumeattach/testing/fixtures_test.go @@ -62,7 +62,7 @@ func HandleListSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, ListOutput) + fmt.Fprint(w, ListOutput) }) } @@ -74,7 +74,7 @@ func HandleGetSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, GetOutput) + fmt.Fprint(w, GetOutput) }) } @@ -96,7 +96,7 @@ func HandleCreateSuccessfully(t *testing.T) { `) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, CreateOutput) + fmt.Fprint(w, CreateOutput) }) } diff --git a/openstack/container/v1/capsules/testing/fixtures_test.go b/openstack/container/v1/capsules/testing/fixtures_test.go index fe7b008013..779a41a0df 100644 --- a/openstack/container/v1/capsules/testing/fixtures_test.go +++ b/openstack/container/v1/capsules/testing/fixtures_test.go @@ -609,7 +609,7 @@ func HandleCapsuleGetOldTimeSuccessfully(t *testing.T) { w.WriteHeader(http.StatusOK) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, CapsuleGetBody_OldTime) + fmt.Fprint(w, CapsuleGetBody_OldTime) }) } @@ -621,7 +621,7 @@ func HandleCapsuleGetNewTimeSuccessfully(t *testing.T) { w.WriteHeader(http.StatusOK) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, CapsuleGetBody_NewTime) + fmt.Fprint(w, CapsuleGetBody_NewTime) }) } @@ -633,7 +633,7 @@ func HandleCapsuleCreateSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) th.TestHeader(t, r, "Accept", "application/json") w.WriteHeader(http.StatusAccepted) - fmt.Fprintf(w, CapsuleGetBody_NewTime) + fmt.Fprint(w, CapsuleGetBody_NewTime) }) } @@ -645,7 +645,7 @@ func HandleCapsuleListSuccessfully(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, CapsuleListBody) + fmt.Fprint(w, CapsuleListBody) }) } @@ -657,7 +657,7 @@ func HandleCapsuleV132ListSuccessfully(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, CapsuleV132ListBody) + fmt.Fprint(w, CapsuleV132ListBody) }) } diff --git a/openstack/containerinfra/apiversions/testing/fixtures_test.go b/openstack/containerinfra/apiversions/testing/fixtures_test.go index e95058151d..f42844214c 100644 --- a/openstack/containerinfra/apiversions/testing/fixtures_test.go +++ b/openstack/containerinfra/apiversions/testing/fixtures_test.go @@ -71,7 +71,7 @@ func MockListResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, MagnumAllAPIVersionsResponse) + fmt.Fprint(w, MagnumAllAPIVersionsResponse) }) } @@ -83,6 +83,6 @@ func MockGetResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, MagnumAPIVersionResponse) + fmt.Fprint(w, MagnumAPIVersionResponse) }) } diff --git a/openstack/containerinfra/v1/certificates/testing/fixtures_test.go b/openstack/containerinfra/v1/certificates/testing/fixtures_test.go index 3f88c34242..b51d77cbd4 100644 --- a/openstack/containerinfra/v1/certificates/testing/fixtures_test.go +++ b/openstack/containerinfra/v1/certificates/testing/fixtures_test.go @@ -106,6 +106,6 @@ func HandleUpdateCertificateSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.WriteHeader(http.StatusAccepted) - fmt.Fprintf(w, `{}`) + fmt.Fprint(w, `{}`) }) } diff --git a/openstack/containerinfra/v1/nodegroups/testing/fixtures_test.go b/openstack/containerinfra/v1/nodegroups/testing/fixtures_test.go index 51e63cc318..90de8b6fe6 100644 --- a/openstack/containerinfra/v1/nodegroups/testing/fixtures_test.go +++ b/openstack/containerinfra/v1/nodegroups/testing/fixtures_test.go @@ -221,7 +221,7 @@ func handleCreateNodeGroupSuccess(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusAccepted) - fmt.Fprintf(w, nodeGroupCreateResponse) + fmt.Fprint(w, nodeGroupCreateResponse) }) } @@ -233,7 +233,7 @@ func handleCreateNodeGroupDuplicate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusConflict) - fmt.Fprintf(w, nodeGroupCreateDuplicateResponse) + fmt.Fprint(w, nodeGroupCreateDuplicateResponse) }) } @@ -245,7 +245,7 @@ func handleCreateNodeGroupMaster(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusBadRequest) - fmt.Fprintf(w, nodeGroupCreateMasterResponse) + fmt.Fprint(w, nodeGroupCreateMasterResponse) }) } @@ -257,7 +257,7 @@ func handleCreateNodeGroupBadSizes(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusConflict) - fmt.Fprintf(w, nodeGroupCreateBadSizesResponse) + fmt.Fprint(w, nodeGroupCreateBadSizesResponse) }) } @@ -269,7 +269,7 @@ func handleUpdateNodeGroupSuccess(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusAccepted) - fmt.Fprintf(w, nodeGroupUpdateResponse) + fmt.Fprint(w, nodeGroupUpdateResponse) }) } @@ -281,7 +281,7 @@ func handleUpdateNodeGroupInternal(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusBadRequest) - fmt.Fprintf(w, nodeGroupUpdateInternalResponse) + fmt.Fprint(w, nodeGroupUpdateInternalResponse) }) } @@ -293,7 +293,7 @@ func handleUpdateNodeGroupBadField(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusBadRequest) - fmt.Fprintf(w, nodeGroupUpdateBadFieldResponse) + fmt.Fprint(w, nodeGroupUpdateBadFieldResponse) }) } @@ -305,7 +305,7 @@ func handleUpdateNodeGroupBadMin(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusConflict) - fmt.Fprintf(w, nodeGroupUpdateBadMinResponse) + fmt.Fprint(w, nodeGroupUpdateBadMinResponse) }) } @@ -326,7 +326,7 @@ func handleDeleteNodeGroupNotFound(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusNotFound) - fmt.Fprintf(w, nodeGroupDeleteNotFoundResponse) + fmt.Fprint(w, nodeGroupDeleteNotFoundResponse) }) } @@ -338,7 +338,7 @@ func handleDeleteNodeGroupClusterNotFound(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusNotFound) - fmt.Fprintf(w, nodeGroupDeleteClusterNotFoundResponse) + fmt.Fprint(w, nodeGroupDeleteClusterNotFoundResponse) }) } @@ -350,7 +350,7 @@ func handleDeleteNodeGroupDefault(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusBadRequest) - fmt.Fprintf(w, nodeGroupDeleteDefaultResponse) + fmt.Fprint(w, nodeGroupDeleteDefaultResponse) }) } diff --git a/openstack/dns/v2/recordsets/testing/fixtures_test.go b/openstack/dns/v2/recordsets/testing/fixtures_test.go index 9d2289f100..71d1d0898e 100644 --- a/openstack/dns/v2/recordsets/testing/fixtures_test.go +++ b/openstack/dns/v2/recordsets/testing/fixtures_test.go @@ -212,9 +212,9 @@ func HandleListByZoneSuccessfully(t *testing.T) { marker := r.Form.Get("marker") switch marker { case "f7b10e9b-0cae-4a91-b162-562bc6096648": - fmt.Fprintf(w, ListByZoneOutputLimited) + fmt.Fprint(w, ListByZoneOutputLimited) case "": - fmt.Fprintf(w, ListByZoneOutput) + fmt.Fprint(w, ListByZoneOutput) } }) } @@ -227,7 +227,7 @@ func HandleGetSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, GetOutput) + fmt.Fprint(w, GetOutput) }) } @@ -282,7 +282,7 @@ func HandleCreateSuccessfully(t *testing.T) { w.WriteHeader(http.StatusCreated) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, CreateRecordSetResponse) + fmt.Fprint(w, CreateRecordSetResponse) }) } @@ -334,7 +334,7 @@ func HandleUpdateSuccessfully(t *testing.T) { w.WriteHeader(http.StatusOK) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, UpdateRecordSetResponse) + fmt.Fprint(w, UpdateRecordSetResponse) }) } @@ -373,6 +373,6 @@ func HandleDeleteSuccessfully(t *testing.T) { w.WriteHeader(http.StatusAccepted) //w.Header().Add("Content-Type", "application/json") - //fmt.Fprintf(w, DeleteZoneResponse) + //fmt.Fprint(w, DeleteZoneResponse) }) } diff --git a/openstack/dns/v2/transfer/accept/testing/fixtures_test.go b/openstack/dns/v2/transfer/accept/testing/fixtures_test.go index b8c3fe5888..3dae54e6aa 100644 --- a/openstack/dns/v2/transfer/accept/testing/fixtures_test.go +++ b/openstack/dns/v2/transfer/accept/testing/fixtures_test.go @@ -133,7 +133,7 @@ func HandleListSuccessfully(t *testing.T) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, ListOutput) + fmt.Fprint(w, ListOutput) }) } @@ -145,7 +145,7 @@ func HandleFilteredListSuccessfully(t *testing.T) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, FilteredListOutput) + fmt.Fprint(w, FilteredListOutput) }) } @@ -157,7 +157,7 @@ func HandleGetSuccessfully(t *testing.T) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, GetOutput) + fmt.Fprint(w, GetOutput) }) } @@ -200,6 +200,6 @@ func HandleCreateSuccessfully(t *testing.T) { w.WriteHeader(http.StatusCreated) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, CreateTransferAcceptResponse) + fmt.Fprint(w, CreateTransferAcceptResponse) }) } diff --git a/openstack/dns/v2/transfer/request/testing/fixtures_test.go b/openstack/dns/v2/transfer/request/testing/fixtures_test.go index 758b566604..3de1f2aca3 100644 --- a/openstack/dns/v2/transfer/request/testing/fixtures_test.go +++ b/openstack/dns/v2/transfer/request/testing/fixtures_test.go @@ -119,7 +119,7 @@ func HandleListSuccessfully(t *testing.T) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, ListOutput) + fmt.Fprint(w, ListOutput) }) } @@ -131,7 +131,7 @@ func HandleGetSuccessfully(t *testing.T) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, GetOutput) + fmt.Fprint(w, GetOutput) }) } @@ -175,7 +175,7 @@ func HandleCreateSuccessfully(t *testing.T) { w.WriteHeader(http.StatusCreated) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, CreateTransferRequestResponse) + fmt.Fprint(w, CreateTransferRequestResponse) }) } @@ -215,7 +215,7 @@ func HandleUpdateSuccessfully(t *testing.T) { w.WriteHeader(http.StatusOK) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, UpdatedTransferRequestResponse) + fmt.Fprint(w, UpdatedTransferRequestResponse) }) } diff --git a/openstack/dns/v2/zones/testing/fixtures_test.go b/openstack/dns/v2/zones/testing/fixtures_test.go index d7d9120643..6b0ee7ccf7 100644 --- a/openstack/dns/v2/zones/testing/fixtures_test.go +++ b/openstack/dns/v2/zones/testing/fixtures_test.go @@ -149,7 +149,7 @@ func HandleListSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, ListOutput) + fmt.Fprint(w, ListOutput) }) } @@ -160,7 +160,7 @@ func HandleGetSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, GetOutput) + fmt.Fprint(w, GetOutput) }) } @@ -212,7 +212,7 @@ func HandleCreateSuccessfully(t *testing.T) { w.WriteHeader(http.StatusCreated) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, CreateZoneResponse) + fmt.Fprint(w, CreateZoneResponse) }) } @@ -259,7 +259,7 @@ func HandleUpdateSuccessfully(t *testing.T) { w.WriteHeader(http.StatusOK) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, UpdateZoneResponse) + fmt.Fprint(w, UpdateZoneResponse) }) } @@ -297,6 +297,6 @@ func HandleDeleteSuccessfully(t *testing.T) { w.WriteHeader(http.StatusAccepted) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, DeleteZoneResponse) + fmt.Fprint(w, DeleteZoneResponse) }) } diff --git a/openstack/identity/v2/extensions/testing/fixtures_test.go b/openstack/identity/v2/extensions/testing/fixtures_test.go index 3733eba312..8e9bfa14da 100644 --- a/openstack/identity/v2/extensions/testing/fixtures_test.go +++ b/openstack/identity/v2/extensions/testing/fixtures_test.go @@ -37,7 +37,7 @@ func HandleListExtensionsSuccessfully(t *testing.T) { w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "extensions": { "values": [ diff --git a/openstack/identity/v2/roles/testing/fixtures_test.go b/openstack/identity/v2/roles/testing/fixtures_test.go index 0b5af6e541..170e80099c 100644 --- a/openstack/identity/v2/roles/testing/fixtures_test.go +++ b/openstack/identity/v2/roles/testing/fixtures_test.go @@ -17,7 +17,7 @@ func MockListRoleResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "roles": [ { diff --git a/openstack/identity/v2/tenants/testing/fixtures_test.go b/openstack/identity/v2/tenants/testing/fixtures_test.go index 7c50152faa..e7de74ccd5 100644 --- a/openstack/identity/v2/tenants/testing/fixtures_test.go +++ b/openstack/identity/v2/tenants/testing/fixtures_test.go @@ -59,7 +59,7 @@ func HandleListTenantsSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListOutput) + fmt.Fprint(w, ListOutput) }) } @@ -81,7 +81,7 @@ func mockCreateTenantResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "tenant": { "name": "new_tenant", @@ -120,7 +120,7 @@ func mockUpdateTenantResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "tenant": { "name": "new_name", @@ -141,7 +141,7 @@ func mockGetTenantResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "tenant": { "name": "new_tenant", diff --git a/openstack/identity/v2/tokens/testing/fixtures_test.go b/openstack/identity/v2/tokens/testing/fixtures_test.go index 8eb7d6f7ea..1ee6d32e75 100644 --- a/openstack/identity/v2/tokens/testing/fixtures_test.go +++ b/openstack/identity/v2/tokens/testing/fixtures_test.go @@ -152,7 +152,7 @@ func HandleTokenPost(t *testing.T, requestJSON string) { } w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, TokenCreationResponse) + fmt.Fprint(w, TokenCreationResponse) }) } @@ -165,7 +165,7 @@ func HandleTokenGet(t *testing.T, token string) { th.TestHeader(t, r, "X-Auth-Token", thclient.TokenID) w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, TokenGetResponse) + fmt.Fprint(w, TokenGetResponse) }) } diff --git a/openstack/identity/v2/users/testing/fixtures_test.go b/openstack/identity/v2/users/testing/fixtures_test.go index f38f05dba2..3e5285360b 100644 --- a/openstack/identity/v2/users/testing/fixtures_test.go +++ b/openstack/identity/v2/users/testing/fixtures_test.go @@ -17,7 +17,7 @@ func MockListUserResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "users":[ { @@ -61,7 +61,7 @@ func mockCreateUserResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "user": { "name": "new_user", @@ -83,7 +83,7 @@ func mockGetUserResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "user": { "name": "new_user", @@ -115,7 +115,7 @@ func mockUpdateUserResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "user": { "name": "new_name", @@ -145,7 +145,7 @@ func mockListRolesResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "roles": [ { diff --git a/openstack/identity/v3/applicationcredentials/testing/fixtures_test.go b/openstack/identity/v3/applicationcredentials/testing/fixtures_test.go index fabb021a0c..ae06c1bc57 100644 --- a/openstack/identity/v3/applicationcredentials/testing/fixtures_test.go +++ b/openstack/identity/v3/applicationcredentials/testing/fixtures_test.go @@ -415,7 +415,7 @@ func HandleListApplicationCredentialsSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListOutput) + fmt.Fprint(w, ListOutput) }) } @@ -429,7 +429,7 @@ func HandleGetApplicationCredentialSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, GetOutput) + fmt.Fprint(w, GetOutput) }) } @@ -442,7 +442,7 @@ func HandleCreateApplicationCredentialSuccessfully(t *testing.T) { th.TestJSONRequest(t, r, CreateRequest) w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, CreateResponse) + fmt.Fprint(w, CreateResponse) }) } @@ -455,7 +455,7 @@ func HandleCreateNoSecretApplicationCredentialSuccessfully(t *testing.T) { th.TestJSONRequest(t, r, CreateNoSecretRequest) w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, CreateNoSecretResponse) + fmt.Fprint(w, CreateNoSecretResponse) }) } @@ -466,7 +466,7 @@ func HandleCreateUnrestrictedApplicationCredentialSuccessfully(t *testing.T) { th.TestJSONRequest(t, r, CreateUnrestrictedRequest) w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, CreateUnrestrictedResponse) + fmt.Fprint(w, CreateUnrestrictedResponse) }) } @@ -491,7 +491,7 @@ func HandleListAccessRulesSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListAccessRulesOutput) + fmt.Fprint(w, ListAccessRulesOutput) }) } @@ -505,7 +505,7 @@ func HandleGetAccessRuleSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, GetAccessRuleOutput) + fmt.Fprint(w, GetAccessRuleOutput) }) } diff --git a/openstack/identity/v3/catalog/testing/fixtures_test.go b/openstack/identity/v3/catalog/testing/fixtures_test.go index 541fcac4af..ad9e9d9ce2 100644 --- a/openstack/identity/v3/catalog/testing/fixtures_test.go +++ b/openstack/identity/v3/catalog/testing/fixtures_test.go @@ -85,6 +85,6 @@ func HandleListCatalogSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - _, _ = fmt.Fprintf(w, ListOutput) + _, _ = fmt.Fprint(w, ListOutput) }) } diff --git a/openstack/identity/v3/credentials/testing/fixtures_test.go b/openstack/identity/v3/credentials/testing/fixtures_test.go index 8da4769ed6..e32d77d0db 100644 --- a/openstack/identity/v3/credentials/testing/fixtures_test.go +++ b/openstack/identity/v3/credentials/testing/fixtures_test.go @@ -161,7 +161,7 @@ func HandleListCredentialsSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListOutput) + fmt.Fprint(w, ListOutput) }) } @@ -175,7 +175,7 @@ func HandleGetCredentialSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, GetOutput) + fmt.Fprint(w, GetOutput) }) } @@ -188,7 +188,7 @@ func HandleCreateCredentialSuccessfully(t *testing.T) { th.TestJSONRequest(t, r, CreateRequest) w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, GetOutput) + fmt.Fprint(w, GetOutput) }) } @@ -212,6 +212,6 @@ func HandleUpdateCredentialSuccessfully(t *testing.T) { th.TestJSONRequest(t, r, UpdateRequest) w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, UpdateOutput) + fmt.Fprint(w, UpdateOutput) }) } diff --git a/openstack/identity/v3/domains/testing/fixtures_test.go b/openstack/identity/v3/domains/testing/fixtures_test.go index f5025a15c8..a35813a23c 100644 --- a/openstack/identity/v3/domains/testing/fixtures_test.go +++ b/openstack/identity/v3/domains/testing/fixtures_test.go @@ -189,7 +189,7 @@ func HandleListAvailableDomainsSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListAvailableOutput) + fmt.Fprint(w, ListAvailableOutput) }) } @@ -203,7 +203,7 @@ func HandleListDomainsSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListOutput) + fmt.Fprint(w, ListOutput) }) } @@ -217,7 +217,7 @@ func HandleGetDomainSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, GetOutput) + fmt.Fprint(w, GetOutput) }) } @@ -230,7 +230,7 @@ func HandleCreateDomainSuccessfully(t *testing.T) { th.TestJSONRequest(t, r, CreateRequest) w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, GetOutput) + fmt.Fprint(w, GetOutput) }) } @@ -254,6 +254,6 @@ func HandleUpdateDomainSuccessfully(t *testing.T) { th.TestJSONRequest(t, r, UpdateRequest) w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, UpdateOutput) + fmt.Fprint(w, UpdateOutput) }) } diff --git a/openstack/identity/v3/ec2credentials/testing/fixtures_test.go b/openstack/identity/v3/ec2credentials/testing/fixtures_test.go index 738161477d..72a82e1ff4 100644 --- a/openstack/identity/v3/ec2credentials/testing/fixtures_test.go +++ b/openstack/identity/v3/ec2credentials/testing/fixtures_test.go @@ -119,7 +119,7 @@ func HandleListEC2CredentialsSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListOutput) + fmt.Fprint(w, ListOutput) }) } @@ -133,7 +133,7 @@ func HandleGetEC2CredentialSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, GetOutput) + fmt.Fprint(w, GetOutput) }) } @@ -146,7 +146,7 @@ func HandleCreateEC2CredentialSuccessfully(t *testing.T) { th.TestJSONRequest(t, r, CreateRequest) w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, CreateResponse) + fmt.Fprint(w, CreateResponse) }) } diff --git a/openstack/identity/v3/ec2tokens/testing/requests_test.go b/openstack/identity/v3/ec2tokens/testing/requests_test.go index 13239e2d91..8fe0b3c3f8 100644 --- a/openstack/identity/v3/ec2tokens/testing/requests_test.go +++ b/openstack/identity/v3/ec2tokens/testing/requests_test.go @@ -32,7 +32,7 @@ func authTokenPost(t *testing.T, options ec2tokens.AuthOptions, requestJSON stri th.TestJSONRequest(t, r, requestJSON) w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, tokens_testing.TokenOutput) + fmt.Fprint(w, tokens_testing.TokenOutput) }) expected := &tokens.Token{ diff --git a/openstack/identity/v3/endpoints/testing/requests_test.go b/openstack/identity/v3/endpoints/testing/requests_test.go index 8ea857bad4..348a1f1c6e 100644 --- a/openstack/identity/v3/endpoints/testing/requests_test.go +++ b/openstack/identity/v3/endpoints/testing/requests_test.go @@ -33,7 +33,7 @@ func TestCreateSuccessful(t *testing.T) { `) w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "endpoint": { "id": "12", @@ -82,7 +82,7 @@ func TestListEndpoints(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "endpoints": [ { @@ -170,7 +170,7 @@ func TestUpdateEndpoint(t *testing.T) { } `) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "endpoint": { "id": "12", diff --git a/openstack/identity/v3/federation/testing/fixtures_test.go b/openstack/identity/v3/federation/testing/fixtures_test.go index 225cc57997..229d2f489a 100644 --- a/openstack/identity/v3/federation/testing/fixtures_test.go +++ b/openstack/identity/v3/federation/testing/fixtures_test.go @@ -289,7 +289,7 @@ func HandleListMappingsSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListOutput) + fmt.Fprint(w, ListOutput) }) } @@ -302,7 +302,7 @@ func HandleCreateMappingSuccessfully(t *testing.T) { th.TestJSONRequest(t, r, CreateRequest) w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, CreateOutput) + fmt.Fprint(w, CreateOutput) }) } @@ -316,7 +316,7 @@ func HandleGetMappingSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, GetOutput) + fmt.Fprint(w, GetOutput) }) } @@ -329,7 +329,7 @@ func HandleUpdateMappingSuccessfully(t *testing.T) { th.TestJSONRequest(t, r, UpdateRequest) w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, UpdateOutput) + fmt.Fprint(w, UpdateOutput) }) } diff --git a/openstack/identity/v3/groups/testing/fixtures_test.go b/openstack/identity/v3/groups/testing/fixtures_test.go index 0357a1fe06..415d81555f 100644 --- a/openstack/identity/v3/groups/testing/fixtures_test.go +++ b/openstack/identity/v3/groups/testing/fixtures_test.go @@ -160,7 +160,7 @@ func HandleListGroupsSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListOutput) + fmt.Fprint(w, ListOutput) }) } @@ -174,7 +174,7 @@ func HandleGetGroupSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, GetOutput) + fmt.Fprint(w, GetOutput) }) } @@ -187,7 +187,7 @@ func HandleCreateGroupSuccessfully(t *testing.T) { th.TestJSONRequest(t, r, CreateRequest) w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, GetOutput) + fmt.Fprint(w, GetOutput) }) } @@ -200,7 +200,7 @@ func HandleUpdateGroupSuccessfully(t *testing.T) { th.TestJSONRequest(t, r, UpdateRequest) w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, UpdateOutput) + fmt.Fprint(w, UpdateOutput) }) } diff --git a/openstack/identity/v3/limits/testing/fixtures_test.go b/openstack/identity/v3/limits/testing/fixtures_test.go index 6275235b54..5f8cbff160 100644 --- a/openstack/identity/v3/limits/testing/fixtures_test.go +++ b/openstack/identity/v3/limits/testing/fixtures_test.go @@ -183,7 +183,7 @@ func HandleGetEnforcementModelSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, GetEnforcementModelOutput) + fmt.Fprint(w, GetEnforcementModelOutput) }) } @@ -197,7 +197,7 @@ func HandleListLimitsSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListOutput) + fmt.Fprint(w, ListOutput) }) } @@ -210,7 +210,7 @@ func HandleCreateLimitSuccessfully(t *testing.T) { th.TestJSONRequest(t, r, CreateRequest) w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, CreateOutput) + fmt.Fprint(w, CreateOutput) }) } @@ -224,7 +224,7 @@ func HandleGetLimitSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, GetOutput) + fmt.Fprint(w, GetOutput) }) } @@ -237,7 +237,7 @@ func HandleUpdateLimitSuccessfully(t *testing.T) { th.TestJSONRequest(t, r, UpdateRequest) w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, UpdateOutput) + fmt.Fprint(w, UpdateOutput) }) } diff --git a/openstack/identity/v3/oauth1/testing/fixtures_test.go b/openstack/identity/v3/oauth1/testing/fixtures_test.go index 3e8d144047..b8d5dc3327 100644 --- a/openstack/identity/v3/oauth1/testing/fixtures_test.go +++ b/openstack/identity/v3/oauth1/testing/fixtures_test.go @@ -228,7 +228,7 @@ func HandleCreateConsumer(t *testing.T) { th.TestJSONRequest(t, r, CreateConsumerRequest) w.WriteHeader(http.StatusCreated) - _, err := fmt.Fprintf(w, CreateConsumerResponse) + _, err := fmt.Fprint(w, CreateConsumerResponse) th.AssertNoErr(t, err) }) } @@ -243,7 +243,7 @@ func HandleUpdateConsumer(t *testing.T) { th.TestJSONRequest(t, r, UpdateConsumerRequest) w.WriteHeader(http.StatusOK) - _, err := fmt.Fprintf(w, UpdateConsumerResponse) + _, err := fmt.Fprint(w, UpdateConsumerResponse) th.AssertNoErr(t, err) }) } @@ -269,7 +269,7 @@ func HandleGetConsumer(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, GetConsumerResponse) + fmt.Fprint(w, GetConsumerResponse) }) } @@ -306,7 +306,7 @@ func HandleListConsumers(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListConsumersResponse) + fmt.Fprint(w, ListConsumersResponse) }) } @@ -329,7 +329,7 @@ func HandleRequestToken(t *testing.T) { w.Header().Set("Content-Type", oauth1.OAuth1TokenContentType) w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, `oauth_token=29971f&oauth_token_secret=238eb8&oauth_expires_at=2013-09-11T06:07:51.501805Z`) + fmt.Fprint(w, `oauth_token=29971f&oauth_token_secret=238eb8&oauth_expires_at=2013-09-11T06:07:51.501805Z`) }) } @@ -343,7 +343,7 @@ func HandleAuthorizeToken(t *testing.T) { th.TestJSONRequest(t, r, AuthorizeTokenRequest) w.WriteHeader(http.StatusOK) - _, err := fmt.Fprintf(w, AuthorizeTokenResponse) + _, err := fmt.Fprint(w, AuthorizeTokenResponse) th.AssertNoErr(t, err) }) } @@ -366,7 +366,7 @@ func HandleCreateAccessToken(t *testing.T) { w.Header().Set("Content-Type", oauth1.OAuth1TokenContentType) w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, `oauth_token=accd36&oauth_token_secret=aa47da&oauth_expires_at=2013-09-11T06:07:51.501805Z`) + fmt.Fprint(w, `oauth_token=accd36&oauth_token_secret=aa47da&oauth_expires_at=2013-09-11T06:07:51.501805Z`) }) } @@ -380,7 +380,7 @@ func HandleGetAccessToken(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, GetUserAccessTokenResponse) + fmt.Fprint(w, GetUserAccessTokenResponse) }) } @@ -405,7 +405,7 @@ func HandleListAccessTokens(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListUserAccessTokensResponse) + fmt.Fprint(w, ListUserAccessTokensResponse) }) } @@ -419,7 +419,7 @@ func HandleListAccessTokenRoles(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListUserAccessTokenRolesResponse) + fmt.Fprint(w, ListUserAccessTokenRolesResponse) }) } @@ -433,7 +433,7 @@ func HandleGetAccessTokenRole(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListUserAccessTokenRoleResponse) + fmt.Fprint(w, ListUserAccessTokenRoleResponse) }) } @@ -449,6 +449,6 @@ func HandleAuthenticate(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, tokens.TokenOutput) + fmt.Fprint(w, tokens.TokenOutput) }) } diff --git a/openstack/identity/v3/policies/testing/fixtures_test.go b/openstack/identity/v3/policies/testing/fixtures_test.go index 2ebc6c6c41..d261ed865c 100644 --- a/openstack/identity/v3/policies/testing/fixtures_test.go +++ b/openstack/identity/v3/policies/testing/fixtures_test.go @@ -164,9 +164,9 @@ func HandleListPoliciesSuccessfully(t *testing.T) { w.WriteHeader(http.StatusOK) switch r.URL.Query().Get("type") { case "": - fmt.Fprintf(w, ListOutput) + fmt.Fprint(w, ListOutput) case "application/json": - fmt.Fprintf(w, ListWithFilterOutput) + fmt.Fprint(w, ListWithFilterOutput) default: w.WriteHeader(http.StatusBadRequest) } @@ -182,7 +182,7 @@ func HandleCreatePolicySuccessfully(t *testing.T) { th.TestJSONRequest(t, r, CreateRequest) w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, GetOutput) + fmt.Fprint(w, GetOutput) }) } @@ -197,7 +197,7 @@ func HandleGetPolicySuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, GetOutput) + fmt.Fprint(w, GetOutput) }, ) } @@ -212,7 +212,7 @@ func HandleUpdatePolicySuccessfully(t *testing.T) { th.TestJSONRequest(t, r, UpdateRequest) w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, UpdateOutput) + fmt.Fprint(w, UpdateOutput) }, ) } diff --git a/openstack/identity/v3/projectendpoints/testing/requests_test.go b/openstack/identity/v3/projectendpoints/testing/requests_test.go index 9a9c17139f..2e8f6aad4c 100644 --- a/openstack/identity/v3/projectendpoints/testing/requests_test.go +++ b/openstack/identity/v3/projectendpoints/testing/requests_test.go @@ -37,7 +37,7 @@ func TestListEndpoints(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "endpoints": [ { diff --git a/openstack/identity/v3/projects/testing/fixtures_test.go b/openstack/identity/v3/projects/testing/fixtures_test.go index a54edfe21f..568305008a 100644 --- a/openstack/identity/v3/projects/testing/fixtures_test.go +++ b/openstack/identity/v3/projects/testing/fixtures_test.go @@ -285,7 +285,7 @@ func HandleListAvailableProjectsSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListAvailableOutput) + fmt.Fprint(w, ListAvailableOutput) }) } @@ -299,7 +299,7 @@ func HandleListProjectsSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListOutput) + fmt.Fprint(w, ListOutput) }) } @@ -313,7 +313,7 @@ func HandleGetProjectSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, GetOutput) + fmt.Fprint(w, GetOutput) }) } @@ -326,7 +326,7 @@ func HandleCreateProjectSuccessfully(t *testing.T) { th.TestJSONRequest(t, r, CreateRequest) w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, GetOutput) + fmt.Fprint(w, GetOutput) }) } @@ -350,7 +350,7 @@ func HandleUpdateProjectSuccessfully(t *testing.T) { th.TestJSONRequest(t, r, UpdateRequest) w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, UpdateOutput) + fmt.Fprint(w, UpdateOutput) }) } @@ -360,7 +360,7 @@ func HandleListProjectTagsSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListTagsOutput) + fmt.Fprint(w, ListTagsOutput) }) } @@ -371,7 +371,7 @@ func HandleModifyProjectTagsSuccessfully(t *testing.T) { th.TestJSONRequest(t, r, ModifyProjectTagsRequest) w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ModifyProjectTagsOutput) + fmt.Fprint(w, ModifyProjectTagsOutput) }) } func HandleDeleteProjectTagsSuccessfully(t *testing.T) { diff --git a/openstack/identity/v3/regions/testing/fixtures_test.go b/openstack/identity/v3/regions/testing/fixtures_test.go index a4c3a40c38..633ae86dcb 100644 --- a/openstack/identity/v3/regions/testing/fixtures_test.go +++ b/openstack/identity/v3/regions/testing/fixtures_test.go @@ -172,7 +172,7 @@ func HandleListRegionsSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListOutput) + fmt.Fprint(w, ListOutput) }) } @@ -186,7 +186,7 @@ func HandleGetRegionSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, GetOutput) + fmt.Fprint(w, GetOutput) }) } @@ -199,7 +199,7 @@ func HandleCreateRegionSuccessfully(t *testing.T) { th.TestJSONRequest(t, r, CreateRequest) w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, GetOutput) + fmt.Fprint(w, GetOutput) }) } @@ -212,7 +212,7 @@ func HandleUpdateRegionSuccessfully(t *testing.T) { th.TestJSONRequest(t, r, UpdateRequest) w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, UpdateOutput) + fmt.Fprint(w, UpdateOutput) }) } diff --git a/openstack/identity/v3/registeredlimits/testing/fixtures_test.go b/openstack/identity/v3/registeredlimits/testing/fixtures_test.go index 37e11ed6eb..1bcfc5e867 100644 --- a/openstack/identity/v3/registeredlimits/testing/fixtures_test.go +++ b/openstack/identity/v3/registeredlimits/testing/fixtures_test.go @@ -163,7 +163,7 @@ func HandleListRegisteredLimitsSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListOutput) + fmt.Fprint(w, ListOutput) }) } @@ -177,7 +177,7 @@ func HandleGetRegisteredLimitSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, GetOutput) + fmt.Fprint(w, GetOutput) }) } @@ -190,7 +190,7 @@ func HandleCreateRegisteredLimitSuccessfully(t *testing.T) { th.TestJSONRequest(t, r, CreateRequest) w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, CreateOutput) + fmt.Fprint(w, CreateOutput) }) } @@ -214,6 +214,6 @@ func HandleUpdateRegisteredLimitSuccessfully(t *testing.T) { th.TestJSONRequest(t, r, UpdateRequest) w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, UpdateOutput) + fmt.Fprint(w, UpdateOutput) }) } diff --git a/openstack/identity/v3/roles/testing/fixtures_test.go b/openstack/identity/v3/roles/testing/fixtures_test.go index 755f14d4e8..32fe745a94 100644 --- a/openstack/identity/v3/roles/testing/fixtures_test.go +++ b/openstack/identity/v3/roles/testing/fixtures_test.go @@ -350,7 +350,7 @@ func HandleListRolesSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListOutput) + fmt.Fprint(w, ListOutput) }) } @@ -364,7 +364,7 @@ func HandleGetRoleSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, GetOutput) + fmt.Fprint(w, GetOutput) }) } @@ -377,7 +377,7 @@ func HandleCreateRoleSuccessfully(t *testing.T) { th.TestJSONRequest(t, r, CreateRequest) w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, GetOutput) + fmt.Fprint(w, GetOutput) }) } @@ -390,7 +390,7 @@ func HandleUpdateRoleSuccessfully(t *testing.T) { th.TestJSONRequest(t, r, UpdateRequest) w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, UpdateOutput) + fmt.Fprint(w, UpdateOutput) }) } @@ -499,7 +499,7 @@ func HandleListRoleAssignmentsSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListAssignmentOutput) + fmt.Fprint(w, ListAssignmentOutput) }) } @@ -514,7 +514,7 @@ func HandleListRoleAssignmentsWithNamesSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListAssignmentWithNamesOutput) + fmt.Fprint(w, ListAssignmentWithNamesOutput) }) } @@ -529,7 +529,7 @@ func HandleListRoleAssignmentsWithSubtreeSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListAssignmentOutput) + fmt.Fprint(w, ListAssignmentOutput) }) } @@ -557,7 +557,7 @@ func HandleListAssignmentsOnResourceSuccessfully_ProjectsUsers(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListAssignmentsOnResourceOutput) + fmt.Fprint(w, ListAssignmentsOnResourceOutput) } th.Mux.HandleFunc("/projects/{project_id}/users/{user_id}/roles", fn) @@ -571,7 +571,7 @@ func HandleListAssignmentsOnResourceSuccessfully_ProjectsGroups(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListAssignmentsOnResourceOutput) + fmt.Fprint(w, ListAssignmentsOnResourceOutput) } th.Mux.HandleFunc("/projects/{project_id}/groups/{group_id}/roles", fn) @@ -585,7 +585,7 @@ func HandleListAssignmentsOnResourceSuccessfully_DomainsUsers(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListAssignmentsOnResourceOutput) + fmt.Fprint(w, ListAssignmentsOnResourceOutput) } th.Mux.HandleFunc("/domains/{domain_id}/users/{user_id}/roles", fn) @@ -599,7 +599,7 @@ func HandleListAssignmentsOnResourceSuccessfully_DomainsGroups(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListAssignmentsOnResourceOutput) + fmt.Fprint(w, ListAssignmentsOnResourceOutput) } th.Mux.HandleFunc("/domains/{domain_id}/groups/{group_id}/roles", fn) @@ -635,7 +635,7 @@ func HandleCreateRoleInferenceRule(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, CreateRoleInferenceRuleOutput) + fmt.Fprint(w, CreateRoleInferenceRuleOutput) } th.Mux.HandleFunc("/roles/7ceab6192ea34a548cc71b24f72e762c/implies/97e2f5d38bc94842bc3da818c16762ed", fn) @@ -713,7 +713,7 @@ func HandleListRoleInferenceRules(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListRoleInferenceRulesOutput) + fmt.Fprint(w, ListRoleInferenceRulesOutput) } th.Mux.HandleFunc("/role_inferences", fn) @@ -737,7 +737,7 @@ func HandleGetRoleInferenceRule(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, CreateRoleInferenceRuleOutput) + fmt.Fprint(w, CreateRoleInferenceRuleOutput) } th.Mux.HandleFunc("/roles/7ceab6192ea34a548cc71b24f72e762c/implies/97e2f5d38bc94842bc3da818c16762ed", fn) diff --git a/openstack/identity/v3/services/testing/fixtures_test.go b/openstack/identity/v3/services/testing/fixtures_test.go index da713482f8..0a9274c500 100644 --- a/openstack/identity/v3/services/testing/fixtures_test.go +++ b/openstack/identity/v3/services/testing/fixtures_test.go @@ -164,7 +164,7 @@ func HandleListServicesSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListOutput) + fmt.Fprint(w, ListOutput) }) } @@ -178,7 +178,7 @@ func HandleGetServiceSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, GetOutput) + fmt.Fprint(w, GetOutput) }) } @@ -191,7 +191,7 @@ func HandleCreateServiceSuccessfully(t *testing.T) { th.TestJSONRequest(t, r, CreateRequest) w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, GetOutput) + fmt.Fprint(w, GetOutput) }) } @@ -204,6 +204,6 @@ func HandleUpdateServiceSuccessfully(t *testing.T) { th.TestJSONRequest(t, r, UpdateRequest) w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, UpdateOutput) + fmt.Fprint(w, UpdateOutput) }) } diff --git a/openstack/identity/v3/tokens/testing/requests_test.go b/openstack/identity/v3/tokens/testing/requests_test.go index c0aafb9ad4..8bb00fbffa 100644 --- a/openstack/identity/v3/tokens/testing/requests_test.go +++ b/openstack/identity/v3/tokens/testing/requests_test.go @@ -30,7 +30,7 @@ func authTokenPost(t *testing.T, options tokens.AuthOptions, scope *tokens.Scope th.TestJSONRequest(t, r, requestJSON) w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, `{ + fmt.Fprint(w, `{ "token": { "expires_at": "2014-10-02T13:45:00.000000Z" } @@ -369,7 +369,7 @@ func TestCreateUserIDPasswordTrustID(t *testing.T) { th.TestJSONRequest(t, r, requestJSON) w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, responseJSON) + fmt.Fprint(w, responseJSON) }) ao := gophercloud.AuthOptions{ @@ -525,7 +525,7 @@ func TestCreateExtractsTokenFromResponse(t *testing.T) { w.Header().Add("X-Subject-Token", "aaa111") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, `{ + fmt.Fprint(w, `{ "token": { "expires_at": "2014-10-02T13:45:00.000000Z" } @@ -670,7 +670,7 @@ func TestGetRequest(t *testing.T) { th.TestHeader(t, r, "X-Subject-Token", "abcdef12345") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "token": { "expires_at": "2014-08-29T13:10:01.000000Z" } } `) }) @@ -779,7 +779,7 @@ func TestNoTokenInResponse(t *testing.T) { th.Mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, `{}`) + fmt.Fprint(w, `{}`) }) options := tokens.AuthOptions{UserID: "me", Password: "squirrel!"} diff --git a/openstack/identity/v3/trusts/testing/fixtures_test.go b/openstack/identity/v3/trusts/testing/fixtures_test.go index 6cc9a8a7d1..3e7e77fc3c 100644 --- a/openstack/identity/v3/trusts/testing/fixtures_test.go +++ b/openstack/identity/v3/trusts/testing/fixtures_test.go @@ -207,7 +207,7 @@ func HandleCreateTrust(t *testing.T) { th.TestJSONRequest(t, r, CreateRequest) w.WriteHeader(http.StatusCreated) - _, err := fmt.Fprintf(w, CreateResponse) + _, err := fmt.Fprint(w, CreateResponse) th.AssertNoErr(t, err) }) } @@ -221,7 +221,7 @@ func HandleCreateTrustNoExpire(t *testing.T) { th.TestJSONRequest(t, r, CreateRequestNoExpire) w.WriteHeader(http.StatusCreated) - _, err := fmt.Fprintf(w, CreateResponseNoExpire) + _, err := fmt.Fprint(w, CreateResponseNoExpire) th.AssertNoErr(t, err) }) } @@ -247,7 +247,7 @@ func HandleGetTrustSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, GetResponse) + fmt.Fprint(w, GetResponse) }) } @@ -317,7 +317,7 @@ func HandleListTrustsSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListResponse) + fmt.Fprint(w, ListResponse) }) } @@ -331,7 +331,7 @@ func HandleListTrustRolesSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListTrustRolesResponse) + fmt.Fprint(w, ListTrustRolesResponse) }) } @@ -345,7 +345,7 @@ func HandleGetTrustRoleSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, GetTrustRoleResponse) + fmt.Fprint(w, GetTrustRoleResponse) }) } diff --git a/openstack/identity/v3/users/testing/fixtures_test.go b/openstack/identity/v3/users/testing/fixtures_test.go index 023124cb79..faff58d4d0 100644 --- a/openstack/identity/v3/users/testing/fixtures_test.go +++ b/openstack/identity/v3/users/testing/fixtures_test.go @@ -382,7 +382,7 @@ func HandleListUsersSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListOutput) + fmt.Fprint(w, ListOutput) }) } @@ -396,7 +396,7 @@ func HandleGetUserSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, GetOutput) + fmt.Fprint(w, GetOutput) }) } @@ -409,7 +409,7 @@ func HandleCreateUserSuccessfully(t *testing.T) { th.TestJSONRequest(t, r, CreateRequest) w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, GetOutput) + fmt.Fprint(w, GetOutput) }) } @@ -422,7 +422,7 @@ func HandleCreateNoOptionsUserSuccessfully(t *testing.T) { th.TestJSONRequest(t, r, CreateNoOptionsRequest) w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, GetOutputNoOptions) + fmt.Fprint(w, GetOutputNoOptions) }) } @@ -435,7 +435,7 @@ func HandleUpdateUserSuccessfully(t *testing.T) { th.TestJSONRequest(t, r, UpdateRequest) w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, UpdateOutput) + fmt.Fprint(w, UpdateOutput) }) } @@ -472,7 +472,7 @@ func HandleListUserGroupsSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListGroupsOutput) + fmt.Fprint(w, ListGroupsOutput) }) } @@ -519,7 +519,7 @@ func HandleListUserProjectsSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListProjectsOutput) + fmt.Fprint(w, ListProjectsOutput) }) } @@ -533,6 +533,6 @@ func HandleListInGroupSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListOutput) + fmt.Fprint(w, ListOutput) }) } diff --git a/openstack/image/v2/imageimport/testing/requests_test.go b/openstack/image/v2/imageimport/testing/requests_test.go index ae353ad0ac..74df12e548 100644 --- a/openstack/image/v2/imageimport/testing/requests_test.go +++ b/openstack/image/v2/imageimport/testing/requests_test.go @@ -22,7 +22,7 @@ func TestGet(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ImportGetResult) + fmt.Fprint(w, ImportGetResult) }) validImportMethods := []string{ @@ -49,7 +49,7 @@ func TestCreate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusAccepted) - fmt.Fprintf(w, `{}`) + fmt.Fprint(w, `{}`) }) opts := imageimport.CreateOpts{ diff --git a/openstack/image/v2/images/testing/fixtures_test.go b/openstack/image/v2/images/testing/fixtures_test.go index 0c9a7b0318..693f6b9965 100644 --- a/openstack/image/v2/images/testing/fixtures_test.go +++ b/openstack/image/v2/images/testing/fixtures_test.go @@ -130,7 +130,7 @@ func HandleImageListSuccessfully(t *testing.T) { addNext := false var imageJSON []string - fmt.Fprintf(w, `{"images": [`) + fmt.Fprint(w, `{"images": [`) for _, i := range images { if marker == "" || addNext { @@ -149,7 +149,7 @@ func HandleImageListSuccessfully(t *testing.T) { } } t.Logf("Writing out %v image(s)", len(imageJSON)) - fmt.Fprintf(w, strings.Join(imageJSON, ",")) + fmt.Fprint(w, strings.Join(imageJSON, ",")) fmt.Fprintf(w, `], "next": "/images?marker=%s&limit=%v", @@ -176,7 +176,7 @@ func HandleImageCreationSuccessfully(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, `{ + fmt.Fprint(w, `{ "status": "queued", "name": "Ubuntu 12.10", "protected": false, @@ -224,7 +224,7 @@ func HandleImageCreationSuccessfullyNulls(t *testing.T) { w.Header().Set("OpenStack-image-import-methods", "glance-direct,web-download") w.Header().Set("OpenStack-image-store-ids", "123,456") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, `{ + fmt.Fprint(w, `{ "architecture": "x86_64", "status": "queued", "name": "Ubuntu 12.10", @@ -258,7 +258,7 @@ func HandleImageGetSuccessfully(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, `{ + fmt.Fprint(w, `{ "status": "active", "name": "cirros-0.3.2-x86_64-disk", "tags": [], @@ -347,7 +347,7 @@ func HandleImageUpdateSuccessfully(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, `{ + fmt.Fprint(w, `{ "id": "da3b75d9-3f4a-40e7-8a2c-bfab23927dea", "name": "Fedora 17", "status": "active", @@ -389,7 +389,7 @@ func HandleImageListByTagsSuccessfully(t *testing.T) { w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, `{ + fmt.Fprint(w, `{ "images": [ { "status": "active", @@ -449,7 +449,7 @@ func HandleImageUpdatePropertiesSuccessfully(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, `{ + fmt.Fprint(w, `{ "id": "da3b75d9-3f4a-40e7-8a2c-bfab23927dea", "name": "Fedora 17", "status": "active", diff --git a/openstack/image/v2/members/testing/fixtures_test.go b/openstack/image/v2/members/testing/fixtures_test.go index 4100b186f4..6e0bd326e7 100644 --- a/openstack/image/v2/members/testing/fixtures_test.go +++ b/openstack/image/v2/members/testing/fixtures_test.go @@ -18,7 +18,7 @@ func HandleCreateImageMemberSuccessfully(t *testing.T) { th.TestJSONRequest(t, r, `{"member": "8989447062e04a818baf9e073fd04fa7"}`) w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, `{ + fmt.Fprint(w, `{ "created_at": "2013-09-20T19:22:19Z", "image_id": "da3b75d9-3f4a-40e7-8a2c-bfab23927dea", "member_id": "8989447062e04a818baf9e073fd04fa7", @@ -37,7 +37,7 @@ func HandleImageMemberList(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, `{ + fmt.Fprint(w, `{ "members": [ { "created_at": "2013-10-07T17:58:03Z", @@ -68,7 +68,7 @@ func HandleImageMemberEmptyList(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, `{ + fmt.Fprint(w, `{ "members": [], "schema": "/v2/schemas/members" }`) @@ -82,7 +82,7 @@ func HandleImageMemberDetails(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, `{ + fmt.Fprint(w, `{ "status": "pending", "created_at": "2013-11-26T07:21:21Z", "updated_at": "2013-11-26T07:21:21Z", @@ -120,7 +120,7 @@ func HandleImageMemberUpdate(t *testing.T) *CallsCounter { w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, `{ + fmt.Fprint(w, `{ "status": "accepted", "created_at": "2013-11-26T07:21:21Z", "updated_at": "2013-11-26T07:21:21Z", diff --git a/openstack/image/v2/tasks/testing/requests_test.go b/openstack/image/v2/tasks/testing/requests_test.go index feb74068bc..f930304427 100644 --- a/openstack/image/v2/tasks/testing/requests_test.go +++ b/openstack/image/v2/tasks/testing/requests_test.go @@ -24,7 +24,7 @@ func TestList(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, TasksListResult) + fmt.Fprint(w, TasksListResult) }) count := 0 @@ -64,7 +64,7 @@ func TestGet(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, TasksGetResult) + fmt.Fprint(w, TasksGetResult) }) s, err := tasks.Get(context.TODO(), fakeclient.ServiceClient(), "1252f636-1246-4319-bfba-c47cde0efbe0").Extract() @@ -102,7 +102,7 @@ func TestCreate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, TaskCreateResult) + fmt.Fprint(w, TaskCreateResult) }) opts := tasks.CreateOpts{ diff --git a/openstack/keymanager/v1/acls/testing/fixtures_test.go b/openstack/keymanager/v1/acls/testing/fixtures_test.go index 7db2b37b4f..89b6ea7d4d 100644 --- a/openstack/keymanager/v1/acls/testing/fixtures_test.go +++ b/openstack/keymanager/v1/acls/testing/fixtures_test.go @@ -75,7 +75,7 @@ func HandleGetSecretACLSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, GetResponse) + fmt.Fprint(w, GetResponse) }) } @@ -89,7 +89,7 @@ func HandleGetContainerACLSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, GetResponse) + fmt.Fprint(w, GetResponse) }) } @@ -102,7 +102,7 @@ func HandleSetSecretACLSuccessfully(t *testing.T) { th.TestJSONRequest(t, r, SetRequest) w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, SecretSetResponse) + fmt.Fprint(w, SecretSetResponse) }) } @@ -115,7 +115,7 @@ func HandleSetContainerACLSuccessfully(t *testing.T) { th.TestJSONRequest(t, r, SetRequest) w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ContainerSetResponse) + fmt.Fprint(w, ContainerSetResponse) }) } @@ -128,7 +128,7 @@ func HandleUpdateSecretACLSuccessfully(t *testing.T) { th.TestJSONRequest(t, r, UpdateRequest) w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, SecretSetResponse) + fmt.Fprint(w, SecretSetResponse) }) } @@ -141,7 +141,7 @@ func HandleUpdateContainerACLSuccessfully(t *testing.T) { th.TestJSONRequest(t, r, UpdateRequest) w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ContainerSetResponse) + fmt.Fprint(w, ContainerSetResponse) }) } diff --git a/openstack/keymanager/v1/containers/testing/fixtures_test.go b/openstack/keymanager/v1/containers/testing/fixtures_test.go index 4b3997f786..d290a5a9a6 100644 --- a/openstack/keymanager/v1/containers/testing/fixtures_test.go +++ b/openstack/keymanager/v1/containers/testing/fixtures_test.go @@ -235,7 +235,7 @@ func HandleListContainersSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListResponse) + fmt.Fprint(w, ListResponse) }) } @@ -249,7 +249,7 @@ func HandleGetContainerSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, GetResponse) + fmt.Fprint(w, GetResponse) }) } @@ -262,7 +262,7 @@ func HandleCreateContainerSuccessfully(t *testing.T) { th.TestJSONRequest(t, r, CreateRequest) w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, GetResponse) + fmt.Fprint(w, GetResponse) }) } @@ -288,7 +288,7 @@ func HandleListConsumersSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListConsumersResponse) + fmt.Fprint(w, ListConsumersResponse) }) } @@ -302,7 +302,7 @@ func HandleCreateConsumerSuccessfully(t *testing.T) { th.TestJSONRequest(t, r, CreateConsumerRequest) w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, CreateConsumerResponse) + fmt.Fprint(w, CreateConsumerResponse) }) } @@ -316,6 +316,6 @@ func HandleDeleteConsumerSuccessfully(t *testing.T) { th.TestJSONRequest(t, r, CreateConsumerRequest) w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, GetResponse) + fmt.Fprint(w, GetResponse) }) } diff --git a/openstack/keymanager/v1/orders/testing/fixtures_test.go b/openstack/keymanager/v1/orders/testing/fixtures_test.go index 636fe7eb3f..7eb14e0edf 100644 --- a/openstack/keymanager/v1/orders/testing/fixtures_test.go +++ b/openstack/keymanager/v1/orders/testing/fixtures_test.go @@ -143,7 +143,7 @@ func HandleListOrdersSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListResponse) + fmt.Fprint(w, ListResponse) }) } @@ -157,7 +157,7 @@ func HandleGetOrderSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, GetResponse) + fmt.Fprint(w, GetResponse) }) } @@ -170,7 +170,7 @@ func HandleCreateOrderSuccessfully(t *testing.T) { th.TestJSONRequest(t, r, CreateRequest) w.WriteHeader(http.StatusAccepted) - fmt.Fprintf(w, GetResponse) + fmt.Fprint(w, GetResponse) }) } diff --git a/openstack/keymanager/v1/secrets/testing/fixtures_test.go b/openstack/keymanager/v1/secrets/testing/fixtures_test.go index ff13102354..ed0e9ffad0 100644 --- a/openstack/keymanager/v1/secrets/testing/fixtures_test.go +++ b/openstack/keymanager/v1/secrets/testing/fixtures_test.go @@ -198,7 +198,7 @@ func HandleListSecretsSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListResponse) + fmt.Fprint(w, ListResponse) }) } @@ -212,7 +212,7 @@ func HandleGetSecretSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, GetResponse) + fmt.Fprint(w, GetResponse) }) } @@ -225,7 +225,7 @@ func HandleGetPayloadSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "text/plain") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, GetPayloadResponse) + fmt.Fprint(w, GetPayloadResponse) }) } @@ -238,7 +238,7 @@ func HandleCreateSecretSuccessfully(t *testing.T) { th.TestJSONRequest(t, r, CreateRequest) w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, CreateResponse) + fmt.Fprint(w, CreateResponse) }) } @@ -277,7 +277,7 @@ func HandleGetMetadataSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, GetMetadataResponse) + fmt.Fprint(w, GetMetadataResponse) }) } @@ -293,7 +293,7 @@ func HandleCreateMetadataSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, CreateMetadataResponse) + fmt.Fprint(w, CreateMetadataResponse) }) } @@ -308,7 +308,7 @@ func HandleGetMetadatumSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, MetadatumResponse) + fmt.Fprint(w, MetadatumResponse) }) } @@ -324,7 +324,7 @@ func HandleCreateMetadatumSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, MetadatumResponse) + fmt.Fprint(w, MetadatumResponse) }) } @@ -340,7 +340,7 @@ func HandleUpdateMetadatumSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, MetadatumResponse) + fmt.Fprint(w, MetadatumResponse) }) } diff --git a/openstack/loadbalancer/v2/amphorae/testing/fixtures_test.go b/openstack/loadbalancer/v2/amphorae/testing/fixtures_test.go index 8ffafa253e..049f0697bf 100644 --- a/openstack/loadbalancer/v2/amphorae/testing/fixtures_test.go +++ b/openstack/loadbalancer/v2/amphorae/testing/fixtures_test.go @@ -150,9 +150,9 @@ func HandleAmphoraListSuccessfully(t *testing.T) { marker := r.Form.Get("marker") switch marker { case "": - fmt.Fprintf(w, AmphoraeListBody) + fmt.Fprint(w, AmphoraeListBody) case "7f890893-ced0-46ed-8697-33415d070e5a": - fmt.Fprintf(w, `{ "amphorae": [] }`) + fmt.Fprint(w, `{ "amphorae": [] }`) default: t.Fatalf("/v2.0/octavia/amphorae invoked with unexpected marker=[%s]", marker) } @@ -166,7 +166,7 @@ func HandleAmphoraGetSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") - fmt.Fprintf(w, SingleAmphoraBody) + fmt.Fprint(w, SingleAmphoraBody) }) } diff --git a/openstack/loadbalancer/v2/apiversions/testing/fixture.go b/openstack/loadbalancer/v2/apiversions/testing/fixture.go index d21507dbab..b427378d95 100644 --- a/openstack/loadbalancer/v2/apiversions/testing/fixture.go +++ b/openstack/loadbalancer/v2/apiversions/testing/fixture.go @@ -88,6 +88,6 @@ func MockListResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, OctaviaAllAPIVersionsResponse) + fmt.Fprint(w, OctaviaAllAPIVersionsResponse) }) } diff --git a/openstack/loadbalancer/v2/flavorprofiles/testing/fixtures.go b/openstack/loadbalancer/v2/flavorprofiles/testing/fixtures.go index adbdf1b7b3..3558a21919 100644 --- a/openstack/loadbalancer/v2/flavorprofiles/testing/fixtures.go +++ b/openstack/loadbalancer/v2/flavorprofiles/testing/fixtures.go @@ -94,9 +94,9 @@ func HandleFlavorProfileListSuccessfully(t *testing.T) { marker := r.Form.Get("marker") switch marker { case "": - fmt.Fprintf(w, FlavorProfilesListBody) + fmt.Fprint(w, FlavorProfilesListBody) case "3a0d060b-fcec-4250-9ab6-940b806a12dd": - fmt.Fprintf(w, `{ "flavors": [] }`) + fmt.Fprint(w, `{ "flavors": [] }`) default: t.Fatalf("/v2.0/lbaas/flavors invoked with unexpected marker=[%s]", marker) } @@ -117,7 +117,7 @@ func HandleFlavorProfileCreationSuccessfully(t *testing.T, response string) { w.WriteHeader(http.StatusAccepted) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, response) + fmt.Fprint(w, response) }) } @@ -127,7 +127,7 @@ func HandleFlavorProfileGetSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") - fmt.Fprintf(w, SingleFlavorProfileBody) + fmt.Fprint(w, SingleFlavorProfileBody) }) } @@ -154,6 +154,6 @@ func HandleFlavorProfileUpdateSuccessfully(t *testing.T) { } }`) - fmt.Fprintf(w, PostUpdateFlavorBody) + fmt.Fprint(w, PostUpdateFlavorBody) }) } diff --git a/openstack/loadbalancer/v2/flavors/testing/fixtures.go b/openstack/loadbalancer/v2/flavors/testing/fixtures.go index a3169d7ece..1ec935c156 100644 --- a/openstack/loadbalancer/v2/flavors/testing/fixtures.go +++ b/openstack/loadbalancer/v2/flavors/testing/fixtures.go @@ -102,9 +102,9 @@ func HandleFlavorListSuccessfully(t *testing.T) { marker := r.Form.Get("marker") switch marker { case "": - fmt.Fprintf(w, FlavorsListBody) + fmt.Fprint(w, FlavorsListBody) case "3a0d060b-fcec-4250-9ab6-940b806a12dd": - fmt.Fprintf(w, `{ "flavors": [] }`) + fmt.Fprint(w, `{ "flavors": [] }`) default: t.Fatalf("/v2.0/lbaas/flavors invoked with unexpected marker=[%s]", marker) } @@ -126,7 +126,7 @@ func HandleFlavorCreationSuccessfully(t *testing.T, response string) { w.WriteHeader(http.StatusAccepted) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, response) + fmt.Fprint(w, response) }) } @@ -136,7 +136,7 @@ func HandleFlavorGetSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") - fmt.Fprintf(w, SingleFlavorBody) + fmt.Fprint(w, SingleFlavorBody) }) } @@ -163,6 +163,6 @@ func HandleFlavorUpdateSuccessfully(t *testing.T) { } }`) - fmt.Fprintf(w, PostUpdateFlavorBody) + fmt.Fprint(w, PostUpdateFlavorBody) }) } diff --git a/openstack/loadbalancer/v2/flavors/testing/requests_test.go b/openstack/loadbalancer/v2/flavors/testing/requests_test.go index fd668a2134..bc73b1271d 100644 --- a/openstack/loadbalancer/v2/flavors/testing/requests_test.go +++ b/openstack/loadbalancer/v2/flavors/testing/requests_test.go @@ -69,7 +69,7 @@ func TestListFlavorsEnabled(t *testing.T) { t.Errorf("Expected enabled=%s got %q", testCases[cases], enabled) } cases++ - fmt.Fprintf(w, `{"flavorprofiles":[]}`) + fmt.Fprint(w, `{"flavorprofiles":[]}`) }) }() diff --git a/openstack/loadbalancer/v2/l7policies/testing/fixtures_test.go b/openstack/loadbalancer/v2/l7policies/testing/fixtures_test.go index a1773287f9..56b35cd0e0 100644 --- a/openstack/loadbalancer/v2/l7policies/testing/fixtures_test.go +++ b/openstack/loadbalancer/v2/l7policies/testing/fixtures_test.go @@ -131,7 +131,7 @@ func HandleL7PolicyCreationSuccessfully(t *testing.T, response string) { w.WriteHeader(http.StatusAccepted) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, response) + fmt.Fprint(w, response) }) } @@ -218,9 +218,9 @@ func HandleL7PolicyListSuccessfully(t *testing.T) { marker := r.Form.Get("marker") switch marker { case "": - fmt.Fprintf(w, L7PoliciesListBody) + fmt.Fprint(w, L7PoliciesListBody) case "45e08a3e-a78f-4b40-a229-1e7e23eee1ab": - fmt.Fprintf(w, `{ "l7policies": [] }`) + fmt.Fprint(w, `{ "l7policies": [] }`) default: t.Fatalf("/v2.0/lbaas/l7policies invoked with unexpected marker=[%s]", marker) } @@ -234,7 +234,7 @@ func HandleL7PolicyGetSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") - fmt.Fprintf(w, SingleL7PolicyBody) + fmt.Fprint(w, SingleL7PolicyBody) }) } @@ -263,7 +263,7 @@ func HandleL7PolicyUpdateSuccessfully(t *testing.T) { } }`) - fmt.Fprintf(w, PostUpdateL7PolicyBody) + fmt.Fprint(w, PostUpdateL7PolicyBody) }) } @@ -281,7 +281,7 @@ func HandleL7PolicyUpdateNullRedirectURLSuccessfully(t *testing.T) { } }`) - fmt.Fprintf(w, PostUpdateL7PolicyNullRedirectURLBody) + fmt.Fprint(w, PostUpdateL7PolicyNullRedirectURLBody) }) } @@ -317,7 +317,7 @@ func HandleRuleCreationSuccessfully(t *testing.T, response string) { w.WriteHeader(http.StatusAccepted) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, response) + fmt.Fprint(w, response) }) } @@ -362,9 +362,9 @@ func HandleRuleListSuccessfully(t *testing.T) { marker := r.Form.Get("marker") switch marker { case "": - fmt.Fprintf(w, RulesListBody) + fmt.Fprint(w, RulesListBody) case "45e08a3e-a78f-4b40-a229-1e7e23eee1ab": - fmt.Fprintf(w, `{ "rules": [] }`) + fmt.Fprint(w, `{ "rules": [] }`) default: t.Fatalf("/v2.0/lbaas/l7policies/8a1412f0-4c32-4257-8b07-af4770b604fd/rules invoked with unexpected marker=[%s]", marker) } @@ -378,7 +378,7 @@ func HandleRuleGetSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") - fmt.Fprintf(w, SingleRuleBody) + fmt.Fprint(w, SingleRuleBody) }) } @@ -425,6 +425,6 @@ func HandleRuleUpdateSuccessfully(t *testing.T) { } }`) - fmt.Fprintf(w, PostUpdateRuleBody) + fmt.Fprint(w, PostUpdateRuleBody) }) } diff --git a/openstack/loadbalancer/v2/listeners/testing/fixtures_test.go b/openstack/loadbalancer/v2/listeners/testing/fixtures_test.go index edda9b2bac..9f85649411 100644 --- a/openstack/loadbalancer/v2/listeners/testing/fixtures_test.go +++ b/openstack/loadbalancer/v2/listeners/testing/fixtures_test.go @@ -218,9 +218,9 @@ func HandleListenerListSuccessfully(t *testing.T) { marker := r.Form.Get("marker") switch marker { case "": - fmt.Fprintf(w, ListenersListBody) + fmt.Fprint(w, ListenersListBody) case "45e08a3e-a78f-4b40-a229-1e7e23eee1ab": - fmt.Fprintf(w, `{ "listeners": [] }`) + fmt.Fprint(w, `{ "listeners": [] }`) default: t.Fatalf("/v2.0/lbaas/listeners invoked with unexpected marker=[%s]", marker) } @@ -255,7 +255,7 @@ func HandleListenerCreationSuccessfully(t *testing.T, response string) { w.WriteHeader(http.StatusAccepted) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, response) + fmt.Fprint(w, response) }) } @@ -266,7 +266,7 @@ func HandleListenerGetSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") - fmt.Fprintf(w, SingleListenerBody) + fmt.Fprint(w, SingleListenerBody) }) } @@ -304,7 +304,7 @@ func HandleListenerUpdateSuccessfully(t *testing.T) { } }`) - fmt.Fprintf(w, PostUpdateListenerBody) + fmt.Fprint(w, PostUpdateListenerBody) }) } @@ -315,6 +315,6 @@ func HandleListenerGetStatsTree(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") - fmt.Fprintf(w, GetListenerStatsBody) + fmt.Fprint(w, GetListenerStatsBody) }) } diff --git a/openstack/loadbalancer/v2/loadbalancers/testing/fixtures_test.go b/openstack/loadbalancer/v2/loadbalancers/testing/fixtures_test.go index d4f714f7c5..76ef3ec2a7 100644 --- a/openstack/loadbalancer/v2/loadbalancers/testing/fixtures_test.go +++ b/openstack/loadbalancer/v2/loadbalancers/testing/fixtures_test.go @@ -453,9 +453,9 @@ func HandleLoadbalancerListSuccessfully(t *testing.T) { marker := r.Form.Get("marker") switch marker { case "": - fmt.Fprintf(w, LoadbalancersListBody) + fmt.Fprint(w, LoadbalancersListBody) case "45e08a3e-a78f-4b40-a229-1e7e23eee1ab": - fmt.Fprintf(w, `{ "loadbalancers": [] }`) + fmt.Fprint(w, `{ "loadbalancers": [] }`) default: t.Fatalf("/v2.0/lbaas/loadbalancers invoked with unexpected marker=[%s]", marker) } @@ -533,7 +533,7 @@ func HandleFullyPopulatedLoadbalancerCreationSuccessfully(t *testing.T, response w.WriteHeader(http.StatusAccepted) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, response) + fmt.Fprint(w, response) }) } @@ -559,7 +559,7 @@ func HandleLoadbalancerCreationSuccessfully(t *testing.T, response string) { w.WriteHeader(http.StatusAccepted) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, response) + fmt.Fprint(w, response) }) } @@ -570,7 +570,7 @@ func HandleLoadbalancerGetSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") - fmt.Fprintf(w, SingleLoadbalancerBody) + fmt.Fprint(w, SingleLoadbalancerBody) }) } @@ -581,7 +581,7 @@ func HandleLoadbalancerGetStatusesTree(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") - fmt.Fprintf(w, GetLoadbalancerStatusesBody) + fmt.Fprint(w, GetLoadbalancerStatusesBody) }) } @@ -609,7 +609,7 @@ func HandleLoadbalancerUpdateSuccessfully(t *testing.T) { } }`) - fmt.Fprintf(w, PostUpdateLoadbalancerBody) + fmt.Fprint(w, PostUpdateLoadbalancerBody) }) } @@ -620,7 +620,7 @@ func HandleLoadbalancerGetStatsTree(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") - fmt.Fprintf(w, GetLoadbalancerStatsBody) + fmt.Fprint(w, GetLoadbalancerStatsBody) }) } diff --git a/openstack/loadbalancer/v2/monitors/testing/fixtures_test.go b/openstack/loadbalancer/v2/monitors/testing/fixtures_test.go index 9526b9cbca..6b12d2c11c 100644 --- a/openstack/loadbalancer/v2/monitors/testing/fixtures_test.go +++ b/openstack/loadbalancer/v2/monitors/testing/fixtures_test.go @@ -152,9 +152,9 @@ func HandleHealthmonitorListSuccessfully(t *testing.T) { marker := r.Form.Get("marker") switch marker { case "": - fmt.Fprintf(w, HealthmonitorsListBody) + fmt.Fprint(w, HealthmonitorsListBody) case "556c8345-28d8-4f84-a246-e04380b0461d": - fmt.Fprintf(w, `{ "healthmonitors": [] }`) + fmt.Fprint(w, `{ "healthmonitors": [] }`) default: t.Fatalf("/v2.0/lbaas/healthmonitors invoked with unexpected marker=[%s]", marker) } @@ -184,7 +184,7 @@ func HandleHealthmonitorCreationSuccessfully(t *testing.T, response string) { w.WriteHeader(http.StatusAccepted) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, response) + fmt.Fprint(w, response) }) } @@ -195,7 +195,7 @@ func HandleHealthmonitorGetSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") - fmt.Fprintf(w, SingleHealthmonitorBody) + fmt.Fprint(w, SingleHealthmonitorBody) }) } @@ -228,6 +228,6 @@ func HandleHealthmonitorUpdateSuccessfully(t *testing.T) { } }`) - fmt.Fprintf(w, PostUpdateHealthmonitorBody) + fmt.Fprint(w, PostUpdateHealthmonitorBody) }) } diff --git a/openstack/loadbalancer/v2/pools/testing/fixtures_test.go b/openstack/loadbalancer/v2/pools/testing/fixtures_test.go index 47d7c373f8..bcc582a638 100644 --- a/openstack/loadbalancer/v2/pools/testing/fixtures_test.go +++ b/openstack/loadbalancer/v2/pools/testing/fixtures_test.go @@ -145,9 +145,9 @@ func HandlePoolListSuccessfully(t *testing.T) { marker := r.Form.Get("marker") switch marker { case "": - fmt.Fprintf(w, PoolsListBody) + fmt.Fprint(w, PoolsListBody) case "45e08a3e-a78f-4b40-a229-1e7e23eee1ab": - fmt.Fprintf(w, `{ "pools": [] }`) + fmt.Fprint(w, `{ "pools": [] }`) default: t.Fatalf("/v2.0/lbaas/pools invoked with unexpected marker=[%s]", marker) } @@ -172,7 +172,7 @@ func HandlePoolCreationSuccessfully(t *testing.T, response string) { w.WriteHeader(http.StatusAccepted) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, response) + fmt.Fprint(w, response) }) } @@ -183,7 +183,7 @@ func HandlePoolGetSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") - fmt.Fprintf(w, SinglePoolBody) + fmt.Fprint(w, SinglePoolBody) }) } @@ -211,7 +211,7 @@ func HandlePoolUpdateSuccessfully(t *testing.T) { } }`) - fmt.Fprintf(w, PostUpdatePoolBody) + fmt.Fprint(w, PostUpdatePoolBody) }) } @@ -342,9 +342,9 @@ func HandleMemberListSuccessfully(t *testing.T) { marker := r.Form.Get("marker") switch marker { case "": - fmt.Fprintf(w, MembersListBody) + fmt.Fprint(w, MembersListBody) case "45e08a3e-a78f-4b40-a229-1e7e23eee1ab": - fmt.Fprintf(w, `{ "members": [] }`) + fmt.Fprint(w, `{ "members": [] }`) default: t.Fatalf("/v2.0/lbaas/pools/332abe93-f488-41ba-870b-2ac66be7f853/members invoked with unexpected marker=[%s]", marker) } @@ -370,7 +370,7 @@ func HandleMemberCreationSuccessfully(t *testing.T, response string) { w.WriteHeader(http.StatusAccepted) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, response) + fmt.Fprint(w, response) }) } @@ -381,7 +381,7 @@ func HandleMemberGetSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") - fmt.Fprintf(w, SingleMemberBody) + fmt.Fprint(w, SingleMemberBody) }) } @@ -409,7 +409,7 @@ func HandleMemberUpdateSuccessfully(t *testing.T) { } }`) - fmt.Fprintf(w, PostUpdateMemberBody) + fmt.Fprint(w, PostUpdateMemberBody) }) } diff --git a/openstack/loadbalancer/v2/providers/testing/fixtures_test.go b/openstack/loadbalancer/v2/providers/testing/fixtures_test.go index 64db9a39bf..b8a857e618 100644 --- a/openstack/loadbalancer/v2/providers/testing/fixtures_test.go +++ b/openstack/loadbalancer/v2/providers/testing/fixtures_test.go @@ -50,7 +50,7 @@ func HandleProviderListSuccessfully(t *testing.T) { marker := r.Form.Get("marker") switch marker { case "": - fmt.Fprintf(w, ProvidersListBody) + fmt.Fprint(w, ProvidersListBody) default: t.Fatalf("/v2.0/lbaas/providers invoked with unexpected marker=[%s]", marker) } diff --git a/openstack/loadbalancer/v2/quotas/testing/requests_test.go b/openstack/loadbalancer/v2/quotas/testing/requests_test.go index 64c819aecf..6f990428fc 100644 --- a/openstack/loadbalancer/v2/quotas/testing/requests_test.go +++ b/openstack/loadbalancer/v2/quotas/testing/requests_test.go @@ -23,7 +23,7 @@ func TestGet_1(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, GetResponseRaw_1) + fmt.Fprint(w, GetResponseRaw_1) }) q, err := quotas.Get(context.TODO(), fake.ServiceClient(), "0a73845280574ad389c292f6a74afa76").Extract() @@ -42,7 +42,7 @@ func TestGet_2(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, GetResponseRaw_2) + fmt.Fprint(w, GetResponseRaw_2) }) q, err := quotas.Get(context.TODO(), fake.ServiceClient(), "0a73845280574ad389c292f6a74afa76").Extract() @@ -61,7 +61,7 @@ func TestUpdate_1(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusAccepted) - fmt.Fprintf(w, UpdateRequestResponseRaw_1) + fmt.Fprint(w, UpdateRequestResponseRaw_1) }) q, err := quotas.Update(context.TODO(), fake.ServiceClient(), "0a73845280574ad389c292f6a74afa76", quotas.UpdateOpts{ @@ -89,7 +89,7 @@ func TestUpdate_2(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusAccepted) - fmt.Fprintf(w, UpdateRequestResponseRaw_2) + fmt.Fprint(w, UpdateRequestResponseRaw_2) }) q, err := quotas.Update(context.TODO(), fake.ServiceClient(), "0a73845280574ad389c292f6a74afa76", quotas.UpdateOpts{ diff --git a/openstack/messaging/v2/claims/testing/fixtures_test.go b/openstack/messaging/v2/claims/testing/fixtures_test.go index f713687892..5912ff64e6 100644 --- a/openstack/messaging/v2/claims/testing/fixtures_test.go +++ b/openstack/messaging/v2/claims/testing/fixtures_test.go @@ -93,7 +93,7 @@ func HandleCreateSuccessfully(t *testing.T) { w.WriteHeader(http.StatusCreated) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, CreateClaimResponse) + fmt.Fprint(w, CreateClaimResponse) }) } @@ -117,7 +117,7 @@ func HandleGetSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, GetClaimResponse) + fmt.Fprint(w, GetClaimResponse) }) } diff --git a/openstack/messaging/v2/messages/testing/fixtures_test.go b/openstack/messaging/v2/messages/testing/fixtures_test.go index a5a82db253..95cd47592b 100644 --- a/openstack/messaging/v2/messages/testing/fixtures_test.go +++ b/openstack/messaging/v2/messages/testing/fixtures_test.go @@ -229,7 +229,7 @@ func HandleCreateSuccessfully(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, CreateMessageResponse) + fmt.Fprint(w, CreateMessageResponse) }) } @@ -245,7 +245,7 @@ func HandleListSuccessfully(t *testing.T) { switch next { case fmt.Sprintf("/v2/queues/%s/messages?limit=1", QueueName): - fmt.Fprintf(w, ListMessagesResponse1) + fmt.Fprint(w, ListMessagesResponse1) case fmt.Sprintf("/v2/queues/%s/messages?marker=1", QueueName): fmt.Fprint(w, ListMessagesResponse2) case fmt.Sprintf("/v2/queues/%s/messages?marker=2", QueueName): @@ -262,7 +262,7 @@ func HandleGetMessagesSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, GetMessagesResponse) + fmt.Fprint(w, GetMessagesResponse) }) } @@ -274,7 +274,7 @@ func HandleGetSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, GetMessageResponse) + fmt.Fprint(w, GetMessageResponse) }) } @@ -299,7 +299,7 @@ func HandlePopSuccessfully(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, PopMessageResponse) + fmt.Fprint(w, PopMessageResponse) }) } diff --git a/openstack/messaging/v2/queues/testing/fixtures_test.go b/openstack/messaging/v2/queues/testing/fixtures_test.go index 2e9cf5e752..7abfdc35ba 100644 --- a/openstack/messaging/v2/queues/testing/fixtures_test.go +++ b/openstack/messaging/v2/queues/testing/fixtures_test.go @@ -226,7 +226,7 @@ func HandleListSuccessfully(t *testing.T) { switch next { case "/v2/queues?limit=1&with_count=true": - fmt.Fprintf(w, ListQueuesResponse1) + fmt.Fprint(w, ListQueuesResponse1) case "/v2/queues?marker=london": fmt.Fprint(w, ListQueuesResponse2) case "/v2/queues?marker=beijing": @@ -256,7 +256,7 @@ func HandleUpdateSuccessfully(t *testing.T) { th.TestJSONRequest(t, r, UpdateQueueRequest) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, UpdateQueueResponse) + fmt.Fprint(w, UpdateQueueResponse) }) } @@ -268,7 +268,7 @@ func HandleGetSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, GetQueueResponse) + fmt.Fprint(w, GetQueueResponse) }) } @@ -290,7 +290,7 @@ func HandleGetStatsSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, GetStatsResponse) + fmt.Fprint(w, GetStatsResponse) }) } @@ -303,7 +303,7 @@ func HandleShareSuccessfully(t *testing.T) { th.TestJSONRequest(t, r, CreateShareRequest) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, CreateShareResponse) + fmt.Fprint(w, CreateShareResponse) }) } diff --git a/openstack/networking/v2/apiversions/testing/requests_test.go b/openstack/networking/v2/apiversions/testing/requests_test.go index c99c99488b..dbdf61d9fd 100644 --- a/openstack/networking/v2/apiversions/testing/requests_test.go +++ b/openstack/networking/v2/apiversions/testing/requests_test.go @@ -23,7 +23,7 @@ func TestListVersions(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "versions": [ { @@ -96,7 +96,7 @@ func TestAPIInfo(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "resources": [ { diff --git a/openstack/networking/v2/extensions/agents/testing/requests_test.go b/openstack/networking/v2/extensions/agents/testing/requests_test.go index 070ff1b184..41380edac7 100644 --- a/openstack/networking/v2/extensions/agents/testing/requests_test.go +++ b/openstack/networking/v2/extensions/agents/testing/requests_test.go @@ -25,7 +25,7 @@ func TestList(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, AgentsListResult) + fmt.Fprint(w, AgentsListResult) }) count := 0 @@ -66,7 +66,7 @@ func TestGet(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, AgentsGetResult) + fmt.Fprint(w, AgentsGetResult) }) s, err := agents.Get(context.TODO(), fake.ServiceClient(), "43583cf5-472e-4dc8-af5b-6aed4c94ee3a").Extract() @@ -106,7 +106,7 @@ func TestUpdate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, AgentsUpdateResult) + fmt.Fprint(w, AgentsUpdateResult) }) iTrue := true @@ -149,7 +149,7 @@ func TestListDHCPNetworks(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, AgentDHCPNetworksListResult) + fmt.Fprint(w, AgentDHCPNetworksListResult) }) s, err := agents.ListDHCPNetworks(context.TODO(), fake.ServiceClient(), "43583cf5-472e-4dc8-af5b-6aed4c94ee3a").Extract() @@ -223,7 +223,7 @@ func TestListBGPSpeakers(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListBGPSpeakersResult) + fmt.Fprint(w, ListBGPSpeakersResult) }) count := 0 @@ -305,7 +305,7 @@ func TestListDRAgentHostingBGPSpeakers(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListDRAgentHostingBGPSpeakersResult) + fmt.Fprint(w, ListDRAgentHostingBGPSpeakersResult) }) count := 0 @@ -342,7 +342,7 @@ func TestListL3Routers(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, AgentL3RoutersListResult) + fmt.Fprint(w, AgentL3RoutersListResult) }) s, err := agents.ListL3Routers(context.TODO(), fake.ServiceClient(), "43583cf5-472e-4dc8-af5b-6aed4c94ee3a").Extract() diff --git a/openstack/networking/v2/extensions/attributestags/testing/requests_test.go b/openstack/networking/v2/extensions/attributestags/testing/requests_test.go index e9dc3498fb..5f20bdff5f 100644 --- a/openstack/networking/v2/extensions/attributestags/testing/requests_test.go +++ b/openstack/networking/v2/extensions/attributestags/testing/requests_test.go @@ -25,7 +25,7 @@ func TestReplaceAll(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, attributestagsReplaceAllResult) + fmt.Fprint(w, attributestagsReplaceAllResult) }) opts := attributestags.ReplaceAllOpts{ @@ -48,7 +48,7 @@ func TestList(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, attributestagsListResult) + fmt.Fprint(w, attributestagsListResult) }) res, err := attributestags.List(context.TODO(), fake.ServiceClient(), "networks", "fakeid").Extract() diff --git a/openstack/networking/v2/extensions/bgp/peers/testing/requests_test.go b/openstack/networking/v2/extensions/bgp/peers/testing/requests_test.go index 3ec3faa391..f24a0a1a0c 100644 --- a/openstack/networking/v2/extensions/bgp/peers/testing/requests_test.go +++ b/openstack/networking/v2/extensions/bgp/peers/testing/requests_test.go @@ -23,7 +23,7 @@ func TestList(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListBGPPeersResult) + fmt.Fprint(w, ListBGPPeersResult) }) count := 0 @@ -54,7 +54,7 @@ func TestGet(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, GetBGPPeerResult) + fmt.Fprint(w, GetBGPPeerResult) }) s, err := peers.Get(context.TODO(), fake.ServiceClient(), bgpPeerID).Extract() @@ -74,7 +74,7 @@ func TestCreate(t *testing.T) { th.TestJSONRequest(t, r, CreateRequest) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, CreateResponse) + fmt.Fprint(w, CreateResponse) }) var opts peers.CreateOpts @@ -124,7 +124,7 @@ func TestUpdate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, UpdateBGPPeerResponse) + fmt.Fprint(w, UpdateBGPPeerResponse) }) var opts peers.UpdateOpts diff --git a/openstack/networking/v2/extensions/bgp/speakers/testing/requests_test.go b/openstack/networking/v2/extensions/bgp/speakers/testing/requests_test.go index d163086a8a..0ace6b2403 100644 --- a/openstack/networking/v2/extensions/bgp/speakers/testing/requests_test.go +++ b/openstack/networking/v2/extensions/bgp/speakers/testing/requests_test.go @@ -23,7 +23,7 @@ func TestList(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListBGPSpeakerResult) + fmt.Fprint(w, ListBGPSpeakerResult) }) count := 0 @@ -54,7 +54,7 @@ func TestGet(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, GetBGPSpeakerResult) + fmt.Fprint(w, GetBGPSpeakerResult) }) s, err := speakers.Get(context.TODO(), fake.ServiceClient(), bgpSpeakerID).Extract() @@ -74,7 +74,7 @@ func TestCreate(t *testing.T) { th.TestJSONRequest(t, r, CreateRequest) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, CreateResponse) + fmt.Fprint(w, CreateResponse) }) opts := speakers.CreateOpts{ @@ -124,7 +124,7 @@ func TestUpdate(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, GetBGPSpeakerResult) + fmt.Fprint(w, GetBGPSpeakerResult) } else if r.Method == "PUT" { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -134,7 +134,7 @@ func TestUpdate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, UpdateBGPSpeakerResponse) + fmt.Fprint(w, UpdateBGPSpeakerResponse) } else { panic("Unexpected Request") } @@ -168,7 +168,7 @@ func TestAddBGPPeer(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, AddRemoveBGPPeerJSON) + fmt.Fprint(w, AddRemoveBGPPeerJSON) }) opts := speakers.AddBGPPeerOpts{BGPPeerID: bgpPeerID} @@ -207,7 +207,7 @@ func TestGetAdvertisedRoutes(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, GetAdvertisedRoutesResult) + fmt.Fprint(w, GetAdvertisedRoutesResult) }) count := 0 @@ -249,7 +249,7 @@ func TestAddGatewayNetwork(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, AddRemoveGatewayNetworkJSON) + fmt.Fprint(w, AddRemoveGatewayNetworkJSON) }) opts := speakers.AddGatewayNetworkOpts{NetworkID: networkID} @@ -273,7 +273,7 @@ func TestRemoveGatewayNetwork(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, "") + fmt.Fprint(w, "") }) opts := speakers.RemoveGatewayNetworkOpts{NetworkID: networkID} diff --git a/openstack/networking/v2/extensions/bgpvpns/testing/requests_test.go b/openstack/networking/v2/extensions/bgpvpns/testing/requests_test.go index 3b39e7cee0..aacc57aa90 100644 --- a/openstack/networking/v2/extensions/bgpvpns/testing/requests_test.go +++ b/openstack/networking/v2/extensions/bgpvpns/testing/requests_test.go @@ -35,7 +35,7 @@ func TestList(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListBGPVPNsResult) + fmt.Fprint(w, ListBGPVPNsResult) }) count := 0 @@ -67,7 +67,7 @@ func TestGet(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, GetBGPVPNResult) + fmt.Fprint(w, GetBGPVPNResult) }) r, err := bgpvpns.Get(context.TODO(), fake.ServiceClient(), bgpVpnID).Extract() @@ -87,7 +87,7 @@ func TestCreate(t *testing.T) { th.TestJSONRequest(t, r, CreateRequest) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, CreateResponse) + fmt.Fprint(w, CreateResponse) }) opts := bgpvpns.CreateOpts{ @@ -148,7 +148,7 @@ func TestUpdate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, UpdateBGPVPNResponse) + fmt.Fprint(w, UpdateBGPVPNResponse) }) name := "foo" @@ -186,7 +186,7 @@ func TestListNetworkAssociations(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListNetworkAssociationsResult) + fmt.Fprint(w, ListNetworkAssociationsResult) }) count := 0 @@ -223,7 +223,7 @@ func TestCreateNetworkAssociation(t *testing.T) { th.TestJSONRequest(t, r, CreateNetworkAssociationRequest) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, CreateNetworkAssociationResponse) + fmt.Fprint(w, CreateNetworkAssociationResponse) }) opts := bgpvpns.CreateNetworkAssociationOpts{ @@ -245,7 +245,7 @@ func TestGetNetworkAssociation(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, GetNetworkAssociationResult) + fmt.Fprint(w, GetNetworkAssociationResult) }) r, err := bgpvpns.GetNetworkAssociation(context.TODO(), fake.ServiceClient(), bgpVpnID, networkAssociationID).Extract() @@ -289,7 +289,7 @@ func TestListRouterAssociations(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListRouterAssociationsResult) + fmt.Fprint(w, ListRouterAssociationsResult) }) count := 0 @@ -326,7 +326,7 @@ func TestCreateRouterAssociation(t *testing.T) { th.TestJSONRequest(t, r, CreateRouterAssociationRequest) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, CreateRouterAssociationResponse) + fmt.Fprint(w, CreateRouterAssociationResponse) }) opts := bgpvpns.CreateRouterAssociationOpts{ @@ -348,7 +348,7 @@ func TestGetRouterAssociation(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, GetRouterAssociationResult) + fmt.Fprint(w, GetRouterAssociationResult) }) r, err := bgpvpns.GetRouterAssociation(context.TODO(), fake.ServiceClient(), bgpVpnID, routerAssociationID).Extract() @@ -370,7 +370,7 @@ func TestUpdateRouterAssociation(t *testing.T) { th.TestJSONRequest(t, r, UpdateRouterAssociationRequest) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, UpdateRouterAssociationResponse) + fmt.Fprint(w, UpdateRouterAssociationResponse) }) opts := bgpvpns.UpdateRouterAssociationOpts{ @@ -417,7 +417,7 @@ func TestListPortAssociations(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListPortAssociationsResult) + fmt.Fprint(w, ListPortAssociationsResult) }) count := 0 @@ -454,7 +454,7 @@ func TestCreatePortAssociation(t *testing.T) { th.TestJSONRequest(t, r, CreatePortAssociationRequest) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, CreatePortAssociationResponse) + fmt.Fprint(w, CreatePortAssociationResponse) }) opts := bgpvpns.CreatePortAssociationOpts{ @@ -476,7 +476,7 @@ func TestGetPortAssociation(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, GetPortAssociationResult) + fmt.Fprint(w, GetPortAssociationResult) }) r, err := bgpvpns.GetPortAssociation(context.TODO(), fake.ServiceClient(), bgpVpnID, portAssociationID).Extract() @@ -498,7 +498,7 @@ func TestUpdatePortAssociation(t *testing.T) { th.TestJSONRequest(t, r, UpdatePortAssociationRequest) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, UpdatePortAssociationResponse) + fmt.Fprint(w, UpdatePortAssociationResponse) }) opts := bgpvpns.UpdatePortAssociationOpts{ diff --git a/openstack/networking/v2/extensions/dns/testing/fixtures_test.go b/openstack/networking/v2/extensions/dns/testing/fixtures_test.go index 340c90083c..85679382de 100644 --- a/openstack/networking/v2/extensions/dns/testing/fixtures_test.go +++ b/openstack/networking/v2/extensions/dns/testing/fixtures_test.go @@ -78,7 +78,7 @@ func PortHandleListSuccessfully(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, porttest.ListResponse) + fmt.Fprint(w, porttest.ListResponse) }) } @@ -90,7 +90,7 @@ func PortHandleGet(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, porttest.GetResponse) + fmt.Fprint(w, porttest.GetResponse) }) } @@ -121,7 +121,7 @@ func PortHandleCreate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "port": { "status": "DOWN", @@ -184,7 +184,7 @@ func PortHandleUpdate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "port": { "status": "DOWN", @@ -229,7 +229,7 @@ func FloatingIPHandleList(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, floatingiptest.ListResponseDNS) + fmt.Fprint(w, floatingiptest.ListResponseDNS) }) } @@ -241,7 +241,7 @@ func FloatingIPHandleGet(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, fmt.Sprintf(`{"floatingip": %s}`, floatingiptest.FipDNS)) + fmt.Fprint(w, fmt.Sprintf(`{"floatingip": %s}`, floatingiptest.FipDNS)) }) } @@ -264,7 +264,7 @@ func FloatingIPHandleCreate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, fmt.Sprintf(`{"floatingip": %s}`, floatingiptest.FipDNS)) + fmt.Fprint(w, fmt.Sprintf(`{"floatingip": %s}`, floatingiptest.FipDNS)) }) } @@ -278,7 +278,7 @@ func NetworkHandleList(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, networktest.ListResponse) + fmt.Fprint(w, networktest.ListResponse) }) } @@ -290,7 +290,7 @@ func NetworkHandleGet(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, networktest.GetResponse) + fmt.Fprint(w, networktest.GetResponse) }) } @@ -304,7 +304,7 @@ func NetworkHandleCreate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, NetworkCreateResponse) + fmt.Fprint(w, NetworkCreateResponse) }) } @@ -319,6 +319,6 @@ func NetworkHandleUpdate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, NetworkUpdateResponse) + fmt.Fprint(w, NetworkUpdateResponse) }) } diff --git a/openstack/networking/v2/extensions/external/testing/results_test.go b/openstack/networking/v2/extensions/external/testing/results_test.go index 12062e53d8..bf5c02d636 100644 --- a/openstack/networking/v2/extensions/external/testing/results_test.go +++ b/openstack/networking/v2/extensions/external/testing/results_test.go @@ -24,7 +24,7 @@ func TestList(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, nettest.ListResponse) + fmt.Fprint(w, nettest.ListResponse) }) type NetworkWithExternalExt struct { @@ -54,7 +54,7 @@ func TestGet(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, nettest.GetResponse) + fmt.Fprint(w, nettest.GetResponse) }) var s struct { @@ -83,7 +83,7 @@ func TestCreate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, CreateResponse) + fmt.Fprint(w, CreateResponse) }) iTrue := true @@ -118,7 +118,7 @@ func TestUpdate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, UpdateResponse) + fmt.Fprint(w, UpdateResponse) }) iTrue := true diff --git a/openstack/networking/v2/extensions/fwaas_v2/groups/testing/requests_test.go b/openstack/networking/v2/extensions/fwaas_v2/groups/testing/requests_test.go index 59768a756d..540f80aaf4 100644 --- a/openstack/networking/v2/extensions/fwaas_v2/groups/testing/requests_test.go +++ b/openstack/networking/v2/extensions/fwaas_v2/groups/testing/requests_test.go @@ -23,7 +23,7 @@ func TestList(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "firewall_groups": [ { @@ -136,7 +136,7 @@ func TestGet(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "firewall_group": { "id": "6bfb0f10-07f7-4a40-b534-bad4b4ca3428", @@ -199,7 +199,7 @@ func TestCreate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "firewall_group": { "id": "6bfb0f10-07f7-4a40-b534-bad4b4ca3428", @@ -260,7 +260,7 @@ func TestUpdate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "firewall_group": { "id": "6bfb0f10-07f7-4a40-b534-bad4b4ca3428", @@ -319,7 +319,7 @@ func TestRemoveIngressPolicy(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "firewall_group": { "id": "6bfb0f10-07f7-4a40-b534-bad4b4ca3428", @@ -367,7 +367,7 @@ func TestRemoveEgressPolicy(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "firewall_group": { "id": "6bfb0f10-07f7-4a40-b534-bad4b4ca3428", diff --git a/openstack/networking/v2/extensions/fwaas_v2/policies/testing/requests_test.go b/openstack/networking/v2/extensions/fwaas_v2/policies/testing/requests_test.go index 3141f19795..217c062f4c 100644 --- a/openstack/networking/v2/extensions/fwaas_v2/policies/testing/requests_test.go +++ b/openstack/networking/v2/extensions/fwaas_v2/policies/testing/requests_test.go @@ -24,7 +24,7 @@ func TestList(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "firewall_policies": [ { @@ -135,7 +135,7 @@ func TestCreate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "firewall_policy":{ "name": "policy", @@ -189,7 +189,7 @@ func TestInsertRule(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "audited": false, "description": "TESTACC-DESC-8P12aLfW", @@ -252,7 +252,7 @@ func TestGet(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "firewall_policy":{ "name": "www", @@ -310,7 +310,7 @@ func TestUpdate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "firewall_policy":{ "name": "policy", @@ -377,7 +377,7 @@ func TestRemoveRule(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "audited": false, "description": "TESTACC-DESC-skno2e52", diff --git a/openstack/networking/v2/extensions/fwaas_v2/rules/testing/requests_test.go b/openstack/networking/v2/extensions/fwaas_v2/rules/testing/requests_test.go index 36469967d8..f251c563c0 100644 --- a/openstack/networking/v2/extensions/fwaas_v2/rules/testing/requests_test.go +++ b/openstack/networking/v2/extensions/fwaas_v2/rules/testing/requests_test.go @@ -24,7 +24,7 @@ func TestList(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "firewall_rules": [ { @@ -150,7 +150,7 @@ func TestCreate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "firewall_rule":{ "protocol": "tcp", @@ -215,7 +215,7 @@ func TestCreateAnyProtocol(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "firewall_rule":{ "protocol": null, @@ -264,7 +264,7 @@ func TestGet(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "firewall_rule":{ "protocol": "tcp", @@ -333,7 +333,7 @@ func TestUpdate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "firewall_rule":{ "protocol": "tcp", diff --git a/openstack/networking/v2/extensions/layer3/addressscopes/testing/requests_test.go b/openstack/networking/v2/extensions/layer3/addressscopes/testing/requests_test.go index b59bd3893d..815a0c0f08 100644 --- a/openstack/networking/v2/extensions/layer3/addressscopes/testing/requests_test.go +++ b/openstack/networking/v2/extensions/layer3/addressscopes/testing/requests_test.go @@ -23,7 +23,7 @@ func TestList(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, AddressScopesListResult) + fmt.Fprint(w, AddressScopesListResult) }) count := 0 @@ -63,7 +63,7 @@ func TestGet(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, AddressScopesGetResult) + fmt.Fprint(w, AddressScopesGetResult) }) s, err := addressscopes.Get(context.TODO(), fake.ServiceClient(), "9cc35860-522a-4d35-974d-51d4b011801e").Extract() @@ -91,7 +91,7 @@ func TestCreate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, AddressScopeCreateResult) + fmt.Fprint(w, AddressScopeCreateResult) }) opts := addressscopes.CreateOpts{ @@ -124,7 +124,7 @@ func TestUpdate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, AddressScopeUpdateResult) + fmt.Fprint(w, AddressScopeUpdateResult) }) shared := true diff --git a/openstack/networking/v2/extensions/layer3/extraroutes/testing/requests_test.go b/openstack/networking/v2/extensions/layer3/extraroutes/testing/requests_test.go index 66d08c8898..35d7516e1c 100644 --- a/openstack/networking/v2/extensions/layer3/extraroutes/testing/requests_test.go +++ b/openstack/networking/v2/extensions/layer3/extraroutes/testing/requests_test.go @@ -35,7 +35,7 @@ func TestAddExtraRoutes(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "router": { "name": "name", @@ -109,7 +109,7 @@ func TestRemoveExtraRoutes(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "router": { "name": "name", diff --git a/openstack/networking/v2/extensions/layer3/floatingips/testing/requests_test.go b/openstack/networking/v2/extensions/layer3/floatingips/testing/requests_test.go index 92830dabb4..40f5054b99 100644 --- a/openstack/networking/v2/extensions/layer3/floatingips/testing/requests_test.go +++ b/openstack/networking/v2/extensions/layer3/floatingips/testing/requests_test.go @@ -24,7 +24,7 @@ func TestList(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListResponse) + fmt.Fprint(w, ListResponse) }) count := 0 @@ -88,7 +88,7 @@ func TestInvalidNextPageURLs(t *testing.T) { th.Mux.HandleFunc("/v2.0/floatingips", func(w http.ResponseWriter, r *http.Request) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, `{"floatingips": [{}], "floatingips_links": {}}`) + fmt.Fprint(w, `{"floatingips": [{}], "floatingips_links": {}}`) }) err := floatingips.List(fake.ServiceClient(), floatingips.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { @@ -134,7 +134,7 @@ func TestCreate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "floatingip": { "router_id": "d23abc8d-2991-4a55-ba98-2aaea84cc72f", @@ -189,7 +189,7 @@ func TestCreateEmptyPort(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "floatingip": { "router_id": "d23abc8d-2991-4a55-ba98-2aaea84cc72f", @@ -243,7 +243,7 @@ func TestCreateWithSubnetID(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "floatingip": { "router_id": null, @@ -289,7 +289,7 @@ func TestGet(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "floatingip": { "floating_network_id": "90f742b1-6d17-487b-ba95-71881dbc0b64", @@ -342,7 +342,7 @@ func TestAssociate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "floatingip": { "router_id": "d23abc8d-2991-4a55-ba98-2aaea84cc72f", @@ -384,7 +384,7 @@ func TestDisassociate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "floatingip": { "router_id": "d23abc8d-2991-4a55-ba98-2aaea84cc72f", diff --git a/openstack/networking/v2/extensions/layer3/portforwarding/testing/requests_test.go b/openstack/networking/v2/extensions/layer3/portforwarding/testing/requests_test.go index c4ad108146..dc2aa8c49b 100644 --- a/openstack/networking/v2/extensions/layer3/portforwarding/testing/requests_test.go +++ b/openstack/networking/v2/extensions/layer3/portforwarding/testing/requests_test.go @@ -23,7 +23,7 @@ func TestPortForwardingList(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListResponse) + fmt.Fprint(w, ListResponse) }) count := 0 @@ -91,7 +91,7 @@ func TestCreate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "port_forwarding": { "protocol": "tcp", @@ -134,7 +134,7 @@ func TestGet(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "port_forwarding": { "protocol": "tcp", @@ -196,7 +196,7 @@ func TestUpdate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "port_forwarding": { "protocol": "udp", diff --git a/openstack/networking/v2/extensions/layer3/routers/testing/requests_test.go b/openstack/networking/v2/extensions/layer3/routers/testing/requests_test.go index 541dd656b5..6ff1242366 100644 --- a/openstack/networking/v2/extensions/layer3/routers/testing/requests_test.go +++ b/openstack/networking/v2/extensions/layer3/routers/testing/requests_test.go @@ -24,7 +24,7 @@ func TestList(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "routers": [ { @@ -156,7 +156,7 @@ func TestCreate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "router": { "status": "ACTIVE", @@ -224,7 +224,7 @@ func TestGet(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "router": { "status": "ACTIVE", @@ -301,7 +301,7 @@ func TestUpdate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "router": { "status": "ACTIVE", @@ -367,7 +367,7 @@ func TestUpdateWithoutRoutes(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "router": { "status": "ACTIVE", @@ -422,7 +422,7 @@ func TestAllRoutesRemoved(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "router": { "status": "ACTIVE", @@ -481,7 +481,7 @@ func TestAddInterface(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "subnet_id": "0d32a837-8069-4ec3-84c4-3eef3e10b188", "tenant_id": "017d8de156df4177889f31a9bd6edc00", @@ -530,7 +530,7 @@ func TestRemoveInterface(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "subnet_id": "0d32a837-8069-4ec3-84c4-3eef3e10b188", "tenant_id": "017d8de156df4177889f31a9bd6edc00", @@ -561,7 +561,7 @@ func TestListL3Agents(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "agents": [ { diff --git a/openstack/networking/v2/extensions/mtu/testing/results_test.go b/openstack/networking/v2/extensions/mtu/testing/results_test.go index 273bdb5166..916bbc00f8 100644 --- a/openstack/networking/v2/extensions/mtu/testing/results_test.go +++ b/openstack/networking/v2/extensions/mtu/testing/results_test.go @@ -29,7 +29,7 @@ func TestList(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, nettest.ListResponse) + fmt.Fprint(w, nettest.ListResponse) }) type NetworkWithMTUExt struct { @@ -59,7 +59,7 @@ func TestGet(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, nettest.GetResponse) + fmt.Fprint(w, nettest.GetResponse) }) var s NetworkMTU @@ -85,7 +85,7 @@ func TestCreate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, CreateResponse) + fmt.Fprint(w, CreateResponse) }) iTrue := true @@ -123,7 +123,7 @@ func TestUpdate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, UpdateResponse) + fmt.Fprint(w, UpdateResponse) }) iTrue := true diff --git a/openstack/networking/v2/extensions/networkipavailabilities/testing/requests_test.go b/openstack/networking/v2/extensions/networkipavailabilities/testing/requests_test.go index 86166b5e33..cdd6d8d4e2 100644 --- a/openstack/networking/v2/extensions/networkipavailabilities/testing/requests_test.go +++ b/openstack/networking/v2/extensions/networkipavailabilities/testing/requests_test.go @@ -24,7 +24,7 @@ func TestList(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, NetworkIPAvailabilityListResult) + fmt.Fprint(w, NetworkIPAvailabilityListResult) }) count := 0 @@ -65,7 +65,7 @@ func TestGet(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, NetworkIPAvailabilityGetResult) + fmt.Fprint(w, NetworkIPAvailabilityGetResult) }) s, err := networkipavailabilities.Get(context.TODO(), fake.ServiceClient(), "cf11ab78-2302-49fa-870f-851a08c7afb8").Extract() diff --git a/openstack/networking/v2/extensions/portsbinding/testing/fixtures_test.go b/openstack/networking/v2/extensions/portsbinding/testing/fixtures_test.go index 494fe49091..44e2b5db9b 100644 --- a/openstack/networking/v2/extensions/portsbinding/testing/fixtures_test.go +++ b/openstack/networking/v2/extensions/portsbinding/testing/fixtures_test.go @@ -18,7 +18,7 @@ func HandleListSuccessfully(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, porttest.ListResponse) + fmt.Fprint(w, porttest.ListResponse) }) } @@ -30,7 +30,7 @@ func HandleGet(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, porttest.GetResponse) + fmt.Fprint(w, porttest.GetResponse) }) } @@ -62,7 +62,7 @@ func HandleCreate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "port": { "status": "DOWN", @@ -120,7 +120,7 @@ func HandleUpdate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "port": { "status": "DOWN", diff --git a/openstack/networking/v2/extensions/provider/testing/results_test.go b/openstack/networking/v2/extensions/provider/testing/results_test.go index 4e21481de1..acbf9f7a1f 100644 --- a/openstack/networking/v2/extensions/provider/testing/results_test.go +++ b/openstack/networking/v2/extensions/provider/testing/results_test.go @@ -25,7 +25,7 @@ func TestList(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, nettest.ListResponse) + fmt.Fprint(w, nettest.ListResponse) }) type NetworkWithExt struct { @@ -60,7 +60,7 @@ func TestGet(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, nettest.GetResponse) + fmt.Fprint(w, nettest.GetResponse) }) var s struct { @@ -91,7 +91,7 @@ func TestCreate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, nettest.CreateResponse) + fmt.Fprint(w, nettest.CreateResponse) }) var s struct { @@ -142,7 +142,7 @@ func TestCreateWithMultipleProvider(t *testing.T) { `) w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "network": { "status": "ACTIVE", @@ -227,7 +227,7 @@ func TestUpdate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, nettest.UpdateResponse) + fmt.Fprint(w, nettest.UpdateResponse) }) var s struct { diff --git a/openstack/networking/v2/extensions/qos/policies/testing/requests_test.go b/openstack/networking/v2/extensions/qos/policies/testing/requests_test.go index 72b17e5330..4ad4cf3088 100644 --- a/openstack/networking/v2/extensions/qos/policies/testing/requests_test.go +++ b/openstack/networking/v2/extensions/qos/policies/testing/requests_test.go @@ -26,7 +26,7 @@ func TestGetPort(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - _, err := fmt.Fprintf(w, GetPortResponse) + _, err := fmt.Fprint(w, GetPortResponse) th.AssertNoErr(t, err) }) @@ -55,7 +55,7 @@ func TestCreatePort(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - _, err := fmt.Fprintf(w, CreatePortResponse) + _, err := fmt.Fprint(w, CreatePortResponse) th.AssertNoErr(t, err) }) @@ -93,7 +93,7 @@ func TestUpdatePortWithPolicy(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - _, err := fmt.Fprintf(w, UpdatePortWithPolicyResponse) + _, err := fmt.Fprint(w, UpdatePortWithPolicyResponse) th.AssertNoErr(t, err) }) @@ -131,7 +131,7 @@ func TestUpdatePortWithoutPolicy(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - _, err := fmt.Fprintf(w, UpdatePortWithoutPolicyResponse) + _, err := fmt.Fprint(w, UpdatePortWithoutPolicyResponse) th.AssertNoErr(t, err) }) @@ -166,7 +166,7 @@ func TestGetNetwork(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - _, err := fmt.Fprintf(w, GetNetworkResponse) + _, err := fmt.Fprint(w, GetNetworkResponse) th.AssertNoErr(t, err) }) @@ -195,7 +195,7 @@ func TestCreateNetwork(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - _, err := fmt.Fprintf(w, CreateNetworkResponse) + _, err := fmt.Fprint(w, CreateNetworkResponse) th.AssertNoErr(t, err) }) @@ -232,7 +232,7 @@ func TestUpdateNetworkWithPolicy(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - _, err := fmt.Fprintf(w, UpdateNetworkWithPolicyResponse) + _, err := fmt.Fprint(w, UpdateNetworkWithPolicyResponse) th.AssertNoErr(t, err) }) @@ -273,7 +273,7 @@ func TestUpdateNetworkWithoutPolicy(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - _, err := fmt.Fprintf(w, UpdateNetworkWithoutPolicyResponse) + _, err := fmt.Fprint(w, UpdateNetworkWithoutPolicyResponse) th.AssertNoErr(t, err) }) @@ -307,7 +307,7 @@ func TestListPolicies(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListPoliciesResponse) + fmt.Fprint(w, ListPoliciesResponse) }) count := 0 @@ -347,7 +347,7 @@ func TestGetPolicy(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, GetPolicyResponse) + fmt.Fprint(w, GetPolicyResponse) }) p, err := policies.Get(context.TODO(), fake.ServiceClient(), "30a57f4a-336b-4382-8275-d708babd2241").Extract() @@ -387,7 +387,7 @@ func TestCreatePolicy(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, CreatePolicyResponse) + fmt.Fprint(w, CreatePolicyResponse) }) opts := policies.CreateOpts{ @@ -425,7 +425,7 @@ func TestUpdatePolicy(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, UpdatePolicyResponse) + fmt.Fprint(w, UpdatePolicyResponse) }) shared := true diff --git a/openstack/networking/v2/extensions/qos/rules/testing/requests_test.go b/openstack/networking/v2/extensions/qos/rules/testing/requests_test.go index 4ee49605ea..20de755132 100644 --- a/openstack/networking/v2/extensions/qos/rules/testing/requests_test.go +++ b/openstack/networking/v2/extensions/qos/rules/testing/requests_test.go @@ -23,7 +23,7 @@ func TestListBandwidthLimitRule(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, BandwidthLimitRulesListResult) + fmt.Fprint(w, BandwidthLimitRulesListResult) }) count := 0 @@ -71,7 +71,7 @@ func TestGetBandwidthLimitRule(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, BandwidthLimitRulesGetResult) + fmt.Fprint(w, BandwidthLimitRulesGetResult) }) r, err := rules.GetBandwidthLimitRule(context.TODO(), fake.ServiceClient(), "501005fa-3b56-4061-aaca-3f24995112e1", "30a57f4a-336b-4382-8275-d708babd2241").ExtractBandwidthLimitRule() @@ -97,7 +97,7 @@ func TestCreateBandwidthLimitRule(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, BandwidthLimitRulesCreateResult) + fmt.Fprint(w, BandwidthLimitRulesCreateResult) }) opts := rules.CreateBandwidthLimitRuleOpts{ @@ -125,7 +125,7 @@ func TestUpdateBandwidthLimitRule(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, BandwidthLimitRulesUpdateResult) + fmt.Fprint(w, BandwidthLimitRulesUpdateResult) }) maxKBps := 500 @@ -166,7 +166,7 @@ func TestListDSCPMarkingRule(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, DSCPMarkingRulesListResult) + fmt.Fprint(w, DSCPMarkingRulesListResult) }) count := 0 @@ -212,7 +212,7 @@ func TestGetDSCPMarkingRule(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, DSCPMarkingRuleGetResult) + fmt.Fprint(w, DSCPMarkingRuleGetResult) }) r, err := rules.GetDSCPMarkingRule(context.TODO(), fake.ServiceClient(), "501005fa-3b56-4061-aaca-3f24995112e1", "30a57f4a-336b-4382-8275-d708babd2241").ExtractDSCPMarkingRule() @@ -236,7 +236,7 @@ func TestCreateDSCPMarkingRule(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, DSCPMarkingRuleCreateResult) + fmt.Fprint(w, DSCPMarkingRuleCreateResult) }) opts := rules.CreateDSCPMarkingRuleOpts{ @@ -263,7 +263,7 @@ func TestUpdateDSCPMarkingRule(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, DSCPMarkingRuleUpdateResult) + fmt.Fprint(w, DSCPMarkingRuleUpdateResult) }) dscpMark := 26 @@ -302,7 +302,7 @@ func TestListMinimumBandwidthRule(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, MinimumBandwidthRulesListResult) + fmt.Fprint(w, MinimumBandwidthRulesListResult) }) count := 0 @@ -349,7 +349,7 @@ func TestGetMinimumBandwidthRule(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, MinimumBandwidthRulesGetResult) + fmt.Fprint(w, MinimumBandwidthRulesGetResult) }) r, err := rules.GetMinimumBandwidthRule(context.TODO(), fake.ServiceClient(), "501005fa-3b56-4061-aaca-3f24995112e1", "30a57f4a-336b-4382-8275-d708babd2241").ExtractMinimumBandwidthRule() @@ -374,7 +374,7 @@ func TestCreateMinimumBandwidthRule(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, MinimumBandwidthRulesCreateResult) + fmt.Fprint(w, MinimumBandwidthRulesCreateResult) }) opts := rules.CreateMinimumBandwidthRuleOpts{ @@ -400,7 +400,7 @@ func TestUpdateMinimumBandwidthRule(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, MinimumBandwidthRulesUpdateResult) + fmt.Fprint(w, MinimumBandwidthRulesUpdateResult) }) minKBps := 500 diff --git a/openstack/networking/v2/extensions/qos/ruletypes/testing/requests_test.go b/openstack/networking/v2/extensions/qos/ruletypes/testing/requests_test.go index 74eeb49aa4..7bea9f6b66 100644 --- a/openstack/networking/v2/extensions/qos/ruletypes/testing/requests_test.go +++ b/openstack/networking/v2/extensions/qos/ruletypes/testing/requests_test.go @@ -52,7 +52,7 @@ func TestGetRuleType(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - _, err := fmt.Fprintf(w, GetRuleTypeResponse) + _, err := fmt.Fprint(w, GetRuleTypeResponse) th.AssertNoErr(t, err) }) diff --git a/openstack/networking/v2/extensions/quotas/testing/requests_test.go b/openstack/networking/v2/extensions/quotas/testing/requests_test.go index 7ed3100242..a5714d17fe 100644 --- a/openstack/networking/v2/extensions/quotas/testing/requests_test.go +++ b/openstack/networking/v2/extensions/quotas/testing/requests_test.go @@ -23,7 +23,7 @@ func TestGet(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, GetResponseRaw) + fmt.Fprint(w, GetResponseRaw) }) q, err := quotas.Get(context.TODO(), fake.ServiceClient(), "0a73845280574ad389c292f6a74afa76").Extract() @@ -42,7 +42,7 @@ func TestGetDetail(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, GetDetailedResponseRaw) + fmt.Fprint(w, GetDetailedResponseRaw) }) q, err := quotas.GetDetail(context.TODO(), fake.ServiceClient(), "0a73845280574ad389c292f6a74afa76").Extract() @@ -61,7 +61,7 @@ func TestUpdate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, UpdateRequestResponseRaw) + fmt.Fprint(w, UpdateRequestResponseRaw) }) q, err := quotas.Update(context.TODO(), fake.ServiceClient(), "0a73845280574ad389c292f6a74afa76", quotas.UpdateOpts{ diff --git a/openstack/networking/v2/extensions/rbacpolicies/testing/requests_test.go b/openstack/networking/v2/extensions/rbacpolicies/testing/requests_test.go index 7503bc7a74..9fc04412f4 100644 --- a/openstack/networking/v2/extensions/rbacpolicies/testing/requests_test.go +++ b/openstack/networking/v2/extensions/rbacpolicies/testing/requests_test.go @@ -25,7 +25,7 @@ func TestCreate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, CreateResponse) + fmt.Fprint(w, CreateResponse) }) options := rbacpolicies.CreateOpts{ @@ -51,7 +51,7 @@ func TestGet(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, GetResponse) + fmt.Fprint(w, GetResponse) }) n, err := rbacpolicies.Get(context.TODO(), fake.ServiceClient(), "2cf7523a-93b5-4e69-9360-6c6bf986bb7c").Extract() @@ -70,7 +70,7 @@ func TestList(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListResponse) + fmt.Fprint(w, ListResponse) }) client := fake.ServiceClient() @@ -106,7 +106,7 @@ func TestListWithAllPages(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListResponse) + fmt.Fprint(w, ListResponse) }) client := fake.ServiceClient() @@ -159,7 +159,7 @@ func TestUpdate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, UpdateResponse) + fmt.Fprint(w, UpdateResponse) }) options := rbacpolicies.UpdateOpts{TargetTenant: "9d766060b6354c9e8e2da44cab0e8f38"} diff --git a/openstack/networking/v2/extensions/security/groups/testing/requests_test.go b/openstack/networking/v2/extensions/security/groups/testing/requests_test.go index 30c3ab6359..f816f0d6d2 100644 --- a/openstack/networking/v2/extensions/security/groups/testing/requests_test.go +++ b/openstack/networking/v2/extensions/security/groups/testing/requests_test.go @@ -24,7 +24,7 @@ func TestList(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, SecurityGroupListResponse) + fmt.Fprint(w, SecurityGroupListResponse) }) count := 0 @@ -64,7 +64,7 @@ func TestCreate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, SecurityGroupCreateResponse) + fmt.Fprint(w, SecurityGroupCreateResponse) }) opts := groups.CreateOpts{Name: "new-webservers", Description: "security group for webservers"} @@ -87,7 +87,7 @@ func TestUpdate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, SecurityGroupUpdateResponse) + fmt.Fprint(w, SecurityGroupUpdateResponse) }) opts := groups.UpdateOpts{Name: "newer-webservers"} @@ -112,7 +112,7 @@ func TestGet(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, SecurityGroupGetResponse) + fmt.Fprint(w, SecurityGroupGetResponse) }) sg, err := groups.Get(context.TODO(), fake.ServiceClient(), "85cc3048-abc3-43cc-89b3-377341426ac5").Extract() diff --git a/openstack/networking/v2/extensions/security/rules/testing/requests_test.go b/openstack/networking/v2/extensions/security/rules/testing/requests_test.go index 40372c298a..843d7eb202 100644 --- a/openstack/networking/v2/extensions/security/rules/testing/requests_test.go +++ b/openstack/networking/v2/extensions/security/rules/testing/requests_test.go @@ -23,7 +23,7 @@ func TestList(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "security_group_rules": [ { @@ -131,7 +131,7 @@ func TestCreate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "security_group_rule": { "description": "test description of rule", @@ -190,7 +190,7 @@ func TestCreateAnyProtocol(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "security_group_rule": { "description": "test description of rule", @@ -252,7 +252,7 @@ func TestGet(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "security_group_rule": { "direction": "egress", diff --git a/openstack/networking/v2/extensions/subnetpools/testing/requests_test.go b/openstack/networking/v2/extensions/subnetpools/testing/requests_test.go index 50f479b9d1..2d8df70180 100644 --- a/openstack/networking/v2/extensions/subnetpools/testing/requests_test.go +++ b/openstack/networking/v2/extensions/subnetpools/testing/requests_test.go @@ -24,7 +24,7 @@ func TestList(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, SubnetPoolsListResult) + fmt.Fprint(w, SubnetPoolsListResult) }) count := 0 @@ -66,7 +66,7 @@ func TestGet(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, SubnetPoolGetResult) + fmt.Fprint(w, SubnetPoolGetResult) }) s, err := subnetpools.Get(context.TODO(), fake.ServiceClient(), "0a738452-8057-4ad3-89c2-92f6a74afa76").Extract() @@ -106,7 +106,7 @@ func TestCreate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, SubnetPoolCreateResult) + fmt.Fprint(w, SubnetPoolCreateResult) }) opts := subnetpools.CreateOpts{ @@ -148,7 +148,7 @@ func TestUpdate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, SubnetPoolUpdateResponse) + fmt.Fprint(w, SubnetPoolUpdateResponse) }) nullString := "" diff --git a/openstack/networking/v2/extensions/testing/delegate_test.go b/openstack/networking/v2/extensions/testing/delegate_test.go index eb130cd4b0..9f3421f272 100644 --- a/openstack/networking/v2/extensions/testing/delegate_test.go +++ b/openstack/networking/v2/extensions/testing/delegate_test.go @@ -23,7 +23,7 @@ func TestList(t *testing.T) { w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "extensions": [ { @@ -83,7 +83,7 @@ func TestGet(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "extension": { "updated": "2013-02-03T10:00:00-00:00", diff --git a/openstack/networking/v2/extensions/trunks/testing/requests_test.go b/openstack/networking/v2/extensions/trunks/testing/requests_test.go index bc4a2341ab..81e6bef8c2 100644 --- a/openstack/networking/v2/extensions/trunks/testing/requests_test.go +++ b/openstack/networking/v2/extensions/trunks/testing/requests_test.go @@ -25,7 +25,7 @@ func TestCreate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, CreateResponse) + fmt.Fprint(w, CreateResponse) }) iTrue := true @@ -73,7 +73,7 @@ func TestCreateNoSubports(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, CreateNoSubportsResponse) + fmt.Fprint(w, CreateNoSubportsResponse) }) iTrue := true @@ -115,7 +115,7 @@ func TestList(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListResponse) + fmt.Fprint(w, ListResponse) }) client := fake.ServiceClient() @@ -153,7 +153,7 @@ func TestGet(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, GetResponse) + fmt.Fprint(w, GetResponse) }) n, err := trunks.Get(context.TODO(), fake.ServiceClient(), "f6a9718c-5a64-43e3-944f-4deccad8e78c").Extract() @@ -177,7 +177,7 @@ func TestUpdate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, UpdateResponse) + fmt.Fprint(w, UpdateResponse) }) iFalse := false @@ -207,7 +207,7 @@ func TestGetSubports(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListSubportsResponse) + fmt.Fprint(w, ListSubportsResponse) }) client := fake.ServiceClient() @@ -259,7 +259,7 @@ func TestAddSubports(t *testing.T) { th.TestJSONRequest(t, r, AddSubportsRequest) w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, AddSubportsResponse) + fmt.Fprint(w, AddSubportsResponse) }) client := fake.ServiceClient() @@ -287,7 +287,7 @@ func TestRemoveSubports(t *testing.T) { th.TestJSONRequest(t, r, RemoveSubportsRequest) w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, RemoveSubportsResponse) + fmt.Fprint(w, RemoveSubportsResponse) }) client := fake.ServiceClient() diff --git a/openstack/networking/v2/extensions/vlantransparent/testing/requests_test.go b/openstack/networking/v2/extensions/vlantransparent/testing/requests_test.go index d298894de7..dc5d55043a 100644 --- a/openstack/networking/v2/extensions/vlantransparent/testing/requests_test.go +++ b/openstack/networking/v2/extensions/vlantransparent/testing/requests_test.go @@ -23,7 +23,7 @@ func TestList(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, NetworksVLANTransparentListResult) + fmt.Fprint(w, NetworksVLANTransparentListResult) }) type networkVLANTransparentExt struct { @@ -59,7 +59,7 @@ func TestGet(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, NetworksVLANTransparentGetResult) + fmt.Fprint(w, NetworksVLANTransparentGetResult) }) var s struct { @@ -94,7 +94,7 @@ func TestCreate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, NetworksVLANTransparentCreateResult) + fmt.Fprint(w, NetworksVLANTransparentCreateResult) }) iTrue := true @@ -139,7 +139,7 @@ func TestUpdate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, NetworksVLANTransparentUpdateResult) + fmt.Fprint(w, NetworksVLANTransparentUpdateResult) }) iFalse := false diff --git a/openstack/networking/v2/extensions/vpnaas/endpointgroups/testing/requests_test.go b/openstack/networking/v2/extensions/vpnaas/endpointgroups/testing/requests_test.go index 806580dd4e..dbf3ba515e 100644 --- a/openstack/networking/v2/extensions/vpnaas/endpointgroups/testing/requests_test.go +++ b/openstack/networking/v2/extensions/vpnaas/endpointgroups/testing/requests_test.go @@ -36,7 +36,7 @@ func TestCreate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "endpoint_group": { "description": "", @@ -90,7 +90,7 @@ func TestGet(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "endpoint_group": { "description": "", @@ -135,7 +135,7 @@ func TestList(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "endpoint_groups": [ { @@ -224,7 +224,7 @@ func TestUpdate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "endpoint_group": { "description": "updated description", diff --git a/openstack/networking/v2/extensions/vpnaas/ikepolicies/testing/requests_test.go b/openstack/networking/v2/extensions/vpnaas/ikepolicies/testing/requests_test.go index 74b9427cc1..e8e63dfde7 100644 --- a/openstack/networking/v2/extensions/vpnaas/ikepolicies/testing/requests_test.go +++ b/openstack/networking/v2/extensions/vpnaas/ikepolicies/testing/requests_test.go @@ -35,7 +35,7 @@ func TestCreate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "ikepolicy":{ "name": "policy", @@ -97,7 +97,7 @@ func TestGet(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "ikepolicy":{ "name": "policy", @@ -165,7 +165,7 @@ func TestList(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "ikepolicies": [ { @@ -253,7 +253,7 @@ func TestUpdate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "ikepolicy": { "name": "updatedname", diff --git a/openstack/networking/v2/extensions/vpnaas/ipsecpolicies/testing/requests_test.go b/openstack/networking/v2/extensions/vpnaas/ipsecpolicies/testing/requests_test.go index 0363c7c63e..35c09a4ad5 100644 --- a/openstack/networking/v2/extensions/vpnaas/ipsecpolicies/testing/requests_test.go +++ b/openstack/networking/v2/extensions/vpnaas/ipsecpolicies/testing/requests_test.go @@ -41,7 +41,7 @@ func TestCreate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "ipsecpolicy": { "name": "ipsecpolicy1", @@ -111,7 +111,7 @@ func TestGet(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "ipsecpolicy": { "name": "ipsecpolicy1", @@ -180,7 +180,7 @@ func TestList(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "ipsecpolicies": [ { @@ -268,7 +268,7 @@ func TestUpdate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "ipsecpolicy": { diff --git a/openstack/networking/v2/extensions/vpnaas/services/testing/requests_test.go b/openstack/networking/v2/extensions/vpnaas/services/testing/requests_test.go index ce9e50171e..c0a33e8d0f 100644 --- a/openstack/networking/v2/extensions/vpnaas/services/testing/requests_test.go +++ b/openstack/networking/v2/extensions/vpnaas/services/testing/requests_test.go @@ -36,7 +36,7 @@ func TestCreate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "vpnservice": { "router_id": "66e3b16c-8ce5-40fb-bb49-ab6d8dc3f2aa", @@ -91,7 +91,7 @@ func TestList(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "vpnservices":[ { @@ -154,7 +154,7 @@ func TestGet(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "vpnservice": { "router_id": "66e3b16c-8ce5-40fb-bb49-ab6d8dc3f2aa", @@ -223,7 +223,7 @@ func TestUpdate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "vpnservice": { "router_id": "66e3b16c-8ce5-40fb-bb49-ab6d8dc3f2aa", diff --git a/openstack/networking/v2/extensions/vpnaas/siteconnections/testing/requests_test.go b/openstack/networking/v2/extensions/vpnaas/siteconnections/testing/requests_test.go index 68977acee4..58279b75d5 100644 --- a/openstack/networking/v2/extensions/vpnaas/siteconnections/testing/requests_test.go +++ b/openstack/networking/v2/extensions/vpnaas/siteconnections/testing/requests_test.go @@ -45,7 +45,7 @@ func TestCreate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "ipsec_site_connection": { "status": "PENDING_CREATE", @@ -150,7 +150,7 @@ func TestGet(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "ipsec_site_connection": { "status": "PENDING_CREATE", @@ -227,7 +227,7 @@ func TestList(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "ipsec_site_connections":[ { @@ -336,7 +336,7 @@ func TestUpdate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "ipsec_site_connection": { diff --git a/openstack/networking/v2/networks/testing/requests_test.go b/openstack/networking/v2/networks/testing/requests_test.go index c28dd2ed0f..f4e905a64f 100644 --- a/openstack/networking/v2/networks/testing/requests_test.go +++ b/openstack/networking/v2/networks/testing/requests_test.go @@ -25,7 +25,7 @@ func TestList(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListResponse) + fmt.Fprint(w, ListResponse) }) client := fake.ServiceClient() @@ -62,7 +62,7 @@ func TestListWithExtensions(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListResponse) + fmt.Fprint(w, ListResponse) }) client := fake.ServiceClient() @@ -101,7 +101,7 @@ func TestGet(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, GetResponse) + fmt.Fprint(w, GetResponse) }) n, err := networks.Get(context.TODO(), fake.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22").Extract() @@ -122,7 +122,7 @@ func TestGetWithExtensions(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, GetResponse) + fmt.Fprint(w, GetResponse) }) var networkWithExtensions struct { @@ -150,7 +150,7 @@ func TestCreate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, CreateResponse) + fmt.Fprint(w, CreateResponse) }) iTrue := true @@ -176,7 +176,7 @@ func TestCreateWithOptionalFields(t *testing.T) { th.TestJSONRequest(t, r, CreateOptionalFieldsRequest) w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, `{}`) + fmt.Fprint(w, `{}`) }) iTrue := true @@ -205,7 +205,7 @@ func TestUpdate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, UpdateResponse) + fmt.Fprint(w, UpdateResponse) }) iTrue, iFalse := true, false @@ -237,7 +237,7 @@ func TestUpdateRevision(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, UpdateResponse) + fmt.Fprint(w, UpdateResponse) }) th.Mux.HandleFunc("/v2.0/networks/4e8e5957-649f-477b-9e5b-f1f75b21c03d", func(w http.ResponseWriter, r *http.Request) { @@ -251,7 +251,7 @@ func TestUpdateRevision(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, UpdateResponse) + fmt.Fprint(w, UpdateResponse) }) iTrue, iFalse := true, false @@ -293,7 +293,7 @@ func TestCreatePortSecurity(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, CreatePortSecurityResponse) + fmt.Fprint(w, CreatePortSecurityResponse) }) var networkWithExtensions struct { @@ -330,7 +330,7 @@ func TestUpdatePortSecurity(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, UpdatePortSecurityResponse) + fmt.Fprint(w, UpdatePortSecurityResponse) }) var networkWithExtensions struct { diff --git a/openstack/networking/v2/ports/testing/requests_test.go b/openstack/networking/v2/ports/testing/requests_test.go index 7c3569b70b..1b77780610 100644 --- a/openstack/networking/v2/ports/testing/requests_test.go +++ b/openstack/networking/v2/ports/testing/requests_test.go @@ -27,7 +27,7 @@ func TestList(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListResponse) + fmt.Fprint(w, ListResponse) }) count := 0 @@ -86,7 +86,7 @@ func TestListWithExtensions(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListResponse) + fmt.Fprint(w, ListResponse) }) type portWithExt struct { @@ -117,7 +117,7 @@ func TestGet(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, GetResponse) + fmt.Fprint(w, GetResponse) }) n, err := ports.Get(context.TODO(), fake.ServiceClient(), "46d4bfb9-b26e-41f3-bd2e-e6dcc1ccedb2").Extract() @@ -152,7 +152,7 @@ func TestGetWithExtensions(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, GetResponse) + fmt.Fprint(w, GetResponse) }) var portWithExtensions struct { @@ -181,7 +181,7 @@ func TestCreate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, CreateResponse) + fmt.Fprint(w, CreateResponse) }) asu := true @@ -231,7 +231,7 @@ func TestCreateOmitSecurityGroups(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, CreateOmitSecurityGroupsResponse) + fmt.Fprint(w, CreateOmitSecurityGroupsResponse) }) asu := true @@ -280,7 +280,7 @@ func TestCreateWithNoSecurityGroup(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, CreateWithNoSecurityGroupsResponse) + fmt.Fprint(w, CreateWithNoSecurityGroupsResponse) }) asu := true @@ -329,7 +329,7 @@ func TestCreateWithPropagateUplinkStatus(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, CreatePropagateUplinkStatusResponse) + fmt.Fprint(w, CreatePropagateUplinkStatusResponse) }) asu := true @@ -374,7 +374,7 @@ func TestCreateWithValueSpecs(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, CreateValueSpecResponse) + fmt.Fprint(w, CreateValueSpecResponse) }) asu := true @@ -427,7 +427,7 @@ func TestCreateWithInvalidValueSpecs(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, CreateValueSpecResponse) + fmt.Fprint(w, CreateValueSpecResponse) }) asu := true @@ -483,7 +483,7 @@ func TestCreatePortSecurity(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, CreatePortSecurityResponse) + fmt.Fprint(w, CreatePortSecurityResponse) }) var portWithExt struct { @@ -531,7 +531,7 @@ func TestUpdate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, UpdateResponse) + fmt.Fprint(w, UpdateResponse) }) name := "new_port_name" @@ -573,7 +573,7 @@ func TestUpdateOmitSecurityGroups(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, UpdateOmitSecurityGroupsResponse) + fmt.Fprint(w, UpdateOmitSecurityGroupsResponse) }) name := "new_port_name" @@ -614,7 +614,7 @@ func TestUpdatePropagateUplinkStatus(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, UpdatePropagateUplinkStatusResponse) + fmt.Fprint(w, UpdatePropagateUplinkStatusResponse) }) propagateUplinkStatus := true @@ -642,7 +642,7 @@ func TestUpdateValueSpecs(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, UpdateValueSpecsResponse) + fmt.Fprint(w, UpdateValueSpecsResponse) }) options := ports.UpdateOpts{ @@ -669,7 +669,7 @@ func TestUpdatePortSecurity(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, UpdatePortSecurityResponse) + fmt.Fprint(w, UpdatePortSecurityResponse) }) var portWithExt struct { @@ -707,7 +707,7 @@ func TestUpdateRevision(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, UpdateResponse) + fmt.Fprint(w, UpdateResponse) }) th.Mux.HandleFunc("/v2.0/ports/65c0ee9f-d634-4522-8954-51021b570b0e", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") @@ -720,7 +720,7 @@ func TestUpdateRevision(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, UpdateResponse) + fmt.Fprint(w, UpdateResponse) }) name := "new_port_name" @@ -757,7 +757,7 @@ func TestRemoveSecurityGroups(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, RemoveSecurityGroupResponse) + fmt.Fprint(w, RemoveSecurityGroupResponse) }) name := "new_port_name" @@ -799,7 +799,7 @@ func TestRemoveAllowedAddressPairs(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, RemoveAllowedAddressPairsResponse) + fmt.Fprint(w, RemoveAllowedAddressPairsResponse) }) name := "new_port_name" @@ -837,7 +837,7 @@ func TestDontUpdateAllowedAddressPairs(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, DontUpdateAllowedAddressPairsResponse) + fmt.Fprint(w, DontUpdateAllowedAddressPairsResponse) }) name := "new_port_name" @@ -887,7 +887,7 @@ func TestGetWithExtraDHCPOpts(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, GetWithExtraDHCPOptsResponse) + fmt.Fprint(w, GetWithExtraDHCPOptsResponse) }) var s struct { @@ -933,7 +933,7 @@ func TestCreateWithExtraDHCPOpts(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, CreateWithExtraDHCPOptsResponse) + fmt.Fprint(w, CreateWithExtraDHCPOptsResponse) }) adminStateUp := true @@ -996,7 +996,7 @@ func TestUpdateWithExtraDHCPOpts(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, UpdateWithExtraDHCPOptsResponse) + fmt.Fprint(w, UpdateWithExtraDHCPOptsResponse) }) name := "updated-port-with-dhcp-opts" diff --git a/openstack/networking/v2/subnets/testing/requests_test.go b/openstack/networking/v2/subnets/testing/requests_test.go index 1df6fd1ce3..41ec607cd8 100644 --- a/openstack/networking/v2/subnets/testing/requests_test.go +++ b/openstack/networking/v2/subnets/testing/requests_test.go @@ -23,7 +23,7 @@ func TestList(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, SubnetListResult) + fmt.Fprint(w, SubnetListResult) }) count := 0 @@ -65,7 +65,7 @@ func TestGet(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, SubnetGetResult) + fmt.Fprint(w, SubnetGetResult) }) s, err := subnets.Get(context.TODO(), fake.ServiceClient(), "54d6f61d-db07-451c-9ab3-b9609b6b6f0b").Extract() @@ -104,7 +104,7 @@ func TestCreate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, SubnetCreateResult) + fmt.Fprint(w, SubnetCreateResult) }) var gatewayIP = "192.168.199.1" @@ -166,7 +166,7 @@ func TestCreateNoGateway(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, SubnetCreateWithNoGatewayResponse) + fmt.Fprint(w, SubnetCreateWithNoGatewayResponse) }) var noGateway = "" @@ -217,7 +217,7 @@ func TestCreateDefaultGateway(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, SubnetCreateWithDefaultGatewayResponse) + fmt.Fprint(w, SubnetCreateWithDefaultGatewayResponse) }) opts := subnets.CreateOpts{ @@ -266,7 +266,7 @@ func TestCreateIPv6RaAddressMode(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, SubnetCreateWithIPv6RaAddressModeResponse) + fmt.Fprint(w, SubnetCreateWithIPv6RaAddressModeResponse) }) var gatewayIP = "2001:db8:0:a::1" @@ -307,7 +307,7 @@ func TestCreateWithNoCIDR(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, SubnetCreateResult) + fmt.Fprint(w, SubnetCreateResult) }) opts := subnets.CreateOpts{ @@ -356,7 +356,7 @@ func TestCreateWithPrefixlen(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, SubnetCreateResult) + fmt.Fprint(w, SubnetCreateResult) }) opts := subnets.CreateOpts{ @@ -423,7 +423,7 @@ func TestUpdate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, SubnetUpdateResponse) + fmt.Fprint(w, SubnetUpdateResponse) }) dnsNameservers := []string{"foo"} @@ -456,7 +456,7 @@ func TestUpdateGateway(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, SubnetUpdateGatewayResponse) + fmt.Fprint(w, SubnetUpdateGatewayResponse) }) var gatewayIP = "10.0.0.1" @@ -487,7 +487,7 @@ func TestUpdateRemoveGateway(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, SubnetUpdateRemoveGatewayResponse) + fmt.Fprint(w, SubnetUpdateRemoveGatewayResponse) }) var noGateway = "" @@ -518,7 +518,7 @@ func TestUpdateHostRoutes(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, SubnetUpdateHostRoutesResponse) + fmt.Fprint(w, SubnetUpdateHostRoutesResponse) }) HostRoutes := []subnets.HostRoute{ @@ -555,7 +555,7 @@ func TestUpdateRemoveHostRoutes(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, SubnetUpdateRemoveHostRoutesResponse) + fmt.Fprint(w, SubnetUpdateRemoveHostRoutesResponse) }) noHostRoutes := []subnets.HostRoute{} @@ -584,7 +584,7 @@ func TestUpdateAllocationPool(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, SubnetUpdateAllocationPoolResponse) + fmt.Fprint(w, SubnetUpdateAllocationPoolResponse) }) name := "my_new_subnet" @@ -625,7 +625,7 @@ func TestUpdateRevision(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, SubnetUpdateResponse) + fmt.Fprint(w, SubnetUpdateResponse) }) th.Mux.HandleFunc("/v2.0/subnets/08eae331-0402-425a-923c-34f7cfe39c1c", func(w http.ResponseWriter, r *http.Request) { @@ -639,7 +639,7 @@ func TestUpdateRevision(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, SubnetUpdateResponse) + fmt.Fprint(w, SubnetUpdateResponse) }) dnsNameservers := []string{"foo"} diff --git a/openstack/objectstorage/v1/containers/testing/fixtures.go b/openstack/objectstorage/v1/containers/testing/fixtures.go index 0f440472ac..55f4f723b6 100644 --- a/openstack/objectstorage/v1/containers/testing/fixtures.go +++ b/openstack/objectstorage/v1/containers/testing/fixtures.go @@ -56,7 +56,7 @@ func HandleListContainerInfoSuccessfully(t *testing.T) { marker := r.Form.Get("marker") switch marker { case "": - fmt.Fprintf(w, `[ + fmt.Fprint(w, `[ { "count": 0, "bytes": 0, @@ -69,7 +69,7 @@ func HandleListContainerInfoSuccessfully(t *testing.T) { } ]`) case "janeausten": - fmt.Fprintf(w, `[ + fmt.Fprint(w, `[ { "count": 1, "bytes": 14, @@ -77,7 +77,7 @@ func HandleListContainerInfoSuccessfully(t *testing.T) { } ]`) case "marktwain": - fmt.Fprintf(w, `[]`) + fmt.Fprint(w, `[]`) default: t.Fatalf("Unexpected marker: [%s]", marker) } @@ -158,7 +158,7 @@ func HandleBulkDeleteSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, bulkDeleteResponse) + fmt.Fprint(w, bulkDeleteResponse) }) } diff --git a/openstack/objectstorage/v1/objects/testing/fixtures_test.go b/openstack/objectstorage/v1/objects/testing/fixtures_test.go index fd24937f6c..f4546d6ab0 100644 --- a/openstack/objectstorage/v1/objects/testing/fixtures_test.go +++ b/openstack/objectstorage/v1/objects/testing/fixtures_test.go @@ -61,7 +61,7 @@ func HandleDownloadObjectSuccessfully(t *testing.T, options ...option) { } w.Header().Set("Last-Modified", date.Format(time.RFC1123)) w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, "Successful download with Gophercloud") + fmt.Fprint(w, "Successful download with Gophercloud") }) } @@ -118,7 +118,7 @@ func HandleListObjectsInfoSuccessfully(t *testing.T, options ...option) { marker := r.Form.Get("marker") switch marker { case "": - fmt.Fprintf(w, `[ + fmt.Fprint(w, `[ { "hash": "451e372e48e0f6b1114fa0724aa79fa1", "last_modified": "2016-08-17T22:11:58.602650", @@ -135,7 +135,7 @@ func HandleListObjectsInfoSuccessfully(t *testing.T, options ...option) { } ]`) case "hello": - fmt.Fprintf(w, `[]`) + fmt.Fprint(w, `[]`) default: t.Fatalf("Unexpected marker: [%s]", marker) } @@ -157,13 +157,13 @@ func HandleListSubdirSuccessfully(t *testing.T) { marker := r.Form.Get("marker") switch marker { case "": - fmt.Fprintf(w, `[ + fmt.Fprint(w, `[ { "subdir": "directory/" } ]`) case "directory/": - fmt.Fprintf(w, `[]`) + fmt.Fprint(w, `[]`) default: t.Fatalf("Unexpected marker: [%s]", marker) } @@ -323,7 +323,7 @@ func HandleBulkDeleteSuccessfully(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, bulkDeleteResponse) + fmt.Fprint(w, bulkDeleteResponse) }) } diff --git a/openstack/objectstorage/v1/swauth/testing/fixtures_test.go b/openstack/objectstorage/v1/swauth/testing/fixtures_test.go index b8e0b33f24..01bbfd1a84 100644 --- a/openstack/objectstorage/v1/swauth/testing/fixtures_test.go +++ b/openstack/objectstorage/v1/swauth/testing/fixtures_test.go @@ -24,6 +24,6 @@ func HandleAuthSuccessfully(t *testing.T, authOpts swauth.AuthOpts) { w.Header().Add("X-Auth-Token", AuthResult.Token) w.Header().Add("X-Storage-Url", AuthResult.StorageURL) - fmt.Fprintf(w, "") + fmt.Fprint(w, "") }) } diff --git a/openstack/orchestration/v1/apiversions/testing/requests_test.go b/openstack/orchestration/v1/apiversions/testing/requests_test.go index ec4ad6d228..d7149f1cbd 100644 --- a/openstack/orchestration/v1/apiversions/testing/requests_test.go +++ b/openstack/orchestration/v1/apiversions/testing/requests_test.go @@ -24,7 +24,7 @@ func TestListVersions(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "versions": [ { diff --git a/openstack/orchestration/v1/buildinfo/testing/fixtures_test.go b/openstack/orchestration/v1/buildinfo/testing/fixtures_test.go index 72527032d8..74a91e4df3 100644 --- a/openstack/orchestration/v1/buildinfo/testing/fixtures_test.go +++ b/openstack/orchestration/v1/buildinfo/testing/fixtures_test.go @@ -41,6 +41,6 @@ func HandleGetSuccessfully(t *testing.T, output string) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, output) + fmt.Fprint(w, output) }) } diff --git a/openstack/orchestration/v1/stackevents/testing/fixtures_test.go b/openstack/orchestration/v1/stackevents/testing/fixtures_test.go index 4c22428a9a..a0e31b4ba5 100644 --- a/openstack/orchestration/v1/stackevents/testing/fixtures_test.go +++ b/openstack/orchestration/v1/stackevents/testing/fixtures_test.go @@ -128,7 +128,7 @@ func HandleFindSuccessfully(t *testing.T, output string) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, output) + fmt.Fprint(w, output) }) } @@ -250,9 +250,9 @@ func HandleListSuccessfully(t *testing.T, output string) { marker := r.Form.Get("marker") switch marker { case "": - fmt.Fprintf(w, output) + fmt.Fprint(w, output) case "93940999-7d40-44ae-8de4-19624e7b8d18": - fmt.Fprintf(w, `{"events":[]}`) + fmt.Fprint(w, `{"events":[]}`) default: t.Fatalf("Unexpected marker: [%s]", marker) } @@ -377,9 +377,9 @@ func HandleListResourceEventsSuccessfully(t *testing.T, output string) { marker := r.Form.Get("marker") switch marker { case "": - fmt.Fprintf(w, output) + fmt.Fprint(w, output) case "93940999-7d40-44ae-8de4-19624e7b8d18": - fmt.Fprintf(w, `{"events":[]}`) + fmt.Fprint(w, `{"events":[]}`) default: t.Fatalf("Unexpected marker: [%s]", marker) } @@ -449,6 +449,6 @@ func HandleGetSuccessfully(t *testing.T, output string) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, output) + fmt.Fprint(w, output) }) } diff --git a/openstack/orchestration/v1/stackresources/testing/fixtures_test.go b/openstack/orchestration/v1/stackresources/testing/fixtures_test.go index a306d8de8b..fa1e66575e 100644 --- a/openstack/orchestration/v1/stackresources/testing/fixtures_test.go +++ b/openstack/orchestration/v1/stackresources/testing/fixtures_test.go @@ -82,7 +82,7 @@ func HandleFindSuccessfully(t *testing.T, output string) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, output) + fmt.Fprint(w, output) }) } @@ -157,9 +157,9 @@ func HandleListSuccessfully(t *testing.T, output string) { marker := r.Form.Get("marker") switch marker { case "": - fmt.Fprintf(w, output) + fmt.Fprint(w, output) case "49181cd6-169a-4130-9455-31185bbfc5bf": - fmt.Fprintf(w, `{"resources":[]}`) + fmt.Fprint(w, `{"resources":[]}`) default: t.Fatalf("Unexpected marker: [%s]", marker) } @@ -227,7 +227,7 @@ func HandleGetSuccessfully(t *testing.T, output string) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, output) + fmt.Fprint(w, output) }) } @@ -256,7 +256,7 @@ func HandleMetadataSuccessfully(t *testing.T, output string) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, output) + fmt.Fprint(w, output) }) } @@ -309,7 +309,7 @@ func HandleListTypesSuccessfully(t *testing.T, output string) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, output) + fmt.Fprint(w, output) }) } @@ -370,7 +370,7 @@ func HandleGetSchemaSuccessfully(t *testing.T, output string) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, output) + fmt.Fprint(w, output) }) } @@ -440,7 +440,7 @@ func HandleGetTemplateSuccessfully(t *testing.T, output string) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, output) + fmt.Fprint(w, output) }) } diff --git a/openstack/orchestration/v1/stacks/testing/fixtures_test.go b/openstack/orchestration/v1/stacks/testing/fixtures_test.go index 2244b7d89d..9baed3aced 100644 --- a/openstack/orchestration/v1/stacks/testing/fixtures_test.go +++ b/openstack/orchestration/v1/stacks/testing/fixtures_test.go @@ -48,7 +48,7 @@ func HandleCreateSuccessfully(t *testing.T, output string) { th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Accept", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, output) + fmt.Fprint(w, output) }) } @@ -142,9 +142,9 @@ func HandleListSuccessfully(t *testing.T, output string) { marker := r.Form.Get("marker") switch marker { case "": - fmt.Fprintf(w, output) + fmt.Fprint(w, output) case "db6977b2-27aa-4775-9ae7-6213212d4ada": - fmt.Fprintf(w, `[]`) + fmt.Fprint(w, `[]`) default: t.Fatalf("Unexpected marker: [%s]", marker) } @@ -221,7 +221,7 @@ func HandleGetSuccessfully(t *testing.T, output string) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, output) + fmt.Fprint(w, output) }) } @@ -233,7 +233,7 @@ func HandleFindSuccessfully(t *testing.T, output string) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, output) + fmt.Fprint(w, output) }) } @@ -309,7 +309,7 @@ func HandlePreviewSuccessfully(t *testing.T, output string) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, output) + fmt.Fprint(w, output) }) } @@ -432,6 +432,6 @@ func HandleAbandonSuccessfully(t *testing.T, output string) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, output) + fmt.Fprint(w, output) }) } diff --git a/openstack/orchestration/v1/stacks/utils_test.go b/openstack/orchestration/v1/stacks/utils_test.go index 07fbb90cba..b7dd86bf0e 100644 --- a/openstack/orchestration/v1/stacks/utils_test.go +++ b/openstack/orchestration/v1/stacks/utils_test.go @@ -68,7 +68,7 @@ func TestFetch(t *testing.T) { th.TestMethod(t, r, "GET") w.Header().Set("Content-Type", "application/jason") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, "Fee-fi-fo-fum") + fmt.Fprint(w, "Fee-fi-fo-fum") }) client := fakeClient{BaseClient: getHTTPClient()} diff --git a/openstack/orchestration/v1/stacktemplates/testing/fixtures_test.go b/openstack/orchestration/v1/stacktemplates/testing/fixtures_test.go index 5b9c9ad345..2e6505702e 100644 --- a/openstack/orchestration/v1/stacktemplates/testing/fixtures_test.go +++ b/openstack/orchestration/v1/stacktemplates/testing/fixtures_test.go @@ -48,7 +48,7 @@ func HandleGetSuccessfully(t *testing.T, output string) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, output) + fmt.Fprint(w, output) }) } @@ -91,6 +91,6 @@ func HandleValidateSuccessfully(t *testing.T, output string) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, output) + fmt.Fprint(w, output) }) } diff --git a/openstack/placement/v1/resourceproviders/testing/fixtures_test.go b/openstack/placement/v1/resourceproviders/testing/fixtures_test.go index e663cab280..8766d88e27 100644 --- a/openstack/placement/v1/resourceproviders/testing/fixtures_test.go +++ b/openstack/placement/v1/resourceproviders/testing/fixtures_test.go @@ -277,7 +277,7 @@ func HandleResourceProviderList(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ResourceProvidersBody) + fmt.Fprint(w, ResourceProvidersBody) }) } @@ -289,7 +289,7 @@ func HandleResourceProviderCreate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ResourceProviderCreateBody) + fmt.Fprint(w, ResourceProviderCreateBody) }) } @@ -301,7 +301,7 @@ func HandleResourceProviderGet(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ResourceProviderCreateBody) + fmt.Fprint(w, ResourceProviderCreateBody) }) } @@ -324,7 +324,7 @@ func HandleResourceProviderUpdate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ResourceProviderUpdateResponse) + fmt.Fprint(w, ResourceProviderUpdateResponse) }) } @@ -339,7 +339,7 @@ func HandleResourceProviderGetUsages(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, UsagesBody) + fmt.Fprint(w, UsagesBody) }) } @@ -354,7 +354,7 @@ func HandleResourceProviderGetInventories(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, InventoriesBody) + fmt.Fprint(w, InventoriesBody) }) } @@ -369,7 +369,7 @@ func HandleResourceProviderGetAllocations(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, AllocationsBody) + fmt.Fprint(w, AllocationsBody) }) } @@ -384,6 +384,6 @@ func HandleResourceProviderGetTraits(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, TraitsBody) + fmt.Fprint(w, TraitsBody) }) } diff --git a/openstack/sharedfilesystems/apiversions/testing/fixtures_test.go b/openstack/sharedfilesystems/apiversions/testing/fixtures_test.go index 949434480f..37826cab70 100644 --- a/openstack/sharedfilesystems/apiversions/testing/fixtures_test.go +++ b/openstack/sharedfilesystems/apiversions/testing/fixtures_test.go @@ -186,7 +186,7 @@ func MockListResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ManilaAllAPIVersionsResponse) + fmt.Fprint(w, ManilaAllAPIVersionsResponse) }) } @@ -198,7 +198,7 @@ func MockGetResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ManilaAPIVersionResponse) + fmt.Fprint(w, ManilaAPIVersionResponse) }) } @@ -210,7 +210,7 @@ func MockGetNoResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ManilaAPIInvalidVersionResponse_1) + fmt.Fprint(w, ManilaAPIInvalidVersionResponse_1) }) } @@ -222,6 +222,6 @@ func MockGetMultipleResponses(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ManilaAPIInvalidVersionResponse_2) + fmt.Fprint(w, ManilaAPIInvalidVersionResponse_2) }) } diff --git a/openstack/sharedfilesystems/v2/availabilityzones/testing/fixtures_test.go b/openstack/sharedfilesystems/v2/availabilityzones/testing/fixtures_test.go index d6cd25830f..fa18c4cfc9 100644 --- a/openstack/sharedfilesystems/v2/availabilityzones/testing/fixtures_test.go +++ b/openstack/sharedfilesystems/v2/availabilityzones/testing/fixtures_test.go @@ -17,7 +17,7 @@ func MockListResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "availability_zones": [ { diff --git a/openstack/sharedfilesystems/v2/errors/testing/fixtures_test.go b/openstack/sharedfilesystems/v2/errors/testing/fixtures_test.go index 5a6f7f013c..3adbc89b25 100644 --- a/openstack/sharedfilesystems/v2/errors/testing/fixtures_test.go +++ b/openstack/sharedfilesystems/v2/errors/testing/fixtures_test.go @@ -37,6 +37,6 @@ func MockCreateResponse(t *testing.T) { th.TestJSONRequest(t, r, createRequest) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusNotFound) - fmt.Fprintf(w, createResponse) + fmt.Fprint(w, createResponse) }) } diff --git a/openstack/sharedfilesystems/v2/messages/testing/fixtures_test.go b/openstack/sharedfilesystems/v2/messages/testing/fixtures_test.go index 111b6dbf97..123bad35ce 100644 --- a/openstack/sharedfilesystems/v2/messages/testing/fixtures_test.go +++ b/openstack/sharedfilesystems/v2/messages/testing/fixtures_test.go @@ -25,7 +25,7 @@ func MockListResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "messages": [ { @@ -67,7 +67,7 @@ func MockFilteredListResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "messages": [ { @@ -95,7 +95,7 @@ func MockGetResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "message": { "resource_id": "4336d74f-3bdc-4f27-9657-c01ec63680bf", diff --git a/openstack/sharedfilesystems/v2/replicas/testing/fixtures_test.go b/openstack/sharedfilesystems/v2/replicas/testing/fixtures_test.go index 00585c9c26..41fa0164c9 100644 --- a/openstack/sharedfilesystems/v2/replicas/testing/fixtures_test.go +++ b/openstack/sharedfilesystems/v2/replicas/testing/fixtures_test.go @@ -48,7 +48,7 @@ func MockCreateResponse(t *testing.T) { th.TestJSONRequest(t, r, createRequest) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusAccepted) - fmt.Fprintf(w, createResponse) + fmt.Fprint(w, createResponse) }) } @@ -175,7 +175,7 @@ func MockGetResponse(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "X-OpenStack-Manila-API-Version", "2.11") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, getResponse) + fmt.Fprint(w, getResponse) }) } @@ -330,7 +330,7 @@ func MockListExportLocationsResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") th.TestHeader(t, r, "X-OpenStack-Manila-API-Version", "2.47") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, listExportLocationsResponse) + fmt.Fprint(w, listExportLocationsResponse) }) } @@ -355,6 +355,6 @@ func MockGetExportLocationResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") th.TestHeader(t, r, "X-OpenStack-Manila-API-Version", "2.47") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, getExportLocationResponse) + fmt.Fprint(w, getExportLocationResponse) }) } diff --git a/openstack/sharedfilesystems/v2/schedulerstats/testing/fixtures_test.go b/openstack/sharedfilesystems/v2/schedulerstats/testing/fixtures_test.go index 88c4b31203..fdd861d9c8 100644 --- a/openstack/sharedfilesystems/v2/schedulerstats/testing/fixtures_test.go +++ b/openstack/sharedfilesystems/v2/schedulerstats/testing/fixtures_test.go @@ -274,7 +274,7 @@ func HandlePoolsListSuccessfully(t *testing.T) { if err := r.ParseForm(); err != nil { t.Errorf("Failed to parse request form %v", err) } - fmt.Fprintf(w, PoolsListBody) + fmt.Fprint(w, PoolsListBody) }) th.Mux.HandleFunc("/scheduler-stats/pools/detail", func(w http.ResponseWriter, r *http.Request) { @@ -286,6 +286,6 @@ func HandlePoolsListSuccessfully(t *testing.T) { if err := r.ParseForm(); err != nil { t.Errorf("Failed to parse request form %v", err) } - fmt.Fprintf(w, PoolsListBodyDetail) + fmt.Fprint(w, PoolsListBodyDetail) }) } diff --git a/openstack/sharedfilesystems/v2/securityservices/testing/fixtures_test.go b/openstack/sharedfilesystems/v2/securityservices/testing/fixtures_test.go index c0b7645770..279fcee4a4 100644 --- a/openstack/sharedfilesystems/v2/securityservices/testing/fixtures_test.go +++ b/openstack/sharedfilesystems/v2/securityservices/testing/fixtures_test.go @@ -30,7 +30,7 @@ func MockCreateResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "security_service": { "status": "new", @@ -67,7 +67,7 @@ func MockListResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "security_services": [ { @@ -113,7 +113,7 @@ func MockFilteredListResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "security_services": [ { @@ -143,7 +143,7 @@ func MockGetResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "security_service": { "status": "new", @@ -169,7 +169,7 @@ func MockUpdateResponse(t *testing.T) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "security_service": { "status": "new", diff --git a/openstack/sharedfilesystems/v2/services/testing/fixtures_test.go b/openstack/sharedfilesystems/v2/services/testing/fixtures_test.go index 67f7b94c78..9916b033fc 100644 --- a/openstack/sharedfilesystems/v2/services/testing/fixtures_test.go +++ b/openstack/sharedfilesystems/v2/services/testing/fixtures_test.go @@ -66,6 +66,6 @@ func HandleListSuccessfully(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, ServiceListBody) + fmt.Fprint(w, ServiceListBody) }) } diff --git a/openstack/sharedfilesystems/v2/shareaccessrules/testing/fixtures_test.go b/openstack/sharedfilesystems/v2/shareaccessrules/testing/fixtures_test.go index d82014357d..cc63ffac9c 100644 --- a/openstack/sharedfilesystems/v2/shareaccessrules/testing/fixtures_test.go +++ b/openstack/sharedfilesystems/v2/shareaccessrules/testing/fixtures_test.go @@ -40,7 +40,7 @@ func MockGetResponse(t *testing.T) { th.TestHeader(t, r, "Accept", "application/json") w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, getResponse) + fmt.Fprint(w, getResponse) }) } diff --git a/openstack/sharedfilesystems/v2/shareaccessrules/testing/requests_test.go b/openstack/sharedfilesystems/v2/shareaccessrules/testing/requests_test.go index 4f86a642d4..7566788e40 100644 --- a/openstack/sharedfilesystems/v2/shareaccessrules/testing/requests_test.go +++ b/openstack/sharedfilesystems/v2/shareaccessrules/testing/requests_test.go @@ -49,6 +49,6 @@ func MockListResponse(t *testing.T) { th.TestHeader(t, r, "Accept", "application/json") w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, listResponse) + fmt.Fprint(w, listResponse) }) } diff --git a/openstack/sharedfilesystems/v2/sharenetworks/testing/fixtures_test.go b/openstack/sharedfilesystems/v2/sharenetworks/testing/fixtures_test.go index cfa3b1712d..eb608f9b6a 100644 --- a/openstack/sharedfilesystems/v2/sharenetworks/testing/fixtures_test.go +++ b/openstack/sharedfilesystems/v2/sharenetworks/testing/fixtures_test.go @@ -55,7 +55,7 @@ func MockCreateResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusAccepted) - fmt.Fprintf(w, createResp("my_network", + fmt.Fprint(w, createResp("my_network", "This is my share network", "998b42ee-2cee-4d36-8b95-67b5ca1f2109", "53482b62-2c84-4a53-b6ab-30d9d9800d06")) @@ -85,7 +85,7 @@ func MockListResponse(t *testing.T) { switch marker { case "": - fmt.Fprintf(w, `{ + fmt.Fprint(w, `{ "share_networks": [ { "name": "net_my1", @@ -135,7 +135,7 @@ func MockListResponse(t *testing.T) { ] }`) default: - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "share_networks": [] }`) @@ -157,7 +157,7 @@ func MockFilteredListResponse(t *testing.T) { marker := r.Form.Get("offset") switch marker { case "": - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "share_networks": [ { @@ -178,7 +178,7 @@ func MockFilteredListResponse(t *testing.T) { ] }`) case "1": - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "share_networks": [ { @@ -199,7 +199,7 @@ func MockFilteredListResponse(t *testing.T) { ] }`) case "2": - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "share_networks": [ { @@ -220,7 +220,7 @@ func MockFilteredListResponse(t *testing.T) { ] }`) default: - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "share_networks": [] }`) @@ -235,7 +235,7 @@ func MockGetResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "share_network": { "name": "net_my1", @@ -261,7 +261,7 @@ func MockUpdateNeutronResponse(t *testing.T) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "share_network": { "name": "net_my2", @@ -288,7 +288,7 @@ func MockUpdateNovaResponse(t *testing.T) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "share_network": { "name": "net_my2", @@ -315,7 +315,7 @@ func MockAddSecurityServiceResponse(t *testing.T) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "share_network": { "name": "net2", @@ -341,7 +341,7 @@ func MockRemoveSecurityServiceResponse(t *testing.T) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "share_network": { "name": "net2", diff --git a/openstack/sharedfilesystems/v2/shares/testing/fixtures_test.go b/openstack/sharedfilesystems/v2/shares/testing/fixtures_test.go index cfb9e73d2e..36db8b7a22 100644 --- a/openstack/sharedfilesystems/v2/shares/testing/fixtures_test.go +++ b/openstack/sharedfilesystems/v2/shares/testing/fixtures_test.go @@ -84,7 +84,7 @@ func MockCreateResponse(t *testing.T) { th.TestJSONRequest(t, r, createRequest) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, createResponse) + fmt.Fprint(w, createResponse) }) } @@ -158,7 +158,7 @@ func MockUpdateResponse(t *testing.T) { th.TestJSONRequest(t, r, updateRequest) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, updateResponse) + fmt.Fprint(w, updateResponse) }) } @@ -211,7 +211,7 @@ func MockGetResponse(t *testing.T) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, getResponse) + fmt.Fprint(w, getResponse) }) } @@ -304,7 +304,7 @@ func MockListExportLocationsResponse(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, listExportLocationsResponse) + fmt.Fprint(w, listExportLocationsResponse) }) } @@ -325,7 +325,7 @@ func MockGetExportLocationResponse(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, getExportLocationResponse) + fmt.Fprint(w, getExportLocationResponse) }) } @@ -359,7 +359,7 @@ func MockGrantAccessResponse(t *testing.T) { th.TestJSONRequest(t, r, grantAccessRequest) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, grantAccessResponse) + fmt.Fprint(w, grantAccessResponse) }) } @@ -410,7 +410,7 @@ func MockListAccessRightsResponse(t *testing.T) { th.TestJSONRequest(t, r, listAccessRightsRequest) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, listAccessRightsResponse) + fmt.Fprint(w, listAccessRightsResponse) }) } diff --git a/openstack/sharedfilesystems/v2/sharetransfers/testing/fixtures_test.go b/openstack/sharedfilesystems/v2/sharetransfers/testing/fixtures_test.go index 980292f38f..342c4c5101 100644 --- a/openstack/sharedfilesystems/v2/sharetransfers/testing/fixtures_test.go +++ b/openstack/sharedfilesystems/v2/sharetransfers/testing/fixtures_test.go @@ -147,7 +147,7 @@ func HandleCreateTransfer(t *testing.T) { th.TestJSONRequest(t, r, CreateRequest) w.WriteHeader(http.StatusAccepted) - fmt.Fprintf(w, CreateResponse) + fmt.Fprint(w, CreateResponse) }) } @@ -179,7 +179,7 @@ func HandleListTransfers(t *testing.T) { th.TestFormValues(t, r, map[string]string{"all_tenants": "true"}) w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListOutput) + fmt.Fprint(w, ListOutput) }) } @@ -191,7 +191,7 @@ func HandleListTransfersDetail(t *testing.T) { th.TestFormValues(t, r, map[string]string{"all_tenants": "true"}) w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListOutput) + fmt.Fprint(w, ListOutput) }) } @@ -202,6 +202,6 @@ func HandleGetTransfer(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, GetOutput) + fmt.Fprint(w, GetOutput) }) } diff --git a/openstack/sharedfilesystems/v2/sharetypes/testing/fixtures_test.go b/openstack/sharedfilesystems/v2/sharetypes/testing/fixtures_test.go index 767d42807a..17fb21fa78 100644 --- a/openstack/sharedfilesystems/v2/sharetypes/testing/fixtures_test.go +++ b/openstack/sharedfilesystems/v2/sharetypes/testing/fixtures_test.go @@ -30,7 +30,7 @@ func MockCreateResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusAccepted) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "volume_type": { "os-share-type-access:is_public": true, @@ -76,7 +76,7 @@ func MockListResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "volume_types": [ { @@ -141,7 +141,7 @@ func MockGetDefaultResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "volume_type": { "required_extra_specs": null, @@ -172,7 +172,7 @@ func MockGetExtraSpecsResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "extra_specs": { "snapshot_support": "True", @@ -199,7 +199,7 @@ func MockSetExtraSpecsResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusAccepted) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "extra_specs": { "my_key": "my_value" @@ -223,7 +223,7 @@ func MockShowAccessResponse(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "share_type_access": [ { diff --git a/openstack/sharedfilesystems/v2/snapshots/testing/fixtures_test.go b/openstack/sharedfilesystems/v2/snapshots/testing/fixtures_test.go index e34d1081a4..88e94c371a 100644 --- a/openstack/sharedfilesystems/v2/snapshots/testing/fixtures_test.go +++ b/openstack/sharedfilesystems/v2/snapshots/testing/fixtures_test.go @@ -59,7 +59,7 @@ func MockCreateResponse(t *testing.T) { th.TestJSONRequest(t, r, createRequest) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusAccepted) - fmt.Fprintf(w, createResponse) + fmt.Fprint(w, createResponse) }) } @@ -114,7 +114,7 @@ func MockUpdateResponse(t *testing.T) { th.TestJSONRequest(t, r, updateRequest) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, updateResponse) + fmt.Fprint(w, updateResponse) }) } @@ -150,7 +150,7 @@ func MockGetResponse(t *testing.T) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, getResponse) + fmt.Fprint(w, getResponse) }) } diff --git a/openstack/testing/client_test.go b/openstack/testing/client_test.go index 2c158dbfc3..75192a524c 100644 --- a/openstack/testing/client_test.go +++ b/openstack/testing/client_test.go @@ -46,7 +46,7 @@ func TestAuthenticatedClientV3(t *testing.T) { w.Header().Add("X-Subject-Token", ID) w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, `{ "token": { "expires_at": "2013-02-02T18:30:59.000000Z" } }`) + fmt.Fprint(w, `{ "token": { "expires_at": "2013-02-02T18:30:59.000000Z" } }`) }) options := gophercloud.AuthOptions{ @@ -91,7 +91,7 @@ func TestAuthenticatedClientV2(t *testing.T) { }) th.Mux.HandleFunc("/v2.0/tokens", func(w http.ResponseWriter, r *http.Request) { - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "access": { "token": { @@ -197,7 +197,7 @@ func TestIdentityAdminV3Client(t *testing.T) { w.Header().Add("X-Subject-Token", ID) w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "token": { "audit_ids": ["VcxU2JYqT8OzfUVvrjEITQ", "qNUTIJntTzO1-XUk5STybw"], diff --git a/openstack/workflow/v2/crontriggers/testing/requests_test.go b/openstack/workflow/v2/crontriggers/testing/requests_test.go index fd3bac58e0..8267e2bc79 100644 --- a/openstack/workflow/v2/crontriggers/testing/requests_test.go +++ b/openstack/workflow/v2/crontriggers/testing/requests_test.go @@ -25,7 +25,7 @@ func TestCreateCronTrigger(t *testing.T) { w.WriteHeader(http.StatusCreated) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "created_at": "2018-09-12 15:48:18", "first_execution_time": "2018-09-12 17:48:00", @@ -110,7 +110,7 @@ func TestGetCronTrigger(t *testing.T) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-token", fake.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "created_at": "2018-09-12 15:48:18", "first_execution_time": "2018-09-12 17:48:00", @@ -195,7 +195,7 @@ func TestListCronTriggers(t *testing.T) { "next": "%s/cron_triggers?marker=0520ffd8-f7f1-4f2e-845b-55d953a1cf46" }`, th.Server.URL) case "0520ffd8-f7f1-4f2e-845b-55d953a1cf46": - fmt.Fprintf(w, `{ "cron_triggers": [] }`) + fmt.Fprint(w, `{ "cron_triggers": [] }`) default: t.Fatalf("Unexpected marker: [%s]", marker) } diff --git a/openstack/workflow/v2/executions/testing/requests_test.go b/openstack/workflow/v2/executions/testing/requests_test.go index d0b4641793..86a4700457 100644 --- a/openstack/workflow/v2/executions/testing/requests_test.go +++ b/openstack/workflow/v2/executions/testing/requests_test.go @@ -25,7 +25,7 @@ func TestCreateExecution(t *testing.T) { w.WriteHeader(http.StatusCreated) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "created_at": "2018-09-12 14:48:49", "description": "description", @@ -92,7 +92,7 @@ func TestGetExecution(t *testing.T) { th.TestHeader(t, r, "X-Auth-token", fake.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "created_at": "2018-09-12 14:48:49", "description": "description", @@ -189,7 +189,7 @@ func TestListExecutions(t *testing.T) { "next": "%s/executions?marker=50bb59f1-eb77-4017-a77f-6d575b002667" }`, th.Server.URL) case "50bb59f1-eb77-4017-a77f-6d575b002667": - fmt.Fprintf(w, `{ "executions": [] }`) + fmt.Fprint(w, `{ "executions": [] }`) default: t.Fatalf("Unexpected marker: [%s]", marker) } diff --git a/openstack/workflow/v2/workflows/testing/requests_test.go b/openstack/workflow/v2/workflows/testing/requests_test.go index 78f0f78a09..a5d656685f 100644 --- a/openstack/workflow/v2/workflows/testing/requests_test.go +++ b/openstack/workflow/v2/workflows/testing/requests_test.go @@ -46,11 +46,11 @@ workflow_echo: w.WriteHeader(http.StatusCreated) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, `{ + fmt.Fprint(w, `{ "workflows": [ { "created_at": "2018-09-12 15:48:17", - "definition": "---\nversion: '2.0'\n\nworkflow_echo:\n description: Simple workflow example\n type: direct\n\n input:\n - msg\n\n tasks:\n test:\n action: std.echo output=\"<%% $.msg %%>\"", + "definition": "---\nversion: '2.0'\n\nworkflow_echo:\n description: Simple workflow example\n type: direct\n\n input:\n - msg\n\n tasks:\n test:\n action: std.echo output=\"<% $.msg %>\"", "id": "604a3a1e-94e3-4066-a34a-aa56873ef236", "input": "msg", "name": "workflow_echo", @@ -118,10 +118,10 @@ func TestGetWorkflow(t *testing.T) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-token", fake.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, ` + fmt.Fprint(w, ` { "created_at": "2018-09-12 15:48:17", - "definition": "---\nversion: '2.0'\n\nworkflow_echo:\n description: Simple workflow example\n type: direct\n\n input:\n - msg\n\n tasks:\n test:\n action: std.echo output=\"<%% $.msg %%>\"", + "definition": "---\nversion: '2.0'\n\nworkflow_echo:\n description: Simple workflow example\n type: direct\n\n input:\n - msg\n\n tasks:\n test:\n action: std.echo output=\"<% $.msg %>\"", "id": "604a3a1e-94e3-4066-a34a-aa56873ef236", "input": "msg", "name": "workflow_echo", @@ -187,7 +187,7 @@ func TestListWorkflows(t *testing.T) { ] }`, th.Server.URL) case "604a3a1e-94e3-4066-a34a-aa56873ef236": - fmt.Fprintf(w, `{ "workflows": [] }`) + fmt.Fprint(w, `{ "workflows": [] }`) default: t.Fatalf("Unexpected marker: [%s]", marker) } diff --git a/pagination/testing/linked_test.go b/pagination/testing/linked_test.go index 25166ad861..e28c2b0483 100644 --- a/pagination/testing/linked_test.go +++ b/pagination/testing/linked_test.go @@ -45,7 +45,7 @@ func createLinked() pagination.Pager { th.Mux.HandleFunc("/page3", func(w http.ResponseWriter, r *http.Request) { w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, `{ "ints": [7, 8, 9], "links": { "next": null } }`) + fmt.Fprint(w, `{ "ints": [7, 8, 9], "links": { "next": null } }`) }) client := createClient() diff --git a/pagination/testing/marker_test.go b/pagination/testing/marker_test.go index 45c943e5b7..a41915175d 100644 --- a/pagination/testing/marker_test.go +++ b/pagination/testing/marker_test.go @@ -46,11 +46,11 @@ func createMarkerPaged(t *testing.T) pagination.Pager { ms := r.Form["marker"] switch { case len(ms) == 0: - fmt.Fprintf(w, "aaa\nbbb\nccc") + fmt.Fprint(w, "aaa\nbbb\nccc") case len(ms) == 1 && ms[0] == "ccc": - fmt.Fprintf(w, "ddd\neee\nfff") + fmt.Fprint(w, "ddd\neee\nfff") case len(ms) == 1 && ms[0] == "fff": - fmt.Fprintf(w, "ggg\nhhh\niii") + fmt.Fprint(w, "ggg\nhhh\niii") case len(ms) == 1 && ms[0] == "iii": w.WriteHeader(http.StatusNoContent) default: diff --git a/pagination/testing/single_test.go b/pagination/testing/single_test.go index 6bcd930cb2..090324a573 100644 --- a/pagination/testing/single_test.go +++ b/pagination/testing/single_test.go @@ -38,7 +38,7 @@ func setupSinglePaged() pagination.Pager { th.Mux.HandleFunc("/only", func(w http.ResponseWriter, r *http.Request) { w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, `{ "ints": [1, 2, 3] }`) + fmt.Fprint(w, `{ "ints": [1, 2, 3] }`) }) createPage := func(r pagination.PageResult) pagination.Page { diff --git a/testhelper/fixture/helper.go b/testhelper/fixture/helper.go index a0f3b5c7b2..7c84378770 100644 --- a/testhelper/fixture/helper.go +++ b/testhelper/fixture/helper.go @@ -25,7 +25,7 @@ func SetupHandler(t *testing.T, url, method, requestBody, responseBody string, s w.WriteHeader(status) if responseBody != "" { - fmt.Fprintf(w, responseBody) + fmt.Fprint(w, responseBody) } }) } diff --git a/testing/provider_client_test.go b/testing/provider_client_test.go index 18704fd4b1..44fc37756c 100644 --- a/testing/provider_client_test.go +++ b/testing/provider_client_test.go @@ -99,7 +99,7 @@ func TestConcurrentReauth(t *testing.T) { } w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, `{}`) + fmt.Fprint(w, `{}`) }) wg := new(sync.WaitGroup) @@ -276,7 +276,7 @@ func TestRequestThatCameDuringReauthWaitsUntilItIsCompleted(t *testing.T) { } w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, `{}`) + fmt.Fprint(w, `{}`) }) wg := new(sync.WaitGroup) From 752f35e5ad551a3446795aaf68fb99cc134923e9 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Thu, 28 Nov 2024 14:11:35 +0000 Subject: [PATCH 071/353] make: Bump golangci-lint We also add the '-v' and '--max-same-issues' flags so that we get some indication that things are running and show more output. Signed-off-by: Stephen Finucane --- Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 066946cf8d..2a0618a6b6 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ undefine GOFLAGS -GOLANGCI_LINT_VERSION?=v1.57.1 -GO_TEST?=go run gotest.tools/gotestsum@latest --format testname +GOLANGCI_LINT_VERSION?=v1.62.2 +GO_TEST?=go run gotest.tools/gotestsum@latest --format testname -- ifeq ($(shell command -v podman 2> /dev/null),) RUNNER=docker @@ -23,7 +23,7 @@ lint: -v ~/.cache/golangci-lint/$(GOLANGCI_LINT_VERSION):/root/.cache \ -w /app \ -e GOFLAGS="-tags=acceptance" \ - golangci/golangci-lint:$(GOLANGCI_LINT_VERSION) golangci-lint run + golangci/golangci-lint:$(GOLANGCI_LINT_VERSION) golangci-lint run -v --max-same-issues 50 .PHONY: lint format: From 9c474a14d039c14e3ed669672e604608f22cdfe6 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Wed, 17 Jul 2024 11:14:24 +0100 Subject: [PATCH 072/353] tests: Remove service update integration test Go runs tests in parallel for different packages in parallel. The service update test was disabling and re-enabling all compute services, and if this ran at the same time as another test that created a server then the server creation (and therefore the test) would fail. There does not appear to be any way to resolve this. We could run all integration tests serially instead, but this would be a backwards steps that will massively increase test run time. We could also rewrite the test to only disable 1 of N nova-compute services, but that would require us to fence off this compute node in all other tests using non-default parameters to server create. Given the lack of better options, we simply remove the test and assume our testing to date on this method has been good enough and unit tests will be enough to carry us forward. Signed-off-by: Stephen Finucane --- .../openstack/compute/v2/services_test.go | 57 ------------------- 1 file changed, 57 deletions(-) diff --git a/internal/acceptance/openstack/compute/v2/services_test.go b/internal/acceptance/openstack/compute/v2/services_test.go index d913173810..7b8d8725b5 100644 --- a/internal/acceptance/openstack/compute/v2/services_test.go +++ b/internal/acceptance/openstack/compute/v2/services_test.go @@ -64,60 +64,3 @@ func TestServicesListWithOpts(t *testing.T) { th.AssertEquals(t, true, found) } - -func TestServicesUpdate(t *testing.T) { - clients.RequireAdmin(t) - - client, err := clients.NewComputeV2Client() - th.AssertNoErr(t, err) - - listOpts := services.ListOpts{ - Binary: "nova-compute", - } - - client.Microversion = "2.53" - allPages, err := services.List(client, listOpts).AllPages(context.TODO()) - th.AssertNoErr(t, err) - - allServices, err := services.ExtractServices(allPages) - th.AssertNoErr(t, err) - - // disable all services - for _, service := range allServices { - opts := services.UpdateOpts{ - Status: services.ServiceDisabled, - } - updated, err := services.Update(context.TODO(), client, service.ID, opts).Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, updated.ID, service.ID) - } - - // verify all services are disabled - allPages, err = services.List(client, listOpts).AllPages(context.TODO()) - th.AssertNoErr(t, err) - - allServices, err = services.ExtractServices(allPages) - th.AssertNoErr(t, err) - - for _, service := range allServices { - th.AssertEquals(t, service.Status, "disabled") - } - - // reenable all services - allPages, err = services.List(client, listOpts).AllPages(context.TODO()) - th.AssertNoErr(t, err) - - allServices, err = services.ExtractServices(allPages) - th.AssertNoErr(t, err) - - for _, service := range allServices { - opts := services.UpdateOpts{ - Status: services.ServiceEnabled, - } - updated, err := services.Update(context.TODO(), client, service.ID, opts).Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, updated.ID, service.ID) - } -} From 8874ad4a740bdb229e1b5a4ed4f9e49b4c2473ad Mon Sep 17 00:00:00 2001 From: Pierre Prinetti Date: Fri, 6 Dec 2024 16:33:47 +0100 Subject: [PATCH 073/353] Prepare v2.3.0 --- CHANGELOG.md | 8 ++++++++ provider_client.go | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index efe2d9f6af..2520ac743b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## v2.3.0 (2024-12-06) + +* [GH-3213](https://github.com/gophercloud/gophercloud/pull/3213) [v2] Handle nova api version > 2.87 for hypervisor +* [GH-3236](https://github.com/gophercloud/gophercloud/pull/3236) [v2] Added required fields for Node API Parity +* [GH-3248](https://github.com/gophercloud/gophercloud/pull/3248) [v2] Add support for disable_power_off +* [GH-3261](https://github.com/gophercloud/gophercloud/pull/3261) [v2] Misc cleanups +* [GH-3262](https://github.com/gophercloud/gophercloud/pull/3262) [v2] Address govet 1.24 issue + ## v2.2.0 (2024-10-18) * [GH-3176](https://github.com/gophercloud/gophercloud/pull/3176) [v2] [containerinfra]: add "MasterLBEnabled" in Cluster results diff --git a/provider_client.go b/provider_client.go index 007266f635..26c925ceff 100644 --- a/provider_client.go +++ b/provider_client.go @@ -13,7 +13,7 @@ import ( // DefaultUserAgent is the default User-Agent string set in the request header. const ( - DefaultUserAgent = "gophercloud/v2.2.0" + DefaultUserAgent = "gophercloud/v2.3.0" DefaultMaxBackoffRetries = 60 ) From 3beb4984055398abfd00c1263a2d239438188e7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Andr=C3=A9?= Date: Fri, 6 Dec 2024 18:08:53 +0100 Subject: [PATCH 074/353] trivial: change order of args for AssertEquals() calls The expected order is "expected, actual" and getting this right helps debugging. --- .../networking/v2/extensions/extensions.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/internal/acceptance/openstack/networking/v2/extensions/extensions.go b/internal/acceptance/openstack/networking/v2/extensions/extensions.go index 4de1401f4d..84f020ff38 100644 --- a/internal/acceptance/openstack/networking/v2/extensions/extensions.go +++ b/internal/acceptance/openstack/networking/v2/extensions/extensions.go @@ -43,8 +43,8 @@ func CreateExternalNetwork(t *testing.T, client *gophercloud.ServiceClient) (*ne t.Logf("Created external network: %s", networkName) - th.AssertEquals(t, network.Name, networkName) - th.AssertEquals(t, network.Description, networkDescription) + th.AssertEquals(t, networkName, network.Name) + th.AssertEquals(t, networkDescription, network.Description) return network, nil } @@ -74,9 +74,9 @@ func CreatePortWithSecurityGroup(t *testing.T, client *gophercloud.ServiceClient t.Logf("Successfully created port: %s", portName) - th.AssertEquals(t, port.Name, portName) - th.AssertEquals(t, port.Description, portDescription) - th.AssertEquals(t, port.NetworkID, networkID) + th.AssertEquals(t, portName, port.Name) + th.AssertEquals(t, portDescription, port.Description) + th.AssertEquals(t, networkID, port.NetworkID) return port, nil } @@ -101,8 +101,8 @@ func CreateSecurityGroup(t *testing.T, client *gophercloud.ServiceClient) (*grou t.Logf("Created security group: %s", secGroup.ID) - th.AssertEquals(t, secGroup.Name, secGroupName) - th.AssertEquals(t, secGroup.Description, secGroupDescription) + th.AssertEquals(t, secGroupName, secGroup.Name) + th.AssertEquals(t, secGroupDescription, secGroup.Description) return secGroup, nil } From 04387f1f798b24df232415857f488cc1cce4da80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Andr=C3=A9?= Date: Sun, 8 Dec 2024 22:34:47 +0100 Subject: [PATCH 075/353] Allow BuildRequestBody() to work with collection of structs When passing an array or a slice to `BuildRequestBody()`, the `parent` string becomes mandatory. This makes it possible to build requests for bulk operations. --- params.go | 52 +++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 45 insertions(+), 7 deletions(-) diff --git a/params.go b/params.go index 09b322a6a2..4a2ed6c942 100644 --- a/params.go +++ b/params.go @@ -11,9 +11,11 @@ import ( ) /* -BuildRequestBody builds a map[string]interface from the given `struct`. If -parent is not an empty string, the final map[string]interface returned will -encapsulate the built one. For example: +BuildRequestBody builds a map[string]interface from the given `struct`, or +collection of `structs`. If parent is not an empty string, the final +map[string]interface returned will encapsulate the built one. Parent is +required when passing a list of `structs`. +For example: disk := 1 createOpts := flavors.CreateOpts{ @@ -27,7 +29,29 @@ encapsulate the built one. For example: body, err := gophercloud.BuildRequestBody(createOpts, "flavor") -The above example can be run as-is, however it is recommended to look at how + + opts := []rules.CreateOpts{ + { + Direction: "ingress", + PortRangeMin: 80, + EtherType: rules.EtherType4, + PortRangeMax: 80, + Protocol: "tcp", + SecGroupID: "a7734e61-b545-452d-a3cd-0189cbd9747a", + }, + { + Direction: "ingress", + PortRangeMin: 443, + EtherType: rules.EtherType4, + PortRangeMax: 443, + Protocol: "tcp", + SecGroupID: "a7734e61-b545-452d-a3cd-0189cbd9747a", + }, + } + + body, err := gophercloud.BuildRequestBody(opts, "security_group_rules") + +The above examples can be run as-is, however it is recommended to look at how BuildRequestBody is used within Gophercloud to more fully understand how it fits within the request process as a whole rather than use it directly as shown above. @@ -44,7 +68,8 @@ func BuildRequestBody(opts any, parent string) (map[string]any, error) { } optsMap := make(map[string]any) - if optsValue.Kind() == reflect.Struct { + switch optsValue.Kind() { + case reflect.Struct: //fmt.Printf("optsValue.Kind() is a reflect.Struct: %+v\n", optsValue.Kind()) for i := 0; i < optsValue.NumField(); i++ { v := optsValue.Field(i) @@ -184,9 +209,22 @@ func BuildRequestBody(opts any, parent string) (map[string]any, error) { } //fmt.Printf("optsMap after parent added: %+v\n", optsMap) return optsMap, nil + case reflect.Slice, reflect.Array: + optsMaps := make([]map[string]any, optsValue.Len()) + for i := 0; i < optsValue.Len(); i++ { + b, err := BuildRequestBody(optsValue.Index(i).Interface(), "") + if err != nil { + return nil, err + } + optsMaps[i] = b + } + if parent == "" { + return nil, fmt.Errorf("Parent is required when passing an array or a slice.") + } + return map[string]any{parent: optsMaps}, nil } - // Return an error if the underlying type of 'opts' isn't a struct. - return nil, fmt.Errorf("Options type is not a struct.") + // Return an error if we can't work with the underlying type of 'opts' + return nil, fmt.Errorf("Options type is not a struct, a slice, or an array.") } // EnabledState is a convenience type, mostly used in Create and Update From 89e66ee3f817d8f64f2d80ee786b545a15ae34d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Andr=C3=A9?= Date: Fri, 6 Dec 2024 17:53:37 +0100 Subject: [PATCH 076/353] SG rules: implement bulk create Implement bulk creation of security group rules [1]. [1] https://docs.openstack.org/api-ref/network/v2/#bulk-create-security-group-rule --- .../networking/v2/extensions/extensions.go | 38 ++++++++ .../networking/v2/extensions/security_test.go | 6 ++ .../v2/extensions/security/rules/requests.go | 17 ++++ .../v2/extensions/security/rules/results.go | 19 ++++ .../security/rules/testing/requests_test.go | 95 +++++++++++++++++++ 5 files changed, 175 insertions(+) diff --git a/internal/acceptance/openstack/networking/v2/extensions/extensions.go b/internal/acceptance/openstack/networking/v2/extensions/extensions.go index 84f020ff38..535bd950ab 100644 --- a/internal/acceptance/openstack/networking/v2/extensions/extensions.go +++ b/internal/acceptance/openstack/networking/v2/extensions/extensions.go @@ -140,6 +140,44 @@ func CreateSecurityGroupRule(t *testing.T, client *gophercloud.ServiceClient, se return rule, nil } +// CreateSecurityGroupRulesBulk will create security group rules with a random name +// and random port between 80 and 99. +// An error will be returned if one was failed to be created. +func CreateSecurityGroupRulesBulk(t *testing.T, client *gophercloud.ServiceClient, secGroupID string) ([]rules.SecGroupRule, error) { + t.Logf("Attempting to bulk create security group rules in group: %s", secGroupID) + + sgRulesCreateOpts := make([]rules.CreateOpts, 3) + for i := range 3 { + description := "Rule description" + fromPort := tools.RandomInt(80, 89) + toPort := tools.RandomInt(90, 99) + + sgRulesCreateOpts[i] = rules.CreateOpts{ + Description: description, + Direction: "ingress", + EtherType: "IPv4", + SecGroupID: secGroupID, + PortRangeMin: fromPort, + PortRangeMax: toPort, + Protocol: rules.ProtocolTCP, + } + } + + rules, err := rules.CreateBulk(context.TODO(), client, sgRulesCreateOpts).Extract() + if err != nil { + return rules, err + } + + for i, rule := range rules { + t.Logf("Created security group rule: %s", rule.ID) + + th.AssertEquals(t, sgRulesCreateOpts[i].SecGroupID, rule.SecGroupID) + th.AssertEquals(t, sgRulesCreateOpts[i].Description, rule.Description) + } + + return rules, nil +} + // DeleteSecurityGroup will delete a security group of a specified ID. // A fatal error will occur if the deletion failed. This works best as a // deferred function diff --git a/internal/acceptance/openstack/networking/v2/extensions/security_test.go b/internal/acceptance/openstack/networking/v2/extensions/security_test.go index 670735ec5e..8d855bbb0a 100644 --- a/internal/acceptance/openstack/networking/v2/extensions/security_test.go +++ b/internal/acceptance/openstack/networking/v2/extensions/security_test.go @@ -26,6 +26,12 @@ func TestSecurityGroupsCreateUpdateDelete(t *testing.T) { th.AssertNoErr(t, err) defer DeleteSecurityGroupRule(t, client, rule.ID) + rules, err := CreateSecurityGroupRulesBulk(t, client, group.ID) + th.AssertNoErr(t, err) + for _, r := range rules { + defer DeleteSecurityGroupRule(t, client, r.ID) + } + tools.PrintResource(t, group) var name = "Update group" diff --git a/openstack/networking/v2/extensions/security/rules/requests.go b/openstack/networking/v2/extensions/security/rules/requests.go index f2ea9f2d16..8976224b42 100644 --- a/openstack/networking/v2/extensions/security/rules/requests.go +++ b/openstack/networking/v2/extensions/security/rules/requests.go @@ -150,6 +150,23 @@ func Create(ctx context.Context, c *gophercloud.ServiceClient, opts CreateOptsBu return } +// CreateBulk is an operation which adds new security group rules and associates them +// with an existing security group (whose ID is specified in CreateOpts). +// As of Dalmatian (2024.2) neutron only allows bulk creation of rules when +// they all belong to the same tenant and security group. +// https://github.com/openstack/neutron/blob/6183792/neutron/db/securitygroups_db.py#L814-L828 +func CreateBulk(ctx context.Context, c *gophercloud.ServiceClient, opts []CreateOpts) (r CreateBulkResult) { + body, err := gophercloud.BuildRequestBody(opts, "security_group_rules") + if err != nil { + r.Err = err + return + } + + resp, err := c.Post(ctx, rootURL(c), body, &r.Body, nil) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} + // Get retrieves a particular security group rule based on its unique ID. func Get(ctx context.Context, c *gophercloud.ServiceClient, id string) (r GetResult) { resp, err := c.Get(ctx, resourceURL(c, id), &r.Body, nil) diff --git a/openstack/networking/v2/extensions/security/rules/results.go b/openstack/networking/v2/extensions/security/rules/results.go index cfdb27fa17..0901ced578 100644 --- a/openstack/networking/v2/extensions/security/rules/results.go +++ b/openstack/networking/v2/extensions/security/rules/results.go @@ -103,6 +103,10 @@ type commonResult struct { gophercloud.Result } +type bulkResult struct { + gophercloud.Result +} + // Extract is a function that accepts a result and extracts a security rule. func (r commonResult) Extract() (*SecGroupRule, error) { var s struct { @@ -112,12 +116,27 @@ func (r commonResult) Extract() (*SecGroupRule, error) { return s.SecGroupRule, err } +// Extract is a function that accepts a result and extracts security rules. +func (r bulkResult) Extract() ([]SecGroupRule, error) { + var s struct { + SecGroupRules []SecGroupRule `json:"security_group_rules"` + } + err := r.ExtractInto(&s) + return s.SecGroupRules, err +} + // CreateResult represents the result of a create operation. Call its Extract // method to interpret it as a SecGroupRule. type CreateResult struct { commonResult } +// CreateBulkResult represents the result of a bulk create operation. Call its +// Extract method to interpret it as a slice of SecGroupRules. +type CreateBulkResult struct { + bulkResult +} + // GetResult represents the result of a get operation. Call its Extract // method to interpret it as a SecGroupRule. type GetResult struct { diff --git a/openstack/networking/v2/extensions/security/rules/testing/requests_test.go b/openstack/networking/v2/extensions/security/rules/testing/requests_test.go index 843d7eb202..10aa461908 100644 --- a/openstack/networking/v2/extensions/security/rules/testing/requests_test.go +++ b/openstack/networking/v2/extensions/security/rules/testing/requests_test.go @@ -222,6 +222,101 @@ func TestCreateAnyProtocol(t *testing.T) { th.AssertNoErr(t, err) } +func TestCreateBulk(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + + th.Mux.HandleFunc("/v2.0/security-group-rules", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "POST") + th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "Content-Type", "application/json") + th.TestHeader(t, r, "Accept", "application/json") + th.TestJSONRequest(t, r, ` +{ + "security_group_rules": [ + { + "description": "test description of rule", + "direction": "ingress", + "port_range_min": 80, + "ethertype": "IPv4", + "port_range_max": 80, + "protocol": "tcp", + "remote_group_id": "85cc3048-abc3-43cc-89b3-377341426ac5", + "security_group_id": "a7734e61-b545-452d-a3cd-0189cbd9747a" + }, + { + "description": "test description of rule", + "direction": "ingress", + "port_range_min": 443, + "ethertype": "IPv4", + "port_range_max": 443, + "protocol": "tcp", + "security_group_id": "a7734e61-b545-452d-a3cd-0189cbd9747a" + } + ] +} + `) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusCreated) + + fmt.Fprint(w, ` +{ + "security_group_rules": [ + { + "description": "test description of rule", + "direction": "ingress", + "ethertype": "IPv4", + "port_range_max": 80, + "port_range_min": 80, + "protocol": "tcp", + "remote_group_id": "85cc3048-abc3-43cc-89b3-377341426ac5", + "remote_ip_prefix": null, + "security_group_id": "a7734e61-b545-452d-a3cd-0189cbd9747a", + "tenant_id": "e4f50856753b4dc6afee5fa6b9b6c550" + }, + { + "description": "test description of rule", + "direction": "ingress", + "ethertype": "IPv4", + "port_range_max": 443, + "port_range_min": 443, + "protocol": "tcp", + "remote_group_id": null, + "remote_ip_prefix": null, + "security_group_id": "a7734e61-b545-452d-a3cd-0189cbd9747a", + "tenant_id": "e4f50856753b4dc6afee5fa6b9b6c550" + } + ] +} + `) + }) + + opts := []rules.CreateOpts{ + { + Description: "test description of rule", + Direction: "ingress", + PortRangeMin: 80, + EtherType: rules.EtherType4, + PortRangeMax: 80, + Protocol: "tcp", + RemoteGroupID: "85cc3048-abc3-43cc-89b3-377341426ac5", + SecGroupID: "a7734e61-b545-452d-a3cd-0189cbd9747a", + }, + { + Description: "test description of rule", + Direction: "ingress", + PortRangeMin: 443, + EtherType: rules.EtherType4, + PortRangeMax: 443, + Protocol: "tcp", + SecGroupID: "a7734e61-b545-452d-a3cd-0189cbd9747a", + }, + } + _, err := rules.CreateBulk(context.TODO(), fake.ServiceClient(), opts).Extract() + th.AssertNoErr(t, err) +} + func TestRequiredCreateOpts(t *testing.T) { res := rules.Create(context.TODO(), fake.ServiceClient(), rules.CreateOpts{Direction: rules.DirIngress}) if res.Err == nil { From 9158f73253184abfdb4a849aa0e82f2c25b270cb Mon Sep 17 00:00:00 2001 From: Paul des Garets Date: Fri, 29 Apr 2022 12:59:55 +0200 Subject: [PATCH 077/353] ObjectStorage v1: Add Sync headers --- openstack/objectstorage/v1/containers/results.go | 2 ++ openstack/objectstorage/v1/containers/testing/fixtures.go | 2 ++ openstack/objectstorage/v1/containers/testing/requests_test.go | 2 ++ 3 files changed, 6 insertions(+) diff --git a/openstack/objectstorage/v1/containers/results.go b/openstack/objectstorage/v1/containers/results.go index 8e71c15063..fddfa26bf1 100644 --- a/openstack/objectstorage/v1/containers/results.go +++ b/openstack/objectstorage/v1/containers/results.go @@ -111,6 +111,8 @@ type GetHeader struct { TempURLKey2 string `json:"X-Container-Meta-Temp-URL-Key-2"` Timestamp float64 `json:"X-Timestamp,string"` VersionsEnabled bool `json:"-"` + SyncKey string `json:"X-Sync-Key"` + SyncTo string `json:"X-Sync-To"` } func (r *GetHeader) UnmarshalJSON(b []byte) error { diff --git a/openstack/objectstorage/v1/containers/testing/fixtures.go b/openstack/objectstorage/v1/containers/testing/fixtures.go index 55f4f723b6..35c0f734cf 100644 --- a/openstack/objectstorage/v1/containers/testing/fixtures.go +++ b/openstack/objectstorage/v1/containers/testing/fixtures.go @@ -258,6 +258,8 @@ func HandleGetContainerSuccessfully(t *testing.T, options ...option) { w.Header().Set("X-Trans-Id", "tx554ed59667a64c61866f1-0057b4ba37") w.Header().Set("X-Storage-Policy", "test_policy") w.Header().Set("X-Versions-Enabled", "True") + w.Header().Set("X-Sync-Key", "272465181849") + w.Header().Set("X-Sync-To", "anotherContainer") w.WriteHeader(http.StatusNoContent) }) } diff --git a/openstack/objectstorage/v1/containers/testing/requests_test.go b/openstack/objectstorage/v1/containers/testing/requests_test.go index 9a2074d510..fedf0f2fe6 100644 --- a/openstack/objectstorage/v1/containers/testing/requests_test.go +++ b/openstack/objectstorage/v1/containers/testing/requests_test.go @@ -244,6 +244,8 @@ func TestGetContainer(t *testing.T) { StoragePolicy: "test_policy", Timestamp: 1471298837.95721, VersionsEnabled: true, + SyncKey: "272465181849", + SyncTo: "anotherContainer", } actual, err := res.Extract() th.AssertNoErr(t, err) From 39e8a0aef26fed0f6fbbc0e0a22d1919454af344 Mon Sep 17 00:00:00 2001 From: Paul des Garets Date: Fri, 29 Apr 2022 13:00:13 +0200 Subject: [PATCH 078/353] Compute v2: Add locked status --- openstack/compute/v2/servers/results.go | 4 ++++ openstack/compute/v2/servers/testing/fixtures_test.go | 7 +++++-- openstack/compute/v2/servers/testing/requests_test.go | 2 ++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/openstack/compute/v2/servers/results.go b/openstack/compute/v2/servers/results.go index dc51564176..385001c8dd 100644 --- a/openstack/compute/v2/servers/results.go +++ b/openstack/compute/v2/servers/results.go @@ -279,6 +279,10 @@ type Server struct { // AvailabilityZone is the availabilty zone the server is in. AvailabilityZone string `json:"OS-EXT-AZ:availability_zone"` + + // Locked indicates the lock status of the server + // This requires microversion 2.9 or later + Locked *bool `json:"locked"` } type AttachedVolume struct { diff --git a/openstack/compute/v2/servers/testing/fixtures_test.go b/openstack/compute/v2/servers/testing/fixtures_test.go index 1c25b40074..a9c3980d88 100644 --- a/openstack/compute/v2/servers/testing/fixtures_test.go +++ b/openstack/compute/v2/servers/testing/fixtures_test.go @@ -158,7 +158,8 @@ const ServerListBody = ` "progress": 0, "OS-EXT-STS:power_state": 1, "config_drive": "", - "metadata": {} + "metadata": {}, + "locked": true }, { "status": "ACTIVE", @@ -297,7 +298,8 @@ const SingleServerBody = ` "progress": 0, "OS-EXT-STS:power_state": 1, "config_drive": "", - "metadata": {} + "metadata": {}, + "locked": true } } ` @@ -631,6 +633,7 @@ var ( TerminatedAt: time.Time{}, DiskConfig: servers.Manual, AvailabilityZone: "nova", + Locked: func() *bool { b := true; return &b }(), } ConsoleOutput = "abc" diff --git a/openstack/compute/v2/servers/testing/requests_test.go b/openstack/compute/v2/servers/testing/requests_test.go index b6ebefce5e..b50ea185c9 100644 --- a/openstack/compute/v2/servers/testing/requests_test.go +++ b/openstack/compute/v2/servers/testing/requests_test.go @@ -774,6 +774,7 @@ func TestGetFaultyServer(t *testing.T) { FaultyServer := ServerDerp FaultyServer.Fault = DerpFault + FaultyServer.Locked = nil th.CheckDeepEquals(t, FaultyServer, *actual) } @@ -1145,6 +1146,7 @@ func TestCreateServerWithTags(t *testing.T) { tags := []string{"foo", "bar"} ServerDerpTags := ServerDerp ServerDerpTags.Tags = &tags + ServerDerpTags.Locked = nil createOpts := servers.CreateOpts{ Name: "derp", From 271026c9d62cd620347e353bef35326d6359f4ae Mon Sep 17 00:00:00 2001 From: Pierre Prinetti Date: Tue, 10 Dec 2024 16:43:12 +0100 Subject: [PATCH 079/353] Prepare v2.4.0 --- CHANGELOG.md | 5 +++++ provider_client.go | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2520ac743b..859a950867 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## v2.4.0 (2024-12-18) + +* [GH-3270](https://github.com/gophercloud/gophercloud/pull/3270) [v2] SG rules: implement bulk create +* [GH-3273](https://github.com/gophercloud/gophercloud/pull/3273) [v2] Add missing fields in Objectstorage and compute API + ## v2.3.0 (2024-12-06) * [GH-3213](https://github.com/gophercloud/gophercloud/pull/3213) [v2] Handle nova api version > 2.87 for hypervisor diff --git a/provider_client.go b/provider_client.go index 26c925ceff..ad3edc92d6 100644 --- a/provider_client.go +++ b/provider_client.go @@ -13,7 +13,7 @@ import ( // DefaultUserAgent is the default User-Agent string set in the request header. const ( - DefaultUserAgent = "gophercloud/v2.3.0" + DefaultUserAgent = "gophercloud/v2.4.0" DefaultMaxBackoffRetries = 60 ) From b44fe9e135a100c4ed90925561f30cf5ac364254 Mon Sep 17 00:00:00 2001 From: Pierre Prinetti Date: Sun, 22 Dec 2024 17:26:48 +0100 Subject: [PATCH 080/353] test: Ensure that randomly created secgroup rules don't conflict --- .../openstack/networking/v2/extensions/extensions.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/acceptance/openstack/networking/v2/extensions/extensions.go b/internal/acceptance/openstack/networking/v2/extensions/extensions.go index 535bd950ab..f50878abeb 100644 --- a/internal/acceptance/openstack/networking/v2/extensions/extensions.go +++ b/internal/acceptance/openstack/networking/v2/extensions/extensions.go @@ -149,8 +149,8 @@ func CreateSecurityGroupRulesBulk(t *testing.T, client *gophercloud.ServiceClien sgRulesCreateOpts := make([]rules.CreateOpts, 3) for i := range 3 { description := "Rule description" - fromPort := tools.RandomInt(80, 89) - toPort := tools.RandomInt(90, 99) + fromPort := tools.RandomInt(1080, 1089) + toPort := tools.RandomInt(1090, 1099) sgRulesCreateOpts[i] = rules.CreateOpts{ Description: description, From c10137018d0009f24075c5560e454cd97e7be43c Mon Sep 17 00:00:00 2001 From: Nobuhiro MIKI Date: Fri, 19 Jan 2024 07:29:18 +0000 Subject: [PATCH 081/353] Fix panic in ExtractIntoStructPtr and ExtractIntoSlicePtr MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Passing nil as an argument to 'ExtractIntoStructPtr' or 'ExtractIntoSlicePtr' causes "panic: runtime error: invalid memory address or nil pointer dereference". This is an invalid argument and should be corrected to return an error. For reference, standard package functions such as 'json.Unmarshal' return an error instead of panic. Signed-off-by: Nobuhiro MIKI Co-authored-by: pýrus --- results.go | 18 ++++++++++++++++++ testing/results_test.go | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/results.go b/results.go index 9e6f630abb..b12c15a026 100644 --- a/results.go +++ b/results.go @@ -184,10 +184,19 @@ func (r Result) ExtractIntoStructPtr(to any, label string) error { return r.Err } + if to == nil { + return fmt.Errorf("Expected pointer, got %T", to) + } + t := reflect.TypeOf(to) if k := t.Kind(); k != reflect.Ptr { return fmt.Errorf("Expected pointer, got %v", k) } + + if reflect.ValueOf(to).IsNil() { + return fmt.Errorf("Expected pointer, got %T", to) + } + switch t.Elem().Kind() { case reflect.Struct: return r.extractIntoPtr(to, label) @@ -210,10 +219,19 @@ func (r Result) ExtractIntoSlicePtr(to any, label string) error { return r.Err } + if to == nil { + return fmt.Errorf("Expected pointer, got %T", to) + } + t := reflect.TypeOf(to) if k := t.Kind(); k != reflect.Ptr { return fmt.Errorf("Expected pointer, got %v", k) } + + if reflect.ValueOf(to).IsNil() { + return fmt.Errorf("Expected pointer, got %T", to) + } + switch t.Elem().Kind() { case reflect.Slice: return r.extractIntoPtr(to, label) diff --git a/testing/results_test.go b/testing/results_test.go index 21ef44c802..51ba60499b 100644 --- a/testing/results_test.go +++ b/testing/results_test.go @@ -113,6 +113,40 @@ func TestUnmarshalAnonymousStructs(t *testing.T) { th.AssertEquals(t, "Canada unmarshalled", actual.Location) } +func TestUnmarshalNilStruct(t *testing.T) { + var x *TestPerson + var y TestPerson + + err1 := gophercloud.Result{}.ExtractIntoStructPtr(&x, "") + err2 := gophercloud.Result{}.ExtractIntoStructPtr(nil, "") + err3 := gophercloud.Result{}.ExtractIntoStructPtr(y, "") + err4 := gophercloud.Result{}.ExtractIntoStructPtr(&y, "") + err5 := gophercloud.Result{}.ExtractIntoStructPtr(x, "") + + th.AssertErr(t, err1) + th.AssertErr(t, err2) + th.AssertErr(t, err3) + th.AssertNoErr(t, err4) + th.AssertErr(t, err5) +} + +func TestUnmarshalNilSlice(t *testing.T) { + var x *[]TestPerson + var y []TestPerson + + err1 := gophercloud.Result{}.ExtractIntoSlicePtr(&x, "") + err2 := gophercloud.Result{}.ExtractIntoSlicePtr(nil, "") + err3 := gophercloud.Result{}.ExtractIntoSlicePtr(y, "") + err4 := gophercloud.Result{}.ExtractIntoSlicePtr(&y, "") + err5 := gophercloud.Result{}.ExtractIntoSlicePtr(x, "") + + th.AssertErr(t, err1) + th.AssertErr(t, err2) + th.AssertErr(t, err3) + th.AssertNoErr(t, err4) + th.AssertErr(t, err5) +} + // TestUnmarshalSliceofAnonymousStructs tests if UnmarshalJSON is called on each // of the anonymous structs contained in an overarching struct slice. func TestUnmarshalSliceOfAnonymousStructs(t *testing.T) { From a7e2d67549574b887daa686e51cdb7a543c6b5fa Mon Sep 17 00:00:00 2001 From: Pavlo Shchelokovskyy Date: Wed, 15 Jan 2025 15:28:38 +0200 Subject: [PATCH 082/353] Fix JSON field name hints in APIVersion structs `son:"status"` is not a valid hint for JSON (de/en)coder. --- openstack/loadbalancer/v2/apiversions/results.go | 2 +- openstack/networking/v2/apiversions/results.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/openstack/loadbalancer/v2/apiversions/results.go b/openstack/loadbalancer/v2/apiversions/results.go index 4d3d1ae222..11780a2a4d 100644 --- a/openstack/loadbalancer/v2/apiversions/results.go +++ b/openstack/loadbalancer/v2/apiversions/results.go @@ -5,7 +5,7 @@ import "github.com/gophercloud/gophercloud/v2/pagination" // APIVersion represents an API version for load balancer. It contains // the status of the API, and its unique ID. type APIVersion struct { - Status string `son:"status"` + Status string `json:"status"` ID string `json:"id"` } diff --git a/openstack/networking/v2/apiversions/results.go b/openstack/networking/v2/apiversions/results.go index 89f30152b2..90fac7347d 100644 --- a/openstack/networking/v2/apiversions/results.go +++ b/openstack/networking/v2/apiversions/results.go @@ -7,7 +7,7 @@ import ( // APIVersion represents an API version for Neutron. It contains the status of // the API, and its unique ID. type APIVersion struct { - Status string `son:"status"` + Status string `json:"status"` ID string `json:"id"` } From d59f0370af3e07736b40fa040f379fafa86b1575 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Andr=C3=A9?= Date: Tue, 4 Feb 2025 09:58:05 +0100 Subject: [PATCH 083/353] Add permissions to the label-issue workflow It needs write permissions on PRs as well otherwise it fails to runs. --- .github/workflows/label-issue.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/label-issue.yaml b/.github/workflows/label-issue.yaml index a1fbff16e0..45ab4cbe34 100644 --- a/.github/workflows/label-issue.yaml +++ b/.github/workflows/label-issue.yaml @@ -11,6 +11,7 @@ jobs: runs-on: ubuntu-latest permissions: issues: write + pull-requests: write steps: - run: gh issue edit "$NUMBER" --remove-label "needinfo" env: From bd09bac26c02f52cab666eba1779e8970dc7c103 Mon Sep 17 00:00:00 2001 From: victorcam Date: Mon, 27 Jan 2025 16:59:37 +0100 Subject: [PATCH 084/353] Add support for zone sharing in DNS v2 This commit introduces functionality to share and unshare DNS zones with other projects using the OpenStack DNS v2 API. The following changes are included: - Added `Share` and `Unshare` methods in `requests.go` to handle API calls. - Updated `results.go` to include parsing for share/unshare responses. - Enhanced `urls.go` to generate proper URLs for share-related operations. - Created unit tests in `requests_test.go` to validate `Share` and `Unshare`. These additions allow users to manage shared zones programmatically and align Gophercloud with the DNS v2 API capabilities. --- openstack/dns/v2/zones/requests.go | 36 ++++++++- openstack/dns/v2/zones/results.go | 5 ++ .../dns/v2/zones/testing/requests_test.go | 73 +++++++++++++++++++ openstack/dns/v2/zones/urls.go | 4 +- 4 files changed, 113 insertions(+), 5 deletions(-) diff --git a/openstack/dns/v2/zones/requests.go b/openstack/dns/v2/zones/requests.go index fba4371ced..835e31bfed 100644 --- a/openstack/dns/v2/zones/requests.go +++ b/openstack/dns/v2/zones/requests.go @@ -57,7 +57,7 @@ func List(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pa // Get returns information about a zone, given its ID. func Get(ctx context.Context, client *gophercloud.ServiceClient, zoneID string) (r GetResult) { - resp, err := client.Get(ctx, zoneURL(client, zoneID), &r.Body, nil) + resp, err := client.Get(ctx, ZoneURL(client, zoneID), &r.Body, nil) _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) return } @@ -162,7 +162,7 @@ func Update(ctx context.Context, client *gophercloud.ServiceClient, zoneID strin r.Err = err return } - resp, err := client.Patch(ctx, zoneURL(client, zoneID), &b, &r.Body, &gophercloud.RequestOpts{ + resp, err := client.Patch(ctx, ZoneURL(client, zoneID), &b, &r.Body, &gophercloud.RequestOpts{ OkCodes: []int{200, 202}, }) _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) @@ -171,10 +171,40 @@ func Update(ctx context.Context, client *gophercloud.ServiceClient, zoneID strin // Delete implements a zone delete request. func Delete(ctx context.Context, client *gophercloud.ServiceClient, zoneID string) (r DeleteResult) { - resp, err := client.Delete(ctx, zoneURL(client, zoneID), &gophercloud.RequestOpts{ + resp, err := client.Delete(ctx, ZoneURL(client, zoneID), &gophercloud.RequestOpts{ OkCodes: []int{202}, JSONResponse: &r.Body, }) _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) return } + +// ShareZoneOpts specifies the target project for sharing a zone. +type ShareZoneOpts struct { + // TargetProjectID is the ID of the project to share the zone with. + TargetProjectID string `json:"target_project_id" required:"true"` +} + +// Share shares a zone with another project. +func Share(ctx context.Context, client *gophercloud.ServiceClient, zoneID string, opts ShareZoneOpts) (r gophercloud.ErrResult) { + body, err := gophercloud.BuildRequestBody(opts, "") + if err != nil { + r.Err = err + return + } + + resp, err := client.Post(ctx, ZoneURL(client, zoneID, "shares"), body, nil, &gophercloud.RequestOpts{ + OkCodes: []int{202}, + }) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} + +// Unshare removes a share for a zone. +func Unshare(ctx context.Context, client *gophercloud.ServiceClient, zoneID, shareID string) (r gophercloud.ErrResult) { + resp, err := client.Delete(ctx, ZoneURL(client, zoneID, "shares", shareID), &gophercloud.RequestOpts{ + OkCodes: []int{202}, + }) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} diff --git a/openstack/dns/v2/zones/results.go b/openstack/dns/v2/zones/results.go index ae2f27dbc5..7ccf5ace9b 100644 --- a/openstack/dns/v2/zones/results.go +++ b/openstack/dns/v2/zones/results.go @@ -50,6 +50,11 @@ type ZonePage struct { pagination.LinkedPageBase } +// ErrResult represents a generic error result. +type ErrResult struct { + gophercloud.ErrResult +} + // IsEmpty returns true if the page contains no results. func (r ZonePage) IsEmpty() (bool, error) { if r.StatusCode == 204 { diff --git a/openstack/dns/v2/zones/testing/requests_test.go b/openstack/dns/v2/zones/testing/requests_test.go index 0b64e81ecf..554694a6f6 100644 --- a/openstack/dns/v2/zones/testing/requests_test.go +++ b/openstack/dns/v2/zones/testing/requests_test.go @@ -2,8 +2,12 @@ package testing import ( "context" + "encoding/json" + "io" + "net/http" "testing" + "github.com/gophercloud/gophercloud/v2" "github.com/gophercloud/gophercloud/v2/openstack/dns/v2/zones" "github.com/gophercloud/gophercloud/v2/pagination" th "github.com/gophercloud/gophercloud/v2/testhelper" @@ -105,3 +109,72 @@ func TestDelete(t *testing.T) { th.AssertNoErr(t, err) th.CheckDeepEquals(t, &DeletedZone, actual) } + +func TestZoneURL(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + + client := &gophercloud.ServiceClient{ + ProviderClient: &gophercloud.ProviderClient{}, + Endpoint: th.Endpoint(), + } + + url := zones.ZoneURL(client, "zone-id", "shares", "share-id") + expected := client.ServiceURL("zones", "zone-id", "shares", "share-id") + + if url != expected { + t.Fatalf("unexpected URL: got %s, expected %s", url, expected) + } +} + +func TestShareZone(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + + // Debugging: Print the mock server endpoint to ensure requests are routed correctly. + t.Logf("Mock server endpoint: %s", th.Endpoint()) + + // Mock handler for sharing a zone + th.Mux.HandleFunc("/zones/zone-id/shares", func(w http.ResponseWriter, r *http.Request) { + t.Logf("Received request at path: %s", r.URL.Path) + th.AssertEquals(t, r.Method, "POST") + + // Read and close the request body + body, err := io.ReadAll(r.Body) + defer r.Body.Close() + th.AssertNoErr(t, err) + + // Parse the body into a map for comparison + expectedBody := map[string]string{"target_project_id": "project-id"} + actualBody := map[string]string{} + err = json.Unmarshal(body, &actualBody) + th.AssertNoErr(t, err) + + // Assert that the request body matches the expected map + th.CheckDeepEquals(t, expectedBody, actualBody) + + w.WriteHeader(http.StatusAccepted) + }) + + client := client.ServiceClient() + + opts := zones.ShareZoneOpts{TargetProjectID: "project-id"} + err := zones.Share(context.TODO(), client, "zone-id", opts).ExtractErr() + th.AssertNoErr(t, err) +} + +func TestUnshareZone(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + + // Mock handler for unsharing a zone + th.Mux.HandleFunc("/zones/zone-id/shares/share-id", func(w http.ResponseWriter, r *http.Request) { + th.AssertEquals(t, r.Method, "DELETE") + w.WriteHeader(http.StatusAccepted) + }) + + client := client.ServiceClient() + + err := zones.Unshare(context.TODO(), client, "zone-id", "share-id").ExtractErr() + th.AssertNoErr(t, err) +} diff --git a/openstack/dns/v2/zones/urls.go b/openstack/dns/v2/zones/urls.go index d157b30ef3..df574de918 100644 --- a/openstack/dns/v2/zones/urls.go +++ b/openstack/dns/v2/zones/urls.go @@ -6,6 +6,6 @@ func baseURL(c *gophercloud.ServiceClient) string { return c.ServiceURL("zones") } -func zoneURL(c *gophercloud.ServiceClient, zoneID string) string { - return c.ServiceURL("zones", zoneID) +func ZoneURL(client *gophercloud.ServiceClient, parts ...string) string { + return client.ServiceURL(append([]string{"zones"}, parts...)...) } From 979e4c8ade766893c4b491e7e14622cb681d2c97 Mon Sep 17 00:00:00 2001 From: victorcam Date: Fri, 7 Feb 2025 10:07:48 +0100 Subject: [PATCH 085/353] opts builder support, URL helpers & status code corrections --- openstack/dns/v2/zones/requests.go | 28 +++++++--- .../dns/v2/zones/testing/requests_test.go | 52 ++++--------------- openstack/dns/v2/zones/urls.go | 16 +++++- 3 files changed, 44 insertions(+), 52 deletions(-) diff --git a/openstack/dns/v2/zones/requests.go b/openstack/dns/v2/zones/requests.go index 835e31bfed..b8ac4cf8a5 100644 --- a/openstack/dns/v2/zones/requests.go +++ b/openstack/dns/v2/zones/requests.go @@ -57,7 +57,7 @@ func List(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pa // Get returns information about a zone, given its ID. func Get(ctx context.Context, client *gophercloud.ServiceClient, zoneID string) (r GetResult) { - resp, err := client.Get(ctx, ZoneURL(client, zoneID), &r.Body, nil) + resp, err := client.Get(ctx, zoneURL(client, zoneID), &r.Body, nil) _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) return } @@ -162,7 +162,7 @@ func Update(ctx context.Context, client *gophercloud.ServiceClient, zoneID strin r.Err = err return } - resp, err := client.Patch(ctx, ZoneURL(client, zoneID), &b, &r.Body, &gophercloud.RequestOpts{ + resp, err := client.Patch(ctx, zoneURL(client, zoneID), &b, &r.Body, &gophercloud.RequestOpts{ OkCodes: []int{200, 202}, }) _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) @@ -171,7 +171,7 @@ func Update(ctx context.Context, client *gophercloud.ServiceClient, zoneID strin // Delete implements a zone delete request. func Delete(ctx context.Context, client *gophercloud.ServiceClient, zoneID string) (r DeleteResult) { - resp, err := client.Delete(ctx, ZoneURL(client, zoneID), &gophercloud.RequestOpts{ + resp, err := client.Delete(ctx, zoneURL(client, zoneID), &gophercloud.RequestOpts{ OkCodes: []int{202}, JSONResponse: &r.Body, }) @@ -179,22 +179,34 @@ func Delete(ctx context.Context, client *gophercloud.ServiceClient, zoneID strin return } +// request body for sharing a zone. +type ShareOptsBuilder interface { + ToShareMap() (map[string]interface{}, error) +} + // ShareZoneOpts specifies the target project for sharing a zone. type ShareZoneOpts struct { // TargetProjectID is the ID of the project to share the zone with. TargetProjectID string `json:"target_project_id" required:"true"` } +// ToShareMap constructs a request body from a ShareZoneOpts. +func (opts ShareZoneOpts) ToShareMap() (map[string]interface{}, error) { + return map[string]interface{}{ + "target_project_id": opts.TargetProjectID, + }, nil +} + // Share shares a zone with another project. -func Share(ctx context.Context, client *gophercloud.ServiceClient, zoneID string, opts ShareZoneOpts) (r gophercloud.ErrResult) { +func Share(ctx context.Context, client *gophercloud.ServiceClient, zoneID string, opts ShareOptsBuilder) (r gophercloud.ErrResult) { body, err := gophercloud.BuildRequestBody(opts, "") if err != nil { r.Err = err return } - resp, err := client.Post(ctx, ZoneURL(client, zoneID, "shares"), body, nil, &gophercloud.RequestOpts{ - OkCodes: []int{202}, + resp, err := client.Post(ctx, zoneShareURL(client, zoneID), body, nil, &gophercloud.RequestOpts{ + OkCodes: []int{201}, }) _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) return @@ -202,8 +214,8 @@ func Share(ctx context.Context, client *gophercloud.ServiceClient, zoneID string // Unshare removes a share for a zone. func Unshare(ctx context.Context, client *gophercloud.ServiceClient, zoneID, shareID string) (r gophercloud.ErrResult) { - resp, err := client.Delete(ctx, ZoneURL(client, zoneID, "shares", shareID), &gophercloud.RequestOpts{ - OkCodes: []int{202}, + resp, err := client.Delete(ctx, zoneUnshareURL(client, zoneID, shareID), &gophercloud.RequestOpts{ + OkCodes: []int{204}, }) _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) return diff --git a/openstack/dns/v2/zones/testing/requests_test.go b/openstack/dns/v2/zones/testing/requests_test.go index 554694a6f6..b75b99e967 100644 --- a/openstack/dns/v2/zones/testing/requests_test.go +++ b/openstack/dns/v2/zones/testing/requests_test.go @@ -7,7 +7,6 @@ import ( "net/http" "testing" - "github.com/gophercloud/gophercloud/v2" "github.com/gophercloud/gophercloud/v2/openstack/dns/v2/zones" "github.com/gophercloud/gophercloud/v2/pagination" th "github.com/gophercloud/gophercloud/v2/testhelper" @@ -110,71 +109,40 @@ func TestDelete(t *testing.T) { th.CheckDeepEquals(t, &DeletedZone, actual) } -func TestZoneURL(t *testing.T) { +func TestShare(t *testing.T) { th.SetupHTTP() defer th.TeardownHTTP() - client := &gophercloud.ServiceClient{ - ProviderClient: &gophercloud.ProviderClient{}, - Endpoint: th.Endpoint(), - } - - url := zones.ZoneURL(client, "zone-id", "shares", "share-id") - expected := client.ServiceURL("zones", "zone-id", "shares", "share-id") - - if url != expected { - t.Fatalf("unexpected URL: got %s, expected %s", url, expected) - } -} - -func TestShareZone(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - // Debugging: Print the mock server endpoint to ensure requests are routed correctly. - t.Logf("Mock server endpoint: %s", th.Endpoint()) - - // Mock handler for sharing a zone th.Mux.HandleFunc("/zones/zone-id/shares", func(w http.ResponseWriter, r *http.Request) { - t.Logf("Received request at path: %s", r.URL.Path) th.AssertEquals(t, r.Method, "POST") - // Read and close the request body body, err := io.ReadAll(r.Body) defer r.Body.Close() th.AssertNoErr(t, err) - // Parse the body into a map for comparison - expectedBody := map[string]string{"target_project_id": "project-id"} - actualBody := map[string]string{} - err = json.Unmarshal(body, &actualBody) + var reqBody map[string]string + err = json.Unmarshal(body, &reqBody) th.AssertNoErr(t, err) + expectedBody := map[string]string{"target_project_id": "project-id"} + th.CheckDeepEquals(t, expectedBody, reqBody) - // Assert that the request body matches the expected map - th.CheckDeepEquals(t, expectedBody, actualBody) - - w.WriteHeader(http.StatusAccepted) + w.WriteHeader(http.StatusCreated) }) - client := client.ServiceClient() - opts := zones.ShareZoneOpts{TargetProjectID: "project-id"} - err := zones.Share(context.TODO(), client, "zone-id", opts).ExtractErr() + err := zones.Share(context.TODO(), client.ServiceClient(), "zone-id", opts).ExtractErr() th.AssertNoErr(t, err) } -func TestUnshareZone(t *testing.T) { +func TestUnshare(t *testing.T) { th.SetupHTTP() defer th.TeardownHTTP() - // Mock handler for unsharing a zone th.Mux.HandleFunc("/zones/zone-id/shares/share-id", func(w http.ResponseWriter, r *http.Request) { th.AssertEquals(t, r.Method, "DELETE") - w.WriteHeader(http.StatusAccepted) + w.WriteHeader(http.StatusNoContent) }) - client := client.ServiceClient() - - err := zones.Unshare(context.TODO(), client, "zone-id", "share-id").ExtractErr() + err := zones.Unshare(context.TODO(), client.ServiceClient(), "zone-id", "share-id").ExtractErr() th.AssertNoErr(t, err) } diff --git a/openstack/dns/v2/zones/urls.go b/openstack/dns/v2/zones/urls.go index df574de918..ba156882f8 100644 --- a/openstack/dns/v2/zones/urls.go +++ b/openstack/dns/v2/zones/urls.go @@ -2,10 +2,22 @@ package zones import "github.com/gophercloud/gophercloud/v2" +// baseURL returns the base URL for zones. func baseURL(c *gophercloud.ServiceClient) string { return c.ServiceURL("zones") } -func ZoneURL(client *gophercloud.ServiceClient, parts ...string) string { - return client.ServiceURL(append([]string{"zones"}, parts...)...) +// zoneURL returns the URL for a specific zone. +func zoneURL(c *gophercloud.ServiceClient, zoneID string) string { + return c.ServiceURL("zones", zoneID) +} + +// zoneShareURL returns the URL for sharing a zone. +func zoneShareURL(c *gophercloud.ServiceClient, zoneID string) string { + return c.ServiceURL("zones", zoneID, "shares") +} + +// zoneUnshareURL returns the URL for unsharing a zone. +func zoneUnshareURL(c *gophercloud.ServiceClient, zoneID, shareID string) string { + return c.ServiceURL("zones", zoneID, "shares", shareID) } From a1ae0ef3acc7aeacc0a29790a82cb85cac0e9db3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 12 Dec 2024 14:27:03 +0000 Subject: [PATCH 086/353] build(deps): bump golang.org/x/crypto from 0.30.0 to 0.31.0 Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.30.0 to 0.31.0. - [Commits](https://github.com/golang/crypto/compare/v0.30.0...v0.31.0) --- updated-dependencies: - dependency-name: golang.org/x/crypto dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index dc5d92e323..3c5d9e0e23 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/gophercloud/gophercloud/v2 go 1.22 require ( - golang.org/x/crypto v0.30.0 + golang.org/x/crypto v0.31.0 gopkg.in/yaml.v2 v2.4.0 ) diff --git a/go.sum b/go.sum index 1812f7828d..428bb87959 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY= -golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= From 90d046de7b7f3ad035785afb3eb101d849d1d94f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 7 Jan 2025 09:38:59 +0000 Subject: [PATCH 087/353] build(deps): bump golang.org/x/crypto from 0.31.0 to 0.32.0 Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.31.0 to 0.32.0. - [Commits](https://github.com/golang/crypto/compare/v0.31.0...v0.32.0) --- updated-dependencies: - dependency-name: golang.org/x/crypto dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 4 ++-- go.sum | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/go.mod b/go.mod index 3c5d9e0e23..92836172ef 100644 --- a/go.mod +++ b/go.mod @@ -3,8 +3,8 @@ module github.com/gophercloud/gophercloud/v2 go 1.22 require ( - golang.org/x/crypto v0.31.0 + golang.org/x/crypto v0.32.0 gopkg.in/yaml.v2 v2.4.0 ) -require golang.org/x/sys v0.28.0 // indirect +require golang.org/x/sys v0.29.0 // indirect diff --git a/go.sum b/go.sum index 428bb87959..355c39493f 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,9 @@ -golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= -golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= -golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= -golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= -golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= +golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= +golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= +golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= +golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg= +golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= From 9f44fd8fdb1640111bcbd29fa2fc5d2cf0753947 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Feb 2025 09:27:31 +0000 Subject: [PATCH 088/353] build(deps): bump golang.org/x/crypto from 0.32.0 to 0.33.0 Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.32.0 to 0.33.0. - [Commits](https://github.com/golang/crypto/compare/v0.32.0...v0.33.0) --- updated-dependencies: - dependency-name: golang.org/x/crypto dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 4 ++-- go.sum | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/go.mod b/go.mod index 92836172ef..ac4634f884 100644 --- a/go.mod +++ b/go.mod @@ -3,8 +3,8 @@ module github.com/gophercloud/gophercloud/v2 go 1.22 require ( - golang.org/x/crypto v0.32.0 + golang.org/x/crypto v0.33.0 gopkg.in/yaml.v2 v2.4.0 ) -require golang.org/x/sys v0.29.0 // indirect +require golang.org/x/sys v0.30.0 // indirect diff --git a/go.sum b/go.sum index 355c39493f..0bfa14296f 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,9 @@ -golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= -golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= -golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= -golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg= -golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek= +golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus= +golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M= +golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= +golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU= +golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= From 477294fc2b55727157c67cbfff8662f5c8ef4169 Mon Sep 17 00:00:00 2001 From: Pierre Prinetti Date: Tue, 11 Feb 2025 11:34:03 +0100 Subject: [PATCH 089/353] Prepare v2.5.0 --- CHANGELOG.md | 11 +++++++++++ provider_client.go | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 859a950867..2cfef4fd82 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,14 @@ +## v2.5.0 (2025-02-11) + +* [GH-3278](https://github.com/gophercloud/gophercloud/pull/3278) [v2] test: Ensure that randomly created secgroup rules don't conflict +* [GH-3287](https://github.com/gophercloud/gophercloud/pull/3287) [v2] Fix panic in ExtractIntoStructPtr +* [GH-3288](https://github.com/gophercloud/gophercloud/pull/3288) [v2] Fix JSON field name hints in APIVersion structs +* [GH-3292](https://github.com/gophercloud/gophercloud/pull/3292) [v2] Add permissions to the label-issue workflow +* [GH-3294](https://github.com/gophercloud/gophercloud/pull/3294) [v2] Add support for zone sharing in DNS v2 +* [GH-3296](https://github.com/gophercloud/gophercloud/pull/3296) build(deps): bump golang.org/x/crypto from 0.30.0 to 0.31.0 +* [GH-3297](https://github.com/gophercloud/gophercloud/pull/3297) [v2] build(deps): bump golang.org/x/crypto from 0.31.0 to 0.32.0 +* [GH-3298](https://github.com/gophercloud/gophercloud/pull/3298) [v2] build(deps): bump golang.org/x/crypto from 0.32.0 to 0.33.0 + ## v2.4.0 (2024-12-18) * [GH-3270](https://github.com/gophercloud/gophercloud/pull/3270) [v2] SG rules: implement bulk create diff --git a/provider_client.go b/provider_client.go index ad3edc92d6..2d52c73326 100644 --- a/provider_client.go +++ b/provider_client.go @@ -13,7 +13,7 @@ import ( // DefaultUserAgent is the default User-Agent string set in the request header. const ( - DefaultUserAgent = "gophercloud/v2.4.0" + DefaultUserAgent = "gophercloud/v2.5.0" DefaultMaxBackoffRetries = 60 ) From ef79b92df4bb70f41ed0ed1e454294ae9c3af9fd Mon Sep 17 00:00:00 2001 From: chuliang Date: Mon, 4 Sep 2023 13:56:18 +0000 Subject: [PATCH 090/353] identity: Add Get endpoint by ID Co-Authored-By: chuliang Co-Authored-By: Pierre Prinetti Co-Authored-By: Stephen Finucane --- .../openstack/identity/v3/endpoint_test.go | 23 +++ openstack/identity/v3/endpoints/requests.go | 7 + openstack/identity/v3/endpoints/results.go | 6 + .../v3/endpoints/testing/requests_test.go | 169 +++++++++++------- openstack/identity/v3/projects/doc.go | 2 +- 5 files changed, 137 insertions(+), 70 deletions(-) diff --git a/internal/acceptance/openstack/identity/v3/endpoint_test.go b/internal/acceptance/openstack/identity/v3/endpoint_test.go index ae2254102a..8dd9e5bad1 100644 --- a/internal/acceptance/openstack/identity/v3/endpoint_test.go +++ b/internal/acceptance/openstack/identity/v3/endpoint_test.go @@ -39,6 +39,29 @@ func TestEndpointsList(t *testing.T) { th.AssertEquals(t, found, true) } +func TestEndpointsGet(t *testing.T) { + clients.RequireAdmin(t) + + client, err := clients.NewIdentityV3Client() + th.AssertNoErr(t, err) + + allPages, err := endpoints.List(client, nil).AllPages(context.TODO()) + th.AssertNoErr(t, err) + + allEndpoints, err := endpoints.ExtractEndpoints(allPages) + th.AssertNoErr(t, err) + + endpoint := allEndpoints[0] + e, err := endpoints.Get(context.TODO(), client, endpoint.ID).Extract() + if err != nil { + t.Fatalf("Unable to get endpoint: %v", err) + } + + tools.PrintResource(t, e) + + th.AssertEquals(t, e.Name, e.Name) +} + func TestEndpointsNavigateCatalog(t *testing.T) { clients.RequireAdmin(t) diff --git a/openstack/identity/v3/endpoints/requests.go b/openstack/identity/v3/endpoints/requests.go index 35eb966077..4386bb9bc9 100644 --- a/openstack/identity/v3/endpoints/requests.go +++ b/openstack/identity/v3/endpoints/requests.go @@ -90,6 +90,13 @@ func List(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pa }) } +// Get retrieves details on a single endpoint, by ID. +func Get(ctx context.Context, client *gophercloud.ServiceClient, id string) (r GetResult) { + resp, err := client.Get(ctx, endpointURL(client, id), &r.Body, nil) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} + // UpdateOptsBuilder allows extensions to add parameters to the Update request. type UpdateOptsBuilder interface { ToEndpointUpdateMap() (map[string]any, error) diff --git a/openstack/identity/v3/endpoints/results.go b/openstack/identity/v3/endpoints/results.go index 9efec30af2..19d279ebc6 100644 --- a/openstack/identity/v3/endpoints/results.go +++ b/openstack/identity/v3/endpoints/results.go @@ -19,6 +19,12 @@ func (r commonResult) Extract() (*Endpoint, error) { return s.Endpoint, err } +// GetResult is the response from a Get operation. Call its Extract method +// to interpret it as an Endpoint. +type GetResult struct { + commonResult +} + // CreateResult is the response from a Create operation. Call its Extract // method to interpret it as an Endpoint. type CreateResult struct { diff --git a/openstack/identity/v3/endpoints/testing/requests_test.go b/openstack/identity/v3/endpoints/testing/requests_test.go index 348a1f1c6e..ad138acd49 100644 --- a/openstack/identity/v3/endpoints/testing/requests_test.go +++ b/openstack/identity/v3/endpoints/testing/requests_test.go @@ -20,35 +20,31 @@ func TestCreateSuccessful(t *testing.T) { th.Mux.HandleFunc("/endpoints", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - th.TestJSONRequest(t, r, ` - { - "endpoint": { - "interface": "public", - "name": "the-endiest-of-points", - "region": "underground", - "url": "https://1.2.3.4:9000/", - "service_id": "asdfasdfasdfasdf" - } - } - `) + th.TestJSONRequest(t, r, `{ + "endpoint": { + "interface": "public", + "name": "the-endiest-of-points", + "region": "underground", + "url": "https://1.2.3.4:9000/", + "service_id": "asdfasdfasdfasdf" + } + }`) w.WriteHeader(http.StatusCreated) - fmt.Fprint(w, ` - { - "endpoint": { - "id": "12", - "interface": "public", - "enabled": true, - "links": { - "self": "https://localhost:5000/v3/endpoints/12" - }, - "name": "the-endiest-of-points", - "region": "underground", - "service_id": "asdfasdfasdfasdf", - "url": "https://1.2.3.4:9000/" - } - } - `) + fmt.Fprint(w, `{ + "endpoint": { + "id": "12", + "interface": "public", + "enabled": true, + "links": { + "self": "https://localhost:5000/v3/endpoints/12" + }, + "name": "the-endiest-of-points", + "region": "underground", + "service_id": "asdfasdfasdfasdf", + "url": "https://1.2.3.4:9000/" + } + }`) }) actual, err := endpoints.Create(context.TODO(), client.ServiceClient(), endpoints.CreateOpts{ @@ -82,40 +78,38 @@ func TestListEndpoints(t *testing.T) { th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") - fmt.Fprint(w, ` - { - "endpoints": [ - { - "id": "12", - "interface": "public", - "enabled": true, - "links": { - "self": "https://localhost:5000/v3/endpoints/12" - }, - "name": "the-endiest-of-points", - "region": "underground", - "service_id": "asdfasdfasdfasdf", - "url": "https://1.2.3.4:9000/" + fmt.Fprint(w, `{ + "endpoints": [ + { + "id": "12", + "interface": "public", + "enabled": true, + "links": { + "self": "https://localhost:5000/v3/endpoints/12" }, - { - "id": "13", - "interface": "internal", - "enabled": false, - "links": { - "self": "https://localhost:5000/v3/endpoints/13" - }, - "name": "shhhh", - "region": "underground", - "service_id": "asdfasdfasdfasdf", - "url": "https://1.2.3.4:9001/" - } - ], - "links": { - "next": null, - "previous": null + "name": "the-endiest-of-points", + "region": "underground", + "service_id": "asdfasdfasdfasdf", + "url": "https://1.2.3.4:9000/" + }, + { + "id": "13", + "interface": "internal", + "enabled": false, + "links": { + "self": "https://localhost:5000/v3/endpoints/13" + }, + "name": "shhhh", + "region": "underground", + "service_id": "asdfasdfasdfasdf", + "url": "https://1.2.3.4:9001/" } + ], + "links": { + "next": null, + "previous": null } - `) + }`) }) count := 0 @@ -154,6 +148,47 @@ func TestListEndpoints(t *testing.T) { th.AssertEquals(t, 1, count) } +func TestGetEndpoint(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + + th.Mux.HandleFunc("/endpoints/12", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + fmt.Fprint(w, `{ + "endpoint": { + "id": "12", + "interface": "public", + "enabled": true, + "links": { + "self": "https://localhost:5000/v3/endpoints/12" + }, + "name": "the-endiest-of-points", + "region": "underground", + "service_id": "asdfasdfasdfasdf", + "url": "https://1.2.3.4:9000/" + } + }`) + }) + + actual, err := endpoints.Get(context.TODO(), client.ServiceClient(), "12").Extract() + if err != nil { + t.Fatalf("Unexpected error from Get: %v", err) + } + + expected := &endpoints.Endpoint{ + ID: "12", + Availability: gophercloud.AvailabilityPublic, + Enabled: true, + Name: "the-endiest-of-points", + Region: "underground", + ServiceID: "asdfasdfasdfasdf", + URL: "https://1.2.3.4:9000/", + } + th.AssertDeepEquals(t, expected, actual) +} + func TestUpdateEndpoint(t *testing.T) { th.SetupHTTP() defer th.TeardownHTTP() @@ -161,17 +196,14 @@ func TestUpdateEndpoint(t *testing.T) { th.Mux.HandleFunc("/endpoints/12", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PATCH") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - th.TestJSONRequest(t, r, ` - { - "endpoint": { - "name": "renamed", + th.TestJSONRequest(t, r, `{ + "endpoint": { + "name": "renamed", "region": "somewhere-else" - } - } - `) + } + }`) - fmt.Fprint(w, ` - { + fmt.Fprint(w, `{ "endpoint": { "id": "12", "interface": "public", @@ -184,8 +216,7 @@ func TestUpdateEndpoint(t *testing.T) { "service_id": "asdfasdfasdfasdf", "url": "https://1.2.3.4:9000/" } - } - `) + }`) }) actual, err := endpoints.Update(context.TODO(), client.ServiceClient(), "12", endpoints.UpdateOpts{ diff --git a/openstack/identity/v3/projects/doc.go b/openstack/identity/v3/projects/doc.go index 6aea466a51..6100327397 100644 --- a/openstack/identity/v3/projects/doc.go +++ b/openstack/identity/v3/projects/doc.go @@ -73,7 +73,7 @@ Example to List all tags of a Project panic(err) } -Example to modify all tags of a Project +Example to modify all tags of a Project projectID := "966b3c7d36a24facaf20b7e458bf2192" tags := ["foo", "bar"] From e47eabd40a92c417433d67834648f352a2b43c69 Mon Sep 17 00:00:00 2001 From: ngin8-beta <77710475+ngin8-beta@users.noreply.github.com> Date: Thu, 13 Feb 2025 10:35:30 +0900 Subject: [PATCH 091/353] Added support for hypervisor_hostname (cherry picked from commit da9417f3358d56bae822ebb6386c70305b336d1c) --- openstack/compute/v2/servers/requests.go | 3 +++ .../v2/servers/testing/requests_test.go | 22 +++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/openstack/compute/v2/servers/requests.go b/openstack/compute/v2/servers/requests.go index dd3b132d1d..44e8cccaeb 100644 --- a/openstack/compute/v2/servers/requests.go +++ b/openstack/compute/v2/servers/requests.go @@ -508,6 +508,9 @@ type CreateOpts struct { // DiskConfig [optional] controls how the created server's disk is partitioned. DiskConfig DiskConfig `json:"OS-DCF:diskConfig,omitempty"` + + // HypervisorHostname is the name of the hypervisor to which the server is scheduled. + HypervisorHostname string `json:"hypervisor_hostname,omitempty"` } // ToServerCreateMap assembles a request body based on the contents of a diff --git a/openstack/compute/v2/servers/testing/requests_test.go b/openstack/compute/v2/servers/testing/requests_test.go index b50ea185c9..66a33dd688 100644 --- a/openstack/compute/v2/servers/testing/requests_test.go +++ b/openstack/compute/v2/servers/testing/requests_test.go @@ -1160,3 +1160,25 @@ func TestCreateServerWithTags(t *testing.T) { th.AssertNoErr(t, err) th.CheckDeepEquals(t, ServerDerpTags, *actualServer) } + +func TestCreateServerWithHypervisorHostname(t *testing.T) { + opts := servers.CreateOpts{ + Name: "createdserver", + FlavorRef: "performance1-1", + ImageRef: "asdfasdfasdf", + HypervisorHostname: "test-hypervisor", + } + expected := ` + { + "server": { + "name":"createdserver", + "flavorRef":"performance1-1", + "imageRef":"asdfasdfasdf", + "hypervisor_hostname":"test-hypervisor" + } + } + ` + actual, err := opts.ToServerCreateMap() + th.AssertNoErr(t, err) + th.CheckJSONEquals(t, expected, actual) +} From b46c5fd2a357d3f5021bddc02abe54be894972bb Mon Sep 17 00:00:00 2001 From: Emilien Macchi Date: Mon, 3 Mar 2025 08:50:13 -0500 Subject: [PATCH 092/353] Prepare v2.6.0 --- CHANGELOG.md | 4 ++++ provider_client.go | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2cfef4fd82..cffb759590 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## v2.6.0 (2025-03-03) + +* [GH-3309](https://github.com/gophercloud/gophercloud/pull/3309) Backport: Added support for hypervisor_hostname to v2 + ## v2.5.0 (2025-02-11) * [GH-3278](https://github.com/gophercloud/gophercloud/pull/3278) [v2] test: Ensure that randomly created secgroup rules don't conflict diff --git a/provider_client.go b/provider_client.go index 2d52c73326..8dac878eb9 100644 --- a/provider_client.go +++ b/provider_client.go @@ -13,7 +13,7 @@ import ( // DefaultUserAgent is the default User-Agent string set in the request header. const ( - DefaultUserAgent = "gophercloud/v2.5.0" + DefaultUserAgent = "gophercloud/v2.6.0" DefaultMaxBackoffRetries = 60 ) From 2a76f50e59d764a3ad682be0c367d25f3005729b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Andr=C3=A9?= Date: Mon, 10 Mar 2025 09:46:12 +0100 Subject: [PATCH 093/353] Switch to a version of gocovmerge compatible with go 1.22 The original `gocovmerge` repository [1] has not seen a commit in 9 years and should be considered unmaintained. Switch to fork has a go.mod pinned to go 1.22. Please review the diff [2] between the two repos to check if it's safe to use in gophercloud. [1] https://github.com/wadey/gocovmerge [2] https://github.com/wadey/gocovmerge/compare/master...alexfalkowski:gocovmerge:v1.4.0 --- .github/workflows/unit.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/unit.yaml b/.github/workflows/unit.yaml index 11fddb5f68..0ae498baf7 100644 --- a/.github/workflows/unit.yaml +++ b/.github/workflows/unit.yaml @@ -30,7 +30,7 @@ jobs: cd "$(mktemp -d)" go mod init unit_tests - go install github.com/wadey/gocovmerge@master + go install github.com/alexfalkowski/gocovmerge@v1.4.0 - name: Run unit tests run: | From cfa7409cb2d1a8c4098968d31b4ca92338ab4bce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Andr=C3=A9?= Date: Thu, 6 Mar 2025 13:53:09 +0100 Subject: [PATCH 094/353] Improve support for network `standard-attr-revisions` extension Consistently add support for the neutron `Resource revision numbers` extension [1] for more resources that support it. It adds a `RevisionNumber` field to all responses, and allows filtering via the `RevisionNumber` list option. It was only partially implemented. Also support the `If-Match` constraints, and add test for it. [1] https://docs.openstack.org/api-ref/network/v2/#revisions --- .../v2/extensions/layer3/floatingips_test.go | 60 +++++ .../v2/extensions/layer3/routers_test.go | 66 ++++++ .../extensions/qos/policies/policies_test.go | 66 ++++++ .../networking/v2/extensions/security_test.go | 63 ++++++ .../subnetpools/subnetpools_test.go | 61 +++++ .../v2/extensions/trunks/trunks_test.go | 212 ++++++++++-------- .../extensions/layer3/floatingips/requests.go | 20 +- .../extensions/layer3/floatingips/results.go | 3 + .../v2/extensions/layer3/routers/requests.go | 52 +++-- .../v2/extensions/layer3/routers/results.go | 3 + .../v2/extensions/qos/policies/requests.go | 21 +- .../v2/extensions/qos/policies/results.go | 2 +- .../v2/extensions/security/groups/requests.go | 48 ++-- .../v2/extensions/security/groups/results.go | 3 + .../v2/extensions/security/rules/requests.go | 1 + .../v2/extensions/security/rules/results.go | 3 + .../v2/extensions/subnetpools/requests.go | 22 +- .../v2/extensions/trunks/requests.go | 48 ++-- .../v2/extensions/trunks/results.go | 1 + openstack/networking/v2/networks/requests.go | 33 +-- openstack/networking/v2/ports/requests.go | 1 + openstack/networking/v2/subnets/requests.go | 1 + 22 files changed, 628 insertions(+), 162 deletions(-) diff --git a/internal/acceptance/openstack/networking/v2/extensions/layer3/floatingips_test.go b/internal/acceptance/openstack/networking/v2/extensions/layer3/floatingips_test.go index fee8cacd38..5f4d771614 100644 --- a/internal/acceptance/openstack/networking/v2/extensions/layer3/floatingips_test.go +++ b/internal/acceptance/openstack/networking/v2/extensions/layer3/floatingips_test.go @@ -4,6 +4,7 @@ package layer3 import ( "context" + "strings" "testing" "github.com/gophercloud/gophercloud/v2/internal/acceptance/clients" @@ -203,3 +204,62 @@ func TestLayer3FloatingIPsCreateDeleteBySubnetID(t *testing.T) { DeleteFloatingIP(t, client, fip.ID) } + +func TestLayer3FloatingIPsRevision(t *testing.T) { + client, err := clients.NewNetworkV2Client() + th.AssertNoErr(t, err) + + choices, err := clients.AcceptanceTestChoicesFromEnv() + th.AssertNoErr(t, err) + + fip, err := CreateFloatingIP(t, client, choices.ExternalNetworkID, "") + th.AssertNoErr(t, err) + defer DeleteFloatingIP(t, client, fip.ID) + + tools.PrintResource(t, fip) + + // Store the current revision number. + oldRevisionNumber := fip.RevisionNumber + + // Update the fip without revision number. + // This should work. + newDescription := "" + updateOpts := &floatingips.UpdateOpts{ + Description: &newDescription, + } + fip, err = floatingips.Update(context.TODO(), client, fip.ID, updateOpts).Extract() + th.AssertNoErr(t, err) + + tools.PrintResource(t, fip) + + // This should fail due to an old revision number. + newDescription = "new description" + updateOpts = &floatingips.UpdateOpts{ + Description: &newDescription, + RevisionNumber: &oldRevisionNumber, + } + _, err = floatingips.Update(context.TODO(), client, fip.ID, updateOpts).Extract() + th.AssertErr(t, err) + if !strings.Contains(err.Error(), "RevisionNumberConstraintFailed") { + t.Fatalf("expected to see an error of type RevisionNumberConstraintFailed, but got the following error instead: %v", err) + } + + // Reread the fip to show that it did not change. + fip, err = floatingips.Get(context.TODO(), client, fip.ID).Extract() + th.AssertNoErr(t, err) + + tools.PrintResource(t, fip) + + // This should work because now we do provide a valid revision number. + newDescription = "new description" + updateOpts = &floatingips.UpdateOpts{ + Description: &newDescription, + RevisionNumber: &fip.RevisionNumber, + } + fip, err = floatingips.Update(context.TODO(), client, fip.ID, updateOpts).Extract() + th.AssertNoErr(t, err) + + tools.PrintResource(t, fip) + + th.AssertEquals(t, fip.Description, newDescription) +} diff --git a/internal/acceptance/openstack/networking/v2/extensions/layer3/routers_test.go b/internal/acceptance/openstack/networking/v2/extensions/layer3/routers_test.go index 8d1800f719..1df4375164 100644 --- a/internal/acceptance/openstack/networking/v2/extensions/layer3/routers_test.go +++ b/internal/acceptance/openstack/networking/v2/extensions/layer3/routers_test.go @@ -4,6 +4,7 @@ package layer3 import ( "context" + "strings" "testing" "github.com/gophercloud/gophercloud/v2/internal/acceptance/clients" @@ -213,3 +214,68 @@ func TestLayer3RouterAgents(t *testing.T) { th.AssertEquals(t, found, true) } + +func TestLayer3RouterRevision(t *testing.T) { + client, err := clients.NewNetworkV2Client() + th.AssertNoErr(t, err) + + network, err := networking.CreateNetwork(t, client) + th.AssertNoErr(t, err) + defer networking.DeleteNetwork(t, client, network.ID) + + router, err := CreateRouter(t, client, network.ID) + th.AssertNoErr(t, err) + defer DeleteRouter(t, client, router.ID) + + tools.PrintResource(t, router) + + // Store the current revision number. + oldRevisionNumber := router.RevisionNumber + + // Update the router without revision number. + // This should work. + newName := tools.RandomString("TESTACC-", 8) + newDescription := "" + updateOpts := &routers.UpdateOpts{ + Name: newName, + Description: &newDescription, + } + router, err = routers.Update(context.TODO(), client, router.ID, updateOpts).Extract() + th.AssertNoErr(t, err) + + tools.PrintResource(t, router) + + // This should fail due to an old revision number. + newDescription = "new description" + updateOpts = &routers.UpdateOpts{ + Name: newName, + Description: &newDescription, + RevisionNumber: &oldRevisionNumber, + } + _, err = routers.Update(context.TODO(), client, router.ID, updateOpts).Extract() + th.AssertErr(t, err) + if !strings.Contains(err.Error(), "RevisionNumberConstraintFailed") { + t.Fatalf("expected to see an error of type RevisionNumberConstraintFailed, but got the following error instead: %v", err) + } + + // Reread the router to show that it did not change. + router, err = routers.Get(context.TODO(), client, router.ID).Extract() + th.AssertNoErr(t, err) + + tools.PrintResource(t, router) + + // This should work because now we do provide a valid revision number. + newDescription = "new description" + updateOpts = &routers.UpdateOpts{ + Name: newName, + Description: &newDescription, + RevisionNumber: &router.RevisionNumber, + } + router, err = routers.Update(context.TODO(), client, router.ID, updateOpts).Extract() + th.AssertNoErr(t, err) + + tools.PrintResource(t, router) + + th.AssertEquals(t, router.Name, newName) + th.AssertEquals(t, router.Description, newDescription) +} diff --git a/internal/acceptance/openstack/networking/v2/extensions/qos/policies/policies_test.go b/internal/acceptance/openstack/networking/v2/extensions/qos/policies/policies_test.go index fc9563df38..9ee2304c75 100644 --- a/internal/acceptance/openstack/networking/v2/extensions/qos/policies/policies_test.go +++ b/internal/acceptance/openstack/networking/v2/extensions/qos/policies/policies_test.go @@ -4,6 +4,7 @@ package policies import ( "context" + "strings" "testing" "github.com/gophercloud/gophercloud/v2/internal/acceptance/clients" @@ -59,3 +60,68 @@ func TestPoliciesCRUD(t *testing.T) { th.AssertEquals(t, found, true) } + +func TestPoliciesRevision(t *testing.T) { + client, err := clients.NewNetworkV2Client() + th.AssertNoErr(t, err) + + // Skip these tests if we don't have the required extension + v2.RequireNeutronExtension(t, client, "qos") + + // Create a policy + policy, err := CreateQoSPolicy(t, client) + th.AssertNoErr(t, err) + defer DeleteQoSPolicy(t, client, policy.ID) + + tools.PrintResource(t, policy) + + // Store the current revision number. + oldRevisionNumber := policy.RevisionNumber + + // Update the policy without revision number. + // This should work. + newName := tools.RandomString("TESTACC-", 8) + newDescription := "" + updateOpts := &policies.UpdateOpts{ + Name: newName, + Description: &newDescription, + } + policy, err = policies.Update(context.TODO(), client, policy.ID, updateOpts).Extract() + th.AssertNoErr(t, err) + + tools.PrintResource(t, policy) + + // This should fail due to an old revision number. + newDescription = "new description" + updateOpts = &policies.UpdateOpts{ + Name: newName, + Description: &newDescription, + RevisionNumber: &oldRevisionNumber, + } + _, err = policies.Update(context.TODO(), client, policy.ID, updateOpts).Extract() + th.AssertErr(t, err) + if !strings.Contains(err.Error(), "RevisionNumberConstraintFailed") { + t.Fatalf("expected to see an error of type RevisionNumberConstraintFailed, but got the following error instead: %v", err) + } + + // Reread the policy to show that it did not change. + policy, err = policies.Get(context.TODO(), client, policy.ID).Extract() + th.AssertNoErr(t, err) + + tools.PrintResource(t, policy) + + // This should work because now we do provide a valid revision number. + newDescription = "new description" + updateOpts = &policies.UpdateOpts{ + Name: newName, + Description: &newDescription, + RevisionNumber: &policy.RevisionNumber, + } + policy, err = policies.Update(context.TODO(), client, policy.ID, updateOpts).Extract() + th.AssertNoErr(t, err) + + tools.PrintResource(t, policy) + + th.AssertEquals(t, policy.Name, newName) + th.AssertEquals(t, policy.Description, newDescription) +} diff --git a/internal/acceptance/openstack/networking/v2/extensions/security_test.go b/internal/acceptance/openstack/networking/v2/extensions/security_test.go index 8d855bbb0a..33fc3f176d 100644 --- a/internal/acceptance/openstack/networking/v2/extensions/security_test.go +++ b/internal/acceptance/openstack/networking/v2/extensions/security_test.go @@ -4,6 +4,7 @@ package extensions import ( "context" + "strings" "testing" "github.com/gophercloud/gophercloud/v2/internal/acceptance/clients" @@ -93,3 +94,65 @@ func TestSecurityGroupsPort(t *testing.T) { tools.PrintResource(t, port) } + +func TestSecurityGroupsRevision(t *testing.T) { + client, err := clients.NewNetworkV2Client() + th.AssertNoErr(t, err) + + // Create a group + group, err := CreateSecurityGroup(t, client) + th.AssertNoErr(t, err) + defer DeleteSecurityGroup(t, client, group.ID) + + tools.PrintResource(t, group) + + // Store the current revision number. + oldRevisionNumber := group.RevisionNumber + + // Update the group without revision number. + // This should work. + newName := tools.RandomString("TESTACC-", 8) + newDescription := "" + updateOpts := &groups.UpdateOpts{ + Name: newName, + Description: &newDescription, + } + group, err = groups.Update(context.TODO(), client, group.ID, updateOpts).Extract() + th.AssertNoErr(t, err) + + tools.PrintResource(t, group) + + // This should fail due to an old revision number. + newDescription = "new description" + updateOpts = &groups.UpdateOpts{ + Name: newName, + Description: &newDescription, + RevisionNumber: &oldRevisionNumber, + } + _, err = groups.Update(context.TODO(), client, group.ID, updateOpts).Extract() + th.AssertErr(t, err) + if !strings.Contains(err.Error(), "RevisionNumberConstraintFailed") { + t.Fatalf("expected to see an error of type RevisionNumberConstraintFailed, but got the following error instead: %v", err) + } + + // Reread the group to show that it did not change. + group, err = groups.Get(context.TODO(), client, group.ID).Extract() + th.AssertNoErr(t, err) + + tools.PrintResource(t, group) + + // This should work because now we do provide a valid revision number. + newDescription = "new description" + updateOpts = &groups.UpdateOpts{ + Name: newName, + Description: &newDescription, + RevisionNumber: &group.RevisionNumber, + } + group, err = groups.Update(context.TODO(), client, group.ID, updateOpts).Extract() + th.AssertNoErr(t, err) + + tools.PrintResource(t, group) + + th.AssertEquals(t, group.Name, newName) + th.AssertEquals(t, group.Description, newDescription) +} diff --git a/internal/acceptance/openstack/networking/v2/extensions/subnetpools/subnetpools_test.go b/internal/acceptance/openstack/networking/v2/extensions/subnetpools/subnetpools_test.go index 8a0575d8fe..8c9cb3120b 100644 --- a/internal/acceptance/openstack/networking/v2/extensions/subnetpools/subnetpools_test.go +++ b/internal/acceptance/openstack/networking/v2/extensions/subnetpools/subnetpools_test.go @@ -4,6 +4,7 @@ package v2 import ( "context" + "strings" "testing" "github.com/gophercloud/gophercloud/v2/internal/acceptance/clients" @@ -55,3 +56,63 @@ func TestSubnetPoolsCRUD(t *testing.T) { th.AssertEquals(t, found, true) } + +func TestSubnetPoolsRevision(t *testing.T) { + client, err := clients.NewNetworkV2Client() + th.AssertNoErr(t, err) + + // Create a subnetpool + subnetPool, err := CreateSubnetPool(t, client) + th.AssertNoErr(t, err) + defer DeleteSubnetPool(t, client, subnetPool.ID) + + // Store the current revision number. + oldRevisionNumber := subnetPool.RevisionNumber + + // Update the subnet pool without revision number. + // This should work. + newName := tools.RandomString("TESTACC-", 8) + newDescription := "" + updateOpts := &subnetpools.UpdateOpts{ + Name: newName, + Description: &newDescription, + } + subnetPool, err = subnetpools.Update(context.TODO(), client, subnetPool.ID, updateOpts).Extract() + th.AssertNoErr(t, err) + + tools.PrintResource(t, subnetPool) + + // This should fail due to an old revision number. + newDescription = "new description" + updateOpts = &subnetpools.UpdateOpts{ + Name: newName, + Description: &newDescription, + RevisionNumber: &oldRevisionNumber, + } + _, err = subnetpools.Update(context.TODO(), client, subnetPool.ID, updateOpts).Extract() + th.AssertErr(t, err) + if !strings.Contains(err.Error(), "RevisionNumberConstraintFailed") { + t.Fatalf("expected to see an error of type RevisionNumberConstraintFailed, but got the following error instead: %v", err) + } + + // Reread the subnet pool to show that it did not change. + subnetPool, err = subnetpools.Get(context.TODO(), client, subnetPool.ID).Extract() + th.AssertNoErr(t, err) + + tools.PrintResource(t, subnetPool) + + // This should work because now we do provide a valid revision number. + newDescription = "new description" + updateOpts = &subnetpools.UpdateOpts{ + Name: newName, + Description: &newDescription, + RevisionNumber: &subnetPool.RevisionNumber, + } + subnetPool, err = subnetpools.Update(context.TODO(), client, subnetPool.ID, updateOpts).Extract() + th.AssertNoErr(t, err) + + tools.PrintResource(t, subnetPool) + + th.AssertEquals(t, subnetPool.Name, newName) + th.AssertEquals(t, subnetPool.Description, newDescription) +} diff --git a/internal/acceptance/openstack/networking/v2/extensions/trunks/trunks_test.go b/internal/acceptance/openstack/networking/v2/extensions/trunks/trunks_test.go index 65ebd90a78..3e0af63175 100644 --- a/internal/acceptance/openstack/networking/v2/extensions/trunks/trunks_test.go +++ b/internal/acceptance/openstack/networking/v2/extensions/trunks/trunks_test.go @@ -5,6 +5,7 @@ package trunks import ( "context" "sort" + "strings" "testing" "github.com/gophercloud/gophercloud/v2/internal/acceptance/clients" @@ -17,56 +18,40 @@ import ( func TestTrunkCRUD(t *testing.T) { client, err := clients.NewNetworkV2Client() - if err != nil { - t.Fatalf("Unable to create a network client: %v", err) - } + th.AssertNoErr(t, err) // Skip these tests if we don't have the required extension v2.RequireNeutronExtension(t, client, "trunk") // Create Network network, err := v2.CreateNetwork(t, client) - if err != nil { - t.Fatalf("Unable to create network: %v", err) - } + th.AssertNoErr(t, err) defer v2.DeleteNetwork(t, client, network.ID) // Create Subnet subnet, err := v2.CreateSubnet(t, client, network.ID) - if err != nil { - t.Fatalf("Unable to create subnet: %v", err) - } + th.AssertNoErr(t, err) defer v2.DeleteSubnet(t, client, subnet.ID) // Create port parentPort, err := v2.CreatePort(t, client, network.ID, subnet.ID) - if err != nil { - t.Fatalf("Unable to create port: %v", err) - } + th.AssertNoErr(t, err) defer v2.DeletePort(t, client, parentPort.ID) subport1, err := v2.CreatePort(t, client, network.ID, subnet.ID) - if err != nil { - t.Fatalf("Unable to create port: %v", err) - } + th.AssertNoErr(t, err) defer v2.DeletePort(t, client, subport1.ID) subport2, err := v2.CreatePort(t, client, network.ID, subnet.ID) - if err != nil { - t.Fatalf("Unable to create port: %v", err) - } + th.AssertNoErr(t, err) defer v2.DeletePort(t, client, subport2.ID) trunk, err := CreateTrunk(t, client, parentPort.ID, subport1.ID, subport2.ID) - if err != nil { - t.Fatalf("Unable to create trunk: %v", err) - } + th.AssertNoErr(t, err) defer DeleteTrunk(t, client, trunk.ID) _, err = trunks.Get(context.TODO(), client, trunk.ID).Extract() - if err != nil { - t.Fatalf("Unable to get trunk: %v", err) - } + th.AssertNoErr(t, err) // Update Trunk name := "" @@ -76,9 +61,7 @@ func TestTrunkCRUD(t *testing.T) { Description: &description, } updatedTrunk, err := trunks.Update(context.TODO(), client, trunk.ID, updateOpts).Extract() - if err != nil { - t.Fatalf("Unable to update trunk: %v", err) - } + th.AssertNoErr(t, err) if trunk.Name == updatedTrunk.Name { t.Fatalf("Trunk name was not updated correctly") @@ -93,9 +76,7 @@ func TestTrunkCRUD(t *testing.T) { // Get subports subports, err := trunks.GetSubports(context.TODO(), client, trunk.ID).Extract() - if err != nil { - t.Fatalf("Unable to get subports from the Trunk: %v", err) - } + th.AssertNoErr(t, err) th.AssertDeepEquals(t, trunk.Subports[0], subports[0]) th.AssertDeepEquals(t, trunk.Subports[1], subports[1]) @@ -104,22 +85,16 @@ func TestTrunkCRUD(t *testing.T) { func TestTrunkList(t *testing.T) { client, err := clients.NewNetworkV2Client() - if err != nil { - t.Fatalf("Unable to create a network client: %v", err) - } + th.AssertNoErr(t, err) // Skip these tests if we don't have the required extension v2.RequireNeutronExtension(t, client, "trunk") allPages, err := trunks.List(client, nil).AllPages(context.TODO()) - if err != nil { - t.Fatalf("Unable to list trunks: %v", err) - } + th.AssertNoErr(t, err) allTrunks, err := trunks.ExtractTrunks(allPages) - if err != nil { - t.Fatalf("Unable to extract trunks: %v", err) - } + th.AssertNoErr(t, err) for _, trunk := range allTrunks { tools.PrintResource(t, trunk) @@ -128,50 +103,36 @@ func TestTrunkList(t *testing.T) { func TestTrunkSubportOperation(t *testing.T) { client, err := clients.NewNetworkV2Client() - if err != nil { - t.Fatalf("Unable to create a network client: %v", err) - } + th.AssertNoErr(t, err) // Skip these tests if we don't have the required extension v2.RequireNeutronExtension(t, client, "trunk") // Create Network network, err := v2.CreateNetwork(t, client) - if err != nil { - t.Fatalf("Unable to create network: %v", err) - } + th.AssertNoErr(t, err) defer v2.DeleteNetwork(t, client, network.ID) // Create Subnet subnet, err := v2.CreateSubnet(t, client, network.ID) - if err != nil { - t.Fatalf("Unable to create subnet: %v", err) - } + th.AssertNoErr(t, err) defer v2.DeleteSubnet(t, client, subnet.ID) // Create port parentPort, err := v2.CreatePort(t, client, network.ID, subnet.ID) - if err != nil { - t.Fatalf("Unable to create port: %v", err) - } + th.AssertNoErr(t, err) defer v2.DeletePort(t, client, parentPort.ID) subport1, err := v2.CreatePort(t, client, network.ID, subnet.ID) - if err != nil { - t.Fatalf("Unable to create port: %v", err) - } + th.AssertNoErr(t, err) defer v2.DeletePort(t, client, subport1.ID) subport2, err := v2.CreatePort(t, client, network.ID, subnet.ID) - if err != nil { - t.Fatalf("Unable to create port: %v", err) - } + th.AssertNoErr(t, err) defer v2.DeletePort(t, client, subport2.ID) trunk, err := CreateTrunk(t, client, parentPort.ID) - if err != nil { - t.Fatalf("Unable to create trunk: %v", err) - } + th.AssertNoErr(t, err) defer DeleteTrunk(t, client, trunk.ID) // Add subports to the trunk @@ -190,9 +151,7 @@ func TestTrunkSubportOperation(t *testing.T) { }, } updatedTrunk, err := trunks.AddSubports(context.TODO(), client, trunk.ID, addSubportsOpts).Extract() - if err != nil { - t.Fatalf("Unable to add subports to the Trunk: %v", err) - } + th.AssertNoErr(t, err) th.AssertEquals(t, 2, len(updatedTrunk.Subports)) th.AssertDeepEquals(t, addSubportsOpts.Subports[0], updatedTrunk.Subports[0]) th.AssertDeepEquals(t, addSubportsOpts.Subports[1], updatedTrunk.Subports[1]) @@ -205,58 +164,42 @@ func TestTrunkSubportOperation(t *testing.T) { }, } updatedAgainTrunk, err := trunks.RemoveSubports(context.TODO(), client, trunk.ID, subRemoveOpts).Extract() - if err != nil { - t.Fatalf("Unable to remove subports from the Trunk: %v", err) - } + th.AssertNoErr(t, err) th.AssertDeepEquals(t, trunk.Subports, updatedAgainTrunk.Subports) } func TestTrunkTags(t *testing.T) { client, err := clients.NewNetworkV2Client() - if err != nil { - t.Fatalf("Unable to create a network client: %v", err) - } + th.AssertNoErr(t, err) // Skip these tests if we don't have the required extension v2.RequireNeutronExtension(t, client, "trunk") // Create Network network, err := v2.CreateNetwork(t, client) - if err != nil { - t.Fatalf("Unable to create network: %v", err) - } + th.AssertNoErr(t, err) defer v2.DeleteNetwork(t, client, network.ID) // Create Subnet subnet, err := v2.CreateSubnet(t, client, network.ID) - if err != nil { - t.Fatalf("Unable to create subnet: %v", err) - } + th.AssertNoErr(t, err) defer v2.DeleteSubnet(t, client, subnet.ID) // Create port parentPort, err := v2.CreatePort(t, client, network.ID, subnet.ID) - if err != nil { - t.Fatalf("Unable to create port: %v", err) - } + th.AssertNoErr(t, err) defer v2.DeletePort(t, client, parentPort.ID) subport1, err := v2.CreatePort(t, client, network.ID, subnet.ID) - if err != nil { - t.Fatalf("Unable to create port: %v", err) - } + th.AssertNoErr(t, err) defer v2.DeletePort(t, client, subport1.ID) subport2, err := v2.CreatePort(t, client, network.ID, subnet.ID) - if err != nil { - t.Fatalf("Unable to create port: %v", err) - } + th.AssertNoErr(t, err) defer v2.DeletePort(t, client, subport2.ID) trunk, err := CreateTrunk(t, client, parentPort.ID, subport1.ID, subport2.ID) - if err != nil { - t.Fatalf("Unable to create trunk: %v", err) - } + th.AssertNoErr(t, err) defer DeleteTrunk(t, client, trunk.ID) tagReplaceAllOpts := attributestags.ReplaceAllOpts{ @@ -264,14 +207,10 @@ func TestTrunkTags(t *testing.T) { Tags: []string{"a", "b", "c"}, } _, err = attributestags.ReplaceAll(context.TODO(), client, "trunks", trunk.ID, tagReplaceAllOpts).Extract() - if err != nil { - t.Fatalf("Unable to set trunk tags: %v", err) - } + th.AssertNoErr(t, err) gtrunk, err := trunks.Get(context.TODO(), client, trunk.ID).Extract() - if err != nil { - t.Fatalf("Unable to get trunk: %v", err) - } + th.AssertNoErr(t, err) tags := gtrunk.Tags sort.Strings(tags) // Ensure ordering, older OpenStack versions aren't sorted... th.AssertDeepEquals(t, []string{"a", "b", "c"}, tags) @@ -297,3 +236,90 @@ func TestTrunkTags(t *testing.T) { th.AssertNoErr(t, err) th.AssertEquals(t, 0, len(tags)) } + +func TestTrunkRevision(t *testing.T) { + client, err := clients.NewNetworkV2Client() + th.AssertNoErr(t, err) + + // Skip these tests if we don't have the required extension + v2.RequireNeutronExtension(t, client, "trunk") + + // Create Network + network, err := v2.CreateNetwork(t, client) + th.AssertNoErr(t, err) + defer v2.DeleteNetwork(t, client, network.ID) + + // Create Subnet + subnet, err := v2.CreateSubnet(t, client, network.ID) + th.AssertNoErr(t, err) + defer v2.DeleteSubnet(t, client, subnet.ID) + + // Create port + parentPort, err := v2.CreatePort(t, client, network.ID, subnet.ID) + th.AssertNoErr(t, err) + defer v2.DeletePort(t, client, parentPort.ID) + + subport1, err := v2.CreatePort(t, client, network.ID, subnet.ID) + th.AssertNoErr(t, err) + defer v2.DeletePort(t, client, subport1.ID) + + subport2, err := v2.CreatePort(t, client, network.ID, subnet.ID) + th.AssertNoErr(t, err) + defer v2.DeletePort(t, client, subport2.ID) + + trunk, err := CreateTrunk(t, client, parentPort.ID, subport1.ID, subport2.ID) + th.AssertNoErr(t, err) + defer DeleteTrunk(t, client, trunk.ID) + + tools.PrintResource(t, trunk) + + // Store the current revision number. + oldRevisionNumber := trunk.RevisionNumber + + // Update the trunk without revision number. + // This should work. + newName := tools.RandomString("TESTACC-", 8) + newDescription := "" + updateOpts := &trunks.UpdateOpts{ + Name: &newName, + Description: &newDescription, + } + trunk, err = trunks.Update(context.TODO(), client, trunk.ID, updateOpts).Extract() + th.AssertNoErr(t, err) + + tools.PrintResource(t, trunk) + + // This should fail due to an old revision number. + newDescription = "new description" + updateOpts = &trunks.UpdateOpts{ + Name: &newName, + Description: &newDescription, + RevisionNumber: &oldRevisionNumber, + } + _, err = trunks.Update(context.TODO(), client, trunk.ID, updateOpts).Extract() + th.AssertErr(t, err) + if !strings.Contains(err.Error(), "RevisionNumberConstraintFailed") { + t.Fatalf("expected to see an error of type RevisionNumberConstraintFailed, but got the following error instead: %v", err) + } + + // Reread the trunk to show that it did not change. + trunk, err = trunks.Get(context.TODO(), client, trunk.ID).Extract() + th.AssertNoErr(t, err) + + tools.PrintResource(t, trunk) + + // This should work because now we do provide a valid revision number. + newDescription = "new description" + updateOpts = &trunks.UpdateOpts{ + Name: &newName, + Description: &newDescription, + RevisionNumber: &trunk.RevisionNumber, + } + trunk, err = trunks.Update(context.TODO(), client, trunk.ID, updateOpts).Extract() + th.AssertNoErr(t, err) + + tools.PrintResource(t, trunk) + + th.AssertEquals(t, trunk.Name, newName) + th.AssertEquals(t, trunk.Description, newDescription) +} diff --git a/openstack/networking/v2/extensions/layer3/floatingips/requests.go b/openstack/networking/v2/extensions/layer3/floatingips/requests.go index a3afb0403c..be8949d693 100644 --- a/openstack/networking/v2/extensions/layer3/floatingips/requests.go +++ b/openstack/networking/v2/extensions/layer3/floatingips/requests.go @@ -2,6 +2,7 @@ package floatingips import ( "context" + "fmt" "github.com/gophercloud/gophercloud/v2" "github.com/gophercloud/gophercloud/v2/pagination" @@ -37,6 +38,7 @@ type ListOpts struct { TagsAny string `q:"tags-any"` NotTags string `q:"not-tags"` NotTagsAny string `q:"not-tags-any"` + RevisionNumber *int `q:"revision_number"` } // ToNetworkListQuery formats a ListOpts into a query string. @@ -144,6 +146,11 @@ type UpdateOpts struct { Description *string `json:"description,omitempty"` PortID *string `json:"port_id,omitempty"` FixedIP string `json:"fixed_ip_address,omitempty"` + + // RevisionNumber implements extension:standard-attr-revisions. If != "" it + // will set revision_number=%s. If the revision number does not match, the + // update will fail. + RevisionNumber *int `json:"-" h:"If-Match"` } // ToFloatingIPUpdateMap allows UpdateOpts to satisfy the UpdateOptsBuilder @@ -171,8 +178,19 @@ func Update(ctx context.Context, c *gophercloud.ServiceClient, id string, opts U r.Err = err return } + h, err := gophercloud.BuildHeaders(opts) + if err != nil { + r.Err = err + return + } + for k := range h { + if k == "If-Match" { + h[k] = fmt.Sprintf("revision_number=%s", h[k]) + } + } resp, err := c.Put(ctx, resourceURL(c, id), b, &r.Body, &gophercloud.RequestOpts{ - OkCodes: []int{200}, + MoreHeaders: h, + OkCodes: []int{200}, }) _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) return diff --git a/openstack/networking/v2/extensions/layer3/floatingips/results.go b/openstack/networking/v2/extensions/layer3/floatingips/results.go index 50740ebf30..7ea6160032 100644 --- a/openstack/networking/v2/extensions/layer3/floatingips/results.go +++ b/openstack/networking/v2/extensions/layer3/floatingips/results.go @@ -56,6 +56,9 @@ type FloatingIP struct { // Tags optionally set via extensions/attributestags Tags []string `json:"tags"` + + // RevisionNumber optionally set via extensions/standard-attr-revisions + RevisionNumber int `json:"revision_number"` } func (r *FloatingIP) UnmarshalJSON(b []byte) error { diff --git a/openstack/networking/v2/extensions/layer3/routers/requests.go b/openstack/networking/v2/extensions/layer3/routers/requests.go index dcc7977a46..f6ca654841 100644 --- a/openstack/networking/v2/extensions/layer3/routers/requests.go +++ b/openstack/networking/v2/extensions/layer3/routers/requests.go @@ -2,6 +2,7 @@ package routers import ( "context" + "fmt" "github.com/gophercloud/gophercloud/v2" "github.com/gophercloud/gophercloud/v2/pagination" @@ -13,22 +14,23 @@ import ( // sort by a particular network attribute. SortDir sets the direction, and is // either `asc' or `desc'. Marker and Limit are used for pagination. type ListOpts struct { - ID string `q:"id"` - Name string `q:"name"` - Description string `q:"description"` - AdminStateUp *bool `q:"admin_state_up"` - Distributed *bool `q:"distributed"` - Status string `q:"status"` - TenantID string `q:"tenant_id"` - ProjectID string `q:"project_id"` - Limit int `q:"limit"` - Marker string `q:"marker"` - SortKey string `q:"sort_key"` - SortDir string `q:"sort_dir"` - Tags string `q:"tags"` - TagsAny string `q:"tags-any"` - NotTags string `q:"not-tags"` - NotTagsAny string `q:"not-tags-any"` + ID string `q:"id"` + Name string `q:"name"` + Description string `q:"description"` + AdminStateUp *bool `q:"admin_state_up"` + Distributed *bool `q:"distributed"` + Status string `q:"status"` + TenantID string `q:"tenant_id"` + ProjectID string `q:"project_id"` + Limit int `q:"limit"` + Marker string `q:"marker"` + SortKey string `q:"sort_key"` + SortDir string `q:"sort_dir"` + Tags string `q:"tags"` + TagsAny string `q:"tags-any"` + NotTags string `q:"not-tags"` + NotTagsAny string `q:"not-tags-any"` + RevisionNumber *int `q:"revision_number"` } // List returns a Pager which allows you to iterate over a collection of @@ -112,6 +114,11 @@ type UpdateOpts struct { Distributed *bool `json:"distributed,omitempty"` GatewayInfo *GatewayInfo `json:"external_gateway_info,omitempty"` Routes *[]Route `json:"routes,omitempty"` + + // RevisionNumber implements extension:standard-attr-revisions. If != "" it + // will set revision_number=%s. If the revision number does not match, the + // update will fail. + RevisionNumber *int `json:"-" h:"If-Match"` } // ToRouterUpdateMap builds an update body based on UpdateOpts. @@ -130,8 +137,19 @@ func Update(ctx context.Context, c *gophercloud.ServiceClient, id string, opts U r.Err = err return } + h, err := gophercloud.BuildHeaders(opts) + if err != nil { + r.Err = err + return + } + for k := range h { + if k == "If-Match" { + h[k] = fmt.Sprintf("revision_number=%s", h[k]) + } + } resp, err := c.Put(ctx, resourceURL(c, id), b, &r.Body, &gophercloud.RequestOpts{ - OkCodes: []int{200}, + MoreHeaders: h, + OkCodes: []int{200}, }) _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) return diff --git a/openstack/networking/v2/extensions/layer3/routers/results.go b/openstack/networking/v2/extensions/layer3/routers/results.go index 25e8ab7b59..cb2d444034 100644 --- a/openstack/networking/v2/extensions/layer3/routers/results.go +++ b/openstack/networking/v2/extensions/layer3/routers/results.go @@ -77,6 +77,9 @@ type Router struct { // Tags optionally set via extensions/attributestags Tags []string `json:"tags"` + + // RevisionNumber optionally set via extensions/standard-attr-revisions + RevisionNumber int `json:"revision_number"` } // RouterPage is the page returned by a pager when traversing over a diff --git a/openstack/networking/v2/extensions/qos/policies/requests.go b/openstack/networking/v2/extensions/qos/policies/requests.go index 88d9f85fb8..832ea2d73e 100644 --- a/openstack/networking/v2/extensions/qos/policies/requests.go +++ b/openstack/networking/v2/extensions/qos/policies/requests.go @@ -2,6 +2,7 @@ package policies import ( "context" + "fmt" "github.com/gophercloud/gophercloud/v2" "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/networks" @@ -134,7 +135,6 @@ type ListOpts struct { ProjectID string `q:"project_id"` Name string `q:"name"` Description string `q:"description"` - RevisionNumber *int `q:"revision_number"` IsDefault *bool `q:"is_default"` Shared *bool `q:"shared"` Limit int `q:"limit"` @@ -145,6 +145,7 @@ type ListOpts struct { TagsAny string `q:"tags-any"` NotTags string `q:"not-tags"` NotTagsAny string `q:"not-tags-any"` + RevisionNumber *int `q:"revision_number"` } // ToPolicyListQuery formats a ListOpts into a query string. @@ -243,6 +244,11 @@ type UpdateOpts struct { // IsDefault indicates if this QoS policy is default policy or not. IsDefault *bool `json:"is_default,omitempty"` + + // RevisionNumber implements extension:standard-attr-revisions. If != "" it + // will set revision_number=%s. If the revision number does not match, the + // update will fail. + RevisionNumber *int `json:"-" h:"If-Match"` } // ToPolicyUpdateMap builds a request body from UpdateOpts. @@ -258,8 +264,19 @@ func Update(ctx context.Context, c *gophercloud.ServiceClient, policyID string, r.Err = err return } + h, err := gophercloud.BuildHeaders(opts) + if err != nil { + r.Err = err + return + } + for k := range h { + if k == "If-Match" { + h[k] = fmt.Sprintf("revision_number=%s", h[k]) + } + } resp, err := c.Put(ctx, updateURL(c, policyID), b, &r.Body, &gophercloud.RequestOpts{ - OkCodes: []int{200}, + MoreHeaders: h, + OkCodes: []int{200}, }) _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) return diff --git a/openstack/networking/v2/extensions/qos/policies/results.go b/openstack/networking/v2/extensions/qos/policies/results.go index 70c70379d7..c35853bac8 100644 --- a/openstack/networking/v2/extensions/qos/policies/results.go +++ b/openstack/networking/v2/extensions/qos/policies/results.go @@ -79,7 +79,7 @@ type Policy struct { // Shared indicates whether this policy is shared across all projects. Shared bool `json:"shared"` - // RevisionNumber represents revision number of the policy. + // RevisionNumber optionally set via extensions/standard-attr-revisions RevisionNumber int `json:"revision_number"` // Rules represents QoS rules of the policy. diff --git a/openstack/networking/v2/extensions/security/groups/requests.go b/openstack/networking/v2/extensions/security/groups/requests.go index fabb744114..95f7bfabdf 100644 --- a/openstack/networking/v2/extensions/security/groups/requests.go +++ b/openstack/networking/v2/extensions/security/groups/requests.go @@ -2,6 +2,7 @@ package groups import ( "context" + "fmt" "github.com/gophercloud/gophercloud/v2" "github.com/gophercloud/gophercloud/v2/pagination" @@ -13,20 +14,21 @@ import ( // sort by a particular network attribute. SortDir sets the direction, and is // either `asc' or `desc'. Marker and Limit are used for pagination. type ListOpts struct { - ID string `q:"id"` - Name string `q:"name"` - Description string `q:"description"` - Stateful *bool `q:"stateful"` - TenantID string `q:"tenant_id"` - ProjectID string `q:"project_id"` - Limit int `q:"limit"` - Marker string `q:"marker"` - SortKey string `q:"sort_key"` - SortDir string `q:"sort_dir"` - Tags string `q:"tags"` - TagsAny string `q:"tags-any"` - NotTags string `q:"not-tags"` - NotTagsAny string `q:"not-tags-any"` + ID string `q:"id"` + Name string `q:"name"` + Description string `q:"description"` + Stateful *bool `q:"stateful"` + TenantID string `q:"tenant_id"` + ProjectID string `q:"project_id"` + Limit int `q:"limit"` + Marker string `q:"marker"` + SortKey string `q:"sort_key"` + SortDir string `q:"sort_dir"` + Tags string `q:"tags"` + TagsAny string `q:"tags-any"` + NotTags string `q:"not-tags"` + NotTagsAny string `q:"not-tags-any"` + RevisionNumber *int `q:"revision_number"` } // List returns a Pager which allows you to iterate over a collection of @@ -104,6 +106,11 @@ type UpdateOpts struct { // Stateful indicates if the security group is stateful or stateless. Stateful *bool `json:"stateful,omitempty"` + + // RevisionNumber implements extension:standard-attr-revisions. If != "" it + // will set revision_number=%s. If the revision number does not match, the + // update will fail. + RevisionNumber *int `json:"-" h:"If-Match"` } // ToSecGroupUpdateMap builds a request body from UpdateOpts. @@ -118,9 +125,20 @@ func Update(ctx context.Context, c *gophercloud.ServiceClient, id string, opts U r.Err = err return } + h, err := gophercloud.BuildHeaders(opts) + if err != nil { + r.Err = err + return + } + for k := range h { + if k == "If-Match" { + h[k] = fmt.Sprintf("revision_number=%s", h[k]) + } + } resp, err := c.Put(ctx, resourceURL(c, id), b, &r.Body, &gophercloud.RequestOpts{ - OkCodes: []int{200}, + MoreHeaders: h, + OkCodes: []int{200}, }) _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) return diff --git a/openstack/networking/v2/extensions/security/groups/results.go b/openstack/networking/v2/extensions/security/groups/results.go index b3aa2efb48..6a8a16fa86 100644 --- a/openstack/networking/v2/extensions/security/groups/results.go +++ b/openstack/networking/v2/extensions/security/groups/results.go @@ -41,6 +41,9 @@ type SecGroup struct { // Tags optionally set via extensions/attributestags Tags []string `json:"tags"` + + // RevisionNumber optionally set via extensions/standard-attr-revisions + RevisionNumber int `json:"revision_number"` } func (r *SecGroup) UnmarshalJSON(b []byte) error { diff --git a/openstack/networking/v2/extensions/security/rules/requests.go b/openstack/networking/v2/extensions/security/rules/requests.go index 8976224b42..77768a3dac 100644 --- a/openstack/networking/v2/extensions/security/rules/requests.go +++ b/openstack/networking/v2/extensions/security/rules/requests.go @@ -29,6 +29,7 @@ type ListOpts struct { Marker string `q:"marker"` SortKey string `q:"sort_key"` SortDir string `q:"sort_dir"` + RevisionNumber *int `q:"revision_number"` } // List returns a Pager which allows you to iterate over a collection of diff --git a/openstack/networking/v2/extensions/security/rules/results.go b/openstack/networking/v2/extensions/security/rules/results.go index 0901ced578..9aa91dbe97 100644 --- a/openstack/networking/v2/extensions/security/rules/results.go +++ b/openstack/networking/v2/extensions/security/rules/results.go @@ -56,6 +56,9 @@ type SecGroupRule struct { // ProjectID is the project owner of this security group rule. ProjectID string `json:"project_id"` + + // RevisionNumber optionally set via extensions/standard-attr-revisions + RevisionNumber int `json:"revision_number"` } // SecGroupRulePage is the page returned by a pager when traversing over a diff --git a/openstack/networking/v2/extensions/subnetpools/requests.go b/openstack/networking/v2/extensions/subnetpools/requests.go index 8823e94b2f..b18427a6e7 100644 --- a/openstack/networking/v2/extensions/subnetpools/requests.go +++ b/openstack/networking/v2/extensions/subnetpools/requests.go @@ -2,6 +2,7 @@ package subnetpools import ( "context" + "fmt" "github.com/gophercloud/gophercloud/v2" "github.com/gophercloud/gophercloud/v2/pagination" @@ -33,7 +34,6 @@ type ListOpts struct { Shared *bool `q:"shared"` Description string `q:"description"` IsDefault *bool `q:"is_default"` - RevisionNumber int `q:"revision_number"` Limit int `q:"limit"` Marker string `q:"marker"` SortKey string `q:"sort_key"` @@ -42,6 +42,8 @@ type ListOpts struct { TagsAny string `q:"tags-any"` NotTags string `q:"not-tags"` NotTagsAny string `q:"not-tags-any"` + // type int does not allow to filter with revision_number=0 + RevisionNumber int `q:"revision_number"` } // ToSubnetPoolListQuery formats a ListOpts into a query string. @@ -201,6 +203,11 @@ type UpdateOpts struct { // IsDefault indicates if the subnetpool is default pool or not. IsDefault *bool `json:"is_default,omitempty"` + + // RevisionNumber implements extension:standard-attr-revisions. If != "" it + // will set revision_number=%s. If the revision number does not match, the + // update will fail. + RevisionNumber *int `json:"-" h:"If-Match"` } // ToSubnetPoolUpdateMap builds a request body from UpdateOpts. @@ -216,8 +223,19 @@ func Update(ctx context.Context, c *gophercloud.ServiceClient, subnetPoolID stri r.Err = err return } + h, err := gophercloud.BuildHeaders(opts) + if err != nil { + r.Err = err + return + } + for k := range h { + if k == "If-Match" { + h[k] = fmt.Sprintf("revision_number=%s", h[k]) + } + } resp, err := c.Put(ctx, updateURL(c, subnetPoolID), b, &r.Body, &gophercloud.RequestOpts{ - OkCodes: []int{200}, + MoreHeaders: h, + OkCodes: []int{200}, }) _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) return diff --git a/openstack/networking/v2/extensions/trunks/requests.go b/openstack/networking/v2/extensions/trunks/requests.go index a58d81ac17..ea4dba2507 100644 --- a/openstack/networking/v2/extensions/trunks/requests.go +++ b/openstack/networking/v2/extensions/trunks/requests.go @@ -2,6 +2,7 @@ package trunks import ( "context" + "fmt" "github.com/gophercloud/gophercloud/v2" "github.com/gophercloud/gophercloud/v2/pagination" @@ -63,21 +64,22 @@ type ListOptsBuilder interface { // by a particular trunk attribute. SortDir sets the direction, and is either // `asc' or `desc'. Marker and Limit are used for pagination. type ListOpts struct { - AdminStateUp *bool `q:"admin_state_up"` - Description string `q:"description"` - ID string `q:"id"` - Name string `q:"name"` - PortID string `q:"port_id"` + AdminStateUp *bool `q:"admin_state_up"` + Description string `q:"description"` + ID string `q:"id"` + Name string `q:"name"` + PortID string `q:"port_id"` + Status string `q:"status"` + TenantID string `q:"tenant_id"` + ProjectID string `q:"project_id"` + SortDir string `q:"sort_dir"` + SortKey string `q:"sort_key"` + Tags string `q:"tags"` + TagsAny string `q:"tags-any"` + NotTags string `q:"not-tags"` + NotTagsAny string `q:"not-tags-any"` + // TODO change type to *int for consistency RevisionNumber string `q:"revision_number"` - Status string `q:"status"` - TenantID string `q:"tenant_id"` - ProjectID string `q:"project_id"` - SortDir string `q:"sort_dir"` - SortKey string `q:"sort_key"` - Tags string `q:"tags"` - TagsAny string `q:"tags-any"` - NotTags string `q:"not-tags"` - NotTagsAny string `q:"not-tags-any"` } // ToTrunkListQuery formats a ListOpts into a query string. @@ -122,6 +124,11 @@ type UpdateOpts struct { AdminStateUp *bool `json:"admin_state_up,omitempty"` Name *string `json:"name,omitempty"` Description *string `json:"description,omitempty"` + + // RevisionNumber implements extension:standard-attr-revisions. If != "" it + // will set revision_number=%s. If the revision number does not match, the + // update will fail. + RevisionNumber *int `json:"-" h:"If-Match"` } func (opts UpdateOpts) ToTrunkUpdateMap() (map[string]any, error) { @@ -134,8 +141,19 @@ func Update(ctx context.Context, c *gophercloud.ServiceClient, id string, opts U r.Err = err return } + h, err := gophercloud.BuildHeaders(opts) + if err != nil { + r.Err = err + return + } + for k := range h { + if k == "If-Match" { + h[k] = fmt.Sprintf("revision_number=%s", h[k]) + } + } resp, err := c.Put(ctx, updateURL(c, id), body, &r.Body, &gophercloud.RequestOpts{ - OkCodes: []int{200}, + MoreHeaders: h, + OkCodes: []int{200}, }) _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) return diff --git a/openstack/networking/v2/extensions/trunks/results.go b/openstack/networking/v2/extensions/trunks/results.go index 20edcf9a88..72efd636fb 100644 --- a/openstack/networking/v2/extensions/trunks/results.go +++ b/openstack/networking/v2/extensions/trunks/results.go @@ -81,6 +81,7 @@ type Trunk struct { // if the resource has not been updated, this field will show as null. UpdatedAt time.Time `json:"updated_at"` + // RevisionNumber optionally set via extensions/standard-attr-revisions RevisionNumber int `json:"revision_number"` // UUID of the trunk's parent port diff --git a/openstack/networking/v2/networks/requests.go b/openstack/networking/v2/networks/requests.go index 29d14187ab..d4dd64ff93 100644 --- a/openstack/networking/v2/networks/requests.go +++ b/openstack/networking/v2/networks/requests.go @@ -20,22 +20,23 @@ type ListOptsBuilder interface { // by a particular network attribute. SortDir sets the direction, and is either // `asc' or `desc'. Marker and Limit are used for pagination. type ListOpts struct { - Status string `q:"status"` - Name string `q:"name"` - Description string `q:"description"` - AdminStateUp *bool `q:"admin_state_up"` - TenantID string `q:"tenant_id"` - ProjectID string `q:"project_id"` - Shared *bool `q:"shared"` - ID string `q:"id"` - Marker string `q:"marker"` - Limit int `q:"limit"` - SortKey string `q:"sort_key"` - SortDir string `q:"sort_dir"` - Tags string `q:"tags"` - TagsAny string `q:"tags-any"` - NotTags string `q:"not-tags"` - NotTagsAny string `q:"not-tags-any"` + Status string `q:"status"` + Name string `q:"name"` + Description string `q:"description"` + AdminStateUp *bool `q:"admin_state_up"` + TenantID string `q:"tenant_id"` + ProjectID string `q:"project_id"` + Shared *bool `q:"shared"` + ID string `q:"id"` + Marker string `q:"marker"` + Limit int `q:"limit"` + SortKey string `q:"sort_key"` + SortDir string `q:"sort_dir"` + Tags string `q:"tags"` + TagsAny string `q:"tags-any"` + NotTags string `q:"not-tags"` + NotTagsAny string `q:"not-tags-any"` + RevisionNumber *int `q:"revision_number"` } // ToNetworkListQuery formats a ListOpts into a query string. diff --git a/openstack/networking/v2/ports/requests.go b/openstack/networking/v2/ports/requests.go index 218c2897f7..bfff2dffb2 100644 --- a/openstack/networking/v2/ports/requests.go +++ b/openstack/networking/v2/ports/requests.go @@ -41,6 +41,7 @@ type ListOpts struct { TagsAny string `q:"tags-any"` NotTags string `q:"not-tags"` NotTagsAny string `q:"not-tags-any"` + RevisionNumber *int `q:"revision_number"` SecurityGroups []string `q:"security_groups"` FixedIPs []FixedIPOpts } diff --git a/openstack/networking/v2/subnets/requests.go b/openstack/networking/v2/subnets/requests.go index db597d6864..150afd7394 100644 --- a/openstack/networking/v2/subnets/requests.go +++ b/openstack/networking/v2/subnets/requests.go @@ -42,6 +42,7 @@ type ListOpts struct { TagsAny string `q:"tags-any"` NotTags string `q:"not-tags"` NotTagsAny string `q:"not-tags-any"` + RevisionNumber *int `q:"revision_number"` } // ToSubnetListQuery formats a ListOpts into a query string. From 99b0a51a254c4e3332a0117a6f2ed4461bdc99fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Andr=C3=A9?= Date: Thu, 6 Mar 2025 17:27:50 +0100 Subject: [PATCH 095/353] Improve support for network standard-attr-timestamp extension Add a few missing `CreatedAt` and `UpdatedAt` fields for networking resources. --- .../networking/v2/extensions/layer3/routers/results.go | 6 ++++++ .../networking/v2/extensions/security/rules/results.go | 8 ++++++++ openstack/networking/v2/subnets/results.go | 8 ++++++++ 3 files changed, 22 insertions(+) diff --git a/openstack/networking/v2/extensions/layer3/routers/results.go b/openstack/networking/v2/extensions/layer3/routers/results.go index cb2d444034..d75615b773 100644 --- a/openstack/networking/v2/extensions/layer3/routers/results.go +++ b/openstack/networking/v2/extensions/layer3/routers/results.go @@ -80,6 +80,12 @@ type Router struct { // RevisionNumber optionally set via extensions/standard-attr-revisions RevisionNumber int `json:"revision_number"` + + // Timestamp when the router was created + CreatedAt time.Time `json:"created_at"` + + // Timestamp when the router was last updated + UpdatedAt time.Time `json:"updated_at"` } // RouterPage is the page returned by a pager when traversing over a diff --git a/openstack/networking/v2/extensions/security/rules/results.go b/openstack/networking/v2/extensions/security/rules/results.go index 9aa91dbe97..8a3355dfe0 100644 --- a/openstack/networking/v2/extensions/security/rules/results.go +++ b/openstack/networking/v2/extensions/security/rules/results.go @@ -1,6 +1,8 @@ package rules import ( + "time" + "github.com/gophercloud/gophercloud/v2" "github.com/gophercloud/gophercloud/v2/pagination" ) @@ -59,6 +61,12 @@ type SecGroupRule struct { // RevisionNumber optionally set via extensions/standard-attr-revisions RevisionNumber int `json:"revision_number"` + + // Timestamp when the rule was created + CreatedAt time.Time `json:"created_at"` + + // Timestamp when the rule was last updated + UpdatedAt time.Time `json:"updated_at"` } // SecGroupRulePage is the page returned by a pager when traversing over a diff --git a/openstack/networking/v2/subnets/results.go b/openstack/networking/v2/subnets/results.go index 7d5ba13cc5..01c6acc070 100644 --- a/openstack/networking/v2/subnets/results.go +++ b/openstack/networking/v2/subnets/results.go @@ -1,6 +1,8 @@ package subnets import ( + "time" + "github.com/gophercloud/gophercloud/v2" "github.com/gophercloud/gophercloud/v2/pagination" ) @@ -121,6 +123,12 @@ type Subnet struct { // RevisionNumber optionally set via extensions/standard-attr-revisions RevisionNumber int `json:"revision_number"` + + // Timestamp when the subnet was created + CreatedAt time.Time `json:"created_at"` + + // Timestamp when the subnet was last updated + UpdatedAt time.Time `json:"updated_at"` } // SubnetPage is the page returned by a pager when traversing over a collection From 302bf61b00ffc2de5c4275296e6bf4a52645854d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Andr=C3=A9?= Date: Tue, 11 Mar 2025 08:26:17 +0100 Subject: [PATCH 096/353] CI: skip TestLayer3RouterRevision on bobcat Due to https://bugs.launchpad.net/neutron/+bug/2101871, which causes neutron to return a 500 error. --- .../openstack/networking/v2/extensions/layer3/routers_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/internal/acceptance/openstack/networking/v2/extensions/layer3/routers_test.go b/internal/acceptance/openstack/networking/v2/extensions/layer3/routers_test.go index 1df4375164..5930be2a1e 100644 --- a/internal/acceptance/openstack/networking/v2/extensions/layer3/routers_test.go +++ b/internal/acceptance/openstack/networking/v2/extensions/layer3/routers_test.go @@ -216,6 +216,8 @@ func TestLayer3RouterAgents(t *testing.T) { } func TestLayer3RouterRevision(t *testing.T) { + // https://bugs.launchpad.net/neutron/+bug/2101871 + clients.SkipRelease(t, "stable/2023.2") client, err := clients.NewNetworkV2Client() th.AssertNoErr(t, err) From 9e7a3d4942b49dfa736c8808314956be3733ce42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Andr=C3=A9?= Date: Tue, 11 Mar 2025 09:52:44 +0100 Subject: [PATCH 097/353] CI: Fix SkipRelease for stable branches Since 5819dc0c7b6c72a3d6cddb1584e8f28ad42a2cc8, `getReleaseFromEnv()` trims the `stable/` prefix, which caused the condition in `SkipRelease()` to fail if we looked for a release name including the prefix. Fix `SkipRelease()` to account for release names with a `stable/` prefix. --- internal/acceptance/clients/conditions.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/acceptance/clients/conditions.go b/internal/acceptance/clients/conditions.go index 619d31a94e..c48ac208a9 100644 --- a/internal/acceptance/clients/conditions.go +++ b/internal/acceptance/clients/conditions.go @@ -119,7 +119,7 @@ func getReleaseFromEnv(t *testing.T) string { // release. Releases are named such as 'stable/mitaka', master, etc. func SkipRelease(t *testing.T, release string) { current := getReleaseFromEnv(t) - if current == release { + if current == strings.TrimPrefix(release, "stable/") { t.Skipf("this is not supported in %s", release) } } From e0b454daad41a88f229a56aa7f1a2af13cb2cb58 Mon Sep 17 00:00:00 2001 From: Emilien Macchi Date: Fri, 29 Nov 2024 10:26:22 -0500 Subject: [PATCH 098/353] Merge pull request #3209 from shiftstack/proper-service-discovery Configure and respect service type aliases --- endpoint_search.go | 61 ++++++++++++++++++++++- openstack/blockstorage/noauth/requests.go | 4 +- openstack/client.go | 16 +++--- openstack/endpoint_location.go | 6 ++- service_client.go | 10 ++-- testing/endpoint_search_test.go | 4 +- 6 files changed, 83 insertions(+), 18 deletions(-) diff --git a/endpoint_search.go b/endpoint_search.go index 2fbc3c97f1..8818e769b8 100644 --- a/endpoint_search.go +++ b/endpoint_search.go @@ -1,5 +1,7 @@ package gophercloud +import "slices" + // Availability indicates to whom a specific service endpoint is accessible: // the internet at large, internal networks only, or only to administrators. // Different identity services use different terminology for these. Identity v2 @@ -22,6 +24,31 @@ const ( AvailabilityInternal Availability = "internal" ) +// ServiceTypeAliases contains a mapping of service types to any aliases, as +// defined by the OpenStack Service Types Authority. Only service types that +// we support are included. +var ServiceTypeAliases = map[string][]string{ + "application-container": {"container"}, + "baremetal": {"bare-metal"}, + "baremetal-introspection": {}, + "block-storage": {"block-store", "volume", "volumev2", "volumev3"}, + "compute": {}, + "container-infrastructure-management": {"container-infrastructure", "container-infra"}, + "database": {}, + "dns": {}, + "identity": {}, + "image": {}, + "key-manager": {}, + "load-balancer": {}, + "message": {"messaging"}, + "networking": {}, + "object-store": {}, + "orchestration": {}, + "placement": {}, + "shared-file-system": {"sharev2", "share"}, + "workflow": {"workflowv2"}, +} + // EndpointOpts specifies search criteria used by queries against an // OpenStack service catalog. The options must contain enough information to // unambiguously identify one, and only one, endpoint within the catalog. @@ -30,8 +57,9 @@ const ( // package, like "openstack.NewComputeV2()". type EndpointOpts struct { // Type [required] is the service type for the client (e.g., "compute", - // "object-store"). Generally, this will be supplied by the service client - // function, but a user-given value will be honored if provided. + // "object-store"), as defined by the OpenStack Service Types Authority. + // This will generally be supplied by the service client function, but a + // user-given value will be honored if provided. Type string // Name [optional] is the service name for the client (e.g., "nova") as it @@ -39,6 +67,13 @@ type EndpointOpts struct { // different Name, which is why both Type and Name are sometimes needed. Name string + // Aliases [optional] is the set of aliases of the service type (e.g. + // "volumev2"/"volumev3", "volume" and "block-store" for the + // "block-storage" service type), as defined by the OpenStack Service Types + // Authority. As with Type, this will generally be supplied by the service + // client function, but a user-given value will be honored if provided. + Aliases []string + // Region [required] is the geographic region in which the endpoint resides, // generally specifying which datacenter should house your resources. // Required only for services that span multiple regions. @@ -73,4 +108,26 @@ func (eo *EndpointOpts) ApplyDefaults(t string) { if eo.Availability == "" { eo.Availability = AvailabilityPublic } + if len(eo.Aliases) == 0 { + if aliases, ok := ServiceTypeAliases[eo.Type]; ok { + // happy path: user requested a service type by its official name + eo.Aliases = aliases + } else { + // unhappy path: user requested a service type by its alias or an + // invalid/unsupported service type + // TODO(stephenfin): This should probably be an error in v3 + for t, aliases := range ServiceTypeAliases { + if slices.Contains(aliases, eo.Type) { + // we intentionally override the service type, even if it + // was explicitly requested by the user + eo.Type = t + eo.Aliases = aliases + } + } + } + } +} + +func (eo *EndpointOpts) Types() []string { + return append([]string{eo.Type}, eo.Aliases...) } diff --git a/openstack/blockstorage/noauth/requests.go b/openstack/blockstorage/noauth/requests.go index 87f2d9b7f9..cf887553f0 100644 --- a/openstack/blockstorage/noauth/requests.go +++ b/openstack/blockstorage/noauth/requests.go @@ -51,10 +51,10 @@ func initClientOpts(client *gophercloud.ProviderClient, eo EndpointOpts, clientT // NewBlockStorageNoAuthV2 creates a ServiceClient that may be used to access "noauth" v2 block storage service. func NewBlockStorageNoAuthV2(client *gophercloud.ProviderClient, eo EndpointOpts) (*gophercloud.ServiceClient, error) { - return initClientOpts(client, eo, "volumev2") + return initClientOpts(client, eo, "block-storage") } // NewBlockStorageNoAuthV3 creates a ServiceClient that may be used to access "noauth" v3 block storage service. func NewBlockStorageNoAuthV3(client *gophercloud.ProviderClient, eo EndpointOpts) (*gophercloud.ServiceClient, error) { - return initClientOpts(client, eo, "volumev3") + return initClientOpts(client, eo, "block-storage") } diff --git a/openstack/client.go b/openstack/client.go index 43b569d3b4..122a3ee699 100644 --- a/openstack/client.go +++ b/openstack/client.go @@ -344,6 +344,7 @@ func NewIdentityV3(client *gophercloud.ProviderClient, eo gophercloud.EndpointOp }, nil } +// TODO(stephenfin): Allow passing aliases to all New${SERVICE}V${VERSION} methods in v3 func initClientOpts(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts, clientType string) (*gophercloud.ServiceClient, error) { sc := new(gophercloud.ServiceClient) eo.ApplyDefaults(clientType) @@ -393,6 +394,7 @@ func NewNetworkV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpt return sc, err } +// TODO(stephenfin): Remove this in v3. We no longer support the V1 Block Storage service. // NewBlockStorageV1 creates a ServiceClient that may be used to access the v1 // block storage service. func NewBlockStorageV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { @@ -402,17 +404,17 @@ func NewBlockStorageV1(client *gophercloud.ProviderClient, eo gophercloud.Endpoi // NewBlockStorageV2 creates a ServiceClient that may be used to access the v2 // block storage service. func NewBlockStorageV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { - return initClientOpts(client, eo, "volumev2") + return initClientOpts(client, eo, "block-storage") } // NewBlockStorageV3 creates a ServiceClient that may be used to access the v3 block storage service. func NewBlockStorageV3(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { - return initClientOpts(client, eo, "volumev3") + return initClientOpts(client, eo, "block-storage") } // NewSharedFileSystemV2 creates a ServiceClient that may be used to access the v2 shared file system service. func NewSharedFileSystemV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { - return initClientOpts(client, eo, "sharev2") + return initClientOpts(client, eo, "shared-file-system") } // NewOrchestrationV1 creates a ServiceClient that may be used to access the v1 @@ -457,14 +459,14 @@ func NewLoadBalancerV2(client *gophercloud.ProviderClient, eo gophercloud.Endpoi // NewMessagingV2 creates a ServiceClient that may be used with the v2 messaging // service. func NewMessagingV2(client *gophercloud.ProviderClient, clientID string, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { - sc, err := initClientOpts(client, eo, "messaging") + sc, err := initClientOpts(client, eo, "message") sc.MoreHeaders = map[string]string{"Client-ID": clientID} return sc, err } // NewContainerV1 creates a ServiceClient that may be used with v1 container package func NewContainerV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { - return initClientOpts(client, eo, "container") + return initClientOpts(client, eo, "application-container") } // NewKeyManagerV1 creates a ServiceClient that may be used with the v1 key @@ -478,12 +480,12 @@ func NewKeyManagerV1(client *gophercloud.ProviderClient, eo gophercloud.Endpoint // NewContainerInfraV1 creates a ServiceClient that may be used with the v1 container infra management // package. func NewContainerInfraV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { - return initClientOpts(client, eo, "container-infra") + return initClientOpts(client, eo, "container-infrastructure-management") } // NewWorkflowV2 creates a ServiceClient that may be used with the v2 workflow management package. func NewWorkflowV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { - return initClientOpts(client, eo, "workflowv2") + return initClientOpts(client, eo, "workflow") } // NewPlacementV1 creates a ServiceClient that may be used with the placement package. diff --git a/openstack/endpoint_location.go b/openstack/endpoint_location.go index 2cdbd3e7f7..14cff0d755 100644 --- a/openstack/endpoint_location.go +++ b/openstack/endpoint_location.go @@ -1,6 +1,8 @@ package openstack import ( + "slices" + "github.com/gophercloud/gophercloud/v2" tokens2 "github.com/gophercloud/gophercloud/v2/openstack/identity/v2/tokens" tokens3 "github.com/gophercloud/gophercloud/v2/openstack/identity/v3/tokens" @@ -20,7 +22,7 @@ func V2EndpointURL(catalog *tokens2.ServiceCatalog, opts gophercloud.EndpointOpt // Extract Endpoints from the catalog entries that match the requested Type, Name if provided, and Region if provided. var endpoints = make([]tokens2.Endpoint, 0, 1) for _, entry := range catalog.Entries { - if (entry.Type == opts.Type) && (opts.Name == "" || entry.Name == opts.Name) { + if (slices.Contains(opts.Types(), entry.Type)) && (opts.Name == "" || entry.Name == opts.Name) { for _, endpoint := range entry.Endpoints { if opts.Region == "" || endpoint.Region == opts.Region { endpoints = append(endpoints, endpoint) @@ -74,7 +76,7 @@ func V3EndpointURL(catalog *tokens3.ServiceCatalog, opts gophercloud.EndpointOpt // Name if provided, and Region if provided. var endpoints = make([]tokens3.Endpoint, 0, 1) for _, entry := range catalog.Entries { - if (entry.Type == opts.Type) && (opts.Name == "" || entry.Name == opts.Name) { + if (slices.Contains(opts.Types(), entry.Type)) && (opts.Name == "" || entry.Name == opts.Name) { for _, endpoint := range entry.Endpoints { if opts.Availability != gophercloud.AvailabilityAdmin && opts.Availability != gophercloud.AvailabilityPublic && diff --git a/service_client.go b/service_client.go index 11b80108c3..c1f9f41d4d 100644 --- a/service_client.go +++ b/service_client.go @@ -115,13 +115,17 @@ func (client *ServiceClient) Head(ctx context.Context, url string, opts *Request } func (client *ServiceClient) setMicroversionHeader(opts *RequestOpts) { + serviceType := client.Type + switch client.Type { case "compute": opts.MoreHeaders["X-OpenStack-Nova-API-Version"] = client.Microversion - case "sharev2": + case "shared-file-system", "sharev2", "share": opts.MoreHeaders["X-OpenStack-Manila-API-Version"] = client.Microversion - case "volume": + case "block-storage", "block-store", "volume", "volumev3": opts.MoreHeaders["X-OpenStack-Volume-API-Version"] = client.Microversion + // cinder should accept block-storage but (as of Dalmatian) does not + serviceType = "volume" case "baremetal": opts.MoreHeaders["X-OpenStack-Ironic-API-Version"] = client.Microversion case "baremetal-introspection": @@ -129,7 +133,7 @@ func (client *ServiceClient) setMicroversionHeader(opts *RequestOpts) { } if client.Type != "" { - opts.MoreHeaders["OpenStack-API-Version"] = client.Type + " " + client.Microversion + opts.MoreHeaders["OpenStack-API-Version"] = serviceType + " " + client.Microversion } } diff --git a/testing/endpoint_search_test.go b/testing/endpoint_search_test.go index 278955ecdf..c1ae9b92db 100644 --- a/testing/endpoint_search_test.go +++ b/testing/endpoint_search_test.go @@ -10,11 +10,11 @@ import ( func TestApplyDefaultsToEndpointOpts(t *testing.T) { eo := gophercloud.EndpointOpts{Availability: gophercloud.AvailabilityPublic} eo.ApplyDefaults("compute") - expected := gophercloud.EndpointOpts{Availability: gophercloud.AvailabilityPublic, Type: "compute"} + expected := gophercloud.EndpointOpts{Availability: gophercloud.AvailabilityPublic, Type: "compute", Aliases: []string{}} th.CheckDeepEquals(t, expected, eo) eo = gophercloud.EndpointOpts{Type: "compute"} eo.ApplyDefaults("object-store") - expected = gophercloud.EndpointOpts{Availability: gophercloud.AvailabilityPublic, Type: "compute"} + expected = gophercloud.EndpointOpts{Availability: gophercloud.AvailabilityPublic, Type: "compute", Aliases: []string{}} th.CheckDeepEquals(t, expected, eo) } From 88b963b4c7880b8533edc58abb4985bc521e2e39 Mon Sep 17 00:00:00 2001 From: dkokkino Date: Thu, 20 Feb 2025 12:36:13 +0100 Subject: [PATCH 099/353] Enhance Snapshot struct and add ListDetail function in V3 blockstorage - Extended Snapshot struct to include additional fields: Progress, ProjectID, GroupSnapshotID, UserID, ConsumesQuota - Implemented ListDetail function to retrieve detailed snapshot information from the snapshots/detail endpoint - Added new test to validate the inclusion of additional fields and the functionality of the ListDetails function Fixes: #2403 --- .../blockstorage/v3/snapshots_test.go | 17 ++++++ .../blockstorage/v3/snapshots/requests.go | 15 +++++ .../blockstorage/v3/snapshots/results.go | 15 +++++ .../v3/snapshots/testing/fixtures_test.go | 56 +++++++++++++++++++ .../v3/snapshots/testing/requests_test.go | 56 +++++++++++++++++++ openstack/blockstorage/v3/snapshots/urls.go | 4 ++ 6 files changed, 163 insertions(+) diff --git a/internal/acceptance/openstack/blockstorage/v3/snapshots_test.go b/internal/acceptance/openstack/blockstorage/v3/snapshots_test.go index bdb4c8fed3..18f045fc30 100644 --- a/internal/acceptance/openstack/blockstorage/v3/snapshots_test.go +++ b/internal/acceptance/openstack/blockstorage/v3/snapshots_test.go @@ -73,7 +73,24 @@ func TestSnapshots(t *testing.T) { return true, nil }) + th.AssertNoErr(t, err) + + err = snapshots.ListDetail(client, listOpts).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + actual, err := snapshots.ExtractSnapshots(page) + th.AssertNoErr(t, err) + th.AssertEquals(t, 1, len(actual)) + + var found bool + for _, v := range actual { + if v.ID == snapshot1.ID || v.ID == snapshot2.ID { + found = true + } + } + th.AssertEquals(t, found, true) + + return true, nil + }) th.AssertNoErr(t, err) } diff --git a/openstack/blockstorage/v3/snapshots/requests.go b/openstack/blockstorage/v3/snapshots/requests.go index 644e9cb1d3..85b67df879 100644 --- a/openstack/blockstorage/v3/snapshots/requests.go +++ b/openstack/blockstorage/v3/snapshots/requests.go @@ -122,6 +122,21 @@ func List(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pa }) } +// ListDetail returns Snapshots with additional details optionally limited by the conditions provided in ListOpts. +func ListDetail(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { + url := listDetailsURL(client) + if opts != nil { + query, err := opts.ToSnapshotListQuery() + if err != nil { + return pagination.Pager{Err: err} + } + url += query + } + return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { + return SnapshotPage{pagination.LinkedPageBase{PageResult: r}} + }) +} + // UpdateOptsBuilder allows extensions to add additional parameters to the // Update request. type UpdateOptsBuilder interface { diff --git a/openstack/blockstorage/v3/snapshots/results.go b/openstack/blockstorage/v3/snapshots/results.go index 8a1440da42..87a2dec2c6 100644 --- a/openstack/blockstorage/v3/snapshots/results.go +++ b/openstack/blockstorage/v3/snapshots/results.go @@ -36,6 +36,21 @@ type Snapshot struct { // User-defined key-value pairs. Metadata map[string]string `json:"metadata"` + + // Progress of the snapshot creation. + Progress string `json:"os-extended-snapshot-attributes:progress"` + + // Project ID that owns the snapshot. + ProjectID string `json:"os-extended-snapshot-attributes:project_id"` + + // ID of the group snapshot, if applicable. + GroupSnapshotID string `json:"group_snapshot_id"` + + // User ID that created the snapshot. + UserID string `json:"user_id"` + + // Indicates whether the snapshot consumes quota. + ConsumesQuota bool `json:"consumes_quota"` } // CreateResult contains the response body and error from a Create request. diff --git a/openstack/blockstorage/v3/snapshots/testing/fixtures_test.go b/openstack/blockstorage/v3/snapshots/testing/fixtures_test.go index 25e54b9b3e..e1bfd37584 100644 --- a/openstack/blockstorage/v3/snapshots/testing/fixtures_test.go +++ b/openstack/blockstorage/v3/snapshots/testing/fixtures_test.go @@ -61,6 +61,62 @@ func MockListResponse(t *testing.T) { }) } +func MockListDetailsResponse(t *testing.T) { + th.Mux.HandleFunc("/snapshots/detail", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + + if err := r.ParseForm(); err != nil { + t.Errorf("Failed to parse request form %v", err) + } + marker := r.Form.Get("marker") + switch marker { + case "": + fmt.Fprint(w, ` + { + "snapshots": [ + { + "id": "289da7f8-6440-407c-9fb4-7db01ec49164", + "name": "snapshot-001", + "volume_id": "521752a6-acf6-4b2d-bc7a-119f9148cd8c", + "description": "Daily Backup", + "status": "available", + "size": 30, + "created_at": "2017-05-30T03:35:03.000000", + "os-extended-snapshot-attributes:progress": "100%", + "os-extended-snapshot-attributes:project_id": "84b8950a-8594-4e5b-8dce-0dfa9c696357", + "group_snapshot_id": null, + "user_id": "075da7f8-6440-407c-9fb4-7db01ec49531", + "consumes_quota": true + }, + { + "id": "96c3bda7-c82a-4f50-be73-ca7621794835", + "name": "snapshot-002", + "volume_id": "76b8950a-8594-4e5b-8dce-0dfa9c696358", + "description": "Weekly Backup", + "status": "available", + "size": 25, + "created_at": "2017-05-30T03:35:03.000000", + "os-extended-snapshot-attributes:progress": "50%", + "os-extended-snapshot-attributes:project_id": "84b8950a-8594-4e5b-8dce-0dfa9c696357", + "group_snapshot_id": "865da7f8-6440-407c-9fb4-7db01ec40876", + "user_id": "075da7f8-6440-407c-9fb4-7db01ec49531", + "consumes_quota": false + } + ] + } + `) + case "1": + fmt.Fprint(w, `{"snapshots": []}`) + default: + t.Fatalf("Unexpected marker: [%s]", marker) + } + }) +} + // MockGetResponse provides mock response for get snapshot API call func MockGetResponse(t *testing.T) { th.Mux.HandleFunc("/snapshots/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { diff --git a/openstack/blockstorage/v3/snapshots/testing/requests_test.go b/openstack/blockstorage/v3/snapshots/testing/requests_test.go index e0ca0b8e0f..aca65ba7a0 100644 --- a/openstack/blockstorage/v3/snapshots/testing/requests_test.go +++ b/openstack/blockstorage/v3/snapshots/testing/requests_test.go @@ -59,6 +59,62 @@ func TestList(t *testing.T) { } } +func TestDetailList(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + + MockListDetailsResponse(t) + + count := 0 + + err := snapshots.ListDetail(client.ServiceClient(), &snapshots.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + count++ + actual, err := snapshots.ExtractSnapshots(page) + if err != nil { + t.Errorf("Failed to extract snapshots: %v", err) + return false, err + } + expected := []snapshots.Snapshot{ + { + ID: "289da7f8-6440-407c-9fb4-7db01ec49164", + Name: "snapshot-001", + VolumeID: "521752a6-acf6-4b2d-bc7a-119f9148cd8c", + Status: "available", + Size: 30, + CreatedAt: time.Date(2017, 5, 30, 3, 35, 3, 0, time.UTC), + Description: "Daily Backup", + Progress: "100%", + ProjectID: "84b8950a-8594-4e5b-8dce-0dfa9c696357", + GroupSnapshotID: "", + UserID: "075da7f8-6440-407c-9fb4-7db01ec49531", + ConsumesQuota: true, + }, + { + ID: "96c3bda7-c82a-4f50-be73-ca7621794835", + Name: "snapshot-002", + VolumeID: "76b8950a-8594-4e5b-8dce-0dfa9c696358", + Status: "available", + Size: 25, + CreatedAt: time.Date(2017, 5, 30, 3, 35, 3, 0, time.UTC), + Description: "Weekly Backup", + Progress: "50%", + ProjectID: "84b8950a-8594-4e5b-8dce-0dfa9c696357", + GroupSnapshotID: "865da7f8-6440-407c-9fb4-7db01ec40876", + UserID: "075da7f8-6440-407c-9fb4-7db01ec49531", + ConsumesQuota: false, + }, + } + th.CheckDeepEquals(t, expected, actual) + + return true, nil + }) + th.AssertNoErr(t, err) + + if count != 1 { + t.Errorf("Expected 1 page, got %d", count) + } +} + func TestGet(t *testing.T) { th.SetupHTTP() defer th.TeardownHTTP() diff --git a/openstack/blockstorage/v3/snapshots/urls.go b/openstack/blockstorage/v3/snapshots/urls.go index b68cee9ccf..de6a83cc32 100644 --- a/openstack/blockstorage/v3/snapshots/urls.go +++ b/openstack/blockstorage/v3/snapshots/urls.go @@ -18,6 +18,10 @@ func listURL(c *gophercloud.ServiceClient) string { return createURL(c) } +func listDetailsURL(c *gophercloud.ServiceClient) string { + return c.ServiceURL("snapshots", "detail") +} + func updateURL(c *gophercloud.ServiceClient, id string) string { return deleteURL(c, id) } From b76a690afa47c92e990fefa9f75f4583d91ea95d Mon Sep 17 00:00:00 2001 From: Bodo Petermann Date: Wed, 26 Feb 2025 13:55:45 +0100 Subject: [PATCH 100/353] vpnaas: add support for more ciphers (auth, encryption, pfs modes) For VPNaaS IKE policies and IPSEC policies several choices for encryption algorithms, auth algorithms and PFS modes have been added. Encryption algorithms: add AES CCM mode and AES GCM mode variants for 128/192/256 bit keys and 8/12/16 octet ICVs. Add AES CTR modes for 128/192/256 bit keys. Auth algorithms: add aes-xcbc and aes-cmac. PFS: add Diffie Hellman groups 15 to 31. Closes: #3314 --- .../extensions/vpnaas/ikepolicies/requests.go | 72 ++++++++++++++---- .../vpnaas/ipsecpolicies/requests.go | 76 ++++++++++++++----- 2 files changed, 114 insertions(+), 34 deletions(-) diff --git a/openstack/networking/v2/extensions/vpnaas/ikepolicies/requests.go b/openstack/networking/v2/extensions/vpnaas/ikepolicies/requests.go index 7d5c81e13b..f0845d6a60 100644 --- a/openstack/networking/v2/extensions/vpnaas/ikepolicies/requests.go +++ b/openstack/networking/v2/extensions/vpnaas/ikepolicies/requests.go @@ -15,22 +15,62 @@ type IKEVersion string type Phase1NegotiationMode string const ( - AuthAlgorithmSHA1 AuthAlgorithm = "sha1" - AuthAlgorithmSHA256 AuthAlgorithm = "sha256" - AuthAlgorithmSHA384 AuthAlgorithm = "sha384" - AuthAlgorithmSHA512 AuthAlgorithm = "sha512" - EncryptionAlgorithm3DES EncryptionAlgorithm = "3des" - EncryptionAlgorithmAES128 EncryptionAlgorithm = "aes-128" - EncryptionAlgorithmAES256 EncryptionAlgorithm = "aes-256" - EncryptionAlgorithmAES192 EncryptionAlgorithm = "aes-192" - UnitSeconds Unit = "seconds" - UnitKilobytes Unit = "kilobytes" - PFSGroup2 PFS = "group2" - PFSGroup5 PFS = "group5" - PFSGroup14 PFS = "group14" - IKEVersionv1 IKEVersion = "v1" - IKEVersionv2 IKEVersion = "v2" - Phase1NegotiationModeMain Phase1NegotiationMode = "main" + AuthAlgorithmSHA1 AuthAlgorithm = "sha1" + AuthAlgorithmSHA256 AuthAlgorithm = "sha256" + AuthAlgorithmSHA384 AuthAlgorithm = "sha384" + AuthAlgorithmSHA512 AuthAlgorithm = "sha512" + AuthAlgorithmAESXCBC AuthAlgorithm = "aes-xcbc" + AuthAlgorithmAESCMAC AuthAlgorithm = "aes-cmac" + EncryptionAlgorithm3DES EncryptionAlgorithm = "3des" + EncryptionAlgorithmAES128 EncryptionAlgorithm = "aes-128" + EncryptionAlgorithmAES192 EncryptionAlgorithm = "aes-192" + EncryptionAlgorithmAES256 EncryptionAlgorithm = "aes-256" + EncryptionAlgorithmAES128CTR EncryptionAlgorithm = "aes-128-ctr" + EncryptionAlgorithmAES192CTR EncryptionAlgorithm = "aes-192-ctr" + EncryptionAlgorithmAES256CTR EncryptionAlgorithm = "aes-256-ctr" + EncryptionAlgorithmAES128CCM8 EncryptionAlgorithm = "aes-128-ccm-8" + EncryptionAlgorithmAES128CCM12 EncryptionAlgorithm = "aes-128-ccm-12" + EncryptionAlgorithmAES128CCM16 EncryptionAlgorithm = "aes-128-ccm-16" + EncryptionAlgorithmAES192CCM8 EncryptionAlgorithm = "aes-192-ccm-8" + EncryptionAlgorithmAES192CCM12 EncryptionAlgorithm = "aes-192-ccm-12" + EncryptionAlgorithmAES192CCM16 EncryptionAlgorithm = "aes-192-ccm-16" + EncryptionAlgorithmAES256CCM8 EncryptionAlgorithm = "aes-256-ccm-8" + EncryptionAlgorithmAES256CCM12 EncryptionAlgorithm = "aes-256-ccm-12" + EncryptionAlgorithmAES256CCM16 EncryptionAlgorithm = "aes-256-ccm-16" + EncryptionAlgorithmAES128GCM8 EncryptionAlgorithm = "aes-128-gcm-8" + EncryptionAlgorithmAES128GCM12 EncryptionAlgorithm = "aes-128-gcm-12" + EncryptionAlgorithmAES128GCM16 EncryptionAlgorithm = "aes-128-gcm-16" + EncryptionAlgorithmAES192GCM8 EncryptionAlgorithm = "aes-192-gcm-8" + EncryptionAlgorithmAES192GCM12 EncryptionAlgorithm = "aes-192-gcm-12" + EncryptionAlgorithmAES192GCM16 EncryptionAlgorithm = "aes-192-gcm-16" + EncryptionAlgorithmAES256GCM8 EncryptionAlgorithm = "aes-256-gcm-8" + EncryptionAlgorithmAES256GCM12 EncryptionAlgorithm = "aes-256-gcm-12" + EncryptionAlgorithmAES256GCM16 EncryptionAlgorithm = "aes-256-gcm-16" + UnitSeconds Unit = "seconds" + UnitKilobytes Unit = "kilobytes" + PFSGroup2 PFS = "group2" + PFSGroup5 PFS = "group5" + PFSGroup14 PFS = "group14" + PFSGroup15 PFS = "group15" + PFSGroup16 PFS = "group16" + PFSGroup17 PFS = "group17" + PFSGroup18 PFS = "group18" + PFSGroup19 PFS = "group19" + PFSGroup20 PFS = "group20" + PFSGroup21 PFS = "group21" + PFSGroup22 PFS = "group22" + PFSGroup23 PFS = "group23" + PFSGroup24 PFS = "group24" + PFSGroup25 PFS = "group25" + PFSGroup26 PFS = "group26" + PFSGroup27 PFS = "group27" + PFSGroup28 PFS = "group28" + PFSGroup29 PFS = "group29" + PFSGroup30 PFS = "group30" + PFSGroup31 PFS = "group31" + IKEVersionv1 IKEVersion = "v1" + IKEVersionv2 IKEVersion = "v2" + Phase1NegotiationModeMain Phase1NegotiationMode = "main" ) // CreateOptsBuilder allows extensions to add additional parameters to the diff --git a/openstack/networking/v2/extensions/vpnaas/ipsecpolicies/requests.go b/openstack/networking/v2/extensions/vpnaas/ipsecpolicies/requests.go index 4397c0587b..9f34895c15 100644 --- a/openstack/networking/v2/extensions/vpnaas/ipsecpolicies/requests.go +++ b/openstack/networking/v2/extensions/vpnaas/ipsecpolicies/requests.go @@ -15,24 +15,64 @@ type PFS string type Unit string const ( - TransformProtocolESP TransformProtocol = "esp" - TransformProtocolAH TransformProtocol = "ah" - TransformProtocolAHESP TransformProtocol = "ah-esp" - AuthAlgorithmSHA1 AuthAlgorithm = "sha1" - AuthAlgorithmSHA256 AuthAlgorithm = "sha256" - AuthAlgorithmSHA384 AuthAlgorithm = "sha384" - AuthAlgorithmSHA512 AuthAlgorithm = "sha512" - EncryptionAlgorithm3DES EncryptionAlgorithm = "3des" - EncryptionAlgorithmAES128 EncryptionAlgorithm = "aes-128" - EncryptionAlgorithmAES256 EncryptionAlgorithm = "aes-256" - EncryptionAlgorithmAES192 EncryptionAlgorithm = "aes-192" - EncapsulationModeTunnel EncapsulationMode = "tunnel" - EncapsulationModeTransport EncapsulationMode = "transport" - UnitSeconds Unit = "seconds" - UnitKilobytes Unit = "kilobytes" - PFSGroup2 PFS = "group2" - PFSGroup5 PFS = "group5" - PFSGroup14 PFS = "group14" + TransformProtocolESP TransformProtocol = "esp" + TransformProtocolAH TransformProtocol = "ah" + TransformProtocolAHESP TransformProtocol = "ah-esp" + AuthAlgorithmSHA1 AuthAlgorithm = "sha1" + AuthAlgorithmSHA256 AuthAlgorithm = "sha256" + AuthAlgorithmSHA384 AuthAlgorithm = "sha384" + AuthAlgorithmSHA512 AuthAlgorithm = "sha512" + AuthAlgorithmAESXCBC AuthAlgorithm = "aes-xcbc" + AuthAlgorithmAESCMAC AuthAlgorithm = "aes-cmac" + EncryptionAlgorithm3DES EncryptionAlgorithm = "3des" + EncryptionAlgorithmAES128 EncryptionAlgorithm = "aes-128" + EncryptionAlgorithmAES192 EncryptionAlgorithm = "aes-192" + EncryptionAlgorithmAES256 EncryptionAlgorithm = "aes-256" + EncryptionAlgorithmAES128CTR EncryptionAlgorithm = "aes-128-ctr" + EncryptionAlgorithmAES192CTR EncryptionAlgorithm = "aes-192-ctr" + EncryptionAlgorithmAES256CTR EncryptionAlgorithm = "aes-256-ctr" + EncryptionAlgorithmAES128CCM8 EncryptionAlgorithm = "aes-128-ccm-8" + EncryptionAlgorithmAES128CCM12 EncryptionAlgorithm = "aes-128-ccm-12" + EncryptionAlgorithmAES128CCM16 EncryptionAlgorithm = "aes-128-ccm-16" + EncryptionAlgorithmAES192CCM8 EncryptionAlgorithm = "aes-192-ccm-8" + EncryptionAlgorithmAES192CCM12 EncryptionAlgorithm = "aes-192-ccm-12" + EncryptionAlgorithmAES192CCM16 EncryptionAlgorithm = "aes-192-ccm-16" + EncryptionAlgorithmAES256CCM8 EncryptionAlgorithm = "aes-256-ccm-8" + EncryptionAlgorithmAES256CCM12 EncryptionAlgorithm = "aes-256-ccm-12" + EncryptionAlgorithmAES256CCM16 EncryptionAlgorithm = "aes-256-ccm-16" + EncryptionAlgorithmAES128GCM8 EncryptionAlgorithm = "aes-128-gcm-8" + EncryptionAlgorithmAES128GCM12 EncryptionAlgorithm = "aes-128-gcm-12" + EncryptionAlgorithmAES128GCM16 EncryptionAlgorithm = "aes-128-gcm-16" + EncryptionAlgorithmAES192GCM8 EncryptionAlgorithm = "aes-192-gcm-8" + EncryptionAlgorithmAES192GCM12 EncryptionAlgorithm = "aes-192-gcm-12" + EncryptionAlgorithmAES192GCM16 EncryptionAlgorithm = "aes-192-gcm-16" + EncryptionAlgorithmAES256GCM8 EncryptionAlgorithm = "aes-256-gcm-8" + EncryptionAlgorithmAES256GCM12 EncryptionAlgorithm = "aes-256-gcm-12" + EncryptionAlgorithmAES256GCM16 EncryptionAlgorithm = "aes-256-gcm-16" + EncapsulationModeTunnel EncapsulationMode = "tunnel" + EncapsulationModeTransport EncapsulationMode = "transport" + UnitSeconds Unit = "seconds" + UnitKilobytes Unit = "kilobytes" + PFSGroup2 PFS = "group2" + PFSGroup5 PFS = "group5" + PFSGroup14 PFS = "group14" + PFSGroup15 PFS = "group15" + PFSGroup16 PFS = "group16" + PFSGroup17 PFS = "group17" + PFSGroup18 PFS = "group18" + PFSGroup19 PFS = "group19" + PFSGroup20 PFS = "group20" + PFSGroup21 PFS = "group21" + PFSGroup22 PFS = "group22" + PFSGroup23 PFS = "group23" + PFSGroup24 PFS = "group24" + PFSGroup25 PFS = "group25" + PFSGroup26 PFS = "group26" + PFSGroup27 PFS = "group27" + PFSGroup28 PFS = "group28" + PFSGroup29 PFS = "group29" + PFSGroup30 PFS = "group30" + PFSGroup31 PFS = "group31" ) // CreateOptsBuilder allows extensions to add additional parameters to the From c9240e7aa89fd0782b7fb8e651e0a4cace68edca Mon Sep 17 00:00:00 2001 From: Sharpz7 Date: Mon, 24 Feb 2025 21:57:36 +0000 Subject: [PATCH 101/353] Added support for VIF's in Baremetal --- .../openstack/baremetal/v1/nodes_test.go | 47 +++++++++++ openstack/baremetal/v1/nodes/requests.go | 58 ++++++++++++++ openstack/baremetal/v1/nodes/results.go | 37 +++++++++ .../v1/nodes/testing/fixtures_test.go | 75 +++++++++++++++++ .../v1/nodes/testing/requests_test.go | 80 +++++++++++++++++++ openstack/baremetal/v1/nodes/urls.go | 8 ++ 6 files changed, 305 insertions(+) diff --git a/internal/acceptance/openstack/baremetal/v1/nodes_test.go b/internal/acceptance/openstack/baremetal/v1/nodes_test.go index 669ea69cdc..b3a2923fbf 100644 --- a/internal/acceptance/openstack/baremetal/v1/nodes_test.go +++ b/internal/acceptance/openstack/baremetal/v1/nodes_test.go @@ -272,3 +272,50 @@ func TestNodesServicingHold(t *testing.T) { }, nodes.Active) th.AssertNoErr(t, err) } + +func TestNodesVirtualInterfaces(t *testing.T) { + clients.SkipReleasesBelow(t, "stable/2023.2") // Adjust based on when this feature was added + clients.RequireLong(t) + + client, err := clients.NewBareMetalV1Client() + th.AssertNoErr(t, err) + client.Microversion = "1.28" // VIFs were added in API version 1.28 + + node, err := CreateNode(t, client) + th.AssertNoErr(t, err) + defer DeleteNode(t, client, node) + + // First, list VIFs (should be empty initially) + vifs, err := nodes.ListVirtualInterfaces(context.TODO(), client, node.UUID).Extract() + th.AssertNoErr(t, err) + th.AssertEquals(t, 0, len(vifs)) + + // For a real test, we would need a valid VIF ID from the networking service + // Since this is difficult in a test environment, we can test the API call + // with a fake ID and expect it to fail with a specific error + fakeVifID := "1974dcfa-836f-41b2-b541-686c100900e5" + + // Try to attach a VIF (this will likely fail with a 404 Not Found since the VIF doesn't exist) + err = nodes.AttachVirtualInterface(context.TODO(), client, node.UUID, nodes.VirtualInterfaceOpts{ + ID: fakeVifID, + }).ExtractErr() + + // We expect this to fail, but we're testing the API call itself + // In a real environment with valid VIFs, you would check for success instead + if err == nil { + t.Logf("Warning: Expected error when attaching non-existent VIF, but got success. This might indicate the test environment has a VIF with ID %s", fakeVifID) + } + + // Try to detach a VIF (this will likely fail with a 404 Not Found) + err = nodes.DetachVirtualInterface(context.TODO(), client, node.UUID, fakeVifID).ExtractErr() + + // Again, we expect this to fail in most test environments + if err == nil { + t.Logf("Warning: Expected error when detaching non-existent VIF, but got success. This might indicate the test environment has a VIF with ID %s", fakeVifID) + } + + // List VIFs again to confirm state hasn't changed + vifs, err = nodes.ListVirtualInterfaces(context.TODO(), client, node.UUID).Extract() + th.AssertNoErr(t, err) + th.AssertEquals(t, 0, len(vifs)) +} diff --git a/openstack/baremetal/v1/nodes/requests.go b/openstack/baremetal/v1/nodes/requests.go index 8b2eb4b218..cddd269a3d 100644 --- a/openstack/baremetal/v1/nodes/requests.go +++ b/openstack/baremetal/v1/nodes/requests.go @@ -1002,3 +1002,61 @@ func DetachVirtualMedia(ctx context.Context, client *gophercloud.ServiceClient, _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) return } + +// VirtualInterfaceOpts defines options for attaching a VIF to a node +type VirtualInterfaceOpts struct { + // The UUID or name of the VIF + ID string `json:"id" required:"true"` + // The UUID of a port to attach the VIF to. Cannot be specified with PortgroupUUID + PortUUID string `json:"port_uuid,omitempty"` + // The UUID of a portgroup to attach the VIF to. Cannot be specified with PortUUID + PortgroupUUID string `json:"portgroup_uuid,omitempty"` +} + +// VirtualInterfaceOptsBuilder allows extensions to add additional parameters to the +// AttachVirtualInterface request. +type VirtualInterfaceOptsBuilder interface { + ToVirtualInterfaceMap() (map[string]any, error) +} + +// ToVirtualInterfaceMap assembles a request body based on the contents of a VirtualInterfaceOpts. +func (opts VirtualInterfaceOpts) ToVirtualInterfaceMap() (map[string]any, error) { + if opts.PortUUID != "" && opts.PortgroupUUID != "" { + return nil, fmt.Errorf("cannot specify both port_uuid and portgroup_uuid") + } + + return gophercloud.BuildRequestBody(opts, "") +} + +// ListVirtualInterfaces returns a list of VIFs that are attached to the node. +func ListVirtualInterfaces(ctx context.Context, client *gophercloud.ServiceClient, id string) (r ListVirtualInterfacesResult) { + resp, err := client.Get(ctx, virtualInterfaceURL(client, id), &r.Body, &gophercloud.RequestOpts{ + OkCodes: []int{200}, + }) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} + +// AttachVirtualInterface attaches a VIF to a node. +func AttachVirtualInterface(ctx context.Context, client *gophercloud.ServiceClient, id string, opts VirtualInterfaceOptsBuilder) (r VirtualInterfaceAttachResult) { + reqBody, err := opts.ToVirtualInterfaceMap() + if err != nil { + r.Err = err + return + } + + resp, err := client.Post(ctx, virtualInterfaceURL(client, id), reqBody, nil, &gophercloud.RequestOpts{ + OkCodes: []int{204}, + }) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} + +// DetachVirtualInterface detaches a VIF from a node. +func DetachVirtualInterface(ctx context.Context, client *gophercloud.ServiceClient, id string, vifID string) (r VirtualInterfaceDetachResult) { + resp, err := client.Delete(ctx, virtualInterfaceDeleteURL(client, id, vifID), &gophercloud.RequestOpts{ + OkCodes: []int{204}, + }) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} diff --git a/openstack/baremetal/v1/nodes/results.go b/openstack/baremetal/v1/nodes/results.go index 507e0d6a4f..3e1976d3ef 100644 --- a/openstack/baremetal/v1/nodes/results.go +++ b/openstack/baremetal/v1/nodes/results.go @@ -710,3 +710,40 @@ type VirtualMediaAttachResult struct { type VirtualMediaDetachResult struct { gophercloud.ErrResult } + +// VirtualInterfaceAttachResult is the response from an AttachVirtualInterface operation. +type VirtualInterfaceAttachResult struct { + gophercloud.ErrResult +} + +// VirtualInterfaceDetachResult is the response from a DetachVirtualInterface operation. +type VirtualInterfaceDetachResult struct { + gophercloud.ErrResult +} + +// VIF represents a virtual interface attached to a node. +type VIF struct { + // The UUID or name of the VIF + ID string `json:"id"` +} + +// ListVirtualInterfacesResult is the response from a ListVirtualInterfaces operation. +type ListVirtualInterfacesResult struct { + gophercloud.Result + gophercloud.HeaderResult +} + +// Extract interprets any ListVirtualInterfacesResult as a list of VIFs. +func (r ListVirtualInterfacesResult) Extract() ([]VIF, error) { + var s struct { + VIFs []VIF `json:"vifs"` + } + + err := r.Result.ExtractInto(&s) + return s.VIFs, err +} + +// ExtractHeader interprets any ListVirtualInterfacesResult as a HeaderResult. +func (r ListVirtualInterfacesResult) ExtractHeader() (gophercloud.HeaderResult, error) { + return r.HeaderResult, nil +} diff --git a/openstack/baremetal/v1/nodes/testing/fixtures_test.go b/openstack/baremetal/v1/nodes/testing/fixtures_test.go index 88abebcebb..282d5dbc7f 100644 --- a/openstack/baremetal/v1/nodes/testing/fixtures_test.go +++ b/openstack/baremetal/v1/nodes/testing/fixtures_test.go @@ -1849,3 +1849,78 @@ func HandleDetachVirtualMediaSuccessfully(t *testing.T, withType bool) { w.WriteHeader(http.StatusNoContent) }) } + +// HandleListVirtualInterfacesSuccessfully sets up the test server to respond to a ListVirtualInterfaces request +func HandleListVirtualInterfacesSuccessfully(t *testing.T) { + th.Mux.HandleFunc("/nodes/1234asdf/vifs", + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.TestHeader(t, r, "Accept", "application/json") + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + fmt.Fprintf(w, ` +{ + "vifs": [ + { + "id": "1974dcfa-836f-41b2-b541-686c100900e5" + } + ] +}`) + }) +} + +// HandleAttachVirtualInterfaceSuccessfully sets up the test server to respond to an AttachVirtualInterface request +func HandleAttachVirtualInterfaceSuccessfully(t *testing.T) { + th.Mux.HandleFunc("/nodes/1234asdf/vifs", + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "POST") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.TestHeader(t, r, "Content-Type", "application/json") + th.TestHeader(t, r, "Accept", "application/json") + th.TestJSONRequest(t, r, `{"id":"1974dcfa-836f-41b2-b541-686c100900e5"}`) + + w.WriteHeader(http.StatusNoContent) + }) +} + +// HandleAttachVirtualInterfaceWithPortSuccessfully sets up the test server to respond to an AttachVirtualInterface request with port +func HandleAttachVirtualInterfaceWithPortSuccessfully(t *testing.T) { + th.Mux.HandleFunc("/nodes/1234asdf/vifs", + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "POST") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.TestHeader(t, r, "Content-Type", "application/json") + th.TestHeader(t, r, "Accept", "application/json") + th.TestJSONRequest(t, r, `{"id":"1974dcfa-836f-41b2-b541-686c100900e5","port_uuid":"b2f96298-5172-45e9-b174-8d1ba936ab47"}`) + + w.WriteHeader(http.StatusNoContent) + }) +} + +// HandleAttachVirtualInterfaceWithPortgroupSuccessfully sets up the test server to respond to an AttachVirtualInterface request with portgroup +func HandleAttachVirtualInterfaceWithPortgroupSuccessfully(t *testing.T) { + th.Mux.HandleFunc("/nodes/1234asdf/vifs", + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "POST") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.TestHeader(t, r, "Content-Type", "application/json") + th.TestHeader(t, r, "Accept", "application/json") + th.TestJSONRequest(t, r, `{"id":"1974dcfa-836f-41b2-b541-686c100900e5","portgroup_uuid":"c24944b5-a52e-4c5c-9c0a-52a0235a08a2"}`) + + w.WriteHeader(http.StatusNoContent) + }) +} + +// HandleDetachVirtualInterfaceSuccessfully sets up the test server to respond to a DetachVirtualInterface request +func HandleDetachVirtualInterfaceSuccessfully(t *testing.T) { + th.Mux.HandleFunc("/nodes/1234asdf/vifs/1974dcfa-836f-41b2-b541-686c100900e5", + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "DELETE") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.TestHeader(t, r, "Accept", "application/json") + + w.WriteHeader(http.StatusNoContent) + }) +} diff --git a/openstack/baremetal/v1/nodes/testing/requests_test.go b/openstack/baremetal/v1/nodes/testing/requests_test.go index 5529e795ad..487c350175 100644 --- a/openstack/baremetal/v1/nodes/testing/requests_test.go +++ b/openstack/baremetal/v1/nodes/testing/requests_test.go @@ -829,3 +829,83 @@ func TestVirtualMediaDetachWithTypes(t *testing.T) { err := nodes.DetachVirtualMedia(context.TODO(), c, "1234asdf", opts).ExtractErr() th.AssertNoErr(t, err) } + +func TestListVirtualInterfaces(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + HandleListVirtualInterfacesSuccessfully(t) + + c := client.ServiceClient() + actual, err := nodes.ListVirtualInterfaces(context.TODO(), c, "1234asdf").Extract() + th.AssertNoErr(t, err) + + expected := []nodes.VIF{ + { + ID: "1974dcfa-836f-41b2-b541-686c100900e5", + }, + } + + th.CheckDeepEquals(t, expected, actual) +} + +func TestAttachVirtualInterface(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + HandleAttachVirtualInterfaceSuccessfully(t) + + c := client.ServiceClient() + opts := nodes.VirtualInterfaceOpts{ + ID: "1974dcfa-836f-41b2-b541-686c100900e5", + } + err := nodes.AttachVirtualInterface(context.TODO(), c, "1234asdf", opts).ExtractErr() + th.AssertNoErr(t, err) +} + +func TestAttachVirtualInterfaceWithPort(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + HandleAttachVirtualInterfaceWithPortSuccessfully(t) + + c := client.ServiceClient() + opts := nodes.VirtualInterfaceOpts{ + ID: "1974dcfa-836f-41b2-b541-686c100900e5", + PortUUID: "b2f96298-5172-45e9-b174-8d1ba936ab47", + } + err := nodes.AttachVirtualInterface(context.TODO(), c, "1234asdf", opts).ExtractErr() + th.AssertNoErr(t, err) +} + +func TestAttachVirtualInterfaceWithPortgroup(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + HandleAttachVirtualInterfaceWithPortgroupSuccessfully(t) + + c := client.ServiceClient() + opts := nodes.VirtualInterfaceOpts{ + ID: "1974dcfa-836f-41b2-b541-686c100900e5", + PortgroupUUID: "c24944b5-a52e-4c5c-9c0a-52a0235a08a2", + } + err := nodes.AttachVirtualInterface(context.TODO(), c, "1234asdf", opts).ExtractErr() + th.AssertNoErr(t, err) +} + +func TestDetachVirtualInterface(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + HandleDetachVirtualInterfaceSuccessfully(t) + + c := client.ServiceClient() + err := nodes.DetachVirtualInterface(context.TODO(), c, "1234asdf", "1974dcfa-836f-41b2-b541-686c100900e5").ExtractErr() + th.AssertNoErr(t, err) +} + +func TestVirtualInterfaceOptsValidation(t *testing.T) { + opts := nodes.VirtualInterfaceOpts{ + ID: "1974dcfa-836f-41b2-b541-686c100900e5", + PortUUID: "b2f96298-5172-45e9-b174-8d1ba936ab47", + PortgroupUUID: "c24944b5-a52e-4c5c-9c0a-52a0235a08a2", + } + + _, err := opts.ToVirtualInterfaceMap() + th.AssertEquals(t, err.Error(), "cannot specify both port_uuid and portgroup_uuid") +} diff --git a/openstack/baremetal/v1/nodes/urls.go b/openstack/baremetal/v1/nodes/urls.go index 2948bb659e..b86e4820e5 100644 --- a/openstack/baremetal/v1/nodes/urls.go +++ b/openstack/baremetal/v1/nodes/urls.go @@ -89,3 +89,11 @@ func firmwareListURL(client *gophercloud.ServiceClient, id string) string { func virtualMediaURL(client *gophercloud.ServiceClient, id string) string { return client.ServiceURL("nodes", id, "vmedia") } + +func virtualInterfaceURL(client *gophercloud.ServiceClient, id string) string { + return client.ServiceURL("nodes", id, "vifs") +} + +func virtualInterfaceDeleteURL(client *gophercloud.ServiceClient, id string, vifID string) string { + return client.ServiceURL("nodes", id, "vifs", vifID) +} From cf7f9d959a08af748051b5f118970ecdba68f412 Mon Sep 17 00:00:00 2001 From: Sharpz7 Date: Fri, 28 Feb 2025 05:43:17 +0000 Subject: [PATCH 102/353] Added bugfix for functional tests --- internal/acceptance/openstack/baremetal/v1/nodes_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/internal/acceptance/openstack/baremetal/v1/nodes_test.go b/internal/acceptance/openstack/baremetal/v1/nodes_test.go index b3a2923fbf..1151135e62 100644 --- a/internal/acceptance/openstack/baremetal/v1/nodes_test.go +++ b/internal/acceptance/openstack/baremetal/v1/nodes_test.go @@ -279,7 +279,8 @@ func TestNodesVirtualInterfaces(t *testing.T) { client, err := clients.NewBareMetalV1Client() th.AssertNoErr(t, err) - client.Microversion = "1.28" // VIFs were added in API version 1.28 + // VIFs were added in API version 1.28, but at least 1.38 is needed for tests to pass + client.Microversion = "1.38" node, err := CreateNode(t, client) th.AssertNoErr(t, err) From 18d7f8d8bf0b99e4e80c80e031e0f62c866f28c5 Mon Sep 17 00:00:00 2001 From: Himanshu Roy Date: Mon, 3 Feb 2025 19:04:34 +0530 Subject: [PATCH 103/353] add support to get virtual media for a node --- openstack/baremetal/v1/nodes/requests.go | 12 ++++++++++++ openstack/baremetal/v1/nodes/results.go | 5 +++++ 2 files changed, 17 insertions(+) diff --git a/openstack/baremetal/v1/nodes/requests.go b/openstack/baremetal/v1/nodes/requests.go index cddd269a3d..6268f5037e 100644 --- a/openstack/baremetal/v1/nodes/requests.go +++ b/openstack/baremetal/v1/nodes/requests.go @@ -1003,6 +1003,18 @@ func DetachVirtualMedia(ctx context.Context, client *gophercloud.ServiceClient, return } +// Request the list of virtual media devices attached to the Node. +// Requires microversion 1.93 or later. +func GetVirtualMedia(ctx context.Context, client *gophercloud.ServiceClient, id string) (r VirtualMediaGetResult) { + + resp, err := client.Get(ctx, virtualMediaURL(client, id), &r.Body, &gophercloud.RequestOpts{ + OkCodes: []int{200}, + }) + + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} + // VirtualInterfaceOpts defines options for attaching a VIF to a node type VirtualInterfaceOpts struct { // The UUID or name of the VIF diff --git a/openstack/baremetal/v1/nodes/results.go b/openstack/baremetal/v1/nodes/results.go index 3e1976d3ef..b33517a388 100644 --- a/openstack/baremetal/v1/nodes/results.go +++ b/openstack/baremetal/v1/nodes/results.go @@ -711,6 +711,11 @@ type VirtualMediaDetachResult struct { gophercloud.ErrResult } +// Requires microversion 1.93 or later. +type VirtualMediaGetResult struct { + gophercloud.Result +} + // VirtualInterfaceAttachResult is the response from an AttachVirtualInterface operation. type VirtualInterfaceAttachResult struct { gophercloud.ErrResult From 7ffac16b10a06a23814ff6b14a786d0b5b39683a Mon Sep 17 00:00:00 2001 From: Himanshu Roy Date: Fri, 14 Feb 2025 17:19:45 +0530 Subject: [PATCH 104/353] virtual media get api tests Signed-off-by: Himanshu Roy --- .../openstack/baremetal/v1/nodes_test.go | 5 ++- .../v1/nodes/testing/fixtures_test.go | 35 +++++++++++++++++++ .../v1/nodes/testing/requests_test.go | 20 +++++++++++ 3 files changed, 59 insertions(+), 1 deletion(-) diff --git a/internal/acceptance/openstack/baremetal/v1/nodes_test.go b/internal/acceptance/openstack/baremetal/v1/nodes_test.go index 1151135e62..a4865783a1 100644 --- a/internal/acceptance/openstack/baremetal/v1/nodes_test.go +++ b/internal/acceptance/openstack/baremetal/v1/nodes_test.go @@ -219,7 +219,7 @@ func TestNodesVirtualMedia(t *testing.T) { client, err := clients.NewBareMetalV1Client() th.AssertNoErr(t, err) - client.Microversion = "1.89" + client.Microversion = "1.93" node, err := CreateNode(t, client) th.AssertNoErr(t, err) @@ -241,6 +241,9 @@ func TestNodesVirtualMedia(t *testing.T) { err = nodes.DetachVirtualMedia(context.TODO(), client, node.UUID, nodes.DetachVirtualMediaOpts{}).ExtractErr() th.AssertNoErr(t, err) + + err = nodes.GetVirtualMedia(context.TODO(), client, node.UUID).Err + th.AssertNoErr(t, err) } func TestNodesServicingHold(t *testing.T) { diff --git a/openstack/baremetal/v1/nodes/testing/fixtures_test.go b/openstack/baremetal/v1/nodes/testing/fixtures_test.go index 282d5dbc7f..371a4f00a9 100644 --- a/openstack/baremetal/v1/nodes/testing/fixtures_test.go +++ b/openstack/baremetal/v1/nodes/testing/fixtures_test.go @@ -900,6 +900,28 @@ const NodeVirtualMediaAttachBodyWithSource = ` } ` +const NodeVirtualMediaGetBodyAttached = ` +{ + "image": "https://example.com/image", + "inserted": true, + "media_types": [ + "CD", + "DVD" + ] +} +` + +const NodeVirtualMediaGetBodyNotAttached = ` +{ + "image": "", + "inserted": false, + "media_types": [ + "CD", + "DVD" + ] +} +` + var ( createdAtFoo, _ = time.Parse(time.RFC3339, "2019-01-31T19:59:28+00:00") createdAtBar, _ = time.Parse(time.RFC3339, "2019-01-31T19:59:29+00:00") @@ -1850,6 +1872,19 @@ func HandleDetachVirtualMediaSuccessfully(t *testing.T, withType bool) { }) } +func HandleGetVirtualMediaSuccessfully(t *testing.T, attached bool) { + th.Mux.HandleFunc("/nodes/1234asdf/vmedia", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + w.WriteHeader(http.StatusOK) + if attached { + fmt.Fprint(w, NodeVirtualMediaGetBodyAttached) + } else { + fmt.Fprint(w, NodeVirtualMediaGetBodyNotAttached) + } + }) +} + // HandleListVirtualInterfacesSuccessfully sets up the test server to respond to a ListVirtualInterfaces request func HandleListVirtualInterfacesSuccessfully(t *testing.T) { th.Mux.HandleFunc("/nodes/1234asdf/vifs", diff --git a/openstack/baremetal/v1/nodes/testing/requests_test.go b/openstack/baremetal/v1/nodes/testing/requests_test.go index 487c350175..24452be0c2 100644 --- a/openstack/baremetal/v1/nodes/testing/requests_test.go +++ b/openstack/baremetal/v1/nodes/testing/requests_test.go @@ -830,6 +830,26 @@ func TestVirtualMediaDetachWithTypes(t *testing.T) { th.AssertNoErr(t, err) } +func TestVirtualMediaGetAttached(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + HandleGetVirtualMediaSuccessfully(t, true) + + c := client.ServiceClient() + err := nodes.GetVirtualMedia(context.TODO(), c, "1234asdf").Err + th.AssertNoErr(t, err) +} + +func TestVirtualMediaGetNotAttached(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + HandleGetVirtualMediaSuccessfully(t, false) + + c := client.ServiceClient() + err := nodes.GetVirtualMedia(context.TODO(), c, "1234asdf").Err + th.AssertNoErr(t, err) +} + func TestListVirtualInterfaces(t *testing.T) { th.SetupHTTP() defer th.TeardownHTTP() From b33345d7170b81c89d13ecb08e10560367b592e0 Mon Sep 17 00:00:00 2001 From: Himanshu Roy Date: Fri, 7 Mar 2025 10:44:15 +0530 Subject: [PATCH 105/353] ignore error for vmedia get api for ipmi driver Signed-off-by: Himanshu Roy --- internal/acceptance/openstack/baremetal/v1/nodes_test.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/internal/acceptance/openstack/baremetal/v1/nodes_test.go b/internal/acceptance/openstack/baremetal/v1/nodes_test.go index a4865783a1..be48ee9197 100644 --- a/internal/acceptance/openstack/baremetal/v1/nodes_test.go +++ b/internal/acceptance/openstack/baremetal/v1/nodes_test.go @@ -243,7 +243,13 @@ func TestNodesVirtualMedia(t *testing.T) { th.AssertNoErr(t, err) err = nodes.GetVirtualMedia(context.TODO(), client, node.UUID).Err - th.AssertNoErr(t, err) + // Since Virtual Media GET api call is synchronous, we get a HTTP 400 + // response as CreateNode has ipmi driver hardcoded, but the api is + // only supported by the redfish driver + // (TODO: hroyrh) fix this once redfish driver is used in the tests + if node.Driver == "redfish" { + th.AssertNoErr(t, err) + } } func TestNodesServicingHold(t *testing.T) { From 11349b4c3f71c79bf2322189f13da3033a678dfd Mon Sep 17 00:00:00 2001 From: Pierre Prinetti Date: Thu, 3 Apr 2025 11:39:47 +0200 Subject: [PATCH 106/353] Prepare v2.7.0 --- CHANGELOG.md | 11 +++++++++++ provider_client.go | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cffb759590..73fe513468 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,14 @@ +## v2.7.0 (2025-04-03) + +* [GH-3306](https://github.com/gophercloud/gophercloud/pull/3306) [v2] identity: Add Get endpoint by ID +* [GH-3325](https://github.com/gophercloud/gophercloud/pull/3325) [v2] Switch to a version of gocovmerge compatible with go 1.22 +* [GH-3327](https://github.com/gophercloud/gophercloud/pull/3327) Merge pull request #3209 from shiftstack/proper-service-discovery +* [GH-3328](https://github.com/gophercloud/gophercloud/pull/3328) [v2] Improve support for `network standard-attr-*` extensions +* [GH-3330](https://github.com/gophercloud/gophercloud/pull/3330) [v2] Enhance Snapshot struct and add ListDetail function in V3 blockstorage +* [GH-3333](https://github.com/gophercloud/gophercloud/pull/3333) [v2] vpnaas: add support for more ciphers (auth, encryption, pfs modes) +* [GH-3334](https://github.com/gophercloud/gophercloud/pull/3334) [v2] Added support for VIF's in Baremetal +* [GH-3335](https://github.com/gophercloud/gophercloud/pull/3335) [v2] Baremetal virtual media Get API + ## v2.6.0 (2025-03-03) * [GH-3309](https://github.com/gophercloud/gophercloud/pull/3309) Backport: Added support for hypervisor_hostname to v2 diff --git a/provider_client.go b/provider_client.go index 8dac878eb9..52fcd38ab3 100644 --- a/provider_client.go +++ b/provider_client.go @@ -13,7 +13,7 @@ import ( // DefaultUserAgent is the default User-Agent string set in the request header. const ( - DefaultUserAgent = "gophercloud/v2.6.0" + DefaultUserAgent = "gophercloud/v2.7.0" DefaultMaxBackoffRetries = 60 ) From e77cecaf2c1a241173b106cf92c1fcaec1e92c4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?p=C3=BDrus?= Date: Mon, 14 Apr 2025 14:02:04 +0200 Subject: [PATCH 107/353] [networking] add ExtractRoutersInto func helper to routers --- .../v2/extensions/layer3/routers/results.go | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/openstack/networking/v2/extensions/layer3/routers/results.go b/openstack/networking/v2/extensions/layer3/routers/results.go index d75615b773..14845524c0 100644 --- a/openstack/networking/v2/extensions/layer3/routers/results.go +++ b/openstack/networking/v2/extensions/layer3/routers/results.go @@ -122,11 +122,14 @@ func (r RouterPage) IsEmpty() (bool, error) { // and extracts the elements into a slice of Router structs. In other words, // a generic collection is mapped into a relevant slice. func ExtractRouters(r pagination.Page) ([]Router, error) { - var s struct { - Routers []Router `json:"routers"` - } - err := (r.(RouterPage)).ExtractInto(&s) - return s.Routers, err + var s []Router + err := ExtractRoutersInto(r, &s) + return s, err +} + +// ExtractRoutersInto extracts the elements into a slice of Router structs. +func ExtractRoutersInto(r pagination.Page, v any) error { + return r.(RouterPage).Result.ExtractIntoSlicePtr(v, "routers") } type commonResult struct { From b6fff00e12f3cb0e6fc942cf628f40255beb82c5 Mon Sep 17 00:00:00 2001 From: Jonathan Herlin Date: Wed, 23 Apr 2025 14:21:55 +0200 Subject: [PATCH 108/353] Fix typo --- openstack/config/clouds/clouds.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openstack/config/clouds/clouds.go b/openstack/config/clouds/clouds.go index e2310fbc10..1466058097 100644 --- a/openstack/config/clouds/clouds.go +++ b/openstack/config/clouds/clouds.go @@ -40,7 +40,7 @@ import ( // clouds.yaml, use that location as the only search location for `clouds.yaml` and `secure.yaml`; // - otherwise, the search locations for `clouds.yaml` and `secure.yaml` are: // 1. the current working directory (on Linux: `./`) -// 2. the directory `openstack` under the standatd user config location for +// 2. the directory `openstack` under the standard user config location for // the operating system (on Linux: `${XDG_CONFIG_HOME:-$HOME/.config}/openstack/`) // 3. on Linux, `/etc/openstack/` // From ad2d30871f9cabe82a79f6619306b9cbb25cc1ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?p=C3=BDrus?= Date: Tue, 29 Apr 2025 14:45:20 +0200 Subject: [PATCH 109/353] tests: fix devstack master branch tests --- .github/workflows/functional-containerinfra.yaml | 7 +++++++ .github/workflows/functional-dns.yaml | 8 ++++++++ .github/workflows/functional-keymanager.yaml | 8 ++++++++ .github/workflows/functional-loadbalancer.yaml | 8 ++++++++ .github/workflows/functional-sharedfilesystems.yaml | 8 ++++++++ 5 files changed, 39 insertions(+) diff --git a/.github/workflows/functional-containerinfra.yaml b/.github/workflows/functional-containerinfra.yaml index a2ed183682..68ea9d3593 100644 --- a/.github/workflows/functional-containerinfra.yaml +++ b/.github/workflows/functional-containerinfra.yaml @@ -15,6 +15,12 @@ jobs: openstack_version: "master" ubuntu_version: "22.04" devstack_conf_overrides: | + # ensure we're using a working version of setuptools + if [ -n "\$TOP_DIR" ]; then + sed -i 's/setuptools\[core\]$/setuptools[core]==79.0.1/g' \$TOP_DIR/lib/infra \$TOP_DIR/inc/python + sed -i 's/pip_install "-U" "pbr"/pip_install "-U" "pbr" "setuptools[core]==79.0.1"/g' \$TOP_DIR/lib/infra + fi + enable_plugin magnum https://github.com/openstack/magnum master MAGNUMCLIENT_BRANCH=master additional_services: "openstack-cli-server" @@ -54,6 +60,7 @@ jobs: GLANCE_LIMIT_IMAGE_SIZE_TOTAL=5000 SWIFT_MAX_FILE_SIZE=5368709122 KEYSTONE_ADMIN_ENDPOINT=true + ${{ matrix.devstack_conf_overrides }} enabled_services: "h-eng,h-api,h-api-cfn,h-api-cw,${{ matrix.additional_services }}" - name: Checkout go diff --git a/.github/workflows/functional-dns.yaml b/.github/workflows/functional-dns.yaml index 6b52023985..d4f74c7c4f 100644 --- a/.github/workflows/functional-dns.yaml +++ b/.github/workflows/functional-dns.yaml @@ -15,6 +15,12 @@ jobs: - name: "master" openstack_version: "master" ubuntu_version: "22.04" + devstack_conf_overrides: | + # ensure we're using a working version of setuptools + if [ -n "\$TOP_DIR" ]; then + sed -i 's/setuptools\[core\]$/setuptools[core]==79.0.1/g' \$TOP_DIR/lib/infra \$TOP_DIR/inc/python + sed -i 's/pip_install "-U" "pbr"/pip_install "-U" "pbr" "setuptools[core]==79.0.1"/g' \$TOP_DIR/lib/infra + fi additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" @@ -39,6 +45,8 @@ jobs: branch: ${{ matrix.openstack_version }} conf_overrides: | enable_plugin designate https://github.com/openstack/designate ${{ matrix.openstack_version }} + + ${{ matrix.devstack_conf_overrides }} enabled_services: "designate,designate-central,designate-api,designate-worker,designate-producer,designate-mdns,${{ matrix.additional_services }}" - name: Checkout go uses: actions/setup-go@v5 diff --git a/.github/workflows/functional-keymanager.yaml b/.github/workflows/functional-keymanager.yaml index 595a096697..8f914f0028 100644 --- a/.github/workflows/functional-keymanager.yaml +++ b/.github/workflows/functional-keymanager.yaml @@ -14,6 +14,12 @@ jobs: - name: "master" openstack_version: "master" ubuntu_version: "22.04" + devstack_conf_overrides: | + # ensure we're using a working version of setuptools + if [ -n "\$TOP_DIR" ]; then + sed -i 's/setuptools\[core\]$/setuptools[core]==79.0.1/g' \$TOP_DIR/lib/infra \$TOP_DIR/inc/python + sed -i 's/pip_install "-U" "pbr"/pip_install "-U" "pbr" "setuptools[core]==79.0.1"/g' \$TOP_DIR/lib/infra + fi additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" @@ -38,6 +44,8 @@ jobs: branch: ${{ matrix.openstack_version }} conf_overrides: | enable_plugin barbican https://github.com/openstack/barbican ${{ matrix.openstack_version }} + + ${{ matrix.devstack_conf_overrides }} enabled_services: "barbican-svc,barbican-retry,barbican-keystone-listener,${{ matrix.additional_services }}" - name: Checkout go uses: actions/setup-go@v5 diff --git a/.github/workflows/functional-loadbalancer.yaml b/.github/workflows/functional-loadbalancer.yaml index 11d67aef31..2fb3dc6bd3 100644 --- a/.github/workflows/functional-loadbalancer.yaml +++ b/.github/workflows/functional-loadbalancer.yaml @@ -14,6 +14,12 @@ jobs: - name: "master" openstack_version: "master" ubuntu_version: "22.04" + devstack_conf_overrides: | + # ensure we're using a working version of setuptools + if [ -n "\$TOP_DIR" ]; then + sed -i 's/setuptools\[core\]$/setuptools[core]==79.0.1/g' \$TOP_DIR/lib/infra \$TOP_DIR/inc/python + sed -i 's/pip_install "-U" "pbr"/pip_install "-U" "pbr" "setuptools[core]==79.0.1"/g' \$TOP_DIR/lib/infra + fi additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" @@ -39,6 +45,8 @@ jobs: conf_overrides: | enable_plugin octavia https://github.com/openstack/octavia ${{ matrix.openstack_version }} enable_plugin neutron https://github.com/openstack/neutron ${{ matrix.openstack_version }} + + ${{ matrix.devstack_conf_overrides }} enabled_services: "octavia,o-api,o-cw,o-hk,o-hm,o-da,neutron-qos,${{ matrix.additional_services }}" - name: Checkout go uses: actions/setup-go@v5 diff --git a/.github/workflows/functional-sharedfilesystems.yaml b/.github/workflows/functional-sharedfilesystems.yaml index d2702759a5..257b4490ec 100644 --- a/.github/workflows/functional-sharedfilesystems.yaml +++ b/.github/workflows/functional-sharedfilesystems.yaml @@ -14,6 +14,12 @@ jobs: - name: "master" openstack_version: "master" ubuntu_version: "22.04" + devstack_conf_overrides: | + # ensure we're using a working version of setuptools + if [ -n "\$TOP_DIR" ]; then + sed -i 's/setuptools\[core\]$/setuptools[core]==79.0.1/g' \$TOP_DIR/lib/infra \$TOP_DIR/inc/python + sed -i 's/pip_install "-U" "pbr"/pip_install "-U" "pbr" "setuptools[core]==79.0.1"/g' \$TOP_DIR/lib/infra + fi additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" @@ -52,6 +58,8 @@ jobs: MANILA_DEFAULT_SHARE_TYPE_EXTRA_SPECS='snapshot_support=True create_share_from_snapshot_support=True revert_to_snapshot_support=True mount_snapshot_support=True' MANILA_CONFIGURE_DEFAULT_TYPES=True MANILA_INSTALL_TEMPEST_PLUGIN_SYSTEMWIDE=false + + ${{ matrix.devstack_conf_overrides }} enabled_services: "${{ matrix.additional_services }}" - name: Checkout go uses: actions/setup-go@v5 From 0f39dd1b34172f91a54b69480c35b5f5ffc53308 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?p=C3=BDrus?= Date: Wed, 30 Apr 2025 15:20:10 +0200 Subject: [PATCH 110/353] tests: fix containerinfra template creation --- .../containerinfra/v1/containerinfra.go | 6 +++++ .../clustertemplates/testing/fixtures_test.go | 22 +++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/internal/acceptance/openstack/containerinfra/v1/containerinfra.go b/internal/acceptance/openstack/containerinfra/v1/containerinfra.go index 9b26c0ad2d..84ee98e87d 100644 --- a/internal/acceptance/openstack/containerinfra/v1/containerinfra.go +++ b/internal/acceptance/openstack/containerinfra/v1/containerinfra.go @@ -31,6 +31,9 @@ func CreateClusterTemplateCOE(t *testing.T, client *gophercloud.ServiceClient, c t.Logf("Attempting to create %s cluster template: %s", coe, name) boolFalse := false + labels := map[string]string{ + "test": "test", + } createOpts := clustertemplates.CreateOpts{ COE: coe, DNSNameServer: "8.8.8.8", @@ -45,6 +48,8 @@ func CreateClusterTemplateCOE(t *testing.T, client *gophercloud.ServiceClient, c Public: &boolFalse, RegistryEnabled: &boolFalse, ServerType: "vm", + // workaround for https://bugs.launchpad.net/magnum/+bug/2109685 + Labels: labels, } res := clustertemplates.Create(context.TODO(), client, createOpts) @@ -68,6 +73,7 @@ func CreateClusterTemplateCOE(t *testing.T, client *gophercloud.ServiceClient, c tools.PrintResource(t, clusterTemplate.CreatedAt) th.AssertEquals(t, name, clusterTemplate.Name) + th.AssertDeepEquals(t, labels, clusterTemplate.Labels) th.AssertEquals(t, choices.ExternalNetworkID, clusterTemplate.ExternalNetworkID) th.AssertEquals(t, choices.MagnumImageID, clusterTemplate.ImageID) diff --git a/openstack/containerinfra/v1/clustertemplates/testing/fixtures_test.go b/openstack/containerinfra/v1/clustertemplates/testing/fixtures_test.go index f269d99cb3..8028ff836f 100644 --- a/openstack/containerinfra/v1/clustertemplates/testing/fixtures_test.go +++ b/openstack/containerinfra/v1/clustertemplates/testing/fixtures_test.go @@ -278,6 +278,28 @@ func HandleCreateClusterTemplateSuccessfully(t *testing.T) { th.Mux.HandleFunc("/v1/clustertemplates", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestJSONRequest(t, r, `{ + "coe": "kubernetes", + "dns_nameserver": "8.8.8.8", + "docker_storage_driver": "devicemapper", + "docker_volume_size": 3, + "external_network_id": "public", + "flavor_id": "m1.small", + "hidden": true, + "http_proxy": "http://10.164.177.169:8080", + "https_proxy": "http://10.164.177.169:8080", + "image_id": "Fedora-Atomic-27-20180212.2.x86_64", + "keypair_id": "kp", + "master_lb_enabled": true, + "name": "kubernetes-dev", + "network_driver": "flannel", + "no_proxy": "10.0.0.0/8,172.0.0.0/8,192.0.0.0/8,localhost", + "public": false, + "registry_enabled": false, + "server_type": "vm", + "tls_disabled": false, + "volume_driver": "cinder" + }`) w.Header().Add("Content-Type", "application/json") w.Header().Add("OpenStack-API-Minimum-Version", "container-infra 1.1") From 56c28512a5a466dc18d80849ac9f6c012cec579f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?p=C3=BDrus?= Date: Mon, 28 Apr 2025 10:49:59 +0200 Subject: [PATCH 111/353] octavia: fix http_version type to float --- .../openstack/loadbalancer/v2/loadbalancer.go | 10 +++++ .../loadbalancer/v2/monitors/requests.go | 41 ++++++++++++++++++- openstack/loadbalancer/v2/monitors/results.go | 25 ++++++++++- .../v2/monitors/testing/fixtures_test.go | 12 ++++++ .../v2/monitors/testing/requests_test.go | 2 + 5 files changed, 87 insertions(+), 3 deletions(-) diff --git a/internal/acceptance/openstack/loadbalancer/v2/loadbalancer.go b/internal/acceptance/openstack/loadbalancer/v2/loadbalancer.go index e8596506ef..db067a81c1 100644 --- a/internal/acceptance/openstack/loadbalancer/v2/loadbalancer.go +++ b/internal/acceptance/openstack/loadbalancer/v2/loadbalancer.go @@ -213,6 +213,7 @@ func CreateLoadBalancerFullyPopulated(t *testing.T, client *gophercloud.ServiceC MaxRetries: 5, MaxRetriesDown: 4, Type: monitors.TypeHTTP, + HTTPVersion: "1.0", }, }, L7Policies: []l7policies.CreateOpts{{ @@ -271,6 +272,13 @@ func CreateLoadBalancerFullyPopulated(t *testing.T, client *gophercloud.ServiceC th.AssertEquals(t, lb.Pools[0].Members[0].ProtocolPort, memberPort) th.AssertEquals(t, lb.Pools[0].Members[0].Weight, memberWeight) + th.AssertEquals(t, lb.Pools[0].Monitor.Delay, 10) + th.AssertEquals(t, lb.Pools[0].Monitor.Timeout, 5) + th.AssertEquals(t, lb.Pools[0].Monitor.MaxRetries, 5) + th.AssertEquals(t, lb.Pools[0].Monitor.MaxRetriesDown, 4) + th.AssertEquals(t, lb.Pools[0].Monitor.Type, string(monitors.TypeHTTP)) + th.AssertEquals(t, lb.Pools[0].Monitor.HTTPVersion, "1.0") + if len(tags) > 0 { th.AssertDeepEquals(t, lb.Tags, tags) } @@ -332,6 +340,7 @@ func CreateMonitor(t *testing.T, client *gophercloud.ServiceClient, lb *loadbala MaxRetries: 5, MaxRetriesDown: 4, Type: monitors.TypePING, + HTTPVersion: "1.1", } monitor, err := monitors.Create(context.TODO(), client, createOpts).Extract() @@ -351,6 +360,7 @@ func CreateMonitor(t *testing.T, client *gophercloud.ServiceClient, lb *loadbala th.AssertEquals(t, monitor.Timeout, 5) th.AssertEquals(t, monitor.MaxRetries, 5) th.AssertEquals(t, monitor.MaxRetriesDown, 4) + th.AssertEquals(t, monitor.HTTPVersion, "1.1") return monitor, nil } diff --git a/openstack/loadbalancer/v2/monitors/requests.go b/openstack/loadbalancer/v2/monitors/requests.go index be5701c5f4..15a503badc 100644 --- a/openstack/loadbalancer/v2/monitors/requests.go +++ b/openstack/loadbalancer/v2/monitors/requests.go @@ -2,6 +2,7 @@ package monitors import ( "context" + "strconv" "github.com/gophercloud/gophercloud/v2" "github.com/gophercloud/gophercloud/v2/pagination" @@ -153,7 +154,25 @@ type CreateOpts struct { // ToMonitorCreateMap builds a request body from CreateOpts. func (opts CreateOpts) ToMonitorCreateMap() (map[string]any, error) { - return gophercloud.BuildRequestBody(opts, "healthmonitor") + b, err := gophercloud.BuildRequestBody(opts, "healthmonitor") + if err != nil { + return nil, err + } + + if v, ok := b["healthmonitor"]; ok { + if m, ok := v.(map[string]any); ok { + if v, ok := m["http_version"]; ok { + if v, ok := v.(string); ok { + m["http_version"], err = strconv.ParseFloat(v, 64) + if err != nil { + return nil, err + } + } + } + } + } + + return b, nil } /* @@ -247,7 +266,25 @@ type UpdateOpts struct { // ToMonitorUpdateMap builds a request body from UpdateOpts. func (opts UpdateOpts) ToMonitorUpdateMap() (map[string]any, error) { - return gophercloud.BuildRequestBody(opts, "healthmonitor") + b, err := gophercloud.BuildRequestBody(opts, "healthmonitor") + if err != nil { + return nil, err + } + + if v, ok := b["healthmonitor"]; ok { + if m, ok := v.(map[string]any); ok { + if v, ok := m["http_version"]; ok { + if v, ok := v.(string); ok { + m["http_version"], err = strconv.ParseFloat(v, 64) + if err != nil { + return nil, err + } + } + } + } + } + + return b, nil } // Update is an operation which modifies the attributes of the specified diff --git a/openstack/loadbalancer/v2/monitors/results.go b/openstack/loadbalancer/v2/monitors/results.go index 644ef18700..6e8563faaa 100644 --- a/openstack/loadbalancer/v2/monitors/results.go +++ b/openstack/loadbalancer/v2/monitors/results.go @@ -1,6 +1,9 @@ package monitors import ( + "encoding/json" + "strconv" + "github.com/gophercloud/gophercloud/v2" "github.com/gophercloud/gophercloud/v2/pagination" ) @@ -61,7 +64,7 @@ type Monitor struct { HTTPMethod string `json:"http_method"` // The HTTP version that the monitor uses for requests. - HTTPVersion string `json:"http_version"` + HTTPVersion string `json:"-"` // The HTTP path of the request sent by the monitor to test the health of a // member. Must be a string beginning with a forward slash (/). @@ -96,6 +99,26 @@ type Monitor struct { Tags []string `json:"tags"` } +func (r *Monitor) UnmarshalJSON(b []byte) error { + type tmp Monitor + var s struct { + tmp + HTTPVersion float64 `json:"http_version"` + } + + err := json.Unmarshal(b, &s) + if err != nil { + return err + } + + *r = Monitor(s.tmp) + if s.HTTPVersion != 0 { + r.HTTPVersion = strconv.FormatFloat(s.HTTPVersion, 'f', 1, 64) + } + + return nil +} + // MonitorPage is the page returned by a pager when traversing over a // collection of health monitors. type MonitorPage struct { diff --git a/openstack/loadbalancer/v2/monitors/testing/fixtures_test.go b/openstack/loadbalancer/v2/monitors/testing/fixtures_test.go index 6b12d2c11c..b56d44dbe6 100644 --- a/openstack/loadbalancer/v2/monitors/testing/fixtures_test.go +++ b/openstack/loadbalancer/v2/monitors/testing/fixtures_test.go @@ -31,11 +31,13 @@ const HealthmonitorsListBody = ` "admin_state_up":true, "project_id":"83657cfcdfe44cd5920adaf26c48ceea", "delay":5, + "domain_name": "www.example.com", "name":"db", "expected_codes":"200", "max_retries":2, "max_retries_down":4, "http_method":"GET", + "http_version": 1.1, "timeout":2, "url_path":"/", "type":"HTTP", @@ -54,11 +56,13 @@ const SingleHealthmonitorBody = ` "admin_state_up":true, "project_id":"83657cfcdfe44cd5920adaf26c48ceea", "delay":5, + "domain_name": "www.example.com", "name":"db", "expected_codes":"200", "max_retries":2, "max_retries_down":4, "http_method":"GET", + "http_version": 1.1, "timeout":2, "url_path":"/", "type":"HTTP", @@ -76,11 +80,13 @@ const PostUpdateHealthmonitorBody = ` "admin_state_up":true, "project_id":"83657cfcdfe44cd5920adaf26c48ceea", "delay":3, + "domain_name": "www.example.com", "name":"NewHealthmonitorName", "expected_codes":"301", "max_retries":10, "max_retries_down":8, "http_method":"GET", + "http_version": 1.1, "timeout":20, "url_path":"/another_check", "type":"HTTP", @@ -107,6 +113,7 @@ var ( } HealthmonitorDb = monitors.Monitor{ AdminStateUp: true, + DomainName: "www.example.com", Name: "db", ProjectID: "83657cfcdfe44cd5920adaf26c48ceea", Delay: 5, @@ -117,12 +124,14 @@ var ( URLPath: "/", Type: "HTTP", HTTPMethod: "GET", + HTTPVersion: "1.1", ID: "5d4b5228-33b0-4e60-b225-9b727c1a20e7", Pools: []monitors.PoolID{{ID: "d459f7d8-c6ee-439d-8713-d3fc08aeed8d"}}, Tags: []string{}, } HealthmonitorUpdated = monitors.Monitor{ AdminStateUp: true, + DomainName: "www.example.com", Name: "NewHealthmonitorName", ProjectID: "83657cfcdfe44cd5920adaf26c48ceea", Delay: 3, @@ -133,6 +142,7 @@ var ( URLPath: "/another_check", Type: "HTTP", HTTPMethod: "GET", + HTTPVersion: "1.1", ID: "5d4b5228-33b0-4e60-b225-9b727c1a20e7", Pools: []monitors.PoolID{{ID: "d459f7d8-c6ee-439d-8713-d3fc08aeed8d"}}, Tags: []string{}, @@ -173,7 +183,9 @@ func HandleHealthmonitorCreationSuccessfully(t *testing.T, response string) { "pool_id":"84f1b61f-58c4-45bf-a8a9-2dafb9e5214d", "project_id":"453105b9-1754-413f-aab1-55f1af620750", "delay":20, + "domain_name": "www.example.com", "name":"db", + "http_version": 1.1, "timeout":10, "max_retries":5, "max_retries_down":4, diff --git a/openstack/loadbalancer/v2/monitors/testing/requests_test.go b/openstack/loadbalancer/v2/monitors/testing/requests_test.go index 0ca13f360e..1af0aaf9a8 100644 --- a/openstack/loadbalancer/v2/monitors/testing/requests_test.go +++ b/openstack/loadbalancer/v2/monitors/testing/requests_test.go @@ -60,6 +60,7 @@ func TestCreateHealthmonitor(t *testing.T) { actual, err := monitors.Create(context.TODO(), fake.ServiceClient(), monitors.CreateOpts{ Type: "HTTP", + DomainName: "www.example.com", Name: "db", PoolID: "84f1b61f-58c4-45bf-a8a9-2dafb9e5214d", ProjectID: "453105b9-1754-413f-aab1-55f1af620750", @@ -67,6 +68,7 @@ func TestCreateHealthmonitor(t *testing.T) { Timeout: 10, MaxRetries: 5, MaxRetriesDown: 4, + HTTPVersion: "1.1", Tags: []string{}, URLPath: "/check", ExpectedCodes: "200-299", From fc94678f56f9a404034c7e489afce8073f574eeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?p=C3=BDrus?= Date: Tue, 13 May 2025 14:12:59 +0200 Subject: [PATCH 112/353] tests: fix failing rabbitmq service --- .github/workflows/functional-baremetal.yaml | 2 +- .github/workflows/functional-basic.yaml | 2 +- .github/workflows/functional-blockstorage.yaml | 2 +- .github/workflows/functional-compute.yaml | 2 +- .github/workflows/functional-containerinfra.yaml | 2 +- .github/workflows/functional-dns.yaml | 2 +- .github/workflows/functional-fwaas_v2.yaml | 2 +- .github/workflows/functional-identity.yaml | 2 +- .github/workflows/functional-image.yaml | 2 +- .github/workflows/functional-keymanager.yaml | 2 +- .github/workflows/functional-loadbalancer.yaml | 2 +- .github/workflows/functional-messaging.yaml | 2 +- .github/workflows/functional-networking.yaml | 2 +- .github/workflows/functional-objectstorage.yaml | 2 +- .github/workflows/functional-orchestration.yaml | 2 +- .github/workflows/functional-placement.yaml | 2 +- .github/workflows/functional-sharedfilesystems.yaml | 2 +- .github/workflows/functional-workflow.yaml | 2 +- 18 files changed, 18 insertions(+), 18 deletions(-) diff --git a/.github/workflows/functional-baremetal.yaml b/.github/workflows/functional-baremetal.yaml index ac2d37d6f2..f976a638d1 100644 --- a/.github/workflows/functional-baremetal.yaml +++ b/.github/workflows/functional-baremetal.yaml @@ -50,7 +50,7 @@ jobs: - name: Work around broken dnsmasq run: sudo apt-get purge -y dnsmasq-base - name: Deploy devstack - uses: EmilienM/devstack-action@e82a9cbead099cba72f99537e82a360c3e319c69 + uses: gophercloud@devstack-action@v0.17 with: branch: ${{ matrix.openstack_version }} conf_overrides: | diff --git a/.github/workflows/functional-basic.yaml b/.github/workflows/functional-basic.yaml index 392ea1f06f..223c524fae 100644 --- a/.github/workflows/functional-basic.yaml +++ b/.github/workflows/functional-basic.yaml @@ -36,7 +36,7 @@ jobs: - name: Checkout Gophercloud uses: actions/checkout@v4 - name: Deploy devstack - uses: EmilienM/devstack-action@e82a9cbead099cba72f99537e82a360c3e319c69 + uses: gophercloud@devstack-action@v0.17 with: branch: ${{ matrix.openstack_version }} enabled_services: 's-account,s-container,s-object,s-proxy,${{ matrix.additional_services }}' diff --git a/.github/workflows/functional-blockstorage.yaml b/.github/workflows/functional-blockstorage.yaml index c0b58484a7..cd17b1ba53 100644 --- a/.github/workflows/functional-blockstorage.yaml +++ b/.github/workflows/functional-blockstorage.yaml @@ -33,7 +33,7 @@ jobs: - name: Checkout Gophercloud uses: actions/checkout@v4 - name: Deploy devstack - uses: EmilienM/devstack-action@e82a9cbead099cba72f99537e82a360c3e319c69 + uses: gophercloud@devstack-action@v0.17 with: branch: ${{ matrix.openstack_version }} conf_overrides: | diff --git a/.github/workflows/functional-compute.yaml b/.github/workflows/functional-compute.yaml index 0ad2dfa8d6..e61106ec85 100644 --- a/.github/workflows/functional-compute.yaml +++ b/.github/workflows/functional-compute.yaml @@ -33,7 +33,7 @@ jobs: - name: Checkout Gophercloud uses: actions/checkout@v4 - name: Deploy devstack - uses: EmilienM/devstack-action@e82a9cbead099cba72f99537e82a360c3e319c69 + uses: gophercloud@devstack-action@v0.17 with: branch: ${{ matrix.openstack_version }} conf_overrides: | diff --git a/.github/workflows/functional-containerinfra.yaml b/.github/workflows/functional-containerinfra.yaml index 68ea9d3593..1bc90934c8 100644 --- a/.github/workflows/functional-containerinfra.yaml +++ b/.github/workflows/functional-containerinfra.yaml @@ -51,7 +51,7 @@ jobs: - name: Checkout Gophercloud uses: actions/checkout@v4 - name: Deploy devstack - uses: EmilienM/devstack-action@e82a9cbead099cba72f99537e82a360c3e319c69 + uses: gophercloud@devstack-action@v0.17 with: branch: ${{ matrix.openstack_version }} conf_overrides: | diff --git a/.github/workflows/functional-dns.yaml b/.github/workflows/functional-dns.yaml index d4f74c7c4f..7daf7bf4b3 100644 --- a/.github/workflows/functional-dns.yaml +++ b/.github/workflows/functional-dns.yaml @@ -40,7 +40,7 @@ jobs: - name: Checkout Gophercloud uses: actions/checkout@v4 - name: Deploy devstack - uses: EmilienM/devstack-action@e82a9cbead099cba72f99537e82a360c3e319c69 + uses: gophercloud@devstack-action@v0.17 with: branch: ${{ matrix.openstack_version }} conf_overrides: | diff --git a/.github/workflows/functional-fwaas_v2.yaml b/.github/workflows/functional-fwaas_v2.yaml index d308ade3ed..ea7215ccb2 100644 --- a/.github/workflows/functional-fwaas_v2.yaml +++ b/.github/workflows/functional-fwaas_v2.yaml @@ -33,7 +33,7 @@ jobs: - name: Checkout Gophercloud uses: actions/checkout@v4 - name: Deploy devstack - uses: EmilienM/devstack-action@e82a9cbead099cba72f99537e82a360c3e319c69 + uses: gophercloud@devstack-action@v0.17 with: branch: ${{ matrix.openstack_version }} conf_overrides: | diff --git a/.github/workflows/functional-identity.yaml b/.github/workflows/functional-identity.yaml index 7a9d4ffaeb..df08ba60f7 100644 --- a/.github/workflows/functional-identity.yaml +++ b/.github/workflows/functional-identity.yaml @@ -33,7 +33,7 @@ jobs: - name: Checkout Gophercloud uses: actions/checkout@v4 - name: Deploy devstack - uses: EmilienM/devstack-action@e82a9cbead099cba72f99537e82a360c3e319c69 + uses: gophercloud@devstack-action@v0.17 with: branch: ${{ matrix.openstack_version }} enabled_services: "${{ matrix.additional_services }}" diff --git a/.github/workflows/functional-image.yaml b/.github/workflows/functional-image.yaml index c6b956b882..c451814c50 100644 --- a/.github/workflows/functional-image.yaml +++ b/.github/workflows/functional-image.yaml @@ -33,7 +33,7 @@ jobs: - name: Checkout Gophercloud uses: actions/checkout@v4 - name: Deploy devstack - uses: EmilienM/devstack-action@e82a9cbead099cba72f99537e82a360c3e319c69 + uses: gophercloud@devstack-action@v0.17 with: branch: ${{ matrix.openstack_version }} enabled_services: "${{ matrix.additional_services }}" diff --git a/.github/workflows/functional-keymanager.yaml b/.github/workflows/functional-keymanager.yaml index 8f914f0028..eeaf17cedc 100644 --- a/.github/workflows/functional-keymanager.yaml +++ b/.github/workflows/functional-keymanager.yaml @@ -39,7 +39,7 @@ jobs: - name: Checkout Gophercloud uses: actions/checkout@v4 - name: Deploy devstack - uses: EmilienM/devstack-action@e82a9cbead099cba72f99537e82a360c3e319c69 + uses: gophercloud@devstack-action@v0.17 with: branch: ${{ matrix.openstack_version }} conf_overrides: | diff --git a/.github/workflows/functional-loadbalancer.yaml b/.github/workflows/functional-loadbalancer.yaml index 2fb3dc6bd3..42e3608243 100644 --- a/.github/workflows/functional-loadbalancer.yaml +++ b/.github/workflows/functional-loadbalancer.yaml @@ -39,7 +39,7 @@ jobs: - name: Checkout Gophercloud uses: actions/checkout@v4 - name: Deploy devstack - uses: EmilienM/devstack-action@e82a9cbead099cba72f99537e82a360c3e319c69 + uses: gophercloud@devstack-action@v0.17 with: branch: ${{ matrix.openstack_version }} conf_overrides: | diff --git a/.github/workflows/functional-messaging.yaml b/.github/workflows/functional-messaging.yaml index 87c5b93ded..a5a545ad97 100644 --- a/.github/workflows/functional-messaging.yaml +++ b/.github/workflows/functional-messaging.yaml @@ -33,7 +33,7 @@ jobs: - name: Checkout Gophercloud uses: actions/checkout@v4 - name: Deploy devstack - uses: EmilienM/devstack-action@e82a9cbead099cba72f99537e82a360c3e319c69 + uses: gophercloud@devstack-action@v0.17 with: branch: ${{ matrix.openstack_version }} conf_overrides: | diff --git a/.github/workflows/functional-networking.yaml b/.github/workflows/functional-networking.yaml index 67ab119605..8cf92fbfb0 100644 --- a/.github/workflows/functional-networking.yaml +++ b/.github/workflows/functional-networking.yaml @@ -41,7 +41,7 @@ jobs: "update_port:binding:profile": "rule:admin_only or rule:service_api" EOF - name: Deploy devstack - uses: EmilienM/devstack-action@e82a9cbead099cba72f99537e82a360c3e319c69 + uses: gophercloud@devstack-action@v0.17 with: branch: ${{ matrix.openstack_version }} conf_overrides: | diff --git a/.github/workflows/functional-objectstorage.yaml b/.github/workflows/functional-objectstorage.yaml index c71d17f372..6ad7e4c281 100644 --- a/.github/workflows/functional-objectstorage.yaml +++ b/.github/workflows/functional-objectstorage.yaml @@ -33,7 +33,7 @@ jobs: - name: Checkout Gophercloud uses: actions/checkout@v4 - name: Deploy devstack - uses: EmilienM/devstack-action@e82a9cbead099cba72f99537e82a360c3e319c69 + uses: gophercloud@devstack-action@v0.17 with: branch: ${{ matrix.openstack_version }} conf_overrides: | diff --git a/.github/workflows/functional-orchestration.yaml b/.github/workflows/functional-orchestration.yaml index 71213eea50..08123c3289 100644 --- a/.github/workflows/functional-orchestration.yaml +++ b/.github/workflows/functional-orchestration.yaml @@ -33,7 +33,7 @@ jobs: - name: Checkout Gophercloud uses: actions/checkout@v4 - name: Deploy devstack - uses: EmilienM/devstack-action@e82a9cbead099cba72f99537e82a360c3e319c69 + uses: gophercloud@devstack-action@v0.17 with: branch: ${{ matrix.openstack_version }} conf_overrides: | diff --git a/.github/workflows/functional-placement.yaml b/.github/workflows/functional-placement.yaml index 15982c5318..3ea0e5b3eb 100644 --- a/.github/workflows/functional-placement.yaml +++ b/.github/workflows/functional-placement.yaml @@ -33,7 +33,7 @@ jobs: - name: Checkout Gophercloud uses: actions/checkout@v4 - name: Deploy devstack - uses: EmilienM/devstack-action@e82a9cbead099cba72f99537e82a360c3e319c69 + uses: gophercloud@devstack-action@v0.17 with: branch: ${{ matrix.openstack_version }} enabled_services: "${{ matrix.additional_services }}" diff --git a/.github/workflows/functional-sharedfilesystems.yaml b/.github/workflows/functional-sharedfilesystems.yaml index 257b4490ec..c8d891a7c9 100644 --- a/.github/workflows/functional-sharedfilesystems.yaml +++ b/.github/workflows/functional-sharedfilesystems.yaml @@ -39,7 +39,7 @@ jobs: - name: Checkout Gophercloud uses: actions/checkout@v4 - name: Deploy devstack - uses: EmilienM/devstack-action@e82a9cbead099cba72f99537e82a360c3e319c69 + uses: gophercloud@devstack-action@v0.17 with: branch: ${{ matrix.openstack_version }} conf_overrides: | diff --git a/.github/workflows/functional-workflow.yaml b/.github/workflows/functional-workflow.yaml index f124fc6412..582128d5ff 100644 --- a/.github/workflows/functional-workflow.yaml +++ b/.github/workflows/functional-workflow.yaml @@ -40,7 +40,7 @@ jobs: - name: Checkout Gophercloud uses: actions/checkout@v4 - name: Deploy devstack - uses: EmilienM/devstack-action@e82a9cbead099cba72f99537e82a360c3e319c69 + uses: gophercloud@devstack-action@v0.17 with: branch: ${{ matrix.openstack_version }} conf_overrides: | From d7ca34a34598156b437c7ae45dc4bb0533db45d9 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Fri, 18 Apr 2025 11:10:44 +0100 Subject: [PATCH 113/353] Drop CI coverage for Bobcat Bobcat enters the unmaintained [1] phase on 2025-04-30. We can no longer rely on this for testing. [1] https://docs.openstack.org/project-team-guide/stable-branches.html#unmaintained Signed-off-by: Stephen Finucane --- .github/workflows/functional-baremetal.yaml | 5 ----- .github/workflows/functional-basic.yaml | 4 ---- .github/workflows/functional-blockstorage.yaml | 4 ---- .github/workflows/functional-compute.yaml | 4 ---- .github/workflows/functional-containerinfra.yaml | 7 ------- .github/workflows/functional-dns.yaml | 4 ---- .github/workflows/functional-fwaas_v2.yaml | 4 ---- .github/workflows/functional-identity.yaml | 4 ---- .github/workflows/functional-image.yaml | 4 ---- .github/workflows/functional-keymanager.yaml | 4 ---- .github/workflows/functional-loadbalancer.yaml | 4 ---- .github/workflows/functional-messaging.yaml | 4 ---- .github/workflows/functional-networking.yaml | 4 ---- .github/workflows/functional-objectstorage.yaml | 4 ---- .github/workflows/functional-orchestration.yaml | 4 ---- .github/workflows/functional-placement.yaml | 4 ---- .github/workflows/functional-sharedfilesystems.yaml | 4 ---- .github/workflows/functional-workflow.yaml | 8 -------- 18 files changed, 80 deletions(-) diff --git a/.github/workflows/functional-baremetal.yaml b/.github/workflows/functional-baremetal.yaml index f976a638d1..035a78cb2b 100644 --- a/.github/workflows/functional-baremetal.yaml +++ b/.github/workflows/functional-baremetal.yaml @@ -29,11 +29,6 @@ jobs: ubuntu_version: "22.04" use_system_scope: true additional_services: "" - - name: "bobcat" - openstack_version: "stable/2023.2" - ubuntu_version: "22.04" - use_system_scope: false - additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Deploy OpenStack ${{ matrix.name }} with Ironic and run baremetal acceptance tests steps: diff --git a/.github/workflows/functional-basic.yaml b/.github/workflows/functional-basic.yaml index 223c524fae..6c3587c35d 100644 --- a/.github/workflows/functional-basic.yaml +++ b/.github/workflows/functional-basic.yaml @@ -26,10 +26,6 @@ jobs: openstack_version: "stable/2024.1" ubuntu_version: "22.04" additional_services: "" - - name: "bobcat" - openstack_version: "stable/2023.2" - ubuntu_version: "22.04" - additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Deploy OpenStack ${{ matrix.name }} with defaults and run basic acceptance tests steps: diff --git a/.github/workflows/functional-blockstorage.yaml b/.github/workflows/functional-blockstorage.yaml index cd17b1ba53..f94bef2658 100644 --- a/.github/workflows/functional-blockstorage.yaml +++ b/.github/workflows/functional-blockstorage.yaml @@ -23,10 +23,6 @@ jobs: openstack_version: "stable/2024.1" ubuntu_version: "22.04" additional_services: "" - - name: "bobcat" - openstack_version: "stable/2023.2" - ubuntu_version: "22.04" - additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Deploy OpenStack ${{ matrix.name }} with Cinder and run blockstorage acceptance tests steps: diff --git a/.github/workflows/functional-compute.yaml b/.github/workflows/functional-compute.yaml index e61106ec85..b26c82b8da 100644 --- a/.github/workflows/functional-compute.yaml +++ b/.github/workflows/functional-compute.yaml @@ -23,10 +23,6 @@ jobs: openstack_version: "stable/2024.1" ubuntu_version: "22.04" additional_services: "" - - name: "bobcat" - openstack_version: "stable/2023.2" - ubuntu_version: "22.04" - additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Deploy OpenStack ${{ matrix.name }} with Nova and run compute acceptance tests steps: diff --git a/.github/workflows/functional-containerinfra.yaml b/.github/workflows/functional-containerinfra.yaml index 1bc90934c8..59da6bf1d4 100644 --- a/.github/workflows/functional-containerinfra.yaml +++ b/.github/workflows/functional-containerinfra.yaml @@ -38,13 +38,6 @@ jobs: enable_plugin magnum https://github.com/openstack/magnum stable/2024.1 MAGNUMCLIENT_BRANCH=stable/2024.1 additional_services: "" - - name: "bobcat" - openstack_version: "stable/2023.2" - ubuntu_version: "22.04" - devstack_conf_overrides: | - enable_plugin magnum https://github.com/openstack/magnum stable/2023.2 - MAGNUMCLIENT_BRANCH=stable/2023.2 - additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Deploy OpenStack ${{ matrix.name }} with Magnum and run containerinfra acceptance tests steps: diff --git a/.github/workflows/functional-dns.yaml b/.github/workflows/functional-dns.yaml index 7daf7bf4b3..cbf27b04f0 100644 --- a/.github/workflows/functional-dns.yaml +++ b/.github/workflows/functional-dns.yaml @@ -30,10 +30,6 @@ jobs: openstack_version: "stable/2024.1" ubuntu_version: "22.04" additional_services: "" - - name: "bobcat" - openstack_version: "stable/2023.2" - ubuntu_version: "22.04" - additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Deploy OpenStack ${{ matrix.name }} with Designate and run dns acceptance tests steps: diff --git a/.github/workflows/functional-fwaas_v2.yaml b/.github/workflows/functional-fwaas_v2.yaml index ea7215ccb2..880fa8994c 100644 --- a/.github/workflows/functional-fwaas_v2.yaml +++ b/.github/workflows/functional-fwaas_v2.yaml @@ -23,10 +23,6 @@ jobs: openstack_version: "stable/2024.1" ubuntu_version: "22.04" additional_services: "" - - name: "bobcat" - openstack_version: "stable/2023.2" - ubuntu_version: "22.04" - additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Deploy OpenStack ${{ matrix.name }} with enabled FWaaS_v2 and run networking acceptance tests steps: diff --git a/.github/workflows/functional-identity.yaml b/.github/workflows/functional-identity.yaml index df08ba60f7..9c58e24d5a 100644 --- a/.github/workflows/functional-identity.yaml +++ b/.github/workflows/functional-identity.yaml @@ -23,10 +23,6 @@ jobs: openstack_version: "stable/2024.1" ubuntu_version: "22.04" additional_services: "" - - name: "bobcat" - openstack_version: "stable/2023.2" - ubuntu_version: "22.04" - additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Deploy OpenStack ${{ matrix.name }} with Keystone and run identity acceptance tests steps: diff --git a/.github/workflows/functional-image.yaml b/.github/workflows/functional-image.yaml index c451814c50..74164ae7e1 100644 --- a/.github/workflows/functional-image.yaml +++ b/.github/workflows/functional-image.yaml @@ -23,10 +23,6 @@ jobs: openstack_version: "stable/2024.1" ubuntu_version: "22.04" additional_services: "" - - name: "bobcat" - openstack_version: "stable/2023.2" - ubuntu_version: "22.04" - additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Deploy OpenStack ${{ matrix.name }} with Glance and run image acceptance tests steps: diff --git a/.github/workflows/functional-keymanager.yaml b/.github/workflows/functional-keymanager.yaml index eeaf17cedc..bcdbe5c614 100644 --- a/.github/workflows/functional-keymanager.yaml +++ b/.github/workflows/functional-keymanager.yaml @@ -29,10 +29,6 @@ jobs: openstack_version: "stable/2024.1" ubuntu_version: "22.04" additional_services: "" - - name: "bobcat" - openstack_version: "stable/2023.2" - ubuntu_version: "22.04" - additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Deploy OpenStack ${{ matrix.name }} with Barbican and run keymanager acceptance tests steps: diff --git a/.github/workflows/functional-loadbalancer.yaml b/.github/workflows/functional-loadbalancer.yaml index 42e3608243..142a30d123 100644 --- a/.github/workflows/functional-loadbalancer.yaml +++ b/.github/workflows/functional-loadbalancer.yaml @@ -29,10 +29,6 @@ jobs: openstack_version: "stable/2024.1" ubuntu_version: "22.04" additional_services: "" - - name: "bobcat" - openstack_version: "stable/2023.2" - ubuntu_version: "22.04" - additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Deploy OpenStack ${{ matrix.name }} with Octavia and run loadbalancer acceptance tests steps: diff --git a/.github/workflows/functional-messaging.yaml b/.github/workflows/functional-messaging.yaml index a5a545ad97..f47e6f620c 100644 --- a/.github/workflows/functional-messaging.yaml +++ b/.github/workflows/functional-messaging.yaml @@ -23,10 +23,6 @@ jobs: openstack_version: "stable/2024.1" ubuntu_version: "22.04" additional_services: "" - - name: "bobcat" - openstack_version: "stable/2023.2" - ubuntu_version: "22.04" - additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Deploy OpenStack ${{ matrix.name }} with Zaqar and run messaging acceptance tests steps: diff --git a/.github/workflows/functional-networking.yaml b/.github/workflows/functional-networking.yaml index 8cf92fbfb0..7127596ff7 100644 --- a/.github/workflows/functional-networking.yaml +++ b/.github/workflows/functional-networking.yaml @@ -23,10 +23,6 @@ jobs: openstack_version: "stable/2024.1" ubuntu_version: "22.04" additional_services: "" - - name: "bobcat" - openstack_version: "stable/2023.2" - ubuntu_version: "22.04" - additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Deploy OpenStack ${{ matrix.name }} with Neutron and run networking acceptance tests steps: diff --git a/.github/workflows/functional-objectstorage.yaml b/.github/workflows/functional-objectstorage.yaml index 6ad7e4c281..9b98a32d3f 100644 --- a/.github/workflows/functional-objectstorage.yaml +++ b/.github/workflows/functional-objectstorage.yaml @@ -23,10 +23,6 @@ jobs: openstack_version: "stable/2024.1" ubuntu_version: "22.04" additional_services: "" - - name: "bobcat" - openstack_version: "stable/2023.2" - ubuntu_version: "22.04" - additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Deploy OpenStack ${{ matrix.name }} with Swift and run objectstorage acceptance tests steps: diff --git a/.github/workflows/functional-orchestration.yaml b/.github/workflows/functional-orchestration.yaml index 08123c3289..111a1c1a86 100644 --- a/.github/workflows/functional-orchestration.yaml +++ b/.github/workflows/functional-orchestration.yaml @@ -23,10 +23,6 @@ jobs: openstack_version: "stable/2024.1" ubuntu_version: "22.04" additional_services: "" - - name: "bobcat" - openstack_version: "stable/2023.2" - ubuntu_version: "22.04" - additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Deploy OpenStack ${{ matrix.name }} with Heat and run orchestration acceptance tests steps: diff --git a/.github/workflows/functional-placement.yaml b/.github/workflows/functional-placement.yaml index 3ea0e5b3eb..261bf74200 100644 --- a/.github/workflows/functional-placement.yaml +++ b/.github/workflows/functional-placement.yaml @@ -23,10 +23,6 @@ jobs: openstack_version: "stable/2024.1" ubuntu_version: "22.04" additional_services: "" - - name: "bobcat" - openstack_version: "stable/2023.2" - ubuntu_version: "22.04" - additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Deploy OpenStack ${{ matrix.name }} with Placement and run placement acceptance tests steps: diff --git a/.github/workflows/functional-sharedfilesystems.yaml b/.github/workflows/functional-sharedfilesystems.yaml index c8d891a7c9..75704987d7 100644 --- a/.github/workflows/functional-sharedfilesystems.yaml +++ b/.github/workflows/functional-sharedfilesystems.yaml @@ -29,10 +29,6 @@ jobs: openstack_version: "stable/2024.1" ubuntu_version: "22.04" additional_services: "" - - name: "bobcat" - openstack_version: "stable/2023.2" - ubuntu_version: "22.04" - additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Deploy OpenStack ${{ matrix.name }} with Manila and run sharedfilesystems acceptance tests steps: diff --git a/.github/workflows/functional-workflow.yaml b/.github/workflows/functional-workflow.yaml index 582128d5ff..376cc181e8 100644 --- a/.github/workflows/functional-workflow.yaml +++ b/.github/workflows/functional-workflow.yaml @@ -26,14 +26,6 @@ jobs: ubuntu_version: "22.04" mistral_plugin_version: "stable/2024.1" additional_services: "" - - name: "bobcat" - openstack_version: "stable/2023.2" - ubuntu_version: "22.04" - # Devstack support is broken with Mistral v2023.2, and requires 2 patches: - # * https://github.com/openstack/mistral/commit/e343ccb078d8ba261ac70afca93f4358589730d3 - # * https://github.com/openstack/mistral/commit/ecdeadeb7a1aa87cba2cdb0c1a2bb1ffc4aabf25 - mistral_plugin_version: "ecdeadeb7a1aa87cba2cdb0c1a2bb1ffc4aabf25" - additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Deploy OpenStack ${{ matrix.name }} with Mistral and run workflow acceptance tests steps: From 7ccacfab735847896d655713e5fb5c4d0c4f9594 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Fri, 18 Apr 2025 11:11:57 +0100 Subject: [PATCH 114/353] Simplify functional-baremetal jobs All versions use system scope now. Signed-off-by: Stephen Finucane --- .github/workflows/functional-baremetal.yaml | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/.github/workflows/functional-baremetal.yaml b/.github/workflows/functional-baremetal.yaml index 035a78cb2b..df5e4c88dc 100644 --- a/.github/workflows/functional-baremetal.yaml +++ b/.github/workflows/functional-baremetal.yaml @@ -14,20 +14,14 @@ jobs: - name: "master" openstack_version: "master" ubuntu_version: "22.04" - use_system_scope: true additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" ubuntu_version: "22.04" - # NOTE(dtantsur): this forces running tests with a system scope - # token, which is required for certain actions. Use it on versions - # starting with 2024.1. - use_system_scope: true additional_services: "openstack-cli-server" - name: "caracal" openstack_version: "stable/2024.1" ubuntu_version: "22.04" - use_system_scope: true additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Deploy OpenStack ${{ matrix.name }} with Ironic and run baremetal acceptance tests @@ -93,8 +87,7 @@ jobs: DEVSTACK_PATH: ${{ github.workspace }}/devstack PACKAGE: "./internal/acceptance/openstack/baremetal/..." OS_BRANCH: ${{ matrix.openstack_version }} - # TODO(dtantsur): default to true when no longer supporting versions before 2024.1 - USE_SYSTEM_SCOPE: ${{ matrix.use_system_scope }} + USE_SYSTEM_SCOPE: true - name: Generate logs on failure run: ./script/collectlogs if: failure() From 6b0ebdc335537523bd6aa8e6650b5aee94daaa3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?p=C3=BDrus?= Date: Fri, 2 May 2025 11:53:18 +0200 Subject: [PATCH 115/353] core: add missing Builder interfaces --- openstack/blockstorage/v2/backups/requests.go | 16 ++++++++++++-- .../blockstorage/v2/transfers/requests.go | 16 ++++++++++++-- openstack/blockstorage/v2/volumes/requests.go | 16 ++++++++++++-- openstack/blockstorage/v3/backups/requests.go | 16 ++++++++++++-- .../blockstorage/v3/transfers/requests.go | 16 ++++++++++++-- openstack/blockstorage/v3/volumes/requests.go | 16 ++++++++++++-- openstack/compute/v2/aggregates/requests.go | 16 ++++++++++++-- openstack/compute/v2/services/requests.go | 8 ++++++- .../identity/v3/ec2credentials/requests.go | 8 ++++++- openstack/identity/v3/oauth1/requests.go | 8 ++++++- openstack/identity/v3/projects/requests.go | 3 +-- .../v2/flavorprofiles/requests.go | 2 +- openstack/loadbalancer/v2/flavors/requests.go | 2 +- .../loadbalancer/v2/l7policies/requests.go | 8 ++++++- .../loadbalancer/v2/listeners/requests.go | 2 +- .../loadbalancer/v2/loadbalancers/requests.go | 2 +- .../v2/extensions/bgp/peers/requests.go | 4 ++-- .../v2/extensions/bgp/speakers/requests.go | 2 +- .../v2/extensions/bgpvpns/requests.go | 4 ++-- .../v2/extensions/layer3/routers/requests.go | 21 ++++++++++++++++--- .../v2/extensions/security/rules/requests.go | 21 ++++++++++++++++--- .../v2/sharetransfers/requests.go | 8 ++++++- 22 files changed, 179 insertions(+), 36 deletions(-) diff --git a/openstack/blockstorage/v2/backups/requests.go b/openstack/blockstorage/v2/backups/requests.go index 573946ab25..a791191d96 100644 --- a/openstack/blockstorage/v2/backups/requests.go +++ b/openstack/blockstorage/v2/backups/requests.go @@ -238,6 +238,12 @@ func Update(ctx context.Context, client *gophercloud.ServiceClient, id string, o return } +// RestoreOptsBuilder allows extensions to add additional parameters to the +// Restore request. +type RestoreOptsBuilder interface { + ToRestoreMap() (map[string]any, error) +} + // RestoreOpts contains options for restoring a Backup. This object is passed to // the backups.RestoreFromBackup function. type RestoreOpts struct { @@ -257,7 +263,7 @@ func (opts RestoreOpts) ToRestoreMap() (map[string]any, error) { // RestoreFromBackup will restore a Backup to a volume based on the values in // RestoreOpts. To extract the Restore object from the response, call the // Extract method on the RestoreResult. -func RestoreFromBackup(ctx context.Context, client *gophercloud.ServiceClient, id string, opts RestoreOpts) (r RestoreResult) { +func RestoreFromBackup(ctx context.Context, client *gophercloud.ServiceClient, id string, opts RestoreOptsBuilder) (r RestoreResult) { b, err := opts.ToRestoreMap() if err != nil { r.Err = err @@ -278,6 +284,12 @@ func Export(ctx context.Context, client *gophercloud.ServiceClient, id string) ( return } +// ImportOptsBuilder allows extensions to add additional parameters to the +// Import request. +type ImportOptsBuilder interface { + ToBackupImportMap() (map[string]any, error) +} + // ImportOpts contains options for importing a Backup. This object is passed to // the backups.ImportBackup function. type ImportOpts BackupRecord @@ -291,7 +303,7 @@ func (opts ImportOpts) ToBackupImportMap() (map[string]any, error) { // Import will import a Backup data to a backup based on the values in // ImportOpts. To extract the Backup object from the response, call the // Extract method on the ImportResult. -func Import(ctx context.Context, client *gophercloud.ServiceClient, opts ImportOpts) (r ImportResult) { +func Import(ctx context.Context, client *gophercloud.ServiceClient, opts ImportOptsBuilder) (r ImportResult) { b, err := opts.ToBackupImportMap() if err != nil { r.Err = err diff --git a/openstack/blockstorage/v2/transfers/requests.go b/openstack/blockstorage/v2/transfers/requests.go index 9c762cfe1e..4d146ff235 100644 --- a/openstack/blockstorage/v2/transfers/requests.go +++ b/openstack/blockstorage/v2/transfers/requests.go @@ -7,6 +7,12 @@ import ( "github.com/gophercloud/gophercloud/v2/pagination" ) +// CreateOptsBuilder allows extensions to add additional parameters to the +// Create request. +type CreateOptsBuilder interface { + ToCreateMap() (map[string]any, error) +} + // CreateOpts contains options for a Volume transfer. type CreateOpts struct { // The ID of the volume to transfer. @@ -23,7 +29,7 @@ func (opts CreateOpts) ToCreateMap() (map[string]any, error) { } // Create will create a volume tranfer request based on the values in CreateOpts. -func Create(ctx context.Context, client *gophercloud.ServiceClient, opts CreateOpts) (r CreateResult) { +func Create(ctx context.Context, client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { b, err := opts.ToCreateMap() if err != nil { r.Err = err @@ -36,6 +42,12 @@ func Create(ctx context.Context, client *gophercloud.ServiceClient, opts CreateO return } +// AcceptOptsBuilder allows extensions to add additional parameters to the +// Accept request. +type AcceptOptsBuilder interface { + ToAcceptMap() (map[string]any, error) +} + // AcceptOpts contains options for a Volume transfer accept reqeust. type AcceptOpts struct { // The auth key of the volume transfer to accept. @@ -49,7 +61,7 @@ func (opts AcceptOpts) ToAcceptMap() (map[string]any, error) { } // Accept will accept a volume tranfer request based on the values in AcceptOpts. -func Accept(ctx context.Context, client *gophercloud.ServiceClient, id string, opts AcceptOpts) (r CreateResult) { +func Accept(ctx context.Context, client *gophercloud.ServiceClient, id string, opts AcceptOptsBuilder) (r CreateResult) { b, err := opts.ToAcceptMap() if err != nil { r.Err = err diff --git a/openstack/blockstorage/v2/volumes/requests.go b/openstack/blockstorage/v2/volumes/requests.go index 9d1e797fc9..62b36d2143 100644 --- a/openstack/blockstorage/v2/volumes/requests.go +++ b/openstack/blockstorage/v2/volumes/requests.go @@ -617,6 +617,12 @@ func SetImageMetadata(ctx context.Context, client *gophercloud.ServiceClient, id return } +// BootableOptsBuilder allows extensions to add additional parameters to the +// SetBootable request. +type BootableOptsBuilder interface { + ToBootableMap() (map[string]any, error) +} + // BootableOpts contains options for setting bootable status to a volume. type BootableOpts struct { // Enables or disables the bootable attribute. You can boot an instance from a bootable volume. @@ -630,7 +636,7 @@ func (opts BootableOpts) ToBootableMap() (map[string]any, error) { } // SetBootable will set bootable status on a volume based on the values in BootableOpts -func SetBootable(ctx context.Context, client *gophercloud.ServiceClient, id string, opts BootableOpts) (r SetBootableResult) { +func SetBootable(ctx context.Context, client *gophercloud.ServiceClient, id string, opts BootableOptsBuilder) (r SetBootableResult) { b, err := opts.ToBootableMap() if err != nil { r.Err = err @@ -691,6 +697,12 @@ func ChangeType(ctx context.Context, client *gophercloud.ServiceClient, id strin return } +// ReImageOptsBuilder allows extensions to add additional parameters to the +// ReImage request. +type ReImageOptsBuilder interface { + ToReImageMap() (map[string]any, error) +} + // ReImageOpts contains options for Re-image a volume. type ReImageOpts struct { // New image id @@ -705,7 +717,7 @@ func (opts ReImageOpts) ToReImageMap() (map[string]any, error) { } // ReImage will re-image a volume based on the values in ReImageOpts -func ReImage(ctx context.Context, client *gophercloud.ServiceClient, id string, opts ReImageOpts) (r ReImageResult) { +func ReImage(ctx context.Context, client *gophercloud.ServiceClient, id string, opts ReImageOptsBuilder) (r ReImageResult) { b, err := opts.ToReImageMap() if err != nil { r.Err = err diff --git a/openstack/blockstorage/v3/backups/requests.go b/openstack/blockstorage/v3/backups/requests.go index a1f3cc8eef..d75da4c254 100644 --- a/openstack/blockstorage/v3/backups/requests.go +++ b/openstack/blockstorage/v3/backups/requests.go @@ -238,6 +238,12 @@ func Update(ctx context.Context, client *gophercloud.ServiceClient, id string, o return } +// RestoreOptsBuilder allows extensions to add additional parameters to the +// Restore request. +type RestoreOptsBuilder interface { + ToRestoreMap() (map[string]any, error) +} + // RestoreOpts contains options for restoring a Backup. This object is passed to // the backups.RestoreFromBackup function. type RestoreOpts struct { @@ -257,7 +263,7 @@ func (opts RestoreOpts) ToRestoreMap() (map[string]any, error) { // RestoreFromBackup will restore a Backup to a volume based on the values in // RestoreOpts. To extract the Restore object from the response, call the // Extract method on the RestoreResult. -func RestoreFromBackup(ctx context.Context, client *gophercloud.ServiceClient, id string, opts RestoreOpts) (r RestoreResult) { +func RestoreFromBackup(ctx context.Context, client *gophercloud.ServiceClient, id string, opts RestoreOptsBuilder) (r RestoreResult) { b, err := opts.ToRestoreMap() if err != nil { r.Err = err @@ -278,6 +284,12 @@ func Export(ctx context.Context, client *gophercloud.ServiceClient, id string) ( return } +// ImportOptsBuilder allows extensions to add additional parameters to the +// Import request. +type ImportOptsBuilder interface { + ToBackupImportMap() (map[string]any, error) +} + // ImportOpts contains options for importing a Backup. This object is passed to // the backups.ImportBackup function. type ImportOpts BackupRecord @@ -291,7 +303,7 @@ func (opts ImportOpts) ToBackupImportMap() (map[string]any, error) { // Import will import a Backup data to a backup based on the values in // ImportOpts. To extract the Backup object from the response, call the // Extract method on the ImportResult. -func Import(ctx context.Context, client *gophercloud.ServiceClient, opts ImportOpts) (r ImportResult) { +func Import(ctx context.Context, client *gophercloud.ServiceClient, opts ImportOptsBuilder) (r ImportResult) { b, err := opts.ToBackupImportMap() if err != nil { r.Err = err diff --git a/openstack/blockstorage/v3/transfers/requests.go b/openstack/blockstorage/v3/transfers/requests.go index 9c762cfe1e..4d146ff235 100644 --- a/openstack/blockstorage/v3/transfers/requests.go +++ b/openstack/blockstorage/v3/transfers/requests.go @@ -7,6 +7,12 @@ import ( "github.com/gophercloud/gophercloud/v2/pagination" ) +// CreateOptsBuilder allows extensions to add additional parameters to the +// Create request. +type CreateOptsBuilder interface { + ToCreateMap() (map[string]any, error) +} + // CreateOpts contains options for a Volume transfer. type CreateOpts struct { // The ID of the volume to transfer. @@ -23,7 +29,7 @@ func (opts CreateOpts) ToCreateMap() (map[string]any, error) { } // Create will create a volume tranfer request based on the values in CreateOpts. -func Create(ctx context.Context, client *gophercloud.ServiceClient, opts CreateOpts) (r CreateResult) { +func Create(ctx context.Context, client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { b, err := opts.ToCreateMap() if err != nil { r.Err = err @@ -36,6 +42,12 @@ func Create(ctx context.Context, client *gophercloud.ServiceClient, opts CreateO return } +// AcceptOptsBuilder allows extensions to add additional parameters to the +// Accept request. +type AcceptOptsBuilder interface { + ToAcceptMap() (map[string]any, error) +} + // AcceptOpts contains options for a Volume transfer accept reqeust. type AcceptOpts struct { // The auth key of the volume transfer to accept. @@ -49,7 +61,7 @@ func (opts AcceptOpts) ToAcceptMap() (map[string]any, error) { } // Accept will accept a volume tranfer request based on the values in AcceptOpts. -func Accept(ctx context.Context, client *gophercloud.ServiceClient, id string, opts AcceptOpts) (r CreateResult) { +func Accept(ctx context.Context, client *gophercloud.ServiceClient, id string, opts AcceptOptsBuilder) (r CreateResult) { b, err := opts.ToAcceptMap() if err != nil { r.Err = err diff --git a/openstack/blockstorage/v3/volumes/requests.go b/openstack/blockstorage/v3/volumes/requests.go index 77210943b5..4dc2c1be7e 100644 --- a/openstack/blockstorage/v3/volumes/requests.go +++ b/openstack/blockstorage/v3/volumes/requests.go @@ -623,6 +623,12 @@ func SetImageMetadata(ctx context.Context, client *gophercloud.ServiceClient, id return } +// BootableOptsBuilder allows extensions to add additional parameters to the +// SetBootable request. +type BootableOptsBuilder interface { + ToBootableMap() (map[string]any, error) +} + // BootableOpts contains options for setting bootable status to a volume. type BootableOpts struct { // Enables or disables the bootable attribute. You can boot an instance from a bootable volume. @@ -636,7 +642,7 @@ func (opts BootableOpts) ToBootableMap() (map[string]any, error) { } // SetBootable will set bootable status on a volume based on the values in BootableOpts -func SetBootable(ctx context.Context, client *gophercloud.ServiceClient, id string, opts BootableOpts) (r SetBootableResult) { +func SetBootable(ctx context.Context, client *gophercloud.ServiceClient, id string, opts BootableOptsBuilder) (r SetBootableResult) { b, err := opts.ToBootableMap() if err != nil { r.Err = err @@ -697,6 +703,12 @@ func ChangeType(ctx context.Context, client *gophercloud.ServiceClient, id strin return } +// ReImageOptsBuilder allows extensions to add additional parameters to the +// ReImage request. +type ReImageOptsBuilder interface { + ToReImageMap() (map[string]any, error) +} + // ReImageOpts contains options for Re-image a volume. type ReImageOpts struct { // New image id @@ -711,7 +723,7 @@ func (opts ReImageOpts) ToReImageMap() (map[string]any, error) { } // ReImage will re-image a volume based on the values in ReImageOpts -func ReImage(ctx context.Context, client *gophercloud.ServiceClient, id string, opts ReImageOpts) (r ReImageResult) { +func ReImage(ctx context.Context, client *gophercloud.ServiceClient, id string, opts ReImageOptsBuilder) (r ReImageResult) { b, err := opts.ToReImageMap() if err != nil { r.Err = err diff --git a/openstack/compute/v2/aggregates/requests.go b/openstack/compute/v2/aggregates/requests.go index 7111c203b0..634b9fa97d 100644 --- a/openstack/compute/v2/aggregates/requests.go +++ b/openstack/compute/v2/aggregates/requests.go @@ -15,6 +15,12 @@ func List(client *gophercloud.ServiceClient) pagination.Pager { }) } +// CreateOptsBuilder allows extensions to add additional parameters to the +// Create request. +type CreateOptsBuilder interface { + ToAggregatesCreateMap() (map[string]any, error) +} + type CreateOpts struct { // The name of the host aggregate. Name string `json:"name" required:"true"` @@ -31,7 +37,7 @@ func (opts CreateOpts) ToAggregatesCreateMap() (map[string]any, error) { } // Create makes a request against the API to create an aggregate. -func Create(ctx context.Context, client *gophercloud.ServiceClient, opts CreateOpts) (r CreateResult) { +func Create(ctx context.Context, client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { b, err := opts.ToAggregatesCreateMap() if err != nil { r.Err = err @@ -64,6 +70,12 @@ func Get(ctx context.Context, client *gophercloud.ServiceClient, aggregateID int return } +// UpdateOptsBuilder allows extensions to add additional parameters to the +// Update request. +type UpdateOptsBuilder interface { + ToAggregatesUpdateMap() (map[string]any, error) +} + type UpdateOpts struct { // The name of the host aggregate. Name string `json:"name,omitempty"` @@ -80,7 +92,7 @@ func (opts UpdateOpts) ToAggregatesUpdateMap() (map[string]any, error) { } // Update makes a request against the API to update a specific aggregate. -func Update(ctx context.Context, client *gophercloud.ServiceClient, aggregateID int, opts UpdateOpts) (r UpdateResult) { +func Update(ctx context.Context, client *gophercloud.ServiceClient, aggregateID int, opts UpdateOptsBuilder) (r UpdateResult) { v := strconv.Itoa(aggregateID) b, err := opts.ToAggregatesUpdateMap() diff --git a/openstack/compute/v2/services/requests.go b/openstack/compute/v2/services/requests.go index 7f6ac1d6d8..32be17cb70 100644 --- a/openstack/compute/v2/services/requests.go +++ b/openstack/compute/v2/services/requests.go @@ -51,6 +51,12 @@ const ( ServiceDisabled ServiceStatus = "disabled" ) +// UpdateOptsBuilder allows extensions to add additional parameters to the +// Update request. +type UpdateOptsBuilder interface { + ToServiceUpdateMap() (map[string]any, error) +} + // UpdateOpts specifies the base attributes that may be updated on a service. type UpdateOpts struct { // Status represents the new service status. One of enabled or disabled. @@ -70,7 +76,7 @@ func (opts UpdateOpts) ToServiceUpdateMap() (map[string]any, error) { } // Update requests that various attributes of the indicated service be changed. -func Update(ctx context.Context, client *gophercloud.ServiceClient, id string, opts UpdateOpts) (r UpdateResult) { +func Update(ctx context.Context, client *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) { b, err := opts.ToServiceUpdateMap() if err != nil { r.Err = err diff --git a/openstack/identity/v3/ec2credentials/requests.go b/openstack/identity/v3/ec2credentials/requests.go index aefb2b14b7..df3c59aff2 100644 --- a/openstack/identity/v3/ec2credentials/requests.go +++ b/openstack/identity/v3/ec2credentials/requests.go @@ -22,6 +22,12 @@ func Get(ctx context.Context, client *gophercloud.ServiceClient, userID string, return } +// CreateOptsBuilder allows extensions to add additional parameters to the +// Create request. +type CreateOptsBuilder interface { + ToCredentialCreateMap() (map[string]any, error) +} + // CreateOpts provides options used to create an EC2 credential. type CreateOpts struct { // TenantID is the project ID scope of the EC2 credential. @@ -34,7 +40,7 @@ func (opts CreateOpts) ToCredentialCreateMap() (map[string]any, error) { } // Create creates a new EC2 Credential. -func Create(ctx context.Context, client *gophercloud.ServiceClient, userID string, opts CreateOpts) (r CreateResult) { +func Create(ctx context.Context, client *gophercloud.ServiceClient, userID string, opts CreateOptsBuilder) (r CreateResult) { b, err := opts.ToCredentialCreateMap() if err != nil { r.Err = err diff --git a/openstack/identity/v3/oauth1/requests.go b/openstack/identity/v3/oauth1/requests.go index 8c66b36e20..0b23269ffa 100644 --- a/openstack/identity/v3/oauth1/requests.go +++ b/openstack/identity/v3/oauth1/requests.go @@ -214,6 +214,12 @@ func GetConsumer(ctx context.Context, client *gophercloud.ServiceClient, id stri return } +// UpdateConsumerOptsBuilder allows extensions to add additional parameters to the +// UpdateConsumer request. +type UpdateConsumerOptsBuilder interface { + ToOAuth1UpdateConsumerMap() (map[string]any, error) +} + // UpdateConsumerOpts provides options used to update a consumer. type UpdateConsumerOpts struct { // Description is the consumer description. @@ -227,7 +233,7 @@ func (opts UpdateConsumerOpts) ToOAuth1UpdateConsumerMap() (map[string]any, erro } // UpdateConsumer updates an existing Consumer. -func UpdateConsumer(ctx context.Context, client *gophercloud.ServiceClient, id string, opts UpdateConsumerOpts) (r UpdateConsumerResult) { +func UpdateConsumer(ctx context.Context, client *gophercloud.ServiceClient, id string, opts UpdateConsumerOptsBuilder) (r UpdateConsumerResult) { b, err := opts.ToOAuth1UpdateConsumerMap() if err != nil { r.Err = err diff --git a/openstack/identity/v3/projects/requests.go b/openstack/identity/v3/projects/requests.go index 30338fc514..6fb8448a9f 100644 --- a/openstack/identity/v3/projects/requests.go +++ b/openstack/identity/v3/projects/requests.go @@ -276,8 +276,7 @@ func (opts ModifyTagsOpts) ToModifyTagsCreateMap() (map[string]any, error) { } // ModifyTags deletes all tags of a project and adds new ones. -func ModifyTags(ctx context.Context, client *gophercloud.ServiceClient, projectID string, opts ModifyTagsOpts) (r ModifyTagsResult) { - +func ModifyTags(ctx context.Context, client *gophercloud.ServiceClient, projectID string, opts ModifyTagsOptsBuilder) (r ModifyTagsResult) { b, err := opts.ToModifyTagsCreateMap() if err != nil { r.Err = err diff --git a/openstack/loadbalancer/v2/flavorprofiles/requests.go b/openstack/loadbalancer/v2/flavorprofiles/requests.go index e51b9d99e6..364f9ccd38 100644 --- a/openstack/loadbalancer/v2/flavorprofiles/requests.go +++ b/openstack/loadbalancer/v2/flavorprofiles/requests.go @@ -121,7 +121,7 @@ func (opts UpdateOpts) ToFlavorProfileUpdateMap() (map[string]any, error) { // Update is an operation which modifies the attributes of the specified // FlavorProfile. -func Update(ctx context.Context, c *gophercloud.ServiceClient, id string, opts UpdateOpts) (r UpdateResult) { +func Update(ctx context.Context, c *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) { b, err := opts.ToFlavorProfileUpdateMap() if err != nil { r.Err = err diff --git a/openstack/loadbalancer/v2/flavors/requests.go b/openstack/loadbalancer/v2/flavors/requests.go index 710a6edf5b..67196a5202 100644 --- a/openstack/loadbalancer/v2/flavors/requests.go +++ b/openstack/loadbalancer/v2/flavors/requests.go @@ -127,7 +127,7 @@ func (opts UpdateOpts) ToFlavorUpdateMap() (map[string]any, error) { // Update is an operation which modifies the attributes of the specified // Flavor. -func Update(ctx context.Context, c *gophercloud.ServiceClient, id string, opts UpdateOpts) (r UpdateResult) { +func Update(ctx context.Context, c *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) { b, err := opts.ToFlavorUpdateMap() if err != nil { r.Err = err diff --git a/openstack/loadbalancer/v2/l7policies/requests.go b/openstack/loadbalancer/v2/l7policies/requests.go index 62a4f179ee..ab0b22c6bc 100644 --- a/openstack/loadbalancer/v2/l7policies/requests.go +++ b/openstack/loadbalancer/v2/l7policies/requests.go @@ -263,6 +263,12 @@ func Update(ctx context.Context, c *gophercloud.ServiceClient, id string, opts U return } +// CreateRuleOptsBuilder allows extensions to add additional parameters to the +// CreateRule request. +type CreateRuleOptsBuilder interface { + ToRuleCreateMap() (map[string]any, error) +} + // CreateRuleOpts is the common options struct used in this package's CreateRule // operation. type CreateRuleOpts struct { @@ -300,7 +306,7 @@ func (opts CreateRuleOpts) ToRuleCreateMap() (map[string]any, error) { } // CreateRule will create and associate a Rule with a particular L7Policy. -func CreateRule(ctx context.Context, c *gophercloud.ServiceClient, policyID string, opts CreateRuleOpts) (r CreateRuleResult) { +func CreateRule(ctx context.Context, c *gophercloud.ServiceClient, policyID string, opts CreateRuleOptsBuilder) (r CreateRuleResult) { b, err := opts.ToRuleCreateMap() if err != nil { r.Err = err diff --git a/openstack/loadbalancer/v2/listeners/requests.go b/openstack/loadbalancer/v2/listeners/requests.go index 3216fbddd0..abd5d08970 100644 --- a/openstack/loadbalancer/v2/listeners/requests.go +++ b/openstack/loadbalancer/v2/listeners/requests.go @@ -380,7 +380,7 @@ func (opts UpdateOpts) ToListenerUpdateMap() (map[string]any, error) { // Update is an operation which modifies the attributes of the specified // Listener. -func Update(ctx context.Context, c *gophercloud.ServiceClient, id string, opts UpdateOpts) (r UpdateResult) { +func Update(ctx context.Context, c *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) { b, err := opts.ToListenerUpdateMap() if err != nil { r.Err = err diff --git a/openstack/loadbalancer/v2/loadbalancers/requests.go b/openstack/loadbalancer/v2/loadbalancers/requests.go index f815806f39..095170edd3 100644 --- a/openstack/loadbalancer/v2/loadbalancers/requests.go +++ b/openstack/loadbalancer/v2/loadbalancers/requests.go @@ -208,7 +208,7 @@ func (opts UpdateOpts) ToLoadBalancerUpdateMap() (map[string]any, error) { // Update is an operation which modifies the attributes of the specified // LoadBalancer. -func Update(ctx context.Context, c *gophercloud.ServiceClient, id string, opts UpdateOpts) (r UpdateResult) { +func Update(ctx context.Context, c *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) { b, err := opts.ToLoadBalancerUpdateMap() if err != nil { r.Err = err diff --git a/openstack/networking/v2/extensions/bgp/peers/requests.go b/openstack/networking/v2/extensions/bgp/peers/requests.go index eef38c0b79..589c4f7ad8 100644 --- a/openstack/networking/v2/extensions/bgp/peers/requests.go +++ b/openstack/networking/v2/extensions/bgp/peers/requests.go @@ -43,7 +43,7 @@ func (opts CreateOpts) ToPeerCreateMap() (map[string]any, error) { } // Create a BGP Peer -func Create(ctx context.Context, c *gophercloud.ServiceClient, opts CreateOpts) (r CreateResult) { +func Create(ctx context.Context, c *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { b, err := opts.ToPeerCreateMap() if err != nil { r.Err = err @@ -79,7 +79,7 @@ func (opts UpdateOpts) ToPeerUpdateMap() (map[string]any, error) { } // Update accept a BGP Peer ID and an UpdateOpts and update the BGP Peer -func Update(ctx context.Context, c *gophercloud.ServiceClient, bgpPeerID string, opts UpdateOpts) (r UpdateResult) { +func Update(ctx context.Context, c *gophercloud.ServiceClient, bgpPeerID string, opts UpdateOptsBuilder) (r UpdateResult) { b, err := opts.ToPeerUpdateMap() if err != nil { r.Err = err diff --git a/openstack/networking/v2/extensions/bgp/speakers/requests.go b/openstack/networking/v2/extensions/bgp/speakers/requests.go index b6dd26d909..8597602a7d 100644 --- a/openstack/networking/v2/extensions/bgp/speakers/requests.go +++ b/openstack/networking/v2/extensions/bgp/speakers/requests.go @@ -43,7 +43,7 @@ func (opts CreateOpts) ToSpeakerCreateMap() (map[string]any, error) { } // Create accepts a CreateOpts and create a BGP Speaker. -func Create(ctx context.Context, c *gophercloud.ServiceClient, opts CreateOpts) (r CreateResult) { +func Create(ctx context.Context, c *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { b, err := opts.ToSpeakerCreateMap() if err != nil { r.Err = err diff --git a/openstack/networking/v2/extensions/bgpvpns/requests.go b/openstack/networking/v2/extensions/bgpvpns/requests.go index 587961edee..374b4daf5b 100644 --- a/openstack/networking/v2/extensions/bgpvpns/requests.go +++ b/openstack/networking/v2/extensions/bgpvpns/requests.go @@ -81,7 +81,7 @@ func (opts CreateOpts) ToBGPVPNCreateMap() (map[string]any, error) { } // Create a BGP VPN -func Create(ctx context.Context, c *gophercloud.ServiceClient, opts CreateOpts) (r CreateResult) { +func Create(ctx context.Context, c *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { b, err := opts.ToBGPVPNCreateMap() if err != nil { r.Err = err @@ -121,7 +121,7 @@ func (opts UpdateOpts) ToBGPVPNUpdateMap() (map[string]any, error) { } // Update accept a BGP VPN ID and an UpdateOpts and update the BGP VPN -func Update(ctx context.Context, c *gophercloud.ServiceClient, id string, opts UpdateOpts) (r UpdateResult) { +func Update(ctx context.Context, c *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) { b, err := opts.ToBGPVPNUpdateMap() if err != nil { r.Err = err diff --git a/openstack/networking/v2/extensions/layer3/routers/requests.go b/openstack/networking/v2/extensions/layer3/routers/requests.go index f6ca654841..5d31ec1138 100644 --- a/openstack/networking/v2/extensions/layer3/routers/requests.go +++ b/openstack/networking/v2/extensions/layer3/routers/requests.go @@ -8,6 +8,12 @@ import ( "github.com/gophercloud/gophercloud/v2/pagination" ) +// ListOptsBuilder allows extensions to add additional parameters to the List +// request. +type ListOptsBuilder interface { + ToRouterListQuery() (string, error) +} + // ListOpts allows the filtering and sorting of paginated collections through // the API. Filtering is achieved by passing in struct field values that map to // the floating IP attributes you want to see returned. SortKey allows you to @@ -33,18 +39,27 @@ type ListOpts struct { RevisionNumber *int `q:"revision_number"` } +// ToRouterListQuery formats a ListOpts into a query string. +func (opts ListOpts) ToRouterListQuery() (string, error) { + q, err := gophercloud.BuildQueryString(&opts) + if err != nil { + return "", err + } + return q.String(), nil +} + // List returns a Pager which allows you to iterate over a collection of // routers. It accepts a ListOpts struct, which allows you to filter and sort // the returned collection for greater efficiency. // // Default policy settings return only those routers that are owned by the // tenant who submits the request, unless an admin user submits the request. -func List(c *gophercloud.ServiceClient, opts ListOpts) pagination.Pager { - q, err := gophercloud.BuildQueryString(&opts) +func List(c *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { + q, err := opts.ToRouterListQuery() if err != nil { return pagination.Pager{Err: err} } - u := rootURL(c) + q.String() + u := rootURL(c) + q return pagination.NewPager(c, u, func(r pagination.PageResult) pagination.Page { return RouterPage{pagination.LinkedPageBase{PageResult: r}} }) diff --git a/openstack/networking/v2/extensions/security/rules/requests.go b/openstack/networking/v2/extensions/security/rules/requests.go index 77768a3dac..2bb8ffc6c2 100644 --- a/openstack/networking/v2/extensions/security/rules/requests.go +++ b/openstack/networking/v2/extensions/security/rules/requests.go @@ -7,6 +7,12 @@ import ( "github.com/gophercloud/gophercloud/v2/pagination" ) +// ListOptsBuilder allows extensions to add additional parameters to the List +// request. +type ListOptsBuilder interface { + ToSecGroupListQuery() (string, error) +} + // ListOpts allows the filtering and sorting of paginated collections through // the API. Filtering is achieved by passing in struct field values that map to // the security group rule attributes you want to see returned. SortKey allows @@ -32,15 +38,24 @@ type ListOpts struct { RevisionNumber *int `q:"revision_number"` } +// ToSecGroupListQuery formats a ListOpts into a query string. +func (opts ListOpts) ToSecGroupListQuery() (string, error) { + q, err := gophercloud.BuildQueryString(&opts) + if err != nil { + return "", err + } + return q.String(), nil +} + // List returns a Pager which allows you to iterate over a collection of // security group rules. It accepts a ListOpts struct, which allows you to filter // and sort the returned collection for greater efficiency. -func List(c *gophercloud.ServiceClient, opts ListOpts) pagination.Pager { - q, err := gophercloud.BuildQueryString(&opts) +func List(c *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { + q, err := opts.ToSecGroupListQuery() if err != nil { return pagination.Pager{Err: err} } - u := rootURL(c) + q.String() + u := rootURL(c) + q return pagination.NewPager(c, u, func(r pagination.PageResult) pagination.Page { return SecGroupRulePage{pagination.LinkedPageBase{PageResult: r}} }) diff --git a/openstack/sharedfilesystems/v2/sharetransfers/requests.go b/openstack/sharedfilesystems/v2/sharetransfers/requests.go index 642d2a36d2..88b1950eb2 100644 --- a/openstack/sharedfilesystems/v2/sharetransfers/requests.go +++ b/openstack/sharedfilesystems/v2/sharetransfers/requests.go @@ -42,6 +42,12 @@ func Create(ctx context.Context, client *gophercloud.ServiceClient, opts CreateO return } +// AcceptOptsBuilder allows extensions to add additional parameters to the +// Accept request. +type AcceptOptsBuilder interface { + ToAcceptMap() (map[string]any, error) +} + // AcceptOpts contains options for a Share transfer accept reqeust. type AcceptOpts struct { // The auth key of the share transfer to accept. @@ -58,7 +64,7 @@ func (opts AcceptOpts) ToAcceptMap() (map[string]any, error) { } // Accept will accept a share tranfer request based on the values in AcceptOpts. -func Accept(ctx context.Context, client *gophercloud.ServiceClient, id string, opts AcceptOpts) (r AcceptResult) { +func Accept(ctx context.Context, client *gophercloud.ServiceClient, id string, opts AcceptOptsBuilder) (r AcceptResult) { b, err := opts.ToAcceptMap() if err != nil { r.Err = err From 71fd95ca276337817982ac97769fec32d91c7033 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Wed, 15 May 2024 15:43:02 +0100 Subject: [PATCH 116/353] tests: Search for compute service It's more common than the object storage service and allows us to run on a DevStack with default configuration. Signed-off-by: Stephen Finucane (cherry picked from commit c81a270a0cd598a263e471c11102647f5f8a0298) --- internal/acceptance/openstack/client_test.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/internal/acceptance/openstack/client_test.go b/internal/acceptance/openstack/client_test.go index 69e9a09367..3b252a2853 100644 --- a/internal/acceptance/openstack/client_test.go +++ b/internal/acceptance/openstack/client_test.go @@ -36,14 +36,14 @@ func TestAuthenticatedClient(t *testing.T) { t.Logf("Client successfully acquired a token: %v", client.TokenID) - // Find the storage service in the service catalog. - storage, err := openstack.NewObjectStorageV1(client, gophercloud.EndpointOpts{ + // Find the compute service in the service catalog. + compute, err := openstack.NewComputeV2(client, gophercloud.EndpointOpts{ Region: os.Getenv("OS_REGION_NAME"), }) if err != nil { - t.Errorf("Unable to locate a storage service: %v", err) + t.Errorf("Unable to locate a compute service: %v", err) } else { - t.Logf("Located a storage service at endpoint: [%s]", storage.Endpoint) + t.Logf("Located a compute service at endpoint: [%s]", compute.Endpoint) } } From ca1ccc25355cc90c251c2c0d00be40b1b8df0d34 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Wed, 22 May 2024 11:54:15 +0100 Subject: [PATCH 117/353] make: Correct typos We mangled this, probably since we were renaming the 'imageservice' module to 'image' at the time. Signed-off-by: Stephen Finucane (cherry picked from commit c56703d8872779ff2b3866b240cb58ff3e218a67) --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 2a0618a6b6..51b4d20478 100644 --- a/Makefile +++ b/Makefile @@ -38,7 +38,7 @@ coverage: $(GO_TEST) -covermode count -coverprofile cover.out -coverpkg=./... ./... .PHONY: coverage -acceptance: acceptance-baremetal acceptance-blockstorage acceptance-compute acceptance-container acceptance-containerinfra acceptance-db acceptance-dns acceptance-identity acceptance-imageservice acceptance-keymanager acceptance-loadbalancer acceptance-messaging acceptance-networking acceptance-objectstorage acceptance-orchestration acceptance-placement acceptance-sharedfilesystems acceptance-workflow +acceptance: acceptance-baremetal acceptance-blockstorage acceptance-compute acceptance-container acceptance-containerinfra acceptance-db acceptance-dns acceptance-identity acceptance-image acceptance-keymanager acceptance-loadbalancer acceptance-messaging acceptance-networking acceptance-objectstorage acceptance-orchestration acceptance-placement acceptance-sharedfilesystems acceptance-workflow .PHONY: acceptance acceptance-baremetal: @@ -74,7 +74,7 @@ acceptance-identity: .PHONY: acceptance-identity acceptance-image: - $(GO_TEST) -tags "fixtures acceptance" ./internal/acceptance/openstack/imageservice/... + $(GO_TEST) -tags "fixtures acceptance" ./internal/acceptance/openstack/image/... .PHONY: acceptance-image acceptance-keymanager: From f46c96dd87d13db8abe044005636bfc20cd0eb4e Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Wed, 8 May 2024 18:12:37 +0100 Subject: [PATCH 118/353] make: Add 'acceptance-basic' target For use in CI. Signed-off-by: Stephen Finucane (cherry picked from commit cfeb6d5aff9e3126e5180d4a15b133461c409491) --- Makefile | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 51b4d20478..cc30e43fd9 100644 --- a/Makefile +++ b/Makefile @@ -38,9 +38,13 @@ coverage: $(GO_TEST) -covermode count -coverprofile cover.out -coverpkg=./... ./... .PHONY: coverage -acceptance: acceptance-baremetal acceptance-blockstorage acceptance-compute acceptance-container acceptance-containerinfra acceptance-db acceptance-dns acceptance-identity acceptance-image acceptance-keymanager acceptance-loadbalancer acceptance-messaging acceptance-networking acceptance-objectstorage acceptance-orchestration acceptance-placement acceptance-sharedfilesystems acceptance-workflow +acceptance: acceptance-basic acceptance-baremetal acceptance-blockstorage acceptance-compute acceptance-container acceptance-containerinfra acceptance-db acceptance-dns acceptance-identity acceptance-image acceptance-keymanager acceptance-loadbalancer acceptance-messaging acceptance-networking acceptance-objectstorage acceptance-orchestration acceptance-placement acceptance-sharedfilesystems acceptance-workflow .PHONY: acceptance +acceptance-basic: + $(GO_TEST) -tags "fixtures acceptance" ./internal/acceptance/openstack +.PHONY: acceptance-basic + acceptance-baremetal: $(GO_TEST) -tags "fixtures acceptance" ./internal/acceptance/openstack/baremetal/... .PHONY: acceptance-baremetal From 8178ebffb17e8a3e3b98197edabf632661e53276 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Mon, 20 May 2024 17:49:33 +0100 Subject: [PATCH 119/353] make: Add timeout for acceptance tests Signed-off-by: Stephen Finucane (cherry picked from commit 7f4ed82c98a3436c7beb9b5216486c68920622b6) --- Makefile | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/Makefile b/Makefile index cc30e43fd9..47c397a6b1 100644 --- a/Makefile +++ b/Makefile @@ -2,6 +2,7 @@ undefine GOFLAGS GOLANGCI_LINT_VERSION?=v1.62.2 GO_TEST?=go run gotest.tools/gotestsum@latest --format testname -- +TIMEOUT := "60m" ifeq ($(shell command -v podman 2> /dev/null),) RUNNER=docker @@ -42,77 +43,77 @@ acceptance: acceptance-basic acceptance-baremetal acceptance-blockstorage accept .PHONY: acceptance acceptance-basic: - $(GO_TEST) -tags "fixtures acceptance" ./internal/acceptance/openstack + $(GO_TEST) -timeout $(TIMEOUT) -tags "fixtures acceptance" ./internal/acceptance/openstack .PHONY: acceptance-basic acceptance-baremetal: - $(GO_TEST) -tags "fixtures acceptance" ./internal/acceptance/openstack/baremetal/... + $(GO_TEST) -timeout $(TIMEOUT) -tags "fixtures acceptance" ./internal/acceptance/openstack/baremetal/... .PHONY: acceptance-baremetal acceptance-blockstorage: - $(GO_TEST) -tags "fixtures acceptance" ./internal/acceptance/openstack/blockstorage/... + $(GO_TEST) -timeout $(TIMEOUT) -tags "fixtures acceptance" ./internal/acceptance/openstack/blockstorage/... .PHONY: acceptance-blockstorage acceptance-compute: - $(GO_TEST) -tags "fixtures acceptance" ./internal/acceptance/openstack/compute/... + $(GO_TEST) -timeout $(TIMEOUT) -tags "fixtures acceptance" ./internal/acceptance/openstack/compute/... .PHONY: acceptance-compute acceptance-container: - $(GO_TEST) -tags "fixtures acceptance" ./internal/acceptance/openstack/container/... + $(GO_TEST) -timeout $(TIMEOUT) -tags "fixtures acceptance" ./internal/acceptance/openstack/container/... .PHONY: acceptance-container acceptance-containerinfra: - $(GO_TEST) -tags "fixtures acceptance" ./internal/acceptance/openstack/containerinfra/... + $(GO_TEST) -timeout $(TIMEOUT) -tags "fixtures acceptance" ./internal/acceptance/openstack/containerinfra/... .PHONY: acceptance-containerinfra acceptance-db: - $(GO_TEST) -tags "fixtures acceptance" ./internal/acceptance/openstack/db/... + $(GO_TEST) -timeout $(TIMEOUT) -tags "fixtures acceptance" ./internal/acceptance/openstack/db/... .PHONY: acceptance-db acceptance-dns: - $(GO_TEST) -tags "fixtures acceptance" ./internal/acceptance/openstack/dns/... + $(GO_TEST) -timeout $(TIMEOUT) -tags "fixtures acceptance" ./internal/acceptance/openstack/dns/... .PHONY: acceptance-dns acceptance-identity: - $(GO_TEST) -tags "fixtures acceptance" ./internal/acceptance/openstack/identity/... + $(GO_TEST) -timeout $(TIMEOUT) -tags "fixtures acceptance" ./internal/acceptance/openstack/identity/... .PHONY: acceptance-identity acceptance-image: - $(GO_TEST) -tags "fixtures acceptance" ./internal/acceptance/openstack/image/... + $(GO_TEST) -timeout $(TIMEOUT) -tags "fixtures acceptance" ./internal/acceptance/openstack/image/... .PHONY: acceptance-image acceptance-keymanager: - $(GO_TEST) -tags "fixtures acceptance" ./internal/acceptance/openstack/keymanager/... + $(GO_TEST) -timeout $(TIMEOUT) -tags "fixtures acceptance" ./internal/acceptance/openstack/keymanager/... .PHONY: acceptance-keymanager acceptance-loadbalancer: - $(GO_TEST) -tags "fixtures acceptance" ./internal/acceptance/openstack/loadbalancer/... + $(GO_TEST) -timeout $(TIMEOUT) -tags "fixtures acceptance" ./internal/acceptance/openstack/loadbalancer/... .PHONY: acceptance-loadbalancer acceptance-messaging: - $(GO_TEST) -tags "fixtures acceptance" ./internal/acceptance/openstack/messaging/... + $(GO_TEST) -timeout $(TIMEOUT) -tags "fixtures acceptance" ./internal/acceptance/openstack/messaging/... .PHONY: acceptance-messaging acceptance-networking: - $(GO_TEST) -tags "fixtures acceptance" ./internal/acceptance/openstack/networking/... + $(GO_TEST) -timeout $(TIMEOUT) -tags "fixtures acceptance" ./internal/acceptance/openstack/networking/... .PHONY: acceptance-networking acceptance-objectstorage: - $(GO_TEST) -tags "fixtures acceptance" ./internal/acceptance/openstack/objectstorage/... + $(GO_TEST) -timeout $(TIMEOUT) -tags "fixtures acceptance" ./internal/acceptance/openstack/objectstorage/... .PHONY: acceptance-objectstorage acceptance-orchestration: - $(GO_TEST) -tags "fixtures acceptance" ./internal/acceptance/openstack/orchestration/... + $(GO_TEST) -timeout $(TIMEOUT) -tags "fixtures acceptance" ./internal/acceptance/openstack/orchestration/... .PHONY: acceptance-orchestration acceptance-placement: - $(GO_TEST) -tags "fixtures acceptance" ./internal/acceptance/openstack/placement/... + $(GO_TEST) -timeout $(TIMEOUT) -tags "fixtures acceptance" ./internal/acceptance/openstack/placement/... .PHONY: acceptance-placement acceptance-sharedfilesystems: - $(GO_TEST) -tags "fixtures acceptance" ./internal/acceptance/openstack/sharedfilesystems/... + $(GO_TEST) -timeout $(TIMEOUT) -tags "fixtures acceptance" ./internal/acceptance/openstack/sharedfilesystems/... .PHONY: acceptance-sharefilesystems acceptance-workflow: - $(GO_TEST) -tags "fixtures acceptance" ./internal/acceptance/openstack/workflow/... + $(GO_TEST) -timeout $(TIMEOUT) -tags "fixtures acceptance" ./internal/acceptance/openstack/workflow/... .PHONY: acceptance-workflow From e84fb1de91432667704fd1c4db3019c2f4276aef Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Wed, 17 Jul 2024 16:15:38 +0100 Subject: [PATCH 120/353] make: Create golangci-lint cache dir if necessary Signed-off-by: Stephen Finucane (cherry picked from commit 56b90f65323ee37de6fa9d84fff629ec4388d2c9) --- Makefile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 47c397a6b1..86356b78ab 100644 --- a/Makefile +++ b/Makefile @@ -10,15 +10,18 @@ else RUNNER=podman endif -# if the golangci-lint steps fails with the following error message: +# if the golangci-lint steps fails with one of the following error messages: # # directory prefix . does not contain main module or its selected dependencies # +# failed to initialize build cache at /root/.cache/golangci-lint: mkdir /root/.cache/golangci-lint: permission denied +# # you probably have to fix the SELinux security context for root directory plus your cache # # chcon -Rt svirt_sandbox_file_t . # chcon -Rt svirt_sandbox_file_t ~/.cache/golangci-lint lint: + mkdir -p ~/.cache/golangci-lint/$(GOLANGCI_LINT_VERSION) $(RUNNER) run -t --rm \ -v $(shell pwd):/app \ -v ~/.cache/golangci-lint/$(GOLANGCI_LINT_VERSION):/root/.cache \ From 0106df855d280f8cce09ddc3ff74f61741337688 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Wed, 8 May 2024 18:10:36 +0100 Subject: [PATCH 121/353] CI: Switch to Makefile for running acceptance tests We can remove the 'acceptancetest' script in the process. Note that this isn't a 1:1 match: the fwaasv2 test job now runs the entire networking test suite and not just the fwaasv2-specific tests but seeing as this is using OVS rather than OVN that doesn't seem like such a bad thing. Signed-off-by: Stephen Finucane (cherry picked from commit 90cded10439a88581c9cd5afbbca206bc20c3230) --- .github/workflows/functional-baremetal.yaml | 5 ++-- .github/workflows/functional-basic.yaml | 5 ++-- .../workflows/functional-blockstorage.yaml | 5 ++-- .github/workflows/functional-compute.yaml | 5 ++-- .../workflows/functional-containerinfra.yaml | 5 ++-- .github/workflows/functional-dns.yaml | 5 ++-- .github/workflows/functional-fwaas_v2.yaml | 5 ++-- .github/workflows/functional-identity.yaml | 5 ++-- .github/workflows/functional-image.yaml | 5 ++-- .github/workflows/functional-keymanager.yaml | 5 ++-- .../workflows/functional-loadbalancer.yaml | 5 ++-- .github/workflows/functional-messaging.yaml | 5 ++-- .github/workflows/functional-networking.yaml | 5 ++-- .../workflows/functional-objectstorage.yaml | 5 ++-- .../workflows/functional-orchestration.yaml | 5 ++-- .github/workflows/functional-placement.yaml | 5 ++-- .../functional-sharedfilesystems.yaml | 5 ++-- .github/workflows/functional-workflow.yaml | 5 ++-- internal/acceptance/README.md | 8 +++++- script/acceptancetest | 26 ------------------- 20 files changed, 61 insertions(+), 63 deletions(-) delete mode 100755 script/acceptancetest diff --git a/.github/workflows/functional-baremetal.yaml b/.github/workflows/functional-baremetal.yaml index df5e4c88dc..384cc121a7 100644 --- a/.github/workflows/functional-baremetal.yaml +++ b/.github/workflows/functional-baremetal.yaml @@ -82,10 +82,11 @@ jobs: with: go-version: '^1.22' - name: Run Gophercloud acceptance tests - run: ./script/acceptancetest + run: | + source ${{ github.workspace }}/script/stackenv + make acceptance-baremetal env: DEVSTACK_PATH: ${{ github.workspace }}/devstack - PACKAGE: "./internal/acceptance/openstack/baremetal/..." OS_BRANCH: ${{ matrix.openstack_version }} USE_SYSTEM_SCOPE: true - name: Generate logs on failure diff --git a/.github/workflows/functional-basic.yaml b/.github/workflows/functional-basic.yaml index 6c3587c35d..aee751f2b9 100644 --- a/.github/workflows/functional-basic.yaml +++ b/.github/workflows/functional-basic.yaml @@ -41,10 +41,11 @@ jobs: with: go-version: '^1.22' - name: Run Gophercloud acceptance tests - run: ./script/acceptancetest + run: | + source ${{ github.workspace }}/script/stackenv + make acceptance-basic env: DEVSTACK_PATH: ${{ github.workspace }}/devstack - PACKAGE: './internal/acceptance/openstack' OS_BRANCH: ${{ matrix.openstack_version }} - name: Generate logs on failure run: ./script/collectlogs diff --git a/.github/workflows/functional-blockstorage.yaml b/.github/workflows/functional-blockstorage.yaml index f94bef2658..742ce60a7a 100644 --- a/.github/workflows/functional-blockstorage.yaml +++ b/.github/workflows/functional-blockstorage.yaml @@ -40,10 +40,11 @@ jobs: with: go-version: '^1.22' - name: Run Gophercloud acceptance tests - run: ./script/acceptancetest + run: | + source ${{ github.workspace }}/script/stackenv + make acceptance-blockstorage env: DEVSTACK_PATH: ${{ github.workspace }}/devstack - PACKAGE: "./internal/acceptance/openstack/blockstorage/..." OS_BRANCH: ${{ matrix.openstack_version }} - name: Generate logs on failure run: ./script/collectlogs diff --git a/.github/workflows/functional-compute.yaml b/.github/workflows/functional-compute.yaml index b26c82b8da..515ec9d6b7 100644 --- a/.github/workflows/functional-compute.yaml +++ b/.github/workflows/functional-compute.yaml @@ -40,10 +40,11 @@ jobs: with: go-version: '^1.22' - name: Run Gophercloud acceptance tests - run: ./script/acceptancetest + run: | + source ${{ github.workspace }}/script/stackenv + make acceptance-compute env: DEVSTACK_PATH: ${{ github.workspace }}/devstack - PACKAGE: "./internal/acceptance/openstack/compute/..." OS_BRANCH: ${{ matrix.openstack_version }} - name: Generate logs on failure run: ./script/collectlogs diff --git a/.github/workflows/functional-containerinfra.yaml b/.github/workflows/functional-containerinfra.yaml index 59da6bf1d4..ecd728690e 100644 --- a/.github/workflows/functional-containerinfra.yaml +++ b/.github/workflows/functional-containerinfra.yaml @@ -61,10 +61,11 @@ jobs: with: go-version: '^1.22' - name: Run Gophercloud acceptance tests - run: ./script/acceptancetest + run: | + source ${{ github.workspace }}/script/stackenv + make acceptance-containerinfra env: DEVSTACK_PATH: ${{ github.workspace }}/devstack - PACKAGE: "./internal/acceptance/openstack/containerinfra/..." OS_BRANCH: ${{ matrix.openstack_version }} - name: Generate logs on failure run: ./script/collectlogs diff --git a/.github/workflows/functional-dns.yaml b/.github/workflows/functional-dns.yaml index cbf27b04f0..f9a468c5cc 100644 --- a/.github/workflows/functional-dns.yaml +++ b/.github/workflows/functional-dns.yaml @@ -49,10 +49,11 @@ jobs: with: go-version: '^1.22' - name: Run Gophercloud acceptance tests - run: ./script/acceptancetest + run: | + source ${{ github.workspace }}/script/stackenv + make acceptance-dns env: DEVSTACK_PATH: ${{ github.workspace }}/devstack - PACKAGE: "./internal/acceptance/openstack/dns/..." OS_BRANCH: ${{ matrix.openstack_version }} - name: Generate logs on failure run: ./script/collectlogs diff --git a/.github/workflows/functional-fwaas_v2.yaml b/.github/workflows/functional-fwaas_v2.yaml index 880fa8994c..890d198d28 100644 --- a/.github/workflows/functional-fwaas_v2.yaml +++ b/.github/workflows/functional-fwaas_v2.yaml @@ -45,10 +45,11 @@ jobs: with: go-version: '^1.22' - name: Run Gophercloud acceptance tests - run: ./script/acceptancetest + run: | + source ${{ github.workspace }}/script/stackenv + make acceptance-networking env: DEVSTACK_PATH: ${{ github.workspace }}/devstack - PACKAGE: "./internal/acceptance/openstack/networking/v2/extensions/fwaas_v2/..." OS_BRANCH: ${{ matrix.openstack_version }} - name: Generate logs on failure run: ./script/collectlogs diff --git a/.github/workflows/functional-identity.yaml b/.github/workflows/functional-identity.yaml index 9c58e24d5a..049a3fe343 100644 --- a/.github/workflows/functional-identity.yaml +++ b/.github/workflows/functional-identity.yaml @@ -38,10 +38,11 @@ jobs: with: go-version: '^1.22' - name: Run Gophercloud acceptance tests - run: ./script/acceptancetest + run: | + source ${{ github.workspace }}/script/stackenv + make acceptance-identity env: DEVSTACK_PATH: ${{ github.workspace }}/devstack - PACKAGE: "./internal/acceptance/openstack/identity/..." OS_BRANCH: ${{ matrix.openstack_version }} - name: Generate logs on failure run: ./script/collectlogs diff --git a/.github/workflows/functional-image.yaml b/.github/workflows/functional-image.yaml index 74164ae7e1..5e506a5fd2 100644 --- a/.github/workflows/functional-image.yaml +++ b/.github/workflows/functional-image.yaml @@ -38,10 +38,11 @@ jobs: with: go-version: '^1.22' - name: Run Gophercloud acceptance tests - run: ./script/acceptancetest + run: | + source ${{ github.workspace }}/script/stackenv + make acceptance-image env: DEVSTACK_PATH: ${{ github.workspace }}/devstack - PACKAGE: "./internal/acceptance/openstack/image/..." OS_BRANCH: ${{ matrix.openstack_version }} - name: Generate logs on failure run: ./script/collectlogs diff --git a/.github/workflows/functional-keymanager.yaml b/.github/workflows/functional-keymanager.yaml index bcdbe5c614..73f1584974 100644 --- a/.github/workflows/functional-keymanager.yaml +++ b/.github/workflows/functional-keymanager.yaml @@ -48,10 +48,11 @@ jobs: with: go-version: '^1.22' - name: Run Gophercloud acceptance tests - run: ./script/acceptancetest + run: | + source ${{ github.workspace }}/script/stackenv + make acceptance-keymanager env: DEVSTACK_PATH: ${{ github.workspace }}/devstack - PACKAGE: "./internal/acceptance/openstack/keymanager/..." OS_BRANCH: ${{ matrix.openstack_version }} - name: Generate logs on failure run: ./script/collectlogs diff --git a/.github/workflows/functional-loadbalancer.yaml b/.github/workflows/functional-loadbalancer.yaml index 142a30d123..eefa3f070b 100644 --- a/.github/workflows/functional-loadbalancer.yaml +++ b/.github/workflows/functional-loadbalancer.yaml @@ -49,10 +49,11 @@ jobs: with: go-version: '^1.22' - name: Run Gophercloud acceptance tests - run: ./script/acceptancetest + run: | + source ${{ github.workspace }}/script/stackenv + make acceptance-loadbalancer env: DEVSTACK_PATH: ${{ github.workspace }}/devstack - PACKAGE: "./internal/acceptance/openstack/loadbalancer/..." OS_BRANCH: ${{ matrix.openstack_version }} - name: Generate logs on failure run: ./script/collectlogs diff --git a/.github/workflows/functional-messaging.yaml b/.github/workflows/functional-messaging.yaml index f47e6f620c..d113187e8b 100644 --- a/.github/workflows/functional-messaging.yaml +++ b/.github/workflows/functional-messaging.yaml @@ -41,10 +41,11 @@ jobs: with: go-version: '^1.22' - name: Run Gophercloud acceptance tests - run: ./script/acceptancetest + run: | + source ${{ github.workspace }}/script/stackenv + make acceptance-messaging env: DEVSTACK_PATH: ${{ github.workspace }}/devstack - PACKAGE: "./internal/acceptance/openstack/messaging/..." OS_BRANCH: ${{ matrix.openstack_version }} - name: Generate logs on failure run: ./script/collectlogs diff --git a/.github/workflows/functional-networking.yaml b/.github/workflows/functional-networking.yaml index 7127596ff7..ee4647665d 100644 --- a/.github/workflows/functional-networking.yaml +++ b/.github/workflows/functional-networking.yaml @@ -55,10 +55,11 @@ jobs: with: go-version: '^1.22' - name: Run Gophercloud acceptance tests - run: ./script/acceptancetest + run: | + source ${{ github.workspace }}/script/stackenv + make acceptance-networking env: DEVSTACK_PATH: ${{ github.workspace }}/devstack - PACKAGE: "./internal/acceptance/openstack/networking/..." OS_BRANCH: ${{ matrix.openstack_version }} - name: Generate logs on failure run: ./script/collectlogs diff --git a/.github/workflows/functional-objectstorage.yaml b/.github/workflows/functional-objectstorage.yaml index 9b98a32d3f..4ffffcd865 100644 --- a/.github/workflows/functional-objectstorage.yaml +++ b/.github/workflows/functional-objectstorage.yaml @@ -44,10 +44,11 @@ jobs: with: go-version: '^1.22' - name: Run Gophercloud acceptance tests - run: ./script/acceptancetest + run: | + source ${{ github.workspace }}/script/stackenv + make acceptance-objectstorage env: DEVSTACK_PATH: ${{ github.workspace }}/devstack - PACKAGE: "./internal/acceptance/openstack/objectstorage/..." OS_BRANCH: ${{ matrix.openstack_version }} - name: Generate logs on failure run: ./script/collectlogs diff --git a/.github/workflows/functional-orchestration.yaml b/.github/workflows/functional-orchestration.yaml index 111a1c1a86..93c35070c3 100644 --- a/.github/workflows/functional-orchestration.yaml +++ b/.github/workflows/functional-orchestration.yaml @@ -40,10 +40,11 @@ jobs: with: go-version: '^1.22' - name: Run Gophercloud acceptance tests - run: ./script/acceptancetest + run: | + source ${{ github.workspace }}/script/stackenv + make acceptance-orchestration env: DEVSTACK_PATH: ${{ github.workspace }}/devstack - PACKAGE: "./internal/acceptance/openstack/orchestration/..." OS_BRANCH: ${{ matrix.openstack_version }} - name: Generate logs on failure run: ./script/collectlogs diff --git a/.github/workflows/functional-placement.yaml b/.github/workflows/functional-placement.yaml index 261bf74200..4df23efff2 100644 --- a/.github/workflows/functional-placement.yaml +++ b/.github/workflows/functional-placement.yaml @@ -38,10 +38,11 @@ jobs: with: go-version: '^1.22' - name: Run Gophercloud acceptance tests - run: ./script/acceptancetest + run: | + source ${{ github.workspace }}/script/stackenv + make acceptance-placement env: DEVSTACK_PATH: ${{ github.workspace }}/devstack - PACKAGE: "./internal/acceptance/openstack/placement/..." OS_BRANCH: ${{ matrix.openstack_version }} - name: Generate logs on failure run: ./script/collectlogs diff --git a/.github/workflows/functional-sharedfilesystems.yaml b/.github/workflows/functional-sharedfilesystems.yaml index 75704987d7..bc817a17b7 100644 --- a/.github/workflows/functional-sharedfilesystems.yaml +++ b/.github/workflows/functional-sharedfilesystems.yaml @@ -62,10 +62,11 @@ jobs: with: go-version: '^1.22' - name: Run Gophercloud acceptance tests - run: ./script/acceptancetest + run: | + source ${{ github.workspace }}/script/stackenv + make acceptance-sharedfilesystems env: DEVSTACK_PATH: ${{ github.workspace }}/devstack - PACKAGE: "./internal/acceptance/openstack/sharedfilesystems/..." OS_BRANCH: ${{ matrix.openstack_version }} - name: Generate logs on failure run: ./script/collectlogs diff --git a/.github/workflows/functional-workflow.yaml b/.github/workflows/functional-workflow.yaml index 376cc181e8..cf4c52fb72 100644 --- a/.github/workflows/functional-workflow.yaml +++ b/.github/workflows/functional-workflow.yaml @@ -43,10 +43,11 @@ jobs: with: go-version: '^1.22' - name: Run Gophercloud acceptance tests - run: ./script/acceptancetest + run: | + source ${{ github.workspace }}/script/stackenv + make acceptance-workflow env: DEVSTACK_PATH: ${{ github.workspace }}/devstack - PACKAGE: "./internal/acceptance/openstack/workflow/..." OS_BRANCH: ${{ matrix.openstack_version }} - name: Generate logs on failure run: ./script/collectlogs diff --git a/internal/acceptance/README.md b/internal/acceptance/README.md index cbbbac7f39..febf394f10 100644 --- a/internal/acceptance/README.md +++ b/internal/acceptance/README.md @@ -91,7 +91,13 @@ to set them manually. From the root directory, run: ``` -./script/acceptancetest +make acceptance +``` + +You can also run tests for a specific service: + +``` +make acceptance-compute ``` Alternatively, add the following to your `.bashrc`: diff --git a/script/acceptancetest b/script/acceptancetest deleted file mode 100755 index 7e223bae5e..0000000000 --- a/script/acceptancetest +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/bash -# -# Run acceptance tests. - -# We intentionally don't set '-u' (error on unbound variables) or '-e' (exit on -# first failure) initially since DevStack is not designed to run with these -# flags and things crash and burn *spectacularly* 🔥🔥🔥 -set -xo pipefail - -# shellcheck disable=SC1091 -source "$(dirname "$0")/stackenv" - -# ...but we can do it after the fact -set -eu - -timeout="60m" - -LOG_DIR=${LOG_DIR:-} -if [[ -z "${LOG_DIR}" ]]; then - echo "LOG_DIR not set, will set a temp directory" - LOG_DIR=/tmp/devstack-logs -fi -mkdir -p "${LOG_DIR}" - -# shellcheck disable=SC2068 -go test -v -timeout $timeout -tags "fixtures acceptance" "${PACKAGE:-./internal/acceptance/openstack/...}" $@ |& tee -a "${LOG_DIR}/acceptance_tests.log" From 194878dc513613e1d457becfdc8fff9d37e2250c Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Tue, 28 May 2024 16:08:22 +0100 Subject: [PATCH 122/353] CI: Switch to Makefile for running linters Signed-off-by: Stephen Finucane (cherry picked from commit 641d7c128f993a7d0a43f9b8c47b509f2e413f2e) --- .github/workflows/lint.yaml | 22 +++++++++------------- script/format | 7 ------- script/vet | 8 -------- 3 files changed, 9 insertions(+), 28 deletions(-) delete mode 100755 script/format delete mode 100755 script/vet diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 665b887187..ed7399819d 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -1,27 +1,23 @@ -on: [push, pull_request] name: Linters +on: + - push + - pull_request permissions: contents: read - jobs: test: runs-on: ubuntu-latest - steps: + - name: Checkout Gophercloud + uses: actions/checkout@v4 - uses: actions/setup-go@v5 with: go-version: '1' - - - uses: actions/checkout@v4 - - - name: Run go fmt + - name: Run linters run: | - ./script/format - - - name: Run go vet - run: | - ./script/vet - + make lint + # TODO: Use 'go mod tidy -diff' instead once go 1.23 is out + # https://github.com/golang/go/issues/27005 - name: Ensure go.mod is up-to-date run: | if [ $(go mod tidy && git diff | wc -l) -gt 0 ]; then git diff && exit 1; fi diff --git a/script/format b/script/format deleted file mode 100755 index 1bbf74ce39..0000000000 --- a/script/format +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env bash -# -# Run 'go fmt' to warn about unformatted code - -set -euxo pipefail - -go fmt ./... diff --git a/script/vet b/script/vet deleted file mode 100755 index ecb74ef37d..0000000000 --- a/script/vet +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash -# -# Run go vet. - -set -euxo pipefail - -export GOFLAGS="-tags=acceptance" -go vet ./... From e951c1a0100b2faebd2855efa9f00893955fb84a Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Tue, 28 May 2024 16:13:43 +0100 Subject: [PATCH 123/353] CI: Switch to Makefile for running unit tests Conflicts: .github/workflows/unit.yaml NOTE(stephenfin): Conflicts are due to trivial spacing. Signed-off-by: Stephen Finucane (cherry picked from commit c237277801bd53071228e74903c910eaee8d82d6) --- .github/workflows/unit.yaml | 19 +++++++------------ script/coverage | 24 ------------------------ script/unittest | 10 ---------- 3 files changed, 7 insertions(+), 46 deletions(-) delete mode 100755 script/coverage delete mode 100755 script/unittest diff --git a/.github/workflows/unit.yaml b/.github/workflows/unit.yaml index 0ae498baf7..abab3a5237 100644 --- a/.github/workflows/unit.yaml +++ b/.github/workflows/unit.yaml @@ -1,8 +1,9 @@ -on: [push, pull_request] name: Unit Testing +on: + - push + - pull_request permissions: contents: read - jobs: test: permissions: @@ -15,35 +16,29 @@ jobs: go-version: - "1.22.3" - "1" - steps: + - name: Checkout Gophercloud + uses: actions/checkout@v4 - name: Setup Go ${{ matrix.go-version }} uses: actions/setup-go@v5 with: go-version: ${{ matrix.go-version }} - - - uses: actions/checkout@v4 - - name: Setup environment run: | # Changing into a different directory to avoid polluting go.sum with "go get" cd "$(mktemp -d)" go mod init unit_tests - go install github.com/alexfalkowski/gocovmerge@v1.4.0 - - name: Run unit tests run: | - ./script/coverage - ./script/unittest - + make unit + make coverage - name: Check coverage uses: coverallsapp/github-action@v2 with: file: cover.out flag-name: Go-${{ matrix.go-version }} parallel: true - finish: permissions: checks: write # for coverallsapp/github-action to create a new check based on the results diff --git a/script/coverage b/script/coverage deleted file mode 100755 index ec5b2776b8..0000000000 --- a/script/coverage +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/bash -# -# Run unit tests with coverage enabled. - -set -euxo pipefail - -n=1 -for testpkg in $(go list ./testing ./.../testing); do - covpkg="${testpkg/"/testing"/}" - go test -covermode count -coverprofile "testing_"$n.coverprofile -coverpkg "$covpkg" "$testpkg" 2>/dev/null - n=$((n+1)) -done - -base_pkg=$(go list) -# Look for additional test files -for path in $(find . -path '*/testing' -prune -o -path '*/internal' -prune -o -name '*_test.go' -exec dirname {} \; | uniq); do - pkg="${base_pkg}${path:1}" - go test -covermode count -coverprofile "testing_"$n.coverprofile -coverpkg "$pkg" "$pkg" 2>/dev/null - n=$((n+1)) -done - -# shellcheck disable=SC2046 -gocovmerge $(ls -- *.coverprofile) > cover.out -rm ./*.coverprofile diff --git a/script/unittest b/script/unittest deleted file mode 100755 index 1f1b1864f4..0000000000 --- a/script/unittest +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash -# -# Run the unit tests. - -set -euxo pipefail - -# Do extra rounds of testing to help identify reauth concurrency issues. -# All other packages are tested in the `coverage` tests. -# shellcheck disable=SC2068 -go test -v -race -count=5 ./testing $@ From e71d6720452e4ee35e784c92b9eb1791d0dcc029 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Tue, 28 May 2024 16:15:28 +0100 Subject: [PATCH 124/353] script: Remove unused script Users can use 'make unit' for this now. Signed-off-by: Stephen Finucane (cherry picked from commit 5d3669360365e02a26344e66147fdf43bc221b5a) --- script/test | 8 -------- 1 file changed, 8 deletions(-) delete mode 100755 script/test diff --git a/script/test b/script/test deleted file mode 100755 index e71e7514bb..0000000000 --- a/script/test +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash -# -# Run all the tests. - -set -euxo pipefail - -# shellcheck disable=SC2068 -go test -v -tags 'acceptance fixtures' ./... $@ From 4b982e2bb2a29580fb37c510196f27abc15dc0f6 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Wed, 4 Dec 2024 17:26:58 +0000 Subject: [PATCH 125/353] Remove workarounds for untested Ubuntu versions We no longer test on Ubuntu 20.04. Signed-off-by: Stephen Finucane (cherry picked from commit 05723996dceb14849cef43b56f402fee96e57de7) --- .github/workflows/functional-baremetal.yaml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/.github/workflows/functional-baremetal.yaml b/.github/workflows/functional-baremetal.yaml index 384cc121a7..ad04f95913 100644 --- a/.github/workflows/functional-baremetal.yaml +++ b/.github/workflows/functional-baremetal.yaml @@ -28,14 +28,6 @@ jobs: steps: - name: Checkout Gophercloud uses: actions/checkout@v4 - - name: Workaround for grub-efi-amd64-signed - run: sudo rm /var/cache/debconf/config.dat - shell: bash - if: matrix.ubuntu_version == '20.04' - - name: Ensure update and upgrade - run: sudo apt update && sudo apt -y upgrade - shell: bash - if: matrix.ubuntu_version == '20.04' - name: Work around broken dnsmasq run: sudo apt-get purge -y dnsmasq-base - name: Deploy devstack From f36037cb3c532c09e2bb3b8b5e0b0f4407d60609 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Tue, 13 May 2025 17:32:29 +0100 Subject: [PATCH 126/353] Replace errant character in workflows It's annoying that GitHub doesn't surface this error. Signed-off-by: Stephen Finucane Fixes: c4a191eea6af0d7cf6b1ff71312a0b493ba066a6 (cherry picked from commit 7c10efbf7c3b35cbbc6f650f72f4e0ee6344784d) --- .github/workflows/functional-baremetal.yaml | 2 +- .github/workflows/functional-basic.yaml | 2 +- .github/workflows/functional-blockstorage.yaml | 2 +- .github/workflows/functional-compute.yaml | 2 +- .github/workflows/functional-containerinfra.yaml | 2 +- .github/workflows/functional-dns.yaml | 2 +- .github/workflows/functional-fwaas_v2.yaml | 2 +- .github/workflows/functional-identity.yaml | 2 +- .github/workflows/functional-image.yaml | 2 +- .github/workflows/functional-keymanager.yaml | 2 +- .github/workflows/functional-loadbalancer.yaml | 2 +- .github/workflows/functional-messaging.yaml | 2 +- .github/workflows/functional-networking.yaml | 2 +- .github/workflows/functional-objectstorage.yaml | 2 +- .github/workflows/functional-orchestration.yaml | 2 +- .github/workflows/functional-placement.yaml | 2 +- .github/workflows/functional-sharedfilesystems.yaml | 2 +- .github/workflows/functional-workflow.yaml | 2 +- 18 files changed, 18 insertions(+), 18 deletions(-) diff --git a/.github/workflows/functional-baremetal.yaml b/.github/workflows/functional-baremetal.yaml index ad04f95913..19fb54fc02 100644 --- a/.github/workflows/functional-baremetal.yaml +++ b/.github/workflows/functional-baremetal.yaml @@ -31,7 +31,7 @@ jobs: - name: Work around broken dnsmasq run: sudo apt-get purge -y dnsmasq-base - name: Deploy devstack - uses: gophercloud@devstack-action@v0.17 + uses: gophercloud/devstack-action@v0.17 with: branch: ${{ matrix.openstack_version }} conf_overrides: | diff --git a/.github/workflows/functional-basic.yaml b/.github/workflows/functional-basic.yaml index aee751f2b9..80808ac181 100644 --- a/.github/workflows/functional-basic.yaml +++ b/.github/workflows/functional-basic.yaml @@ -32,7 +32,7 @@ jobs: - name: Checkout Gophercloud uses: actions/checkout@v4 - name: Deploy devstack - uses: gophercloud@devstack-action@v0.17 + uses: gophercloud/devstack-action@v0.17 with: branch: ${{ matrix.openstack_version }} enabled_services: 's-account,s-container,s-object,s-proxy,${{ matrix.additional_services }}' diff --git a/.github/workflows/functional-blockstorage.yaml b/.github/workflows/functional-blockstorage.yaml index 742ce60a7a..8ee647a364 100644 --- a/.github/workflows/functional-blockstorage.yaml +++ b/.github/workflows/functional-blockstorage.yaml @@ -29,7 +29,7 @@ jobs: - name: Checkout Gophercloud uses: actions/checkout@v4 - name: Deploy devstack - uses: gophercloud@devstack-action@v0.17 + uses: gophercloud/devstack-action@v0.17 with: branch: ${{ matrix.openstack_version }} conf_overrides: | diff --git a/.github/workflows/functional-compute.yaml b/.github/workflows/functional-compute.yaml index 515ec9d6b7..e65d553344 100644 --- a/.github/workflows/functional-compute.yaml +++ b/.github/workflows/functional-compute.yaml @@ -29,7 +29,7 @@ jobs: - name: Checkout Gophercloud uses: actions/checkout@v4 - name: Deploy devstack - uses: gophercloud@devstack-action@v0.17 + uses: gophercloud/devstack-action@v0.17 with: branch: ${{ matrix.openstack_version }} conf_overrides: | diff --git a/.github/workflows/functional-containerinfra.yaml b/.github/workflows/functional-containerinfra.yaml index ecd728690e..5a4bdbc31d 100644 --- a/.github/workflows/functional-containerinfra.yaml +++ b/.github/workflows/functional-containerinfra.yaml @@ -44,7 +44,7 @@ jobs: - name: Checkout Gophercloud uses: actions/checkout@v4 - name: Deploy devstack - uses: gophercloud@devstack-action@v0.17 + uses: gophercloud/devstack-action@v0.17 with: branch: ${{ matrix.openstack_version }} conf_overrides: | diff --git a/.github/workflows/functional-dns.yaml b/.github/workflows/functional-dns.yaml index f9a468c5cc..e95c2173ce 100644 --- a/.github/workflows/functional-dns.yaml +++ b/.github/workflows/functional-dns.yaml @@ -36,7 +36,7 @@ jobs: - name: Checkout Gophercloud uses: actions/checkout@v4 - name: Deploy devstack - uses: gophercloud@devstack-action@v0.17 + uses: gophercloud/devstack-action@v0.17 with: branch: ${{ matrix.openstack_version }} conf_overrides: | diff --git a/.github/workflows/functional-fwaas_v2.yaml b/.github/workflows/functional-fwaas_v2.yaml index 890d198d28..96dfff581a 100644 --- a/.github/workflows/functional-fwaas_v2.yaml +++ b/.github/workflows/functional-fwaas_v2.yaml @@ -29,7 +29,7 @@ jobs: - name: Checkout Gophercloud uses: actions/checkout@v4 - name: Deploy devstack - uses: gophercloud@devstack-action@v0.17 + uses: gophercloud/devstack-action@v0.17 with: branch: ${{ matrix.openstack_version }} conf_overrides: | diff --git a/.github/workflows/functional-identity.yaml b/.github/workflows/functional-identity.yaml index 049a3fe343..6bdf6a2c0b 100644 --- a/.github/workflows/functional-identity.yaml +++ b/.github/workflows/functional-identity.yaml @@ -29,7 +29,7 @@ jobs: - name: Checkout Gophercloud uses: actions/checkout@v4 - name: Deploy devstack - uses: gophercloud@devstack-action@v0.17 + uses: gophercloud/devstack-action@v0.17 with: branch: ${{ matrix.openstack_version }} enabled_services: "${{ matrix.additional_services }}" diff --git a/.github/workflows/functional-image.yaml b/.github/workflows/functional-image.yaml index 5e506a5fd2..d4f7e0e4f1 100644 --- a/.github/workflows/functional-image.yaml +++ b/.github/workflows/functional-image.yaml @@ -29,7 +29,7 @@ jobs: - name: Checkout Gophercloud uses: actions/checkout@v4 - name: Deploy devstack - uses: gophercloud@devstack-action@v0.17 + uses: gophercloud/devstack-action@v0.17 with: branch: ${{ matrix.openstack_version }} enabled_services: "${{ matrix.additional_services }}" diff --git a/.github/workflows/functional-keymanager.yaml b/.github/workflows/functional-keymanager.yaml index 73f1584974..96a653d421 100644 --- a/.github/workflows/functional-keymanager.yaml +++ b/.github/workflows/functional-keymanager.yaml @@ -35,7 +35,7 @@ jobs: - name: Checkout Gophercloud uses: actions/checkout@v4 - name: Deploy devstack - uses: gophercloud@devstack-action@v0.17 + uses: gophercloud/devstack-action@v0.17 with: branch: ${{ matrix.openstack_version }} conf_overrides: | diff --git a/.github/workflows/functional-loadbalancer.yaml b/.github/workflows/functional-loadbalancer.yaml index eefa3f070b..6145d10c25 100644 --- a/.github/workflows/functional-loadbalancer.yaml +++ b/.github/workflows/functional-loadbalancer.yaml @@ -35,7 +35,7 @@ jobs: - name: Checkout Gophercloud uses: actions/checkout@v4 - name: Deploy devstack - uses: gophercloud@devstack-action@v0.17 + uses: gophercloud/devstack-action@v0.17 with: branch: ${{ matrix.openstack_version }} conf_overrides: | diff --git a/.github/workflows/functional-messaging.yaml b/.github/workflows/functional-messaging.yaml index d113187e8b..b007942410 100644 --- a/.github/workflows/functional-messaging.yaml +++ b/.github/workflows/functional-messaging.yaml @@ -29,7 +29,7 @@ jobs: - name: Checkout Gophercloud uses: actions/checkout@v4 - name: Deploy devstack - uses: gophercloud@devstack-action@v0.17 + uses: gophercloud/devstack-action@v0.17 with: branch: ${{ matrix.openstack_version }} conf_overrides: | diff --git a/.github/workflows/functional-networking.yaml b/.github/workflows/functional-networking.yaml index ee4647665d..c4cd4a149c 100644 --- a/.github/workflows/functional-networking.yaml +++ b/.github/workflows/functional-networking.yaml @@ -37,7 +37,7 @@ jobs: "update_port:binding:profile": "rule:admin_only or rule:service_api" EOF - name: Deploy devstack - uses: gophercloud@devstack-action@v0.17 + uses: gophercloud/devstack-action@v0.17 with: branch: ${{ matrix.openstack_version }} conf_overrides: | diff --git a/.github/workflows/functional-objectstorage.yaml b/.github/workflows/functional-objectstorage.yaml index 4ffffcd865..0e31102a7d 100644 --- a/.github/workflows/functional-objectstorage.yaml +++ b/.github/workflows/functional-objectstorage.yaml @@ -29,7 +29,7 @@ jobs: - name: Checkout Gophercloud uses: actions/checkout@v4 - name: Deploy devstack - uses: gophercloud@devstack-action@v0.17 + uses: gophercloud/devstack-action@v0.17 with: branch: ${{ matrix.openstack_version }} conf_overrides: | diff --git a/.github/workflows/functional-orchestration.yaml b/.github/workflows/functional-orchestration.yaml index 93c35070c3..8ee464602d 100644 --- a/.github/workflows/functional-orchestration.yaml +++ b/.github/workflows/functional-orchestration.yaml @@ -29,7 +29,7 @@ jobs: - name: Checkout Gophercloud uses: actions/checkout@v4 - name: Deploy devstack - uses: gophercloud@devstack-action@v0.17 + uses: gophercloud/devstack-action@v0.17 with: branch: ${{ matrix.openstack_version }} conf_overrides: | diff --git a/.github/workflows/functional-placement.yaml b/.github/workflows/functional-placement.yaml index 4df23efff2..6afb44a0c1 100644 --- a/.github/workflows/functional-placement.yaml +++ b/.github/workflows/functional-placement.yaml @@ -29,7 +29,7 @@ jobs: - name: Checkout Gophercloud uses: actions/checkout@v4 - name: Deploy devstack - uses: gophercloud@devstack-action@v0.17 + uses: gophercloud/devstack-action@v0.17 with: branch: ${{ matrix.openstack_version }} enabled_services: "${{ matrix.additional_services }}" diff --git a/.github/workflows/functional-sharedfilesystems.yaml b/.github/workflows/functional-sharedfilesystems.yaml index bc817a17b7..cf737ac368 100644 --- a/.github/workflows/functional-sharedfilesystems.yaml +++ b/.github/workflows/functional-sharedfilesystems.yaml @@ -35,7 +35,7 @@ jobs: - name: Checkout Gophercloud uses: actions/checkout@v4 - name: Deploy devstack - uses: gophercloud@devstack-action@v0.17 + uses: gophercloud/devstack-action@v0.17 with: branch: ${{ matrix.openstack_version }} conf_overrides: | diff --git a/.github/workflows/functional-workflow.yaml b/.github/workflows/functional-workflow.yaml index cf4c52fb72..62f2af2698 100644 --- a/.github/workflows/functional-workflow.yaml +++ b/.github/workflows/functional-workflow.yaml @@ -32,7 +32,7 @@ jobs: - name: Checkout Gophercloud uses: actions/checkout@v4 - name: Deploy devstack - uses: gophercloud@devstack-action@v0.17 + uses: gophercloud/devstack-action@v0.17 with: branch: ${{ matrix.openstack_version }} conf_overrides: | From b113a13593f9c6d710fddae260af35b55866752b Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Tue, 13 May 2025 17:02:29 +0100 Subject: [PATCH 127/353] Run functional tests if workflow changes Signed-off-by: Stephen Finucane (cherry picked from commit 69b54462666840df025cdee8dfd76bfda4fddd81) --- .github/workflows/functional-baremetal.yaml | 1 + .github/workflows/functional-blockstorage.yaml | 1 + .github/workflows/functional-compute.yaml | 1 + .github/workflows/functional-containerinfra.yaml | 1 + .github/workflows/functional-dns.yaml | 4 ++-- .github/workflows/functional-fwaas_v2.yaml | 1 + .github/workflows/functional-identity.yaml | 1 + .github/workflows/functional-image.yaml | 1 + .github/workflows/functional-keymanager.yaml | 1 + .github/workflows/functional-loadbalancer.yaml | 1 + .github/workflows/functional-messaging.yaml | 1 + .github/workflows/functional-networking.yaml | 1 + .github/workflows/functional-objectstorage.yaml | 1 + .github/workflows/functional-orchestration.yaml | 1 + .github/workflows/functional-placement.yaml | 1 + .github/workflows/functional-sharedfilesystems.yaml | 1 + .github/workflows/functional-workflow.yaml | 1 + 17 files changed, 18 insertions(+), 2 deletions(-) diff --git a/.github/workflows/functional-baremetal.yaml b/.github/workflows/functional-baremetal.yaml index 19fb54fc02..eb04f8c920 100644 --- a/.github/workflows/functional-baremetal.yaml +++ b/.github/workflows/functional-baremetal.yaml @@ -3,6 +3,7 @@ on: pull_request: paths: - '**baremetal**' + - '.github/workflows/functional-baremetal.yaml' schedule: - cron: '0 0 */3 * *' jobs: diff --git a/.github/workflows/functional-blockstorage.yaml b/.github/workflows/functional-blockstorage.yaml index 8ee647a364..1a36b0da04 100644 --- a/.github/workflows/functional-blockstorage.yaml +++ b/.github/workflows/functional-blockstorage.yaml @@ -3,6 +3,7 @@ on: pull_request: paths: - '**blockstorage**' + - '.github/workflows/functional-blockstorage.yaml' schedule: - cron: '0 0 */3 * *' jobs: diff --git a/.github/workflows/functional-compute.yaml b/.github/workflows/functional-compute.yaml index e65d553344..87f0ef7e67 100644 --- a/.github/workflows/functional-compute.yaml +++ b/.github/workflows/functional-compute.yaml @@ -3,6 +3,7 @@ on: pull_request: paths: - '**compute**' + - '.github/workflows/functional-compute.yaml' schedule: - cron: '0 0 */3 * *' jobs: diff --git a/.github/workflows/functional-containerinfra.yaml b/.github/workflows/functional-containerinfra.yaml index 5a4bdbc31d..ad3c275b66 100644 --- a/.github/workflows/functional-containerinfra.yaml +++ b/.github/workflows/functional-containerinfra.yaml @@ -3,6 +3,7 @@ on: pull_request: paths: - '**containerinfra**' + - '.github/workflows/functional-containerinfra.yaml' schedule: - cron: '0 0 */3 * *' jobs: diff --git a/.github/workflows/functional-dns.yaml b/.github/workflows/functional-dns.yaml index e95c2173ce..43e8123cc0 100644 --- a/.github/workflows/functional-dns.yaml +++ b/.github/workflows/functional-dns.yaml @@ -2,8 +2,8 @@ name: functional-dns on: pull_request: paths: - - '**openstack/dns**' - - '**functional-dns.yaml' + - '**dns**' + - '.github/workflows/functional-dns.yaml' schedule: - cron: '0 0 */3 * *' jobs: diff --git a/.github/workflows/functional-fwaas_v2.yaml b/.github/workflows/functional-fwaas_v2.yaml index 96dfff581a..f715da56a9 100644 --- a/.github/workflows/functional-fwaas_v2.yaml +++ b/.github/workflows/functional-fwaas_v2.yaml @@ -3,6 +3,7 @@ on: pull_request: paths: - '**networking/v2/extensions/fwaas_v2**' + - '.github/workflows/functional-fwaas_v2.yaml' schedule: - cron: '0 0 */3 * *' jobs: diff --git a/.github/workflows/functional-identity.yaml b/.github/workflows/functional-identity.yaml index 6bdf6a2c0b..d3cb23f02c 100644 --- a/.github/workflows/functional-identity.yaml +++ b/.github/workflows/functional-identity.yaml @@ -3,6 +3,7 @@ on: pull_request: paths: - '**identity**' + - '.github/workflows/functional-identity.yaml' schedule: - cron: '0 0 */3 * *' jobs: diff --git a/.github/workflows/functional-image.yaml b/.github/workflows/functional-image.yaml index d4f7e0e4f1..26579dd4e7 100644 --- a/.github/workflows/functional-image.yaml +++ b/.github/workflows/functional-image.yaml @@ -3,6 +3,7 @@ on: pull_request: paths: - '**image**' + - '.github/workflows/functional-image.yaml' schedule: - cron: '0 0 */3 * *' jobs: diff --git a/.github/workflows/functional-keymanager.yaml b/.github/workflows/functional-keymanager.yaml index 96a653d421..099939e5a3 100644 --- a/.github/workflows/functional-keymanager.yaml +++ b/.github/workflows/functional-keymanager.yaml @@ -3,6 +3,7 @@ on: pull_request: paths: - '**keymanager**' + - '.github/workflows/functional-keymanager.yaml' schedule: - cron: '0 0 */3 * *' jobs: diff --git a/.github/workflows/functional-loadbalancer.yaml b/.github/workflows/functional-loadbalancer.yaml index 6145d10c25..6b720aecac 100644 --- a/.github/workflows/functional-loadbalancer.yaml +++ b/.github/workflows/functional-loadbalancer.yaml @@ -3,6 +3,7 @@ on: pull_request: paths: - '**loadbalancer**' + - '.github/workflows/functional-loadbalancer.yaml' schedule: - cron: '0 0 */3 * *' jobs: diff --git a/.github/workflows/functional-messaging.yaml b/.github/workflows/functional-messaging.yaml index b007942410..0ddb5f1efd 100644 --- a/.github/workflows/functional-messaging.yaml +++ b/.github/workflows/functional-messaging.yaml @@ -3,6 +3,7 @@ on: pull_request: paths: - '**messaging**' + - '.github/workflows/functional-messaging.yaml' schedule: - cron: '0 0 */3 * *' jobs: diff --git a/.github/workflows/functional-networking.yaml b/.github/workflows/functional-networking.yaml index c4cd4a149c..a0608a2b98 100644 --- a/.github/workflows/functional-networking.yaml +++ b/.github/workflows/functional-networking.yaml @@ -3,6 +3,7 @@ on: pull_request: paths: - '**networking**' + - '.github/workflows/functional-networking.yaml' schedule: - cron: '0 0 */3 * *' jobs: diff --git a/.github/workflows/functional-objectstorage.yaml b/.github/workflows/functional-objectstorage.yaml index 0e31102a7d..b22f5ef454 100644 --- a/.github/workflows/functional-objectstorage.yaml +++ b/.github/workflows/functional-objectstorage.yaml @@ -3,6 +3,7 @@ on: pull_request: paths: - '**objectstorage**' + - '.github/workflows/functional-objectstorage.yaml' schedule: - cron: '0 0 */3 * *' jobs: diff --git a/.github/workflows/functional-orchestration.yaml b/.github/workflows/functional-orchestration.yaml index 8ee464602d..a301e45688 100644 --- a/.github/workflows/functional-orchestration.yaml +++ b/.github/workflows/functional-orchestration.yaml @@ -3,6 +3,7 @@ on: pull_request: paths: - '**orchestration**' + - '.github/workflows/functional-orchestration.yaml' schedule: - cron: '0 0 */3 * *' jobs: diff --git a/.github/workflows/functional-placement.yaml b/.github/workflows/functional-placement.yaml index 6afb44a0c1..c6356e95e2 100644 --- a/.github/workflows/functional-placement.yaml +++ b/.github/workflows/functional-placement.yaml @@ -3,6 +3,7 @@ on: pull_request: paths: - '**placement**' + - '.github/workflows/functional-placement.yaml' schedule: - cron: '0 0 */3 * *' jobs: diff --git a/.github/workflows/functional-sharedfilesystems.yaml b/.github/workflows/functional-sharedfilesystems.yaml index cf737ac368..08aca0f0e8 100644 --- a/.github/workflows/functional-sharedfilesystems.yaml +++ b/.github/workflows/functional-sharedfilesystems.yaml @@ -3,6 +3,7 @@ on: pull_request: paths: - '**sharedfilesystems**' + - '.github/workflows/functional-sharedfilesystems.yaml' schedule: - cron: '0 0 */3 * *' jobs: diff --git a/.github/workflows/functional-workflow.yaml b/.github/workflows/functional-workflow.yaml index 62f2af2698..d4d389581b 100644 --- a/.github/workflows/functional-workflow.yaml +++ b/.github/workflows/functional-workflow.yaml @@ -3,6 +3,7 @@ on: pull_request: paths: - '**workflow**' + - '.github/workflows/functional-workflow.yaml' schedule: - cron: '0 0 */3 * *' jobs: From 243570027ee37c2dca463c6b71e631a986143171 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Wed, 7 May 2025 11:11:12 +0100 Subject: [PATCH 128/353] tests: Devolve acceptance test conditions Place service-specific conditions in service-specific locations. We also removed the now-unused RequireNovaNetwork helper. Conflicts: internal/acceptance/openstack/baremetal/httpbasic/portgroups_test.go NOTE(stephenfin): Conflicts are because the file doesn't exist on the v2 branch (yet) Signed-off-by: Stephen Finucane (cherry picked from commit 2a22f9d7af83e3a8d284a4815a527df16ae1d799) --- internal/acceptance/clients/conditions.go | 97 +++---------------- .../baremetal/httpbasic/allocations_test.go | 2 +- .../baremetal/httpbasic/conditions.go | 14 +++ .../baremetal/httpbasic/nodes_test.go | 8 +- .../baremetal/httpbasic/ports_test.go | 4 +- .../baremetal/noauth/allocations_test.go | 2 +- .../openstack/baremetal/noauth/conditions.go | 15 +++ .../openstack/baremetal/noauth/nodes_test.go | 6 +- .../openstack/baremetal/noauth/ports_test.go | 4 +- .../blockstorage/noauth/conditions.go | 14 +++ .../blockstorage/noauth/snapshots_test.go | 4 +- .../blockstorage/noauth/volumes_test.go | 4 +- .../openstack/compute/v2/conditions.go | 22 +++++ .../openstack/compute/v2/migrate_test.go | 2 +- .../openstack/compute/v2/servers_test.go | 2 +- .../openstack/identity/v2/conditions.go | 14 +++ .../openstack/identity/v2/extension_test.go | 4 +- .../openstack/identity/v2/role_test.go | 4 +- .../openstack/identity/v2/tenant_test.go | 4 +- .../openstack/identity/v2/token_test.go | 4 +- .../openstack/identity/v2/user_test.go | 4 +- .../openstack/networking/v2/conditions.go | 9 ++ .../extensions/layer3/portforwardings_test.go | 2 +- .../sharedfilesystems/v2/conditions.go | 14 +++ .../sharedfilesystems/v2/replicas_test.go | 12 +-- 25 files changed, 151 insertions(+), 120 deletions(-) create mode 100644 internal/acceptance/openstack/baremetal/httpbasic/conditions.go create mode 100644 internal/acceptance/openstack/baremetal/noauth/conditions.go create mode 100644 internal/acceptance/openstack/blockstorage/noauth/conditions.go create mode 100644 internal/acceptance/openstack/compute/v2/conditions.go create mode 100644 internal/acceptance/openstack/identity/v2/conditions.go create mode 100644 internal/acceptance/openstack/sharedfilesystems/v2/conditions.go diff --git a/internal/acceptance/clients/conditions.go b/internal/acceptance/clients/conditions.go index c48ac208a9..6077f4bdef 100644 --- a/internal/acceptance/clients/conditions.go +++ b/internal/acceptance/clients/conditions.go @@ -14,14 +14,6 @@ func RequiredSystemScope(t *testing.T) { } } -// RequireManilaReplicas will restrict a test to only be run with enabled -// manila replicas. -func RequireManilaReplicas(t *testing.T) { - if os.Getenv("OS_MANILA_REPLICAS") != "true" { - t.Skip("manila replicas must be enabled to run this test") - } -} - // RequireAdmin will restrict a test to only be run by admin users. func RequireAdmin(t *testing.T) { if os.Getenv("OS_USERNAME") != "admin" { @@ -36,38 +28,6 @@ func RequireNonAdmin(t *testing.T) { } } -// RequirePortForwarding will restrict a test to only be run in environments -// that support port forwarding -func RequirePortForwarding(t *testing.T) { - if os.Getenv("OS_PORTFORWARDING_ENVIRONMENT") == "" { - t.Skip("this test requires support for port forwarding") - } -} - -// RequireGuestAgent will restrict a test to only be run in -// environments that support the QEMU guest agent. -func RequireGuestAgent(t *testing.T) { - if os.Getenv("OS_GUEST_AGENT") == "" { - t.Skip("this test requires support for qemu guest agent and to set OS_GUEST_AGENT to 1") - } -} - -// RequireIdentityV2 will restrict a test to only be run in -// environments that support the Identity V2 API. -func RequireIdentityV2(t *testing.T) { - if os.Getenv("OS_IDENTITY_API_VERSION") != "2.0" { - t.Skip("this test requires support for the identity v2 API") - } -} - -// RequireLiveMigration will restrict a test to only be run in -// environments that support live migration. -func RequireLiveMigration(t *testing.T) { - if os.Getenv("OS_LIVE_MIGRATE") == "" { - t.Skip("this test requires support for live migration and to set OS_LIVE_MIGRATE to 1") - } -} - // RequireLong will ensure long-running tests can run. func RequireLong(t *testing.T) { if testing.Short() { @@ -75,38 +35,6 @@ func RequireLong(t *testing.T) { } } -// RequireNovaNetwork will restrict a test to only be run in -// environments that support nova-network. -func RequireNovaNetwork(t *testing.T) { - if os.Getenv("OS_NOVANET") == "" { - t.Skip("this test requires nova-network and to set OS_NOVANET to 1") - } -} - -// RequireCinderNoAuth will restrict a test to be only run in environments that -// have Cinder using noauth. -func RequireCinderNoAuth(t *testing.T) { - if os.Getenv("CINDER_ENDPOINT") == "" || os.Getenv("OS_USERNAME") == "" { - t.Skip("this test requires Cinder using noauth, set OS_USERNAME and CINDER_ENDPOINT") - } -} - -// RequireIronicNoAuth will restrict a test to be only run in environments that -// have Ironic using noauth. -func RequireIronicNoAuth(t *testing.T) { - if os.Getenv("IRONIC_ENDPOINT") == "" || os.Getenv("OS_USERNAME") == "" { - t.Skip("this test requires IRONIC using noauth, set OS_USERNAME and IRONIC_ENDPOINT") - } -} - -// RequireIronicHTTPBasic will restrict a test to be only run in environments -// that have Ironic using http_basic. -func RequireIronicHTTPBasic(t *testing.T) { - if os.Getenv("IRONIC_ENDPOINT") == "" || os.Getenv("OS_USERNAME") == "" || os.Getenv("OS_PASSWORD") == "" { - t.Skip("this test requires Ironic using http_basic, set OS_USERNAME, OS_PASSWORD and IRONIC_ENDPOINT") - } -} - func getReleaseFromEnv(t *testing.T) string { current := strings.TrimPrefix(os.Getenv("OS_BRANCH"), "stable/") if current == "" { @@ -115,8 +43,8 @@ func getReleaseFromEnv(t *testing.T) string { return current } -// SkipRelease will have the test be skipped on a certain -// release. Releases are named such as 'stable/mitaka', master, etc. +// SkipRelease will have the test be skipped on a certain release. +// Releases are named such as 'stable/dalmatian', master, etc. func SkipRelease(t *testing.T, release string) { current := getReleaseFromEnv(t) if current == strings.TrimPrefix(release, "stable/") { @@ -124,8 +52,8 @@ func SkipRelease(t *testing.T, release string) { } } -// SkipReleasesBelow will have the test be skipped on releases below a certain -// one. Releases are named such as 'stable/mitaka', master, etc. +// SkipReleasesBelow will have the test be skipped on releases below a certain one. +// Releases are named such as 'stable/dalmatian', master, etc. func SkipReleasesBelow(t *testing.T, release string) { current := getReleaseFromEnv(t) @@ -134,9 +62,9 @@ func SkipReleasesBelow(t *testing.T, release string) { } } -// SkipReleasesAbove will have the test be skipped on releases above a certain -// one. The test is always skipped on master release. Releases are named such -// as 'stable/mitaka', master, etc. +// SkipReleasesAbove will have the test be skipped on releases above a certain one. +// The test is always skipped on master release. +// Releases are named such as 'stable/dalmatian', master, etc. func SkipReleasesAbove(t *testing.T, release string) { current := getReleaseFromEnv(t) @@ -150,9 +78,9 @@ func isReleaseNumeral(release string) bool { return err == nil } -// IsCurrentAbove will return true on releases above a certain -// one. The result is always true on master release. Releases are named such -// as 'stable/mitaka', master, etc. +// IsCurrentAbove will return true on releases above a certain one. +// The result is always true on master release. +// Releases are named such as 'stable/dalmatian', master, etc. func IsCurrentAbove(t *testing.T, release string) bool { current := getReleaseFromEnv(t) release = strings.TrimPrefix(release, "stable/") @@ -174,8 +102,9 @@ func IsCurrentAbove(t *testing.T, release string) bool { return false } -// IsCurrentBelow will return true on releases below a certain -// one. Releases are named such as 'stable/mitaka', master, etc. +// IsCurrentBelow will return true on releases below a certain one. +// The result is always false on master release. +// Releases are named such as 'stable/dalmatian', master, etc. func IsCurrentBelow(t *testing.T, release string) bool { current := getReleaseFromEnv(t) release = strings.TrimPrefix(release, "stable/") diff --git a/internal/acceptance/openstack/baremetal/httpbasic/allocations_test.go b/internal/acceptance/openstack/baremetal/httpbasic/allocations_test.go index 932c067ad0..faa667d05b 100644 --- a/internal/acceptance/openstack/baremetal/httpbasic/allocations_test.go +++ b/internal/acceptance/openstack/baremetal/httpbasic/allocations_test.go @@ -15,7 +15,7 @@ import ( func TestAllocationsCreateDestroy(t *testing.T) { clients.RequireLong(t) - clients.RequireIronicHTTPBasic(t) + RequireIronicHTTPBasic(t) client, err := clients.NewBareMetalV1HTTPBasic() th.AssertNoErr(t, err) diff --git a/internal/acceptance/openstack/baremetal/httpbasic/conditions.go b/internal/acceptance/openstack/baremetal/httpbasic/conditions.go new file mode 100644 index 0000000000..15d1c9f724 --- /dev/null +++ b/internal/acceptance/openstack/baremetal/httpbasic/conditions.go @@ -0,0 +1,14 @@ +package httpbasic + +import ( + "os" + "testing" +) + +// RequireIronicHTTPBasic will restrict a test to be only run in environments +// that have Ironic using http_basic. +func RequireIronicHTTPBasic(t *testing.T) { + if os.Getenv("IRONIC_ENDPOINT") == "" || os.Getenv("OS_USERNAME") == "" || os.Getenv("OS_PASSWORD") == "" { + t.Skip("this test requires Ironic using http_basic, set OS_USERNAME, OS_PASSWORD and IRONIC_ENDPOINT") + } +} diff --git a/internal/acceptance/openstack/baremetal/httpbasic/nodes_test.go b/internal/acceptance/openstack/baremetal/httpbasic/nodes_test.go index e35ae1e25a..a0c656d7f7 100644 --- a/internal/acceptance/openstack/baremetal/httpbasic/nodes_test.go +++ b/internal/acceptance/openstack/baremetal/httpbasic/nodes_test.go @@ -16,7 +16,7 @@ import ( func TestNodesCreateDestroy(t *testing.T) { clients.RequireLong(t) - clients.RequireIronicHTTPBasic(t) + RequireIronicHTTPBasic(t) client, err := clients.NewBareMetalV1HTTPBasic() th.AssertNoErr(t, err) @@ -49,7 +49,7 @@ func TestNodesCreateDestroy(t *testing.T) { func TestNodesUpdate(t *testing.T) { clients.RequireLong(t) - clients.RequireIronicHTTPBasic(t) + RequireIronicHTTPBasic(t) client, err := clients.NewBareMetalV1HTTPBasic() th.AssertNoErr(t, err) @@ -74,7 +74,7 @@ func TestNodesUpdate(t *testing.T) { func TestNodesRAIDConfig(t *testing.T) { clients.SkipReleasesBelow(t, "stable/ussuri") clients.RequireLong(t) - clients.RequireIronicHTTPBasic(t) + RequireIronicHTTPBasic(t) client, err := clients.NewBareMetalV1HTTPBasic() th.AssertNoErr(t, err) @@ -104,7 +104,7 @@ func TestNodesRAIDConfig(t *testing.T) { func TestNodesFirmwareInterface(t *testing.T) { clients.SkipReleasesBelow(t, "stable/2023.2") clients.RequireLong(t) - clients.RequireIronicHTTPBasic(t) + RequireIronicHTTPBasic(t) client, err := clients.NewBareMetalV1HTTPBasic() th.AssertNoErr(t, err) diff --git a/internal/acceptance/openstack/baremetal/httpbasic/ports_test.go b/internal/acceptance/openstack/baremetal/httpbasic/ports_test.go index 9912c49322..7773f8b23e 100644 --- a/internal/acceptance/openstack/baremetal/httpbasic/ports_test.go +++ b/internal/acceptance/openstack/baremetal/httpbasic/ports_test.go @@ -16,7 +16,7 @@ import ( func TestPortsCreateDestroy(t *testing.T) { clients.RequireLong(t) - clients.RequireIronicHTTPBasic(t) + RequireIronicHTTPBasic(t) client, err := clients.NewBareMetalV1HTTPBasic() th.AssertNoErr(t, err) @@ -52,7 +52,7 @@ func TestPortsCreateDestroy(t *testing.T) { func TestPortsUpdate(t *testing.T) { clients.RequireLong(t) - clients.RequireIronicHTTPBasic(t) + RequireIronicHTTPBasic(t) client, err := clients.NewBareMetalV1HTTPBasic() th.AssertNoErr(t, err) diff --git a/internal/acceptance/openstack/baremetal/noauth/allocations_test.go b/internal/acceptance/openstack/baremetal/noauth/allocations_test.go index e6cb33ac3d..d0b34737c5 100644 --- a/internal/acceptance/openstack/baremetal/noauth/allocations_test.go +++ b/internal/acceptance/openstack/baremetal/noauth/allocations_test.go @@ -15,7 +15,7 @@ import ( func TestAllocationsCreateDestroy(t *testing.T) { clients.RequireLong(t) - clients.RequireIronicNoAuth(t) + RequireIronicNoAuth(t) client, err := clients.NewBareMetalV1NoAuthClient() th.AssertNoErr(t, err) diff --git a/internal/acceptance/openstack/baremetal/noauth/conditions.go b/internal/acceptance/openstack/baremetal/noauth/conditions.go new file mode 100644 index 0000000000..762f141f52 --- /dev/null +++ b/internal/acceptance/openstack/baremetal/noauth/conditions.go @@ -0,0 +1,15 @@ +package noauth + +import ( + "os" + "testing" +) + +// RequireIronicNoAuth will restrict a test to be only run in environments that + +// have Ironic using noauth. +func RequireIronicNoAuth(t *testing.T) { + if os.Getenv("IRONIC_ENDPOINT") == "" || os.Getenv("OS_USERNAME") == "" { + t.Skip("this test requires IRONIC using noauth, set OS_USERNAME and IRONIC_ENDPOINT") + } +} diff --git a/internal/acceptance/openstack/baremetal/noauth/nodes_test.go b/internal/acceptance/openstack/baremetal/noauth/nodes_test.go index bd05203b2e..64b9826a03 100644 --- a/internal/acceptance/openstack/baremetal/noauth/nodes_test.go +++ b/internal/acceptance/openstack/baremetal/noauth/nodes_test.go @@ -16,7 +16,7 @@ import ( func TestNodesCreateDestroy(t *testing.T) { clients.RequireLong(t) - clients.RequireIronicNoAuth(t) + RequireIronicNoAuth(t) client, err := clients.NewBareMetalV1NoAuthClient() th.AssertNoErr(t, err) @@ -49,7 +49,7 @@ func TestNodesCreateDestroy(t *testing.T) { func TestNodesUpdate(t *testing.T) { clients.RequireLong(t) - clients.RequireIronicNoAuth(t) + RequireIronicNoAuth(t) client, err := clients.NewBareMetalV1NoAuthClient() th.AssertNoErr(t, err) @@ -74,7 +74,7 @@ func TestNodesUpdate(t *testing.T) { func TestNodesRAIDConfig(t *testing.T) { clients.SkipReleasesBelow(t, "stable/ussuri") clients.RequireLong(t) - clients.RequireIronicNoAuth(t) + RequireIronicNoAuth(t) client, err := clients.NewBareMetalV1NoAuthClient() th.AssertNoErr(t, err) diff --git a/internal/acceptance/openstack/baremetal/noauth/ports_test.go b/internal/acceptance/openstack/baremetal/noauth/ports_test.go index 980b2dec32..3f10b3b85c 100644 --- a/internal/acceptance/openstack/baremetal/noauth/ports_test.go +++ b/internal/acceptance/openstack/baremetal/noauth/ports_test.go @@ -16,7 +16,7 @@ import ( func TestPortsCreateDestroy(t *testing.T) { clients.RequireLong(t) - clients.RequireIronicNoAuth(t) + RequireIronicNoAuth(t) client, err := clients.NewBareMetalV1NoAuthClient() th.AssertNoErr(t, err) @@ -52,7 +52,7 @@ func TestPortsCreateDestroy(t *testing.T) { func TestPortsUpdate(t *testing.T) { clients.RequireLong(t) - clients.RequireIronicNoAuth(t) + RequireIronicNoAuth(t) client, err := clients.NewBareMetalV1NoAuthClient() th.AssertNoErr(t, err) diff --git a/internal/acceptance/openstack/blockstorage/noauth/conditions.go b/internal/acceptance/openstack/blockstorage/noauth/conditions.go new file mode 100644 index 0000000000..b1fd42e3bb --- /dev/null +++ b/internal/acceptance/openstack/blockstorage/noauth/conditions.go @@ -0,0 +1,14 @@ +package noauth + +import ( + "os" + "testing" +) + +// RequireCinderNoAuth will restrict a test to be only run in environments that +// have Cinder using noauth. +func RequireCinderNoAuth(t *testing.T) { + if os.Getenv("CINDER_ENDPOINT") == "" || os.Getenv("OS_USERNAME") == "" { + t.Skip("this test requires Cinder using noauth, set OS_USERNAME and CINDER_ENDPOINT") + } +} diff --git a/internal/acceptance/openstack/blockstorage/noauth/snapshots_test.go b/internal/acceptance/openstack/blockstorage/noauth/snapshots_test.go index 5b8bb2a982..f1daa352eb 100644 --- a/internal/acceptance/openstack/blockstorage/noauth/snapshots_test.go +++ b/internal/acceptance/openstack/blockstorage/noauth/snapshots_test.go @@ -12,7 +12,7 @@ import ( ) func TestSnapshotsList(t *testing.T) { - clients.RequireCinderNoAuth(t) + RequireCinderNoAuth(t) client, err := clients.NewBlockStorageV3NoAuthClient() if err != nil { @@ -35,7 +35,7 @@ func TestSnapshotsList(t *testing.T) { } func TestSnapshotsCreateDelete(t *testing.T) { - clients.RequireCinderNoAuth(t) + RequireCinderNoAuth(t) client, err := clients.NewBlockStorageV3NoAuthClient() if err != nil { diff --git a/internal/acceptance/openstack/blockstorage/noauth/volumes_test.go b/internal/acceptance/openstack/blockstorage/noauth/volumes_test.go index 0c993addad..15d4815426 100644 --- a/internal/acceptance/openstack/blockstorage/noauth/volumes_test.go +++ b/internal/acceptance/openstack/blockstorage/noauth/volumes_test.go @@ -12,7 +12,7 @@ import ( ) func TestVolumesList(t *testing.T) { - clients.RequireCinderNoAuth(t) + RequireCinderNoAuth(t) client, err := clients.NewBlockStorageV3NoAuthClient() if err != nil { @@ -35,7 +35,7 @@ func TestVolumesList(t *testing.T) { } func TestVolumesCreateDestroy(t *testing.T) { - clients.RequireCinderNoAuth(t) + RequireCinderNoAuth(t) client, err := clients.NewBlockStorageV3NoAuthClient() if err != nil { diff --git a/internal/acceptance/openstack/compute/v2/conditions.go b/internal/acceptance/openstack/compute/v2/conditions.go new file mode 100644 index 0000000000..565a3e1cfe --- /dev/null +++ b/internal/acceptance/openstack/compute/v2/conditions.go @@ -0,0 +1,22 @@ +package v2 + +import ( + "os" + "testing" +) + +// RequireGuestAgent will restrict a test to only be run in +// environments that support the QEMU guest agent. +func RequireGuestAgent(t *testing.T) { + if os.Getenv("OS_GUEST_AGENT") == "" { + t.Skip("this test requires support for qemu guest agent and to set OS_GUEST_AGENT to 1") + } +} + +// RequireLiveMigration will restrict a test to only be run in +// environments that support live migration. +func RequireLiveMigration(t *testing.T) { + if os.Getenv("OS_LIVE_MIGRATE") == "" { + t.Skip("this test requires support for live migration and to set OS_LIVE_MIGRATE to 1") + } +} diff --git a/internal/acceptance/openstack/compute/v2/migrate_test.go b/internal/acceptance/openstack/compute/v2/migrate_test.go index f22d6e67c6..6db845c0b3 100644 --- a/internal/acceptance/openstack/compute/v2/migrate_test.go +++ b/internal/acceptance/openstack/compute/v2/migrate_test.go @@ -31,7 +31,7 @@ func TestMigrate(t *testing.T) { func TestLiveMigrate(t *testing.T) { clients.RequireLong(t) clients.RequireAdmin(t) - clients.RequireLiveMigration(t) + RequireLiveMigration(t) client, err := clients.NewComputeV2Client() th.AssertNoErr(t, err) diff --git a/internal/acceptance/openstack/compute/v2/servers_test.go b/internal/acceptance/openstack/compute/v2/servers_test.go index 5934805ba2..0c5d034491 100644 --- a/internal/acceptance/openstack/compute/v2/servers_test.go +++ b/internal/acceptance/openstack/compute/v2/servers_test.go @@ -234,7 +234,7 @@ func TestServersMetadata(t *testing.T) { func TestServersActionChangeAdminPassword(t *testing.T) { clients.RequireLong(t) - clients.RequireGuestAgent(t) + RequireGuestAgent(t) client, err := clients.NewComputeV2Client() th.AssertNoErr(t, err) diff --git a/internal/acceptance/openstack/identity/v2/conditions.go b/internal/acceptance/openstack/identity/v2/conditions.go new file mode 100644 index 0000000000..9871afaf30 --- /dev/null +++ b/internal/acceptance/openstack/identity/v2/conditions.go @@ -0,0 +1,14 @@ +package v2 + +import ( + "os" + "testing" +) + +// RequireIdentityV2 will restrict a test to only be run in +// environments that support the Identity V2 API. +func RequireIdentityV2(t *testing.T) { + if os.Getenv("OS_IDENTITY_API_VERSION") != "2.0" { + t.Skip("this test requires support for the identity v2 API") + } +} diff --git a/internal/acceptance/openstack/identity/v2/extension_test.go b/internal/acceptance/openstack/identity/v2/extension_test.go index ada4ddef4f..f43523340a 100644 --- a/internal/acceptance/openstack/identity/v2/extension_test.go +++ b/internal/acceptance/openstack/identity/v2/extension_test.go @@ -13,7 +13,7 @@ import ( ) func TestExtensionsList(t *testing.T) { - clients.RequireIdentityV2(t) + RequireIdentityV2(t) clients.RequireAdmin(t) client, err := clients.NewIdentityV2Client() @@ -37,7 +37,7 @@ func TestExtensionsList(t *testing.T) { } func TestExtensionsGet(t *testing.T) { - clients.RequireIdentityV2(t) + RequireIdentityV2(t) clients.RequireAdmin(t) client, err := clients.NewIdentityV2Client() diff --git a/internal/acceptance/openstack/identity/v2/role_test.go b/internal/acceptance/openstack/identity/v2/role_test.go index 2eed42a3c3..49635f7f98 100644 --- a/internal/acceptance/openstack/identity/v2/role_test.go +++ b/internal/acceptance/openstack/identity/v2/role_test.go @@ -14,7 +14,7 @@ import ( ) func TestRolesAddToUser(t *testing.T) { - clients.RequireIdentityV2(t) + RequireIdentityV2(t) clients.RequireAdmin(t) client, err := clients.NewIdentityV2AdminClient() @@ -53,7 +53,7 @@ func TestRolesAddToUser(t *testing.T) { } func TestRolesList(t *testing.T) { - clients.RequireIdentityV2(t) + RequireIdentityV2(t) clients.RequireAdmin(t) client, err := clients.NewIdentityV2AdminClient() diff --git a/internal/acceptance/openstack/identity/v2/tenant_test.go b/internal/acceptance/openstack/identity/v2/tenant_test.go index d390f14d35..2c7092e91d 100644 --- a/internal/acceptance/openstack/identity/v2/tenant_test.go +++ b/internal/acceptance/openstack/identity/v2/tenant_test.go @@ -13,7 +13,7 @@ import ( ) func TestTenantsList(t *testing.T) { - clients.RequireIdentityV2(t) + RequireIdentityV2(t) clients.RequireAdmin(t) client, err := clients.NewIdentityV2Client() @@ -38,7 +38,7 @@ func TestTenantsList(t *testing.T) { } func TestTenantsCRUD(t *testing.T) { - clients.RequireIdentityV2(t) + RequireIdentityV2(t) clients.RequireAdmin(t) client, err := clients.NewIdentityV2AdminClient() diff --git a/internal/acceptance/openstack/identity/v2/token_test.go b/internal/acceptance/openstack/identity/v2/token_test.go index fba2dbc0a5..61d93f2187 100644 --- a/internal/acceptance/openstack/identity/v2/token_test.go +++ b/internal/acceptance/openstack/identity/v2/token_test.go @@ -14,7 +14,7 @@ import ( ) func TestTokenAuthenticate(t *testing.T) { - clients.RequireIdentityV2(t) + RequireIdentityV2(t) clients.RequireAdmin(t) client, err := clients.NewIdentityV2UnauthenticatedClient() @@ -38,7 +38,7 @@ func TestTokenAuthenticate(t *testing.T) { } func TestTokenValidate(t *testing.T) { - clients.RequireIdentityV2(t) + RequireIdentityV2(t) clients.RequireAdmin(t) client, err := clients.NewIdentityV2Client() diff --git a/internal/acceptance/openstack/identity/v2/user_test.go b/internal/acceptance/openstack/identity/v2/user_test.go index f54e218d30..e0f614e511 100644 --- a/internal/acceptance/openstack/identity/v2/user_test.go +++ b/internal/acceptance/openstack/identity/v2/user_test.go @@ -13,7 +13,7 @@ import ( ) func TestUsersList(t *testing.T) { - clients.RequireIdentityV2(t) + RequireIdentityV2(t) clients.RequireAdmin(t) client, err := clients.NewIdentityV2AdminClient() @@ -38,7 +38,7 @@ func TestUsersList(t *testing.T) { } func TestUsersCreateUpdateDelete(t *testing.T) { - clients.RequireIdentityV2(t) + RequireIdentityV2(t) clients.RequireAdmin(t) client, err := clients.NewIdentityV2AdminClient() diff --git a/internal/acceptance/openstack/networking/v2/conditions.go b/internal/acceptance/openstack/networking/v2/conditions.go index 036cba6044..6ce6b145f3 100644 --- a/internal/acceptance/openstack/networking/v2/conditions.go +++ b/internal/acceptance/openstack/networking/v2/conditions.go @@ -2,6 +2,7 @@ package v2 import ( "context" + "os" "testing" "github.com/gophercloud/gophercloud/v2" @@ -16,3 +17,11 @@ func RequireNeutronExtension(t *testing.T, client *gophercloud.ServiceClient, ex t.Skipf("this test requires %s Neutron extension", extension) } } + +// RequirePortForwarding will restrict a test to only be run in environments +// that support port forwarding +func RequirePortForwarding(t *testing.T) { + if os.Getenv("OS_PORTFORWARDING_ENVIRONMENT") == "" { + t.Skip("this test requires support for port forwarding") + } +} diff --git a/internal/acceptance/openstack/networking/v2/extensions/layer3/portforwardings_test.go b/internal/acceptance/openstack/networking/v2/extensions/layer3/portforwardings_test.go index 3d3f208529..d6f3e9595e 100644 --- a/internal/acceptance/openstack/networking/v2/extensions/layer3/portforwardings_test.go +++ b/internal/acceptance/openstack/networking/v2/extensions/layer3/portforwardings_test.go @@ -15,7 +15,7 @@ import ( ) func TestLayer3PortForwardingsCreateDelete(t *testing.T) { - clients.RequirePortForwarding(t) + networking.RequirePortForwarding(t) client, err := clients.NewNetworkV2Client() th.AssertNoErr(t, err) diff --git a/internal/acceptance/openstack/sharedfilesystems/v2/conditions.go b/internal/acceptance/openstack/sharedfilesystems/v2/conditions.go new file mode 100644 index 0000000000..de48b6939a --- /dev/null +++ b/internal/acceptance/openstack/sharedfilesystems/v2/conditions.go @@ -0,0 +1,14 @@ +package v2 + +import ( + "os" + "testing" +) + +// RequireManilaReplicas will restrict a test to only be run with enabled +// manila replicas. +func RequireManilaReplicas(t *testing.T) { + if os.Getenv("OS_MANILA_REPLICAS") != "true" { + t.Skip("manila replicas must be enabled to run this test") + } +} diff --git a/internal/acceptance/openstack/sharedfilesystems/v2/replicas_test.go b/internal/acceptance/openstack/sharedfilesystems/v2/replicas_test.go index 41913ac266..8432afeb77 100644 --- a/internal/acceptance/openstack/sharedfilesystems/v2/replicas_test.go +++ b/internal/acceptance/openstack/sharedfilesystems/v2/replicas_test.go @@ -18,7 +18,7 @@ import ( const replicasPathMicroversion = "2.56" func TestReplicaCreate(t *testing.T) { - clients.RequireManilaReplicas(t) + RequireManilaReplicas(t) client, err := clients.NewSharedFileSystemV2Client() if err != nil { @@ -55,7 +55,7 @@ func TestReplicaCreate(t *testing.T) { } func TestReplicaPromote(t *testing.T) { - clients.RequireManilaReplicas(t) + RequireManilaReplicas(t) client, err := clients.NewSharedFileSystemV2Client() if err != nil { @@ -131,7 +131,7 @@ func TestReplicaPromote(t *testing.T) { } func TestReplicaExportLocations(t *testing.T) { - clients.RequireManilaReplicas(t) + RequireManilaReplicas(t) client, err := clients.NewSharedFileSystemV2Client() if err != nil { @@ -198,7 +198,7 @@ func TestReplicaExportLocations(t *testing.T) { } func TestReplicaListDetail(t *testing.T) { - clients.RequireManilaReplicas(t) + RequireManilaReplicas(t) client, err := clients.NewSharedFileSystemV2Client() if err != nil { @@ -231,7 +231,7 @@ func TestReplicaListDetail(t *testing.T) { } func TestReplicaResetStatus(t *testing.T) { - clients.RequireManilaReplicas(t) + RequireManilaReplicas(t) client, err := clients.NewSharedFileSystemV2Client() if err != nil { @@ -272,7 +272,7 @@ func TestReplicaResetStatus(t *testing.T) { // This test available only for cloud admins func TestReplicaForceDelete(t *testing.T) { - clients.RequireManilaReplicas(t) + RequireManilaReplicas(t) clients.RequireAdmin(t) client, err := clients.NewSharedFileSystemV2Client() From ff696573cc81bc41f2480bb7a6847dbf34a2a083 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Tue, 13 May 2025 18:19:56 +0100 Subject: [PATCH 129/353] tests: Skip vpnaas tests if extension missing Signed-off-by: Stephen Finucane (cherry picked from commit 8314ff1af652bb22cea9a49cc219c3a591e1e8a7) --- .../v2/extensions/vpnaas/group_test.go | 7 +++++++ .../v2/extensions/vpnaas/ikepolicy_test.go | 7 +++++++ .../v2/extensions/vpnaas/ipsecpolicy_test.go | 7 +++++++ .../v2/extensions/vpnaas/service_test.go | 9 +++++++++ .../extensions/vpnaas/siteconnection_test.go | 18 +++++++++++++----- 5 files changed, 43 insertions(+), 5 deletions(-) diff --git a/internal/acceptance/openstack/networking/v2/extensions/vpnaas/group_test.go b/internal/acceptance/openstack/networking/v2/extensions/vpnaas/group_test.go index 8fe5e0638c..862324736f 100644 --- a/internal/acceptance/openstack/networking/v2/extensions/vpnaas/group_test.go +++ b/internal/acceptance/openstack/networking/v2/extensions/vpnaas/group_test.go @@ -7,6 +7,7 @@ import ( "testing" "github.com/gophercloud/gophercloud/v2/internal/acceptance/clients" + networking "github.com/gophercloud/gophercloud/v2/internal/acceptance/openstack/networking/v2" "github.com/gophercloud/gophercloud/v2/internal/acceptance/tools" "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/extensions/vpnaas/endpointgroups" th "github.com/gophercloud/gophercloud/v2/testhelper" @@ -16,6 +17,9 @@ func TestGroupList(t *testing.T) { client, err := clients.NewNetworkV2Client() th.AssertNoErr(t, err) + // Skip these tests if we don't have the required extension + networking.RequireNeutronExtension(t, client, "vpnaas") + allPages, err := endpointgroups.List(client, nil).AllPages(context.TODO()) th.AssertNoErr(t, err) @@ -31,6 +35,9 @@ func TestGroupCRUD(t *testing.T) { client, err := clients.NewNetworkV2Client() th.AssertNoErr(t, err) + // Skip these tests if we don't have the required extension + networking.RequireNeutronExtension(t, client, "vpnaas") + group, err := CreateEndpointGroup(t, client) th.AssertNoErr(t, err) defer DeleteEndpointGroup(t, client, group.ID) diff --git a/internal/acceptance/openstack/networking/v2/extensions/vpnaas/ikepolicy_test.go b/internal/acceptance/openstack/networking/v2/extensions/vpnaas/ikepolicy_test.go index c0407c99a4..eeb573edf0 100644 --- a/internal/acceptance/openstack/networking/v2/extensions/vpnaas/ikepolicy_test.go +++ b/internal/acceptance/openstack/networking/v2/extensions/vpnaas/ikepolicy_test.go @@ -7,6 +7,7 @@ import ( "testing" "github.com/gophercloud/gophercloud/v2/internal/acceptance/clients" + networking "github.com/gophercloud/gophercloud/v2/internal/acceptance/openstack/networking/v2" "github.com/gophercloud/gophercloud/v2/internal/acceptance/tools" "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/extensions/vpnaas/ikepolicies" th "github.com/gophercloud/gophercloud/v2/testhelper" @@ -16,6 +17,9 @@ func TestIKEPolicyList(t *testing.T) { client, err := clients.NewNetworkV2Client() th.AssertNoErr(t, err) + // Skip these tests if we don't have the required extension + networking.RequireNeutronExtension(t, client, "vpnaas") + allPages, err := ikepolicies.List(client, nil).AllPages(context.TODO()) th.AssertNoErr(t, err) @@ -31,6 +35,9 @@ func TestIKEPolicyCRUD(t *testing.T) { client, err := clients.NewNetworkV2Client() th.AssertNoErr(t, err) + // Skip these tests if we don't have the required extension + networking.RequireNeutronExtension(t, client, "vpnaas") + policy, err := CreateIKEPolicy(t, client) th.AssertNoErr(t, err) defer DeleteIKEPolicy(t, client, policy.ID) diff --git a/internal/acceptance/openstack/networking/v2/extensions/vpnaas/ipsecpolicy_test.go b/internal/acceptance/openstack/networking/v2/extensions/vpnaas/ipsecpolicy_test.go index f9aed9b2aa..74dc5a3758 100644 --- a/internal/acceptance/openstack/networking/v2/extensions/vpnaas/ipsecpolicy_test.go +++ b/internal/acceptance/openstack/networking/v2/extensions/vpnaas/ipsecpolicy_test.go @@ -7,6 +7,7 @@ import ( "testing" "github.com/gophercloud/gophercloud/v2/internal/acceptance/clients" + networking "github.com/gophercloud/gophercloud/v2/internal/acceptance/openstack/networking/v2" "github.com/gophercloud/gophercloud/v2/internal/acceptance/tools" "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/extensions/vpnaas/ipsecpolicies" th "github.com/gophercloud/gophercloud/v2/testhelper" @@ -16,6 +17,9 @@ func TestIPSecPolicyList(t *testing.T) { client, err := clients.NewNetworkV2Client() th.AssertNoErr(t, err) + // Skip these tests if we don't have the required extension + networking.RequireNeutronExtension(t, client, "vpnaas") + allPages, err := ipsecpolicies.List(client, nil).AllPages(context.TODO()) th.AssertNoErr(t, err) @@ -31,6 +35,9 @@ func TestIPSecPolicyCRUD(t *testing.T) { client, err := clients.NewNetworkV2Client() th.AssertNoErr(t, err) + // Skip these tests if we don't have the required extension + networking.RequireNeutronExtension(t, client, "vpnaas") + policy, err := CreateIPSecPolicy(t, client) th.AssertNoErr(t, err) defer DeleteIPSecPolicy(t, client, policy.ID) diff --git a/internal/acceptance/openstack/networking/v2/extensions/vpnaas/service_test.go b/internal/acceptance/openstack/networking/v2/extensions/vpnaas/service_test.go index 2ac1c7734c..b932dbdeb3 100644 --- a/internal/acceptance/openstack/networking/v2/extensions/vpnaas/service_test.go +++ b/internal/acceptance/openstack/networking/v2/extensions/vpnaas/service_test.go @@ -7,6 +7,7 @@ import ( "testing" "github.com/gophercloud/gophercloud/v2/internal/acceptance/clients" + networking "github.com/gophercloud/gophercloud/v2/internal/acceptance/openstack/networking/v2" layer3 "github.com/gophercloud/gophercloud/v2/internal/acceptance/openstack/networking/v2/extensions/layer3" "github.com/gophercloud/gophercloud/v2/internal/acceptance/tools" "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/extensions/vpnaas/services" @@ -17,6 +18,9 @@ func TestServiceList(t *testing.T) { client, err := clients.NewNetworkV2Client() th.AssertNoErr(t, err) + // Skip these tests if we don't have the required extension + networking.RequireNeutronExtension(t, client, "vpnaas") + allPages, err := services.List(client, nil).AllPages(context.TODO()) th.AssertNoErr(t, err) @@ -29,10 +33,15 @@ func TestServiceList(t *testing.T) { } func TestServiceCRUD(t *testing.T) { + // TODO(stephenfin): Why are we skipping this? Can we unskip? If not, we should remove. clients.SkipReleasesAbove(t, "stable/wallaby") + client, err := clients.NewNetworkV2Client() th.AssertNoErr(t, err) + // Skip these tests if we don't have the required extension + networking.RequireNeutronExtension(t, client, "vpnaas") + router, err := layer3.CreateExternalRouter(t, client) th.AssertNoErr(t, err) defer layer3.DeleteRouter(t, client, router.ID) diff --git a/internal/acceptance/openstack/networking/v2/extensions/vpnaas/siteconnection_test.go b/internal/acceptance/openstack/networking/v2/extensions/vpnaas/siteconnection_test.go index 8aa8e49f57..68a7f45192 100644 --- a/internal/acceptance/openstack/networking/v2/extensions/vpnaas/siteconnection_test.go +++ b/internal/acceptance/openstack/networking/v2/extensions/vpnaas/siteconnection_test.go @@ -7,7 +7,7 @@ import ( "testing" "github.com/gophercloud/gophercloud/v2/internal/acceptance/clients" - networks "github.com/gophercloud/gophercloud/v2/internal/acceptance/openstack/networking/v2" + networking "github.com/gophercloud/gophercloud/v2/internal/acceptance/openstack/networking/v2" layer3 "github.com/gophercloud/gophercloud/v2/internal/acceptance/openstack/networking/v2/extensions/layer3" "github.com/gophercloud/gophercloud/v2/internal/acceptance/tools" "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/extensions/layer3/routers" @@ -19,6 +19,9 @@ func TestConnectionList(t *testing.T) { client, err := clients.NewNetworkV2Client() th.AssertNoErr(t, err) + // Skip these tests if we don't have the required extension + networking.RequireNeutronExtension(t, client, "vpnaas") + allPages, err := siteconnections.List(client, nil).AllPages(context.TODO()) th.AssertNoErr(t, err) @@ -31,19 +34,24 @@ func TestConnectionList(t *testing.T) { } func TestConnectionCRUD(t *testing.T) { + // TODO(stephenfin): Why are we skipping this? Can we unskip? If not, we should remove. clients.SkipReleasesAbove(t, "stable/wallaby") + client, err := clients.NewNetworkV2Client() th.AssertNoErr(t, err) + // Skip these tests if we don't have the required extension + networking.RequireNeutronExtension(t, client, "vpnaas") + // Create Network - network, err := networks.CreateNetwork(t, client) + network, err := networking.CreateNetwork(t, client) th.AssertNoErr(t, err) - defer networks.DeleteNetwork(t, client, network.ID) + defer networking.DeleteNetwork(t, client, network.ID) // Create Subnet - subnet, err := networks.CreateSubnet(t, client, network.ID) + subnet, err := networking.CreateSubnet(t, client, network.ID) th.AssertNoErr(t, err) - defer networks.DeleteSubnet(t, client, subnet.ID) + defer networking.DeleteSubnet(t, client, subnet.ID) router, err := layer3.CreateExternalRouter(t, client) th.AssertNoErr(t, err) From 9728281ea9dbeb26b830026e0c9e7c84c3fc1666 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Wed, 14 May 2025 10:22:03 +0100 Subject: [PATCH 130/353] tests: Configure policy in fwaas functional workflow We already do this for the networking workflow. Now do it for the fwaas-specific workflow. Signed-off-by: Stephen Finucane (cherry picked from commit df9032a3eded801cd0865109c595c513630b207f) --- .github/workflows/functional-fwaas_v2.yaml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/.github/workflows/functional-fwaas_v2.yaml b/.github/workflows/functional-fwaas_v2.yaml index f715da56a9..cb84f9f465 100644 --- a/.github/workflows/functional-fwaas_v2.yaml +++ b/.github/workflows/functional-fwaas_v2.yaml @@ -1,3 +1,7 @@ +# TODO(stephenfin): neutron-fwaas may support OVN now. If so, we can combine +# this job with the functional-networking job. See [1] +# +# [1] https://bugs.launchpad.net/neutron/+bug/1971958 name: functional-fwaas_v2 on: pull_request: @@ -29,6 +33,14 @@ jobs: steps: - name: Checkout Gophercloud uses: actions/checkout@v4 + - name: Create additional neutron policies + run: | + mkdir /tmp/neutron-policies + cat << EOF >> /tmp/neutron-policies/port_binding.yaml + --- + "create_port:binding:profile": "rule:admin_only or rule:service_api" + "update_port:binding:profile": "rule:admin_only or rule:service_api" + EOF - name: Deploy devstack uses: gophercloud/devstack-action@v0.17 with: @@ -40,6 +52,10 @@ jobs: Q_ML2_PLUGIN_TYPE_DRIVERS=flat,gre,vlan,vxlan Q_ML2_TENANT_NETWORK_TYPE=vxlan Q_TUNNEL_TYPES=vxlan,gre + + [[post-config|\$NEUTRON_CONF]] + [oslo_policy] + policy_dirs = /tmp/neutron-policies enabled_services: 'q-svc,q-agt,q-dhcp,q-l3,q-meta,q-fwaas-v2,-cinder,-horizon,-tempest,-swift,-c-sch,-c-api,-c-vol,-c-bak,-ovn,-ovn-controller,-ovn-northd,-q-ovn-metadata-agent,${{ matrix.additional_services }}' - name: Checkout go uses: actions/setup-go@v5 From f1e827bd523e1948c4a209abd595e4571303500b Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Wed, 14 May 2025 10:30:55 +0100 Subject: [PATCH 131/353] tests: Skip bgp tests if extension missing Signed-off-by: Stephen Finucane (cherry picked from commit 148e43ab9df8bf76a8410e7bb4a4b5463249d858) --- .../networking/v2/extensions/agents/agents_test.go | 9 ++++++--- .../networking/v2/extensions/bgp/peers/bgppeers_test.go | 4 ++++ .../v2/extensions/bgp/speakers/bgpspeakers_test.go | 4 ++++ 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/internal/acceptance/openstack/networking/v2/extensions/agents/agents_test.go b/internal/acceptance/openstack/networking/v2/extensions/agents/agents_test.go index 37b5e39c3b..068ea001c5 100644 --- a/internal/acceptance/openstack/networking/v2/extensions/agents/agents_test.go +++ b/internal/acceptance/openstack/networking/v2/extensions/agents/agents_test.go @@ -16,8 +16,8 @@ import ( th "github.com/gophercloud/gophercloud/v2/testhelper" ) -func TestAgentsRUD(t *testing.T) { - t.Skip("TestAgentsRUD needs to be re-worked to work with both ML2/OVS and OVN") +func TestAgentsCRUD(t *testing.T) { + t.Skip("TestAgentsCRUD needs to be re-worked to work with both ML2/OVS and OVN") clients.RequireAdmin(t) client, err := clients.NewNetworkV2Client() @@ -96,13 +96,16 @@ func TestAgentsRUD(t *testing.T) { th.AssertNoErr(t, err) } -func TestBGPAgentRUD(t *testing.T) { +func TestBGPAgentCRUD(t *testing.T) { timeout := 15 * time.Minute clients.RequireAdmin(t) client, err := clients.NewNetworkV2Client() th.AssertNoErr(t, err) + // Skip these tests if we don't have the required extension + networking.RequireNeutronExtension(t, client, "bgp") + // List BGP Agents listOpts := &agents.ListOpts{ AgentType: "BGP Dynamic Routing Agent", diff --git a/internal/acceptance/openstack/networking/v2/extensions/bgp/peers/bgppeers_test.go b/internal/acceptance/openstack/networking/v2/extensions/bgp/peers/bgppeers_test.go index 8fdee3c034..baad9a8a5e 100644 --- a/internal/acceptance/openstack/networking/v2/extensions/bgp/peers/bgppeers_test.go +++ b/internal/acceptance/openstack/networking/v2/extensions/bgp/peers/bgppeers_test.go @@ -7,6 +7,7 @@ import ( "testing" "github.com/gophercloud/gophercloud/v2/internal/acceptance/clients" + networking "github.com/gophercloud/gophercloud/v2/internal/acceptance/openstack/networking/v2" "github.com/gophercloud/gophercloud/v2/internal/acceptance/tools" "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/extensions/bgp/peers" th "github.com/gophercloud/gophercloud/v2/testhelper" @@ -18,6 +19,9 @@ func TestBGPPeerCRUD(t *testing.T) { client, err := clients.NewNetworkV2Client() th.AssertNoErr(t, err) + // Skip these tests if we don't have the required extension + networking.RequireNeutronExtension(t, client, "bgp") + // Create a BGP Peer bgpPeerCreated, err := CreateBGPPeer(t, client) th.AssertNoErr(t, err) diff --git a/internal/acceptance/openstack/networking/v2/extensions/bgp/speakers/bgpspeakers_test.go b/internal/acceptance/openstack/networking/v2/extensions/bgp/speakers/bgpspeakers_test.go index 5b50d6df59..2ab5584d5b 100644 --- a/internal/acceptance/openstack/networking/v2/extensions/bgp/speakers/bgpspeakers_test.go +++ b/internal/acceptance/openstack/networking/v2/extensions/bgp/speakers/bgpspeakers_test.go @@ -17,9 +17,13 @@ import ( func TestBGPSpeakerCRUD(t *testing.T) { clients.RequireAdmin(t) + client, err := clients.NewNetworkV2Client() th.AssertNoErr(t, err) + // Skip these tests if we don't have the required extension + networking.RequireNeutronExtension(t, client, "bgp") + // Create a BGP Speaker bgpSpeaker, err := CreateBGPSpeaker(t, client) th.AssertNoErr(t, err) From 5fa68ead7ab71d5381e68765bd9b4fd496b79162 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Wed, 14 May 2025 10:31:06 +0100 Subject: [PATCH 132/353] tests: Skip bgpvpn tests if extension missing We also fix some typos in test names. Signed-off-by: Stephen Finucane (cherry picked from commit 13997f39b2effa7ab02922e6f94a54172aa68eac) --- .../v2/extensions/bgpvpns/bgpvpns_test.go | 14 +++++++++++++- .../networking/v2/extensions/dns/dns_test.go | 4 ++-- .../networking/v2/extensions/mtu/mtu_test.go | 2 +- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/internal/acceptance/openstack/networking/v2/extensions/bgpvpns/bgpvpns_test.go b/internal/acceptance/openstack/networking/v2/extensions/bgpvpns/bgpvpns_test.go index 01542d6ec3..3c915901e8 100644 --- a/internal/acceptance/openstack/networking/v2/extensions/bgpvpns/bgpvpns_test.go +++ b/internal/acceptance/openstack/networking/v2/extensions/bgpvpns/bgpvpns_test.go @@ -20,6 +20,9 @@ func TestBGPVPNCRUD(t *testing.T) { client, err := clients.NewNetworkV2Client() th.AssertNoErr(t, err) + // Skip these tests if we don't have the required extension + networking.RequireNeutronExtension(t, client, "bgpvpn") + // Create a BGP VPN bgpVpnCreated, err := CreateBGPVPN(t, client) th.AssertNoErr(t, err) @@ -60,12 +63,15 @@ func TestBGPVPNCRUD(t *testing.T) { t.Logf("BGP VPN %s deleted", bgpVpnUpdated.Name) } -func TestBGPVPNNetworkAssociationCRD(t *testing.T) { +func TestBGPVPNNetworkAssociationCRUD(t *testing.T) { clients.RequireAdmin(t) client, err := clients.NewNetworkV2Client() th.AssertNoErr(t, err) + // Skip these tests if we don't have the required extension + networking.RequireNeutronExtension(t, client, "bgpvpn") + // Create a BGP VPN bgpVpnCreated, err := CreateBGPVPN(t, client) th.AssertNoErr(t, err) @@ -117,6 +123,9 @@ func TestBGPVPNRouterAssociationCRUD(t *testing.T) { client, err := clients.NewNetworkV2Client() th.AssertNoErr(t, err) + // Skip these tests if we don't have the required extension + networking.RequireNeutronExtension(t, client, "bgpvpn") + // Create a BGP VPN bgpVpnCreated, err := CreateBGPVPN(t, client) th.AssertNoErr(t, err) @@ -182,6 +191,9 @@ func TestBGPVPNPortAssociationCRUD(t *testing.T) { client, err := clients.NewNetworkV2Client() th.AssertNoErr(t, err) + // Skip these tests if we don't have the required extension + networking.RequireNeutronExtension(t, client, "bgpvpn") + // Create a BGP VPN bgpVpnCreated, err := CreateBGPVPN(t, client) th.AssertNoErr(t, err) diff --git a/internal/acceptance/openstack/networking/v2/extensions/dns/dns_test.go b/internal/acceptance/openstack/networking/v2/extensions/dns/dns_test.go index d709a4252d..fd239f8a40 100644 --- a/internal/acceptance/openstack/networking/v2/extensions/dns/dns_test.go +++ b/internal/acceptance/openstack/networking/v2/extensions/dns/dns_test.go @@ -141,8 +141,8 @@ func TestDNSPortCRUDL(t *testing.T) { th.AssertDeepEquals(t, newPort, getNewPort) } -func TestDNSFloatingIPCRDL(t *testing.T) { - t.Skip("Skipping TestDNSFloatingIPCRDL for now, as it doesn't work with ML2/OVN.") +func TestDNSFloatingIPCRUD(t *testing.T) { + t.Skip("Skipping TestDNSFloatingIPCRUD for now, as it doesn't work with ML2/OVN.") clients.RequireAdmin(t) client, err := clients.NewNetworkV2Client() diff --git a/internal/acceptance/openstack/networking/v2/extensions/mtu/mtu_test.go b/internal/acceptance/openstack/networking/v2/extensions/mtu/mtu_test.go index a71c96cc43..63e4f7790b 100644 --- a/internal/acceptance/openstack/networking/v2/extensions/mtu/mtu_test.go +++ b/internal/acceptance/openstack/networking/v2/extensions/mtu/mtu_test.go @@ -16,7 +16,7 @@ import ( th "github.com/gophercloud/gophercloud/v2/testhelper" ) -func TestMTUNetworkCRUDL(t *testing.T) { +func TestMTUNetworkCRUD(t *testing.T) { clients.RequireAdmin(t) client, err := clients.NewNetworkV2Client() From 105bc565429435daff6da13990394801f2883147 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Wed, 14 May 2025 15:16:13 +0100 Subject: [PATCH 133/353] tests: Fix TestBGPAgentCRUD Change our deployment so that we use the static scheduler, and rework the test to handle this. Instead of waiting for the speaker to be associated with an agent (which won't happen with the static scheduler) we now jump straight to assigning it. Signed-off-by: Stephen Finucane Closes: #3380 (cherry picked from commit 669a870ec02690a2adc7945a840e22fbf4933d62) --- .github/workflows/functional-networking.yaml | 1 + .../v2/extensions/agents/agents_test.go | 111 ++++++++---------- 2 files changed, 50 insertions(+), 62 deletions(-) diff --git a/.github/workflows/functional-networking.yaml b/.github/workflows/functional-networking.yaml index 7127596ff7..a07c2ef2b0 100644 --- a/.github/workflows/functional-networking.yaml +++ b/.github/workflows/functional-networking.yaml @@ -45,6 +45,7 @@ jobs: enable_plugin neutron-vpnaas https://github.com/openstack/neutron-vpnaas ${{ matrix.openstack_version }} enable_plugin networking-bgpvpn https://github.com/openstack/networking-bgpvpn.git ${{ matrix.openstack_version }} Q_ML2_PLUGIN_EXT_DRIVERS=qos,port_security,dns_domain_keywords + BGP_SCHEDULER_DRIVER=neutron_dynamic_routing.services.bgp.scheduler.bgp_dragent_scheduler.StaticScheduler [[post-config|\$NEUTRON_CONF]] [oslo_policy] diff --git a/internal/acceptance/openstack/networking/v2/extensions/agents/agents_test.go b/internal/acceptance/openstack/networking/v2/extensions/agents/agents_test.go index 37b5e39c3b..021f0d7baf 100644 --- a/internal/acceptance/openstack/networking/v2/extensions/agents/agents_test.go +++ b/internal/acceptance/openstack/networking/v2/extensions/agents/agents_test.go @@ -119,86 +119,73 @@ func TestBGPAgentRUD(t *testing.T) { // Create a BGP Speaker bgpSpeaker, err := spk.CreateBGPSpeaker(t, client) th.AssertNoErr(t, err) + + // List BGP Speaker-Agent associations pages, err := agents.ListDRAgentHostingBGPSpeakers(client, bgpSpeaker.ID).AllPages(context.TODO()) th.AssertNoErr(t, err) - bgpAgents, err := agents.ExtractAgents(pages) - th.AssertNoErr(t, err) - th.AssertIntGreaterOrEqual(t, len(bgpAgents), 1) - - // List the BGP Agents that accommodate the BGP Speaker - err = tools.WaitForTimeout( - func(ctx context.Context) (bool, error) { - flag := true - for _, agt := range bgpAgents { - t.Logf("BGP Speaker %s has been scheduled to agent %s", bgpSpeaker.ID, agt.ID) - bgpAgent, err := agents.Get(ctx, client, agt.ID).Extract() - th.AssertNoErr(t, err) - numOfSpeakers := int(bgpAgent.Configurations["bgp_speakers"].(float64)) - flag = flag && (numOfSpeakers == 1) - } - return flag, nil - }, timeout) + bgpAgentsForSpeaker, err := agents.ExtractAgents(pages) th.AssertNoErr(t, err) - // List the BGP speakers on the first agent - bgpAgent, err := agents.Get(context.TODO(), client, bgpAgents[0].ID).Extract() - th.AssertNoErr(t, err) - agentConf := bgpAgent.Configurations - numOfSpeakers := int(agentConf["bgp_speakers"].(float64)) - t.Logf("Agent %s has %d speaker(s)", bgpAgents[0].ID, numOfSpeakers) + // If there are no associations, we can assume the static scheduler is in + // effect and we must manually associate/disassociate the speaker from the + // agent. + // + // https://docs.openstack.org/neutron-dynamic-routing/latest/admin/agent-scheduler.html + doManualAssignment := len(bgpAgentsForSpeaker) == 0 + var agentID string - pages, err = agents.ListBGPSpeakers(client, bgpAgents[0].ID).AllPages(context.TODO()) - th.AssertNoErr(t, err) - allSpeakers, err := agents.ExtractBGPSpeakers(pages) - th.AssertNoErr(t, err) - out := "Speakers:" - for _, speaker := range allSpeakers { - out += " " + speaker.ID + if doManualAssignment { + // If using manual assignment, schedule a BGP Speaker to an agent + agentID = allAgents[0].ID + opts := agents.ScheduleBGPSpeakerOpts{ + SpeakerID: bgpSpeaker.ID, + } + err = agents.ScheduleBGPSpeaker(context.TODO(), client, agentID, opts).ExtractErr() + th.AssertNoErr(t, err) + t.Logf("Successfully scheduled speaker %s to agent %s", bgpSpeaker.ID, agentID) + } else { + // If using automatic assignment, pick the first agent that the speaker + // was assigned to (it may be assigned to many, depending on how many + // nodes there are) + agentID = bgpAgentsForSpeaker[0].ID } - t.Log(out) - // Remove the BGP Speaker from the first agent - err = agents.RemoveBGPSpeaker(context.TODO(), client, bgpAgents[0].ID, bgpSpeaker.ID).ExtractErr() + // Wait for the association to complete. + pages, err = agents.ListDRAgentHostingBGPSpeakers(client, bgpSpeaker.ID).AllPages(context.TODO()) + th.AssertNoErr(t, err) + bgpAgentsForSpeaker, err = agents.ExtractAgents(pages) th.AssertNoErr(t, err) - t.Logf("BGP Speaker %s has been removed from agent %s", bgpSpeaker.ID, bgpAgents[0].ID) err = tools.WaitForTimeout( func(ctx context.Context) (bool, error) { - bgpAgent, err := agents.Get(ctx, client, bgpAgents[0].ID).Extract() + bgpAgent, err := agents.Get(ctx, client, agentID).Extract() th.AssertNoErr(t, err) agentConf := bgpAgent.Configurations numOfSpeakers := int(agentConf["bgp_speakers"].(float64)) - t.Logf("Agent %s has %d speaker(s)", bgpAgent.ID, numOfSpeakers) - return numOfSpeakers == 0, nil + t.Logf("Agent %s has %d speaker(s)", agentID, numOfSpeakers) + return 1 == numOfSpeakers, nil }, timeout) th.AssertNoErr(t, err) - // Remove all BGP Speakers from the agent - pages, err = agents.ListBGPSpeakers(client, bgpAgents[0].ID).AllPages(context.TODO()) + // Disassociate the BGP Speaker from the agent. + err = agents.RemoveBGPSpeaker(context.TODO(), client, bgpAgentsForSpeaker[0].ID, bgpSpeaker.ID).ExtractErr() th.AssertNoErr(t, err) - allSpeakers, err = agents.ExtractBGPSpeakers(pages) - th.AssertNoErr(t, err) - for _, speaker := range allSpeakers { - th.AssertNoErr(t, agents.RemoveBGPSpeaker(context.TODO(), client, bgpAgents[0].ID, speaker.ID).ExtractErr()) - } + t.Logf("BGP Speaker %s has been removed from agent %s", bgpSpeaker.ID, bgpAgentsForSpeaker[0].ID) - // Schedule a BGP Speaker to an agent - opts := agents.ScheduleBGPSpeakerOpts{ - SpeakerID: bgpSpeaker.ID, + // Only validate the disassociation if we know the static scheduler is in + // effect as it'll simply be recreated if we're using the chance scheduler + // and running in a single node deployment. + if doManualAssignment { + err = tools.WaitForTimeout( + func(ctx context.Context) (bool, error) { + bgpAgent, err := agents.Get(ctx, client, bgpAgentsForSpeaker[0].ID).Extract() + th.AssertNoErr(t, err) + agentConf := bgpAgent.Configurations + numOfSpeakers := int(agentConf["bgp_speakers"].(float64)) + t.Logf("Agent %s has %d speaker(s)", bgpAgent.ID, numOfSpeakers) + return numOfSpeakers == 0, nil + }, timeout) + th.AssertNoErr(t, err) } - err = agents.ScheduleBGPSpeaker(context.TODO(), client, bgpAgents[0].ID, opts).ExtractErr() - th.AssertNoErr(t, err) - t.Logf("Successfully scheduled speaker %s to agent %s", bgpSpeaker.ID, bgpAgents[0].ID) - - err = tools.WaitForTimeout( - func(ctx context.Context) (bool, error) { - bgpAgent, err := agents.Get(ctx, client, bgpAgents[0].ID).Extract() - th.AssertNoErr(t, err) - agentConf := bgpAgent.Configurations - numOfSpeakers := int(agentConf["bgp_speakers"].(float64)) - t.Logf("Agent %s has %d speaker(s)", bgpAgent.ID, numOfSpeakers) - return 1 == numOfSpeakers, nil - }, timeout) - th.AssertNoErr(t, err) // Delete the BGP Speaker err = speakers.Delete(context.TODO(), client, bgpSpeaker.ID).ExtractErr() @@ -206,7 +193,7 @@ func TestBGPAgentRUD(t *testing.T) { t.Logf("Successfully deleted the BGP Speaker, %s", bgpSpeaker.ID) err = tools.WaitForTimeout( func(ctx context.Context) (bool, error) { - bgpAgent, err := agents.Get(ctx, client, bgpAgents[0].ID).Extract() + bgpAgent, err := agents.Get(ctx, client, agentID).Extract() th.AssertNoErr(t, err) agentConf := bgpAgent.Configurations numOfSpeakers := int(agentConf["bgp_speakers"].(float64)) From 257e67a68f45915e5d336902c54e2d669527daf7 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Fri, 18 Apr 2025 11:14:24 +0100 Subject: [PATCH 134/353] Move master CI jobs to Ubuntu 24.04 (Noble) Signed-off-by: Stephen Finucane --- .github/workflows/functional-baremetal.yaml | 2 +- .github/workflows/functional-basic.yaml | 2 +- .github/workflows/functional-blockstorage.yaml | 2 +- .github/workflows/functional-compute.yaml | 2 +- .github/workflows/functional-containerinfra.yaml | 2 +- .github/workflows/functional-dns.yaml | 2 +- .github/workflows/functional-fwaas_v2.yaml | 2 +- .github/workflows/functional-identity.yaml | 2 +- .github/workflows/functional-image.yaml | 2 +- .github/workflows/functional-keymanager.yaml | 2 +- .github/workflows/functional-loadbalancer.yaml | 2 +- .github/workflows/functional-messaging.yaml | 2 +- .github/workflows/functional-networking.yaml | 2 +- .github/workflows/functional-objectstorage.yaml | 2 +- .github/workflows/functional-orchestration.yaml | 2 +- .github/workflows/functional-placement.yaml | 2 +- .github/workflows/functional-sharedfilesystems.yaml | 2 +- .github/workflows/functional-workflow.yaml | 2 +- 18 files changed, 18 insertions(+), 18 deletions(-) diff --git a/.github/workflows/functional-baremetal.yaml b/.github/workflows/functional-baremetal.yaml index eb04f8c920..75d79d1251 100644 --- a/.github/workflows/functional-baremetal.yaml +++ b/.github/workflows/functional-baremetal.yaml @@ -14,7 +14,7 @@ jobs: include: - name: "master" openstack_version: "master" - ubuntu_version: "22.04" + ubuntu_version: "24.04" additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" diff --git a/.github/workflows/functional-basic.yaml b/.github/workflows/functional-basic.yaml index 80808ac181..0145ab0917 100644 --- a/.github/workflows/functional-basic.yaml +++ b/.github/workflows/functional-basic.yaml @@ -16,7 +16,7 @@ jobs: include: - name: "master" openstack_version: "master" - ubuntu_version: "22.04" + ubuntu_version: "24.04" additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" diff --git a/.github/workflows/functional-blockstorage.yaml b/.github/workflows/functional-blockstorage.yaml index 1a36b0da04..96dc8bdf16 100644 --- a/.github/workflows/functional-blockstorage.yaml +++ b/.github/workflows/functional-blockstorage.yaml @@ -14,7 +14,7 @@ jobs: include: - name: "master" openstack_version: "master" - ubuntu_version: "22.04" + ubuntu_version: "24.04" additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" diff --git a/.github/workflows/functional-compute.yaml b/.github/workflows/functional-compute.yaml index 87f0ef7e67..30ec290dd0 100644 --- a/.github/workflows/functional-compute.yaml +++ b/.github/workflows/functional-compute.yaml @@ -14,7 +14,7 @@ jobs: include: - name: "master" openstack_version: "master" - ubuntu_version: "22.04" + ubuntu_version: "24.04" additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" diff --git a/.github/workflows/functional-containerinfra.yaml b/.github/workflows/functional-containerinfra.yaml index ad3c275b66..7e6b023c24 100644 --- a/.github/workflows/functional-containerinfra.yaml +++ b/.github/workflows/functional-containerinfra.yaml @@ -14,7 +14,7 @@ jobs: include: - name: "master" openstack_version: "master" - ubuntu_version: "22.04" + ubuntu_version: "24.04" devstack_conf_overrides: | # ensure we're using a working version of setuptools if [ -n "\$TOP_DIR" ]; then diff --git a/.github/workflows/functional-dns.yaml b/.github/workflows/functional-dns.yaml index 43e8123cc0..9df2aea628 100644 --- a/.github/workflows/functional-dns.yaml +++ b/.github/workflows/functional-dns.yaml @@ -14,7 +14,7 @@ jobs: include: - name: "master" openstack_version: "master" - ubuntu_version: "22.04" + ubuntu_version: "24.04" devstack_conf_overrides: | # ensure we're using a working version of setuptools if [ -n "\$TOP_DIR" ]; then diff --git a/.github/workflows/functional-fwaas_v2.yaml b/.github/workflows/functional-fwaas_v2.yaml index cb84f9f465..bf7762fdbf 100644 --- a/.github/workflows/functional-fwaas_v2.yaml +++ b/.github/workflows/functional-fwaas_v2.yaml @@ -18,7 +18,7 @@ jobs: include: - name: "master" openstack_version: "master" - ubuntu_version: "22.04" + ubuntu_version: "24.04" additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" diff --git a/.github/workflows/functional-identity.yaml b/.github/workflows/functional-identity.yaml index d3cb23f02c..623361dc17 100644 --- a/.github/workflows/functional-identity.yaml +++ b/.github/workflows/functional-identity.yaml @@ -14,7 +14,7 @@ jobs: include: - name: "master" openstack_version: "master" - ubuntu_version: "22.04" + ubuntu_version: "24.04" additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" diff --git a/.github/workflows/functional-image.yaml b/.github/workflows/functional-image.yaml index 26579dd4e7..e78dccbb86 100644 --- a/.github/workflows/functional-image.yaml +++ b/.github/workflows/functional-image.yaml @@ -14,7 +14,7 @@ jobs: include: - name: "master" openstack_version: "master" - ubuntu_version: "22.04" + ubuntu_version: "24.04" additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" diff --git a/.github/workflows/functional-keymanager.yaml b/.github/workflows/functional-keymanager.yaml index 099939e5a3..4e22a0f379 100644 --- a/.github/workflows/functional-keymanager.yaml +++ b/.github/workflows/functional-keymanager.yaml @@ -14,7 +14,7 @@ jobs: include: - name: "master" openstack_version: "master" - ubuntu_version: "22.04" + ubuntu_version: "24.04" devstack_conf_overrides: | # ensure we're using a working version of setuptools if [ -n "\$TOP_DIR" ]; then diff --git a/.github/workflows/functional-loadbalancer.yaml b/.github/workflows/functional-loadbalancer.yaml index 6b720aecac..2de31cb705 100644 --- a/.github/workflows/functional-loadbalancer.yaml +++ b/.github/workflows/functional-loadbalancer.yaml @@ -14,7 +14,7 @@ jobs: include: - name: "master" openstack_version: "master" - ubuntu_version: "22.04" + ubuntu_version: "24.04" devstack_conf_overrides: | # ensure we're using a working version of setuptools if [ -n "\$TOP_DIR" ]; then diff --git a/.github/workflows/functional-messaging.yaml b/.github/workflows/functional-messaging.yaml index 0ddb5f1efd..52ae48ec2f 100644 --- a/.github/workflows/functional-messaging.yaml +++ b/.github/workflows/functional-messaging.yaml @@ -14,7 +14,7 @@ jobs: include: - name: "master" openstack_version: "master" - ubuntu_version: "22.04" + ubuntu_version: "24.04" additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" diff --git a/.github/workflows/functional-networking.yaml b/.github/workflows/functional-networking.yaml index a0608a2b98..4765b45597 100644 --- a/.github/workflows/functional-networking.yaml +++ b/.github/workflows/functional-networking.yaml @@ -14,7 +14,7 @@ jobs: include: - name: "master" openstack_version: "master" - ubuntu_version: "22.04" + ubuntu_version: "24.04" additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" diff --git a/.github/workflows/functional-objectstorage.yaml b/.github/workflows/functional-objectstorage.yaml index b22f5ef454..9954f9fa19 100644 --- a/.github/workflows/functional-objectstorage.yaml +++ b/.github/workflows/functional-objectstorage.yaml @@ -14,7 +14,7 @@ jobs: include: - name: "master" openstack_version: "master" - ubuntu_version: "22.04" + ubuntu_version: "24.04" additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" diff --git a/.github/workflows/functional-orchestration.yaml b/.github/workflows/functional-orchestration.yaml index a301e45688..1d6073a562 100644 --- a/.github/workflows/functional-orchestration.yaml +++ b/.github/workflows/functional-orchestration.yaml @@ -14,7 +14,7 @@ jobs: include: - name: "master" openstack_version: "master" - ubuntu_version: "22.04" + ubuntu_version: "24.04" additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" diff --git a/.github/workflows/functional-placement.yaml b/.github/workflows/functional-placement.yaml index c6356e95e2..1226fb65a0 100644 --- a/.github/workflows/functional-placement.yaml +++ b/.github/workflows/functional-placement.yaml @@ -14,7 +14,7 @@ jobs: include: - name: "master" openstack_version: "master" - ubuntu_version: "22.04" + ubuntu_version: "24.04" additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" diff --git a/.github/workflows/functional-sharedfilesystems.yaml b/.github/workflows/functional-sharedfilesystems.yaml index 08aca0f0e8..48177ab05c 100644 --- a/.github/workflows/functional-sharedfilesystems.yaml +++ b/.github/workflows/functional-sharedfilesystems.yaml @@ -14,7 +14,7 @@ jobs: include: - name: "master" openstack_version: "master" - ubuntu_version: "22.04" + ubuntu_version: "24.04" devstack_conf_overrides: | # ensure we're using a working version of setuptools if [ -n "\$TOP_DIR" ]; then diff --git a/.github/workflows/functional-workflow.yaml b/.github/workflows/functional-workflow.yaml index d4d389581b..4fdf8d9a0e 100644 --- a/.github/workflows/functional-workflow.yaml +++ b/.github/workflows/functional-workflow.yaml @@ -14,7 +14,7 @@ jobs: include: - name: "master" openstack_version: "master" - ubuntu_version: "22.04" + ubuntu_version: "24.04" mistral_plugin_version: "master" additional_services: "openstack-cli-server" - name: "dalmatian" From 391dae2b3199f5e1c5f580840b75d44b64c1d982 Mon Sep 17 00:00:00 2001 From: Zhiwei Huang Date: Wed, 20 Mar 2024 16:15:13 +0800 Subject: [PATCH 135/353] Update the doc of openstack.AuthOptionsFromEnv function If OS_PROJECT_NAME is set, it requires the domain to be set as well to get unique project entity on the identity service (keystone). Signed-off-by: Zhiwei Huang --- openstack/auth_env.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openstack/auth_env.go b/openstack/auth_env.go index 893787b787..9ecc5b4efe 100644 --- a/openstack/auth_env.go +++ b/openstack/auth_env.go @@ -24,8 +24,8 @@ OS_PROJECT_NAME and the latter are expected against a v3 auth api. If OS_PROJECT_ID and OS_PROJECT_NAME are set, they will still be referred as "tenant" in Gophercloud. -If OS_PROJECT_NAME is set, it requires OS_PROJECT_ID to be set as well to -handle projects not on the default domain. +If OS_PROJECT_NAME is set, it requires OS_DOMAIN_ID or OS_DOMAIN_NAME to be +set as well to handle projects not on the default domain. To use this function, first set the OS_* environment variables (for example, by sourcing an `openrc` file), then: From b1de04576e89d4c228e92af7695382d4749dfb22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Andr=C3=A9?= Date: Wed, 12 Mar 2025 09:08:11 +0100 Subject: [PATCH 136/353] networking: add constants for statuses This avoids the need to define these constants in consumer code. Router also has a status field, but there's no documentation for it, so let's not guess what the valid statuses are. --- openstack/networking/v2/apiversions/constants.go | 7 +++++++ .../v2/extensions/layer3/floatingips/constants.go | 7 +++++++ .../networking/v2/extensions/trunks/constants.go | 9 +++++++++ .../v2/extensions/vpnaas/services/constants.go | 11 +++++++++++ .../v2/extensions/vpnaas/siteconnections/constants.go | 11 +++++++++++ openstack/networking/v2/networks/constants.go | 8 ++++++++ openstack/networking/v2/ports/constants.go | 8 ++++++++ 7 files changed, 61 insertions(+) create mode 100644 openstack/networking/v2/apiversions/constants.go create mode 100644 openstack/networking/v2/extensions/layer3/floatingips/constants.go create mode 100644 openstack/networking/v2/extensions/trunks/constants.go create mode 100644 openstack/networking/v2/extensions/vpnaas/services/constants.go create mode 100644 openstack/networking/v2/extensions/vpnaas/siteconnections/constants.go create mode 100644 openstack/networking/v2/networks/constants.go create mode 100644 openstack/networking/v2/ports/constants.go diff --git a/openstack/networking/v2/apiversions/constants.go b/openstack/networking/v2/apiversions/constants.go new file mode 100644 index 0000000000..2ffd32aa0d --- /dev/null +++ b/openstack/networking/v2/apiversions/constants.go @@ -0,0 +1,7 @@ +package apiversions + +const ( + StatusCurrent = "CURRENT" + StatusDeprecated = "DEPRECATED" + StatusStable = "STABLE" +) diff --git a/openstack/networking/v2/extensions/layer3/floatingips/constants.go b/openstack/networking/v2/extensions/layer3/floatingips/constants.go new file mode 100644 index 0000000000..85dff7818c --- /dev/null +++ b/openstack/networking/v2/extensions/layer3/floatingips/constants.go @@ -0,0 +1,7 @@ +package floatingips + +const ( + StatusActive = "ACTIVE" + StatusDown = "DOWN" + StatusError = "ERROR" +) diff --git a/openstack/networking/v2/extensions/trunks/constants.go b/openstack/networking/v2/extensions/trunks/constants.go new file mode 100644 index 0000000000..6bec77fa79 --- /dev/null +++ b/openstack/networking/v2/extensions/trunks/constants.go @@ -0,0 +1,9 @@ +package trunks + +const ( + StatusActive = "ACTIVE" + StatusBuild = "BUILD" + StatusDegraded = "DEGRADED" + StatusDown = "DOWN" + StatusError = "ERROR" +) diff --git a/openstack/networking/v2/extensions/vpnaas/services/constants.go b/openstack/networking/v2/extensions/vpnaas/services/constants.go new file mode 100644 index 0000000000..4917083923 --- /dev/null +++ b/openstack/networking/v2/extensions/vpnaas/services/constants.go @@ -0,0 +1,11 @@ +package services + +const ( + StatusActive = "ACTIVE" + StatusBuild = "BUILD" + StatusDown = "DOWN" + StatusError = "ERROR" + StatusPendingCreate = "PENDING_CREATE" + StatusPendingDelete = "PENDING_DELETE" + StatusPendingUpdate = "PENDING_UPDATE" +) diff --git a/openstack/networking/v2/extensions/vpnaas/siteconnections/constants.go b/openstack/networking/v2/extensions/vpnaas/siteconnections/constants.go new file mode 100644 index 0000000000..d4f4e0f448 --- /dev/null +++ b/openstack/networking/v2/extensions/vpnaas/siteconnections/constants.go @@ -0,0 +1,11 @@ +package siteconnections + +const ( + StatusActive = "ACTIVE" + StatusBuild = "BUILD" + StatusDown = "DOWN" + StatusError = "ERROR" + StatusPendingCreate = "PENDING_CREATE" + StatusPendingDelete = "PENDING_DELETE" + StatusPendingUpdate = "PENDING_UPDATE" +) diff --git a/openstack/networking/v2/networks/constants.go b/openstack/networking/v2/networks/constants.go new file mode 100644 index 0000000000..1214ce9deb --- /dev/null +++ b/openstack/networking/v2/networks/constants.go @@ -0,0 +1,8 @@ +package networks + +const ( + StatusActive = "ACTIVE" + StatusBuild = "BUILD" + StatusDown = "DOWN" + StatusError = "ERROR" +) diff --git a/openstack/networking/v2/ports/constants.go b/openstack/networking/v2/ports/constants.go new file mode 100644 index 0000000000..6275839bf4 --- /dev/null +++ b/openstack/networking/v2/ports/constants.go @@ -0,0 +1,8 @@ +package ports + +const ( + StatusActive = "ACTIVE" + StatusBuild = "BUILD" + StatusDown = "DOWN" + StatusError = "ERROR" +) From 29194cf28296510301cbd966a642880a3e17e336 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?p=C3=BDrus?= Date: Fri, 2 May 2025 15:33:22 +0200 Subject: [PATCH 137/353] dns: implement shared zones list --- internal/acceptance/openstack/dns/v2/dns.go | 35 +++++++++ .../openstack/dns/v2/shares_test.go | 66 ++++++++++++++++ openstack/dns/v2/zones/requests.go | 48 +++++++++++- openstack/dns/v2/zones/results.go | 78 +++++++++++++++++++ .../dns/v2/zones/testing/fixtures_test.go | 54 +++++++++++++ .../dns/v2/zones/testing/requests_test.go | 28 ++++++- openstack/dns/v2/zones/urls.go | 10 +-- 7 files changed, 310 insertions(+), 9 deletions(-) create mode 100644 internal/acceptance/openstack/dns/v2/shares_test.go diff --git a/internal/acceptance/openstack/dns/v2/dns.go b/internal/acceptance/openstack/dns/v2/dns.go index c31f238a6e..9adb61882d 100644 --- a/internal/acceptance/openstack/dns/v2/dns.go +++ b/internal/acceptance/openstack/dns/v2/dns.go @@ -186,6 +186,41 @@ func DeleteTransferRequest(t *testing.T, client *gophercloud.ServiceClient, tr * t.Logf("Deleted zone transfer request: %s", tr.ID) } +// CreateShare will create a zone share. An error will be returned if the +// zone share was unable to be created. +func CreateShare(t *testing.T, client *gophercloud.ServiceClient, zone *zones.Zone, targetProjectID string) (*zones.ZoneShare, error) { + t.Logf("Attempting to share zone %s with project %s", zone.ID, targetProjectID) + + createOpts := zones.ShareZoneOpts{ + TargetProjectID: targetProjectID, + } + + share, err := zones.Share(context.TODO(), client, zone.ID, createOpts).Extract() + if err != nil { + return share, err + } + + t.Logf("Created share for zone: %s", zone.ID) + + th.AssertEquals(t, share.ZoneID, zone.ID) + th.AssertEquals(t, share.TargetProjectID, targetProjectID) + + return share, nil +} + +// UnshareZone will unshare a zone. An error will be returned if the +// zone unshare was unable to be created. +func UnshareZone(t *testing.T, client *gophercloud.ServiceClient, share *zones.ZoneShare) { + t.Logf("Attempting to unshare zone %s with project %s", share.ZoneID, share.TargetProjectID) + + err := zones.Unshare(context.TODO(), client, share.ZoneID, share.ID).ExtractErr() + if err != nil { + t.Fatalf("Unable to unshare zone %s: %v", share.ZoneID, err) + } + + t.Logf("Unshared zone: %s", share.ZoneID) +} + // DeleteRecordSet will delete a specified record set. A fatal error will occur if // the record set failed to be deleted. This works best when used as a deferred // function. diff --git a/internal/acceptance/openstack/dns/v2/shares_test.go b/internal/acceptance/openstack/dns/v2/shares_test.go new file mode 100644 index 0000000000..496ee8f1b4 --- /dev/null +++ b/internal/acceptance/openstack/dns/v2/shares_test.go @@ -0,0 +1,66 @@ +//go:build acceptance || dns || zone_shares + +package v2 + +import ( + "context" + "testing" + + "github.com/gophercloud/gophercloud/v2/internal/acceptance/clients" + identity "github.com/gophercloud/gophercloud/v2/internal/acceptance/openstack/identity/v3" + "github.com/gophercloud/gophercloud/v2/internal/acceptance/tools" + "github.com/gophercloud/gophercloud/v2/openstack/dns/v2/zones" + th "github.com/gophercloud/gophercloud/v2/testhelper" +) + +func TestShareCRD(t *testing.T) { + // Create new project + identityClient, err := clients.NewIdentityV3Client() + th.AssertNoErr(t, err) + + project, err := identity.CreateProject(t, identityClient, nil) + th.AssertNoErr(t, err) + defer identity.DeleteProject(t, identityClient, project.ID) + + // Create new Zone + client, err := clients.NewDNSV2Client() + th.AssertNoErr(t, err) + + zone, err := CreateZone(t, client) + th.AssertNoErr(t, err) + defer DeleteZone(t, client, zone) + + // Create a zone share to new tenant + share, err := CreateShare(t, client, zone, project.ID) + th.AssertNoErr(t, err) + tools.PrintResource(t, share) + defer UnshareZone(t, client, share) + + // Get the share + getShare, err := zones.GetShare(context.TODO(), client, share.ZoneID, share.ID).Extract() + th.AssertNoErr(t, err) + tools.PrintResource(t, getShare) + th.AssertDeepEquals(t, *share, *getShare) + + // List shares + allPages, err := zones.ListShares(client, share.ZoneID, nil).AllPages(context.TODO()) + th.AssertNoErr(t, err) + + allShares, err := zones.ExtractZoneShares(allPages) + th.AssertNoErr(t, err) + tools.PrintResource(t, allShares) + + foundShare := -1 + for i, s := range allShares { + tools.PrintResource(t, &s) + if share.ID == s.ID { + foundShare = i + break + } + } + if foundShare == -1 { + t.Fatalf("Share %s not found in list", share.ID) + } + + th.AssertDeepEquals(t, *share, allShares[foundShare]) +} diff --git a/openstack/dns/v2/zones/requests.go b/openstack/dns/v2/zones/requests.go index b8ac4cf8a5..b0049a9148 100644 --- a/openstack/dns/v2/zones/requests.go +++ b/openstack/dns/v2/zones/requests.go @@ -179,6 +179,48 @@ func Delete(ctx context.Context, client *gophercloud.ServiceClient, zoneID strin return } +// ListSharesOptsBuilder allows extensions to add additional parameters to the List +// request. +type ListSharesOptsBuilder interface { + ToZoneListSharesHeadersMap() (map[string]string, error) +} + +// ListSharesOpts is a structure that holds parameters for listing zone shares. +type ListSharesOpts struct { + AllProjects bool `h:"X-Auth-All-Projects"` +} + +// ToZoneListSharesHeadersMap formats a ListSharesOpts into header parameters. +func (opts ListSharesOpts) ToZoneListSharesHeadersMap() (map[string]string, error) { + return gophercloud.BuildHeaders(opts) +} + +// ListShares implements a zone list shares request. +func ListShares(client *gophercloud.ServiceClient, zoneID string, opts ListSharesOptsBuilder) pagination.Pager { + var h map[string]string + var err error + + if opts != nil { + h, err = opts.ToZoneListSharesHeadersMap() + if err != nil { + return pagination.Pager{Err: err} + } + } + + pager := pagination.NewPager(client, sharesBaseURL(client, zoneID), func(r pagination.PageResult) pagination.Page { + return ZoneSharePage{pagination.LinkedPageBase{PageResult: r}} + }) + pager.Headers = h + return pager +} + +// GetShare returns information about a shared zone, given its ID. +func GetShare(ctx context.Context, client *gophercloud.ServiceClient, zoneID, shareID string) (r ZoneShareResult) { + resp, err := client.Get(ctx, shareURL(client, zoneID, shareID), &r.Body, nil) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} + // request body for sharing a zone. type ShareOptsBuilder interface { ToShareMap() (map[string]interface{}, error) @@ -198,14 +240,14 @@ func (opts ShareZoneOpts) ToShareMap() (map[string]interface{}, error) { } // Share shares a zone with another project. -func Share(ctx context.Context, client *gophercloud.ServiceClient, zoneID string, opts ShareOptsBuilder) (r gophercloud.ErrResult) { +func Share(ctx context.Context, client *gophercloud.ServiceClient, zoneID string, opts ShareOptsBuilder) (r ZoneShareResult) { body, err := gophercloud.BuildRequestBody(opts, "") if err != nil { r.Err = err return } - resp, err := client.Post(ctx, zoneShareURL(client, zoneID), body, nil, &gophercloud.RequestOpts{ + resp, err := client.Post(ctx, sharesBaseURL(client, zoneID), body, &r.Body, &gophercloud.RequestOpts{ OkCodes: []int{201}, }) _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) @@ -214,7 +256,7 @@ func Share(ctx context.Context, client *gophercloud.ServiceClient, zoneID string // Unshare removes a share for a zone. func Unshare(ctx context.Context, client *gophercloud.ServiceClient, zoneID, shareID string) (r gophercloud.ErrResult) { - resp, err := client.Delete(ctx, zoneUnshareURL(client, zoneID, shareID), &gophercloud.RequestOpts{ + resp, err := client.Delete(ctx, shareURL(client, zoneID, shareID), &gophercloud.RequestOpts{ OkCodes: []int{204}, }) _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) diff --git a/openstack/dns/v2/zones/results.go b/openstack/dns/v2/zones/results.go index 7ccf5ace9b..9b93e4f4b0 100644 --- a/openstack/dns/v2/zones/results.go +++ b/openstack/dns/v2/zones/results.go @@ -173,3 +173,81 @@ func (r *Zone) UnmarshalJSON(b []byte) error { return err } + +// ZoneShare represents a shared zone. +type ZoneShare struct { + // ID uniquely identifies this zone share. + ID string `json:"id"` + + // ZoneID is the ID of the zone being shared. + ZoneID string `json:"zone_id"` + + // ProjectID is the ID of the project with which the zone is shared. + ProjectID string `json:"project_id"` + + // TargetProjectID is the ID of the project with which the zone is shared. + TargetProjectID string `json:"target_project_id"` + + // CreatedAt is the date when the zone share was created. + CreatedAt time.Time `json:"-"` + + // UpdatedAt is the date when the zone share was last updated. + UpdatedAt time.Time `json:"-"` +} + +func (r *ZoneShare) UnmarshalJSON(b []byte) error { + type tmp ZoneShare + var s struct { + tmp + CreatedAt gophercloud.JSONRFC3339MilliNoZ `json:"created_at"` + UpdatedAt gophercloud.JSONRFC3339MilliNoZ `json:"updated_at"` + } + + err := json.Unmarshal(b, &s) + if err != nil { + return err + } + *r = ZoneShare(s.tmp) + + r.CreatedAt = time.Time(s.CreatedAt) + r.UpdatedAt = time.Time(s.UpdatedAt) + + return nil +} + +// ZoneShareResult is the result of a GetZoneShare request. +type ZoneShareResult struct { + gophercloud.Result +} + +// Extract interprets a GetResult, CreateResult or UpdateResult as a Zone. +// An error is returned if the original call or the extraction failed. +func (r ZoneShareResult) Extract() (*ZoneShare, error) { + var s *ZoneShare + err := r.ExtractInto(&s) + return s, err +} + +// ZoneSharePage is a single page of ZoneShare results. +type ZoneSharePage struct { + pagination.LinkedPageBase +} + +// IsEmpty returns true if the page contains no results. +func (r ZoneSharePage) IsEmpty() (bool, error) { + if r.StatusCode == 204 { + return true, nil + } + + s, err := ExtractZoneShares(r) + return len(s) == 0, err +} + +// ExtractZoneShares extracts a slice of ZoneShares from a List result. +func ExtractZoneShares(r pagination.Page) ([]ZoneShare, error) { + var s struct { + ZoneShares []ZoneShare `json:"shared_zones"` + } + err := (r.(ZoneSharePage)).ExtractInto(&s) + return s.ZoneShares, err +} diff --git a/openstack/dns/v2/zones/testing/fixtures_test.go b/openstack/dns/v2/zones/testing/fixtures_test.go index 6b0ee7ccf7..c52002bed8 100644 --- a/openstack/dns/v2/zones/testing/fixtures_test.go +++ b/openstack/dns/v2/zones/testing/fixtures_test.go @@ -300,3 +300,57 @@ func HandleDeleteSuccessfully(t *testing.T) { fmt.Fprint(w, DeleteZoneResponse) }) } + +// ShareZoneResponse is a sample response to share a zone. +const ShareZoneResponse = ` +{ + "id": "fd40b017-bf97-461c-8d30-d4e922b28edd", + "zone_id": "a3365b47-ee93-43ad-9a60-2b2ca96b1898", + "project_id": "16ade46c85a1435bb86d9138d37da57e", + "target_project_id": "232e37df46af42089710e2ae39111c2f", + "created_at": "2022-11-30T22:20:27.000000", + "updated_at": null, + "links": { + "self": "http://127.0.0.1:60053/v2/zones/a3365b47-ee93-43ad-9a60-2b2ca96b1898/shares/fd40b017-bf97-461c-8d30-d4e922b28edd", + "zone": "http://127.0.0.1:60053/v2/zones/a3365b47-ee93-43ad-9a60-2b2ca96b1898" + } +} +` + +// ShareZoneCreatedAt is the expected created at time for the shared zone +var ShareZoneCreatedAt, _ = time.Parse(gophercloud.RFC3339MilliNoZ, "2022-11-30T22:20:27.000000") + +// ShareZone is the expected shared zone +var ShareZone = zones.ZoneShare{ + ID: "fd40b017-bf97-461c-8d30-d4e922b28edd", + ZoneID: "a3365b47-ee93-43ad-9a60-2b2ca96b1898", + ProjectID: "16ade46c85a1435bb86d9138d37da57e", + TargetProjectID: "232e37df46af42089710e2ae39111c2f", + CreatedAt: ShareZoneCreatedAt, +} + +// ListSharesResponse is a sample response to list zone shares. +const ListSharesResponse = ` +{ + "shared_zones": [ + { + "id": "fd40b017-bf97-461c-8d30-d4e922b28edd", + "zone_id": "a3365b47-ee93-43ad-9a60-2b2ca96b1898", + "project_id": "16ade46c85a1435bb86d9138d37da57e", + "target_project_id": "232e37df46af42089710e2ae39111c2f", + "created_at": "2022-11-30T22:20:27.000000", + "updated_at": null, + "links": { + "self": "http://127.0.0.1:60053/v2/zones/a3365b47-ee93-43ad-9a60-2b2ca96b1898/shares/fd40b017-bf97-461c-8d30-d4e922b28edd", + "zone": "http://127.0.0.1:60053/v2/zones/a3365b47-ee93-43ad-9a60-2b2ca96b1898" + } + } + ], + "links": { + "self": "http://127.0.0.1:60053/v2/zones/a3365b47-ee93-43ad-9a60-2b2ca96b1898/shares" + } +} +` + +// ListZoneShares is the expected list of shared zones +var ListZoneShares = []zones.ZoneShare{ShareZone} diff --git a/openstack/dns/v2/zones/testing/requests_test.go b/openstack/dns/v2/zones/testing/requests_test.go index b75b99e967..0e60364ddb 100644 --- a/openstack/dns/v2/zones/testing/requests_test.go +++ b/openstack/dns/v2/zones/testing/requests_test.go @@ -3,6 +3,7 @@ package testing import ( "context" "encoding/json" + "fmt" "io" "net/http" "testing" @@ -127,11 +128,14 @@ func TestShare(t *testing.T) { th.CheckDeepEquals(t, expectedBody, reqBody) w.WriteHeader(http.StatusCreated) + w.Header().Add("Content-Type", "application/json") + fmt.Fprint(w, ShareZoneResponse) }) opts := zones.ShareZoneOpts{TargetProjectID: "project-id"} - err := zones.Share(context.TODO(), client.ServiceClient(), "zone-id", opts).ExtractErr() + zone, err := zones.Share(context.TODO(), client.ServiceClient(), "zone-id", opts).Extract() th.AssertNoErr(t, err) + th.CheckDeepEquals(t, ShareZone, *zone) } func TestUnshare(t *testing.T) { @@ -146,3 +150,25 @@ func TestUnshare(t *testing.T) { err := zones.Unshare(context.TODO(), client.ServiceClient(), "zone-id", "share-id").ExtractErr() th.AssertNoErr(t, err) } + +func TestListShares(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + + th.Mux.HandleFunc("/zones/zone-id/shares", func(w http.ResponseWriter, r *http.Request) { + th.AssertEquals(t, r.Method, "GET") + th.AssertEquals(t, "true", r.Header.Get("X-Auth-All-Projects")) + + w.Header().Add("Content-Type", "application/json") + fmt.Fprint(w, ListSharesResponse) + }) + + opts := zones.ListSharesOpts{ + AllProjects: true, + } + pages, err := zones.ListShares(client.ServiceClient(), "zone-id", opts).AllPages(context.TODO()) + th.AssertNoErr(t, err) + actual, err := zones.ExtractZoneShares(pages) + th.AssertNoErr(t, err) + th.CheckDeepEquals(t, ListZoneShares, actual) +} diff --git a/openstack/dns/v2/zones/urls.go b/openstack/dns/v2/zones/urls.go index ba156882f8..99416a3e19 100644 --- a/openstack/dns/v2/zones/urls.go +++ b/openstack/dns/v2/zones/urls.go @@ -12,12 +12,12 @@ func zoneURL(c *gophercloud.ServiceClient, zoneID string) string { return c.ServiceURL("zones", zoneID) } -// zoneShareURL returns the URL for sharing a zone. -func zoneShareURL(c *gophercloud.ServiceClient, zoneID string) string { +// sharesBaseURL returns the URL for shared zones. +func sharesBaseURL(c *gophercloud.ServiceClient, zoneID string) string { return c.ServiceURL("zones", zoneID, "shares") } -// zoneUnshareURL returns the URL for unsharing a zone. -func zoneUnshareURL(c *gophercloud.ServiceClient, zoneID, shareID string) string { - return c.ServiceURL("zones", zoneID, "shares", shareID) +// shareURL returns the URL for a shared zone. +func shareURL(c *gophercloud.ServiceClient, zoneID, sharedZoneID string) string { + return c.ServiceURL("zones", zoneID, "shares", sharedZoneID) } From 531587a39a19e9ac0987c4c942163f5fc32c535f Mon Sep 17 00:00:00 2001 From: Pierre Prinetti Date: Thu, 22 May 2025 15:49:48 +0200 Subject: [PATCH 138/353] acceptance: Prevent 409 when bulk-creating secgroup rules Reduce the randomness of port creation. --- .../openstack/networking/v2/extensions/extensions.go | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/internal/acceptance/openstack/networking/v2/extensions/extensions.go b/internal/acceptance/openstack/networking/v2/extensions/extensions.go index f50878abeb..9565d1e30c 100644 --- a/internal/acceptance/openstack/networking/v2/extensions/extensions.go +++ b/internal/acceptance/openstack/networking/v2/extensions/extensions.go @@ -140,20 +140,18 @@ func CreateSecurityGroupRule(t *testing.T, client *gophercloud.ServiceClient, se return rule, nil } -// CreateSecurityGroupRulesBulk will create security group rules with a random name -// and random port between 80 and 99. +// CreateSecurityGroupRulesBulk will create 3 security group rules with ports between 1080 and 1099. // An error will be returned if one was failed to be created. func CreateSecurityGroupRulesBulk(t *testing.T, client *gophercloud.ServiceClient, secGroupID string) ([]rules.SecGroupRule, error) { t.Logf("Attempting to bulk create security group rules in group: %s", secGroupID) sgRulesCreateOpts := make([]rules.CreateOpts, 3) - for i := range 3 { - description := "Rule description" - fromPort := tools.RandomInt(1080, 1089) - toPort := tools.RandomInt(1090, 1099) + for i := range sgRulesCreateOpts { + fromPort := 1080 + i + toPort := tools.RandomInt(fromPort, 1099) sgRulesCreateOpts[i] = rules.CreateOpts{ - Description: description, + Description: "Rule description", Direction: "ingress", EtherType: "IPv4", SecGroupID: secGroupID, From de9d73759f507118c31b88061ece563a9be2bc2f Mon Sep 17 00:00:00 2001 From: kayrus Date: Thu, 8 May 2025 19:07:33 +0200 Subject: [PATCH 139/353] identity: add support for string boolean in users' enabled member --- openstack/identity/v3/users/results.go | 19 ++++++++++++++++++- .../v3/users/testing/fixtures_test.go | 2 +- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/openstack/identity/v3/users/results.go b/openstack/identity/v3/users/results.go index dc48da2a2f..d9e7aaab66 100644 --- a/openstack/identity/v3/users/results.go +++ b/openstack/identity/v3/users/results.go @@ -2,6 +2,8 @@ package users import ( "encoding/json" + "fmt" + "strconv" "time" "github.com/gophercloud/gophercloud/v2" @@ -20,7 +22,7 @@ type User struct { DomainID string `json:"domain_id"` // Enabled is whether or not the user is enabled. - Enabled bool `json:"enabled"` + Enabled bool `json:"-"` // Extra is a collection of miscellaneous key/values. Extra map[string]any `json:"-"` @@ -45,6 +47,7 @@ func (r *User) UnmarshalJSON(b []byte) error { type tmp User var s struct { tmp + Enabled any `json:"enabled"` Extra map[string]any `json:"extra"` PasswordExpiresAt gophercloud.JSONRFC3339MilliNoZ `json:"password_expires_at"` } @@ -56,6 +59,20 @@ func (r *User) UnmarshalJSON(b []byte) error { r.PasswordExpiresAt = time.Time(s.PasswordExpiresAt) + switch t := s.Enabled.(type) { + case nil: + r.Enabled = false + case bool: + r.Enabled = t + case string: + r.Enabled, err = strconv.ParseBool(t) + if err != nil { + return fmt.Errorf("Failed to parse Enabled %q: %v", t, err) + } + default: + return fmt.Errorf("Unknown type for Enabled: %T (value: %v)", t, t) + } + // Collect other fields and bundle them into Extra // but only if a field titled "extra" wasn't sent. if s.Extra != nil { diff --git a/openstack/identity/v3/users/testing/fixtures_test.go b/openstack/identity/v3/users/testing/fixtures_test.go index faff58d4d0..fbabad6eeb 100644 --- a/openstack/identity/v3/users/testing/fixtures_test.go +++ b/openstack/identity/v3/users/testing/fixtures_test.go @@ -25,7 +25,7 @@ const ListOutput = ` "users": [ { "domain_id": "default", - "enabled": true, + "enabled": "True", "id": "2844b2a08be147a08ef58317d6471f1f", "links": { "self": "http://example.com/identity/v3/users/2844b2a08be147a08ef58317d6471f1f" From cece9a4d6559a3cad7b3b28b0cc85dcfc5de301e Mon Sep 17 00:00:00 2001 From: kayrus Date: Wed, 10 Jul 2024 16:33:02 +0200 Subject: [PATCH 140/353] Adjust List func to accept a Builder in tenants, routers and security groups packages --- openstack/identity/v2/tenants/requests.go | 18 +++++++++++++++--- .../v2/extensions/layer3/routers/requests.go | 13 ++++++++----- .../v2/extensions/security/rules/requests.go | 13 ++++++++----- 3 files changed, 31 insertions(+), 13 deletions(-) diff --git a/openstack/identity/v2/tenants/requests.go b/openstack/identity/v2/tenants/requests.go index a08980df2c..84a8b9df1d 100644 --- a/openstack/identity/v2/tenants/requests.go +++ b/openstack/identity/v2/tenants/requests.go @@ -7,6 +7,12 @@ import ( "github.com/gophercloud/gophercloud/v2/pagination" ) +// ListOptsBuilder allows extensions to add additional parameters to the +// List request. +type ListOptsBuilder interface { + ToTenantListQuery() (string, error) +} + // ListOpts filters the Tenants that are returned by the List call. type ListOpts struct { // Marker is the ID of the last Tenant on the previous page. @@ -16,15 +22,21 @@ type ListOpts struct { Limit int `q:"limit"` } +// ToTenantListQuery formats a ListOpts into a query string. +func (opts ListOpts) ToTenantListQuery() (string, error) { + q, err := gophercloud.BuildQueryString(opts) + return q.String(), err +} + // List enumerates the Tenants to which the current token has access. -func List(client *gophercloud.ServiceClient, opts *ListOpts) pagination.Pager { +func List(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { url := listURL(client) if opts != nil { - q, err := gophercloud.BuildQueryString(opts) + query, err := opts.ToTenantListQuery() if err != nil { return pagination.Pager{Err: err} } - url += q.String() + url += query } return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { return TenantPage{pagination.LinkedPageBase{PageResult: r}} diff --git a/openstack/networking/v2/extensions/layer3/routers/requests.go b/openstack/networking/v2/extensions/layer3/routers/requests.go index 5d31ec1138..def4699db3 100644 --- a/openstack/networking/v2/extensions/layer3/routers/requests.go +++ b/openstack/networking/v2/extensions/layer3/routers/requests.go @@ -55,12 +55,15 @@ func (opts ListOpts) ToRouterListQuery() (string, error) { // Default policy settings return only those routers that are owned by the // tenant who submits the request, unless an admin user submits the request. func List(c *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { - q, err := opts.ToRouterListQuery() - if err != nil { - return pagination.Pager{Err: err} + url := rootURL(c) + if opts != nil { + query, err := opts.ToRouterListQuery() + if err != nil { + return pagination.Pager{Err: err} + } + url += query } - u := rootURL(c) + q - return pagination.NewPager(c, u, func(r pagination.PageResult) pagination.Page { + return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page { return RouterPage{pagination.LinkedPageBase{PageResult: r}} }) } diff --git a/openstack/networking/v2/extensions/security/rules/requests.go b/openstack/networking/v2/extensions/security/rules/requests.go index 2bb8ffc6c2..d78b6b8ec3 100644 --- a/openstack/networking/v2/extensions/security/rules/requests.go +++ b/openstack/networking/v2/extensions/security/rules/requests.go @@ -51,12 +51,15 @@ func (opts ListOpts) ToSecGroupListQuery() (string, error) { // security group rules. It accepts a ListOpts struct, which allows you to filter // and sort the returned collection for greater efficiency. func List(c *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { - q, err := opts.ToSecGroupListQuery() - if err != nil { - return pagination.Pager{Err: err} + url := rootURL(c) + if opts != nil { + query, err := opts.ToSecGroupListQuery() + if err != nil { + return pagination.Pager{Err: err} + } + url += query } - u := rootURL(c) + q - return pagination.NewPager(c, u, func(r pagination.PageResult) pagination.Page { + return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page { return SecGroupRulePage{pagination.LinkedPageBase{PageResult: r}} }) } From a1f6ade8361a76504d6bee7496ea3221b797b8a0 Mon Sep 17 00:00:00 2001 From: TOMOFUMI-KONDO Date: Sat, 15 Mar 2025 13:01:38 +0900 Subject: [PATCH 141/353] blockstorage: add manage-existing api call Implemented missing blockstorage api call to manage existing volume. ref. https://docs.openstack.org/api-ref/block-storage/v3/#manage-an-existing-volume --- .../blockstorage/v3/manageablevolumes/doc.go | 32 +++++++ .../v3/manageablevolumes/requests.go | 61 ++++++++++++ .../v3/manageablevolumes/results.go | 22 +++++ .../v3/manageablevolumes/testing/doc.go | 2 + .../testing/fixtures_test.go | 93 +++++++++++++++++++ .../testing/requests_test.go | 44 +++++++++ .../blockstorage/v3/manageablevolumes/urls.go | 7 ++ 7 files changed, 261 insertions(+) create mode 100644 openstack/blockstorage/v3/manageablevolumes/doc.go create mode 100644 openstack/blockstorage/v3/manageablevolumes/requests.go create mode 100644 openstack/blockstorage/v3/manageablevolumes/results.go create mode 100644 openstack/blockstorage/v3/manageablevolumes/testing/doc.go create mode 100644 openstack/blockstorage/v3/manageablevolumes/testing/fixtures_test.go create mode 100644 openstack/blockstorage/v3/manageablevolumes/testing/requests_test.go create mode 100644 openstack/blockstorage/v3/manageablevolumes/urls.go diff --git a/openstack/blockstorage/v3/manageablevolumes/doc.go b/openstack/blockstorage/v3/manageablevolumes/doc.go new file mode 100644 index 0000000000..a2217fc0fb --- /dev/null +++ b/openstack/blockstorage/v3/manageablevolumes/doc.go @@ -0,0 +1,32 @@ +/* +Package manageablevolumes information and interaction with manageable volumes +for the OpenStack Block Storage service. + +NOTE: Requires at least microversion 3.8 + +Example to manage an existing volume + + manageOpts := manageablevolumes.ManageExistingOpts{ + Host: "host@lvm#LVM", + Ref: map[string]string{ + "source-name": "volume-73796b96-169f-4675-a5bc-73fc0f8f9a17", + }, + Name: "New Volume", + AvailabilityZone: "nova", + Description: "Volume imported from existingLV", + VolumeType: "lvm", + Bootable: true, + Metadata: map[string]string{ + "key1": "value1", + "key2": "value2" + }, + } + + managedVolume, err := manageablevolumes.ManageExisting(context.TODO(), client, manageOpts).Extract() + if err != nil { + log.Fatal(err) + } + + fmt.Printf("Managed volume: %+v\n", managedVolume) +*/ +package manageablevolumes diff --git a/openstack/blockstorage/v3/manageablevolumes/requests.go b/openstack/blockstorage/v3/manageablevolumes/requests.go new file mode 100644 index 0000000000..42c5593cda --- /dev/null +++ b/openstack/blockstorage/v3/manageablevolumes/requests.go @@ -0,0 +1,61 @@ +package manageablevolumes + +import ( + "context" + + "github.com/gophercloud/gophercloud/v2" +) + +// ManageExistingOptsBuilder allows extentions to add additional parameters to the ManageExisting request. +type ManageExistingOptsBuilder interface { + ToManageExistingMap() (map[string]any, error) +} + +// ManageExistingOpts contains options for managing a existing volume. +// This object is passed to the volumes.ManageExisting function. +// For more information about the parameters, see the Volume object and OpenStack BlockStorage API Guide. +type ManageExistingOpts struct { + // The OpenStack Block Storage host where the existing resource resides. + // Optional only if cluster field is provided. + Host string `json:"host,omitempty"` + // The OpenStack Block Storage cluster where the resource resides. + // Optional only if host field is provided. + Cluster string `json:"cluster,omitempty"` + // A reference to the existing volume. + // The internal structure of this reference depends on the volume driver implementation. + // For details about the required elements in the structure, see the documentation for the volume driver. + Ref map[string]string `json:"ref,omitempty"` + // Human-readable display name for the volume. + Name string `json:"name,omitempty"` + // The availability zone. + AvailabilityZone string `json:"availability_zone,omitempty"` + // Human-readable description for the volume. + Description string `json:"description,omitempty"` + // The associated volume type + VolumeType string `json:"volume_type,omitempty"` + // Indicates whether this is a bootable volume. + Bootable bool `json:"bootable,omitempty"` + // One or more metadata key and value pairs to associate with the volume. + Metadata map[string]string `json:"metadata,omitempty"` +} + +// ToManageExistingMap assembles a request body based on the contents of a ManageExistingOpts. +func (opts ManageExistingOpts) ToManageExistingMap() (map[string]any, error) { + return gophercloud.BuildRequestBody(opts, "volume") +} + +// ManageExisting will manage an existing volume based on the values in ManageExistingOpts. +// To extract the Volume object from response, call the Extract method on the ManageExistingResult. +func ManageExisting(ctx context.Context, client *gophercloud.ServiceClient, opts ManageExistingOptsBuilder) (r ManageExistingResult) { + b, err := opts.ToManageExistingMap() + if err != nil { + r.Err = err + return + } + + resp, err := client.Post(ctx, createURL(client), b, &r.Body, &gophercloud.RequestOpts{ + OkCodes: []int{202}, + }) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} diff --git a/openstack/blockstorage/v3/manageablevolumes/results.go b/openstack/blockstorage/v3/manageablevolumes/results.go new file mode 100644 index 0000000000..317ed21fb3 --- /dev/null +++ b/openstack/blockstorage/v3/manageablevolumes/results.go @@ -0,0 +1,22 @@ +package manageablevolumes + +import ( + "github.com/gophercloud/gophercloud/v2" + "github.com/gophercloud/gophercloud/v2/openstack/blockstorage/v3/volumes" +) + +type ManageExistingResult struct { + gophercloud.Result +} + +// Extract will get the Volume object out of the ManageExistingResult object. +func (r ManageExistingResult) Extract() (*volumes.Volume, error) { + var s volumes.Volume + err := r.ExtractInto(&s) + return &s, err +} + +// ExtractInto converts our response data into a volume struct +func (r ManageExistingResult) ExtractInto(v any) error { + return r.Result.ExtractIntoStructPtr(v, "volume") +} diff --git a/openstack/blockstorage/v3/manageablevolumes/testing/doc.go b/openstack/blockstorage/v3/manageablevolumes/testing/doc.go new file mode 100644 index 0000000000..4acd665887 --- /dev/null +++ b/openstack/blockstorage/v3/manageablevolumes/testing/doc.go @@ -0,0 +1,2 @@ +// manageablevolumes unit tests +package testing diff --git a/openstack/blockstorage/v3/manageablevolumes/testing/fixtures_test.go b/openstack/blockstorage/v3/manageablevolumes/testing/fixtures_test.go new file mode 100644 index 0000000000..5fdc8fb995 --- /dev/null +++ b/openstack/blockstorage/v3/manageablevolumes/testing/fixtures_test.go @@ -0,0 +1,93 @@ +package testing + +import ( + "fmt" + "net/http" + "testing" + + th "github.com/gophercloud/gophercloud/v2/testhelper" + fake "github.com/gophercloud/gophercloud/v2/testhelper/client" +) + +func MockManageExistingResponse(t *testing.T) { + th.Mux.HandleFunc("/manageable_volumes", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "POST") + th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "Content-Type", "application/json") + th.TestHeader(t, r, "Accept", "application/json") + th.TestJSONRequest(t, r, ` +{ + "volume": { + "host": "host@lvm#LVM", + "ref": { + "source-name": "volume-73796b96-169f-4675-a5bc-73fc0f8f9a17" + }, + "name": "New Volume", + "availability_zone": "nova", + "description": "Volume imported from existingLV", + "volume_type": "lvm", + "bootable": true, + "metadata": { + "key1": "value1", + "key2": "value2" + } + } +} + `) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusAccepted) + + fmt.Fprint(w, ` +{ + "volume": { + "id": "23cf872b-c781-4cd4-847d-5f2ec8cbd91c", + "status": "creating", + "size": 0, + "availability_zone": "nova", + "created_at": "2025-03-20T11:58:05.000000", + "updated_at": "2025-03-20T11:58:05.000000", + "name": "New Volume", + "description": "Volume imported from existingLV", + "volume_type": "lvm", + "snapshot_id": null, + "source_volid": null, + "metadata": { + "key1": "value1", + "key2": "value2" + }, + "links": [ + { + "href": "http://10.0.2.15:8776/v3/87c8522052ca4eed98bc672b4c1a3ddb/volumes/23cf872b-c781-4cd4-847d-5f2ec8cbd91c", + "rel": "self" + }, + { + "href": "http://10.0.2.15:8776/87c8522052ca4eed98bc672b4c1a3ddb/volumes/23cf872b-c781-4cd4-847d-5f2ec8cbd91c", + "rel": "bookmark" + } + ], + "user_id": "eae1472b5fc5496998a3d06550929e7e", + "bootable": "true", + "encrypted": false, + "replication_status": null, + "consistencygroup_id": null, + "multiattach": false, + "attachments": [], + "created_at": "2014-07-18T00:12:54.000000", + "migration_status": null, + "group_id": null, + "provider_id": null, + "shared_targets": true, + "service_uuid": null, + "cluster_name": null, + "volume_type_id": "a218796e-605b-4b6f-9dfc-8be95a0d7d03", + "consumes_quota": true, + "os-vol-mig-status-attr:migstat": null, + "os-vol-mig-status-attr:name_id": null, + "os-vol-tenant-attr:tenant_id": "87c8522052ca4eed98bc672b4c1a3ddb", + "os-vol-host-attr:host": "host@lvm#LVM" + } +} + `) + }) +} diff --git a/openstack/blockstorage/v3/manageablevolumes/testing/requests_test.go b/openstack/blockstorage/v3/manageablevolumes/testing/requests_test.go new file mode 100644 index 0000000000..cabbfde4ea --- /dev/null +++ b/openstack/blockstorage/v3/manageablevolumes/testing/requests_test.go @@ -0,0 +1,44 @@ +package testing + +import ( + "context" + "testing" + + "github.com/gophercloud/gophercloud/v2/openstack/blockstorage/v3/manageablevolumes" + th "github.com/gophercloud/gophercloud/v2/testhelper" + "github.com/gophercloud/gophercloud/v2/testhelper/client" +) + +func TestManageExisting(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + + MockManageExistingResponse(t) + + options := &manageablevolumes.ManageExistingOpts{ + Host: "host@lvm#LVM", + Ref: map[string]string{"source-name": "volume-73796b96-169f-4675-a5bc-73fc0f8f9a17"}, + Name: "New Volume", + AvailabilityZone: "nova", + Description: "Volume imported from existingLV", + VolumeType: "lvm", + Bootable: true, + Metadata: map[string]string{ + "key1": "value1", + "key2": "value2", + }, + } + n, err := manageablevolumes.ManageExisting(context.TODO(), client.ServiceClient(), options).Extract() + th.AssertNoErr(t, err) + + th.AssertEquals(t, n.Host, "host@lvm#LVM") + th.AssertEquals(t, n.Name, "New Volume") + th.AssertEquals(t, n.AvailabilityZone, "nova") + th.AssertEquals(t, n.Description, "Volume imported from existingLV") + th.AssertEquals(t, n.Bootable, "true") + th.AssertDeepEquals(t, n.Metadata, map[string]string{ + "key1": "value1", + "key2": "value2", + }) + th.AssertEquals(t, n.ID, "23cf872b-c781-4cd4-847d-5f2ec8cbd91c") +} diff --git a/openstack/blockstorage/v3/manageablevolumes/urls.go b/openstack/blockstorage/v3/manageablevolumes/urls.go new file mode 100644 index 0000000000..c58c94a396 --- /dev/null +++ b/openstack/blockstorage/v3/manageablevolumes/urls.go @@ -0,0 +1,7 @@ +package manageablevolumes + +import "github.com/gophercloud/gophercloud/v2" + +func createURL(c *gophercloud.ServiceClient) string { + return c.ServiceURL("manageable_volumes") +} From 181673ba95b740036d5b2d225ce549fe2d54c1e1 Mon Sep 17 00:00:00 2001 From: TOMOFUMI-KONDO Date: Sun, 23 Mar 2025 22:06:24 +0900 Subject: [PATCH 142/353] blockstorage: add unmanage api call Implemented missing blockstorage api call to unmanage volume. ref. https://docs.openstack.org/api-ref/block-storage/v3/#unmanage-a-volume --- openstack/blockstorage/v3/volumes/doc.go | 7 +++++++ openstack/blockstorage/v3/volumes/requests.go | 11 +++++++++++ openstack/blockstorage/v3/volumes/results.go | 5 +++++ .../v3/volumes/testing/fixtures_test.go | 16 ++++++++++++++++ .../v3/volumes/testing/requests_test.go | 10 ++++++++++ 5 files changed, 49 insertions(+) diff --git a/openstack/blockstorage/v3/volumes/doc.go b/openstack/blockstorage/v3/volumes/doc.go index 2ab4af93ee..e018b57a8d 100644 --- a/openstack/blockstorage/v3/volumes/doc.go +++ b/openstack/blockstorage/v3/volumes/doc.go @@ -157,5 +157,12 @@ Example of Attaching a Volume to an Instance if err != nil { panic(err) } + +Example of Unmanaging a Volume + + err := volumes.Unmanage(context.TODO(), client, volume.ID).ExtractErr() + if err != nil { + panic(err) + } */ package volumes diff --git a/openstack/blockstorage/v3/volumes/requests.go b/openstack/blockstorage/v3/volumes/requests.go index 4dc2c1be7e..1026d1ecaa 100644 --- a/openstack/blockstorage/v3/volumes/requests.go +++ b/openstack/blockstorage/v3/volumes/requests.go @@ -775,3 +775,14 @@ func ResetStatus(ctx context.Context, client *gophercloud.ServiceClient, id stri _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) return } + +// Unmanage removes a volume from Block Storage management without +// removing the back-end storage object that is associated with it. +func Unmanage(ctx context.Context, client *gophercloud.ServiceClient, id string) (r UnmanageResult) { + body := map[string]any{"os-unmanage": make(map[string]any)} + resp, err := client.Post(ctx, actionURL(client, id), body, nil, &gophercloud.RequestOpts{ + OkCodes: []int{202}, + }) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} diff --git a/openstack/blockstorage/v3/volumes/results.go b/openstack/blockstorage/v3/volumes/results.go index 3f184b398e..e99ef5e197 100644 --- a/openstack/blockstorage/v3/volumes/results.go +++ b/openstack/blockstorage/v3/volumes/results.go @@ -399,3 +399,8 @@ type ReImageResult struct { type ResetStatusResult struct { gophercloud.ErrResult } + +// UnmanageResult contains the response error from a Unmanage request. +type UnmanageResult struct { + gophercloud.ErrResult +} diff --git a/openstack/blockstorage/v3/volumes/testing/fixtures_test.go b/openstack/blockstorage/v3/volumes/testing/fixtures_test.go index 9b4630a978..3e156aca1e 100644 --- a/openstack/blockstorage/v3/volumes/testing/fixtures_test.go +++ b/openstack/blockstorage/v3/volumes/testing/fixtures_test.go @@ -648,3 +648,19 @@ func MockResetStatusResponse(t *testing.T) { w.WriteHeader(http.StatusAccepted) }) } + +func MockUnmanageResponse(t *testing.T) { + th.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "POST") + th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "Content-Type", "application/json") + th.TestJSONRequest(t, r, ` +{ + "os-unmanage": {} +} + `) + + w.WriteHeader(http.StatusAccepted) + }) +} diff --git a/openstack/blockstorage/v3/volumes/testing/requests_test.go b/openstack/blockstorage/v3/volumes/testing/requests_test.go index 5e32346747..4fbd79f00c 100644 --- a/openstack/blockstorage/v3/volumes/testing/requests_test.go +++ b/openstack/blockstorage/v3/volumes/testing/requests_test.go @@ -538,3 +538,13 @@ func TestResetStatus(t *testing.T) { err := volumes.ResetStatus(context.TODO(), client.ServiceClient(), "cd281d77-8217-4830-be95-9528227c105c", options).ExtractErr() th.AssertNoErr(t, err) } + +func TestUnmanage(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + + MockUnmanageResponse(t) + + err := volumes.Unmanage(context.TODO(), client.ServiceClient(), "cd281d77-8217-4830-be95-9528227c105c").ExtractErr() + th.AssertNoErr(t, err) +} From c7705dc36c6787d4e355a7e0d87cbc289f9e0b74 Mon Sep 17 00:00:00 2001 From: TOMOFUMI-KONDO Date: Mon, 24 Mar 2025 09:35:15 +0900 Subject: [PATCH 143/353] blockstorage: acceptance test for manage/unmanage volume Added acceptance test for managing a existing volume and unmanaging a volume api calls. --- .../openstack/blockstorage/v3/blockstorage.go | 71 +++++++++++++++++++ .../blockstorage/v3/manageablevolumes_test.go | 57 +++++++++++++++ 2 files changed, 128 insertions(+) create mode 100644 internal/acceptance/openstack/blockstorage/v3/manageablevolumes_test.go diff --git a/internal/acceptance/openstack/blockstorage/v3/blockstorage.go b/internal/acceptance/openstack/blockstorage/v3/blockstorage.go index 56cf612abf..d28ac05c40 100644 --- a/internal/acceptance/openstack/blockstorage/v3/blockstorage.go +++ b/internal/acceptance/openstack/blockstorage/v3/blockstorage.go @@ -14,6 +14,7 @@ import ( "github.com/gophercloud/gophercloud/v2" "github.com/gophercloud/gophercloud/v2/internal/acceptance/tools" "github.com/gophercloud/gophercloud/v2/openstack/blockstorage/v3/backups" + "github.com/gophercloud/gophercloud/v2/openstack/blockstorage/v3/manageablevolumes" "github.com/gophercloud/gophercloud/v2/openstack/blockstorage/v3/qos" "github.com/gophercloud/gophercloud/v2/openstack/blockstorage/v3/snapshots" "github.com/gophercloud/gophercloud/v2/openstack/blockstorage/v3/volumes" @@ -779,3 +780,73 @@ func ReImage(t *testing.T, client *gophercloud.ServiceClient, volume *volumes.Vo return nil } + +func Unmanage(t *testing.T, client *gophercloud.ServiceClient, volume *volumes.Volume) error { + t.Logf("Attempting to unmanage volume %s", volume.ID) + + err := volumes.Unmanage(context.TODO(), client, volume.ID).ExtractErr() + if err != nil { + return err + } + + gophercloud.WaitFor(context.TODO(), func(ctx context.Context) (bool, error) { + if _, err := volumes.Get(ctx, client, volume.ID).Extract(); err != nil { + if _, ok := err.(gophercloud.ErrResourceNotFound); ok { + return true, nil + } + return false, err + } + return false, nil + }) + + t.Logf("Successfully unmanaged volume %s", volume.ID) + + return nil +} + +func ManageExisting(t *testing.T, client *gophercloud.ServiceClient, volume *volumes.Volume) (*volumes.Volume, error) { + t.Logf("Attempting to manage existing volume %s", volume.Name) + + manageOpts := manageablevolumes.ManageExistingOpts{ + Host: volume.Host, + Ref: map[string]string{ + "source-name": fmt.Sprintf("volume-%s", volume.ID), + }, + Name: volume.Name, + AvailabilityZone: volume.AvailabilityZone, + Description: volume.Description, + VolumeType: volume.VolumeType, + Bootable: volume.Bootable == "true", + Metadata: volume.Metadata, + } + + managed, err := manageablevolumes.ManageExisting(context.TODO(), client, manageOpts).Extract() + if err != nil { + return managed, err + } + + ctx, cancel := context.WithTimeout(context.TODO(), 60*time.Second) + defer cancel() + + if err := volumes.WaitForStatus(ctx, client, managed.ID, "available"); err != nil { + return managed, err + } + + managed, err = volumes.Get(context.TODO(), client, managed.ID).Extract() + if err != nil { + return managed, err + } + + tools.PrintResource(t, managed) + th.AssertEquals(t, managed.Host, volume.Host) + th.AssertEquals(t, managed.Name, volume.Name) + th.AssertEquals(t, managed.AvailabilityZone, volume.AvailabilityZone) + th.AssertEquals(t, managed.Description, volume.Description) + th.AssertEquals(t, managed.VolumeType, volume.VolumeType) + th.AssertEquals(t, managed.Bootable, volume.Bootable) + th.AssertDeepEquals(t, managed.Metadata, volume.Metadata) + + t.Logf("Successfully managed existing volume %s", managed.ID) + + return managed, nil +} diff --git a/internal/acceptance/openstack/blockstorage/v3/manageablevolumes_test.go b/internal/acceptance/openstack/blockstorage/v3/manageablevolumes_test.go new file mode 100644 index 0000000000..a555e706cf --- /dev/null +++ b/internal/acceptance/openstack/blockstorage/v3/manageablevolumes_test.go @@ -0,0 +1,57 @@ +//go:build acceptance || blockstorage || volumes + +package v3 + +import ( + "context" + "testing" + + "github.com/gophercloud/gophercloud/v2/internal/acceptance/clients" + "github.com/gophercloud/gophercloud/v2/openstack/blockstorage/v3/volumes" + th "github.com/gophercloud/gophercloud/v2/testhelper" +) + +func TestManageableVolumes(t *testing.T) { + clients.RequireLong(t) + + client, err := clients.NewBlockStorageV3Client() + th.AssertNoErr(t, err) + + client.Microversion = "3.8" + + volume1, err := CreateVolume(t, client) + th.AssertNoErr(t, err) + + err = Unmanage(t, client, volume1) + if err != nil { + DeleteVolume(t, client, volume1) + } + th.AssertNoErr(t, err) + + managed1, err := ManageExisting(t, client, volume1) + th.AssertNoErr(t, err) + defer DeleteVolume(t, client, managed1) + + th.CheckEquals(t, volume1.Host, managed1.Host) + th.AssertEquals(t, volume1.Name, managed1.Name) + th.AssertEquals(t, volume1.AvailabilityZone, managed1.AvailabilityZone) + th.AssertEquals(t, volume1.Description, managed1.Description) + th.AssertEquals(t, volume1.VolumeType, managed1.VolumeType) + th.AssertEquals(t, volume1.Bootable, managed1.Bootable) + th.AssertDeepEquals(t, volume1.Metadata, managed1.Metadata) + th.AssertEquals(t, volume1.Size, managed1.Size) + + allPages, err := volumes.List(client, volumes.ListOpts{}).AllPages(context.TODO()) + th.AssertNoErr(t, err) + allVolumes, err := volumes.ExtractVolumes(allPages) + th.AssertNoErr(t, err) + + var found bool + for _, v := range allVolumes { + if v.ID == managed1.ID { + found = true + break + } + } + th.AssertEquals(t, true, found) +} From c24fe187710f92b1b4cd4eac36385d5f8e3cf0aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?p=C3=BDrus?= Date: Tue, 27 May 2025 13:22:17 +0200 Subject: [PATCH 144/353] Fix linter error --- .../acceptance/openstack/blockstorage/v3/blockstorage.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/internal/acceptance/openstack/blockstorage/v3/blockstorage.go b/internal/acceptance/openstack/blockstorage/v3/blockstorage.go index d28ac05c40..55c30d5ba8 100644 --- a/internal/acceptance/openstack/blockstorage/v3/blockstorage.go +++ b/internal/acceptance/openstack/blockstorage/v3/blockstorage.go @@ -789,7 +789,7 @@ func Unmanage(t *testing.T, client *gophercloud.ServiceClient, volume *volumes.V return err } - gophercloud.WaitFor(context.TODO(), func(ctx context.Context) (bool, error) { + err = gophercloud.WaitFor(context.TODO(), func(ctx context.Context) (bool, error) { if _, err := volumes.Get(ctx, client, volume.ID).Extract(); err != nil { if _, ok := err.(gophercloud.ErrResourceNotFound); ok { return true, nil @@ -798,6 +798,9 @@ func Unmanage(t *testing.T, client *gophercloud.ServiceClient, volume *volumes.V } return false, nil }) + if err != nil { + return fmt.Errorf("error waiting for volume %s to be unmanaged: %v", volume.ID, err) + } t.Logf("Successfully unmanaged volume %s", volume.ID) From ed64c54cc2f1b3e45d8350a6af98668936fe52e0 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Mon, 26 May 2025 11:42:58 +0100 Subject: [PATCH 145/353] tests: Correct error handling We get an unexpected response code, not the actual response code. Handle accordingly. Signed-off-by: Stephen Finucane --- .../acceptance/openstack/blockstorage/v3/blockstorage.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/internal/acceptance/openstack/blockstorage/v3/blockstorage.go b/internal/acceptance/openstack/blockstorage/v3/blockstorage.go index 55c30d5ba8..62e11af9b1 100644 --- a/internal/acceptance/openstack/blockstorage/v3/blockstorage.go +++ b/internal/acceptance/openstack/blockstorage/v3/blockstorage.go @@ -791,8 +791,10 @@ func Unmanage(t *testing.T, client *gophercloud.ServiceClient, volume *volumes.V err = gophercloud.WaitFor(context.TODO(), func(ctx context.Context) (bool, error) { if _, err := volumes.Get(ctx, client, volume.ID).Extract(); err != nil { - if _, ok := err.(gophercloud.ErrResourceNotFound); ok { - return true, nil + if errCode, ok := err.(gophercloud.ErrUnexpectedResponseCode); ok { + if errCode.Actual == 404 { + return true, nil + } } return false, err } From c268ac0dd06302f49576a55076b33d513580a666 Mon Sep 17 00:00:00 2001 From: James Scott Date: Thu, 17 Oct 2024 10:37:12 +0100 Subject: [PATCH 146/353] Added address groups to Networking extensions, with tests. Field added to SecGroupRules --- .../networking/v2/extensions/extensions.go | 43 ++++ .../networking/v2/extensions/security_test.go | 77 ++++++ .../extensions/security/addressgroups/doc.go | 91 +++++++ .../security/addressgroups/requests.go | 197 +++++++++++++++ .../security/addressgroups/results.go | 115 +++++++++ .../addressgroups/testing/fixtures_test.go | 119 ++++++++++ .../addressgroups/testing/requests_test.go | 224 ++++++++++++++++++ .../extensions/security/addressgroups/urls.go | 21 ++ .../v2/extensions/security/rules/requests.go | 43 ++-- .../v2/extensions/security/rules/results.go | 4 + 10 files changed, 915 insertions(+), 19 deletions(-) create mode 100644 openstack/networking/v2/extensions/security/addressgroups/doc.go create mode 100644 openstack/networking/v2/extensions/security/addressgroups/requests.go create mode 100644 openstack/networking/v2/extensions/security/addressgroups/results.go create mode 100644 openstack/networking/v2/extensions/security/addressgroups/testing/fixtures_test.go create mode 100644 openstack/networking/v2/extensions/security/addressgroups/testing/requests_test.go create mode 100644 openstack/networking/v2/extensions/security/addressgroups/urls.go diff --git a/internal/acceptance/openstack/networking/v2/extensions/extensions.go b/internal/acceptance/openstack/networking/v2/extensions/extensions.go index 9565d1e30c..ae0b52f595 100644 --- a/internal/acceptance/openstack/networking/v2/extensions/extensions.go +++ b/internal/acceptance/openstack/networking/v2/extensions/extensions.go @@ -7,6 +7,7 @@ import ( "github.com/gophercloud/gophercloud/v2" "github.com/gophercloud/gophercloud/v2/internal/acceptance/tools" "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/extensions/external" + "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/extensions/security/addressgroups" "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/extensions/security/groups" "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/extensions/security/rules" "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/networks" @@ -199,3 +200,45 @@ func DeleteSecurityGroupRule(t *testing.T, client *gophercloud.ServiceClient, ru t.Fatalf("Unable to delete security group rule: %v", err) } } + +// CreateSecurityAddressGroup will create a security address group with a random name. +func CreateSecurityAddressGroup(t *testing.T, client *gophercloud.ServiceClient) (*addressgroups.AddressGroup, error) { + addressGroupName := tools.RandomString("TESTACC-", 8) + addressGroupDescription := tools.RandomString("TESTACC-DESC-", 8) + + t.Logf("Attempting to create security address group: %s", addressGroupName) + + addresses := []string{ + "192.168.1.1/32", + } + createOpts := addressgroups.CreateOpts{ + Name: addressGroupName, + Description: addressGroupDescription, + Addresses: addresses, + } + + addressGroup, err := addressgroups.Create(context.TODO(), client, createOpts).Extract() + if err != nil { + return addressGroup, err + } + + t.Logf("Created security address group: %s", addressGroup.ID) + + th.AssertEquals(t, addressGroupName, addressGroup.Name) + th.AssertEquals(t, addressGroupDescription, addressGroup.Description) + th.AssertDeepEquals(t, addresses, addressGroup.Addresses) + + return addressGroup, nil +} + +// DeleteSecurityAddressGroup will delete a security address group of a specified ID. +// A fatal error will occur if the deletion failed. This works best as a +// deferred function +func DeleteSecurityAddressGroup(t *testing.T, client *gophercloud.ServiceClient, addressGroupID string) { + t.Logf("Attempting to delete security address group: %s", addressGroupID) + + err := addressgroups.Delete(context.TODO(), client, addressGroupID).ExtractErr() + if err != nil { + t.Fatalf("Unable to delete security address group: %v", err) + } +} diff --git a/internal/acceptance/openstack/networking/v2/extensions/security_test.go b/internal/acceptance/openstack/networking/v2/extensions/security_test.go index 33fc3f176d..ab3a058082 100644 --- a/internal/acceptance/openstack/networking/v2/extensions/security_test.go +++ b/internal/acceptance/openstack/networking/v2/extensions/security_test.go @@ -10,6 +10,7 @@ import ( "github.com/gophercloud/gophercloud/v2/internal/acceptance/clients" networking "github.com/gophercloud/gophercloud/v2/internal/acceptance/openstack/networking/v2" "github.com/gophercloud/gophercloud/v2/internal/acceptance/tools" + "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/extensions/security/addressgroups" "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/extensions/security/groups" th "github.com/gophercloud/gophercloud/v2/testhelper" ) @@ -156,3 +157,79 @@ func TestSecurityGroupsRevision(t *testing.T) { th.AssertEquals(t, group.Name, newName) th.AssertEquals(t, group.Description, newDescription) } + +func TestSecurityAddressGroups(t *testing.T) { + client, err := clients.NewNetworkV2Client() + th.AssertNoErr(t, err) + + group, err := CreateSecurityAddressGroup(t, client) + th.AssertNoErr(t, err) + defer DeleteSecurityAddressGroup(t, client, group.ID) + + tools.PrintResource(t, group) + + name := "Update group" + description := "" + updateOpts := addressgroups.UpdateOpts{ + Name: &name, + Description: &description, + } + newGroup, err := addressgroups.Update(context.TODO(), client, group.ID, updateOpts).Extract() + th.AssertNoErr(t, err) + tools.PrintResource(t, newGroup) + + th.AssertEquals(t, newGroup.Name, name) + th.AssertEquals(t, newGroup.Description, description) + + listOpts := addressgroups.ListOpts{} + allPages, err := addressgroups.List(client, listOpts).AllPages(context.TODO()) + th.AssertNoErr(t, err) + allGroups, err := addressgroups.ExtractGroups(allPages) + th.AssertNoErr(t, err) + + var found = -1 + for i, v := range allGroups { + if v.ID == group.ID { + found = i + break + } + } + if found == -1 { + t.Fatalf("Expected to find group %s in the list of groups", group.ID) + } + + th.AssertEquals(t, allGroups[found].Name, newGroup.Name) + th.AssertEquals(t, allGroups[found].Description, newGroup.Description) + th.AssertDeepEquals(t, allGroups[found].Addresses, newGroup.Addresses) + + // Test that we can add a new address to the group. + newAddresses := []string{ + "192.168.170.0/24", + } + addAddressOpts := addressgroups.UpdateAddressesOpts{ + Addresses: newAddresses, + } + updatedGroup, err := addressgroups.AddAddresses(context.TODO(), client, group.ID, addAddressOpts).Extract() + th.AssertNoErr(t, err) + tools.PrintResource(t, updatedGroup) + + // Check that the new address was added. + expectedAddresses := append(group.Addresses, newAddresses...) + th.AssertDeepEquals(t, updatedGroup.Addresses, expectedAddresses) + + // Test that we can remove an address from the group. + removeAddressOpts := addressgroups.UpdateAddressesOpts{ + Addresses: newAddresses, + } + updatedGroup, err = addressgroups.RemoveAddresses(context.TODO(), client, group.ID, removeAddressOpts).Extract() + th.AssertNoErr(t, err) + tools.PrintResource(t, updatedGroup) + + // Check that the address was removed. + expectedAddresses = group.Addresses + th.AssertDeepEquals(t, updatedGroup.Addresses, expectedAddresses) + + // Verify that the group exists. + _, err = addressgroups.Get(context.TODO(), client, group.ID).Extract() + th.AssertNoErr(t, err) +} diff --git a/openstack/networking/v2/extensions/security/addressgroups/doc.go b/openstack/networking/v2/extensions/security/addressgroups/doc.go new file mode 100644 index 0000000000..e1921f4306 --- /dev/null +++ b/openstack/networking/v2/extensions/security/addressgroups/doc.go @@ -0,0 +1,91 @@ +/* +Package addressgroups provides information and interaction with Address Groups +for the OpenStack Networking services. + +Example to List Address Groups + + listOpts := addressgroups.ListOpts{ + } + + allPages, err := addressgroups.List(networkClient, listOpts).AllPages(context.TODO()) + if err != nil { + panic(err) + } + + allAddressGroups, err := addressgroups.ExtractGroups(allPages) + if err != nil { + panic(err) + } + + for _, addressGroup := range allAddressGroups { + fmt.Printf("%+v\n", addressGroup) + } + +Example to Get an Address Group + + groupID := "37d94f8a-d136-465c-ae46-144f0d8ef141" + addressGroup, err := addressgroups.Get(context.TODO(), networkClient, groupID).Extract() + if err != nil { + panic(err) + } + +Example to Create an Address Group + + createOpts := addressgroups.CreateOpts{ + Name: "addressGroupName", + Addresses: []string{"10.2.30.4/32", "10.2.30.6/32"}, + Description: "Created address group", + } + + addressGroup, err := addressgroups.Create(context.TODO(), networkClient, createOpts).Extract() + if err != nil { + panic(err) + } + +Example to Delete a Address Group + + groupID := "37d94f8a-d136-465c-ae46-144f0d8ef141" + err := addressgroups.Delete(context.TODO(), computeClient, groupID).ExtractErr() + if err != nil { + panic(err) + } + +Example to update an existing Address Group + + groupID := "37d94f8a-d136-465c-ae46-144f0d8ef141" + name := "ADDR_GP_2" + description := "new description" + updateOpts := addressgroups.UpdateOpts{ + Name: &name, + Description: &description, + } + addressGroup, err := addressgroups.UpdateAddressGroup(context.TODO(), networkClient, groupID, createOpts).Extract() + if err != nil { + panic(err) + } + +Example to add addresses to an existing Address Group + + groupID := "37d94f8a-d136-465c-ae46-144f0d8ef141" + createOpts := addressgroups.UpdateAddressesOpts{ + Addresses: []string{"10.2.30.4/32", "10.2.30.6/32"}, + } + addressGroup, err := addressgroups.AddAddresses(context.TODO(), networkClient, groupID, createOpts).Extract() + if err != nil { + panic(err) + } + +Example to remove addresses from an existing Address Group + + groupID := "37d94f8a-d136-465c-ae46-144f0d8ef141" + createOpts := addressgroups.UpdateAddressesOpts{ + Addresses: []string{"10.2.30.4/32", "10.2.30.6/32"}, + } + addressGroup, err := addressgroups.RemoveAddresses(context.TODO(), networkClient, groupID, createOpts).Extract() + if err != nil { + panic(err) + } + +*/ + +package addressgroups diff --git a/openstack/networking/v2/extensions/security/addressgroups/requests.go b/openstack/networking/v2/extensions/security/addressgroups/requests.go new file mode 100644 index 0000000000..8d2d6fedb3 --- /dev/null +++ b/openstack/networking/v2/extensions/security/addressgroups/requests.go @@ -0,0 +1,197 @@ +package addressgroups + +import ( + "context" + + "github.com/gophercloud/gophercloud/v2" + "github.com/gophercloud/gophercloud/v2/pagination" +) + +// ListOptsBuilder allows extensions to add additional parameters to the +// List request. +type ListOptsBuilder interface { + ToAddressGroupListQuery() (string, error) +} + +// ListOpts allows the filtering and sorting of paginated collections through +// the API. Filtering is achieved by passing in struct field values that map to +// the address group attributes you want to see returned. SortKey allows +// you to sort by a particular network attribute. SortDir sets the direction, +// and is either `asc' or `desc'. Marker and Limit are used for pagination. +type ListOpts struct { + ID string `q:"id"` + Name string `q:"name"` + Description string `q:"description"` + ProjectID string `q:"project_id"` + Addresses []string `q:"addresses"` + Limit int `q:"limit"` + Marker string `q:"marker"` + SortKey string `q:"sort_key"` + SortDir string `q:"sort_dir"` +} + +// ToAddressGroupListQuery formats a ListOpts into a query string. +func (opts ListOpts) ToAddressGroupListQuery() (string, error) { + q, err := gophercloud.BuildQueryString(opts) + return q.String(), err +} + +// List returns a Pager which allows you to iterate over a collection of +// address groups. It accepts a ListOpts struct, which allows you to filter +// and sort the returned collection for greater efficiency. +func List(c *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { + url := rootURL(c) + if opts != nil { + query, err := opts.ToAddressGroupListQuery() + if err != nil { + return pagination.Pager{Err: err} + } + url += query + } + return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page { + return AddressGroupPage{pagination.LinkedPageBase{PageResult: r}} + }) +} + +// CreateOptsBuilder allows extensions to add additional parameters to the +// Create request. +type CreateOptsBuilder interface { + ToAddressGroupCreateMap() (map[string]any, error) +} + +// CreateOpts contains all the values needed to create a new address group. +type CreateOpts struct { + // The address group ID to associate with this address group. + ID string `json:"id,omitempty"` + + // Human readable name for the address group (255 characters limit). Does not have to be unique. + Name string `json:"name,omitempty"` + + // Human readable description for the address group (255 characters limit). + Description string `json:"description,omitempty"` + + // Owner of the address group. + // Only administrative users can specify a project UUID other than their own. + ProjectID string `json:"project_id,omitempty"` + + // Array of address. It supports both CIDR and IP range objects. + // An example of addresses: [“132.168.4.12/24”, “132.168.5.12-132.168.5.24”, “2001::db8::f00/64”] + Addresses []string `json:"addresses" required:"true"` +} + +// ToAddressGroupCreateMap builds a request body from CreateOpts. +func (opts CreateOpts) ToAddressGroupCreateMap() (map[string]any, error) { + return gophercloud.BuildRequestBody(opts, "address_group") +} + +// ToAddressesCreateMap builds a request body from CreateOpts. +func (opts CreateOpts) ToAddressesCreateMap() (map[string]any, error) { + return gophercloud.BuildRequestBody(opts, "") +} + +// Create is an operation which creates a new address group and associates it +// with an existing address group (whose ID is specified in CreateOpts). +func Create(ctx context.Context, c *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { + b, err := opts.ToAddressGroupCreateMap() + if err != nil { + r.Err = err + return + } + resp, err := c.Post(ctx, rootURL(c), b, &r.Body, nil) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} + +// Get retrieves a particular address group based on its unique ID. +func Get(ctx context.Context, c *gophercloud.ServiceClient, id string) (r GetResult) { + resp, err := c.Get(ctx, resourceURL(c, id), &r.Body, nil) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} + +// Delete will permanently delete a particular address group based on its +// unique ID. +func Delete(ctx context.Context, c *gophercloud.ServiceClient, id string) (r DeleteResult) { + resp, err := c.Delete(ctx, resourceURL(c, id), nil) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} + +// UpdateOptsBuilder allows extensions to add additional parameters to the +// Update requests. +type UpdateOptsBuilder interface { + ToAddressGroupUpdateMap() (map[string]any, error) +} + +// UpdateOpts contains all the values needed to update an address group. +type UpdateOpts struct { + // Human readable name for the address group (255 characters limit). Does not have to be unique. + Name *string `json:"name,omitempty"` + // Human readable description for the address group (255 characters limit). + Description *string `json:"description,omitempty"` +} + +// ToAddressGroupUpdateMap builds a request body from UpdateOpts. +func (opts UpdateOpts) ToAddressGroupUpdateMap() (map[string]any, error) { + return gophercloud.BuildRequestBody(opts, "address_group") +} + +// Update will update a particular address group with a complete new set of data. +func Update(ctx context.Context, c *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) { + b, err := opts.ToAddressGroupUpdateMap() + if err != nil { + r.Err = err + return + } + resp, err := c.Put(ctx, resourceURL(c, id), b, &r.Body, &gophercloud.RequestOpts{ + OkCodes: []int{200}, + }) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} + +// UpdateAddressesOpts will add or remove a list of particular addresses from +// an address group. It is used by both AddAddresses and RemoveAddresses +// requests. +type UpdateAddressesOpts struct { + Addresses []string `json:"addresses" required:"true"` +} + +// AddressesBuilder allows extensions to add additional parameters to the +// AddAddresses or RemoveAddresses requests. +type UpdateAddressesBuilder interface { + ToUpdateAddressesMap() (map[string]any, error) +} + +// ToAddressesCreateMap builds a request body from CreateOpts. +func (opts UpdateAddressesOpts) ToUpdateAddressesMap() (map[string]any, error) { + return gophercloud.BuildRequestBody(opts, "") +} + +// AddAddresses will add IP addresses to a particular address group. +func AddAddresses(ctx context.Context, c *gophercloud.ServiceClient, id string, opts UpdateAddressesBuilder) (r AddAddressesResult) { + b, err := opts.ToUpdateAddressesMap() + if err != nil { + r.Err = err + return + } + resp, err := c.Put(ctx, resourceAddAddressesURL(c, id), b, &r.Body, &gophercloud.RequestOpts{ + OkCodes: []int{200}, + }) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} + +// RemoveAddresses will remove particular IP addresses from a particular address group. +func RemoveAddresses(ctx context.Context, c *gophercloud.ServiceClient, id string, opts UpdateAddressesBuilder) (r RemoveAddressesResult) { + b, err := opts.ToUpdateAddressesMap() + if err != nil { + r.Err = err + return + } + resp, err := c.Put(ctx, resourceRemoveAddressesURL(c, id), b, &r.Body, &gophercloud.RequestOpts{ + OkCodes: []int{200}, + }) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} diff --git a/openstack/networking/v2/extensions/security/addressgroups/results.go b/openstack/networking/v2/extensions/security/addressgroups/results.go new file mode 100644 index 0000000000..b949def3a7 --- /dev/null +++ b/openstack/networking/v2/extensions/security/addressgroups/results.go @@ -0,0 +1,115 @@ +package addressgroups + +import ( + "github.com/gophercloud/gophercloud/v2" + "github.com/gophercloud/gophercloud/v2/pagination" +) + +// AddressGroup represents a container for address groups. +type AddressGroup struct { + // Unique identifier for the address_group object. + ID string `json:"id"` + + // Human readable name for the address group (255 characters limit). Does not have to be unique. + Name string `json:"name"` + + // Human readable description for the address group (255 characters limit). + Description string `json:"description"` + + // ProjectID is the project owner of this address group. + ProjectID string `json:"project_id"` + + // Array of address. It supports both CIDR and IP range objects. + // An example of addresses: [“132.168.4.12/24”, “132.168.5.12-132.168.5.24”, “2001::db8::f00/64”] + Addresses []string `json:"addresses"` +} + +// AddressGroupPage is the page returned by a pager when traversing over a +// collection of address group addresses. +type AddressGroupPage struct { + pagination.LinkedPageBase +} + +// NextPageURL is invoked when a paginated collection of address groups has +// reached the end of a page and the pager seeks to traverse over a new one. In +// order to do this, it needs to construct the next page's URL. +func (r AddressGroupPage) NextPageURL() (string, error) { + var s struct { + Links []gophercloud.Link `json:"address_groups_links"` + } + err := r.ExtractInto(&s) + if err != nil { + return "", err + } + return gophercloud.ExtractNextURL(s.Links) +} + +// IsEmpty checks whether a AddressGroupPage struct is empty. +func (r AddressGroupPage) IsEmpty() (bool, error) { + if r.StatusCode == 204 { + return true, nil + } + + is, err := ExtractGroups(r) + return len(is) == 0, err +} + +// ExtractGroups accepts a Page struct, specifically a AddressGroupPage struct, +// and extracts the elements into a slice of AddressGroup structs. In other words, +// a generic collection is mapped into a relevant slice. +func ExtractGroups(r pagination.Page) ([]AddressGroup, error) { + var s struct { + AddressGroups []AddressGroup `json:"address_groups"` + } + err := (r.(AddressGroupPage)).ExtractInto(&s) + return s.AddressGroups, err +} + +type commonResult struct { + gophercloud.Result +} + +// Extract is a function that accepts a result and extracts a address group. +func (r commonResult) Extract() (*AddressGroup, error) { + var s struct { + AddressGroup *AddressGroup `json:"address_group"` + } + err := r.ExtractInto(&s) + return s.AddressGroup, err +} + +// CreateResult represents the result of a create operation. Call its Extract +// method to interpret it as a AddressGroup. +type CreateResult struct { + commonResult +} + +// GetResult represents the result of a get operation. Call its Extract +// method to interpret it as a AddressGroup. +type GetResult struct { + commonResult +} + +// DeleteResult represents the result of a delete operation. Call its +// ExtractErr method to determine if the request succeeded or failed. +type DeleteResult struct { + gophercloud.ErrResult +} + +// UpdateResult represents the result of an update address group operation. Call its Extract +// method to interpret it as a AddressGroup. +type UpdateResult struct { + commonResult +} + +// AddAddressesResult represents the result of an add addresses operation. Call its Extract +// method to interpret it as a AddressGroup. +type AddAddressesResult struct { + commonResult +} + +// RemoveAddressesResult represents the result of a remove addresses operation. Call its Extract +// method to interpret it as a AddressGroup. +type RemoveAddressesResult struct { + commonResult +} diff --git a/openstack/networking/v2/extensions/security/addressgroups/testing/fixtures_test.go b/openstack/networking/v2/extensions/security/addressgroups/testing/fixtures_test.go new file mode 100644 index 0000000000..5375868636 --- /dev/null +++ b/openstack/networking/v2/extensions/security/addressgroups/testing/fixtures_test.go @@ -0,0 +1,119 @@ +package testing + +const AddressGroupListResponse = ` +{ + "address_groups": [ + { + "id": "8722e0e0-9cc9-4490-9660-8c9a5732fbb0", + "project_id": "45977fa2dbd7482098dd68d0d8970117", + "name": "ADDR_GP_1", + "addresses": [ + "132.168.4.12/24" + ] + } + ] +} +` + +const AddressGroupGetResponse = ` +{ + "address_group": { + "description": "", + "id": "8722e0e0-9cc9-4490-9660-8c9a5732fbb0", + "name": "ADDR_GP_1", + "project_id": "45977fa2dbd7482098dd68d0d8970117", + "addresses": [ + "132.168.4.12/24" + ] + } +} +` + +const AddressGroupCreateRequest = ` +{ + "address_group": { + "name": "ADDR_GP_1", + "addresses": [ + "132.168.4.12/24" + ] + } +} +` + +const AddressGroupCreateResponse = ` +{ + "address_group": { + "description": "", + "id": "8722e0e0-9cc9-4490-9660-8c9a5732fbb0", + "name": "ADDR_GP_1", + "project_id": "45977fa2dbd7482098dd68d0d8970117", + "addresses": [ + "132.168.4.12/24" + ] + } +} +` + +const AddressGroupUpdateRequest = ` +{ + "address_group": { + "description": "new description", + "name": "ADDR_GP_2" + } +} +` + +const AddressGroupUpdateResponse = ` +{ + "address_group": { + "description": "new description", + "id": "8722e0e0-9cc9-4490-9660-8c9a5732fbb0", + "name": "ADDR_GP_2", + "project_id": "45977fa2dbd7482098dd68d0d8970117", + "addresses": [ + "192.168.4.1/32" + ] + } +} +` + +const AddressGroupAddAddressesRequest = ` +{ + "addresses": ["192.168.4.1/32"] +} +` + +const AddressGroupAddAddressesResponse = ` +{ + "address_group": { + "description": "original description", + "id": "8722e0e0-9cc9-4490-9660-8c9a5732fbb0", + "name": "ADDR_GP_1", + "project_id": "45977fa2dbd7482098dd68d0d8970117", + "addresses": [ + "132.168.4.12/24", + "192.168.4.1/32" + ] + } +} +` + +const AddressGroupRemoveAddressesRequest = ` +{ + "addresses": ["192.168.4.1/32"] +} +` + +const AddressGroupRemoveAddressesResponse = ` +{ + "address_group": { + "description": "original description", + "id": "8722e0e0-9cc9-4490-9660-8c9a5732fbb0", + "name": "ADDR_GP_1", + "project_id": "45977fa2dbd7482098dd68d0d8970117", + "addresses": [ + "132.168.4.12/24" + ] + } +} +` diff --git a/openstack/networking/v2/extensions/security/addressgroups/testing/requests_test.go b/openstack/networking/v2/extensions/security/addressgroups/testing/requests_test.go new file mode 100644 index 0000000000..1b974a1497 --- /dev/null +++ b/openstack/networking/v2/extensions/security/addressgroups/testing/requests_test.go @@ -0,0 +1,224 @@ +package testing + +import ( + "context" + "fmt" + "net/http" + "testing" + + fake "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/common" + "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/extensions/security/addressgroups" + "github.com/gophercloud/gophercloud/v2/pagination" + th "github.com/gophercloud/gophercloud/v2/testhelper" +) + +func TestList(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + + th.Mux.HandleFunc("/v2.0/address-groups", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + + fmt.Fprintf(w, AddressGroupListResponse) + }) + + count := 0 + + err := addressgroups.List(fake.ServiceClient(), addressgroups.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + count++ + actual, err := addressgroups.ExtractGroups(page) + if err != nil { + t.Errorf("Failed to extract address groups: %v", err) + return false, err + } + + expected := []addressgroups.AddressGroup{ + { + Description: "", + ID: "8722e0e0-9cc9-4490-9660-8c9a5732fbb0", + Name: "ADDR_GP_1", + ProjectID: "45977fa2dbd7482098dd68d0d8970117", + Addresses: []string{ + "132.168.4.12/24", + }, + }, + } + + th.CheckDeepEquals(t, expected, actual) + + return true, nil + }) + th.AssertNoErr(t, err) + + if count != 1 { + t.Errorf("Expected 1 page, got %d", count) + } +} + +func TestCreate(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + + th.Mux.HandleFunc("/v2.0/address-groups", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "POST") + th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "Content-Type", "application/json") + th.TestHeader(t, r, "Accept", "application/json") + th.TestJSONRequest(t, r, AddressGroupCreateRequest) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusCreated) + + fmt.Fprintf(w, AddressGroupCreateResponse) + }) + + opts := addressgroups.CreateOpts{ + Name: "ADDR_GP_1", + Addresses: []string{ + "132.168.4.12/24", + }, + } + _, err := addressgroups.Create(context.TODO(), fake.ServiceClient(), opts).Extract() + th.AssertNoErr(t, err) +} + +func TestRequiredCreateOpts(t *testing.T) { + _, err := addressgroups.Create(context.TODO(), fake.ServiceClient(), addressgroups.CreateOpts{Name: "ADDR_GP_1"}).Extract() + if err == nil { + t.Fatalf("Expected error, got none") + } +} + +func TestGet(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + + th.Mux.HandleFunc("/v2.0/address-groups/8722e0e0-9cc9-4490-9660-8c9a5732fbb0", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + + fmt.Fprintf(w, AddressGroupGetResponse) + }) + + sr, err := addressgroups.Get(context.TODO(), fake.ServiceClient(), "8722e0e0-9cc9-4490-9660-8c9a5732fbb0").Extract() + th.AssertNoErr(t, err) + th.AssertEquals(t, "", sr.Description) + th.AssertEquals(t, "8722e0e0-9cc9-4490-9660-8c9a5732fbb0", sr.ID) + th.AssertEquals(t, "45977fa2dbd7482098dd68d0d8970117", sr.ProjectID) + th.CheckDeepEquals(t, []string{"132.168.4.12/24"}, sr.Addresses) + th.AssertEquals(t, "ADDR_GP_1", sr.Name) +} + +func TestUpdate(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + + th.Mux.HandleFunc("/v2.0/address-groups/8722e0e0-9cc9-4490-9660-8c9a5732fbb0", + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "PUT") + th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "Content-Type", "application/json") + th.TestHeader(t, r, "Accept", "application/json") + th.TestJSONRequest(t, r, AddressGroupUpdateRequest) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + + fmt.Fprintf(w, AddressGroupUpdateResponse) + }) + + name := "ADDR_GP_2" + description := "new description" + opts := addressgroups.UpdateOpts{ + Name: &name, + Description: &description, + } + ag, err := addressgroups.Update(context.TODO(), fake.ServiceClient(), "8722e0e0-9cc9-4490-9660-8c9a5732fbb0", opts).Extract() + th.AssertNoErr(t, err) + + th.CheckDeepEquals(t, []string{"192.168.4.1/32"}, ag.Addresses) + th.AssertEquals(t, "new description", ag.Description) + th.AssertEquals(t, "8722e0e0-9cc9-4490-9660-8c9a5732fbb0", ag.ID) + th.AssertEquals(t, "45977fa2dbd7482098dd68d0d8970117", ag.ProjectID) + th.AssertEquals(t, "ADDR_GP_2", ag.Name) +} + +func TestAddAddresses(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + + th.Mux.HandleFunc("/v2.0/address-groups/8722e0e0-9cc9-4490-9660-8c9a5732fbb0/add_addresses", + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "PUT") + th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "Content-Type", "application/json") + th.TestHeader(t, r, "Accept", "application/json") + th.TestJSONRequest(t, r, AddressGroupAddAddressesRequest) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + + fmt.Fprintf(w, AddressGroupAddAddressesResponse) + }) + + opts := addressgroups.UpdateAddressesOpts{ + Addresses: []string{"192.168.4.1/32"}, + } + ag, err := addressgroups.AddAddresses(context.TODO(), fake.ServiceClient(), "8722e0e0-9cc9-4490-9660-8c9a5732fbb0", opts).Extract() + th.AssertNoErr(t, err) + + th.CheckDeepEquals(t, []string{"132.168.4.12/24", "192.168.4.1/32"}, ag.Addresses) + th.AssertEquals(t, "original description", ag.Description) + th.AssertEquals(t, "8722e0e0-9cc9-4490-9660-8c9a5732fbb0", ag.ID) +} + +func TestRemoveAddresses(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + + th.Mux.HandleFunc("/v2.0/address-groups/8722e0e0-9cc9-4490-9660-8c9a5732fbb0/remove_addresses", + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "PUT") + th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "Content-Type", "application/json") + th.TestHeader(t, r, "Accept", "application/json") + th.TestJSONRequest(t, r, AddressGroupRemoveAddressesRequest) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + + fmt.Fprintf(w, AddressGroupRemoveAddressesResponse) + }) + + opts := addressgroups.UpdateAddressesOpts{ + Addresses: []string{"192.168.4.1/32"}, + } + ag, err := addressgroups.RemoveAddresses(context.TODO(), fake.ServiceClient(), "8722e0e0-9cc9-4490-9660-8c9a5732fbb0", opts).Extract() + th.AssertNoErr(t, err) + + th.CheckDeepEquals(t, []string{"132.168.4.12/24"}, ag.Addresses) + th.AssertEquals(t, "original description", ag.Description) + th.AssertEquals(t, "8722e0e0-9cc9-4490-9660-8c9a5732fbb0", ag.ID) +} + +func TestDelete(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + + th.Mux.HandleFunc("/v2.0/address-groups/4ec89087-d057-4e2c-911f-60a3b47ee304", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "DELETE") + th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + + w.WriteHeader(http.StatusNoContent) + }) + + err := addressgroups.Delete(context.TODO(), fake.ServiceClient(), "4ec89087-d057-4e2c-911f-60a3b47ee304").ExtractErr() + th.AssertNoErr(t, err) +} diff --git a/openstack/networking/v2/extensions/security/addressgroups/urls.go b/openstack/networking/v2/extensions/security/addressgroups/urls.go new file mode 100644 index 0000000000..60525743ed --- /dev/null +++ b/openstack/networking/v2/extensions/security/addressgroups/urls.go @@ -0,0 +1,21 @@ +package addressgroups + +import "github.com/gophercloud/gophercloud/v2" + +const rootPath = "address-groups" + +func rootURL(c *gophercloud.ServiceClient) string { + return c.ServiceURL(rootPath) +} + +func resourceURL(c *gophercloud.ServiceClient, id string) string { + return c.ServiceURL(rootPath, id) +} + +func resourceAddAddressesURL(c *gophercloud.ServiceClient, id string) string { + return c.ServiceURL(rootPath, id, "add_addresses") +} + +func resourceRemoveAddressesURL(c *gophercloud.ServiceClient, id string) string { + return c.ServiceURL(rootPath, id, "remove_addresses") +} diff --git a/openstack/networking/v2/extensions/security/rules/requests.go b/openstack/networking/v2/extensions/security/rules/requests.go index d78b6b8ec3..703007b7bb 100644 --- a/openstack/networking/v2/extensions/security/rules/requests.go +++ b/openstack/networking/v2/extensions/security/rules/requests.go @@ -19,23 +19,24 @@ type ListOptsBuilder interface { // you to sort by a particular network attribute. SortDir sets the direction, // and is either `asc' or `desc'. Marker and Limit are used for pagination. type ListOpts struct { - Direction string `q:"direction"` - EtherType string `q:"ethertype"` - ID string `q:"id"` - Description string `q:"description"` - PortRangeMax int `q:"port_range_max"` - PortRangeMin int `q:"port_range_min"` - Protocol string `q:"protocol"` - RemoteGroupID string `q:"remote_group_id"` - RemoteIPPrefix string `q:"remote_ip_prefix"` - SecGroupID string `q:"security_group_id"` - TenantID string `q:"tenant_id"` - ProjectID string `q:"project_id"` - Limit int `q:"limit"` - Marker string `q:"marker"` - SortKey string `q:"sort_key"` - SortDir string `q:"sort_dir"` - RevisionNumber *int `q:"revision_number"` + Direction string `q:"direction"` + EtherType string `q:"ethertype"` + ID string `q:"id"` + Description string `q:"description"` + PortRangeMax int `q:"port_range_max"` + PortRangeMin int `q:"port_range_min"` + Protocol string `q:"protocol"` + RemoteAddressGroupID string `q:"remote_address_group_id"` + RemoteGroupID string `q:"remote_group_id"` + RemoteIPPrefix string `q:"remote_ip_prefix"` + SecGroupID string `q:"security_group_id"` + TenantID string `q:"tenant_id"` + ProjectID string `q:"project_id"` + Limit int `q:"limit"` + Marker string `q:"marker"` + SortKey string `q:"sort_key"` + SortDir string `q:"sort_dir"` + RevisionNumber *int `q:"revision_number"` } // ToSecGroupListQuery formats a ListOpts into a query string. @@ -137,12 +138,16 @@ type CreateOpts struct { // "tcp", "udp", "icmp" or an empty string. Protocol RuleProtocol `json:"protocol,omitempty"` + // The remote address group ID to be associated with this security group rule. + // You can specify either RemoteAddressGroupID, RemoteGroupID, or RemoteIPPrefix + RemoteAddressGroupID string `json:"remote_address_group_id,omitempty"` + // The remote group ID to be associated with this security group rule. You can - // specify either RemoteGroupID or RemoteIPPrefix. + // specify either RemoteAddressGroupID,RemoteGroupID or RemoteIPPrefix. RemoteGroupID string `json:"remote_group_id,omitempty"` // The remote IP prefix to be associated with this security group rule. You can - // specify either RemoteGroupID or RemoteIPPrefix. This attribute matches the + // specify either RemoteAddressGroupID,RemoteGroupID or RemoteIPPrefix. This attribute matches the // specified IP prefix as the source IP address of the IP packet. RemoteIPPrefix string `json:"remote_ip_prefix,omitempty"` diff --git a/openstack/networking/v2/extensions/security/rules/results.go b/openstack/networking/v2/extensions/security/rules/results.go index 8a3355dfe0..2d528bd284 100644 --- a/openstack/networking/v2/extensions/security/rules/results.go +++ b/openstack/networking/v2/extensions/security/rules/results.go @@ -44,6 +44,10 @@ type SecGroupRule struct { // "tcp", "udp", "icmp" or an empty string. Protocol string + // The remote address group ID to be associated with this security group rule. + // You can specify either RemoteAddressGroupID, RemoteGroupID, or RemoteIPPrefix + RemoteAddressGroupID string `json:"remote_address_group_id"` + // The remote group ID to be associated with this security group rule. You // can specify either RemoteGroupID or RemoteIPPrefix. RemoteGroupID string `json:"remote_group_id"` From f9b4f0d99beaac3b9093c34bcdb11ca9ee99dde5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?p=C3=BDrus?= Date: Tue, 27 May 2025 17:03:07 +0200 Subject: [PATCH 147/353] neutron: add segment_id support to subnets --- openstack/networking/v2/subnets/requests.go | 9 +++++++++ openstack/networking/v2/subnets/results.go | 4 ++++ 2 files changed, 13 insertions(+) diff --git a/openstack/networking/v2/subnets/requests.go b/openstack/networking/v2/subnets/requests.go index 150afd7394..6f1679b0b2 100644 --- a/openstack/networking/v2/subnets/requests.go +++ b/openstack/networking/v2/subnets/requests.go @@ -43,6 +43,7 @@ type ListOpts struct { NotTags string `q:"not-tags"` NotTagsAny string `q:"not-tags-any"` RevisionNumber *int `q:"revision_number"` + SegmentID string `q:"segment_id"` } // ToSubnetListQuery formats a ListOpts into a query string. @@ -147,6 +148,10 @@ type CreateOpts struct { // Prefixlen is used when user creates a subnet from the subnetpool. It will // overwrite the "default_prefixlen" value of the referenced subnetpool. Prefixlen int `json:"prefixlen,omitempty"` + + // SegmentID is a network segment the subnet is associated with. It is + // available when segment extension is enabled. + SegmentID string `json:"segment_id,omitempty"` } // ToSubnetCreateMap builds a request body from CreateOpts. @@ -219,6 +224,10 @@ type UpdateOpts struct { // will set revision_number=%s. If the revision number does not match, the // update will fail. RevisionNumber *int `json:"-" h:"If-Match"` + + // SegmentID is a network segment the subnet is associated with. It is + // available when segment extension is enabled. + SegmentID *string `json:"segment_id,omitempty"` } // ToSubnetUpdateMap builds a request body from UpdateOpts. diff --git a/openstack/networking/v2/subnets/results.go b/openstack/networking/v2/subnets/results.go index 01c6acc070..9d9e751c97 100644 --- a/openstack/networking/v2/subnets/results.go +++ b/openstack/networking/v2/subnets/results.go @@ -124,6 +124,10 @@ type Subnet struct { // RevisionNumber optionally set via extensions/standard-attr-revisions RevisionNumber int `json:"revision_number"` + // SegmentID of a network segment the subnet is associated with. It is + // available when segment extension is enabled. + SegmentID string `json:"segment_id"` + // Timestamp when the subnet was created CreatedAt time.Time `json:"created_at"` From 7fa3aa99b1877f73457bb898172a54d1ba76ef45 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 Jun 2025 15:14:22 +0000 Subject: [PATCH 148/353] build(deps): bump joelanford/go-apidiff from 0.8.2 to 0.8.3 Bumps [joelanford/go-apidiff](https://github.com/joelanford/go-apidiff) from 0.8.2 to 0.8.3. - [Release notes](https://github.com/joelanford/go-apidiff/releases) - [Commits](https://github.com/joelanford/go-apidiff/compare/002aa613b261e8d1547b516fb71793280f05bb78...60c4206be8f84348ebda2a3e0c3ac9cb54b8f685) --- updated-dependencies: - dependency-name: joelanford/go-apidiff dependency-version: 0.8.3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/label-pr.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/label-pr.yaml b/.github/workflows/label-pr.yaml index 44d46b0e15..1a2419c7cf 100644 --- a/.github/workflows/label-pr.yaml +++ b/.github/workflows/label-pr.yaml @@ -33,7 +33,7 @@ jobs: # if semver=major, this will return RC=1, so let's ignore the failure so label # can be set later. We check for actual errors in the next step. continue-on-error: true - uses: joelanford/go-apidiff@002aa613b261e8d1547b516fb71793280f05bb78 + uses: joelanford/go-apidiff@60c4206be8f84348ebda2a3e0c3ac9cb54b8f685 # go-apidiff returns RC=1 when semver=major, which makes the workflow to return # a failure. Instead let's just return a failure if go-apidiff failed to run. From b683ee39af6d645e5a5daf17d5be359fe1750d56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?p=C3=BDrus?= Date: Fri, 6 Jun 2025 08:35:19 +0200 Subject: [PATCH 149/353] [v2] tests: bump devstack-action --- .github/workflows/functional-baremetal.yaml | 2 +- .github/workflows/functional-basic.yaml | 2 +- .github/workflows/functional-blockstorage.yaml | 2 +- .github/workflows/functional-compute.yaml | 2 +- .github/workflows/functional-containerinfra.yaml | 2 +- .github/workflows/functional-dns.yaml | 2 +- .github/workflows/functional-fwaas_v2.yaml | 2 +- .github/workflows/functional-identity.yaml | 2 +- .github/workflows/functional-image.yaml | 2 +- .github/workflows/functional-keymanager.yaml | 2 +- .github/workflows/functional-loadbalancer.yaml | 2 +- .github/workflows/functional-messaging.yaml | 2 +- .github/workflows/functional-networking.yaml | 2 +- .github/workflows/functional-objectstorage.yaml | 2 +- .github/workflows/functional-orchestration.yaml | 2 +- .github/workflows/functional-placement.yaml | 2 +- .github/workflows/functional-sharedfilesystems.yaml | 2 +- .github/workflows/functional-workflow.yaml | 2 +- 18 files changed, 18 insertions(+), 18 deletions(-) diff --git a/.github/workflows/functional-baremetal.yaml b/.github/workflows/functional-baremetal.yaml index 75d79d1251..48adb28279 100644 --- a/.github/workflows/functional-baremetal.yaml +++ b/.github/workflows/functional-baremetal.yaml @@ -32,7 +32,7 @@ jobs: - name: Work around broken dnsmasq run: sudo apt-get purge -y dnsmasq-base - name: Deploy devstack - uses: gophercloud/devstack-action@v0.17 + uses: gophercloud/devstack-action@v0.19 with: branch: ${{ matrix.openstack_version }} conf_overrides: | diff --git a/.github/workflows/functional-basic.yaml b/.github/workflows/functional-basic.yaml index 0145ab0917..9310200cf2 100644 --- a/.github/workflows/functional-basic.yaml +++ b/.github/workflows/functional-basic.yaml @@ -32,7 +32,7 @@ jobs: - name: Checkout Gophercloud uses: actions/checkout@v4 - name: Deploy devstack - uses: gophercloud/devstack-action@v0.17 + uses: gophercloud/devstack-action@v0.19 with: branch: ${{ matrix.openstack_version }} enabled_services: 's-account,s-container,s-object,s-proxy,${{ matrix.additional_services }}' diff --git a/.github/workflows/functional-blockstorage.yaml b/.github/workflows/functional-blockstorage.yaml index 96dc8bdf16..7fa73c2ab1 100644 --- a/.github/workflows/functional-blockstorage.yaml +++ b/.github/workflows/functional-blockstorage.yaml @@ -30,7 +30,7 @@ jobs: - name: Checkout Gophercloud uses: actions/checkout@v4 - name: Deploy devstack - uses: gophercloud/devstack-action@v0.17 + uses: gophercloud/devstack-action@v0.19 with: branch: ${{ matrix.openstack_version }} conf_overrides: | diff --git a/.github/workflows/functional-compute.yaml b/.github/workflows/functional-compute.yaml index 30ec290dd0..e279edb138 100644 --- a/.github/workflows/functional-compute.yaml +++ b/.github/workflows/functional-compute.yaml @@ -30,7 +30,7 @@ jobs: - name: Checkout Gophercloud uses: actions/checkout@v4 - name: Deploy devstack - uses: gophercloud/devstack-action@v0.17 + uses: gophercloud/devstack-action@v0.19 with: branch: ${{ matrix.openstack_version }} conf_overrides: | diff --git a/.github/workflows/functional-containerinfra.yaml b/.github/workflows/functional-containerinfra.yaml index 7e6b023c24..f331301cdb 100644 --- a/.github/workflows/functional-containerinfra.yaml +++ b/.github/workflows/functional-containerinfra.yaml @@ -45,7 +45,7 @@ jobs: - name: Checkout Gophercloud uses: actions/checkout@v4 - name: Deploy devstack - uses: gophercloud/devstack-action@v0.17 + uses: gophercloud/devstack-action@v0.19 with: branch: ${{ matrix.openstack_version }} conf_overrides: | diff --git a/.github/workflows/functional-dns.yaml b/.github/workflows/functional-dns.yaml index 9df2aea628..beb2e1ac5e 100644 --- a/.github/workflows/functional-dns.yaml +++ b/.github/workflows/functional-dns.yaml @@ -36,7 +36,7 @@ jobs: - name: Checkout Gophercloud uses: actions/checkout@v4 - name: Deploy devstack - uses: gophercloud/devstack-action@v0.17 + uses: gophercloud/devstack-action@v0.19 with: branch: ${{ matrix.openstack_version }} conf_overrides: | diff --git a/.github/workflows/functional-fwaas_v2.yaml b/.github/workflows/functional-fwaas_v2.yaml index bf7762fdbf..2481b0d21d 100644 --- a/.github/workflows/functional-fwaas_v2.yaml +++ b/.github/workflows/functional-fwaas_v2.yaml @@ -42,7 +42,7 @@ jobs: "update_port:binding:profile": "rule:admin_only or rule:service_api" EOF - name: Deploy devstack - uses: gophercloud/devstack-action@v0.17 + uses: gophercloud/devstack-action@v0.19 with: branch: ${{ matrix.openstack_version }} conf_overrides: | diff --git a/.github/workflows/functional-identity.yaml b/.github/workflows/functional-identity.yaml index 623361dc17..688655d6f5 100644 --- a/.github/workflows/functional-identity.yaml +++ b/.github/workflows/functional-identity.yaml @@ -30,7 +30,7 @@ jobs: - name: Checkout Gophercloud uses: actions/checkout@v4 - name: Deploy devstack - uses: gophercloud/devstack-action@v0.17 + uses: gophercloud/devstack-action@v0.19 with: branch: ${{ matrix.openstack_version }} enabled_services: "${{ matrix.additional_services }}" diff --git a/.github/workflows/functional-image.yaml b/.github/workflows/functional-image.yaml index e78dccbb86..20697896e2 100644 --- a/.github/workflows/functional-image.yaml +++ b/.github/workflows/functional-image.yaml @@ -30,7 +30,7 @@ jobs: - name: Checkout Gophercloud uses: actions/checkout@v4 - name: Deploy devstack - uses: gophercloud/devstack-action@v0.17 + uses: gophercloud/devstack-action@v0.19 with: branch: ${{ matrix.openstack_version }} enabled_services: "${{ matrix.additional_services }}" diff --git a/.github/workflows/functional-keymanager.yaml b/.github/workflows/functional-keymanager.yaml index 4e22a0f379..ca046de8b0 100644 --- a/.github/workflows/functional-keymanager.yaml +++ b/.github/workflows/functional-keymanager.yaml @@ -36,7 +36,7 @@ jobs: - name: Checkout Gophercloud uses: actions/checkout@v4 - name: Deploy devstack - uses: gophercloud/devstack-action@v0.17 + uses: gophercloud/devstack-action@v0.19 with: branch: ${{ matrix.openstack_version }} conf_overrides: | diff --git a/.github/workflows/functional-loadbalancer.yaml b/.github/workflows/functional-loadbalancer.yaml index 2de31cb705..5ea8b7842b 100644 --- a/.github/workflows/functional-loadbalancer.yaml +++ b/.github/workflows/functional-loadbalancer.yaml @@ -36,7 +36,7 @@ jobs: - name: Checkout Gophercloud uses: actions/checkout@v4 - name: Deploy devstack - uses: gophercloud/devstack-action@v0.17 + uses: gophercloud/devstack-action@v0.19 with: branch: ${{ matrix.openstack_version }} conf_overrides: | diff --git a/.github/workflows/functional-messaging.yaml b/.github/workflows/functional-messaging.yaml index 52ae48ec2f..5e89e6f33e 100644 --- a/.github/workflows/functional-messaging.yaml +++ b/.github/workflows/functional-messaging.yaml @@ -30,7 +30,7 @@ jobs: - name: Checkout Gophercloud uses: actions/checkout@v4 - name: Deploy devstack - uses: gophercloud/devstack-action@v0.17 + uses: gophercloud/devstack-action@v0.19 with: branch: ${{ matrix.openstack_version }} conf_overrides: | diff --git a/.github/workflows/functional-networking.yaml b/.github/workflows/functional-networking.yaml index 0db64abe2e..1b5b1edb1e 100644 --- a/.github/workflows/functional-networking.yaml +++ b/.github/workflows/functional-networking.yaml @@ -38,7 +38,7 @@ jobs: "update_port:binding:profile": "rule:admin_only or rule:service_api" EOF - name: Deploy devstack - uses: gophercloud/devstack-action@v0.17 + uses: gophercloud/devstack-action@v0.19 with: branch: ${{ matrix.openstack_version }} conf_overrides: | diff --git a/.github/workflows/functional-objectstorage.yaml b/.github/workflows/functional-objectstorage.yaml index 9954f9fa19..180a79caf1 100644 --- a/.github/workflows/functional-objectstorage.yaml +++ b/.github/workflows/functional-objectstorage.yaml @@ -30,7 +30,7 @@ jobs: - name: Checkout Gophercloud uses: actions/checkout@v4 - name: Deploy devstack - uses: gophercloud/devstack-action@v0.17 + uses: gophercloud/devstack-action@v0.19 with: branch: ${{ matrix.openstack_version }} conf_overrides: | diff --git a/.github/workflows/functional-orchestration.yaml b/.github/workflows/functional-orchestration.yaml index 1d6073a562..8d147b1569 100644 --- a/.github/workflows/functional-orchestration.yaml +++ b/.github/workflows/functional-orchestration.yaml @@ -30,7 +30,7 @@ jobs: - name: Checkout Gophercloud uses: actions/checkout@v4 - name: Deploy devstack - uses: gophercloud/devstack-action@v0.17 + uses: gophercloud/devstack-action@v0.19 with: branch: ${{ matrix.openstack_version }} conf_overrides: | diff --git a/.github/workflows/functional-placement.yaml b/.github/workflows/functional-placement.yaml index 1226fb65a0..de02e307fe 100644 --- a/.github/workflows/functional-placement.yaml +++ b/.github/workflows/functional-placement.yaml @@ -30,7 +30,7 @@ jobs: - name: Checkout Gophercloud uses: actions/checkout@v4 - name: Deploy devstack - uses: gophercloud/devstack-action@v0.17 + uses: gophercloud/devstack-action@v0.19 with: branch: ${{ matrix.openstack_version }} enabled_services: "${{ matrix.additional_services }}" diff --git a/.github/workflows/functional-sharedfilesystems.yaml b/.github/workflows/functional-sharedfilesystems.yaml index 48177ab05c..f56bcd066f 100644 --- a/.github/workflows/functional-sharedfilesystems.yaml +++ b/.github/workflows/functional-sharedfilesystems.yaml @@ -36,7 +36,7 @@ jobs: - name: Checkout Gophercloud uses: actions/checkout@v4 - name: Deploy devstack - uses: gophercloud/devstack-action@v0.17 + uses: gophercloud/devstack-action@v0.19 with: branch: ${{ matrix.openstack_version }} conf_overrides: | diff --git a/.github/workflows/functional-workflow.yaml b/.github/workflows/functional-workflow.yaml index 4fdf8d9a0e..2d48495f24 100644 --- a/.github/workflows/functional-workflow.yaml +++ b/.github/workflows/functional-workflow.yaml @@ -33,7 +33,7 @@ jobs: - name: Checkout Gophercloud uses: actions/checkout@v4 - name: Deploy devstack - uses: gophercloud/devstack-action@v0.17 + uses: gophercloud/devstack-action@v0.19 with: branch: ${{ matrix.openstack_version }} conf_overrides: | From bf5fea57200f0f75baf29af72278cf7d0663ab71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Andr=C3=A9?= Date: Thu, 12 Jun 2025 11:04:00 +0200 Subject: [PATCH 150/353] Fix documentation for gateway_ip in subnet update The neutron documentation was wrong, and not providing a gateway_ip is a no-op for subnet update. Neutron docs being fixed at [1]. [1] https://review.opendev.org/c/openstack/neutron-lib/+/952428 --- openstack/networking/v2/subnets/requests.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/openstack/networking/v2/subnets/requests.go b/openstack/networking/v2/subnets/requests.go index 6f1679b0b2..85c5d2b402 100644 --- a/openstack/networking/v2/subnets/requests.go +++ b/openstack/networking/v2/subnets/requests.go @@ -199,9 +199,8 @@ type UpdateOpts struct { // AllocationPools are IP Address pools that will be available for DHCP. AllocationPools []AllocationPool `json:"allocation_pools,omitempty"` - // GatewayIP sets gateway information for the subnet. Setting to nil will - // cause a default gateway to automatically be created. Setting to an empty - // string will cause the subnet to be created with no gateway. Setting to + // GatewayIP sets gateway information for the subnet. Setting to an empty + // string will cause the subnet to not have a gateway. Setting to // an explicit address will set that address as the gateway. GatewayIP *string `json:"gateway_ip,omitempty"` From aebe26fd3279a7efc1662b8a11e5c24b6cf11219 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Wed, 18 Jun 2025 10:18:01 +0100 Subject: [PATCH 151/353] Use container-infra for OpenStack-API-Version Due to a bug in Magnum, we are currently unable to use the official service types in this header. The fix is in progress [1] but even once that lands we will need to support older deployments without the fix. [1] https://review.opendev.org/c/openstack/magnum/+/952804 Signed-off-by: Stephen Finucane Closes: #3429 --- service_client.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/service_client.go b/service_client.go index c1f9f41d4d..015c3f2339 100644 --- a/service_client.go +++ b/service_client.go @@ -130,6 +130,9 @@ func (client *ServiceClient) setMicroversionHeader(opts *RequestOpts) { opts.MoreHeaders["X-OpenStack-Ironic-API-Version"] = client.Microversion case "baremetal-introspection": opts.MoreHeaders["X-OpenStack-Ironic-Inspector-API-Version"] = client.Microversion + case "container-infrastructure-management", "container-infrastructure", "container-infra": + // magnum should accept container-infrastructure-management but (as of Epoxy) does not + serviceType = "container-infra" } if client.Type != "" { From 921ffab31e8997020803c70c43e9160150fda12a Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Thu, 19 Jun 2025 10:55:32 +0100 Subject: [PATCH 152/353] make: Use fixed version of gotestsum The latest version bump the minimum go version to 1.23 [1], which breaks jobs on the v2 branch. [1] https://github.com/gotestyourself/gotestsum/compare/v1.12.2...v1.12.3#diff-33ef32bf6c23acb95f5902d7097b7a1d5128ca061167ec0716715b0b9eeaa5f6 Signed-off-by: Stephen Finucane --- Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 86356b78ab..7aa2ac3e9f 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,8 @@ undefine GOFLAGS GOLANGCI_LINT_VERSION?=v1.62.2 -GO_TEST?=go run gotest.tools/gotestsum@latest --format testname -- +GOTESTSUM_VERSION?=v1.12.2 +GO_TEST?=go run gotest.tools/gotestsum@$(GOTESTSUM_VERSION) --format testname -- TIMEOUT := "60m" ifeq ($(shell command -v podman 2> /dev/null),) From 43f2c9c317ad5c96672b70c76132a2205de9faa3 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Wed, 17 Jul 2024 11:46:11 +0100 Subject: [PATCH 153/353] tests: Avoid use of global objects Global tests objects are harmful, in so far as any attempt to modify them can result in failures further down the food chain. Don't use them and instead generate new objects on the fly. Signed-off-by: Stephen Finucane (cherry picked from commit 610f5456380be620265c701a6d9d36c0ddcb6715) --- .../v2/servergroups/testing/fixtures_test.go | 67 +++-- .../v2/servergroups/testing/requests_test.go | 36 +-- .../v1/capsules/testing/fixtures_test.go | 278 ++++++++++-------- .../v1/capsules/testing/requests_test.go | 40 +-- 4 files changed, 220 insertions(+), 201 deletions(-) diff --git a/openstack/compute/v2/servergroups/testing/fixtures_test.go b/openstack/compute/v2/servergroups/testing/fixtures_test.go index 2ad519023a..d2a87a4467 100644 --- a/openstack/compute/v2/servergroups/testing/fixtures_test.go +++ b/openstack/compute/v2/servergroups/testing/fixtures_test.go @@ -57,9 +57,6 @@ const GetOutputMicroversion = ` "server_group": { "id": "616fb98f-46ca-475e-917e-2563e5a8cd19", "name": "test", - "policies": [ - "anti-affinity" - ], "policy": "anti-affinity", "rules": { "max_server_per_host": 3 @@ -91,9 +88,6 @@ const CreateOutputMicroversion = ` "server_group": { "id": "616fb98f-46ca-475e-917e-2563e5a8cd19", "name": "test", - "policies": [ - "anti-affinity" - ], "policy": "anti-affinity", "rules": { "max_server_per_host": 3 @@ -104,8 +98,10 @@ const CreateOutputMicroversion = ` } ` -// FirstServerGroup is the first result in ListOutput. -var FirstServerGroup = servergroups.ServerGroup{ +var policy = "anti-affinity" + +// ExpectedServerGroupGet is parsed result from GetOutput. +var ExpectedServerGroupGet = servergroups.ServerGroup{ ID: "616fb98f-46ca-475e-917e-2563e5a8cd19", Name: "test", Policies: []string{ @@ -115,23 +111,43 @@ var FirstServerGroup = servergroups.ServerGroup{ Metadata: map[string]any{}, } -// SecondServerGroup is the second result in ListOutput. -var SecondServerGroup = servergroups.ServerGroup{ - ID: "4d8c3732-a248-40ed-bebc-539a6ffd25c0", - Name: "test2", - Policies: []string{ - "affinity", +// ExpectedServerGroupGet is parsed result from GetOutputMicroversion. +var ExpectedServerGroupGetMicroversion = servergroups.ServerGroup{ + ID: "616fb98f-46ca-475e-917e-2563e5a8cd19", + Name: "test", + Policy: &policy, + Rules: &servergroups.Rules{ + MaxServerPerHost: 3, }, Members: []string{}, Metadata: map[string]any{}, } -// ExpectedServerGroupSlice is the slice of results that should be parsed +// ExpectedServerGroupList is the slice of results that should be parsed // from ListOutput, in the expected order. -var ExpectedServerGroupSlice = []servergroups.ServerGroup{FirstServerGroup, SecondServerGroup} +var ExpectedServerGroupList = []servergroups.ServerGroup{ + { + ID: "616fb98f-46ca-475e-917e-2563e5a8cd19", + Name: "test", + Policies: []string{ + "anti-affinity", + }, + Members: []string{}, + Metadata: map[string]any{}, + }, + { + ID: "4d8c3732-a248-40ed-bebc-539a6ffd25c0", + Name: "test2", + Policies: []string{ + "affinity", + }, + Members: []string{}, + Metadata: map[string]any{}, + }, +} -// CreatedServerGroup is the parsed result from CreateOutput. -var CreatedServerGroup = servergroups.ServerGroup{ +// ExpectedServerGroupCreate is the parsed result from CreateOutput. +var ExpectedServerGroupCreate = servergroups.ServerGroup{ ID: "616fb98f-46ca-475e-917e-2563e5a8cd19", Name: "test", Policies: []string{ @@ -141,6 +157,18 @@ var CreatedServerGroup = servergroups.ServerGroup{ Metadata: map[string]any{}, } +// CreatedServerGroup is the parsed result from CreateOutputMicroversion. +var ExpectedServerGroupCreateMicroversion = servergroups.ServerGroup{ + ID: "616fb98f-46ca-475e-917e-2563e5a8cd19", + Name: "test", + Policy: &policy, + Rules: &servergroups.Rules{ + MaxServerPerHost: 3, + }, + Members: []string{}, + Metadata: map[string]any{}, +} + // HandleListSuccessfully configures the test server to respond to a List request. func HandleListSuccessfully(t *testing.T) { th.Mux.HandleFunc("/os-server-groups", func(w http.ResponseWriter, r *http.Request) { @@ -208,9 +236,6 @@ func HandleCreateMicroversionSuccessfully(t *testing.T) { { "server_group": { "name": "test", - "policies": [ - "anti-affinity" - ], "policy": "anti-affinity", "rules": { "max_server_per_host": 3 diff --git a/openstack/compute/v2/servergroups/testing/requests_test.go b/openstack/compute/v2/servergroups/testing/requests_test.go index 91a9b75168..dde919a78a 100644 --- a/openstack/compute/v2/servergroups/testing/requests_test.go +++ b/openstack/compute/v2/servergroups/testing/requests_test.go @@ -20,7 +20,7 @@ func TestList(t *testing.T) { count++ actual, err := servergroups.ExtractServerGroups(page) th.AssertNoErr(t, err) - th.CheckDeepEquals(t, ExpectedServerGroupSlice, actual) + th.CheckDeepEquals(t, ExpectedServerGroupList, actual) return true, nil }) @@ -38,7 +38,7 @@ func TestCreate(t *testing.T) { Policies: []string{"anti-affinity"}, }).Extract() th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &CreatedServerGroup, actual) + th.CheckDeepEquals(t, &ExpectedServerGroupCreate, actual) } func TestCreateMicroversion(t *testing.T) { @@ -46,23 +46,15 @@ func TestCreateMicroversion(t *testing.T) { defer th.TeardownHTTP() HandleCreateMicroversionSuccessfully(t) - policy := "anti-affinity" - rules := servergroups.Rules{ - MaxServerPerHost: 3, - } - CreatedServerGroup.Policy = &policy - CreatedServerGroup.Rules = &rules - result := servergroups.Create(context.TODO(), client.ServiceClient(), servergroups.CreateOpts{ - Name: "test", - Policies: []string{"anti-affinity"}, - Policy: policy, - Rules: &rules, + Name: "test", + Policy: policy, + Rules: ExpectedServerGroupCreateMicroversion.Rules, }) actual, err := result.Extract() th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &CreatedServerGroup, actual) + th.CheckDeepEquals(t, &ExpectedServerGroupCreateMicroversion, actual) } func TestGet(t *testing.T) { @@ -72,7 +64,7 @@ func TestGet(t *testing.T) { actual, err := servergroups.Get(context.TODO(), client.ServiceClient(), "4d8c3732-a248-40ed-bebc-539a6ffd25c0").Extract() th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &FirstServerGroup, actual) + th.CheckDeepEquals(t, &ExpectedServerGroupGet, actual) } func TestGetMicroversion(t *testing.T) { @@ -80,19 +72,9 @@ func TestGetMicroversion(t *testing.T) { defer th.TeardownHTTP() HandleGetMicroversionSuccessfully(t) - policy := "anti-affinity" - rules := servergroups.Rules{ - MaxServerPerHost: 3, - } - FirstServerGroup.Policy = &policy - FirstServerGroup.Rules = &rules - - result := servergroups.Get(context.TODO(), client.ServiceClient(), "4d8c3732-a248-40ed-bebc-539a6ffd25c0") - - // Extract basic fields. - actual, err := result.Extract() + actual, err := servergroups.Get(context.TODO(), client.ServiceClient(), "4d8c3732-a248-40ed-bebc-539a6ffd25c0").Extract() th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &FirstServerGroup, actual) + th.CheckDeepEquals(t, &ExpectedServerGroupGetMicroversion, actual) } func TestDelete(t *testing.T) { diff --git a/openstack/container/v1/capsules/testing/fixtures_test.go b/openstack/container/v1/capsules/testing/fixtures_test.go index 779a41a0df..541b163b44 100644 --- a/openstack/container/v1/capsules/testing/fixtures_test.go +++ b/openstack/container/v1/capsules/testing/fixtures_test.go @@ -4,7 +4,9 @@ import ( "fmt" "net/http" "testing" + "time" + "github.com/gophercloud/gophercloud/v2" "github.com/gophercloud/gophercloud/v2/openstack/container/v1/capsules" th "github.com/gophercloud/gophercloud/v2/testhelper" fakeclient "github.com/gophercloud/gophercloud/v2/testhelper/client" @@ -455,150 +457,168 @@ const CapsuleV132ListBody = ` ] }` -var ExpectedContainer1 = capsules.Container{ - Name: "test-demo-omicron-13", - UUID: "1739e28a-d391-4fd9-93a5-3ba3f29a4c9b", - UserID: "d33b18c384574fd2a3299447aac285f0", - ProjectID: "6b8ffef2a0ac42ee87887b9cc98bdf68", - CPU: float64(1), - Memory: "1024M", - Host: "test-host", - Status: "Running", - Image: "test", - Labels: map[string]string{ - "foo": "bar", - }, - WorkDir: "/root", - Disk: 0, - Command: []string{ - "testcmd", - }, - Ports: []int{ - 80, - }, - SecurityGroups: []string{ - "default", - }, - ImagePullPolicy: "ifnotpresent", - Runtime: "runc", - TaskState: "Creating", - HostName: "test-hostname", - Environment: map[string]string{ - "USER1": "test", - }, - StatusReason: "No reason", - StatusDetail: "Just created", - ImageDriver: "docker", - Interactive: true, - AutoRemove: false, - AutoHeal: false, - RestartPolicy: map[string]string{ - "MaximumRetryCount": "0", - "Name": "always", - }, - Addresses: map[string][]capsules.Address{ - "b1295212-64e1-471d-aa01-25ff46f9818d": { - { - PreserveOnDelete: false, - Addr: "172.24.4.11", - Port: "8439060f-381a-4386-a518-33d5a4058636", - Version: float64(4), - SubnetID: "4a2bcd64-93ad-4436-9f48-3a7f9b267e0a", +func GetFakeContainer() capsules.Container { + createdAt, _ := time.Parse(gophercloud.RFC3339ZNoTNoZ, "2018-01-12 09:37:25") + updatedAt, _ := time.Parse(gophercloud.RFC3339ZNoTNoZ, "2018-01-12 09:37:26") + startedAt, _ := time.Parse(gophercloud.RFC3339ZNoTNoZ, "2018-01-12 09:37:26") + + return capsules.Container{ + Name: "test-demo-omicron-13", + UUID: "1739e28a-d391-4fd9-93a5-3ba3f29a4c9b", + UserID: "d33b18c384574fd2a3299447aac285f0", + ProjectID: "6b8ffef2a0ac42ee87887b9cc98bdf68", + CreatedAt: createdAt, + UpdatedAt: updatedAt, + StartedAt: startedAt, + CPU: float64(1), + Memory: "1024M", + Host: "test-host", + Status: "Running", + Image: "test", + Labels: map[string]string{ + "foo": "bar", + }, + WorkDir: "/root", + Disk: 0, + Command: []string{ + "testcmd", + }, + Ports: []int{ + 80, + }, + SecurityGroups: []string{ + "default", + }, + ImagePullPolicy: "ifnotpresent", + Runtime: "runc", + TaskState: "Creating", + HostName: "test-hostname", + Environment: map[string]string{ + "USER1": "test", + }, + StatusReason: "No reason", + StatusDetail: "Just created", + ImageDriver: "docker", + Interactive: true, + AutoRemove: false, + AutoHeal: false, + RestartPolicy: map[string]string{ + "MaximumRetryCount": "0", + "Name": "always", + }, + Addresses: map[string][]capsules.Address{ + "b1295212-64e1-471d-aa01-25ff46f9818d": { + { + PreserveOnDelete: false, + Addr: "172.24.4.11", + Port: "8439060f-381a-4386-a518-33d5a4058636", + Version: float64(4), + SubnetID: "4a2bcd64-93ad-4436-9f48-3a7f9b267e0a", + }, }, }, - }, + } } -var ExpectedCapsule = capsules.Capsule{ - UUID: "cc654059-1a77-47a3-bfcf-715bde5aad9e", - Status: "Running", - UserID: "d33b18c384574fd2a3299447aac285f0", - ProjectID: "6b8ffef2a0ac42ee87887b9cc98bdf68", - CPU: float64(1), - Memory: "1024M", - MetaName: "test", - Links: []any{ - map[string]any{ - "href": "http://10.10.10.10/v1/capsules/cc654059-1a77-47a3-bfcf-715bde5aad9e", - "rel": "self", +func GetFakeCapsule() capsules.Capsule { + createdAt, _ := time.Parse(gophercloud.RFC3339ZNoTNoZ, "2018-01-12 09:37:25") + updatedAt, _ := time.Parse(gophercloud.RFC3339ZNoTNoZ, "2018-01-12 09:37:26") + + return capsules.Capsule{ + UUID: "cc654059-1a77-47a3-bfcf-715bde5aad9e", + Status: "Running", + UserID: "d33b18c384574fd2a3299447aac285f0", + ProjectID: "6b8ffef2a0ac42ee87887b9cc98bdf68", + CreatedAt: createdAt, + UpdatedAt: updatedAt, + CPU: float64(1), + Memory: "1024M", + MetaName: "test", + Links: []any{ + map[string]any{ + "href": "http://10.10.10.10/v1/capsules/cc654059-1a77-47a3-bfcf-715bde5aad9e", + "rel": "self", + }, + map[string]any{ + "href": "http://10.10.10.10/capsules/cc654059-1a77-47a3-bfcf-715bde5aad9e", + "rel": "bookmark", + }, }, - map[string]any{ - "href": "http://10.10.10.10/capsules/cc654059-1a77-47a3-bfcf-715bde5aad9e", - "rel": "bookmark", + CapsuleVersion: "beta", + RestartPolicy: "always", + MetaLabels: map[string]string{ + "web": "app", }, - }, - CapsuleVersion: "beta", - RestartPolicy: "always", - MetaLabels: map[string]string{ - "web": "app", - }, - ContainersUUIDs: []string{ - "1739e28a-d391-4fd9-93a5-3ba3f29a4c9b", - }, - Addresses: map[string][]capsules.Address{ - "b1295212-64e1-471d-aa01-25ff46f9818d": { - { - PreserveOnDelete: false, - Addr: "172.24.4.11", - Port: "8439060f-381a-4386-a518-33d5a4058636", - Version: float64(4), - SubnetID: "4a2bcd64-93ad-4436-9f48-3a7f9b267e0a", + ContainersUUIDs: []string{ + "1739e28a-d391-4fd9-93a5-3ba3f29a4c9b", + }, + Addresses: map[string][]capsules.Address{ + "b1295212-64e1-471d-aa01-25ff46f9818d": { + { + PreserveOnDelete: false, + Addr: "172.24.4.11", + Port: "8439060f-381a-4386-a518-33d5a4058636", + Version: float64(4), + SubnetID: "4a2bcd64-93ad-4436-9f48-3a7f9b267e0a", + }, }, }, - }, - VolumesInfo: map[string][]string{ - "67618d54-dd55-4f7e-91b3-39ffb3ba7f5f": { - "1739e28a-d391-4fd9-93a5-3ba3f29a4c9b", + VolumesInfo: map[string][]string{ + "67618d54-dd55-4f7e-91b3-39ffb3ba7f5f": { + "1739e28a-d391-4fd9-93a5-3ba3f29a4c9b", + }, }, - }, - Host: "test-host", - StatusReason: "No reason", - Containers: []capsules.Container{ - ExpectedContainer1, - }, + Host: "test-host", + StatusReason: "No reason", + Containers: []capsules.Container{ + GetFakeContainer(), + }, + } } -var ExpectedCapsuleV132 = capsules.CapsuleV132{ - UUID: "cc654059-1a77-47a3-bfcf-715bde5aad9e", - Status: "Running", - UserID: "d33b18c384574fd2a3299447aac285f0", - ProjectID: "6b8ffef2a0ac42ee87887b9cc98bdf68", - CPU: float64(1), - Memory: "1024M", - MetaName: "test", - Links: []any{ - map[string]any{ - "href": "http://10.10.10.10/v1/capsules/cc654059-1a77-47a3-bfcf-715bde5aad9e", - "rel": "self", +func GetFakeCapsuleV132() capsules.CapsuleV132 { + return capsules.CapsuleV132{ + UUID: "cc654059-1a77-47a3-bfcf-715bde5aad9e", + Status: "Running", + UserID: "d33b18c384574fd2a3299447aac285f0", + ProjectID: "6b8ffef2a0ac42ee87887b9cc98bdf68", + CPU: float64(1), + Memory: "1024M", + MetaName: "test", + Links: []any{ + map[string]any{ + "href": "http://10.10.10.10/v1/capsules/cc654059-1a77-47a3-bfcf-715bde5aad9e", + "rel": "self", + }, + map[string]any{ + "href": "http://10.10.10.10/capsules/cc654059-1a77-47a3-bfcf-715bde5aad9e", + "rel": "bookmark", + }, }, - map[string]any{ - "href": "http://10.10.10.10/capsules/cc654059-1a77-47a3-bfcf-715bde5aad9e", - "rel": "bookmark", + RestartPolicy: map[string]string{ + "MaximumRetryCount": "0", + "Name": "always", }, - }, - RestartPolicy: map[string]string{ - "MaximumRetryCount": "0", - "Name": "always", - }, - MetaLabels: map[string]string{ - "web": "app", - }, - Addresses: map[string][]capsules.Address{ - "b1295212-64e1-471d-aa01-25ff46f9818d": { - { - PreserveOnDelete: false, - Addr: "172.24.4.11", - Port: "8439060f-381a-4386-a518-33d5a4058636", - Version: float64(4), - SubnetID: "4a2bcd64-93ad-4436-9f48-3a7f9b267e0a", + MetaLabels: map[string]string{ + "web": "app", + }, + Addresses: map[string][]capsules.Address{ + "b1295212-64e1-471d-aa01-25ff46f9818d": { + { + PreserveOnDelete: false, + Addr: "172.24.4.11", + Port: "8439060f-381a-4386-a518-33d5a4058636", + Version: float64(4), + SubnetID: "4a2bcd64-93ad-4436-9f48-3a7f9b267e0a", + }, }, }, - }, - Host: "test-host", - StatusReason: "No reason", - Containers: []capsules.Container{ - ExpectedContainer1, - }, + Host: "test-host", + StatusReason: "No reason", + Containers: []capsules.Container{ + GetFakeContainer(), + }, + } } // HandleCapsuleGetOldTimeSuccessfully test setup diff --git a/openstack/container/v1/capsules/testing/requests_test.go b/openstack/container/v1/capsules/testing/requests_test.go index 2925f93ecc..3805a0aef4 100644 --- a/openstack/container/v1/capsules/testing/requests_test.go +++ b/openstack/container/v1/capsules/testing/requests_test.go @@ -22,16 +22,17 @@ func TestGetCapsule_OldTime(t *testing.T) { updatedAt, _ := time.Parse(gophercloud.RFC3339ZNoT, "2018-01-12 09:37:26+00:00") startedAt, _ := time.Parse(gophercloud.RFC3339ZNoT, "2018-01-12 09:37:26+00:00") - ExpectedCapsule.CreatedAt = createdAt - ExpectedCapsule.UpdatedAt = updatedAt - ExpectedCapsule.Containers[0].CreatedAt = createdAt - ExpectedCapsule.Containers[0].UpdatedAt = updatedAt - ExpectedCapsule.Containers[0].StartedAt = startedAt + ec := GetFakeCapsule() + ec.CreatedAt = createdAt + ec.UpdatedAt = updatedAt + ec.Containers[0].CreatedAt = createdAt + ec.Containers[0].UpdatedAt = updatedAt + ec.Containers[0].StartedAt = startedAt - actualCapsule, err := capsules.Get(context.TODO(), fakeclient.ServiceClient(), ExpectedCapsule.UUID).Extract() + actualCapsule, err := capsules.Get(context.TODO(), fakeclient.ServiceClient(), ec.UUID).Extract() th.AssertNoErr(t, err) - th.AssertDeepEquals(t, &ExpectedCapsule, actualCapsule) + th.AssertDeepEquals(t, &ec, actualCapsule) } func TestGetCapsule_NewTime(t *testing.T) { @@ -40,20 +41,12 @@ func TestGetCapsule_NewTime(t *testing.T) { HandleCapsuleGetNewTimeSuccessfully(t) - createdAt, _ := time.Parse(gophercloud.RFC3339ZNoTNoZ, "2018-01-12 09:37:25") - updatedAt, _ := time.Parse(gophercloud.RFC3339ZNoTNoZ, "2018-01-12 09:37:26") - startedAt, _ := time.Parse(gophercloud.RFC3339ZNoTNoZ, "2018-01-12 09:37:26") - - ExpectedCapsule.CreatedAt = createdAt - ExpectedCapsule.UpdatedAt = updatedAt - ExpectedCapsule.Containers[0].CreatedAt = createdAt - ExpectedCapsule.Containers[0].UpdatedAt = updatedAt - ExpectedCapsule.Containers[0].StartedAt = startedAt + ec := GetFakeCapsule() - actualCapsule, err := capsules.Get(context.TODO(), fakeclient.ServiceClient(), ExpectedCapsule.UUID).Extract() + actualCapsule, err := capsules.Get(context.TODO(), fakeclient.ServiceClient(), ec.UUID).Extract() th.AssertNoErr(t, err) - th.AssertDeepEquals(t, &ExpectedCapsule, actualCapsule) + th.AssertDeepEquals(t, &ec, actualCapsule) } func TestCreateCapsule(t *testing.T) { @@ -61,16 +54,17 @@ func TestCreateCapsule(t *testing.T) { defer th.TeardownHTTP() HandleCapsuleCreateSuccessfully(t) + ec := GetFakeCapsule() + template := new(capsules.Template) template.Bin = []byte(ValidJSONTemplate) - createOpts := capsules.CreateOpts{ TemplateOpts: template, } actualCapsule, err := capsules.Create(context.TODO(), fakeclient.ServiceClient(), createOpts).Extract() th.AssertNoErr(t, err) - th.AssertDeepEquals(t, &ExpectedCapsule, actualCapsule) + th.AssertDeepEquals(t, &ec, actualCapsule) } func TestListCapsule(t *testing.T) { @@ -82,8 +76,7 @@ func TestListCapsule(t *testing.T) { createdAt, _ := time.Parse(gophercloud.RFC3339ZNoT, "2018-01-12 09:37:25+00:00") updatedAt, _ := time.Parse(gophercloud.RFC3339ZNoT, "2018-01-12 09:37:25+01:00") - ec := ExpectedCapsule - + ec := GetFakeCapsule() ec.CreatedAt = createdAt ec.UpdatedAt = updatedAt ec.Containers = nil @@ -120,8 +113,7 @@ func TestListCapsuleV132(t *testing.T) { createdAt, _ := time.Parse(gophercloud.RFC3339ZNoTNoZ, "2018-01-12 09:37:25") updatedAt, _ := time.Parse(gophercloud.RFC3339ZNoTNoZ, "2018-01-12 09:37:25") - ec := ExpectedCapsuleV132 - + ec := GetFakeCapsuleV132() ec.CreatedAt = createdAt ec.UpdatedAt = updatedAt ec.Containers = nil From e918088e41c379016ae39184fd2f643e361f47ef Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Wed, 17 Jul 2024 12:19:41 +0100 Subject: [PATCH 154/353] tests: Add missing fake servers The fake service clients rely on the fake server being initialised, even if we don't actually use it. Add the missing calls, renaming some tests in the process. PS: You can reproduce this without the '-shuffle on' by simply deleting any of the test cases preceding those that we are modifying here and running the tests. Signed-off-by: Stephen Finucane (cherry picked from commit 47b361b2587a8e25f27c84f4fa9d6cd52502f146) --- .../baremetal/v1/nodes/testing/requests_test.go | 13 ++++++++++++- .../v2/flavorprofiles/testing/requests_test.go | 3 +++ .../v2/flavors/testing/requests_test.go | 3 +++ .../v2/l7policies/testing/requests_test.go | 3 +++ .../v2/listeners/testing/requests_test.go | 3 +++ .../v2/monitors/testing/requests_test.go | 6 ++++++ .../loadbalancer/v2/pools/testing/requests_test.go | 6 ++++++ .../v2/extensions/dns/testing/requests_test.go | 3 +++ .../layer3/floatingips/testing/requests_test.go | 5 ++++- .../layer3/routers/testing/requests_test.go | 3 +++ .../portsbinding/testing/requests_test.go | 3 +++ .../security/rules/testing/requests_test.go | 3 +++ .../networking/v2/ports/testing/requests_test.go | 3 +++ .../networking/v2/subnets/testing/requests_test.go | 3 +++ .../v2/securityservices/testing/requests_test.go | 5 ++++- .../v2/sharetypes/testing/requests_test.go | 5 ++++- 16 files changed, 66 insertions(+), 4 deletions(-) diff --git a/openstack/baremetal/v1/nodes/testing/requests_test.go b/openstack/baremetal/v1/nodes/testing/requests_test.go index 24452be0c2..1313725499 100644 --- a/openstack/baremetal/v1/nodes/testing/requests_test.go +++ b/openstack/baremetal/v1/nodes/testing/requests_test.go @@ -159,6 +159,9 @@ func TestUpdateNode(t *testing.T) { } func TestUpdateRequiredOp(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + c := client.ServiceClient() _, err := nodes.Update(context.TODO(), c, "1234asdf", nodes.UpdateOpts{ nodes.UpdateOperation{ @@ -174,6 +177,9 @@ func TestUpdateRequiredOp(t *testing.T) { } func TestUpdateRequiredPath(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + c := client.ServiceClient() _, err := nodes.Update(context.TODO(), c, "1234asdf", nodes.UpdateOpts{ nodes.UpdateOperation{ @@ -283,7 +289,6 @@ func TestNodeChangeProvisionStateActiveWithSteps(t *testing.T) { func TestHandleNodeChangeProvisionStateConfigDrive(t *testing.T) { th.SetupHTTP() defer th.TeardownHTTP() - HandleNodeChangeProvisionStateConfigDrive(t) c := client.ServiceClient() @@ -343,6 +348,9 @@ func TestNodeChangeProvisionStateCleanWithConflict(t *testing.T) { } func TestCleanStepRequiresInterface(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + c := client.ServiceClient() err := nodes.ChangeProvisionState(context.TODO(), c, "1234asdf", nodes.ProvisionStateOpts{ Target: nodes.TargetClean, @@ -362,6 +370,9 @@ func TestCleanStepRequiresInterface(t *testing.T) { } func TestCleanStepRequiresStep(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + c := client.ServiceClient() err := nodes.ChangeProvisionState(context.TODO(), c, "1234asdf", nodes.ProvisionStateOpts{ Target: nodes.TargetClean, diff --git a/openstack/loadbalancer/v2/flavorprofiles/testing/requests_test.go b/openstack/loadbalancer/v2/flavorprofiles/testing/requests_test.go index aebb2c9408..d81434134f 100644 --- a/openstack/loadbalancer/v2/flavorprofiles/testing/requests_test.go +++ b/openstack/loadbalancer/v2/flavorprofiles/testing/requests_test.go @@ -70,6 +70,9 @@ func TestCreateFlavorProfile(t *testing.T) { } func TestRequiredCreateOpts(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + res := flavorprofiles.Create(context.TODO(), fake.ServiceClient(), flavorprofiles.CreateOpts{}) if res.Err == nil { t.Fatalf("Expected error, got none") diff --git a/openstack/loadbalancer/v2/flavors/testing/requests_test.go b/openstack/loadbalancer/v2/flavors/testing/requests_test.go index bc73b1271d..20e5e853b0 100644 --- a/openstack/loadbalancer/v2/flavors/testing/requests_test.go +++ b/openstack/loadbalancer/v2/flavors/testing/requests_test.go @@ -118,6 +118,9 @@ func TestCreateFlavor(t *testing.T) { } func TestRequiredCreateOpts(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + res := flavors.Create(context.TODO(), fake.ServiceClient(), flavors.CreateOpts{}) if res.Err == nil { t.Fatalf("Expected error, got none") diff --git a/openstack/loadbalancer/v2/l7policies/testing/requests_test.go b/openstack/loadbalancer/v2/l7policies/testing/requests_test.go index 328215982d..4ccfd1701c 100644 --- a/openstack/loadbalancer/v2/l7policies/testing/requests_test.go +++ b/openstack/loadbalancer/v2/l7policies/testing/requests_test.go @@ -27,6 +27,9 @@ func TestCreateL7Policy(t *testing.T) { } func TestRequiredL7PolicyCreateOpts(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + // no param specified. res := l7policies.Create(context.TODO(), fake.ServiceClient(), l7policies.CreateOpts{}) if res.Err == nil { diff --git a/openstack/loadbalancer/v2/listeners/testing/requests_test.go b/openstack/loadbalancer/v2/listeners/testing/requests_test.go index 220119a43a..019b2c9f65 100644 --- a/openstack/loadbalancer/v2/listeners/testing/requests_test.go +++ b/openstack/loadbalancer/v2/listeners/testing/requests_test.go @@ -77,6 +77,9 @@ func TestCreateListener(t *testing.T) { } func TestRequiredCreateOpts(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + res := listeners.Create(context.TODO(), fake.ServiceClient(), listeners.CreateOpts{}) if res.Err == nil { t.Fatalf("Expected error, got none") diff --git a/openstack/loadbalancer/v2/monitors/testing/requests_test.go b/openstack/loadbalancer/v2/monitors/testing/requests_test.go index 1af0aaf9a8..952b7fef03 100644 --- a/openstack/loadbalancer/v2/monitors/testing/requests_test.go +++ b/openstack/loadbalancer/v2/monitors/testing/requests_test.go @@ -79,6 +79,9 @@ func TestCreateHealthmonitor(t *testing.T) { } func TestRequiredCreateOpts(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + res := monitors.Create(context.TODO(), fake.ServiceClient(), monitors.CreateOpts{}) if res.Err == nil { t.Fatalf("Expected error, got none") @@ -136,6 +139,9 @@ func TestUpdateHealthmonitor(t *testing.T) { } func TestDelayMustBeGreaterOrEqualThanTimeout(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + _, err := monitors.Create(context.TODO(), fake.ServiceClient(), monitors.CreateOpts{ Type: "HTTP", PoolID: "d459f7d8-c6ee-439d-8713-d3fc08aeed8d", diff --git a/openstack/loadbalancer/v2/pools/testing/requests_test.go b/openstack/loadbalancer/v2/pools/testing/requests_test.go index 6e3126329a..fe40e09471 100644 --- a/openstack/loadbalancer/v2/pools/testing/requests_test.go +++ b/openstack/loadbalancer/v2/pools/testing/requests_test.go @@ -112,6 +112,9 @@ func TestUpdatePool(t *testing.T) { } func TestRequiredPoolCreateOpts(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + res := pools.Create(context.TODO(), fake.ServiceClient(), pools.CreateOpts{}) if res.Err == nil { t.Fatalf("Expected error, got none") @@ -206,6 +209,9 @@ func TestCreateMember(t *testing.T) { } func TestRequiredMemberCreateOpts(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + res := pools.CreateMember(context.TODO(), fake.ServiceClient(), "", pools.CreateMemberOpts{}) if res.Err == nil { t.Fatalf("Expected error, got none") diff --git a/openstack/networking/v2/extensions/dns/testing/requests_test.go b/openstack/networking/v2/extensions/dns/testing/requests_test.go index 645edf7d32..3174c8c791 100644 --- a/openstack/networking/v2/extensions/dns/testing/requests_test.go +++ b/openstack/networking/v2/extensions/dns/testing/requests_test.go @@ -174,6 +174,9 @@ func TestPortCreate(t *testing.T) { } func TestPortRequiredCreateOpts(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + res := ports.Create(context.TODO(), fake.ServiceClient(), dns.PortCreateOptsExt{CreateOptsBuilder: ports.CreateOpts{}}) if res.Err == nil { t.Fatalf("Expected error, got none") diff --git a/openstack/networking/v2/extensions/layer3/floatingips/testing/requests_test.go b/openstack/networking/v2/extensions/layer3/floatingips/testing/requests_test.go index 40f5054b99..7b213110d7 100644 --- a/openstack/networking/v2/extensions/layer3/floatingips/testing/requests_test.go +++ b/openstack/networking/v2/extensions/layer3/floatingips/testing/requests_test.go @@ -101,7 +101,10 @@ func TestInvalidNextPageURLs(t *testing.T) { th.AssertErr(t, err) } -func TestRequiredFieldsForCreate(t *testing.T) { +func TestRequiredCreateOpts(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + res1 := floatingips.Create(context.TODO(), fake.ServiceClient(), floatingips.CreateOpts{FloatingNetworkID: ""}) if res1.Err == nil { t.Fatalf("Expected error, got none") diff --git a/openstack/networking/v2/extensions/layer3/routers/testing/requests_test.go b/openstack/networking/v2/extensions/layer3/routers/testing/requests_test.go index 6ff1242366..679d30aa28 100644 --- a/openstack/networking/v2/extensions/layer3/routers/testing/requests_test.go +++ b/openstack/networking/v2/extensions/layer3/routers/testing/requests_test.go @@ -502,6 +502,9 @@ func TestAddInterface(t *testing.T) { } func TestAddInterfaceRequiredOpts(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + _, err := routers.AddInterface(context.TODO(), fake.ServiceClient(), "foo", routers.AddInterfaceOpts{}).Extract() if err == nil { t.Fatalf("Expected error, got none") diff --git a/openstack/networking/v2/extensions/portsbinding/testing/requests_test.go b/openstack/networking/v2/extensions/portsbinding/testing/requests_test.go index 4f0073b4a5..e613c1ea52 100644 --- a/openstack/networking/v2/extensions/portsbinding/testing/requests_test.go +++ b/openstack/networking/v2/extensions/portsbinding/testing/requests_test.go @@ -143,6 +143,9 @@ func TestCreate(t *testing.T) { } func TestRequiredCreateOpts(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + res := ports.Create(context.TODO(), fake.ServiceClient(), portsbinding.CreateOptsExt{CreateOptsBuilder: ports.CreateOpts{}}) if res.Err == nil { t.Fatalf("Expected error, got none") diff --git a/openstack/networking/v2/extensions/security/rules/testing/requests_test.go b/openstack/networking/v2/extensions/security/rules/testing/requests_test.go index 10aa461908..d705eaf018 100644 --- a/openstack/networking/v2/extensions/security/rules/testing/requests_test.go +++ b/openstack/networking/v2/extensions/security/rules/testing/requests_test.go @@ -318,6 +318,9 @@ func TestCreateBulk(t *testing.T) { } func TestRequiredCreateOpts(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + res := rules.Create(context.TODO(), fake.ServiceClient(), rules.CreateOpts{Direction: rules.DirIngress}) if res.Err == nil { t.Fatalf("Expected error, got none") diff --git a/openstack/networking/v2/ports/testing/requests_test.go b/openstack/networking/v2/ports/testing/requests_test.go index 1b77780610..f1950b4edc 100644 --- a/openstack/networking/v2/ports/testing/requests_test.go +++ b/openstack/networking/v2/ports/testing/requests_test.go @@ -463,6 +463,9 @@ func TestCreateWithInvalidValueSpecs(t *testing.T) { } func TestRequiredCreateOpts(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + res := ports.Create(context.TODO(), fake.ServiceClient(), ports.CreateOpts{}) if res.Err == nil { t.Fatalf("Expected error, got none") diff --git a/openstack/networking/v2/subnets/testing/requests_test.go b/openstack/networking/v2/subnets/testing/requests_test.go index 41ec607cd8..3ae42f2942 100644 --- a/openstack/networking/v2/subnets/testing/requests_test.go +++ b/openstack/networking/v2/subnets/testing/requests_test.go @@ -393,6 +393,9 @@ func TestCreateWithPrefixlen(t *testing.T) { } func TestRequiredCreateOpts(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + res := subnets.Create(context.TODO(), fake.ServiceClient(), subnets.CreateOpts{}) if res.Err == nil { t.Fatalf("Expected error, got none") diff --git a/openstack/sharedfilesystems/v2/securityservices/testing/requests_test.go b/openstack/sharedfilesystems/v2/securityservices/testing/requests_test.go index 391485cdc2..c4cf972827 100644 --- a/openstack/sharedfilesystems/v2/securityservices/testing/requests_test.go +++ b/openstack/sharedfilesystems/v2/securityservices/testing/requests_test.go @@ -39,7 +39,10 @@ func TestCreate(t *testing.T) { } // Verifies that a security service cannot be created without a type -func TestCreateFails(t *testing.T) { +func TestRequiredCreateOpts(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + options := &securityservices.CreateOpts{ Name: "SecServ1", Description: "Creating my first Security Service", diff --git a/openstack/sharedfilesystems/v2/sharetypes/testing/requests_test.go b/openstack/sharedfilesystems/v2/sharetypes/testing/requests_test.go index a88145561f..4490a44c7d 100644 --- a/openstack/sharedfilesystems/v2/sharetypes/testing/requests_test.go +++ b/openstack/sharedfilesystems/v2/sharetypes/testing/requests_test.go @@ -37,7 +37,10 @@ func TestCreate(t *testing.T) { } // Verifies that a share type can't be created if the required parameters are missing -func TestCreateFails(t *testing.T) { +func TestRequiredCreateOpts(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + options := &sharetypes.CreateOpts{ Name: "my_new_share_type", } From fcf44f40913455ddab65c25c43a942dde1fa91c3 Mon Sep 17 00:00:00 2001 From: Stefan Majewsky Date: Mon, 21 Oct 2024 15:46:48 +0200 Subject: [PATCH 155/353] [nova] fix pagination of hypervisors.List() This is a mildly backwards-incompatible change, but since most people only use this API on the level of pagination.Pager, it ought not be a big deal in practice. Closes #3222. (cherry picked from commit 97c0a325b35aa66b26724d72afb22d03d7296111) --- openstack/compute/v2/hypervisors/requests.go | 2 +- openstack/compute/v2/hypervisors/results.go | 15 +++++++- .../v2/hypervisors/testing/fixtures_test.go | 35 ++++++++++++++++--- .../v2/hypervisors/testing/requests_test.go | 9 +++-- 4 files changed, 49 insertions(+), 12 deletions(-) diff --git a/openstack/compute/v2/hypervisors/requests.go b/openstack/compute/v2/hypervisors/requests.go index 37ecbee17a..b17dd35781 100644 --- a/openstack/compute/v2/hypervisors/requests.go +++ b/openstack/compute/v2/hypervisors/requests.go @@ -53,7 +53,7 @@ func List(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pa } return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { - return HypervisorPage{pagination.SinglePageBase(r)} + return HypervisorPage{pagination.LinkedPageBase{PageResult: r}} }) } diff --git a/openstack/compute/v2/hypervisors/results.go b/openstack/compute/v2/hypervisors/results.go index ee6046c6c0..0a35dfdf0f 100644 --- a/openstack/compute/v2/hypervisors/results.go +++ b/openstack/compute/v2/hypervisors/results.go @@ -240,7 +240,7 @@ func (r *Hypervisor) UnmarshalJSON(b []byte) error { // HypervisorPage represents a single page of all Hypervisors from a List // request. type HypervisorPage struct { - pagination.SinglePageBase + pagination.LinkedPageBase } // IsEmpty determines whether or not a HypervisorPage is empty. @@ -253,6 +253,19 @@ func (page HypervisorPage) IsEmpty() (bool, error) { return len(va) == 0, err } +// NextPageURL uses the response's embedded link reference to navigate to the +// next page of results. +func (page HypervisorPage) NextPageURL() (string, error) { + var s struct { + Links []gophercloud.Link `json:"hypervisors_links"` + } + err := page.ExtractInto(&s) + if err != nil { + return "", err + } + return gophercloud.ExtractNextURL(s.Links) +} + // ExtractHypervisors interprets a page of results as a slice of Hypervisors. func ExtractHypervisors(p pagination.Page) ([]Hypervisor, error) { var h struct { diff --git a/openstack/compute/v2/hypervisors/testing/fixtures_test.go b/openstack/compute/v2/hypervisors/testing/fixtures_test.go index fa0b93a3f8..4bdb2c0613 100644 --- a/openstack/compute/v2/hypervisors/testing/fixtures_test.go +++ b/openstack/compute/v2/hypervisors/testing/fixtures_test.go @@ -6,6 +6,7 @@ import ( "testing" "github.com/gophercloud/gophercloud/v2/openstack/compute/v2/hypervisors" + "github.com/gophercloud/gophercloud/v2/testhelper" th "github.com/gophercloud/gophercloud/v2/testhelper" "github.com/gophercloud/gophercloud/v2/testhelper/client" ) @@ -85,8 +86,8 @@ const HypervisorListBodyPre253 = ` ] }` -// HypervisorListBody represents a raw hypervisor list result with Pike+ release. -const HypervisorListBody = ` +// HypervisorListBodyPage1 represents page 1 of a raw hypervisor list result with Pike+ release. +const HypervisorListBodyPage1 = ` { "hypervisors": [ { @@ -127,7 +128,20 @@ const HypervisorListBody = ` }, "vcpus": 1, "vcpus_used": 0 - }, + } + ], + "hypervisors_links": [ + { + "href": "%s/os-hypervisors/detail?marker=c48f6247-abe4-4a24-824e-ea39e108874f", + "rel": "next" + } + ] +}` + +// HypervisorListBodyPage2 represents page 2 of a raw hypervisor list result with Pike+ release. +const HypervisorListBodyPage2 = ` +{ + "hypervisors": [ { "cpu_info": "{\"arch\": \"x86_64\", \"model\": \"Nehalem\", \"vendor\": \"Intel\", \"features\": [\"pge\", \"clflush\"], \"topology\": {\"cores\": 1, \"threads\": 1, \"sockets\": 4}}", "current_workload": 0, @@ -157,6 +171,9 @@ const HypervisorListBody = ` ] }` +// HypervisorListBodyEmpty represents an empty raw hypervisor list result, marking the end of pagination. +const HypervisorListBodyEmpty = `{ "hypervisors": [] }` + // HypervisorListWithParametersBody represents a raw hypervisor list result with Pike+ release. const HypervisorListWithParametersBody = ` { @@ -624,8 +641,16 @@ func HandleHypervisorListSuccessfully(t *testing.T) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - w.Header().Add("Content-Type", "application/json") - fmt.Fprint(w, HypervisorListBody) + switch r.URL.Query().Get("marker") { + case "": + w.Header().Add("Content-Type", "application/json") + fmt.Fprintf(w, HypervisorListBodyPage1, testhelper.Server.URL) + case "c48f6247-abe4-4a24-824e-ea39e108874f": + w.Header().Add("Content-Type", "application/json") + fmt.Fprint(w, HypervisorListBodyPage2) + default: + http.Error(w, "unexpected marker value", http.StatusInternalServerError) + } }) } diff --git a/openstack/compute/v2/hypervisors/testing/requests_test.go b/openstack/compute/v2/hypervisors/testing/requests_test.go index 0303f7f1d0..5acf7d0d1a 100644 --- a/openstack/compute/v2/hypervisors/testing/requests_test.go +++ b/openstack/compute/v2/hypervisors/testing/requests_test.go @@ -69,19 +69,18 @@ func TestListHypervisors(t *testing.T) { return false, err } - if len(actual) != 2 { - t.Fatalf("Expected 2 hypervisors, got %d", len(actual)) + if len(actual) != 1 { + t.Fatalf("Expected 1 hypervisors on page %d, got %d", pages, len(actual)) } th.CheckDeepEquals(t, HypervisorFake, actual[0]) - th.CheckDeepEquals(t, HypervisorFake, actual[1]) return true, nil }) th.AssertNoErr(t, err) - if pages != 1 { - t.Errorf("Expected 1 page, saw %d", pages) + if pages != 2 { + t.Errorf("Expected 2 pages, saw %d", pages) } } From dd4d795f6a96e35e6d4d3af64db2770b79376824 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Wed, 17 Jul 2024 13:36:04 +0100 Subject: [PATCH 156/353] trivial: Remove duplicate imports Ahead of some large-scale rework here. Signed-off-by: Stephen Finucane (cherry picked from commit 1476dae00a42ee02c5c37adaff86165524419ecf) --- openstack/compute/v2/hypervisors/testing/fixtures_test.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/openstack/compute/v2/hypervisors/testing/fixtures_test.go b/openstack/compute/v2/hypervisors/testing/fixtures_test.go index 4bdb2c0613..ebb23c1f31 100644 --- a/openstack/compute/v2/hypervisors/testing/fixtures_test.go +++ b/openstack/compute/v2/hypervisors/testing/fixtures_test.go @@ -6,7 +6,6 @@ import ( "testing" "github.com/gophercloud/gophercloud/v2/openstack/compute/v2/hypervisors" - "github.com/gophercloud/gophercloud/v2/testhelper" th "github.com/gophercloud/gophercloud/v2/testhelper" "github.com/gophercloud/gophercloud/v2/testhelper/client" ) @@ -644,7 +643,7 @@ func HandleHypervisorListSuccessfully(t *testing.T) { switch r.URL.Query().Get("marker") { case "": w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, HypervisorListBodyPage1, testhelper.Server.URL) + fmt.Fprintf(w, HypervisorListBodyPage1, th.Server.URL) case "c48f6247-abe4-4a24-824e-ea39e108874f": w.Header().Add("Content-Type", "application/json") fmt.Fprint(w, HypervisorListBodyPage2) From 2de3b171b36566765d834b403970933f857706b0 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Tue, 20 May 2025 17:46:10 +0100 Subject: [PATCH 157/353] tests: Consistent testhelper client naming All aliases were discovered with: ag '[^\t]"github.com/gophercloud/gophercloud/v2/testhelper/client"' They were then replaced with judicious use of sed and ag. Starting with the most common alias, 'fake', first replace the alias: sed -i 's/\/client/' $(ag 'fake "github.com/gophercloud/gophercloud/v2/testhelper/client"' -l) This was repeated for the other aliases, 'fakeclient' and 'thclient'. We then dropped the now unnecessary aliasing: sed -i 's/\ "/"/' $(ag 'client "github.com/gophercloud/gophercloud/v2/testhelper/client"' -l) Signed-off-by: Stephen Finucane (cherry picked from commit beeed5be120d299bff38a0218e9f9e973d23eb71) --- .../v2/backups/testing/fixtures_test.go | 22 +++---- .../v2/snapshots/testing/fixtures_test.go | 12 ++-- .../v2/volumes/testing/fixtures_test.go | 42 ++++++------- .../v3/attachments/testing/fixtures_test.go | 16 ++--- .../v3/backups/testing/fixtures_test.go | 22 +++---- .../v3/qos/testing/fixtures_test.go | 22 +++---- .../v3/snapshots/testing/fixtures_test.go | 22 +++---- .../v3/volumes/testing/fixtures_test.go | 44 ++++++------- .../v3/volumetypes/testing/fixtures_test.go | 32 +++++----- .../v2/flavors/testing/fixtures_test.go | 12 ++-- .../v2/flavors/testing/requests_test.go | 44 ++++++------- .../remoteconsoles/testing/requests_test.go | 6 +- .../v2/secgroups/testing/fixtures_test.go | 28 ++++----- .../v1/capsules/testing/fixtures_test.go | 14 ++--- .../v1/capsules/testing/requests_test.go | 14 ++--- .../v1/certificates/testing/fixtures_test.go | 8 +-- .../v1/certificates/testing/requests_test.go | 8 +-- .../v1/clusters/testing/fixtures_test.go | 18 +++--- .../v1/clusters/testing/requests_test.go | 18 +++--- .../clustertemplates/testing/fixtures_test.go | 18 +++--- .../clustertemplates/testing/requests_test.go | 18 +++--- .../v1/nodegroups/testing/fixtures_test.go | 38 ++++++------ .../v1/nodegroups/testing/requests_test.go | 38 ++++++------ .../v1/quotas/testing/fixtures_test.go | 4 +- .../v1/quotas/testing/requests_test.go | 4 +- .../configurations/testing/requests_test.go | 24 +++---- .../db/v1/databases/testing/requests_test.go | 8 +-- .../db/v1/datastores/testing/requests_test.go | 10 +-- .../db/v1/flavors/testing/requests_test.go | 6 +- .../db/v1/instances/testing/requests_test.go | 26 ++++---- .../db/v1/users/testing/requests_test.go | 8 +-- .../v2/roles/testing/fixtures_test.go | 8 +-- .../v2/tokens/testing/fixtures_test.go | 4 +- .../v2/users/testing/fixtures_test.go | 14 ++--- .../v3/osinherit/testing/fixtures_test.go | 26 ++++---- .../v3/policies/testing/fixtures_test.go | 12 ++-- .../v3/roles/testing/fixtures_test.go | 50 +++++++-------- .../v2/imagedata/testing/fixtures_test.go | 8 +-- .../v2/imagedata/testing/requests_test.go | 8 +-- .../v2/imageimport/testing/requests_test.go | 10 +-- .../image/v2/images/testing/fixtures_test.go | 18 +++--- .../image/v2/images/testing/requests_test.go | 20 +++--- .../image/v2/members/testing/fixtures_test.go | 14 ++--- .../image/v2/members/testing/requests_test.go | 14 ++--- .../image/v2/tasks/testing/requests_test.go | 14 ++--- .../v2/claims/testing/fixtures_test.go | 12 ++-- .../v2/claims/testing/requests_test.go | 12 ++-- .../v2/messages/testing/fixtures_test.go | 16 ++--- .../v2/messages/testing/requests_test.go | 16 ++--- .../v2/queues/testing/fixtures_test.go | 18 +++--- .../v2/queues/testing/requests_test.go | 18 +++--- .../v2/apiversions/testing/requests_test.go | 14 ++--- .../qos/ruletypes/testing/requests_test.go | 10 +-- .../trunk_details/testing/requests_test.go | 6 +- .../v1/accounts/testing/fixtures.go | 8 +-- .../v1/accounts/testing/requests_test.go | 8 +-- .../v1/containers/testing/fixtures.go | 20 +++--- .../v1/containers/testing/requests_test.go | 34 +++++----- .../v1/objects/testing/fixtures_test.go | 28 ++++----- .../v1/objects/testing/requests_test.go | 62 +++++++++---------- .../v1/apiversions/testing/requests_test.go | 8 +-- .../v1/buildinfo/testing/fixtures_test.go | 4 +- .../v1/buildinfo/testing/requests_test.go | 4 +- .../v1/resourcetypes/testing/fixtures_test.go | 8 +-- .../v1/resourcetypes/testing/requests_test.go | 12 ++-- .../v1/stackevents/testing/fixtures_test.go | 10 +-- .../v1/stackevents/testing/requests_test.go | 10 +-- .../stackresources/testing/fixtures_test.go | 18 +++--- .../stackresources/testing/requests_test.go | 18 +++--- .../v1/stacks/testing/fixtures_test.go | 20 +++--- .../v1/stacks/testing/requests_test.go | 26 ++++---- .../stacktemplates/testing/fixtures_test.go | 6 +- .../stacktemplates/testing/requests_test.go | 6 +- .../testing/fixtures_test.go | 20 +++--- .../testing/requests_test.go | 20 +++--- .../testing/fixtures_test.go | 4 +- .../v2/errors/testing/fixtures_test.go | 4 +- .../v2/messages/testing/fixtures_test.go | 10 +-- .../v2/replicas/testing/fixtures_test.go | 26 ++++---- .../securityservices/testing/fixtures_test.go | 14 ++--- .../shareaccessrules/testing/fixtures_test.go | 4 +- .../shareaccessrules/testing/requests_test.go | 3 +- .../v2/sharenetworks/testing/fixtures_test.go | 20 +++--- .../v2/shares/testing/fixtures_test.go | 44 ++++++------- .../v2/sharetypes/testing/fixtures_test.go | 22 +++---- .../v2/snapshots/testing/fixtures_test.go | 16 ++--- .../v2/crontriggers/testing/requests_test.go | 18 +++--- .../v2/executions/testing/requests_test.go | 18 +++--- .../v2/workflows/testing/requests_test.go | 18 +++--- 89 files changed, 759 insertions(+), 760 deletions(-) diff --git a/openstack/blockstorage/v2/backups/testing/fixtures_test.go b/openstack/blockstorage/v2/backups/testing/fixtures_test.go index 4f1f45c122..8290c17672 100644 --- a/openstack/blockstorage/v2/backups/testing/fixtures_test.go +++ b/openstack/blockstorage/v2/backups/testing/fixtures_test.go @@ -9,7 +9,7 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/blockstorage/v2/backups" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) const ListResponse = ` @@ -197,7 +197,7 @@ var ( func MockListResponse(t *testing.T) { th.Mux.HandleFunc("/backups", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -220,7 +220,7 @@ func MockListResponse(t *testing.T) { func MockListDetailResponse(t *testing.T) { th.Mux.HandleFunc("/backups/detail", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -243,7 +243,7 @@ func MockListDetailResponse(t *testing.T) { func MockGetResponse(t *testing.T) { th.Mux.HandleFunc("/backups/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -254,7 +254,7 @@ func MockGetResponse(t *testing.T) { func MockCreateResponse(t *testing.T) { th.Mux.HandleFunc("/backups", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, CreateRequest) @@ -269,7 +269,7 @@ func MockCreateResponse(t *testing.T) { func MockRestoreResponse(t *testing.T) { th.Mux.HandleFunc("/backups/d32019d3-bc6e-4319-9c1d-6722fc136a22/restore", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, RestoreRequest) @@ -284,7 +284,7 @@ func MockRestoreResponse(t *testing.T) { func MockDeleteResponse(t *testing.T) { th.Mux.HandleFunc("/backups/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) } @@ -292,7 +292,7 @@ func MockDeleteResponse(t *testing.T) { func MockExportResponse(t *testing.T) { th.Mux.HandleFunc("/backups/d32019d3-bc6e-4319-9c1d-6722fc136a22/export_record", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") w.Header().Add("Content-Type", "application/json") @@ -305,7 +305,7 @@ func MockExportResponse(t *testing.T) { func MockImportResponse(t *testing.T) { th.Mux.HandleFunc("/backups/import_record", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, ImportRequest) @@ -321,7 +321,7 @@ func MockImportResponse(t *testing.T) { func MockResetStatusResponse(t *testing.T) { th.Mux.HandleFunc("/backups/d32019d3-bc6e-4319-9c1d-6722fc136a22/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestJSONRequest(t, r, ResetRequest) @@ -333,7 +333,7 @@ func MockResetStatusResponse(t *testing.T) { func MockForceDeleteResponse(t *testing.T) { th.Mux.HandleFunc("/backups/d32019d3-bc6e-4319-9c1d-6722fc136a22/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestJSONRequest(t, r, ForceDeleteRequest) diff --git a/openstack/blockstorage/v2/snapshots/testing/fixtures_test.go b/openstack/blockstorage/v2/snapshots/testing/fixtures_test.go index b2e5cf4c06..da258e366b 100644 --- a/openstack/blockstorage/v2/snapshots/testing/fixtures_test.go +++ b/openstack/blockstorage/v2/snapshots/testing/fixtures_test.go @@ -6,13 +6,13 @@ import ( "testing" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) func MockListResponse(t *testing.T) { th.Mux.HandleFunc("/snapshots", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -47,7 +47,7 @@ func MockListResponse(t *testing.T) { func MockGetResponse(t *testing.T) { th.Mux.HandleFunc("/snapshots/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -70,7 +70,7 @@ func MockGetResponse(t *testing.T) { func MockCreateResponse(t *testing.T) { th.Mux.HandleFunc("/snapshots", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, ` @@ -105,7 +105,7 @@ func MockCreateResponse(t *testing.T) { func MockUpdateMetadataResponse(t *testing.T) { th.Mux.HandleFunc("/snapshots/123/metadata", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestJSONRequest(t, r, ` { @@ -128,7 +128,7 @@ func MockUpdateMetadataResponse(t *testing.T) { func MockDeleteResponse(t *testing.T) { th.Mux.HandleFunc("/snapshots/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) } diff --git a/openstack/blockstorage/v2/volumes/testing/fixtures_test.go b/openstack/blockstorage/v2/volumes/testing/fixtures_test.go index d6688f7850..06c9123915 100644 --- a/openstack/blockstorage/v2/volumes/testing/fixtures_test.go +++ b/openstack/blockstorage/v2/volumes/testing/fixtures_test.go @@ -6,13 +6,13 @@ import ( "testing" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) func MockListResponse(t *testing.T) { th.Mux.HandleFunc("/volumes/detail", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -89,7 +89,7 @@ func MockListResponse(t *testing.T) { func MockGetResponse(t *testing.T) { th.Mux.HandleFunc("/volumes/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -137,7 +137,7 @@ func MockGetResponse(t *testing.T) { func MockCreateResponse(t *testing.T) { th.Mux.HandleFunc("/volumes", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, ` @@ -182,7 +182,7 @@ func MockCreateResponse(t *testing.T) { func MockDeleteResponse(t *testing.T) { th.Mux.HandleFunc("/volumes/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusAccepted) }) } @@ -190,7 +190,7 @@ func MockDeleteResponse(t *testing.T) { func MockUpdateResponse(t *testing.T) { th.Mux.HandleFunc("/volumes/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusOK) fmt.Fprint(w, ` { @@ -206,7 +206,7 @@ func MockAttachResponse(t *testing.T) { th.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, ` @@ -231,7 +231,7 @@ func MockBeginDetachingResponse(t *testing.T) { th.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, ` @@ -251,7 +251,7 @@ func MockDetachResponse(t *testing.T) { th.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, ` @@ -271,7 +271,7 @@ func MockUploadImageResponse(t *testing.T) { th.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, ` @@ -323,7 +323,7 @@ func MockReserveResponse(t *testing.T) { th.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, ` @@ -343,7 +343,7 @@ func MockUnreserveResponse(t *testing.T) { th.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, ` @@ -363,7 +363,7 @@ func MockInitializeConnectionResponse(t *testing.T) { th.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, ` @@ -420,7 +420,7 @@ func MockTerminateConnectionResponse(t *testing.T) { th.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, ` @@ -451,7 +451,7 @@ func MockExtendSizeResponse(t *testing.T) { th.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, ` @@ -473,7 +473,7 @@ func MockExtendSizeResponse(t *testing.T) { func MockForceDeleteResponse(t *testing.T) { th.Mux.HandleFunc("/volumes/d32019d3-bc6e-4319-9c1d-6722fc136a22/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestBody(t, r, `{"os-force_delete":""}`) w.WriteHeader(http.StatusAccepted) }) @@ -482,7 +482,7 @@ func MockForceDeleteResponse(t *testing.T) { func MockSetImageMetadataResponse(t *testing.T) { th.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, ` @@ -504,7 +504,7 @@ func MockSetImageMetadataResponse(t *testing.T) { func MockSetBootableResponse(t *testing.T) { th.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, ` @@ -523,7 +523,7 @@ func MockSetBootableResponse(t *testing.T) { func MockReImageResponse(t *testing.T) { th.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, ` @@ -544,7 +544,7 @@ func MockChangeTypeResponse(t *testing.T) { th.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, ` @@ -568,7 +568,7 @@ func MockResetStatusResponse(t *testing.T) { th.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestJSONRequest(t, r, ` { diff --git a/openstack/blockstorage/v3/attachments/testing/fixtures_test.go b/openstack/blockstorage/v3/attachments/testing/fixtures_test.go index 18471c3b38..7f1a58e1c3 100644 --- a/openstack/blockstorage/v3/attachments/testing/fixtures_test.go +++ b/openstack/blockstorage/v3/attachments/testing/fixtures_test.go @@ -9,7 +9,7 @@ import ( "github.com/gophercloud/gophercloud/v2" "github.com/gophercloud/gophercloud/v2/openstack/blockstorage/v3/attachments" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) var ( @@ -30,7 +30,7 @@ var ( func MockListResponse(t *testing.T) { th.Mux.HandleFunc("/attachments/detail", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -74,7 +74,7 @@ func MockListResponse(t *testing.T) { func MockGetResponse(t *testing.T) { th.Mux.HandleFunc("/attachments/05551600-a936-4d4a-ba42-79a037c1-c91a", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -98,7 +98,7 @@ func MockGetResponse(t *testing.T) { func MockCreateResponse(t *testing.T) { th.Mux.HandleFunc("/attachments", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, ` @@ -143,7 +143,7 @@ func MockCreateResponse(t *testing.T) { func MockDeleteResponse(t *testing.T) { th.Mux.HandleFunc("/attachments/05551600-a936-4d4a-ba42-79a037c1-c91a", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusOK) }) } @@ -151,7 +151,7 @@ func MockDeleteResponse(t *testing.T) { func MockUpdateResponse(t *testing.T) { th.Mux.HandleFunc("/attachments/05551600-a936-4d4a-ba42-79a037c1-c91a", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, ` { @@ -191,7 +191,7 @@ func MockUpdateResponse(t *testing.T) { func MockUpdateEmptyResponse(t *testing.T) { th.Mux.HandleFunc("/attachments/05551600-a936-4d4a-ba42-79a037c1-c91a", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, ` { @@ -228,7 +228,7 @@ var completeRequest = ` func MockCompleteResponse(t *testing.T) { th.Mux.HandleFunc("/attachments/05551600-a936-4d4a-ba42-79a037c1-c91a/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, completeRequest) w.WriteHeader(http.StatusNoContent) }) diff --git a/openstack/blockstorage/v3/backups/testing/fixtures_test.go b/openstack/blockstorage/v3/backups/testing/fixtures_test.go index 9bbaec87d4..f786de3a86 100644 --- a/openstack/blockstorage/v3/backups/testing/fixtures_test.go +++ b/openstack/blockstorage/v3/backups/testing/fixtures_test.go @@ -9,7 +9,7 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/blockstorage/v3/backups" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) const ListResponse = ` @@ -197,7 +197,7 @@ var ( func MockListResponse(t *testing.T) { th.Mux.HandleFunc("/backups", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -220,7 +220,7 @@ func MockListResponse(t *testing.T) { func MockListDetailResponse(t *testing.T) { th.Mux.HandleFunc("/backups/detail", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -243,7 +243,7 @@ func MockListDetailResponse(t *testing.T) { func MockGetResponse(t *testing.T) { th.Mux.HandleFunc("/backups/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -254,7 +254,7 @@ func MockGetResponse(t *testing.T) { func MockCreateResponse(t *testing.T) { th.Mux.HandleFunc("/backups", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, CreateRequest) @@ -269,7 +269,7 @@ func MockCreateResponse(t *testing.T) { func MockRestoreResponse(t *testing.T) { th.Mux.HandleFunc("/backups/d32019d3-bc6e-4319-9c1d-6722fc136a22/restore", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, RestoreRequest) @@ -284,7 +284,7 @@ func MockRestoreResponse(t *testing.T) { func MockDeleteResponse(t *testing.T) { th.Mux.HandleFunc("/backups/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) } @@ -292,7 +292,7 @@ func MockDeleteResponse(t *testing.T) { func MockExportResponse(t *testing.T) { th.Mux.HandleFunc("/backups/d32019d3-bc6e-4319-9c1d-6722fc136a22/export_record", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") w.Header().Add("Content-Type", "application/json") @@ -305,7 +305,7 @@ func MockExportResponse(t *testing.T) { func MockImportResponse(t *testing.T) { th.Mux.HandleFunc("/backups/import_record", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, ImportRequest) @@ -321,7 +321,7 @@ func MockImportResponse(t *testing.T) { func MockResetStatusResponse(t *testing.T) { th.Mux.HandleFunc("/backups/d32019d3-bc6e-4319-9c1d-6722fc136a22/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestJSONRequest(t, r, ResetRequest) @@ -333,7 +333,7 @@ func MockResetStatusResponse(t *testing.T) { func MockForceDeleteResponse(t *testing.T) { th.Mux.HandleFunc("/backups/d32019d3-bc6e-4319-9c1d-6722fc136a22/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestJSONRequest(t, r, ForceDeleteRequest) diff --git a/openstack/blockstorage/v3/qos/testing/fixtures_test.go b/openstack/blockstorage/v3/qos/testing/fixtures_test.go index e6cd002cea..7d55ddc577 100644 --- a/openstack/blockstorage/v3/qos/testing/fixtures_test.go +++ b/openstack/blockstorage/v3/qos/testing/fixtures_test.go @@ -7,7 +7,7 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/blockstorage/v3/qos" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) var createQoSExpected = qos.QoS{ @@ -31,7 +31,7 @@ var getQoSExpected = qos.QoS{ func MockCreateResponse(t *testing.T) { th.Mux.HandleFunc("/qos-specs", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, ` @@ -65,7 +65,7 @@ func MockCreateResponse(t *testing.T) { func MockDeleteResponse(t *testing.T) { th.Mux.HandleFunc("/qos-specs/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusAccepted) }) } @@ -73,7 +73,7 @@ func MockDeleteResponse(t *testing.T) { func MockListResponse(t *testing.T) { th.Mux.HandleFunc("/qos-specs", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") if err := r.ParseForm(); err != nil { @@ -120,7 +120,7 @@ func MockListResponse(t *testing.T) { func MockGetResponse(t *testing.T) { th.Mux.HandleFunc("/qos-specs/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -160,7 +160,7 @@ var UpdateQos = map[string]string{ func MockUpdateResponse(t *testing.T) { th.Mux.HandleFunc("/qos-specs/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, `{ "qos_specs": { @@ -179,7 +179,7 @@ func MockUpdateResponse(t *testing.T) { func MockDeleteKeysResponse(t *testing.T) { th.Mux.HandleFunc("/qos-specs/d32019d3-bc6e-4319-9c1d-6722fc136a22/delete_keys", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, `{ "keys": [ "read_iops_sec" @@ -193,7 +193,7 @@ func MockDeleteKeysResponse(t *testing.T) { func MockAssociateResponse(t *testing.T) { th.Mux.HandleFunc("/qos-specs/d32019d3-bc6e-4319-9c1d-6722fc136a22/associate", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusAccepted) }) } @@ -201,7 +201,7 @@ func MockAssociateResponse(t *testing.T) { func MockDisassociateResponse(t *testing.T) { th.Mux.HandleFunc("/qos-specs/d32019d3-bc6e-4319-9c1d-6722fc136a22/disassociate", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusAccepted) }) } @@ -209,7 +209,7 @@ func MockDisassociateResponse(t *testing.T) { func MockDisassociateAllResponse(t *testing.T) { th.Mux.HandleFunc("/qos-specs/d32019d3-bc6e-4319-9c1d-6722fc136a22/disassociate_all", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusAccepted) }) } @@ -217,7 +217,7 @@ func MockDisassociateAllResponse(t *testing.T) { func MockListAssociationsResponse(t *testing.T) { th.Mux.HandleFunc("/qos-specs/d32019d3-bc6e-4319-9c1d-6722fc136a22/associations", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") fmt.Fprint(w, ` { diff --git a/openstack/blockstorage/v3/snapshots/testing/fixtures_test.go b/openstack/blockstorage/v3/snapshots/testing/fixtures_test.go index e1bfd37584..f74934e3c4 100644 --- a/openstack/blockstorage/v3/snapshots/testing/fixtures_test.go +++ b/openstack/blockstorage/v3/snapshots/testing/fixtures_test.go @@ -6,14 +6,14 @@ import ( "testing" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) // MockListResponse provides mock response for list snapshot API call func MockListResponse(t *testing.T) { th.Mux.HandleFunc("/snapshots", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -64,7 +64,7 @@ func MockListResponse(t *testing.T) { func MockListDetailsResponse(t *testing.T) { th.Mux.HandleFunc("/snapshots/detail", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -121,7 +121,7 @@ func MockListDetailsResponse(t *testing.T) { func MockGetResponse(t *testing.T) { th.Mux.HandleFunc("/snapshots/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -145,7 +145,7 @@ func MockGetResponse(t *testing.T) { func MockCreateResponse(t *testing.T) { th.Mux.HandleFunc("/snapshots", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, ` @@ -181,7 +181,7 @@ func MockCreateResponse(t *testing.T) { func MockUpdateMetadataResponse(t *testing.T) { th.Mux.HandleFunc("/snapshots/123/metadata", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestJSONRequest(t, r, ` { @@ -205,7 +205,7 @@ func MockUpdateMetadataResponse(t *testing.T) { func MockDeleteResponse(t *testing.T) { th.Mux.HandleFunc("/snapshots/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) } @@ -214,7 +214,7 @@ func MockDeleteResponse(t *testing.T) { func MockUpdateResponse(t *testing.T) { th.Mux.HandleFunc("/snapshots/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -239,7 +239,7 @@ func MockUpdateResponse(t *testing.T) { func MockResetStatusResponse(t *testing.T) { th.Mux.HandleFunc("/snapshots/d32019d3-bc6e-4319-9c1d-6722fc136a22/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestJSONRequest(t, r, ` { @@ -256,7 +256,7 @@ func MockResetStatusResponse(t *testing.T) { func MockUpdateStatusResponse(t *testing.T) { th.Mux.HandleFunc("/snapshots/d32019d3-bc6e-4319-9c1d-6722fc136a22/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestJSONRequest(t, r, ` { @@ -274,7 +274,7 @@ func MockUpdateStatusResponse(t *testing.T) { func MockForceDeleteResponse(t *testing.T) { th.Mux.HandleFunc("/snapshots/d32019d3-bc6e-4319-9c1d-6722fc136a22/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestJSONRequest(t, r, ` { diff --git a/openstack/blockstorage/v3/volumes/testing/fixtures_test.go b/openstack/blockstorage/v3/volumes/testing/fixtures_test.go index 3e156aca1e..adc16c0ea5 100644 --- a/openstack/blockstorage/v3/volumes/testing/fixtures_test.go +++ b/openstack/blockstorage/v3/volumes/testing/fixtures_test.go @@ -6,13 +6,13 @@ import ( "testing" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) func MockListResponse(t *testing.T) { th.Mux.HandleFunc("/volumes/detail", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -105,7 +105,7 @@ func MockListResponse(t *testing.T) { func MockGetResponse(t *testing.T) { th.Mux.HandleFunc("/volumes/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -156,7 +156,7 @@ func MockGetResponse(t *testing.T) { func MockCreateResponse(t *testing.T) { th.Mux.HandleFunc("/volumes", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, ` @@ -201,7 +201,7 @@ func MockCreateResponse(t *testing.T) { func MockDeleteResponse(t *testing.T) { th.Mux.HandleFunc("/volumes/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusAccepted) }) } @@ -209,7 +209,7 @@ func MockDeleteResponse(t *testing.T) { func MockUpdateResponse(t *testing.T) { th.Mux.HandleFunc("/volumes/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusOK) fmt.Fprint(w, ` { @@ -224,7 +224,7 @@ func MockUpdateResponse(t *testing.T) { func MockCreateVolumeFromBackupResponse(t *testing.T) { th.Mux.HandleFunc("/volumes", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, ` @@ -270,7 +270,7 @@ func MockAttachResponse(t *testing.T) { th.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, ` @@ -295,7 +295,7 @@ func MockBeginDetachingResponse(t *testing.T) { th.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, ` @@ -315,7 +315,7 @@ func MockDetachResponse(t *testing.T) { th.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, ` @@ -335,7 +335,7 @@ func MockUploadImageResponse(t *testing.T) { th.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, ` @@ -387,7 +387,7 @@ func MockReserveResponse(t *testing.T) { th.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, ` @@ -407,7 +407,7 @@ func MockUnreserveResponse(t *testing.T) { th.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, ` @@ -427,7 +427,7 @@ func MockInitializeConnectionResponse(t *testing.T) { th.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, ` @@ -484,7 +484,7 @@ func MockTerminateConnectionResponse(t *testing.T) { th.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, ` @@ -515,7 +515,7 @@ func MockExtendSizeResponse(t *testing.T) { th.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, ` @@ -537,7 +537,7 @@ func MockExtendSizeResponse(t *testing.T) { func MockForceDeleteResponse(t *testing.T) { th.Mux.HandleFunc("/volumes/d32019d3-bc6e-4319-9c1d-6722fc136a22/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestBody(t, r, `{"os-force_delete":""}`) w.WriteHeader(http.StatusAccepted) }) @@ -546,7 +546,7 @@ func MockForceDeleteResponse(t *testing.T) { func MockSetImageMetadataResponse(t *testing.T) { th.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, ` @@ -568,7 +568,7 @@ func MockSetImageMetadataResponse(t *testing.T) { func MockSetBootableResponse(t *testing.T) { th.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, ` @@ -587,7 +587,7 @@ func MockSetBootableResponse(t *testing.T) { func MockReImageResponse(t *testing.T) { th.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, ` @@ -608,7 +608,7 @@ func MockChangeTypeResponse(t *testing.T) { th.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, ` @@ -632,7 +632,7 @@ func MockResetStatusResponse(t *testing.T) { th.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestJSONRequest(t, r, ` { diff --git a/openstack/blockstorage/v3/volumetypes/testing/fixtures_test.go b/openstack/blockstorage/v3/volumetypes/testing/fixtures_test.go index c7eb37893e..9cd6d10af7 100644 --- a/openstack/blockstorage/v3/volumetypes/testing/fixtures_test.go +++ b/openstack/blockstorage/v3/volumetypes/testing/fixtures_test.go @@ -6,13 +6,13 @@ import ( "testing" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) func MockListResponse(t *testing.T) { th.Mux.HandleFunc("/types", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -68,7 +68,7 @@ func MockListResponse(t *testing.T) { func MockGetResponse(t *testing.T) { th.Mux.HandleFunc("/types/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -93,7 +93,7 @@ func MockGetResponse(t *testing.T) { func MockCreateResponse(t *testing.T) { th.Mux.HandleFunc("/types", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, ` @@ -133,7 +133,7 @@ func MockCreateResponse(t *testing.T) { func MockDeleteResponse(t *testing.T) { th.Mux.HandleFunc("/types/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusAccepted) }) } @@ -141,7 +141,7 @@ func MockDeleteResponse(t *testing.T) { func MockUpdateResponse(t *testing.T) { th.Mux.HandleFunc("/types/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusOK) fmt.Fprint(w, ` { @@ -198,7 +198,7 @@ var UpdatedExtraSpec = map[string]string{ func HandleExtraSpecsListSuccessfully(t *testing.T) { th.Mux.HandleFunc("/types/1/extra_specs", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") w.Header().Set("Content-Type", "application/json") @@ -210,7 +210,7 @@ func HandleExtraSpecsListSuccessfully(t *testing.T) { func HandleExtraSpecGetSuccessfully(t *testing.T) { th.Mux.HandleFunc("/types/1/extra_specs/capabilities", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") w.Header().Set("Content-Type", "application/json") @@ -222,7 +222,7 @@ func HandleExtraSpecGetSuccessfully(t *testing.T) { func HandleExtraSpecsCreateSuccessfully(t *testing.T) { th.Mux.HandleFunc("/types/1/extra_specs", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, `{ "extra_specs": { @@ -240,7 +240,7 @@ func HandleExtraSpecsCreateSuccessfully(t *testing.T) { func HandleExtraSpecUpdateSuccessfully(t *testing.T) { th.Mux.HandleFunc("/types/1/extra_specs/capabilities", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, `{ "capabilities": "gpu-2" @@ -255,7 +255,7 @@ func HandleExtraSpecUpdateSuccessfully(t *testing.T) { func HandleExtraSpecDeleteSuccessfully(t *testing.T) { th.Mux.HandleFunc("/types/1/extra_specs/capabilities", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusAccepted) }) @@ -264,7 +264,7 @@ func HandleExtraSpecDeleteSuccessfully(t *testing.T) { func MockEncryptionCreateResponse(t *testing.T) { th.Mux.HandleFunc("/types/a5082c24-2a27-43a4-b48e-fcec1240e36b/encryption", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, ` @@ -299,7 +299,7 @@ func MockEncryptionCreateResponse(t *testing.T) { func MockDeleteEncryptionResponse(t *testing.T) { th.Mux.HandleFunc("/types/a5082c24-2a27-43a4-b48e-fcec1240e36b/encryption/81e069c6-7394-4856-8df7-3b237ca61f74", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusAccepted) }) } @@ -307,7 +307,7 @@ func MockDeleteEncryptionResponse(t *testing.T) { func MockEncryptionUpdateResponse(t *testing.T) { th.Mux.HandleFunc("/types/a5082c24-2a27-43a4-b48e-fcec1240e36b/encryption/81e069c6-7394-4856-8df7-3b237ca61f74", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, ` @@ -340,7 +340,7 @@ func MockEncryptionUpdateResponse(t *testing.T) { func MockEncryptionGetResponse(t *testing.T) { th.Mux.HandleFunc("/types/a5082c24-2a27-43a4-b48e-fcec1240e36b/encryption", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -365,7 +365,7 @@ func MockEncryptionGetResponse(t *testing.T) { func MockEncryptionGetSpecResponse(t *testing.T) { th.Mux.HandleFunc("/types/a5082c24-2a27-43a4-b48e-fcec1240e36b/encryption/cipher", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) diff --git a/openstack/compute/v2/flavors/testing/fixtures_test.go b/openstack/compute/v2/flavors/testing/fixtures_test.go index a92cdcd1d8..b4badea884 100644 --- a/openstack/compute/v2/flavors/testing/fixtures_test.go +++ b/openstack/compute/v2/flavors/testing/fixtures_test.go @@ -6,7 +6,7 @@ import ( "testing" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) // ExtraSpecsGetBody provides a GET result of the extra_specs for a flavor @@ -52,7 +52,7 @@ var UpdatedExtraSpec = map[string]string{ func HandleExtraSpecsListSuccessfully(t *testing.T) { th.Mux.HandleFunc("/flavors/1/os-extra_specs", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") w.Header().Set("Content-Type", "application/json") @@ -64,7 +64,7 @@ func HandleExtraSpecsListSuccessfully(t *testing.T) { func HandleExtraSpecGetSuccessfully(t *testing.T) { th.Mux.HandleFunc("/flavors/1/os-extra_specs/hw:cpu_policy", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") w.Header().Set("Content-Type", "application/json") @@ -76,7 +76,7 @@ func HandleExtraSpecGetSuccessfully(t *testing.T) { func HandleExtraSpecsCreateSuccessfully(t *testing.T) { th.Mux.HandleFunc("/flavors/1/os-extra_specs", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, `{ "extra_specs": { @@ -94,7 +94,7 @@ func HandleExtraSpecsCreateSuccessfully(t *testing.T) { func HandleExtraSpecUpdateSuccessfully(t *testing.T) { th.Mux.HandleFunc("/flavors/1/os-extra_specs/hw:cpu_policy", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, `{ "hw:cpu_policy": "CPU-POLICY-2" @@ -109,7 +109,7 @@ func HandleExtraSpecUpdateSuccessfully(t *testing.T) { func HandleExtraSpecDeleteSuccessfully(t *testing.T) { th.Mux.HandleFunc("/flavors/1/os-extra_specs/hw:cpu_policy", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusOK) }) diff --git a/openstack/compute/v2/flavors/testing/requests_test.go b/openstack/compute/v2/flavors/testing/requests_test.go index efd6e4bcee..7685417083 100644 --- a/openstack/compute/v2/flavors/testing/requests_test.go +++ b/openstack/compute/v2/flavors/testing/requests_test.go @@ -10,7 +10,7 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/compute/v2/flavors" "github.com/gophercloud/gophercloud/v2/pagination" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) func TestListFlavors(t *testing.T) { @@ -19,7 +19,7 @@ func TestListFlavors(t *testing.T) { th.Mux.HandleFunc("/flavors/detail", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") if err := r.ParseForm(); err != nil { @@ -84,7 +84,7 @@ func TestListFlavors(t *testing.T) { pages := 0 // Get public and private flavors - err := flavors.ListDetail(fake.ServiceClient(), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := flavors.ListDetail(client.ServiceClient(), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := flavors.ExtractFlavors(page) @@ -118,7 +118,7 @@ func TestGetFlavor(t *testing.T) { th.Mux.HandleFunc("/flavors/12345", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") fmt.Fprint(w, ` @@ -140,7 +140,7 @@ func TestGetFlavor(t *testing.T) { `) }) - actual, err := flavors.Get(context.TODO(), fake.ServiceClient(), "12345").Extract() + actual, err := flavors.Get(context.TODO(), client.ServiceClient(), "12345").Extract() if err != nil { t.Fatalf("Unable to get flavor: %v", err) } @@ -167,7 +167,7 @@ func TestCreateFlavor(t *testing.T) { th.Mux.HandleFunc("/flavors", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") fmt.Fprint(w, ` @@ -196,7 +196,7 @@ func TestCreateFlavor(t *testing.T) { RxTxFactor: 1.0, Description: "foo", } - actual, err := flavors.Create(context.TODO(), fake.ServiceClient(), opts).Extract() + actual, err := flavors.Create(context.TODO(), client.ServiceClient(), opts).Extract() if err != nil { t.Fatalf("Unable to create flavor: %v", err) } @@ -222,7 +222,7 @@ func TestUpdateFlavor(t *testing.T) { th.Mux.HandleFunc("/flavors/12345678", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") fmt.Fprint(w, ` @@ -244,7 +244,7 @@ func TestUpdateFlavor(t *testing.T) { opts := &flavors.UpdateOpts{ Description: "foo", } - actual, err := flavors.Update(context.TODO(), fake.ServiceClient(), "12345678", opts).Extract() + actual, err := flavors.Update(context.TODO(), client.ServiceClient(), "12345678", opts).Extract() if err != nil { t.Fatalf("Unable to update flavor: %v", err) } @@ -271,12 +271,12 @@ func TestDeleteFlavor(t *testing.T) { th.Mux.HandleFunc("/flavors/12345678", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusAccepted) }) - res := flavors.Delete(context.TODO(), fake.ServiceClient(), "12345678") + res := flavors.Delete(context.TODO(), client.ServiceClient(), "12345678") th.AssertNoErr(t, res.Err) } @@ -286,7 +286,7 @@ func TestFlavorAccessesList(t *testing.T) { th.Mux.HandleFunc("/flavors/12345678/os-flavor-access", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") fmt.Fprint(w, ` { @@ -307,7 +307,7 @@ func TestFlavorAccessesList(t *testing.T) { }, } - allPages, err := flavors.ListAccesses(fake.ServiceClient(), "12345678").AllPages(context.TODO()) + allPages, err := flavors.ListAccesses(client.ServiceClient(), "12345678").AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := flavors.ExtractAccesses(allPages) @@ -324,7 +324,7 @@ func TestFlavorAccessAdd(t *testing.T) { th.Mux.HandleFunc("/flavors/12345678/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "accept", "application/json") th.TestJSONRequest(t, r, ` { @@ -359,7 +359,7 @@ func TestFlavorAccessAdd(t *testing.T) { Tenant: "2f954bcf047c4ee9b09a37d49ae6db54", } - actual, err := flavors.AddAccess(context.TODO(), fake.ServiceClient(), "12345678", addAccessOpts).Extract() + actual, err := flavors.AddAccess(context.TODO(), client.ServiceClient(), "12345678", addAccessOpts).Extract() th.AssertNoErr(t, err) if !reflect.DeepEqual(expected, actual) { @@ -373,7 +373,7 @@ func TestFlavorAccessRemove(t *testing.T) { th.Mux.HandleFunc("/flavors/12345678/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "accept", "application/json") th.TestJSONRequest(t, r, ` { @@ -397,7 +397,7 @@ func TestFlavorAccessRemove(t *testing.T) { Tenant: "2f954bcf047c4ee9b09a37d49ae6db54", } - actual, err := flavors.RemoveAccess(context.TODO(), fake.ServiceClient(), "12345678", removeAccessOpts).Extract() + actual, err := flavors.RemoveAccess(context.TODO(), client.ServiceClient(), "12345678", removeAccessOpts).Extract() th.AssertNoErr(t, err) if !reflect.DeepEqual(expected, actual) { @@ -411,7 +411,7 @@ func TestFlavorExtraSpecsList(t *testing.T) { HandleExtraSpecsListSuccessfully(t) expected := ExtraSpecs - actual, err := flavors.ListExtraSpecs(context.TODO(), fake.ServiceClient(), "1").Extract() + actual, err := flavors.ListExtraSpecs(context.TODO(), client.ServiceClient(), "1").Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, expected, actual) } @@ -422,7 +422,7 @@ func TestFlavorExtraSpecGet(t *testing.T) { HandleExtraSpecGetSuccessfully(t) expected := ExtraSpec - actual, err := flavors.GetExtraSpec(context.TODO(), fake.ServiceClient(), "1", "hw:cpu_policy").Extract() + actual, err := flavors.GetExtraSpec(context.TODO(), client.ServiceClient(), "1", "hw:cpu_policy").Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, expected, actual) } @@ -437,7 +437,7 @@ func TestFlavorExtraSpecsCreate(t *testing.T) { "hw:cpu_thread_policy": "CPU-THREAD-POLICY", } expected := ExtraSpecs - actual, err := flavors.CreateExtraSpecs(context.TODO(), fake.ServiceClient(), "1", createOpts).Extract() + actual, err := flavors.CreateExtraSpecs(context.TODO(), client.ServiceClient(), "1", createOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, expected, actual) } @@ -451,7 +451,7 @@ func TestFlavorExtraSpecUpdate(t *testing.T) { "hw:cpu_policy": "CPU-POLICY-2", } expected := UpdatedExtraSpec - actual, err := flavors.UpdateExtraSpec(context.TODO(), fake.ServiceClient(), "1", updateOpts).Extract() + actual, err := flavors.UpdateExtraSpec(context.TODO(), client.ServiceClient(), "1", updateOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, expected, actual) } @@ -461,6 +461,6 @@ func TestFlavorExtraSpecDelete(t *testing.T) { defer th.TeardownHTTP() HandleExtraSpecDeleteSuccessfully(t) - res := flavors.DeleteExtraSpec(context.TODO(), fake.ServiceClient(), "1", "hw:cpu_policy") + res := flavors.DeleteExtraSpec(context.TODO(), client.ServiceClient(), "1", "hw:cpu_policy") th.AssertNoErr(t, res.Err) } diff --git a/openstack/compute/v2/remoteconsoles/testing/requests_test.go b/openstack/compute/v2/remoteconsoles/testing/requests_test.go index 3a49e4d46f..c4d67998e1 100644 --- a/openstack/compute/v2/remoteconsoles/testing/requests_test.go +++ b/openstack/compute/v2/remoteconsoles/testing/requests_test.go @@ -8,7 +8,7 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/compute/v2/remoteconsoles" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) func TestCreate(t *testing.T) { @@ -17,7 +17,7 @@ func TestCreate(t *testing.T) { th.Mux.HandleFunc("/servers/b16ba811-199d-4ffd-8839-ba96c1185a67/remote-consoles", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, RemoteConsoleCreateRequest) @@ -32,7 +32,7 @@ func TestCreate(t *testing.T) { Protocol: remoteconsoles.ConsoleProtocolVNC, Type: remoteconsoles.ConsoleTypeNoVNC, } - s, err := remoteconsoles.Create(context.TODO(), fake.ServiceClient(), "b16ba811-199d-4ffd-8839-ba96c1185a67", opts).Extract() + s, err := remoteconsoles.Create(context.TODO(), client.ServiceClient(), "b16ba811-199d-4ffd-8839-ba96c1185a67", opts).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, s.Protocol, string(remoteconsoles.ConsoleProtocolVNC)) diff --git a/openstack/compute/v2/secgroups/testing/fixtures_test.go b/openstack/compute/v2/secgroups/testing/fixtures_test.go index df3614b66b..4f7222f7bf 100644 --- a/openstack/compute/v2/secgroups/testing/fixtures_test.go +++ b/openstack/compute/v2/secgroups/testing/fixtures_test.go @@ -6,7 +6,7 @@ import ( "testing" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) const rootPath = "/os-security-groups" @@ -28,7 +28,7 @@ const listGroupsJSON = ` func mockListGroupsResponse(t *testing.T) { th.Mux.HandleFunc(rootPath, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -41,7 +41,7 @@ func mockListGroupsByServerResponse(t *testing.T, serverID string) { url := fmt.Sprintf("/servers/%s%s", serverID, rootPath) th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -53,7 +53,7 @@ func mockListGroupsByServerResponse(t *testing.T, serverID string) { func mockCreateGroupResponse(t *testing.T) { th.Mux.HandleFunc(rootPath, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, ` { @@ -85,7 +85,7 @@ func mockUpdateGroupResponse(t *testing.T, groupID string) { url := fmt.Sprintf("%s/%s", rootPath, groupID) th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, ` { @@ -117,7 +117,7 @@ func mockGetGroupsResponse(t *testing.T, groupID string) { url := fmt.Sprintf("%s/%s", rootPath, groupID) th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -155,7 +155,7 @@ func mockGetNumericIDGroupResponse(t *testing.T, groupID int) { url := fmt.Sprintf("%s/%d", rootPath, groupID) th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -174,7 +174,7 @@ func mockGetNumericIDGroupRuleResponse(t *testing.T, groupID int) { url := fmt.Sprintf("%s/%d", rootPath, groupID) th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -199,7 +199,7 @@ func mockDeleteGroupResponse(t *testing.T, groupID string) { url := fmt.Sprintf("%s/%s", rootPath, groupID) th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusAccepted) }) @@ -208,7 +208,7 @@ func mockDeleteGroupResponse(t *testing.T, groupID string) { func mockAddRuleResponse(t *testing.T) { th.Mux.HandleFunc("/os-security-group-rules", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, ` { @@ -244,7 +244,7 @@ func mockAddRuleResponse(t *testing.T) { func mockAddRuleResponseICMPZero(t *testing.T) { th.Mux.HandleFunc("/os-security-group-rules", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, ` { @@ -281,7 +281,7 @@ func mockDeleteRuleResponse(t *testing.T, ruleID string) { url := fmt.Sprintf("/os-security-group-rules/%s", ruleID) th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusAccepted) }) @@ -291,7 +291,7 @@ func mockAddServerToGroupResponse(t *testing.T, serverID string) { url := fmt.Sprintf("/servers/%s/action", serverID) th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, ` { @@ -310,7 +310,7 @@ func mockRemoveServerFromGroupResponse(t *testing.T, serverID string) { url := fmt.Sprintf("/servers/%s/action", serverID) th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, ` { diff --git a/openstack/container/v1/capsules/testing/fixtures_test.go b/openstack/container/v1/capsules/testing/fixtures_test.go index 541b163b44..9ce111382e 100644 --- a/openstack/container/v1/capsules/testing/fixtures_test.go +++ b/openstack/container/v1/capsules/testing/fixtures_test.go @@ -9,7 +9,7 @@ import ( "github.com/gophercloud/gophercloud/v2" "github.com/gophercloud/gophercloud/v2/openstack/container/v1/capsules" th "github.com/gophercloud/gophercloud/v2/testhelper" - fakeclient "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) // ValidJSONTemplate is a valid OpenStack Capsule template in JSON format @@ -625,7 +625,7 @@ func GetFakeCapsuleV132() capsules.CapsuleV132 { func HandleCapsuleGetOldTimeSuccessfully(t *testing.T) { th.Mux.HandleFunc("/capsules/cc654059-1a77-47a3-bfcf-715bde5aad9e", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusOK) w.Header().Add("Content-Type", "application/json") @@ -637,7 +637,7 @@ func HandleCapsuleGetOldTimeSuccessfully(t *testing.T) { func HandleCapsuleGetNewTimeSuccessfully(t *testing.T) { th.Mux.HandleFunc("/capsules/cc654059-1a77-47a3-bfcf-715bde5aad9e", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusOK) w.Header().Add("Content-Type", "application/json") @@ -650,7 +650,7 @@ func HandleCapsuleGetNewTimeSuccessfully(t *testing.T) { func HandleCapsuleCreateSuccessfully(t *testing.T) { th.Mux.HandleFunc("/capsules", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") w.WriteHeader(http.StatusAccepted) fmt.Fprint(w, CapsuleGetBody_NewTime) @@ -661,7 +661,7 @@ func HandleCapsuleCreateSuccessfully(t *testing.T) { func HandleCapsuleListSuccessfully(t *testing.T) { th.Mux.HandleFunc("/capsules/", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -673,7 +673,7 @@ func HandleCapsuleListSuccessfully(t *testing.T) { func HandleCapsuleV132ListSuccessfully(t *testing.T) { th.Mux.HandleFunc("/capsules/", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -684,7 +684,7 @@ func HandleCapsuleV132ListSuccessfully(t *testing.T) { func HandleCapsuleDeleteSuccessfully(t *testing.T) { th.Mux.HandleFunc("/capsules/963a239d-3946-452b-be5a-055eab65a421", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) } diff --git a/openstack/container/v1/capsules/testing/requests_test.go b/openstack/container/v1/capsules/testing/requests_test.go index 3805a0aef4..c789ac44f4 100644 --- a/openstack/container/v1/capsules/testing/requests_test.go +++ b/openstack/container/v1/capsules/testing/requests_test.go @@ -9,7 +9,7 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/container/v1/capsules" "github.com/gophercloud/gophercloud/v2/pagination" th "github.com/gophercloud/gophercloud/v2/testhelper" - fakeclient "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) func TestGetCapsule_OldTime(t *testing.T) { @@ -29,7 +29,7 @@ func TestGetCapsule_OldTime(t *testing.T) { ec.Containers[0].UpdatedAt = updatedAt ec.Containers[0].StartedAt = startedAt - actualCapsule, err := capsules.Get(context.TODO(), fakeclient.ServiceClient(), ec.UUID).Extract() + actualCapsule, err := capsules.Get(context.TODO(), client.ServiceClient(), ec.UUID).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, &ec, actualCapsule) @@ -43,7 +43,7 @@ func TestGetCapsule_NewTime(t *testing.T) { ec := GetFakeCapsule() - actualCapsule, err := capsules.Get(context.TODO(), fakeclient.ServiceClient(), ec.UUID).Extract() + actualCapsule, err := capsules.Get(context.TODO(), client.ServiceClient(), ec.UUID).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, &ec, actualCapsule) @@ -61,7 +61,7 @@ func TestCreateCapsule(t *testing.T) { createOpts := capsules.CreateOpts{ TemplateOpts: template, } - actualCapsule, err := capsules.Create(context.TODO(), fakeclient.ServiceClient(), createOpts).Extract() + actualCapsule, err := capsules.Create(context.TODO(), client.ServiceClient(), createOpts).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, &ec, actualCapsule) @@ -84,7 +84,7 @@ func TestListCapsule(t *testing.T) { expected := []capsules.Capsule{ec} count := 0 - results := capsules.List(fakeclient.ServiceClient(), nil) + results := capsules.List(client.ServiceClient(), nil) err := results.EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := capsules.ExtractCapsules(page) @@ -121,7 +121,7 @@ func TestListCapsuleV132(t *testing.T) { expected := []capsules.CapsuleV132{ec} count := 0 - results := capsules.List(fakeclient.ServiceClient(), nil) + results := capsules.List(client.ServiceClient(), nil) err := results.EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := capsules.ExtractCapsules(page) @@ -147,6 +147,6 @@ func TestDelete(t *testing.T) { HandleCapsuleDeleteSuccessfully(t) - res := capsules.Delete(context.TODO(), fakeclient.ServiceClient(), "963a239d-3946-452b-be5a-055eab65a421") + res := capsules.Delete(context.TODO(), client.ServiceClient(), "963a239d-3946-452b-be5a-055eab65a421") th.AssertNoErr(t, res.Err) } diff --git a/openstack/containerinfra/v1/certificates/testing/fixtures_test.go b/openstack/containerinfra/v1/certificates/testing/fixtures_test.go index b51d77cbd4..c62eb618af 100644 --- a/openstack/containerinfra/v1/certificates/testing/fixtures_test.go +++ b/openstack/containerinfra/v1/certificates/testing/fixtures_test.go @@ -8,7 +8,7 @@ import ( "github.com/gophercloud/gophercloud/v2" "github.com/gophercloud/gophercloud/v2/openstack/containerinfra/v1/certificates" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) const CertificateResponse = ` @@ -70,7 +70,7 @@ var ExpectedCreateCertificateResponse = certificates.Certificate{ func HandleGetCertificateSuccessfully(t *testing.T) { th.Mux.HandleFunc("/v1/certificates/d564b18a-2890-4152-be3d-e05d784ff72", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.Header().Add("OpenStack-API-Minimum-Version", "container-infra 1.1") @@ -86,7 +86,7 @@ func HandleGetCertificateSuccessfully(t *testing.T) { func HandleCreateCertificateSuccessfully(t *testing.T) { th.Mux.HandleFunc("/v1/certificates/", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.Header().Add("OpenStack-API-Minimum-Version", "container-infra 1.1") @@ -103,7 +103,7 @@ func HandleUpdateCertificateSuccessfully(t *testing.T) { th.Mux.HandleFunc("/v1/certificates/d564b18a-2890-4152-be3d-e05d784ff72", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PATCH") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusAccepted) fmt.Fprint(w, `{}`) diff --git a/openstack/containerinfra/v1/certificates/testing/requests_test.go b/openstack/containerinfra/v1/certificates/testing/requests_test.go index 25a287e401..0d08c2647c 100644 --- a/openstack/containerinfra/v1/certificates/testing/requests_test.go +++ b/openstack/containerinfra/v1/certificates/testing/requests_test.go @@ -6,7 +6,7 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/containerinfra/v1/certificates" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) func TestGetCertificates(t *testing.T) { @@ -15,7 +15,7 @@ func TestGetCertificates(t *testing.T) { HandleGetCertificateSuccessfully(t) - sc := fake.ServiceClient() + sc := client.ServiceClient() sc.Endpoint = sc.Endpoint + "v1/" actual, err := certificates.Get(context.TODO(), sc, "d564b18a-2890-4152-be3d-e05d784ff72").Extract() @@ -29,7 +29,7 @@ func TestCreateCertificates(t *testing.T) { HandleCreateCertificateSuccessfully(t) - sc := fake.ServiceClient() + sc := client.ServiceClient() sc.Endpoint = sc.Endpoint + "v1/" opts := certificates.CreateOpts{ @@ -48,7 +48,7 @@ func TestUpdateCertificates(t *testing.T) { HandleUpdateCertificateSuccessfully(t) - sc := fake.ServiceClient() + sc := client.ServiceClient() sc.Endpoint = sc.Endpoint + "v1/" err := certificates.Update(context.TODO(), sc, "d564b18a-2890-4152-be3d-e05d784ff72").ExtractErr() diff --git a/openstack/containerinfra/v1/clusters/testing/fixtures_test.go b/openstack/containerinfra/v1/clusters/testing/fixtures_test.go index ccbfddfc6d..64c557225d 100644 --- a/openstack/containerinfra/v1/clusters/testing/fixtures_test.go +++ b/openstack/containerinfra/v1/clusters/testing/fixtures_test.go @@ -9,7 +9,7 @@ import ( "github.com/gophercloud/gophercloud/v2" "github.com/gophercloud/gophercloud/v2/openstack/containerinfra/v1/clusters" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) const clusterUUID = "746e779a-751a-456b-a3e9-c883d734946f" @@ -98,7 +98,7 @@ var ExpectedClusterUUID = clusterUUID func HandleCreateClusterSuccessfully(t *testing.T) { th.Mux.HandleFunc("/v1/clusters", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.Header().Add("X-OpenStack-Request-Id", requestUUID) @@ -111,7 +111,7 @@ func HandleCreateClusterSuccessfully(t *testing.T) { func HandleGetClusterSuccessfully(t *testing.T) { th.Mux.HandleFunc("/v1/clusters/"+clusterUUID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -250,7 +250,7 @@ var ExpectedClusters = []clusters.Cluster{ExpectedCluster} func HandleListClusterSuccessfully(t *testing.T) { th.Mux.HandleFunc("/v1/clusters", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.Header().Add("X-OpenStack-Request-Id", requestUUID) @@ -263,7 +263,7 @@ func HandleListClusterSuccessfully(t *testing.T) { func HandleListDetailClusterSuccessfully(t *testing.T) { th.Mux.HandleFunc("/v1/clusters/detail", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.Header().Add("X-OpenStack-Request-Id", requestUUID) @@ -281,7 +281,7 @@ var UpdateResponse = fmt.Sprintf(` func HandleUpdateClusterSuccessfully(t *testing.T) { th.Mux.HandleFunc("/v1/clusters/"+clusterUUID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PATCH") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.Header().Add("X-OpenStack-Request-Id", requestUUID) @@ -299,7 +299,7 @@ var UpgradeResponse = fmt.Sprintf(` func HandleUpgradeClusterSuccessfully(t *testing.T) { th.Mux.HandleFunc("/v1/clusters/"+clusterUUID+"/actions/upgrade", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.Header().Add("X-OpenStack-Request-Id", requestUUID) @@ -312,7 +312,7 @@ func HandleUpgradeClusterSuccessfully(t *testing.T) { func HandleDeleteClusterSuccessfully(t *testing.T) { th.Mux.HandleFunc("/v1/clusters/"+clusterUUID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.Header().Add("X-OpenStack-Request-Id", requestUUID) @@ -328,7 +328,7 @@ var ResizeResponse = fmt.Sprintf(` func HandleResizeClusterSuccessfully(t *testing.T) { th.Mux.HandleFunc("/v1/clusters/"+clusterUUID+"/actions/resize", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.Header().Add("X-OpenStack-Request-Id", requestUUID) diff --git a/openstack/containerinfra/v1/clusters/testing/requests_test.go b/openstack/containerinfra/v1/clusters/testing/requests_test.go index c7cd21efcc..6d1358e645 100644 --- a/openstack/containerinfra/v1/clusters/testing/requests_test.go +++ b/openstack/containerinfra/v1/clusters/testing/requests_test.go @@ -8,7 +8,7 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/containerinfra/v1/clusters" "github.com/gophercloud/gophercloud/v2/pagination" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) func TestCreateCluster(t *testing.T) { @@ -39,7 +39,7 @@ func TestCreateCluster(t *testing.T) { MergeLabels: gophercloud.Enabled, } - sc := fake.ServiceClient() + sc := client.ServiceClient() sc.Endpoint = sc.Endpoint + "v1/" res := clusters.Create(context.TODO(), sc, opts) th.AssertNoErr(t, res.Err) @@ -59,7 +59,7 @@ func TestGetCluster(t *testing.T) { HandleGetClusterSuccessfully(t) - sc := fake.ServiceClient() + sc := client.ServiceClient() sc.Endpoint = sc.Endpoint + "v1/" actual, err := clusters.Get(context.TODO(), sc, "746e779a-751a-456b-a3e9-c883d734946f").Extract() th.AssertNoErr(t, err) @@ -75,7 +75,7 @@ func TestListClusters(t *testing.T) { HandleListClusterSuccessfully(t) count := 0 - sc := fake.ServiceClient() + sc := client.ServiceClient() sc.Endpoint = sc.Endpoint + "v1/" err := clusters.List(sc, clusters.ListOpts{Limit: 2}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ @@ -103,7 +103,7 @@ func TestListDetailClusters(t *testing.T) { HandleListDetailClusterSuccessfully(t) count := 0 - sc := fake.ServiceClient() + sc := client.ServiceClient() sc.Endpoint = sc.Endpoint + "v1/" err := clusters.ListDetail(sc, clusters.ListOpts{Limit: 2}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ @@ -143,7 +143,7 @@ func TestUpdateCluster(t *testing.T) { }, } - sc := fake.ServiceClient() + sc := client.ServiceClient() sc.Endpoint = sc.Endpoint + "v1/" res := clusters.Update(context.TODO(), sc, clusterUUID, updateOpts) th.AssertNoErr(t, res.Err) @@ -167,7 +167,7 @@ func TestUpgradeCluster(t *testing.T) { ClusterTemplate: "0562d357-8641-4759-8fed-8173f02c9633", } - sc := fake.ServiceClient() + sc := client.ServiceClient() sc.Endpoint = sc.Endpoint + "v1/" res := clusters.Upgrade(context.TODO(), sc, clusterUUID, opts) th.AssertNoErr(t, res.Err) @@ -187,7 +187,7 @@ func TestDeleteCluster(t *testing.T) { HandleDeleteClusterSuccessfully(t) - sc := fake.ServiceClient() + sc := client.ServiceClient() sc.Endpoint = sc.Endpoint + "v1/" r := clusters.Delete(context.TODO(), sc, clusterUUID) err := r.ExtractErr() @@ -219,7 +219,7 @@ func TestResizeCluster(t *testing.T) { NodeCount: &nodeCount, } - sc := fake.ServiceClient() + sc := client.ServiceClient() sc.Endpoint = sc.Endpoint + "v1/" res := clusters.Resize(context.TODO(), sc, clusterUUID, opts) th.AssertNoErr(t, res.Err) diff --git a/openstack/containerinfra/v1/clustertemplates/testing/fixtures_test.go b/openstack/containerinfra/v1/clustertemplates/testing/fixtures_test.go index 8028ff836f..92dfa795d2 100644 --- a/openstack/containerinfra/v1/clustertemplates/testing/fixtures_test.go +++ b/openstack/containerinfra/v1/clustertemplates/testing/fixtures_test.go @@ -9,7 +9,7 @@ import ( "github.com/gophercloud/gophercloud/v2" "github.com/gophercloud/gophercloud/v2/openstack/containerinfra/v1/clustertemplates" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) const ClusterTemplateResponse = ` @@ -277,7 +277,7 @@ var ExpectedClusterTemplates = []clustertemplates.ClusterTemplate{ExpectedCluste func HandleCreateClusterTemplateSuccessfully(t *testing.T) { th.Mux.HandleFunc("/v1/clustertemplates", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, `{ "coe": "kubernetes", "dns_nameserver": "8.8.8.8", @@ -315,7 +315,7 @@ func HandleCreateClusterTemplateSuccessfully(t *testing.T) { func HandleDeleteClusterSuccessfully(t *testing.T) { th.Mux.HandleFunc("/v1/clustertemplates/6dc6d336e3fc4c0a951b5698cd1236ee", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.Header().Add("OpenStack-API-Minimum-Version", "container-infra 1.1") @@ -329,7 +329,7 @@ func HandleDeleteClusterSuccessfully(t *testing.T) { func HandleListClusterTemplateSuccessfully(t *testing.T) { th.Mux.HandleFunc("/v1/clustertemplates", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -341,7 +341,7 @@ func HandleListClusterTemplateSuccessfully(t *testing.T) { func HandleGetClusterTemplateSuccessfully(t *testing.T) { th.Mux.HandleFunc("/v1/clustertemplates/7d85f602-a948-4a30-afd4-e84f47471c15", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -353,7 +353,7 @@ func HandleGetClusterTemplateSuccessfully(t *testing.T) { func HandleGetClusterTemplateEmptyTimeSuccessfully(t *testing.T) { th.Mux.HandleFunc("/v1/clustertemplates/7d85f602-a948-4a30-afd4-e84f47471c15", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -530,7 +530,7 @@ var ExpectedUpdateClusterTemplate_EmptyTime = clustertemplates.ClusterTemplate{ func HandleUpdateClusterTemplateSuccessfully(t *testing.T) { th.Mux.HandleFunc("/v1/clustertemplates/7d85f602-a948-4a30-afd4-e84f47471c15", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PATCH") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -542,7 +542,7 @@ func HandleUpdateClusterTemplateSuccessfully(t *testing.T) { func HandleUpdateClusterTemplateEmptyTimeSuccessfully(t *testing.T) { th.Mux.HandleFunc("/v1/clustertemplates/7d85f602-a948-4a30-afd4-e84f47471c15", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PATCH") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -554,7 +554,7 @@ func HandleUpdateClusterTemplateEmptyTimeSuccessfully(t *testing.T) { func HandleUpdateClusterTemplateInvalidUpdate(t *testing.T) { th.Mux.HandleFunc("/v1/clustertemplates/7d85f602-a948-4a30-afd4-e84f47471c15", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PATCH") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusBadRequest) diff --git a/openstack/containerinfra/v1/clustertemplates/testing/requests_test.go b/openstack/containerinfra/v1/clustertemplates/testing/requests_test.go index 8bab4017f2..4d4b3b154b 100644 --- a/openstack/containerinfra/v1/clustertemplates/testing/requests_test.go +++ b/openstack/containerinfra/v1/clustertemplates/testing/requests_test.go @@ -7,7 +7,7 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/containerinfra/v1/clustertemplates" "github.com/gophercloud/gophercloud/v2/pagination" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) func TestCreateClusterTemplate(t *testing.T) { @@ -46,7 +46,7 @@ func TestCreateClusterTemplate(t *testing.T) { Hidden: &boolTrue, } - sc := fake.ServiceClient() + sc := client.ServiceClient() sc.Endpoint = sc.Endpoint + "v1/" res := clustertemplates.Create(context.TODO(), sc, opts) th.AssertNoErr(t, res.Err) @@ -67,7 +67,7 @@ func TestDeleteClusterTemplate(t *testing.T) { HandleDeleteClusterSuccessfully(t) - sc := fake.ServiceClient() + sc := client.ServiceClient() sc.Endpoint = sc.Endpoint + "v1/" res := clustertemplates.Delete(context.TODO(), sc, "6dc6d336e3fc4c0a951b5698cd1236ee") th.AssertNoErr(t, res.Err) @@ -83,7 +83,7 @@ func TestListClusterTemplates(t *testing.T) { count := 0 - sc := fake.ServiceClient() + sc := client.ServiceClient() sc.Endpoint = sc.Endpoint + "v1/" err := clustertemplates.List(sc, clustertemplates.ListOpts{Limit: 2}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ @@ -109,7 +109,7 @@ func TestGetClusterTemplate(t *testing.T) { HandleGetClusterTemplateSuccessfully(t) - sc := fake.ServiceClient() + sc := client.ServiceClient() sc.Endpoint = sc.Endpoint + "v1/" actual, err := clustertemplates.Get(context.TODO(), sc, "7d85f602-a948-4a30-afd4-e84f47471c15").Extract() th.AssertNoErr(t, err) @@ -123,7 +123,7 @@ func TestGetClusterTemplateEmptyTime(t *testing.T) { HandleGetClusterTemplateEmptyTimeSuccessfully(t) - sc := fake.ServiceClient() + sc := client.ServiceClient() sc.Endpoint = sc.Endpoint + "v1/" actual, err := clustertemplates.Get(context.TODO(), sc, "7d85f602-a948-4a30-afd4-e84f47471c15").Extract() th.AssertNoErr(t, err) @@ -150,7 +150,7 @@ func TestUpdateClusterTemplate(t *testing.T) { }, } - sc := fake.ServiceClient() + sc := client.ServiceClient() sc.Endpoint = sc.Endpoint + "v1/" res := clustertemplates.Update(context.TODO(), sc, "7d85f602-a948-4a30-afd4-e84f47471c15", updateOpts) th.AssertNoErr(t, res.Err) @@ -180,7 +180,7 @@ func TestUpdateClusterTemplateEmptyTime(t *testing.T) { }, } - sc := fake.ServiceClient() + sc := client.ServiceClient() sc.Endpoint = sc.Endpoint + "v1/" actual, err := clustertemplates.Update(context.TODO(), sc, "7d85f602-a948-4a30-afd4-e84f47471c15", updateOpts).Extract() th.AssertNoErr(t, err) @@ -208,7 +208,7 @@ func TestUpdateClusterTemplateInvalidUpdate(t *testing.T) { }, } - sc := fake.ServiceClient() + sc := client.ServiceClient() sc.Endpoint = sc.Endpoint + "v1/" _, err := clustertemplates.Update(context.TODO(), sc, "7d85f602-a948-4a30-afd4-e84f47471c15", updateOpts).Extract() th.AssertEquals(t, true, err != nil) diff --git a/openstack/containerinfra/v1/nodegroups/testing/fixtures_test.go b/openstack/containerinfra/v1/nodegroups/testing/fixtures_test.go index 90de8b6fe6..650db54c40 100644 --- a/openstack/containerinfra/v1/nodegroups/testing/fixtures_test.go +++ b/openstack/containerinfra/v1/nodegroups/testing/fixtures_test.go @@ -9,7 +9,7 @@ import ( "github.com/gophercloud/gophercloud/v2" "github.com/gophercloud/gophercloud/v2/openstack/containerinfra/v1/nodegroups" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) const ( @@ -128,7 +128,7 @@ var expectedUpdatedNodeGroup = nodegroups.NodeGroup{ func handleGetNodeGroupSuccess(t *testing.T) { th.Mux.HandleFunc("/v1/clusters/"+clusterUUID+"/nodegroups/"+nodeGroup1UUID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, http.MethodGet) - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -140,7 +140,7 @@ func handleGetNodeGroupSuccess(t *testing.T) { func handleGetNodeGroupNotFound(t *testing.T) { th.Mux.HandleFunc("/v1/clusters/"+clusterUUID+"/nodegroups/"+badNodeGroupUUID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, http.MethodGet) - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusNotFound) @@ -152,7 +152,7 @@ func handleGetNodeGroupNotFound(t *testing.T) { func handleGetNodeGroupClusterNotFound(t *testing.T) { th.Mux.HandleFunc("/v1/clusters/"+badClusterUUID+"/nodegroups/"+badNodeGroupUUID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, http.MethodGet) - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusNotFound) @@ -164,7 +164,7 @@ func handleGetNodeGroupClusterNotFound(t *testing.T) { func handleListNodeGroupsSuccess(t *testing.T) { th.Mux.HandleFunc("/v1/clusters/"+clusterUUID+"/nodegroups", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, http.MethodGet) - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -176,7 +176,7 @@ func handleListNodeGroupsSuccess(t *testing.T) { func handleListNodeGroupsLimitSuccess(t *testing.T) { th.Mux.HandleFunc("/v1/clusters/"+clusterUUID+"/nodegroups", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, http.MethodGet) - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -204,7 +204,7 @@ func handleListNodeGroupsLimitSuccess(t *testing.T) { func handleListNodeGroupsClusterNotFound(t *testing.T) { th.Mux.HandleFunc("/v1/clusters/"+badClusterUUID+"/nodegroups", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, http.MethodGet) - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusNotFound) @@ -216,7 +216,7 @@ func handleListNodeGroupsClusterNotFound(t *testing.T) { func handleCreateNodeGroupSuccess(t *testing.T) { th.Mux.HandleFunc("/v1/clusters/"+clusterUUID+"/nodegroups", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, http.MethodPost) - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusAccepted) @@ -228,7 +228,7 @@ func handleCreateNodeGroupSuccess(t *testing.T) { func handleCreateNodeGroupDuplicate(t *testing.T) { th.Mux.HandleFunc("/v1/clusters/"+clusterUUID+"/nodegroups", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, http.MethodPost) - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusConflict) @@ -240,7 +240,7 @@ func handleCreateNodeGroupDuplicate(t *testing.T) { func handleCreateNodeGroupMaster(t *testing.T) { th.Mux.HandleFunc("/v1/clusters/"+clusterUUID+"/nodegroups", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, http.MethodPost) - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusBadRequest) @@ -252,7 +252,7 @@ func handleCreateNodeGroupMaster(t *testing.T) { func handleCreateNodeGroupBadSizes(t *testing.T) { th.Mux.HandleFunc("/v1/clusters/"+clusterUUID+"/nodegroups", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, http.MethodPost) - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusConflict) @@ -264,7 +264,7 @@ func handleCreateNodeGroupBadSizes(t *testing.T) { func handleUpdateNodeGroupSuccess(t *testing.T) { th.Mux.HandleFunc("/v1/clusters/"+clusterUUID+"/nodegroups/"+nodeGroup2UUID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, http.MethodPatch) - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusAccepted) @@ -276,7 +276,7 @@ func handleUpdateNodeGroupSuccess(t *testing.T) { func handleUpdateNodeGroupInternal(t *testing.T) { th.Mux.HandleFunc("/v1/clusters/"+clusterUUID+"/nodegroups/"+nodeGroup2UUID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, http.MethodPatch) - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusBadRequest) @@ -288,7 +288,7 @@ func handleUpdateNodeGroupInternal(t *testing.T) { func handleUpdateNodeGroupBadField(t *testing.T) { th.Mux.HandleFunc("/v1/clusters/"+clusterUUID+"/nodegroups/"+nodeGroup2UUID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, http.MethodPatch) - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusBadRequest) @@ -300,7 +300,7 @@ func handleUpdateNodeGroupBadField(t *testing.T) { func handleUpdateNodeGroupBadMin(t *testing.T) { th.Mux.HandleFunc("/v1/clusters/"+clusterUUID+"/nodegroups/"+nodeGroup2UUID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, http.MethodPatch) - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusConflict) @@ -312,7 +312,7 @@ func handleUpdateNodeGroupBadMin(t *testing.T) { func handleDeleteNodeGroupSuccess(t *testing.T) { th.Mux.HandleFunc("/v1/clusters/"+clusterUUID+"/nodegroups/"+nodeGroup2UUID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, http.MethodDelete) - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) @@ -321,7 +321,7 @@ func handleDeleteNodeGroupSuccess(t *testing.T) { func handleDeleteNodeGroupNotFound(t *testing.T) { th.Mux.HandleFunc("/v1/clusters/"+clusterUUID+"/nodegroups/"+badNodeGroupUUID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, http.MethodDelete) - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusNotFound) @@ -333,7 +333,7 @@ func handleDeleteNodeGroupNotFound(t *testing.T) { func handleDeleteNodeGroupClusterNotFound(t *testing.T) { th.Mux.HandleFunc("/v1/clusters/"+badClusterUUID+"/nodegroups/"+badNodeGroupUUID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, http.MethodDelete) - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusNotFound) @@ -345,7 +345,7 @@ func handleDeleteNodeGroupClusterNotFound(t *testing.T) { func handleDeleteNodeGroupDefault(t *testing.T) { th.Mux.HandleFunc("/v1/clusters/"+clusterUUID+"/nodegroups/"+nodeGroup2UUID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, http.MethodDelete) - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusBadRequest) diff --git a/openstack/containerinfra/v1/nodegroups/testing/requests_test.go b/openstack/containerinfra/v1/nodegroups/testing/requests_test.go index 6e929a2e17..8d0f0d4b3d 100644 --- a/openstack/containerinfra/v1/nodegroups/testing/requests_test.go +++ b/openstack/containerinfra/v1/nodegroups/testing/requests_test.go @@ -8,7 +8,7 @@ import ( "github.com/gophercloud/gophercloud/v2" "github.com/gophercloud/gophercloud/v2/openstack/containerinfra/v1/nodegroups" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) // TestGetNodeGroupSuccess gets a node group successfully. @@ -18,7 +18,7 @@ func TestGetNodeGroupSuccess(t *testing.T) { handleGetNodeGroupSuccess(t) - sc := fake.ServiceClient() + sc := client.ServiceClient() sc.Endpoint = sc.Endpoint + "v1/" ng, err := nodegroups.Get(context.TODO(), sc, clusterUUID, nodeGroup1UUID).Extract() @@ -34,7 +34,7 @@ func TestGetNodeGroupNotFound(t *testing.T) { handleGetNodeGroupNotFound(t) - sc := fake.ServiceClient() + sc := client.ServiceClient() sc.Endpoint = sc.Endpoint + "v1/" _, err := nodegroups.Get(context.TODO(), sc, clusterUUID, badNodeGroupUUID).Extract() @@ -49,7 +49,7 @@ func TestGetNodeGroupClusterNotFound(t *testing.T) { handleGetNodeGroupClusterNotFound(t) - sc := fake.ServiceClient() + sc := client.ServiceClient() sc.Endpoint = sc.Endpoint + "v1/" _, err := nodegroups.Get(context.TODO(), sc, badClusterUUID, badNodeGroupUUID).Extract() @@ -63,7 +63,7 @@ func TestListNodeGroupsSuccess(t *testing.T) { handleListNodeGroupsSuccess(t) - sc := fake.ServiceClient() + sc := client.ServiceClient() sc.Endpoint = sc.Endpoint + "v1/" ngPages, err := nodegroups.List(sc, clusterUUID, nodegroups.ListOpts{}).AllPages(context.TODO()) @@ -85,7 +85,7 @@ func TestListNodeGroupsLimitSuccess(t *testing.T) { handleListNodeGroupsLimitSuccess(t) - sc := fake.ServiceClient() + sc := client.ServiceClient() sc.Endpoint = sc.Endpoint + "v1/" listOpts := nodegroups.ListOpts{Limit: 1} @@ -107,7 +107,7 @@ func TestListNodeGroupsClusterNotFound(t *testing.T) { handleListNodeGroupsClusterNotFound(t) - sc := fake.ServiceClient() + sc := client.ServiceClient() sc.Endpoint = sc.Endpoint + "v1/" _, err := nodegroups.List(sc, clusterUUID, nodegroups.ListOpts{}).AllPages(context.TODO()) @@ -121,7 +121,7 @@ func TestCreateNodeGroupSuccess(t *testing.T) { handleCreateNodeGroupSuccess(t) - sc := fake.ServiceClient() + sc := client.ServiceClient() sc.Endpoint = sc.Endpoint + "v1/" createOpts := nodegroups.CreateOpts{ @@ -142,7 +142,7 @@ func TestCreateNodeGroupDuplicate(t *testing.T) { handleCreateNodeGroupDuplicate(t) - sc := fake.ServiceClient() + sc := client.ServiceClient() sc.Endpoint = sc.Endpoint + "v1/" createOpts := nodegroups.CreateOpts{ @@ -161,7 +161,7 @@ func TestCreateNodeGroupMaster(t *testing.T) { handleCreateNodeGroupMaster(t) - sc := fake.ServiceClient() + sc := client.ServiceClient() sc.Endpoint = sc.Endpoint + "v1/" createOpts := nodegroups.CreateOpts{ @@ -181,7 +181,7 @@ func TestCreateNodeGroupBadSizes(t *testing.T) { handleCreateNodeGroupBadSizes(t) - sc := fake.ServiceClient() + sc := client.ServiceClient() sc.Endpoint = sc.Endpoint + "v1/" maxNodes := 3 @@ -202,7 +202,7 @@ func TestUpdateNodeGroupSuccess(t *testing.T) { handleUpdateNodeGroupSuccess(t) - sc := fake.ServiceClient() + sc := client.ServiceClient() sc.Endpoint = sc.Endpoint + "v1/" updateOpts := []nodegroups.UpdateOptsBuilder{ @@ -226,7 +226,7 @@ func TestUpdateNodeGroupInternal(t *testing.T) { handleUpdateNodeGroupInternal(t) - sc := fake.ServiceClient() + sc := client.ServiceClient() sc.Endpoint = sc.Endpoint + "v1/" updateOpts := []nodegroups.UpdateOptsBuilder{ @@ -249,7 +249,7 @@ func TestUpdateNodeGroupBadField(t *testing.T) { handleUpdateNodeGroupBadField(t) - sc := fake.ServiceClient() + sc := client.ServiceClient() sc.Endpoint = sc.Endpoint + "v1/" updateOpts := []nodegroups.UpdateOptsBuilder{ @@ -272,7 +272,7 @@ func TestUpdateNodeGroupBadMin(t *testing.T) { handleUpdateNodeGroupBadMin(t) - sc := fake.ServiceClient() + sc := client.ServiceClient() sc.Endpoint = sc.Endpoint + "v1/" updateOpts := []nodegroups.UpdateOptsBuilder{ @@ -294,7 +294,7 @@ func TestDeleteNodeGroupSuccess(t *testing.T) { handleDeleteNodeGroupSuccess(t) - sc := fake.ServiceClient() + sc := client.ServiceClient() sc.Endpoint = sc.Endpoint + "v1/" err := nodegroups.Delete(context.TODO(), sc, clusterUUID, nodeGroup2UUID).ExtractErr() @@ -308,7 +308,7 @@ func TestDeleteNodeGroupNotFound(t *testing.T) { handleDeleteNodeGroupNotFound(t) - sc := fake.ServiceClient() + sc := client.ServiceClient() sc.Endpoint = sc.Endpoint + "v1/" err := nodegroups.Delete(context.TODO(), sc, clusterUUID, badNodeGroupUUID).ExtractErr() @@ -322,7 +322,7 @@ func TestDeleteNodeGroupClusterNotFound(t *testing.T) { handleDeleteNodeGroupClusterNotFound(t) - sc := fake.ServiceClient() + sc := client.ServiceClient() sc.Endpoint = sc.Endpoint + "v1/" err := nodegroups.Delete(context.TODO(), sc, badClusterUUID, badNodeGroupUUID).ExtractErr() @@ -336,7 +336,7 @@ func TestDeleteNodeGroupDefault(t *testing.T) { handleDeleteNodeGroupDefault(t) - sc := fake.ServiceClient() + sc := client.ServiceClient() sc.Endpoint = sc.Endpoint + "v1/" err := nodegroups.Delete(context.TODO(), sc, clusterUUID, nodeGroup2UUID).ExtractErr() diff --git a/openstack/containerinfra/v1/quotas/testing/fixtures_test.go b/openstack/containerinfra/v1/quotas/testing/fixtures_test.go index 2aad3abb66..84fc1b3f5e 100644 --- a/openstack/containerinfra/v1/quotas/testing/fixtures_test.go +++ b/openstack/containerinfra/v1/quotas/testing/fixtures_test.go @@ -6,7 +6,7 @@ import ( "testing" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) const projectID = "aa5436ab58144c768ca4e9d2e9f5c3b2" @@ -25,7 +25,7 @@ var CreateResponse = fmt.Sprintf(` func HandleCreateQuotaSuccessfully(t *testing.T) { th.Mux.HandleFunc("/v1/quotas", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.Header().Add("X-OpenStack-Request-Id", requestUUID) diff --git a/openstack/containerinfra/v1/quotas/testing/requests_test.go b/openstack/containerinfra/v1/quotas/testing/requests_test.go index 75dde3000f..0aa89f79e1 100644 --- a/openstack/containerinfra/v1/quotas/testing/requests_test.go +++ b/openstack/containerinfra/v1/quotas/testing/requests_test.go @@ -6,7 +6,7 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/containerinfra/v1/quotas" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) func TestCreateQuota(t *testing.T) { @@ -21,7 +21,7 @@ func TestCreateQuota(t *testing.T) { HardLimit: 10, } - sc := fake.ServiceClient() + sc := client.ServiceClient() sc.Endpoint = sc.Endpoint + "v1/" res := quotas.Create(context.TODO(), sc, opts) diff --git a/openstack/db/v1/configurations/testing/requests_test.go b/openstack/db/v1/configurations/testing/requests_test.go index 49d928e94e..a8bafcd518 100644 --- a/openstack/db/v1/configurations/testing/requests_test.go +++ b/openstack/db/v1/configurations/testing/requests_test.go @@ -8,7 +8,7 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/db/v1/instances" "github.com/gophercloud/gophercloud/v2/pagination" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" "github.com/gophercloud/gophercloud/v2/testhelper/fixture" ) @@ -32,7 +32,7 @@ func TestList(t *testing.T) { fixture.SetupHandler(t, _baseURL, "GET", "", ListConfigsJSON, 200) count := 0 - err := configurations.List(fake.ServiceClient()).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := configurations.List(client.ServiceClient()).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := configurations.ExtractConfigs(page) th.AssertNoErr(t, err) @@ -52,7 +52,7 @@ func TestGet(t *testing.T) { defer th.TeardownHTTP() fixture.SetupHandler(t, resURL, "GET", "", GetConfigJSON, 200) - config, err := configurations.Get(context.TODO(), fake.ServiceClient(), configID).Extract() + config, err := configurations.Get(context.TODO(), client.ServiceClient(), configID).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, &ExampleConfig, config) } @@ -75,7 +75,7 @@ func TestCreate(t *testing.T) { }, } - config, err := configurations.Create(context.TODO(), fake.ServiceClient(), opts).Extract() + config, err := configurations.Create(context.TODO(), client.ServiceClient(), opts).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, &ExampleConfigWithValues, config) } @@ -91,7 +91,7 @@ func TestUpdate(t *testing.T) { }, } - err := configurations.Update(context.TODO(), fake.ServiceClient(), configID, opts).ExtractErr() + err := configurations.Update(context.TODO(), client.ServiceClient(), configID, opts).ExtractErr() th.AssertNoErr(t, err) } @@ -106,7 +106,7 @@ func TestReplace(t *testing.T) { }, } - err := configurations.Replace(context.TODO(), fake.ServiceClient(), configID, opts).ExtractErr() + err := configurations.Replace(context.TODO(), client.ServiceClient(), configID, opts).ExtractErr() th.AssertNoErr(t, err) } @@ -115,7 +115,7 @@ func TestDelete(t *testing.T) { defer th.TeardownHTTP() fixture.SetupHandler(t, resURL, "DELETE", "", "", 202) - err := configurations.Delete(context.TODO(), fake.ServiceClient(), configID).ExtractErr() + err := configurations.Delete(context.TODO(), client.ServiceClient(), configID).ExtractErr() th.AssertNoErr(t, err) } @@ -130,7 +130,7 @@ func TestListInstances(t *testing.T) { } pages := 0 - err := configurations.ListInstances(fake.ServiceClient(), configID).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := configurations.ListInstances(client.ServiceClient(), configID).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := instances.ExtractInstances(page) @@ -153,7 +153,7 @@ func TestListDSParams(t *testing.T) { fixture.SetupHandler(t, dsParamListURL, "GET", "", ListParamsJSON, 200) pages := 0 - err := configurations.ListDatastoreParams(fake.ServiceClient(), dsID, versionID).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := configurations.ListDatastoreParams(client.ServiceClient(), dsID, versionID).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := configurations.ExtractParams(page) @@ -182,7 +182,7 @@ func TestGetDSParam(t *testing.T) { defer th.TeardownHTTP() fixture.SetupHandler(t, dsParamGetURL, "GET", "", GetParamJSON, 200) - param, err := configurations.GetDatastoreParam(context.TODO(), fake.ServiceClient(), dsID, versionID, paramID).Extract() + param, err := configurations.GetDatastoreParam(context.TODO(), client.ServiceClient(), dsID, versionID, paramID).Extract() th.AssertNoErr(t, err) expected := &configurations.Param{ @@ -198,7 +198,7 @@ func TestListGlobalParams(t *testing.T) { fixture.SetupHandler(t, globalParamListURL, "GET", "", ListParamsJSON, 200) pages := 0 - err := configurations.ListGlobalParams(fake.ServiceClient(), versionID).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := configurations.ListGlobalParams(client.ServiceClient(), versionID).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := configurations.ExtractParams(page) @@ -227,7 +227,7 @@ func TestGetGlobalParam(t *testing.T) { defer th.TeardownHTTP() fixture.SetupHandler(t, globalParamGetURL, "GET", "", GetParamJSON, 200) - param, err := configurations.GetGlobalParam(context.TODO(), fake.ServiceClient(), versionID, paramID).Extract() + param, err := configurations.GetGlobalParam(context.TODO(), client.ServiceClient(), versionID, paramID).Extract() th.AssertNoErr(t, err) expected := &configurations.Param{ diff --git a/openstack/db/v1/databases/testing/requests_test.go b/openstack/db/v1/databases/testing/requests_test.go index d509a7f1a9..ff257674af 100644 --- a/openstack/db/v1/databases/testing/requests_test.go +++ b/openstack/db/v1/databases/testing/requests_test.go @@ -7,7 +7,7 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/db/v1/databases" "github.com/gophercloud/gophercloud/v2/pagination" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) func TestCreate(t *testing.T) { @@ -20,7 +20,7 @@ func TestCreate(t *testing.T) { databases.CreateOpts{Name: "sampledb"}, } - res := databases.Create(context.TODO(), fake.ServiceClient(), instanceID, opts) + res := databases.Create(context.TODO(), client.ServiceClient(), instanceID, opts) th.AssertNoErr(t, res.Err) } @@ -38,7 +38,7 @@ func TestList(t *testing.T) { } pages := 0 - err := databases.List(fake.ServiceClient(), instanceID).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := databases.List(client.ServiceClient(), instanceID).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := databases.ExtractDBs(page) @@ -63,6 +63,6 @@ func TestDelete(t *testing.T) { defer th.TeardownHTTP() HandleDelete(t) - err := databases.Delete(context.TODO(), fake.ServiceClient(), instanceID, "{dbName}").ExtractErr() + err := databases.Delete(context.TODO(), client.ServiceClient(), instanceID, "{dbName}").ExtractErr() th.AssertNoErr(t, err) } diff --git a/openstack/db/v1/datastores/testing/requests_test.go b/openstack/db/v1/datastores/testing/requests_test.go index 47e3dbfae4..2d11466f32 100644 --- a/openstack/db/v1/datastores/testing/requests_test.go +++ b/openstack/db/v1/datastores/testing/requests_test.go @@ -7,7 +7,7 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/db/v1/datastores" "github.com/gophercloud/gophercloud/v2/pagination" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" "github.com/gophercloud/gophercloud/v2/testhelper/fixture" ) @@ -18,7 +18,7 @@ func TestList(t *testing.T) { pages := 0 - err := datastores.List(fake.ServiceClient()).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := datastores.List(client.ServiceClient()).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := datastores.ExtractDatastores(page) @@ -40,7 +40,7 @@ func TestGet(t *testing.T) { defer th.TeardownHTTP() fixture.SetupHandler(t, "/datastores/{dsID}", "GET", "", GetDSResp, 200) - ds, err := datastores.Get(context.TODO(), fake.ServiceClient(), "{dsID}").Extract() + ds, err := datastores.Get(context.TODO(), client.ServiceClient(), "{dsID}").Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, &ExampleDatastore, ds) } @@ -52,7 +52,7 @@ func TestListVersions(t *testing.T) { pages := 0 - err := datastores.ListVersions(fake.ServiceClient(), "{dsID}").EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := datastores.ListVersions(client.ServiceClient(), "{dsID}").EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := datastores.ExtractVersions(page) @@ -74,7 +74,7 @@ func TestGetVersion(t *testing.T) { defer th.TeardownHTTP() fixture.SetupHandler(t, "/datastores/{dsID}/versions/{versionID}", "GET", "", GetVersionResp, 200) - ds, err := datastores.GetVersion(context.TODO(), fake.ServiceClient(), "{dsID}", "{versionID}").Extract() + ds, err := datastores.GetVersion(context.TODO(), client.ServiceClient(), "{dsID}", "{versionID}").Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, &ExampleVersion1, ds) } diff --git a/openstack/db/v1/flavors/testing/requests_test.go b/openstack/db/v1/flavors/testing/requests_test.go index c4a419627a..36ecf2799d 100644 --- a/openstack/db/v1/flavors/testing/requests_test.go +++ b/openstack/db/v1/flavors/testing/requests_test.go @@ -8,7 +8,7 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/db/v1/flavors" "github.com/gophercloud/gophercloud/v2/pagination" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) func TestListFlavors(t *testing.T) { @@ -17,7 +17,7 @@ func TestListFlavors(t *testing.T) { HandleList(t) pages := 0 - err := flavors.List(fake.ServiceClient()).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := flavors.List(client.ServiceClient()).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := flavors.ExtractFlavors(page) @@ -91,7 +91,7 @@ func TestGetFlavor(t *testing.T) { defer th.TeardownHTTP() HandleGet(t) - actual, err := flavors.Get(context.TODO(), fake.ServiceClient(), flavorID).Extract() + actual, err := flavors.Get(context.TODO(), client.ServiceClient(), flavorID).Extract() th.AssertNoErr(t, err) expected := &flavors.Flavor{ diff --git a/openstack/db/v1/instances/testing/requests_test.go b/openstack/db/v1/instances/testing/requests_test.go index 1e08a796ac..0394b8a58d 100644 --- a/openstack/db/v1/instances/testing/requests_test.go +++ b/openstack/db/v1/instances/testing/requests_test.go @@ -9,7 +9,7 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/db/v1/users" "github.com/gophercloud/gophercloud/v2/pagination" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) func TestCreate(t *testing.T) { @@ -39,7 +39,7 @@ func TestCreate(t *testing.T) { VolumeType: "ssd", } - instance, err := instances.Create(context.TODO(), fake.ServiceClient(), opts).Extract() + instance, err := instances.Create(context.TODO(), client.ServiceClient(), opts).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, &expectedInstance, instance) @@ -72,7 +72,7 @@ func TestCreateWithFault(t *testing.T) { VolumeType: "ssd", } - instance, err := instances.Create(context.TODO(), fake.ServiceClient(), opts).Extract() + instance, err := instances.Create(context.TODO(), client.ServiceClient(), opts).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, &expectedInstanceWithFault, instance) @@ -84,7 +84,7 @@ func TestInstanceList(t *testing.T) { HandleList(t) pages := 0 - err := instances.List(fake.ServiceClient()).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := instances.List(client.ServiceClient()).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := instances.ExtractInstances(page) @@ -105,7 +105,7 @@ func TestGetInstance(t *testing.T) { defer th.TeardownHTTP() HandleGet(t) - instance, err := instances.Get(context.TODO(), fake.ServiceClient(), instanceID).Extract() + instance, err := instances.Get(context.TODO(), client.ServiceClient(), instanceID).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, &expectedGetInstance, instance) @@ -116,7 +116,7 @@ func TestDeleteInstance(t *testing.T) { defer th.TeardownHTTP() HandleDelete(t) - res := instances.Delete(context.TODO(), fake.ServiceClient(), instanceID) + res := instances.Delete(context.TODO(), client.ServiceClient(), instanceID) th.AssertNoErr(t, res.Err) } @@ -126,7 +126,7 @@ func TestEnableRootUser(t *testing.T) { HandleEnableRoot(t) expected := &users.User{Name: "root", Password: "secretsecret"} - user, err := instances.EnableRootUser(context.TODO(), fake.ServiceClient(), instanceID).Extract() + user, err := instances.EnableRootUser(context.TODO(), client.ServiceClient(), instanceID).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, expected, user) @@ -137,7 +137,7 @@ func TestIsRootEnabled(t *testing.T) { defer th.TeardownHTTP() HandleIsRootEnabled(t) - isEnabled, err := instances.IsRootEnabled(context.TODO(), fake.ServiceClient(), instanceID).Extract() + isEnabled, err := instances.IsRootEnabled(context.TODO(), client.ServiceClient(), instanceID).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, true, isEnabled) @@ -148,7 +148,7 @@ func TestRestart(t *testing.T) { defer th.TeardownHTTP() HandleRestart(t) - res := instances.Restart(context.TODO(), fake.ServiceClient(), instanceID) + res := instances.Restart(context.TODO(), client.ServiceClient(), instanceID) th.AssertNoErr(t, res.Err) } @@ -157,7 +157,7 @@ func TestResize(t *testing.T) { defer th.TeardownHTTP() HandleResize(t) - res := instances.Resize(context.TODO(), fake.ServiceClient(), instanceID, "2") + res := instances.Resize(context.TODO(), client.ServiceClient(), instanceID, "2") th.AssertNoErr(t, res.Err) } @@ -166,7 +166,7 @@ func TestResizeVolume(t *testing.T) { defer th.TeardownHTTP() HandleResizeVol(t) - res := instances.ResizeVolume(context.TODO(), fake.ServiceClient(), instanceID, 4) + res := instances.ResizeVolume(context.TODO(), client.ServiceClient(), instanceID, 4) th.AssertNoErr(t, res.Err) } @@ -175,7 +175,7 @@ func TestAttachConfigurationGroup(t *testing.T) { defer th.TeardownHTTP() HandleAttachConfigurationGroup(t) - res := instances.AttachConfigurationGroup(context.TODO(), fake.ServiceClient(), instanceID, configGroupID) + res := instances.AttachConfigurationGroup(context.TODO(), client.ServiceClient(), instanceID, configGroupID) th.AssertNoErr(t, res.Err) } @@ -184,6 +184,6 @@ func TestDetachConfigurationGroup(t *testing.T) { defer th.TeardownHTTP() HandleDetachConfigurationGroup(t) - res := instances.DetachConfigurationGroup(context.TODO(), fake.ServiceClient(), instanceID) + res := instances.DetachConfigurationGroup(context.TODO(), client.ServiceClient(), instanceID) th.AssertNoErr(t, res.Err) } diff --git a/openstack/db/v1/users/testing/requests_test.go b/openstack/db/v1/users/testing/requests_test.go index 40713f5446..ef7a03073a 100644 --- a/openstack/db/v1/users/testing/requests_test.go +++ b/openstack/db/v1/users/testing/requests_test.go @@ -8,7 +8,7 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/db/v1/users" "github.com/gophercloud/gophercloud/v2/pagination" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) func TestCreate(t *testing.T) { @@ -34,7 +34,7 @@ func TestCreate(t *testing.T) { }, } - res := users.Create(context.TODO(), fake.ServiceClient(), instanceID, opts) + res := users.Create(context.TODO(), client.ServiceClient(), instanceID, opts) th.AssertNoErr(t, res.Err) } @@ -60,7 +60,7 @@ func TestUserList(t *testing.T) { } pages := 0 - err := users.List(fake.ServiceClient(), instanceID).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := users.List(client.ServiceClient(), instanceID).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := users.ExtractUsers(page) @@ -81,6 +81,6 @@ func TestDelete(t *testing.T) { defer th.TeardownHTTP() HandleDelete(t) - res := users.Delete(context.TODO(), fake.ServiceClient(), instanceID, "{userName}") + res := users.Delete(context.TODO(), client.ServiceClient(), instanceID, "{userName}") th.AssertNoErr(t, res.Err) } diff --git a/openstack/identity/v2/roles/testing/fixtures_test.go b/openstack/identity/v2/roles/testing/fixtures_test.go index 170e80099c..6893dc32e0 100644 --- a/openstack/identity/v2/roles/testing/fixtures_test.go +++ b/openstack/identity/v2/roles/testing/fixtures_test.go @@ -6,13 +6,13 @@ import ( "testing" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) func MockListRoleResponse(t *testing.T) { th.Mux.HandleFunc("/OS-KSADM/roles", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -34,7 +34,7 @@ func MockListRoleResponse(t *testing.T) { func MockAddUserRoleResponse(t *testing.T) { th.Mux.HandleFunc("/tenants/{tenant_id}/users/{user_id}/roles/OS-KSADM/{role_id}", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusCreated) }) } @@ -42,7 +42,7 @@ func MockAddUserRoleResponse(t *testing.T) { func MockDeleteUserRoleResponse(t *testing.T) { th.Mux.HandleFunc("/tenants/{tenant_id}/users/{user_id}/roles/OS-KSADM/{role_id}", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) } diff --git a/openstack/identity/v2/tokens/testing/fixtures_test.go b/openstack/identity/v2/tokens/testing/fixtures_test.go index 1ee6d32e75..6ed7a3f2e6 100644 --- a/openstack/identity/v2/tokens/testing/fixtures_test.go +++ b/openstack/identity/v2/tokens/testing/fixtures_test.go @@ -9,7 +9,7 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/identity/v2/tenants" "github.com/gophercloud/gophercloud/v2/openstack/identity/v2/tokens" th "github.com/gophercloud/gophercloud/v2/testhelper" - thclient "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) // ExpectedToken is the token that should be parsed from TokenCreationResponse. @@ -162,7 +162,7 @@ func HandleTokenGet(t *testing.T, token string) { th.Mux.HandleFunc("/tokens/"+token, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") - th.TestHeader(t, r, "X-Auth-Token", thclient.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusOK) fmt.Fprint(w, TokenGetResponse) diff --git a/openstack/identity/v2/users/testing/fixtures_test.go b/openstack/identity/v2/users/testing/fixtures_test.go index 3e5285360b..6a0ed5eacd 100644 --- a/openstack/identity/v2/users/testing/fixtures_test.go +++ b/openstack/identity/v2/users/testing/fixtures_test.go @@ -6,13 +6,13 @@ import ( "testing" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) func MockListUserResponse(t *testing.T) { th.Mux.HandleFunc("/users", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -45,7 +45,7 @@ func MockListUserResponse(t *testing.T) { func mockCreateUserResponse(t *testing.T) { th.Mux.HandleFunc("/users", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, ` { @@ -78,7 +78,7 @@ func mockCreateUserResponse(t *testing.T) { func mockGetUserResponse(t *testing.T) { th.Mux.HandleFunc("/users/new_user", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -100,7 +100,7 @@ func mockGetUserResponse(t *testing.T) { func mockUpdateUserResponse(t *testing.T) { th.Mux.HandleFunc("/users/c39e3de9be2d4c779f1dfd6abacc176d", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, ` { @@ -132,7 +132,7 @@ func mockUpdateUserResponse(t *testing.T) { func mockDeleteUserResponse(t *testing.T) { th.Mux.HandleFunc("/users/c39e3de9be2d4c779f1dfd6abacc176d", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) } @@ -140,7 +140,7 @@ func mockDeleteUserResponse(t *testing.T) { func mockListRolesResponse(t *testing.T) { th.Mux.HandleFunc("/tenants/1d8b6120dcc640fda4fc9194ffc80273/users/c39e3de9be2d4c779f1dfd6abacc176d/roles", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) diff --git a/openstack/identity/v3/osinherit/testing/fixtures_test.go b/openstack/identity/v3/osinherit/testing/fixtures_test.go index e0c33646f6..8e2415ea0c 100644 --- a/openstack/identity/v3/osinherit/testing/fixtures_test.go +++ b/openstack/identity/v3/osinherit/testing/fixtures_test.go @@ -5,31 +5,31 @@ import ( "testing" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) func HandleAssignSuccessfully(t *testing.T) { th.Mux.HandleFunc("/OS-INHERIT/projects/{project_id}/users/{user_id}/roles/{role_id}/inherited_to_projects", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) th.Mux.HandleFunc("/OS-INHERIT/projects/{project_id}/groups/{group_id}/roles/{role_id}/inherited_to_projects", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) th.Mux.HandleFunc("/OS-INHERIT/domains/{domain_id}/users/{user_id}/roles/{role_id}/inherited_to_projects", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) th.Mux.HandleFunc("/OS-INHERIT/domains/{domain_id}/groups/{group_id}/roles/{role_id}/inherited_to_projects", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) } @@ -37,25 +37,25 @@ func HandleAssignSuccessfully(t *testing.T) { func HandleValidateSuccessfully(t *testing.T) { th.Mux.HandleFunc("/OS-INHERIT/projects/{project_id}/users/{user_id}/roles/{role_id}/inherited_to_projects", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "HEAD") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) th.Mux.HandleFunc("/OS-INHERIT/projects/{project_id}/groups/{group_id}/roles/{role_id}/inherited_to_projects", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "HEAD") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) th.Mux.HandleFunc("/OS-INHERIT/domains/{domain_id}/users/{user_id}/roles/{role_id}/inherited_to_projects", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "HEAD") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) th.Mux.HandleFunc("/OS-INHERIT/domains/{domain_id}/groups/{group_id}/roles/{role_id}/inherited_to_projects", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "HEAD") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) } @@ -63,25 +63,25 @@ func HandleValidateSuccessfully(t *testing.T) { func HandleUnassignSuccessfully(t *testing.T) { th.Mux.HandleFunc("/OS-INHERIT/projects/{project_id}/users/{user_id}/roles/{role_id}/inherited_to_projects", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) th.Mux.HandleFunc("/OS-INHERIT/projects/{project_id}/groups/{group_id}/roles/{role_id}/inherited_to_projects", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) th.Mux.HandleFunc("/OS-INHERIT/domains/{domain_id}/users/{user_id}/roles/{role_id}/inherited_to_projects", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) th.Mux.HandleFunc("/OS-INHERIT/domains/{domain_id}/groups/{group_id}/roles/{role_id}/inherited_to_projects", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) } diff --git a/openstack/identity/v3/policies/testing/fixtures_test.go b/openstack/identity/v3/policies/testing/fixtures_test.go index d261ed865c..e40d50b340 100644 --- a/openstack/identity/v3/policies/testing/fixtures_test.go +++ b/openstack/identity/v3/policies/testing/fixtures_test.go @@ -7,7 +7,7 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/identity/v3/policies" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) // ListOutput provides a single page of Policy results. @@ -158,7 +158,7 @@ func HandleListPoliciesSuccessfully(t *testing.T) { th.Mux.HandleFunc("/policies", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -178,7 +178,7 @@ func HandleListPoliciesSuccessfully(t *testing.T) { func HandleCreatePolicySuccessfully(t *testing.T) { th.Mux.HandleFunc("/policies", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, CreateRequest) w.WriteHeader(http.StatusCreated) @@ -193,7 +193,7 @@ func HandleGetPolicySuccessfully(t *testing.T) { func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -208,7 +208,7 @@ func HandleUpdatePolicySuccessfully(t *testing.T) { th.Mux.HandleFunc("/policies/b49884da9d31494ea02aff38d4b4e701", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PATCH") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, UpdateRequest) w.WriteHeader(http.StatusOK) @@ -222,7 +222,7 @@ func HandleUpdatePolicySuccessfully(t *testing.T) { func HandleDeletePolicySuccessfully(t *testing.T) { th.Mux.HandleFunc("/policies/9fe1d3", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) diff --git a/openstack/identity/v3/roles/testing/fixtures_test.go b/openstack/identity/v3/roles/testing/fixtures_test.go index 32fe745a94..4e6ec8e843 100644 --- a/openstack/identity/v3/roles/testing/fixtures_test.go +++ b/openstack/identity/v3/roles/testing/fixtures_test.go @@ -7,7 +7,7 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/identity/v3/roles" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) // ListOutput provides a single page of Role results. @@ -346,7 +346,7 @@ func HandleListRolesSuccessfully(t *testing.T) { th.Mux.HandleFunc("/roles", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -360,7 +360,7 @@ func HandleGetRoleSuccessfully(t *testing.T) { th.Mux.HandleFunc("/roles/9fe1d3", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -373,7 +373,7 @@ func HandleGetRoleSuccessfully(t *testing.T) { func HandleCreateRoleSuccessfully(t *testing.T) { th.Mux.HandleFunc("/roles", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, CreateRequest) w.WriteHeader(http.StatusCreated) @@ -386,7 +386,7 @@ func HandleCreateRoleSuccessfully(t *testing.T) { func HandleUpdateRoleSuccessfully(t *testing.T) { th.Mux.HandleFunc("/roles/9fe1d3", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PATCH") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, UpdateRequest) w.WriteHeader(http.StatusOK) @@ -399,7 +399,7 @@ func HandleUpdateRoleSuccessfully(t *testing.T) { func HandleDeleteRoleSuccessfully(t *testing.T) { th.Mux.HandleFunc("/roles/9fe1d3", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) @@ -408,25 +408,25 @@ func HandleDeleteRoleSuccessfully(t *testing.T) { func HandleAssignSuccessfully(t *testing.T) { th.Mux.HandleFunc("/projects/{project_id}/users/{user_id}/roles/{role_id}", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) th.Mux.HandleFunc("/projects/{project_id}/groups/{group_id}/roles/{role_id}", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) th.Mux.HandleFunc("/domains/{domain_id}/users/{user_id}/roles/{role_id}", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) th.Mux.HandleFunc("/domains/{domain_id}/groups/{group_id}/roles/{role_id}", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) } @@ -434,25 +434,25 @@ func HandleAssignSuccessfully(t *testing.T) { func HandleUnassignSuccessfully(t *testing.T) { th.Mux.HandleFunc("/projects/{project_id}/users/{user_id}/roles/{role_id}", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) th.Mux.HandleFunc("/projects/{project_id}/groups/{group_id}/roles/{role_id}", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) th.Mux.HandleFunc("/domains/{domain_id}/users/{user_id}/roles/{role_id}", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) th.Mux.HandleFunc("/domains/{domain_id}/groups/{group_id}/roles/{role_id}", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) } @@ -495,7 +495,7 @@ func HandleListRoleAssignmentsSuccessfully(t *testing.T) { th.Mux.HandleFunc("/role_assignments", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -509,7 +509,7 @@ func HandleListRoleAssignmentsWithNamesSuccessfully(t *testing.T) { th.Mux.HandleFunc("/role_assignments", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.AssertEquals(t, "include_names=true", r.URL.RawQuery) w.Header().Set("Content-Type", "application/json") @@ -524,7 +524,7 @@ func HandleListRoleAssignmentsWithSubtreeSuccessfully(t *testing.T) { th.Mux.HandleFunc("/role_assignments", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.AssertEquals(t, "include_subtree=true", r.URL.RawQuery) w.Header().Set("Content-Type", "application/json") @@ -553,7 +553,7 @@ func HandleListAssignmentsOnResourceSuccessfully_ProjectsUsers(t *testing.T) { fn := func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -567,7 +567,7 @@ func HandleListAssignmentsOnResourceSuccessfully_ProjectsGroups(t *testing.T) { fn := func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -581,7 +581,7 @@ func HandleListAssignmentsOnResourceSuccessfully_DomainsUsers(t *testing.T) { fn := func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -595,7 +595,7 @@ func HandleListAssignmentsOnResourceSuccessfully_DomainsGroups(t *testing.T) { fn := func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -631,7 +631,7 @@ func HandleCreateRoleInferenceRule(t *testing.T) { fn := func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "Accept", "application/json") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) @@ -709,7 +709,7 @@ func HandleListRoleInferenceRules(t *testing.T) { fn := func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -722,7 +722,7 @@ func HandleListRoleInferenceRules(t *testing.T) { func HandleDeleteRoleInferenceRule(t *testing.T) { fn := func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) } @@ -733,7 +733,7 @@ func HandleGetRoleInferenceRule(t *testing.T) { fn := func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) diff --git a/openstack/image/v2/imagedata/testing/fixtures_test.go b/openstack/image/v2/imagedata/testing/fixtures_test.go index fa3b4af781..38179965cc 100644 --- a/openstack/image/v2/imagedata/testing/fixtures_test.go +++ b/openstack/image/v2/imagedata/testing/fixtures_test.go @@ -6,14 +6,14 @@ import ( "testing" th "github.com/gophercloud/gophercloud/v2/testhelper" - fakeclient "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) // HandlePutImageDataSuccessfully setup func HandlePutImageDataSuccessfully(t *testing.T) { th.Mux.HandleFunc("/images/da3b75d9-3f4a-40e7-8a2c-bfab23927dea/file", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) b, err := io.ReadAll(r.Body) if err != nil { @@ -30,7 +30,7 @@ func HandlePutImageDataSuccessfully(t *testing.T) { func HandleStageImageDataSuccessfully(t *testing.T) { th.Mux.HandleFunc("/images/da3b75d9-3f4a-40e7-8a2c-bfab23927dea/stage", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) b, err := io.ReadAll(r.Body) if err != nil { @@ -47,7 +47,7 @@ func HandleStageImageDataSuccessfully(t *testing.T) { func HandleGetImageDataSuccessfully(t *testing.T) { th.Mux.HandleFunc("/images/da3b75d9-3f4a-40e7-8a2c-bfab23927dea/file", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusOK) diff --git a/openstack/image/v2/imagedata/testing/requests_test.go b/openstack/image/v2/imagedata/testing/requests_test.go index 8e1461e1c7..3596dded66 100644 --- a/openstack/image/v2/imagedata/testing/requests_test.go +++ b/openstack/image/v2/imagedata/testing/requests_test.go @@ -8,7 +8,7 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/image/v2/imagedata" th "github.com/gophercloud/gophercloud/v2/testhelper" - fakeclient "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) func TestUpload(t *testing.T) { @@ -19,7 +19,7 @@ func TestUpload(t *testing.T) { err := imagedata.Upload( context.TODO(), - fakeclient.ServiceClient(), + client.ServiceClient(), "da3b75d9-3f4a-40e7-8a2c-bfab23927dea", readSeekerOfBytes([]byte{5, 3, 7, 24})).ExtractErr() @@ -34,7 +34,7 @@ func TestStage(t *testing.T) { err := imagedata.Stage( context.TODO(), - fakeclient.ServiceClient(), + client.ServiceClient(), "da3b75d9-3f4a-40e7-8a2c-bfab23927dea", readSeekerOfBytes([]byte{5, 3, 7, 24})).ExtractErr() @@ -93,7 +93,7 @@ func TestDownload(t *testing.T) { HandleGetImageDataSuccessfully(t) - rdr, err := imagedata.Download(context.TODO(), fakeclient.ServiceClient(), "da3b75d9-3f4a-40e7-8a2c-bfab23927dea").Extract() + rdr, err := imagedata.Download(context.TODO(), client.ServiceClient(), "da3b75d9-3f4a-40e7-8a2c-bfab23927dea").Extract() th.AssertNoErr(t, err) defer rdr.Close() diff --git a/openstack/image/v2/imageimport/testing/requests_test.go b/openstack/image/v2/imageimport/testing/requests_test.go index 74df12e548..7db88a1d5d 100644 --- a/openstack/image/v2/imageimport/testing/requests_test.go +++ b/openstack/image/v2/imageimport/testing/requests_test.go @@ -8,7 +8,7 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/image/v2/imageimport" th "github.com/gophercloud/gophercloud/v2/testhelper" - fakeclient "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) func TestGet(t *testing.T) { @@ -17,7 +17,7 @@ func TestGet(t *testing.T) { th.Mux.HandleFunc("/info/import", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -30,7 +30,7 @@ func TestGet(t *testing.T) { string(imageimport.WebDownloadMethod), } - s, err := imageimport.Get(context.TODO(), fakeclient.ServiceClient()).Extract() + s, err := imageimport.Get(context.TODO(), client.ServiceClient()).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, s.ImportMethods.Description, "Import methods available.") @@ -44,7 +44,7 @@ func TestCreate(t *testing.T) { th.Mux.HandleFunc("/images/da3b75d9-3f4a-40e7-8a2c-bfab23927dea/import", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, ImportCreateRequest) w.Header().Add("Content-Type", "application/json") @@ -56,6 +56,6 @@ func TestCreate(t *testing.T) { Name: imageimport.WebDownloadMethod, URI: "http://download.cirros-cloud.net/0.4.0/cirros-0.4.0-x86_64-disk.img", } - err := imageimport.Create(context.TODO(), fakeclient.ServiceClient(), "da3b75d9-3f4a-40e7-8a2c-bfab23927dea", opts).ExtractErr() + err := imageimport.Create(context.TODO(), client.ServiceClient(), "da3b75d9-3f4a-40e7-8a2c-bfab23927dea", opts).ExtractErr() th.AssertNoErr(t, err) } diff --git a/openstack/image/v2/images/testing/fixtures_test.go b/openstack/image/v2/images/testing/fixtures_test.go index 693f6b9965..d36d6b15d6 100644 --- a/openstack/image/v2/images/testing/fixtures_test.go +++ b/openstack/image/v2/images/testing/fixtures_test.go @@ -8,7 +8,7 @@ import ( "testing" th "github.com/gophercloud/gophercloud/v2/testhelper" - fakeclient "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) type imageEntry struct { @@ -101,7 +101,7 @@ func HandleImageListSuccessfully(t *testing.T) { th.Mux.HandleFunc("/images", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") @@ -163,7 +163,7 @@ func HandleImageListSuccessfully(t *testing.T) { func HandleImageCreationSuccessfully(t *testing.T) { th.Mux.HandleFunc("/images", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, `{ "id": "e7db3b45-8db7-47ad-8109-3fb55c2c24fd", "name": "Ubuntu 12.10", @@ -209,7 +209,7 @@ func HandleImageCreationSuccessfully(t *testing.T) { func HandleImageCreationSuccessfullyNulls(t *testing.T) { th.Mux.HandleFunc("/images", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, `{ "id": "e7db3b45-8db7-47ad-8109-3fb55c2c24fd", "architecture": "x86_64", @@ -254,7 +254,7 @@ func HandleImageCreationSuccessfullyNulls(t *testing.T) { func HandleImageGetSuccessfully(t *testing.T) { th.Mux.HandleFunc("/images/1bea47ed-f6a9-463b-b423-14b9cca9ad27", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -290,7 +290,7 @@ func HandleImageGetSuccessfully(t *testing.T) { func HandleImageDeleteSuccessfully(t *testing.T) { th.Mux.HandleFunc("/images/1bea47ed-f6a9-463b-b423-14b9cca9ad27", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) @@ -300,7 +300,7 @@ func HandleImageDeleteSuccessfully(t *testing.T) { func HandleImageUpdateSuccessfully(t *testing.T) { th.Mux.HandleFunc("/images/da3b75d9-3f4a-40e7-8a2c-bfab23927dea", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PATCH") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, `[ { @@ -383,7 +383,7 @@ func HandleImageUpdateSuccessfully(t *testing.T) { func HandleImageListByTagsSuccessfully(t *testing.T) { th.Mux.HandleFunc("/images", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") @@ -425,7 +425,7 @@ func HandleImageListByTagsSuccessfully(t *testing.T) { func HandleImageUpdatePropertiesSuccessfully(t *testing.T) { th.Mux.HandleFunc("/images/da3b75d9-3f4a-40e7-8a2c-bfab23927dea", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PATCH") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, `[ { diff --git a/openstack/image/v2/images/testing/requests_test.go b/openstack/image/v2/images/testing/requests_test.go index 8b857871af..d3e363b79d 100644 --- a/openstack/image/v2/images/testing/requests_test.go +++ b/openstack/image/v2/images/testing/requests_test.go @@ -8,7 +8,7 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/image/v2/images" "github.com/gophercloud/gophercloud/v2/pagination" th "github.com/gophercloud/gophercloud/v2/testhelper" - fakeclient "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) func TestListImage(t *testing.T) { @@ -19,7 +19,7 @@ func TestListImage(t *testing.T) { t.Logf("Id\tName\tOwner\tChecksum\tSizeBytes") - pager := images.List(fakeclient.ServiceClient(), images.ListOpts{Limit: 1}) + pager := images.List(client.ServiceClient(), images.ListOpts{Limit: 1}) t.Logf("Pager state %v", pager) count, pages := 0, 0 err := pager.EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { @@ -50,7 +50,7 @@ func TestAllPagesImage(t *testing.T) { HandleImageListSuccessfully(t) - pages, err := images.List(fakeclient.ServiceClient(), nil).AllPages(context.TODO()) + pages, err := images.List(client.ServiceClient(), nil).AllPages(context.TODO()) th.AssertNoErr(t, err) images, err := images.ExtractImages(pages) th.AssertNoErr(t, err) @@ -66,7 +66,7 @@ func TestCreateImage(t *testing.T) { id := "e7db3b45-8db7-47ad-8109-3fb55c2c24fd" name := "Ubuntu 12.10" - actualImage, err := images.Create(context.TODO(), fakeclient.ServiceClient(), images.CreateOpts{ + actualImage, err := images.Create(context.TODO(), client.ServiceClient(), images.CreateOpts{ ID: id, Name: name, Properties: map[string]string{ @@ -127,7 +127,7 @@ func TestCreateImageNulls(t *testing.T) { id := "e7db3b45-8db7-47ad-8109-3fb55c2c24fd" name := "Ubuntu 12.10" - actualImage, err := images.Create(context.TODO(), fakeclient.ServiceClient(), images.CreateOpts{ + actualImage, err := images.Create(context.TODO(), client.ServiceClient(), images.CreateOpts{ ID: id, Name: name, Tags: []string{"ubuntu", "quantal"}, @@ -193,7 +193,7 @@ func TestGetImage(t *testing.T) { HandleImageGetSuccessfully(t) - actualImage, err := images.Get(context.TODO(), fakeclient.ServiceClient(), "1bea47ed-f6a9-463b-b423-14b9cca9ad27").Extract() + actualImage, err := images.Get(context.TODO(), client.ServiceClient(), "1bea47ed-f6a9-463b-b423-14b9cca9ad27").Extract() th.AssertNoErr(t, err) @@ -251,7 +251,7 @@ func TestDeleteImage(t *testing.T) { HandleImageDeleteSuccessfully(t) - result := images.Delete(context.TODO(), fakeclient.ServiceClient(), "1bea47ed-f6a9-463b-b423-14b9cca9ad27") + result := images.Delete(context.TODO(), client.ServiceClient(), "1bea47ed-f6a9-463b-b423-14b9cca9ad27") th.AssertNoErr(t, result.Err) } @@ -261,7 +261,7 @@ func TestUpdateImage(t *testing.T) { HandleImageUpdateSuccessfully(t) - actualImage, err := images.Update(context.TODO(), fakeclient.ServiceClient(), "da3b75d9-3f4a-40e7-8a2c-bfab23927dea", images.UpdateOpts{ + actualImage, err := images.Update(context.TODO(), client.ServiceClient(), "da3b75d9-3f4a-40e7-8a2c-bfab23927dea", images.UpdateOpts{ images.ReplaceImageName{NewName: "Fedora 17"}, images.ReplaceImageTags{NewTags: []string{"fedora", "beefy"}}, images.ReplaceImageMinDisk{NewMinDisk: 21}, @@ -356,7 +356,7 @@ func TestImageListByTags(t *testing.T) { th.AssertNoErr(t, err) th.AssertEquals(t, expectedQueryString, actualQueryString) - pages, err := images.List(fakeclient.ServiceClient(), listOpts).AllPages(context.TODO()) + pages, err := images.List(client.ServiceClient(), listOpts).AllPages(context.TODO()) th.AssertNoErr(t, err) allImages, err := images.ExtractImages(pages) th.AssertNoErr(t, err) @@ -415,7 +415,7 @@ func TestUpdateImageProperties(t *testing.T) { HandleImageUpdatePropertiesSuccessfully(t) - actualImage, err := images.Update(context.TODO(), fakeclient.ServiceClient(), "da3b75d9-3f4a-40e7-8a2c-bfab23927dea", images.UpdateOpts{ + actualImage, err := images.Update(context.TODO(), client.ServiceClient(), "da3b75d9-3f4a-40e7-8a2c-bfab23927dea", images.UpdateOpts{ images.UpdateImageProperty{ Op: images.AddOp, Name: "hw_disk_bus", diff --git a/openstack/image/v2/members/testing/fixtures_test.go b/openstack/image/v2/members/testing/fixtures_test.go index 6e0bd326e7..cc2e60b9a7 100644 --- a/openstack/image/v2/members/testing/fixtures_test.go +++ b/openstack/image/v2/members/testing/fixtures_test.go @@ -6,14 +6,14 @@ import ( "testing" th "github.com/gophercloud/gophercloud/v2/testhelper" - fakeclient "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) // HandleCreateImageMemberSuccessfully setup func HandleCreateImageMemberSuccessfully(t *testing.T) { th.Mux.HandleFunc("/images/da3b75d9-3f4a-40e7-8a2c-bfab23927dea/members", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, `{"member": "8989447062e04a818baf9e073fd04fa7"}`) @@ -34,7 +34,7 @@ func HandleCreateImageMemberSuccessfully(t *testing.T) { func HandleImageMemberList(t *testing.T) { th.Mux.HandleFunc("/images/da3b75d9-3f4a-40e7-8a2c-bfab23927dea/members", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") fmt.Fprint(w, `{ @@ -65,7 +65,7 @@ func HandleImageMemberList(t *testing.T) { func HandleImageMemberEmptyList(t *testing.T) { th.Mux.HandleFunc("/images/da3b75d9-3f4a-40e7-8a2c-bfab23927dea/members", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") fmt.Fprint(w, `{ @@ -79,7 +79,7 @@ func HandleImageMemberEmptyList(t *testing.T) { func HandleImageMemberDetails(t *testing.T) { th.Mux.HandleFunc("/images/da3b75d9-3f4a-40e7-8a2c-bfab23927dea/members/8989447062e04a818baf9e073fd04fa7", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusOK) fmt.Fprint(w, `{ @@ -100,7 +100,7 @@ func HandleImageMemberDeleteSuccessfully(t *testing.T) *CallsCounter { counter.Counter = counter.Counter + 1 th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) @@ -114,7 +114,7 @@ func HandleImageMemberUpdate(t *testing.T) *CallsCounter { counter.Counter = counter.Counter + 1 th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, `{"status": "accepted"}`) diff --git a/openstack/image/v2/members/testing/requests_test.go b/openstack/image/v2/members/testing/requests_test.go index 273d82581d..0d5e84d3ab 100644 --- a/openstack/image/v2/members/testing/requests_test.go +++ b/openstack/image/v2/members/testing/requests_test.go @@ -8,7 +8,7 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/image/v2/members" "github.com/gophercloud/gophercloud/v2/pagination" th "github.com/gophercloud/gophercloud/v2/testhelper" - fakeclient "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) const createdAtString = "2013-09-20T19:22:19Z" @@ -19,7 +19,7 @@ func TestCreateMemberSuccessfully(t *testing.T) { defer th.TeardownHTTP() HandleCreateImageMemberSuccessfully(t) - im, err := members.Create(context.TODO(), fakeclient.ServiceClient(), "da3b75d9-3f4a-40e7-8a2c-bfab23927dea", + im, err := members.Create(context.TODO(), client.ServiceClient(), "da3b75d9-3f4a-40e7-8a2c-bfab23927dea", "8989447062e04a818baf9e073fd04fa7").Extract() th.AssertNoErr(t, err) @@ -46,7 +46,7 @@ func TestMemberListSuccessfully(t *testing.T) { HandleImageMemberList(t) - pager := members.List(fakeclient.ServiceClient(), "da3b75d9-3f4a-40e7-8a2c-bfab23927dea") + pager := members.List(client.ServiceClient(), "da3b75d9-3f4a-40e7-8a2c-bfab23927dea") t.Logf("Pager state %v", pager) count, pages := 0, 0 err := pager.EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { @@ -76,7 +76,7 @@ func TestMemberListEmpty(t *testing.T) { HandleImageMemberEmptyList(t) - pager := members.List(fakeclient.ServiceClient(), "da3b75d9-3f4a-40e7-8a2c-bfab23927dea") + pager := members.List(client.ServiceClient(), "da3b75d9-3f4a-40e7-8a2c-bfab23927dea") t.Logf("Pager state %v", pager) count, pages := 0, 0 err := pager.EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { @@ -105,7 +105,7 @@ func TestShowMemberDetails(t *testing.T) { defer th.TeardownHTTP() HandleImageMemberDetails(t) - md, err := members.Get(context.TODO(), fakeclient.ServiceClient(), + md, err := members.Get(context.TODO(), client.ServiceClient(), "da3b75d9-3f4a-40e7-8a2c-bfab23927dea", "8989447062e04a818baf9e073fd04fa7").Extract() @@ -136,7 +136,7 @@ func TestDeleteMember(t *testing.T) { counter := HandleImageMemberDeleteSuccessfully(t) - result := members.Delete(context.TODO(), fakeclient.ServiceClient(), "da3b75d9-3f4a-40e7-8a2c-bfab23927dea", + result := members.Delete(context.TODO(), client.ServiceClient(), "da3b75d9-3f4a-40e7-8a2c-bfab23927dea", "8989447062e04a818baf9e073fd04fa7") th.AssertEquals(t, 1, counter.Counter) th.AssertNoErr(t, result.Err) @@ -147,7 +147,7 @@ func TestMemberUpdateSuccessfully(t *testing.T) { defer th.TeardownHTTP() counter := HandleImageMemberUpdate(t) - im, err := members.Update(context.TODO(), fakeclient.ServiceClient(), "da3b75d9-3f4a-40e7-8a2c-bfab23927dea", + im, err := members.Update(context.TODO(), client.ServiceClient(), "da3b75d9-3f4a-40e7-8a2c-bfab23927dea", "8989447062e04a818baf9e073fd04fa7", members.UpdateOpts{ Status: "accepted", diff --git a/openstack/image/v2/tasks/testing/requests_test.go b/openstack/image/v2/tasks/testing/requests_test.go index f930304427..5ddd556794 100644 --- a/openstack/image/v2/tasks/testing/requests_test.go +++ b/openstack/image/v2/tasks/testing/requests_test.go @@ -10,7 +10,7 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/image/v2/tasks" "github.com/gophercloud/gophercloud/v2/pagination" th "github.com/gophercloud/gophercloud/v2/testhelper" - fakeclient "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) func TestList(t *testing.T) { @@ -19,7 +19,7 @@ func TestList(t *testing.T) { th.Mux.HandleFunc("/tasks", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -29,7 +29,7 @@ func TestList(t *testing.T) { count := 0 - err := tasks.List(fakeclient.ServiceClient(), tasks.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := tasks.List(client.ServiceClient(), tasks.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := tasks.ExtractTasks(page) if err != nil { @@ -59,7 +59,7 @@ func TestGet(t *testing.T) { th.Mux.HandleFunc("/tasks/1252f636-1246-4319-bfba-c47cde0efbe0", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -67,7 +67,7 @@ func TestGet(t *testing.T) { fmt.Fprint(w, TasksGetResult) }) - s, err := tasks.Get(context.TODO(), fakeclient.ServiceClient(), "1252f636-1246-4319-bfba-c47cde0efbe0").Extract() + s, err := tasks.Get(context.TODO(), client.ServiceClient(), "1252f636-1246-4319-bfba-c47cde0efbe0").Extract() th.AssertNoErr(t, err) th.AssertEquals(t, s.Status, string(tasks.TaskStatusPending)) @@ -96,7 +96,7 @@ func TestCreate(t *testing.T) { th.Mux.HandleFunc("/tasks", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, TaskCreateRequest) w.Header().Add("Content-Type", "application/json") @@ -116,7 +116,7 @@ func TestCreate(t *testing.T) { "import_from": "https://cloud-images.ubuntu.com/bionic/current/bionic-server-cloudimg-amd64.img", }, } - s, err := tasks.Create(context.TODO(), fakeclient.ServiceClient(), opts).Extract() + s, err := tasks.Create(context.TODO(), client.ServiceClient(), opts).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, s.Status, string(tasks.TaskStatusPending)) diff --git a/openstack/messaging/v2/claims/testing/fixtures_test.go b/openstack/messaging/v2/claims/testing/fixtures_test.go index 5912ff64e6..a90c7b392c 100644 --- a/openstack/messaging/v2/claims/testing/fixtures_test.go +++ b/openstack/messaging/v2/claims/testing/fixtures_test.go @@ -7,7 +7,7 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/messaging/v2/claims" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) // QueueName is the name of the queue @@ -88,7 +88,7 @@ func HandleCreateSuccessfully(t *testing.T) { th.Mux.HandleFunc(fmt.Sprintf("/v2/queues/%s/claims", QueueName), func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, CreateClaimRequest) w.WriteHeader(http.StatusCreated) @@ -102,7 +102,7 @@ func HandleCreateNoContent(t *testing.T) { th.Mux.HandleFunc(fmt.Sprintf("/v2/queues/%s/claims", QueueName), func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, CreateClaimRequest) w.WriteHeader(http.StatusNoContent) @@ -114,7 +114,7 @@ func HandleGetSuccessfully(t *testing.T) { th.Mux.HandleFunc(fmt.Sprintf("/v2/queues/%s/claims/%s", QueueName, ClaimID), func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") fmt.Fprint(w, GetClaimResponse) @@ -126,7 +126,7 @@ func HandleUpdateSuccessfully(t *testing.T) { th.Mux.HandleFunc(fmt.Sprintf("/v2/queues/%s/claims/%s", QueueName, ClaimID), func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PATCH") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, UpdateClaimRequest) w.WriteHeader(http.StatusNoContent) @@ -138,7 +138,7 @@ func HandleDeleteSuccessfully(t *testing.T) { th.Mux.HandleFunc(fmt.Sprintf("/v2/queues/%s/claims/%s", QueueName, ClaimID), func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) diff --git a/openstack/messaging/v2/claims/testing/requests_test.go b/openstack/messaging/v2/claims/testing/requests_test.go index 8040796601..7f7a78a455 100644 --- a/openstack/messaging/v2/claims/testing/requests_test.go +++ b/openstack/messaging/v2/claims/testing/requests_test.go @@ -6,7 +6,7 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/messaging/v2/claims" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) func TestCreate(t *testing.T) { @@ -20,7 +20,7 @@ func TestCreate(t *testing.T) { Limit: 10, } - actual, err := claims.Create(context.TODO(), fake.ServiceClient(), QueueName, createOpts).Extract() + actual, err := claims.Create(context.TODO(), client.ServiceClient(), QueueName, createOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, CreatedClaim, actual) } @@ -36,7 +36,7 @@ func TestCreateNoContent(t *testing.T) { Limit: 10, } - actual, err := claims.Create(context.TODO(), fake.ServiceClient(), QueueName, createOpts).Extract() + actual, err := claims.Create(context.TODO(), client.ServiceClient(), QueueName, createOpts).Extract() th.AssertNoErr(t, err) var expected []claims.Messages th.CheckDeepEquals(t, expected, actual) @@ -47,7 +47,7 @@ func TestGet(t *testing.T) { defer th.TeardownHTTP() HandleGetSuccessfully(t) - actual, err := claims.Get(context.TODO(), fake.ServiceClient(), QueueName, ClaimID).Extract() + actual, err := claims.Get(context.TODO(), client.ServiceClient(), QueueName, ClaimID).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, &FirstClaim, actual) } @@ -62,7 +62,7 @@ func TestUpdate(t *testing.T) { TTL: 1200, } - err := claims.Update(context.TODO(), fake.ServiceClient(), QueueName, ClaimID, updateOpts).ExtractErr() + err := claims.Update(context.TODO(), client.ServiceClient(), QueueName, ClaimID, updateOpts).ExtractErr() th.AssertNoErr(t, err) } @@ -71,6 +71,6 @@ func TestDelete(t *testing.T) { defer th.TeardownHTTP() HandleDeleteSuccessfully(t) - err := claims.Delete(context.TODO(), fake.ServiceClient(), QueueName, ClaimID).ExtractErr() + err := claims.Delete(context.TODO(), client.ServiceClient(), QueueName, ClaimID).ExtractErr() th.AssertNoErr(t, err) } diff --git a/openstack/messaging/v2/messages/testing/fixtures_test.go b/openstack/messaging/v2/messages/testing/fixtures_test.go index 95cd47592b..ca28d7ce7a 100644 --- a/openstack/messaging/v2/messages/testing/fixtures_test.go +++ b/openstack/messaging/v2/messages/testing/fixtures_test.go @@ -7,7 +7,7 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/messaging/v2/messages" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) // QueueName is the name of the queue @@ -224,7 +224,7 @@ func HandleCreateSuccessfully(t *testing.T) { th.Mux.HandleFunc(fmt.Sprintf("/v2/queues/%s/messages", QueueName), func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, CreateMessageRequest) w.Header().Add("Content-Type", "application/json") @@ -238,7 +238,7 @@ func HandleListSuccessfully(t *testing.T) { th.Mux.HandleFunc(fmt.Sprintf("/v2/queues/%s/messages", QueueName), func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") next := r.RequestURI @@ -259,7 +259,7 @@ func HandleGetMessagesSuccessfully(t *testing.T) { th.Mux.HandleFunc(fmt.Sprintf("/v2/queues/%s/messages", QueueName), func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") fmt.Fprint(w, GetMessagesResponse) @@ -271,7 +271,7 @@ func HandleGetSuccessfully(t *testing.T) { th.Mux.HandleFunc(fmt.Sprintf("/v2/queues/%s/messages/%s", QueueName, MessageID), func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") fmt.Fprint(w, GetMessageResponse) @@ -283,7 +283,7 @@ func HandleDeleteMessagesSuccessfully(t *testing.T) { th.Mux.HandleFunc(fmt.Sprintf("/v2/queues/%s/messages", QueueName), func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusNoContent) @@ -295,7 +295,7 @@ func HandlePopSuccessfully(t *testing.T) { th.Mux.HandleFunc(fmt.Sprintf("/v2/queues/%s/messages", QueueName), func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -308,7 +308,7 @@ func HandleDeleteSuccessfully(t *testing.T) { th.Mux.HandleFunc(fmt.Sprintf("/v2/queues/%s/messages/%s", QueueName, MessageID), func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusNoContent) diff --git a/openstack/messaging/v2/messages/testing/requests_test.go b/openstack/messaging/v2/messages/testing/requests_test.go index e2ee71be83..9d31d5812f 100644 --- a/openstack/messaging/v2/messages/testing/requests_test.go +++ b/openstack/messaging/v2/messages/testing/requests_test.go @@ -7,7 +7,7 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/messaging/v2/messages" "github.com/gophercloud/gophercloud/v2/pagination" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) func TestList(t *testing.T) { @@ -20,7 +20,7 @@ func TestList(t *testing.T) { } count := 0 - err := messages.List(fake.ServiceClient(), QueueName, listOpts).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := messages.List(client.ServiceClient(), QueueName, listOpts).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { actual, err := messages.ExtractMessages(page) th.AssertNoErr(t, err) @@ -57,7 +57,7 @@ func TestCreate(t *testing.T) { }, } - actual, err := messages.Create(context.TODO(), fake.ServiceClient(), QueueName, createOpts).Extract() + actual, err := messages.Create(context.TODO(), client.ServiceClient(), QueueName, createOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, ExpectedResources, actual) } @@ -71,7 +71,7 @@ func TestGetMessages(t *testing.T) { IDs: []string{"9988776655"}, } - actual, err := messages.GetMessages(context.TODO(), fake.ServiceClient(), QueueName, getMessagesOpts).Extract() + actual, err := messages.GetMessages(context.TODO(), client.ServiceClient(), QueueName, getMessagesOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, ExpectedMessagesSet, actual) } @@ -81,7 +81,7 @@ func TestGetMessage(t *testing.T) { defer th.TeardownHTTP() HandleGetSuccessfully(t) - actual, err := messages.Get(context.TODO(), fake.ServiceClient(), QueueName, MessageID).Extract() + actual, err := messages.Get(context.TODO(), client.ServiceClient(), QueueName, MessageID).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, FirstMessage, actual) } @@ -95,7 +95,7 @@ func TestDeleteMessages(t *testing.T) { IDs: []string{"9988776655"}, } - err := messages.DeleteMessages(context.TODO(), fake.ServiceClient(), QueueName, deleteMessagesOpts).ExtractErr() + err := messages.DeleteMessages(context.TODO(), client.ServiceClient(), QueueName, deleteMessagesOpts).ExtractErr() th.AssertNoErr(t, err) } @@ -108,7 +108,7 @@ func TestPopMessages(t *testing.T) { Pop: 1, } - actual, err := messages.PopMessages(context.TODO(), fake.ServiceClient(), QueueName, popMessagesOpts).Extract() + actual, err := messages.PopMessages(context.TODO(), client.ServiceClient(), QueueName, popMessagesOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, ExpectedPopMessage, actual) } @@ -122,6 +122,6 @@ func TestDeleteMessage(t *testing.T) { ClaimID: "12345", } - err := messages.Delete(context.TODO(), fake.ServiceClient(), QueueName, MessageID, deleteOpts).ExtractErr() + err := messages.Delete(context.TODO(), client.ServiceClient(), QueueName, MessageID, deleteOpts).ExtractErr() th.AssertNoErr(t, err) } diff --git a/openstack/messaging/v2/queues/testing/fixtures_test.go b/openstack/messaging/v2/queues/testing/fixtures_test.go index 7abfdc35ba..bd9f71187d 100644 --- a/openstack/messaging/v2/queues/testing/fixtures_test.go +++ b/openstack/messaging/v2/queues/testing/fixtures_test.go @@ -7,7 +7,7 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/messaging/v2/queues" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) // QueueName is the name of the queue @@ -219,7 +219,7 @@ func HandleListSuccessfully(t *testing.T) { th.Mux.HandleFunc("/v2/queues", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") next := r.RequestURI @@ -240,7 +240,7 @@ func HandleCreateSuccessfully(t *testing.T) { th.Mux.HandleFunc(fmt.Sprintf("/v2/queues/%s", QueueName), func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, CreateQueueRequest) w.WriteHeader(http.StatusNoContent) @@ -252,7 +252,7 @@ func HandleUpdateSuccessfully(t *testing.T) { th.Mux.HandleFunc(fmt.Sprintf("/v2/queues/%s", QueueName), func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PATCH") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, UpdateQueueRequest) w.Header().Add("Content-Type", "application/json") @@ -265,7 +265,7 @@ func HandleGetSuccessfully(t *testing.T) { th.Mux.HandleFunc(fmt.Sprintf("/v2/queues/%s", QueueName), func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") fmt.Fprint(w, GetQueueResponse) @@ -277,7 +277,7 @@ func HandleDeleteSuccessfully(t *testing.T) { th.Mux.HandleFunc(fmt.Sprintf("/v2/queues/%s", QueueName), func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) } @@ -287,7 +287,7 @@ func HandleGetStatsSuccessfully(t *testing.T) { th.Mux.HandleFunc(fmt.Sprintf("/v2/queues/%s/stats", QueueName), func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") fmt.Fprint(w, GetStatsResponse) @@ -299,7 +299,7 @@ func HandleShareSuccessfully(t *testing.T) { th.Mux.HandleFunc(fmt.Sprintf("/v2/queues/%s/share", QueueName), func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, CreateShareRequest) w.Header().Add("Content-Type", "application/json") @@ -312,7 +312,7 @@ func HandlePurgeSuccessfully(t *testing.T) { th.Mux.HandleFunc(fmt.Sprintf("/v2/queues/%s/purge", QueueName), func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, CreatePurgeRequest) w.WriteHeader(http.StatusNoContent) diff --git a/openstack/messaging/v2/queues/testing/requests_test.go b/openstack/messaging/v2/queues/testing/requests_test.go index eb83908d5d..adbb003fc4 100644 --- a/openstack/messaging/v2/queues/testing/requests_test.go +++ b/openstack/messaging/v2/queues/testing/requests_test.go @@ -7,7 +7,7 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/messaging/v2/queues" "github.com/gophercloud/gophercloud/v2/pagination" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) func TestList(t *testing.T) { @@ -21,7 +21,7 @@ func TestList(t *testing.T) { } count := 0 - err := queues.List(fake.ServiceClient(), listOpts).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := queues.List(client.ServiceClient(), listOpts).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { actual, err := queues.ExtractQueues(page) th.AssertNoErr(t, err) countField, err := page.(queues.QueuePage).GetCount() @@ -56,7 +56,7 @@ func TestCreate(t *testing.T) { Extra: map[string]any{"description": "Queue for unit testing."}, } - err := queues.Create(context.TODO(), fake.ServiceClient(), createOpts).ExtractErr() + err := queues.Create(context.TODO(), client.ServiceClient(), createOpts).ExtractErr() th.AssertNoErr(t, err) } @@ -76,7 +76,7 @@ func TestUpdate(t *testing.T) { Extra: map[string]any{"description": "Update queue description"}, } - actual, err := queues.Update(context.TODO(), fake.ServiceClient(), QueueName, updateOpts).Extract() + actual, err := queues.Update(context.TODO(), client.ServiceClient(), QueueName, updateOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, updatedQueueResult, actual) } @@ -86,7 +86,7 @@ func TestGet(t *testing.T) { defer th.TeardownHTTP() HandleGetSuccessfully(t) - actual, err := queues.Get(context.TODO(), fake.ServiceClient(), QueueName).Extract() + actual, err := queues.Get(context.TODO(), client.ServiceClient(), QueueName).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, QueueDetails, actual) } @@ -96,7 +96,7 @@ func TestDelete(t *testing.T) { defer th.TeardownHTTP() HandleDeleteSuccessfully(t) - err := queues.Delete(context.TODO(), fake.ServiceClient(), QueueName).ExtractErr() + err := queues.Delete(context.TODO(), client.ServiceClient(), QueueName).ExtractErr() th.AssertNoErr(t, err) } @@ -105,7 +105,7 @@ func TestGetStat(t *testing.T) { defer th.TeardownHTTP() HandleGetStatsSuccessfully(t) - actual, err := queues.GetStats(context.TODO(), fake.ServiceClient(), QueueName).Extract() + actual, err := queues.GetStats(context.TODO(), client.ServiceClient(), QueueName).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, ExpectedStats, actual) } @@ -121,7 +121,7 @@ func TestShare(t *testing.T) { Expires: "2016-09-01T00:00:00", } - actual, err := queues.Share(context.TODO(), fake.ServiceClient(), QueueName, shareOpts).Extract() + actual, err := queues.Share(context.TODO(), client.ServiceClient(), QueueName, shareOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, ExpectedShare, actual) } @@ -135,6 +135,6 @@ func TestPurge(t *testing.T) { ResourceTypes: []queues.PurgeResource{queues.ResourceMessages, queues.ResourceSubscriptions}, } - err := queues.Purge(context.TODO(), fake.ServiceClient(), QueueName, purgeOpts).ExtractErr() + err := queues.Purge(context.TODO(), client.ServiceClient(), QueueName, purgeOpts).ExtractErr() th.AssertNoErr(t, err) } diff --git a/openstack/networking/v2/apiversions/testing/requests_test.go b/openstack/networking/v2/apiversions/testing/requests_test.go index dbdf61d9fd..4e54283f92 100644 --- a/openstack/networking/v2/apiversions/testing/requests_test.go +++ b/openstack/networking/v2/apiversions/testing/requests_test.go @@ -9,7 +9,7 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/apiversions" "github.com/gophercloud/gophercloud/v2/pagination" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) func TestListVersions(t *testing.T) { @@ -18,7 +18,7 @@ func TestListVersions(t *testing.T) { th.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -42,7 +42,7 @@ func TestListVersions(t *testing.T) { count := 0 - err := apiversions.ListVersions(fake.ServiceClient()).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := apiversions.ListVersions(client.ServiceClient()).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := apiversions.ExtractAPIVersions(page) if err != nil { @@ -76,7 +76,7 @@ func TestNonJSONCannotBeExtractedIntoAPIVersions(t *testing.T) { w.WriteHeader(http.StatusOK) }) - err := apiversions.ListVersions(fake.ServiceClient()).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := apiversions.ListVersions(client.ServiceClient()).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { if _, err := apiversions.ExtractAPIVersions(page); err == nil { t.Fatalf("Expected error, got nil") } @@ -91,7 +91,7 @@ func TestAPIInfo(t *testing.T) { th.Mux.HandleFunc("/v2.0/", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -136,7 +136,7 @@ func TestAPIInfo(t *testing.T) { count := 0 - err := apiversions.ListVersionResources(fake.ServiceClient(), "v2.0").EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := apiversions.ListVersionResources(client.ServiceClient(), "v2.0").EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := apiversions.ExtractVersionResources(page) if err != nil { @@ -178,7 +178,7 @@ func TestNonJSONCannotBeExtractedIntoAPIVersionResources(t *testing.T) { w.WriteHeader(http.StatusOK) }) - err := apiversions.ListVersionResources(fake.ServiceClient(), "v2.0").EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := apiversions.ListVersionResources(client.ServiceClient(), "v2.0").EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { if _, err := apiversions.ExtractVersionResources(page); err == nil { t.Fatalf("Expected error, got nil") } diff --git a/openstack/networking/v2/extensions/qos/ruletypes/testing/requests_test.go b/openstack/networking/v2/extensions/qos/ruletypes/testing/requests_test.go index 7bea9f6b66..03a3fddab1 100644 --- a/openstack/networking/v2/extensions/qos/ruletypes/testing/requests_test.go +++ b/openstack/networking/v2/extensions/qos/ruletypes/testing/requests_test.go @@ -8,7 +8,7 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/extensions/qos/ruletypes" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) func TestListRuleTypes(t *testing.T) { @@ -17,7 +17,7 @@ func TestListRuleTypes(t *testing.T) { th.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -25,7 +25,7 @@ func TestListRuleTypes(t *testing.T) { fmt.Fprint(w, ListRuleTypesResponse) }) - page, err := ruletypes.ListRuleTypes(fake.ServiceClient()).AllPages(context.TODO()) + page, err := ruletypes.ListRuleTypes(client.ServiceClient()).AllPages(context.TODO()) if err != nil { t.Errorf("Failed to list rule types pages: %v", err) return @@ -47,7 +47,7 @@ func TestGetRuleType(t *testing.T) { th.Mux.HandleFunc("/qos/rule-types/bandwidth_limit", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -56,7 +56,7 @@ func TestGetRuleType(t *testing.T) { th.AssertNoErr(t, err) }) - r, err := ruletypes.GetRuleType(context.TODO(), fake.ServiceClient(), "bandwidth_limit").Extract() + r, err := ruletypes.GetRuleType(context.TODO(), client.ServiceClient(), "bandwidth_limit").Extract() th.AssertNoErr(t, err) th.AssertEquals(t, "bandwidth_limit", r.Type) diff --git a/openstack/networking/v2/extensions/trunk_details/testing/requests_test.go b/openstack/networking/v2/extensions/trunk_details/testing/requests_test.go index b99e711b1b..cca584c6d1 100644 --- a/openstack/networking/v2/extensions/trunk_details/testing/requests_test.go +++ b/openstack/networking/v2/extensions/trunk_details/testing/requests_test.go @@ -9,7 +9,7 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/extensions/trunk_details" "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/ports" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) func TestServerWithUsageExt(t *testing.T) { @@ -20,7 +20,7 @@ func TestServerWithUsageExt(t *testing.T) { th.Mux.HandleFunc("/ports/"+portIDFixture, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") fmt.Fprint(w, PortWithTrunkDetailsResult) @@ -32,7 +32,7 @@ func TestServerWithUsageExt(t *testing.T) { } // Extract basic fields. - err := ports.Get(context.TODO(), fake.ServiceClient(), portIDFixture).ExtractInto(&portExt) + err := ports.Get(context.TODO(), client.ServiceClient(), portIDFixture).ExtractInto(&portExt) th.AssertNoErr(t, err) th.AssertEquals(t, portExt.TrunkDetails.TrunkID, "f170c831-8c55-4ceb-ad13-75eab4a121e5") diff --git a/openstack/objectstorage/v1/accounts/testing/fixtures.go b/openstack/objectstorage/v1/accounts/testing/fixtures.go index 42284933e8..06948268db 100644 --- a/openstack/objectstorage/v1/accounts/testing/fixtures.go +++ b/openstack/objectstorage/v1/accounts/testing/fixtures.go @@ -5,7 +5,7 @@ import ( "testing" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) // HandleGetAccountSuccessfully creates an HTTP handler at `/` on the test handler mux that @@ -13,7 +13,7 @@ import ( func HandleGetAccountSuccessfully(t *testing.T) { th.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "HEAD") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Set("X-Account-Container-Count", "2") w.Header().Set("X-Account-Object-Count", "5") @@ -32,7 +32,7 @@ func HandleGetAccountSuccessfully(t *testing.T) { func HandleGetAccountNoQuotaSuccessfully(t *testing.T) { th.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "HEAD") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Set("X-Account-Container-Count", "2") w.Header().Set("X-Account-Object-Count", "5") @@ -49,7 +49,7 @@ func HandleGetAccountNoQuotaSuccessfully(t *testing.T) { func HandleUpdateAccountSuccessfully(t *testing.T) { th.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "X-Account-Meta-Gophercloud-Test", "accounts") th.TestHeader(t, r, "X-Remove-Account-Meta-Gophercloud-Test-Remove", "remove") th.TestHeader(t, r, "Content-Type", "") diff --git a/openstack/objectstorage/v1/accounts/testing/requests_test.go b/openstack/objectstorage/v1/accounts/testing/requests_test.go index 6ed29c1ae5..7bb5ad7986 100644 --- a/openstack/objectstorage/v1/accounts/testing/requests_test.go +++ b/openstack/objectstorage/v1/accounts/testing/requests_test.go @@ -7,7 +7,7 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/objectstorage/v1/accounts" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) func TestUpdateAccount(t *testing.T) { @@ -21,7 +21,7 @@ func TestUpdateAccount(t *testing.T) { ContentType: new(string), DetectContentType: new(bool), } - res := accounts.Update(context.TODO(), fake.ServiceClient(), options) + res := accounts.Update(context.TODO(), client.ServiceClient(), options) th.AssertNoErr(t, res.Err) expected := &accounts.UpdateHeader{ @@ -38,7 +38,7 @@ func TestGetAccount(t *testing.T) { HandleGetAccountSuccessfully(t) expectedMetadata := map[string]string{"Subject": "books", "Quota-Bytes": "42", "Temp-Url-Key": "testsecret"} - res := accounts.Get(context.TODO(), fake.ServiceClient(), &accounts.GetOpts{}) + res := accounts.Get(context.TODO(), client.ServiceClient(), &accounts.GetOpts{}) th.AssertNoErr(t, res.Err) actualMetadata, _ := res.ExtractMetadata() th.CheckDeepEquals(t, expectedMetadata, actualMetadata) @@ -65,7 +65,7 @@ func TestGetAccountNoQuota(t *testing.T) { HandleGetAccountNoQuotaSuccessfully(t) expectedMetadata := map[string]string{"Subject": "books"} - res := accounts.Get(context.TODO(), fake.ServiceClient(), &accounts.GetOpts{}) + res := accounts.Get(context.TODO(), client.ServiceClient(), &accounts.GetOpts{}) th.AssertNoErr(t, res.Err) actualMetadata, _ := res.ExtractMetadata() th.CheckDeepEquals(t, expectedMetadata, actualMetadata) diff --git a/openstack/objectstorage/v1/containers/testing/fixtures.go b/openstack/objectstorage/v1/containers/testing/fixtures.go index 35c0f734cf..224ea2d8ed 100644 --- a/openstack/objectstorage/v1/containers/testing/fixtures.go +++ b/openstack/objectstorage/v1/containers/testing/fixtures.go @@ -7,7 +7,7 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/objectstorage/v1/containers" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) type handlerOptions struct { @@ -46,7 +46,7 @@ var ExpectedListNames = []string{"janeausten", "marktwain"} func HandleListContainerInfoSuccessfully(t *testing.T) { th.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") w.Header().Set("Content-Type", "application/json") @@ -90,7 +90,7 @@ func HandleListContainerInfoSuccessfully(t *testing.T) { func HandleListZeroContainerNames204(t *testing.T) { th.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") w.WriteHeader(http.StatusNoContent) @@ -102,7 +102,7 @@ func HandleListZeroContainerNames204(t *testing.T) { func HandleCreateContainerSuccessfully(t *testing.T) { th.Mux.HandleFunc("/testContainer", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") w.Header().Add("X-Container-Meta-Foo", "bar") @@ -127,7 +127,7 @@ func HandleDeleteContainerSuccessfully(t *testing.T, options ...option) { th.Mux.HandleFunc(ho.path, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") w.WriteHeader(http.StatusNoContent) }) @@ -148,7 +148,7 @@ const bulkDeleteResponse = ` func HandleBulkDeleteSuccessfully(t *testing.T) { th.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "Content-Type", "text/plain") th.TestFormValues(t, r, map[string]string{ @@ -174,7 +174,7 @@ func HandleUpdateContainerSuccessfully(t *testing.T, options ...option) { th.Mux.HandleFunc(ho.path, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Container-Write", "") th.TestHeader(t, r, "X-Container-Read", "") @@ -197,7 +197,7 @@ func HandleUpdateContainerVersioningOn(t *testing.T, options ...option) { th.Mux.HandleFunc(ho.path, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Container-Write", "") th.TestHeader(t, r, "X-Container-Read", "") @@ -221,7 +221,7 @@ func HandleUpdateContainerVersioningOff(t *testing.T, options ...option) { th.Mux.HandleFunc(ho.path, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Container-Write", "") th.TestHeader(t, r, "X-Container-Read", "") @@ -245,7 +245,7 @@ func HandleGetContainerSuccessfully(t *testing.T, options ...option) { th.Mux.HandleFunc(ho.path, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "HEAD") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") w.Header().Set("Accept-Ranges", "bytes") w.Header().Set("Content-Type", "application/json; charset=utf-8") diff --git a/openstack/objectstorage/v1/containers/testing/requests_test.go b/openstack/objectstorage/v1/containers/testing/requests_test.go index fedf0f2fe6..a286e3f5f7 100644 --- a/openstack/objectstorage/v1/containers/testing/requests_test.go +++ b/openstack/objectstorage/v1/containers/testing/requests_test.go @@ -9,7 +9,7 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/objectstorage/v1/containers" "github.com/gophercloud/gophercloud/v2/pagination" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) func TestContainerNames(t *testing.T) { @@ -35,7 +35,7 @@ func TestContainerNames(t *testing.T) { defer th.TeardownHTTP() HandleCreateContainerSuccessfully(t) - _, err := containers.Create(context.TODO(), fake.ServiceClient(), tc.containerName, nil).Extract() + _, err := containers.Create(context.TODO(), client.ServiceClient(), tc.containerName, nil).Extract() th.CheckErr(t, err, &tc.expectedError) }) t.Run("delete", func(t *testing.T) { @@ -43,7 +43,7 @@ func TestContainerNames(t *testing.T) { defer th.TeardownHTTP() HandleDeleteContainerSuccessfully(t, WithPath("/")) - res := containers.Delete(context.TODO(), fake.ServiceClient(), tc.containerName) + res := containers.Delete(context.TODO(), client.ServiceClient(), tc.containerName) th.CheckErr(t, res.Err, &tc.expectedError) }) t.Run("update", func(t *testing.T) { @@ -60,7 +60,7 @@ func TestContainerNames(t *testing.T) { ContainerSyncKey: new(string), ContentType: &contentType, } - res := containers.Update(context.TODO(), fake.ServiceClient(), tc.containerName, options) + res := containers.Update(context.TODO(), client.ServiceClient(), tc.containerName, options) th.CheckErr(t, res.Err, &tc.expectedError) }) t.Run("get", func(t *testing.T) { @@ -68,7 +68,7 @@ func TestContainerNames(t *testing.T) { defer th.TeardownHTTP() HandleGetContainerSuccessfully(t, WithPath("/")) - res := containers.Get(context.TODO(), fake.ServiceClient(), tc.containerName, nil) + res := containers.Get(context.TODO(), client.ServiceClient(), tc.containerName, nil) _, err := res.ExtractMetadata() th.CheckErr(t, err, &tc.expectedError) @@ -85,7 +85,7 @@ func TestListContainerInfo(t *testing.T) { HandleListContainerInfoSuccessfully(t) count := 0 - err := containers.List(fake.ServiceClient(), &containers.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := containers.List(client.ServiceClient(), &containers.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := containers.ExtractInfo(page) th.AssertNoErr(t, err) @@ -103,7 +103,7 @@ func TestListAllContainerInfo(t *testing.T) { defer th.TeardownHTTP() HandleListContainerInfoSuccessfully(t) - allPages, err := containers.List(fake.ServiceClient(), &containers.ListOpts{}).AllPages(context.TODO()) + allPages, err := containers.List(client.ServiceClient(), &containers.ListOpts{}).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := containers.ExtractInfo(allPages) th.AssertNoErr(t, err) @@ -116,7 +116,7 @@ func TestListContainerNames(t *testing.T) { HandleListContainerInfoSuccessfully(t) count := 0 - err := containers.List(fake.ServiceClient(), &containers.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := containers.List(client.ServiceClient(), &containers.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := containers.ExtractNames(page) if err != nil { @@ -137,7 +137,7 @@ func TestListAllContainerNames(t *testing.T) { defer th.TeardownHTTP() HandleListContainerInfoSuccessfully(t) - allPages, err := containers.List(fake.ServiceClient(), &containers.ListOpts{}).AllPages(context.TODO()) + allPages, err := containers.List(client.ServiceClient(), &containers.ListOpts{}).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := containers.ExtractNames(allPages) th.AssertNoErr(t, err) @@ -149,7 +149,7 @@ func TestListZeroContainerNames(t *testing.T) { defer th.TeardownHTTP() HandleListZeroContainerNames204(t) - allPages, err := containers.List(fake.ServiceClient(), &containers.ListOpts{}).AllPages(context.TODO()) + allPages, err := containers.List(client.ServiceClient(), &containers.ListOpts{}).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := containers.ExtractNames(allPages) th.AssertNoErr(t, err) @@ -162,7 +162,7 @@ func TestCreateContainer(t *testing.T) { HandleCreateContainerSuccessfully(t) options := containers.CreateOpts{ContentType: "application/json", Metadata: map[string]string{"foo": "bar"}} - res := containers.Create(context.TODO(), fake.ServiceClient(), "testContainer", options) + res := containers.Create(context.TODO(), client.ServiceClient(), "testContainer", options) th.CheckEquals(t, "bar", res.Header["X-Container-Meta-Foo"][0]) expected := &containers.CreateHeader{ @@ -181,7 +181,7 @@ func TestDeleteContainer(t *testing.T) { defer th.TeardownHTTP() HandleDeleteContainerSuccessfully(t) - res := containers.Delete(context.TODO(), fake.ServiceClient(), "testContainer") + res := containers.Delete(context.TODO(), client.ServiceClient(), "testContainer") th.AssertNoErr(t, res.Err) } @@ -197,7 +197,7 @@ func TestBulkDelete(t *testing.T) { Errors: [][]string{}, } - resp, err := containers.BulkDelete(context.TODO(), fake.ServiceClient(), []string{"testContainer1", "testContainer2"}).Extract() + resp, err := containers.BulkDelete(context.TODO(), client.ServiceClient(), []string{"testContainer1", "testContainer2"}).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, expected, *resp) } @@ -216,7 +216,7 @@ func TestUpdateContainer(t *testing.T) { ContainerSyncKey: new(string), ContentType: &contentType, } - res := containers.Update(context.TODO(), fake.ServiceClient(), "testContainer", options) + res := containers.Update(context.TODO(), client.ServiceClient(), "testContainer", options) th.AssertNoErr(t, res.Err) } @@ -228,7 +228,7 @@ func TestGetContainer(t *testing.T) { getOpts := containers.GetOpts{ Newest: true, } - res := containers.Get(context.TODO(), fake.ServiceClient(), "testContainer", getOpts) + res := containers.Get(context.TODO(), client.ServiceClient(), "testContainer", getOpts) _, err := res.ExtractMetadata() th.AssertNoErr(t, err) @@ -267,7 +267,7 @@ func TestUpdateContainerVersioningOff(t *testing.T) { ContentType: &contentType, VersionsEnabled: new(bool), } - _, err := containers.Update(context.TODO(), fake.ServiceClient(), "testVersioning", options).Extract() + _, err := containers.Update(context.TODO(), client.ServiceClient(), "testVersioning", options).Extract() th.AssertNoErr(t, err) } @@ -287,6 +287,6 @@ func TestUpdateContainerVersioningOn(t *testing.T) { ContentType: &contentType, VersionsEnabled: &iTrue, } - _, err := containers.Update(context.TODO(), fake.ServiceClient(), "testVersioning", options).Extract() + _, err := containers.Update(context.TODO(), client.ServiceClient(), "testVersioning", options).Extract() th.AssertNoErr(t, err) } diff --git a/openstack/objectstorage/v1/objects/testing/fixtures_test.go b/openstack/objectstorage/v1/objects/testing/fixtures_test.go index f4546d6ab0..c1d23d8cc1 100644 --- a/openstack/objectstorage/v1/objects/testing/fixtures_test.go +++ b/openstack/objectstorage/v1/objects/testing/fixtures_test.go @@ -10,7 +10,7 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/objectstorage/v1/objects" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) type handlerOptions struct { @@ -38,7 +38,7 @@ func HandleDownloadObjectSuccessfully(t *testing.T, options ...option) { th.Mux.HandleFunc(ho.path, func(w http.ResponseWriter, r *http.Request) { date := time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC) th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") w.Header().Set("Date", date.Format(time.RFC1123)) w.Header().Set("X-Static-Large-Object", "True") @@ -108,7 +108,7 @@ func HandleListObjectsInfoSuccessfully(t *testing.T, options ...option) { th.Mux.HandleFunc(ho.path, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") w.Header().Set("Content-Type", "application/json") @@ -147,7 +147,7 @@ func HandleListObjectsInfoSuccessfully(t *testing.T, options ...option) { func HandleListSubdirSuccessfully(t *testing.T) { th.Mux.HandleFunc("/testContainer", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") w.Header().Set("Content-Type", "application/json") @@ -176,7 +176,7 @@ func HandleListSubdirSuccessfully(t *testing.T) { func HandleListZeroObjectNames204(t *testing.T) { th.Mux.HandleFunc("/testContainer", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") w.WriteHeader(http.StatusNoContent) @@ -195,7 +195,7 @@ func HandleCreateTextObjectSuccessfully(t *testing.T, content string, options .. th.Mux.HandleFunc(ho.path, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "text/plain") th.TestHeader(t, r, "Accept", "application/json") th.TestBody(t, r, `Did gyre and gimble in the wabe`) @@ -215,7 +215,7 @@ func HandleCreateTextObjectSuccessfully(t *testing.T, content string, options .. func HandleCreateTextWithCacheControlSuccessfully(t *testing.T, content string) { th.Mux.HandleFunc("/testContainer/testObject", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Cache-Control", `max-age="3600", public`) th.TestHeader(t, r, "Accept", "application/json") th.TestBody(t, r, `All mimsy were the borogoves`) @@ -236,7 +236,7 @@ func HandleCreateTextWithCacheControlSuccessfully(t *testing.T, content string) func HandleCreateTypelessObjectSuccessfully(t *testing.T, content string) { th.Mux.HandleFunc("/testContainer/testObject", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") th.TestBody(t, r, `The sky was the color of television, tuned to a dead channel.`) @@ -259,7 +259,7 @@ func HandleCreateTypelessObjectSuccessfully(t *testing.T, content string) { func HandleCopyObjectSuccessfully(t *testing.T, destination string) { th.Mux.HandleFunc("/testContainer/testObject", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "COPY") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "Destination", destination) w.WriteHeader(http.StatusCreated) @@ -271,7 +271,7 @@ func HandleCopyObjectSuccessfully(t *testing.T, destination string) { func HandleCopyObjectVersionSuccessfully(t *testing.T) { th.Mux.HandleFunc("/testContainer/testObject", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "COPY") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "Destination", "/newTestContainer/newTestObject") th.TestFormValues(t, r, map[string]string{"version-id": "123456788"}) @@ -292,7 +292,7 @@ func HandleDeleteObjectSuccessfully(t *testing.T, options ...option) { th.Mux.HandleFunc(ho.path, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") w.WriteHeader(http.StatusNoContent) }) @@ -313,7 +313,7 @@ const bulkDeleteResponse = ` func HandleBulkDeleteSuccessfully(t *testing.T) { th.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "Content-Type", "text/plain") th.TestFormValues(t, r, map[string]string{ @@ -339,7 +339,7 @@ func HandleUpdateObjectSuccessfully(t *testing.T, options ...option) { th.Mux.HandleFunc(ho.path, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Object-Meta-Gophercloud-Test", "objects") th.TestHeader(t, r, "X-Remove-Object-Meta-Gophercloud-Test-Remove", "remove") @@ -365,7 +365,7 @@ func HandleGetObjectSuccessfully(t *testing.T, options ...option) { th.Mux.HandleFunc(ho.path, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "HEAD") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") w.Header().Add("X-Object-Meta-Gophercloud-Test", "objects") w.Header().Add("X-Static-Large-Object", "true") diff --git a/openstack/objectstorage/v1/objects/testing/requests_test.go b/openstack/objectstorage/v1/objects/testing/requests_test.go index 60747a2efc..a6399f6a53 100644 --- a/openstack/objectstorage/v1/objects/testing/requests_test.go +++ b/openstack/objectstorage/v1/objects/testing/requests_test.go @@ -17,7 +17,7 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/objectstorage/v1/objects" "github.com/gophercloud/gophercloud/v2/pagination" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) func TestContainerNames(t *testing.T) { @@ -43,7 +43,7 @@ func TestContainerNames(t *testing.T) { defer th.TeardownHTTP() HandleListObjectsInfoSuccessfully(t, WithPath("/")) - _, err := objects.List(fake.ServiceClient(), tc.containerName, nil).AllPages(context.TODO()) + _, err := objects.List(client.ServiceClient(), tc.containerName, nil).AllPages(context.TODO()) th.CheckErr(t, err, &tc.expectedError) }) t.Run("download", func(t *testing.T) { @@ -51,7 +51,7 @@ func TestContainerNames(t *testing.T) { defer th.TeardownHTTP() HandleDownloadObjectSuccessfully(t, WithPath("/")) - _, err := objects.Download(context.TODO(), fake.ServiceClient(), tc.containerName, "testObject", nil).Extract() + _, err := objects.Download(context.TODO(), client.ServiceClient(), tc.containerName, "testObject", nil).Extract() th.CheckErr(t, err, &tc.expectedError) }) t.Run("create", func(t *testing.T) { @@ -60,7 +60,7 @@ func TestContainerNames(t *testing.T) { content := "Ceci n'est pas une pipe" HandleCreateTextObjectSuccessfully(t, content, WithPath("/")) - res := objects.Create(context.TODO(), fake.ServiceClient(), tc.containerName, "testObject", &objects.CreateOpts{ + res := objects.Create(context.TODO(), client.ServiceClient(), tc.containerName, "testObject", &objects.CreateOpts{ ContentType: "text/plain", Content: strings.NewReader(content), }) @@ -71,7 +71,7 @@ func TestContainerNames(t *testing.T) { defer th.TeardownHTTP() HandleDeleteObjectSuccessfully(t, WithPath("/")) - res := objects.Delete(context.TODO(), fake.ServiceClient(), tc.containerName, "testObject", nil) + res := objects.Delete(context.TODO(), client.ServiceClient(), tc.containerName, "testObject", nil) th.CheckErr(t, res.Err, &tc.expectedError) }) t.Run("get", func(t *testing.T) { @@ -79,7 +79,7 @@ func TestContainerNames(t *testing.T) { defer th.TeardownHTTP() HandleGetObjectSuccessfully(t, WithPath("/")) - _, err := objects.Get(context.TODO(), fake.ServiceClient(), tc.containerName, "testObject", nil).ExtractMetadata() + _, err := objects.Get(context.TODO(), client.ServiceClient(), tc.containerName, "testObject", nil).ExtractMetadata() th.CheckErr(t, err, &tc.expectedError) }) t.Run("update", func(t *testing.T) { @@ -87,7 +87,7 @@ func TestContainerNames(t *testing.T) { defer th.TeardownHTTP() HandleUpdateObjectSuccessfully(t) - res := objects.Update(context.TODO(), fake.ServiceClient(), tc.containerName, "testObject", &objects.UpdateOpts{ + res := objects.Update(context.TODO(), client.ServiceClient(), tc.containerName, "testObject", &objects.UpdateOpts{ Metadata: map[string]string{"Gophercloud-Test": "objects"}, }) th.CheckErr(t, res.Err, &tc.expectedError) @@ -101,7 +101,7 @@ func TestContainerNames(t *testing.T) { // Handle fetching of secret key inside of CreateTempURL containerTesting.HandleGetContainerSuccessfully(t) accountTesting.HandleGetAccountSuccessfully(t) - client := fake.ServiceClient() + client := client.ServiceClient() // Append v1/ to client endpoint URL to be compliant with tempURL generator client.Endpoint = client.Endpoint + "v1/" @@ -118,7 +118,7 @@ func TestContainerNames(t *testing.T) { defer th.TeardownHTTP() HandleBulkDeleteSuccessfully(t) - res := objects.BulkDelete(context.TODO(), fake.ServiceClient(), tc.containerName, []string{"testObject"}) + res := objects.BulkDelete(context.TODO(), client.ServiceClient(), tc.containerName, []string{"testObject"}) th.CheckErr(t, res.Err, &tc.expectedError) }) }) @@ -130,7 +130,7 @@ func TestDownloadReader(t *testing.T) { defer th.TeardownHTTP() HandleDownloadObjectSuccessfully(t) - response := objects.Download(context.TODO(), fake.ServiceClient(), "testContainer", "testObject", nil) + response := objects.Download(context.TODO(), client.ServiceClient(), "testContainer", "testObject", nil) defer response.Body.Close() // Check reader @@ -145,7 +145,7 @@ func TestDownloadExtraction(t *testing.T) { defer th.TeardownHTTP() HandleDownloadObjectSuccessfully(t) - response := objects.Download(context.TODO(), fake.ServiceClient(), "testContainer", "testObject", nil) + response := objects.Download(context.TODO(), client.ServiceClient(), "testContainer", "testObject", nil) // Check []byte extraction bytes, err := response.ExtractContent() @@ -172,14 +172,14 @@ func TestDownloadWithLastModified(t *testing.T) { options1 := &objects.DownloadOpts{ IfUnmodifiedSince: time.Date(2009, time.November, 10, 22, 59, 59, 0, time.UTC), } - response1 := objects.Download(context.TODO(), fake.ServiceClient(), "testContainer", "testObject", options1) + response1 := objects.Download(context.TODO(), client.ServiceClient(), "testContainer", "testObject", options1) _, err1 := response1.Extract() th.AssertErr(t, err1) options2 := &objects.DownloadOpts{ IfModifiedSince: time.Date(2009, time.November, 10, 23, 0, 1, 0, time.UTC), } - response2 := objects.Download(context.TODO(), fake.ServiceClient(), "testContainer", "testObject", options2) + response2 := objects.Download(context.TODO(), client.ServiceClient(), "testContainer", "testObject", options2) content, err2 := response2.ExtractContent() th.AssertNoErr(t, err2) th.AssertEquals(t, 0, len(content)) @@ -192,7 +192,7 @@ func TestListObjectInfo(t *testing.T) { count := 0 options := &objects.ListOpts{} - err := objects.List(fake.ServiceClient(), "testContainer", options).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := objects.List(client.ServiceClient(), "testContainer", options).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := objects.ExtractInfo(page) th.AssertNoErr(t, err) @@ -212,7 +212,7 @@ func TestListObjectSubdir(t *testing.T) { count := 0 options := &objects.ListOpts{Prefix: "", Delimiter: "/"} - err := objects.List(fake.ServiceClient(), "testContainer", options).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := objects.List(client.ServiceClient(), "testContainer", options).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := objects.ExtractInfo(page) th.AssertNoErr(t, err) @@ -233,7 +233,7 @@ func TestListObjectNames(t *testing.T) { // Check without delimiter. count := 0 options := &objects.ListOpts{} - err := objects.List(fake.ServiceClient(), "testContainer", options).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := objects.List(client.ServiceClient(), "testContainer", options).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := objects.ExtractNames(page) if err != nil { @@ -251,7 +251,7 @@ func TestListObjectNames(t *testing.T) { // Check with delimiter. count = 0 options = &objects.ListOpts{Delimiter: "/"} - err = objects.List(fake.ServiceClient(), "testContainer", options).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err = objects.List(client.ServiceClient(), "testContainer", options).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := objects.ExtractNames(page) if err != nil { @@ -274,7 +274,7 @@ func TestListZeroObjectNames204(t *testing.T) { count := 0 options := &objects.ListOpts{} - err := objects.List(fake.ServiceClient(), "testContainer", options).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := objects.List(client.ServiceClient(), "testContainer", options).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := objects.ExtractNames(page) if err != nil { @@ -299,7 +299,7 @@ func TestCreateObject(t *testing.T) { HandleCreateTextObjectSuccessfully(t, content) options := &objects.CreateOpts{ContentType: "text/plain", Content: strings.NewReader(content)} - res := objects.Create(context.TODO(), fake.ServiceClient(), "testContainer", "testObject", options) + res := objects.Create(context.TODO(), client.ServiceClient(), "testContainer", "testObject", options) th.AssertNoErr(t, res.Err) } @@ -315,7 +315,7 @@ func TestCreateObjectWithCacheControl(t *testing.T) { CacheControl: `max-age="3600", public`, Content: strings.NewReader(content), } - res := objects.Create(context.TODO(), fake.ServiceClient(), "testContainer", "testObject", options) + res := objects.Create(context.TODO(), client.ServiceClient(), "testContainer", "testObject", options) th.AssertNoErr(t, res.Err) } @@ -327,7 +327,7 @@ func TestCreateObjectWithoutContentType(t *testing.T) { HandleCreateTypelessObjectSuccessfully(t, content) - res := objects.Create(context.TODO(), fake.ServiceClient(), "testContainer", "testObject", &objects.CreateOpts{Content: strings.NewReader(content)}) + res := objects.Create(context.TODO(), client.ServiceClient(), "testContainer", "testObject", &objects.CreateOpts{Content: strings.NewReader(content)}) th.AssertNoErr(t, res.Err) } @@ -338,7 +338,7 @@ func TestCopyObject(t *testing.T) { HandleCopyObjectSuccessfully(t, "/newTestContainer/newTestObject") options := &objects.CopyOpts{Destination: "/newTestContainer/newTestObject"} - res := objects.Copy(context.TODO(), fake.ServiceClient(), "testContainer", "testObject", options) + res := objects.Copy(context.TODO(), client.ServiceClient(), "testContainer", "testObject", options) th.AssertNoErr(t, res.Err) }) t.Run("slash", func(t *testing.T) { @@ -347,7 +347,7 @@ func TestCopyObject(t *testing.T) { HandleCopyObjectSuccessfully(t, "/newTestContainer/path%2Fto%2FnewTestObject") options := &objects.CopyOpts{Destination: "/newTestContainer/path/to/newTestObject"} - res := objects.Copy(context.TODO(), fake.ServiceClient(), "testContainer", "testObject", options) + res := objects.Copy(context.TODO(), client.ServiceClient(), "testContainer", "testObject", options) th.AssertNoErr(t, res.Err) }) t.Run("emojis", func(t *testing.T) { @@ -356,7 +356,7 @@ func TestCopyObject(t *testing.T) { HandleCopyObjectSuccessfully(t, "/newTestContainer/new%F0%9F%98%8ATest%2C%3B%22O%28bject%21_%E7%AF%84") options := &objects.CopyOpts{Destination: "/newTestContainer/new😊Test,;\"O(bject!_範"} - res := objects.Copy(context.TODO(), fake.ServiceClient(), "testContainer", "testObject", options) + res := objects.Copy(context.TODO(), client.ServiceClient(), "testContainer", "testObject", options) th.AssertNoErr(t, res.Err) }) } @@ -367,7 +367,7 @@ func TestCopyObjectVersion(t *testing.T) { HandleCopyObjectVersionSuccessfully(t) options := &objects.CopyOpts{Destination: "/newTestContainer/newTestObject", ObjectVersionID: "123456788"} - res, err := objects.Copy(context.TODO(), fake.ServiceClient(), "testContainer", "testObject", options).Extract() + res, err := objects.Copy(context.TODO(), client.ServiceClient(), "testContainer", "testObject", options).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, "123456789", res.ObjectVersionID) } @@ -377,7 +377,7 @@ func TestDeleteObject(t *testing.T) { defer th.TeardownHTTP() HandleDeleteObjectSuccessfully(t) - res := objects.Delete(context.TODO(), fake.ServiceClient(), "testContainer", "testObject", nil) + res := objects.Delete(context.TODO(), client.ServiceClient(), "testContainer", "testObject", nil) th.AssertNoErr(t, res.Err) } @@ -393,7 +393,7 @@ func TestBulkDelete(t *testing.T) { Errors: [][]string{}, } - resp, err := objects.BulkDelete(context.TODO(), fake.ServiceClient(), "testContainer", []string{"testObject1", "testObject2"}).Extract() + resp, err := objects.BulkDelete(context.TODO(), client.ServiceClient(), "testContainer", []string{"testObject1", "testObject2"}).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, expected, *resp) } @@ -414,7 +414,7 @@ func TestUpateObjectMetadata(t *testing.T) { DeleteAt: i, DetectContentType: new(bool), } - res := objects.Update(context.TODO(), fake.ServiceClient(), "testContainer", "testObject", options) + res := objects.Update(context.TODO(), client.ServiceClient(), "testContainer", "testObject", options) th.AssertNoErr(t, res.Err) } @@ -424,14 +424,14 @@ func TestGetObject(t *testing.T) { HandleGetObjectSuccessfully(t) expected := map[string]string{"Gophercloud-Test": "objects"} - actual, err := objects.Get(context.TODO(), fake.ServiceClient(), "testContainer", "testObject", nil).ExtractMetadata() + actual, err := objects.Get(context.TODO(), client.ServiceClient(), "testContainer", "testObject", nil).ExtractMetadata() th.AssertNoErr(t, err) th.CheckDeepEquals(t, expected, actual) getOpts := objects.GetOpts{ Newest: true, } - actualHeaders, err := objects.Get(context.TODO(), fake.ServiceClient(), "testContainer", "testObject", getOpts).Extract() + actualHeaders, err := objects.Get(context.TODO(), client.ServiceClient(), "testContainer", "testObject", getOpts).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, true, actualHeaders.StaticLargeObject) } @@ -512,7 +512,7 @@ func TestCreateTempURL(t *testing.T) { // Handle fetching of secret key inside of CreateTempURL containerTesting.HandleGetContainerSuccessfully(t) accountTesting.HandleGetAccountSuccessfully(t) - client := fake.ServiceClient() + client := client.ServiceClient() // Append v1/ to client endpoint URL to be compliant with tempURL generator client.Endpoint = client.Endpoint + "v1/" diff --git a/openstack/orchestration/v1/apiversions/testing/requests_test.go b/openstack/orchestration/v1/apiversions/testing/requests_test.go index d7149f1cbd..9edae2d541 100644 --- a/openstack/orchestration/v1/apiversions/testing/requests_test.go +++ b/openstack/orchestration/v1/apiversions/testing/requests_test.go @@ -10,7 +10,7 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/orchestration/v1/apiversions" "github.com/gophercloud/gophercloud/v2/pagination" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) func TestListVersions(t *testing.T) { @@ -19,7 +19,7 @@ func TestListVersions(t *testing.T) { th.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -43,7 +43,7 @@ func TestListVersions(t *testing.T) { count := 0 - err := apiversions.ListVersions(fake.ServiceClient()).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := apiversions.ListVersions(client.ServiceClient()).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := apiversions.ExtractAPIVersions(page) if err != nil { @@ -83,7 +83,7 @@ func TestNonJSONCannotBeExtractedIntoAPIVersions(t *testing.T) { w.WriteHeader(http.StatusOK) }) - err := apiversions.ListVersions(fake.ServiceClient()).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := apiversions.ListVersions(client.ServiceClient()).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { if _, err := apiversions.ExtractAPIVersions(page); err == nil { t.Fatalf("Expected error, got nil") } diff --git a/openstack/orchestration/v1/buildinfo/testing/fixtures_test.go b/openstack/orchestration/v1/buildinfo/testing/fixtures_test.go index 74a91e4df3..f05c9898ba 100644 --- a/openstack/orchestration/v1/buildinfo/testing/fixtures_test.go +++ b/openstack/orchestration/v1/buildinfo/testing/fixtures_test.go @@ -7,7 +7,7 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/orchestration/v1/buildinfo" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) // GetExpected represents the expected object from a Get request. @@ -36,7 +36,7 @@ const GetOutput = ` func HandleGetSuccessfully(t *testing.T, output string) { th.Mux.HandleFunc("/build_info", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") w.Header().Set("Content-Type", "application/json") diff --git a/openstack/orchestration/v1/buildinfo/testing/requests_test.go b/openstack/orchestration/v1/buildinfo/testing/requests_test.go index 5177e7d409..241b6dde7d 100644 --- a/openstack/orchestration/v1/buildinfo/testing/requests_test.go +++ b/openstack/orchestration/v1/buildinfo/testing/requests_test.go @@ -6,7 +6,7 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/orchestration/v1/buildinfo" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) func TestGetTemplate(t *testing.T) { @@ -14,7 +14,7 @@ func TestGetTemplate(t *testing.T) { defer th.TeardownHTTP() HandleGetSuccessfully(t, GetOutput) - actual, err := buildinfo.Get(context.TODO(), fake.ServiceClient()).Extract() + actual, err := buildinfo.Get(context.TODO(), client.ServiceClient()).Extract() th.AssertNoErr(t, err) expected := GetExpected diff --git a/openstack/orchestration/v1/resourcetypes/testing/fixtures_test.go b/openstack/orchestration/v1/resourcetypes/testing/fixtures_test.go index 37a91b0901..3c170b1984 100644 --- a/openstack/orchestration/v1/resourcetypes/testing/fixtures_test.go +++ b/openstack/orchestration/v1/resourcetypes/testing/fixtures_test.go @@ -7,7 +7,7 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/orchestration/v1/resourcetypes" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) const BasicListOutput = ` @@ -79,7 +79,7 @@ func HandleListSuccessfully(t *testing.T) { th.Mux.HandleFunc("/resource_types", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") w.Header().Set("Content-Type", "application/json") @@ -328,7 +328,7 @@ func HandleGetSchemaSuccessfully(t *testing.T) { th.Mux.HandleFunc("/resource_types/OS::Test::TestServer", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") w.Header().Set("Content-Type", "application/json") @@ -374,7 +374,7 @@ func HandleGenerateTemplateSuccessfully(t *testing.T) { th.Mux.HandleFunc("/resource_types/OS::Heat::None/template", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") w.Header().Set("Content-Type", "application/json") diff --git a/openstack/orchestration/v1/resourcetypes/testing/requests_test.go b/openstack/orchestration/v1/resourcetypes/testing/requests_test.go index b426d55f6a..ccccdf87e0 100644 --- a/openstack/orchestration/v1/resourcetypes/testing/requests_test.go +++ b/openstack/orchestration/v1/resourcetypes/testing/requests_test.go @@ -6,7 +6,7 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/orchestration/v1/resourcetypes" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) func TestBasicListResourceTypes(t *testing.T) { @@ -14,7 +14,7 @@ func TestBasicListResourceTypes(t *testing.T) { defer th.TeardownHTTP() HandleListSuccessfully(t) - result := resourcetypes.List(context.TODO(), fake.ServiceClient(), nil) + result := resourcetypes.List(context.TODO(), client.ServiceClient(), nil) th.AssertNoErr(t, result.Err) actual, err := result.Extract() @@ -28,7 +28,7 @@ func TestFullListResourceTypes(t *testing.T) { defer th.TeardownHTTP() HandleListSuccessfully(t) - result := resourcetypes.List(context.TODO(), fake.ServiceClient(), resourcetypes.ListOpts{ + result := resourcetypes.List(context.TODO(), client.ServiceClient(), resourcetypes.ListOpts{ WithDescription: true, }) th.AssertNoErr(t, result.Err) @@ -44,7 +44,7 @@ func TestFilteredListResourceTypes(t *testing.T) { defer th.TeardownHTTP() HandleListSuccessfully(t) - result := resourcetypes.List(context.TODO(), fake.ServiceClient(), resourcetypes.ListOpts{ + result := resourcetypes.List(context.TODO(), client.ServiceClient(), resourcetypes.ListOpts{ NameRegex: listFilterRegex, WithDescription: true, }) @@ -61,7 +61,7 @@ func TestGetSchema(t *testing.T) { defer th.TeardownHTTP() HandleGetSchemaSuccessfully(t) - result := resourcetypes.GetSchema(context.TODO(), fake.ServiceClient(), "OS::Test::TestServer") + result := resourcetypes.GetSchema(context.TODO(), client.ServiceClient(), "OS::Test::TestServer") th.AssertNoErr(t, result.Err) actual, err := result.Extract() @@ -75,7 +75,7 @@ func TestGenerateTemplate(t *testing.T) { defer th.TeardownHTTP() HandleGenerateTemplateSuccessfully(t) - result := resourcetypes.GenerateTemplate(context.TODO(), fake.ServiceClient(), "OS::Heat::None", nil) + result := resourcetypes.GenerateTemplate(context.TODO(), client.ServiceClient(), "OS::Heat::None", nil) th.AssertNoErr(t, result.Err) actual, err := result.Extract() diff --git a/openstack/orchestration/v1/stackevents/testing/fixtures_test.go b/openstack/orchestration/v1/stackevents/testing/fixtures_test.go index a0e31b4ba5..0f45487d14 100644 --- a/openstack/orchestration/v1/stackevents/testing/fixtures_test.go +++ b/openstack/orchestration/v1/stackevents/testing/fixtures_test.go @@ -9,7 +9,7 @@ import ( "github.com/gophercloud/gophercloud/v2" "github.com/gophercloud/gophercloud/v2/openstack/orchestration/v1/stackevents" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) var Timestamp1, _ = time.Parse(time.RFC3339, "2018-06-26T07:58:17Z") @@ -123,7 +123,7 @@ const FindOutput = ` func HandleFindSuccessfully(t *testing.T, output string) { th.Mux.HandleFunc("/stacks/postman_stack/events", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") w.Header().Set("Content-Type", "application/json") @@ -240,7 +240,7 @@ const ListOutput = ` func HandleListSuccessfully(t *testing.T, output string) { th.Mux.HandleFunc("/stacks/hello_world/49181cd6-169a-4130-9455-31185bbfc5bf/events", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") w.Header().Set("Content-Type", "application/json") @@ -367,7 +367,7 @@ const ListResourceEventsOutput = ` func HandleListResourceEventsSuccessfully(t *testing.T, output string) { th.Mux.HandleFunc("/stacks/hello_world/49181cd6-169a-4130-9455-31185bbfc5bf/resources/my_resource/events", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") w.Header().Set("Content-Type", "application/json") @@ -444,7 +444,7 @@ const GetOutput = ` func HandleGetSuccessfully(t *testing.T, output string) { th.Mux.HandleFunc("/stacks/hello_world/49181cd6-169a-4130-9455-31185bbfc5bf/resources/my_resource/events/93940999-7d40-44ae-8de4-19624e7b8d18", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") w.Header().Set("Content-Type", "application/json") diff --git a/openstack/orchestration/v1/stackevents/testing/requests_test.go b/openstack/orchestration/v1/stackevents/testing/requests_test.go index bed2d8a2bf..17471c9b49 100644 --- a/openstack/orchestration/v1/stackevents/testing/requests_test.go +++ b/openstack/orchestration/v1/stackevents/testing/requests_test.go @@ -7,7 +7,7 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/orchestration/v1/stackevents" "github.com/gophercloud/gophercloud/v2/pagination" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) func TestFindEvents(t *testing.T) { @@ -15,7 +15,7 @@ func TestFindEvents(t *testing.T) { defer th.TeardownHTTP() HandleFindSuccessfully(t, FindOutput) - actual, err := stackevents.Find(context.TODO(), fake.ServiceClient(), "postman_stack").Extract() + actual, err := stackevents.Find(context.TODO(), client.ServiceClient(), "postman_stack").Extract() th.AssertNoErr(t, err) expected := FindExpected @@ -28,7 +28,7 @@ func TestList(t *testing.T) { HandleListSuccessfully(t, ListOutput) count := 0 - err := stackevents.List(fake.ServiceClient(), "hello_world", "49181cd6-169a-4130-9455-31185bbfc5bf", nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := stackevents.List(client.ServiceClient(), "hello_world", "49181cd6-169a-4130-9455-31185bbfc5bf", nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := stackevents.ExtractEvents(page) th.AssertNoErr(t, err) @@ -47,7 +47,7 @@ func TestListResourceEvents(t *testing.T) { HandleListResourceEventsSuccessfully(t, ListResourceEventsOutput) count := 0 - err := stackevents.ListResourceEvents(fake.ServiceClient(), "hello_world", "49181cd6-169a-4130-9455-31185bbfc5bf", "my_resource", nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := stackevents.ListResourceEvents(client.ServiceClient(), "hello_world", "49181cd6-169a-4130-9455-31185bbfc5bf", "my_resource", nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := stackevents.ExtractResourceEvents(page) th.AssertNoErr(t, err) @@ -65,7 +65,7 @@ func TestGetEvent(t *testing.T) { defer th.TeardownHTTP() HandleGetSuccessfully(t, GetOutput) - actual, err := stackevents.Get(context.TODO(), fake.ServiceClient(), "hello_world", "49181cd6-169a-4130-9455-31185bbfc5bf", "my_resource", "93940999-7d40-44ae-8de4-19624e7b8d18").Extract() + actual, err := stackevents.Get(context.TODO(), client.ServiceClient(), "hello_world", "49181cd6-169a-4130-9455-31185bbfc5bf", "my_resource", "93940999-7d40-44ae-8de4-19624e7b8d18").Extract() th.AssertNoErr(t, err) expected := GetExpected diff --git a/openstack/orchestration/v1/stackresources/testing/fixtures_test.go b/openstack/orchestration/v1/stackresources/testing/fixtures_test.go index fa1e66575e..55edb88bc0 100644 --- a/openstack/orchestration/v1/stackresources/testing/fixtures_test.go +++ b/openstack/orchestration/v1/stackresources/testing/fixtures_test.go @@ -9,7 +9,7 @@ import ( "github.com/gophercloud/gophercloud/v2" "github.com/gophercloud/gophercloud/v2/openstack/orchestration/v1/stackresources" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) var Create_time, _ = time.Parse(time.RFC3339, "2018-06-26T07:57:17Z") @@ -77,7 +77,7 @@ const FindOutput = ` func HandleFindSuccessfully(t *testing.T, output string) { th.Mux.HandleFunc("/stacks/hello_world/resources", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") w.Header().Set("Content-Type", "application/json") @@ -147,7 +147,7 @@ const ListOutput = `{ func HandleListSuccessfully(t *testing.T, output string) { th.Mux.HandleFunc("/stacks/hello_world/49181cd6-169a-4130-9455-31185bbfc5bf/resources", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") w.Header().Set("Content-Type", "application/json") @@ -222,7 +222,7 @@ const GetOutput = ` func HandleGetSuccessfully(t *testing.T, output string) { th.Mux.HandleFunc("/stacks/teststack/0b1771bd-9336-4f2b-ae86-a80f971faf1e/resources/wordpress_instance", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") w.Header().Set("Content-Type", "application/json") @@ -251,7 +251,7 @@ const MetadataOutput = ` func HandleMetadataSuccessfully(t *testing.T, output string) { th.Mux.HandleFunc("/stacks/teststack/0b1771bd-9336-4f2b-ae86-a80f971faf1e/resources/wordpress_instance/metadata", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") w.Header().Set("Content-Type", "application/json") @@ -304,7 +304,7 @@ const ListTypesOutput = ` func HandleListTypesSuccessfully(t *testing.T, output string) { th.Mux.HandleFunc("/resource_types", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") w.Header().Set("Content-Type", "application/json") @@ -365,7 +365,7 @@ const GetSchemaOutput = ` func HandleGetSchemaSuccessfully(t *testing.T, output string) { th.Mux.HandleFunc("/resource_types/OS::Heat::AResourceName", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") w.Header().Set("Content-Type", "application/json") @@ -435,7 +435,7 @@ const GetTemplateOutput = ` func HandleGetTemplateSuccessfully(t *testing.T, output string) { th.Mux.HandleFunc("/resource_types/OS::Heat::AResourceName/template", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") w.Header().Set("Content-Type", "application/json") @@ -449,7 +449,7 @@ func HandleGetTemplateSuccessfully(t *testing.T, output string) { func HandleMarkUnhealthySuccessfully(t *testing.T) { th.Mux.HandleFunc("/stacks/teststack/0b1771bd-9336-4f2b-ae86-a80f971faf1e/resources/wordpress_instance", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PATCH") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") w.Header().Set("Content-Type", "application/json") diff --git a/openstack/orchestration/v1/stackresources/testing/requests_test.go b/openstack/orchestration/v1/stackresources/testing/requests_test.go index 358b30621b..e3f6e1510b 100644 --- a/openstack/orchestration/v1/stackresources/testing/requests_test.go +++ b/openstack/orchestration/v1/stackresources/testing/requests_test.go @@ -8,7 +8,7 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/orchestration/v1/stackresources" "github.com/gophercloud/gophercloud/v2/pagination" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) func TestFindResources(t *testing.T) { @@ -16,7 +16,7 @@ func TestFindResources(t *testing.T) { defer th.TeardownHTTP() HandleFindSuccessfully(t, FindOutput) - actual, err := stackresources.Find(context.TODO(), fake.ServiceClient(), "hello_world").Extract() + actual, err := stackresources.Find(context.TODO(), client.ServiceClient(), "hello_world").Extract() th.AssertNoErr(t, err) expected := FindExpected @@ -29,7 +29,7 @@ func TestListResources(t *testing.T) { HandleListSuccessfully(t, ListOutput) count := 0 - err := stackresources.List(fake.ServiceClient(), "hello_world", "49181cd6-169a-4130-9455-31185bbfc5bf", nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := stackresources.List(client.ServiceClient(), "hello_world", "49181cd6-169a-4130-9455-31185bbfc5bf", nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := stackresources.ExtractResources(page) th.AssertNoErr(t, err) @@ -47,7 +47,7 @@ func TestGetResource(t *testing.T) { defer th.TeardownHTTP() HandleGetSuccessfully(t, GetOutput) - actual, err := stackresources.Get(context.TODO(), fake.ServiceClient(), "teststack", "0b1771bd-9336-4f2b-ae86-a80f971faf1e", "wordpress_instance").Extract() + actual, err := stackresources.Get(context.TODO(), client.ServiceClient(), "teststack", "0b1771bd-9336-4f2b-ae86-a80f971faf1e", "wordpress_instance").Extract() th.AssertNoErr(t, err) expected := GetExpected @@ -59,7 +59,7 @@ func TestResourceMetadata(t *testing.T) { defer th.TeardownHTTP() HandleMetadataSuccessfully(t, MetadataOutput) - actual, err := stackresources.Metadata(context.TODO(), fake.ServiceClient(), "teststack", "0b1771bd-9336-4f2b-ae86-a80f971faf1e", "wordpress_instance").Extract() + actual, err := stackresources.Metadata(context.TODO(), client.ServiceClient(), "teststack", "0b1771bd-9336-4f2b-ae86-a80f971faf1e", "wordpress_instance").Extract() th.AssertNoErr(t, err) expected := MetadataExpected @@ -72,7 +72,7 @@ func TestListResourceTypes(t *testing.T) { HandleListTypesSuccessfully(t, ListTypesOutput) count := 0 - err := stackresources.ListTypes(fake.ServiceClient()).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := stackresources.ListTypes(client.ServiceClient()).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := stackresources.ExtractResourceTypes(page) th.AssertNoErr(t, err) @@ -93,7 +93,7 @@ func TestGetResourceSchema(t *testing.T) { defer th.TeardownHTTP() HandleGetSchemaSuccessfully(t, GetSchemaOutput) - actual, err := stackresources.Schema(context.TODO(), fake.ServiceClient(), "OS::Heat::AResourceName").Extract() + actual, err := stackresources.Schema(context.TODO(), client.ServiceClient(), "OS::Heat::AResourceName").Extract() th.AssertNoErr(t, err) expected := GetSchemaExpected @@ -105,7 +105,7 @@ func TestGetResourceTemplate(t *testing.T) { defer th.TeardownHTTP() HandleGetTemplateSuccessfully(t, GetTemplateOutput) - actual, err := stackresources.Template(context.TODO(), fake.ServiceClient(), "OS::Heat::AResourceName").Extract() + actual, err := stackresources.Template(context.TODO(), client.ServiceClient(), "OS::Heat::AResourceName").Extract() th.AssertNoErr(t, err) expected := GetTemplateExpected @@ -121,6 +121,6 @@ func TestMarkUnhealthyResource(t *testing.T) { MarkUnhealthy: true, ResourceStatusReason: "Kubelet.Ready is Unknown more than 10 mins.", } - err := stackresources.MarkUnhealthy(context.TODO(), fake.ServiceClient(), "teststack", "0b1771bd-9336-4f2b-ae86-a80f971faf1e", "wordpress_instance", markUnhealthyOpts).ExtractErr() + err := stackresources.MarkUnhealthy(context.TODO(), client.ServiceClient(), "teststack", "0b1771bd-9336-4f2b-ae86-a80f971faf1e", "wordpress_instance", markUnhealthyOpts).ExtractErr() th.AssertNoErr(t, err) } diff --git a/openstack/orchestration/v1/stacks/testing/fixtures_test.go b/openstack/orchestration/v1/stacks/testing/fixtures_test.go index 9baed3aced..bdb773e54b 100644 --- a/openstack/orchestration/v1/stacks/testing/fixtures_test.go +++ b/openstack/orchestration/v1/stacks/testing/fixtures_test.go @@ -9,7 +9,7 @@ import ( "github.com/gophercloud/gophercloud/v2" "github.com/gophercloud/gophercloud/v2/openstack/orchestration/v1/stacks" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) var Create_time, _ = time.Parse(time.RFC3339, "2018-06-26T07:58:17Z") @@ -45,7 +45,7 @@ const CreateOutput = ` func HandleCreateSuccessfully(t *testing.T, output string) { th.Mux.HandleFunc("/stacks", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") w.WriteHeader(http.StatusCreated) fmt.Fprint(w, output) @@ -132,7 +132,7 @@ const FullListOutput = ` func HandleListSuccessfully(t *testing.T, output string) { th.Mux.HandleFunc("/stacks", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") w.Header().Set("Content-Type", "application/json") @@ -216,7 +216,7 @@ const GetOutput = ` func HandleGetSuccessfully(t *testing.T, output string) { th.Mux.HandleFunc("/stacks/postman_stack/16ef0584-4458-41eb-87c8-0dc8d5f66c87", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") w.Header().Set("Content-Type", "application/json") @@ -228,7 +228,7 @@ func HandleGetSuccessfully(t *testing.T, output string) { func HandleFindSuccessfully(t *testing.T, output string) { th.Mux.HandleFunc("/stacks/16ef0584-4458-41eb-87c8-0dc8d5f66c87", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") w.Header().Set("Content-Type", "application/json") @@ -242,7 +242,7 @@ func HandleFindSuccessfully(t *testing.T, output string) { func HandleUpdateSuccessfully(t *testing.T) { th.Mux.HandleFunc("/stacks/gophercloud-test-stack-2/db6977b2-27aa-4775-9ae7-6213212d4ada", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") w.Header().Set("Content-Type", "application/json") @@ -255,7 +255,7 @@ func HandleUpdateSuccessfully(t *testing.T) { func HandleUpdatePatchSuccessfully(t *testing.T) { th.Mux.HandleFunc("/stacks/gophercloud-test-stack-2/db6977b2-27aa-4775-9ae7-6213212d4ada", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PATCH") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") w.Header().Set("Content-Type", "application/json") @@ -268,7 +268,7 @@ func HandleUpdatePatchSuccessfully(t *testing.T) { func HandleDeleteSuccessfully(t *testing.T) { th.Mux.HandleFunc("/stacks/gophercloud-test-stack-2/db6977b2-27aa-4775-9ae7-6213212d4ada", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") w.Header().Set("Content-Type", "application/json") @@ -304,7 +304,7 @@ var PreviewExpected = &stacks.PreviewedStack{ func HandlePreviewSuccessfully(t *testing.T, output string) { th.Mux.HandleFunc("/stacks/preview", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") w.Header().Set("Content-Type", "application/json") @@ -427,7 +427,7 @@ const AbandonOutput = ` func HandleAbandonSuccessfully(t *testing.T, output string) { th.Mux.HandleFunc("/stacks/postman_stack/16ef0584-4458-41eb-87c8-0dc8d5f66c8/abandon", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") w.Header().Set("Content-Type", "application/json") diff --git a/openstack/orchestration/v1/stacks/testing/requests_test.go b/openstack/orchestration/v1/stacks/testing/requests_test.go index 224893f5d0..e7b6de1595 100644 --- a/openstack/orchestration/v1/stacks/testing/requests_test.go +++ b/openstack/orchestration/v1/stacks/testing/requests_test.go @@ -8,7 +8,7 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/orchestration/v1/stacks" "github.com/gophercloud/gophercloud/v2/pagination" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) func TestCreateStack(t *testing.T) { @@ -33,7 +33,7 @@ func TestCreateStack(t *testing.T) { TemplateOpts: template, DisableRollback: gophercloud.Disabled, } - actual, err := stacks.Create(context.TODO(), fake.ServiceClient(), createOpts).Extract() + actual, err := stacks.Create(context.TODO(), client.ServiceClient(), createOpts).Extract() th.AssertNoErr(t, err) expected := CreateExpected @@ -59,7 +59,7 @@ func TestCreateStackMissingRequiredInOpts(t *testing.T) { createOpts := stacks.CreateOpts{ DisableRollback: gophercloud.Disabled, } - r := stacks.Create(context.TODO(), fake.ServiceClient(), createOpts) + r := stacks.Create(context.TODO(), client.ServiceClient(), createOpts) th.AssertEquals(t, "error creating the options map: Missing input for argument [Name]", r.Err.Error()) } @@ -102,7 +102,7 @@ func TestAdoptStack(t *testing.T) { TemplateOpts: template, DisableRollback: gophercloud.Disabled, } - actual, err := stacks.Adopt(context.TODO(), fake.ServiceClient(), adoptOpts).Extract() + actual, err := stacks.Adopt(context.TODO(), client.ServiceClient(), adoptOpts).Extract() th.AssertNoErr(t, err) expected := CreateExpected @@ -115,7 +115,7 @@ func TestListStack(t *testing.T) { HandleListSuccessfully(t, FullListOutput) count := 0 - err := stacks.List(fake.ServiceClient(), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := stacks.List(client.ServiceClient(), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := stacks.ExtractStacks(page) th.AssertNoErr(t, err) @@ -133,7 +133,7 @@ func TestGetStack(t *testing.T) { defer th.TeardownHTTP() HandleGetSuccessfully(t, GetOutput) - actual, err := stacks.Get(context.TODO(), fake.ServiceClient(), "postman_stack", "16ef0584-4458-41eb-87c8-0dc8d5f66c87").Extract() + actual, err := stacks.Get(context.TODO(), client.ServiceClient(), "postman_stack", "16ef0584-4458-41eb-87c8-0dc8d5f66c87").Extract() th.AssertNoErr(t, err) expected := GetExpected @@ -145,7 +145,7 @@ func TestFindStack(t *testing.T) { defer th.TeardownHTTP() HandleFindSuccessfully(t, GetOutput) - actual, err := stacks.Find(context.TODO(), fake.ServiceClient(), "16ef0584-4458-41eb-87c8-0dc8d5f66c87").Extract() + actual, err := stacks.Find(context.TODO(), client.ServiceClient(), "16ef0584-4458-41eb-87c8-0dc8d5f66c87").Extract() th.AssertNoErr(t, err) expected := GetExpected @@ -172,7 +172,7 @@ func TestUpdateStack(t *testing.T) { updateOpts := &stacks.UpdateOpts{ TemplateOpts: template, } - err := stacks.Update(context.TODO(), fake.ServiceClient(), "gophercloud-test-stack-2", "db6977b2-27aa-4775-9ae7-6213212d4ada", updateOpts).ExtractErr() + err := stacks.Update(context.TODO(), client.ServiceClient(), "gophercloud-test-stack-2", "db6977b2-27aa-4775-9ae7-6213212d4ada", updateOpts).ExtractErr() th.AssertNoErr(t, err) } @@ -189,7 +189,7 @@ func TestUpdateStackNoTemplate(t *testing.T) { } expected := stacks.ErrTemplateRequired{} - err := stacks.Update(context.TODO(), fake.ServiceClient(), "gophercloud-test-stack-2", "db6977b2-27aa-4775-9ae7-6213212d4ada", updateOpts).ExtractErr() + err := stacks.Update(context.TODO(), client.ServiceClient(), "gophercloud-test-stack-2", "db6977b2-27aa-4775-9ae7-6213212d4ada", updateOpts).ExtractErr() th.AssertEquals(t, expected, err) } @@ -204,7 +204,7 @@ func TestUpdatePatchStack(t *testing.T) { updateOpts := &stacks.UpdateOpts{ Parameters: parameters, } - err := stacks.UpdatePatch(context.TODO(), fake.ServiceClient(), "gophercloud-test-stack-2", "db6977b2-27aa-4775-9ae7-6213212d4ada", updateOpts).ExtractErr() + err := stacks.UpdatePatch(context.TODO(), client.ServiceClient(), "gophercloud-test-stack-2", "db6977b2-27aa-4775-9ae7-6213212d4ada", updateOpts).ExtractErr() th.AssertNoErr(t, err) } @@ -213,7 +213,7 @@ func TestDeleteStack(t *testing.T) { defer th.TeardownHTTP() HandleDeleteSuccessfully(t) - err := stacks.Delete(context.TODO(), fake.ServiceClient(), "gophercloud-test-stack-2", "db6977b2-27aa-4775-9ae7-6213212d4ada").ExtractErr() + err := stacks.Delete(context.TODO(), client.ServiceClient(), "gophercloud-test-stack-2", "db6977b2-27aa-4775-9ae7-6213212d4ada").ExtractErr() th.AssertNoErr(t, err) } @@ -240,7 +240,7 @@ func TestPreviewStack(t *testing.T) { TemplateOpts: template, DisableRollback: gophercloud.Disabled, } - actual, err := stacks.Preview(context.TODO(), fake.ServiceClient(), previewOpts).Extract() + actual, err := stacks.Preview(context.TODO(), client.ServiceClient(), previewOpts).Extract() th.AssertNoErr(t, err) expected := PreviewExpected @@ -252,7 +252,7 @@ func TestAbandonStack(t *testing.T) { defer th.TeardownHTTP() HandleAbandonSuccessfully(t, AbandonOutput) - actual, err := stacks.Abandon(context.TODO(), fake.ServiceClient(), "postman_stack", "16ef0584-4458-41eb-87c8-0dc8d5f66c8").Extract() + actual, err := stacks.Abandon(context.TODO(), client.ServiceClient(), "postman_stack", "16ef0584-4458-41eb-87c8-0dc8d5f66c8").Extract() th.AssertNoErr(t, err) expected := AbandonExpected diff --git a/openstack/orchestration/v1/stacktemplates/testing/fixtures_test.go b/openstack/orchestration/v1/stacktemplates/testing/fixtures_test.go index 2e6505702e..5d5da59dfc 100644 --- a/openstack/orchestration/v1/stacktemplates/testing/fixtures_test.go +++ b/openstack/orchestration/v1/stacktemplates/testing/fixtures_test.go @@ -7,7 +7,7 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/orchestration/v1/stacktemplates" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) // GetExpected represents the expected object from a Get request. @@ -43,7 +43,7 @@ const GetOutput = ` func HandleGetSuccessfully(t *testing.T, output string) { th.Mux.HandleFunc("/stacks/postman_stack/16ef0584-4458-41eb-87c8-0dc8d5f66c87/template", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") w.Header().Set("Content-Type", "application/json") @@ -86,7 +86,7 @@ const ValidateOutput = ` func HandleValidateSuccessfully(t *testing.T, output string) { th.Mux.HandleFunc("/validate", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") w.Header().Set("Content-Type", "application/json") diff --git a/openstack/orchestration/v1/stacktemplates/testing/requests_test.go b/openstack/orchestration/v1/stacktemplates/testing/requests_test.go index f52f4f75d7..f703d7bd61 100644 --- a/openstack/orchestration/v1/stacktemplates/testing/requests_test.go +++ b/openstack/orchestration/v1/stacktemplates/testing/requests_test.go @@ -6,7 +6,7 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/orchestration/v1/stacktemplates" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) func TestGetTemplate(t *testing.T) { @@ -14,7 +14,7 @@ func TestGetTemplate(t *testing.T) { defer th.TeardownHTTP() HandleGetSuccessfully(t, GetOutput) - actual, err := stacktemplates.Get(context.TODO(), fake.ServiceClient(), "postman_stack", "16ef0584-4458-41eb-87c8-0dc8d5f66c87").Extract() + actual, err := stacktemplates.Get(context.TODO(), client.ServiceClient(), "postman_stack", "16ef0584-4458-41eb-87c8-0dc8d5f66c87").Extract() th.AssertNoErr(t, err) expected := GetExpected @@ -51,7 +51,7 @@ func TestValidateTemplate(t *testing.T) { } }`, } - actual, err := stacktemplates.Validate(context.TODO(), fake.ServiceClient(), opts).Extract() + actual, err := stacktemplates.Validate(context.TODO(), client.ServiceClient(), opts).Extract() th.AssertNoErr(t, err) expected := ValidateExpected diff --git a/openstack/placement/v1/resourceproviders/testing/fixtures_test.go b/openstack/placement/v1/resourceproviders/testing/fixtures_test.go index 8766d88e27..6c5556736c 100644 --- a/openstack/placement/v1/resourceproviders/testing/fixtures_test.go +++ b/openstack/placement/v1/resourceproviders/testing/fixtures_test.go @@ -8,7 +8,7 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/placement/v1/resourceproviders" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) const ResourceProviderTestID = "99c09379-6e52-4ef8-9a95-b9ce6f68452e" @@ -272,7 +272,7 @@ func HandleResourceProviderList(t *testing.T) { th.Mux.HandleFunc("/resource_providers", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -284,7 +284,7 @@ func HandleResourceProviderList(t *testing.T) { func HandleResourceProviderCreate(t *testing.T) { th.Mux.HandleFunc("/resource_providers", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -296,7 +296,7 @@ func HandleResourceProviderCreate(t *testing.T) { func HandleResourceProviderGet(t *testing.T) { th.Mux.HandleFunc("/resource_providers/99c09379-6e52-4ef8-9a95-b9ce6f68452e", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -308,7 +308,7 @@ func HandleResourceProviderGet(t *testing.T) { func HandleResourceProviderDelete(t *testing.T) { th.Mux.HandleFunc("/resource_providers/b99b3ab4-3aa6-4fba-b827-69b88b9c544a", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) } @@ -316,7 +316,7 @@ func HandleResourceProviderDelete(t *testing.T) { func HandleResourceProviderUpdate(t *testing.T) { th.Mux.HandleFunc("/resource_providers/4e8e5957-649f-477b-9e5b-f1f75b21c03c", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, ResourceProviderUpdateRequest) @@ -334,7 +334,7 @@ func HandleResourceProviderGetUsages(t *testing.T) { th.Mux.HandleFunc(usageTestUrl, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -349,7 +349,7 @@ func HandleResourceProviderGetInventories(t *testing.T) { th.Mux.HandleFunc(inventoriesTestUrl, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -364,7 +364,7 @@ func HandleResourceProviderGetAllocations(t *testing.T) { th.Mux.HandleFunc(allocationsTestUrl, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -379,7 +379,7 @@ func HandleResourceProviderGetTraits(t *testing.T) { th.Mux.HandleFunc(traitsTestUrl, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) diff --git a/openstack/placement/v1/resourceproviders/testing/requests_test.go b/openstack/placement/v1/resourceproviders/testing/requests_test.go index ad0db1475c..6e6ac3c777 100644 --- a/openstack/placement/v1/resourceproviders/testing/requests_test.go +++ b/openstack/placement/v1/resourceproviders/testing/requests_test.go @@ -8,7 +8,7 @@ import ( "github.com/gophercloud/gophercloud/v2/pagination" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) func TestListResourceProviders(t *testing.T) { @@ -18,7 +18,7 @@ func TestListResourceProviders(t *testing.T) { HandleResourceProviderList(t) count := 0 - err := resourceproviders.List(fake.ServiceClient(), resourceproviders.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := resourceproviders.List(client.ServiceClient(), resourceproviders.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := resourceproviders.ExtractResourceProviders(page) @@ -52,7 +52,7 @@ func TestCreateResourceProvider(t *testing.T) { ParentProviderUUID: ExpectedResourceProvider1.ParentProviderUUID, } - actual, err := resourceproviders.Create(context.TODO(), fake.ServiceClient(), opts).Extract() + actual, err := resourceproviders.Create(context.TODO(), client.ServiceClient(), opts).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, &expected, actual) @@ -66,7 +66,7 @@ func TestGetResourceProvider(t *testing.T) { expected := ExpectedResourceProvider1 - actual, err := resourceproviders.Get(context.TODO(), fake.ServiceClient(), ExpectedResourceProvider1.UUID).Extract() + actual, err := resourceproviders.Get(context.TODO(), client.ServiceClient(), ExpectedResourceProvider1.UUID).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, &expected, actual) @@ -78,7 +78,7 @@ func TestDeleteResourceProvider(t *testing.T) { HandleResourceProviderDelete(t) - res := resourceproviders.Delete(context.TODO(), fake.ServiceClient(), "b99b3ab4-3aa6-4fba-b827-69b88b9c544a") + res := resourceproviders.Delete(context.TODO(), client.ServiceClient(), "b99b3ab4-3aa6-4fba-b827-69b88b9c544a") th.AssertNoErr(t, res.Err) } @@ -95,7 +95,7 @@ func TestUpdate(t *testing.T) { Name: &name, ParentProviderUUID: &parentProviderUUID, } - rp, err := resourceproviders.Update(context.TODO(), fake.ServiceClient(), "4e8e5957-649f-477b-9e5b-f1f75b21c03c", options).Extract() + rp, err := resourceproviders.Update(context.TODO(), client.ServiceClient(), "4e8e5957-649f-477b-9e5b-f1f75b21c03c", options).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, rp.Name, name) @@ -108,7 +108,7 @@ func TestGetResourceProvidersUsages(t *testing.T) { HandleResourceProviderGetUsages(t) - actual, err := resourceproviders.GetUsages(context.TODO(), fake.ServiceClient(), ResourceProviderTestID).Extract() + actual, err := resourceproviders.GetUsages(context.TODO(), client.ServiceClient(), ResourceProviderTestID).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, ExpectedUsages, *actual) } @@ -119,7 +119,7 @@ func TestGetResourceProvidersInventories(t *testing.T) { HandleResourceProviderGetInventories(t) - actual, err := resourceproviders.GetInventories(context.TODO(), fake.ServiceClient(), ResourceProviderTestID).Extract() + actual, err := resourceproviders.GetInventories(context.TODO(), client.ServiceClient(), ResourceProviderTestID).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, ExpectedInventories, *actual) } @@ -130,7 +130,7 @@ func TestGetResourceProvidersAllocations(t *testing.T) { HandleResourceProviderGetAllocations(t) - actual, err := resourceproviders.GetAllocations(context.TODO(), fake.ServiceClient(), ResourceProviderTestID).Extract() + actual, err := resourceproviders.GetAllocations(context.TODO(), client.ServiceClient(), ResourceProviderTestID).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, ExpectedAllocations, *actual) } @@ -141,7 +141,7 @@ func TestGetResourceProvidersTraits(t *testing.T) { HandleResourceProviderGetTraits(t) - actual, err := resourceproviders.GetTraits(context.TODO(), fake.ServiceClient(), ResourceProviderTestID).Extract() + actual, err := resourceproviders.GetTraits(context.TODO(), client.ServiceClient(), ResourceProviderTestID).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, ExpectedTraits, *actual) } diff --git a/openstack/sharedfilesystems/v2/availabilityzones/testing/fixtures_test.go b/openstack/sharedfilesystems/v2/availabilityzones/testing/fixtures_test.go index fa18c4cfc9..3097260664 100644 --- a/openstack/sharedfilesystems/v2/availabilityzones/testing/fixtures_test.go +++ b/openstack/sharedfilesystems/v2/availabilityzones/testing/fixtures_test.go @@ -6,13 +6,13 @@ import ( "testing" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) func MockListResponse(t *testing.T) { th.Mux.HandleFunc("/os-availability-zone", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) diff --git a/openstack/sharedfilesystems/v2/errors/testing/fixtures_test.go b/openstack/sharedfilesystems/v2/errors/testing/fixtures_test.go index 3adbc89b25..88a091f30d 100644 --- a/openstack/sharedfilesystems/v2/errors/testing/fixtures_test.go +++ b/openstack/sharedfilesystems/v2/errors/testing/fixtures_test.go @@ -6,7 +6,7 @@ import ( "testing" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) const shareEndpoint = "/shares" @@ -31,7 +31,7 @@ var createResponse = `{ func MockCreateResponse(t *testing.T) { th.Mux.HandleFunc(shareEndpoint, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, createRequest) diff --git a/openstack/sharedfilesystems/v2/messages/testing/fixtures_test.go b/openstack/sharedfilesystems/v2/messages/testing/fixtures_test.go index 123bad35ce..72e2cbd77d 100644 --- a/openstack/sharedfilesystems/v2/messages/testing/fixtures_test.go +++ b/openstack/sharedfilesystems/v2/messages/testing/fixtures_test.go @@ -6,13 +6,13 @@ import ( "testing" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) func MockDeleteResponse(t *testing.T) { th.Mux.HandleFunc("/messages/messageID", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusAccepted) }) } @@ -20,7 +20,7 @@ func MockDeleteResponse(t *testing.T) { func MockListResponse(t *testing.T) { th.Mux.HandleFunc("/messages", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -62,7 +62,7 @@ func MockListResponse(t *testing.T) { func MockFilteredListResponse(t *testing.T) { th.Mux.HandleFunc("/messages", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -91,7 +91,7 @@ func MockFilteredListResponse(t *testing.T) { func MockGetResponse(t *testing.T) { th.Mux.HandleFunc("/messages/2076373e-13a7-4b84-9e67-15ce8cceaff8", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) diff --git a/openstack/sharedfilesystems/v2/replicas/testing/fixtures_test.go b/openstack/sharedfilesystems/v2/replicas/testing/fixtures_test.go index 41fa0164c9..c62f2c1725 100644 --- a/openstack/sharedfilesystems/v2/replicas/testing/fixtures_test.go +++ b/openstack/sharedfilesystems/v2/replicas/testing/fixtures_test.go @@ -6,7 +6,7 @@ import ( "testing" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) const ( @@ -41,7 +41,7 @@ var createResponse = `{ func MockCreateResponse(t *testing.T) { th.Mux.HandleFunc(shareEndpoint, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-OpenStack-Manila-API-Version", "2.11") @@ -56,7 +56,7 @@ func MockCreateResponse(t *testing.T) { func MockDeleteResponse(t *testing.T) { th.Mux.HandleFunc(shareEndpoint+"/"+replicaID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "X-OpenStack-Manila-API-Version", "2.11") w.WriteHeader(http.StatusAccepted) }) @@ -72,7 +72,7 @@ var promoteRequest = `{ func MockPromoteResponse(t *testing.T) { th.Mux.HandleFunc(shareEndpoint+"/"+replicaID+"/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-OpenStack-Manila-API-Version", "2.11") @@ -89,7 +89,7 @@ var resyncRequest = `{ func MockResyncResponse(t *testing.T) { th.Mux.HandleFunc(shareEndpoint+"/"+replicaID+"/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-OpenStack-Manila-API-Version", "2.11") @@ -108,7 +108,7 @@ var resetStatusRequest = `{ func MockResetStatusResponse(t *testing.T) { th.Mux.HandleFunc(shareEndpoint+"/"+replicaID+"/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-OpenStack-Manila-API-Version", "2.11") @@ -127,7 +127,7 @@ var resetStateRequest = `{ func MockResetStateResponse(t *testing.T) { th.Mux.HandleFunc(shareEndpoint+"/"+replicaID+"/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-OpenStack-Manila-API-Version", "2.11") @@ -144,7 +144,7 @@ var deleteRequest = `{ func MockForceDeleteResponse(t *testing.T) { th.Mux.HandleFunc(shareEndpoint+"/"+replicaID+"/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-OpenStack-Manila-API-Version", "2.11") @@ -172,7 +172,7 @@ var getResponse = `{ func MockGetResponse(t *testing.T) { th.Mux.HandleFunc(shareEndpoint+"/"+replicaID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "X-OpenStack-Manila-API-Version", "2.11") w.WriteHeader(http.StatusOK) fmt.Fprint(w, getResponse) @@ -209,7 +209,7 @@ var listEmptyResponse = `{"share_replicas": []}` func MockListResponse(t *testing.T) { th.Mux.HandleFunc(shareEndpoint, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "X-OpenStack-Manila-API-Version", "2.11") w.Header().Add("Content-Type", "application/json") @@ -278,7 +278,7 @@ var listDetailEmptyResponse = `{"share_replicas": []}` func MockListDetailResponse(t *testing.T) { th.Mux.HandleFunc(shareEndpoint+"/detail", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "X-OpenStack-Manila-API-Version", "2.11") w.Header().Add("Content-Type", "application/json") @@ -326,7 +326,7 @@ var listExportLocationsResponse = `{ func MockListExportLocationsResponse(t *testing.T) { th.Mux.HandleFunc(shareEndpoint+"/"+replicaID+"/export-locations", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") th.TestHeader(t, r, "X-OpenStack-Manila-API-Version", "2.47") w.WriteHeader(http.StatusOK) @@ -351,7 +351,7 @@ var getExportLocationResponse = `{ func MockGetExportLocationResponse(t *testing.T) { th.Mux.HandleFunc(shareEndpoint+"/"+replicaID+"/export-locations/ae73e762-e8b9-4aad-aad3-23afb7cd6825", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") th.TestHeader(t, r, "X-OpenStack-Manila-API-Version", "2.47") w.WriteHeader(http.StatusOK) diff --git a/openstack/sharedfilesystems/v2/securityservices/testing/fixtures_test.go b/openstack/sharedfilesystems/v2/securityservices/testing/fixtures_test.go index 279fcee4a4..243a6a4b45 100644 --- a/openstack/sharedfilesystems/v2/securityservices/testing/fixtures_test.go +++ b/openstack/sharedfilesystems/v2/securityservices/testing/fixtures_test.go @@ -6,13 +6,13 @@ import ( "testing" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) func MockCreateResponse(t *testing.T) { th.Mux.HandleFunc("/security-services", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, ` @@ -54,7 +54,7 @@ func MockCreateResponse(t *testing.T) { func MockDeleteResponse(t *testing.T) { th.Mux.HandleFunc("/security-services/securityServiceID", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusAccepted) }) } @@ -62,7 +62,7 @@ func MockDeleteResponse(t *testing.T) { func MockListResponse(t *testing.T) { th.Mux.HandleFunc("/security-services/detail", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -108,7 +108,7 @@ func MockListResponse(t *testing.T) { func MockFilteredListResponse(t *testing.T) { th.Mux.HandleFunc("/security-services/detail", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -139,7 +139,7 @@ func MockFilteredListResponse(t *testing.T) { func MockGetResponse(t *testing.T) { th.Mux.HandleFunc("/security-services/3c829734-0679-4c17-9637-801da48c0d5f", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -167,7 +167,7 @@ func MockGetResponse(t *testing.T) { func MockUpdateResponse(t *testing.T) { th.Mux.HandleFunc("/security-services/securityServiceID", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusOK) fmt.Fprint(w, ` { diff --git a/openstack/sharedfilesystems/v2/shareaccessrules/testing/fixtures_test.go b/openstack/sharedfilesystems/v2/shareaccessrules/testing/fixtures_test.go index cc63ffac9c..49948ec59f 100644 --- a/openstack/sharedfilesystems/v2/shareaccessrules/testing/fixtures_test.go +++ b/openstack/sharedfilesystems/v2/shareaccessrules/testing/fixtures_test.go @@ -6,7 +6,7 @@ import ( "testing" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) const ( @@ -36,7 +36,7 @@ var getResponse = `{ func MockGetResponse(t *testing.T) { th.Mux.HandleFunc(shareAccessRulesEndpoint+"/"+shareAccessRuleID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) diff --git a/openstack/sharedfilesystems/v2/shareaccessrules/testing/requests_test.go b/openstack/sharedfilesystems/v2/shareaccessrules/testing/requests_test.go index 7566788e40..c5e3961cfd 100644 --- a/openstack/sharedfilesystems/v2/shareaccessrules/testing/requests_test.go +++ b/openstack/sharedfilesystems/v2/shareaccessrules/testing/requests_test.go @@ -10,7 +10,6 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/sharedfilesystems/v2/shareaccessrules" th "github.com/gophercloud/gophercloud/v2/testhelper" "github.com/gophercloud/gophercloud/v2/testhelper/client" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" ) func TestGet(t *testing.T) { @@ -45,7 +44,7 @@ func TestGet(t *testing.T) { func MockListResponse(t *testing.T) { th.Mux.HandleFunc(shareAccessRulesEndpoint, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) diff --git a/openstack/sharedfilesystems/v2/sharenetworks/testing/fixtures_test.go b/openstack/sharedfilesystems/v2/sharenetworks/testing/fixtures_test.go index eb608f9b6a..8c217f4b0a 100644 --- a/openstack/sharedfilesystems/v2/sharenetworks/testing/fixtures_test.go +++ b/openstack/sharedfilesystems/v2/sharenetworks/testing/fixtures_test.go @@ -6,7 +6,7 @@ import ( "testing" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) func createReq(name, description, network, subnetwork string) string { @@ -44,7 +44,7 @@ func createResp(name, description, network, subnetwork string) string { func MockCreateResponse(t *testing.T) { th.Mux.HandleFunc("/share-networks", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, createReq("my_network", @@ -65,7 +65,7 @@ func MockCreateResponse(t *testing.T) { func MockDeleteResponse(t *testing.T) { th.Mux.HandleFunc("/share-networks/fa158a3d-6d9f-4187-9ca5-abbb82646eb2", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusAccepted) }) } @@ -73,7 +73,7 @@ func MockDeleteResponse(t *testing.T) { func MockListResponse(t *testing.T) { th.Mux.HandleFunc("/share-networks/detail", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -146,7 +146,7 @@ func MockListResponse(t *testing.T) { func MockFilteredListResponse(t *testing.T) { th.Mux.HandleFunc("/share-networks/detail", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -231,7 +231,7 @@ func MockFilteredListResponse(t *testing.T) { func MockGetResponse(t *testing.T) { th.Mux.HandleFunc("/share-networks/7f950b52-6141-4a08-bbb5-bb7ffa3ea5fd", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -259,7 +259,7 @@ func MockGetResponse(t *testing.T) { func MockUpdateNeutronResponse(t *testing.T) { th.Mux.HandleFunc("/share-networks/713df749-aac0-4a54-af52-10f6c991e80c", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusOK) fmt.Fprint(w, ` { @@ -286,7 +286,7 @@ func MockUpdateNeutronResponse(t *testing.T) { func MockUpdateNovaResponse(t *testing.T) { th.Mux.HandleFunc("/share-networks/713df749-aac0-4a54-af52-10f6c991e80c", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusOK) fmt.Fprint(w, ` { @@ -313,7 +313,7 @@ func MockUpdateNovaResponse(t *testing.T) { func MockAddSecurityServiceResponse(t *testing.T) { th.Mux.HandleFunc("/share-networks/shareNetworkID/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusOK) fmt.Fprint(w, ` { @@ -339,7 +339,7 @@ func MockAddSecurityServiceResponse(t *testing.T) { func MockRemoveSecurityServiceResponse(t *testing.T) { th.Mux.HandleFunc("/share-networks/shareNetworkID/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusOK) fmt.Fprint(w, ` { diff --git a/openstack/sharedfilesystems/v2/shares/testing/fixtures_test.go b/openstack/sharedfilesystems/v2/shares/testing/fixtures_test.go index 36db8b7a22..c27ece7a85 100644 --- a/openstack/sharedfilesystems/v2/shares/testing/fixtures_test.go +++ b/openstack/sharedfilesystems/v2/shares/testing/fixtures_test.go @@ -6,7 +6,7 @@ import ( "testing" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) const ( @@ -78,7 +78,7 @@ var createResponse = `{ func MockCreateResponse(t *testing.T) { th.Mux.HandleFunc(shareEndpoint, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, createRequest) @@ -92,7 +92,7 @@ func MockCreateResponse(t *testing.T) { func MockDeleteResponse(t *testing.T) { th.Mux.HandleFunc(shareEndpoint+"/"+shareID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusAccepted) }) } @@ -152,7 +152,7 @@ var updateResponse = ` func MockUpdateResponse(t *testing.T) { th.Mux.HandleFunc(shareEndpoint+"/"+shareID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, updateRequest) @@ -209,7 +209,7 @@ var getResponse = `{ func MockGetResponse(t *testing.T) { th.Mux.HandleFunc(shareEndpoint+"/"+shareID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusOK) fmt.Fprint(w, getResponse) }) @@ -266,7 +266,7 @@ var listDetailEmptyResponse = `{"shares": []}` func MockListDetailResponse(t *testing.T) { th.Mux.HandleFunc(shareEndpoint+"/detail", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -301,7 +301,7 @@ var listExportLocationsResponse = `{ func MockListExportLocationsResponse(t *testing.T) { th.Mux.HandleFunc(shareEndpoint+"/"+shareID+"/export_locations", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) fmt.Fprint(w, listExportLocationsResponse) @@ -322,7 +322,7 @@ var getExportLocationResponse = `{ func MockGetExportLocationResponse(t *testing.T) { th.Mux.HandleFunc(shareEndpoint+"/"+shareID+"/export_locations/80ed63fc-83bc-4afc-b881-da4a345ac83d", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) fmt.Fprint(w, getExportLocationResponse) @@ -353,7 +353,7 @@ var grantAccessResponse = `{ func MockGrantAccessResponse(t *testing.T) { th.Mux.HandleFunc(shareEndpoint+"/"+shareID+"/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, grantAccessRequest) @@ -373,7 +373,7 @@ var revokeAccessRequest = `{ func MockRevokeAccessResponse(t *testing.T) { th.Mux.HandleFunc(shareEndpoint+"/"+shareID+"/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, revokeAccessRequest) @@ -404,7 +404,7 @@ var listAccessRightsResponse = `{ func MockListAccessRightsResponse(t *testing.T) { th.Mux.HandleFunc(shareEndpoint+"/"+shareID+"/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, listAccessRightsRequest) @@ -424,7 +424,7 @@ var extendRequest = `{ func MockExtendResponse(t *testing.T) { th.Mux.HandleFunc(shareEndpoint+"/"+shareID+"/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, extendRequest) @@ -443,7 +443,7 @@ var shrinkRequest = `{ func MockShrinkResponse(t *testing.T) { th.Mux.HandleFunc(shareEndpoint+"/"+shareID+"/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, shrinkRequest) @@ -462,7 +462,7 @@ var getMetadataResponse = `{ func MockGetMetadataResponse(t *testing.T) { th.Mux.HandleFunc(shareEndpoint+"/"+shareID+"/metadata", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -480,7 +480,7 @@ var getMetadatumResponse = `{ func MockGetMetadatumResponse(t *testing.T, key string) { th.Mux.HandleFunc(shareEndpoint+"/"+shareID+"/metadata/"+key, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -504,7 +504,7 @@ var setMetadataResponse = `{ func MockSetMetadataResponse(t *testing.T) { th.Mux.HandleFunc(shareEndpoint+"/"+shareID+"/metadata", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, setMetadataRequest) @@ -530,7 +530,7 @@ var updateMetadataResponse = `{ func MockUpdateMetadataResponse(t *testing.T) { th.Mux.HandleFunc(shareEndpoint+"/"+shareID+"/metadata", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, updateMetadataRequest) @@ -544,7 +544,7 @@ func MockUpdateMetadataResponse(t *testing.T) { func MockDeleteMetadatumResponse(t *testing.T, key string) { th.Mux.HandleFunc(shareEndpoint+"/"+shareID+"/metadata/"+key, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusOK) }) } @@ -559,7 +559,7 @@ var revertRequest = `{ func MockRevertResponse(t *testing.T) { th.Mux.HandleFunc(shareEndpoint+"/"+shareID+"/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, revertRequest) @@ -578,7 +578,7 @@ var resetStatusRequest = `{ func MockResetStatusResponse(t *testing.T) { th.Mux.HandleFunc(shareEndpoint+"/"+shareID+"/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, resetStatusRequest) @@ -595,7 +595,7 @@ var forceDeleteRequest = `{ func MockForceDeleteResponse(t *testing.T) { th.Mux.HandleFunc(shareEndpoint+"/"+shareID+"/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, forceDeleteRequest) @@ -612,7 +612,7 @@ var unmanageRequest = `{ func MockUnmanageResponse(t *testing.T) { th.Mux.HandleFunc(shareEndpoint+"/"+shareID+"/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, unmanageRequest) diff --git a/openstack/sharedfilesystems/v2/sharetypes/testing/fixtures_test.go b/openstack/sharedfilesystems/v2/sharetypes/testing/fixtures_test.go index 17fb21fa78..2330f8a12c 100644 --- a/openstack/sharedfilesystems/v2/sharetypes/testing/fixtures_test.go +++ b/openstack/sharedfilesystems/v2/sharetypes/testing/fixtures_test.go @@ -6,13 +6,13 @@ import ( "testing" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) func MockCreateResponse(t *testing.T) { th.Mux.HandleFunc("/types", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, ` @@ -63,7 +63,7 @@ func MockCreateResponse(t *testing.T) { func MockDeleteResponse(t *testing.T) { th.Mux.HandleFunc("/types/shareTypeID", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusAccepted) }) } @@ -71,7 +71,7 @@ func MockDeleteResponse(t *testing.T) { func MockListResponse(t *testing.T) { th.Mux.HandleFunc("/types", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -137,7 +137,7 @@ func MockListResponse(t *testing.T) { func MockGetDefaultResponse(t *testing.T) { th.Mux.HandleFunc("/types/default", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -168,7 +168,7 @@ func MockGetDefaultResponse(t *testing.T) { func MockGetExtraSpecsResponse(t *testing.T) { th.Mux.HandleFunc("/types/shareTypeID/extra_specs", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -186,7 +186,7 @@ func MockGetExtraSpecsResponse(t *testing.T) { func MockSetExtraSpecsResponse(t *testing.T) { th.Mux.HandleFunc("/types/shareTypeID/extra_specs", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, ` @@ -211,7 +211,7 @@ func MockSetExtraSpecsResponse(t *testing.T) { func MockUnsetExtraSpecsResponse(t *testing.T) { th.Mux.HandleFunc("/types/shareTypeID/extra_specs/my_key", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusAccepted) }) } @@ -219,7 +219,7 @@ func MockUnsetExtraSpecsResponse(t *testing.T) { func MockShowAccessResponse(t *testing.T) { th.Mux.HandleFunc("/types/shareTypeID/share_type_access", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -242,7 +242,7 @@ func MockShowAccessResponse(t *testing.T) { func MockAddAccessResponse(t *testing.T) { th.Mux.HandleFunc("/types/shareTypeID/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, ` @@ -258,7 +258,7 @@ func MockAddAccessResponse(t *testing.T) { func MockRemoveAccessResponse(t *testing.T) { th.Mux.HandleFunc("/types/shareTypeID/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, ` diff --git a/openstack/sharedfilesystems/v2/snapshots/testing/fixtures_test.go b/openstack/sharedfilesystems/v2/snapshots/testing/fixtures_test.go index 88e94c371a..2175dd4739 100644 --- a/openstack/sharedfilesystems/v2/snapshots/testing/fixtures_test.go +++ b/openstack/sharedfilesystems/v2/snapshots/testing/fixtures_test.go @@ -6,7 +6,7 @@ import ( "testing" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) const ( @@ -53,7 +53,7 @@ var createResponse = `{ func MockCreateResponse(t *testing.T) { th.Mux.HandleFunc(snapshotEndpoint, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, createRequest) @@ -67,7 +67,7 @@ func MockCreateResponse(t *testing.T) { func MockDeleteResponse(t *testing.T) { th.Mux.HandleFunc(snapshotEndpoint+"/"+snapshotID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusAccepted) }) } @@ -108,7 +108,7 @@ var updateResponse = `{ func MockUpdateResponse(t *testing.T) { th.Mux.HandleFunc(snapshotEndpoint+"/"+snapshotID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, updateRequest) @@ -148,7 +148,7 @@ var getResponse = `{ func MockGetResponse(t *testing.T) { th.Mux.HandleFunc(snapshotEndpoint+"/"+snapshotID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusOK) fmt.Fprint(w, getResponse) }) @@ -188,7 +188,7 @@ var listDetailEmptyResponse = `{"snapshots": []}` func MockListDetailResponse(t *testing.T) { th.Mux.HandleFunc(snapshotEndpoint+"/detail", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -217,7 +217,7 @@ var resetStatusRequest = `{ func MockResetStatusResponse(t *testing.T) { th.Mux.HandleFunc(snapshotEndpoint+"/"+snapshotID+"/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, resetStatusRequest) @@ -234,7 +234,7 @@ var forceDeleteRequest = `{ func MockForceDeleteResponse(t *testing.T) { th.Mux.HandleFunc(snapshotEndpoint+"/"+snapshotID+"/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, forceDeleteRequest) diff --git a/openstack/workflow/v2/crontriggers/testing/requests_test.go b/openstack/workflow/v2/crontriggers/testing/requests_test.go index 8267e2bc79..ec2b2bf738 100644 --- a/openstack/workflow/v2/crontriggers/testing/requests_test.go +++ b/openstack/workflow/v2/crontriggers/testing/requests_test.go @@ -12,7 +12,7 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/workflow/v2/crontriggers" "github.com/gophercloud/gophercloud/v2/pagination" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) func TestCreateCronTrigger(t *testing.T) { @@ -21,7 +21,7 @@ func TestCreateCronTrigger(t *testing.T) { th.Mux.HandleFunc("/cron_triggers", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusCreated) w.Header().Add("Content-Type", "application/json") @@ -58,7 +58,7 @@ func TestCreateCronTrigger(t *testing.T) { }, } - actual, err := crontriggers.Create(context.TODO(), fake.ServiceClient(), opts).Extract() + actual, err := crontriggers.Create(context.TODO(), client.ServiceClient(), opts).Extract() if err != nil { t.Fatalf("Unable to create cron trigger: %v", err) } @@ -94,12 +94,12 @@ func TestDeleteCronTrigger(t *testing.T) { th.Mux.HandleFunc("/cron_triggers/0520ffd8-f7f1-4f2e-845b-55d953a1cf46", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusAccepted) }) - res := crontriggers.Delete(context.TODO(), fake.ServiceClient(), "0520ffd8-f7f1-4f2e-845b-55d953a1cf46") + res := crontriggers.Delete(context.TODO(), client.ServiceClient(), "0520ffd8-f7f1-4f2e-845b-55d953a1cf46") th.AssertNoErr(t, res.Err) } @@ -108,7 +108,7 @@ func TestGetCronTrigger(t *testing.T) { defer th.TeardownHTTP() th.Mux.HandleFunc("/cron_triggers/0520ffd8-f7f1-4f2e-845b-55d953a1cf46", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-token", client.TokenID) w.Header().Add("Content-Type", "application/json") fmt.Fprint(w, ` { @@ -129,7 +129,7 @@ func TestGetCronTrigger(t *testing.T) { } `) }) - actual, err := crontriggers.Get(context.TODO(), fake.ServiceClient(), "0520ffd8-f7f1-4f2e-845b-55d953a1cf46").Extract() + actual, err := crontriggers.Get(context.TODO(), client.ServiceClient(), "0520ffd8-f7f1-4f2e-845b-55d953a1cf46").Extract() if err != nil { t.Fatalf("Unable to get cron trigger: %v", err) } @@ -165,7 +165,7 @@ func TestListCronTriggers(t *testing.T) { defer th.TeardownHTTP() th.Mux.HandleFunc("/cron_triggers", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") if err := r.ParseForm(); err != nil { t.Errorf("Failed to parse request form %v", err) @@ -202,7 +202,7 @@ func TestListCronTriggers(t *testing.T) { }) pages := 0 // Get all cron triggers - err := crontriggers.List(fake.ServiceClient(), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := crontriggers.List(client.ServiceClient(), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := crontriggers.ExtractCronTriggers(page) if err != nil { diff --git a/openstack/workflow/v2/executions/testing/requests_test.go b/openstack/workflow/v2/executions/testing/requests_test.go index 86a4700457..0d2c57de2f 100644 --- a/openstack/workflow/v2/executions/testing/requests_test.go +++ b/openstack/workflow/v2/executions/testing/requests_test.go @@ -12,7 +12,7 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/workflow/v2/executions" "github.com/gophercloud/gophercloud/v2/pagination" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) func TestCreateExecution(t *testing.T) { @@ -21,7 +21,7 @@ func TestCreateExecution(t *testing.T) { th.Mux.HandleFunc("/executions", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusCreated) w.Header().Add("Content-Type", "application/json") @@ -54,7 +54,7 @@ func TestCreateExecution(t *testing.T) { Description: "description", } - actual, err := executions.Create(context.TODO(), fake.ServiceClient(), opts).Extract() + actual, err := executions.Create(context.TODO(), client.ServiceClient(), opts).Extract() if err != nil { t.Fatalf("Unable to create execution: %v", err) } @@ -89,7 +89,7 @@ func TestGetExecution(t *testing.T) { th.Mux.HandleFunc("/executions/50bb59f1-eb77-4017-a77f-6d575b002667", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-token", client.TokenID) w.Header().Add("Content-Type", "application/json") fmt.Fprint(w, ` @@ -113,7 +113,7 @@ func TestGetExecution(t *testing.T) { `) }) - actual, err := executions.Get(context.TODO(), fake.ServiceClient(), "50bb59f1-eb77-4017-a77f-6d575b002667").Extract() + actual, err := executions.Get(context.TODO(), client.ServiceClient(), "50bb59f1-eb77-4017-a77f-6d575b002667").Extract() if err != nil { t.Fatalf("Unable to get execution: %v", err) } @@ -147,10 +147,10 @@ func TestDeleteExecution(t *testing.T) { defer th.TeardownHTTP() th.Mux.HandleFunc("/executions/1", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusAccepted) }) - res := executions.Delete(context.TODO(), fake.ServiceClient(), "1") + res := executions.Delete(context.TODO(), client.ServiceClient(), "1") th.AssertNoErr(t, res.Err) } @@ -159,7 +159,7 @@ func TestListExecutions(t *testing.T) { defer th.TeardownHTTP() th.Mux.HandleFunc("/executions", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") if err := r.ParseForm(); err != nil { t.Errorf("Failed to parse request form %v", err) @@ -196,7 +196,7 @@ func TestListExecutions(t *testing.T) { }) pages := 0 // Get all executions - err := executions.List(fake.ServiceClient(), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := executions.List(client.ServiceClient(), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := executions.ExtractExecutions(page) if err != nil { diff --git a/openstack/workflow/v2/workflows/testing/requests_test.go b/openstack/workflow/v2/workflows/testing/requests_test.go index a5d656685f..ff8d51cc23 100644 --- a/openstack/workflow/v2/workflows/testing/requests_test.go +++ b/openstack/workflow/v2/workflows/testing/requests_test.go @@ -13,7 +13,7 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/workflow/v2/workflows" "github.com/gophercloud/gophercloud/v2/pagination" th "github.com/gophercloud/gophercloud/v2/testhelper" - fake "github.com/gophercloud/gophercloud/v2/testhelper/client" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) func TestCreateWorkflow(t *testing.T) { @@ -35,7 +35,7 @@ workflow_echo: th.Mux.HandleFunc("/workflows", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "text/plain") th.TestFormValues(t, r, map[string]string{ "namespace": "some-namespace", @@ -70,7 +70,7 @@ workflow_echo: Definition: strings.NewReader(definition), } - actual, err := workflows.Create(context.TODO(), fake.ServiceClient(), opts).Extract() + actual, err := workflows.Create(context.TODO(), client.ServiceClient(), opts).Extract() if err != nil { t.Fatalf("Unable to create workflow: %v", err) } @@ -102,12 +102,12 @@ func TestDeleteWorkflow(t *testing.T) { th.Mux.HandleFunc("/workflows/604a3a1e-94e3-4066-a34a-aa56873ef236", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusAccepted) }) - res := workflows.Delete(context.TODO(), fake.ServiceClient(), "604a3a1e-94e3-4066-a34a-aa56873ef236") + res := workflows.Delete(context.TODO(), client.ServiceClient(), "604a3a1e-94e3-4066-a34a-aa56873ef236") th.AssertNoErr(t, res.Err) } @@ -116,7 +116,7 @@ func TestGetWorkflow(t *testing.T) { defer th.TeardownHTTP() th.Mux.HandleFunc("/workflows/1", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-token", client.TokenID) w.Header().Add("Content-Type", "application/json") fmt.Fprint(w, ` { @@ -133,7 +133,7 @@ func TestGetWorkflow(t *testing.T) { } `) }) - actual, err := workflows.Get(context.TODO(), fake.ServiceClient(), "1").Extract() + actual, err := workflows.Get(context.TODO(), client.ServiceClient(), "1").Extract() if err != nil { t.Fatalf("Unable to get workflow: %v", err) } @@ -161,7 +161,7 @@ func TestListWorkflows(t *testing.T) { defer th.TeardownHTTP() th.Mux.HandleFunc("/workflows", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") if err := r.ParseForm(); err != nil { t.Errorf("Failed to parse request form %v", err) @@ -194,7 +194,7 @@ func TestListWorkflows(t *testing.T) { }) pages := 0 // Get all workflows - err := workflows.List(fake.ServiceClient(), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := workflows.List(client.ServiceClient(), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := workflows.ExtractWorkflows(page) if err != nil { From da5ed91eba29f302cb3cebf438e69409b0192a01 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Wed, 17 Jul 2024 14:22:24 +0100 Subject: [PATCH 158/353] tests: Remove duplicate fake client method Signed-off-by: Stephen Finucane (cherry picked from commit 2f524851f328ff31b195c0eaa5f550bc7ec01b46) --- pagination/testing/linked_test.go | 3 ++- pagination/testing/marker_test.go | 3 ++- pagination/testing/pagination_test.go | 13 ------------- pagination/testing/single_test.go | 3 ++- 4 files changed, 6 insertions(+), 16 deletions(-) delete mode 100644 pagination/testing/pagination_test.go diff --git a/pagination/testing/linked_test.go b/pagination/testing/linked_test.go index e28c2b0483..30f4bdbd31 100644 --- a/pagination/testing/linked_test.go +++ b/pagination/testing/linked_test.go @@ -9,6 +9,7 @@ import ( "github.com/gophercloud/gophercloud/v2/pagination" th "github.com/gophercloud/gophercloud/v2/testhelper" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) // LinkedPager sample and test cases. @@ -48,7 +49,7 @@ func createLinked() pagination.Pager { fmt.Fprint(w, `{ "ints": [7, 8, 9], "links": { "next": null } }`) }) - client := createClient() + client := client.ServiceClient() createPage := func(r pagination.PageResult) pagination.Page { return LinkedPageResult{pagination.LinkedPageBase{PageResult: r}} diff --git a/pagination/testing/marker_test.go b/pagination/testing/marker_test.go index a41915175d..312ba5ac0a 100644 --- a/pagination/testing/marker_test.go +++ b/pagination/testing/marker_test.go @@ -9,6 +9,7 @@ import ( "github.com/gophercloud/gophercloud/v2/pagination" th "github.com/gophercloud/gophercloud/v2/testhelper" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) // MarkerPager sample and test cases. @@ -58,7 +59,7 @@ func createMarkerPaged(t *testing.T) pagination.Pager { } }) - client := createClient() + client := client.ServiceClient() createPage := func(r pagination.PageResult) pagination.Page { p := MarkerPageResult{pagination.MarkerPageBase{PageResult: r}} diff --git a/pagination/testing/pagination_test.go b/pagination/testing/pagination_test.go deleted file mode 100644 index e10ef56847..0000000000 --- a/pagination/testing/pagination_test.go +++ /dev/null @@ -1,13 +0,0 @@ -package testing - -import ( - "github.com/gophercloud/gophercloud/v2" - th "github.com/gophercloud/gophercloud/v2/testhelper" -) - -func createClient() *gophercloud.ServiceClient { - return &gophercloud.ServiceClient{ - ProviderClient: &gophercloud.ProviderClient{TokenID: "abc123"}, - Endpoint: th.Endpoint(), - } -} diff --git a/pagination/testing/single_test.go b/pagination/testing/single_test.go index 090324a573..3988e8af5d 100644 --- a/pagination/testing/single_test.go +++ b/pagination/testing/single_test.go @@ -8,6 +8,7 @@ import ( "github.com/gophercloud/gophercloud/v2/pagination" th "github.com/gophercloud/gophercloud/v2/testhelper" + "github.com/gophercloud/gophercloud/v2/testhelper/client" ) // SinglePage sample and test cases. @@ -34,7 +35,7 @@ func ExtractSingleInts(r pagination.Page) ([]int, error) { func setupSinglePaged() pagination.Pager { th.SetupHTTP() - client := createClient() + client := client.ServiceClient() th.Mux.HandleFunc("/only", func(w http.ResponseWriter, r *http.Request) { w.Header().Add("Content-Type", "application/json") From bf9b2d2acc1e41e0ba23a597ea33f1fde26d3ccd Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Wed, 17 Jul 2024 15:11:26 +0100 Subject: [PATCH 159/353] tests: Avoid use of global mocked server The meat of this changes is in 'testhelper/http_responses.go' and 'testhelper/client/fake.go'. The rest of the change is bulk generated updates to handle those changes: Create a "FakeServer" instance instead of configuring the global fake: sed -i 's/th.SetupHTTP/fakeServer := th.SetupHTTP/g' $(ag 'th.SetupHTTP' -l) Tear down this instance on test completion: sed -i 's/defer th.TeardownHTTP/defer fakeServer.Teardown/g' $(ag 'defer th.TeardownHTTP' -l) Update calls to the global 'Mux' instance with calls to the FakeServer version: sed -i 's/th.Mux.HandleFunc/fakeServer.Mux.HandleFunc/g' $(ag 'th.Mux.HandleFunc' -l) Update calls to ServiceClient to include a 'FakeServer' parameter: sed -i 's/client.ServiceClient()/client.ServiceClient(fakeServer)/' $(ag -w client.ServiceClient -l) Plus alises for the same: sed -i 's/fake.ServiceClient()/fake.ServiceClient(fakeServer)/' $(ag 'fake.ServiceClient' -l) Update definitions and calls to various MockFoo and HandleFoo helpers - plus lowercase, private variants of same - to include a 'FakeServer' parameter: sed -i 's/\(func Mock\w\+(t \*testing.T\)/\1, fakeServer th.FakeServer/' $(ag 'func Mock\w+\(t \*testing.T' -l) sed -i 's/\(\tMock\w\+(t\)/\1, fakeServer/' $(ag '\tMock\w+\(t' -l) sed -i 's/\(func mock\w\+(t \*testing.T\)/\1, fakeServer th.FakeServer/' $(ag 'func mock\w+\(t \*testing.T' -l) sed -i 's/\(\tmock\w\+(t\)/\1, fakeServer/' $(ag '\tmock\w+\(t' -l) sed -i 's/\(func Handle\w\+(t \*testing.T\)/\1, fakeServer th.FakeServer/' $(ag 'func Handle\w+\(t \*testing.T' -l) sed -i 's/\(\tHandle\w\+(t\)/\1, fakeServer/' $(ag '\tHandle\w+\(t' -l) sed -i 's/\(func handle\w\+(t \*testing.T\)/\1, fakeServer th.FakeServer/' $(ag 'func handle\w+\(t \*testing.T' -l) sed -i 's/\(\thandle\w\+(t\)/\1, fakeServer/' $(ag '\thandle\w+\(t' -l) Finally, there were some manual fixes to handle stuff that the regexes missed. Conflicts: openstack/baremetal/v1/portgroups/testing/fixtures.go openstack/baremetal/v1/portgroups/testing/requests_test.go openstack/compute/v2/servers/testing/requests_test.go openstack/db/v1/quotas/testing/fixtures_test.go openstack/db/v1/quotas/testing/requests_test.go openstack/dns/v2/zones/testing/requests_test.go openstack/loadbalancer/v2/flavors/testing/fixtures.go openstack/loadbalancer/v2/flavors/testing/requests_test.go openstack/networking/v2/extensions/security/rules/testing/requests_test.go Changes: openstack/blockstorage/v3/manageablevolumes/testing/fixtures_test.go openstack/blockstorage/v3/manageablevolumes/testing/requests_test.go openstack/blockstorage/v3/volumes/testing/fixtures_test.go openstack/blockstorage/v3/volumes/testing/requests_test.go openstack/networking/v2/extensions/security/addressgroups/testing/requests_test.go NOTE(stephenfin): Conflicts are generally due to tests or test files that don't exist on the v2 branch. Changes are due to tests that have been removed or moved on the main branch. Signed-off-by: Stephen Finucane (cherry picked from commit eed41cd71f365844d0e11d6fd6fc5437f0617d1d) --- .../.template/testing/requests_test.go | 12 +- .../apiversions/testing/fixtures_test.go | 8 +- .../apiversions/testing/requests_test.go | 16 +- .../v1/allocations/testing/fixtures_test.go | 16 +- .../v1/allocations/testing/requests_test.go | 32 +- .../v1/conductors/testing/fixtures_test.go | 12 +- .../v1/conductors/testing/requests_test.go | 24 +- .../v1/drivers/testing/fixtures_test.go | 16 +- .../v1/drivers/testing/requests_test.go | 32 +- .../v1/nodes/testing/fixtures_test.go | 168 ++++---- .../v1/nodes/testing/requests_test.go | 384 +++++++++--------- .../v1/ports/testing/fixtures_test.go | 24 +- .../v1/ports/testing/requests_test.go | 48 +-- .../v1/introspection/testing/fixtures.go | 24 +- .../v1/introspection/testing/requests_test.go | 48 +-- .../apiversions/testing/fixtures_test.go | 8 +- .../apiversions/testing/requests_test.go | 32 +- .../testing/fixtures_test.go | 4 +- .../testing/requests_test.go | 8 +- .../v2/backups/testing/fixtures_test.go | 44 +- .../v2/backups/testing/requests_test.go | 80 ++-- .../v2/limits/testing/fixtures_test.go | 4 +- .../v2/limits/testing/requests_test.go | 8 +- .../v2/quotasets/testing/fixtures_test.go | 8 +- .../v2/quotasets/testing/requests_test.go | 48 +-- .../schedulerstats/testing/fixtures_test.go | 4 +- .../schedulerstats/testing/requests_test.go | 8 +- .../v2/services/testing/fixtures_test.go | 4 +- .../v2/services/testing/requests_test.go | 8 +- .../v2/snapshots/testing/fixtures_test.go | 20 +- .../v2/snapshots/testing/requests_test.go | 40 +- .../v2/transfers/testing/fixtures_test.go | 20 +- .../v2/transfers/testing/requests_test.go | 48 +-- .../v2/volumes/testing/fixtures_test.go | 80 ++-- .../v2/volumes/testing/requests_test.go | 186 ++++----- .../v3/attachments/testing/fixtures_test.go | 30 +- .../v3/attachments/testing/requests_test.go | 56 +-- .../testing/fixtures_test.go | 4 +- .../testing/requests_test.go | 8 +- .../v3/backups/testing/fixtures_test.go | 44 +- .../v3/backups/testing/requests_test.go | 80 ++-- .../v3/limits/testing/fixtures_test.go | 4 +- .../v3/limits/testing/requests_test.go | 8 +- .../testing/fixtures_test.go | 4 +- .../testing/requests_test.go | 8 +- .../v3/qos/testing/fixtures_test.go | 42 +- .../v3/qos/testing/requests_test.go | 80 ++-- .../v3/quotasets/testing/fixtures_test.go | 8 +- .../v3/quotasets/testing/requests_test.go | 48 +-- .../schedulerstats/testing/fixtures_test.go | 4 +- .../schedulerstats/testing/requests_test.go | 8 +- .../v3/services/testing/fixtures_test.go | 4 +- .../v3/services/testing/requests_test.go | 8 +- .../v3/snapshots/testing/fixtures_test.go | 42 +- .../v3/snapshots/testing/requests_test.go | 80 ++-- .../v3/transfers/testing/fixtures_test.go | 20 +- .../v3/transfers/testing/requests_test.go | 48 +-- .../v3/volumes/testing/fixtures_test.go | 92 ++--- .../v3/volumes/testing/requests_test.go | 202 ++++----- .../v3/volumetypes/testing/fixtures_test.go | 62 +-- .../v3/volumetypes/testing/requests_test.go | 144 +++---- .../common/extensions/testing/fixtures.go | 8 +- .../extensions/testing/requests_test.go | 16 +- .../apiversions/testing/fixtures_test.go | 12 +- .../apiversions/testing/requests_test.go | 24 +- .../v2/aggregates/testing/fixtures_test.go | 32 +- .../v2/aggregates/testing/requests_test.go | 64 +-- .../attachinterfaces/testing/fixtures_test.go | 16 +- .../attachinterfaces/testing/requests_test.go | 40 +- .../testing/fixtures_test.go | 8 +- .../testing/requests_test.go | 16 +- .../v2/diagnostics/testing/fixtures_test.go | 4 +- .../v2/diagnostics/testing/requests_test.go | 8 +- .../v2/extensions/testing/delegate_test.go | 16 +- .../v2/extensions/testing/fixtures_test.go | 8 +- .../v2/flavors/testing/fixtures_test.go | 20 +- .../v2/flavors/testing/requests_test.go | 106 ++--- .../v2/hypervisors/testing/fixtures_test.go | 34 +- .../v2/hypervisors/testing/requests_test.go | 80 ++-- .../instanceactions/testing/fixtures_test.go | 8 +- .../instanceactions/testing/request_test.go | 16 +- .../v2/keypairs/testing/fixtures_test.go | 28 +- .../v2/keypairs/testing/requests_test.go | 64 +-- .../v2/limits/testing/fixtures_test.go | 4 +- .../v2/limits/testing/requests_test.go | 8 +- .../v2/quotasets/testing/fixtures_test.go | 20 +- .../v2/quotasets/testing/requests_test.go | 48 +-- .../remoteconsoles/testing/requests_test.go | 8 +- .../v2/secgroups/testing/fixtures_test.go | 52 +-- .../v2/secgroups/testing/requests_test.go | 104 ++--- .../v2/servergroups/testing/fixtures_test.go | 24 +- .../v2/servergroups/testing/requests_test.go | 48 +-- .../v2/servers/testing/fixtures_test.go | 122 +++--- .../v2/servers/testing/requests_test.go | 280 ++++++------- .../v2/servers/testing/results_test.go | 8 +- .../v2/services/testing/fixtures_test.go | 16 +- .../v2/services/testing/requests_test.go | 32 +- .../compute/v2/tags/testing/requests_test.go | 64 +-- .../compute/v2/usage/testing/fixtures_test.go | 8 +- .../compute/v2/usage/testing/requests_test.go | 16 +- .../v2/volumeattach/testing/fixtures_test.go | 16 +- .../v2/volumeattach/testing/requests_test.go | 32 +- .../v1/capsules/testing/fixtures_test.go | 24 +- .../v1/capsules/testing/requests_test.go | 48 +-- .../apiversions/testing/fixtures_test.go | 8 +- .../apiversions/testing/requests_test.go | 16 +- .../v1/certificates/testing/fixtures_test.go | 12 +- .../v1/certificates/testing/requests_test.go | 24 +- .../v1/clusters/testing/fixtures_test.go | 32 +- .../v1/clusters/testing/requests_test.go | 64 +-- .../clustertemplates/testing/fixtures_test.go | 32 +- .../clustertemplates/testing/requests_test.go | 64 +-- .../v1/nodegroups/testing/fixtures_test.go | 76 ++-- .../v1/nodegroups/testing/requests_test.go | 144 +++---- .../v1/quotas/testing/fixtures_test.go | 4 +- .../v1/quotas/testing/requests_test.go | 8 +- .../configurations/testing/requests_test.go | 88 ++-- .../db/v1/databases/testing/fixtures_test.go | 13 +- .../db/v1/databases/testing/requests_test.go | 24 +- .../db/v1/datastores/testing/requests_test.go | 32 +- .../db/v1/flavors/testing/fixtures_test.go | 9 +- .../db/v1/flavors/testing/requests_test.go | 16 +- .../db/v1/instances/testing/fixtures_test.go | 49 +-- .../db/v1/instances/testing/requests_test.go | 96 ++--- .../db/v1/users/testing/fixtures_test.go | 13 +- .../db/v1/users/testing/requests_test.go | 24 +- .../v2/recordsets/testing/fixtures_test.go | 20 +- .../v2/recordsets/testing/requests_test.go | 56 +-- .../transfer/accept/testing/accepts_test.go | 40 +- .../transfer/accept/testing/fixtures_test.go | 16 +- .../transfer/request/testing/fixtures_test.go | 20 +- .../transfer/request/testing/requests_test.go | 56 +-- .../dns/v2/zones/testing/fixtures_test.go | 20 +- .../dns/v2/zones/testing/requests_test.go | 72 ++-- .../v2/extensions/testing/fixtures_test.go | 4 +- .../v2/extensions/testing/requests_test.go | 16 +- .../v2/roles/testing/fixtures_test.go | 12 +- .../v2/roles/testing/requests_test.go | 24 +- .../v2/tenants/testing/fixtures_test.go | 20 +- .../v2/tenants/testing/requests_test.go | 40 +- .../v2/tokens/testing/fixtures_test.go | 8 +- .../v2/tokens/testing/requests_test.go | 24 +- .../v2/users/testing/fixtures_test.go | 24 +- .../v2/users/testing/requests_test.go | 48 +-- .../testing/fixtures_test.go | 36 +- .../testing/requests_test.go | 80 ++-- .../v3/catalog/testing/catalog_test.go | 8 +- .../v3/catalog/testing/fixtures_test.go | 4 +- .../v3/credentials/testing/fixtures_test.go | 20 +- .../v3/credentials/testing/requests_test.go | 48 +-- .../v3/domains/testing/fixtures_test.go | 24 +- .../v3/domains/testing/requests_test.go | 56 +-- .../ec2credentials/testing/fixtures_test.go | 16 +- .../ec2credentials/testing/requests_test.go | 40 +- .../v3/ec2tokens/testing/requests_test.go | 8 +- .../v3/endpoints/testing/requests_test.go | 40 +- .../v3/federation/testing/fixtures_test.go | 20 +- .../v3/federation/testing/requests_test.go | 48 +-- .../v3/groups/testing/fixtures_test.go | 20 +- .../v3/groups/testing/requests_test.go | 48 +-- .../v3/limits/testing/fixtures_test.go | 24 +- .../v3/limits/testing/requests_test.go | 56 +-- .../v3/oauth1/testing/fixtures_test.go | 56 +-- .../v3/oauth1/testing/requests_test.go | 136 +++---- .../v3/osinherit/testing/fixtures_test.go | 30 +- .../v3/osinherit/testing/requests_test.go | 54 +-- .../v3/policies/testing/fixtures_test.go | 20 +- .../v3/policies/testing/requests_test.go | 56 +-- .../projectendpoints/testing/requests_test.go | 24 +- .../v3/projects/testing/fixtures_test.go | 36 +- .../v3/projects/testing/requests_test.go | 74 ++-- .../v3/regions/testing/fixtures_test.go | 20 +- .../v3/regions/testing/requests_test.go | 48 +-- .../registeredlimits/testing/fixtures_test.go | 20 +- .../registeredlimits/testing/requests_test.go | 48 +-- .../v3/roles/testing/fixtures_test.go | 84 ++-- .../v3/roles/testing/requests_test.go | 164 ++++---- .../v3/services/testing/fixtures_test.go | 16 +- .../v3/services/testing/requests_test.go | 48 +-- .../v3/tokens/testing/requests_test.go | 82 ++-- .../v3/trusts/testing/fixtures_test.go | 32 +- .../v3/trusts/testing/requests_test.go | 88 ++-- .../v3/users/testing/fixtures_test.go | 52 +-- .../v3/users/testing/requests_test.go | 112 ++--- .../v2/imagedata/testing/fixtures_test.go | 12 +- .../v2/imagedata/testing/requests_test.go | 24 +- .../v2/imageimport/testing/requests_test.go | 16 +- .../image/v2/images/testing/fixtures_test.go | 32 +- .../image/v2/images/testing/requests_test.go | 72 ++-- .../image/v2/members/testing/fixtures_test.go | 24 +- .../image/v2/members/testing/requests_test.go | 48 +-- .../image/v2/tasks/testing/requests_test.go | 24 +- .../v1/acls/testing/fixtures_test.go | 32 +- .../v1/acls/testing/requests_test.go | 64 +-- .../v1/containers/testing/fixtures_test.go | 28 +- .../v1/containers/testing/requests_test.go | 72 ++-- .../v1/orders/testing/fixtures_test.go | 16 +- .../v1/orders/testing/requests_test.go | 40 +- .../v1/secrets/testing/fixtures_test.go | 48 +-- .../v1/secrets/testing/requests_test.go | 104 ++--- .../v2/amphorae/testing/fixtures_test.go | 12 +- .../v2/amphorae/testing/requests_test.go | 32 +- .../v2/apiversions/testing/fixture.go | 4 +- .../v2/apiversions/testing/requests_test.go | 8 +- .../v2/flavorprofiles/testing/fixtures.go | 20 +- .../flavorprofiles/testing/requests_test.go | 54 +-- .../v2/flavors/testing/fixtures.go | 20 +- .../v2/flavors/testing/requests_test.go | 62 +-- .../v2/l7policies/testing/fixtures_test.go | 44 +- .../v2/l7policies/testing/requests_test.go | 138 +++---- .../v2/listeners/testing/fixtures_test.go | 24 +- .../v2/listeners/testing/requests_test.go | 70 ++-- .../v2/loadbalancers/testing/fixtures_test.go | 36 +- .../v2/loadbalancers/testing/requests_test.go | 88 ++-- .../v2/monitors/testing/fixtures_test.go | 20 +- .../v2/monitors/testing/requests_test.go | 64 +-- .../v2/pools/testing/fixtures_test.go | 48 +-- .../v2/pools/testing/requests_test.go | 146 +++---- .../v2/providers/testing/fixtures_test.go | 4 +- .../v2/providers/testing/requests_test.go | 16 +- .../v2/quotas/testing/requests_test.go | 32 +- .../loadbalancer/v2/testhelper/client.go | 5 +- .../v2/claims/testing/fixtures_test.go | 20 +- .../v2/claims/testing/requests_test.go | 40 +- .../v2/messages/testing/fixtures_test.go | 28 +- .../v2/messages/testing/requests_test.go | 56 +-- .../v2/queues/testing/fixtures_test.go | 32 +- .../v2/queues/testing/requests_test.go | 64 +-- .../v2/apiversions/testing/requests_test.go | 32 +- .../networking/v2/common/common_tests.go | 5 +- .../agents/testing/requests_test.go | 112 ++--- .../attributestags/testing/requests_test.go | 56 +-- .../bgp/peers/testing/requests_test.go | 40 +- .../bgp/speakers/testing/requests_test.go | 80 ++-- .../bgpvpns/testing/requests_test.go | 152 +++---- .../extensions/dns/testing/fixtures_test.go | 44 +- .../extensions/dns/testing/requests_test.go | 78 ++-- .../external/testing/results_test.go | 32 +- .../fwaas_v2/groups/testing/requests_test.go | 56 +-- .../policies/testing/requests_test.go | 62 +-- .../fwaas_v2/rules/testing/requests_test.go | 48 +-- .../addressscopes/testing/requests_test.go | 40 +- .../extraroutes/testing/requests_test.go | 16 +- .../floatingips/testing/requests_test.go | 80 ++-- .../portforwarding/testing/requests_test.go | 40 +- .../layer3/routers/testing/requests_test.go | 88 ++-- .../v2/extensions/mtu/testing/results_test.go | 32 +- .../testing/requests_test.go | 16 +- .../portsbinding/testing/fixtures_test.go | 16 +- .../portsbinding/testing/requests_test.go | 38 +- .../provider/testing/results_test.go | 40 +- .../qos/policies/testing/requests_test.go | 104 ++--- .../networking/v2/extensions/qos/rules/doc.go | 6 +- .../qos/rules/testing/requests_test.go | 120 +++--- .../qos/ruletypes/testing/requests_test.go | 16 +- .../quotas/testing/requests_test.go | 24 +- .../rbacpolicies/testing/requests_test.go | 48 +-- .../addressgroups/testing/requests_test.go | 61 +-- .../security/groups/testing/requests_test.go | 40 +- .../security/rules/testing/requests_test.go | 60 +-- .../subnetpools/testing/requests_test.go | 40 +- .../v2/extensions/testing/delegate_test.go | 16 +- .../trunk_details/testing/requests_test.go | 8 +- .../trunks/testing/requests_test.go | 74 ++-- .../vlantransparent/testing/requests_test.go | 32 +- .../endpointgroups/testing/requests_test.go | 40 +- .../ikepolicies/testing/requests_test.go | 40 +- .../ipsecpolicies/testing/requests_test.go | 40 +- .../vpnaas/services/testing/requests_test.go | 40 +- .../siteconnections/testing/requests_test.go | 40 +- .../v2/networks/testing/requests_test.go | 92 ++--- .../v2/ports/testing/requests_test.go | 204 +++++----- .../v2/subnets/testing/requests_test.go | 142 +++---- .../v1/accounts/testing/fixtures.go | 12 +- .../v1/accounts/testing/requests_test.go | 24 +- .../v1/containers/testing/fixtures.go | 36 +- .../v1/containers/testing/requests_test.go | 128 +++--- .../v1/objects/testing/fixtures_test.go | 52 +-- .../v1/objects/testing/requests_test.go | 228 ++++++----- .../v1/swauth/testing/fixtures_test.go | 4 +- .../v1/swauth/testing/requests_test.go | 8 +- .../v1/apiversions/testing/requests_test.go | 16 +- .../v1/buildinfo/testing/fixtures_test.go | 4 +- .../v1/buildinfo/testing/requests_test.go | 8 +- .../v1/resourcetypes/testing/fixtures_test.go | 12 +- .../v1/resourcetypes/testing/requests_test.go | 40 +- .../v1/stackevents/testing/fixtures_test.go | 16 +- .../v1/stackevents/testing/requests_test.go | 32 +- .../stackresources/testing/fixtures_test.go | 32 +- .../stackresources/testing/requests_test.go | 64 +-- .../v1/stacks/environment_test.go | 10 +- .../orchestration/v1/stacks/template_test.go | 26 +- .../v1/stacks/testing/fixtures_test.go | 36 +- .../v1/stacks/testing/requests_test.go | 96 ++--- .../orchestration/v1/stacks/utils_test.go | 11 +- .../stacktemplates/testing/fixtures_test.go | 8 +- .../stacktemplates/testing/requests_test.go | 16 +- .../testing/fixtures_test.go | 36 +- .../testing/requests_test.go | 72 ++-- .../apiversions/testing/fixtures_test.go | 16 +- .../apiversions/testing/requests_test.go | 32 +- .../testing/fixtures_test.go | 4 +- .../testing/requests_test.go | 8 +- .../v2/errors/testing/fixtures_test.go | 4 +- .../v2/errors/testing/request_test.go | 8 +- .../v2/messages/testing/fixtures_test.go | 16 +- .../v2/messages/testing/requests_test.go | 32 +- .../v2/replicas/testing/fixtures_test.go | 48 +-- .../v2/replicas/testing/request_test.go | 100 ++--- .../schedulerstats/testing/fixtures_test.go | 6 +- .../schedulerstats/testing/requests_test.go | 10 +- .../securityservices/testing/fixtures_test.go | 24 +- .../securityservices/testing/requests_test.go | 54 +-- .../v2/services/testing/fixtures_test.go | 4 +- .../v2/services/testing/requests_test.go | 8 +- .../shareaccessrules/testing/fixtures_test.go | 4 +- .../shareaccessrules/testing/requests_test.go | 12 +- .../v2/sharenetworks/testing/fixtures_test.go | 36 +- .../v2/sharenetworks/testing/requests_test.go | 72 ++-- .../v2/shares/testing/fixtures_test.go | 84 ++-- .../v2/shares/testing/request_test.go | 168 ++++---- .../sharetransfers/testing/fixtures_test.go | 24 +- .../sharetransfers/testing/requests_test.go | 56 +-- .../v2/sharetypes/testing/fixtures_test.go | 40 +- .../v2/sharetypes/testing/requests_test.go | 88 ++-- .../v2/snapshots/testing/fixtures_test.go | 28 +- .../v2/snapshots/testing/request_test.go | 56 +-- openstack/testing/client_test.go | 36 +- .../utils/testing/choose_version_test.go | 72 ++-- .../v2/crontriggers/testing/requests_test.go | 34 +- .../v2/executions/testing/requests_test.go | 34 +- openstack/workflow/v2/workflows/doc.go | 2 +- .../v2/workflows/testing/requests_test.go | 34 +- pagination/testing/linked_test.go | 30 +- pagination/testing/marker_test.go | 22 +- pagination/testing/single_test.go | 21 +- testhelper/client/fake.go | 4 +- testhelper/fixture/helper.go | 4 +- testhelper/http_responses.go | 62 +-- testing/provider_client_test.go | 88 ++-- testing/service_client_test.go | 8 +- 341 files changed, 7207 insertions(+), 7184 deletions(-) diff --git a/docs/contributor-tutorial/.template/testing/requests_test.go b/docs/contributor-tutorial/.template/testing/requests_test.go index c1766d8624..f325d204de 100644 --- a/docs/contributor-tutorial/.template/testing/requests_test.go +++ b/docs/contributor-tutorial/.template/testing/requests_test.go @@ -16,7 +16,7 @@ func TestListResources(t *testing.T) { HandleListResourcesSuccessfully(t) count := 0 - err := resources.List(client.ServiceClient(), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := resources.List(client.ServiceClient(fakeServer), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := resources.ExtractResources(page) @@ -35,7 +35,7 @@ func TestListResourcesAllPages(t *testing.T) { defer th.TeardownHTTP() HandleListResourcesSuccessfully(t) - allPages, err := resources.List(client.ServiceClient(), nil).AllPages(context.TODO()) + allPages, err := resources.List(client.ServiceClient(fakeServer), nil).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := resources.ExtractResources(allPages) th.AssertNoErr(t, err) @@ -47,7 +47,7 @@ func TestGetResource(t *testing.T) { defer th.TeardownHTTP() HandleGetResourceSuccessfully(t) - actual, err := resources.Get(context.TODO(), client.ServiceClient(), "9fe1d3").Extract() + actual, err := resources.Get(context.TODO(), client.ServiceClient(fakeServer), "9fe1d3").Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, SecondResource, *actual) } @@ -61,7 +61,7 @@ func TestCreateResource(t *testing.T) { Name: "resource two", } - actual, err := resources.Create(context.TODO(), client.ServiceClient(), createOpts).Extract() + actual, err := resources.Create(context.TODO(), client.ServiceClient(fakeServer), createOpts).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, SecondResource, *actual) } @@ -71,7 +71,7 @@ func TestDeleteResource(t *testing.T) { defer th.TeardownHTTP() HandleDeleteResourceSuccessfully(t) - res := resources.Delete(context.TODO(), client.ServiceClient(), "9fe1d3") + res := resources.Delete(context.TODO(), client.ServiceClient(fakeServer), "9fe1d3") th.AssertNoErr(t, res.Err) } @@ -84,7 +84,7 @@ func TestUpdateResource(t *testing.T) { Description: "Staging Resource", } - actual, err := resources.Update(context.TODO(), client.ServiceClient(), "9fe1d3", updateOpts).Extract() + actual, err := resources.Update(context.TODO(), client.ServiceClient(fakeServer), "9fe1d3", updateOpts).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, SecondResourceUpdated, *actual) } diff --git a/openstack/baremetal/apiversions/testing/fixtures_test.go b/openstack/baremetal/apiversions/testing/fixtures_test.go index d0e11553c2..2d799a07c1 100644 --- a/openstack/baremetal/apiversions/testing/fixtures_test.go +++ b/openstack/baremetal/apiversions/testing/fixtures_test.go @@ -81,8 +81,8 @@ var IronicAllAPIVersionResults = apiversions.APIVersions{ }, } -func MockListResponse(t *testing.T) { - th.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { +func MockListResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -93,8 +93,8 @@ func MockListResponse(t *testing.T) { }) } -func MockGetResponse(t *testing.T) { - th.Mux.HandleFunc("/v1/", func(w http.ResponseWriter, r *http.Request) { +func MockGetResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v1/", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/baremetal/apiversions/testing/requests_test.go b/openstack/baremetal/apiversions/testing/requests_test.go index 27d9fa5e22..2a9de065cb 100644 --- a/openstack/baremetal/apiversions/testing/requests_test.go +++ b/openstack/baremetal/apiversions/testing/requests_test.go @@ -10,24 +10,24 @@ import ( ) func TestListAPIVersions(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockListResponse(t) + MockListResponse(t, fakeServer) - actual, err := apiversions.List(context.TODO(), client.ServiceClient()).Extract() + actual, err := apiversions.List(context.TODO(), client.ServiceClient(fakeServer)).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, IronicAllAPIVersionResults, *actual) } func TestGetAPIVersion(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockGetResponse(t) + MockGetResponse(t, fakeServer) - actual, err := apiversions.Get(context.TODO(), client.ServiceClient(), "v1").Extract() + actual, err := apiversions.Get(context.TODO(), client.ServiceClient(fakeServer), "v1").Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, IronicAPIVersion1Result, *actual) diff --git a/openstack/baremetal/v1/allocations/testing/fixtures_test.go b/openstack/baremetal/v1/allocations/testing/fixtures_test.go index 7ee9fa4834..9350437592 100644 --- a/openstack/baremetal/v1/allocations/testing/fixtures_test.go +++ b/openstack/baremetal/v1/allocations/testing/fixtures_test.go @@ -108,8 +108,8 @@ var ( ) // HandleAllocationListSuccessfully sets up the test server to respond to a allocation List request. -func HandleAllocationListSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/allocations", func(w http.ResponseWriter, r *http.Request) { +func HandleAllocationListSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/allocations", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") @@ -132,8 +132,8 @@ func HandleAllocationListSuccessfully(t *testing.T) { // HandleAllocationCreationSuccessfully sets up the test server to respond to a allocation creation request // with a given response. -func HandleAllocationCreationSuccessfully(t *testing.T, response string) { - th.Mux.HandleFunc("/allocations", func(w http.ResponseWriter, r *http.Request) { +func HandleAllocationCreationSuccessfully(t *testing.T, fakeServer th.FakeServer, response string) { + fakeServer.Mux.HandleFunc("/allocations", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, `{ @@ -150,8 +150,8 @@ func HandleAllocationCreationSuccessfully(t *testing.T, response string) { } // HandleAllocationDeletionSuccessfully sets up the test server to respond to a allocation deletion request. -func HandleAllocationDeletionSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/allocations/344a3e2-978a-444e-990a-cbf47c62ef88", func(w http.ResponseWriter, r *http.Request) { +func HandleAllocationDeletionSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/allocations/344a3e2-978a-444e-990a-cbf47c62ef88", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -159,8 +159,8 @@ func HandleAllocationDeletionSuccessfully(t *testing.T) { }) } -func HandleAllocationGetSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/allocations/344a3e2-978a-444e-990a-cbf47c62ef88", func(w http.ResponseWriter, r *http.Request) { +func HandleAllocationGetSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/allocations/344a3e2-978a-444e-990a-cbf47c62ef88", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") diff --git a/openstack/baremetal/v1/allocations/testing/requests_test.go b/openstack/baremetal/v1/allocations/testing/requests_test.go index 2eec2aa51b..c30334eafa 100644 --- a/openstack/baremetal/v1/allocations/testing/requests_test.go +++ b/openstack/baremetal/v1/allocations/testing/requests_test.go @@ -11,12 +11,12 @@ import ( ) func TestListAllocations(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleAllocationListSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleAllocationListSuccessfully(t, fakeServer) pages := 0 - err := allocations.List(client.ServiceClient(), allocations.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := allocations.List(client.ServiceClient(fakeServer), allocations.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := allocations.ExtractAllocations(page) @@ -41,11 +41,11 @@ func TestListAllocations(t *testing.T) { } func TestCreateAllocation(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleAllocationCreationSuccessfully(t, SingleAllocationBody) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleAllocationCreationSuccessfully(t, fakeServer, SingleAllocationBody) - actual, err := allocations.Create(context.TODO(), client.ServiceClient(), allocations.CreateOpts{ + actual, err := allocations.Create(context.TODO(), client.ServiceClient(fakeServer), allocations.CreateOpts{ Name: "allocation-1", ResourceClass: "baremetal", CandidateNodes: []string{"344a3e2-978a-444e-990a-cbf47c62ef88"}, @@ -57,20 +57,20 @@ func TestCreateAllocation(t *testing.T) { } func TestDeleteAllocation(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleAllocationDeletionSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleAllocationDeletionSuccessfully(t, fakeServer) - res := allocations.Delete(context.TODO(), client.ServiceClient(), "344a3e2-978a-444e-990a-cbf47c62ef88") + res := allocations.Delete(context.TODO(), client.ServiceClient(fakeServer), "344a3e2-978a-444e-990a-cbf47c62ef88") th.AssertNoErr(t, res.Err) } func TestGetAllocation(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleAllocationGetSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleAllocationGetSuccessfully(t, fakeServer) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) actual, err := allocations.Get(context.TODO(), c, "344a3e2-978a-444e-990a-cbf47c62ef88").Extract() if err != nil { t.Fatalf("Unexpected Get error: %v", err) diff --git a/openstack/baremetal/v1/conductors/testing/fixtures_test.go b/openstack/baremetal/v1/conductors/testing/fixtures_test.go index fd66a34d4b..4b264fd7e8 100644 --- a/openstack/baremetal/v1/conductors/testing/fixtures_test.go +++ b/openstack/baremetal/v1/conductors/testing/fixtures_test.go @@ -138,8 +138,8 @@ var ( ) // HandleConductorListSuccessfully sets up the test server to respond to a server List request. -func HandleConductorListSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/conductors", func(w http.ResponseWriter, r *http.Request) { +func HandleConductorListSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/conductors", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") @@ -161,8 +161,8 @@ func HandleConductorListSuccessfully(t *testing.T) { } // HandleConductorListDetailSuccessfully sets up the test server to respond to a server List request. -func HandleConductorListDetailSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/conductors", func(w http.ResponseWriter, r *http.Request) { +func HandleConductorListDetailSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/conductors", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") @@ -174,8 +174,8 @@ func HandleConductorListDetailSuccessfully(t *testing.T) { }) } -func HandleConductorGetSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/conductors/1234asdf", func(w http.ResponseWriter, r *http.Request) { +func HandleConductorGetSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/conductors/1234asdf", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") diff --git a/openstack/baremetal/v1/conductors/testing/requests_test.go b/openstack/baremetal/v1/conductors/testing/requests_test.go index 6f6aa518ad..103faf579e 100644 --- a/openstack/baremetal/v1/conductors/testing/requests_test.go +++ b/openstack/baremetal/v1/conductors/testing/requests_test.go @@ -11,12 +11,12 @@ import ( ) func TestListConductors(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleConductorListSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleConductorListSuccessfully(t, fakeServer) pages := 0 - err := conductors.List(client.ServiceClient(), conductors.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := conductors.List(client.ServiceClient(fakeServer), conductors.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := conductors.ExtractConductors(page) @@ -41,12 +41,12 @@ func TestListConductors(t *testing.T) { } func TestListDetailConductors(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleConductorListDetailSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleConductorListDetailSuccessfully(t, fakeServer) pages := 0 - err := conductors.List(client.ServiceClient(), conductors.ListOpts{Detail: true}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := conductors.List(client.ServiceClient(fakeServer), conductors.ListOpts{Detail: true}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := conductors.ExtractConductors(page) @@ -93,11 +93,11 @@ func TestListOpts(t *testing.T) { } func TestGetConductor(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleConductorGetSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleConductorGetSuccessfully(t, fakeServer) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) actual, err := conductors.Get(context.TODO(), c, "1234asdf").Extract() if err != nil { t.Fatalf("Unexpected Get error: %v", err) diff --git a/openstack/baremetal/v1/drivers/testing/fixtures_test.go b/openstack/baremetal/v1/drivers/testing/fixtures_test.go index 6c6d0fcc7e..7fb607fd1f 100644 --- a/openstack/baremetal/v1/drivers/testing/fixtures_test.go +++ b/openstack/baremetal/v1/drivers/testing/fixtures_test.go @@ -368,8 +368,8 @@ var ( ) // HandleListDriversSuccessfully sets up the test server to respond to a drivers ListDrivers request. -func HandleListDriversSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/drivers", func(w http.ResponseWriter, r *http.Request) { +func HandleListDriversSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/drivers", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") @@ -382,8 +382,8 @@ func HandleListDriversSuccessfully(t *testing.T) { } // HandleGetDriverDetailsSuccessfully sets up the test server to respond to a drivers GetDriverDetails request. -func HandleGetDriverDetailsSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/drivers/ipmi", func(w http.ResponseWriter, r *http.Request) { +func HandleGetDriverDetailsSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/drivers/ipmi", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -393,8 +393,8 @@ func HandleGetDriverDetailsSuccessfully(t *testing.T) { } // HandleGetDriverPropertiesSuccessfully sets up the test server to respond to a drivers GetDriverProperties request. -func HandleGetDriverPropertiesSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/drivers/agent_ipmitool/properties", func(w http.ResponseWriter, r *http.Request) { +func HandleGetDriverPropertiesSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/drivers/agent_ipmitool/properties", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -404,8 +404,8 @@ func HandleGetDriverPropertiesSuccessfully(t *testing.T) { } // HandleGetDriverDiskPropertiesSuccessfully sets up the test server to respond to a drivers GetDriverDiskProperties request. -func HandleGetDriverDiskPropertiesSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/drivers/agent_ipmitool/raid/logical_disk_properties", func(w http.ResponseWriter, r *http.Request) { +func HandleGetDriverDiskPropertiesSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/drivers/agent_ipmitool/raid/logical_disk_properties", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") diff --git a/openstack/baremetal/v1/drivers/testing/requests_test.go b/openstack/baremetal/v1/drivers/testing/requests_test.go index f99e3198c0..58d83f27a6 100644 --- a/openstack/baremetal/v1/drivers/testing/requests_test.go +++ b/openstack/baremetal/v1/drivers/testing/requests_test.go @@ -11,12 +11,12 @@ import ( ) func TestListDrivers(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListDriversSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListDriversSuccessfully(t, fakeServer) pages := 0 - err := drivers.ListDrivers(client.ServiceClient(), drivers.ListDriversOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := drivers.ListDrivers(client.ServiceClient(fakeServer), drivers.ListDriversOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := drivers.ExtractDrivers(page) @@ -43,11 +43,11 @@ func TestListDrivers(t *testing.T) { } func TestGetDriverDetails(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetDriverDetailsSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetDriverDetailsSuccessfully(t, fakeServer) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) actual, err := drivers.GetDriverDetails(context.TODO(), c, "ipmi").Extract() if err != nil { t.Fatalf("Unexpected Get error: %v", err) @@ -57,11 +57,11 @@ func TestGetDriverDetails(t *testing.T) { } func TestGetDriverProperties(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetDriverPropertiesSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetDriverPropertiesSuccessfully(t, fakeServer) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) actual, err := drivers.GetDriverProperties(context.TODO(), c, "agent_ipmitool").Extract() if err != nil { t.Fatalf("Unexpected Get error: %v", err) @@ -71,11 +71,11 @@ func TestGetDriverProperties(t *testing.T) { } func TestGetDriverDiskProperties(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetDriverDiskPropertiesSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetDriverDiskPropertiesSuccessfully(t, fakeServer) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) actual, err := drivers.GetDriverDiskProperties(context.TODO(), c, "agent_ipmitool").Extract() if err != nil { t.Fatalf("Unexpected Get error: %v", err) diff --git a/openstack/baremetal/v1/nodes/testing/fixtures_test.go b/openstack/baremetal/v1/nodes/testing/fixtures_test.go index 371a4f00a9..064351ea87 100644 --- a/openstack/baremetal/v1/nodes/testing/fixtures_test.go +++ b/openstack/baremetal/v1/nodes/testing/fixtures_test.go @@ -1419,8 +1419,8 @@ var ( ) // HandleNodeListSuccessfully sets up the test server to respond to a server List request. -func HandleNodeListSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/nodes", func(w http.ResponseWriter, r *http.Request) { +func HandleNodeListSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/nodes", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") @@ -1442,8 +1442,8 @@ func HandleNodeListSuccessfully(t *testing.T) { } // HandleNodeListSuccessfully sets up the test server to respond to a server List request. -func HandleNodeListDetailSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/nodes/detail", func(w http.ResponseWriter, r *http.Request) { +func HandleNodeListDetailSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/nodes/detail", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") @@ -1457,8 +1457,8 @@ func HandleNodeListDetailSuccessfully(t *testing.T) { // HandleServerCreationSuccessfully sets up the test server to respond to a server creation request // with a given response. -func HandleNodeCreationSuccessfully(t *testing.T, response string) { - th.Mux.HandleFunc("/nodes", func(w http.ResponseWriter, r *http.Request) { +func HandleNodeCreationSuccessfully(t *testing.T, fakeServer th.FakeServer, response string) { + fakeServer.Mux.HandleFunc("/nodes", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, `{ @@ -1483,8 +1483,8 @@ func HandleNodeCreationSuccessfully(t *testing.T, response string) { } // HandleNodeDeletionSuccessfully sets up the test server to respond to a server deletion request. -func HandleNodeDeletionSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/nodes/asdfasdfasdf", func(w http.ResponseWriter, r *http.Request) { +func HandleNodeDeletionSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/nodes/asdfasdfasdf", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -1492,8 +1492,8 @@ func HandleNodeDeletionSuccessfully(t *testing.T) { }) } -func HandleNodeGetSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/nodes/1234asdf", func(w http.ResponseWriter, r *http.Request) { +func HandleNodeGetSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/nodes/1234asdf", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -1502,8 +1502,8 @@ func HandleNodeGetSuccessfully(t *testing.T) { }) } -func HandleNodeUpdateSuccessfully(t *testing.T, response string) { - th.Mux.HandleFunc("/nodes/1234asdf", func(w http.ResponseWriter, r *http.Request) { +func HandleNodeUpdateSuccessfully(t *testing.T, fakeServer th.FakeServer, response string) { + fakeServer.Mux.HandleFunc("/nodes/1234asdf", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PATCH") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -1514,8 +1514,8 @@ func HandleNodeUpdateSuccessfully(t *testing.T, response string) { }) } -func HandleNodeValidateSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/nodes/1234asdf/validate", func(w http.ResponseWriter, r *http.Request) { +func HandleNodeValidateSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/nodes/1234asdf/validate", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -1525,8 +1525,8 @@ func HandleNodeValidateSuccessfully(t *testing.T) { } // HandleInjectNMISuccessfully sets up the test server to respond to a node InjectNMI request -func HandleInjectNMISuccessfully(t *testing.T) { - th.Mux.HandleFunc("/nodes/1234asdf/management/inject_nmi", func(w http.ResponseWriter, r *http.Request) { +func HandleInjectNMISuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/nodes/1234asdf/management/inject_nmi", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, "{}") @@ -1536,8 +1536,8 @@ func HandleInjectNMISuccessfully(t *testing.T) { } // HandleSetBootDeviceSuccessfully sets up the test server to respond to a set boot device request for a node -func HandleSetBootDeviceSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/nodes/1234asdf/management/boot_device", func(w http.ResponseWriter, r *http.Request) { +func HandleSetBootDeviceSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/nodes/1234asdf/management/boot_device", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, NodeBootDeviceBody) @@ -1547,8 +1547,8 @@ func HandleSetBootDeviceSuccessfully(t *testing.T) { } // HandleGetBootDeviceSuccessfully sets up the test server to respond to a get boot device request for a node -func HandleGetBootDeviceSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/nodes/1234asdf/management/boot_device", func(w http.ResponseWriter, r *http.Request) { +func HandleGetBootDeviceSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/nodes/1234asdf/management/boot_device", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusOK) @@ -1557,8 +1557,8 @@ func HandleGetBootDeviceSuccessfully(t *testing.T) { } // HandleGetBootDeviceSuccessfully sets up the test server to respond to a get boot device request for a node -func HandleGetSupportedBootDeviceSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/nodes/1234asdf/management/boot_device/supported", func(w http.ResponseWriter, r *http.Request) { +func HandleGetSupportedBootDeviceSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/nodes/1234asdf/management/boot_device/supported", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusOK) @@ -1566,8 +1566,8 @@ func HandleGetSupportedBootDeviceSuccessfully(t *testing.T) { }) } -func HandleNodeChangeProvisionStateActive(t *testing.T) { - th.Mux.HandleFunc("/nodes/1234asdf/states/provision", func(w http.ResponseWriter, r *http.Request) { +func HandleNodeChangeProvisionStateActive(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/nodes/1234asdf/states/provision", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, NodeProvisionStateActiveBody) @@ -1575,8 +1575,8 @@ func HandleNodeChangeProvisionStateActive(t *testing.T) { }) } -func HandleNodeChangeProvisionStateActiveWithSteps(t *testing.T) { - th.Mux.HandleFunc("/nodes/1234asdf/states/provision", func(w http.ResponseWriter, r *http.Request) { +func HandleNodeChangeProvisionStateActiveWithSteps(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/nodes/1234asdf/states/provision", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, NodeProvisionStateActiveBodyWithSteps) @@ -1584,8 +1584,8 @@ func HandleNodeChangeProvisionStateActiveWithSteps(t *testing.T) { }) } -func HandleNodeChangeProvisionStateClean(t *testing.T) { - th.Mux.HandleFunc("/nodes/1234asdf/states/provision", func(w http.ResponseWriter, r *http.Request) { +func HandleNodeChangeProvisionStateClean(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/nodes/1234asdf/states/provision", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, NodeProvisionStateCleanBody) @@ -1593,8 +1593,8 @@ func HandleNodeChangeProvisionStateClean(t *testing.T) { }) } -func HandleNodeChangeProvisionStateCleanWithConflict(t *testing.T) { - th.Mux.HandleFunc("/nodes/1234asdf/states/provision", func(w http.ResponseWriter, r *http.Request) { +func HandleNodeChangeProvisionStateCleanWithConflict(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/nodes/1234asdf/states/provision", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, NodeProvisionStateCleanBody) @@ -1602,8 +1602,8 @@ func HandleNodeChangeProvisionStateCleanWithConflict(t *testing.T) { }) } -func HandleNodeChangeProvisionStateConfigDrive(t *testing.T) { - th.Mux.HandleFunc("/nodes/1234asdf/states/provision", func(w http.ResponseWriter, r *http.Request) { +func HandleNodeChangeProvisionStateConfigDrive(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/nodes/1234asdf/states/provision", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, NodeProvisionStateConfigDriveBody) @@ -1611,8 +1611,8 @@ func HandleNodeChangeProvisionStateConfigDrive(t *testing.T) { }) } -func HandleNodeChangeProvisionStateService(t *testing.T) { - th.Mux.HandleFunc("/nodes/1234asdf/states/provision", func(w http.ResponseWriter, r *http.Request) { +func HandleNodeChangeProvisionStateService(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/nodes/1234asdf/states/provision", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, NodeProvisionStateServiceBody) @@ -1621,8 +1621,8 @@ func HandleNodeChangeProvisionStateService(t *testing.T) { } // HandleChangePowerStateSuccessfully sets up the test server to respond to a change power state request for a node -func HandleChangePowerStateSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/nodes/1234asdf/states/power", func(w http.ResponseWriter, r *http.Request) { +func HandleChangePowerStateSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/nodes/1234asdf/states/power", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, `{ @@ -1635,8 +1635,8 @@ func HandleChangePowerStateSuccessfully(t *testing.T) { } // HandleChangePowerStateWithConflict sets up the test server to respond to a change power state request for a node with a 409 error -func HandleChangePowerStateWithConflict(t *testing.T) { - th.Mux.HandleFunc("/nodes/1234asdf/states/power", func(w http.ResponseWriter, r *http.Request) { +func HandleChangePowerStateWithConflict(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/nodes/1234asdf/states/power", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, `{ @@ -1648,8 +1648,8 @@ func HandleChangePowerStateWithConflict(t *testing.T) { }) } -func HandleSetRAIDConfig(t *testing.T) { - th.Mux.HandleFunc("/nodes/1234asdf/states/raid", func(w http.ResponseWriter, r *http.Request) { +func HandleSetRAIDConfig(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/nodes/1234asdf/states/raid", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, ` @@ -1668,8 +1668,8 @@ func HandleSetRAIDConfig(t *testing.T) { }) } -func HandleSetRAIDConfigMaxSize(t *testing.T) { - th.Mux.HandleFunc("/nodes/1234asdf/states/raid", func(w http.ResponseWriter, r *http.Request) { +func HandleSetRAIDConfigMaxSize(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/nodes/1234asdf/states/raid", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, ` @@ -1688,8 +1688,8 @@ func HandleSetRAIDConfigMaxSize(t *testing.T) { }) } -func HandleListBIOSSettingsSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/nodes/1234asdf/bios", func(w http.ResponseWriter, r *http.Request) { +func HandleListBIOSSettingsSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/nodes/1234asdf/bios", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -1698,8 +1698,8 @@ func HandleListBIOSSettingsSuccessfully(t *testing.T) { }) } -func HandleListDetailBIOSSettingsSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/nodes/1234asdf/bios", func(w http.ResponseWriter, r *http.Request) { +func HandleListDetailBIOSSettingsSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/nodes/1234asdf/bios", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -1708,8 +1708,8 @@ func HandleListDetailBIOSSettingsSuccessfully(t *testing.T) { }) } -func HandleGetBIOSSettingSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/nodes/1234asdf/bios/ProcVirtualization", func(w http.ResponseWriter, r *http.Request) { +func HandleGetBIOSSettingSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/nodes/1234asdf/bios/ProcVirtualization", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -1718,8 +1718,8 @@ func HandleGetBIOSSettingSuccessfully(t *testing.T) { }) } -func HandleGetVendorPassthruMethodsSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/nodes/1234asdf/vendor_passthru/methods", func(w http.ResponseWriter, r *http.Request) { +func HandleGetVendorPassthruMethodsSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/nodes/1234asdf/vendor_passthru/methods", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -1728,8 +1728,8 @@ func HandleGetVendorPassthruMethodsSuccessfully(t *testing.T) { }) } -func HandleGetAllSubscriptionsVendorPassthruSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/nodes/1234asdf/vendor_passthru", func(w http.ResponseWriter, r *http.Request) { +func HandleGetAllSubscriptionsVendorPassthruSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/nodes/1234asdf/vendor_passthru", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -1739,8 +1739,8 @@ func HandleGetAllSubscriptionsVendorPassthruSuccessfully(t *testing.T) { }) } -func HandleGetSubscriptionVendorPassthruSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/nodes/1234asdf/vendor_passthru", func(w http.ResponseWriter, r *http.Request) { +func HandleGetSubscriptionVendorPassthruSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/nodes/1234asdf/vendor_passthru", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -1755,8 +1755,8 @@ func HandleGetSubscriptionVendorPassthruSuccessfully(t *testing.T) { }) } -func HandleCreateSubscriptionVendorPassthruAllParametersSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/nodes/1234asdf/vendor_passthru", func(w http.ResponseWriter, r *http.Request) { +func HandleCreateSubscriptionVendorPassthruAllParametersSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/nodes/1234asdf/vendor_passthru", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -1775,8 +1775,8 @@ func HandleCreateSubscriptionVendorPassthruAllParametersSuccessfully(t *testing. }) } -func HandleCreateSubscriptionVendorPassthruRequiredParametersSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/nodes/1234asdf/vendor_passthru", func(w http.ResponseWriter, r *http.Request) { +func HandleCreateSubscriptionVendorPassthruRequiredParametersSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/nodes/1234asdf/vendor_passthru", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -1791,8 +1791,8 @@ func HandleCreateSubscriptionVendorPassthruRequiredParametersSuccessfully(t *tes }) } -func HandleDeleteSubscriptionVendorPassthruSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/nodes/1234asdf/vendor_passthru", func(w http.ResponseWriter, r *http.Request) { +func HandleDeleteSubscriptionVendorPassthruSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/nodes/1234asdf/vendor_passthru", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -1807,8 +1807,8 @@ func HandleDeleteSubscriptionVendorPassthruSuccessfully(t *testing.T) { }) } -func HandleSetNodeMaintenanceSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/nodes/1234asdf/maintenance", func(w http.ResponseWriter, r *http.Request) { +func HandleSetNodeMaintenanceSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/nodes/1234asdf/maintenance", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, NodeSetMaintenanceBody) @@ -1817,8 +1817,8 @@ func HandleSetNodeMaintenanceSuccessfully(t *testing.T) { }) } -func HandleUnsetNodeMaintenanceSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/nodes/1234asdf/maintenance", func(w http.ResponseWriter, r *http.Request) { +func HandleUnsetNodeMaintenanceSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/nodes/1234asdf/maintenance", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -1827,8 +1827,8 @@ func HandleUnsetNodeMaintenanceSuccessfully(t *testing.T) { } // HandleGetInventorySuccessfully sets up the test server to respond to a get inventory request for a node -func HandleGetInventorySuccessfully(t *testing.T) { - th.Mux.HandleFunc("/nodes/1234asdf/inventory", func(w http.ResponseWriter, r *http.Request) { +func HandleGetInventorySuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/nodes/1234asdf/inventory", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusOK) @@ -1837,8 +1837,8 @@ func HandleGetInventorySuccessfully(t *testing.T) { } // HandleListFirmware -func HandleListFirmwareSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/nodes/1234asdf/firmware", func(w http.ResponseWriter, r *http.Request) { +func HandleListFirmwareSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/nodes/1234asdf/firmware", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusOK) @@ -1846,8 +1846,8 @@ func HandleListFirmwareSuccessfully(t *testing.T) { }) } -func HandleAttachVirtualMediaSuccessfully(t *testing.T, withSource bool) { - th.Mux.HandleFunc("/nodes/1234asdf/vmedia", func(w http.ResponseWriter, r *http.Request) { +func HandleAttachVirtualMediaSuccessfully(t *testing.T, fakeServer th.FakeServer, withSource bool) { + fakeServer.Mux.HandleFunc("/nodes/1234asdf/vmedia", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) if withSource { @@ -1859,8 +1859,8 @@ func HandleAttachVirtualMediaSuccessfully(t *testing.T, withSource bool) { }) } -func HandleDetachVirtualMediaSuccessfully(t *testing.T, withType bool) { - th.Mux.HandleFunc("/nodes/1234asdf/vmedia", func(w http.ResponseWriter, r *http.Request) { +func HandleDetachVirtualMediaSuccessfully(t *testing.T, fakeServer th.FakeServer, withType bool) { + fakeServer.Mux.HandleFunc("/nodes/1234asdf/vmedia", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) if withType { @@ -1872,8 +1872,8 @@ func HandleDetachVirtualMediaSuccessfully(t *testing.T, withType bool) { }) } -func HandleGetVirtualMediaSuccessfully(t *testing.T, attached bool) { - th.Mux.HandleFunc("/nodes/1234asdf/vmedia", func(w http.ResponseWriter, r *http.Request) { +func HandleGetVirtualMediaSuccessfully(t *testing.T, fakeServer th.FakeServer, attached bool) { + fakeServer.Mux.HandleFunc("/nodes/1234asdf/vmedia", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusOK) @@ -1886,8 +1886,8 @@ func HandleGetVirtualMediaSuccessfully(t *testing.T, attached bool) { } // HandleListVirtualInterfacesSuccessfully sets up the test server to respond to a ListVirtualInterfaces request -func HandleListVirtualInterfacesSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/nodes/1234asdf/vifs", +func HandleListVirtualInterfacesSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/nodes/1234asdf/vifs", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -1907,8 +1907,8 @@ func HandleListVirtualInterfacesSuccessfully(t *testing.T) { } // HandleAttachVirtualInterfaceSuccessfully sets up the test server to respond to an AttachVirtualInterface request -func HandleAttachVirtualInterfaceSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/nodes/1234asdf/vifs", +func HandleAttachVirtualInterfaceSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/nodes/1234asdf/vifs", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -1921,8 +1921,8 @@ func HandleAttachVirtualInterfaceSuccessfully(t *testing.T) { } // HandleAttachVirtualInterfaceWithPortSuccessfully sets up the test server to respond to an AttachVirtualInterface request with port -func HandleAttachVirtualInterfaceWithPortSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/nodes/1234asdf/vifs", +func HandleAttachVirtualInterfaceWithPortSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/nodes/1234asdf/vifs", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -1935,8 +1935,8 @@ func HandleAttachVirtualInterfaceWithPortSuccessfully(t *testing.T) { } // HandleAttachVirtualInterfaceWithPortgroupSuccessfully sets up the test server to respond to an AttachVirtualInterface request with portgroup -func HandleAttachVirtualInterfaceWithPortgroupSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/nodes/1234asdf/vifs", +func HandleAttachVirtualInterfaceWithPortgroupSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/nodes/1234asdf/vifs", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -1949,8 +1949,8 @@ func HandleAttachVirtualInterfaceWithPortgroupSuccessfully(t *testing.T) { } // HandleDetachVirtualInterfaceSuccessfully sets up the test server to respond to a DetachVirtualInterface request -func HandleDetachVirtualInterfaceSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/nodes/1234asdf/vifs/1974dcfa-836f-41b2-b541-686c100900e5", +func HandleDetachVirtualInterfaceSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/nodes/1234asdf/vifs/1974dcfa-836f-41b2-b541-686c100900e5", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/baremetal/v1/nodes/testing/requests_test.go b/openstack/baremetal/v1/nodes/testing/requests_test.go index 1313725499..c881cfba80 100644 --- a/openstack/baremetal/v1/nodes/testing/requests_test.go +++ b/openstack/baremetal/v1/nodes/testing/requests_test.go @@ -13,12 +13,12 @@ import ( ) func TestListDetailNodes(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleNodeListDetailSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleNodeListDetailSuccessfully(t, fakeServer) pages := 0 - err := nodes.ListDetail(client.ServiceClient(), nodes.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := nodes.ListDetail(client.ServiceClient(fakeServer), nodes.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := nodes.ExtractNodes(page) @@ -44,12 +44,12 @@ func TestListDetailNodes(t *testing.T) { } func TestListNodes(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleNodeListSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleNodeListSuccessfully(t, fakeServer) pages := 0 - err := nodes.List(client.ServiceClient(), nodes.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := nodes.List(client.ServiceClient(fakeServer), nodes.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := nodes.ExtractNodes(page) @@ -90,11 +90,11 @@ func TestListOpts(t *testing.T) { } func TestCreateNode(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleNodeCreationSuccessfully(t, SingleNodeBody) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleNodeCreationSuccessfully(t, fakeServer, SingleNodeBody) - actual, err := nodes.Create(context.TODO(), client.ServiceClient(), nodes.CreateOpts{ + actual, err := nodes.Create(context.TODO(), client.ServiceClient(fakeServer), nodes.CreateOpts{ Name: "foo", Driver: "ipmi", BootInterface: "pxe", @@ -114,20 +114,20 @@ func TestCreateNode(t *testing.T) { } func TestDeleteNode(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleNodeDeletionSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleNodeDeletionSuccessfully(t, fakeServer) - res := nodes.Delete(context.TODO(), client.ServiceClient(), "asdfasdfasdf") + res := nodes.Delete(context.TODO(), client.ServiceClient(fakeServer), "asdfasdfasdf") th.AssertNoErr(t, res.Err) } func TestGetNode(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleNodeGetSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleNodeGetSuccessfully(t, fakeServer) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) actual, err := nodes.Get(context.TODO(), c, "1234asdf").Extract() if err != nil { t.Fatalf("Unexpected Get error: %v", err) @@ -137,11 +137,11 @@ func TestGetNode(t *testing.T) { } func TestUpdateNode(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleNodeUpdateSuccessfully(t, SingleNodeBody) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleNodeUpdateSuccessfully(t, fakeServer, SingleNodeBody) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) actual, err := nodes.Update(context.TODO(), c, "1234asdf", nodes.UpdateOpts{ nodes.UpdateOperation{ Op: nodes.ReplaceOp, @@ -159,10 +159,10 @@ func TestUpdateNode(t *testing.T) { } func TestUpdateRequiredOp(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) _, err := nodes.Update(context.TODO(), c, "1234asdf", nodes.UpdateOpts{ nodes.UpdateOperation{ Path: "/driver", @@ -177,10 +177,10 @@ func TestUpdateRequiredOp(t *testing.T) { } func TestUpdateRequiredPath(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) _, err := nodes.Update(context.TODO(), c, "1234asdf", nodes.UpdateOpts{ nodes.UpdateOperation{ Op: nodes.ReplaceOp, @@ -194,32 +194,32 @@ func TestUpdateRequiredPath(t *testing.T) { } func TestValidateNode(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleNodeValidateSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleNodeValidateSuccessfully(t, fakeServer) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) actual, err := nodes.Validate(context.TODO(), c, "1234asdf").Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, NodeFooValidation, *actual) } func TestInjectNMI(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleInjectNMISuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleInjectNMISuccessfully(t, fakeServer) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) err := nodes.InjectNMI(context.TODO(), c, "1234asdf").ExtractErr() th.AssertNoErr(t, err) } func TestSetBootDevice(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleSetBootDeviceSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleSetBootDeviceSuccessfully(t, fakeServer) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) err := nodes.SetBootDevice(context.TODO(), c, "1234asdf", nodes.BootDeviceOpts{ BootDevice: "pxe", Persistent: false, @@ -228,33 +228,33 @@ func TestSetBootDevice(t *testing.T) { } func TestGetBootDevice(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetBootDeviceSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetBootDeviceSuccessfully(t, fakeServer) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) bootDevice, err := nodes.GetBootDevice(context.TODO(), c, "1234asdf").Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, NodeBootDevice, *bootDevice) } func TestGetSupportedBootDevices(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetSupportedBootDeviceSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetSupportedBootDeviceSuccessfully(t, fakeServer) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) bootDevices, err := nodes.GetSupportedBootDevices(context.TODO(), c, "1234asdf").Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, NodeSupportedBootDevice, bootDevices) } func TestNodeChangeProvisionStateActive(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleNodeChangeProvisionStateActive(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleNodeChangeProvisionStateActive(t, fakeServer) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) err := nodes.ChangeProvisionState(context.TODO(), c, "1234asdf", nodes.ProvisionStateOpts{ Target: nodes.TargetActive, ConfigDrive: "http://127.0.0.1/images/test-node-config-drive.iso.gz", @@ -264,11 +264,11 @@ func TestNodeChangeProvisionStateActive(t *testing.T) { } func TestNodeChangeProvisionStateActiveWithSteps(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleNodeChangeProvisionStateActiveWithSteps(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleNodeChangeProvisionStateActiveWithSteps(t, fakeServer) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) err := nodes.ChangeProvisionState(context.TODO(), c, "1234asdf", nodes.ProvisionStateOpts{ Target: nodes.TargetActive, DeploySteps: []nodes.DeployStep{ @@ -287,11 +287,11 @@ func TestNodeChangeProvisionStateActiveWithSteps(t *testing.T) { } func TestHandleNodeChangeProvisionStateConfigDrive(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleNodeChangeProvisionStateConfigDrive(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleNodeChangeProvisionStateConfigDrive(t, fakeServer) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) err := nodes.ChangeProvisionState(context.TODO(), c, "1234asdf", nodes.ProvisionStateOpts{ Target: nodes.TargetActive, @@ -302,11 +302,11 @@ func TestHandleNodeChangeProvisionStateConfigDrive(t *testing.T) { } func TestNodeChangeProvisionStateClean(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleNodeChangeProvisionStateClean(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleNodeChangeProvisionStateClean(t, fakeServer) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) err := nodes.ChangeProvisionState(context.TODO(), c, "1234asdf", nodes.ProvisionStateOpts{ Target: nodes.TargetClean, CleanSteps: []nodes.CleanStep{ @@ -324,11 +324,11 @@ func TestNodeChangeProvisionStateClean(t *testing.T) { } func TestNodeChangeProvisionStateCleanWithConflict(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleNodeChangeProvisionStateCleanWithConflict(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleNodeChangeProvisionStateCleanWithConflict(t, fakeServer) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) err := nodes.ChangeProvisionState(context.TODO(), c, "1234asdf", nodes.ProvisionStateOpts{ Target: nodes.TargetClean, CleanSteps: []nodes.CleanStep{ @@ -348,10 +348,10 @@ func TestNodeChangeProvisionStateCleanWithConflict(t *testing.T) { } func TestCleanStepRequiresInterface(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) err := nodes.ChangeProvisionState(context.TODO(), c, "1234asdf", nodes.ProvisionStateOpts{ Target: nodes.TargetClean, CleanSteps: []nodes.CleanStep{ @@ -370,10 +370,10 @@ func TestCleanStepRequiresInterface(t *testing.T) { } func TestCleanStepRequiresStep(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) err := nodes.ChangeProvisionState(context.TODO(), c, "1234asdf", nodes.ProvisionStateOpts{ Target: nodes.TargetClean, CleanSteps: []nodes.CleanStep{ @@ -392,11 +392,11 @@ func TestCleanStepRequiresStep(t *testing.T) { } func TestNodeChangeProvisionStateService(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleNodeChangeProvisionStateService(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleNodeChangeProvisionStateService(t, fakeServer) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) err := nodes.ChangeProvisionState(context.TODO(), c, "1234asdf", nodes.ProvisionStateOpts{ Target: nodes.TargetService, ServiceSteps: []nodes.ServiceStep{ @@ -414,31 +414,31 @@ func TestNodeChangeProvisionStateService(t *testing.T) { } func TestChangePowerState(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleChangePowerStateSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleChangePowerStateSuccessfully(t, fakeServer) opts := nodes.PowerStateOpts{ Target: nodes.PowerOn, Timeout: 100, } - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) err := nodes.ChangePowerState(context.TODO(), c, "1234asdf", opts).ExtractErr() th.AssertNoErr(t, err) } func TestChangePowerStateWithConflict(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleChangePowerStateWithConflict(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleChangePowerStateWithConflict(t, fakeServer) opts := nodes.PowerStateOpts{ Target: nodes.PowerOn, Timeout: 100, } - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) err := nodes.ChangePowerState(context.TODO(), c, "1234asdf", opts).ExtractErr() if !gophercloud.ResponseCodeIs(err, http.StatusConflict) { t.Fatalf("expected 409 response, but got %s", err.Error()) @@ -446,9 +446,9 @@ func TestChangePowerStateWithConflict(t *testing.T) { } func TestSetRAIDConfig(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleSetRAIDConfig(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleSetRAIDConfig(t, fakeServer) sizeGB := 100 isRootVolume := true @@ -463,16 +463,16 @@ func TestSetRAIDConfig(t *testing.T) { }, } - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) err := nodes.SetRAIDConfig(context.TODO(), c, "1234asdf", config).ExtractErr() th.AssertNoErr(t, err) } // Without specifying a size, we need to send a string: "MAX" func TestSetRAIDConfigMaxSize(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleSetRAIDConfigMaxSize(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleSetRAIDConfigMaxSize(t, fakeServer) isRootVolume := true @@ -485,7 +485,7 @@ func TestSetRAIDConfigMaxSize(t *testing.T) { }, } - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) err := nodes.SetRAIDConfig(context.TODO(), c, "1234asdf", config).ExtractErr() th.AssertNoErr(t, err) } @@ -583,37 +583,37 @@ func TestToRAIDConfigMap(t *testing.T) { } func TestListBIOSSettings(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListBIOSSettingsSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListBIOSSettingsSuccessfully(t, fakeServer) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) actual, err := nodes.ListBIOSSettings(context.TODO(), c, "1234asdf", nil).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, NodeBIOSSettings, actual) } func TestListDetailBIOSSettings(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListDetailBIOSSettingsSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListDetailBIOSSettingsSuccessfully(t, fakeServer) opts := nodes.ListBIOSSettingsOpts{ Detail: true, } - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) actual, err := nodes.ListBIOSSettings(context.TODO(), c, "1234asdf", opts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, NodeDetailBIOSSettings, actual) } func TestGetBIOSSetting(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetBIOSSettingSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetBIOSSettingSuccessfully(t, fakeServer) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) actual, err := nodes.GetBIOSSetting(context.TODO(), c, "1234asdf", "ProcVirtualization").Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, NodeSingleBIOSSetting, *actual) @@ -631,22 +631,22 @@ func TestListBIOSSettingsOpts(t *testing.T) { } func TestGetVendorPassthruMethods(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetVendorPassthruMethodsSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetVendorPassthruMethodsSuccessfully(t, fakeServer) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) actual, err := nodes.GetVendorPassthruMethods(context.TODO(), c, "1234asdf").Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, NodeVendorPassthruMethods, *actual) } func TestGetAllSubscriptions(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetAllSubscriptionsVendorPassthruSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetAllSubscriptionsVendorPassthruSuccessfully(t, fakeServer) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) method := nodes.CallVendorPassthruOpts{ Method: "get_all_subscriptions", } @@ -656,11 +656,11 @@ func TestGetAllSubscriptions(t *testing.T) { } func TestGetSubscription(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetSubscriptionVendorPassthruSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetSubscriptionVendorPassthruSuccessfully(t, fakeServer) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) method := nodes.CallVendorPassthruOpts{ Method: "get_subscription", } @@ -673,11 +673,11 @@ func TestGetSubscription(t *testing.T) { } func TestCreateSubscriptionAllParameters(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateSubscriptionVendorPassthruAllParametersSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCreateSubscriptionVendorPassthruAllParametersSuccessfully(t, fakeServer) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) method := nodes.CallVendorPassthruOpts{ Method: "create_subscription", } @@ -694,11 +694,11 @@ func TestCreateSubscriptionAllParameters(t *testing.T) { } func TestCreateSubscriptionWithRequiredParameters(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateSubscriptionVendorPassthruRequiredParametersSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCreateSubscriptionVendorPassthruRequiredParametersSuccessfully(t, fakeServer) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) method := nodes.CallVendorPassthruOpts{ Method: "create_subscription", } @@ -711,11 +711,11 @@ func TestCreateSubscriptionWithRequiredParameters(t *testing.T) { } func TestDeleteSubscription(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDeleteSubscriptionVendorPassthruSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDeleteSubscriptionVendorPassthruSuccessfully(t, fakeServer) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) method := nodes.CallVendorPassthruOpts{ Method: "delete_subscription", } @@ -727,11 +727,11 @@ func TestDeleteSubscription(t *testing.T) { } func TestSetMaintenance(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleSetNodeMaintenanceSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleSetNodeMaintenanceSuccessfully(t, fakeServer) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) err := nodes.SetMaintenance(context.TODO(), c, "1234asdf", nodes.MaintenanceOpts{ Reason: "I'm tired", }).ExtractErr() @@ -739,21 +739,21 @@ func TestSetMaintenance(t *testing.T) { } func TestUnsetMaintenance(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleUnsetNodeMaintenanceSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleUnsetNodeMaintenanceSuccessfully(t, fakeServer) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) err := nodes.UnsetMaintenance(context.TODO(), c, "1234asdf").ExtractErr() th.AssertNoErr(t, err) } func TestGetInventory(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetInventorySuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetInventorySuccessfully(t, fakeServer) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) actual, err := nodes.GetInventory(context.TODO(), c, "1234asdf").Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, NodeInventoryData.Inventory, actual.Inventory) @@ -768,11 +768,11 @@ func TestGetInventory(t *testing.T) { } func TestListFirmware(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListFirmwareSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListFirmwareSuccessfully(t, fakeServer) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) actual, err := nodes.ListFirmware(context.TODO(), c, "1234asdf").Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, NodeFirmwareList, actual) @@ -790,11 +790,11 @@ func TestVirtualMediaOpts(t *testing.T) { } func TestVirtualMediaAttach(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleAttachVirtualMediaSuccessfully(t, false) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleAttachVirtualMediaSuccessfully(t, fakeServer, false) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) opts := nodes.AttachVirtualMediaOpts{ ImageURL: "https://example.com/image", DeviceType: nodes.VirtualMediaCD, @@ -804,11 +804,11 @@ func TestVirtualMediaAttach(t *testing.T) { } func TestVirtualMediaAttachWithSource(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleAttachVirtualMediaSuccessfully(t, true) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleAttachVirtualMediaSuccessfully(t, fakeServer, true) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) opts := nodes.AttachVirtualMediaOpts{ ImageURL: "https://example.com/image", DeviceType: nodes.VirtualMediaCD, @@ -819,21 +819,21 @@ func TestVirtualMediaAttachWithSource(t *testing.T) { } func TestVirtualMediaDetach(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDetachVirtualMediaSuccessfully(t, false) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDetachVirtualMediaSuccessfully(t, fakeServer, false) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) err := nodes.DetachVirtualMedia(context.TODO(), c, "1234asdf", nodes.DetachVirtualMediaOpts{}).ExtractErr() th.AssertNoErr(t, err) } func TestVirtualMediaDetachWithTypes(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDetachVirtualMediaSuccessfully(t, true) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDetachVirtualMediaSuccessfully(t, fakeServer, true) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) opts := nodes.DetachVirtualMediaOpts{ DeviceTypes: []nodes.VirtualMediaDeviceType{nodes.VirtualMediaCD}, } @@ -842,31 +842,31 @@ func TestVirtualMediaDetachWithTypes(t *testing.T) { } func TestVirtualMediaGetAttached(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetVirtualMediaSuccessfully(t, true) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetVirtualMediaSuccessfully(t, fakeServer, true) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) err := nodes.GetVirtualMedia(context.TODO(), c, "1234asdf").Err th.AssertNoErr(t, err) } func TestVirtualMediaGetNotAttached(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetVirtualMediaSuccessfully(t, false) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetVirtualMediaSuccessfully(t, fakeServer, false) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) err := nodes.GetVirtualMedia(context.TODO(), c, "1234asdf").Err th.AssertNoErr(t, err) } func TestListVirtualInterfaces(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListVirtualInterfacesSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListVirtualInterfacesSuccessfully(t, fakeServer) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) actual, err := nodes.ListVirtualInterfaces(context.TODO(), c, "1234asdf").Extract() th.AssertNoErr(t, err) @@ -880,11 +880,11 @@ func TestListVirtualInterfaces(t *testing.T) { } func TestAttachVirtualInterface(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleAttachVirtualInterfaceSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleAttachVirtualInterfaceSuccessfully(t, fakeServer) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) opts := nodes.VirtualInterfaceOpts{ ID: "1974dcfa-836f-41b2-b541-686c100900e5", } @@ -893,11 +893,11 @@ func TestAttachVirtualInterface(t *testing.T) { } func TestAttachVirtualInterfaceWithPort(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleAttachVirtualInterfaceWithPortSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleAttachVirtualInterfaceWithPortSuccessfully(t, fakeServer) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) opts := nodes.VirtualInterfaceOpts{ ID: "1974dcfa-836f-41b2-b541-686c100900e5", PortUUID: "b2f96298-5172-45e9-b174-8d1ba936ab47", @@ -907,11 +907,11 @@ func TestAttachVirtualInterfaceWithPort(t *testing.T) { } func TestAttachVirtualInterfaceWithPortgroup(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleAttachVirtualInterfaceWithPortgroupSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleAttachVirtualInterfaceWithPortgroupSuccessfully(t, fakeServer) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) opts := nodes.VirtualInterfaceOpts{ ID: "1974dcfa-836f-41b2-b541-686c100900e5", PortgroupUUID: "c24944b5-a52e-4c5c-9c0a-52a0235a08a2", @@ -921,11 +921,11 @@ func TestAttachVirtualInterfaceWithPortgroup(t *testing.T) { } func TestDetachVirtualInterface(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDetachVirtualInterfaceSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDetachVirtualInterfaceSuccessfully(t, fakeServer) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) err := nodes.DetachVirtualInterface(context.TODO(), c, "1234asdf", "1974dcfa-836f-41b2-b541-686c100900e5").ExtractErr() th.AssertNoErr(t, err) } diff --git a/openstack/baremetal/v1/ports/testing/fixtures_test.go b/openstack/baremetal/v1/ports/testing/fixtures_test.go index a6221ecd4a..0d1ec9cdfa 100644 --- a/openstack/baremetal/v1/ports/testing/fixtures_test.go +++ b/openstack/baremetal/v1/ports/testing/fixtures_test.go @@ -169,8 +169,8 @@ var ( ) // HandlePortListSuccessfully sets up the test server to respond to a port List request. -func HandlePortListSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/ports", func(w http.ResponseWriter, r *http.Request) { +func HandlePortListSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/ports", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") @@ -192,8 +192,8 @@ func HandlePortListSuccessfully(t *testing.T) { } // HandlePortListSuccessfully sets up the test server to respond to a port List request. -func HandlePortListDetailSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/ports/detail", func(w http.ResponseWriter, r *http.Request) { +func HandlePortListDetailSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/ports/detail", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") @@ -207,8 +207,8 @@ func HandlePortListDetailSuccessfully(t *testing.T) { // HandleSPortCreationSuccessfully sets up the test server to respond to a port creation request // with a given response. -func HandlePortCreationSuccessfully(t *testing.T, response string) { - th.Mux.HandleFunc("/ports", func(w http.ResponseWriter, r *http.Request) { +func HandlePortCreationSuccessfully(t *testing.T, fakeServer th.FakeServer, response string) { + fakeServer.Mux.HandleFunc("/ports", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, `{ @@ -224,8 +224,8 @@ func HandlePortCreationSuccessfully(t *testing.T, response string) { } // HandlePortDeletionSuccessfully sets up the test server to respond to a port deletion request. -func HandlePortDeletionSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/ports/3abe3f36-9708-4e9f-b07e-0f898061d3a7", func(w http.ResponseWriter, r *http.Request) { +func HandlePortDeletionSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/ports/3abe3f36-9708-4e9f-b07e-0f898061d3a7", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -233,8 +233,8 @@ func HandlePortDeletionSuccessfully(t *testing.T) { }) } -func HandlePortGetSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/ports/f2845e11-dbd4-4728-a8c0-30d19f48924a", func(w http.ResponseWriter, r *http.Request) { +func HandlePortGetSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/ports/f2845e11-dbd4-4728-a8c0-30d19f48924a", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -243,8 +243,8 @@ func HandlePortGetSuccessfully(t *testing.T) { }) } -func HandlePortUpdateSuccessfully(t *testing.T, response string) { - th.Mux.HandleFunc("/ports/f2845e11-dbd4-4728-a8c0-30d19f48924a", func(w http.ResponseWriter, r *http.Request) { +func HandlePortUpdateSuccessfully(t *testing.T, fakeServer th.FakeServer, response string) { + fakeServer.Mux.HandleFunc("/ports/f2845e11-dbd4-4728-a8c0-30d19f48924a", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PATCH") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") diff --git a/openstack/baremetal/v1/ports/testing/requests_test.go b/openstack/baremetal/v1/ports/testing/requests_test.go index b52d3c521c..1d335c24d9 100644 --- a/openstack/baremetal/v1/ports/testing/requests_test.go +++ b/openstack/baremetal/v1/ports/testing/requests_test.go @@ -11,12 +11,12 @@ import ( ) func TestListDetailPorts(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandlePortListDetailSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandlePortListDetailSuccessfully(t, fakeServer) pages := 0 - err := ports.ListDetail(client.ServiceClient(), ports.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := ports.ListDetail(client.ServiceClient(fakeServer), ports.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := ports.ExtractPorts(page) @@ -41,12 +41,12 @@ func TestListDetailPorts(t *testing.T) { } func TestListPorts(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandlePortListSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandlePortListSuccessfully(t, fakeServer) pages := 0 - err := ports.List(client.ServiceClient(), ports.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := ports.List(client.ServiceClient(fakeServer), ports.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := ports.ExtractPorts(page) @@ -86,12 +86,12 @@ func TestListOpts(t *testing.T) { } func TestCreatePort(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandlePortCreationSuccessfully(t, SinglePortBody) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandlePortCreationSuccessfully(t, fakeServer, SinglePortBody) iTrue := true - actual, err := ports.Create(context.TODO(), client.ServiceClient(), ports.CreateOpts{ + actual, err := ports.Create(context.TODO(), client.ServiceClient(fakeServer), ports.CreateOpts{ NodeUUID: "ddd06a60-b91e-4ab4-a6e7-56c0b25b6086", Address: "52:54:00:4d:87:e6", PXEEnabled: &iTrue, @@ -102,20 +102,20 @@ func TestCreatePort(t *testing.T) { } func TestDeletePort(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandlePortDeletionSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandlePortDeletionSuccessfully(t, fakeServer) - res := ports.Delete(context.TODO(), client.ServiceClient(), "3abe3f36-9708-4e9f-b07e-0f898061d3a7") + res := ports.Delete(context.TODO(), client.ServiceClient(fakeServer), "3abe3f36-9708-4e9f-b07e-0f898061d3a7") th.AssertNoErr(t, res.Err) } func TestGetPort(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandlePortGetSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandlePortGetSuccessfully(t, fakeServer) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) actual, err := ports.Get(context.TODO(), c, "f2845e11-dbd4-4728-a8c0-30d19f48924a").Extract() if err != nil { t.Fatalf("Unexpected Get error: %v", err) @@ -125,11 +125,11 @@ func TestGetPort(t *testing.T) { } func TestUpdatePort(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandlePortUpdateSuccessfully(t, SinglePortBody) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandlePortUpdateSuccessfully(t, fakeServer, SinglePortBody) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) actual, err := ports.Update(context.TODO(), c, "f2845e11-dbd4-4728-a8c0-30d19f48924a", ports.UpdateOpts{ ports.UpdateOperation{ Op: ports.ReplaceOp, diff --git a/openstack/baremetalintrospection/v1/introspection/testing/fixtures.go b/openstack/baremetalintrospection/v1/introspection/testing/fixtures.go index 56a4299aef..6170e53036 100644 --- a/openstack/baremetalintrospection/v1/introspection/testing/fixtures.go +++ b/openstack/baremetalintrospection/v1/introspection/testing/fixtures.go @@ -454,8 +454,8 @@ var ( ) // HandleListIntrospectionsSuccessfully sets up the test server to respond to a server ListIntrospections request. -func HandleListIntrospectionsSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/introspection", func(w http.ResponseWriter, r *http.Request) { +func HandleListIntrospectionsSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/introspection", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") @@ -479,8 +479,8 @@ func HandleListIntrospectionsSuccessfully(t *testing.T) { } // HandleGetIntrospectionStatusSuccessfully sets up the test server to respond to a GetIntrospectionStatus request. -func HandleGetIntrospectionStatusSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/introspection/c244557e-899f-46fa-a1ff-5b2c6718616b", func(w http.ResponseWriter, r *http.Request) { +func HandleGetIntrospectionStatusSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/introspection/c244557e-899f-46fa-a1ff-5b2c6718616b", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -489,8 +489,8 @@ func HandleGetIntrospectionStatusSuccessfully(t *testing.T) { } // HandleStartIntrospectionSuccessfully sets up the test server to respond to a StartIntrospection request. -func HandleStartIntrospectionSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/introspection/c244557e-899f-46fa-a1ff-5b2c6718616b", func(w http.ResponseWriter, r *http.Request) { +func HandleStartIntrospectionSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/introspection/c244557e-899f-46fa-a1ff-5b2c6718616b", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusAccepted) @@ -498,8 +498,8 @@ func HandleStartIntrospectionSuccessfully(t *testing.T) { } // HandleAbortIntrospectionSuccessfully sets up the test server to respond to an AbortIntrospection request. -func HandleAbortIntrospectionSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/introspection/c244557e-899f-46fa-a1ff-5b2c6718616b/abort", func(w http.ResponseWriter, r *http.Request) { +func HandleAbortIntrospectionSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/introspection/c244557e-899f-46fa-a1ff-5b2c6718616b/abort", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusAccepted) @@ -507,8 +507,8 @@ func HandleAbortIntrospectionSuccessfully(t *testing.T) { } // HandleGetIntrospectionDataSuccessfully sets up the test server to respond to a GetIntrospectionData request. -func HandleGetIntrospectionDataSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/introspection/c244557e-899f-46fa-a1ff-5b2c6718616b/data", func(w http.ResponseWriter, r *http.Request) { +func HandleGetIntrospectionDataSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/introspection/c244557e-899f-46fa-a1ff-5b2c6718616b/data", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -518,8 +518,8 @@ func HandleGetIntrospectionDataSuccessfully(t *testing.T) { } // HandleReApplyIntrospectionSuccessfully sets up the test server to respond to a ReApplyIntrospection request. -func HandleReApplyIntrospectionSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/introspection/c244557e-899f-46fa-a1ff-5b2c6718616b/data/unprocessed", func(w http.ResponseWriter, r *http.Request) { +func HandleReApplyIntrospectionSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/introspection/c244557e-899f-46fa-a1ff-5b2c6718616b/data/unprocessed", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusAccepted) diff --git a/openstack/baremetalintrospection/v1/introspection/testing/requests_test.go b/openstack/baremetalintrospection/v1/introspection/testing/requests_test.go index b36318ce76..97d788c56d 100644 --- a/openstack/baremetalintrospection/v1/introspection/testing/requests_test.go +++ b/openstack/baremetalintrospection/v1/introspection/testing/requests_test.go @@ -11,12 +11,12 @@ import ( ) func TestListIntrospections(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListIntrospectionsSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListIntrospectionsSuccessfully(t, fakeServer) pages := 0 - err := introspection.ListIntrospections(client.ServiceClient(), introspection.ListIntrospectionsOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := introspection.ListIntrospections(client.ServiceClient(fakeServer), introspection.ListIntrospectionsOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := introspection.ExtractIntrospections(page) @@ -41,11 +41,11 @@ func TestListIntrospections(t *testing.T) { } func TestGetIntrospectionStatus(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetIntrospectionStatusSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetIntrospectionStatusSuccessfully(t, fakeServer) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) actual, err := introspection.GetIntrospectionStatus(context.TODO(), c, "c244557e-899f-46fa-a1ff-5b2c6718616b").Extract() if err != nil { t.Fatalf("Unexpected Get error: %v", err) @@ -55,31 +55,31 @@ func TestGetIntrospectionStatus(t *testing.T) { } func TestStartIntrospection(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleStartIntrospectionSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleStartIntrospectionSuccessfully(t, fakeServer) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) err := introspection.StartIntrospection(context.TODO(), c, "c244557e-899f-46fa-a1ff-5b2c6718616b", introspection.StartOpts{}).ExtractErr() th.AssertNoErr(t, err) } func TestAbortIntrospection(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleAbortIntrospectionSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleAbortIntrospectionSuccessfully(t, fakeServer) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) err := introspection.AbortIntrospection(context.TODO(), c, "c244557e-899f-46fa-a1ff-5b2c6718616b").ExtractErr() th.AssertNoErr(t, err) } func TestGetIntrospectionData(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetIntrospectionDataSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetIntrospectionDataSuccessfully(t, fakeServer) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) actual, err := introspection.GetIntrospectionData(context.TODO(), c, "c244557e-899f-46fa-a1ff-5b2c6718616b").Extract() if err != nil { t.Fatalf("Unexpected Get error: %v", err) @@ -89,11 +89,11 @@ func TestGetIntrospectionData(t *testing.T) { } func TestReApplyIntrospection(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleReApplyIntrospectionSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleReApplyIntrospectionSuccessfully(t, fakeServer) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) err := introspection.ReApplyIntrospection(context.TODO(), c, "c244557e-899f-46fa-a1ff-5b2c6718616b").ExtractErr() th.AssertNoErr(t, err) } diff --git a/openstack/blockstorage/apiversions/testing/fixtures_test.go b/openstack/blockstorage/apiversions/testing/fixtures_test.go index ed78b1e472..d4a34b9bf4 100644 --- a/openstack/blockstorage/apiversions/testing/fixtures_test.go +++ b/openstack/blockstorage/apiversions/testing/fixtures_test.go @@ -116,8 +116,8 @@ const APIListOldResponse = ` ] }` -func MockListResponse(t *testing.T) { - th.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { +func MockListResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -128,8 +128,8 @@ func MockListResponse(t *testing.T) { }) } -func MockListOldResponse(t *testing.T) { - th.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { +func MockListOldResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/blockstorage/apiversions/testing/requests_test.go b/openstack/blockstorage/apiversions/testing/requests_test.go index 1cfcb72e29..ea48e3581c 100644 --- a/openstack/blockstorage/apiversions/testing/requests_test.go +++ b/openstack/blockstorage/apiversions/testing/requests_test.go @@ -11,12 +11,12 @@ import ( ) func TestListVersions(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockListResponse(t) + MockListResponse(t, fakeServer) - allVersions, err := apiversions.List(client.ServiceClient()).AllPages(context.TODO()) + allVersions, err := apiversions.List(client.ServiceClient(fakeServer)).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := apiversions.ExtractAPIVersions(allVersions) th.AssertNoErr(t, err) @@ -45,12 +45,12 @@ func TestListVersions(t *testing.T) { } func TestListOldVersions(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockListOldResponse(t) + MockListOldResponse(t, fakeServer) - allVersions, err := apiversions.List(client.ServiceClient()).AllPages(context.TODO()) + allVersions, err := apiversions.List(client.ServiceClient(fakeServer)).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := apiversions.ExtractAPIVersions(allVersions) th.AssertNoErr(t, err) @@ -72,12 +72,12 @@ func TestListOldVersions(t *testing.T) { } func TestGetVersion(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockListResponse(t) + MockListResponse(t, fakeServer) - allVersions, err := apiversions.List(client.ServiceClient()).AllPages(context.TODO()) + allVersions, err := apiversions.List(client.ServiceClient(fakeServer)).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := apiversions.ExtractAPIVersion(allVersions, "v3.0") th.AssertNoErr(t, err) @@ -96,12 +96,12 @@ func TestGetVersion(t *testing.T) { } func TestGetOldVersion(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockListOldResponse(t) + MockListOldResponse(t, fakeServer) - allVersions, err := apiversions.List(client.ServiceClient()).AllPages(context.TODO()) + allVersions, err := apiversions.List(client.ServiceClient(fakeServer)).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := apiversions.ExtractAPIVersion(allVersions, "v2.0") th.AssertNoErr(t, err) diff --git a/openstack/blockstorage/v2/availabilityzones/testing/fixtures_test.go b/openstack/blockstorage/v2/availabilityzones/testing/fixtures_test.go index 5c48bdce2e..9c29adac94 100644 --- a/openstack/blockstorage/v2/availabilityzones/testing/fixtures_test.go +++ b/openstack/blockstorage/v2/availabilityzones/testing/fixtures_test.go @@ -41,8 +41,8 @@ var AZResult = []az.AvailabilityZone{ // HandleGetSuccessfully configures the test server to respond to a Get request // for availability zone information. -func HandleGetSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/os-availability-zone", func(w http.ResponseWriter, r *http.Request) { +func HandleGetSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/os-availability-zone", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/blockstorage/v2/availabilityzones/testing/requests_test.go b/openstack/blockstorage/v2/availabilityzones/testing/requests_test.go index 4e8e751f45..0873ab6d2b 100644 --- a/openstack/blockstorage/v2/availabilityzones/testing/requests_test.go +++ b/openstack/blockstorage/v2/availabilityzones/testing/requests_test.go @@ -11,12 +11,12 @@ import ( // Verifies that availability zones can be listed correctly func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleGetSuccessfully(t) + HandleGetSuccessfully(t, fakeServer) - allPages, err := az.List(client.ServiceClient()).AllPages(context.TODO()) + allPages, err := az.List(client.ServiceClient(fakeServer)).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := az.ExtractAvailabilityZones(allPages) diff --git a/openstack/blockstorage/v2/backups/testing/fixtures_test.go b/openstack/blockstorage/v2/backups/testing/fixtures_test.go index 8290c17672..f09e16c955 100644 --- a/openstack/blockstorage/v2/backups/testing/fixtures_test.go +++ b/openstack/blockstorage/v2/backups/testing/fixtures_test.go @@ -194,8 +194,8 @@ var ( backupURL, _ = json.Marshal(backupImport) ) -func MockListResponse(t *testing.T) { - th.Mux.HandleFunc("/backups", func(w http.ResponseWriter, r *http.Request) { +func MockListResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/backups", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -208,7 +208,7 @@ func MockListResponse(t *testing.T) { marker := r.Form.Get("marker") switch marker { case "": - fmt.Fprintf(w, ListResponse, th.Server.URL) + fmt.Fprintf(w, ListResponse, fakeServer.Server.URL) case "1": fmt.Fprint(w, `{"backups": []}`) default: @@ -217,8 +217,8 @@ func MockListResponse(t *testing.T) { }) } -func MockListDetailResponse(t *testing.T) { - th.Mux.HandleFunc("/backups/detail", func(w http.ResponseWriter, r *http.Request) { +func MockListDetailResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/backups/detail", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -231,7 +231,7 @@ func MockListDetailResponse(t *testing.T) { marker := r.Form.Get("marker") switch marker { case "": - fmt.Fprintf(w, ListDetailResponse, th.Server.URL) + fmt.Fprintf(w, ListDetailResponse, fakeServer.Server.URL) case "1": fmt.Fprint(w, `{"backups": []}`) default: @@ -240,8 +240,8 @@ func MockListDetailResponse(t *testing.T) { }) } -func MockGetResponse(t *testing.T) { - th.Mux.HandleFunc("/backups/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { +func MockGetResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/backups/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -251,8 +251,8 @@ func MockGetResponse(t *testing.T) { }) } -func MockCreateResponse(t *testing.T) { - th.Mux.HandleFunc("/backups", func(w http.ResponseWriter, r *http.Request) { +func MockCreateResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/backups", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -266,8 +266,8 @@ func MockCreateResponse(t *testing.T) { }) } -func MockRestoreResponse(t *testing.T) { - th.Mux.HandleFunc("/backups/d32019d3-bc6e-4319-9c1d-6722fc136a22/restore", func(w http.ResponseWriter, r *http.Request) { +func MockRestoreResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/backups/d32019d3-bc6e-4319-9c1d-6722fc136a22/restore", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -281,16 +281,16 @@ func MockRestoreResponse(t *testing.T) { }) } -func MockDeleteResponse(t *testing.T) { - th.Mux.HandleFunc("/backups/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { +func MockDeleteResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/backups/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) } -func MockExportResponse(t *testing.T) { - th.Mux.HandleFunc("/backups/d32019d3-bc6e-4319-9c1d-6722fc136a22/export_record", func(w http.ResponseWriter, r *http.Request) { +func MockExportResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/backups/d32019d3-bc6e-4319-9c1d-6722fc136a22/export_record", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -302,8 +302,8 @@ func MockExportResponse(t *testing.T) { }) } -func MockImportResponse(t *testing.T) { - th.Mux.HandleFunc("/backups/import_record", func(w http.ResponseWriter, r *http.Request) { +func MockImportResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/backups/import_record", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -318,8 +318,8 @@ func MockImportResponse(t *testing.T) { } // MockResetStatusResponse provides mock response for reset backup status API call -func MockResetStatusResponse(t *testing.T) { - th.Mux.HandleFunc("/backups/d32019d3-bc6e-4319-9c1d-6722fc136a22/action", func(w http.ResponseWriter, r *http.Request) { +func MockResetStatusResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/backups/d32019d3-bc6e-4319-9c1d-6722fc136a22/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -330,8 +330,8 @@ func MockResetStatusResponse(t *testing.T) { } // MockForceDeleteResponse provides mock response for force delete backup API call -func MockForceDeleteResponse(t *testing.T) { - th.Mux.HandleFunc("/backups/d32019d3-bc6e-4319-9c1d-6722fc136a22/action", func(w http.ResponseWriter, r *http.Request) { +func MockForceDeleteResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/backups/d32019d3-bc6e-4319-9c1d-6722fc136a22/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") diff --git a/openstack/blockstorage/v2/backups/testing/requests_test.go b/openstack/blockstorage/v2/backups/testing/requests_test.go index f34bb5f775..4298c6258b 100644 --- a/openstack/blockstorage/v2/backups/testing/requests_test.go +++ b/openstack/blockstorage/v2/backups/testing/requests_test.go @@ -13,14 +13,14 @@ import ( ) func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockListResponse(t) + MockListResponse(t, fakeServer) count := 0 - err := backups.List(client.ServiceClient(), &backups.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := backups.List(client.ServiceClient(fakeServer), &backups.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := backups.ExtractBackups(page) if err != nil { @@ -53,14 +53,14 @@ func TestList(t *testing.T) { } func TestListDetail(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockListDetailResponse(t) + MockListDetailResponse(t, fakeServer) count := 0 - err := backups.ListDetail(client.ServiceClient(), &backups.ListDetailOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := backups.ListDetail(client.ServiceClient(fakeServer), &backups.ListDetailOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := backups.ExtractBackups(page) if err != nil { @@ -103,12 +103,12 @@ func TestListDetail(t *testing.T) { } func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockGetResponse(t) + MockGetResponse(t, fakeServer) - v, err := backups.Get(context.TODO(), client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22").Extract() + v, err := backups.Get(context.TODO(), client.ServiceClient(fakeServer), "d32019d3-bc6e-4319-9c1d-6722fc136a22").Extract() th.AssertNoErr(t, err) th.AssertEquals(t, v.Name, "backup-001") @@ -116,13 +116,13 @@ func TestGet(t *testing.T) { } func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockCreateResponse(t) + MockCreateResponse(t, fakeServer) options := backups.CreateOpts{VolumeID: "1234", Name: "backup-001"} - n, err := backups.Create(context.TODO(), client.ServiceClient(), options).Extract() + n, err := backups.Create(context.TODO(), client.ServiceClient(fakeServer), options).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, n.VolumeID, "1234") @@ -131,13 +131,13 @@ func TestCreate(t *testing.T) { } func TestRestore(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockRestoreResponse(t) + MockRestoreResponse(t, fakeServer) options := backups.RestoreOpts{VolumeID: "1234", Name: "vol-001"} - n, err := backups.RestoreFromBackup(context.TODO(), client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22", options).Extract() + n, err := backups.RestoreFromBackup(context.TODO(), client.ServiceClient(fakeServer), "d32019d3-bc6e-4319-9c1d-6722fc136a22", options).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, n.VolumeID, "1234") @@ -146,22 +146,22 @@ func TestRestore(t *testing.T) { } func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockDeleteResponse(t) + MockDeleteResponse(t, fakeServer) - res := backups.Delete(context.TODO(), client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22") + res := backups.Delete(context.TODO(), client.ServiceClient(fakeServer), "d32019d3-bc6e-4319-9c1d-6722fc136a22") th.AssertNoErr(t, res.Err) } func TestExport(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockExportResponse(t) + MockExportResponse(t, fakeServer) - n, err := backups.Export(context.TODO(), client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22").Extract() + n, err := backups.Export(context.TODO(), client.ServiceClient(fakeServer), "d32019d3-bc6e-4319-9c1d-6722fc136a22").Extract() th.AssertNoErr(t, err) th.AssertEquals(t, n.BackupService, "cinder.backup.drivers.swift.SwiftBackupDriver") @@ -174,40 +174,40 @@ func TestExport(t *testing.T) { } func TestImport(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockImportResponse(t) + MockImportResponse(t, fakeServer) options := backups.ImportOpts{ BackupService: "cinder.backup.drivers.swift.SwiftBackupDriver", BackupURL: backupURL, } - n, err := backups.Import(context.TODO(), client.ServiceClient(), options).Extract() + n, err := backups.Import(context.TODO(), client.ServiceClient(fakeServer), options).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, n.ID, "d32019d3-bc6e-4319-9c1d-6722fc136a22") } func TestResetStatus(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockResetStatusResponse(t) + MockResetStatusResponse(t, fakeServer) opts := &backups.ResetStatusOpts{ Status: "error", } - res := backups.ResetStatus(context.TODO(), client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22", opts) + res := backups.ResetStatus(context.TODO(), client.ServiceClient(fakeServer), "d32019d3-bc6e-4319-9c1d-6722fc136a22", opts) th.AssertNoErr(t, res.Err) } func TestForceDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockForceDeleteResponse(t) + MockForceDeleteResponse(t, fakeServer) - res := backups.ForceDelete(context.TODO(), client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22") + res := backups.ForceDelete(context.TODO(), client.ServiceClient(fakeServer), "d32019d3-bc6e-4319-9c1d-6722fc136a22") th.AssertNoErr(t, res.Err) } diff --git a/openstack/blockstorage/v2/limits/testing/fixtures_test.go b/openstack/blockstorage/v2/limits/testing/fixtures_test.go index bdd1308a17..44d9166d74 100644 --- a/openstack/blockstorage/v2/limits/testing/fixtures_test.go +++ b/openstack/blockstorage/v2/limits/testing/fixtures_test.go @@ -118,8 +118,8 @@ var LimitsResult = limits.Limits{ // HandleGetSuccessfully configures the test server to respond to a Get request // for a limit. -func HandleGetSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/limits", func(w http.ResponseWriter, r *http.Request) { +func HandleGetSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/limits", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/blockstorage/v2/limits/testing/requests_test.go b/openstack/blockstorage/v2/limits/testing/requests_test.go index a7b6c0a503..660c84a02e 100644 --- a/openstack/blockstorage/v2/limits/testing/requests_test.go +++ b/openstack/blockstorage/v2/limits/testing/requests_test.go @@ -10,11 +10,11 @@ import ( ) func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetSuccessfully(t, fakeServer) - actual, err := limits.Get(context.TODO(), client.ServiceClient()).Extract() + actual, err := limits.Get(context.TODO(), client.ServiceClient(fakeServer)).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, &LimitsResult, actual) } diff --git a/openstack/blockstorage/v2/quotasets/testing/fixtures_test.go b/openstack/blockstorage/v2/quotasets/testing/fixtures_test.go index 854ff08b63..b170b25e79 100644 --- a/openstack/blockstorage/v2/quotasets/testing/fixtures_test.go +++ b/openstack/blockstorage/v2/quotasets/testing/fixtures_test.go @@ -153,9 +153,9 @@ var partiualUpdateExpectedQuotaSet = quotasets.QuotaSet{ } // HandleSuccessfulRequest configures the test server to respond to an HTTP request. -func HandleSuccessfulRequest(t *testing.T, httpMethod, uriPath, jsonOutput string, uriQueryParams map[string]string) { +func HandleSuccessfulRequest(t *testing.T, fakeServer th.FakeServer, httpMethod, uriPath, jsonOutput string, uriQueryParams map[string]string) { - th.Mux.HandleFunc(uriPath, func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc(uriPath, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, httpMethod) th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") @@ -169,8 +169,8 @@ func HandleSuccessfulRequest(t *testing.T, httpMethod, uriPath, jsonOutput strin } // HandleDeleteSuccessfully tests quotaset deletion. -func HandleDeleteSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/os-quota-sets/"+FirstTenantID, func(w http.ResponseWriter, r *http.Request) { +func HandleDeleteSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/os-quota-sets/"+FirstTenantID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/blockstorage/v2/quotasets/testing/requests_test.go b/openstack/blockstorage/v2/quotasets/testing/requests_test.go index 563b2d1d3d..aacd86aa75 100644 --- a/openstack/blockstorage/v2/quotasets/testing/requests_test.go +++ b/openstack/blockstorage/v2/quotasets/testing/requests_test.go @@ -11,45 +11,45 @@ import ( ) func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() uriQueryParms := map[string]string{} - HandleSuccessfulRequest(t, "GET", "/os-quota-sets/"+FirstTenantID, getExpectedJSONBody, uriQueryParms) - actual, err := quotasets.Get(context.TODO(), client.ServiceClient(), FirstTenantID).Extract() + HandleSuccessfulRequest(t, fakeServer, "GET", "/os-quota-sets/"+FirstTenantID, getExpectedJSONBody, uriQueryParms) + actual, err := quotasets.Get(context.TODO(), client.ServiceClient(fakeServer), FirstTenantID).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, &getExpectedQuotaSet, actual) } func TestGetUsage(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() uriQueryParms := map[string]string{"usage": "true"} - HandleSuccessfulRequest(t, "GET", "/os-quota-sets/"+FirstTenantID, getUsageExpectedJSONBody, uriQueryParms) - actual, err := quotasets.GetUsage(context.TODO(), client.ServiceClient(), FirstTenantID).Extract() + HandleSuccessfulRequest(t, fakeServer, "GET", "/os-quota-sets/"+FirstTenantID, getUsageExpectedJSONBody, uriQueryParms) + actual, err := quotasets.GetUsage(context.TODO(), client.ServiceClient(fakeServer), FirstTenantID).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, getUsageExpectedQuotaSet, actual) } func TestFullUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() uriQueryParms := map[string]string{} - HandleSuccessfulRequest(t, "PUT", "/os-quota-sets/"+FirstTenantID, fullUpdateExpectedJSONBody, uriQueryParms) - actual, err := quotasets.Update(context.TODO(), client.ServiceClient(), FirstTenantID, fullUpdateOpts).Extract() + HandleSuccessfulRequest(t, fakeServer, "PUT", "/os-quota-sets/"+FirstTenantID, fullUpdateExpectedJSONBody, uriQueryParms) + actual, err := quotasets.Update(context.TODO(), client.ServiceClient(fakeServer), FirstTenantID, fullUpdateOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, &fullUpdateExpectedQuotaSet, actual) } func TestPartialUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() uriQueryParms := map[string]string{} - HandleSuccessfulRequest(t, "PUT", "/os-quota-sets/"+FirstTenantID, partialUpdateExpectedJSONBody, uriQueryParms) - actual, err := quotasets.Update(context.TODO(), client.ServiceClient(), FirstTenantID, partialUpdateOpts).Extract() + HandleSuccessfulRequest(t, fakeServer, "PUT", "/os-quota-sets/"+FirstTenantID, partialUpdateExpectedJSONBody, uriQueryParms) + actual, err := quotasets.Update(context.TODO(), client.ServiceClient(fakeServer), FirstTenantID, partialUpdateOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, &partiualUpdateExpectedQuotaSet, actual) } @@ -62,20 +62,20 @@ func (opts ErrorUpdateOpts) ToBlockStorageQuotaUpdateMap() (map[string]any, erro func TestErrorInToBlockStorageQuotaUpdateMap(t *testing.T) { opts := &ErrorUpdateOpts{} - th.SetupHTTP() - defer th.TeardownHTTP() - HandleSuccessfulRequest(t, "PUT", "/os-quota-sets/"+FirstTenantID, "", nil) - _, err := quotasets.Update(context.TODO(), client.ServiceClient(), FirstTenantID, opts).Extract() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleSuccessfulRequest(t, fakeServer, "PUT", "/os-quota-sets/"+FirstTenantID, "", nil) + _, err := quotasets.Update(context.TODO(), client.ServiceClient(fakeServer), FirstTenantID, opts).Extract() if err == nil { t.Fatal("Error handling failed") } } func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDeleteSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDeleteSuccessfully(t, fakeServer) - err := quotasets.Delete(context.TODO(), client.ServiceClient(), FirstTenantID).ExtractErr() + err := quotasets.Delete(context.TODO(), client.ServiceClient(fakeServer), FirstTenantID).ExtractErr() th.AssertNoErr(t, err) } diff --git a/openstack/blockstorage/v2/schedulerstats/testing/fixtures_test.go b/openstack/blockstorage/v2/schedulerstats/testing/fixtures_test.go index 05512dbf6d..b372811312 100644 --- a/openstack/blockstorage/v2/schedulerstats/testing/fixtures_test.go +++ b/openstack/blockstorage/v2/schedulerstats/testing/fixtures_test.go @@ -93,8 +93,8 @@ var ( } ) -func HandleStoragePoolsListSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/scheduler-stats/get_pools", func(w http.ResponseWriter, r *http.Request) { +func HandleStoragePoolsListSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/scheduler-stats/get_pools", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/blockstorage/v2/schedulerstats/testing/requests_test.go b/openstack/blockstorage/v2/schedulerstats/testing/requests_test.go index 7a6cb8b450..35bdb7ea68 100644 --- a/openstack/blockstorage/v2/schedulerstats/testing/requests_test.go +++ b/openstack/blockstorage/v2/schedulerstats/testing/requests_test.go @@ -11,12 +11,12 @@ import ( ) func TestListStoragePoolsDetail(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleStoragePoolsListSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleStoragePoolsListSuccessfully(t, fakeServer) pages := 0 - err := schedulerstats.List(client.ServiceClient(), schedulerstats.ListOpts{Detail: true}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := schedulerstats.List(client.ServiceClient(fakeServer), schedulerstats.ListOpts{Detail: true}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := schedulerstats.ExtractStoragePools(page) diff --git a/openstack/blockstorage/v2/services/testing/fixtures_test.go b/openstack/blockstorage/v2/services/testing/fixtures_test.go index 41fb5bc614..398ad96c44 100644 --- a/openstack/blockstorage/v2/services/testing/fixtures_test.go +++ b/openstack/blockstorage/v2/services/testing/fixtures_test.go @@ -86,8 +86,8 @@ var ThirdFakeService = services.Service{ } // HandleListSuccessfully configures the test server to respond to a List request. -func HandleListSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/os-services", func(w http.ResponseWriter, r *http.Request) { +func HandleListSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/os-services", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/blockstorage/v2/services/testing/requests_test.go b/openstack/blockstorage/v2/services/testing/requests_test.go index d1277a99bf..9fbbe61201 100644 --- a/openstack/blockstorage/v2/services/testing/requests_test.go +++ b/openstack/blockstorage/v2/services/testing/requests_test.go @@ -11,12 +11,12 @@ import ( ) func TestListServices(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListSuccessfully(t, fakeServer) pages := 0 - err := services.List(client.ServiceClient(), services.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := services.List(client.ServiceClient(fakeServer), services.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := services.ExtractServices(page) diff --git a/openstack/blockstorage/v2/snapshots/testing/fixtures_test.go b/openstack/blockstorage/v2/snapshots/testing/fixtures_test.go index da258e366b..964dfff2e6 100644 --- a/openstack/blockstorage/v2/snapshots/testing/fixtures_test.go +++ b/openstack/blockstorage/v2/snapshots/testing/fixtures_test.go @@ -9,8 +9,8 @@ import ( "github.com/gophercloud/gophercloud/v2/testhelper/client" ) -func MockListResponse(t *testing.T) { - th.Mux.HandleFunc("/snapshots", func(w http.ResponseWriter, r *http.Request) { +func MockListResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/snapshots", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -44,8 +44,8 @@ func MockListResponse(t *testing.T) { }) } -func MockGetResponse(t *testing.T) { - th.Mux.HandleFunc("/snapshots/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { +func MockGetResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/snapshots/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -67,8 +67,8 @@ func MockGetResponse(t *testing.T) { }) } -func MockCreateResponse(t *testing.T) { - th.Mux.HandleFunc("/snapshots", func(w http.ResponseWriter, r *http.Request) { +func MockCreateResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/snapshots", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -102,8 +102,8 @@ func MockCreateResponse(t *testing.T) { }) } -func MockUpdateMetadataResponse(t *testing.T) { - th.Mux.HandleFunc("/snapshots/123/metadata", func(w http.ResponseWriter, r *http.Request) { +func MockUpdateMetadataResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/snapshots/123/metadata", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -125,8 +125,8 @@ func MockUpdateMetadataResponse(t *testing.T) { }) } -func MockDeleteResponse(t *testing.T) { - th.Mux.HandleFunc("/snapshots/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { +func MockDeleteResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/snapshots/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) diff --git a/openstack/blockstorage/v2/snapshots/testing/requests_test.go b/openstack/blockstorage/v2/snapshots/testing/requests_test.go index 07d74a14a7..e3b140ce3c 100644 --- a/openstack/blockstorage/v2/snapshots/testing/requests_test.go +++ b/openstack/blockstorage/v2/snapshots/testing/requests_test.go @@ -12,14 +12,14 @@ import ( ) func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockListResponse(t) + MockListResponse(t, fakeServer) count := 0 - err := snapshots.List(client.ServiceClient(), &snapshots.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := snapshots.List(client.ServiceClient(fakeServer), &snapshots.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := snapshots.ExtractSnapshots(page) if err != nil { @@ -60,12 +60,12 @@ func TestList(t *testing.T) { } func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockGetResponse(t) + MockGetResponse(t, fakeServer) - v, err := snapshots.Get(context.TODO(), client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22").Extract() + v, err := snapshots.Get(context.TODO(), client.ServiceClient(fakeServer), "d32019d3-bc6e-4319-9c1d-6722fc136a22").Extract() th.AssertNoErr(t, err) th.AssertEquals(t, v.Name, "snapshot-001") @@ -73,13 +73,13 @@ func TestGet(t *testing.T) { } func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockCreateResponse(t) + MockCreateResponse(t, fakeServer) options := snapshots.CreateOpts{VolumeID: "1234", Name: "snapshot-001"} - n, err := snapshots.Create(context.TODO(), client.ServiceClient(), options).Extract() + n, err := snapshots.Create(context.TODO(), client.ServiceClient(fakeServer), options).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, n.VolumeID, "1234") @@ -88,10 +88,10 @@ func TestCreate(t *testing.T) { } func TestUpdateMetadata(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockUpdateMetadataResponse(t) + MockUpdateMetadataResponse(t, fakeServer) expected := map[string]any{"key": "v1"} @@ -101,18 +101,18 @@ func TestUpdateMetadata(t *testing.T) { }, } - actual, err := snapshots.UpdateMetadata(context.TODO(), client.ServiceClient(), "123", options).ExtractMetadata() + actual, err := snapshots.UpdateMetadata(context.TODO(), client.ServiceClient(fakeServer), "123", options).ExtractMetadata() th.AssertNoErr(t, err) th.AssertDeepEquals(t, actual, expected) } func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockDeleteResponse(t) + MockDeleteResponse(t, fakeServer) - res := snapshots.Delete(context.TODO(), client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22") + res := snapshots.Delete(context.TODO(), client.ServiceClient(fakeServer), "d32019d3-bc6e-4319-9c1d-6722fc136a22") th.AssertNoErr(t, res.Err) } diff --git a/openstack/blockstorage/v2/transfers/testing/fixtures_test.go b/openstack/blockstorage/v2/transfers/testing/fixtures_test.go index 866d5068fc..f24b7fa82c 100644 --- a/openstack/blockstorage/v2/transfers/testing/fixtures_test.go +++ b/openstack/blockstorage/v2/transfers/testing/fixtures_test.go @@ -159,8 +159,8 @@ var AcceptResponse = transfers.Transfer{ }, } -func HandleCreateTransfer(t *testing.T) { - th.Mux.HandleFunc("/os-volume-transfer", func(w http.ResponseWriter, r *http.Request) { +func HandleCreateTransfer(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/os-volume-transfer", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") @@ -171,8 +171,8 @@ func HandleCreateTransfer(t *testing.T) { }) } -func HandleAcceptTransfer(t *testing.T) { - th.Mux.HandleFunc("/os-volume-transfer/b8913bfd-a4d3-4ec5-bd8b-fe2dbeef9f4f/accept", func(w http.ResponseWriter, r *http.Request) { +func HandleAcceptTransfer(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/os-volume-transfer/b8913bfd-a4d3-4ec5-bd8b-fe2dbeef9f4f/accept", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") @@ -183,8 +183,8 @@ func HandleAcceptTransfer(t *testing.T) { }) } -func HandleDeleteTransfer(t *testing.T) { - th.Mux.HandleFunc("/os-volume-transfer/b8913bfd-a4d3-4ec5-bd8b-fe2dbeef9f4f", func(w http.ResponseWriter, r *http.Request) { +func HandleDeleteTransfer(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/os-volume-transfer/b8913bfd-a4d3-4ec5-bd8b-fe2dbeef9f4f", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -192,8 +192,8 @@ func HandleDeleteTransfer(t *testing.T) { }) } -func HandleListTransfers(t *testing.T) { - th.Mux.HandleFunc("/os-volume-transfer/detail", func(w http.ResponseWriter, r *http.Request) { +func HandleListTransfers(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/os-volume-transfer/detail", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") @@ -204,8 +204,8 @@ func HandleListTransfers(t *testing.T) { }) } -func HandleGetTransfer(t *testing.T) { - th.Mux.HandleFunc("/os-volume-transfer/b8913bfd-a4d3-4ec5-bd8b-fe2dbeef9f4f", func(w http.ResponseWriter, r *http.Request) { +func HandleGetTransfer(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/os-volume-transfer/b8913bfd-a4d3-4ec5-bd8b-fe2dbeef9f4f", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") diff --git a/openstack/blockstorage/v2/transfers/testing/requests_test.go b/openstack/blockstorage/v2/transfers/testing/requests_test.go index 32501eb095..f6404fb2a2 100644 --- a/openstack/blockstorage/v2/transfers/testing/requests_test.go +++ b/openstack/blockstorage/v2/transfers/testing/requests_test.go @@ -11,44 +11,44 @@ import ( ) func TestCreateTransfer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateTransfer(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCreateTransfer(t, fakeServer) - actual, err := transfers.Create(context.TODO(), client.ServiceClient(), TransferRequest).Extract() + actual, err := transfers.Create(context.TODO(), client.ServiceClient(fakeServer), TransferRequest).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, TransferResponse, *actual) } func TestAcceptTransfer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleAcceptTransfer(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleAcceptTransfer(t, fakeServer) - actual, err := transfers.Accept(context.TODO(), client.ServiceClient(), TransferResponse.ID, AcceptRequest).Extract() + actual, err := transfers.Accept(context.TODO(), client.ServiceClient(fakeServer), TransferResponse.ID, AcceptRequest).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, AcceptResponse, *actual) } func TestDeleteTransfer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDeleteTransfer(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDeleteTransfer(t, fakeServer) - err := transfers.Delete(context.TODO(), client.ServiceClient(), TransferResponse.ID).ExtractErr() + err := transfers.Delete(context.TODO(), client.ServiceClient(fakeServer), TransferResponse.ID).ExtractErr() th.AssertNoErr(t, err) } func TestListTransfers(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListTransfers(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListTransfers(t, fakeServer) expectedResponse := TransferListResponse expectedResponse[0].AuthKey = "" count := 0 - err := transfers.List(client.ServiceClient(), &transfers.ListOpts{AllTenants: true}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := transfers.List(client.ServiceClient(fakeServer), &transfers.ListOpts{AllTenants: true}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := transfers.ExtractTransfers(page) @@ -63,14 +63,14 @@ func TestListTransfers(t *testing.T) { } func TestListTransfersAllPages(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListTransfers(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListTransfers(t, fakeServer) expectedResponse := TransferListResponse expectedResponse[0].AuthKey = "" - allPages, err := transfers.List(client.ServiceClient(), &transfers.ListOpts{AllTenants: true}).AllPages(context.TODO()) + allPages, err := transfers.List(client.ServiceClient(fakeServer), &transfers.ListOpts{AllTenants: true}).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := transfers.ExtractTransfers(allPages) th.AssertNoErr(t, err) @@ -78,14 +78,14 @@ func TestListTransfersAllPages(t *testing.T) { } func TestGetTransfer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetTransfer(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetTransfer(t, fakeServer) expectedResponse := TransferResponse expectedResponse.AuthKey = "" - actual, err := transfers.Get(context.TODO(), client.ServiceClient(), TransferResponse.ID).Extract() + actual, err := transfers.Get(context.TODO(), client.ServiceClient(fakeServer), TransferResponse.ID).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, expectedResponse, *actual) } diff --git a/openstack/blockstorage/v2/volumes/testing/fixtures_test.go b/openstack/blockstorage/v2/volumes/testing/fixtures_test.go index 06c9123915..5b73310285 100644 --- a/openstack/blockstorage/v2/volumes/testing/fixtures_test.go +++ b/openstack/blockstorage/v2/volumes/testing/fixtures_test.go @@ -9,8 +9,8 @@ import ( "github.com/gophercloud/gophercloud/v2/testhelper/client" ) -func MockListResponse(t *testing.T) { - th.Mux.HandleFunc("/volumes/detail", func(w http.ResponseWriter, r *http.Request) { +func MockListResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/volumes/detail", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -86,8 +86,8 @@ func MockListResponse(t *testing.T) { }) } -func MockGetResponse(t *testing.T) { - th.Mux.HandleFunc("/volumes/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { +func MockGetResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/volumes/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -134,8 +134,8 @@ func MockGetResponse(t *testing.T) { }) } -func MockCreateResponse(t *testing.T) { - th.Mux.HandleFunc("/volumes", func(w http.ResponseWriter, r *http.Request) { +func MockCreateResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/volumes", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -179,16 +179,16 @@ func MockCreateResponse(t *testing.T) { }) } -func MockDeleteResponse(t *testing.T) { - th.Mux.HandleFunc("/volumes/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { +func MockDeleteResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/volumes/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusAccepted) }) } -func MockUpdateResponse(t *testing.T) { - th.Mux.HandleFunc("/volumes/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { +func MockUpdateResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/volumes/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusOK) @@ -202,8 +202,8 @@ func MockUpdateResponse(t *testing.T) { }) } -func MockAttachResponse(t *testing.T) { - th.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", +func MockAttachResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -227,8 +227,8 @@ func MockAttachResponse(t *testing.T) { }) } -func MockBeginDetachingResponse(t *testing.T) { - th.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", +func MockBeginDetachingResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -247,8 +247,8 @@ func MockBeginDetachingResponse(t *testing.T) { }) } -func MockDetachResponse(t *testing.T) { - th.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", +func MockDetachResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -267,8 +267,8 @@ func MockDetachResponse(t *testing.T) { }) } -func MockUploadImageResponse(t *testing.T) { - th.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", +func MockUploadImageResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -319,8 +319,8 @@ func MockUploadImageResponse(t *testing.T) { }) } -func MockReserveResponse(t *testing.T) { - th.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", +func MockReserveResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -339,8 +339,8 @@ func MockReserveResponse(t *testing.T) { }) } -func MockUnreserveResponse(t *testing.T) { - th.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", +func MockUnreserveResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -359,8 +359,8 @@ func MockUnreserveResponse(t *testing.T) { }) } -func MockInitializeConnectionResponse(t *testing.T) { - th.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", +func MockInitializeConnectionResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -416,8 +416,8 @@ func MockInitializeConnectionResponse(t *testing.T) { }) } -func MockTerminateConnectionResponse(t *testing.T) { - th.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", +func MockTerminateConnectionResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -447,8 +447,8 @@ func MockTerminateConnectionResponse(t *testing.T) { }) } -func MockExtendSizeResponse(t *testing.T) { - th.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", +func MockExtendSizeResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -470,8 +470,8 @@ func MockExtendSizeResponse(t *testing.T) { }) } -func MockForceDeleteResponse(t *testing.T) { - th.Mux.HandleFunc("/volumes/d32019d3-bc6e-4319-9c1d-6722fc136a22/action", func(w http.ResponseWriter, r *http.Request) { +func MockForceDeleteResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/volumes/d32019d3-bc6e-4319-9c1d-6722fc136a22/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestBody(t, r, `{"os-force_delete":""}`) @@ -479,8 +479,8 @@ func MockForceDeleteResponse(t *testing.T) { }) } -func MockSetImageMetadataResponse(t *testing.T) { - th.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { +func MockSetImageMetadataResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -501,8 +501,8 @@ func MockSetImageMetadataResponse(t *testing.T) { }) } -func MockSetBootableResponse(t *testing.T) { - th.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { +func MockSetBootableResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -520,8 +520,8 @@ func MockSetBootableResponse(t *testing.T) { }) } -func MockReImageResponse(t *testing.T) { - th.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { +func MockReImageResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -540,8 +540,8 @@ func MockReImageResponse(t *testing.T) { }) } -func MockChangeTypeResponse(t *testing.T) { - th.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", +func MockChangeTypeResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -564,8 +564,8 @@ func MockChangeTypeResponse(t *testing.T) { }) } -func MockResetStatusResponse(t *testing.T) { - th.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", +func MockResetStatusResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/blockstorage/v2/volumes/testing/requests_test.go b/openstack/blockstorage/v2/volumes/testing/requests_test.go index 3d829a56ae..3a1819b3c5 100644 --- a/openstack/blockstorage/v2/volumes/testing/requests_test.go +++ b/openstack/blockstorage/v2/volumes/testing/requests_test.go @@ -13,14 +13,14 @@ import ( ) func TestListWithExtensions(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockListResponse(t) + MockListResponse(t, fakeServer) count := 0 - err := volumes.List(client.ServiceClient(), &volumes.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := volumes.List(client.ServiceClient(fakeServer), &volumes.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := volumes.ExtractVolumes(page) if err != nil { @@ -97,12 +97,12 @@ func TestListWithExtensions(t *testing.T) { } func TestListAllWithExtensions(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockListResponse(t) + MockListResponse(t, fakeServer) - allPages, err := volumes.List(client.ServiceClient(), &volumes.ListOpts{}).AllPages(context.TODO()) + allPages, err := volumes.List(client.ServiceClient(fakeServer), &volumes.ListOpts{}).AllPages(context.TODO()) th.AssertNoErr(t, err) var actual []volumes.Volume @@ -113,12 +113,12 @@ func TestListAllWithExtensions(t *testing.T) { } func TestListAll(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockListResponse(t) + MockListResponse(t, fakeServer) - allPages, err := volumes.List(client.ServiceClient(), &volumes.ListOpts{}).AllPages(context.TODO()) + allPages, err := volumes.List(client.ServiceClient(fakeServer), &volumes.ListOpts{}).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := volumes.ExtractVolumes(allPages) th.AssertNoErr(t, err) @@ -185,12 +185,12 @@ func TestListAll(t *testing.T) { } func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockGetResponse(t) + MockGetResponse(t, fakeServer) - v, err := volumes.Get(context.TODO(), client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22").Extract() + v, err := volumes.Get(context.TODO(), client.ServiceClient(fakeServer), "d32019d3-bc6e-4319-9c1d-6722fc136a22").Extract() th.AssertNoErr(t, err) th.AssertEquals(t, v.Name, "vol-001") @@ -198,13 +198,13 @@ func TestGet(t *testing.T) { } func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockCreateResponse(t) + MockCreateResponse(t, fakeServer) options := &volumes.CreateOpts{Size: 75, Name: "vol-001"} - n, err := volumes.Create(context.TODO(), client.ServiceClient(), options, nil).Extract() + n, err := volumes.Create(context.TODO(), client.ServiceClient(fakeServer), options, nil).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, n.Size, 75) @@ -246,84 +246,84 @@ func TestCreateSchedulerHints(t *testing.T) { } func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockDeleteResponse(t) + MockDeleteResponse(t, fakeServer) - res := volumes.Delete(context.TODO(), client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22", volumes.DeleteOpts{}) + res := volumes.Delete(context.TODO(), client.ServiceClient(fakeServer), "d32019d3-bc6e-4319-9c1d-6722fc136a22", volumes.DeleteOpts{}) th.AssertNoErr(t, res.Err) } func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockUpdateResponse(t) + MockUpdateResponse(t, fakeServer) var name = "vol-002" options := volumes.UpdateOpts{Name: &name} - v, err := volumes.Update(context.TODO(), client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22", options).Extract() + v, err := volumes.Update(context.TODO(), client.ServiceClient(fakeServer), "d32019d3-bc6e-4319-9c1d-6722fc136a22", options).Extract() th.AssertNoErr(t, err) th.CheckEquals(t, "vol-002", v.Name) } func TestGetWithExtensions(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockGetResponse(t) + MockGetResponse(t, fakeServer) var v volumes.Volume - err := volumes.Get(context.TODO(), client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22").ExtractInto(&v) + err := volumes.Get(context.TODO(), client.ServiceClient(fakeServer), "d32019d3-bc6e-4319-9c1d-6722fc136a22").ExtractInto(&v) th.AssertNoErr(t, err) th.AssertEquals(t, "304dc00909ac4d0da6c62d816bcb3459", v.TenantID) - err = volumes.Get(context.TODO(), client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22").ExtractInto(v) + err = volumes.Get(context.TODO(), client.ServiceClient(fakeServer), "d32019d3-bc6e-4319-9c1d-6722fc136a22").ExtractInto(v) if err == nil { t.Errorf("Expected error when providing non-pointer struct") } } func TestAttach(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockAttachResponse(t) + MockAttachResponse(t, fakeServer) options := &volumes.AttachOpts{ MountPoint: "/mnt", Mode: "rw", InstanceUUID: "50902f4f-a974-46a0-85e9-7efc5e22dfdd", } - err := volumes.Attach(context.TODO(), client.ServiceClient(), "cd281d77-8217-4830-be95-9528227c105c", options).ExtractErr() + err := volumes.Attach(context.TODO(), client.ServiceClient(fakeServer), "cd281d77-8217-4830-be95-9528227c105c", options).ExtractErr() th.AssertNoErr(t, err) } func TestBeginDetaching(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockBeginDetachingResponse(t) + MockBeginDetachingResponse(t, fakeServer) - err := volumes.BeginDetaching(context.TODO(), client.ServiceClient(), "cd281d77-8217-4830-be95-9528227c105c").ExtractErr() + err := volumes.BeginDetaching(context.TODO(), client.ServiceClient(fakeServer), "cd281d77-8217-4830-be95-9528227c105c").ExtractErr() th.AssertNoErr(t, err) } func TestDetach(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockDetachResponse(t) + MockDetachResponse(t, fakeServer) - err := volumes.Detach(context.TODO(), client.ServiceClient(), "cd281d77-8217-4830-be95-9528227c105c", &volumes.DetachOpts{}).ExtractErr() + err := volumes.Detach(context.TODO(), client.ServiceClient(fakeServer), "cd281d77-8217-4830-be95-9528227c105c", &volumes.DetachOpts{}).ExtractErr() th.AssertNoErr(t, err) } func TestUploadImage(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - MockUploadImageResponse(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + MockUploadImageResponse(t, fakeServer) options := &volumes.UploadImageOpts{ ContainerFormat: "bare", DiskFormat: "raw", @@ -331,7 +331,7 @@ func TestUploadImage(t *testing.T) { Force: true, } - actual, err := volumes.UploadImage(context.TODO(), client.ServiceClient(), "cd281d77-8217-4830-be95-9528227c105c", options).Extract() + actual, err := volumes.UploadImage(context.TODO(), client.ServiceClient(fakeServer), "cd281d77-8217-4830-be95-9528227c105c", options).Extract() th.AssertNoErr(t, err) expected := volumes.VolumeImage{ @@ -361,30 +361,30 @@ func TestUploadImage(t *testing.T) { } func TestReserve(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockReserveResponse(t) + MockReserveResponse(t, fakeServer) - err := volumes.Reserve(context.TODO(), client.ServiceClient(), "cd281d77-8217-4830-be95-9528227c105c").ExtractErr() + err := volumes.Reserve(context.TODO(), client.ServiceClient(fakeServer), "cd281d77-8217-4830-be95-9528227c105c").ExtractErr() th.AssertNoErr(t, err) } func TestUnreserve(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockUnreserveResponse(t) + MockUnreserveResponse(t, fakeServer) - err := volumes.Unreserve(context.TODO(), client.ServiceClient(), "cd281d77-8217-4830-be95-9528227c105c").ExtractErr() + err := volumes.Unreserve(context.TODO(), client.ServiceClient(fakeServer), "cd281d77-8217-4830-be95-9528227c105c").ExtractErr() th.AssertNoErr(t, err) } func TestInitializeConnection(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockInitializeConnectionResponse(t) + MockInitializeConnectionResponse(t, fakeServer) options := &volumes.InitializeConnectionOpts{ IP: "127.0.0.1", @@ -394,15 +394,15 @@ func TestInitializeConnection(t *testing.T) { Platform: "x86_64", OSType: "linux2", } - _, err := volumes.InitializeConnection(context.TODO(), client.ServiceClient(), "cd281d77-8217-4830-be95-9528227c105c", options).Extract() + _, err := volumes.InitializeConnection(context.TODO(), client.ServiceClient(fakeServer), "cd281d77-8217-4830-be95-9528227c105c", options).Extract() th.AssertNoErr(t, err) } func TestTerminateConnection(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockTerminateConnectionResponse(t) + MockTerminateConnectionResponse(t, fakeServer) options := &volumes.TerminateConnectionOpts{ IP: "127.0.0.1", @@ -412,39 +412,39 @@ func TestTerminateConnection(t *testing.T) { Platform: "x86_64", OSType: "linux2", } - err := volumes.TerminateConnection(context.TODO(), client.ServiceClient(), "cd281d77-8217-4830-be95-9528227c105c", options).ExtractErr() + err := volumes.TerminateConnection(context.TODO(), client.ServiceClient(fakeServer), "cd281d77-8217-4830-be95-9528227c105c", options).ExtractErr() th.AssertNoErr(t, err) } func TestExtendSize(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockExtendSizeResponse(t) + MockExtendSizeResponse(t, fakeServer) options := &volumes.ExtendSizeOpts{ NewSize: 3, } - err := volumes.ExtendSize(context.TODO(), client.ServiceClient(), "cd281d77-8217-4830-be95-9528227c105c", options).ExtractErr() + err := volumes.ExtendSize(context.TODO(), client.ServiceClient(fakeServer), "cd281d77-8217-4830-be95-9528227c105c", options).ExtractErr() th.AssertNoErr(t, err) } func TestForceDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockForceDeleteResponse(t) + MockForceDeleteResponse(t, fakeServer) - res := volumes.ForceDelete(context.TODO(), client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22") + res := volumes.ForceDelete(context.TODO(), client.ServiceClient(fakeServer), "d32019d3-bc6e-4319-9c1d-6722fc136a22") th.AssertNoErr(t, res.Err) } func TestSetImageMetadata(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockSetImageMetadataResponse(t) + MockSetImageMetadataResponse(t, fakeServer) options := &volumes.ImageMetadataOpts{ Metadata: map[string]string{ @@ -452,59 +452,59 @@ func TestSetImageMetadata(t *testing.T) { }, } - err := volumes.SetImageMetadata(context.TODO(), client.ServiceClient(), "cd281d77-8217-4830-be95-9528227c105c", options).ExtractErr() + err := volumes.SetImageMetadata(context.TODO(), client.ServiceClient(fakeServer), "cd281d77-8217-4830-be95-9528227c105c", options).ExtractErr() th.AssertNoErr(t, err) } func TestSetBootable(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockSetBootableResponse(t) + MockSetBootableResponse(t, fakeServer) options := volumes.BootableOpts{ Bootable: true, } - err := volumes.SetBootable(context.TODO(), client.ServiceClient(), "cd281d77-8217-4830-be95-9528227c105c", options).ExtractErr() + err := volumes.SetBootable(context.TODO(), client.ServiceClient(fakeServer), "cd281d77-8217-4830-be95-9528227c105c", options).ExtractErr() th.AssertNoErr(t, err) } func TestReImage(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockReImageResponse(t) + MockReImageResponse(t, fakeServer) options := volumes.ReImageOpts{ ImageID: "71543ced-a8af-45b6-a5c4-a46282108a90", ReImageReserved: false, } - err := volumes.ReImage(context.TODO(), client.ServiceClient(), "cd281d77-8217-4830-be95-9528227c105c", options).ExtractErr() + err := volumes.ReImage(context.TODO(), client.ServiceClient(fakeServer), "cd281d77-8217-4830-be95-9528227c105c", options).ExtractErr() th.AssertNoErr(t, err) } func TestChangeType(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockChangeTypeResponse(t) + MockChangeTypeResponse(t, fakeServer) options := &volumes.ChangeTypeOpts{ NewType: "ssd", MigrationPolicy: "on-demand", } - err := volumes.ChangeType(context.TODO(), client.ServiceClient(), "cd281d77-8217-4830-be95-9528227c105c", options).ExtractErr() + err := volumes.ChangeType(context.TODO(), client.ServiceClient(fakeServer), "cd281d77-8217-4830-be95-9528227c105c", options).ExtractErr() th.AssertNoErr(t, err) } func TestResetStatus(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockResetStatusResponse(t) + MockResetStatusResponse(t, fakeServer) options := &volumes.ResetStatusOpts{ Status: "error", @@ -512,6 +512,6 @@ func TestResetStatus(t *testing.T) { MigrationStatus: "migrating", } - err := volumes.ResetStatus(context.TODO(), client.ServiceClient(), "cd281d77-8217-4830-be95-9528227c105c", options).ExtractErr() + err := volumes.ResetStatus(context.TODO(), client.ServiceClient(fakeServer), "cd281d77-8217-4830-be95-9528227c105c", options).ExtractErr() th.AssertNoErr(t, err) } diff --git a/openstack/blockstorage/v3/attachments/testing/fixtures_test.go b/openstack/blockstorage/v3/attachments/testing/fixtures_test.go index 7f1a58e1c3..6d35b5f304 100644 --- a/openstack/blockstorage/v3/attachments/testing/fixtures_test.go +++ b/openstack/blockstorage/v3/attachments/testing/fixtures_test.go @@ -27,8 +27,8 @@ var ( } ) -func MockListResponse(t *testing.T) { - th.Mux.HandleFunc("/attachments/detail", func(w http.ResponseWriter, r *http.Request) { +func MockListResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/attachments/detail", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -62,7 +62,7 @@ func MockListResponse(t *testing.T) { } ] } - `, th.Server.URL) + `, fakeServer.Server.URL) case "1": fmt.Fprint(w, `{"volumes": []}`) default: @@ -71,8 +71,8 @@ func MockListResponse(t *testing.T) { }) } -func MockGetResponse(t *testing.T) { - th.Mux.HandleFunc("/attachments/05551600-a936-4d4a-ba42-79a037c1-c91a", func(w http.ResponseWriter, r *http.Request) { +func MockGetResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/attachments/05551600-a936-4d4a-ba42-79a037c1-c91a", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -95,8 +95,8 @@ func MockGetResponse(t *testing.T) { }) } -func MockCreateResponse(t *testing.T) { - th.Mux.HandleFunc("/attachments", func(w http.ResponseWriter, r *http.Request) { +func MockCreateResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/attachments", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -140,16 +140,16 @@ func MockCreateResponse(t *testing.T) { }) } -func MockDeleteResponse(t *testing.T) { - th.Mux.HandleFunc("/attachments/05551600-a936-4d4a-ba42-79a037c1-c91a", func(w http.ResponseWriter, r *http.Request) { +func MockDeleteResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/attachments/05551600-a936-4d4a-ba42-79a037c1-c91a", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusOK) }) } -func MockUpdateResponse(t *testing.T) { - th.Mux.HandleFunc("/attachments/05551600-a936-4d4a-ba42-79a037c1-c91a", func(w http.ResponseWriter, r *http.Request) { +func MockUpdateResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/attachments/05551600-a936-4d4a-ba42-79a037c1-c91a", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -188,8 +188,8 @@ func MockUpdateResponse(t *testing.T) { }) } -func MockUpdateEmptyResponse(t *testing.T) { - th.Mux.HandleFunc("/attachments/05551600-a936-4d4a-ba42-79a037c1-c91a", func(w http.ResponseWriter, r *http.Request) { +func MockUpdateEmptyResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/attachments/05551600-a936-4d4a-ba42-79a037c1-c91a", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -225,8 +225,8 @@ var completeRequest = ` } ` -func MockCompleteResponse(t *testing.T) { - th.Mux.HandleFunc("/attachments/05551600-a936-4d4a-ba42-79a037c1-c91a/action", func(w http.ResponseWriter, r *http.Request) { +func MockCompleteResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/attachments/05551600-a936-4d4a-ba42-79a037c1-c91a/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, completeRequest) diff --git a/openstack/blockstorage/v3/attachments/testing/requests_test.go b/openstack/blockstorage/v3/attachments/testing/requests_test.go index 4f9f91dcb4..5f1591950b 100644 --- a/openstack/blockstorage/v3/attachments/testing/requests_test.go +++ b/openstack/blockstorage/v3/attachments/testing/requests_test.go @@ -10,12 +10,12 @@ import ( ) func TestListAll(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockListResponse(t) + MockListResponse(t, fakeServer) - allPages, err := attachments.List(client.ServiceClient(), &attachments.ListOpts{}).AllPages(context.TODO()) + allPages, err := attachments.List(client.ServiceClient(fakeServer), &attachments.ListOpts{}).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := attachments.ExtractAttachments(allPages) th.AssertNoErr(t, err) @@ -27,22 +27,22 @@ func TestListAll(t *testing.T) { } func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockGetResponse(t) + MockGetResponse(t, fakeServer) - attachment, err := attachments.Get(context.TODO(), client.ServiceClient(), "05551600-a936-4d4a-ba42-79a037c1-c91a").Extract() + attachment, err := attachments.Get(context.TODO(), client.ServiceClient(fakeServer), "05551600-a936-4d4a-ba42-79a037c1-c91a").Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, expectedAttachment, attachment) } func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockCreateResponse(t) + MockCreateResponse(t, fakeServer) options := &attachments.CreateOpts{ InstanceUUID: "83ec2e3b-4321-422b-8706-a84185f52a0a", @@ -58,27 +58,27 @@ func TestCreate(t *testing.T) { }, VolumeUUID: "289da7f8-6440-407c-9fb4-7db01ec49164", } - attachment, err := attachments.Create(context.TODO(), client.ServiceClient(), options).Extract() + attachment, err := attachments.Create(context.TODO(), client.ServiceClient(fakeServer), options).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, expectedAttachment, attachment) } func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockDeleteResponse(t) + MockDeleteResponse(t, fakeServer) - res := attachments.Delete(context.TODO(), client.ServiceClient(), "05551600-a936-4d4a-ba42-79a037c1-c91a") + res := attachments.Delete(context.TODO(), client.ServiceClient(fakeServer), "05551600-a936-4d4a-ba42-79a037c1-c91a") th.AssertNoErr(t, res.Err) } func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockUpdateResponse(t) + MockUpdateResponse(t, fakeServer) options := &attachments.UpdateOpts{ Connector: map[string]any{ @@ -92,29 +92,29 @@ func TestUpdate(t *testing.T) { "mode": "rw", }, } - attachment, err := attachments.Update(context.TODO(), client.ServiceClient(), "05551600-a936-4d4a-ba42-79a037c1-c91a", options).Extract() + attachment, err := attachments.Update(context.TODO(), client.ServiceClient(fakeServer), "05551600-a936-4d4a-ba42-79a037c1-c91a", options).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, expectedAttachment, attachment) } func TestUpdateEmpty(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockUpdateEmptyResponse(t) + MockUpdateEmptyResponse(t, fakeServer) options := attachments.UpdateOpts{} - attachment, err := attachments.Update(context.TODO(), client.ServiceClient(), "05551600-a936-4d4a-ba42-79a037c1-c91a", options).Extract() + attachment, err := attachments.Update(context.TODO(), client.ServiceClient(fakeServer), "05551600-a936-4d4a-ba42-79a037c1-c91a", options).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, expectedAttachment, attachment) } func TestComplete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockCompleteResponse(t) + MockCompleteResponse(t, fakeServer) - err := attachments.Complete(context.TODO(), client.ServiceClient(), "05551600-a936-4d4a-ba42-79a037c1-c91a").ExtractErr() + err := attachments.Complete(context.TODO(), client.ServiceClient(fakeServer), "05551600-a936-4d4a-ba42-79a037c1-c91a").ExtractErr() th.AssertNoErr(t, err) } diff --git a/openstack/blockstorage/v3/availabilityzones/testing/fixtures_test.go b/openstack/blockstorage/v3/availabilityzones/testing/fixtures_test.go index 780c7dec26..067ba9fa12 100644 --- a/openstack/blockstorage/v3/availabilityzones/testing/fixtures_test.go +++ b/openstack/blockstorage/v3/availabilityzones/testing/fixtures_test.go @@ -41,8 +41,8 @@ var AZResult = []az.AvailabilityZone{ // HandleGetSuccessfully configures the test server to respond to a Get request // for availability zone information. -func HandleGetSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/os-availability-zone", func(w http.ResponseWriter, r *http.Request) { +func HandleGetSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/os-availability-zone", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/blockstorage/v3/availabilityzones/testing/requests_test.go b/openstack/blockstorage/v3/availabilityzones/testing/requests_test.go index 3d1ed1bd0f..fce05f2c05 100644 --- a/openstack/blockstorage/v3/availabilityzones/testing/requests_test.go +++ b/openstack/blockstorage/v3/availabilityzones/testing/requests_test.go @@ -11,12 +11,12 @@ import ( // Verifies that availability zones can be listed correctly func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleGetSuccessfully(t) + HandleGetSuccessfully(t, fakeServer) - allPages, err := az.List(client.ServiceClient()).AllPages(context.TODO()) + allPages, err := az.List(client.ServiceClient(fakeServer)).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := az.ExtractAvailabilityZones(allPages) diff --git a/openstack/blockstorage/v3/backups/testing/fixtures_test.go b/openstack/blockstorage/v3/backups/testing/fixtures_test.go index f786de3a86..51b0f953aa 100644 --- a/openstack/blockstorage/v3/backups/testing/fixtures_test.go +++ b/openstack/blockstorage/v3/backups/testing/fixtures_test.go @@ -194,8 +194,8 @@ var ( backupURL, _ = json.Marshal(backupImport) ) -func MockListResponse(t *testing.T) { - th.Mux.HandleFunc("/backups", func(w http.ResponseWriter, r *http.Request) { +func MockListResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/backups", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -208,7 +208,7 @@ func MockListResponse(t *testing.T) { marker := r.Form.Get("marker") switch marker { case "": - fmt.Fprintf(w, ListResponse, th.Server.URL) + fmt.Fprintf(w, ListResponse, fakeServer.Server.URL) case "1": fmt.Fprint(w, `{"backups": []}`) default: @@ -217,8 +217,8 @@ func MockListResponse(t *testing.T) { }) } -func MockListDetailResponse(t *testing.T) { - th.Mux.HandleFunc("/backups/detail", func(w http.ResponseWriter, r *http.Request) { +func MockListDetailResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/backups/detail", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -231,7 +231,7 @@ func MockListDetailResponse(t *testing.T) { marker := r.Form.Get("marker") switch marker { case "": - fmt.Fprintf(w, ListDetailResponse, th.Server.URL) + fmt.Fprintf(w, ListDetailResponse, fakeServer.Server.URL) case "1": fmt.Fprint(w, `{"backups": []}`) default: @@ -240,8 +240,8 @@ func MockListDetailResponse(t *testing.T) { }) } -func MockGetResponse(t *testing.T) { - th.Mux.HandleFunc("/backups/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { +func MockGetResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/backups/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -251,8 +251,8 @@ func MockGetResponse(t *testing.T) { }) } -func MockCreateResponse(t *testing.T) { - th.Mux.HandleFunc("/backups", func(w http.ResponseWriter, r *http.Request) { +func MockCreateResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/backups", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -266,8 +266,8 @@ func MockCreateResponse(t *testing.T) { }) } -func MockRestoreResponse(t *testing.T) { - th.Mux.HandleFunc("/backups/d32019d3-bc6e-4319-9c1d-6722fc136a22/restore", func(w http.ResponseWriter, r *http.Request) { +func MockRestoreResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/backups/d32019d3-bc6e-4319-9c1d-6722fc136a22/restore", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -281,16 +281,16 @@ func MockRestoreResponse(t *testing.T) { }) } -func MockDeleteResponse(t *testing.T) { - th.Mux.HandleFunc("/backups/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { +func MockDeleteResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/backups/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) } -func MockExportResponse(t *testing.T) { - th.Mux.HandleFunc("/backups/d32019d3-bc6e-4319-9c1d-6722fc136a22/export_record", func(w http.ResponseWriter, r *http.Request) { +func MockExportResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/backups/d32019d3-bc6e-4319-9c1d-6722fc136a22/export_record", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -302,8 +302,8 @@ func MockExportResponse(t *testing.T) { }) } -func MockImportResponse(t *testing.T) { - th.Mux.HandleFunc("/backups/import_record", func(w http.ResponseWriter, r *http.Request) { +func MockImportResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/backups/import_record", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -318,8 +318,8 @@ func MockImportResponse(t *testing.T) { } // MockResetStatusResponse provides mock response for reset backup status API call -func MockResetStatusResponse(t *testing.T) { - th.Mux.HandleFunc("/backups/d32019d3-bc6e-4319-9c1d-6722fc136a22/action", func(w http.ResponseWriter, r *http.Request) { +func MockResetStatusResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/backups/d32019d3-bc6e-4319-9c1d-6722fc136a22/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -330,8 +330,8 @@ func MockResetStatusResponse(t *testing.T) { } // MockForceDeleteResponse provides mock response for force delete backup API call -func MockForceDeleteResponse(t *testing.T) { - th.Mux.HandleFunc("/backups/d32019d3-bc6e-4319-9c1d-6722fc136a22/action", func(w http.ResponseWriter, r *http.Request) { +func MockForceDeleteResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/backups/d32019d3-bc6e-4319-9c1d-6722fc136a22/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") diff --git a/openstack/blockstorage/v3/backups/testing/requests_test.go b/openstack/blockstorage/v3/backups/testing/requests_test.go index b9c302896d..76b39cb09c 100644 --- a/openstack/blockstorage/v3/backups/testing/requests_test.go +++ b/openstack/blockstorage/v3/backups/testing/requests_test.go @@ -13,14 +13,14 @@ import ( ) func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockListResponse(t) + MockListResponse(t, fakeServer) count := 0 - err := backups.List(client.ServiceClient(), &backups.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := backups.List(client.ServiceClient(fakeServer), &backups.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := backups.ExtractBackups(page) if err != nil { @@ -53,14 +53,14 @@ func TestList(t *testing.T) { } func TestListDetail(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockListDetailResponse(t) + MockListDetailResponse(t, fakeServer) count := 0 - err := backups.ListDetail(client.ServiceClient(), &backups.ListDetailOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := backups.ListDetail(client.ServiceClient(fakeServer), &backups.ListDetailOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := backups.ExtractBackups(page) if err != nil { @@ -103,12 +103,12 @@ func TestListDetail(t *testing.T) { } func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockGetResponse(t) + MockGetResponse(t, fakeServer) - v, err := backups.Get(context.TODO(), client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22").Extract() + v, err := backups.Get(context.TODO(), client.ServiceClient(fakeServer), "d32019d3-bc6e-4319-9c1d-6722fc136a22").Extract() th.AssertNoErr(t, err) th.AssertEquals(t, v.Name, "backup-001") @@ -116,13 +116,13 @@ func TestGet(t *testing.T) { } func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockCreateResponse(t) + MockCreateResponse(t, fakeServer) options := backups.CreateOpts{VolumeID: "1234", Name: "backup-001"} - n, err := backups.Create(context.TODO(), client.ServiceClient(), options).Extract() + n, err := backups.Create(context.TODO(), client.ServiceClient(fakeServer), options).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, n.VolumeID, "1234") @@ -131,13 +131,13 @@ func TestCreate(t *testing.T) { } func TestRestore(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockRestoreResponse(t) + MockRestoreResponse(t, fakeServer) options := backups.RestoreOpts{VolumeID: "1234", Name: "vol-001"} - n, err := backups.RestoreFromBackup(context.TODO(), client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22", options).Extract() + n, err := backups.RestoreFromBackup(context.TODO(), client.ServiceClient(fakeServer), "d32019d3-bc6e-4319-9c1d-6722fc136a22", options).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, n.VolumeID, "1234") @@ -146,22 +146,22 @@ func TestRestore(t *testing.T) { } func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockDeleteResponse(t) + MockDeleteResponse(t, fakeServer) - res := backups.Delete(context.TODO(), client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22") + res := backups.Delete(context.TODO(), client.ServiceClient(fakeServer), "d32019d3-bc6e-4319-9c1d-6722fc136a22") th.AssertNoErr(t, res.Err) } func TestExport(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockExportResponse(t) + MockExportResponse(t, fakeServer) - n, err := backups.Export(context.TODO(), client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22").Extract() + n, err := backups.Export(context.TODO(), client.ServiceClient(fakeServer), "d32019d3-bc6e-4319-9c1d-6722fc136a22").Extract() th.AssertNoErr(t, err) th.AssertEquals(t, n.BackupService, "cinder.backup.drivers.swift.SwiftBackupDriver") @@ -174,40 +174,40 @@ func TestExport(t *testing.T) { } func TestImport(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockImportResponse(t) + MockImportResponse(t, fakeServer) options := backups.ImportOpts{ BackupService: "cinder.backup.drivers.swift.SwiftBackupDriver", BackupURL: backupURL, } - n, err := backups.Import(context.TODO(), client.ServiceClient(), options).Extract() + n, err := backups.Import(context.TODO(), client.ServiceClient(fakeServer), options).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, n.ID, "d32019d3-bc6e-4319-9c1d-6722fc136a22") } func TestResetStatus(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockResetStatusResponse(t) + MockResetStatusResponse(t, fakeServer) opts := &backups.ResetStatusOpts{ Status: "error", } - res := backups.ResetStatus(context.TODO(), client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22", opts) + res := backups.ResetStatus(context.TODO(), client.ServiceClient(fakeServer), "d32019d3-bc6e-4319-9c1d-6722fc136a22", opts) th.AssertNoErr(t, res.Err) } func TestForceDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockForceDeleteResponse(t) + MockForceDeleteResponse(t, fakeServer) - res := backups.ForceDelete(context.TODO(), client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22") + res := backups.ForceDelete(context.TODO(), client.ServiceClient(fakeServer), "d32019d3-bc6e-4319-9c1d-6722fc136a22") th.AssertNoErr(t, res.Err) } diff --git a/openstack/blockstorage/v3/limits/testing/fixtures_test.go b/openstack/blockstorage/v3/limits/testing/fixtures_test.go index 68fe8ae833..318ef7779c 100644 --- a/openstack/blockstorage/v3/limits/testing/fixtures_test.go +++ b/openstack/blockstorage/v3/limits/testing/fixtures_test.go @@ -118,8 +118,8 @@ var LimitsResult = limits.Limits{ // HandleGetSuccessfully configures the test server to respond to a Get request // for a limit. -func HandleGetSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/limits", func(w http.ResponseWriter, r *http.Request) { +func HandleGetSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/limits", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/blockstorage/v3/limits/testing/requests_test.go b/openstack/blockstorage/v3/limits/testing/requests_test.go index bd2a2cbfd2..8296ef751b 100644 --- a/openstack/blockstorage/v3/limits/testing/requests_test.go +++ b/openstack/blockstorage/v3/limits/testing/requests_test.go @@ -10,11 +10,11 @@ import ( ) func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetSuccessfully(t, fakeServer) - actual, err := limits.Get(context.TODO(), client.ServiceClient()).Extract() + actual, err := limits.Get(context.TODO(), client.ServiceClient(fakeServer)).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, &LimitsResult, actual) } diff --git a/openstack/blockstorage/v3/manageablevolumes/testing/fixtures_test.go b/openstack/blockstorage/v3/manageablevolumes/testing/fixtures_test.go index 5fdc8fb995..cc124c02e3 100644 --- a/openstack/blockstorage/v3/manageablevolumes/testing/fixtures_test.go +++ b/openstack/blockstorage/v3/manageablevolumes/testing/fixtures_test.go @@ -9,8 +9,8 @@ import ( fake "github.com/gophercloud/gophercloud/v2/testhelper/client" ) -func MockManageExistingResponse(t *testing.T) { - th.Mux.HandleFunc("/manageable_volumes", func(w http.ResponseWriter, r *http.Request) { +func MockManageExistingResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/manageable_volumes", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") diff --git a/openstack/blockstorage/v3/manageablevolumes/testing/requests_test.go b/openstack/blockstorage/v3/manageablevolumes/testing/requests_test.go index cabbfde4ea..7cbf0fe3f4 100644 --- a/openstack/blockstorage/v3/manageablevolumes/testing/requests_test.go +++ b/openstack/blockstorage/v3/manageablevolumes/testing/requests_test.go @@ -10,10 +10,10 @@ import ( ) func TestManageExisting(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockManageExistingResponse(t) + MockManageExistingResponse(t, fakeServer) options := &manageablevolumes.ManageExistingOpts{ Host: "host@lvm#LVM", @@ -28,7 +28,7 @@ func TestManageExisting(t *testing.T) { "key2": "value2", }, } - n, err := manageablevolumes.ManageExisting(context.TODO(), client.ServiceClient(), options).Extract() + n, err := manageablevolumes.ManageExisting(context.TODO(), client.ServiceClient(fakeServer), options).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, n.Host, "host@lvm#LVM") diff --git a/openstack/blockstorage/v3/qos/testing/fixtures_test.go b/openstack/blockstorage/v3/qos/testing/fixtures_test.go index 7d55ddc577..0e52ba2048 100644 --- a/openstack/blockstorage/v3/qos/testing/fixtures_test.go +++ b/openstack/blockstorage/v3/qos/testing/fixtures_test.go @@ -28,8 +28,8 @@ var getQoSExpected = qos.QoS{ }, } -func MockCreateResponse(t *testing.T) { - th.Mux.HandleFunc("/qos-specs", func(w http.ResponseWriter, r *http.Request) { +func MockCreateResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/qos-specs", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -62,16 +62,16 @@ func MockCreateResponse(t *testing.T) { }) } -func MockDeleteResponse(t *testing.T) { - th.Mux.HandleFunc("/qos-specs/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { +func MockDeleteResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/qos-specs/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusAccepted) }) } -func MockListResponse(t *testing.T) { - th.Mux.HandleFunc("/qos-specs", func(w http.ResponseWriter, r *http.Request) { +func MockListResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/qos-specs", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -108,7 +108,7 @@ func MockListResponse(t *testing.T) { } ] } - `, th.Server.URL) + `, fakeServer.Server.URL) case "2": fmt.Fprint(w, `{ "qos_specs": [] }`) default: @@ -117,8 +117,8 @@ func MockListResponse(t *testing.T) { }) } -func MockGetResponse(t *testing.T) { - th.Mux.HandleFunc("/qos-specs/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { +func MockGetResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/qos-specs/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") @@ -157,8 +157,8 @@ var UpdateQos = map[string]string{ "write_iops_sec": "40000", } -func MockUpdateResponse(t *testing.T) { - th.Mux.HandleFunc("/qos-specs/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { +func MockUpdateResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/qos-specs/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -176,8 +176,8 @@ func MockUpdateResponse(t *testing.T) { }) } -func MockDeleteKeysResponse(t *testing.T) { - th.Mux.HandleFunc("/qos-specs/d32019d3-bc6e-4319-9c1d-6722fc136a22/delete_keys", func(w http.ResponseWriter, r *http.Request) { +func MockDeleteKeysResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/qos-specs/d32019d3-bc6e-4319-9c1d-6722fc136a22/delete_keys", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, `{ @@ -190,32 +190,32 @@ func MockDeleteKeysResponse(t *testing.T) { }) } -func MockAssociateResponse(t *testing.T) { - th.Mux.HandleFunc("/qos-specs/d32019d3-bc6e-4319-9c1d-6722fc136a22/associate", func(w http.ResponseWriter, r *http.Request) { +func MockAssociateResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/qos-specs/d32019d3-bc6e-4319-9c1d-6722fc136a22/associate", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusAccepted) }) } -func MockDisassociateResponse(t *testing.T) { - th.Mux.HandleFunc("/qos-specs/d32019d3-bc6e-4319-9c1d-6722fc136a22/disassociate", func(w http.ResponseWriter, r *http.Request) { +func MockDisassociateResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/qos-specs/d32019d3-bc6e-4319-9c1d-6722fc136a22/disassociate", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusAccepted) }) } -func MockDisassociateAllResponse(t *testing.T) { - th.Mux.HandleFunc("/qos-specs/d32019d3-bc6e-4319-9c1d-6722fc136a22/disassociate_all", func(w http.ResponseWriter, r *http.Request) { +func MockDisassociateAllResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/qos-specs/d32019d3-bc6e-4319-9c1d-6722fc136a22/disassociate_all", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusAccepted) }) } -func MockListAssociationsResponse(t *testing.T) { - th.Mux.HandleFunc("/qos-specs/d32019d3-bc6e-4319-9c1d-6722fc136a22/associations", func(w http.ResponseWriter, r *http.Request) { +func MockListAssociationsResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/qos-specs/d32019d3-bc6e-4319-9c1d-6722fc136a22/associations", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") diff --git a/openstack/blockstorage/v3/qos/testing/requests_test.go b/openstack/blockstorage/v3/qos/testing/requests_test.go index be88fbd302..7ccfa4a424 100644 --- a/openstack/blockstorage/v3/qos/testing/requests_test.go +++ b/openstack/blockstorage/v3/qos/testing/requests_test.go @@ -12,10 +12,10 @@ import ( ) func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockCreateResponse(t) + MockCreateResponse(t, fakeServer) options := qos.CreateOpts{ Name: "qos-001", @@ -24,29 +24,29 @@ func TestCreate(t *testing.T) { "read_iops_sec": "20000", }, } - actual, err := qos.Create(context.TODO(), client.ServiceClient(), options).Extract() + actual, err := qos.Create(context.TODO(), client.ServiceClient(fakeServer), options).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, &createQoSExpected, actual) } func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockDeleteResponse(t) + MockDeleteResponse(t, fakeServer) - res := qos.Delete(context.TODO(), client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22", qos.DeleteOpts{}) + res := qos.Delete(context.TODO(), client.ServiceClient(fakeServer), "d32019d3-bc6e-4319-9c1d-6722fc136a22", qos.DeleteOpts{}) th.AssertNoErr(t, res.Err) } func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockListResponse(t) + MockListResponse(t, fakeServer) pages := 0 - err := qos.List(client.ServiceClient(), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := qos.List(client.ServiceClient(fakeServer), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := qos.ExtractQoS(page) if err != nil { @@ -76,20 +76,20 @@ func TestList(t *testing.T) { } func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockGetResponse(t) + MockGetResponse(t, fakeServer) - actual, err := qos.Get(context.TODO(), client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22").Extract() + actual, err := qos.Get(context.TODO(), client.ServiceClient(fakeServer), "d32019d3-bc6e-4319-9c1d-6722fc136a22").Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, &getQoSExpected, actual) } func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - MockUpdateResponse(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + MockUpdateResponse(t, fakeServer) updateOpts := qos.UpdateOpts{ Consumer: qos.ConsumerBack, @@ -100,64 +100,64 @@ func TestUpdate(t *testing.T) { } expected := UpdateQos - actual, err := qos.Update(context.TODO(), client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22", updateOpts).Extract() + actual, err := qos.Update(context.TODO(), client.ServiceClient(fakeServer), "d32019d3-bc6e-4319-9c1d-6722fc136a22", updateOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, expected, actual) } func TestDeleteKeys(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockDeleteKeysResponse(t) + MockDeleteKeysResponse(t, fakeServer) - res := qos.DeleteKeys(context.TODO(), client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22", qos.DeleteKeysOpts{"read_iops_sec"}) + res := qos.DeleteKeys(context.TODO(), client.ServiceClient(fakeServer), "d32019d3-bc6e-4319-9c1d-6722fc136a22", qos.DeleteKeysOpts{"read_iops_sec"}) th.AssertNoErr(t, res.Err) } func TestAssociate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockAssociateResponse(t) + MockAssociateResponse(t, fakeServer) associateOpts := qos.AssociateOpts{ VolumeTypeID: "b596be6a-0ce9-43fa-804a-5c5e181ede76", } - res := qos.Associate(context.TODO(), client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22", associateOpts) + res := qos.Associate(context.TODO(), client.ServiceClient(fakeServer), "d32019d3-bc6e-4319-9c1d-6722fc136a22", associateOpts) th.AssertNoErr(t, res.Err) } func TestDisssociate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockDisassociateResponse(t) + MockDisassociateResponse(t, fakeServer) disassociateOpts := qos.DisassociateOpts{ VolumeTypeID: "b596be6a-0ce9-43fa-804a-5c5e181ede76", } - res := qos.Disassociate(context.TODO(), client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22", disassociateOpts) + res := qos.Disassociate(context.TODO(), client.ServiceClient(fakeServer), "d32019d3-bc6e-4319-9c1d-6722fc136a22", disassociateOpts) th.AssertNoErr(t, res.Err) } func TestDissasociateAll(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockDisassociateAllResponse(t) + MockDisassociateAllResponse(t, fakeServer) - res := qos.DisassociateAll(context.TODO(), client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22") + res := qos.DisassociateAll(context.TODO(), client.ServiceClient(fakeServer), "d32019d3-bc6e-4319-9c1d-6722fc136a22") th.AssertNoErr(t, res.Err) } func TestQosAssociationsList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockListAssociationsResponse(t) + MockListAssociationsResponse(t, fakeServer) expected := []qos.QosAssociation{ { @@ -167,7 +167,7 @@ func TestQosAssociationsList(t *testing.T) { }, } - allPages, err := qos.ListAssociations(client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22").AllPages(context.TODO()) + allPages, err := qos.ListAssociations(client.ServiceClient(fakeServer), "d32019d3-bc6e-4319-9c1d-6722fc136a22").AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := qos.ExtractAssociations(allPages) diff --git a/openstack/blockstorage/v3/quotasets/testing/fixtures_test.go b/openstack/blockstorage/v3/quotasets/testing/fixtures_test.go index 103afef6ef..55c0fc6ddc 100644 --- a/openstack/blockstorage/v3/quotasets/testing/fixtures_test.go +++ b/openstack/blockstorage/v3/quotasets/testing/fixtures_test.go @@ -153,9 +153,9 @@ var partiualUpdateExpectedQuotaSet = quotasets.QuotaSet{ } // HandleSuccessfulRequest configures the test server to respond to an HTTP request. -func HandleSuccessfulRequest(t *testing.T, httpMethod, uriPath, jsonOutput string, uriQueryParams map[string]string) { +func HandleSuccessfulRequest(t *testing.T, fakeServer th.FakeServer, httpMethod, uriPath, jsonOutput string, uriQueryParams map[string]string) { - th.Mux.HandleFunc(uriPath, func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc(uriPath, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, httpMethod) th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") @@ -169,8 +169,8 @@ func HandleSuccessfulRequest(t *testing.T, httpMethod, uriPath, jsonOutput strin } // HandleDeleteSuccessfully tests quotaset deletion. -func HandleDeleteSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/os-quota-sets/"+FirstTenantID, func(w http.ResponseWriter, r *http.Request) { +func HandleDeleteSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/os-quota-sets/"+FirstTenantID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/blockstorage/v3/quotasets/testing/requests_test.go b/openstack/blockstorage/v3/quotasets/testing/requests_test.go index ca17ef10b4..c8f7bb579c 100644 --- a/openstack/blockstorage/v3/quotasets/testing/requests_test.go +++ b/openstack/blockstorage/v3/quotasets/testing/requests_test.go @@ -11,45 +11,45 @@ import ( ) func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() uriQueryParms := map[string]string{} - HandleSuccessfulRequest(t, "GET", "/os-quota-sets/"+FirstTenantID, getExpectedJSONBody, uriQueryParms) - actual, err := quotasets.Get(context.TODO(), client.ServiceClient(), FirstTenantID).Extract() + HandleSuccessfulRequest(t, fakeServer, "GET", "/os-quota-sets/"+FirstTenantID, getExpectedJSONBody, uriQueryParms) + actual, err := quotasets.Get(context.TODO(), client.ServiceClient(fakeServer), FirstTenantID).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, &getExpectedQuotaSet, actual) } func TestGetUsage(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() uriQueryParms := map[string]string{"usage": "true"} - HandleSuccessfulRequest(t, "GET", "/os-quota-sets/"+FirstTenantID, getUsageExpectedJSONBody, uriQueryParms) - actual, err := quotasets.GetUsage(context.TODO(), client.ServiceClient(), FirstTenantID).Extract() + HandleSuccessfulRequest(t, fakeServer, "GET", "/os-quota-sets/"+FirstTenantID, getUsageExpectedJSONBody, uriQueryParms) + actual, err := quotasets.GetUsage(context.TODO(), client.ServiceClient(fakeServer), FirstTenantID).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, getUsageExpectedQuotaSet, actual) } func TestFullUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() uriQueryParms := map[string]string{} - HandleSuccessfulRequest(t, "PUT", "/os-quota-sets/"+FirstTenantID, fullUpdateExpectedJSONBody, uriQueryParms) - actual, err := quotasets.Update(context.TODO(), client.ServiceClient(), FirstTenantID, fullUpdateOpts).Extract() + HandleSuccessfulRequest(t, fakeServer, "PUT", "/os-quota-sets/"+FirstTenantID, fullUpdateExpectedJSONBody, uriQueryParms) + actual, err := quotasets.Update(context.TODO(), client.ServiceClient(fakeServer), FirstTenantID, fullUpdateOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, &fullUpdateExpectedQuotaSet, actual) } func TestPartialUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() uriQueryParms := map[string]string{} - HandleSuccessfulRequest(t, "PUT", "/os-quota-sets/"+FirstTenantID, partialUpdateExpectedJSONBody, uriQueryParms) - actual, err := quotasets.Update(context.TODO(), client.ServiceClient(), FirstTenantID, partialUpdateOpts).Extract() + HandleSuccessfulRequest(t, fakeServer, "PUT", "/os-quota-sets/"+FirstTenantID, partialUpdateExpectedJSONBody, uriQueryParms) + actual, err := quotasets.Update(context.TODO(), client.ServiceClient(fakeServer), FirstTenantID, partialUpdateOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, &partiualUpdateExpectedQuotaSet, actual) } @@ -62,20 +62,20 @@ func (opts ErrorUpdateOpts) ToBlockStorageQuotaUpdateMap() (map[string]any, erro func TestErrorInToBlockStorageQuotaUpdateMap(t *testing.T) { opts := &ErrorUpdateOpts{} - th.SetupHTTP() - defer th.TeardownHTTP() - HandleSuccessfulRequest(t, "PUT", "/os-quota-sets/"+FirstTenantID, "", nil) - _, err := quotasets.Update(context.TODO(), client.ServiceClient(), FirstTenantID, opts).Extract() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleSuccessfulRequest(t, fakeServer, "PUT", "/os-quota-sets/"+FirstTenantID, "", nil) + _, err := quotasets.Update(context.TODO(), client.ServiceClient(fakeServer), FirstTenantID, opts).Extract() if err == nil { t.Fatal("Error handling failed") } } func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDeleteSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDeleteSuccessfully(t, fakeServer) - err := quotasets.Delete(context.TODO(), client.ServiceClient(), FirstTenantID).ExtractErr() + err := quotasets.Delete(context.TODO(), client.ServiceClient(fakeServer), FirstTenantID).ExtractErr() th.AssertNoErr(t, err) } diff --git a/openstack/blockstorage/v3/schedulerstats/testing/fixtures_test.go b/openstack/blockstorage/v3/schedulerstats/testing/fixtures_test.go index 18462bfb20..d84f647cb2 100644 --- a/openstack/blockstorage/v3/schedulerstats/testing/fixtures_test.go +++ b/openstack/blockstorage/v3/schedulerstats/testing/fixtures_test.go @@ -93,8 +93,8 @@ var ( } ) -func HandleStoragePoolsListSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/scheduler-stats/get_pools", func(w http.ResponseWriter, r *http.Request) { +func HandleStoragePoolsListSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/scheduler-stats/get_pools", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/blockstorage/v3/schedulerstats/testing/requests_test.go b/openstack/blockstorage/v3/schedulerstats/testing/requests_test.go index c125763276..d42cf69b6b 100644 --- a/openstack/blockstorage/v3/schedulerstats/testing/requests_test.go +++ b/openstack/blockstorage/v3/schedulerstats/testing/requests_test.go @@ -11,12 +11,12 @@ import ( ) func TestListStoragePoolsDetail(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleStoragePoolsListSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleStoragePoolsListSuccessfully(t, fakeServer) pages := 0 - err := schedulerstats.List(client.ServiceClient(), schedulerstats.ListOpts{Detail: true}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := schedulerstats.List(client.ServiceClient(fakeServer), schedulerstats.ListOpts{Detail: true}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := schedulerstats.ExtractStoragePools(page) diff --git a/openstack/blockstorage/v3/services/testing/fixtures_test.go b/openstack/blockstorage/v3/services/testing/fixtures_test.go index 63771ff032..f1acd556d3 100644 --- a/openstack/blockstorage/v3/services/testing/fixtures_test.go +++ b/openstack/blockstorage/v3/services/testing/fixtures_test.go @@ -86,8 +86,8 @@ var ThirdFakeService = services.Service{ } // HandleListSuccessfully configures the test server to respond to a List request. -func HandleListSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/os-services", func(w http.ResponseWriter, r *http.Request) { +func HandleListSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/os-services", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/blockstorage/v3/services/testing/requests_test.go b/openstack/blockstorage/v3/services/testing/requests_test.go index 4e291da96b..12fa3bc33f 100644 --- a/openstack/blockstorage/v3/services/testing/requests_test.go +++ b/openstack/blockstorage/v3/services/testing/requests_test.go @@ -11,12 +11,12 @@ import ( ) func TestListServices(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListSuccessfully(t, fakeServer) pages := 0 - err := services.List(client.ServiceClient(), services.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := services.List(client.ServiceClient(fakeServer), services.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := services.ExtractServices(page) diff --git a/openstack/blockstorage/v3/snapshots/testing/fixtures_test.go b/openstack/blockstorage/v3/snapshots/testing/fixtures_test.go index f74934e3c4..a5ce93c38b 100644 --- a/openstack/blockstorage/v3/snapshots/testing/fixtures_test.go +++ b/openstack/blockstorage/v3/snapshots/testing/fixtures_test.go @@ -10,8 +10,8 @@ import ( ) // MockListResponse provides mock response for list snapshot API call -func MockListResponse(t *testing.T) { - th.Mux.HandleFunc("/snapshots", func(w http.ResponseWriter, r *http.Request) { +func MockListResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/snapshots", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -52,7 +52,7 @@ func MockListResponse(t *testing.T) { "rel": "next" }] } - `, th.Server.URL) + `, fakeServer.Server.URL) case "1": fmt.Fprint(w, `{"snapshots": []}`) default: @@ -61,8 +61,8 @@ func MockListResponse(t *testing.T) { }) } -func MockListDetailsResponse(t *testing.T) { - th.Mux.HandleFunc("/snapshots/detail", func(w http.ResponseWriter, r *http.Request) { +func MockListDetailsResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/snapshots/detail", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -118,8 +118,8 @@ func MockListDetailsResponse(t *testing.T) { } // MockGetResponse provides mock response for get snapshot API call -func MockGetResponse(t *testing.T) { - th.Mux.HandleFunc("/snapshots/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { +func MockGetResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/snapshots/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -142,8 +142,8 @@ func MockGetResponse(t *testing.T) { } // MockCreateResponse provides mock response for create snapshot API call -func MockCreateResponse(t *testing.T) { - th.Mux.HandleFunc("/snapshots", func(w http.ResponseWriter, r *http.Request) { +func MockCreateResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/snapshots", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -178,8 +178,8 @@ func MockCreateResponse(t *testing.T) { } // MockUpdateMetadataResponse provides mock response for update metadata snapshot API call -func MockUpdateMetadataResponse(t *testing.T) { - th.Mux.HandleFunc("/snapshots/123/metadata", func(w http.ResponseWriter, r *http.Request) { +func MockUpdateMetadataResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/snapshots/123/metadata", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -202,8 +202,8 @@ func MockUpdateMetadataResponse(t *testing.T) { } // MockDeleteResponse provides mock response for delete snapshot API call -func MockDeleteResponse(t *testing.T) { - th.Mux.HandleFunc("/snapshots/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { +func MockDeleteResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/snapshots/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) @@ -211,8 +211,8 @@ func MockDeleteResponse(t *testing.T) { } // MockUpdateResponse provides mock response for update snapshot API call -func MockUpdateResponse(t *testing.T) { - th.Mux.HandleFunc("/snapshots/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { +func MockUpdateResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/snapshots/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -236,8 +236,8 @@ func MockUpdateResponse(t *testing.T) { } // MockResetStatusResponse provides mock response for reset snapshot status API call -func MockResetStatusResponse(t *testing.T) { - th.Mux.HandleFunc("/snapshots/d32019d3-bc6e-4319-9c1d-6722fc136a22/action", func(w http.ResponseWriter, r *http.Request) { +func MockResetStatusResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/snapshots/d32019d3-bc6e-4319-9c1d-6722fc136a22/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -253,8 +253,8 @@ func MockResetStatusResponse(t *testing.T) { } // MockUpdateStatusResponse provides mock response for update snapshot status API call -func MockUpdateStatusResponse(t *testing.T) { - th.Mux.HandleFunc("/snapshots/d32019d3-bc6e-4319-9c1d-6722fc136a22/action", func(w http.ResponseWriter, r *http.Request) { +func MockUpdateStatusResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/snapshots/d32019d3-bc6e-4319-9c1d-6722fc136a22/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -271,8 +271,8 @@ func MockUpdateStatusResponse(t *testing.T) { } // MockForceDeleteResponse provides mock response for force delete snapshot API call -func MockForceDeleteResponse(t *testing.T) { - th.Mux.HandleFunc("/snapshots/d32019d3-bc6e-4319-9c1d-6722fc136a22/action", func(w http.ResponseWriter, r *http.Request) { +func MockForceDeleteResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/snapshots/d32019d3-bc6e-4319-9c1d-6722fc136a22/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") diff --git a/openstack/blockstorage/v3/snapshots/testing/requests_test.go b/openstack/blockstorage/v3/snapshots/testing/requests_test.go index aca65ba7a0..fb7a6d3196 100644 --- a/openstack/blockstorage/v3/snapshots/testing/requests_test.go +++ b/openstack/blockstorage/v3/snapshots/testing/requests_test.go @@ -12,14 +12,14 @@ import ( ) func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockListResponse(t) + MockListResponse(t, fakeServer) count := 0 - err := snapshots.List(client.ServiceClient(), &snapshots.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := snapshots.List(client.ServiceClient(fakeServer), &snapshots.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := snapshots.ExtractSnapshots(page) if err != nil { @@ -60,14 +60,14 @@ func TestList(t *testing.T) { } func TestDetailList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockListDetailsResponse(t) + MockListDetailsResponse(t, fakeServer) count := 0 - err := snapshots.ListDetail(client.ServiceClient(), &snapshots.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := snapshots.ListDetail(client.ServiceClient(fakeServer), &snapshots.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := snapshots.ExtractSnapshots(page) if err != nil { @@ -116,12 +116,12 @@ func TestDetailList(t *testing.T) { } func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockGetResponse(t) + MockGetResponse(t, fakeServer) - v, err := snapshots.Get(context.TODO(), client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22").Extract() + v, err := snapshots.Get(context.TODO(), client.ServiceClient(fakeServer), "d32019d3-bc6e-4319-9c1d-6722fc136a22").Extract() th.AssertNoErr(t, err) th.AssertEquals(t, v.Name, "snapshot-001") @@ -129,13 +129,13 @@ func TestGet(t *testing.T) { } func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockCreateResponse(t) + MockCreateResponse(t, fakeServer) options := snapshots.CreateOpts{VolumeID: "1234", Name: "snapshot-001"} - n, err := snapshots.Create(context.TODO(), client.ServiceClient(), options).Extract() + n, err := snapshots.Create(context.TODO(), client.ServiceClient(fakeServer), options).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, n.VolumeID, "1234") @@ -144,10 +144,10 @@ func TestCreate(t *testing.T) { } func TestUpdateMetadata(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockUpdateMetadataResponse(t) + MockUpdateMetadataResponse(t, fakeServer) expected := map[string]any{"key": "v1"} @@ -157,70 +157,70 @@ func TestUpdateMetadata(t *testing.T) { }, } - actual, err := snapshots.UpdateMetadata(context.TODO(), client.ServiceClient(), "123", options).ExtractMetadata() + actual, err := snapshots.UpdateMetadata(context.TODO(), client.ServiceClient(fakeServer), "123", options).ExtractMetadata() th.AssertNoErr(t, err) th.AssertDeepEquals(t, actual, expected) } func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockDeleteResponse(t) + MockDeleteResponse(t, fakeServer) - res := snapshots.Delete(context.TODO(), client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22") + res := snapshots.Delete(context.TODO(), client.ServiceClient(fakeServer), "d32019d3-bc6e-4319-9c1d-6722fc136a22") th.AssertNoErr(t, res.Err) } func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockUpdateResponse(t) + MockUpdateResponse(t, fakeServer) var name = "snapshot-002" var description = "Daily backup 002" options := snapshots.UpdateOpts{Name: &name, Description: &description} - v, err := snapshots.Update(context.TODO(), client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22", options).Extract() + v, err := snapshots.Update(context.TODO(), client.ServiceClient(fakeServer), "d32019d3-bc6e-4319-9c1d-6722fc136a22", options).Extract() th.AssertNoErr(t, err) th.CheckEquals(t, "snapshot-002", v.Name) th.CheckEquals(t, "Daily backup 002", v.Description) } func TestResetStatus(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockResetStatusResponse(t) + MockResetStatusResponse(t, fakeServer) opts := &snapshots.ResetStatusOpts{ Status: "error", } - res := snapshots.ResetStatus(context.TODO(), client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22", opts) + res := snapshots.ResetStatus(context.TODO(), client.ServiceClient(fakeServer), "d32019d3-bc6e-4319-9c1d-6722fc136a22", opts) th.AssertNoErr(t, res.Err) } func TestUpdateStatus(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockUpdateStatusResponse(t) + MockUpdateStatusResponse(t, fakeServer) opts := &snapshots.UpdateStatusOpts{ Status: "error", Progress: "80%", } - res := snapshots.UpdateStatus(context.TODO(), client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22", opts) + res := snapshots.UpdateStatus(context.TODO(), client.ServiceClient(fakeServer), "d32019d3-bc6e-4319-9c1d-6722fc136a22", opts) th.AssertNoErr(t, res.Err) } func TestForceDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockForceDeleteResponse(t) + MockForceDeleteResponse(t, fakeServer) - res := snapshots.ForceDelete(context.TODO(), client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22") + res := snapshots.ForceDelete(context.TODO(), client.ServiceClient(fakeServer), "d32019d3-bc6e-4319-9c1d-6722fc136a22") th.AssertNoErr(t, res.Err) } diff --git a/openstack/blockstorage/v3/transfers/testing/fixtures_test.go b/openstack/blockstorage/v3/transfers/testing/fixtures_test.go index 859e454eca..2e1d50b667 100644 --- a/openstack/blockstorage/v3/transfers/testing/fixtures_test.go +++ b/openstack/blockstorage/v3/transfers/testing/fixtures_test.go @@ -159,8 +159,8 @@ var AcceptResponse = transfers.Transfer{ }, } -func HandleCreateTransfer(t *testing.T) { - th.Mux.HandleFunc("/os-volume-transfer", func(w http.ResponseWriter, r *http.Request) { +func HandleCreateTransfer(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/os-volume-transfer", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") @@ -171,8 +171,8 @@ func HandleCreateTransfer(t *testing.T) { }) } -func HandleAcceptTransfer(t *testing.T) { - th.Mux.HandleFunc("/os-volume-transfer/b8913bfd-a4d3-4ec5-bd8b-fe2dbeef9f4f/accept", func(w http.ResponseWriter, r *http.Request) { +func HandleAcceptTransfer(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/os-volume-transfer/b8913bfd-a4d3-4ec5-bd8b-fe2dbeef9f4f/accept", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") @@ -183,8 +183,8 @@ func HandleAcceptTransfer(t *testing.T) { }) } -func HandleDeleteTransfer(t *testing.T) { - th.Mux.HandleFunc("/os-volume-transfer/b8913bfd-a4d3-4ec5-bd8b-fe2dbeef9f4f", func(w http.ResponseWriter, r *http.Request) { +func HandleDeleteTransfer(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/os-volume-transfer/b8913bfd-a4d3-4ec5-bd8b-fe2dbeef9f4f", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -192,8 +192,8 @@ func HandleDeleteTransfer(t *testing.T) { }) } -func HandleListTransfers(t *testing.T) { - th.Mux.HandleFunc("/os-volume-transfer/detail", func(w http.ResponseWriter, r *http.Request) { +func HandleListTransfers(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/os-volume-transfer/detail", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") @@ -204,8 +204,8 @@ func HandleListTransfers(t *testing.T) { }) } -func HandleGetTransfer(t *testing.T) { - th.Mux.HandleFunc("/os-volume-transfer/b8913bfd-a4d3-4ec5-bd8b-fe2dbeef9f4f", func(w http.ResponseWriter, r *http.Request) { +func HandleGetTransfer(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/os-volume-transfer/b8913bfd-a4d3-4ec5-bd8b-fe2dbeef9f4f", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") diff --git a/openstack/blockstorage/v3/transfers/testing/requests_test.go b/openstack/blockstorage/v3/transfers/testing/requests_test.go index 43013a71ec..5b5428e1f4 100644 --- a/openstack/blockstorage/v3/transfers/testing/requests_test.go +++ b/openstack/blockstorage/v3/transfers/testing/requests_test.go @@ -11,44 +11,44 @@ import ( ) func TestCreateTransfer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateTransfer(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCreateTransfer(t, fakeServer) - actual, err := transfers.Create(context.TODO(), client.ServiceClient(), TransferRequest).Extract() + actual, err := transfers.Create(context.TODO(), client.ServiceClient(fakeServer), TransferRequest).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, TransferResponse, *actual) } func TestAcceptTransfer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleAcceptTransfer(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleAcceptTransfer(t, fakeServer) - actual, err := transfers.Accept(context.TODO(), client.ServiceClient(), TransferResponse.ID, AcceptRequest).Extract() + actual, err := transfers.Accept(context.TODO(), client.ServiceClient(fakeServer), TransferResponse.ID, AcceptRequest).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, AcceptResponse, *actual) } func TestDeleteTransfer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDeleteTransfer(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDeleteTransfer(t, fakeServer) - err := transfers.Delete(context.TODO(), client.ServiceClient(), TransferResponse.ID).ExtractErr() + err := transfers.Delete(context.TODO(), client.ServiceClient(fakeServer), TransferResponse.ID).ExtractErr() th.AssertNoErr(t, err) } func TestListTransfers(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListTransfers(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListTransfers(t, fakeServer) expectedResponse := TransferListResponse expectedResponse[0].AuthKey = "" count := 0 - err := transfers.List(client.ServiceClient(), &transfers.ListOpts{AllTenants: true}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := transfers.List(client.ServiceClient(fakeServer), &transfers.ListOpts{AllTenants: true}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := transfers.ExtractTransfers(page) @@ -63,14 +63,14 @@ func TestListTransfers(t *testing.T) { } func TestListTransfersAllPages(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListTransfers(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListTransfers(t, fakeServer) expectedResponse := TransferListResponse expectedResponse[0].AuthKey = "" - allPages, err := transfers.List(client.ServiceClient(), &transfers.ListOpts{AllTenants: true}).AllPages(context.TODO()) + allPages, err := transfers.List(client.ServiceClient(fakeServer), &transfers.ListOpts{AllTenants: true}).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := transfers.ExtractTransfers(allPages) th.AssertNoErr(t, err) @@ -78,14 +78,14 @@ func TestListTransfersAllPages(t *testing.T) { } func TestGetTransfer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetTransfer(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetTransfer(t, fakeServer) expectedResponse := TransferResponse expectedResponse.AuthKey = "" - actual, err := transfers.Get(context.TODO(), client.ServiceClient(), TransferResponse.ID).Extract() + actual, err := transfers.Get(context.TODO(), client.ServiceClient(fakeServer), TransferResponse.ID).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, expectedResponse, *actual) } diff --git a/openstack/blockstorage/v3/volumes/testing/fixtures_test.go b/openstack/blockstorage/v3/volumes/testing/fixtures_test.go index adc16c0ea5..2cabeb7ceb 100644 --- a/openstack/blockstorage/v3/volumes/testing/fixtures_test.go +++ b/openstack/blockstorage/v3/volumes/testing/fixtures_test.go @@ -9,8 +9,8 @@ import ( "github.com/gophercloud/gophercloud/v2/testhelper/client" ) -func MockListResponse(t *testing.T) { - th.Mux.HandleFunc("/volumes/detail", func(w http.ResponseWriter, r *http.Request) { +func MockListResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/volumes/detail", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -93,7 +93,7 @@ func MockListResponse(t *testing.T) { "rel": "next" }] } - `, th.Server.URL) + `, fakeServer.Server.URL) case "1": fmt.Fprint(w, `{"volumes": []}`) default: @@ -102,8 +102,8 @@ func MockListResponse(t *testing.T) { }) } -func MockGetResponse(t *testing.T) { - th.Mux.HandleFunc("/volumes/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { +func MockGetResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/volumes/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -153,8 +153,8 @@ func MockGetResponse(t *testing.T) { }) } -func MockCreateResponse(t *testing.T) { - th.Mux.HandleFunc("/volumes", func(w http.ResponseWriter, r *http.Request) { +func MockCreateResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/volumes", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -198,16 +198,16 @@ func MockCreateResponse(t *testing.T) { }) } -func MockDeleteResponse(t *testing.T) { - th.Mux.HandleFunc("/volumes/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { +func MockDeleteResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/volumes/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusAccepted) }) } -func MockUpdateResponse(t *testing.T) { - th.Mux.HandleFunc("/volumes/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { +func MockUpdateResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/volumes/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusOK) @@ -221,8 +221,8 @@ func MockUpdateResponse(t *testing.T) { }) } -func MockCreateVolumeFromBackupResponse(t *testing.T) { - th.Mux.HandleFunc("/volumes", func(w http.ResponseWriter, r *http.Request) { +func MockCreateVolumeFromBackupResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/volumes", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -266,8 +266,8 @@ func MockCreateVolumeFromBackupResponse(t *testing.T) { }) } -func MockAttachResponse(t *testing.T) { - th.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", +func MockAttachResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -291,8 +291,8 @@ func MockAttachResponse(t *testing.T) { }) } -func MockBeginDetachingResponse(t *testing.T) { - th.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", +func MockBeginDetachingResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -311,8 +311,8 @@ func MockBeginDetachingResponse(t *testing.T) { }) } -func MockDetachResponse(t *testing.T) { - th.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", +func MockDetachResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -331,8 +331,8 @@ func MockDetachResponse(t *testing.T) { }) } -func MockUploadImageResponse(t *testing.T) { - th.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", +func MockUploadImageResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -383,8 +383,8 @@ func MockUploadImageResponse(t *testing.T) { }) } -func MockReserveResponse(t *testing.T) { - th.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", +func MockReserveResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -403,8 +403,8 @@ func MockReserveResponse(t *testing.T) { }) } -func MockUnreserveResponse(t *testing.T) { - th.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", +func MockUnreserveResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -423,8 +423,8 @@ func MockUnreserveResponse(t *testing.T) { }) } -func MockInitializeConnectionResponse(t *testing.T) { - th.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", +func MockInitializeConnectionResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -480,8 +480,8 @@ func MockInitializeConnectionResponse(t *testing.T) { }) } -func MockTerminateConnectionResponse(t *testing.T) { - th.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", +func MockTerminateConnectionResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -511,8 +511,8 @@ func MockTerminateConnectionResponse(t *testing.T) { }) } -func MockExtendSizeResponse(t *testing.T) { - th.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", +func MockExtendSizeResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -534,8 +534,8 @@ func MockExtendSizeResponse(t *testing.T) { }) } -func MockForceDeleteResponse(t *testing.T) { - th.Mux.HandleFunc("/volumes/d32019d3-bc6e-4319-9c1d-6722fc136a22/action", func(w http.ResponseWriter, r *http.Request) { +func MockForceDeleteResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/volumes/d32019d3-bc6e-4319-9c1d-6722fc136a22/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestBody(t, r, `{"os-force_delete":""}`) @@ -543,8 +543,8 @@ func MockForceDeleteResponse(t *testing.T) { }) } -func MockSetImageMetadataResponse(t *testing.T) { - th.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { +func MockSetImageMetadataResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -565,8 +565,8 @@ func MockSetImageMetadataResponse(t *testing.T) { }) } -func MockSetBootableResponse(t *testing.T) { - th.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { +func MockSetBootableResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -584,8 +584,8 @@ func MockSetBootableResponse(t *testing.T) { }) } -func MockReImageResponse(t *testing.T) { - th.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { +func MockReImageResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -604,8 +604,8 @@ func MockReImageResponse(t *testing.T) { }) } -func MockChangeTypeResponse(t *testing.T) { - th.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", +func MockChangeTypeResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -628,8 +628,8 @@ func MockChangeTypeResponse(t *testing.T) { }) } -func MockResetStatusResponse(t *testing.T) { - th.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", +func MockResetStatusResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -649,11 +649,11 @@ func MockResetStatusResponse(t *testing.T) { }) } -func MockUnmanageResponse(t *testing.T) { - th.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", +func MockUnmanageResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/volumes/cd281d77-8217-4830-be95-9528227c105c/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestJSONRequest(t, r, ` { diff --git a/openstack/blockstorage/v3/volumes/testing/requests_test.go b/openstack/blockstorage/v3/volumes/testing/requests_test.go index 4fbd79f00c..5bd49594fc 100644 --- a/openstack/blockstorage/v3/volumes/testing/requests_test.go +++ b/openstack/blockstorage/v3/volumes/testing/requests_test.go @@ -13,14 +13,14 @@ import ( ) func TestListWithExtensions(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockListResponse(t) + MockListResponse(t, fakeServer) count := 0 - err := volumes.List(client.ServiceClient(), &volumes.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := volumes.List(client.ServiceClient(fakeServer), &volumes.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := volumes.ExtractVolumes(page) if err != nil { @@ -98,12 +98,12 @@ func TestListWithExtensions(t *testing.T) { } func TestListAllWithExtensions(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockListResponse(t) + MockListResponse(t, fakeServer) - allPages, err := volumes.List(client.ServiceClient(), &volumes.ListOpts{}).AllPages(context.TODO()) + allPages, err := volumes.List(client.ServiceClient(fakeServer), &volumes.ListOpts{}).AllPages(context.TODO()) th.AssertNoErr(t, err) var actual []volumes.Volume @@ -116,12 +116,12 @@ func TestListAllWithExtensions(t *testing.T) { } func TestListAll(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockListResponse(t) + MockListResponse(t, fakeServer) - allPages, err := volumes.List(client.ServiceClient(), &volumes.ListOpts{}).AllPages(context.TODO()) + allPages, err := volumes.List(client.ServiceClient(fakeServer), &volumes.ListOpts{}).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := volumes.ExtractVolumes(allPages) th.AssertNoErr(t, err) @@ -189,12 +189,12 @@ func TestListAll(t *testing.T) { } func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockGetResponse(t) + MockGetResponse(t, fakeServer) - v, err := volumes.Get(context.TODO(), client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22").Extract() + v, err := volumes.Get(context.TODO(), client.ServiceClient(fakeServer), "d32019d3-bc6e-4319-9c1d-6722fc136a22").Extract() th.AssertNoErr(t, err) th.AssertEquals(t, v.Name, "vol-001") @@ -202,13 +202,13 @@ func TestGet(t *testing.T) { } func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockCreateResponse(t) + MockCreateResponse(t, fakeServer) options := &volumes.CreateOpts{Size: 75, Name: "vol-001"} - n, err := volumes.Create(context.TODO(), client.ServiceClient(), options, nil).Extract() + n, err := volumes.Create(context.TODO(), client.ServiceClient(fakeServer), options, nil).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, n.Size, 75) @@ -250,57 +250,57 @@ func TestCreateSchedulerHints(t *testing.T) { } func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockDeleteResponse(t) + MockDeleteResponse(t, fakeServer) - res := volumes.Delete(context.TODO(), client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22", volumes.DeleteOpts{}) + res := volumes.Delete(context.TODO(), client.ServiceClient(fakeServer), "d32019d3-bc6e-4319-9c1d-6722fc136a22", volumes.DeleteOpts{}) th.AssertNoErr(t, res.Err) } func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockUpdateResponse(t) + MockUpdateResponse(t, fakeServer) var name = "vol-002" options := volumes.UpdateOpts{Name: &name} - v, err := volumes.Update(context.TODO(), client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22", options).Extract() + v, err := volumes.Update(context.TODO(), client.ServiceClient(fakeServer), "d32019d3-bc6e-4319-9c1d-6722fc136a22", options).Extract() th.AssertNoErr(t, err) th.CheckEquals(t, "vol-002", v.Name) } func TestGetWithExtensions(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockGetResponse(t) + MockGetResponse(t, fakeServer) var v volumes.Volume - err := volumes.Get(context.TODO(), client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22").ExtractInto(&v) + err := volumes.Get(context.TODO(), client.ServiceClient(fakeServer), "d32019d3-bc6e-4319-9c1d-6722fc136a22").ExtractInto(&v) th.AssertNoErr(t, err) th.AssertEquals(t, "304dc00909ac4d0da6c62d816bcb3459", v.TenantID) th.AssertEquals(t, "centos", v.VolumeImageMetadata["image_name"]) - err = volumes.Get(context.TODO(), client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22").ExtractInto(v) + err = volumes.Get(context.TODO(), client.ServiceClient(fakeServer), "d32019d3-bc6e-4319-9c1d-6722fc136a22").ExtractInto(v) if err == nil { t.Errorf("Expected error when providing non-pointer struct") } } func TestCreateFromBackup(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockCreateVolumeFromBackupResponse(t) + MockCreateVolumeFromBackupResponse(t, fakeServer) options := volumes.CreateOpts{ Name: "vol-001", BackupID: "20c792f0-bb03-434f-b653-06ef238e337e", } - v, err := volumes.Create(context.TODO(), client.ServiceClient(), options, nil).Extract() + v, err := volumes.Create(context.TODO(), client.ServiceClient(fakeServer), options, nil).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, v.Size, 30) @@ -309,44 +309,44 @@ func TestCreateFromBackup(t *testing.T) { } func TestAttach(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockAttachResponse(t) + MockAttachResponse(t, fakeServer) options := &volumes.AttachOpts{ MountPoint: "/mnt", Mode: "rw", InstanceUUID: "50902f4f-a974-46a0-85e9-7efc5e22dfdd", } - err := volumes.Attach(context.TODO(), client.ServiceClient(), "cd281d77-8217-4830-be95-9528227c105c", options).ExtractErr() + err := volumes.Attach(context.TODO(), client.ServiceClient(fakeServer), "cd281d77-8217-4830-be95-9528227c105c", options).ExtractErr() th.AssertNoErr(t, err) } func TestBeginDetaching(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockBeginDetachingResponse(t) + MockBeginDetachingResponse(t, fakeServer) - err := volumes.BeginDetaching(context.TODO(), client.ServiceClient(), "cd281d77-8217-4830-be95-9528227c105c").ExtractErr() + err := volumes.BeginDetaching(context.TODO(), client.ServiceClient(fakeServer), "cd281d77-8217-4830-be95-9528227c105c").ExtractErr() th.AssertNoErr(t, err) } func TestDetach(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockDetachResponse(t) + MockDetachResponse(t, fakeServer) - err := volumes.Detach(context.TODO(), client.ServiceClient(), "cd281d77-8217-4830-be95-9528227c105c", &volumes.DetachOpts{}).ExtractErr() + err := volumes.Detach(context.TODO(), client.ServiceClient(fakeServer), "cd281d77-8217-4830-be95-9528227c105c", &volumes.DetachOpts{}).ExtractErr() th.AssertNoErr(t, err) } func TestUploadImage(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - MockUploadImageResponse(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + MockUploadImageResponse(t, fakeServer) options := &volumes.UploadImageOpts{ ContainerFormat: "bare", DiskFormat: "raw", @@ -354,7 +354,7 @@ func TestUploadImage(t *testing.T) { Force: true, } - actual, err := volumes.UploadImage(context.TODO(), client.ServiceClient(), "cd281d77-8217-4830-be95-9528227c105c", options).Extract() + actual, err := volumes.UploadImage(context.TODO(), client.ServiceClient(fakeServer), "cd281d77-8217-4830-be95-9528227c105c", options).Extract() th.AssertNoErr(t, err) expected := volumes.VolumeImage{ @@ -384,30 +384,30 @@ func TestUploadImage(t *testing.T) { } func TestReserve(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockReserveResponse(t) + MockReserveResponse(t, fakeServer) - err := volumes.Reserve(context.TODO(), client.ServiceClient(), "cd281d77-8217-4830-be95-9528227c105c").ExtractErr() + err := volumes.Reserve(context.TODO(), client.ServiceClient(fakeServer), "cd281d77-8217-4830-be95-9528227c105c").ExtractErr() th.AssertNoErr(t, err) } func TestUnreserve(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockUnreserveResponse(t) + MockUnreserveResponse(t, fakeServer) - err := volumes.Unreserve(context.TODO(), client.ServiceClient(), "cd281d77-8217-4830-be95-9528227c105c").ExtractErr() + err := volumes.Unreserve(context.TODO(), client.ServiceClient(fakeServer), "cd281d77-8217-4830-be95-9528227c105c").ExtractErr() th.AssertNoErr(t, err) } func TestInitializeConnection(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockInitializeConnectionResponse(t) + MockInitializeConnectionResponse(t, fakeServer) options := &volumes.InitializeConnectionOpts{ IP: "127.0.0.1", @@ -417,15 +417,15 @@ func TestInitializeConnection(t *testing.T) { Platform: "x86_64", OSType: "linux2", } - _, err := volumes.InitializeConnection(context.TODO(), client.ServiceClient(), "cd281d77-8217-4830-be95-9528227c105c", options).Extract() + _, err := volumes.InitializeConnection(context.TODO(), client.ServiceClient(fakeServer), "cd281d77-8217-4830-be95-9528227c105c", options).Extract() th.AssertNoErr(t, err) } func TestTerminateConnection(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockTerminateConnectionResponse(t) + MockTerminateConnectionResponse(t, fakeServer) options := &volumes.TerminateConnectionOpts{ IP: "127.0.0.1", @@ -435,39 +435,39 @@ func TestTerminateConnection(t *testing.T) { Platform: "x86_64", OSType: "linux2", } - err := volumes.TerminateConnection(context.TODO(), client.ServiceClient(), "cd281d77-8217-4830-be95-9528227c105c", options).ExtractErr() + err := volumes.TerminateConnection(context.TODO(), client.ServiceClient(fakeServer), "cd281d77-8217-4830-be95-9528227c105c", options).ExtractErr() th.AssertNoErr(t, err) } func TestExtendSize(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockExtendSizeResponse(t) + MockExtendSizeResponse(t, fakeServer) options := &volumes.ExtendSizeOpts{ NewSize: 3, } - err := volumes.ExtendSize(context.TODO(), client.ServiceClient(), "cd281d77-8217-4830-be95-9528227c105c", options).ExtractErr() + err := volumes.ExtendSize(context.TODO(), client.ServiceClient(fakeServer), "cd281d77-8217-4830-be95-9528227c105c", options).ExtractErr() th.AssertNoErr(t, err) } func TestForceDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockForceDeleteResponse(t) + MockForceDeleteResponse(t, fakeServer) - res := volumes.ForceDelete(context.TODO(), client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22") + res := volumes.ForceDelete(context.TODO(), client.ServiceClient(fakeServer), "d32019d3-bc6e-4319-9c1d-6722fc136a22") th.AssertNoErr(t, res.Err) } func TestSetImageMetadata(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockSetImageMetadataResponse(t) + MockSetImageMetadataResponse(t, fakeServer) options := &volumes.ImageMetadataOpts{ Metadata: map[string]string{ @@ -475,59 +475,59 @@ func TestSetImageMetadata(t *testing.T) { }, } - err := volumes.SetImageMetadata(context.TODO(), client.ServiceClient(), "cd281d77-8217-4830-be95-9528227c105c", options).ExtractErr() + err := volumes.SetImageMetadata(context.TODO(), client.ServiceClient(fakeServer), "cd281d77-8217-4830-be95-9528227c105c", options).ExtractErr() th.AssertNoErr(t, err) } func TestSetBootable(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockSetBootableResponse(t) + MockSetBootableResponse(t, fakeServer) options := volumes.BootableOpts{ Bootable: true, } - err := volumes.SetBootable(context.TODO(), client.ServiceClient(), "cd281d77-8217-4830-be95-9528227c105c", options).ExtractErr() + err := volumes.SetBootable(context.TODO(), client.ServiceClient(fakeServer), "cd281d77-8217-4830-be95-9528227c105c", options).ExtractErr() th.AssertNoErr(t, err) } func TestReImage(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockReImageResponse(t) + MockReImageResponse(t, fakeServer) options := volumes.ReImageOpts{ ImageID: "71543ced-a8af-45b6-a5c4-a46282108a90", ReImageReserved: false, } - err := volumes.ReImage(context.TODO(), client.ServiceClient(), "cd281d77-8217-4830-be95-9528227c105c", options).ExtractErr() + err := volumes.ReImage(context.TODO(), client.ServiceClient(fakeServer), "cd281d77-8217-4830-be95-9528227c105c", options).ExtractErr() th.AssertNoErr(t, err) } func TestChangeType(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockChangeTypeResponse(t) + MockChangeTypeResponse(t, fakeServer) options := &volumes.ChangeTypeOpts{ NewType: "ssd", MigrationPolicy: "on-demand", } - err := volumes.ChangeType(context.TODO(), client.ServiceClient(), "cd281d77-8217-4830-be95-9528227c105c", options).ExtractErr() + err := volumes.ChangeType(context.TODO(), client.ServiceClient(fakeServer), "cd281d77-8217-4830-be95-9528227c105c", options).ExtractErr() th.AssertNoErr(t, err) } func TestResetStatus(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockResetStatusResponse(t) + MockResetStatusResponse(t, fakeServer) options := &volumes.ResetStatusOpts{ Status: "error", @@ -535,16 +535,16 @@ func TestResetStatus(t *testing.T) { MigrationStatus: "migrating", } - err := volumes.ResetStatus(context.TODO(), client.ServiceClient(), "cd281d77-8217-4830-be95-9528227c105c", options).ExtractErr() + err := volumes.ResetStatus(context.TODO(), client.ServiceClient(fakeServer), "cd281d77-8217-4830-be95-9528227c105c", options).ExtractErr() th.AssertNoErr(t, err) } func TestUnmanage(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockUnmanageResponse(t) + MockUnmanageResponse(t, fakeServer) - err := volumes.Unmanage(context.TODO(), client.ServiceClient(), "cd281d77-8217-4830-be95-9528227c105c").ExtractErr() + err := volumes.Unmanage(context.TODO(), client.ServiceClient(fakeServer), "cd281d77-8217-4830-be95-9528227c105c").ExtractErr() th.AssertNoErr(t, err) } diff --git a/openstack/blockstorage/v3/volumetypes/testing/fixtures_test.go b/openstack/blockstorage/v3/volumetypes/testing/fixtures_test.go index 9cd6d10af7..d8f5786bb4 100644 --- a/openstack/blockstorage/v3/volumetypes/testing/fixtures_test.go +++ b/openstack/blockstorage/v3/volumetypes/testing/fixtures_test.go @@ -9,8 +9,8 @@ import ( "github.com/gophercloud/gophercloud/v2/testhelper/client" ) -func MockListResponse(t *testing.T) { - th.Mux.HandleFunc("/types", func(w http.ResponseWriter, r *http.Request) { +func MockListResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/types", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -56,7 +56,7 @@ func MockListResponse(t *testing.T) { } ] } - `, th.Server.URL) + `, fakeServer.Server.URL) case "1": fmt.Fprint(w, `{"volume_types": []}`) default: @@ -65,8 +65,8 @@ func MockListResponse(t *testing.T) { }) } -func MockGetResponse(t *testing.T) { - th.Mux.HandleFunc("/types/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { +func MockGetResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/types/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -90,8 +90,8 @@ func MockGetResponse(t *testing.T) { }) } -func MockCreateResponse(t *testing.T) { - th.Mux.HandleFunc("/types", func(w http.ResponseWriter, r *http.Request) { +func MockCreateResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/types", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -130,16 +130,16 @@ func MockCreateResponse(t *testing.T) { }) } -func MockDeleteResponse(t *testing.T) { - th.Mux.HandleFunc("/types/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { +func MockDeleteResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/types/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusAccepted) }) } -func MockUpdateResponse(t *testing.T) { - th.Mux.HandleFunc("/types/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { +func MockUpdateResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/types/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusOK) @@ -195,8 +195,8 @@ var UpdatedExtraSpec = map[string]string{ "capabilities": "gpu-2", } -func HandleExtraSpecsListSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/types/1/extra_specs", func(w http.ResponseWriter, r *http.Request) { +func HandleExtraSpecsListSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/types/1/extra_specs", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -207,8 +207,8 @@ func HandleExtraSpecsListSuccessfully(t *testing.T) { }) } -func HandleExtraSpecGetSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/types/1/extra_specs/capabilities", func(w http.ResponseWriter, r *http.Request) { +func HandleExtraSpecGetSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/types/1/extra_specs/capabilities", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -219,8 +219,8 @@ func HandleExtraSpecGetSuccessfully(t *testing.T) { }) } -func HandleExtraSpecsCreateSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/types/1/extra_specs", func(w http.ResponseWriter, r *http.Request) { +func HandleExtraSpecsCreateSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/types/1/extra_specs", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -237,8 +237,8 @@ func HandleExtraSpecsCreateSuccessfully(t *testing.T) { }) } -func HandleExtraSpecUpdateSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/types/1/extra_specs/capabilities", func(w http.ResponseWriter, r *http.Request) { +func HandleExtraSpecUpdateSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/types/1/extra_specs/capabilities", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -252,8 +252,8 @@ func HandleExtraSpecUpdateSuccessfully(t *testing.T) { }) } -func HandleExtraSpecDeleteSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/types/1/extra_specs/capabilities", func(w http.ResponseWriter, r *http.Request) { +func HandleExtraSpecDeleteSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/types/1/extra_specs/capabilities", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -261,8 +261,8 @@ func HandleExtraSpecDeleteSuccessfully(t *testing.T) { }) } -func MockEncryptionCreateResponse(t *testing.T) { - th.Mux.HandleFunc("/types/a5082c24-2a27-43a4-b48e-fcec1240e36b/encryption", func(w http.ResponseWriter, r *http.Request) { +func MockEncryptionCreateResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/types/a5082c24-2a27-43a4-b48e-fcec1240e36b/encryption", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -296,16 +296,16 @@ func MockEncryptionCreateResponse(t *testing.T) { }) } -func MockDeleteEncryptionResponse(t *testing.T) { - th.Mux.HandleFunc("/types/a5082c24-2a27-43a4-b48e-fcec1240e36b/encryption/81e069c6-7394-4856-8df7-3b237ca61f74", func(w http.ResponseWriter, r *http.Request) { +func MockDeleteEncryptionResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/types/a5082c24-2a27-43a4-b48e-fcec1240e36b/encryption/81e069c6-7394-4856-8df7-3b237ca61f74", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusAccepted) }) } -func MockEncryptionUpdateResponse(t *testing.T) { - th.Mux.HandleFunc("/types/a5082c24-2a27-43a4-b48e-fcec1240e36b/encryption/81e069c6-7394-4856-8df7-3b237ca61f74", func(w http.ResponseWriter, r *http.Request) { +func MockEncryptionUpdateResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/types/a5082c24-2a27-43a4-b48e-fcec1240e36b/encryption/81e069c6-7394-4856-8df7-3b237ca61f74", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -337,8 +337,8 @@ func MockEncryptionUpdateResponse(t *testing.T) { }) } -func MockEncryptionGetResponse(t *testing.T) { - th.Mux.HandleFunc("/types/a5082c24-2a27-43a4-b48e-fcec1240e36b/encryption", func(w http.ResponseWriter, r *http.Request) { +func MockEncryptionGetResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/types/a5082c24-2a27-43a4-b48e-fcec1240e36b/encryption", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -362,8 +362,8 @@ func MockEncryptionGetResponse(t *testing.T) { }) } -func MockEncryptionGetSpecResponse(t *testing.T) { - th.Mux.HandleFunc("/types/a5082c24-2a27-43a4-b48e-fcec1240e36b/encryption/cipher", func(w http.ResponseWriter, r *http.Request) { +func MockEncryptionGetSpecResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/types/a5082c24-2a27-43a4-b48e-fcec1240e36b/encryption/cipher", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/blockstorage/v3/volumetypes/testing/requests_test.go b/openstack/blockstorage/v3/volumetypes/testing/requests_test.go index f222be2395..920714d72a 100644 --- a/openstack/blockstorage/v3/volumetypes/testing/requests_test.go +++ b/openstack/blockstorage/v3/volumetypes/testing/requests_test.go @@ -14,12 +14,12 @@ import ( ) func TestListAll(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockListResponse(t) + MockListResponse(t, fakeServer) pages := 0 - err := volumetypes.List(client.ServiceClient(), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := volumetypes.List(client.ServiceClient(fakeServer), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := volumetypes.ExtractVolumeTypes(page) if err != nil { @@ -52,12 +52,12 @@ func TestListAll(t *testing.T) { } func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockGetResponse(t) + MockGetResponse(t, fakeServer) - v, err := volumetypes.Get(context.TODO(), client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22").Extract() + v, err := volumetypes.Get(context.TODO(), client.ServiceClient(fakeServer), "d32019d3-bc6e-4319-9c1d-6722fc136a22").Extract() th.AssertNoErr(t, err) th.AssertEquals(t, v.Name, "vol-type-001") @@ -68,10 +68,10 @@ func TestGet(t *testing.T) { } func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockCreateResponse(t) + MockCreateResponse(t, fakeServer) var isPublic = true @@ -82,7 +82,7 @@ func TestCreate(t *testing.T) { ExtraSpecs: map[string]string{"capabilities": "gpu"}, } - n, err := volumetypes.Create(context.TODO(), client.ServiceClient(), options).Extract() + n, err := volumetypes.Create(context.TODO(), client.ServiceClient(fakeServer), options).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, n.Name, "test_type") @@ -94,20 +94,20 @@ func TestCreate(t *testing.T) { } func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockDeleteResponse(t) + MockDeleteResponse(t, fakeServer) - res := volumetypes.Delete(context.TODO(), client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22") + res := volumetypes.Delete(context.TODO(), client.ServiceClient(fakeServer), "d32019d3-bc6e-4319-9c1d-6722fc136a22") th.AssertNoErr(t, res.Err) } func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockUpdateResponse(t) + MockUpdateResponse(t, fakeServer) var isPublic = true var name = "vol-type-002" @@ -116,77 +116,77 @@ func TestUpdate(t *testing.T) { IsPublic: &isPublic, } - v, err := volumetypes.Update(context.TODO(), client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22", options).Extract() + v, err := volumetypes.Update(context.TODO(), client.ServiceClient(fakeServer), "d32019d3-bc6e-4319-9c1d-6722fc136a22", options).Extract() th.AssertNoErr(t, err) th.CheckEquals(t, "vol-type-002", v.Name) th.CheckEquals(t, true, v.IsPublic) } func TestVolumeTypeExtraSpecsList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleExtraSpecsListSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleExtraSpecsListSuccessfully(t, fakeServer) expected := ExtraSpecs - actual, err := volumetypes.ListExtraSpecs(context.TODO(), client.ServiceClient(), "1").Extract() + actual, err := volumetypes.ListExtraSpecs(context.TODO(), client.ServiceClient(fakeServer), "1").Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, expected, actual) } func TestVolumeTypeExtraSpecGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleExtraSpecGetSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleExtraSpecGetSuccessfully(t, fakeServer) expected := ExtraSpec - actual, err := volumetypes.GetExtraSpec(context.TODO(), client.ServiceClient(), "1", "capabilities").Extract() + actual, err := volumetypes.GetExtraSpec(context.TODO(), client.ServiceClient(fakeServer), "1", "capabilities").Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, expected, actual) } func TestVolumeTypeExtraSpecsCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleExtraSpecsCreateSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleExtraSpecsCreateSuccessfully(t, fakeServer) createOpts := volumetypes.ExtraSpecsOpts{ "capabilities": "gpu", "volume_backend_name": "ssd", } expected := ExtraSpecs - actual, err := volumetypes.CreateExtraSpecs(context.TODO(), client.ServiceClient(), "1", createOpts).Extract() + actual, err := volumetypes.CreateExtraSpecs(context.TODO(), client.ServiceClient(fakeServer), "1", createOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, expected, actual) } func TestVolumeTypeExtraSpecUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleExtraSpecUpdateSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleExtraSpecUpdateSuccessfully(t, fakeServer) updateOpts := volumetypes.ExtraSpecsOpts{ "capabilities": "gpu-2", } expected := UpdatedExtraSpec - actual, err := volumetypes.UpdateExtraSpec(context.TODO(), client.ServiceClient(), "1", updateOpts).Extract() + actual, err := volumetypes.UpdateExtraSpec(context.TODO(), client.ServiceClient(fakeServer), "1", updateOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, expected, actual) } func TestVolumeTypeExtraSpecDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleExtraSpecDeleteSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleExtraSpecDeleteSuccessfully(t, fakeServer) - res := volumetypes.DeleteExtraSpec(context.TODO(), client.ServiceClient(), "1", "capabilities") + res := volumetypes.DeleteExtraSpec(context.TODO(), client.ServiceClient(fakeServer), "1", "capabilities") th.AssertNoErr(t, res.Err) } func TestVolumeTypeListAccesses(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/types/a5082c24-2a27-43a4-b48e-fcec1240e36b/os-volume-type-access", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/types/a5082c24-2a27-43a4-b48e-fcec1240e36b/os-volume-type-access", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") @@ -209,7 +209,7 @@ func TestVolumeTypeListAccesses(t *testing.T) { }, } - allPages, err := volumetypes.ListAccesses(client.ServiceClient(), "a5082c24-2a27-43a4-b48e-fcec1240e36b").AllPages(context.TODO()) + allPages, err := volumetypes.ListAccesses(client.ServiceClient(fakeServer), "a5082c24-2a27-43a4-b48e-fcec1240e36b").AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := volumetypes.ExtractAccesses(allPages) @@ -221,10 +221,10 @@ func TestVolumeTypeListAccesses(t *testing.T) { } func TestVolumeTypeAddAccess(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/types/a5082c24-2a27-43a4-b48e-fcec1240e36b/action", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/types/a5082c24-2a27-43a4-b48e-fcec1240e36b/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "accept", "application/json") @@ -244,16 +244,16 @@ func TestVolumeTypeAddAccess(t *testing.T) { Project: "6f70656e737461636b20342065766572", } - err := volumetypes.AddAccess(context.TODO(), client.ServiceClient(), "a5082c24-2a27-43a4-b48e-fcec1240e36b", addAccessOpts).ExtractErr() + err := volumetypes.AddAccess(context.TODO(), client.ServiceClient(fakeServer), "a5082c24-2a27-43a4-b48e-fcec1240e36b", addAccessOpts).ExtractErr() th.AssertNoErr(t, err) } func TestVolumeTypeRemoveAccess(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/types/a5082c24-2a27-43a4-b48e-fcec1240e36b/action", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/types/a5082c24-2a27-43a4-b48e-fcec1240e36b/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "accept", "application/json") @@ -273,16 +273,16 @@ func TestVolumeTypeRemoveAccess(t *testing.T) { Project: "6f70656e737461636b20342065766572", } - err := volumetypes.RemoveAccess(context.TODO(), client.ServiceClient(), "a5082c24-2a27-43a4-b48e-fcec1240e36b", removeAccessOpts).ExtractErr() + err := volumetypes.RemoveAccess(context.TODO(), client.ServiceClient(fakeServer), "a5082c24-2a27-43a4-b48e-fcec1240e36b", removeAccessOpts).ExtractErr() th.AssertNoErr(t, err) } func TestCreateEncryption(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockEncryptionCreateResponse(t) + MockEncryptionCreateResponse(t, fakeServer) options := &volumetypes.CreateEncryptionOpts{ KeySize: 256, @@ -291,7 +291,7 @@ func TestCreateEncryption(t *testing.T) { Cipher: "aes-xts-plain64", } id := "a5082c24-2a27-43a4-b48e-fcec1240e36b" - n, err := volumetypes.CreateEncryption(context.TODO(), client.ServiceClient(), id, options).Extract() + n, err := volumetypes.CreateEncryption(context.TODO(), client.ServiceClient(fakeServer), id, options).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, "a5082c24-2a27-43a4-b48e-fcec1240e36b", n.VolumeTypeID) @@ -303,20 +303,20 @@ func TestCreateEncryption(t *testing.T) { } func TestDeleteEncryption(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockDeleteEncryptionResponse(t) + MockDeleteEncryptionResponse(t, fakeServer) - res := volumetypes.DeleteEncryption(context.TODO(), client.ServiceClient(), "a5082c24-2a27-43a4-b48e-fcec1240e36b", "81e069c6-7394-4856-8df7-3b237ca61f74") + res := volumetypes.DeleteEncryption(context.TODO(), client.ServiceClient(fakeServer), "a5082c24-2a27-43a4-b48e-fcec1240e36b", "81e069c6-7394-4856-8df7-3b237ca61f74") th.AssertNoErr(t, res.Err) } func TestUpdateEncryption(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockEncryptionUpdateResponse(t) + MockEncryptionUpdateResponse(t, fakeServer) options := &volumetypes.UpdateEncryptionOpts{ KeySize: 256, @@ -326,7 +326,7 @@ func TestUpdateEncryption(t *testing.T) { } id := "a5082c24-2a27-43a4-b48e-fcec1240e36b" encryptionID := "81e069c6-7394-4856-8df7-3b237ca61f74" - n, err := volumetypes.UpdateEncryption(context.TODO(), client.ServiceClient(), id, encryptionID, options).Extract() + n, err := volumetypes.UpdateEncryption(context.TODO(), client.ServiceClient(fakeServer), id, encryptionID, options).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, "front-end", n.ControlLocation) @@ -336,12 +336,12 @@ func TestUpdateEncryption(t *testing.T) { } func TestGetEncryption(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockEncryptionGetResponse(t) + MockEncryptionGetResponse(t, fakeServer) id := "a5082c24-2a27-43a4-b48e-fcec1240e36b" - n, err := volumetypes.GetEncryption(context.TODO(), client.ServiceClient(), id).Extract() + n, err := volumetypes.GetEncryption(context.TODO(), client.ServiceClient(fakeServer), id).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, "a5082c24-2a27-43a4-b48e-fcec1240e36b", n.VolumeTypeID) @@ -357,12 +357,12 @@ func TestGetEncryption(t *testing.T) { } func TestGetEncryptionSpec(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockEncryptionGetSpecResponse(t) + MockEncryptionGetSpecResponse(t, fakeServer) id := "a5082c24-2a27-43a4-b48e-fcec1240e36b" - n, err := volumetypes.GetEncryptionSpec(context.TODO(), client.ServiceClient(), id, "cipher").Extract() + n, err := volumetypes.GetEncryptionSpec(context.TODO(), client.ServiceClient(fakeServer), id, "cipher").Extract() th.AssertNoErr(t, err) key := "cipher" diff --git a/openstack/common/extensions/testing/fixtures.go b/openstack/common/extensions/testing/fixtures.go index 91f6a041b1..092763818c 100644 --- a/openstack/common/extensions/testing/fixtures.go +++ b/openstack/common/extensions/testing/fixtures.go @@ -64,8 +64,8 @@ var SingleExtension = &extensions.Extension{ // HandleListExtensionsSuccessfully creates an HTTP handler at `/extensions` on the test handler // mux that response with a list containing a single tenant. -func HandleListExtensionsSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/extensions", func(w http.ResponseWriter, r *http.Request) { +func HandleListExtensionsSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/extensions", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -77,8 +77,8 @@ func HandleListExtensionsSuccessfully(t *testing.T) { // HandleGetExtensionSuccessfully creates an HTTP handler at `/extensions/agent` that responds with // a JSON payload corresponding to SingleExtension. -func HandleGetExtensionSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/extensions/agent", func(w http.ResponseWriter, r *http.Request) { +func HandleGetExtensionSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/extensions/agent", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/common/extensions/testing/requests_test.go b/openstack/common/extensions/testing/requests_test.go index 37a7a5092d..5713bf2d9a 100644 --- a/openstack/common/extensions/testing/requests_test.go +++ b/openstack/common/extensions/testing/requests_test.go @@ -11,13 +11,13 @@ import ( ) func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListExtensionsSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListExtensionsSuccessfully(t, fakeServer) count := 0 - err := extensions.List(client.ServiceClient()).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := extensions.List(client.ServiceClient(fakeServer)).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := extensions.ExtractExtensions(page) th.AssertNoErr(t, err) @@ -31,11 +31,11 @@ func TestList(t *testing.T) { } func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetExtensionSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetExtensionSuccessfully(t, fakeServer) - actual, err := extensions.Get(context.TODO(), client.ServiceClient(), "agent").Extract() + actual, err := extensions.Get(context.TODO(), client.ServiceClient(fakeServer), "agent").Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, SingleExtension, actual) } diff --git a/openstack/compute/apiversions/testing/fixtures_test.go b/openstack/compute/apiversions/testing/fixtures_test.go index 49162c77ce..ac122e2d2c 100644 --- a/openstack/compute/apiversions/testing/fixtures_test.go +++ b/openstack/compute/apiversions/testing/fixtures_test.go @@ -161,8 +161,8 @@ var NovaAllAPIVersionResults = []apiversions.APIVersion{ NovaAPIVersion21Result, } -func MockListResponse(t *testing.T) { - th.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { +func MockListResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -173,8 +173,8 @@ func MockListResponse(t *testing.T) { }) } -func MockGetResponse(t *testing.T) { - th.Mux.HandleFunc("/v2.1/", func(w http.ResponseWriter, r *http.Request) { +func MockGetResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.1/", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -185,8 +185,8 @@ func MockGetResponse(t *testing.T) { }) } -func MockGetMultipleResponses(t *testing.T) { - th.Mux.HandleFunc("/v3/", func(w http.ResponseWriter, r *http.Request) { +func MockGetMultipleResponses(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v3/", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/compute/apiversions/testing/requests_test.go b/openstack/compute/apiversions/testing/requests_test.go index 737976b750..59d05b9eb2 100644 --- a/openstack/compute/apiversions/testing/requests_test.go +++ b/openstack/compute/apiversions/testing/requests_test.go @@ -10,12 +10,12 @@ import ( ) func TestListAPIVersions(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockListResponse(t) + MockListResponse(t, fakeServer) - allVersions, err := apiversions.List(client.ServiceClient()).AllPages(context.TODO()) + allVersions, err := apiversions.List(client.ServiceClient(fakeServer)).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := apiversions.ExtractAPIVersions(allVersions) @@ -25,23 +25,23 @@ func TestListAPIVersions(t *testing.T) { } func TestGetAPIVersion(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockGetResponse(t) + MockGetResponse(t, fakeServer) - actual, err := apiversions.Get(context.TODO(), client.ServiceClient(), "v2.1").Extract() + actual, err := apiversions.Get(context.TODO(), client.ServiceClient(fakeServer), "v2.1").Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, NovaAPIVersion21Result, *actual) } func TestGetMultipleAPIVersion(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockGetMultipleResponses(t) + MockGetMultipleResponses(t, fakeServer) - _, err := apiversions.Get(context.TODO(), client.ServiceClient(), "v3").Extract() + _, err := apiversions.Get(context.TODO(), client.ServiceClient(fakeServer), "v3").Extract() th.AssertEquals(t, err.Error(), "Unable to find requested API version") } diff --git a/openstack/compute/v2/aggregates/testing/fixtures_test.go b/openstack/compute/v2/aggregates/testing/fixtures_test.go index 11cebc8915..751ca766e7 100644 --- a/openstack/compute/v2/aggregates/testing/fixtures_test.go +++ b/openstack/compute/v2/aggregates/testing/fixtures_test.go @@ -258,8 +258,8 @@ var ( ) // HandleListSuccessfully configures the test server to respond to a List request. -func HandleListSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/os-aggregates", func(w http.ResponseWriter, r *http.Request) { +func HandleListSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/os-aggregates", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -268,8 +268,8 @@ func HandleListSuccessfully(t *testing.T) { }) } -func HandleCreateSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/os-aggregates", func(w http.ResponseWriter, r *http.Request) { +func HandleCreateSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/os-aggregates", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -278,9 +278,9 @@ func HandleCreateSuccessfully(t *testing.T) { }) } -func HandleDeleteSuccessfully(t *testing.T) { +func HandleDeleteSuccessfully(t *testing.T, fakeServer th.FakeServer) { v := strconv.Itoa(AggregateIDtoDelete) - th.Mux.HandleFunc("/os-aggregates/"+v, func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/os-aggregates/"+v, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -288,9 +288,9 @@ func HandleDeleteSuccessfully(t *testing.T) { }) } -func HandleGetSuccessfully(t *testing.T) { +func HandleGetSuccessfully(t *testing.T, fakeServer th.FakeServer) { v := strconv.Itoa(AggregateIDtoGet) - th.Mux.HandleFunc("/os-aggregates/"+v, func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/os-aggregates/"+v, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -299,9 +299,9 @@ func HandleGetSuccessfully(t *testing.T) { }) } -func HandleUpdateSuccessfully(t *testing.T) { +func HandleUpdateSuccessfully(t *testing.T, fakeServer th.FakeServer) { v := strconv.Itoa(AggregateIDtoUpdate) - th.Mux.HandleFunc("/os-aggregates/"+v, func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/os-aggregates/"+v, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -310,9 +310,9 @@ func HandleUpdateSuccessfully(t *testing.T) { }) } -func HandleAddHostSuccessfully(t *testing.T) { +func HandleAddHostSuccessfully(t *testing.T, fakeServer th.FakeServer) { v := strconv.Itoa(AggregateWithAddedHost.ID) - th.Mux.HandleFunc("/os-aggregates/"+v+"/action", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/os-aggregates/"+v+"/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -321,9 +321,9 @@ func HandleAddHostSuccessfully(t *testing.T) { }) } -func HandleRemoveHostSuccessfully(t *testing.T) { +func HandleRemoveHostSuccessfully(t *testing.T, fakeServer th.FakeServer) { v := strconv.Itoa(AggregateWithRemovedHost.ID) - th.Mux.HandleFunc("/os-aggregates/"+v+"/action", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/os-aggregates/"+v+"/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -332,9 +332,9 @@ func HandleRemoveHostSuccessfully(t *testing.T) { }) } -func HandleSetMetadataSuccessfully(t *testing.T) { +func HandleSetMetadataSuccessfully(t *testing.T, fakeServer th.FakeServer) { v := strconv.Itoa(AggregateWithUpdatedMetadata.ID) - th.Mux.HandleFunc("/os-aggregates/"+v+"/action", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/os-aggregates/"+v+"/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/compute/v2/aggregates/testing/requests_test.go b/openstack/compute/v2/aggregates/testing/requests_test.go index 2e229bf71c..c02026a66f 100644 --- a/openstack/compute/v2/aggregates/testing/requests_test.go +++ b/openstack/compute/v2/aggregates/testing/requests_test.go @@ -11,12 +11,12 @@ import ( ) func TestListAggregates(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListSuccessfully(t, fakeServer) pages := 0 - err := aggregates.List(client.ServiceClient()).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := aggregates.List(client.ServiceClient(fakeServer)).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := aggregates.ExtractAggregates(page) @@ -41,9 +41,9 @@ func TestListAggregates(t *testing.T) { } func TestCreateAggregates(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCreateSuccessfully(t, fakeServer) expected := CreatedAggregate @@ -52,38 +52,38 @@ func TestCreateAggregates(t *testing.T) { AvailabilityZone: "london", } - actual, err := aggregates.Create(context.TODO(), client.ServiceClient(), opts).Extract() + actual, err := aggregates.Create(context.TODO(), client.ServiceClient(fakeServer), opts).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, &expected, actual) } func TestDeleteAggregates(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDeleteSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDeleteSuccessfully(t, fakeServer) - err := aggregates.Delete(context.TODO(), client.ServiceClient(), AggregateIDtoDelete).ExtractErr() + err := aggregates.Delete(context.TODO(), client.ServiceClient(fakeServer), AggregateIDtoDelete).ExtractErr() th.AssertNoErr(t, err) } func TestGetAggregates(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetSuccessfully(t, fakeServer) expected := SecondFakeAggregate - actual, err := aggregates.Get(context.TODO(), client.ServiceClient(), AggregateIDtoGet).Extract() + actual, err := aggregates.Get(context.TODO(), client.ServiceClient(fakeServer), AggregateIDtoGet).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, &expected, actual) } func TestUpdateAggregate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleUpdateSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleUpdateSuccessfully(t, fakeServer) expected := UpdatedAggregate @@ -92,16 +92,16 @@ func TestUpdateAggregate(t *testing.T) { AvailabilityZone: "nova2", } - actual, err := aggregates.Update(context.TODO(), client.ServiceClient(), expected.ID, opts).Extract() + actual, err := aggregates.Update(context.TODO(), client.ServiceClient(fakeServer), expected.ID, opts).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, &expected, actual) } func TestAddHostAggregate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleAddHostSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleAddHostSuccessfully(t, fakeServer) expected := AggregateWithAddedHost @@ -109,16 +109,16 @@ func TestAddHostAggregate(t *testing.T) { Host: "cmp1", } - actual, err := aggregates.AddHost(context.TODO(), client.ServiceClient(), expected.ID, opts).Extract() + actual, err := aggregates.AddHost(context.TODO(), client.ServiceClient(fakeServer), expected.ID, opts).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, &expected, actual) } func TestRemoveHostAggregate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleRemoveHostSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleRemoveHostSuccessfully(t, fakeServer) expected := AggregateWithRemovedHost @@ -126,16 +126,16 @@ func TestRemoveHostAggregate(t *testing.T) { Host: "cmp1", } - actual, err := aggregates.RemoveHost(context.TODO(), client.ServiceClient(), expected.ID, opts).Extract() + actual, err := aggregates.RemoveHost(context.TODO(), client.ServiceClient(fakeServer), expected.ID, opts).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, &expected, actual) } func TestSetMetadataAggregate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleSetMetadataSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleSetMetadataSuccessfully(t, fakeServer) expected := AggregateWithUpdatedMetadata @@ -143,7 +143,7 @@ func TestSetMetadataAggregate(t *testing.T) { Metadata: map[string]any{"key": "value"}, } - actual, err := aggregates.SetMetadata(context.TODO(), client.ServiceClient(), expected.ID, opts).Extract() + actual, err := aggregates.SetMetadata(context.TODO(), client.ServiceClient(fakeServer), expected.ID, opts).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, &expected, actual) diff --git a/openstack/compute/v2/attachinterfaces/testing/fixtures_test.go b/openstack/compute/v2/attachinterfaces/testing/fixtures_test.go index 59a03d57d2..16effc6514 100644 --- a/openstack/compute/v2/attachinterfaces/testing/fixtures_test.go +++ b/openstack/compute/v2/attachinterfaces/testing/fixtures_test.go @@ -63,8 +63,8 @@ var CreateInterfacesExpected = attachinterfaces.Interface{ } // HandleInterfaceListSuccessfully sets up the test server to respond to a ListInterfaces request. -func HandleInterfaceListSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/servers/b07e7a3b-d951-4efc-a4f9-ac9f001afb7f/os-interface", func(w http.ResponseWriter, r *http.Request) { +func HandleInterfaceListSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/servers/b07e7a3b-d951-4efc-a4f9-ac9f001afb7f/os-interface", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -93,8 +93,8 @@ func HandleInterfaceListSuccessfully(t *testing.T) { } // HandleInterfaceGetSuccessfully sets up the test server to respond to a GetInterface request. -func HandleInterfaceGetSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/servers/b07e7a3b-d951-4efc-a4f9-ac9f001afb7f/os-interface/0dde1598-b374-474e-986f-5b8dd1df1d4e", func(w http.ResponseWriter, r *http.Request) { +func HandleInterfaceGetSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/servers/b07e7a3b-d951-4efc-a4f9-ac9f001afb7f/os-interface/0dde1598-b374-474e-986f-5b8dd1df1d4e", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -122,8 +122,8 @@ func HandleInterfaceGetSuccessfully(t *testing.T) { } // HandleInterfaceCreateSuccessfully sets up the test server to respond to a CreateInterface request. -func HandleInterfaceCreateSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/servers/b07e7a3b-d951-4efc-a4f9-ac9f001afb7f/os-interface", func(w http.ResponseWriter, r *http.Request) { +func HandleInterfaceCreateSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/servers/b07e7a3b-d951-4efc-a4f9-ac9f001afb7f/os-interface", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, `{ @@ -152,8 +152,8 @@ func HandleInterfaceCreateSuccessfully(t *testing.T) { } // HandleInterfaceDeleteSuccessfully sets up the test server to respond to a DeleteInterface request. -func HandleInterfaceDeleteSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/servers/b07e7a3b-d951-4efc-a4f9-ac9f001afb7f/os-interface/0dde1598-b374-474e-986f-5b8dd1df1d4e", func(w http.ResponseWriter, r *http.Request) { +func HandleInterfaceDeleteSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/servers/b07e7a3b-d951-4efc-a4f9-ac9f001afb7f/os-interface/0dde1598-b374-474e-986f-5b8dd1df1d4e", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/compute/v2/attachinterfaces/testing/requests_test.go b/openstack/compute/v2/attachinterfaces/testing/requests_test.go index d436bc081d..a8fe239467 100644 --- a/openstack/compute/v2/attachinterfaces/testing/requests_test.go +++ b/openstack/compute/v2/attachinterfaces/testing/requests_test.go @@ -11,13 +11,13 @@ import ( ) func TestListInterface(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleInterfaceListSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleInterfaceListSuccessfully(t, fakeServer) expected := ListInterfacesExpected pages := 0 - err := attachinterfaces.List(client.ServiceClient(), "b07e7a3b-d951-4efc-a4f9-ac9f001afb7f").EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := attachinterfaces.List(client.ServiceClient(fakeServer), "b07e7a3b-d951-4efc-a4f9-ac9f001afb7f").EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := attachinterfaces.ExtractInterfaces(page) @@ -35,42 +35,42 @@ func TestListInterface(t *testing.T) { } func TestListInterfacesAllPages(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleInterfaceListSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleInterfaceListSuccessfully(t, fakeServer) - allPages, err := attachinterfaces.List(client.ServiceClient(), "b07e7a3b-d951-4efc-a4f9-ac9f001afb7f").AllPages(context.TODO()) + allPages, err := attachinterfaces.List(client.ServiceClient(fakeServer), "b07e7a3b-d951-4efc-a4f9-ac9f001afb7f").AllPages(context.TODO()) th.AssertNoErr(t, err) _, err = attachinterfaces.ExtractInterfaces(allPages) th.AssertNoErr(t, err) } func TestGetInterface(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleInterfaceGetSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleInterfaceGetSuccessfully(t, fakeServer) expected := GetInterfaceExpected serverID := "b07e7a3b-d951-4efc-a4f9-ac9f001afb7f" interfaceID := "0dde1598-b374-474e-986f-5b8dd1df1d4e" - actual, err := attachinterfaces.Get(context.TODO(), client.ServiceClient(), serverID, interfaceID).Extract() + actual, err := attachinterfaces.Get(context.TODO(), client.ServiceClient(fakeServer), serverID, interfaceID).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, &expected, actual) } func TestCreateInterface(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleInterfaceCreateSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleInterfaceCreateSuccessfully(t, fakeServer) expected := CreateInterfacesExpected serverID := "b07e7a3b-d951-4efc-a4f9-ac9f001afb7f" networkID := "8a5fe506-7e9f-4091-899b-96336909d93c" - actual, err := attachinterfaces.Create(context.TODO(), client.ServiceClient(), serverID, attachinterfaces.CreateOpts{ + actual, err := attachinterfaces.Create(context.TODO(), client.ServiceClient(fakeServer), serverID, attachinterfaces.CreateOpts{ NetworkID: networkID, }).Extract() th.AssertNoErr(t, err) @@ -78,13 +78,13 @@ func TestCreateInterface(t *testing.T) { } func TestDeleteInterface(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleInterfaceDeleteSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleInterfaceDeleteSuccessfully(t, fakeServer) serverID := "b07e7a3b-d951-4efc-a4f9-ac9f001afb7f" portID := "0dde1598-b374-474e-986f-5b8dd1df1d4e" - err := attachinterfaces.Delete(context.TODO(), client.ServiceClient(), serverID, portID).ExtractErr() + err := attachinterfaces.Delete(context.TODO(), client.ServiceClient(fakeServer), serverID, portID).ExtractErr() th.AssertNoErr(t, err) } diff --git a/openstack/compute/v2/availabilityzones/testing/fixtures_test.go b/openstack/compute/v2/availabilityzones/testing/fixtures_test.go index a36c64649c..53899fbf79 100644 --- a/openstack/compute/v2/availabilityzones/testing/fixtures_test.go +++ b/openstack/compute/v2/availabilityzones/testing/fixtures_test.go @@ -174,8 +174,8 @@ var AZDetailResult = []az.AvailabilityZone{ // HandleGetSuccessfully configures the test server to respond to a Get request // for availability zone information. -func HandleGetSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/os-availability-zone", func(w http.ResponseWriter, r *http.Request) { +func HandleGetSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/os-availability-zone", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -186,8 +186,8 @@ func HandleGetSuccessfully(t *testing.T) { // HandleGetDetailSuccessfully configures the test server to respond to a Get request // for detailed availability zone information. -func HandleGetDetailSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/os-availability-zone/detail", func(w http.ResponseWriter, r *http.Request) { +func HandleGetDetailSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/os-availability-zone/detail", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/compute/v2/availabilityzones/testing/requests_test.go b/openstack/compute/v2/availabilityzones/testing/requests_test.go index f537d9d18b..fb6a20ee25 100644 --- a/openstack/compute/v2/availabilityzones/testing/requests_test.go +++ b/openstack/compute/v2/availabilityzones/testing/requests_test.go @@ -11,12 +11,12 @@ import ( // Verifies that availability zones can be listed correctly func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleGetSuccessfully(t) + HandleGetSuccessfully(t, fakeServer) - allPages, err := az.List(client.ServiceClient()).AllPages(context.TODO()) + allPages, err := az.List(client.ServiceClient(fakeServer)).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := az.ExtractAvailabilityZones(allPages) @@ -27,12 +27,12 @@ func TestList(t *testing.T) { // Verifies that detailed availability zones can be listed correctly func TestListDetail(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleGetDetailSuccessfully(t) + HandleGetDetailSuccessfully(t, fakeServer) - allPages, err := az.ListDetail(client.ServiceClient()).AllPages(context.TODO()) + allPages, err := az.ListDetail(client.ServiceClient(fakeServer)).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := az.ExtractAvailabilityZones(allPages) diff --git a/openstack/compute/v2/diagnostics/testing/fixtures_test.go b/openstack/compute/v2/diagnostics/testing/fixtures_test.go index 35cfd134bb..41e5dcf0f0 100644 --- a/openstack/compute/v2/diagnostics/testing/fixtures_test.go +++ b/openstack/compute/v2/diagnostics/testing/fixtures_test.go @@ -9,8 +9,8 @@ import ( ) // HandleDiagnosticGetSuccessfully sets up the test server to respond to a diagnostic Get request. -func HandleDiagnosticGetSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/servers/1234asdf/diagnostics", func(w http.ResponseWriter, r *http.Request) { +func HandleDiagnosticGetSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/servers/1234asdf/diagnostics", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") diff --git a/openstack/compute/v2/diagnostics/testing/requests_test.go b/openstack/compute/v2/diagnostics/testing/requests_test.go index 983c4d18e9..6f3feceea4 100644 --- a/openstack/compute/v2/diagnostics/testing/requests_test.go +++ b/openstack/compute/v2/diagnostics/testing/requests_test.go @@ -10,14 +10,14 @@ import ( ) func TestGetDiagnostics(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleDiagnosticGetSuccessfully(t) + HandleDiagnosticGetSuccessfully(t, fakeServer) expected := map[string]any{"cpu0_time": float64(173), "memory": float64(524288)} - res, err := diagnostics.Get(context.TODO(), client.ServiceClient(), "1234asdf").Extract() + res, err := diagnostics.Get(context.TODO(), client.ServiceClient(fakeServer), "1234asdf").Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, expected, res) diff --git a/openstack/compute/v2/extensions/testing/delegate_test.go b/openstack/compute/v2/extensions/testing/delegate_test.go index a2b8774c8e..4461b7464f 100644 --- a/openstack/compute/v2/extensions/testing/delegate_test.go +++ b/openstack/compute/v2/extensions/testing/delegate_test.go @@ -12,13 +12,13 @@ import ( ) func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleListExtensionsSuccessfully(t) + HandleListExtensionsSuccessfully(t, fakeServer) count := 0 - err := extensions.List(client.ServiceClient()).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := extensions.List(client.ServiceClient(fakeServer)).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := extensions.ExtractExtensions(page) th.AssertNoErr(t, err) @@ -42,12 +42,12 @@ func TestList(t *testing.T) { } func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleGetExtensionsSuccessfully(t) + HandleGetExtensionsSuccessfully(t, fakeServer) - ext, err := extensions.Get(context.TODO(), client.ServiceClient(), "agent").Extract() + ext, err := extensions.Get(context.TODO(), client.ServiceClient(fakeServer), "agent").Extract() th.AssertNoErr(t, err) th.AssertEquals(t, ext.Updated, "2013-02-03T10:00:00-00:00") diff --git a/openstack/compute/v2/extensions/testing/fixtures_test.go b/openstack/compute/v2/extensions/testing/fixtures_test.go index b1622af764..c330c9c869 100644 --- a/openstack/compute/v2/extensions/testing/fixtures_test.go +++ b/openstack/compute/v2/extensions/testing/fixtures_test.go @@ -9,8 +9,8 @@ import ( "github.com/gophercloud/gophercloud/v2/testhelper/client" ) -func HandleListExtensionsSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/extensions", func(w http.ResponseWriter, r *http.Request) { +func HandleListExtensionsSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/extensions", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -33,8 +33,8 @@ func HandleListExtensionsSuccessfully(t *testing.T) { }) } -func HandleGetExtensionsSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/extensions/agent", func(w http.ResponseWriter, r *http.Request) { +func HandleGetExtensionsSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/extensions/agent", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/compute/v2/flavors/testing/fixtures_test.go b/openstack/compute/v2/flavors/testing/fixtures_test.go index b4badea884..1dfdbf695f 100644 --- a/openstack/compute/v2/flavors/testing/fixtures_test.go +++ b/openstack/compute/v2/flavors/testing/fixtures_test.go @@ -49,8 +49,8 @@ var UpdatedExtraSpec = map[string]string{ "hw:cpu_policy": "CPU-POLICY-2", } -func HandleExtraSpecsListSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/flavors/1/os-extra_specs", func(w http.ResponseWriter, r *http.Request) { +func HandleExtraSpecsListSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/flavors/1/os-extra_specs", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -61,8 +61,8 @@ func HandleExtraSpecsListSuccessfully(t *testing.T) { }) } -func HandleExtraSpecGetSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/flavors/1/os-extra_specs/hw:cpu_policy", func(w http.ResponseWriter, r *http.Request) { +func HandleExtraSpecGetSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/flavors/1/os-extra_specs/hw:cpu_policy", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -73,8 +73,8 @@ func HandleExtraSpecGetSuccessfully(t *testing.T) { }) } -func HandleExtraSpecsCreateSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/flavors/1/os-extra_specs", func(w http.ResponseWriter, r *http.Request) { +func HandleExtraSpecsCreateSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/flavors/1/os-extra_specs", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -91,8 +91,8 @@ func HandleExtraSpecsCreateSuccessfully(t *testing.T) { }) } -func HandleExtraSpecUpdateSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/flavors/1/os-extra_specs/hw:cpu_policy", func(w http.ResponseWriter, r *http.Request) { +func HandleExtraSpecUpdateSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/flavors/1/os-extra_specs/hw:cpu_policy", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -106,8 +106,8 @@ func HandleExtraSpecUpdateSuccessfully(t *testing.T) { }) } -func HandleExtraSpecDeleteSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/flavors/1/os-extra_specs/hw:cpu_policy", func(w http.ResponseWriter, r *http.Request) { +func HandleExtraSpecDeleteSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/flavors/1/os-extra_specs/hw:cpu_policy", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/compute/v2/flavors/testing/requests_test.go b/openstack/compute/v2/flavors/testing/requests_test.go index 7685417083..147bed33d7 100644 --- a/openstack/compute/v2/flavors/testing/requests_test.go +++ b/openstack/compute/v2/flavors/testing/requests_test.go @@ -14,10 +14,10 @@ import ( ) func TestListFlavors(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/flavors/detail", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/flavors/detail", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -74,7 +74,7 @@ func TestListFlavors(t *testing.T) { } ] } - `, th.Server.URL) + `, fakeServer.Server.URL) case "2": fmt.Fprint(w, `{ "flavors": [] }`) default: @@ -84,7 +84,7 @@ func TestListFlavors(t *testing.T) { pages := 0 // Get public and private flavors - err := flavors.ListDetail(client.ServiceClient(), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := flavors.ListDetail(client.ServiceClient(fakeServer), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := flavors.ExtractFlavors(page) @@ -113,10 +113,10 @@ func TestListFlavors(t *testing.T) { } func TestGetFlavor(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/flavors/12345", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/flavors/12345", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -140,7 +140,7 @@ func TestGetFlavor(t *testing.T) { `) }) - actual, err := flavors.Get(context.TODO(), client.ServiceClient(), "12345").Extract() + actual, err := flavors.Get(context.TODO(), client.ServiceClient(fakeServer), "12345").Extract() if err != nil { t.Fatalf("Unable to get flavor: %v", err) } @@ -162,10 +162,10 @@ func TestGetFlavor(t *testing.T) { } func TestCreateFlavor(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/flavors", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/flavors", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -196,7 +196,7 @@ func TestCreateFlavor(t *testing.T) { RxTxFactor: 1.0, Description: "foo", } - actual, err := flavors.Create(context.TODO(), client.ServiceClient(), opts).Extract() + actual, err := flavors.Create(context.TODO(), client.ServiceClient(fakeServer), opts).Extract() if err != nil { t.Fatalf("Unable to create flavor: %v", err) } @@ -217,10 +217,10 @@ func TestCreateFlavor(t *testing.T) { } func TestUpdateFlavor(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/flavors/12345678", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/flavors/12345678", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -244,7 +244,7 @@ func TestUpdateFlavor(t *testing.T) { opts := &flavors.UpdateOpts{ Description: "foo", } - actual, err := flavors.Update(context.TODO(), client.ServiceClient(), "12345678", opts).Extract() + actual, err := flavors.Update(context.TODO(), client.ServiceClient(fakeServer), "12345678", opts).Extract() if err != nil { t.Fatalf("Unable to update flavor: %v", err) } @@ -266,25 +266,25 @@ func TestUpdateFlavor(t *testing.T) { } func TestDeleteFlavor(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/flavors/12345678", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/flavors/12345678", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusAccepted) }) - res := flavors.Delete(context.TODO(), client.ServiceClient(), "12345678") + res := flavors.Delete(context.TODO(), client.ServiceClient(fakeServer), "12345678") th.AssertNoErr(t, res.Err) } func TestFlavorAccessesList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/flavors/12345678/os-flavor-access", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/flavors/12345678/os-flavor-access", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") @@ -307,7 +307,7 @@ func TestFlavorAccessesList(t *testing.T) { }, } - allPages, err := flavors.ListAccesses(client.ServiceClient(), "12345678").AllPages(context.TODO()) + allPages, err := flavors.ListAccesses(client.ServiceClient(fakeServer), "12345678").AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := flavors.ExtractAccesses(allPages) @@ -319,10 +319,10 @@ func TestFlavorAccessesList(t *testing.T) { } func TestFlavorAccessAdd(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/flavors/12345678/action", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/flavors/12345678/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "accept", "application/json") @@ -359,7 +359,7 @@ func TestFlavorAccessAdd(t *testing.T) { Tenant: "2f954bcf047c4ee9b09a37d49ae6db54", } - actual, err := flavors.AddAccess(context.TODO(), client.ServiceClient(), "12345678", addAccessOpts).Extract() + actual, err := flavors.AddAccess(context.TODO(), client.ServiceClient(fakeServer), "12345678", addAccessOpts).Extract() th.AssertNoErr(t, err) if !reflect.DeepEqual(expected, actual) { @@ -368,10 +368,10 @@ func TestFlavorAccessAdd(t *testing.T) { } func TestFlavorAccessRemove(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/flavors/12345678/action", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/flavors/12345678/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "accept", "application/json") @@ -397,7 +397,7 @@ func TestFlavorAccessRemove(t *testing.T) { Tenant: "2f954bcf047c4ee9b09a37d49ae6db54", } - actual, err := flavors.RemoveAccess(context.TODO(), client.ServiceClient(), "12345678", removeAccessOpts).Extract() + actual, err := flavors.RemoveAccess(context.TODO(), client.ServiceClient(fakeServer), "12345678", removeAccessOpts).Extract() th.AssertNoErr(t, err) if !reflect.DeepEqual(expected, actual) { @@ -406,61 +406,61 @@ func TestFlavorAccessRemove(t *testing.T) { } func TestFlavorExtraSpecsList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleExtraSpecsListSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleExtraSpecsListSuccessfully(t, fakeServer) expected := ExtraSpecs - actual, err := flavors.ListExtraSpecs(context.TODO(), client.ServiceClient(), "1").Extract() + actual, err := flavors.ListExtraSpecs(context.TODO(), client.ServiceClient(fakeServer), "1").Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, expected, actual) } func TestFlavorExtraSpecGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleExtraSpecGetSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleExtraSpecGetSuccessfully(t, fakeServer) expected := ExtraSpec - actual, err := flavors.GetExtraSpec(context.TODO(), client.ServiceClient(), "1", "hw:cpu_policy").Extract() + actual, err := flavors.GetExtraSpec(context.TODO(), client.ServiceClient(fakeServer), "1", "hw:cpu_policy").Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, expected, actual) } func TestFlavorExtraSpecsCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleExtraSpecsCreateSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleExtraSpecsCreateSuccessfully(t, fakeServer) createOpts := flavors.ExtraSpecsOpts{ "hw:cpu_policy": "CPU-POLICY", "hw:cpu_thread_policy": "CPU-THREAD-POLICY", } expected := ExtraSpecs - actual, err := flavors.CreateExtraSpecs(context.TODO(), client.ServiceClient(), "1", createOpts).Extract() + actual, err := flavors.CreateExtraSpecs(context.TODO(), client.ServiceClient(fakeServer), "1", createOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, expected, actual) } func TestFlavorExtraSpecUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleExtraSpecUpdateSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleExtraSpecUpdateSuccessfully(t, fakeServer) updateOpts := flavors.ExtraSpecsOpts{ "hw:cpu_policy": "CPU-POLICY-2", } expected := UpdatedExtraSpec - actual, err := flavors.UpdateExtraSpec(context.TODO(), client.ServiceClient(), "1", updateOpts).Extract() + actual, err := flavors.UpdateExtraSpec(context.TODO(), client.ServiceClient(fakeServer), "1", updateOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, expected, actual) } func TestFlavorExtraSpecDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleExtraSpecDeleteSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleExtraSpecDeleteSuccessfully(t, fakeServer) - res := flavors.DeleteExtraSpec(context.TODO(), client.ServiceClient(), "1", "hw:cpu_policy") + res := flavors.DeleteExtraSpec(context.TODO(), client.ServiceClient(fakeServer), "1", "hw:cpu_policy") th.AssertNoErr(t, res.Err) } diff --git a/openstack/compute/v2/hypervisors/testing/fixtures_test.go b/openstack/compute/v2/hypervisors/testing/fixtures_test.go index ebb23c1f31..ebfd816c03 100644 --- a/openstack/compute/v2/hypervisors/testing/fixtures_test.go +++ b/openstack/compute/v2/hypervisors/testing/fixtures_test.go @@ -615,8 +615,8 @@ var ( } ) -func HandleHypervisorsStatisticsSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/os-hypervisors/statistics", func(w http.ResponseWriter, r *http.Request) { +func HandleHypervisorsStatisticsSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/os-hypervisors/statistics", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -625,8 +625,8 @@ func HandleHypervisorsStatisticsSuccessfully(t *testing.T) { }) } -func HandleHypervisorListPre253Successfully(t *testing.T) { - th.Mux.HandleFunc("/os-hypervisors/detail", func(w http.ResponseWriter, r *http.Request) { +func HandleHypervisorListPre253Successfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/os-hypervisors/detail", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -635,15 +635,15 @@ func HandleHypervisorListPre253Successfully(t *testing.T) { }) } -func HandleHypervisorListSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/os-hypervisors/detail", func(w http.ResponseWriter, r *http.Request) { +func HandleHypervisorListSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/os-hypervisors/detail", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) switch r.URL.Query().Get("marker") { case "": w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, HypervisorListBodyPage1, th.Server.URL) + fmt.Fprintf(w, HypervisorListBodyPage1, fakeServer.Server.URL) case "c48f6247-abe4-4a24-824e-ea39e108874f": w.Header().Add("Content-Type", "application/json") fmt.Fprint(w, HypervisorListBodyPage2) @@ -653,8 +653,8 @@ func HandleHypervisorListSuccessfully(t *testing.T) { }) } -func HandleHypervisorListWithParametersSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/os-hypervisors/detail", func(w http.ResponseWriter, r *http.Request) { +func HandleHypervisorListWithParametersSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/os-hypervisors/detail", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestFormValues(t, r, map[string]string{ @@ -666,8 +666,8 @@ func HandleHypervisorListWithParametersSuccessfully(t *testing.T) { }) } -func HandleHypervisorGetSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/os-hypervisors/"+HypervisorFake.ID, func(w http.ResponseWriter, r *http.Request) { +func HandleHypervisorGetSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/os-hypervisors/"+HypervisorFake.ID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -676,8 +676,8 @@ func HandleHypervisorGetSuccessfully(t *testing.T) { }) } -func HandleHypervisorGetEmptyCPUInfoSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/os-hypervisors/"+HypervisorFake.ID, func(w http.ResponseWriter, r *http.Request) { +func HandleHypervisorGetEmptyCPUInfoSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/os-hypervisors/"+HypervisorFake.ID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -686,8 +686,8 @@ func HandleHypervisorGetEmptyCPUInfoSuccessfully(t *testing.T) { }) } -func HandleHypervisorAfterV287ResponseSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/os-hypervisors/"+HypervisorFake.ID, func(w http.ResponseWriter, r *http.Request) { +func HandleHypervisorAfterV287ResponseSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/os-hypervisors/"+HypervisorFake.ID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -696,8 +696,8 @@ func HandleHypervisorAfterV287ResponseSuccessfully(t *testing.T) { }) } -func HandleHypervisorUptimeSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/os-hypervisors/"+HypervisorFake.ID+"/uptime", func(w http.ResponseWriter, r *http.Request) { +func HandleHypervisorUptimeSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/os-hypervisors/"+HypervisorFake.ID+"/uptime", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/compute/v2/hypervisors/testing/requests_test.go b/openstack/compute/v2/hypervisors/testing/requests_test.go index 5acf7d0d1a..a2b2183e48 100644 --- a/openstack/compute/v2/hypervisors/testing/requests_test.go +++ b/openstack/compute/v2/hypervisors/testing/requests_test.go @@ -11,12 +11,12 @@ import ( ) func TestListHypervisorsPre253(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleHypervisorListPre253Successfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleHypervisorListPre253Successfully(t, fakeServer) pages := 0 - err := hypervisors.List(client.ServiceClient(), + err := hypervisors.List(client.ServiceClient(fakeServer), hypervisors.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ @@ -42,11 +42,11 @@ func TestListHypervisorsPre253(t *testing.T) { } func TestListAllHypervisorsPre253(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleHypervisorListPre253Successfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleHypervisorListPre253Successfully(t, fakeServer) - allPages, err := hypervisors.List(client.ServiceClient(), hypervisors.ListOpts{}).AllPages(context.TODO()) + allPages, err := hypervisors.List(client.ServiceClient(fakeServer), hypervisors.ListOpts{}).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := hypervisors.ExtractHypervisors(allPages) th.AssertNoErr(t, err) @@ -55,12 +55,12 @@ func TestListAllHypervisorsPre253(t *testing.T) { } func TestListHypervisors(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleHypervisorListSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleHypervisorListSuccessfully(t, fakeServer) pages := 0 - err := hypervisors.List(client.ServiceClient(), + err := hypervisors.List(client.ServiceClient(fakeServer), hypervisors.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ @@ -85,11 +85,11 @@ func TestListHypervisors(t *testing.T) { } func TestListAllHypervisors(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleHypervisorListSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleHypervisorListSuccessfully(t, fakeServer) - allPages, err := hypervisors.List(client.ServiceClient(), hypervisors.ListOpts{}).AllPages(context.TODO()) + allPages, err := hypervisors.List(client.ServiceClient(fakeServer), hypervisors.ListOpts{}).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := hypervisors.ExtractHypervisors(allPages) th.AssertNoErr(t, err) @@ -98,12 +98,12 @@ func TestListAllHypervisors(t *testing.T) { } func TestListAllHypervisorsWithParameters(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleHypervisorListWithParametersSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleHypervisorListWithParametersSuccessfully(t, fakeServer) with_servers := true - allPages, err := hypervisors.List(client.ServiceClient(), hypervisors.ListOpts{WithServers: &with_servers}).AllPages(context.TODO()) + allPages, err := hypervisors.List(client.ServiceClient(fakeServer), hypervisors.ListOpts{WithServers: &with_servers}).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := hypervisors.ExtractHypervisors(allPages) th.AssertNoErr(t, err) @@ -112,61 +112,61 @@ func TestListAllHypervisorsWithParameters(t *testing.T) { } func TestHypervisorsStatistics(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleHypervisorsStatisticsSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleHypervisorsStatisticsSuccessfully(t, fakeServer) expected := HypervisorsStatisticsExpected - actual, err := hypervisors.GetStatistics(context.TODO(), client.ServiceClient()).Extract() + actual, err := hypervisors.GetStatistics(context.TODO(), client.ServiceClient(fakeServer)).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, &expected, actual) } func TestGetHypervisor(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleHypervisorGetSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleHypervisorGetSuccessfully(t, fakeServer) expected := HypervisorFake - actual, err := hypervisors.Get(context.TODO(), client.ServiceClient(), expected.ID).Extract() + actual, err := hypervisors.Get(context.TODO(), client.ServiceClient(fakeServer), expected.ID).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, &expected, actual) } func TestGetHypervisorEmptyCPUInfo(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleHypervisorGetEmptyCPUInfoSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleHypervisorGetEmptyCPUInfoSuccessfully(t, fakeServer) expected := HypervisorEmptyCPUInfo - actual, err := hypervisors.Get(context.TODO(), client.ServiceClient(), expected.ID).Extract() + actual, err := hypervisors.Get(context.TODO(), client.ServiceClient(fakeServer), expected.ID).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, &expected, actual) } func TestGetHypervisorAfterV287Response(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleHypervisorAfterV287ResponseSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleHypervisorAfterV287ResponseSuccessfully(t, fakeServer) expected := HypervisorAfterV287Response - actual, err := hypervisors.Get(context.TODO(), client.ServiceClient(), expected.ID).Extract() + actual, err := hypervisors.Get(context.TODO(), client.ServiceClient(fakeServer), expected.ID).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, &expected, actual) } func TestHypervisorsUptime(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleHypervisorUptimeSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleHypervisorUptimeSuccessfully(t, fakeServer) expected := HypervisorUptimeExpected - actual, err := hypervisors.GetUptime(context.TODO(), client.ServiceClient(), HypervisorFake.ID).Extract() + actual, err := hypervisors.GetUptime(context.TODO(), client.ServiceClient(fakeServer), HypervisorFake.ID).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, &expected, actual) } diff --git a/openstack/compute/v2/instanceactions/testing/fixtures_test.go b/openstack/compute/v2/instanceactions/testing/fixtures_test.go index cbbf6def28..1a53cbc7c2 100644 --- a/openstack/compute/v2/instanceactions/testing/fixtures_test.go +++ b/openstack/compute/v2/instanceactions/testing/fixtures_test.go @@ -34,8 +34,8 @@ var ListExpected = []instanceactions.InstanceAction{ } // HandleInstanceActionListSuccessfully sets up the test server to respond to a ListAddresses request. -func HandleInstanceActionListSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/servers/asdfasdfasdf/os-instance-actions", func(w http.ResponseWriter, r *http.Request) { +func HandleInstanceActionListSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/servers/asdfasdfasdf/os-instance-actions", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -94,8 +94,8 @@ var GetExpected = instanceactions.InstanceActionDetail{ } // HandleInstanceActionGetSuccessfully sets up the test server to respond to a Get request. -func HandleInstanceActionGetSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/servers/asdfasdfasdf/os-instance-actions/okzeorkmkfs", func(w http.ResponseWriter, r *http.Request) { +func HandleInstanceActionGetSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/servers/asdfasdfasdf/os-instance-actions/okzeorkmkfs", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/compute/v2/instanceactions/testing/request_test.go b/openstack/compute/v2/instanceactions/testing/request_test.go index 459c776948..1b36152d74 100644 --- a/openstack/compute/v2/instanceactions/testing/request_test.go +++ b/openstack/compute/v2/instanceactions/testing/request_test.go @@ -11,13 +11,13 @@ import ( ) func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleInstanceActionListSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleInstanceActionListSuccessfully(t, fakeServer) expected := ListExpected pages := 0 - err := instanceactions.List(client.ServiceClient(), "asdfasdfasdf", nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := instanceactions.List(client.ServiceClient(fakeServer), "asdfasdfasdf", nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := instanceactions.ExtractInstanceActions(page) @@ -35,11 +35,11 @@ func TestList(t *testing.T) { } func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleInstanceActionGetSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleInstanceActionGetSuccessfully(t, fakeServer) - client := client.ServiceClient() + client := client.ServiceClient(fakeServer) actual, err := instanceactions.Get(context.TODO(), client, "asdfasdfasdf", "okzeorkmkfs").Extract() if err != nil { t.Fatalf("Unexpected Get error: %v", err) diff --git a/openstack/compute/v2/keypairs/testing/fixtures_test.go b/openstack/compute/v2/keypairs/testing/fixtures_test.go index 92460e9259..27dc933992 100644 --- a/openstack/compute/v2/keypairs/testing/fixtures_test.go +++ b/openstack/compute/v2/keypairs/testing/fixtures_test.go @@ -151,8 +151,8 @@ var ImportedKeyPair = keypairs.KeyPair{ } // HandleListSuccessfully configures the test server to respond to a List request. -func HandleListSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/os-keypairs", func(w http.ResponseWriter, r *http.Request) { +func HandleListSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/os-keypairs", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -162,8 +162,8 @@ func HandleListSuccessfully(t *testing.T) { } // HandleGetSuccessfully configures the test server to respond to a Get request for "firstkey". -func HandleGetSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/os-keypairs/firstkey", func(w http.ResponseWriter, r *http.Request) { +func HandleGetSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/os-keypairs/firstkey", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -181,8 +181,8 @@ func HandleGetSuccessfully(t *testing.T) { // HandleCreateSuccessfully configures the test server to respond to a Create request for a new // keypair called "createdkey". -func HandleCreateSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/os-keypairs", func(w http.ResponseWriter, r *http.Request) { +func HandleCreateSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/os-keypairs", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, `{ "keypair": { "name": "createdkey" } }`) @@ -194,8 +194,8 @@ func HandleCreateSuccessfully(t *testing.T) { // HandleCreateSuccessfullyOtherUser configures the test server to respond to a Create request for a new // keypair called "createdkey" for another user, different than the current one. -func HandleCreateSuccessfullyOtherUser(t *testing.T) { - th.Mux.HandleFunc("/os-keypairs", func(w http.ResponseWriter, r *http.Request) { +func HandleCreateSuccessfullyOtherUser(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/os-keypairs", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, `{ "keypair": { "name": "createdkey", "user_id": "fake2" } }`) @@ -207,8 +207,8 @@ func HandleCreateSuccessfullyOtherUser(t *testing.T) { // HandleImportSuccessfully configures the test server to respond to an Import request for an // existing keypair called "importedkey". -func HandleImportSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/os-keypairs", func(w http.ResponseWriter, r *http.Request) { +func HandleImportSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/os-keypairs", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, ` @@ -227,8 +227,8 @@ func HandleImportSuccessfully(t *testing.T) { // HandleDeleteSuccessfully configures the test server to respond to a Delete request for a // keypair called "deletedkey". -func HandleDeleteSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/os-keypairs/deletedkey", func(w http.ResponseWriter, r *http.Request) { +func HandleDeleteSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/os-keypairs/deletedkey", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.AssertEquals(t, r.Form.Get("user_id"), "") @@ -239,8 +239,8 @@ func HandleDeleteSuccessfully(t *testing.T) { // HandleDeleteSuccessfully configures the test server to respond to a Delete request for a // keypair called "deletedkey" for another user. -func HandleDeleteSuccessfullyOtherUser(t *testing.T) { - th.Mux.HandleFunc("/os-keypairs/deletedkey", func(w http.ResponseWriter, r *http.Request) { +func HandleDeleteSuccessfullyOtherUser(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/os-keypairs/deletedkey", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestFormValues(t, r, map[string]string{"user_id": "fake2"}) diff --git a/openstack/compute/v2/keypairs/testing/requests_test.go b/openstack/compute/v2/keypairs/testing/requests_test.go index 35e9f7653b..43961a3b15 100644 --- a/openstack/compute/v2/keypairs/testing/requests_test.go +++ b/openstack/compute/v2/keypairs/testing/requests_test.go @@ -11,12 +11,12 @@ import ( ) func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListSuccessfully(t, fakeServer) count := 0 - err := keypairs.List(client.ServiceClient(), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := keypairs.List(client.ServiceClient(fakeServer), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := keypairs.ExtractKeyPairs(page) th.AssertNoErr(t, err) @@ -29,11 +29,11 @@ func TestList(t *testing.T) { } func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCreateSuccessfully(t, fakeServer) - actual, err := keypairs.Create(context.TODO(), client.ServiceClient(), keypairs.CreateOpts{ + actual, err := keypairs.Create(context.TODO(), client.ServiceClient(fakeServer), keypairs.CreateOpts{ Name: "createdkey", }).Extract() th.AssertNoErr(t, err) @@ -41,11 +41,11 @@ func TestCreate(t *testing.T) { } func TestCreateOtherUser(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateSuccessfullyOtherUser(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCreateSuccessfullyOtherUser(t, fakeServer) - actual, err := keypairs.Create(context.TODO(), client.ServiceClient(), keypairs.CreateOpts{ + actual, err := keypairs.Create(context.TODO(), client.ServiceClient(fakeServer), keypairs.CreateOpts{ Name: "createdkey", UserID: "fake2", }).Extract() @@ -54,11 +54,11 @@ func TestCreateOtherUser(t *testing.T) { } func TestImport(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleImportSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleImportSuccessfully(t, fakeServer) - actual, err := keypairs.Create(context.TODO(), client.ServiceClient(), keypairs.CreateOpts{ + actual, err := keypairs.Create(context.TODO(), client.ServiceClient(fakeServer), keypairs.CreateOpts{ Name: "importedkey", PublicKey: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDx8nkQv/zgGgB4rMYmIf+6A4l6Rr+o/6lHBQdW5aYd44bd8JttDCE/F/pNRr0lRE+PiqSPO8nDPHw0010JeMH9gYgnnFlyY3/OcJ02RhIPyyxYpv9FhY+2YiUkpwFOcLImyrxEsYXpD/0d3ac30bNH6Sw9JD9UZHYcpSxsIbECHw== Generated by Nova", }).Extract() @@ -67,47 +67,47 @@ func TestImport(t *testing.T) { } func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetSuccessfully(t, fakeServer) - actual, err := keypairs.Get(context.TODO(), client.ServiceClient(), "firstkey", nil).Extract() + actual, err := keypairs.Get(context.TODO(), client.ServiceClient(fakeServer), "firstkey", nil).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, &FirstKeyPair, actual) } func TestGetOtherUser(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetSuccessfully(t, fakeServer) getOpts := keypairs.GetOpts{ UserID: "fake2", } - actual, err := keypairs.Get(context.TODO(), client.ServiceClient(), "firstkey", getOpts).Extract() + actual, err := keypairs.Get(context.TODO(), client.ServiceClient(fakeServer), "firstkey", getOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, &FirstKeyPairOtherUser, actual) } func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDeleteSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDeleteSuccessfully(t, fakeServer) - err := keypairs.Delete(context.TODO(), client.ServiceClient(), "deletedkey", nil).ExtractErr() + err := keypairs.Delete(context.TODO(), client.ServiceClient(fakeServer), "deletedkey", nil).ExtractErr() th.AssertNoErr(t, err) } func TestDeleteOtherUser(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDeleteSuccessfullyOtherUser(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDeleteSuccessfullyOtherUser(t, fakeServer) deleteOpts := keypairs.DeleteOpts{ UserID: "fake2", } - err := keypairs.Delete(context.TODO(), client.ServiceClient(), "deletedkey", deleteOpts).ExtractErr() + err := keypairs.Delete(context.TODO(), client.ServiceClient(fakeServer), "deletedkey", deleteOpts).ExtractErr() th.AssertNoErr(t, err) } diff --git a/openstack/compute/v2/limits/testing/fixtures_test.go b/openstack/compute/v2/limits/testing/fixtures_test.go index ee04c72442..365b9d68b8 100644 --- a/openstack/compute/v2/limits/testing/fixtures_test.go +++ b/openstack/compute/v2/limits/testing/fixtures_test.go @@ -69,8 +69,8 @@ const TenantID = "555544443333222211110000ffffeeee" // HandleGetSuccessfully configures the test server to respond to a Get request // for a limit. -func HandleGetSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/limits", func(w http.ResponseWriter, r *http.Request) { +func HandleGetSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/limits", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/compute/v2/limits/testing/requests_test.go b/openstack/compute/v2/limits/testing/requests_test.go index ae9650097e..d795ec958c 100644 --- a/openstack/compute/v2/limits/testing/requests_test.go +++ b/openstack/compute/v2/limits/testing/requests_test.go @@ -10,15 +10,15 @@ import ( ) func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetSuccessfully(t, fakeServer) getOpts := limits.GetOpts{ TenantID: TenantID, } - actual, err := limits.Get(context.TODO(), client.ServiceClient(), getOpts).Extract() + actual, err := limits.Get(context.TODO(), client.ServiceClient(fakeServer), getOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, &LimitsResult, actual) } diff --git a/openstack/compute/v2/quotasets/testing/fixtures_test.go b/openstack/compute/v2/quotasets/testing/fixtures_test.go index 5d0ef24931..a9bac9f36d 100644 --- a/openstack/compute/v2/quotasets/testing/fixtures_test.go +++ b/openstack/compute/v2/quotasets/testing/fixtures_test.go @@ -161,8 +161,8 @@ var UpdatedQuotaSet = quotasets.UpdateOpts{ } // HandleGetSuccessfully configures the test server to respond to a Get request for sample tenant -func HandleGetSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/os-quota-sets/"+FirstTenantID, func(w http.ResponseWriter, r *http.Request) { +func HandleGetSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/os-quota-sets/"+FirstTenantID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -172,8 +172,8 @@ func HandleGetSuccessfully(t *testing.T) { } // HandleGetDetailSuccessfully configures the test server to respond to a Get Details request for sample tenant -func HandleGetDetailSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/os-quota-sets/"+FirstTenantID+"/detail", func(w http.ResponseWriter, r *http.Request) { +func HandleGetDetailSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/os-quota-sets/"+FirstTenantID+"/detail", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") @@ -182,8 +182,8 @@ func HandleGetDetailSuccessfully(t *testing.T) { } // HandlePutSuccessfully configures the test server to respond to a Put request for sample tenant -func HandlePutSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/os-quota-sets/"+FirstTenantID, func(w http.ResponseWriter, r *http.Request) { +func HandlePutSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/os-quota-sets/"+FirstTenantID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, UpdateOutput) @@ -193,8 +193,8 @@ func HandlePutSuccessfully(t *testing.T) { } // HandlePartialPutSuccessfully configures the test server to respond to a Put request for sample tenant that only containes specific values -func HandlePartialPutSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/os-quota-sets/"+FirstTenantID, func(w http.ResponseWriter, r *http.Request) { +func HandlePartialPutSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/os-quota-sets/"+FirstTenantID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, PartialUpdateBody) @@ -204,8 +204,8 @@ func HandlePartialPutSuccessfully(t *testing.T) { } // HandleDeleteSuccessfully configures the test server to respond to a Delete request for sample tenant -func HandleDeleteSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/os-quota-sets/"+FirstTenantID, func(w http.ResponseWriter, r *http.Request) { +func HandleDeleteSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/os-quota-sets/"+FirstTenantID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestBody(t, r, "") diff --git a/openstack/compute/v2/quotasets/testing/requests_test.go b/openstack/compute/v2/quotasets/testing/requests_test.go index eac6e99d0d..c46afd343d 100644 --- a/openstack/compute/v2/quotasets/testing/requests_test.go +++ b/openstack/compute/v2/quotasets/testing/requests_test.go @@ -12,47 +12,47 @@ import ( ) func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetSuccessfully(t) - actual, err := quotasets.Get(context.TODO(), client.ServiceClient(), FirstTenantID).Extract() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetSuccessfully(t, fakeServer) + actual, err := quotasets.Get(context.TODO(), client.ServiceClient(fakeServer), FirstTenantID).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, &FirstQuotaSet, actual) } func TestGetDetail(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetDetailSuccessfully(t) - actual, err := quotasets.GetDetail(context.TODO(), client.ServiceClient(), FirstTenantID).Extract() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetDetailSuccessfully(t, fakeServer) + actual, err := quotasets.GetDetail(context.TODO(), client.ServiceClient(fakeServer), FirstTenantID).Extract() th.CheckDeepEquals(t, FirstQuotaDetailsSet, actual) th.AssertNoErr(t, err) } func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandlePutSuccessfully(t) - actual, err := quotasets.Update(context.TODO(), client.ServiceClient(), FirstTenantID, UpdatedQuotaSet).Extract() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandlePutSuccessfully(t, fakeServer) + actual, err := quotasets.Update(context.TODO(), client.ServiceClient(fakeServer), FirstTenantID, UpdatedQuotaSet).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, &FirstQuotaSet, actual) } func TestPartialUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandlePartialPutSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandlePartialPutSuccessfully(t, fakeServer) opts := quotasets.UpdateOpts{Cores: gophercloud.IntToPointer(200), Force: true} - actual, err := quotasets.Update(context.TODO(), client.ServiceClient(), FirstTenantID, opts).Extract() + actual, err := quotasets.Update(context.TODO(), client.ServiceClient(fakeServer), FirstTenantID, opts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, &FirstQuotaSet, actual) } func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDeleteSuccessfully(t) - _, err := quotasets.Delete(context.TODO(), client.ServiceClient(), FirstTenantID).Extract() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDeleteSuccessfully(t, fakeServer) + _, err := quotasets.Delete(context.TODO(), client.ServiceClient(fakeServer), FirstTenantID).Extract() th.AssertNoErr(t, err) } @@ -64,10 +64,10 @@ func (opts ErrorUpdateOpts) ToComputeQuotaUpdateMap() (map[string]any, error) { func TestErrorInToComputeQuotaUpdateMap(t *testing.T) { opts := &ErrorUpdateOpts{} - th.SetupHTTP() - defer th.TeardownHTTP() - HandlePutSuccessfully(t) - _, err := quotasets.Update(context.TODO(), client.ServiceClient(), FirstTenantID, opts).Extract() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandlePutSuccessfully(t, fakeServer) + _, err := quotasets.Update(context.TODO(), client.ServiceClient(fakeServer), FirstTenantID, opts).Extract() if err == nil { t.Fatal("Error handling failed") } diff --git a/openstack/compute/v2/remoteconsoles/testing/requests_test.go b/openstack/compute/v2/remoteconsoles/testing/requests_test.go index c4d67998e1..0ae0f480d9 100644 --- a/openstack/compute/v2/remoteconsoles/testing/requests_test.go +++ b/openstack/compute/v2/remoteconsoles/testing/requests_test.go @@ -12,10 +12,10 @@ import ( ) func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/servers/b16ba811-199d-4ffd-8839-ba96c1185a67/remote-consoles", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/servers/b16ba811-199d-4ffd-8839-ba96c1185a67/remote-consoles", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -32,7 +32,7 @@ func TestCreate(t *testing.T) { Protocol: remoteconsoles.ConsoleProtocolVNC, Type: remoteconsoles.ConsoleTypeNoVNC, } - s, err := remoteconsoles.Create(context.TODO(), client.ServiceClient(), "b16ba811-199d-4ffd-8839-ba96c1185a67", opts).Extract() + s, err := remoteconsoles.Create(context.TODO(), client.ServiceClient(fakeServer), "b16ba811-199d-4ffd-8839-ba96c1185a67", opts).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, s.Protocol, string(remoteconsoles.ConsoleProtocolVNC)) diff --git a/openstack/compute/v2/secgroups/testing/fixtures_test.go b/openstack/compute/v2/secgroups/testing/fixtures_test.go index 4f7222f7bf..cee5eb6d5e 100644 --- a/openstack/compute/v2/secgroups/testing/fixtures_test.go +++ b/openstack/compute/v2/secgroups/testing/fixtures_test.go @@ -25,8 +25,8 @@ const listGroupsJSON = ` } ` -func mockListGroupsResponse(t *testing.T) { - th.Mux.HandleFunc(rootPath, func(w http.ResponseWriter, r *http.Request) { +func mockListGroupsResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc(rootPath, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -37,9 +37,9 @@ func mockListGroupsResponse(t *testing.T) { }) } -func mockListGroupsByServerResponse(t *testing.T, serverID string) { +func mockListGroupsByServerResponse(t *testing.T, fakeServer th.FakeServer, serverID string) { url := fmt.Sprintf("/servers/%s%s", serverID, rootPath) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -50,8 +50,8 @@ func mockListGroupsByServerResponse(t *testing.T, serverID string) { }) } -func mockCreateGroupResponse(t *testing.T) { - th.Mux.HandleFunc(rootPath, func(w http.ResponseWriter, r *http.Request) { +func mockCreateGroupResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc(rootPath, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -81,9 +81,9 @@ func mockCreateGroupResponse(t *testing.T) { }) } -func mockUpdateGroupResponse(t *testing.T, groupID string) { +func mockUpdateGroupResponse(t *testing.T, fakeServer th.FakeServer, groupID string) { url := fmt.Sprintf("%s/%s", rootPath, groupID) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -113,9 +113,9 @@ func mockUpdateGroupResponse(t *testing.T, groupID string) { }) } -func mockGetGroupsResponse(t *testing.T, groupID string) { +func mockGetGroupsResponse(t *testing.T, fakeServer th.FakeServer, groupID string) { url := fmt.Sprintf("%s/%s", rootPath, groupID) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -151,9 +151,9 @@ func mockGetGroupsResponse(t *testing.T, groupID string) { }) } -func mockGetNumericIDGroupResponse(t *testing.T, groupID int) { +func mockGetNumericIDGroupResponse(t *testing.T, fakeServer th.FakeServer, groupID int) { url := fmt.Sprintf("%s/%d", rootPath, groupID) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -170,9 +170,9 @@ func mockGetNumericIDGroupResponse(t *testing.T, groupID int) { }) } -func mockGetNumericIDGroupRuleResponse(t *testing.T, groupID int) { +func mockGetNumericIDGroupRuleResponse(t *testing.T, fakeServer th.FakeServer, groupID int) { url := fmt.Sprintf("%s/%d", rootPath, groupID) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -195,9 +195,9 @@ func mockGetNumericIDGroupRuleResponse(t *testing.T, groupID int) { }) } -func mockDeleteGroupResponse(t *testing.T, groupID string) { +func mockDeleteGroupResponse(t *testing.T, fakeServer th.FakeServer, groupID string) { url := fmt.Sprintf("%s/%s", rootPath, groupID) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") @@ -205,8 +205,8 @@ func mockDeleteGroupResponse(t *testing.T, groupID string) { }) } -func mockAddRuleResponse(t *testing.T) { - th.Mux.HandleFunc("/os-security-group-rules", func(w http.ResponseWriter, r *http.Request) { +func mockAddRuleResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/os-security-group-rules", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -241,8 +241,8 @@ func mockAddRuleResponse(t *testing.T) { }) } -func mockAddRuleResponseICMPZero(t *testing.T) { - th.Mux.HandleFunc("/os-security-group-rules", func(w http.ResponseWriter, r *http.Request) { +func mockAddRuleResponseICMPZero(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/os-security-group-rules", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -277,9 +277,9 @@ func mockAddRuleResponseICMPZero(t *testing.T) { }) } -func mockDeleteRuleResponse(t *testing.T, ruleID string) { +func mockDeleteRuleResponse(t *testing.T, fakeServer th.FakeServer, ruleID string) { url := fmt.Sprintf("/os-security-group-rules/%s", ruleID) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") @@ -287,9 +287,9 @@ func mockDeleteRuleResponse(t *testing.T, ruleID string) { }) } -func mockAddServerToGroupResponse(t *testing.T, serverID string) { +func mockAddServerToGroupResponse(t *testing.T, fakeServer th.FakeServer, serverID string) { url := fmt.Sprintf("/servers/%s/action", serverID) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -306,9 +306,9 @@ func mockAddServerToGroupResponse(t *testing.T, serverID string) { }) } -func mockRemoveServerFromGroupResponse(t *testing.T, serverID string) { +func mockRemoveServerFromGroupResponse(t *testing.T, fakeServer th.FakeServer, serverID string) { url := fmt.Sprintf("/servers/%s/action", serverID) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/compute/v2/secgroups/testing/requests_test.go b/openstack/compute/v2/secgroups/testing/requests_test.go index 222295d5e8..c069b83a46 100644 --- a/openstack/compute/v2/secgroups/testing/requests_test.go +++ b/openstack/compute/v2/secgroups/testing/requests_test.go @@ -17,14 +17,14 @@ const ( ) func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - mockListGroupsResponse(t) + mockListGroupsResponse(t, fakeServer) count := 0 - err := secgroups.List(client.ServiceClient()).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := secgroups.List(client.ServiceClient(fakeServer)).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := secgroups.ExtractSecurityGroups(page) if err != nil { @@ -52,14 +52,14 @@ func TestList(t *testing.T) { } func TestListByServer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - mockListGroupsByServerResponse(t, serverID) + mockListGroupsByServerResponse(t, fakeServer, serverID) count := 0 - err := secgroups.ListByServer(client.ServiceClient(), serverID).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := secgroups.ListByServer(client.ServiceClient(fakeServer), serverID).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := secgroups.ExtractSecurityGroups(page) if err != nil { @@ -87,17 +87,17 @@ func TestListByServer(t *testing.T) { } func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - mockCreateGroupResponse(t) + mockCreateGroupResponse(t, fakeServer) opts := secgroups.CreateOpts{ Name: "test", Description: "something", } - group, err := secgroups.Create(context.TODO(), client.ServiceClient(), opts).Extract() + group, err := secgroups.Create(context.TODO(), client.ServiceClient(fakeServer), opts).Extract() th.AssertNoErr(t, err) expected := &secgroups.SecurityGroup{ @@ -111,10 +111,10 @@ func TestCreate(t *testing.T) { } func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - mockUpdateGroupResponse(t, groupID) + mockUpdateGroupResponse(t, fakeServer, groupID) description := "new_desc" opts := secgroups.UpdateOpts{ @@ -122,7 +122,7 @@ func TestUpdate(t *testing.T) { Description: &description, } - group, err := secgroups.Update(context.TODO(), client.ServiceClient(), groupID, opts).Extract() + group, err := secgroups.Update(context.TODO(), client.ServiceClient(fakeServer), groupID, opts).Extract() th.AssertNoErr(t, err) expected := &secgroups.SecurityGroup{ @@ -136,12 +136,12 @@ func TestUpdate(t *testing.T) { } func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - mockGetGroupsResponse(t, groupID) + mockGetGroupsResponse(t, fakeServer, groupID) - group, err := secgroups.Get(context.TODO(), client.ServiceClient(), groupID).Extract() + group, err := secgroups.Get(context.TODO(), client.ServiceClient(fakeServer), groupID).Extract() th.AssertNoErr(t, err) expected := &secgroups.SecurityGroup{ @@ -166,14 +166,14 @@ func TestGet(t *testing.T) { } func TestGetNumericID(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() numericGroupID := 12345 - mockGetNumericIDGroupResponse(t, numericGroupID) + mockGetNumericIDGroupResponse(t, fakeServer, numericGroupID) - group, err := secgroups.Get(context.TODO(), client.ServiceClient(), "12345").Extract() + group, err := secgroups.Get(context.TODO(), client.ServiceClient(fakeServer), "12345").Extract() th.AssertNoErr(t, err) expected := &secgroups.SecurityGroup{ID: "12345"} @@ -181,14 +181,14 @@ func TestGetNumericID(t *testing.T) { } func TestGetNumericRuleID(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() numericGroupID := 12345 - mockGetNumericIDGroupRuleResponse(t, numericGroupID) + mockGetNumericIDGroupRuleResponse(t, fakeServer, numericGroupID) - group, err := secgroups.Get(context.TODO(), client.ServiceClient(), "12345").Extract() + group, err := secgroups.Get(context.TODO(), client.ServiceClient(fakeServer), "12345").Extract() th.AssertNoErr(t, err) expected := &secgroups.SecurityGroup{ @@ -204,20 +204,20 @@ func TestGetNumericRuleID(t *testing.T) { } func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - mockDeleteGroupResponse(t, groupID) + mockDeleteGroupResponse(t, fakeServer, groupID) - err := secgroups.Delete(context.TODO(), client.ServiceClient(), groupID).ExtractErr() + err := secgroups.Delete(context.TODO(), client.ServiceClient(fakeServer), groupID).ExtractErr() th.AssertNoErr(t, err) } func TestAddRule(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - mockAddRuleResponse(t) + mockAddRuleResponse(t, fakeServer) opts := secgroups.CreateRuleOpts{ ParentGroupID: groupID, @@ -227,7 +227,7 @@ func TestAddRule(t *testing.T) { CIDR: "0.0.0.0/0", } - rule, err := secgroups.CreateRule(context.TODO(), client.ServiceClient(), opts).Extract() + rule, err := secgroups.CreateRule(context.TODO(), client.ServiceClient(fakeServer), opts).Extract() th.AssertNoErr(t, err) expected := &secgroups.Rule{ @@ -244,10 +244,10 @@ func TestAddRule(t *testing.T) { } func TestAddRuleICMPZero(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - mockAddRuleResponseICMPZero(t) + mockAddRuleResponseICMPZero(t, fakeServer) opts := secgroups.CreateRuleOpts{ ParentGroupID: groupID, @@ -257,7 +257,7 @@ func TestAddRuleICMPZero(t *testing.T) { CIDR: "0.0.0.0/0", } - rule, err := secgroups.CreateRule(context.TODO(), client.ServiceClient(), opts).Extract() + rule, err := secgroups.CreateRule(context.TODO(), client.ServiceClient(fakeServer), opts).Extract() th.AssertNoErr(t, err) expected := &secgroups.Rule{ @@ -274,31 +274,31 @@ func TestAddRuleICMPZero(t *testing.T) { } func TestDeleteRule(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - mockDeleteRuleResponse(t, ruleID) + mockDeleteRuleResponse(t, fakeServer, ruleID) - err := secgroups.DeleteRule(context.TODO(), client.ServiceClient(), ruleID).ExtractErr() + err := secgroups.DeleteRule(context.TODO(), client.ServiceClient(fakeServer), ruleID).ExtractErr() th.AssertNoErr(t, err) } func TestAddServer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - mockAddServerToGroupResponse(t, serverID) + mockAddServerToGroupResponse(t, fakeServer, serverID) - err := secgroups.AddServer(context.TODO(), client.ServiceClient(), serverID, "test").ExtractErr() + err := secgroups.AddServer(context.TODO(), client.ServiceClient(fakeServer), serverID, "test").ExtractErr() th.AssertNoErr(t, err) } func TestRemoveServer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - mockRemoveServerFromGroupResponse(t, serverID) + mockRemoveServerFromGroupResponse(t, fakeServer, serverID) - err := secgroups.RemoveServer(context.TODO(), client.ServiceClient(), serverID, "test").ExtractErr() + err := secgroups.RemoveServer(context.TODO(), client.ServiceClient(fakeServer), serverID, "test").ExtractErr() th.AssertNoErr(t, err) } diff --git a/openstack/compute/v2/servergroups/testing/fixtures_test.go b/openstack/compute/v2/servergroups/testing/fixtures_test.go index d2a87a4467..f9ce09be22 100644 --- a/openstack/compute/v2/servergroups/testing/fixtures_test.go +++ b/openstack/compute/v2/servergroups/testing/fixtures_test.go @@ -170,8 +170,8 @@ var ExpectedServerGroupCreateMicroversion = servergroups.ServerGroup{ } // HandleListSuccessfully configures the test server to respond to a List request. -func HandleListSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/os-server-groups", func(w http.ResponseWriter, r *http.Request) { +func HandleListSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/os-server-groups", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -182,8 +182,8 @@ func HandleListSuccessfully(t *testing.T) { // HandleGetSuccessfully configures the test server to respond to a Get request // for an existing server group -func HandleGetSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/os-server-groups/4d8c3732-a248-40ed-bebc-539a6ffd25c0", func(w http.ResponseWriter, r *http.Request) { +func HandleGetSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/os-server-groups/4d8c3732-a248-40ed-bebc-539a6ffd25c0", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -194,8 +194,8 @@ func HandleGetSuccessfully(t *testing.T) { // HandleGetMicroversionSuccessfully configures the test server to respond to a Get request // for an existing server group with microversion set to 2.64 -func HandleGetMicroversionSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/os-server-groups/4d8c3732-a248-40ed-bebc-539a6ffd25c0", func(w http.ResponseWriter, r *http.Request) { +func HandleGetMicroversionSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/os-server-groups/4d8c3732-a248-40ed-bebc-539a6ffd25c0", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -206,8 +206,8 @@ func HandleGetMicroversionSuccessfully(t *testing.T) { // HandleCreateSuccessfully configures the test server to respond to a Create request // for a new server group -func HandleCreateSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/os-server-groups", func(w http.ResponseWriter, r *http.Request) { +func HandleCreateSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/os-server-groups", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, ` @@ -228,8 +228,8 @@ func HandleCreateSuccessfully(t *testing.T) { // HandleCreateMicroversionSuccessfully configures the test server to respond to a Create request // for a new server group with microversion set to 2.64 -func HandleCreateMicroversionSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/os-server-groups", func(w http.ResponseWriter, r *http.Request) { +func HandleCreateMicroversionSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/os-server-groups", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, ` @@ -251,8 +251,8 @@ func HandleCreateMicroversionSuccessfully(t *testing.T) { // HandleDeleteSuccessfully configures the test server to respond to a Delete request for a // an existing server group -func HandleDeleteSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/os-server-groups/616fb98f-46ca-475e-917e-2563e5a8cd19", func(w http.ResponseWriter, r *http.Request) { +func HandleDeleteSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/os-server-groups/616fb98f-46ca-475e-917e-2563e5a8cd19", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/compute/v2/servergroups/testing/requests_test.go b/openstack/compute/v2/servergroups/testing/requests_test.go index dde919a78a..770d3f7266 100644 --- a/openstack/compute/v2/servergroups/testing/requests_test.go +++ b/openstack/compute/v2/servergroups/testing/requests_test.go @@ -11,12 +11,12 @@ import ( ) func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListSuccessfully(t, fakeServer) count := 0 - err := servergroups.List(client.ServiceClient(), &servergroups.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := servergroups.List(client.ServiceClient(fakeServer), &servergroups.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := servergroups.ExtractServerGroups(page) th.AssertNoErr(t, err) @@ -29,11 +29,11 @@ func TestList(t *testing.T) { } func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCreateSuccessfully(t, fakeServer) - actual, err := servergroups.Create(context.TODO(), client.ServiceClient(), servergroups.CreateOpts{ + actual, err := servergroups.Create(context.TODO(), client.ServiceClient(fakeServer), servergroups.CreateOpts{ Name: "test", Policies: []string{"anti-affinity"}, }).Extract() @@ -42,11 +42,11 @@ func TestCreate(t *testing.T) { } func TestCreateMicroversion(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateMicroversionSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCreateMicroversionSuccessfully(t, fakeServer) - result := servergroups.Create(context.TODO(), client.ServiceClient(), servergroups.CreateOpts{ + result := servergroups.Create(context.TODO(), client.ServiceClient(fakeServer), servergroups.CreateOpts{ Name: "test", Policy: policy, Rules: ExpectedServerGroupCreateMicroversion.Rules, @@ -58,30 +58,30 @@ func TestCreateMicroversion(t *testing.T) { } func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetSuccessfully(t, fakeServer) - actual, err := servergroups.Get(context.TODO(), client.ServiceClient(), "4d8c3732-a248-40ed-bebc-539a6ffd25c0").Extract() + actual, err := servergroups.Get(context.TODO(), client.ServiceClient(fakeServer), "4d8c3732-a248-40ed-bebc-539a6ffd25c0").Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, &ExpectedServerGroupGet, actual) } func TestGetMicroversion(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetMicroversionSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetMicroversionSuccessfully(t, fakeServer) - actual, err := servergroups.Get(context.TODO(), client.ServiceClient(), "4d8c3732-a248-40ed-bebc-539a6ffd25c0").Extract() + actual, err := servergroups.Get(context.TODO(), client.ServiceClient(fakeServer), "4d8c3732-a248-40ed-bebc-539a6ffd25c0").Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, &ExpectedServerGroupGetMicroversion, actual) } func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDeleteSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDeleteSuccessfully(t, fakeServer) - err := servergroups.Delete(context.TODO(), client.ServiceClient(), "616fb98f-46ca-475e-917e-2563e5a8cd19").ExtractErr() + err := servergroups.Delete(context.TODO(), client.ServiceClient(fakeServer), "616fb98f-46ca-475e-917e-2563e5a8cd19").ExtractErr() th.AssertNoErr(t, err) } diff --git a/openstack/compute/v2/servers/testing/fixtures_test.go b/openstack/compute/v2/servers/testing/fixtures_test.go index a9c3980d88..7d7239d2f9 100644 --- a/openstack/compute/v2/servers/testing/fixtures_test.go +++ b/openstack/compute/v2/servers/testing/fixtures_test.go @@ -729,8 +729,8 @@ func (opts CreateOptsWithCustomField) ToServerCreateMap() (map[string]any, error // HandleServerNoNetworkCreationSuccessfully sets up the test server with no // network to respond to a server creation request with a given response. -func HandleServerNoNetworkCreationSuccessfully(t *testing.T, response string) { - th.Mux.HandleFunc("/servers", func(w http.ResponseWriter, r *http.Request) { +func HandleServerNoNetworkCreationSuccessfully(t *testing.T, fakeServer th.FakeServer, response string) { + fakeServer.Mux.HandleFunc("/servers", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, `{ @@ -750,8 +750,8 @@ func HandleServerNoNetworkCreationSuccessfully(t *testing.T, response string) { // HandleServerCreationSuccessfully sets up the test server to respond to a server creation request // with a given response. -func HandleServerCreationSuccessfully(t *testing.T, response string) { - th.Mux.HandleFunc("/servers", func(w http.ResponseWriter, r *http.Request) { +func HandleServerCreationSuccessfully(t *testing.T, fakeServer th.FakeServer, response string) { + fakeServer.Mux.HandleFunc("/servers", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, `{ @@ -767,7 +767,7 @@ func HandleServerCreationSuccessfully(t *testing.T, response string) { fmt.Fprint(w, response) }) - th.Mux.HandleFunc("/images/detail", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/images/detail", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -813,7 +813,7 @@ func HandleServerCreationSuccessfully(t *testing.T, response string) { } }) - th.Mux.HandleFunc("/flavors/detail", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/flavors/detail", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -851,7 +851,7 @@ func HandleServerCreationSuccessfully(t *testing.T, response string) { } ] } - `, th.Server.URL) + `, fakeServer.Server.URL) case "2": fmt.Fprint(w, `{ "flavors": [] }`) default: @@ -862,8 +862,8 @@ func HandleServerCreationSuccessfully(t *testing.T, response string) { // HandleServerCreationWithCustomFieldSuccessfully sets up the test server to respond to a server creation request // with a given response. -func HandleServersCreationSuccessfully(t *testing.T, response string) { - th.Mux.HandleFunc("/servers", func(w http.ResponseWriter, r *http.Request) { +func HandleServersCreationSuccessfully(t *testing.T, fakeServer th.FakeServer, response string) { + fakeServer.Mux.HandleFunc("/servers", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, `{ @@ -884,8 +884,8 @@ func HandleServersCreationSuccessfully(t *testing.T, response string) { // HandleServerCreationWithCustomFieldSuccessfully sets up the test server to respond to a server creation request // with a given response. -func HandleServerCreationWithCustomFieldSuccessfully(t *testing.T, response string) { - th.Mux.HandleFunc("/servers", func(w http.ResponseWriter, r *http.Request) { +func HandleServerCreationWithCustomFieldSuccessfully(t *testing.T, fakeServer th.FakeServer, response string) { + fakeServer.Mux.HandleFunc("/servers", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, `{ @@ -903,8 +903,8 @@ func HandleServerCreationWithCustomFieldSuccessfully(t *testing.T, response stri }) } -func HandleServerCreationWithHostname(t *testing.T, response string) { - th.Mux.HandleFunc("/servers", func(w http.ResponseWriter, r *http.Request) { +func HandleServerCreationWithHostname(t *testing.T, fakeServer th.FakeServer, response string) { + fakeServer.Mux.HandleFunc("/servers", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, `{ @@ -924,8 +924,8 @@ func HandleServerCreationWithHostname(t *testing.T, response string) { // HandleServerCreationWithUserdata sets up the test server to respond to a server creation request // with a given response. -func HandleServerCreationWithUserdata(t *testing.T, response string) { - th.Mux.HandleFunc("/servers", func(w http.ResponseWriter, r *http.Request) { +func HandleServerCreationWithUserdata(t *testing.T, fakeServer th.FakeServer, response string) { + fakeServer.Mux.HandleFunc("/servers", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, `{ @@ -945,8 +945,8 @@ func HandleServerCreationWithUserdata(t *testing.T, response string) { // HandleServerCreationWithMetadata sets up the test server to respond to a server creation request // with a given response. -func HandleServerCreationWithMetadata(t *testing.T, response string) { - th.Mux.HandleFunc("/servers", func(w http.ResponseWriter, r *http.Request) { +func HandleServerCreationWithMetadata(t *testing.T, fakeServer th.FakeServer, response string) { + fakeServer.Mux.HandleFunc("/servers", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, `{ @@ -967,8 +967,8 @@ func HandleServerCreationWithMetadata(t *testing.T, response string) { } // HandleServerListSimpleSuccessfully sets up the test server to respond to a server List request. -func HandleServerListSimpleSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/servers", func(w http.ResponseWriter, r *http.Request) { +func HandleServerListSimpleSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/servers", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -989,8 +989,8 @@ func HandleServerListSimpleSuccessfully(t *testing.T) { } // HandleServerListSuccessfully sets up the test server to respond to a server detail List request. -func HandleServerListSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/servers/detail", func(w http.ResponseWriter, r *http.Request) { +func HandleServerListSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/servers/detail", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -1011,8 +1011,8 @@ func HandleServerListSuccessfully(t *testing.T) { } // HandleServerDeletionSuccessfully sets up the test server to respond to a server deletion request. -func HandleServerDeletionSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/servers/asdfasdfasdf", func(w http.ResponseWriter, r *http.Request) { +func HandleServerDeletionSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/servers/asdfasdfasdf", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -1022,8 +1022,8 @@ func HandleServerDeletionSuccessfully(t *testing.T) { // HandleServerForceDeletionSuccessfully sets up the test server to respond to a server force deletion // request. -func HandleServerForceDeletionSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/servers/asdfasdfasdf/action", func(w http.ResponseWriter, r *http.Request) { +func HandleServerForceDeletionSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/servers/asdfasdfasdf/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, `{ "forceDelete": "" }`) @@ -1033,8 +1033,8 @@ func HandleServerForceDeletionSuccessfully(t *testing.T) { } // HandleServerGetSuccessfully sets up the test server to respond to a server Get request. -func HandleServerGetSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/servers/1234asdf", func(w http.ResponseWriter, r *http.Request) { +func HandleServerGetSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/servers/1234asdf", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -1045,8 +1045,8 @@ func HandleServerGetSuccessfully(t *testing.T) { // HandleServerGetFaultSuccessfully sets up the test server to respond to a server Get // request which contains a fault. -func HandleServerGetFaultSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/servers/1234asdf", func(w http.ResponseWriter, r *http.Request) { +func HandleServerGetFaultSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/servers/1234asdf", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -1056,8 +1056,8 @@ func HandleServerGetFaultSuccessfully(t *testing.T) { } // HandleServerUpdateSuccessfully sets up the test server to respond to a server Update request. -func HandleServerUpdateSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/servers/1234asdf", func(w http.ResponseWriter, r *http.Request) { +func HandleServerUpdateSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/servers/1234asdf", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -1070,8 +1070,8 @@ func HandleServerUpdateSuccessfully(t *testing.T) { // HandleAdminPasswordChangeSuccessfully sets up the test server to respond to a server password // change request. -func HandleAdminPasswordChangeSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/servers/1234asdf/action", func(w http.ResponseWriter, r *http.Request) { +func HandleAdminPasswordChangeSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/servers/1234asdf/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, `{ "changePassword": { "adminPass": "new-password" } }`) @@ -1081,8 +1081,8 @@ func HandleAdminPasswordChangeSuccessfully(t *testing.T) { } // HandleRebootSuccessfully sets up the test server to respond to a reboot request with success. -func HandleRebootSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/servers/1234asdf/action", func(w http.ResponseWriter, r *http.Request) { +func HandleRebootSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/servers/1234asdf/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, `{ "reboot": { "type": "SOFT" } }`) @@ -1092,8 +1092,8 @@ func HandleRebootSuccessfully(t *testing.T) { } // HandleShowConsoleOutputSuccessfully sets up the test server to respond to a os-getConsoleOutput request with success. -func HandleShowConsoleOutputSuccessfully(t *testing.T, response string) { - th.Mux.HandleFunc("/servers/1234asdf/action", func(w http.ResponseWriter, r *http.Request) { +func HandleShowConsoleOutputSuccessfully(t *testing.T, fakeServer th.FakeServer, response string) { + fakeServer.Mux.HandleFunc("/servers/1234asdf/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, `{ "os-getConsoleOutput": { "length": 50 } }`) @@ -1105,8 +1105,8 @@ func HandleShowConsoleOutputSuccessfully(t *testing.T, response string) { } // HandleRebuildSuccessfully sets up the test server to respond to a rebuild request with success. -func HandleRebuildSuccessfully(t *testing.T, response string) { - th.Mux.HandleFunc("/servers/1234asdf/action", func(w http.ResponseWriter, r *http.Request) { +func HandleRebuildSuccessfully(t *testing.T, fakeServer th.FakeServer, response string) { + fakeServer.Mux.HandleFunc("/servers/1234asdf/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, ` @@ -1127,8 +1127,8 @@ func HandleRebuildSuccessfully(t *testing.T, response string) { } // HandleMetadatumGetSuccessfully sets up the test server to respond to a metadatum Get request. -func HandleMetadatumGetSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/servers/1234asdf/metadata/foo", func(w http.ResponseWriter, r *http.Request) { +func HandleMetadatumGetSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/servers/1234asdf/metadata/foo", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -1141,8 +1141,8 @@ func HandleMetadatumGetSuccessfully(t *testing.T) { } // HandleMetadatumCreateSuccessfully sets up the test server to respond to a metadatum Create request. -func HandleMetadatumCreateSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/servers/1234asdf/metadata/foo", func(w http.ResponseWriter, r *http.Request) { +func HandleMetadatumCreateSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/servers/1234asdf/metadata/foo", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, `{ @@ -1159,8 +1159,8 @@ func HandleMetadatumCreateSuccessfully(t *testing.T) { } // HandleMetadatumDeleteSuccessfully sets up the test server to respond to a metadatum Delete request. -func HandleMetadatumDeleteSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/servers/1234asdf/metadata/foo", func(w http.ResponseWriter, r *http.Request) { +func HandleMetadatumDeleteSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/servers/1234asdf/metadata/foo", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -1169,8 +1169,8 @@ func HandleMetadatumDeleteSuccessfully(t *testing.T) { } // HandleMetadataGetSuccessfully sets up the test server to respond to a metadata Get request. -func HandleMetadataGetSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/servers/1234asdf/metadata", func(w http.ResponseWriter, r *http.Request) { +func HandleMetadataGetSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/servers/1234asdf/metadata", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -1182,8 +1182,8 @@ func HandleMetadataGetSuccessfully(t *testing.T) { } // HandleMetadataResetSuccessfully sets up the test server to respond to a metadata Create request. -func HandleMetadataResetSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/servers/1234asdf/metadata", func(w http.ResponseWriter, r *http.Request) { +func HandleMetadataResetSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/servers/1234asdf/metadata", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, `{ @@ -1201,8 +1201,8 @@ func HandleMetadataResetSuccessfully(t *testing.T) { } // HandleMetadataUpdateSuccessfully sets up the test server to respond to a metadata Update request. -func HandleMetadataUpdateSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/servers/1234asdf/metadata", func(w http.ResponseWriter, r *http.Request) { +func HandleMetadataUpdateSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/servers/1234asdf/metadata", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, `{ @@ -1240,8 +1240,8 @@ var ListAddressesExpected = map[string][]servers.Address{ } // HandleAddressListSuccessfully sets up the test server to respond to a ListAddresses request. -func HandleAddressListSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/servers/asdfasdfasdf/ips", func(w http.ResponseWriter, r *http.Request) { +func HandleAddressListSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/servers/asdfasdfasdf/ips", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -1282,8 +1282,8 @@ var ListNetworkAddressesExpected = []servers.Address{ } // HandleNetworkAddressListSuccessfully sets up the test server to respond to a ListAddressesByNetwork request. -func HandleNetworkAddressListSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/servers/asdfasdfasdf/ips/public", func(w http.ResponseWriter, r *http.Request) { +func HandleNetworkAddressListSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/servers/asdfasdfasdf/ips/public", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -1304,8 +1304,8 @@ func HandleNetworkAddressListSuccessfully(t *testing.T) { } // HandleCreateServerImageSuccessfully sets up the test server to respond to a TestCreateServerImage request. -func HandleCreateServerImageSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/servers/serverimage/action", func(w http.ResponseWriter, r *http.Request) { +func HandleCreateServerImageSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/servers/serverimage/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Location", "https://0.0.0.0/images/xxxx-xxxxx-xxxxx-xxxx") @@ -1314,8 +1314,8 @@ func HandleCreateServerImageSuccessfully(t *testing.T) { } // HandlePasswordGetSuccessfully sets up the test server to respond to a password Get request. -func HandlePasswordGetSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/servers/1234asdf/os-server-password", func(w http.ResponseWriter, r *http.Request) { +func HandlePasswordGetSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/servers/1234asdf/os-server-password", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -1326,8 +1326,8 @@ func HandlePasswordGetSuccessfully(t *testing.T) { // HandleServerWithTagsCreationSuccessfully sets up the test server to respond // to a server creation request with a given response. -func HandleServerWithTagsCreationSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/servers", func(w http.ResponseWriter, r *http.Request) { +func HandleServerWithTagsCreationSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/servers", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, ServerWithTagsCreateRequest) diff --git a/openstack/compute/v2/servers/testing/requests_test.go b/openstack/compute/v2/servers/testing/requests_test.go index 66a33dd688..a82e6821a6 100644 --- a/openstack/compute/v2/servers/testing/requests_test.go +++ b/openstack/compute/v2/servers/testing/requests_test.go @@ -14,12 +14,12 @@ import ( ) func TestListServers(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleServerListSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleServerListSuccessfully(t, fakeServer) pages := 0 - err := servers.List(client.ServiceClient(), servers.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := servers.List(client.ServiceClient(fakeServer), servers.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := servers.ExtractServers(page) @@ -45,11 +45,11 @@ func TestListServers(t *testing.T) { } func TestListAllServers(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleServerListSimpleSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleServerListSimpleSuccessfully(t, fakeServer) - allPages, err := servers.ListSimple(client.ServiceClient(), servers.ListOpts{}).AllPages(context.TODO()) + allPages, err := servers.ListSimple(client.ServiceClient(fakeServer), servers.ListOpts{}).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := servers.ExtractServers(allPages) th.AssertNoErr(t, err) @@ -58,11 +58,11 @@ func TestListAllServers(t *testing.T) { } func TestListAllServersWithExtensions(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleServerListSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleServerListSuccessfully(t, fakeServer) - allPages, err := servers.List(client.ServiceClient(), servers.ListOpts{}).AllPages(context.TODO()) + allPages, err := servers.List(client.ServiceClient(fakeServer), servers.ListOpts{}).AllPages(context.TODO()) th.AssertNoErr(t, err) var actual []servers.Server @@ -77,11 +77,11 @@ func TestListAllServersWithExtensions(t *testing.T) { } func TestCreateServer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleServerCreationSuccessfully(t, SingleServerBody) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleServerCreationSuccessfully(t, fakeServer, SingleServerBody) - actual, err := servers.Create(context.TODO(), client.ServiceClient(), servers.CreateOpts{ + actual, err := servers.Create(context.TODO(), client.ServiceClient(fakeServer), servers.CreateOpts{ Name: "derp", ImageRef: "f90f6034-2570-4974-8351-6b49732ef2eb", FlavorRef: "1", @@ -92,11 +92,11 @@ func TestCreateServer(t *testing.T) { } func TestCreateServerNoNetwork(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleServerNoNetworkCreationSuccessfully(t, SingleServerBody) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleServerNoNetworkCreationSuccessfully(t, fakeServer, SingleServerBody) - actual, err := servers.Create(context.TODO(), client.ServiceClient(), servers.CreateOpts{ + actual, err := servers.Create(context.TODO(), client.ServiceClient(fakeServer), servers.CreateOpts{ Name: "derp", ImageRef: "f90f6034-2570-4974-8351-6b49732ef2eb", FlavorRef: "1", @@ -108,11 +108,11 @@ func TestCreateServerNoNetwork(t *testing.T) { } func TestCreateServers(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleServersCreationSuccessfully(t, SingleServerBody) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleServersCreationSuccessfully(t, fakeServer, SingleServerBody) - actual, err := servers.Create(context.TODO(), client.ServiceClient(), servers.CreateOpts{ + actual, err := servers.Create(context.TODO(), client.ServiceClient(fakeServer), servers.CreateOpts{ Name: "derp", ImageRef: "f90f6034-2570-4974-8351-6b49732ef2eb", FlavorRef: "1", @@ -125,11 +125,11 @@ func TestCreateServers(t *testing.T) { } func TestCreateServerWithCustomField(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleServerCreationWithCustomFieldSuccessfully(t, SingleServerBody) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleServerCreationWithCustomFieldSuccessfully(t, fakeServer, SingleServerBody) - actual, err := servers.Create(context.TODO(), client.ServiceClient(), CreateOptsWithCustomField{ + actual, err := servers.Create(context.TODO(), client.ServiceClient(fakeServer), CreateOptsWithCustomField{ CreateOpts: servers.CreateOpts{ Name: "derp", ImageRef: "f90f6034-2570-4974-8351-6b49732ef2eb", @@ -143,11 +143,11 @@ func TestCreateServerWithCustomField(t *testing.T) { } func TestCreateServerWithMetadata(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleServerCreationWithMetadata(t, SingleServerBody) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleServerCreationWithMetadata(t, fakeServer, SingleServerBody) - actual, err := servers.Create(context.TODO(), client.ServiceClient(), servers.CreateOpts{ + actual, err := servers.Create(context.TODO(), client.ServiceClient(fakeServer), servers.CreateOpts{ Name: "derp", ImageRef: "f90f6034-2570-4974-8351-6b49732ef2eb", FlavorRef: "1", @@ -161,11 +161,11 @@ func TestCreateServerWithMetadata(t *testing.T) { } func TestCreateServerWithUserdataString(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleServerCreationWithUserdata(t, SingleServerBody) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleServerCreationWithUserdata(t, fakeServer, SingleServerBody) - actual, err := servers.Create(context.TODO(), client.ServiceClient(), servers.CreateOpts{ + actual, err := servers.Create(context.TODO(), client.ServiceClient(fakeServer), servers.CreateOpts{ Name: "derp", ImageRef: "f90f6034-2570-4974-8351-6b49732ef2eb", FlavorRef: "1", @@ -177,13 +177,13 @@ func TestCreateServerWithUserdataString(t *testing.T) { } func TestCreateServerWithUserdataEncoded(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleServerCreationWithUserdata(t, SingleServerBody) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleServerCreationWithUserdata(t, fakeServer, SingleServerBody) encoded := base64.StdEncoding.EncodeToString([]byte("userdata string")) - actual, err := servers.Create(context.TODO(), client.ServiceClient(), servers.CreateOpts{ + actual, err := servers.Create(context.TODO(), client.ServiceClient(fakeServer), servers.CreateOpts{ Name: "derp", ImageRef: "f90f6034-2570-4974-8351-6b49732ef2eb", FlavorRef: "1", @@ -195,11 +195,11 @@ func TestCreateServerWithUserdataEncoded(t *testing.T) { } func TestCreateServerWithHostname(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleServerCreationWithHostname(t, SingleServerBody) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleServerCreationWithHostname(t, fakeServer, SingleServerBody) - actual, err := servers.Create(context.TODO(), client.ServiceClient(), servers.CreateOpts{ + actual, err := servers.Create(context.TODO(), client.ServiceClient(fakeServer), servers.CreateOpts{ Name: "derp", ImageRef: "f90f6034-2570-4974-8351-6b49732ef2eb", FlavorRef: "1", @@ -730,29 +730,29 @@ func TestCreateComplexSchedulerHints(t *testing.T) { } func TestDeleteServer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleServerDeletionSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleServerDeletionSuccessfully(t, fakeServer) - res := servers.Delete(context.TODO(), client.ServiceClient(), "asdfasdfasdf") + res := servers.Delete(context.TODO(), client.ServiceClient(fakeServer), "asdfasdfasdf") th.AssertNoErr(t, res.Err) } func TestForceDeleteServer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleServerForceDeletionSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleServerForceDeletionSuccessfully(t, fakeServer) - res := servers.ForceDelete(context.TODO(), client.ServiceClient(), "asdfasdfasdf") + res := servers.ForceDelete(context.TODO(), client.ServiceClient(fakeServer), "asdfasdfasdf") th.AssertNoErr(t, res.Err) } func TestGetServer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleServerGetSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleServerGetSuccessfully(t, fakeServer) - client := client.ServiceClient() + client := client.ServiceClient(fakeServer) actual, err := servers.Get(context.TODO(), client, "1234asdf").Extract() if err != nil { t.Fatalf("Unexpected Get error: %v", err) @@ -762,11 +762,11 @@ func TestGetServer(t *testing.T) { } func TestGetFaultyServer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleServerGetFaultSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleServerGetFaultSuccessfully(t, fakeServer) - client := client.ServiceClient() + client := client.ServiceClient(fakeServer) actual, err := servers.Get(context.TODO(), client, "1234asdf").Extract() if err != nil { t.Fatalf("Unexpected Get error: %v", err) @@ -779,15 +779,15 @@ func TestGetFaultyServer(t *testing.T) { } func TestGetServerWithExtensions(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleServerGetSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleServerGetSuccessfully(t, fakeServer) var s struct { servers.Server } - client := client.ServiceClient() + client := client.ServiceClient(fakeServer) err := servers.Get(context.TODO(), client, "1234asdf").ExtractInto(&s) th.AssertNoErr(t, err) th.AssertEquals(t, "nova", s.AvailabilityZone) @@ -803,11 +803,11 @@ func TestGetServerWithExtensions(t *testing.T) { } func TestUpdateServer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleServerUpdateSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleServerUpdateSuccessfully(t, fakeServer) - client := client.ServiceClient() + client := client.ServiceClient(fakeServer) actual, err := servers.Update(context.TODO(), client, "1234asdf", servers.UpdateOpts{Name: "new-name"}).Extract() if err != nil { t.Fatalf("Unexpected Update error: %v", err) @@ -817,52 +817,52 @@ func TestUpdateServer(t *testing.T) { } func TestChangeServerAdminPassword(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleAdminPasswordChangeSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleAdminPasswordChangeSuccessfully(t, fakeServer) - res := servers.ChangeAdminPassword(context.TODO(), client.ServiceClient(), "1234asdf", "new-password") + res := servers.ChangeAdminPassword(context.TODO(), client.ServiceClient(fakeServer), "1234asdf", "new-password") th.AssertNoErr(t, res.Err) } func TestShowConsoleOutput(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleShowConsoleOutputSuccessfully(t, ConsoleOutputBody) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleShowConsoleOutputSuccessfully(t, fakeServer, ConsoleOutputBody) outputOpts := &servers.ShowConsoleOutputOpts{ Length: 50, } - actual, err := servers.ShowConsoleOutput(context.TODO(), client.ServiceClient(), "1234asdf", outputOpts).Extract() + actual, err := servers.ShowConsoleOutput(context.TODO(), client.ServiceClient(fakeServer), "1234asdf", outputOpts).Extract() th.AssertNoErr(t, err) th.AssertByteArrayEquals(t, []byte(ConsoleOutput), []byte(actual)) } func TestGetPassword(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandlePasswordGetSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandlePasswordGetSuccessfully(t, fakeServer) - res := servers.GetPassword(context.TODO(), client.ServiceClient(), "1234asdf") + res := servers.GetPassword(context.TODO(), client.ServiceClient(fakeServer), "1234asdf") th.AssertNoErr(t, res.Err) } func TestRebootServer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleRebootSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleRebootSuccessfully(t, fakeServer) - res := servers.Reboot(context.TODO(), client.ServiceClient(), "1234asdf", servers.RebootOpts{ + res := servers.Reboot(context.TODO(), client.ServiceClient(fakeServer), "1234asdf", servers.RebootOpts{ Type: servers.SoftReboot, }) th.AssertNoErr(t, res.Err) } func TestRebuildServer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleRebuildSuccessfully(t, SingleServerBody) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleRebuildSuccessfully(t, fakeServer, SingleServerBody) opts := servers.RebuildOpts{ Name: "new-name", @@ -871,7 +871,7 @@ func TestRebuildServer(t *testing.T) { AccessIPv4: "1.2.3.4", } - actual, err := servers.Rebuild(context.TODO(), client.ServiceClient(), "1234asdf", opts).Extract() + actual, err := servers.Rebuild(context.TODO(), client.ServiceClient(fakeServer), "1234asdf", opts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, ServerDerp, *actual) @@ -901,10 +901,10 @@ func TestRebuildServerWithDiskConfig(t *testing.T) { } func TestResizeServer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/servers/1234asdf/action", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/servers/1234asdf/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, `{ "resize": { "flavorRef": "2" } }`) @@ -912,7 +912,7 @@ func TestResizeServer(t *testing.T) { w.WriteHeader(http.StatusAccepted) }) - res := servers.Resize(context.TODO(), client.ServiceClient(), "1234asdf", servers.ResizeOpts{FlavorRef: "2"}) + res := servers.Resize(context.TODO(), client.ServiceClient(fakeServer), "1234asdf", servers.ResizeOpts{FlavorRef: "2"}) th.AssertNoErr(t, res.Err) } @@ -936,10 +936,10 @@ func TestResizeServerWithDiskConfig(t *testing.T) { } func TestConfirmResize(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/servers/1234asdf/action", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/servers/1234asdf/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, `{ "confirmResize": null }`) @@ -947,15 +947,15 @@ func TestConfirmResize(t *testing.T) { w.WriteHeader(http.StatusNoContent) }) - res := servers.ConfirmResize(context.TODO(), client.ServiceClient(), "1234asdf") + res := servers.ConfirmResize(context.TODO(), client.ServiceClient(fakeServer), "1234asdf") th.AssertNoErr(t, res.Err) } func TestRevertResize(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/servers/1234asdf/action", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/servers/1234asdf/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, `{ "revertResize": null }`) @@ -963,64 +963,64 @@ func TestRevertResize(t *testing.T) { w.WriteHeader(http.StatusAccepted) }) - res := servers.RevertResize(context.TODO(), client.ServiceClient(), "1234asdf") + res := servers.RevertResize(context.TODO(), client.ServiceClient(fakeServer), "1234asdf") th.AssertNoErr(t, res.Err) } func TestGetMetadatum(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleMetadatumGetSuccessfully(t) + HandleMetadatumGetSuccessfully(t, fakeServer) expected := map[string]string{"foo": "bar"} - actual, err := servers.Metadatum(context.TODO(), client.ServiceClient(), "1234asdf", "foo").Extract() + actual, err := servers.Metadatum(context.TODO(), client.ServiceClient(fakeServer), "1234asdf", "foo").Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, expected, actual) } func TestCreateMetadatum(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleMetadatumCreateSuccessfully(t) + HandleMetadatumCreateSuccessfully(t, fakeServer) expected := map[string]string{"foo": "bar"} - actual, err := servers.CreateMetadatum(context.TODO(), client.ServiceClient(), "1234asdf", servers.MetadatumOpts{"foo": "bar"}).Extract() + actual, err := servers.CreateMetadatum(context.TODO(), client.ServiceClient(fakeServer), "1234asdf", servers.MetadatumOpts{"foo": "bar"}).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, expected, actual) } func TestDeleteMetadatum(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleMetadatumDeleteSuccessfully(t) + HandleMetadatumDeleteSuccessfully(t, fakeServer) - err := servers.DeleteMetadatum(context.TODO(), client.ServiceClient(), "1234asdf", "foo").ExtractErr() + err := servers.DeleteMetadatum(context.TODO(), client.ServiceClient(fakeServer), "1234asdf", "foo").ExtractErr() th.AssertNoErr(t, err) } func TestGetMetadata(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleMetadataGetSuccessfully(t) + HandleMetadataGetSuccessfully(t, fakeServer) expected := map[string]string{"foo": "bar", "this": "that"} - actual, err := servers.Metadata(context.TODO(), client.ServiceClient(), "1234asdf").Extract() + actual, err := servers.Metadata(context.TODO(), client.ServiceClient(fakeServer), "1234asdf").Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, expected, actual) } func TestResetMetadata(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleMetadataResetSuccessfully(t) + HandleMetadataResetSuccessfully(t, fakeServer) expected := map[string]string{"foo": "bar", "this": "that"} - actual, err := servers.ResetMetadata(context.TODO(), client.ServiceClient(), "1234asdf", servers.MetadataOpts{ + actual, err := servers.ResetMetadata(context.TODO(), client.ServiceClient(fakeServer), "1234asdf", servers.MetadataOpts{ "foo": "bar", "this": "that", }).Extract() @@ -1029,13 +1029,13 @@ func TestResetMetadata(t *testing.T) { } func TestUpdateMetadata(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleMetadataUpdateSuccessfully(t) + HandleMetadataUpdateSuccessfully(t, fakeServer) expected := map[string]string{"foo": "baz", "this": "those"} - actual, err := servers.UpdateMetadata(context.TODO(), client.ServiceClient(), "1234asdf", servers.MetadataOpts{ + actual, err := servers.UpdateMetadata(context.TODO(), client.ServiceClient(fakeServer), "1234asdf", servers.MetadataOpts{ "foo": "baz", "this": "those", }).Extract() @@ -1044,13 +1044,13 @@ func TestUpdateMetadata(t *testing.T) { } func TestListAddresses(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleAddressListSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleAddressListSuccessfully(t, fakeServer) expected := ListAddressesExpected pages := 0 - err := servers.ListAddresses(client.ServiceClient(), "asdfasdfasdf").EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := servers.ListAddresses(client.ServiceClient(fakeServer), "asdfasdfasdf").EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := servers.ExtractAddresses(page) @@ -1068,13 +1068,13 @@ func TestListAddresses(t *testing.T) { } func TestListAddressesByNetwork(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleNetworkAddressListSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleNetworkAddressListSuccessfully(t, fakeServer) expected := ListNetworkAddressesExpected pages := 0 - err := servers.ListAddressesByNetwork(client.ServiceClient(), "asdfasdfasdf", "public").EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := servers.ListAddressesByNetwork(client.ServiceClient(fakeServer), "asdfasdfasdf", "public").EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := servers.ExtractNetworkAddresses(page) @@ -1092,11 +1092,11 @@ func TestListAddressesByNetwork(t *testing.T) { } func TestCreateServerImage(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateServerImageSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCreateServerImageSuccessfully(t, fakeServer) - _, err := servers.CreateImage(context.TODO(), client.ServiceClient(), "serverimage", servers.CreateImageOpts{Name: "test"}).ExtractImageID() + _, err := servers.CreateImage(context.TODO(), client.ServiceClient(fakeServer), "serverimage", servers.CreateImageOpts{Name: "test"}).ExtractImageID() th.AssertNoErr(t, err) } @@ -1136,11 +1136,11 @@ func TestMarshalPersonality(t *testing.T) { } func TestCreateServerWithTags(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleServerWithTagsCreationSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleServerWithTagsCreationSuccessfully(t, fakeServer) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) c.Microversion = "2.52" tags := []string{"foo", "bar"} diff --git a/openstack/compute/v2/servers/testing/results_test.go b/openstack/compute/v2/servers/testing/results_test.go index eb751341fa..ba58d63e0c 100644 --- a/openstack/compute/v2/servers/testing/results_test.go +++ b/openstack/compute/v2/servers/testing/results_test.go @@ -102,11 +102,11 @@ KSde3I0ybDz7iS2EtceKB7m4C0slYd+oBkm4efuF00rCOKDwpFq45m0= } func TestListAddressesAllPages(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleAddressListSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleAddressListSuccessfully(t, fakeServer) - allPages, err := servers.ListAddresses(client.ServiceClient(), "asdfasdfasdf").AllPages(context.TODO()) + allPages, err := servers.ListAddresses(client.ServiceClient(fakeServer), "asdfasdfasdf").AllPages(context.TODO()) th.AssertNoErr(t, err) _, err = servers.ExtractAddresses(allPages) th.AssertNoErr(t, err) diff --git a/openstack/compute/v2/services/testing/fixtures_test.go b/openstack/compute/v2/services/testing/fixtures_test.go index 93b124df90..47e549e1b3 100644 --- a/openstack/compute/v2/services/testing/fixtures_test.go +++ b/openstack/compute/v2/services/testing/fixtures_test.go @@ -253,8 +253,8 @@ var FakeServiceUpdateBody = services.Service{ // HandleListPre253Successfully configures the test server to respond to a List // request to a Compute server API pre 2.53 microversion release. -func HandleListPre253Successfully(t *testing.T) { - th.Mux.HandleFunc("/os-services", func(w http.ResponseWriter, r *http.Request) { +func HandleListPre253Successfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/os-services", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -265,8 +265,8 @@ func HandleListPre253Successfully(t *testing.T) { // HandleListSuccessfully configures the test server to respond to a List // request to a Compute server with Pike+ release. -func HandleListSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/os-services", func(w http.ResponseWriter, r *http.Request) { +func HandleListSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/os-services", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -277,8 +277,8 @@ func HandleListSuccessfully(t *testing.T) { // HandleUpdateSuccessfully configures the test server to respond to a Update // request to a Compute server with Pike+ release. -func HandleUpdateSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/os-services/fake-service-id", func(w http.ResponseWriter, r *http.Request) { +func HandleUpdateSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/os-services/fake-service-id", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -291,8 +291,8 @@ func HandleUpdateSuccessfully(t *testing.T) { // HandleDeleteSuccessfully configures the test server to respond to a Delete // request to a Compute server with Pike+ release. -func HandleDeleteSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/os-services/fake-service-id", func(w http.ResponseWriter, r *http.Request) { +func HandleDeleteSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/os-services/fake-service-id", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) diff --git a/openstack/compute/v2/services/testing/requests_test.go b/openstack/compute/v2/services/testing/requests_test.go index df7a9e9a17..3fac76abfe 100644 --- a/openstack/compute/v2/services/testing/requests_test.go +++ b/openstack/compute/v2/services/testing/requests_test.go @@ -11,12 +11,12 @@ import ( ) func TestListServicesPre253(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListPre253Successfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListPre253Successfully(t, fakeServer) pages := 0 - err := services.List(client.ServiceClient(), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := services.List(client.ServiceClient(fakeServer), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := services.ExtractServices(page) @@ -43,16 +43,16 @@ func TestListServicesPre253(t *testing.T) { } func TestListServices(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListSuccessfully(t, fakeServer) pages := 0 opts := services.ListOpts{ Binary: "fake-binary", Host: "host123", } - err := services.List(client.ServiceClient(), opts).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := services.List(client.ServiceClient(fakeServer), opts).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := services.ExtractServices(page) @@ -79,11 +79,11 @@ func TestListServices(t *testing.T) { } func TestUpdateService(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleUpdateSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleUpdateSuccessfully(t, fakeServer) - client := client.ServiceClient() + client := client.ServiceClient(fakeServer) actual, err := services.Update(context.TODO(), client, "fake-service-id", services.UpdateOpts{Status: services.ServiceDisabled}).Extract() if err != nil { t.Fatalf("Unexpected Update error: %v", err) @@ -93,11 +93,11 @@ func TestUpdateService(t *testing.T) { } func TestDeleteService(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDeleteSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDeleteSuccessfully(t, fakeServer) - client := client.ServiceClient() + client := client.ServiceClient(fakeServer) res := services.Delete(context.TODO(), client, "fake-service-id") th.AssertNoErr(t, res.Err) diff --git a/openstack/compute/v2/tags/testing/requests_test.go b/openstack/compute/v2/tags/testing/requests_test.go index dc524a2306..fa93b49485 100644 --- a/openstack/compute/v2/tags/testing/requests_test.go +++ b/openstack/compute/v2/tags/testing/requests_test.go @@ -12,10 +12,10 @@ import ( ) func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/servers/uuid1/tags", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/servers/uuid1/tags", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, http.MethodGet) th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -27,17 +27,17 @@ func TestList(t *testing.T) { }) expected := []string{"foo", "bar", "baz"} - actual, err := tags.List(context.TODO(), client.ServiceClient(), "uuid1").Extract() + actual, err := tags.List(context.TODO(), client.ServiceClient(fakeServer), "uuid1").Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, expected, actual) } func TestCheckOk(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/servers/uuid1/tags/foo", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/servers/uuid1/tags/foo", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, http.MethodGet) th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -45,16 +45,16 @@ func TestCheckOk(t *testing.T) { w.WriteHeader(http.StatusNoContent) }) - exists, err := tags.Check(context.TODO(), client.ServiceClient(), "uuid1", "foo").Extract() + exists, err := tags.Check(context.TODO(), client.ServiceClient(fakeServer), "uuid1", "foo").Extract() th.AssertNoErr(t, err) th.AssertEquals(t, true, exists) } func TestCheckFail(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/servers/uuid1/tags/bar", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/servers/uuid1/tags/bar", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, http.MethodGet) th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -62,16 +62,16 @@ func TestCheckFail(t *testing.T) { w.WriteHeader(http.StatusNotFound) }) - exists, err := tags.Check(context.TODO(), client.ServiceClient(), "uuid1", "bar").Extract() + exists, err := tags.Check(context.TODO(), client.ServiceClient(fakeServer), "uuid1", "bar").Extract() th.AssertNoErr(t, err) th.AssertEquals(t, false, exists) } func TestReplaceAll(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/servers/uuid1/tags", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/servers/uuid1/tags", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, http.MethodPut) th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -83,17 +83,17 @@ func TestReplaceAll(t *testing.T) { }) expected := []string{"tag1", "tag2", "tag3"} - actual, err := tags.ReplaceAll(context.TODO(), client.ServiceClient(), "uuid1", tags.ReplaceAllOpts{Tags: []string{"tag1", "tag2", "tag3"}}).Extract() + actual, err := tags.ReplaceAll(context.TODO(), client.ServiceClient(fakeServer), "uuid1", tags.ReplaceAllOpts{Tags: []string{"tag1", "tag2", "tag3"}}).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, expected, actual) } func TestAddCreated(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/servers/uuid1/tags/foo", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/servers/uuid1/tags/foo", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, http.MethodPut) th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -101,15 +101,15 @@ func TestAddCreated(t *testing.T) { w.WriteHeader(http.StatusCreated) }) - err := tags.Add(context.TODO(), client.ServiceClient(), "uuid1", "foo").ExtractErr() + err := tags.Add(context.TODO(), client.ServiceClient(fakeServer), "uuid1", "foo").ExtractErr() th.AssertNoErr(t, err) } func TestAddExists(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/servers/uuid1/tags/foo", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/servers/uuid1/tags/foo", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, http.MethodPut) th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -117,15 +117,15 @@ func TestAddExists(t *testing.T) { w.WriteHeader(http.StatusNoContent) }) - err := tags.Add(context.TODO(), client.ServiceClient(), "uuid1", "foo").ExtractErr() + err := tags.Add(context.TODO(), client.ServiceClient(fakeServer), "uuid1", "foo").ExtractErr() th.AssertNoErr(t, err) } func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/servers/uuid1/tags/foo", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/servers/uuid1/tags/foo", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, http.MethodDelete) th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -133,15 +133,15 @@ func TestDelete(t *testing.T) { w.WriteHeader(http.StatusNoContent) }) - err := tags.Delete(context.TODO(), client.ServiceClient(), "uuid1", "foo").ExtractErr() + err := tags.Delete(context.TODO(), client.ServiceClient(fakeServer), "uuid1", "foo").ExtractErr() th.AssertNoErr(t, err) } func TestDeleteAll(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/servers/uuid1/tags", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/servers/uuid1/tags", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, http.MethodDelete) th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -149,6 +149,6 @@ func TestDeleteAll(t *testing.T) { w.WriteHeader(http.StatusNoContent) }) - err := tags.DeleteAll(context.TODO(), client.ServiceClient(), "uuid1").ExtractErr() + err := tags.DeleteAll(context.TODO(), client.ServiceClient(fakeServer), "uuid1").ExtractErr() th.AssertNoErr(t, err) } diff --git a/openstack/compute/v2/usage/testing/fixtures_test.go b/openstack/compute/v2/usage/testing/fixtures_test.go index f5b92ca095..1922a0ddab 100644 --- a/openstack/compute/v2/usage/testing/fixtures_test.go +++ b/openstack/compute/v2/usage/testing/fixtures_test.go @@ -74,8 +74,8 @@ const GetSingleTenant = `{ // HandleGetSingleTenantSuccessfully configures the test server to respond to a // Get request for a single tenant -func HandleGetSingleTenantSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/os-simple-tenant-usage/"+FirstTenantID, func(w http.ResponseWriter, r *http.Request) { +func HandleGetSingleTenantSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/os-simple-tenant-usage/"+FirstTenantID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") @@ -224,8 +224,8 @@ const GetAllTenants = `{ // HandleGetAllTenantsSuccessfully configures the test server to respond to a // Get request for all tenants. -func HandleGetAllTenantsSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/os-simple-tenant-usage", func(w http.ResponseWriter, r *http.Request) { +func HandleGetAllTenantsSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/os-simple-tenant-usage", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") diff --git a/openstack/compute/v2/usage/testing/requests_test.go b/openstack/compute/v2/usage/testing/requests_test.go index 163ab1082d..eb1692266f 100644 --- a/openstack/compute/v2/usage/testing/requests_test.go +++ b/openstack/compute/v2/usage/testing/requests_test.go @@ -11,12 +11,12 @@ import ( ) func TestGetTenant(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetSingleTenantSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetSingleTenantSuccessfully(t, fakeServer) count := 0 - err := usage.SingleTenant(client.ServiceClient(), FirstTenantID, nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := usage.SingleTenant(client.ServiceClient(fakeServer), FirstTenantID, nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := usage.ExtractSingleTenant(page) @@ -30,16 +30,16 @@ func TestGetTenant(t *testing.T) { } func TestAllTenants(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetAllTenantsSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetAllTenantsSuccessfully(t, fakeServer) getOpts := usage.AllTenantsOpts{ Detailed: true, } count := 0 - err := usage.AllTenants(client.ServiceClient(), getOpts).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := usage.AllTenants(client.ServiceClient(fakeServer), getOpts).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := usage.ExtractAllTenants(page) diff --git a/openstack/compute/v2/volumeattach/testing/fixtures_test.go b/openstack/compute/v2/volumeattach/testing/fixtures_test.go index d9ada1e8c1..f1450719b1 100644 --- a/openstack/compute/v2/volumeattach/testing/fixtures_test.go +++ b/openstack/compute/v2/volumeattach/testing/fixtures_test.go @@ -56,8 +56,8 @@ const CreateOutput = ` ` // HandleListSuccessfully configures the test server to respond to a List request. -func HandleListSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/servers/4d8c3732-a248-40ed-bebc-539a6ffd25c0/os-volume_attachments", func(w http.ResponseWriter, r *http.Request) { +func HandleListSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/servers/4d8c3732-a248-40ed-bebc-539a6ffd25c0/os-volume_attachments", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -68,8 +68,8 @@ func HandleListSuccessfully(t *testing.T) { // HandleGetSuccessfully configures the test server to respond to a Get request // for an existing attachment -func HandleGetSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/servers/4d8c3732-a248-40ed-bebc-539a6ffd25c0/os-volume_attachments/a26887c6-c47b-4654-abb5-dfadf7d3f804", func(w http.ResponseWriter, r *http.Request) { +func HandleGetSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/servers/4d8c3732-a248-40ed-bebc-539a6ffd25c0/os-volume_attachments/a26887c6-c47b-4654-abb5-dfadf7d3f804", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -80,8 +80,8 @@ func HandleGetSuccessfully(t *testing.T) { // HandleCreateSuccessfully configures the test server to respond to a Create request // for a new attachment -func HandleCreateSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/servers/4d8c3732-a248-40ed-bebc-539a6ffd25c0/os-volume_attachments", func(w http.ResponseWriter, r *http.Request) { +func HandleCreateSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/servers/4d8c3732-a248-40ed-bebc-539a6ffd25c0/os-volume_attachments", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, ` @@ -102,8 +102,8 @@ func HandleCreateSuccessfully(t *testing.T) { // HandleDeleteSuccessfully configures the test server to respond to a Delete request for a // an existing attachment -func HandleDeleteSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/servers/4d8c3732-a248-40ed-bebc-539a6ffd25c0/os-volume_attachments/a26887c6-c47b-4654-abb5-dfadf7d3f804", func(w http.ResponseWriter, r *http.Request) { +func HandleDeleteSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/servers/4d8c3732-a248-40ed-bebc-539a6ffd25c0/os-volume_attachments/a26887c6-c47b-4654-abb5-dfadf7d3f804", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/compute/v2/volumeattach/testing/requests_test.go b/openstack/compute/v2/volumeattach/testing/requests_test.go index 92da356cb1..21f323a353 100644 --- a/openstack/compute/v2/volumeattach/testing/requests_test.go +++ b/openstack/compute/v2/volumeattach/testing/requests_test.go @@ -44,15 +44,15 @@ var CreatedVolumeAttachment = volumeattach.VolumeAttachment{ } func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleListSuccessfully(t) + HandleListSuccessfully(t, fakeServer) serverID := "4d8c3732-a248-40ed-bebc-539a6ffd25c0" count := 0 - err := volumeattach.List(client.ServiceClient(), serverID).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := volumeattach.List(client.ServiceClient(fakeServer), serverID).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := volumeattach.ExtractVolumeAttachments(page) th.AssertNoErr(t, err) @@ -65,14 +65,14 @@ func TestList(t *testing.T) { } func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleCreateSuccessfully(t) + HandleCreateSuccessfully(t, fakeServer) serverID := "4d8c3732-a248-40ed-bebc-539a6ffd25c0" - actual, err := volumeattach.Create(context.TODO(), client.ServiceClient(), serverID, volumeattach.CreateOpts{ + actual, err := volumeattach.Create(context.TODO(), client.ServiceClient(fakeServer), serverID, volumeattach.CreateOpts{ Device: "/dev/vdc", VolumeID: "a26887c6-c47b-4654-abb5-dfadf7d3f804", Tag: iTag, @@ -83,28 +83,28 @@ func TestCreate(t *testing.T) { } func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleGetSuccessfully(t) + HandleGetSuccessfully(t, fakeServer) aID := "a26887c6-c47b-4654-abb5-dfadf7d3f804" serverID := "4d8c3732-a248-40ed-bebc-539a6ffd25c0" - actual, err := volumeattach.Get(context.TODO(), client.ServiceClient(), serverID, aID).Extract() + actual, err := volumeattach.Get(context.TODO(), client.ServiceClient(fakeServer), serverID, aID).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, &SecondVolumeAttachment, actual) } func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleDeleteSuccessfully(t) + HandleDeleteSuccessfully(t, fakeServer) aID := "a26887c6-c47b-4654-abb5-dfadf7d3f804" serverID := "4d8c3732-a248-40ed-bebc-539a6ffd25c0" - err := volumeattach.Delete(context.TODO(), client.ServiceClient(), serverID, aID).ExtractErr() + err := volumeattach.Delete(context.TODO(), client.ServiceClient(fakeServer), serverID, aID).ExtractErr() th.AssertNoErr(t, err) } diff --git a/openstack/container/v1/capsules/testing/fixtures_test.go b/openstack/container/v1/capsules/testing/fixtures_test.go index 9ce111382e..e21b852569 100644 --- a/openstack/container/v1/capsules/testing/fixtures_test.go +++ b/openstack/container/v1/capsules/testing/fixtures_test.go @@ -622,8 +622,8 @@ func GetFakeCapsuleV132() capsules.CapsuleV132 { } // HandleCapsuleGetOldTimeSuccessfully test setup -func HandleCapsuleGetOldTimeSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/capsules/cc654059-1a77-47a3-bfcf-715bde5aad9e", func(w http.ResponseWriter, r *http.Request) { +func HandleCapsuleGetOldTimeSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/capsules/cc654059-1a77-47a3-bfcf-715bde5aad9e", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -634,8 +634,8 @@ func HandleCapsuleGetOldTimeSuccessfully(t *testing.T) { } // HandleCapsuleGetNewTimeSuccessfully test setup -func HandleCapsuleGetNewTimeSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/capsules/cc654059-1a77-47a3-bfcf-715bde5aad9e", func(w http.ResponseWriter, r *http.Request) { +func HandleCapsuleGetNewTimeSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/capsules/cc654059-1a77-47a3-bfcf-715bde5aad9e", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -647,8 +647,8 @@ func HandleCapsuleGetNewTimeSuccessfully(t *testing.T) { // HandleCapsuleCreateSuccessfully creates an HTTP handler at `/capsules` on the test handler mux // that responds with a `Create` response. -func HandleCapsuleCreateSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/capsules", func(w http.ResponseWriter, r *http.Request) { +func HandleCapsuleCreateSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/capsules", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -658,8 +658,8 @@ func HandleCapsuleCreateSuccessfully(t *testing.T) { } // HandleCapsuleListSuccessfully test setup -func HandleCapsuleListSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/capsules/", func(w http.ResponseWriter, r *http.Request) { +func HandleCapsuleListSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/capsules/", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -670,8 +670,8 @@ func HandleCapsuleListSuccessfully(t *testing.T) { } // HandleCapsuleV132ListSuccessfully test setup -func HandleCapsuleV132ListSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/capsules/", func(w http.ResponseWriter, r *http.Request) { +func HandleCapsuleV132ListSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/capsules/", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -681,8 +681,8 @@ func HandleCapsuleV132ListSuccessfully(t *testing.T) { }) } -func HandleCapsuleDeleteSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/capsules/963a239d-3946-452b-be5a-055eab65a421", func(w http.ResponseWriter, r *http.Request) { +func HandleCapsuleDeleteSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/capsules/963a239d-3946-452b-be5a-055eab65a421", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) diff --git a/openstack/container/v1/capsules/testing/requests_test.go b/openstack/container/v1/capsules/testing/requests_test.go index c789ac44f4..20d0850886 100644 --- a/openstack/container/v1/capsules/testing/requests_test.go +++ b/openstack/container/v1/capsules/testing/requests_test.go @@ -13,10 +13,10 @@ import ( ) func TestGetCapsule_OldTime(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleCapsuleGetOldTimeSuccessfully(t) + HandleCapsuleGetOldTimeSuccessfully(t, fakeServer) createdAt, _ := time.Parse(gophercloud.RFC3339ZNoT, "2018-01-12 09:37:25+00:00") updatedAt, _ := time.Parse(gophercloud.RFC3339ZNoT, "2018-01-12 09:37:26+00:00") @@ -29,30 +29,30 @@ func TestGetCapsule_OldTime(t *testing.T) { ec.Containers[0].UpdatedAt = updatedAt ec.Containers[0].StartedAt = startedAt - actualCapsule, err := capsules.Get(context.TODO(), client.ServiceClient(), ec.UUID).Extract() + actualCapsule, err := capsules.Get(context.TODO(), client.ServiceClient(fakeServer), ec.UUID).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, &ec, actualCapsule) } func TestGetCapsule_NewTime(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleCapsuleGetNewTimeSuccessfully(t) + HandleCapsuleGetNewTimeSuccessfully(t, fakeServer) ec := GetFakeCapsule() - actualCapsule, err := capsules.Get(context.TODO(), client.ServiceClient(), ec.UUID).Extract() + actualCapsule, err := capsules.Get(context.TODO(), client.ServiceClient(fakeServer), ec.UUID).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, &ec, actualCapsule) } func TestCreateCapsule(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCapsuleCreateSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCapsuleCreateSuccessfully(t, fakeServer) ec := GetFakeCapsule() @@ -61,17 +61,17 @@ func TestCreateCapsule(t *testing.T) { createOpts := capsules.CreateOpts{ TemplateOpts: template, } - actualCapsule, err := capsules.Create(context.TODO(), client.ServiceClient(), createOpts).Extract() + actualCapsule, err := capsules.Create(context.TODO(), client.ServiceClient(fakeServer), createOpts).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, &ec, actualCapsule) } func TestListCapsule(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleCapsuleListSuccessfully(t) + HandleCapsuleListSuccessfully(t, fakeServer) createdAt, _ := time.Parse(gophercloud.RFC3339ZNoT, "2018-01-12 09:37:25+00:00") updatedAt, _ := time.Parse(gophercloud.RFC3339ZNoT, "2018-01-12 09:37:25+01:00") @@ -84,7 +84,7 @@ func TestListCapsule(t *testing.T) { expected := []capsules.Capsule{ec} count := 0 - results := capsules.List(client.ServiceClient(), nil) + results := capsules.List(client.ServiceClient(fakeServer), nil) err := results.EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := capsules.ExtractCapsules(page) @@ -105,10 +105,10 @@ func TestListCapsule(t *testing.T) { } func TestListCapsuleV132(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleCapsuleV132ListSuccessfully(t) + HandleCapsuleV132ListSuccessfully(t, fakeServer) createdAt, _ := time.Parse(gophercloud.RFC3339ZNoTNoZ, "2018-01-12 09:37:25") updatedAt, _ := time.Parse(gophercloud.RFC3339ZNoTNoZ, "2018-01-12 09:37:25") @@ -121,7 +121,7 @@ func TestListCapsuleV132(t *testing.T) { expected := []capsules.CapsuleV132{ec} count := 0 - results := capsules.List(client.ServiceClient(), nil) + results := capsules.List(client.ServiceClient(fakeServer), nil) err := results.EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := capsules.ExtractCapsules(page) @@ -142,11 +142,11 @@ func TestListCapsuleV132(t *testing.T) { } func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleCapsuleDeleteSuccessfully(t) + HandleCapsuleDeleteSuccessfully(t, fakeServer) - res := capsules.Delete(context.TODO(), client.ServiceClient(), "963a239d-3946-452b-be5a-055eab65a421") + res := capsules.Delete(context.TODO(), client.ServiceClient(fakeServer), "963a239d-3946-452b-be5a-055eab65a421") th.AssertNoErr(t, res.Err) } diff --git a/openstack/containerinfra/apiversions/testing/fixtures_test.go b/openstack/containerinfra/apiversions/testing/fixtures_test.go index f42844214c..dd9711a6c0 100644 --- a/openstack/containerinfra/apiversions/testing/fixtures_test.go +++ b/openstack/containerinfra/apiversions/testing/fixtures_test.go @@ -63,8 +63,8 @@ var MagnumAllAPIVersionResults = []apiversions.APIVersion{ MagnumAPIVersion1Result, } -func MockListResponse(t *testing.T) { - th.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { +func MockListResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -75,8 +75,8 @@ func MockListResponse(t *testing.T) { }) } -func MockGetResponse(t *testing.T) { - th.Mux.HandleFunc("/v1/", func(w http.ResponseWriter, r *http.Request) { +func MockGetResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v1/", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/containerinfra/apiversions/testing/requests_test.go b/openstack/containerinfra/apiversions/testing/requests_test.go index 175be19c74..a2a478243c 100644 --- a/openstack/containerinfra/apiversions/testing/requests_test.go +++ b/openstack/containerinfra/apiversions/testing/requests_test.go @@ -11,12 +11,12 @@ import ( ) func TestListAPIVersions(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockListResponse(t) + MockListResponse(t, fakeServer) - allVersions, err := apiversions.List(client.ServiceClient()).AllPages(context.TODO()) + allVersions, err := apiversions.List(client.ServiceClient(fakeServer)).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := apiversions.ExtractAPIVersions(allVersions) @@ -26,12 +26,12 @@ func TestListAPIVersions(t *testing.T) { } func TestGetAPIVersion(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockGetResponse(t) + MockGetResponse(t, fakeServer) - actual, err := apiversions.Get(context.TODO(), client.ServiceClient(), "v1").Extract() + actual, err := apiversions.Get(context.TODO(), client.ServiceClient(fakeServer), "v1").Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, MagnumAPIVersion1Result, *actual) diff --git a/openstack/containerinfra/v1/certificates/testing/fixtures_test.go b/openstack/containerinfra/v1/certificates/testing/fixtures_test.go index c62eb618af..67381f5787 100644 --- a/openstack/containerinfra/v1/certificates/testing/fixtures_test.go +++ b/openstack/containerinfra/v1/certificates/testing/fixtures_test.go @@ -67,8 +67,8 @@ var ExpectedCreateCertificateResponse = certificates.Certificate{ }, } -func HandleGetCertificateSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v1/certificates/d564b18a-2890-4152-be3d-e05d784ff72", func(w http.ResponseWriter, r *http.Request) { +func HandleGetCertificateSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v1/certificates/d564b18a-2890-4152-be3d-e05d784ff72", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -83,8 +83,8 @@ func HandleGetCertificateSuccessfully(t *testing.T) { }) } -func HandleCreateCertificateSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v1/certificates/", func(w http.ResponseWriter, r *http.Request) { +func HandleCreateCertificateSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v1/certificates/", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -99,8 +99,8 @@ func HandleCreateCertificateSuccessfully(t *testing.T) { }) } -func HandleUpdateCertificateSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v1/certificates/d564b18a-2890-4152-be3d-e05d784ff72", +func HandleUpdateCertificateSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v1/certificates/d564b18a-2890-4152-be3d-e05d784ff72", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PATCH") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/containerinfra/v1/certificates/testing/requests_test.go b/openstack/containerinfra/v1/certificates/testing/requests_test.go index 0d08c2647c..3725c86360 100644 --- a/openstack/containerinfra/v1/certificates/testing/requests_test.go +++ b/openstack/containerinfra/v1/certificates/testing/requests_test.go @@ -10,12 +10,12 @@ import ( ) func TestGetCertificates(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleGetCertificateSuccessfully(t) + HandleGetCertificateSuccessfully(t, fakeServer) - sc := client.ServiceClient() + sc := client.ServiceClient(fakeServer) sc.Endpoint = sc.Endpoint + "v1/" actual, err := certificates.Get(context.TODO(), sc, "d564b18a-2890-4152-be3d-e05d784ff72").Extract() @@ -24,12 +24,12 @@ func TestGetCertificates(t *testing.T) { } func TestCreateCertificates(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleCreateCertificateSuccessfully(t) + HandleCreateCertificateSuccessfully(t, fakeServer) - sc := client.ServiceClient() + sc := client.ServiceClient(fakeServer) sc.Endpoint = sc.Endpoint + "v1/" opts := certificates.CreateOpts{ @@ -43,12 +43,12 @@ func TestCreateCertificates(t *testing.T) { } func TestUpdateCertificates(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleUpdateCertificateSuccessfully(t) + HandleUpdateCertificateSuccessfully(t, fakeServer) - sc := client.ServiceClient() + sc := client.ServiceClient(fakeServer) sc.Endpoint = sc.Endpoint + "v1/" err := certificates.Update(context.TODO(), sc, "d564b18a-2890-4152-be3d-e05d784ff72").ExtractErr() diff --git a/openstack/containerinfra/v1/clusters/testing/fixtures_test.go b/openstack/containerinfra/v1/clusters/testing/fixtures_test.go index 64c557225d..bf0a77c911 100644 --- a/openstack/containerinfra/v1/clusters/testing/fixtures_test.go +++ b/openstack/containerinfra/v1/clusters/testing/fixtures_test.go @@ -95,8 +95,8 @@ var ExpectedCluster2 = clusters.Cluster{ var ExpectedClusterUUID = clusterUUID -func HandleCreateClusterSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v1/clusters", func(w http.ResponseWriter, r *http.Request) { +func HandleCreateClusterSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v1/clusters", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -108,8 +108,8 @@ func HandleCreateClusterSuccessfully(t *testing.T) { }) } -func HandleGetClusterSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v1/clusters/"+clusterUUID, func(w http.ResponseWriter, r *http.Request) { +func HandleGetClusterSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v1/clusters/"+clusterUUID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -247,8 +247,8 @@ var ClusterListResponse = fmt.Sprintf(` var ExpectedClusters = []clusters.Cluster{ExpectedCluster} -func HandleListClusterSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v1/clusters", func(w http.ResponseWriter, r *http.Request) { +func HandleListClusterSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v1/clusters", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -260,8 +260,8 @@ func HandleListClusterSuccessfully(t *testing.T) { }) } -func HandleListDetailClusterSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v1/clusters/detail", func(w http.ResponseWriter, r *http.Request) { +func HandleListDetailClusterSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v1/clusters/detail", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -278,8 +278,8 @@ var UpdateResponse = fmt.Sprintf(` "uuid":"%s" }`, clusterUUID) -func HandleUpdateClusterSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v1/clusters/"+clusterUUID, func(w http.ResponseWriter, r *http.Request) { +func HandleUpdateClusterSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v1/clusters/"+clusterUUID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PATCH") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -296,8 +296,8 @@ var UpgradeResponse = fmt.Sprintf(` "uuid":"%s" }`, clusterUUID) -func HandleUpgradeClusterSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v1/clusters/"+clusterUUID+"/actions/upgrade", func(w http.ResponseWriter, r *http.Request) { +func HandleUpgradeClusterSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v1/clusters/"+clusterUUID+"/actions/upgrade", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -309,8 +309,8 @@ func HandleUpgradeClusterSuccessfully(t *testing.T) { }) } -func HandleDeleteClusterSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v1/clusters/"+clusterUUID, func(w http.ResponseWriter, r *http.Request) { +func HandleDeleteClusterSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v1/clusters/"+clusterUUID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -325,8 +325,8 @@ var ResizeResponse = fmt.Sprintf(` "uuid": "%s" }`, clusterUUID) -func HandleResizeClusterSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v1/clusters/"+clusterUUID+"/actions/resize", func(w http.ResponseWriter, r *http.Request) { +func HandleResizeClusterSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v1/clusters/"+clusterUUID+"/actions/resize", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/containerinfra/v1/clusters/testing/requests_test.go b/openstack/containerinfra/v1/clusters/testing/requests_test.go index 6d1358e645..44a8a353d8 100644 --- a/openstack/containerinfra/v1/clusters/testing/requests_test.go +++ b/openstack/containerinfra/v1/clusters/testing/requests_test.go @@ -12,10 +12,10 @@ import ( ) func TestCreateCluster(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleCreateClusterSuccessfully(t) + HandleCreateClusterSuccessfully(t, fakeServer) masterCount := 1 nodeCount := 1 @@ -39,7 +39,7 @@ func TestCreateCluster(t *testing.T) { MergeLabels: gophercloud.Enabled, } - sc := client.ServiceClient() + sc := client.ServiceClient(fakeServer) sc.Endpoint = sc.Endpoint + "v1/" res := clusters.Create(context.TODO(), sc, opts) th.AssertNoErr(t, res.Err) @@ -54,12 +54,12 @@ func TestCreateCluster(t *testing.T) { } func TestGetCluster(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleGetClusterSuccessfully(t) + HandleGetClusterSuccessfully(t, fakeServer) - sc := client.ServiceClient() + sc := client.ServiceClient(fakeServer) sc.Endpoint = sc.Endpoint + "v1/" actual, err := clusters.Get(context.TODO(), sc, "746e779a-751a-456b-a3e9-c883d734946f").Extract() th.AssertNoErr(t, err) @@ -69,13 +69,13 @@ func TestGetCluster(t *testing.T) { } func TestListClusters(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleListClusterSuccessfully(t) + HandleListClusterSuccessfully(t, fakeServer) count := 0 - sc := client.ServiceClient() + sc := client.ServiceClient(fakeServer) sc.Endpoint = sc.Endpoint + "v1/" err := clusters.List(sc, clusters.ListOpts{Limit: 2}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ @@ -97,13 +97,13 @@ func TestListClusters(t *testing.T) { } func TestListDetailClusters(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleListDetailClusterSuccessfully(t) + HandleListDetailClusterSuccessfully(t, fakeServer) count := 0 - sc := client.ServiceClient() + sc := client.ServiceClient(fakeServer) sc.Endpoint = sc.Endpoint + "v1/" err := clusters.ListDetail(sc, clusters.ListOpts{Limit: 2}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ @@ -125,10 +125,10 @@ func TestListDetailClusters(t *testing.T) { } func TestUpdateCluster(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleUpdateClusterSuccessfully(t) + HandleUpdateClusterSuccessfully(t, fakeServer) updateOpts := []clusters.UpdateOptsBuilder{ clusters.UpdateOpts{ @@ -143,7 +143,7 @@ func TestUpdateCluster(t *testing.T) { }, } - sc := client.ServiceClient() + sc := client.ServiceClient(fakeServer) sc.Endpoint = sc.Endpoint + "v1/" res := clusters.Update(context.TODO(), sc, clusterUUID, updateOpts) th.AssertNoErr(t, res.Err) @@ -158,16 +158,16 @@ func TestUpdateCluster(t *testing.T) { } func TestUpgradeCluster(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleUpgradeClusterSuccessfully(t) + HandleUpgradeClusterSuccessfully(t, fakeServer) opts := clusters.UpgradeOpts{ ClusterTemplate: "0562d357-8641-4759-8fed-8173f02c9633", } - sc := client.ServiceClient() + sc := client.ServiceClient(fakeServer) sc.Endpoint = sc.Endpoint + "v1/" res := clusters.Upgrade(context.TODO(), sc, clusterUUID, opts) th.AssertNoErr(t, res.Err) @@ -182,12 +182,12 @@ func TestUpgradeCluster(t *testing.T) { } func TestDeleteCluster(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleDeleteClusterSuccessfully(t) + HandleDeleteClusterSuccessfully(t, fakeServer) - sc := client.ServiceClient() + sc := client.ServiceClient(fakeServer) sc.Endpoint = sc.Endpoint + "v1/" r := clusters.Delete(context.TODO(), sc, clusterUUID) err := r.ExtractErr() @@ -208,10 +208,10 @@ func TestDeleteCluster(t *testing.T) { } func TestResizeCluster(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleResizeClusterSuccessfully(t) + HandleResizeClusterSuccessfully(t, fakeServer) nodeCount := 2 @@ -219,7 +219,7 @@ func TestResizeCluster(t *testing.T) { NodeCount: &nodeCount, } - sc := client.ServiceClient() + sc := client.ServiceClient(fakeServer) sc.Endpoint = sc.Endpoint + "v1/" res := clusters.Resize(context.TODO(), sc, clusterUUID, opts) th.AssertNoErr(t, res.Err) diff --git a/openstack/containerinfra/v1/clustertemplates/testing/fixtures_test.go b/openstack/containerinfra/v1/clustertemplates/testing/fixtures_test.go index 92dfa795d2..5d47da5988 100644 --- a/openstack/containerinfra/v1/clustertemplates/testing/fixtures_test.go +++ b/openstack/containerinfra/v1/clustertemplates/testing/fixtures_test.go @@ -274,8 +274,8 @@ var ExpectedClusterTemplate_EmptyTime = clustertemplates.ClusterTemplate{ var ExpectedClusterTemplates = []clustertemplates.ClusterTemplate{ExpectedClusterTemplate, ExpectedClusterTemplate_EmptyTime} -func HandleCreateClusterTemplateSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v1/clustertemplates", func(w http.ResponseWriter, r *http.Request) { +func HandleCreateClusterTemplateSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v1/clustertemplates", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, `{ @@ -312,8 +312,8 @@ func HandleCreateClusterTemplateSuccessfully(t *testing.T) { }) } -func HandleDeleteClusterSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v1/clustertemplates/6dc6d336e3fc4c0a951b5698cd1236ee", func(w http.ResponseWriter, r *http.Request) { +func HandleDeleteClusterSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v1/clustertemplates/6dc6d336e3fc4c0a951b5698cd1236ee", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -326,8 +326,8 @@ func HandleDeleteClusterSuccessfully(t *testing.T) { }) } -func HandleListClusterTemplateSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v1/clustertemplates", func(w http.ResponseWriter, r *http.Request) { +func HandleListClusterTemplateSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v1/clustertemplates", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -338,8 +338,8 @@ func HandleListClusterTemplateSuccessfully(t *testing.T) { }) } -func HandleGetClusterTemplateSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v1/clustertemplates/7d85f602-a948-4a30-afd4-e84f47471c15", func(w http.ResponseWriter, r *http.Request) { +func HandleGetClusterTemplateSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v1/clustertemplates/7d85f602-a948-4a30-afd4-e84f47471c15", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -350,8 +350,8 @@ func HandleGetClusterTemplateSuccessfully(t *testing.T) { }) } -func HandleGetClusterTemplateEmptyTimeSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v1/clustertemplates/7d85f602-a948-4a30-afd4-e84f47471c15", func(w http.ResponseWriter, r *http.Request) { +func HandleGetClusterTemplateEmptyTimeSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v1/clustertemplates/7d85f602-a948-4a30-afd4-e84f47471c15", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -527,8 +527,8 @@ var ExpectedUpdateClusterTemplate_EmptyTime = clustertemplates.ClusterTemplate{ Hidden: false, } -func HandleUpdateClusterTemplateSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v1/clustertemplates/7d85f602-a948-4a30-afd4-e84f47471c15", func(w http.ResponseWriter, r *http.Request) { +func HandleUpdateClusterTemplateSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v1/clustertemplates/7d85f602-a948-4a30-afd4-e84f47471c15", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PATCH") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -539,8 +539,8 @@ func HandleUpdateClusterTemplateSuccessfully(t *testing.T) { }) } -func HandleUpdateClusterTemplateEmptyTimeSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v1/clustertemplates/7d85f602-a948-4a30-afd4-e84f47471c15", func(w http.ResponseWriter, r *http.Request) { +func HandleUpdateClusterTemplateEmptyTimeSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v1/clustertemplates/7d85f602-a948-4a30-afd4-e84f47471c15", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PATCH") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -551,8 +551,8 @@ func HandleUpdateClusterTemplateEmptyTimeSuccessfully(t *testing.T) { }) } -func HandleUpdateClusterTemplateInvalidUpdate(t *testing.T) { - th.Mux.HandleFunc("/v1/clustertemplates/7d85f602-a948-4a30-afd4-e84f47471c15", func(w http.ResponseWriter, r *http.Request) { +func HandleUpdateClusterTemplateInvalidUpdate(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v1/clustertemplates/7d85f602-a948-4a30-afd4-e84f47471c15", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PATCH") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/containerinfra/v1/clustertemplates/testing/requests_test.go b/openstack/containerinfra/v1/clustertemplates/testing/requests_test.go index 4d4b3b154b..4e7058dc14 100644 --- a/openstack/containerinfra/v1/clustertemplates/testing/requests_test.go +++ b/openstack/containerinfra/v1/clustertemplates/testing/requests_test.go @@ -11,10 +11,10 @@ import ( ) func TestCreateClusterTemplate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleCreateClusterTemplateSuccessfully(t) + HandleCreateClusterTemplateSuccessfully(t, fakeServer) boolFalse := false boolTrue := true @@ -46,7 +46,7 @@ func TestCreateClusterTemplate(t *testing.T) { Hidden: &boolTrue, } - sc := client.ServiceClient() + sc := client.ServiceClient(fakeServer) sc.Endpoint = sc.Endpoint + "v1/" res := clustertemplates.Create(context.TODO(), sc, opts) th.AssertNoErr(t, res.Err) @@ -62,12 +62,12 @@ func TestCreateClusterTemplate(t *testing.T) { } func TestDeleteClusterTemplate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleDeleteClusterSuccessfully(t) + HandleDeleteClusterSuccessfully(t, fakeServer) - sc := client.ServiceClient() + sc := client.ServiceClient(fakeServer) sc.Endpoint = sc.Endpoint + "v1/" res := clustertemplates.Delete(context.TODO(), sc, "6dc6d336e3fc4c0a951b5698cd1236ee") th.AssertNoErr(t, res.Err) @@ -76,14 +76,14 @@ func TestDeleteClusterTemplate(t *testing.T) { } func TestListClusterTemplates(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleListClusterTemplateSuccessfully(t) + HandleListClusterTemplateSuccessfully(t, fakeServer) count := 0 - sc := client.ServiceClient() + sc := client.ServiceClient(fakeServer) sc.Endpoint = sc.Endpoint + "v1/" err := clustertemplates.List(sc, clustertemplates.ListOpts{Limit: 2}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ @@ -104,12 +104,12 @@ func TestListClusterTemplates(t *testing.T) { } func TestGetClusterTemplate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleGetClusterTemplateSuccessfully(t) + HandleGetClusterTemplateSuccessfully(t, fakeServer) - sc := client.ServiceClient() + sc := client.ServiceClient(fakeServer) sc.Endpoint = sc.Endpoint + "v1/" actual, err := clustertemplates.Get(context.TODO(), sc, "7d85f602-a948-4a30-afd4-e84f47471c15").Extract() th.AssertNoErr(t, err) @@ -118,12 +118,12 @@ func TestGetClusterTemplate(t *testing.T) { } func TestGetClusterTemplateEmptyTime(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleGetClusterTemplateEmptyTimeSuccessfully(t) + HandleGetClusterTemplateEmptyTimeSuccessfully(t, fakeServer) - sc := client.ServiceClient() + sc := client.ServiceClient(fakeServer) sc.Endpoint = sc.Endpoint + "v1/" actual, err := clustertemplates.Get(context.TODO(), sc, "7d85f602-a948-4a30-afd4-e84f47471c15").Extract() th.AssertNoErr(t, err) @@ -132,10 +132,10 @@ func TestGetClusterTemplateEmptyTime(t *testing.T) { } func TestUpdateClusterTemplate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleUpdateClusterTemplateSuccessfully(t) + HandleUpdateClusterTemplateSuccessfully(t, fakeServer) updateOpts := []clustertemplates.UpdateOptsBuilder{ clustertemplates.UpdateOpts{ @@ -150,7 +150,7 @@ func TestUpdateClusterTemplate(t *testing.T) { }, } - sc := client.ServiceClient() + sc := client.ServiceClient(fakeServer) sc.Endpoint = sc.Endpoint + "v1/" res := clustertemplates.Update(context.TODO(), sc, "7d85f602-a948-4a30-afd4-e84f47471c15", updateOpts) th.AssertNoErr(t, res.Err) @@ -162,10 +162,10 @@ func TestUpdateClusterTemplate(t *testing.T) { } func TestUpdateClusterTemplateEmptyTime(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleUpdateClusterTemplateEmptyTimeSuccessfully(t) + HandleUpdateClusterTemplateEmptyTimeSuccessfully(t, fakeServer) updateOpts := []clustertemplates.UpdateOptsBuilder{ clustertemplates.UpdateOpts{ @@ -180,7 +180,7 @@ func TestUpdateClusterTemplateEmptyTime(t *testing.T) { }, } - sc := client.ServiceClient() + sc := client.ServiceClient(fakeServer) sc.Endpoint = sc.Endpoint + "v1/" actual, err := clustertemplates.Update(context.TODO(), sc, "7d85f602-a948-4a30-afd4-e84f47471c15", updateOpts).Extract() th.AssertNoErr(t, err) @@ -188,10 +188,10 @@ func TestUpdateClusterTemplateEmptyTime(t *testing.T) { } func TestUpdateClusterTemplateInvalidUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleUpdateClusterTemplateInvalidUpdate(t) + HandleUpdateClusterTemplateInvalidUpdate(t, fakeServer) updateOpts := []clustertemplates.UpdateOptsBuilder{ clustertemplates.UpdateOpts{ @@ -208,7 +208,7 @@ func TestUpdateClusterTemplateInvalidUpdate(t *testing.T) { }, } - sc := client.ServiceClient() + sc := client.ServiceClient(fakeServer) sc.Endpoint = sc.Endpoint + "v1/" _, err := clustertemplates.Update(context.TODO(), sc, "7d85f602-a948-4a30-afd4-e84f47471c15", updateOpts).Extract() th.AssertEquals(t, true, err != nil) diff --git a/openstack/containerinfra/v1/nodegroups/testing/fixtures_test.go b/openstack/containerinfra/v1/nodegroups/testing/fixtures_test.go index 650db54c40..95b9505c4d 100644 --- a/openstack/containerinfra/v1/nodegroups/testing/fixtures_test.go +++ b/openstack/containerinfra/v1/nodegroups/testing/fixtures_test.go @@ -125,8 +125,8 @@ var expectedUpdatedNodeGroup = nodegroups.NodeGroup{ UpdatedAt: nodeGroup2Updated, } -func handleGetNodeGroupSuccess(t *testing.T) { - th.Mux.HandleFunc("/v1/clusters/"+clusterUUID+"/nodegroups/"+nodeGroup1UUID, func(w http.ResponseWriter, r *http.Request) { +func handleGetNodeGroupSuccess(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v1/clusters/"+clusterUUID+"/nodegroups/"+nodeGroup1UUID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, http.MethodGet) th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -137,8 +137,8 @@ func handleGetNodeGroupSuccess(t *testing.T) { }) } -func handleGetNodeGroupNotFound(t *testing.T) { - th.Mux.HandleFunc("/v1/clusters/"+clusterUUID+"/nodegroups/"+badNodeGroupUUID, func(w http.ResponseWriter, r *http.Request) { +func handleGetNodeGroupNotFound(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v1/clusters/"+clusterUUID+"/nodegroups/"+badNodeGroupUUID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, http.MethodGet) th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -149,8 +149,8 @@ func handleGetNodeGroupNotFound(t *testing.T) { }) } -func handleGetNodeGroupClusterNotFound(t *testing.T) { - th.Mux.HandleFunc("/v1/clusters/"+badClusterUUID+"/nodegroups/"+badNodeGroupUUID, func(w http.ResponseWriter, r *http.Request) { +func handleGetNodeGroupClusterNotFound(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v1/clusters/"+badClusterUUID+"/nodegroups/"+badNodeGroupUUID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, http.MethodGet) th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -161,8 +161,8 @@ func handleGetNodeGroupClusterNotFound(t *testing.T) { }) } -func handleListNodeGroupsSuccess(t *testing.T) { - th.Mux.HandleFunc("/v1/clusters/"+clusterUUID+"/nodegroups", func(w http.ResponseWriter, r *http.Request) { +func handleListNodeGroupsSuccess(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v1/clusters/"+clusterUUID+"/nodegroups", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, http.MethodGet) th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -173,8 +173,8 @@ func handleListNodeGroupsSuccess(t *testing.T) { }) } -func handleListNodeGroupsLimitSuccess(t *testing.T) { - th.Mux.HandleFunc("/v1/clusters/"+clusterUUID+"/nodegroups", func(w http.ResponseWriter, r *http.Request) { +func handleListNodeGroupsLimitSuccess(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v1/clusters/"+clusterUUID+"/nodegroups", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, http.MethodGet) th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -187,12 +187,12 @@ func handleListNodeGroupsLimitSuccess(t *testing.T) { if marker, ok := r.Form["marker"]; !ok { // No marker, this is the first request. th.TestFormValues(t, r, map[string]string{"limit": "1"}) - fmt.Fprintf(w, nodeGroupListLimitResponse1, th.Endpoint()) + fmt.Fprintf(w, nodeGroupListLimitResponse1, fakeServer.Endpoint()) } else { switch marker[0] { case nodeGroup1UUID: // Marker is the UUID of the first node group, return the second. - fmt.Fprintf(w, nodeGroupListLimitResponse2, th.Endpoint()) + fmt.Fprintf(w, nodeGroupListLimitResponse2, fakeServer.Endpoint()) case nodeGroup2UUID: // Marker is the UUID of the second node group, there are no more to return. fmt.Fprint(w, nodeGroupListLimitResponse3) @@ -201,8 +201,8 @@ func handleListNodeGroupsLimitSuccess(t *testing.T) { }) } -func handleListNodeGroupsClusterNotFound(t *testing.T) { - th.Mux.HandleFunc("/v1/clusters/"+badClusterUUID+"/nodegroups", func(w http.ResponseWriter, r *http.Request) { +func handleListNodeGroupsClusterNotFound(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v1/clusters/"+badClusterUUID+"/nodegroups", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, http.MethodGet) th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -213,8 +213,8 @@ func handleListNodeGroupsClusterNotFound(t *testing.T) { }) } -func handleCreateNodeGroupSuccess(t *testing.T) { - th.Mux.HandleFunc("/v1/clusters/"+clusterUUID+"/nodegroups", func(w http.ResponseWriter, r *http.Request) { +func handleCreateNodeGroupSuccess(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v1/clusters/"+clusterUUID+"/nodegroups", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, http.MethodPost) th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -225,8 +225,8 @@ func handleCreateNodeGroupSuccess(t *testing.T) { }) } -func handleCreateNodeGroupDuplicate(t *testing.T) { - th.Mux.HandleFunc("/v1/clusters/"+clusterUUID+"/nodegroups", func(w http.ResponseWriter, r *http.Request) { +func handleCreateNodeGroupDuplicate(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v1/clusters/"+clusterUUID+"/nodegroups", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, http.MethodPost) th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -237,8 +237,8 @@ func handleCreateNodeGroupDuplicate(t *testing.T) { }) } -func handleCreateNodeGroupMaster(t *testing.T) { - th.Mux.HandleFunc("/v1/clusters/"+clusterUUID+"/nodegroups", func(w http.ResponseWriter, r *http.Request) { +func handleCreateNodeGroupMaster(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v1/clusters/"+clusterUUID+"/nodegroups", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, http.MethodPost) th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -249,8 +249,8 @@ func handleCreateNodeGroupMaster(t *testing.T) { }) } -func handleCreateNodeGroupBadSizes(t *testing.T) { - th.Mux.HandleFunc("/v1/clusters/"+clusterUUID+"/nodegroups", func(w http.ResponseWriter, r *http.Request) { +func handleCreateNodeGroupBadSizes(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v1/clusters/"+clusterUUID+"/nodegroups", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, http.MethodPost) th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -261,8 +261,8 @@ func handleCreateNodeGroupBadSizes(t *testing.T) { }) } -func handleUpdateNodeGroupSuccess(t *testing.T) { - th.Mux.HandleFunc("/v1/clusters/"+clusterUUID+"/nodegroups/"+nodeGroup2UUID, func(w http.ResponseWriter, r *http.Request) { +func handleUpdateNodeGroupSuccess(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v1/clusters/"+clusterUUID+"/nodegroups/"+nodeGroup2UUID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, http.MethodPatch) th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -273,8 +273,8 @@ func handleUpdateNodeGroupSuccess(t *testing.T) { }) } -func handleUpdateNodeGroupInternal(t *testing.T) { - th.Mux.HandleFunc("/v1/clusters/"+clusterUUID+"/nodegroups/"+nodeGroup2UUID, func(w http.ResponseWriter, r *http.Request) { +func handleUpdateNodeGroupInternal(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v1/clusters/"+clusterUUID+"/nodegroups/"+nodeGroup2UUID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, http.MethodPatch) th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -285,8 +285,8 @@ func handleUpdateNodeGroupInternal(t *testing.T) { }) } -func handleUpdateNodeGroupBadField(t *testing.T) { - th.Mux.HandleFunc("/v1/clusters/"+clusterUUID+"/nodegroups/"+nodeGroup2UUID, func(w http.ResponseWriter, r *http.Request) { +func handleUpdateNodeGroupBadField(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v1/clusters/"+clusterUUID+"/nodegroups/"+nodeGroup2UUID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, http.MethodPatch) th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -297,8 +297,8 @@ func handleUpdateNodeGroupBadField(t *testing.T) { }) } -func handleUpdateNodeGroupBadMin(t *testing.T) { - th.Mux.HandleFunc("/v1/clusters/"+clusterUUID+"/nodegroups/"+nodeGroup2UUID, func(w http.ResponseWriter, r *http.Request) { +func handleUpdateNodeGroupBadMin(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v1/clusters/"+clusterUUID+"/nodegroups/"+nodeGroup2UUID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, http.MethodPatch) th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -309,8 +309,8 @@ func handleUpdateNodeGroupBadMin(t *testing.T) { }) } -func handleDeleteNodeGroupSuccess(t *testing.T) { - th.Mux.HandleFunc("/v1/clusters/"+clusterUUID+"/nodegroups/"+nodeGroup2UUID, func(w http.ResponseWriter, r *http.Request) { +func handleDeleteNodeGroupSuccess(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v1/clusters/"+clusterUUID+"/nodegroups/"+nodeGroup2UUID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, http.MethodDelete) th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -318,8 +318,8 @@ func handleDeleteNodeGroupSuccess(t *testing.T) { }) } -func handleDeleteNodeGroupNotFound(t *testing.T) { - th.Mux.HandleFunc("/v1/clusters/"+clusterUUID+"/nodegroups/"+badNodeGroupUUID, func(w http.ResponseWriter, r *http.Request) { +func handleDeleteNodeGroupNotFound(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v1/clusters/"+clusterUUID+"/nodegroups/"+badNodeGroupUUID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, http.MethodDelete) th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -330,8 +330,8 @@ func handleDeleteNodeGroupNotFound(t *testing.T) { }) } -func handleDeleteNodeGroupClusterNotFound(t *testing.T) { - th.Mux.HandleFunc("/v1/clusters/"+badClusterUUID+"/nodegroups/"+badNodeGroupUUID, func(w http.ResponseWriter, r *http.Request) { +func handleDeleteNodeGroupClusterNotFound(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v1/clusters/"+badClusterUUID+"/nodegroups/"+badNodeGroupUUID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, http.MethodDelete) th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -342,8 +342,8 @@ func handleDeleteNodeGroupClusterNotFound(t *testing.T) { }) } -func handleDeleteNodeGroupDefault(t *testing.T) { - th.Mux.HandleFunc("/v1/clusters/"+clusterUUID+"/nodegroups/"+nodeGroup2UUID, func(w http.ResponseWriter, r *http.Request) { +func handleDeleteNodeGroupDefault(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v1/clusters/"+clusterUUID+"/nodegroups/"+nodeGroup2UUID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, http.MethodDelete) th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/containerinfra/v1/nodegroups/testing/requests_test.go b/openstack/containerinfra/v1/nodegroups/testing/requests_test.go index 8d0f0d4b3d..0964e23b3d 100644 --- a/openstack/containerinfra/v1/nodegroups/testing/requests_test.go +++ b/openstack/containerinfra/v1/nodegroups/testing/requests_test.go @@ -13,12 +13,12 @@ import ( // TestGetNodeGroupSuccess gets a node group successfully. func TestGetNodeGroupSuccess(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - handleGetNodeGroupSuccess(t) + handleGetNodeGroupSuccess(t, fakeServer) - sc := client.ServiceClient() + sc := client.ServiceClient(fakeServer) sc.Endpoint = sc.Endpoint + "v1/" ng, err := nodegroups.Get(context.TODO(), sc, clusterUUID, nodeGroup1UUID).Extract() @@ -29,12 +29,12 @@ func TestGetNodeGroupSuccess(t *testing.T) { // TestGetNodeGroupNotFound tries to get a node group which does not exist. func TestGetNodeGroupNotFound(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - handleGetNodeGroupNotFound(t) + handleGetNodeGroupNotFound(t, fakeServer) - sc := client.ServiceClient() + sc := client.ServiceClient(fakeServer) sc.Endpoint = sc.Endpoint + "v1/" _, err := nodegroups.Get(context.TODO(), sc, clusterUUID, badNodeGroupUUID).Extract() @@ -44,12 +44,12 @@ func TestGetNodeGroupNotFound(t *testing.T) { // TestGetNodeGroupClusterNotFound tries to get a node group in // a cluster which does not exist. func TestGetNodeGroupClusterNotFound(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - handleGetNodeGroupClusterNotFound(t) + handleGetNodeGroupClusterNotFound(t, fakeServer) - sc := client.ServiceClient() + sc := client.ServiceClient(fakeServer) sc.Endpoint = sc.Endpoint + "v1/" _, err := nodegroups.Get(context.TODO(), sc, badClusterUUID, badNodeGroupUUID).Extract() @@ -58,12 +58,12 @@ func TestGetNodeGroupClusterNotFound(t *testing.T) { // TestListNodeGroupsSuccess lists the node groups of a cluster successfully. func TestListNodeGroupsSuccess(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - handleListNodeGroupsSuccess(t) + handleListNodeGroupsSuccess(t, fakeServer) - sc := client.ServiceClient() + sc := client.ServiceClient(fakeServer) sc.Endpoint = sc.Endpoint + "v1/" ngPages, err := nodegroups.List(sc, clusterUUID, nodegroups.ListOpts{}).AllPages(context.TODO()) @@ -80,12 +80,12 @@ func TestListNodeGroupsSuccess(t *testing.T) { // with each returned page limited to one node group and // also giving a URL to get the next page. func TestListNodeGroupsLimitSuccess(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - handleListNodeGroupsLimitSuccess(t) + handleListNodeGroupsLimitSuccess(t, fakeServer) - sc := client.ServiceClient() + sc := client.ServiceClient(fakeServer) sc.Endpoint = sc.Endpoint + "v1/" listOpts := nodegroups.ListOpts{Limit: 1} @@ -102,12 +102,12 @@ func TestListNodeGroupsLimitSuccess(t *testing.T) { // TestListNodeGroupsClusterNotFound tries to list node groups // of a cluster which does not exist. func TestListNodeGroupsClusterNotFound(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - handleListNodeGroupsClusterNotFound(t) + handleListNodeGroupsClusterNotFound(t, fakeServer) - sc := client.ServiceClient() + sc := client.ServiceClient(fakeServer) sc.Endpoint = sc.Endpoint + "v1/" _, err := nodegroups.List(sc, clusterUUID, nodegroups.ListOpts{}).AllPages(context.TODO()) @@ -116,12 +116,12 @@ func TestListNodeGroupsClusterNotFound(t *testing.T) { // TestCreateNodeGroupSuccess creates a node group successfully. func TestCreateNodeGroupSuccess(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - handleCreateNodeGroupSuccess(t) + handleCreateNodeGroupSuccess(t, fakeServer) - sc := client.ServiceClient() + sc := client.ServiceClient(fakeServer) sc.Endpoint = sc.Endpoint + "v1/" createOpts := nodegroups.CreateOpts{ @@ -137,12 +137,12 @@ func TestCreateNodeGroupSuccess(t *testing.T) { // TestCreateNodeGroupDuplicate creates a node group with // the same name as an existing one. func TestCreateNodeGroupDuplicate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - handleCreateNodeGroupDuplicate(t) + handleCreateNodeGroupDuplicate(t, fakeServer) - sc := client.ServiceClient() + sc := client.ServiceClient(fakeServer) sc.Endpoint = sc.Endpoint + "v1/" createOpts := nodegroups.CreateOpts{ @@ -156,12 +156,12 @@ func TestCreateNodeGroupDuplicate(t *testing.T) { // TestCreateNodeGroupMaster creates a node group with // role=master which is not allowed. func TestCreateNodeGroupMaster(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - handleCreateNodeGroupMaster(t) + handleCreateNodeGroupMaster(t, fakeServer) - sc := client.ServiceClient() + sc := client.ServiceClient(fakeServer) sc.Endpoint = sc.Endpoint + "v1/" createOpts := nodegroups.CreateOpts{ @@ -176,12 +176,12 @@ func TestCreateNodeGroupMaster(t *testing.T) { // TestCreateNodeGroupBadSizes creates a node group with // min_nodes greater than max_nodes. func TestCreateNodeGroupBadSizes(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - handleCreateNodeGroupBadSizes(t) + handleCreateNodeGroupBadSizes(t, fakeServer) - sc := client.ServiceClient() + sc := client.ServiceClient(fakeServer) sc.Endpoint = sc.Endpoint + "v1/" maxNodes := 3 @@ -197,12 +197,12 @@ func TestCreateNodeGroupBadSizes(t *testing.T) { // TestUpdateNodeGroupSuccess updates a node group successfully. func TestUpdateNodeGroupSuccess(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - handleUpdateNodeGroupSuccess(t) + handleUpdateNodeGroupSuccess(t, fakeServer) - sc := client.ServiceClient() + sc := client.ServiceClient(fakeServer) sc.Endpoint = sc.Endpoint + "v1/" updateOpts := []nodegroups.UpdateOptsBuilder{ @@ -221,12 +221,12 @@ func TestUpdateNodeGroupSuccess(t *testing.T) { // TestUpdateNodeGroupInternal tries to update an internal // property of the node group. func TestUpdateNodeGroupInternal(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - handleUpdateNodeGroupInternal(t) + handleUpdateNodeGroupInternal(t, fakeServer) - sc := client.ServiceClient() + sc := client.ServiceClient(fakeServer) sc.Endpoint = sc.Endpoint + "v1/" updateOpts := []nodegroups.UpdateOptsBuilder{ @@ -244,12 +244,12 @@ func TestUpdateNodeGroupInternal(t *testing.T) { // TestUpdateNodeGroupBadField tries to update a // field of the node group that does not exist. func TestUpdateNodeGroupBadField(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - handleUpdateNodeGroupBadField(t) + handleUpdateNodeGroupBadField(t, fakeServer) - sc := client.ServiceClient() + sc := client.ServiceClient(fakeServer) sc.Endpoint = sc.Endpoint + "v1/" updateOpts := []nodegroups.UpdateOptsBuilder{ @@ -267,12 +267,12 @@ func TestUpdateNodeGroupBadField(t *testing.T) { // TestUpdateNodeGroupBadMin tries to set a minimum node count // greater than the current node count func TestUpdateNodeGroupBadMin(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - handleUpdateNodeGroupBadMin(t) + handleUpdateNodeGroupBadMin(t, fakeServer) - sc := client.ServiceClient() + sc := client.ServiceClient(fakeServer) sc.Endpoint = sc.Endpoint + "v1/" updateOpts := []nodegroups.UpdateOptsBuilder{ @@ -289,12 +289,12 @@ func TestUpdateNodeGroupBadMin(t *testing.T) { // TestDeleteNodeGroupSuccess deletes a node group successfully. func TestDeleteNodeGroupSuccess(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - handleDeleteNodeGroupSuccess(t) + handleDeleteNodeGroupSuccess(t, fakeServer) - sc := client.ServiceClient() + sc := client.ServiceClient(fakeServer) sc.Endpoint = sc.Endpoint + "v1/" err := nodegroups.Delete(context.TODO(), sc, clusterUUID, nodeGroup2UUID).ExtractErr() @@ -303,12 +303,12 @@ func TestDeleteNodeGroupSuccess(t *testing.T) { // TestDeleteNodeGroupNotFound tries to delete a node group that does not exist. func TestDeleteNodeGroupNotFound(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - handleDeleteNodeGroupNotFound(t) + handleDeleteNodeGroupNotFound(t, fakeServer) - sc := client.ServiceClient() + sc := client.ServiceClient(fakeServer) sc.Endpoint = sc.Endpoint + "v1/" err := nodegroups.Delete(context.TODO(), sc, clusterUUID, badNodeGroupUUID).ExtractErr() @@ -317,12 +317,12 @@ func TestDeleteNodeGroupNotFound(t *testing.T) { // TestDeleteNodeGroupClusterNotFound tries to delete a node group in a cluster that does not exist. func TestDeleteNodeGroupClusterNotFound(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - handleDeleteNodeGroupClusterNotFound(t) + handleDeleteNodeGroupClusterNotFound(t, fakeServer) - sc := client.ServiceClient() + sc := client.ServiceClient(fakeServer) sc.Endpoint = sc.Endpoint + "v1/" err := nodegroups.Delete(context.TODO(), sc, badClusterUUID, badNodeGroupUUID).ExtractErr() @@ -331,12 +331,12 @@ func TestDeleteNodeGroupClusterNotFound(t *testing.T) { // TestDeleteNodeGroupDefault tries to delete a protected default node group. func TestDeleteNodeGroupDefault(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - handleDeleteNodeGroupDefault(t) + handleDeleteNodeGroupDefault(t, fakeServer) - sc := client.ServiceClient() + sc := client.ServiceClient(fakeServer) sc.Endpoint = sc.Endpoint + "v1/" err := nodegroups.Delete(context.TODO(), sc, clusterUUID, nodeGroup2UUID).ExtractErr() diff --git a/openstack/containerinfra/v1/quotas/testing/fixtures_test.go b/openstack/containerinfra/v1/quotas/testing/fixtures_test.go index 84fc1b3f5e..f4ead5d06a 100644 --- a/openstack/containerinfra/v1/quotas/testing/fixtures_test.go +++ b/openstack/containerinfra/v1/quotas/testing/fixtures_test.go @@ -22,8 +22,8 @@ var CreateResponse = fmt.Sprintf(` "id": 26 }`, projectID) -func HandleCreateQuotaSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v1/quotas", func(w http.ResponseWriter, r *http.Request) { +func HandleCreateQuotaSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v1/quotas", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/containerinfra/v1/quotas/testing/requests_test.go b/openstack/containerinfra/v1/quotas/testing/requests_test.go index 0aa89f79e1..16d966cfa5 100644 --- a/openstack/containerinfra/v1/quotas/testing/requests_test.go +++ b/openstack/containerinfra/v1/quotas/testing/requests_test.go @@ -10,10 +10,10 @@ import ( ) func TestCreateQuota(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleCreateQuotaSuccessfully(t) + HandleCreateQuotaSuccessfully(t, fakeServer) opts := quotas.CreateOpts{ ProjectID: "aa5436ab58144c768ca4e9d2e9f5c3b2", @@ -21,7 +21,7 @@ func TestCreateQuota(t *testing.T) { HardLimit: 10, } - sc := client.ServiceClient() + sc := client.ServiceClient(fakeServer) sc.Endpoint = sc.Endpoint + "v1/" res := quotas.Create(context.TODO(), sc, opts) diff --git a/openstack/db/v1/configurations/testing/requests_test.go b/openstack/db/v1/configurations/testing/requests_test.go index a8bafcd518..11e14ebfb1 100644 --- a/openstack/db/v1/configurations/testing/requests_test.go +++ b/openstack/db/v1/configurations/testing/requests_test.go @@ -27,12 +27,12 @@ var ( ) func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - fixture.SetupHandler(t, _baseURL, "GET", "", ListConfigsJSON, 200) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + fixture.SetupHandler(t, fakeServer, _baseURL, "GET", "", ListConfigsJSON, 200) count := 0 - err := configurations.List(client.ServiceClient()).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := configurations.List(client.ServiceClient(fakeServer)).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := configurations.ExtractConfigs(page) th.AssertNoErr(t, err) @@ -48,19 +48,19 @@ func TestList(t *testing.T) { } func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - fixture.SetupHandler(t, resURL, "GET", "", GetConfigJSON, 200) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + fixture.SetupHandler(t, fakeServer, resURL, "GET", "", GetConfigJSON, 200) - config, err := configurations.Get(context.TODO(), client.ServiceClient(), configID).Extract() + config, err := configurations.Get(context.TODO(), client.ServiceClient(fakeServer), configID).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, &ExampleConfig, config) } func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - fixture.SetupHandler(t, _baseURL, "POST", CreateReq, CreateConfigJSON, 200) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + fixture.SetupHandler(t, fakeServer, _baseURL, "POST", CreateReq, CreateConfigJSON, 200) opts := configurations.CreateOpts{ Datastore: &configurations.DatastoreOpts{ @@ -75,15 +75,15 @@ func TestCreate(t *testing.T) { }, } - config, err := configurations.Create(context.TODO(), client.ServiceClient(), opts).Extract() + config, err := configurations.Create(context.TODO(), client.ServiceClient(fakeServer), opts).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, &ExampleConfigWithValues, config) } func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - fixture.SetupHandler(t, resURL, "PATCH", UpdateReq, "", 200) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + fixture.SetupHandler(t, fakeServer, resURL, "PATCH", UpdateReq, "", 200) opts := configurations.UpdateOpts{ Values: map[string]any{ @@ -91,14 +91,14 @@ func TestUpdate(t *testing.T) { }, } - err := configurations.Update(context.TODO(), client.ServiceClient(), configID, opts).ExtractErr() + err := configurations.Update(context.TODO(), client.ServiceClient(fakeServer), configID, opts).ExtractErr() th.AssertNoErr(t, err) } func TestReplace(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - fixture.SetupHandler(t, resURL, "PUT", UpdateReq, "", 202) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + fixture.SetupHandler(t, fakeServer, resURL, "PUT", UpdateReq, "", 202) opts := configurations.UpdateOpts{ Values: map[string]any{ @@ -106,23 +106,23 @@ func TestReplace(t *testing.T) { }, } - err := configurations.Replace(context.TODO(), client.ServiceClient(), configID, opts).ExtractErr() + err := configurations.Replace(context.TODO(), client.ServiceClient(fakeServer), configID, opts).ExtractErr() th.AssertNoErr(t, err) } func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - fixture.SetupHandler(t, resURL, "DELETE", "", "", 202) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + fixture.SetupHandler(t, fakeServer, resURL, "DELETE", "", "", 202) - err := configurations.Delete(context.TODO(), client.ServiceClient(), configID).ExtractErr() + err := configurations.Delete(context.TODO(), client.ServiceClient(fakeServer), configID).ExtractErr() th.AssertNoErr(t, err) } func TestListInstances(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - fixture.SetupHandler(t, resURL+"/instances", "GET", "", ListInstancesJSON, 200) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + fixture.SetupHandler(t, fakeServer, resURL+"/instances", "GET", "", ListInstancesJSON, 200) expectedInstance := instances.Instance{ ID: "d4603f69-ec7e-4e9b-803f-600b9205576f", @@ -130,7 +130,7 @@ func TestListInstances(t *testing.T) { } pages := 0 - err := configurations.ListInstances(client.ServiceClient(), configID).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := configurations.ListInstances(client.ServiceClient(fakeServer), configID).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := instances.ExtractInstances(page) @@ -148,12 +148,12 @@ func TestListInstances(t *testing.T) { } func TestListDSParams(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - fixture.SetupHandler(t, dsParamListURL, "GET", "", ListParamsJSON, 200) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + fixture.SetupHandler(t, fakeServer, dsParamListURL, "GET", "", ListParamsJSON, 200) pages := 0 - err := configurations.ListDatastoreParams(client.ServiceClient(), dsID, versionID).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := configurations.ListDatastoreParams(client.ServiceClient(fakeServer), dsID, versionID).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := configurations.ExtractParams(page) @@ -178,11 +178,11 @@ func TestListDSParams(t *testing.T) { } func TestGetDSParam(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - fixture.SetupHandler(t, dsParamGetURL, "GET", "", GetParamJSON, 200) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + fixture.SetupHandler(t, fakeServer, dsParamGetURL, "GET", "", GetParamJSON, 200) - param, err := configurations.GetDatastoreParam(context.TODO(), client.ServiceClient(), dsID, versionID, paramID).Extract() + param, err := configurations.GetDatastoreParam(context.TODO(), client.ServiceClient(fakeServer), dsID, versionID, paramID).Extract() th.AssertNoErr(t, err) expected := &configurations.Param{ @@ -193,12 +193,12 @@ func TestGetDSParam(t *testing.T) { } func TestListGlobalParams(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - fixture.SetupHandler(t, globalParamListURL, "GET", "", ListParamsJSON, 200) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + fixture.SetupHandler(t, fakeServer, globalParamListURL, "GET", "", ListParamsJSON, 200) pages := 0 - err := configurations.ListGlobalParams(client.ServiceClient(), versionID).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := configurations.ListGlobalParams(client.ServiceClient(fakeServer), versionID).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := configurations.ExtractParams(page) @@ -223,11 +223,11 @@ func TestListGlobalParams(t *testing.T) { } func TestGetGlobalParam(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - fixture.SetupHandler(t, globalParamGetURL, "GET", "", GetParamJSON, 200) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + fixture.SetupHandler(t, fakeServer, globalParamGetURL, "GET", "", GetParamJSON, 200) - param, err := configurations.GetGlobalParam(context.TODO(), client.ServiceClient(), versionID, paramID).Extract() + param, err := configurations.GetGlobalParam(context.TODO(), client.ServiceClient(fakeServer), versionID, paramID).Extract() th.AssertNoErr(t, err) expected := &configurations.Param{ diff --git a/openstack/db/v1/databases/testing/fixtures_test.go b/openstack/db/v1/databases/testing/fixtures_test.go index b7362c0864..bedeeacab5 100644 --- a/openstack/db/v1/databases/testing/fixtures_test.go +++ b/openstack/db/v1/databases/testing/fixtures_test.go @@ -3,6 +3,7 @@ package testing import ( "testing" + th "github.com/gophercloud/gophercloud/v2/testhelper" "github.com/gophercloud/gophercloud/v2/testhelper/fixture" ) @@ -48,14 +49,14 @@ var listDBsResp = ` } ` -func HandleCreate(t *testing.T) { - fixture.SetupHandler(t, resURL, "POST", createDBsReq, "", 202) +func HandleCreate(t *testing.T, fakeServer th.FakeServer) { + fixture.SetupHandler(t, fakeServer, resURL, "POST", createDBsReq, "", 202) } -func HandleList(t *testing.T) { - fixture.SetupHandler(t, resURL, "GET", "", listDBsResp, 200) +func HandleList(t *testing.T, fakeServer th.FakeServer) { + fixture.SetupHandler(t, fakeServer, resURL, "GET", "", listDBsResp, 200) } -func HandleDelete(t *testing.T) { - fixture.SetupHandler(t, resURL+"/{dbName}", "DELETE", "", "", 202) +func HandleDelete(t *testing.T, fakeServer th.FakeServer) { + fixture.SetupHandler(t, fakeServer, resURL+"/{dbName}", "DELETE", "", "", 202) } diff --git a/openstack/db/v1/databases/testing/requests_test.go b/openstack/db/v1/databases/testing/requests_test.go index ff257674af..d5d39f60ed 100644 --- a/openstack/db/v1/databases/testing/requests_test.go +++ b/openstack/db/v1/databases/testing/requests_test.go @@ -11,23 +11,23 @@ import ( ) func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreate(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCreate(t, fakeServer) opts := databases.BatchCreateOpts{ databases.CreateOpts{Name: "testingdb", CharSet: "utf8", Collate: "utf8_general_ci"}, databases.CreateOpts{Name: "sampledb"}, } - res := databases.Create(context.TODO(), client.ServiceClient(), instanceID, opts) + res := databases.Create(context.TODO(), client.ServiceClient(fakeServer), instanceID, opts) th.AssertNoErr(t, res.Err) } func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleList(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleList(t, fakeServer) expectedDBs := []databases.Database{ {Name: "anotherexampledb"}, @@ -38,7 +38,7 @@ func TestList(t *testing.T) { } pages := 0 - err := databases.List(client.ServiceClient(), instanceID).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := databases.List(client.ServiceClient(fakeServer), instanceID).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := databases.ExtractDBs(page) @@ -59,10 +59,10 @@ func TestList(t *testing.T) { } func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDelete(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDelete(t, fakeServer) - err := databases.Delete(context.TODO(), client.ServiceClient(), instanceID, "{dbName}").ExtractErr() + err := databases.Delete(context.TODO(), client.ServiceClient(fakeServer), instanceID, "{dbName}").ExtractErr() th.AssertNoErr(t, err) } diff --git a/openstack/db/v1/datastores/testing/requests_test.go b/openstack/db/v1/datastores/testing/requests_test.go index 2d11466f32..e902a6f255 100644 --- a/openstack/db/v1/datastores/testing/requests_test.go +++ b/openstack/db/v1/datastores/testing/requests_test.go @@ -12,13 +12,13 @@ import ( ) func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - fixture.SetupHandler(t, "/datastores", "GET", "", ListDSResp, 200) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + fixture.SetupHandler(t, fakeServer, "/datastores", "GET", "", ListDSResp, 200) pages := 0 - err := datastores.List(client.ServiceClient()).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := datastores.List(client.ServiceClient(fakeServer)).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := datastores.ExtractDatastores(page) @@ -36,23 +36,23 @@ func TestList(t *testing.T) { } func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - fixture.SetupHandler(t, "/datastores/{dsID}", "GET", "", GetDSResp, 200) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + fixture.SetupHandler(t, fakeServer, "/datastores/{dsID}", "GET", "", GetDSResp, 200) - ds, err := datastores.Get(context.TODO(), client.ServiceClient(), "{dsID}").Extract() + ds, err := datastores.Get(context.TODO(), client.ServiceClient(fakeServer), "{dsID}").Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, &ExampleDatastore, ds) } func TestListVersions(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - fixture.SetupHandler(t, "/datastores/{dsID}/versions", "GET", "", ListVersionsResp, 200) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + fixture.SetupHandler(t, fakeServer, "/datastores/{dsID}/versions", "GET", "", ListVersionsResp, 200) pages := 0 - err := datastores.ListVersions(client.ServiceClient(), "{dsID}").EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := datastores.ListVersions(client.ServiceClient(fakeServer), "{dsID}").EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := datastores.ExtractVersions(page) @@ -70,11 +70,11 @@ func TestListVersions(t *testing.T) { } func TestGetVersion(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - fixture.SetupHandler(t, "/datastores/{dsID}/versions/{versionID}", "GET", "", GetVersionResp, 200) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + fixture.SetupHandler(t, fakeServer, "/datastores/{dsID}/versions/{versionID}", "GET", "", GetVersionResp, 200) - ds, err := datastores.GetVersion(context.TODO(), client.ServiceClient(), "{dsID}", "{versionID}").Extract() + ds, err := datastores.GetVersion(context.TODO(), client.ServiceClient(fakeServer), "{dsID}", "{versionID}").Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, &ExampleVersion1, ds) } diff --git a/openstack/db/v1/flavors/testing/fixtures_test.go b/openstack/db/v1/flavors/testing/fixtures_test.go index 048b23592e..8ba73b8eb8 100644 --- a/openstack/db/v1/flavors/testing/fixtures_test.go +++ b/openstack/db/v1/flavors/testing/fixtures_test.go @@ -4,6 +4,7 @@ import ( "fmt" "testing" + th "github.com/gophercloud/gophercloud/v2/testhelper" "github.com/gophercloud/gophercloud/v2/testhelper/fixture" ) @@ -43,10 +44,10 @@ var ( getFlavorResp = fmt.Sprintf(`{"flavor": %s}`, flavor1) ) -func HandleList(t *testing.T) { - fixture.SetupHandler(t, _baseURL, "GET", "", listFlavorsResp, 200) +func HandleList(t *testing.T, fakeServer th.FakeServer) { + fixture.SetupHandler(t, fakeServer, _baseURL, "GET", "", listFlavorsResp, 200) } -func HandleGet(t *testing.T) { - fixture.SetupHandler(t, resURL, "GET", "", getFlavorResp, 200) +func HandleGet(t *testing.T, fakeServer th.FakeServer) { + fixture.SetupHandler(t, fakeServer, resURL, "GET", "", getFlavorResp, 200) } diff --git a/openstack/db/v1/flavors/testing/requests_test.go b/openstack/db/v1/flavors/testing/requests_test.go index 36ecf2799d..a1a9ecd3ea 100644 --- a/openstack/db/v1/flavors/testing/requests_test.go +++ b/openstack/db/v1/flavors/testing/requests_test.go @@ -12,12 +12,12 @@ import ( ) func TestListFlavors(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleList(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleList(t, fakeServer) pages := 0 - err := flavors.List(client.ServiceClient()).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := flavors.List(client.ServiceClient(fakeServer)).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := flavors.ExtractFlavors(page) @@ -87,11 +87,11 @@ func TestListFlavors(t *testing.T) { } func TestGetFlavor(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGet(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGet(t, fakeServer) - actual, err := flavors.Get(context.TODO(), client.ServiceClient(), flavorID).Extract() + actual, err := flavors.Get(context.TODO(), client.ServiceClient(fakeServer), flavorID).Extract() th.AssertNoErr(t, err) expected := &flavors.Flavor{ diff --git a/openstack/db/v1/instances/testing/fixtures_test.go b/openstack/db/v1/instances/testing/fixtures_test.go index dc3b9dc0de..f31c2f5e24 100644 --- a/openstack/db/v1/instances/testing/fixtures_test.go +++ b/openstack/db/v1/instances/testing/fixtures_test.go @@ -8,6 +8,7 @@ import ( "github.com/gophercloud/gophercloud/v2" "github.com/gophercloud/gophercloud/v2/openstack/db/v1/datastores" "github.com/gophercloud/gophercloud/v2/openstack/db/v1/instances" + th "github.com/gophercloud/gophercloud/v2/testhelper" "github.com/gophercloud/gophercloud/v2/testhelper/fixture" ) @@ -285,50 +286,50 @@ var expectedInstanceWithFault = instances.Instance{ }, } -func HandleCreate(t *testing.T) { - fixture.SetupHandler(t, rootURL, "POST", createReq, createResp, 200) +func HandleCreate(t *testing.T, fakeServer th.FakeServer) { + fixture.SetupHandler(t, fakeServer, rootURL, "POST", createReq, createResp, 200) } -func HandleCreateWithFault(t *testing.T) { - fixture.SetupHandler(t, rootURL, "POST", createReq, createWithFaultResp, 200) +func HandleCreateWithFault(t *testing.T, fakeServer th.FakeServer) { + fixture.SetupHandler(t, fakeServer, rootURL, "POST", createReq, createWithFaultResp, 200) } -func HandleList(t *testing.T) { - fixture.SetupHandler(t, rootURL, "GET", "", listInstancesResp, 200) +func HandleList(t *testing.T, fakeServer th.FakeServer) { + fixture.SetupHandler(t, fakeServer, rootURL, "GET", "", listInstancesResp, 200) } -func HandleGet(t *testing.T) { - fixture.SetupHandler(t, resURL, "GET", "", getInstanceResp, 200) +func HandleGet(t *testing.T, fakeServer th.FakeServer) { + fixture.SetupHandler(t, fakeServer, resURL, "GET", "", getInstanceResp, 200) } -func HandleDelete(t *testing.T) { - fixture.SetupHandler(t, resURL, "DELETE", "", "", 202) +func HandleDelete(t *testing.T, fakeServer th.FakeServer) { + fixture.SetupHandler(t, fakeServer, resURL, "DELETE", "", "", 202) } -func HandleEnableRoot(t *testing.T) { - fixture.SetupHandler(t, uRootURL, "POST", "", enableUserResp, 200) +func HandleEnableRoot(t *testing.T, fakeServer th.FakeServer) { + fixture.SetupHandler(t, fakeServer, uRootURL, "POST", "", enableUserResp, 200) } -func HandleIsRootEnabled(t *testing.T) { - fixture.SetupHandler(t, uRootURL, "GET", "", isUserEnabledResp, 200) +func HandleIsRootEnabled(t *testing.T, fakeServer th.FakeServer) { + fixture.SetupHandler(t, fakeServer, uRootURL, "GET", "", isUserEnabledResp, 200) } -func HandleRestart(t *testing.T) { - fixture.SetupHandler(t, aURL, "POST", restartReq, "", 202) +func HandleRestart(t *testing.T, fakeServer th.FakeServer) { + fixture.SetupHandler(t, fakeServer, aURL, "POST", restartReq, "", 202) } -func HandleResize(t *testing.T) { - fixture.SetupHandler(t, aURL, "POST", resizeReq, "", 202) +func HandleResize(t *testing.T, fakeServer th.FakeServer) { + fixture.SetupHandler(t, fakeServer, aURL, "POST", resizeReq, "", 202) } -func HandleResizeVol(t *testing.T) { - fixture.SetupHandler(t, aURL, "POST", resizeVolReq, "", 202) +func HandleResizeVol(t *testing.T, fakeServer th.FakeServer) { + fixture.SetupHandler(t, fakeServer, aURL, "POST", resizeVolReq, "", 202) } -func HandleAttachConfigurationGroup(t *testing.T) { - fixture.SetupHandler(t, resURL, "PUT", attachConfigurationGroupReq, "", 202) +func HandleAttachConfigurationGroup(t *testing.T, fakeServer th.FakeServer) { + fixture.SetupHandler(t, fakeServer, resURL, "PUT", attachConfigurationGroupReq, "", 202) } -func HandleDetachConfigurationGroup(t *testing.T) { - fixture.SetupHandler(t, resURL, "PUT", detachConfigurationGroupReq, "", 202) +func HandleDetachConfigurationGroup(t *testing.T, fakeServer th.FakeServer) { + fixture.SetupHandler(t, fakeServer, resURL, "PUT", detachConfigurationGroupReq, "", 202) } diff --git a/openstack/db/v1/instances/testing/requests_test.go b/openstack/db/v1/instances/testing/requests_test.go index 0394b8a58d..b7278bf8d4 100644 --- a/openstack/db/v1/instances/testing/requests_test.go +++ b/openstack/db/v1/instances/testing/requests_test.go @@ -13,9 +13,9 @@ import ( ) func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreate(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCreate(t, fakeServer) opts := instances.CreateOpts{ AvailabilityZone: "us-east1", @@ -39,16 +39,16 @@ func TestCreate(t *testing.T) { VolumeType: "ssd", } - instance, err := instances.Create(context.TODO(), client.ServiceClient(), opts).Extract() + instance, err := instances.Create(context.TODO(), client.ServiceClient(fakeServer), opts).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, &expectedInstance, instance) } func TestCreateWithFault(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateWithFault(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCreateWithFault(t, fakeServer) opts := instances.CreateOpts{ AvailabilityZone: "us-east1", @@ -72,19 +72,19 @@ func TestCreateWithFault(t *testing.T) { VolumeType: "ssd", } - instance, err := instances.Create(context.TODO(), client.ServiceClient(), opts).Extract() + instance, err := instances.Create(context.TODO(), client.ServiceClient(fakeServer), opts).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, &expectedInstanceWithFault, instance) } func TestInstanceList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleList(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleList(t, fakeServer) pages := 0 - err := instances.List(client.ServiceClient()).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := instances.List(client.ServiceClient(fakeServer)).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := instances.ExtractInstances(page) @@ -101,89 +101,89 @@ func TestInstanceList(t *testing.T) { } func TestGetInstance(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGet(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGet(t, fakeServer) - instance, err := instances.Get(context.TODO(), client.ServiceClient(), instanceID).Extract() + instance, err := instances.Get(context.TODO(), client.ServiceClient(fakeServer), instanceID).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, &expectedGetInstance, instance) } func TestDeleteInstance(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDelete(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDelete(t, fakeServer) - res := instances.Delete(context.TODO(), client.ServiceClient(), instanceID) + res := instances.Delete(context.TODO(), client.ServiceClient(fakeServer), instanceID) th.AssertNoErr(t, res.Err) } func TestEnableRootUser(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleEnableRoot(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleEnableRoot(t, fakeServer) expected := &users.User{Name: "root", Password: "secretsecret"} - user, err := instances.EnableRootUser(context.TODO(), client.ServiceClient(), instanceID).Extract() + user, err := instances.EnableRootUser(context.TODO(), client.ServiceClient(fakeServer), instanceID).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, expected, user) } func TestIsRootEnabled(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleIsRootEnabled(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleIsRootEnabled(t, fakeServer) - isEnabled, err := instances.IsRootEnabled(context.TODO(), client.ServiceClient(), instanceID).Extract() + isEnabled, err := instances.IsRootEnabled(context.TODO(), client.ServiceClient(fakeServer), instanceID).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, true, isEnabled) } func TestRestart(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleRestart(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleRestart(t, fakeServer) - res := instances.Restart(context.TODO(), client.ServiceClient(), instanceID) + res := instances.Restart(context.TODO(), client.ServiceClient(fakeServer), instanceID) th.AssertNoErr(t, res.Err) } func TestResize(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleResize(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleResize(t, fakeServer) - res := instances.Resize(context.TODO(), client.ServiceClient(), instanceID, "2") + res := instances.Resize(context.TODO(), client.ServiceClient(fakeServer), instanceID, "2") th.AssertNoErr(t, res.Err) } func TestResizeVolume(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleResizeVol(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleResizeVol(t, fakeServer) - res := instances.ResizeVolume(context.TODO(), client.ServiceClient(), instanceID, 4) + res := instances.ResizeVolume(context.TODO(), client.ServiceClient(fakeServer), instanceID, 4) th.AssertNoErr(t, res.Err) } func TestAttachConfigurationGroup(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleAttachConfigurationGroup(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleAttachConfigurationGroup(t, fakeServer) - res := instances.AttachConfigurationGroup(context.TODO(), client.ServiceClient(), instanceID, configGroupID) + res := instances.AttachConfigurationGroup(context.TODO(), client.ServiceClient(fakeServer), instanceID, configGroupID) th.AssertNoErr(t, res.Err) } func TestDetachConfigurationGroup(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDetachConfigurationGroup(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDetachConfigurationGroup(t, fakeServer) - res := instances.DetachConfigurationGroup(context.TODO(), client.ServiceClient(), instanceID) + res := instances.DetachConfigurationGroup(context.TODO(), client.ServiceClient(fakeServer), instanceID) th.AssertNoErr(t, res.Err) } diff --git a/openstack/db/v1/users/testing/fixtures_test.go b/openstack/db/v1/users/testing/fixtures_test.go index 961e4f6ecd..db758d8040 100644 --- a/openstack/db/v1/users/testing/fixtures_test.go +++ b/openstack/db/v1/users/testing/fixtures_test.go @@ -4,6 +4,7 @@ import ( "fmt" "testing" + th "github.com/gophercloud/gophercloud/v2/testhelper" "github.com/gophercloud/gophercloud/v2/testhelper/fixture" ) @@ -24,14 +25,14 @@ var ( listResp = fmt.Sprintf(`{"users":[%s, %s]}`, fmt.Sprintf(user1, ""), fmt.Sprintf(user2, "")) ) -func HandleCreate(t *testing.T) { - fixture.SetupHandler(t, _rootURL, "POST", createReq, "", 202) +func HandleCreate(t *testing.T, fakeServer th.FakeServer) { + fixture.SetupHandler(t, fakeServer, _rootURL, "POST", createReq, "", 202) } -func HandleList(t *testing.T) { - fixture.SetupHandler(t, _rootURL, "GET", "", listResp, 200) +func HandleList(t *testing.T, fakeServer th.FakeServer) { + fixture.SetupHandler(t, fakeServer, _rootURL, "GET", "", listResp, 200) } -func HandleDelete(t *testing.T) { - fixture.SetupHandler(t, _rootURL+"/{userName}", "DELETE", "", "", 202) +func HandleDelete(t *testing.T, fakeServer th.FakeServer) { + fixture.SetupHandler(t, fakeServer, _rootURL+"/{userName}", "DELETE", "", "", 202) } diff --git a/openstack/db/v1/users/testing/requests_test.go b/openstack/db/v1/users/testing/requests_test.go index ef7a03073a..33665061e0 100644 --- a/openstack/db/v1/users/testing/requests_test.go +++ b/openstack/db/v1/users/testing/requests_test.go @@ -12,9 +12,9 @@ import ( ) func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreate(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCreate(t, fakeServer) opts := users.BatchCreateOpts{ { @@ -34,14 +34,14 @@ func TestCreate(t *testing.T) { }, } - res := users.Create(context.TODO(), client.ServiceClient(), instanceID, opts) + res := users.Create(context.TODO(), client.ServiceClient(fakeServer), instanceID, opts) th.AssertNoErr(t, res.Err) } func TestUserList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleList(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleList(t, fakeServer) expectedUsers := []users.User{ { @@ -60,7 +60,7 @@ func TestUserList(t *testing.T) { } pages := 0 - err := users.List(client.ServiceClient(), instanceID).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := users.List(client.ServiceClient(fakeServer), instanceID).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := users.ExtractUsers(page) @@ -77,10 +77,10 @@ func TestUserList(t *testing.T) { } func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDelete(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDelete(t, fakeServer) - res := users.Delete(context.TODO(), client.ServiceClient(), instanceID, "{userName}") + res := users.Delete(context.TODO(), client.ServiceClient(fakeServer), instanceID, "{userName}") th.AssertNoErr(t, res.Err) } diff --git a/openstack/dns/v2/recordsets/testing/fixtures_test.go b/openstack/dns/v2/recordsets/testing/fixtures_test.go index 71d1d0898e..42a6c0d6e5 100644 --- a/openstack/dns/v2/recordsets/testing/fixtures_test.go +++ b/openstack/dns/v2/recordsets/testing/fixtures_test.go @@ -200,8 +200,8 @@ var ExpectedRecordSetSlice = []recordsets.RecordSet{FirstRecordSet, SecondRecord var ExpectedRecordSetSliceLimited = []recordsets.RecordSet{SecondRecordSet} // HandleListByZoneSuccessfully configures the test server to respond to a ListByZone request. -func HandleListByZoneSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/zones/2150b1bf-dee2-4221-9d85-11f7886fb15f/recordsets", func(w http.ResponseWriter, r *http.Request) { +func HandleListByZoneSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/zones/2150b1bf-dee2-4221-9d85-11f7886fb15f/recordsets", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -220,8 +220,8 @@ func HandleListByZoneSuccessfully(t *testing.T) { } // HandleGetSuccessfully configures the test server to respond to a Get request. -func HandleGetSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/zones/2150b1bf-dee2-4221-9d85-11f7886fb15f/recordsets/f7b10e9b-0cae-4a91-b162-562bc6096648", +func HandleGetSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/zones/2150b1bf-dee2-4221-9d85-11f7886fb15f/recordsets/f7b10e9b-0cae-4a91-b162-562bc6096648", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -273,8 +273,8 @@ const CreateRecordSetResponse = ` var CreatedRecordSet = FirstRecordSet // HandleZoneCreationSuccessfully configures the test server to respond to a Create request. -func HandleCreateSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/zones/2150b1bf-dee2-4221-9d85-11f7886fb15f/recordsets", +func HandleCreateSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/zones/2150b1bf-dee2-4221-9d85-11f7886fb15f/recordsets", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -325,8 +325,8 @@ const UpdateRecordSetResponse = ` ` // HandleUpdateSuccessfully configures the test server to respond to an Update request. -func HandleUpdateSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/zones/2150b1bf-dee2-4221-9d85-11f7886fb15f/recordsets/f7b10e9b-0cae-4a91-b162-562bc6096648", +func HandleUpdateSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/zones/2150b1bf-dee2-4221-9d85-11f7886fb15f/recordsets/f7b10e9b-0cae-4a91-b162-562bc6096648", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -365,8 +365,8 @@ const DeleteRecordSetResponse = ` ` // HandleDeleteSuccessfully configures the test server to respond to an Delete request. -func HandleDeleteSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/zones/2150b1bf-dee2-4221-9d85-11f7886fb15f/recordsets/f7b10e9b-0cae-4a91-b162-562bc6096648", +func HandleDeleteSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/zones/2150b1bf-dee2-4221-9d85-11f7886fb15f/recordsets/f7b10e9b-0cae-4a91-b162-562bc6096648", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/dns/v2/recordsets/testing/requests_test.go b/openstack/dns/v2/recordsets/testing/requests_test.go index 0c2a51b219..fb06587f86 100644 --- a/openstack/dns/v2/recordsets/testing/requests_test.go +++ b/openstack/dns/v2/recordsets/testing/requests_test.go @@ -12,12 +12,12 @@ import ( ) func TestListByZone(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListByZoneSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListByZoneSuccessfully(t, fakeServer) count := 0 - err := recordsets.ListByZone(client.ServiceClient(), "2150b1bf-dee2-4221-9d85-11f7886fb15f", nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := recordsets.ListByZone(client.ServiceClient(fakeServer), "2150b1bf-dee2-4221-9d85-11f7886fb15f", nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := recordsets.ExtractRecordSets(page) th.AssertNoErr(t, err) @@ -30,16 +30,16 @@ func TestListByZone(t *testing.T) { } func TestListByZoneLimited(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListByZoneSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListByZoneSuccessfully(t, fakeServer) count := 0 listOpts := recordsets.ListOpts{ Limit: 1, Marker: "f7b10e9b-0cae-4a91-b162-562bc6096648", } - err := recordsets.ListByZone(client.ServiceClient(), "2150b1bf-dee2-4221-9d85-11f7886fb15f", listOpts).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := recordsets.ListByZone(client.ServiceClient(fakeServer), "2150b1bf-dee2-4221-9d85-11f7886fb15f", listOpts).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := recordsets.ExtractRecordSets(page) th.AssertNoErr(t, err) @@ -52,11 +52,11 @@ func TestListByZoneLimited(t *testing.T) { } func TestListByZoneAllPages(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListByZoneSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListByZoneSuccessfully(t, fakeServer) - allPages, err := recordsets.ListByZone(client.ServiceClient(), "2150b1bf-dee2-4221-9d85-11f7886fb15f", nil).AllPages(context.TODO()) + allPages, err := recordsets.ListByZone(client.ServiceClient(fakeServer), "2150b1bf-dee2-4221-9d85-11f7886fb15f", nil).AllPages(context.TODO()) th.AssertNoErr(t, err) allRecordSets, err := recordsets.ExtractRecordSets(allPages) th.AssertNoErr(t, err) @@ -64,11 +64,11 @@ func TestListByZoneAllPages(t *testing.T) { } func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetSuccessfully(t, fakeServer) - actual, err := recordsets.Get(context.TODO(), client.ServiceClient(), "2150b1bf-dee2-4221-9d85-11f7886fb15f", "f7b10e9b-0cae-4a91-b162-562bc6096648").Extract() + actual, err := recordsets.Get(context.TODO(), client.ServiceClient(fakeServer), "2150b1bf-dee2-4221-9d85-11f7886fb15f", "f7b10e9b-0cae-4a91-b162-562bc6096648").Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, &FirstRecordSet, actual) } @@ -88,9 +88,9 @@ func TestNextPageURL(t *testing.T) { } func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCreateSuccessfully(t, fakeServer) createOpts := recordsets.CreateOpts{ Name: "example.org.", @@ -100,15 +100,15 @@ func TestCreate(t *testing.T) { Records: []string{"10.1.0.2"}, } - actual, err := recordsets.Create(context.TODO(), client.ServiceClient(), "2150b1bf-dee2-4221-9d85-11f7886fb15f", createOpts).Extract() + actual, err := recordsets.Create(context.TODO(), client.ServiceClient(fakeServer), "2150b1bf-dee2-4221-9d85-11f7886fb15f", createOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, &CreatedRecordSet, actual) } func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleUpdateSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleUpdateSuccessfully(t, fakeServer) var description = "Updated description" ttl := 0 @@ -125,15 +125,15 @@ func TestUpdate(t *testing.T) { UpdatedRecordSet.Records = []string{"10.1.0.2", "10.1.0.3"} UpdatedRecordSet.Version = 2 - actual, err := recordsets.Update(context.TODO(), client.ServiceClient(), UpdatedRecordSet.ZoneID, UpdatedRecordSet.ID, updateOpts).Extract() + actual, err := recordsets.Update(context.TODO(), client.ServiceClient(fakeServer), UpdatedRecordSet.ZoneID, UpdatedRecordSet.ID, updateOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, &UpdatedRecordSet, actual) } func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDeleteSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDeleteSuccessfully(t, fakeServer) DeletedRecordSet := CreatedRecordSet DeletedRecordSet.Status = "PENDING" @@ -142,7 +142,7 @@ func TestDelete(t *testing.T) { DeletedRecordSet.Records = []string{"10.1.0.2", "10.1.0.3"} DeletedRecordSet.Version = 2 - err := recordsets.Delete(context.TODO(), client.ServiceClient(), DeletedRecordSet.ZoneID, DeletedRecordSet.ID).ExtractErr() + err := recordsets.Delete(context.TODO(), client.ServiceClient(fakeServer), DeletedRecordSet.ZoneID, DeletedRecordSet.ID).ExtractErr() th.AssertNoErr(t, err) //th.CheckDeepEquals(t, &DeletedZone, actual) } diff --git a/openstack/dns/v2/transfer/accept/testing/accepts_test.go b/openstack/dns/v2/transfer/accept/testing/accepts_test.go index db868bd779..1261cd1583 100644 --- a/openstack/dns/v2/transfer/accept/testing/accepts_test.go +++ b/openstack/dns/v2/transfer/accept/testing/accepts_test.go @@ -11,12 +11,12 @@ import ( ) func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListSuccessfully(t, fakeServer) count := 0 - err := transferAccepts.List(client.ServiceClient(), nil).EachPage( + err := transferAccepts.List(client.ServiceClient(fakeServer), nil).EachPage( context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ @@ -30,15 +30,15 @@ func TestList(t *testing.T) { } func TestListWithOpts(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleFilteredListSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleFilteredListSuccessfully(t, fakeServer) listOpts := transferAccepts.ListOpts{ Status: "ACTIVE", } - allPages, err := transferAccepts.List(client.ServiceClient(), listOpts).AllPages(context.TODO()) + allPages, err := transferAccepts.List(client.ServiceClient(fakeServer), listOpts).AllPages(context.TODO()) th.AssertNoErr(t, err) allTransferAccepts, err := transferAccepts.ExtractTransferAccepts(allPages) th.AssertNoErr(t, err) @@ -46,11 +46,11 @@ func TestListWithOpts(t *testing.T) { } func TestListAllPages(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListSuccessfully(t, fakeServer) - allPages, err := transferAccepts.List(client.ServiceClient(), nil).AllPages(context.TODO()) + allPages, err := transferAccepts.List(client.ServiceClient(fakeServer), nil).AllPages(context.TODO()) th.AssertNoErr(t, err) allTransferAccepts, err := transferAccepts.ExtractTransferAccepts(allPages) th.AssertNoErr(t, err) @@ -58,20 +58,20 @@ func TestListAllPages(t *testing.T) { } func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetSuccessfully(t, fakeServer) actual, err := transferAccepts.Get( - context.TODO(), client.ServiceClient(), "92236f39-0fad-4f8f-bf25-fbdf027de34d").Extract() + context.TODO(), client.ServiceClient(fakeServer), "92236f39-0fad-4f8f-bf25-fbdf027de34d").Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, &FirstTransferAccept, actual) } func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCreateSuccessfully(t, fakeServer) createOpts := transferAccepts.CreateOpts{ Key: "M2KA0Y20", @@ -79,7 +79,7 @@ func TestCreate(t *testing.T) { } actual, err := transferAccepts.Create( - context.TODO(), client.ServiceClient(), createOpts).Extract() + context.TODO(), client.ServiceClient(fakeServer), createOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, &CreatedTransferAccept, actual) } diff --git a/openstack/dns/v2/transfer/accept/testing/fixtures_test.go b/openstack/dns/v2/transfer/accept/testing/fixtures_test.go index 3dae54e6aa..4ef02e7489 100644 --- a/openstack/dns/v2/transfer/accept/testing/fixtures_test.go +++ b/openstack/dns/v2/transfer/accept/testing/fixtures_test.go @@ -126,9 +126,9 @@ var SecondTransferAccept = transferAccepts.TransferAccept{ var ExpectedTransferAcceptSlice = []transferAccepts.TransferAccept{FirstTransferAccept, SecondTransferAccept} // HandleListSuccessfully configures the test server to respond to a List request. -func HandleListSuccessfully(t *testing.T) { +func HandleListSuccessfully(t *testing.T, fakeServer th.FakeServer) { baseURL := "/zones/tasks/transfer_accepts" - th.Mux.HandleFunc(baseURL, + fakeServer.Mux.HandleFunc(baseURL, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -138,9 +138,9 @@ func HandleListSuccessfully(t *testing.T) { } // HandleFilteredListSuccessfully configures the test server to respond to a List request with Opts. -func HandleFilteredListSuccessfully(t *testing.T) { +func HandleFilteredListSuccessfully(t *testing.T, fakeServer th.FakeServer) { baseURL := "/zones/tasks/transfer_accepts" - th.Mux.HandleFunc(baseURL, + fakeServer.Mux.HandleFunc(baseURL, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -150,9 +150,9 @@ func HandleFilteredListSuccessfully(t *testing.T) { } // HandleGetSuccessfully configures the test server to respond to a List request. -func HandleGetSuccessfully(t *testing.T) { +func HandleGetSuccessfully(t *testing.T, fakeServer th.FakeServer) { baseURL := "/zones/tasks/transfer_accepts" - th.Mux.HandleFunc(s.Join([]string{baseURL, FirstTransferAccept.ID}, "/"), + fakeServer.Mux.HandleFunc(s.Join([]string{baseURL, FirstTransferAccept.ID}, "/"), func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -190,9 +190,9 @@ const CreateTransferAcceptResponse = ` var CreatedTransferAccept = FirstTransferAccept // HandleTransferRequestCreationSuccessfully configures the test server to respond to a Create request. -func HandleCreateSuccessfully(t *testing.T) { +func HandleCreateSuccessfully(t *testing.T, fakeServer th.FakeServer) { baseURL := "/zones/tasks/transfer_accepts" - th.Mux.HandleFunc(baseURL, + fakeServer.Mux.HandleFunc(baseURL, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/dns/v2/transfer/request/testing/fixtures_test.go b/openstack/dns/v2/transfer/request/testing/fixtures_test.go index 3de1f2aca3..52ed6b6d3a 100644 --- a/openstack/dns/v2/transfer/request/testing/fixtures_test.go +++ b/openstack/dns/v2/transfer/request/testing/fixtures_test.go @@ -112,9 +112,9 @@ var SecondTransferRequest = transferRequests.TransferRequest{ var ExpectedTransferRequestsSlice = []transferRequests.TransferRequest{FirstTransferRequest, SecondTransferRequest} // HandleListSuccessfully configures the test server to respond to a List request. -func HandleListSuccessfully(t *testing.T) { +func HandleListSuccessfully(t *testing.T, fakeServer th.FakeServer) { baseURL := "/zones/tasks/transfer_requests" - th.Mux.HandleFunc(baseURL, + fakeServer.Mux.HandleFunc(baseURL, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -124,9 +124,9 @@ func HandleListSuccessfully(t *testing.T) { } // HandleGetSuccessfully configures the test server to respond to a List request. -func HandleGetSuccessfully(t *testing.T) { +func HandleGetSuccessfully(t *testing.T, fakeServer th.FakeServer) { baseURL := "/zones/tasks/transfer_requests" - th.Mux.HandleFunc(s.Join([]string{baseURL, FirstTransferRequest.ID}, "/"), + fakeServer.Mux.HandleFunc(s.Join([]string{baseURL, FirstTransferRequest.ID}, "/"), func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -165,9 +165,9 @@ const CreateTransferRequestResponse = ` var CreatedTransferRequest = FirstTransferRequest // HandleTransferRequestCreationSuccessfully configures the test server to respond to a Create request. -func HandleCreateSuccessfully(t *testing.T) { +func HandleCreateSuccessfully(t *testing.T, fakeServer th.FakeServer) { createURL := "/zones/a6a8515c-5d80-48c0-955b-fde631b59791/tasks/transfer_requests" - th.Mux.HandleFunc(createURL, + fakeServer.Mux.HandleFunc(createURL, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -205,9 +205,9 @@ const UpdatedTransferRequestResponse = ` ` // HandleTransferRequestUpdateSuccessfully configures the test server to respond to an Update request. -func HandleUpdateSuccessfully(t *testing.T) { +func HandleUpdateSuccessfully(t *testing.T, fakeServer th.FakeServer) { baseURL := "/zones/tasks/transfer_requests" - th.Mux.HandleFunc(s.Join([]string{baseURL, FirstTransferRequest.ID}, "/"), + fakeServer.Mux.HandleFunc(s.Join([]string{baseURL, FirstTransferRequest.ID}, "/"), func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PATCH") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -220,9 +220,9 @@ func HandleUpdateSuccessfully(t *testing.T) { } // HandleTransferRequestDeleteSuccessfully configures the test server to respond to an Delete request. -func HandleDeleteSuccessfully(t *testing.T) { +func HandleDeleteSuccessfully(t *testing.T, fakeServer th.FakeServer) { baseURL := "/zones/tasks/transfer_requests" - th.Mux.HandleFunc(s.Join([]string{baseURL, FirstTransferRequest.ID}, "/"), + fakeServer.Mux.HandleFunc(s.Join([]string{baseURL, FirstTransferRequest.ID}, "/"), func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/dns/v2/transfer/request/testing/requests_test.go b/openstack/dns/v2/transfer/request/testing/requests_test.go index daad13b664..b2213f61af 100644 --- a/openstack/dns/v2/transfer/request/testing/requests_test.go +++ b/openstack/dns/v2/transfer/request/testing/requests_test.go @@ -11,12 +11,12 @@ import ( ) func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListSuccessfully(t, fakeServer) count := 0 - err := transferRequests.List(client.ServiceClient(), nil).EachPage( + err := transferRequests.List(client.ServiceClient(fakeServer), nil).EachPage( context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ @@ -30,15 +30,15 @@ func TestList(t *testing.T) { } func TestListWithOpts(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListSuccessfully(t, fakeServer) listOpts := transferRequests.ListOpts{ Status: "ACTIVE", } - allPages, err := transferRequests.List(client.ServiceClient(), listOpts).AllPages(context.TODO()) + allPages, err := transferRequests.List(client.ServiceClient(fakeServer), listOpts).AllPages(context.TODO()) th.AssertNoErr(t, err) allTransferRequests, err := transferRequests.ExtractTransferRequests(allPages) th.AssertNoErr(t, err) @@ -46,11 +46,11 @@ func TestListWithOpts(t *testing.T) { } func TestListAllPages(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListSuccessfully(t, fakeServer) - allPages, err := transferRequests.List(client.ServiceClient(), nil).AllPages(context.TODO()) + allPages, err := transferRequests.List(client.ServiceClient(fakeServer), nil).AllPages(context.TODO()) th.AssertNoErr(t, err) allTransferRequests, err := transferRequests.ExtractTransferRequests(allPages) th.AssertNoErr(t, err) @@ -58,20 +58,20 @@ func TestListAllPages(t *testing.T) { } func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetSuccessfully(t, fakeServer) actual, err := transferRequests.Get( - context.TODO(), client.ServiceClient(), "a86dba58-0043-4cc6-a1bb-69d5e86f3ca3").Extract() + context.TODO(), client.ServiceClient(fakeServer), "a86dba58-0043-4cc6-a1bb-69d5e86f3ca3").Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, &FirstTransferRequest, actual) } func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCreateSuccessfully(t, fakeServer) createOpts := transferRequests.CreateOpts{ TargetProjectID: "05d98711-b3a1-4264-a395-f46383671ee6", @@ -79,15 +79,15 @@ func TestCreate(t *testing.T) { } actual, err := transferRequests.Create( - context.TODO(), client.ServiceClient(), FirstTransferRequest.ZoneID, createOpts).Extract() + context.TODO(), client.ServiceClient(fakeServer), FirstTransferRequest.ZoneID, createOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, &CreatedTransferRequest, actual) } func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleUpdateSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleUpdateSuccessfully(t, fakeServer) var description = "Updated Description" updateOpts := transferRequests.UpdateOpts{ @@ -98,18 +98,18 @@ func TestUpdate(t *testing.T) { UpdatedTransferRequest.Description = "Updated Description" actual, err := transferRequests.Update( - context.TODO(), client.ServiceClient(), UpdatedTransferRequest.ID, updateOpts).Extract() + context.TODO(), client.ServiceClient(fakeServer), UpdatedTransferRequest.ID, updateOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, &UpdatedTransferRequest, actual) } func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDeleteSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDeleteSuccessfully(t, fakeServer) DeletedZone := CreatedTransferRequest - err := transferRequests.Delete(context.TODO(), client.ServiceClient(), DeletedZone.ID).ExtractErr() + err := transferRequests.Delete(context.TODO(), client.ServiceClient(fakeServer), DeletedZone.ID).ExtractErr() th.AssertNoErr(t, err) } diff --git a/openstack/dns/v2/zones/testing/fixtures_test.go b/openstack/dns/v2/zones/testing/fixtures_test.go index c52002bed8..8a7b12a09f 100644 --- a/openstack/dns/v2/zones/testing/fixtures_test.go +++ b/openstack/dns/v2/zones/testing/fixtures_test.go @@ -143,8 +143,8 @@ var SecondZone = zones.Zone{ var ExpectedZonesSlice = []zones.Zone{FirstZone, SecondZone} // HandleListSuccessfully configures the test server to respond to a List request. -func HandleListSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/zones", func(w http.ResponseWriter, r *http.Request) { +func HandleListSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/zones", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -154,8 +154,8 @@ func HandleListSuccessfully(t *testing.T) { } // HandleGetSuccessfully configures the test server to respond to a List request. -func HandleGetSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/zones/a86dba58-0043-4cc6-a1bb-69d5e86f3ca3", func(w http.ResponseWriter, r *http.Request) { +func HandleGetSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/zones/a86dba58-0043-4cc6-a1bb-69d5e86f3ca3", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -204,8 +204,8 @@ const CreateZoneResponse = ` var CreatedZone = FirstZone // HandleZoneCreationSuccessfully configures the test server to respond to a Create request. -func HandleCreateSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/zones", func(w http.ResponseWriter, r *http.Request) { +func HandleCreateSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/zones", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, CreateZoneRequest) @@ -250,8 +250,8 @@ const UpdateZoneResponse = ` ` // HandleZoneUpdateSuccessfully configures the test server to respond to an Update request. -func HandleUpdateSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/zones/a86dba58-0043-4cc6-a1bb-69d5e86f3ca3", +func HandleUpdateSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/zones/a86dba58-0043-4cc6-a1bb-69d5e86f3ca3", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PATCH") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -289,8 +289,8 @@ const DeleteZoneResponse = ` ` // HandleZoneDeleteSuccessfully configures the test server to respond to an Delete request. -func HandleDeleteSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/zones/a86dba58-0043-4cc6-a1bb-69d5e86f3ca3", +func HandleDeleteSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/zones/a86dba58-0043-4cc6-a1bb-69d5e86f3ca3", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/dns/v2/zones/testing/requests_test.go b/openstack/dns/v2/zones/testing/requests_test.go index 0e60364ddb..fcc1838ce3 100644 --- a/openstack/dns/v2/zones/testing/requests_test.go +++ b/openstack/dns/v2/zones/testing/requests_test.go @@ -15,12 +15,12 @@ import ( ) func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListSuccessfully(t, fakeServer) count := 0 - err := zones.List(client.ServiceClient(), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := zones.List(client.ServiceClient(fakeServer), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := zones.ExtractZones(page) th.AssertNoErr(t, err) @@ -33,11 +33,11 @@ func TestList(t *testing.T) { } func TestListAllPages(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListSuccessfully(t, fakeServer) - allPages, err := zones.List(client.ServiceClient(), nil).AllPages(context.TODO()) + allPages, err := zones.List(client.ServiceClient(fakeServer), nil).AllPages(context.TODO()) th.AssertNoErr(t, err) allZones, err := zones.ExtractZones(allPages) th.AssertNoErr(t, err) @@ -45,19 +45,19 @@ func TestListAllPages(t *testing.T) { } func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetSuccessfully(t, fakeServer) - actual, err := zones.Get(context.TODO(), client.ServiceClient(), "a86dba58-0043-4cc6-a1bb-69d5e86f3ca3").Extract() + actual, err := zones.Get(context.TODO(), client.ServiceClient(fakeServer), "a86dba58-0043-4cc6-a1bb-69d5e86f3ca3").Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, &FirstZone, actual) } func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCreateSuccessfully(t, fakeServer) createOpts := zones.CreateOpts{ Name: "example.org.", @@ -67,15 +67,15 @@ func TestCreate(t *testing.T) { Description: "This is an example zone.", } - actual, err := zones.Create(context.TODO(), client.ServiceClient(), createOpts).Extract() + actual, err := zones.Create(context.TODO(), client.ServiceClient(fakeServer), createOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, &CreatedZone, actual) } func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleUpdateSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleUpdateSuccessfully(t, fakeServer) var description = "Updated Description" updateOpts := zones.UpdateOpts{ @@ -89,15 +89,15 @@ func TestUpdate(t *testing.T) { UpdatedZone.TTL = 600 UpdatedZone.Description = "Updated Description" - actual, err := zones.Update(context.TODO(), client.ServiceClient(), UpdatedZone.ID, updateOpts).Extract() + actual, err := zones.Update(context.TODO(), client.ServiceClient(fakeServer), UpdatedZone.ID, updateOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, &UpdatedZone, actual) } func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDeleteSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDeleteSuccessfully(t, fakeServer) DeletedZone := CreatedZone DeletedZone.Status = "PENDING" @@ -105,16 +105,16 @@ func TestDelete(t *testing.T) { DeletedZone.TTL = 600 DeletedZone.Description = "Updated Description" - actual, err := zones.Delete(context.TODO(), client.ServiceClient(), DeletedZone.ID).Extract() + actual, err := zones.Delete(context.TODO(), client.ServiceClient(fakeServer), DeletedZone.ID).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, &DeletedZone, actual) } func TestShare(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/zones/zone-id/shares", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/zones/zone-id/shares", func(w http.ResponseWriter, r *http.Request) { th.AssertEquals(t, r.Method, "POST") body, err := io.ReadAll(r.Body) @@ -133,29 +133,29 @@ func TestShare(t *testing.T) { }) opts := zones.ShareZoneOpts{TargetProjectID: "project-id"} - zone, err := zones.Share(context.TODO(), client.ServiceClient(), "zone-id", opts).Extract() + zone, err := zones.Share(context.TODO(), client.ServiceClient(fakeServer), "zone-id", opts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, ShareZone, *zone) } func TestUnshare(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/zones/zone-id/shares/share-id", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/zones/zone-id/shares/share-id", func(w http.ResponseWriter, r *http.Request) { th.AssertEquals(t, r.Method, "DELETE") w.WriteHeader(http.StatusNoContent) }) - err := zones.Unshare(context.TODO(), client.ServiceClient(), "zone-id", "share-id").ExtractErr() + err := zones.Unshare(context.TODO(), client.ServiceClient(fakeServer), "zone-id", "share-id").ExtractErr() th.AssertNoErr(t, err) } func TestListShares(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/zones/zone-id/shares", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/zones/zone-id/shares", func(w http.ResponseWriter, r *http.Request) { th.AssertEquals(t, r.Method, "GET") th.AssertEquals(t, "true", r.Header.Get("X-Auth-All-Projects")) @@ -166,7 +166,7 @@ func TestListShares(t *testing.T) { opts := zones.ListSharesOpts{ AllProjects: true, } - pages, err := zones.ListShares(client.ServiceClient(), "zone-id", opts).AllPages(context.TODO()) + pages, err := zones.ListShares(client.ServiceClient(fakeServer), "zone-id", opts).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := zones.ExtractZoneShares(pages) th.AssertNoErr(t, err) diff --git a/openstack/identity/v2/extensions/testing/fixtures_test.go b/openstack/identity/v2/extensions/testing/fixtures_test.go index 8e9bfa14da..cffbc1ee3f 100644 --- a/openstack/identity/v2/extensions/testing/fixtures_test.go +++ b/openstack/identity/v2/extensions/testing/fixtures_test.go @@ -30,8 +30,8 @@ const ListOutput = ` // HandleListExtensionsSuccessfully creates an HTTP handler that returns ListOutput for a List // call. -func HandleListExtensionsSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/extensions", func(w http.ResponseWriter, r *http.Request) { +func HandleListExtensionsSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/extensions", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/identity/v2/extensions/testing/requests_test.go b/openstack/identity/v2/extensions/testing/requests_test.go index 53c10ab169..0ad8310e14 100644 --- a/openstack/identity/v2/extensions/testing/requests_test.go +++ b/openstack/identity/v2/extensions/testing/requests_test.go @@ -12,12 +12,12 @@ import ( ) func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListExtensionsSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListExtensionsSuccessfully(t, fakeServer) count := 0 - err := extensions.List(client.ServiceClient()).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := extensions.List(client.ServiceClient(fakeServer)).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := extensions.ExtractExtensions(page) th.AssertNoErr(t, err) @@ -30,11 +30,11 @@ func TestList(t *testing.T) { } func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - common.HandleGetExtensionSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + common.HandleGetExtensionSuccessfully(t, fakeServer) - actual, err := extensions.Get(context.TODO(), client.ServiceClient(), "agent").Extract() + actual, err := extensions.Get(context.TODO(), client.ServiceClient(fakeServer), "agent").Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, common.SingleExtension, actual) } diff --git a/openstack/identity/v2/roles/testing/fixtures_test.go b/openstack/identity/v2/roles/testing/fixtures_test.go index 6893dc32e0..ea67ae9876 100644 --- a/openstack/identity/v2/roles/testing/fixtures_test.go +++ b/openstack/identity/v2/roles/testing/fixtures_test.go @@ -9,8 +9,8 @@ import ( "github.com/gophercloud/gophercloud/v2/testhelper/client" ) -func MockListRoleResponse(t *testing.T) { - th.Mux.HandleFunc("/OS-KSADM/roles", func(w http.ResponseWriter, r *http.Request) { +func MockListRoleResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/OS-KSADM/roles", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -31,16 +31,16 @@ func MockListRoleResponse(t *testing.T) { }) } -func MockAddUserRoleResponse(t *testing.T) { - th.Mux.HandleFunc("/tenants/{tenant_id}/users/{user_id}/roles/OS-KSADM/{role_id}", func(w http.ResponseWriter, r *http.Request) { +func MockAddUserRoleResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/tenants/{tenant_id}/users/{user_id}/roles/OS-KSADM/{role_id}", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusCreated) }) } -func MockDeleteUserRoleResponse(t *testing.T) { - th.Mux.HandleFunc("/tenants/{tenant_id}/users/{user_id}/roles/OS-KSADM/{role_id}", func(w http.ResponseWriter, r *http.Request) { +func MockDeleteUserRoleResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/tenants/{tenant_id}/users/{user_id}/roles/OS-KSADM/{role_id}", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) diff --git a/openstack/identity/v2/roles/testing/requests_test.go b/openstack/identity/v2/roles/testing/requests_test.go index a75f362208..52b4c09415 100644 --- a/openstack/identity/v2/roles/testing/requests_test.go +++ b/openstack/identity/v2/roles/testing/requests_test.go @@ -11,14 +11,14 @@ import ( ) func TestRole(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockListRoleResponse(t) + MockListRoleResponse(t, fakeServer) count := 0 - err := roles.List(client.ServiceClient()).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := roles.List(client.ServiceClient(fakeServer)).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := roles.ExtractRoles(page) if err != nil { @@ -44,23 +44,23 @@ func TestRole(t *testing.T) { } func TestAddUser(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockAddUserRoleResponse(t) + MockAddUserRoleResponse(t, fakeServer) - err := roles.AddUser(context.TODO(), client.ServiceClient(), "{tenant_id}", "{user_id}", "{role_id}").ExtractErr() + err := roles.AddUser(context.TODO(), client.ServiceClient(fakeServer), "{tenant_id}", "{user_id}", "{role_id}").ExtractErr() th.AssertNoErr(t, err) } func TestDeleteUser(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockDeleteUserRoleResponse(t) + MockDeleteUserRoleResponse(t, fakeServer) - err := roles.DeleteUser(context.TODO(), client.ServiceClient(), "{tenant_id}", "{user_id}", "{role_id}").ExtractErr() + err := roles.DeleteUser(context.TODO(), client.ServiceClient(fakeServer), "{tenant_id}", "{user_id}", "{role_id}").ExtractErr() th.AssertNoErr(t, err) } diff --git a/openstack/identity/v2/tenants/testing/fixtures_test.go b/openstack/identity/v2/tenants/testing/fixtures_test.go index e7de74ccd5..e35fd52752 100644 --- a/openstack/identity/v2/tenants/testing/fixtures_test.go +++ b/openstack/identity/v2/tenants/testing/fixtures_test.go @@ -51,8 +51,8 @@ var ExpectedTenantSlice = []tenants.Tenant{RedTeam, BlueTeam} // HandleListTenantsSuccessfully creates an HTTP handler at `/tenants` on the test handler mux that // responds with a list of two tenants. -func HandleListTenantsSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/tenants", func(w http.ResponseWriter, r *http.Request) { +func HandleListTenantsSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/tenants", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -63,8 +63,8 @@ func HandleListTenantsSuccessfully(t *testing.T) { }) } -func mockCreateTenantResponse(t *testing.T) { - th.Mux.HandleFunc("/tenants", func(w http.ResponseWriter, r *http.Request) { +func mockCreateTenantResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/tenants", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -94,16 +94,16 @@ func mockCreateTenantResponse(t *testing.T) { }) } -func mockDeleteTenantResponse(t *testing.T) { - th.Mux.HandleFunc("/tenants/2466f69cd4714d89a548a68ed97ffcd4", func(w http.ResponseWriter, r *http.Request) { +func mockDeleteTenantResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/tenants/2466f69cd4714d89a548a68ed97ffcd4", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) } -func mockUpdateTenantResponse(t *testing.T) { - th.Mux.HandleFunc("/tenants/5c62ef576dc7444cbb73b1fe84b97648", func(w http.ResponseWriter, r *http.Request) { +func mockUpdateTenantResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/tenants/5c62ef576dc7444cbb73b1fe84b97648", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -133,8 +133,8 @@ func mockUpdateTenantResponse(t *testing.T) { }) } -func mockGetTenantResponse(t *testing.T) { - th.Mux.HandleFunc("/tenants/5c62ef576dc7444cbb73b1fe84b97648", func(w http.ResponseWriter, r *http.Request) { +func mockGetTenantResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/tenants/5c62ef576dc7444cbb73b1fe84b97648", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/identity/v2/tenants/testing/requests_test.go b/openstack/identity/v2/tenants/testing/requests_test.go index 1e3e05ce3c..d658d37286 100644 --- a/openstack/identity/v2/tenants/testing/requests_test.go +++ b/openstack/identity/v2/tenants/testing/requests_test.go @@ -12,12 +12,12 @@ import ( ) func TestListTenants(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListTenantsSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListTenantsSuccessfully(t, fakeServer) count := 0 - err := tenants.List(client.ServiceClient(), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := tenants.List(client.ServiceClient(fakeServer), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := tenants.ExtractTenants(page) @@ -32,10 +32,10 @@ func TestListTenants(t *testing.T) { } func TestCreateTenant(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - mockCreateTenantResponse(t) + mockCreateTenantResponse(t, fakeServer) opts := tenants.CreateOpts{ Name: "new_tenant", @@ -43,7 +43,7 @@ func TestCreateTenant(t *testing.T) { Enabled: gophercloud.Enabled, } - tenant, err := tenants.Create(context.TODO(), client.ServiceClient(), opts).Extract() + tenant, err := tenants.Create(context.TODO(), client.ServiceClient(fakeServer), opts).Extract() th.AssertNoErr(t, err) @@ -58,20 +58,20 @@ func TestCreateTenant(t *testing.T) { } func TestDeleteTenant(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - mockDeleteTenantResponse(t) + mockDeleteTenantResponse(t, fakeServer) - err := tenants.Delete(context.TODO(), client.ServiceClient(), "2466f69cd4714d89a548a68ed97ffcd4").ExtractErr() + err := tenants.Delete(context.TODO(), client.ServiceClient(fakeServer), "2466f69cd4714d89a548a68ed97ffcd4").ExtractErr() th.AssertNoErr(t, err) } func TestUpdateTenant(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - mockUpdateTenantResponse(t) + mockUpdateTenantResponse(t, fakeServer) id := "5c62ef576dc7444cbb73b1fe84b97648" description := "This is new name" @@ -81,7 +81,7 @@ func TestUpdateTenant(t *testing.T) { Enabled: gophercloud.Enabled, } - tenant, err := tenants.Update(context.TODO(), client.ServiceClient(), id, opts).Extract() + tenant, err := tenants.Update(context.TODO(), client.ServiceClient(fakeServer), id, opts).Extract() th.AssertNoErr(t, err) @@ -96,12 +96,12 @@ func TestUpdateTenant(t *testing.T) { } func TestGetTenant(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - mockGetTenantResponse(t) + mockGetTenantResponse(t, fakeServer) - tenant, err := tenants.Get(context.TODO(), client.ServiceClient(), "5c62ef576dc7444cbb73b1fe84b97648").Extract() + tenant, err := tenants.Get(context.TODO(), client.ServiceClient(fakeServer), "5c62ef576dc7444cbb73b1fe84b97648").Extract() th.AssertNoErr(t, err) expected := &tenants.Tenant{ diff --git a/openstack/identity/v2/tokens/testing/fixtures_test.go b/openstack/identity/v2/tokens/testing/fixtures_test.go index 6ed7a3f2e6..bd093fc7d5 100644 --- a/openstack/identity/v2/tokens/testing/fixtures_test.go +++ b/openstack/identity/v2/tokens/testing/fixtures_test.go @@ -142,8 +142,8 @@ const TokenGetResponse = ` // HandleTokenPost expects a POST against a /tokens handler, ensures that the request body has been // constructed properly given certain auth options, and returns the result. -func HandleTokenPost(t *testing.T, requestJSON string) { - th.Mux.HandleFunc("/tokens", func(w http.ResponseWriter, r *http.Request) { +func HandleTokenPost(t *testing.T, fakeServer th.FakeServer, requestJSON string) { + fakeServer.Mux.HandleFunc("/tokens", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") @@ -158,8 +158,8 @@ func HandleTokenPost(t *testing.T, requestJSON string) { // HandleTokenGet expects a Get against a /tokens handler, ensures that the request body has been // constructed properly given certain auth options, and returns the result. -func HandleTokenGet(t *testing.T, token string) { - th.Mux.HandleFunc("/tokens/"+token, func(w http.ResponseWriter, r *http.Request) { +func HandleTokenGet(t *testing.T, fakeServer th.FakeServer, token string) { + fakeServer.Mux.HandleFunc("/tokens/"+token, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/identity/v2/tokens/testing/requests_test.go b/openstack/identity/v2/tokens/testing/requests_test.go index a688369d65..21ff0a814d 100644 --- a/openstack/identity/v2/tokens/testing/requests_test.go +++ b/openstack/identity/v2/tokens/testing/requests_test.go @@ -11,19 +11,19 @@ import ( ) func tokenPost(t *testing.T, options gophercloud.AuthOptions, requestJSON string) tokens.CreateResult { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleTokenPost(t, requestJSON) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleTokenPost(t, fakeServer, requestJSON) - return tokens.Create(context.TODO(), client.ServiceClient(), options) + return tokens.Create(context.TODO(), client.ServiceClient(fakeServer), options) } func tokenPostErr(t *testing.T, options gophercloud.AuthOptions, expectedErr error) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleTokenPost(t, "") + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleTokenPost(t, fakeServer, "") - actualErr := tokens.Create(context.TODO(), client.ServiceClient(), options).Err + actualErr := tokens.Create(context.TODO(), client.ServiceClient(fakeServer), options).Err th.CheckDeepEquals(t, expectedErr, actualErr) } @@ -94,10 +94,10 @@ func TestRequireUsername(t *testing.T) { } func tokenGet(t *testing.T, tokenId string) tokens.GetResult { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleTokenGet(t, tokenId) - return tokens.Get(context.TODO(), client.ServiceClient(), tokenId) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleTokenGet(t, fakeServer, tokenId) + return tokens.Get(context.TODO(), client.ServiceClient(fakeServer), tokenId) } func TestGetWithToken(t *testing.T) { diff --git a/openstack/identity/v2/users/testing/fixtures_test.go b/openstack/identity/v2/users/testing/fixtures_test.go index 6a0ed5eacd..260333293a 100644 --- a/openstack/identity/v2/users/testing/fixtures_test.go +++ b/openstack/identity/v2/users/testing/fixtures_test.go @@ -9,8 +9,8 @@ import ( "github.com/gophercloud/gophercloud/v2/testhelper/client" ) -func MockListUserResponse(t *testing.T) { - th.Mux.HandleFunc("/users", func(w http.ResponseWriter, r *http.Request) { +func MockListUserResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/users", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -42,8 +42,8 @@ func MockListUserResponse(t *testing.T) { }) } -func mockCreateUserResponse(t *testing.T) { - th.Mux.HandleFunc("/users", func(w http.ResponseWriter, r *http.Request) { +func mockCreateUserResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/users", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -75,8 +75,8 @@ func mockCreateUserResponse(t *testing.T) { }) } -func mockGetUserResponse(t *testing.T) { - th.Mux.HandleFunc("/users/new_user", func(w http.ResponseWriter, r *http.Request) { +func mockGetUserResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/users/new_user", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -97,8 +97,8 @@ func mockGetUserResponse(t *testing.T) { }) } -func mockUpdateUserResponse(t *testing.T) { - th.Mux.HandleFunc("/users/c39e3de9be2d4c779f1dfd6abacc176d", func(w http.ResponseWriter, r *http.Request) { +func mockUpdateUserResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/users/c39e3de9be2d4c779f1dfd6abacc176d", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -129,16 +129,16 @@ func mockUpdateUserResponse(t *testing.T) { }) } -func mockDeleteUserResponse(t *testing.T) { - th.Mux.HandleFunc("/users/c39e3de9be2d4c779f1dfd6abacc176d", func(w http.ResponseWriter, r *http.Request) { +func mockDeleteUserResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/users/c39e3de9be2d4c779f1dfd6abacc176d", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) } -func mockListRolesResponse(t *testing.T) { - th.Mux.HandleFunc("/tenants/1d8b6120dcc640fda4fc9194ffc80273/users/c39e3de9be2d4c779f1dfd6abacc176d/roles", func(w http.ResponseWriter, r *http.Request) { +func mockListRolesResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/tenants/1d8b6120dcc640fda4fc9194ffc80273/users/c39e3de9be2d4c779f1dfd6abacc176d/roles", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/identity/v2/users/testing/requests_test.go b/openstack/identity/v2/users/testing/requests_test.go index c66207d0c3..78553213e4 100644 --- a/openstack/identity/v2/users/testing/requests_test.go +++ b/openstack/identity/v2/users/testing/requests_test.go @@ -12,14 +12,14 @@ import ( ) func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockListUserResponse(t) + MockListUserResponse(t, fakeServer) count := 0 - err := users.List(client.ServiceClient()).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := users.List(client.ServiceClient(fakeServer)).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := users.ExtractUsers(page) th.AssertNoErr(t, err) @@ -50,10 +50,10 @@ func TestList(t *testing.T) { } func TestCreateUser(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - mockCreateUserResponse(t) + mockCreateUserResponse(t, fakeServer) opts := users.CreateOpts{ Name: "new_user", @@ -62,7 +62,7 @@ func TestCreateUser(t *testing.T) { Email: "new_user@foo.com", } - user, err := users.Create(context.TODO(), client.ServiceClient(), opts).Extract() + user, err := users.Create(context.TODO(), client.ServiceClient(fakeServer), opts).Extract() th.AssertNoErr(t, err) @@ -78,12 +78,12 @@ func TestCreateUser(t *testing.T) { } func TestGetUser(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - mockGetUserResponse(t) + mockGetUserResponse(t, fakeServer) - user, err := users.Get(context.TODO(), client.ServiceClient(), "new_user").Extract() + user, err := users.Get(context.TODO(), client.ServiceClient(fakeServer), "new_user").Extract() th.AssertNoErr(t, err) expected := &users.User{ @@ -98,10 +98,10 @@ func TestGetUser(t *testing.T) { } func TestUpdateUser(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - mockUpdateUserResponse(t) + mockUpdateUserResponse(t, fakeServer) id := "c39e3de9be2d4c779f1dfd6abacc176d" opts := users.UpdateOpts{ @@ -110,7 +110,7 @@ func TestUpdateUser(t *testing.T) { Email: "new_email@foo.com", } - user, err := users.Update(context.TODO(), client.ServiceClient(), id, opts).Extract() + user, err := users.Update(context.TODO(), client.ServiceClient(fakeServer), id, opts).Extract() th.AssertNoErr(t, err) @@ -126,25 +126,25 @@ func TestUpdateUser(t *testing.T) { } func TestDeleteUser(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - mockDeleteUserResponse(t) + mockDeleteUserResponse(t, fakeServer) - res := users.Delete(context.TODO(), client.ServiceClient(), "c39e3de9be2d4c779f1dfd6abacc176d") + res := users.Delete(context.TODO(), client.ServiceClient(fakeServer), "c39e3de9be2d4c779f1dfd6abacc176d") th.AssertNoErr(t, res.Err) } func TestListingUserRoles(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - mockListRolesResponse(t) + mockListRolesResponse(t, fakeServer) tenantID := "1d8b6120dcc640fda4fc9194ffc80273" userID := "c39e3de9be2d4c779f1dfd6abacc176d" - err := users.ListRoles(client.ServiceClient(), tenantID, userID).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := users.ListRoles(client.ServiceClient(fakeServer), tenantID, userID).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { actual, err := users.ExtractRoles(page) th.AssertNoErr(t, err) diff --git a/openstack/identity/v3/applicationcredentials/testing/fixtures_test.go b/openstack/identity/v3/applicationcredentials/testing/fixtures_test.go index ae06c1bc57..5289cc29b3 100644 --- a/openstack/identity/v3/applicationcredentials/testing/fixtures_test.go +++ b/openstack/identity/v3/applicationcredentials/testing/fixtures_test.go @@ -407,8 +407,8 @@ var ExpectedApplicationCredentialsSlice = []applicationcredentials.ApplicationCr // HandleListApplicationCredentialsSuccessfully creates an HTTP handler at `/users` on the // test handler mux that responds with a list of two applicationcredentials. -func HandleListApplicationCredentialsSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/users/2844b2a08be147a08ef58317d6471f1f/application_credentials", func(w http.ResponseWriter, r *http.Request) { +func HandleListApplicationCredentialsSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/users/2844b2a08be147a08ef58317d6471f1f/application_credentials", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -421,8 +421,8 @@ func HandleListApplicationCredentialsSuccessfully(t *testing.T) { // HandleGetApplicationCredentialSuccessfully creates an HTTP handler at `/users` on the // test handler mux that responds with a single application credential. -func HandleGetApplicationCredentialSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/users/2844b2a08be147a08ef58317d6471f1f/application_credentials/f741662395b249c9b8acdebf1722c5ae", func(w http.ResponseWriter, r *http.Request) { +func HandleGetApplicationCredentialSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/users/2844b2a08be147a08ef58317d6471f1f/application_credentials/f741662395b249c9b8acdebf1722c5ae", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -435,8 +435,8 @@ func HandleGetApplicationCredentialSuccessfully(t *testing.T) { // HandleCreateApplicationCredentialSuccessfully creates an HTTP handler at `/users` on the // test handler mux that tests application credential creation. -func HandleCreateApplicationCredentialSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/users/2844b2a08be147a08ef58317d6471f1f/application_credentials", func(w http.ResponseWriter, r *http.Request) { +func HandleCreateApplicationCredentialSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/users/2844b2a08be147a08ef58317d6471f1f/application_credentials", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, CreateRequest) @@ -448,8 +448,8 @@ func HandleCreateApplicationCredentialSuccessfully(t *testing.T) { // HandleCreateNoOptionsApplicationCredentialSuccessfully creates an HTTP handler at `/users` on the // test handler mux that tests application credential creation. -func HandleCreateNoSecretApplicationCredentialSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/users/2844b2a08be147a08ef58317d6471f1f/application_credentials", func(w http.ResponseWriter, r *http.Request) { +func HandleCreateNoSecretApplicationCredentialSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/users/2844b2a08be147a08ef58317d6471f1f/application_credentials", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, CreateNoSecretRequest) @@ -459,8 +459,8 @@ func HandleCreateNoSecretApplicationCredentialSuccessfully(t *testing.T) { }) } -func HandleCreateUnrestrictedApplicationCredentialSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/users/2844b2a08be147a08ef58317d6471f1f/application_credentials", func(w http.ResponseWriter, r *http.Request) { +func HandleCreateUnrestrictedApplicationCredentialSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/users/2844b2a08be147a08ef58317d6471f1f/application_credentials", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, CreateUnrestrictedRequest) @@ -472,8 +472,8 @@ func HandleCreateUnrestrictedApplicationCredentialSuccessfully(t *testing.T) { // HandleDeleteApplicationCredentialSuccessfully creates an HTTP handler at `/users` on the // test handler mux that tests application credential deletion. -func HandleDeleteApplicationCredentialSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/users/2844b2a08be147a08ef58317d6471f1f/application_credentials/f741662395b249c9b8acdebf1722c5ae", func(w http.ResponseWriter, r *http.Request) { +func HandleDeleteApplicationCredentialSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/users/2844b2a08be147a08ef58317d6471f1f/application_credentials/f741662395b249c9b8acdebf1722c5ae", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -483,8 +483,8 @@ func HandleDeleteApplicationCredentialSuccessfully(t *testing.T) { // HandleListAccessRulesSuccessfully creates an HTTP handler at `/users` on the // test handler mux that responds with a list of two applicationcredentials. -func HandleListAccessRulesSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/users/2844b2a08be147a08ef58317d6471f1f/access_rules", func(w http.ResponseWriter, r *http.Request) { +func HandleListAccessRulesSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/users/2844b2a08be147a08ef58317d6471f1f/access_rules", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -497,8 +497,8 @@ func HandleListAccessRulesSuccessfully(t *testing.T) { // HandleGetAccessRuleSuccessfully creates an HTTP handler at `/users` on the // test handler mux that responds with a single application credential. -func HandleGetAccessRuleSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/users/2844b2a08be147a08ef58317d6471f1f/access_rules/07d719df00f349ef8de77d542edf010c", func(w http.ResponseWriter, r *http.Request) { +func HandleGetAccessRuleSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/users/2844b2a08be147a08ef58317d6471f1f/access_rules/07d719df00f349ef8de77d542edf010c", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -511,8 +511,8 @@ func HandleGetAccessRuleSuccessfully(t *testing.T) { // HandleDeleteAccessRuleSuccessfully creates an HTTP handler at `/users` on the // test handler mux that tests application credential deletion. -func HandleDeleteAccessRuleSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/users/2844b2a08be147a08ef58317d6471f1f/access_rules/07d719df00f349ef8de77d542edf010c", func(w http.ResponseWriter, r *http.Request) { +func HandleDeleteAccessRuleSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/users/2844b2a08be147a08ef58317d6471f1f/access_rules/07d719df00f349ef8de77d542edf010c", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/identity/v3/applicationcredentials/testing/requests_test.go b/openstack/identity/v3/applicationcredentials/testing/requests_test.go index 11d863609f..d31b183c2b 100644 --- a/openstack/identity/v3/applicationcredentials/testing/requests_test.go +++ b/openstack/identity/v3/applicationcredentials/testing/requests_test.go @@ -11,12 +11,12 @@ import ( ) func TestListApplicationCredentials(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListApplicationCredentialsSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListApplicationCredentialsSuccessfully(t, fakeServer) count := 0 - err := applicationcredentials.List(client.ServiceClient(), userID, nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := applicationcredentials.List(client.ServiceClient(fakeServer), userID, nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := applicationcredentials.ExtractApplicationCredentials(page) @@ -31,11 +31,11 @@ func TestListApplicationCredentials(t *testing.T) { } func TestListApplicationCredentialsAllPages(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListApplicationCredentialsSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListApplicationCredentialsSuccessfully(t, fakeServer) - allPages, err := applicationcredentials.List(client.ServiceClient(), userID, nil).AllPages(context.TODO()) + allPages, err := applicationcredentials.List(client.ServiceClient(fakeServer), userID, nil).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := applicationcredentials.ExtractApplicationCredentials(allPages) th.AssertNoErr(t, err) @@ -45,19 +45,19 @@ func TestListApplicationCredentialsAllPages(t *testing.T) { } func TestGetApplicationCredential(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetApplicationCredentialSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetApplicationCredentialSuccessfully(t, fakeServer) - actual, err := applicationcredentials.Get(context.TODO(), client.ServiceClient(), userID, applicationCredentialID).Extract() + actual, err := applicationcredentials.Get(context.TODO(), client.ServiceClient(fakeServer), userID, applicationCredentialID).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, ApplicationCredential, *actual) } func TestCreateApplicationCredential(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateApplicationCredentialSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCreateApplicationCredentialSuccessfully(t, fakeServer) createOpts := applicationcredentials.CreateOpts{ Name: "test", @@ -77,15 +77,15 @@ func TestCreateApplicationCredential(t *testing.T) { ApplicationCredentialResponse := ApplicationCredential ApplicationCredentialResponse.Secret = "mysecret" - actual, err := applicationcredentials.Create(context.TODO(), client.ServiceClient(), userID, createOpts).Extract() + actual, err := applicationcredentials.Create(context.TODO(), client.ServiceClient(fakeServer), userID, createOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, ApplicationCredentialResponse, *actual) } func TestCreateNoSecretApplicationCredential(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateNoSecretApplicationCredentialSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCreateNoSecretApplicationCredentialSuccessfully(t, fakeServer) createOpts := applicationcredentials.CreateOpts{ Name: "test1", @@ -94,15 +94,15 @@ func TestCreateNoSecretApplicationCredential(t *testing.T) { }, } - actual, err := applicationcredentials.Create(context.TODO(), client.ServiceClient(), userID, createOpts).Extract() + actual, err := applicationcredentials.Create(context.TODO(), client.ServiceClient(fakeServer), userID, createOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, ApplicationCredentialNoSecretResponse, *actual) } func TestCreateUnrestrictedApplicationCredential(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateUnrestrictedApplicationCredentialSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCreateUnrestrictedApplicationCredentialSuccessfully(t, fakeServer) createOpts := applicationcredentials.CreateOpts{ Name: "test2", @@ -117,27 +117,27 @@ func TestCreateUnrestrictedApplicationCredential(t *testing.T) { UnrestrictedApplicationCredentialResponse := UnrestrictedApplicationCredential UnrestrictedApplicationCredentialResponse.Secret = "generated_secret" - actual, err := applicationcredentials.Create(context.TODO(), client.ServiceClient(), userID, createOpts).Extract() + actual, err := applicationcredentials.Create(context.TODO(), client.ServiceClient(fakeServer), userID, createOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, UnrestrictedApplicationCredentialResponse, *actual) } func TestDeleteApplicationCredential(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDeleteApplicationCredentialSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDeleteApplicationCredentialSuccessfully(t, fakeServer) - res := applicationcredentials.Delete(context.TODO(), client.ServiceClient(), userID, applicationCredentialID) + res := applicationcredentials.Delete(context.TODO(), client.ServiceClient(fakeServer), userID, applicationCredentialID) th.AssertNoErr(t, res.Err) } func TestListAccessRules(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListAccessRulesSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListAccessRulesSuccessfully(t, fakeServer) count := 0 - err := applicationcredentials.ListAccessRules(client.ServiceClient(), userID).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := applicationcredentials.ListAccessRules(client.ServiceClient(fakeServer), userID).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := applicationcredentials.ExtractAccessRules(page) @@ -152,20 +152,20 @@ func TestListAccessRules(t *testing.T) { } func TestGetAccessRule(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetAccessRuleSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetAccessRuleSuccessfully(t, fakeServer) - actual, err := applicationcredentials.GetAccessRule(context.TODO(), client.ServiceClient(), userID, accessRuleID).Extract() + actual, err := applicationcredentials.GetAccessRule(context.TODO(), client.ServiceClient(fakeServer), userID, accessRuleID).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, AccessRule, *actual) } func TestDeleteAccessRule(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDeleteAccessRuleSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDeleteAccessRuleSuccessfully(t, fakeServer) - res := applicationcredentials.DeleteAccessRule(context.TODO(), client.ServiceClient(), userID, accessRuleID) + res := applicationcredentials.DeleteAccessRule(context.TODO(), client.ServiceClient(fakeServer), userID, accessRuleID) th.AssertNoErr(t, res.Err) } diff --git a/openstack/identity/v3/catalog/testing/catalog_test.go b/openstack/identity/v3/catalog/testing/catalog_test.go index 4b055081f9..5f35803ca4 100644 --- a/openstack/identity/v3/catalog/testing/catalog_test.go +++ b/openstack/identity/v3/catalog/testing/catalog_test.go @@ -11,12 +11,12 @@ import ( ) func TestListCatalog(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListCatalogSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListCatalogSuccessfully(t, fakeServer) count := 0 - err := catalog.List(client.ServiceClient()).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := catalog.List(client.ServiceClient(fakeServer)).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := catalog.ExtractServiceCatalog(page) diff --git a/openstack/identity/v3/catalog/testing/fixtures_test.go b/openstack/identity/v3/catalog/testing/fixtures_test.go index ad9e9d9ce2..310a40e68f 100644 --- a/openstack/identity/v3/catalog/testing/fixtures_test.go +++ b/openstack/identity/v3/catalog/testing/fixtures_test.go @@ -77,8 +77,8 @@ var ExpectedCatalogSlice = []tokens.CatalogEntry{{ // HandleListCatalogSuccessfully creates an HTTP handler at `/domains` on the // test handler mux that responds with a list of two domains. -func HandleListCatalogSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/auth/catalog", func(w http.ResponseWriter, r *http.Request) { +func HandleListCatalogSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/auth/catalog", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/identity/v3/credentials/testing/fixtures_test.go b/openstack/identity/v3/credentials/testing/fixtures_test.go index e32d77d0db..206700ec04 100644 --- a/openstack/identity/v3/credentials/testing/fixtures_test.go +++ b/openstack/identity/v3/credentials/testing/fixtures_test.go @@ -153,8 +153,8 @@ var ExpectedCredentialsSlice = []credentials.Credential{FirstCredential, SecondC // HandleListCredentialsSuccessfully creates an HTTP handler at `/credentials` on the // test handler mux that responds with a list of two credentials. -func HandleListCredentialsSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/credentials", func(w http.ResponseWriter, r *http.Request) { +func HandleListCredentialsSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/credentials", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -167,8 +167,8 @@ func HandleListCredentialsSuccessfully(t *testing.T) { // HandleGetCredentialSuccessfully creates an HTTP handler at `/credentials` on the // test handler mux that responds with a single credential. -func HandleGetCredentialSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/credentials/3d3367228f9c7665266604462ec60029bcd83ad89614021a80b2eb879c572510", func(w http.ResponseWriter, r *http.Request) { +func HandleGetCredentialSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/credentials/3d3367228f9c7665266604462ec60029bcd83ad89614021a80b2eb879c572510", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -181,8 +181,8 @@ func HandleGetCredentialSuccessfully(t *testing.T) { // HandleCreateCredentialSuccessfully creates an HTTP handler at `/credentials` on the // test handler mux that tests credential creation. -func HandleCreateCredentialSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/credentials", func(w http.ResponseWriter, r *http.Request) { +func HandleCreateCredentialSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/credentials", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, CreateRequest) @@ -194,8 +194,8 @@ func HandleCreateCredentialSuccessfully(t *testing.T) { // HandleDeleteCredentialSuccessfully creates an HTTP handler at `/credentials` on the // test handler mux that tests credential deletion. -func HandleDeleteCredentialSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/credentials/3d3367228f9c7665266604462ec60029bcd83ad89614021a80b2eb879c572510", func(w http.ResponseWriter, r *http.Request) { +func HandleDeleteCredentialSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/credentials/3d3367228f9c7665266604462ec60029bcd83ad89614021a80b2eb879c572510", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -205,8 +205,8 @@ func HandleDeleteCredentialSuccessfully(t *testing.T) { // HandleUpdateCredentialsSuccessfully creates an HTTP handler at `/credentials` on the // test handler mux that tests credentials update. -func HandleUpdateCredentialSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/credentials/2441494e52ab6d594a34d74586075cb299489bdd1e9389e3ab06467a4f460609", func(w http.ResponseWriter, r *http.Request) { +func HandleUpdateCredentialSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/credentials/2441494e52ab6d594a34d74586075cb299489bdd1e9389e3ab06467a4f460609", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PATCH") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, UpdateRequest) diff --git a/openstack/identity/v3/credentials/testing/requests_test.go b/openstack/identity/v3/credentials/testing/requests_test.go index 7b90817c59..86cbe93b59 100644 --- a/openstack/identity/v3/credentials/testing/requests_test.go +++ b/openstack/identity/v3/credentials/testing/requests_test.go @@ -11,12 +11,12 @@ import ( ) func TestListCredentials(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListCredentialsSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListCredentialsSuccessfully(t, fakeServer) count := 0 - err := credentials.List(client.ServiceClient(), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := credentials.List(client.ServiceClient(fakeServer), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := credentials.ExtractCredentials(page) @@ -31,11 +31,11 @@ func TestListCredentials(t *testing.T) { } func TestListCredentialsAllPages(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListCredentialsSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListCredentialsSuccessfully(t, fakeServer) - allPages, err := credentials.List(client.ServiceClient(), nil).AllPages(context.TODO()) + allPages, err := credentials.List(client.ServiceClient(fakeServer), nil).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := credentials.ExtractCredentials(allPages) th.AssertNoErr(t, err) @@ -45,19 +45,19 @@ func TestListCredentialsAllPages(t *testing.T) { } func TestGetCredential(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetCredentialSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetCredentialSuccessfully(t, fakeServer) - actual, err := credentials.Get(context.TODO(), client.ServiceClient(), credentialID).Extract() + actual, err := credentials.Get(context.TODO(), client.ServiceClient(fakeServer), credentialID).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, Credential, *actual) } func TestCreateCredential(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateCredentialSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCreateCredentialSuccessfully(t, fakeServer) createOpts := credentials.CreateOpts{ ProjectID: projectID, @@ -68,24 +68,24 @@ func TestCreateCredential(t *testing.T) { CredentialResponse := Credential - actual, err := credentials.Create(context.TODO(), client.ServiceClient(), createOpts).Extract() + actual, err := credentials.Create(context.TODO(), client.ServiceClient(fakeServer), createOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, CredentialResponse, *actual) } func TestDeleteCredential(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDeleteCredentialSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDeleteCredentialSuccessfully(t, fakeServer) - res := credentials.Delete(context.TODO(), client.ServiceClient(), credentialID) + res := credentials.Delete(context.TODO(), client.ServiceClient(fakeServer), credentialID) th.AssertNoErr(t, res.Err) } func TestUpdateCredential(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleUpdateCredentialSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleUpdateCredentialSuccessfully(t, fakeServer) updateOpts := credentials.UpdateOpts{ ProjectID: "731fc6f265cd486d900f16e84c5cb594", @@ -94,7 +94,7 @@ func TestUpdateCredential(t *testing.T) { Blob: "{\"access\":\"181920\",\"secret\":\"secretKey\"}", } - actual, err := credentials.Update(context.TODO(), client.ServiceClient(), "2441494e52ab6d594a34d74586075cb299489bdd1e9389e3ab06467a4f460609", updateOpts).Extract() + actual, err := credentials.Update(context.TODO(), client.ServiceClient(fakeServer), "2441494e52ab6d594a34d74586075cb299489bdd1e9389e3ab06467a4f460609", updateOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, SecondCredentialUpdated, *actual) } diff --git a/openstack/identity/v3/domains/testing/fixtures_test.go b/openstack/identity/v3/domains/testing/fixtures_test.go index a35813a23c..6c0f570059 100644 --- a/openstack/identity/v3/domains/testing/fixtures_test.go +++ b/openstack/identity/v3/domains/testing/fixtures_test.go @@ -181,8 +181,8 @@ var ExpectedDomainsSlice = []domains.Domain{FirstDomain, SecondDomain} // HandleListAvailableDomainsSuccessfully creates an HTTP handler at `/auth/domains` // on the test handler mux that responds with a list of two domains. -func HandleListAvailableDomainsSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/auth/domains", func(w http.ResponseWriter, r *http.Request) { +func HandleListAvailableDomainsSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/auth/domains", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -195,8 +195,8 @@ func HandleListAvailableDomainsSuccessfully(t *testing.T) { // HandleListDomainsSuccessfully creates an HTTP handler at `/domains` on the // test handler mux that responds with a list of two domains. -func HandleListDomainsSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/domains", func(w http.ResponseWriter, r *http.Request) { +func HandleListDomainsSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/domains", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -209,8 +209,8 @@ func HandleListDomainsSuccessfully(t *testing.T) { // HandleGetDomainSuccessfully creates an HTTP handler at `/domains` on the // test handler mux that responds with a single domain. -func HandleGetDomainSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/domains/9fe1d3", func(w http.ResponseWriter, r *http.Request) { +func HandleGetDomainSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/domains/9fe1d3", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -223,8 +223,8 @@ func HandleGetDomainSuccessfully(t *testing.T) { // HandleCreateDomainSuccessfully creates an HTTP handler at `/domains` on the // test handler mux that tests domain creation. -func HandleCreateDomainSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/domains", func(w http.ResponseWriter, r *http.Request) { +func HandleCreateDomainSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/domains", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, CreateRequest) @@ -236,8 +236,8 @@ func HandleCreateDomainSuccessfully(t *testing.T) { // HandleDeleteDomainSuccessfully creates an HTTP handler at `/domains` on the // test handler mux that tests domain deletion. -func HandleDeleteDomainSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/domains/9fe1d3", func(w http.ResponseWriter, r *http.Request) { +func HandleDeleteDomainSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/domains/9fe1d3", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -247,8 +247,8 @@ func HandleDeleteDomainSuccessfully(t *testing.T) { // HandleUpdateDomainSuccessfully creates an HTTP handler at `/domains` on the // test handler mux that tests domain update. -func HandleUpdateDomainSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/domains/9fe1d3", func(w http.ResponseWriter, r *http.Request) { +func HandleUpdateDomainSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/domains/9fe1d3", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PATCH") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, UpdateRequest) diff --git a/openstack/identity/v3/domains/testing/requests_test.go b/openstack/identity/v3/domains/testing/requests_test.go index 1e0f5ef8f4..00819c7882 100644 --- a/openstack/identity/v3/domains/testing/requests_test.go +++ b/openstack/identity/v3/domains/testing/requests_test.go @@ -11,12 +11,12 @@ import ( ) func TestListAvailableDomains(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListAvailableDomainsSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListAvailableDomainsSuccessfully(t, fakeServer) count := 0 - err := domains.ListAvailable(client.ServiceClient()).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := domains.ListAvailable(client.ServiceClient(fakeServer)).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := domains.ExtractDomains(page) @@ -31,12 +31,12 @@ func TestListAvailableDomains(t *testing.T) { } func TestListDomains(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListDomainsSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListDomainsSuccessfully(t, fakeServer) count := 0 - err := domains.List(client.ServiceClient(), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := domains.List(client.ServiceClient(fakeServer), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := domains.ExtractDomains(page) @@ -51,11 +51,11 @@ func TestListDomains(t *testing.T) { } func TestListDomainsAllPages(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListDomainsSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListDomainsSuccessfully(t, fakeServer) - allPages, err := domains.List(client.ServiceClient(), nil).AllPages(context.TODO()) + allPages, err := domains.List(client.ServiceClient(fakeServer), nil).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := domains.ExtractDomains(allPages) th.AssertNoErr(t, err) @@ -63,49 +63,49 @@ func TestListDomainsAllPages(t *testing.T) { } func TestGetDomain(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetDomainSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetDomainSuccessfully(t, fakeServer) - actual, err := domains.Get(context.TODO(), client.ServiceClient(), "9fe1d3").Extract() + actual, err := domains.Get(context.TODO(), client.ServiceClient(fakeServer), "9fe1d3").Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, SecondDomain, *actual) } func TestCreateDomain(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateDomainSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCreateDomainSuccessfully(t, fakeServer) createOpts := domains.CreateOpts{ Name: "domain two", } - actual, err := domains.Create(context.TODO(), client.ServiceClient(), createOpts).Extract() + actual, err := domains.Create(context.TODO(), client.ServiceClient(fakeServer), createOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, SecondDomain, *actual) } func TestDeleteDomain(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDeleteDomainSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDeleteDomainSuccessfully(t, fakeServer) - res := domains.Delete(context.TODO(), client.ServiceClient(), "9fe1d3") + res := domains.Delete(context.TODO(), client.ServiceClient(fakeServer), "9fe1d3") th.AssertNoErr(t, res.Err) } func TestUpdateDomain(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleUpdateDomainSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleUpdateDomainSuccessfully(t, fakeServer) var description = "Staging Domain" updateOpts := domains.UpdateOpts{ Description: &description, } - actual, err := domains.Update(context.TODO(), client.ServiceClient(), "9fe1d3", updateOpts).Extract() + actual, err := domains.Update(context.TODO(), client.ServiceClient(fakeServer), "9fe1d3", updateOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, SecondDomainUpdated, *actual) } diff --git a/openstack/identity/v3/ec2credentials/testing/fixtures_test.go b/openstack/identity/v3/ec2credentials/testing/fixtures_test.go index 72a82e1ff4..eb29689deb 100644 --- a/openstack/identity/v3/ec2credentials/testing/fixtures_test.go +++ b/openstack/identity/v3/ec2credentials/testing/fixtures_test.go @@ -111,8 +111,8 @@ var ExpectedEC2CredentialsSlice = []ec2credentials.Credential{EC2Credential, Sec // HandleListEC2CredentialsSuccessfully creates an HTTP handler at `/users` on the // test handler mux that responds with a list of two applicationcredentials. -func HandleListEC2CredentialsSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/users/2844b2a08be147a08ef58317d6471f1f/credentials/OS-EC2", func(w http.ResponseWriter, r *http.Request) { +func HandleListEC2CredentialsSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/users/2844b2a08be147a08ef58317d6471f1f/credentials/OS-EC2", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -125,8 +125,8 @@ func HandleListEC2CredentialsSuccessfully(t *testing.T) { // HandleGetEC2CredentialSuccessfully creates an HTTP handler at `/users` on the // test handler mux that responds with a single application credential. -func HandleGetEC2CredentialSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/users/2844b2a08be147a08ef58317d6471f1f/credentials/OS-EC2/f741662395b249c9b8acdebf1722c5ae", func(w http.ResponseWriter, r *http.Request) { +func HandleGetEC2CredentialSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/users/2844b2a08be147a08ef58317d6471f1f/credentials/OS-EC2/f741662395b249c9b8acdebf1722c5ae", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -139,8 +139,8 @@ func HandleGetEC2CredentialSuccessfully(t *testing.T) { // HandleCreateEC2CredentialSuccessfully creates an HTTP handler at `/users` on the // test handler mux that tests application credential creation. -func HandleCreateEC2CredentialSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/users/2844b2a08be147a08ef58317d6471f1f/credentials/OS-EC2", func(w http.ResponseWriter, r *http.Request) { +func HandleCreateEC2CredentialSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/users/2844b2a08be147a08ef58317d6471f1f/credentials/OS-EC2", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, CreateRequest) @@ -152,8 +152,8 @@ func HandleCreateEC2CredentialSuccessfully(t *testing.T) { // HandleDeleteEC2CredentialSuccessfully creates an HTTP handler at `/users` on the // test handler mux that tests application credential deletion. -func HandleDeleteEC2CredentialSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/users/2844b2a08be147a08ef58317d6471f1f/credentials/OS-EC2/f741662395b249c9b8acdebf1722c5ae", func(w http.ResponseWriter, r *http.Request) { +func HandleDeleteEC2CredentialSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/users/2844b2a08be147a08ef58317d6471f1f/credentials/OS-EC2/f741662395b249c9b8acdebf1722c5ae", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/identity/v3/ec2credentials/testing/requests_test.go b/openstack/identity/v3/ec2credentials/testing/requests_test.go index a20e4b70f9..1344aed51c 100644 --- a/openstack/identity/v3/ec2credentials/testing/requests_test.go +++ b/openstack/identity/v3/ec2credentials/testing/requests_test.go @@ -11,12 +11,12 @@ import ( ) func TestListEC2Credentials(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListEC2CredentialsSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListEC2CredentialsSuccessfully(t, fakeServer) count := 0 - err := ec2credentials.List(client.ServiceClient(), userID).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := ec2credentials.List(client.ServiceClient(fakeServer), userID).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := ec2credentials.ExtractCredentials(page) @@ -31,11 +31,11 @@ func TestListEC2Credentials(t *testing.T) { } func TestListEC2CredentialsAllPages(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListEC2CredentialsSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListEC2CredentialsSuccessfully(t, fakeServer) - allPages, err := ec2credentials.List(client.ServiceClient(), userID).AllPages(context.TODO()) + allPages, err := ec2credentials.List(client.ServiceClient(fakeServer), userID).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := ec2credentials.ExtractCredentials(allPages) th.AssertNoErr(t, err) @@ -43,34 +43,34 @@ func TestListEC2CredentialsAllPages(t *testing.T) { } func TestGetEC2Credential(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetEC2CredentialSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetEC2CredentialSuccessfully(t, fakeServer) - actual, err := ec2credentials.Get(context.TODO(), client.ServiceClient(), userID, credentialID).Extract() + actual, err := ec2credentials.Get(context.TODO(), client.ServiceClient(fakeServer), userID, credentialID).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, EC2Credential, *actual) } func TestCreateEC2Credential(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateEC2CredentialSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCreateEC2CredentialSuccessfully(t, fakeServer) createOpts := ec2credentials.CreateOpts{ TenantID: "6238dee2fec940a6bf31e49e9faf995a", } - actual, err := ec2credentials.Create(context.TODO(), client.ServiceClient(), userID, createOpts).Extract() + actual, err := ec2credentials.Create(context.TODO(), client.ServiceClient(fakeServer), userID, createOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, EC2Credential, *actual) } func TestDeleteEC2Credential(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDeleteEC2CredentialSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDeleteEC2CredentialSuccessfully(t, fakeServer) - res := ec2credentials.Delete(context.TODO(), client.ServiceClient(), userID, credentialID) + res := ec2credentials.Delete(context.TODO(), client.ServiceClient(fakeServer), userID, credentialID) th.AssertNoErr(t, res.Err) } diff --git a/openstack/identity/v3/ec2tokens/testing/requests_test.go b/openstack/identity/v3/ec2tokens/testing/requests_test.go index 8fe0b3c3f8..ae075a4c89 100644 --- a/openstack/identity/v3/ec2tokens/testing/requests_test.go +++ b/openstack/identity/v3/ec2tokens/testing/requests_test.go @@ -17,15 +17,15 @@ import ( // authTokenPost verifies that providing certain AuthOptions and Scope results in an expected JSON structure. func authTokenPost(t *testing.T, options ec2tokens.AuthOptions, requestJSON string) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() client := gophercloud.ServiceClient{ ProviderClient: &gophercloud.ProviderClient{}, - Endpoint: th.Endpoint(), + Endpoint: fakeServer.Endpoint(), } - th.Mux.HandleFunc("/ec2tokens", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/ec2tokens", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") diff --git a/openstack/identity/v3/endpoints/testing/requests_test.go b/openstack/identity/v3/endpoints/testing/requests_test.go index ad138acd49..7c418aed88 100644 --- a/openstack/identity/v3/endpoints/testing/requests_test.go +++ b/openstack/identity/v3/endpoints/testing/requests_test.go @@ -14,10 +14,10 @@ import ( ) func TestCreateSuccessful(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/endpoints", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/endpoints", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, `{ @@ -47,7 +47,7 @@ func TestCreateSuccessful(t *testing.T) { }`) }) - actual, err := endpoints.Create(context.TODO(), client.ServiceClient(), endpoints.CreateOpts{ + actual, err := endpoints.Create(context.TODO(), client.ServiceClient(fakeServer), endpoints.CreateOpts{ Availability: gophercloud.AvailabilityPublic, Name: "the-endiest-of-points", Region: "underground", @@ -70,10 +70,10 @@ func TestCreateSuccessful(t *testing.T) { } func TestListEndpoints(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/endpoints", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/endpoints", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -113,7 +113,7 @@ func TestListEndpoints(t *testing.T) { }) count := 0 - err := endpoints.List(client.ServiceClient(), endpoints.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := endpoints.List(client.ServiceClient(fakeServer), endpoints.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := endpoints.ExtractEndpoints(page) if err != nil { @@ -149,10 +149,10 @@ func TestListEndpoints(t *testing.T) { } func TestGetEndpoint(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/endpoints/12", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/endpoints/12", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -172,7 +172,7 @@ func TestGetEndpoint(t *testing.T) { }`) }) - actual, err := endpoints.Get(context.TODO(), client.ServiceClient(), "12").Extract() + actual, err := endpoints.Get(context.TODO(), client.ServiceClient(fakeServer), "12").Extract() if err != nil { t.Fatalf("Unexpected error from Get: %v", err) } @@ -190,10 +190,10 @@ func TestGetEndpoint(t *testing.T) { } func TestUpdateEndpoint(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/endpoints/12", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/endpoints/12", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PATCH") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, `{ @@ -219,7 +219,7 @@ func TestUpdateEndpoint(t *testing.T) { }`) }) - actual, err := endpoints.Update(context.TODO(), client.ServiceClient(), "12", endpoints.UpdateOpts{ + actual, err := endpoints.Update(context.TODO(), client.ServiceClient(fakeServer), "12", endpoints.UpdateOpts{ Name: "renamed", Region: "somewhere-else", }).Extract() @@ -240,16 +240,16 @@ func TestUpdateEndpoint(t *testing.T) { } func TestDeleteEndpoint(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/endpoints/34", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/endpoints/34", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) - res := endpoints.Delete(context.TODO(), client.ServiceClient(), "34") + res := endpoints.Delete(context.TODO(), client.ServiceClient(fakeServer), "34") th.AssertNoErr(t, res.Err) } diff --git a/openstack/identity/v3/federation/testing/fixtures_test.go b/openstack/identity/v3/federation/testing/fixtures_test.go index 229d2f489a..7213e3a913 100644 --- a/openstack/identity/v3/federation/testing/fixtures_test.go +++ b/openstack/identity/v3/federation/testing/fixtures_test.go @@ -281,8 +281,8 @@ var ExpectedMappingsSlice = []federation.Mapping{MappingACME} // HandleListMappingsSuccessfully creates an HTTP handler at `/mappings` on the // test handler mux that responds with a list of two mappings. -func HandleListMappingsSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/OS-FEDERATION/mappings", func(w http.ResponseWriter, r *http.Request) { +func HandleListMappingsSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/OS-FEDERATION/mappings", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -295,8 +295,8 @@ func HandleListMappingsSuccessfully(t *testing.T) { // HandleCreateMappingSuccessfully creates an HTTP handler at `/mappings` on the // test handler mux that tests mapping creation. -func HandleCreateMappingSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/OS-FEDERATION/mappings/ACME", func(w http.ResponseWriter, r *http.Request) { +func HandleCreateMappingSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/OS-FEDERATION/mappings/ACME", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, CreateRequest) @@ -308,8 +308,8 @@ func HandleCreateMappingSuccessfully(t *testing.T) { // HandleGetMappingSuccessfully creates an HTTP handler at `/mappings` on the // test handler mux that responds with a single mapping. -func HandleGetMappingSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/OS-FEDERATION/mappings/ACME", func(w http.ResponseWriter, r *http.Request) { +func HandleGetMappingSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/OS-FEDERATION/mappings/ACME", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -322,8 +322,8 @@ func HandleGetMappingSuccessfully(t *testing.T) { // HandleUpdateMappingSuccessfully creates an HTTP handler at `/mappings` on the // test handler mux that tests mapping update. -func HandleUpdateMappingSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/OS-FEDERATION/mappings/ACME", func(w http.ResponseWriter, r *http.Request) { +func HandleUpdateMappingSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/OS-FEDERATION/mappings/ACME", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PATCH") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, UpdateRequest) @@ -335,8 +335,8 @@ func HandleUpdateMappingSuccessfully(t *testing.T) { // HandleDeleteMappingSuccessfully creates an HTTP handler at `/mappings` on the // test handler mux that tests mapping deletion. -func HandleDeleteMappingSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/OS-FEDERATION/mappings/ACME", func(w http.ResponseWriter, r *http.Request) { +func HandleDeleteMappingSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/OS-FEDERATION/mappings/ACME", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/identity/v3/federation/testing/requests_test.go b/openstack/identity/v3/federation/testing/requests_test.go index 0d156b8d19..29f2db2a85 100644 --- a/openstack/identity/v3/federation/testing/requests_test.go +++ b/openstack/identity/v3/federation/testing/requests_test.go @@ -11,12 +11,12 @@ import ( ) func TestListMappings(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListMappingsSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListMappingsSuccessfully(t, fakeServer) count := 0 - err := federation.ListMappings(client.ServiceClient()).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := federation.ListMappings(client.ServiceClient(fakeServer)).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := federation.ExtractMappings(page) @@ -31,11 +31,11 @@ func TestListMappings(t *testing.T) { } func TestListMappingsAllPages(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListMappingsSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListMappingsSuccessfully(t, fakeServer) - allPages, err := federation.ListMappings(client.ServiceClient()).AllPages(context.TODO()) + allPages, err := federation.ListMappings(client.ServiceClient(fakeServer)).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := federation.ExtractMappings(allPages) th.AssertNoErr(t, err) @@ -43,9 +43,9 @@ func TestListMappingsAllPages(t *testing.T) { } func TestCreateMappings(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateMappingSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCreateMappingSuccessfully(t, fakeServer) createOpts := federation.CreateMappingOpts{ Rules: []federation.MappingRule{ @@ -78,25 +78,25 @@ func TestCreateMappings(t *testing.T) { }, } - actual, err := federation.CreateMapping(context.TODO(), client.ServiceClient(), "ACME", createOpts).Extract() + actual, err := federation.CreateMapping(context.TODO(), client.ServiceClient(fakeServer), "ACME", createOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, MappingACME, *actual) } func TestGetMapping(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetMappingSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetMappingSuccessfully(t, fakeServer) - actual, err := federation.GetMapping(context.TODO(), client.ServiceClient(), "ACME").Extract() + actual, err := federation.GetMapping(context.TODO(), client.ServiceClient(fakeServer), "ACME").Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, MappingACME, *actual) } func TestUpdateMapping(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleUpdateMappingSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleUpdateMappingSuccessfully(t, fakeServer) updateOpts := federation.UpdateMappingOpts{ Rules: []federation.MappingRule{ @@ -129,16 +129,16 @@ func TestUpdateMapping(t *testing.T) { }, } - actual, err := federation.UpdateMapping(context.TODO(), client.ServiceClient(), "ACME", updateOpts).Extract() + actual, err := federation.UpdateMapping(context.TODO(), client.ServiceClient(fakeServer), "ACME", updateOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, MappingUpdated, *actual) } func TestDeleteMapping(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDeleteMappingSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDeleteMappingSuccessfully(t, fakeServer) - res := federation.DeleteMapping(context.TODO(), client.ServiceClient(), "ACME") + res := federation.DeleteMapping(context.TODO(), client.ServiceClient(fakeServer), "ACME") th.AssertNoErr(t, res.Err) } diff --git a/openstack/identity/v3/groups/testing/fixtures_test.go b/openstack/identity/v3/groups/testing/fixtures_test.go index 415d81555f..fb5bd178dd 100644 --- a/openstack/identity/v3/groups/testing/fixtures_test.go +++ b/openstack/identity/v3/groups/testing/fixtures_test.go @@ -152,8 +152,8 @@ var ExpectedGroupsSlice = []groups.Group{FirstGroup, SecondGroup} // HandleListGroupsSuccessfully creates an HTTP handler at `/groups` on the // test handler mux that responds with a list of two groups. -func HandleListGroupsSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/groups", func(w http.ResponseWriter, r *http.Request) { +func HandleListGroupsSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/groups", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -166,8 +166,8 @@ func HandleListGroupsSuccessfully(t *testing.T) { // HandleGetGroupSuccessfully creates an HTTP handler at `/groups` on the // test handler mux that responds with a single group. -func HandleGetGroupSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/groups/9fe1d3", func(w http.ResponseWriter, r *http.Request) { +func HandleGetGroupSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/groups/9fe1d3", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -180,8 +180,8 @@ func HandleGetGroupSuccessfully(t *testing.T) { // HandleCreateGroupSuccessfully creates an HTTP handler at `/groups` on the // test handler mux that tests group creation. -func HandleCreateGroupSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/groups", func(w http.ResponseWriter, r *http.Request) { +func HandleCreateGroupSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/groups", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, CreateRequest) @@ -193,8 +193,8 @@ func HandleCreateGroupSuccessfully(t *testing.T) { // HandleUpdateGroupSuccessfully creates an HTTP handler at `/groups` on the // test handler mux that tests group update. -func HandleUpdateGroupSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/groups/9fe1d3", func(w http.ResponseWriter, r *http.Request) { +func HandleUpdateGroupSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/groups/9fe1d3", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PATCH") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, UpdateRequest) @@ -206,8 +206,8 @@ func HandleUpdateGroupSuccessfully(t *testing.T) { // HandleDeleteGroupSuccessfully creates an HTTP handler at `/groups` on the // test handler mux that tests group deletion. -func HandleDeleteGroupSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/groups/9fe1d3", func(w http.ResponseWriter, r *http.Request) { +func HandleDeleteGroupSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/groups/9fe1d3", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/identity/v3/groups/testing/requests_test.go b/openstack/identity/v3/groups/testing/requests_test.go index 5f6b7b9f56..8117368023 100644 --- a/openstack/identity/v3/groups/testing/requests_test.go +++ b/openstack/identity/v3/groups/testing/requests_test.go @@ -11,12 +11,12 @@ import ( ) func TestListGroups(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListGroupsSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListGroupsSuccessfully(t, fakeServer) count := 0 - err := groups.List(client.ServiceClient(), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := groups.List(client.ServiceClient(fakeServer), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := groups.ExtractGroups(page) @@ -31,11 +31,11 @@ func TestListGroups(t *testing.T) { } func TestListGroupsAllPages(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListGroupsSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListGroupsSuccessfully(t, fakeServer) - allPages, err := groups.List(client.ServiceClient(), nil).AllPages(context.TODO()) + allPages, err := groups.List(client.ServiceClient(fakeServer), nil).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := groups.ExtractGroups(allPages) th.AssertNoErr(t, err) @@ -77,11 +77,11 @@ func TestListGroupsFiltersCheck(t *testing.T) { } func TestGetGroup(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetGroupSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetGroupSuccessfully(t, fakeServer) - actual, err := groups.Get(context.TODO(), client.ServiceClient(), "9fe1d3").Extract() + actual, err := groups.Get(context.TODO(), client.ServiceClient(fakeServer), "9fe1d3").Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, SecondGroup, *actual) @@ -89,9 +89,9 @@ func TestGetGroup(t *testing.T) { } func TestCreateGroup(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateGroupSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCreateGroupSuccessfully(t, fakeServer) createOpts := groups.CreateOpts{ Name: "support", @@ -102,15 +102,15 @@ func TestCreateGroup(t *testing.T) { }, } - actual, err := groups.Create(context.TODO(), client.ServiceClient(), createOpts).Extract() + actual, err := groups.Create(context.TODO(), client.ServiceClient(fakeServer), createOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, SecondGroup, *actual) } func TestUpdateGroup(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleUpdateGroupSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleUpdateGroupSuccessfully(t, fakeServer) var description = "L2 Support Team" updateOpts := groups.UpdateOpts{ @@ -120,16 +120,16 @@ func TestUpdateGroup(t *testing.T) { }, } - actual, err := groups.Update(context.TODO(), client.ServiceClient(), "9fe1d3", updateOpts).Extract() + actual, err := groups.Update(context.TODO(), client.ServiceClient(fakeServer), "9fe1d3", updateOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, SecondGroupUpdated, *actual) } func TestDeleteGroup(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDeleteGroupSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDeleteGroupSuccessfully(t, fakeServer) - res := groups.Delete(context.TODO(), client.ServiceClient(), "9fe1d3") + res := groups.Delete(context.TODO(), client.ServiceClient(fakeServer), "9fe1d3") th.AssertNoErr(t, res.Err) } diff --git a/openstack/identity/v3/limits/testing/fixtures_test.go b/openstack/identity/v3/limits/testing/fixtures_test.go index 5f8cbff160..0674ffc081 100644 --- a/openstack/identity/v3/limits/testing/fixtures_test.go +++ b/openstack/identity/v3/limits/testing/fixtures_test.go @@ -175,8 +175,8 @@ var ExpectedLimitsSlice = []limits.Limit{FirstLimit, SecondLimit} // HandleGetEnforcementModelSuccessfully creates an HTTP handler at `/limits/model` on the // test handler mux that responds with a enforcement model. -func HandleGetEnforcementModelSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/limits/model", func(w http.ResponseWriter, r *http.Request) { +func HandleGetEnforcementModelSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/limits/model", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -189,8 +189,8 @@ func HandleGetEnforcementModelSuccessfully(t *testing.T) { // HandleListLimitsSuccessfully creates an HTTP handler at `/limits` on the // test handler mux that responds with a list of two limits. -func HandleListLimitsSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/limits", func(w http.ResponseWriter, r *http.Request) { +func HandleListLimitsSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/limits", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -203,8 +203,8 @@ func HandleListLimitsSuccessfully(t *testing.T) { // HandleCreateLimitSuccessfully creates an HTTP handler at `/limits` on the // test handler mux that tests limit creation. -func HandleCreateLimitSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/limits", func(w http.ResponseWriter, r *http.Request) { +func HandleCreateLimitSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/limits", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, CreateRequest) @@ -216,8 +216,8 @@ func HandleCreateLimitSuccessfully(t *testing.T) { // HandleGetLimitSuccessfully creates an HTTP handler at `/limits` on the // test handler mux that responds with a single limit. -func HandleGetLimitSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/limits/25a04c7a065c430590881c646cdcdd58", func(w http.ResponseWriter, r *http.Request) { +func HandleGetLimitSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/limits/25a04c7a065c430590881c646cdcdd58", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -230,8 +230,8 @@ func HandleGetLimitSuccessfully(t *testing.T) { // HandleUpdateLimitSuccessfully creates an HTTP handler at `/limits` on the // test handler mux that tests limit update. -func HandleUpdateLimitSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/limits/3229b3849f584faea483d6851f7aab05", func(w http.ResponseWriter, r *http.Request) { +func HandleUpdateLimitSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/limits/3229b3849f584faea483d6851f7aab05", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PATCH") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, UpdateRequest) @@ -243,8 +243,8 @@ func HandleUpdateLimitSuccessfully(t *testing.T) { // HandleDeleteLimitSuccessfully creates an HTTP handler at `/limits` on the // test handler mux that tests limit deletion. -func HandleDeleteLimitSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/limits/3229b3849f584faea483d6851f7aab05", func(w http.ResponseWriter, r *http.Request) { +func HandleDeleteLimitSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/limits/3229b3849f584faea483d6851f7aab05", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/identity/v3/limits/testing/requests_test.go b/openstack/identity/v3/limits/testing/requests_test.go index 15cf4dbb8e..e1dca5f73f 100644 --- a/openstack/identity/v3/limits/testing/requests_test.go +++ b/openstack/identity/v3/limits/testing/requests_test.go @@ -11,22 +11,22 @@ import ( ) func TestGetEnforcementModel(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetEnforcementModelSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetEnforcementModelSuccessfully(t, fakeServer) - actual, err := limits.GetEnforcementModel(context.TODO(), client.ServiceClient()).Extract() + actual, err := limits.GetEnforcementModel(context.TODO(), client.ServiceClient(fakeServer)).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, Model, *actual) } func TestListLimits(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListLimitsSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListLimitsSuccessfully(t, fakeServer) count := 0 - err := limits.List(client.ServiceClient(), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := limits.List(client.ServiceClient(fakeServer), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := limits.ExtractLimits(page) @@ -41,11 +41,11 @@ func TestListLimits(t *testing.T) { } func TestListLimitsAllPages(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListLimitsSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListLimitsSuccessfully(t, fakeServer) - allPages, err := limits.List(client.ServiceClient(), nil).AllPages(context.TODO()) + allPages, err := limits.List(client.ServiceClient(fakeServer), nil).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := limits.ExtractLimits(allPages) th.AssertNoErr(t, err) @@ -53,9 +53,9 @@ func TestListLimitsAllPages(t *testing.T) { } func TestCreateLimits(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateLimitSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCreateLimitSuccessfully(t, fakeServer) createOpts := limits.BatchCreateOpts{ limits.CreateOpts{ @@ -74,25 +74,25 @@ func TestCreateLimits(t *testing.T) { }, } - actual, err := limits.BatchCreate(context.TODO(), client.ServiceClient(), createOpts).Extract() + actual, err := limits.BatchCreate(context.TODO(), client.ServiceClient(fakeServer), createOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, ExpectedLimitsSlice, actual) } func TestGetLimit(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetLimitSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetLimitSuccessfully(t, fakeServer) - actual, err := limits.Get(context.TODO(), client.ServiceClient(), "25a04c7a065c430590881c646cdcdd58").Extract() + actual, err := limits.Get(context.TODO(), client.ServiceClient(fakeServer), "25a04c7a065c430590881c646cdcdd58").Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, FirstLimit, *actual) } func TestUpdateLimit(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleUpdateLimitSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleUpdateLimitSuccessfully(t, fakeServer) var description = "Number of snapshots for project 3a705b9f56bb439381b43c4fe59dccce" var resourceLimit = 5 @@ -101,16 +101,16 @@ func TestUpdateLimit(t *testing.T) { ResourceLimit: &resourceLimit, } - actual, err := limits.Update(context.TODO(), client.ServiceClient(), "3229b3849f584faea483d6851f7aab05", updateOpts).Extract() + actual, err := limits.Update(context.TODO(), client.ServiceClient(fakeServer), "3229b3849f584faea483d6851f7aab05", updateOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, SecondLimitUpdated, *actual) } func TestDeleteLimit(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDeleteLimitSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDeleteLimitSuccessfully(t, fakeServer) - err := limits.Delete(context.TODO(), client.ServiceClient(), "3229b3849f584faea483d6851f7aab05").ExtractErr() + err := limits.Delete(context.TODO(), client.ServiceClient(fakeServer), "3229b3849f584faea483d6851f7aab05").ExtractErr() th.AssertNoErr(t, err) } diff --git a/openstack/identity/v3/oauth1/testing/fixtures_test.go b/openstack/identity/v3/oauth1/testing/fixtures_test.go index b8d5dc3327..493adad8ef 100644 --- a/openstack/identity/v3/oauth1/testing/fixtures_test.go +++ b/openstack/identity/v3/oauth1/testing/fixtures_test.go @@ -220,8 +220,8 @@ var ExpectedUserAccessTokenRolesSlice = []oauth1.AccessTokenRole{UserAccessToken // HandleCreateConsumer creates an HTTP handler at `/OS-OAUTH1/consumers` on the // test handler mux that tests consumer creation. -func HandleCreateConsumer(t *testing.T) { - th.Mux.HandleFunc("/OS-OAUTH1/consumers", func(w http.ResponseWriter, r *http.Request) { +func HandleCreateConsumer(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/OS-OAUTH1/consumers", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") @@ -235,8 +235,8 @@ func HandleCreateConsumer(t *testing.T) { // HandleUpdateConsumer creates an HTTP handler at `/OS-OAUTH1/consumers/7fea2d` on the // test handler mux that tests consumer update. -func HandleUpdateConsumer(t *testing.T) { - th.Mux.HandleFunc("/OS-OAUTH1/consumers/7fea2d", func(w http.ResponseWriter, r *http.Request) { +func HandleUpdateConsumer(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/OS-OAUTH1/consumers/7fea2d", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PATCH") th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") @@ -250,8 +250,8 @@ func HandleUpdateConsumer(t *testing.T) { // HandleDeleteConsumer creates an HTTP handler at `/OS-OAUTH1/consumers/7fea2d` on the // test handler mux that tests consumer deletion. -func HandleDeleteConsumer(t *testing.T) { - th.Mux.HandleFunc("/OS-OAUTH1/consumers/7fea2d", func(w http.ResponseWriter, r *http.Request) { +func HandleDeleteConsumer(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/OS-OAUTH1/consumers/7fea2d", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -261,8 +261,8 @@ func HandleDeleteConsumer(t *testing.T) { // HandleGetConsumer creates an HTTP handler at `/OS-OAUTH1/consumers/7fea2d` on the // test handler mux that responds with a single consumer. -func HandleGetConsumer(t *testing.T) { - th.Mux.HandleFunc("/OS-OAUTH1/consumers/7fea2d", func(w http.ResponseWriter, r *http.Request) { +func HandleGetConsumer(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/OS-OAUTH1/consumers/7fea2d", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -298,8 +298,8 @@ var ExpectedConsumersSlice = []oauth1.Consumer{FirstConsumer, SecondConsumer} // HandleListConsumers creates an HTTP handler at `/OS-OAUTH1/consumers` on the // test handler mux that responds with a list of two consumers. -func HandleListConsumers(t *testing.T) { - th.Mux.HandleFunc("/OS-OAUTH1/consumers", func(w http.ResponseWriter, r *http.Request) { +func HandleListConsumers(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/OS-OAUTH1/consumers", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -318,8 +318,8 @@ var Token = oauth1.Token{ // HandleRequestToken creates an HTTP handler at `/OS-OAUTH1/request_token` on the // test handler mux that responds with a OAuth1 unauthorized token. -func HandleRequestToken(t *testing.T) { - th.Mux.HandleFunc("/OS-OAUTH1/request_token", func(w http.ResponseWriter, r *http.Request) { +func HandleRequestToken(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/OS-OAUTH1/request_token", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -335,8 +335,8 @@ func HandleRequestToken(t *testing.T) { // HandleAuthorizeToken creates an HTTP handler at `/OS-OAUTH1/authorize/29971f` on the // test handler mux that tests unauthorized token authorization. -func HandleAuthorizeToken(t *testing.T) { - th.Mux.HandleFunc("/OS-OAUTH1/authorize/29971f", func(w http.ResponseWriter, r *http.Request) { +func HandleAuthorizeToken(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/OS-OAUTH1/authorize/29971f", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") @@ -356,8 +356,8 @@ var AccessToken = oauth1.Token{ // HandleCreateAccessToken creates an HTTP handler at `/OS-OAUTH1/access_token` on the // test handler mux that responds with a OAuth1 access token. -func HandleCreateAccessToken(t *testing.T) { - th.Mux.HandleFunc("/OS-OAUTH1/access_token", func(w http.ResponseWriter, r *http.Request) { +func HandleCreateAccessToken(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/OS-OAUTH1/access_token", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -372,8 +372,8 @@ func HandleCreateAccessToken(t *testing.T) { // HandleGetAccessToken creates an HTTP handler at `/users/ce9e07/OS-OAUTH1/access_tokens/6be26a` on the // test handler mux that responds with a single access token. -func HandleGetAccessToken(t *testing.T) { - th.Mux.HandleFunc("/users/ce9e07/OS-OAUTH1/access_tokens/6be26a", func(w http.ResponseWriter, r *http.Request) { +func HandleGetAccessToken(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/users/ce9e07/OS-OAUTH1/access_tokens/6be26a", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -386,8 +386,8 @@ func HandleGetAccessToken(t *testing.T) { // HandleRevokeAccessToken creates an HTTP handler at `/users/ce9e07/OS-OAUTH1/access_tokens/6be26a` on the // test handler mux that tests access token deletion. -func HandleRevokeAccessToken(t *testing.T) { - th.Mux.HandleFunc("/users/ce9e07/OS-OAUTH1/access_tokens/6be26a", func(w http.ResponseWriter, r *http.Request) { +func HandleRevokeAccessToken(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/users/ce9e07/OS-OAUTH1/access_tokens/6be26a", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -397,8 +397,8 @@ func HandleRevokeAccessToken(t *testing.T) { // HandleListAccessTokens creates an HTTP handler at `/users/ce9e07/OS-OAUTH1/access_tokens` on the // test handler mux that responds with a slice of access tokens. -func HandleListAccessTokens(t *testing.T) { - th.Mux.HandleFunc("/users/ce9e07/OS-OAUTH1/access_tokens", func(w http.ResponseWriter, r *http.Request) { +func HandleListAccessTokens(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/users/ce9e07/OS-OAUTH1/access_tokens", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -411,8 +411,8 @@ func HandleListAccessTokens(t *testing.T) { // HandleListAccessTokenRoles creates an HTTP handler at `/users/ce9e07/OS-OAUTH1/access_tokens/6be26a/roles` on the // test handler mux that responds with a slice of access token roles. -func HandleListAccessTokenRoles(t *testing.T) { - th.Mux.HandleFunc("/users/ce9e07/OS-OAUTH1/access_tokens/6be26a/roles", func(w http.ResponseWriter, r *http.Request) { +func HandleListAccessTokenRoles(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/users/ce9e07/OS-OAUTH1/access_tokens/6be26a/roles", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -425,8 +425,8 @@ func HandleListAccessTokenRoles(t *testing.T) { // HandleGetAccessTokenRole creates an HTTP handler at `/users/ce9e07/OS-OAUTH1/access_tokens/6be26a/roles/5ad150` on the // test handler mux that responds with an access token role. -func HandleGetAccessTokenRole(t *testing.T) { - th.Mux.HandleFunc("/users/ce9e07/OS-OAUTH1/access_tokens/6be26a/roles/5ad150", func(w http.ResponseWriter, r *http.Request) { +func HandleGetAccessTokenRole(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/users/ce9e07/OS-OAUTH1/access_tokens/6be26a/roles/5ad150", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -439,8 +439,8 @@ func HandleGetAccessTokenRole(t *testing.T) { // HandleAuthenticate creates an HTTP handler at `/auth/tokens` on the // test handler mux that responds with an OpenStack token. -func HandleAuthenticate(t *testing.T) { - th.Mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) { +func HandleAuthenticate(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") diff --git a/openstack/identity/v3/oauth1/testing/requests_test.go b/openstack/identity/v3/oauth1/testing/requests_test.go index 75f37bca0f..1cf2f7174f 100644 --- a/openstack/identity/v3/oauth1/testing/requests_test.go +++ b/openstack/identity/v3/oauth1/testing/requests_test.go @@ -13,11 +13,11 @@ import ( ) func TestCreateConsumer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateConsumer(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCreateConsumer(t, fakeServer) - consumer, err := oauth1.CreateConsumer(context.TODO(), client.ServiceClient(), oauth1.CreateConsumerOpts{ + consumer, err := oauth1.CreateConsumer(context.TODO(), client.ServiceClient(fakeServer), oauth1.CreateConsumerOpts{ Description: "My consumer", }).Extract() th.AssertNoErr(t, err) @@ -26,11 +26,11 @@ func TestCreateConsumer(t *testing.T) { } func TestUpdateConsumer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleUpdateConsumer(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleUpdateConsumer(t, fakeServer) - consumer, err := oauth1.UpdateConsumer(context.TODO(), client.ServiceClient(), "7fea2d", oauth1.UpdateConsumerOpts{ + consumer, err := oauth1.UpdateConsumer(context.TODO(), client.ServiceClient(fakeServer), "7fea2d", oauth1.UpdateConsumerOpts{ Description: "My new consumer", }).Extract() th.AssertNoErr(t, err) @@ -39,32 +39,32 @@ func TestUpdateConsumer(t *testing.T) { } func TestDeleteConsumer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDeleteConsumer(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDeleteConsumer(t, fakeServer) - err := oauth1.DeleteConsumer(context.TODO(), client.ServiceClient(), "7fea2d").ExtractErr() + err := oauth1.DeleteConsumer(context.TODO(), client.ServiceClient(fakeServer), "7fea2d").ExtractErr() th.AssertNoErr(t, err) } func TestGetConsumer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetConsumer(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetConsumer(t, fakeServer) - consumer, err := oauth1.GetConsumer(context.TODO(), client.ServiceClient(), "7fea2d").Extract() + consumer, err := oauth1.GetConsumer(context.TODO(), client.ServiceClient(fakeServer), "7fea2d").Extract() th.AssertNoErr(t, err) th.AssertEquals(t, FirstConsumer, *consumer) } func TestListConsumers(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListConsumers(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListConsumers(t, fakeServer) count := 0 - err := oauth1.ListConsumers(client.ServiceClient()).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := oauth1.ListConsumers(client.ServiceClient(fakeServer)).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := oauth1.ExtractConsumers(page) @@ -79,11 +79,11 @@ func TestListConsumers(t *testing.T) { } func TestListConsumersAllPages(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListConsumers(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListConsumers(t, fakeServer) - allPages, err := oauth1.ListConsumers(client.ServiceClient()).AllPages(context.TODO()) + allPages, err := oauth1.ListConsumers(client.ServiceClient(fakeServer)).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := oauth1.ExtractConsumers(allPages) th.AssertNoErr(t, err) @@ -91,12 +91,12 @@ func TestListConsumersAllPages(t *testing.T) { } func TestRequestToken(t *testing.T) { - th.SetupPersistentPortHTTP(t, 33199) - defer th.TeardownHTTP() - HandleRequestToken(t) + fakeServer := th.SetupPersistentPortHTTP(t, 33199) + defer fakeServer.Teardown() + HandleRequestToken(t, fakeServer) ts := time.Unix(0, 0) - token, err := oauth1.RequestToken(context.TODO(), client.ServiceClient(), oauth1.RequestTokenOpts{ + token, err := oauth1.RequestToken(context.TODO(), client.ServiceClient(fakeServer), oauth1.RequestTokenOpts{ OAuthConsumerKey: Consumer.ID, OAuthConsumerSecret: Consumer.Secret, OAuthSignatureMethod: oauth1.HMACSHA1, @@ -110,11 +110,11 @@ func TestRequestToken(t *testing.T) { } func TestAuthorizeToken(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleAuthorizeToken(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleAuthorizeToken(t, fakeServer) - token, err := oauth1.AuthorizeToken(context.TODO(), client.ServiceClient(), "29971f", oauth1.AuthorizeTokenOpts{ + token, err := oauth1.AuthorizeToken(context.TODO(), client.ServiceClient(fakeServer), "29971f", oauth1.AuthorizeTokenOpts{ Roles: []oauth1.Role{ { ID: "a3b29b", @@ -130,12 +130,12 @@ func TestAuthorizeToken(t *testing.T) { } func TestCreateAccessToken(t *testing.T) { - th.SetupPersistentPortHTTP(t, 33199) - defer th.TeardownHTTP() - HandleCreateAccessToken(t) + fakeServer := th.SetupPersistentPortHTTP(t, 33199) + defer fakeServer.Teardown() + HandleCreateAccessToken(t, fakeServer) ts := time.Unix(1586804894, 0) - token, err := oauth1.CreateAccessToken(context.TODO(), client.ServiceClient(), oauth1.CreateAccessTokenOpts{ + token, err := oauth1.CreateAccessToken(context.TODO(), client.ServiceClient(fakeServer), oauth1.CreateAccessTokenOpts{ OAuthConsumerKey: Consumer.ID, OAuthConsumerSecret: Consumer.Secret, OAuthToken: Token.OAuthToken, @@ -151,32 +151,32 @@ func TestCreateAccessToken(t *testing.T) { } func TestGetAccessToken(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetAccessToken(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetAccessToken(t, fakeServer) - token, err := oauth1.GetAccessToken(context.TODO(), client.ServiceClient(), "ce9e07", "6be26a").Extract() + token, err := oauth1.GetAccessToken(context.TODO(), client.ServiceClient(fakeServer), "ce9e07", "6be26a").Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, UserAccessToken, *token) } func TestRevokeAccessToken(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleRevokeAccessToken(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleRevokeAccessToken(t, fakeServer) - err := oauth1.RevokeAccessToken(context.TODO(), client.ServiceClient(), "ce9e07", "6be26a").ExtractErr() + err := oauth1.RevokeAccessToken(context.TODO(), client.ServiceClient(fakeServer), "ce9e07", "6be26a").ExtractErr() th.AssertNoErr(t, err) } func TestListAccessTokens(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListAccessTokens(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListAccessTokens(t, fakeServer) count := 0 - err := oauth1.ListAccessTokens(client.ServiceClient(), "ce9e07").EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := oauth1.ListAccessTokens(client.ServiceClient(fakeServer), "ce9e07").EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := oauth1.ExtractAccessTokens(page) @@ -191,11 +191,11 @@ func TestListAccessTokens(t *testing.T) { } func TestListAccessTokensAllPages(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListAccessTokens(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListAccessTokens(t, fakeServer) - allPages, err := oauth1.ListAccessTokens(client.ServiceClient(), "ce9e07").AllPages(context.TODO()) + allPages, err := oauth1.ListAccessTokens(client.ServiceClient(fakeServer), "ce9e07").AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := oauth1.ExtractAccessTokens(allPages) th.AssertNoErr(t, err) @@ -203,12 +203,12 @@ func TestListAccessTokensAllPages(t *testing.T) { } func TestListAccessTokenRoles(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListAccessTokenRoles(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListAccessTokenRoles(t, fakeServer) count := 0 - err := oauth1.ListAccessTokenRoles(client.ServiceClient(), "ce9e07", "6be26a").EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := oauth1.ListAccessTokenRoles(client.ServiceClient(fakeServer), "ce9e07", "6be26a").EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := oauth1.ExtractAccessTokenRoles(page) @@ -223,11 +223,11 @@ func TestListAccessTokenRoles(t *testing.T) { } func TestListAccessTokenRolesAllPages(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListAccessTokenRoles(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListAccessTokenRoles(t, fakeServer) - allPages, err := oauth1.ListAccessTokenRoles(client.ServiceClient(), "ce9e07", "6be26a").AllPages(context.TODO()) + allPages, err := oauth1.ListAccessTokenRoles(client.ServiceClient(fakeServer), "ce9e07", "6be26a").AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := oauth1.ExtractAccessTokenRoles(allPages) th.AssertNoErr(t, err) @@ -235,20 +235,20 @@ func TestListAccessTokenRolesAllPages(t *testing.T) { } func TestGetAccessTokenRole(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetAccessTokenRole(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetAccessTokenRole(t, fakeServer) - role, err := oauth1.GetAccessTokenRole(context.TODO(), client.ServiceClient(), "ce9e07", "6be26a", "5ad150").Extract() + role, err := oauth1.GetAccessTokenRole(context.TODO(), client.ServiceClient(fakeServer), "ce9e07", "6be26a", "5ad150").Extract() th.AssertNoErr(t, err) th.AssertEquals(t, UserAccessTokenRole, *role) } func TestAuthenticate(t *testing.T) { - th.SetupPersistentPortHTTP(t, 33199) - defer th.TeardownHTTP() - HandleAuthenticate(t) + fakeServer := th.SetupPersistentPortHTTP(t, 33199) + defer fakeServer.Teardown() + HandleAuthenticate(t, fakeServer) expected := &tokens.Token{ ExpiresAt: time.Date(2017, 6, 3, 2, 19, 49, 0, time.UTC), @@ -265,7 +265,7 @@ func TestAuthenticate(t *testing.T) { OAuthNonce: "66148873158553341551586804894", } - actual, err := oauth1.Create(context.TODO(), client.ServiceClient(), options).Extract() + actual, err := oauth1.Create(context.TODO(), client.ServiceClient(fakeServer), options).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, expected, actual) } diff --git a/openstack/identity/v3/osinherit/testing/fixtures_test.go b/openstack/identity/v3/osinherit/testing/fixtures_test.go index 8e2415ea0c..b053bba456 100644 --- a/openstack/identity/v3/osinherit/testing/fixtures_test.go +++ b/openstack/identity/v3/osinherit/testing/fixtures_test.go @@ -8,78 +8,78 @@ import ( "github.com/gophercloud/gophercloud/v2/testhelper/client" ) -func HandleAssignSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/OS-INHERIT/projects/{project_id}/users/{user_id}/roles/{role_id}/inherited_to_projects", func(w http.ResponseWriter, r *http.Request) { +func HandleAssignSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/OS-INHERIT/projects/{project_id}/users/{user_id}/roles/{role_id}/inherited_to_projects", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) - th.Mux.HandleFunc("/OS-INHERIT/projects/{project_id}/groups/{group_id}/roles/{role_id}/inherited_to_projects", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/OS-INHERIT/projects/{project_id}/groups/{group_id}/roles/{role_id}/inherited_to_projects", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) - th.Mux.HandleFunc("/OS-INHERIT/domains/{domain_id}/users/{user_id}/roles/{role_id}/inherited_to_projects", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/OS-INHERIT/domains/{domain_id}/users/{user_id}/roles/{role_id}/inherited_to_projects", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) - th.Mux.HandleFunc("/OS-INHERIT/domains/{domain_id}/groups/{group_id}/roles/{role_id}/inherited_to_projects", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/OS-INHERIT/domains/{domain_id}/groups/{group_id}/roles/{role_id}/inherited_to_projects", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) } -func HandleValidateSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/OS-INHERIT/projects/{project_id}/users/{user_id}/roles/{role_id}/inherited_to_projects", func(w http.ResponseWriter, r *http.Request) { +func HandleValidateSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/OS-INHERIT/projects/{project_id}/users/{user_id}/roles/{role_id}/inherited_to_projects", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "HEAD") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) - th.Mux.HandleFunc("/OS-INHERIT/projects/{project_id}/groups/{group_id}/roles/{role_id}/inherited_to_projects", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/OS-INHERIT/projects/{project_id}/groups/{group_id}/roles/{role_id}/inherited_to_projects", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "HEAD") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) - th.Mux.HandleFunc("/OS-INHERIT/domains/{domain_id}/users/{user_id}/roles/{role_id}/inherited_to_projects", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/OS-INHERIT/domains/{domain_id}/users/{user_id}/roles/{role_id}/inherited_to_projects", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "HEAD") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) - th.Mux.HandleFunc("/OS-INHERIT/domains/{domain_id}/groups/{group_id}/roles/{role_id}/inherited_to_projects", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/OS-INHERIT/domains/{domain_id}/groups/{group_id}/roles/{role_id}/inherited_to_projects", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "HEAD") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) } -func HandleUnassignSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/OS-INHERIT/projects/{project_id}/users/{user_id}/roles/{role_id}/inherited_to_projects", func(w http.ResponseWriter, r *http.Request) { +func HandleUnassignSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/OS-INHERIT/projects/{project_id}/users/{user_id}/roles/{role_id}/inherited_to_projects", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) - th.Mux.HandleFunc("/OS-INHERIT/projects/{project_id}/groups/{group_id}/roles/{role_id}/inherited_to_projects", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/OS-INHERIT/projects/{project_id}/groups/{group_id}/roles/{role_id}/inherited_to_projects", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) - th.Mux.HandleFunc("/OS-INHERIT/domains/{domain_id}/users/{user_id}/roles/{role_id}/inherited_to_projects", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/OS-INHERIT/domains/{domain_id}/users/{user_id}/roles/{role_id}/inherited_to_projects", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) - th.Mux.HandleFunc("/OS-INHERIT/domains/{domain_id}/groups/{group_id}/roles/{role_id}/inherited_to_projects", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/OS-INHERIT/domains/{domain_id}/groups/{group_id}/roles/{role_id}/inherited_to_projects", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) diff --git a/openstack/identity/v3/osinherit/testing/requests_test.go b/openstack/identity/v3/osinherit/testing/requests_test.go index 7901a689c7..8b90f26498 100644 --- a/openstack/identity/v3/osinherit/testing/requests_test.go +++ b/openstack/identity/v3/osinherit/testing/requests_test.go @@ -10,41 +10,41 @@ import ( ) func TestAssign(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleAssignSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleAssignSuccessfully(t, fakeServer) - err := osinherit.Assign(context.TODO(), client.ServiceClient(), "{role_id}", osinherit.AssignOpts{ + err := osinherit.Assign(context.TODO(), client.ServiceClient(fakeServer), "{role_id}", osinherit.AssignOpts{ UserID: "{user_id}", ProjectID: "{project_id}", }).ExtractErr() th.AssertNoErr(t, err) - err = osinherit.Assign(context.TODO(), client.ServiceClient(), "{role_id}", osinherit.AssignOpts{ + err = osinherit.Assign(context.TODO(), client.ServiceClient(fakeServer), "{role_id}", osinherit.AssignOpts{ UserID: "{user_id}", DomainID: "{domain_id}", }).ExtractErr() th.AssertNoErr(t, err) - err = osinherit.Assign(context.TODO(), client.ServiceClient(), "{role_id}", osinherit.AssignOpts{ + err = osinherit.Assign(context.TODO(), client.ServiceClient(fakeServer), "{role_id}", osinherit.AssignOpts{ GroupID: "{group_id}", ProjectID: "{project_id}", }).ExtractErr() th.AssertNoErr(t, err) - err = osinherit.Assign(context.TODO(), client.ServiceClient(), "{role_id}", osinherit.AssignOpts{ + err = osinherit.Assign(context.TODO(), client.ServiceClient(fakeServer), "{role_id}", osinherit.AssignOpts{ GroupID: "{group_id}", DomainID: "{domain_id}", }).ExtractErr() th.AssertNoErr(t, err) - err = osinherit.Assign(context.TODO(), client.ServiceClient(), "{role_id}", osinherit.AssignOpts{ + err = osinherit.Assign(context.TODO(), client.ServiceClient(fakeServer), "{role_id}", osinherit.AssignOpts{ GroupID: "{group_id}", UserID: "{user_id}", }).ExtractErr() th.AssertErr(t, err) - err = osinherit.Assign(context.TODO(), client.ServiceClient(), "{role_id}", osinherit.AssignOpts{ + err = osinherit.Assign(context.TODO(), client.ServiceClient(fakeServer), "{role_id}", osinherit.AssignOpts{ ProjectID: "{project_id}", DomainID: "{domain_id}", }).ExtractErr() @@ -52,41 +52,41 @@ func TestAssign(t *testing.T) { } func TestValidate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleValidateSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleValidateSuccessfully(t, fakeServer) - err := osinherit.Validate(context.TODO(), client.ServiceClient(), "{role_id}", osinherit.ValidateOpts{ + err := osinherit.Validate(context.TODO(), client.ServiceClient(fakeServer), "{role_id}", osinherit.ValidateOpts{ UserID: "{user_id}", ProjectID: "{project_id}", }).ExtractErr() th.AssertNoErr(t, err) - err = osinherit.Validate(context.TODO(), client.ServiceClient(), "{role_id}", osinherit.ValidateOpts{ + err = osinherit.Validate(context.TODO(), client.ServiceClient(fakeServer), "{role_id}", osinherit.ValidateOpts{ UserID: "{user_id}", DomainID: "{domain_id}", }).ExtractErr() th.AssertNoErr(t, err) - err = osinherit.Validate(context.TODO(), client.ServiceClient(), "{role_id}", osinherit.ValidateOpts{ + err = osinherit.Validate(context.TODO(), client.ServiceClient(fakeServer), "{role_id}", osinherit.ValidateOpts{ GroupID: "{group_id}", ProjectID: "{project_id}", }).ExtractErr() th.AssertNoErr(t, err) - err = osinherit.Validate(context.TODO(), client.ServiceClient(), "{role_id}", osinherit.ValidateOpts{ + err = osinherit.Validate(context.TODO(), client.ServiceClient(fakeServer), "{role_id}", osinherit.ValidateOpts{ GroupID: "{group_id}", DomainID: "{domain_id}", }).ExtractErr() th.AssertNoErr(t, err) - err = osinherit.Validate(context.TODO(), client.ServiceClient(), "{role_id}", osinherit.ValidateOpts{ + err = osinherit.Validate(context.TODO(), client.ServiceClient(fakeServer), "{role_id}", osinherit.ValidateOpts{ GroupID: "{group_id}", UserID: "{user_id}", }).ExtractErr() th.AssertErr(t, err) - err = osinherit.Validate(context.TODO(), client.ServiceClient(), "{role_id}", osinherit.ValidateOpts{ + err = osinherit.Validate(context.TODO(), client.ServiceClient(fakeServer), "{role_id}", osinherit.ValidateOpts{ ProjectID: "{project_id}", DomainID: "{domain_id}", }).ExtractErr() @@ -94,41 +94,41 @@ func TestValidate(t *testing.T) { } func TestUnassign(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleUnassignSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleUnassignSuccessfully(t, fakeServer) - err := osinherit.Unassign(context.TODO(), client.ServiceClient(), "{role_id}", osinherit.UnassignOpts{ + err := osinherit.Unassign(context.TODO(), client.ServiceClient(fakeServer), "{role_id}", osinherit.UnassignOpts{ UserID: "{user_id}", ProjectID: "{project_id}", }).ExtractErr() th.AssertNoErr(t, err) - err = osinherit.Unassign(context.TODO(), client.ServiceClient(), "{role_id}", osinherit.UnassignOpts{ + err = osinherit.Unassign(context.TODO(), client.ServiceClient(fakeServer), "{role_id}", osinherit.UnassignOpts{ UserID: "{user_id}", DomainID: "{domain_id}", }).ExtractErr() th.AssertNoErr(t, err) - err = osinherit.Unassign(context.TODO(), client.ServiceClient(), "{role_id}", osinherit.UnassignOpts{ + err = osinherit.Unassign(context.TODO(), client.ServiceClient(fakeServer), "{role_id}", osinherit.UnassignOpts{ GroupID: "{group_id}", ProjectID: "{project_id}", }).ExtractErr() th.AssertNoErr(t, err) - err = osinherit.Unassign(context.TODO(), client.ServiceClient(), "{role_id}", osinherit.UnassignOpts{ + err = osinherit.Unassign(context.TODO(), client.ServiceClient(fakeServer), "{role_id}", osinherit.UnassignOpts{ GroupID: "{group_id}", DomainID: "{domain_id}", }).ExtractErr() th.AssertNoErr(t, err) - err = osinherit.Unassign(context.TODO(), client.ServiceClient(), "{role_id}", osinherit.UnassignOpts{ + err = osinherit.Unassign(context.TODO(), client.ServiceClient(fakeServer), "{role_id}", osinherit.UnassignOpts{ GroupID: "{group_id}", UserID: "{user_id}", }).ExtractErr() th.AssertErr(t, err) - err = osinherit.Unassign(context.TODO(), client.ServiceClient(), "{role_id}", osinherit.UnassignOpts{ + err = osinherit.Unassign(context.TODO(), client.ServiceClient(fakeServer), "{role_id}", osinherit.UnassignOpts{ ProjectID: "{project_id}", DomainID: "{domain_id}", }).ExtractErr() diff --git a/openstack/identity/v3/policies/testing/fixtures_test.go b/openstack/identity/v3/policies/testing/fixtures_test.go index e40d50b340..50e9366fad 100644 --- a/openstack/identity/v3/policies/testing/fixtures_test.go +++ b/openstack/identity/v3/policies/testing/fixtures_test.go @@ -154,8 +154,8 @@ var ExpectedPoliciesSlice = []policies.Policy{FirstPolicy, SecondPolicy} // HandleListPoliciesSuccessfully creates an HTTP handler at `/policies` on the // test handler mux that responds with a list of two policies. -func HandleListPoliciesSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/policies", func(w http.ResponseWriter, r *http.Request) { +func HandleListPoliciesSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/policies", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -175,8 +175,8 @@ func HandleListPoliciesSuccessfully(t *testing.T) { // HandleCreatePolicySuccessfully creates an HTTP handler at `/policies` on the // test handler mux that tests policy creation. -func HandleCreatePolicySuccessfully(t *testing.T) { - th.Mux.HandleFunc("/policies", func(w http.ResponseWriter, r *http.Request) { +func HandleCreatePolicySuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/policies", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, CreateRequest) @@ -188,8 +188,8 @@ func HandleCreatePolicySuccessfully(t *testing.T) { // HandleGetPolicySuccessfully creates an HTTP handler at `/policies` on the // test handler mux that responds with a single policy. -func HandleGetPolicySuccessfully(t *testing.T) { - th.Mux.HandleFunc("/policies/b49884da9d31494ea02aff38d4b4e701", +func HandleGetPolicySuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/policies/b49884da9d31494ea02aff38d4b4e701", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") @@ -204,8 +204,8 @@ func HandleGetPolicySuccessfully(t *testing.T) { // HandleUpdatePolicySuccessfully creates an HTTP handler at `/policies` on the // test handler mux that tests role update. -func HandleUpdatePolicySuccessfully(t *testing.T) { - th.Mux.HandleFunc("/policies/b49884da9d31494ea02aff38d4b4e701", +func HandleUpdatePolicySuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/policies/b49884da9d31494ea02aff38d4b4e701", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PATCH") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -219,8 +219,8 @@ func HandleUpdatePolicySuccessfully(t *testing.T) { // HandleDeletePolicySuccessfully creates an HTTP handler at `/policies` on the // test handler mux that tests policy deletion. -func HandleDeletePolicySuccessfully(t *testing.T) { - th.Mux.HandleFunc("/policies/9fe1d3", func(w http.ResponseWriter, r *http.Request) { +func HandleDeletePolicySuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/policies/9fe1d3", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/identity/v3/policies/testing/requests_test.go b/openstack/identity/v3/policies/testing/requests_test.go index f837543b31..e54f9703a6 100644 --- a/openstack/identity/v3/policies/testing/requests_test.go +++ b/openstack/identity/v3/policies/testing/requests_test.go @@ -12,12 +12,12 @@ import ( ) func TestListPolicies(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListPoliciesSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListPoliciesSuccessfully(t, fakeServer) count := 0 - err := policies.List(client.ServiceClient(), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := policies.List(client.ServiceClient(fakeServer), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := policies.ExtractPolicies(page) @@ -32,11 +32,11 @@ func TestListPolicies(t *testing.T) { } func TestListPoliciesAllPages(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListPoliciesSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListPoliciesSuccessfully(t, fakeServer) - allPages, err := policies.List(client.ServiceClient(), nil).AllPages(context.TODO()) + allPages, err := policies.List(client.ServiceClient(fakeServer), nil).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := policies.ExtractPolicies(allPages) th.AssertNoErr(t, err) @@ -44,14 +44,14 @@ func TestListPoliciesAllPages(t *testing.T) { } func TestListPoliciesWithFilter(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListPoliciesSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListPoliciesSuccessfully(t, fakeServer) listOpts := policies.ListOpts{ Type: "application/json", } - allPages, err := policies.List(client.ServiceClient(), listOpts).AllPages(context.TODO()) + allPages, err := policies.List(client.ServiceClient(fakeServer), listOpts).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := policies.ExtractPolicies(allPages) th.AssertNoErr(t, err) @@ -91,9 +91,9 @@ func TestListPoliciesFiltersCheck(t *testing.T) { } func TestCreatePolicy(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreatePolicySuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCreatePolicySuccessfully(t, fakeServer) createOpts := policies.CreateOpts{ Type: "application/json", @@ -103,7 +103,7 @@ func TestCreatePolicy(t *testing.T) { }, } - actual, err := policies.Create(context.TODO(), client.ServiceClient(), createOpts).Extract() + actual, err := policies.Create(context.TODO(), client.ServiceClient(fakeServer), createOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, SecondPolicy, *actual) } @@ -152,21 +152,21 @@ func TestCreatePolicyTypeLengthCheck(t *testing.T) { } func TestGetPolicy(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetPolicySuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetPolicySuccessfully(t, fakeServer) id := "b49884da9d31494ea02aff38d4b4e701" - actual, err := policies.Get(context.TODO(), client.ServiceClient(), id).Extract() + actual, err := policies.Get(context.TODO(), client.ServiceClient(fakeServer), id).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, SecondPolicy, *actual) } func TestUpdatePolicy(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleUpdatePolicySuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleUpdatePolicySuccessfully(t, fakeServer) updateOpts := policies.UpdateOpts{ Extra: map[string]any{ @@ -175,7 +175,7 @@ func TestUpdatePolicy(t *testing.T) { } id := "b49884da9d31494ea02aff38d4b4e701" - actual, err := policies.Update(context.TODO(), client.ServiceClient(), id, updateOpts).Extract() + actual, err := policies.Update(context.TODO(), client.ServiceClient(fakeServer), id, updateOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, SecondPolicyUpdated, *actual) } @@ -221,10 +221,10 @@ func TestUpdatePolicyTypeLengthCheck(t *testing.T) { } func TestDeletePolicy(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDeletePolicySuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDeletePolicySuccessfully(t, fakeServer) - res := policies.Delete(context.TODO(), client.ServiceClient(), "9fe1d3") + res := policies.Delete(context.TODO(), client.ServiceClient(fakeServer), "9fe1d3") th.AssertNoErr(t, res.Err) } diff --git a/openstack/identity/v3/projectendpoints/testing/requests_test.go b/openstack/identity/v3/projectendpoints/testing/requests_test.go index 2e8f6aad4c..7e4f3c152a 100644 --- a/openstack/identity/v3/projectendpoints/testing/requests_test.go +++ b/openstack/identity/v3/projectendpoints/testing/requests_test.go @@ -14,25 +14,25 @@ import ( ) func TestCreateSuccessful(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/OS-EP-FILTER/projects/project-id/endpoints/endpoint-id", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/OS-EP-FILTER/projects/project-id/endpoints/endpoint-id", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) - err := projectendpoints.Create(context.TODO(), client.ServiceClient(), "project-id", "endpoint-id").Err + err := projectendpoints.Create(context.TODO(), client.ServiceClient(fakeServer), "project-id", "endpoint-id").Err th.AssertNoErr(t, err) } func TestListEndpoints(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/OS-EP-FILTER/projects/project-id/endpoints", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/OS-EP-FILTER/projects/project-id/endpoints", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -71,7 +71,7 @@ func TestListEndpoints(t *testing.T) { }) count := 0 - err := projectendpoints.List(client.ServiceClient(), "project-id").EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := projectendpoints.List(client.ServiceClient(fakeServer), "project-id").EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := projectendpoints.ExtractEndpoints(page) if err != nil { @@ -103,16 +103,16 @@ func TestListEndpoints(t *testing.T) { } func TestDeleteEndpoint(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/OS-EP-FILTER/projects/project-id/endpoints/endpoint-id", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/OS-EP-FILTER/projects/project-id/endpoints/endpoint-id", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) - res := projectendpoints.Delete(context.TODO(), client.ServiceClient(), "project-id", "endpoint-id") + res := projectendpoints.Delete(context.TODO(), client.ServiceClient(fakeServer), "project-id", "endpoint-id") th.AssertNoErr(t, res.Err) } diff --git a/openstack/identity/v3/projects/testing/fixtures_test.go b/openstack/identity/v3/projects/testing/fixtures_test.go index 568305008a..5c97fc7dd3 100644 --- a/openstack/identity/v3/projects/testing/fixtures_test.go +++ b/openstack/identity/v3/projects/testing/fixtures_test.go @@ -277,8 +277,8 @@ var ExpectedProjects = projects.ProjectTags{ // HandleListAvailableProjectsSuccessfully creates an HTTP handler at `/auth/projects` // on the test handler mux that responds with a list of two tenants. -func HandleListAvailableProjectsSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/auth/projects", func(w http.ResponseWriter, r *http.Request) { +func HandleListAvailableProjectsSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/auth/projects", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -291,8 +291,8 @@ func HandleListAvailableProjectsSuccessfully(t *testing.T) { // HandleListProjectsSuccessfully creates an HTTP handler at `/projects` on the // test handler mux that responds with a list of two tenants. -func HandleListProjectsSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/projects", func(w http.ResponseWriter, r *http.Request) { +func HandleListProjectsSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/projects", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -305,8 +305,8 @@ func HandleListProjectsSuccessfully(t *testing.T) { // HandleGetProjectSuccessfully creates an HTTP handler at `/projects` on the // test handler mux that responds with a single project. -func HandleGetProjectSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/projects/1234", func(w http.ResponseWriter, r *http.Request) { +func HandleGetProjectSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/projects/1234", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -319,8 +319,8 @@ func HandleGetProjectSuccessfully(t *testing.T) { // HandleCreateProjectSuccessfully creates an HTTP handler at `/projects` on the // test handler mux that tests project creation. -func HandleCreateProjectSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/projects", func(w http.ResponseWriter, r *http.Request) { +func HandleCreateProjectSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/projects", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, CreateRequest) @@ -332,8 +332,8 @@ func HandleCreateProjectSuccessfully(t *testing.T) { // HandleDeleteProjectSuccessfully creates an HTTP handler at `/projects` on the // test handler mux that tests project deletion. -func HandleDeleteProjectSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/projects/1234", func(w http.ResponseWriter, r *http.Request) { +func HandleDeleteProjectSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/projects/1234", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -343,8 +343,8 @@ func HandleDeleteProjectSuccessfully(t *testing.T) { // HandleUpdateProjectSuccessfully creates an HTTP handler at `/projects` on the // test handler mux that tests project updates. -func HandleUpdateProjectSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/projects/1234", func(w http.ResponseWriter, r *http.Request) { +func HandleUpdateProjectSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/projects/1234", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PATCH") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, UpdateRequest) @@ -354,8 +354,8 @@ func HandleUpdateProjectSuccessfully(t *testing.T) { }) } -func HandleListProjectTagsSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/projects/966b3c7d36a24facaf20b7e458bf2192/tags", func(w http.ResponseWriter, r *http.Request) { +func HandleListProjectTagsSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/projects/966b3c7d36a24facaf20b7e458bf2192/tags", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -364,8 +364,8 @@ func HandleListProjectTagsSuccessfully(t *testing.T) { }) } -func HandleModifyProjectTagsSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/projects/966b3c7d36a24facaf20b7e458bf2192/tags", func(w http.ResponseWriter, r *http.Request) { +func HandleModifyProjectTagsSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/projects/966b3c7d36a24facaf20b7e458bf2192/tags", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, ModifyProjectTagsRequest) @@ -374,8 +374,8 @@ func HandleModifyProjectTagsSuccessfully(t *testing.T) { fmt.Fprint(w, ModifyProjectTagsOutput) }) } -func HandleDeleteProjectTagsSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/projects/966b3c7d36a24facaf20b7e458bf2192/tags", func(w http.ResponseWriter, r *http.Request) { +func HandleDeleteProjectTagsSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/projects/966b3c7d36a24facaf20b7e458bf2192/tags", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/identity/v3/projects/testing/requests_test.go b/openstack/identity/v3/projects/testing/requests_test.go index aa27c50946..5ecc88e45d 100644 --- a/openstack/identity/v3/projects/testing/requests_test.go +++ b/openstack/identity/v3/projects/testing/requests_test.go @@ -11,12 +11,12 @@ import ( ) func TestListAvailableProjects(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListAvailableProjectsSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListAvailableProjectsSuccessfully(t, fakeServer) count := 0 - err := projects.ListAvailable(client.ServiceClient()).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := projects.ListAvailable(client.ServiceClient(fakeServer)).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := projects.ExtractProjects(page) @@ -31,12 +31,12 @@ func TestListAvailableProjects(t *testing.T) { } func TestListProjects(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListProjectsSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListProjectsSuccessfully(t, fakeServer) count := 0 - err := projects.List(client.ServiceClient(), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := projects.List(client.ServiceClient(fakeServer), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := projects.ExtractProjects(page) @@ -83,19 +83,19 @@ func TestListGroupsFiltersCheck(t *testing.T) { } func TestGetProject(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetProjectSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetProjectSuccessfully(t, fakeServer) - actual, err := projects.Get(context.TODO(), client.ServiceClient(), "1234").Extract() + actual, err := projects.Get(context.TODO(), client.ServiceClient(fakeServer), "1234").Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, RedTeam, *actual) } func TestCreateProject(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateProjectSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCreateProjectSuccessfully(t, fakeServer) createOpts := projects.CreateOpts{ Name: "Red Team", @@ -104,24 +104,24 @@ func TestCreateProject(t *testing.T) { Extra: map[string]any{"test": "old"}, } - actual, err := projects.Create(context.TODO(), client.ServiceClient(), createOpts).Extract() + actual, err := projects.Create(context.TODO(), client.ServiceClient(fakeServer), createOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, RedTeam, *actual) } func TestDeleteProject(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDeleteProjectSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDeleteProjectSuccessfully(t, fakeServer) - res := projects.Delete(context.TODO(), client.ServiceClient(), "1234") + res := projects.Delete(context.TODO(), client.ServiceClient(fakeServer), "1234") th.AssertNoErr(t, res.Err) } func TestUpdateProject(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleUpdateProjectSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleUpdateProjectSuccessfully(t, fakeServer) var description = "The team that is bright red" updateOpts := projects.UpdateOpts{ @@ -131,40 +131,40 @@ func TestUpdateProject(t *testing.T) { Extra: map[string]any{"test": "new"}, } - actual, err := projects.Update(context.TODO(), client.ServiceClient(), "1234", updateOpts).Extract() + actual, err := projects.Update(context.TODO(), client.ServiceClient(fakeServer), "1234", updateOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, UpdatedRedTeam, *actual) - t.Log(projects.Update(context.TODO(), client.ServiceClient(), "1234", updateOpts)) + t.Log(projects.Update(context.TODO(), client.ServiceClient(fakeServer), "1234", updateOpts)) } func TestListProjectTags(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListProjectTagsSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListProjectTagsSuccessfully(t, fakeServer) - actual, err := projects.ListTags(context.TODO(), client.ServiceClient(), "966b3c7d36a24facaf20b7e458bf2192").Extract() + actual, err := projects.ListTags(context.TODO(), client.ServiceClient(fakeServer), "966b3c7d36a24facaf20b7e458bf2192").Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, ExpectedTags, *actual) } func TestModifyProjectTags(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleModifyProjectTagsSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleModifyProjectTagsSuccessfully(t, fakeServer) modifyOpts := projects.ModifyTagsOpts{ Tags: []string{"foo", "bar"}, } - actual, err := projects.ModifyTags(context.TODO(), client.ServiceClient(), "966b3c7d36a24facaf20b7e458bf2192", modifyOpts).Extract() + actual, err := projects.ModifyTags(context.TODO(), client.ServiceClient(fakeServer), "966b3c7d36a24facaf20b7e458bf2192", modifyOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, ExpectedProjects, *actual) } func TestDeleteTags(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDeleteProjectTagsSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDeleteProjectTagsSuccessfully(t, fakeServer) - err := projects.DeleteTags(context.TODO(), client.ServiceClient(), "966b3c7d36a24facaf20b7e458bf2192").ExtractErr() + err := projects.DeleteTags(context.TODO(), client.ServiceClient(fakeServer), "966b3c7d36a24facaf20b7e458bf2192").ExtractErr() th.AssertNoErr(t, err) } diff --git a/openstack/identity/v3/regions/testing/fixtures_test.go b/openstack/identity/v3/regions/testing/fixtures_test.go index 633ae86dcb..d3d1500939 100644 --- a/openstack/identity/v3/regions/testing/fixtures_test.go +++ b/openstack/identity/v3/regions/testing/fixtures_test.go @@ -164,8 +164,8 @@ var ExpectedRegionsSlice = []regions.Region{FirstRegion, SecondRegion} // HandleListRegionsSuccessfully creates an HTTP handler at `/regions` on the // test handler mux that responds with a list of two regions. -func HandleListRegionsSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/regions", func(w http.ResponseWriter, r *http.Request) { +func HandleListRegionsSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/regions", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -178,8 +178,8 @@ func HandleListRegionsSuccessfully(t *testing.T) { // HandleGetRegionSuccessfully creates an HTTP handler at `/regions` on the // test handler mux that responds with a single region. -func HandleGetRegionSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/regions/RegionOne-West", func(w http.ResponseWriter, r *http.Request) { +func HandleGetRegionSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/regions/RegionOne-West", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -192,8 +192,8 @@ func HandleGetRegionSuccessfully(t *testing.T) { // HandleCreateRegionSuccessfully creates an HTTP handler at `/regions` on the // test handler mux that tests region creation. -func HandleCreateRegionSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/regions", func(w http.ResponseWriter, r *http.Request) { +func HandleCreateRegionSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/regions", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, CreateRequest) @@ -205,8 +205,8 @@ func HandleCreateRegionSuccessfully(t *testing.T) { // HandleUpdateRegionSuccessfully creates an HTTP handler at `/regions` on the // test handler mux that tests region update. -func HandleUpdateRegionSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/regions/RegionOne-West", func(w http.ResponseWriter, r *http.Request) { +func HandleUpdateRegionSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/regions/RegionOne-West", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PATCH") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, UpdateRequest) @@ -218,8 +218,8 @@ func HandleUpdateRegionSuccessfully(t *testing.T) { // HandleDeleteRegionSuccessfully creates an HTTP handler at `/regions` on the // test handler mux that tests region deletion. -func HandleDeleteRegionSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/regions/RegionOne-West", func(w http.ResponseWriter, r *http.Request) { +func HandleDeleteRegionSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/regions/RegionOne-West", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/identity/v3/regions/testing/requests_test.go b/openstack/identity/v3/regions/testing/requests_test.go index b85b112d13..0c82efd009 100644 --- a/openstack/identity/v3/regions/testing/requests_test.go +++ b/openstack/identity/v3/regions/testing/requests_test.go @@ -11,12 +11,12 @@ import ( ) func TestListRegions(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListRegionsSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListRegionsSuccessfully(t, fakeServer) count := 0 - err := regions.List(client.ServiceClient(), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := regions.List(client.ServiceClient(fakeServer), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := regions.ExtractRegions(page) @@ -31,11 +31,11 @@ func TestListRegions(t *testing.T) { } func TestListRegionsAllPages(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListRegionsSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListRegionsSuccessfully(t, fakeServer) - allPages, err := regions.List(client.ServiceClient(), nil).AllPages(context.TODO()) + allPages, err := regions.List(client.ServiceClient(fakeServer), nil).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := regions.ExtractRegions(allPages) th.AssertNoErr(t, err) @@ -44,20 +44,20 @@ func TestListRegionsAllPages(t *testing.T) { } func TestGetRegion(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetRegionSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetRegionSuccessfully(t, fakeServer) - actual, err := regions.Get(context.TODO(), client.ServiceClient(), "RegionOne-West").Extract() + actual, err := regions.Get(context.TODO(), client.ServiceClient(fakeServer), "RegionOne-West").Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, SecondRegion, *actual) } func TestCreateRegion(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateRegionSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCreateRegionSuccessfully(t, fakeServer) createOpts := regions.CreateOpts{ ID: "RegionOne-West", @@ -68,15 +68,15 @@ func TestCreateRegion(t *testing.T) { ParentRegionID: "RegionOne", } - actual, err := regions.Create(context.TODO(), client.ServiceClient(), createOpts).Extract() + actual, err := regions.Create(context.TODO(), client.ServiceClient(fakeServer), createOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, SecondRegion, *actual) } func TestUpdateRegion(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleUpdateRegionSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleUpdateRegionSuccessfully(t, fakeServer) var description = "First West sub-region of RegionOne" updateOpts := regions.UpdateOpts{ @@ -92,16 +92,16 @@ func TestUpdateRegion(t *testing.T) { */ } - actual, err := regions.Update(context.TODO(), client.ServiceClient(), "RegionOne-West", updateOpts).Extract() + actual, err := regions.Update(context.TODO(), client.ServiceClient(fakeServer), "RegionOne-West", updateOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, SecondRegionUpdated, *actual) } func TestDeleteRegion(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDeleteRegionSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDeleteRegionSuccessfully(t, fakeServer) - res := regions.Delete(context.TODO(), client.ServiceClient(), "RegionOne-West") + res := regions.Delete(context.TODO(), client.ServiceClient(fakeServer), "RegionOne-West") th.AssertNoErr(t, res.Err) } diff --git a/openstack/identity/v3/registeredlimits/testing/fixtures_test.go b/openstack/identity/v3/registeredlimits/testing/fixtures_test.go index 1bcfc5e867..81ddc3cd7b 100644 --- a/openstack/identity/v3/registeredlimits/testing/fixtures_test.go +++ b/openstack/identity/v3/registeredlimits/testing/fixtures_test.go @@ -155,8 +155,8 @@ var ExpectedRegisteredLimitsSlice = []registeredlimits.RegisteredLimit{FirstRegi // HandleListRegisteredLimitsSuccessfully creates an HTTP handler at `/registered_limits` on the // test handler mux that responds with a list of two registered limits. -func HandleListRegisteredLimitsSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/registered_limits", func(w http.ResponseWriter, r *http.Request) { +func HandleListRegisteredLimitsSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/registered_limits", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -169,8 +169,8 @@ func HandleListRegisteredLimitsSuccessfully(t *testing.T) { // HandleGetRegisteredLimitSuccessfully creates an HTTP handler at `/registered_limits` on the // test handler mux that responds with a single project. -func HandleGetRegisteredLimitSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/registered_limits/3229b3849f584faea483d6851f7aab05", func(w http.ResponseWriter, r *http.Request) { +func HandleGetRegisteredLimitSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/registered_limits/3229b3849f584faea483d6851f7aab05", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -183,8 +183,8 @@ func HandleGetRegisteredLimitSuccessfully(t *testing.T) { // HandleCreateRegisteredLimitSuccessfully creates an HTTP handler at `/registered_limits` on the // test handler mux that tests registered limit creation. -func HandleCreateRegisteredLimitSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/registered_limits", func(w http.ResponseWriter, r *http.Request) { +func HandleCreateRegisteredLimitSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/registered_limits", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, CreateRequest) @@ -196,8 +196,8 @@ func HandleCreateRegisteredLimitSuccessfully(t *testing.T) { // HandleDeleteRegisteredLimitSuccessfully creates an HTTP handler at `/registered_limits` on the // test handler mux that tests registered_limit deletion. -func HandleDeleteRegisteredLimitSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/registered_limits/3229b3849f584faea483d6851f7aab05", func(w http.ResponseWriter, r *http.Request) { +func HandleDeleteRegisteredLimitSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/registered_limits/3229b3849f584faea483d6851f7aab05", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -207,8 +207,8 @@ func HandleDeleteRegisteredLimitSuccessfully(t *testing.T) { // HandleUpdateRegisteredLimitSuccessfully creates an HTTP handler at `/registered_limits` on the // test handler mux that tests registered limits updates. -func HandleUpdateRegisteredLimitSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/registered_limits/3229b3849f584faea483d6851f7aab05", func(w http.ResponseWriter, r *http.Request) { +func HandleUpdateRegisteredLimitSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/registered_limits/3229b3849f584faea483d6851f7aab05", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PATCH") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, UpdateRequest) diff --git a/openstack/identity/v3/registeredlimits/testing/requests_test.go b/openstack/identity/v3/registeredlimits/testing/requests_test.go index ad2a30cb3f..a8f0e73bc7 100644 --- a/openstack/identity/v3/registeredlimits/testing/requests_test.go +++ b/openstack/identity/v3/registeredlimits/testing/requests_test.go @@ -11,12 +11,12 @@ import ( ) func TestListRegisteredLimits(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListRegisteredLimitsSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListRegisteredLimitsSuccessfully(t, fakeServer) count := 0 - err := registeredlimits.List(client.ServiceClient(), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := registeredlimits.List(client.ServiceClient(fakeServer), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := registeredlimits.ExtractRegisteredLimits(page) @@ -31,11 +31,11 @@ func TestListRegisteredLimits(t *testing.T) { } func TestListRegisteredLimitsAllPages(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListRegisteredLimitsSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListRegisteredLimitsSuccessfully(t, fakeServer) - allPages, err := registeredlimits.List(client.ServiceClient(), nil).AllPages(context.TODO()) + allPages, err := registeredlimits.List(client.ServiceClient(fakeServer), nil).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := registeredlimits.ExtractRegisteredLimits(allPages) th.AssertNoErr(t, err) @@ -43,9 +43,9 @@ func TestListRegisteredLimitsAllPages(t *testing.T) { } func TestCreateRegisteredLimits(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateRegisteredLimitSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCreateRegisteredLimitSuccessfully(t, fakeServer) createOpts := registeredlimits.BatchCreateOpts{ registeredlimits.CreateOpts{ @@ -63,34 +63,34 @@ func TestCreateRegisteredLimits(t *testing.T) { }, } - actual, err := registeredlimits.BatchCreate(context.TODO(), client.ServiceClient(), createOpts).Extract() + actual, err := registeredlimits.BatchCreate(context.TODO(), client.ServiceClient(fakeServer), createOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, ExpectedRegisteredLimitsSlice, actual) } func TestGetRegisteredLimit(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetRegisteredLimitSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetRegisteredLimitSuccessfully(t, fakeServer) - actual, err := registeredlimits.Get(context.TODO(), client.ServiceClient(), "3229b3849f584faea483d6851f7aab05").Extract() + actual, err := registeredlimits.Get(context.TODO(), client.ServiceClient(fakeServer), "3229b3849f584faea483d6851f7aab05").Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, SecondRegisteredLimit, *actual) } func TestDeleteRegisteredLimit(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDeleteRegisteredLimitSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDeleteRegisteredLimitSuccessfully(t, fakeServer) - res := registeredlimits.Delete(context.TODO(), client.ServiceClient(), "3229b3849f584faea483d6851f7aab05") + res := registeredlimits.Delete(context.TODO(), client.ServiceClient(fakeServer), "3229b3849f584faea483d6851f7aab05") th.AssertNoErr(t, res.Err) } func TestUpdateRegisteredLimit(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleUpdateRegisteredLimitSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleUpdateRegisteredLimitSuccessfully(t, fakeServer) defaultLimit := 15 updateOpts := registeredlimits.UpdateOpts{ @@ -99,7 +99,7 @@ func TestUpdateRegisteredLimit(t *testing.T) { DefaultLimit: &defaultLimit, } - actual, err := registeredlimits.Update(context.TODO(), client.ServiceClient(), "3229b3849f584faea483d6851f7aab05", updateOpts).Extract() + actual, err := registeredlimits.Update(context.TODO(), client.ServiceClient(fakeServer), "3229b3849f584faea483d6851f7aab05", updateOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, UpdatedSecondRegisteredLimit, *actual) } diff --git a/openstack/identity/v3/roles/testing/fixtures_test.go b/openstack/identity/v3/roles/testing/fixtures_test.go index 4e6ec8e843..1e8403eb64 100644 --- a/openstack/identity/v3/roles/testing/fixtures_test.go +++ b/openstack/identity/v3/roles/testing/fixtures_test.go @@ -342,8 +342,8 @@ var ExpectedRolesSlice = []roles.Role{FirstRole, SecondRole} // HandleListRolesSuccessfully creates an HTTP handler at `/roles` on the // test handler mux that responds with a list of two roles. -func HandleListRolesSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/roles", func(w http.ResponseWriter, r *http.Request) { +func HandleListRolesSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/roles", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -356,8 +356,8 @@ func HandleListRolesSuccessfully(t *testing.T) { // HandleGetRoleSuccessfully creates an HTTP handler at `/roles` on the // test handler mux that responds with a single role. -func HandleGetRoleSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/roles/9fe1d3", func(w http.ResponseWriter, r *http.Request) { +func HandleGetRoleSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/roles/9fe1d3", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -370,8 +370,8 @@ func HandleGetRoleSuccessfully(t *testing.T) { // HandleCreateRoleSuccessfully creates an HTTP handler at `/roles` on the // test handler mux that tests role creation. -func HandleCreateRoleSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/roles", func(w http.ResponseWriter, r *http.Request) { +func HandleCreateRoleSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/roles", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, CreateRequest) @@ -383,8 +383,8 @@ func HandleCreateRoleSuccessfully(t *testing.T) { // HandleUpdateRoleSuccessfully creates an HTTP handler at `/roles` on the // test handler mux that tests role update. -func HandleUpdateRoleSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/roles/9fe1d3", func(w http.ResponseWriter, r *http.Request) { +func HandleUpdateRoleSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/roles/9fe1d3", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PATCH") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, UpdateRequest) @@ -396,8 +396,8 @@ func HandleUpdateRoleSuccessfully(t *testing.T) { // HandleDeleteRoleSuccessfully creates an HTTP handler at `/roles` on the // test handler mux that tests role deletion. -func HandleDeleteRoleSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/roles/9fe1d3", func(w http.ResponseWriter, r *http.Request) { +func HandleDeleteRoleSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/roles/9fe1d3", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -405,52 +405,52 @@ func HandleDeleteRoleSuccessfully(t *testing.T) { }) } -func HandleAssignSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/projects/{project_id}/users/{user_id}/roles/{role_id}", func(w http.ResponseWriter, r *http.Request) { +func HandleAssignSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/projects/{project_id}/users/{user_id}/roles/{role_id}", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) - th.Mux.HandleFunc("/projects/{project_id}/groups/{group_id}/roles/{role_id}", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/projects/{project_id}/groups/{group_id}/roles/{role_id}", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) - th.Mux.HandleFunc("/domains/{domain_id}/users/{user_id}/roles/{role_id}", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/domains/{domain_id}/users/{user_id}/roles/{role_id}", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) - th.Mux.HandleFunc("/domains/{domain_id}/groups/{group_id}/roles/{role_id}", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/domains/{domain_id}/groups/{group_id}/roles/{role_id}", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) } -func HandleUnassignSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/projects/{project_id}/users/{user_id}/roles/{role_id}", func(w http.ResponseWriter, r *http.Request) { +func HandleUnassignSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/projects/{project_id}/users/{user_id}/roles/{role_id}", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) - th.Mux.HandleFunc("/projects/{project_id}/groups/{group_id}/roles/{role_id}", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/projects/{project_id}/groups/{group_id}/roles/{role_id}", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) - th.Mux.HandleFunc("/domains/{domain_id}/users/{user_id}/roles/{role_id}", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/domains/{domain_id}/users/{user_id}/roles/{role_id}", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) - th.Mux.HandleFunc("/domains/{domain_id}/groups/{group_id}/roles/{role_id}", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/domains/{domain_id}/groups/{group_id}/roles/{role_id}", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) @@ -491,8 +491,8 @@ var ExpectedRoleAssignmentsWithNamesSlice = []roles.RoleAssignment{ThirdRoleAssi // HandleListRoleAssignmentsSuccessfully creates an HTTP handler at `/role_assignments` on the // test handler mux that responds with a list of two role assignments. -func HandleListRoleAssignmentsSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/role_assignments", func(w http.ResponseWriter, r *http.Request) { +func HandleListRoleAssignmentsSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/role_assignments", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -505,8 +505,8 @@ func HandleListRoleAssignmentsSuccessfully(t *testing.T) { // HandleListRoleAssignmentsSuccessfully creates an HTTP handler at `/role_assignments` on the // test handler mux that responds with a list of two role assignments. -func HandleListRoleAssignmentsWithNamesSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/role_assignments", func(w http.ResponseWriter, r *http.Request) { +func HandleListRoleAssignmentsWithNamesSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/role_assignments", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -520,8 +520,8 @@ func HandleListRoleAssignmentsWithNamesSuccessfully(t *testing.T) { // HandleListRoleAssignmentsWithSubtreeSuccessfully creates an HTTP handler at `/role_assignments` on the // test handler mux that responds with a list of two role assignments. -func HandleListRoleAssignmentsWithSubtreeSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/role_assignments", func(w http.ResponseWriter, r *http.Request) { +func HandleListRoleAssignmentsWithSubtreeSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/role_assignments", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -549,7 +549,7 @@ var RoleOnResource = roles.Role{ // from ListAssignmentsOnResourceOutput. var ExpectedRolesOnResourceSlice = []roles.Role{RoleOnResource} -func HandleListAssignmentsOnResourceSuccessfully_ProjectsUsers(t *testing.T) { +func HandleListAssignmentsOnResourceSuccessfully_ProjectsUsers(t *testing.T, fakeServer th.FakeServer) { fn := func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") @@ -560,10 +560,10 @@ func HandleListAssignmentsOnResourceSuccessfully_ProjectsUsers(t *testing.T) { fmt.Fprint(w, ListAssignmentsOnResourceOutput) } - th.Mux.HandleFunc("/projects/{project_id}/users/{user_id}/roles", fn) + fakeServer.Mux.HandleFunc("/projects/{project_id}/users/{user_id}/roles", fn) } -func HandleListAssignmentsOnResourceSuccessfully_ProjectsGroups(t *testing.T) { +func HandleListAssignmentsOnResourceSuccessfully_ProjectsGroups(t *testing.T, fakeServer th.FakeServer) { fn := func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") @@ -574,10 +574,10 @@ func HandleListAssignmentsOnResourceSuccessfully_ProjectsGroups(t *testing.T) { fmt.Fprint(w, ListAssignmentsOnResourceOutput) } - th.Mux.HandleFunc("/projects/{project_id}/groups/{group_id}/roles", fn) + fakeServer.Mux.HandleFunc("/projects/{project_id}/groups/{group_id}/roles", fn) } -func HandleListAssignmentsOnResourceSuccessfully_DomainsUsers(t *testing.T) { +func HandleListAssignmentsOnResourceSuccessfully_DomainsUsers(t *testing.T, fakeServer th.FakeServer) { fn := func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") @@ -588,10 +588,10 @@ func HandleListAssignmentsOnResourceSuccessfully_DomainsUsers(t *testing.T) { fmt.Fprint(w, ListAssignmentsOnResourceOutput) } - th.Mux.HandleFunc("/domains/{domain_id}/users/{user_id}/roles", fn) + fakeServer.Mux.HandleFunc("/domains/{domain_id}/users/{user_id}/roles", fn) } -func HandleListAssignmentsOnResourceSuccessfully_DomainsGroups(t *testing.T) { +func HandleListAssignmentsOnResourceSuccessfully_DomainsGroups(t *testing.T, fakeServer th.FakeServer) { fn := func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") @@ -602,7 +602,7 @@ func HandleListAssignmentsOnResourceSuccessfully_DomainsGroups(t *testing.T) { fmt.Fprint(w, ListAssignmentsOnResourceOutput) } - th.Mux.HandleFunc("/domains/{domain_id}/groups/{group_id}/roles", fn) + fakeServer.Mux.HandleFunc("/domains/{domain_id}/groups/{group_id}/roles", fn) } var expectedRoleInferenceRule = roles.RoleInferenceRule{ @@ -627,7 +627,7 @@ var expectedRoleInferenceRule = roles.RoleInferenceRule{ }, } -func HandleCreateRoleInferenceRule(t *testing.T) { +func HandleCreateRoleInferenceRule(t *testing.T, fakeServer th.FakeServer) { fn := func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "Accept", "application/json") @@ -638,7 +638,7 @@ func HandleCreateRoleInferenceRule(t *testing.T) { fmt.Fprint(w, CreateRoleInferenceRuleOutput) } - th.Mux.HandleFunc("/roles/7ceab6192ea34a548cc71b24f72e762c/implies/97e2f5d38bc94842bc3da818c16762ed", fn) + fakeServer.Mux.HandleFunc("/roles/7ceab6192ea34a548cc71b24f72e762c/implies/97e2f5d38bc94842bc3da818c16762ed", fn) } var expectedRoleInferenceRuleList = roles.RoleInferenceRuleList{ @@ -705,7 +705,7 @@ var expectedRoleInferenceRuleList = roles.RoleInferenceRuleList{ }, } -func HandleListRoleInferenceRules(t *testing.T) { +func HandleListRoleInferenceRules(t *testing.T, fakeServer th.FakeServer) { fn := func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") @@ -716,20 +716,20 @@ func HandleListRoleInferenceRules(t *testing.T) { fmt.Fprint(w, ListRoleInferenceRulesOutput) } - th.Mux.HandleFunc("/role_inferences", fn) + fakeServer.Mux.HandleFunc("/role_inferences", fn) } -func HandleDeleteRoleInferenceRule(t *testing.T) { +func HandleDeleteRoleInferenceRule(t *testing.T, fakeServer th.FakeServer) { fn := func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) } - th.Mux.HandleFunc("/roles/7ceab6192ea34a548cc71b24f72e762c/implies/97e2f5d38bc94842bc3da818c16762ed", fn) + fakeServer.Mux.HandleFunc("/roles/7ceab6192ea34a548cc71b24f72e762c/implies/97e2f5d38bc94842bc3da818c16762ed", fn) } -func HandleGetRoleInferenceRule(t *testing.T) { +func HandleGetRoleInferenceRule(t *testing.T, fakeServer th.FakeServer) { fn := func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") @@ -740,5 +740,5 @@ func HandleGetRoleInferenceRule(t *testing.T) { fmt.Fprint(w, CreateRoleInferenceRuleOutput) } - th.Mux.HandleFunc("/roles/7ceab6192ea34a548cc71b24f72e762c/implies/97e2f5d38bc94842bc3da818c16762ed", fn) + fakeServer.Mux.HandleFunc("/roles/7ceab6192ea34a548cc71b24f72e762c/implies/97e2f5d38bc94842bc3da818c16762ed", fn) } diff --git a/openstack/identity/v3/roles/testing/requests_test.go b/openstack/identity/v3/roles/testing/requests_test.go index 5268fc06c7..fb3021064a 100644 --- a/openstack/identity/v3/roles/testing/requests_test.go +++ b/openstack/identity/v3/roles/testing/requests_test.go @@ -11,12 +11,12 @@ import ( ) func TestListRoles(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListRolesSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListRolesSuccessfully(t, fakeServer) count := 0 - err := roles.List(client.ServiceClient(), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := roles.List(client.ServiceClient(fakeServer), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := roles.ExtractRoles(page) @@ -31,11 +31,11 @@ func TestListRoles(t *testing.T) { } func TestListRolesAllPages(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListRolesSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListRolesSuccessfully(t, fakeServer) - allPages, err := roles.List(client.ServiceClient(), nil).AllPages(context.TODO()) + allPages, err := roles.List(client.ServiceClient(fakeServer), nil).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := roles.ExtractRoles(allPages) th.AssertNoErr(t, err) @@ -76,20 +76,20 @@ func TestListUsersFiltersCheck(t *testing.T) { } func TestGetRole(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetRoleSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetRoleSuccessfully(t, fakeServer) - actual, err := roles.Get(context.TODO(), client.ServiceClient(), "9fe1d3").Extract() + actual, err := roles.Get(context.TODO(), client.ServiceClient(fakeServer), "9fe1d3").Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, SecondRole, *actual) } func TestCreateRole(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateRoleSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCreateRoleSuccessfully(t, fakeServer) createOpts := roles.CreateOpts{ Name: "support", @@ -99,15 +99,15 @@ func TestCreateRole(t *testing.T) { }, } - actual, err := roles.Create(context.TODO(), client.ServiceClient(), createOpts).Extract() + actual, err := roles.Create(context.TODO(), client.ServiceClient(fakeServer), createOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, SecondRole, *actual) } func TestUpdateRole(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleUpdateRoleSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleUpdateRoleSuccessfully(t, fakeServer) updateOpts := roles.UpdateOpts{ Extra: map[string]any{ @@ -115,27 +115,27 @@ func TestUpdateRole(t *testing.T) { }, } - actual, err := roles.Update(context.TODO(), client.ServiceClient(), "9fe1d3", updateOpts).Extract() + actual, err := roles.Update(context.TODO(), client.ServiceClient(fakeServer), "9fe1d3", updateOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, SecondRoleUpdated, *actual) } func TestDeleteRole(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDeleteRoleSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDeleteRoleSuccessfully(t, fakeServer) - res := roles.Delete(context.TODO(), client.ServiceClient(), "9fe1d3") + res := roles.Delete(context.TODO(), client.ServiceClient(fakeServer), "9fe1d3") th.AssertNoErr(t, res.Err) } func TestListAssignmentsSinglePage(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListRoleAssignmentsSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListRoleAssignmentsSuccessfully(t, fakeServer) count := 0 - err := roles.ListAssignments(client.ServiceClient(), roles.ListAssignmentsOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := roles.ListAssignments(client.ServiceClient(fakeServer), roles.ListAssignmentsOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := roles.ExtractRoleAssignments(page) th.AssertNoErr(t, err) @@ -149,9 +149,9 @@ func TestListAssignmentsSinglePage(t *testing.T) { } func TestListAssignmentsWithNamesSinglePage(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListRoleAssignmentsWithNamesSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListRoleAssignmentsWithNamesSuccessfully(t, fakeServer) var includeNames = true listOpts := roles.ListAssignmentsOpts{ @@ -159,7 +159,7 @@ func TestListAssignmentsWithNamesSinglePage(t *testing.T) { } count := 0 - err := roles.ListAssignments(client.ServiceClient(), listOpts).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := roles.ListAssignments(client.ServiceClient(fakeServer), listOpts).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := roles.ExtractRoleAssignments(page) th.AssertNoErr(t, err) @@ -173,9 +173,9 @@ func TestListAssignmentsWithNamesSinglePage(t *testing.T) { } func TestListAssignmentsWithSubtreeSinglePage(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListRoleAssignmentsWithSubtreeSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListRoleAssignmentsWithSubtreeSuccessfully(t, fakeServer) var includeSubtree = true listOpts := roles.ListAssignmentsOpts{ @@ -183,7 +183,7 @@ func TestListAssignmentsWithSubtreeSinglePage(t *testing.T) { } count := 0 - err := roles.ListAssignments(client.ServiceClient(), listOpts).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := roles.ListAssignments(client.ServiceClient(fakeServer), listOpts).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := roles.ExtractRoleAssignments(page) th.AssertNoErr(t, err) @@ -197,12 +197,12 @@ func TestListAssignmentsWithSubtreeSinglePage(t *testing.T) { } func TestListAssignmentsOnResource_ProjectsUsers(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListAssignmentsOnResourceSuccessfully_ProjectsUsers(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListAssignmentsOnResourceSuccessfully_ProjectsUsers(t, fakeServer) count := 0 - err := roles.ListAssignmentsOnResource(client.ServiceClient(), roles.ListAssignmentsOnResourceOpts{ + err := roles.ListAssignmentsOnResource(client.ServiceClient(fakeServer), roles.ListAssignmentsOnResourceOpts{ UserID: "{user_id}", ProjectID: "{project_id}", }).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { @@ -219,12 +219,12 @@ func TestListAssignmentsOnResource_ProjectsUsers(t *testing.T) { } func TestListAssignmentsOnResource_DomainsUsers(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListAssignmentsOnResourceSuccessfully_DomainsUsers(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListAssignmentsOnResourceSuccessfully_DomainsUsers(t, fakeServer) count := 0 - err := roles.ListAssignmentsOnResource(client.ServiceClient(), roles.ListAssignmentsOnResourceOpts{ + err := roles.ListAssignmentsOnResource(client.ServiceClient(fakeServer), roles.ListAssignmentsOnResourceOpts{ UserID: "{user_id}", DomainID: "{domain_id}", }).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { @@ -241,12 +241,12 @@ func TestListAssignmentsOnResource_DomainsUsers(t *testing.T) { } func TestListAssignmentsOnResource_ProjectsGroups(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListAssignmentsOnResourceSuccessfully_ProjectsGroups(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListAssignmentsOnResourceSuccessfully_ProjectsGroups(t, fakeServer) count := 0 - err := roles.ListAssignmentsOnResource(client.ServiceClient(), roles.ListAssignmentsOnResourceOpts{ + err := roles.ListAssignmentsOnResource(client.ServiceClient(fakeServer), roles.ListAssignmentsOnResourceOpts{ GroupID: "{group_id}", ProjectID: "{project_id}", }).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { @@ -263,12 +263,12 @@ func TestListAssignmentsOnResource_ProjectsGroups(t *testing.T) { } func TestListAssignmentsOnResource_DomainsGroups(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListAssignmentsOnResourceSuccessfully_DomainsGroups(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListAssignmentsOnResourceSuccessfully_DomainsGroups(t, fakeServer) count := 0 - err := roles.ListAssignmentsOnResource(client.ServiceClient(), roles.ListAssignmentsOnResourceOpts{ + err := roles.ListAssignmentsOnResource(client.ServiceClient(fakeServer), roles.ListAssignmentsOnResourceOpts{ GroupID: "{group_id}", DomainID: "{domain_id}", }).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { @@ -285,29 +285,29 @@ func TestListAssignmentsOnResource_DomainsGroups(t *testing.T) { } func TestAssign(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleAssignSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleAssignSuccessfully(t, fakeServer) - err := roles.Assign(context.TODO(), client.ServiceClient(), "{role_id}", roles.AssignOpts{ + err := roles.Assign(context.TODO(), client.ServiceClient(fakeServer), "{role_id}", roles.AssignOpts{ UserID: "{user_id}", ProjectID: "{project_id}", }).ExtractErr() th.AssertNoErr(t, err) - err = roles.Assign(context.TODO(), client.ServiceClient(), "{role_id}", roles.AssignOpts{ + err = roles.Assign(context.TODO(), client.ServiceClient(fakeServer), "{role_id}", roles.AssignOpts{ UserID: "{user_id}", DomainID: "{domain_id}", }).ExtractErr() th.AssertNoErr(t, err) - err = roles.Assign(context.TODO(), client.ServiceClient(), "{role_id}", roles.AssignOpts{ + err = roles.Assign(context.TODO(), client.ServiceClient(fakeServer), "{role_id}", roles.AssignOpts{ GroupID: "{group_id}", ProjectID: "{project_id}", }).ExtractErr() th.AssertNoErr(t, err) - err = roles.Assign(context.TODO(), client.ServiceClient(), "{role_id}", roles.AssignOpts{ + err = roles.Assign(context.TODO(), client.ServiceClient(fakeServer), "{role_id}", roles.AssignOpts{ GroupID: "{group_id}", DomainID: "{domain_id}", }).ExtractErr() @@ -315,29 +315,29 @@ func TestAssign(t *testing.T) { } func TestUnassign(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleUnassignSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleUnassignSuccessfully(t, fakeServer) - err := roles.Unassign(context.TODO(), client.ServiceClient(), "{role_id}", roles.UnassignOpts{ + err := roles.Unassign(context.TODO(), client.ServiceClient(fakeServer), "{role_id}", roles.UnassignOpts{ UserID: "{user_id}", ProjectID: "{project_id}", }).ExtractErr() th.AssertNoErr(t, err) - err = roles.Unassign(context.TODO(), client.ServiceClient(), "{role_id}", roles.UnassignOpts{ + err = roles.Unassign(context.TODO(), client.ServiceClient(fakeServer), "{role_id}", roles.UnassignOpts{ UserID: "{user_id}", DomainID: "{domain_id}", }).ExtractErr() th.AssertNoErr(t, err) - err = roles.Unassign(context.TODO(), client.ServiceClient(), "{role_id}", roles.UnassignOpts{ + err = roles.Unassign(context.TODO(), client.ServiceClient(fakeServer), "{role_id}", roles.UnassignOpts{ GroupID: "{group_id}", ProjectID: "{project_id}", }).ExtractErr() th.AssertNoErr(t, err) - err = roles.Unassign(context.TODO(), client.ServiceClient(), "{role_id}", roles.UnassignOpts{ + err = roles.Unassign(context.TODO(), client.ServiceClient(fakeServer), "{role_id}", roles.UnassignOpts{ GroupID: "{group_id}", DomainID: "{domain_id}", }).ExtractErr() @@ -345,40 +345,40 @@ func TestUnassign(t *testing.T) { } func TestCreateRoleInferenceRule(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateRoleInferenceRule(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCreateRoleInferenceRule(t, fakeServer) - actual, err := roles.CreateRoleInferenceRule(context.TODO(), client.ServiceClient(), "7ceab6192ea34a548cc71b24f72e762c", "97e2f5d38bc94842bc3da818c16762ed").Extract() + actual, err := roles.CreateRoleInferenceRule(context.TODO(), client.ServiceClient(fakeServer), "7ceab6192ea34a548cc71b24f72e762c", "97e2f5d38bc94842bc3da818c16762ed").Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, expectedRoleInferenceRule, *actual) } func TestListRoleInferenceRules(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListRoleInferenceRules(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListRoleInferenceRules(t, fakeServer) - actual, err := roles.ListRoleInferenceRules(context.TODO(), client.ServiceClient()).Extract() + actual, err := roles.ListRoleInferenceRules(context.TODO(), client.ServiceClient(fakeServer)).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, expectedRoleInferenceRuleList, *actual) } func TestDeleteRoleInferenceRule(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDeleteRoleInferenceRule(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDeleteRoleInferenceRule(t, fakeServer) - err := roles.DeleteRoleInferenceRule(context.TODO(), client.ServiceClient(), "7ceab6192ea34a548cc71b24f72e762c", "97e2f5d38bc94842bc3da818c16762ed").ExtractErr() + err := roles.DeleteRoleInferenceRule(context.TODO(), client.ServiceClient(fakeServer), "7ceab6192ea34a548cc71b24f72e762c", "97e2f5d38bc94842bc3da818c16762ed").ExtractErr() th.AssertNoErr(t, err) } func TestGetInferenceRule(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetRoleInferenceRule(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetRoleInferenceRule(t, fakeServer) - actual, err := roles.GetRoleInferenceRule(context.TODO(), client.ServiceClient(), "7ceab6192ea34a548cc71b24f72e762c", "97e2f5d38bc94842bc3da818c16762ed").Extract() + actual, err := roles.GetRoleInferenceRule(context.TODO(), client.ServiceClient(fakeServer), "7ceab6192ea34a548cc71b24f72e762c", "97e2f5d38bc94842bc3da818c16762ed").Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, expectedRoleInferenceRule, *actual) } diff --git a/openstack/identity/v3/services/testing/fixtures_test.go b/openstack/identity/v3/services/testing/fixtures_test.go index 0a9274c500..9bd0076c58 100644 --- a/openstack/identity/v3/services/testing/fixtures_test.go +++ b/openstack/identity/v3/services/testing/fixtures_test.go @@ -156,8 +156,8 @@ var ExpectedServicesSlice = []services.Service{FirstService, SecondService} // HandleListServicesSuccessfully creates an HTTP handler at `/services` on the // test handler mux that responds with a list of two services. -func HandleListServicesSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/services", func(w http.ResponseWriter, r *http.Request) { +func HandleListServicesSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/services", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -170,8 +170,8 @@ func HandleListServicesSuccessfully(t *testing.T) { // HandleGetServiceSuccessfully creates an HTTP handler at `/services` on the // test handler mux that responds with a single service. -func HandleGetServiceSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/services/9876", func(w http.ResponseWriter, r *http.Request) { +func HandleGetServiceSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/services/9876", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -184,8 +184,8 @@ func HandleGetServiceSuccessfully(t *testing.T) { // HandleCreateServiceSuccessfully creates an HTTP handler at `/services` on the // test handler mux that tests service creation. -func HandleCreateServiceSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/services", func(w http.ResponseWriter, r *http.Request) { +func HandleCreateServiceSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/services", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, CreateRequest) @@ -197,8 +197,8 @@ func HandleCreateServiceSuccessfully(t *testing.T) { // HandleUpdateServiceSuccessfully creates an HTTP handler at `/services` on the // test handler mux that tests service update. -func HandleUpdateServiceSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/services/9876", func(w http.ResponseWriter, r *http.Request) { +func HandleUpdateServiceSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/services/9876", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PATCH") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, UpdateRequest) diff --git a/openstack/identity/v3/services/testing/requests_test.go b/openstack/identity/v3/services/testing/requests_test.go index 77a212654e..12c241ea9e 100644 --- a/openstack/identity/v3/services/testing/requests_test.go +++ b/openstack/identity/v3/services/testing/requests_test.go @@ -12,9 +12,9 @@ import ( ) func TestCreateSuccessful(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateServiceSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCreateServiceSuccessfully(t, fakeServer) createOpts := services.CreateOpts{ Type: "compute", @@ -25,18 +25,18 @@ func TestCreateSuccessful(t *testing.T) { }, } - actual, err := services.Create(context.TODO(), client.ServiceClient(), createOpts).Extract() + actual, err := services.Create(context.TODO(), client.ServiceClient(fakeServer), createOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, SecondService, *actual) } func TestListServices(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListServicesSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListServicesSuccessfully(t, fakeServer) count := 0 - err := services.List(client.ServiceClient(), services.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := services.List(client.ServiceClient(fakeServer), services.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := services.ExtractServices(page) @@ -51,11 +51,11 @@ func TestListServices(t *testing.T) { } func TestListServicesAllPages(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListServicesSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListServicesSuccessfully(t, fakeServer) - allPages, err := services.List(client.ServiceClient(), nil).AllPages(context.TODO()) + allPages, err := services.List(client.ServiceClient(fakeServer), nil).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := services.ExtractServices(allPages) th.AssertNoErr(t, err) @@ -65,11 +65,11 @@ func TestListServicesAllPages(t *testing.T) { } func TestGetSuccessful(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetServiceSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetServiceSuccessfully(t, fakeServer) - actual, err := services.Get(context.TODO(), client.ServiceClient(), "9876").Extract() + actual, err := services.Get(context.TODO(), client.ServiceClient(fakeServer), "9876").Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, SecondService, *actual) @@ -77,9 +77,9 @@ func TestGetSuccessful(t *testing.T) { } func TestUpdateSuccessful(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleUpdateServiceSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleUpdateServiceSuccessfully(t, fakeServer) updateOpts := services.UpdateOpts{ Type: "compute2", @@ -87,22 +87,22 @@ func TestUpdateSuccessful(t *testing.T) { "description": "Service Two Updated", }, } - actual, err := services.Update(context.TODO(), client.ServiceClient(), "9876", updateOpts).Extract() + actual, err := services.Update(context.TODO(), client.ServiceClient(fakeServer), "9876", updateOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, SecondServiceUpdated, *actual) th.AssertEquals(t, SecondServiceUpdated.Extra["description"], "Service Two Updated") } func TestDeleteSuccessful(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/services/12345", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/services/12345", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) - res := services.Delete(context.TODO(), client.ServiceClient(), "12345") + res := services.Delete(context.TODO(), client.ServiceClient(fakeServer), "12345") th.AssertNoErr(t, res.Err) } diff --git a/openstack/identity/v3/tokens/testing/requests_test.go b/openstack/identity/v3/tokens/testing/requests_test.go index 8bb00fbffa..8157de3ca7 100644 --- a/openstack/identity/v3/tokens/testing/requests_test.go +++ b/openstack/identity/v3/tokens/testing/requests_test.go @@ -15,15 +15,15 @@ import ( // authTokenPost verifies that providing certain AuthOptions and Scope results in an expected JSON structure. func authTokenPost(t *testing.T, options tokens.AuthOptions, scope *tokens.Scope, requestJSON string) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() client := gophercloud.ServiceClient{ ProviderClient: &gophercloud.ProviderClient{}, - Endpoint: th.Endpoint(), + Endpoint: fakeServer.Endpoint(), } - th.Mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") @@ -50,12 +50,12 @@ func authTokenPost(t *testing.T, options tokens.AuthOptions, scope *tokens.Scope } func authTokenPostErr(t *testing.T, options tokens.AuthOptions, scope *tokens.Scope, includeToken bool, expectedErr error) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() client := gophercloud.ServiceClient{ ProviderClient: &gophercloud.ProviderClient{}, - Endpoint: th.Endpoint(), + Endpoint: fakeServer.Endpoint(), } if includeToken { client.TokenID = "abcdef123456" @@ -303,8 +303,8 @@ func TestCreateSystemScope(t *testing.T) { } func TestCreateUserIDPasswordTrustID(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() requestJSON := `{ "auth": { @@ -362,7 +362,7 @@ func TestCreateUserIDPasswordTrustID(t *testing.T) { } } }` - th.Mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") @@ -380,7 +380,7 @@ func TestCreateUserIDPasswordTrustID(t *testing.T) { }, } - rsp := tokens.Create(context.TODO(), client.ServiceClient(), &ao) + rsp := tokens.Create(context.TODO(), client.ServiceClient(fakeServer), &ao) token, err := rsp.Extract() if err != nil { @@ -513,15 +513,15 @@ func TestCreatePasswordTOTPProjectNameAndDomainNameScope(t *testing.T) { } func TestCreateExtractsTokenFromResponse(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() client := gophercloud.ServiceClient{ ProviderClient: &gophercloud.ProviderClient{}, - Endpoint: th.Endpoint(), + Endpoint: fakeServer.Endpoint(), } - th.Mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) { w.Header().Add("X-Subject-Token", "aaa111") w.WriteHeader(http.StatusCreated) @@ -652,17 +652,17 @@ func TestCreateFailureEmptyScope(t *testing.T) { */ func TestGetRequest(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() client := gophercloud.ServiceClient{ ProviderClient: &gophercloud.ProviderClient{ TokenID: "12345abcdef", }, - Endpoint: th.Endpoint(), + Endpoint: fakeServer.Endpoint(), } - th.Mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeaderUnset(t, r, "Content-Type") th.TestHeader(t, r, "Accept", "application/json") @@ -686,15 +686,15 @@ func TestGetRequest(t *testing.T) { } } -func prepareAuthTokenHandler(t *testing.T, expectedMethod string, status int) gophercloud.ServiceClient { +func prepareAuthTokenHandler(t *testing.T, fakeServer th.FakeServer, expectedMethod string, status int) gophercloud.ServiceClient { client := gophercloud.ServiceClient{ ProviderClient: &gophercloud.ProviderClient{ TokenID: "12345abcdef", }, - Endpoint: th.Endpoint(), + Endpoint: fakeServer.Endpoint(), } - th.Mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, expectedMethod) th.TestHeaderUnset(t, r, "Content-Type") th.TestHeader(t, r, "Accept", "application/json") @@ -708,9 +708,9 @@ func prepareAuthTokenHandler(t *testing.T, expectedMethod string, status int) go } func TestValidateRequestSuccessful(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - client := prepareAuthTokenHandler(t, "HEAD", http.StatusNoContent) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + client := prepareAuthTokenHandler(t, fakeServer, "HEAD", http.StatusNoContent) ok, err := tokens.Validate(context.TODO(), &client, "abcdef12345") if err != nil { @@ -723,9 +723,9 @@ func TestValidateRequestSuccessful(t *testing.T) { } func TestValidateRequestFailure(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - client := prepareAuthTokenHandler(t, "HEAD", http.StatusNotFound) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + client := prepareAuthTokenHandler(t, fakeServer, "HEAD", http.StatusNotFound) ok, err := tokens.Validate(context.TODO(), &client, "abcdef12345") if err != nil { @@ -738,9 +738,9 @@ func TestValidateRequestFailure(t *testing.T) { } func TestValidateRequestError(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - client := prepareAuthTokenHandler(t, "HEAD", http.StatusMethodNotAllowed) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + client := prepareAuthTokenHandler(t, fakeServer, "HEAD", http.StatusMethodNotAllowed) _, err := tokens.Validate(context.TODO(), &client, "abcdef12345") if err == nil { @@ -749,18 +749,18 @@ func TestValidateRequestError(t *testing.T) { } func TestRevokeRequestSuccessful(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - client := prepareAuthTokenHandler(t, "DELETE", http.StatusNoContent) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + client := prepareAuthTokenHandler(t, fakeServer, "DELETE", http.StatusNoContent) res := tokens.Revoke(context.TODO(), &client, "abcdef12345") th.AssertNoErr(t, res.Err) } func TestRevokeRequestError(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - client := prepareAuthTokenHandler(t, "DELETE", http.StatusNotFound) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + client := prepareAuthTokenHandler(t, fakeServer, "DELETE", http.StatusNotFound) res := tokens.Revoke(context.TODO(), &client, "abcdef12345") if res.Err == nil { @@ -769,15 +769,15 @@ func TestRevokeRequestError(t *testing.T) { } func TestNoTokenInResponse(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() client := gophercloud.ServiceClient{ ProviderClient: &gophercloud.ProviderClient{}, - Endpoint: th.Endpoint(), + Endpoint: fakeServer.Endpoint(), } - th.Mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusCreated) fmt.Fprint(w, `{}`) }) diff --git a/openstack/identity/v3/trusts/testing/fixtures_test.go b/openstack/identity/v3/trusts/testing/fixtures_test.go index 3e7e77fc3c..0962b53e0e 100644 --- a/openstack/identity/v3/trusts/testing/fixtures_test.go +++ b/openstack/identity/v3/trusts/testing/fixtures_test.go @@ -200,8 +200,8 @@ var ExpectedTrustRolesSlice = []trusts.Role{FirstRole, SecondRole} // HandleCreateTrust creates an HTTP handler at `/OS-TRUST/trusts` on the // test handler mux that tests trust creation. -func HandleCreateTrust(t *testing.T) { - th.Mux.HandleFunc("/OS-TRUST/trusts", func(w http.ResponseWriter, r *http.Request) { +func HandleCreateTrust(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/OS-TRUST/trusts", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, CreateRequest) @@ -214,8 +214,8 @@ func HandleCreateTrust(t *testing.T) { // HandleCreateTrustNoExpire creates an HTTP handler at `/OS-TRUST/trusts` on the // test handler mux that tests trust creation. -func HandleCreateTrustNoExpire(t *testing.T) { - th.Mux.HandleFunc("/OS-TRUST/trusts", func(w http.ResponseWriter, r *http.Request) { +func HandleCreateTrustNoExpire(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/OS-TRUST/trusts", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, CreateRequestNoExpire) @@ -228,8 +228,8 @@ func HandleCreateTrustNoExpire(t *testing.T) { // HandleDeleteUserSuccessfully creates an HTTP handler at `/users` on the // test handler mux that tests user deletion. -func HandleDeleteTrust(t *testing.T) { - th.Mux.HandleFunc("/OS-TRUST/trusts/3422b7c113894f5d90665e1a79655e23", func(w http.ResponseWriter, r *http.Request) { +func HandleDeleteTrust(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/OS-TRUST/trusts/3422b7c113894f5d90665e1a79655e23", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -239,8 +239,8 @@ func HandleDeleteTrust(t *testing.T) { // HandleGetTrustSuccessfully creates an HTTP handler at `/OS-TRUST/trusts` on the // test handler mux that responds with a single trusts. -func HandleGetTrustSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/OS-TRUST/trusts/987fe8", func(w http.ResponseWriter, r *http.Request) { +func HandleGetTrustSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/OS-TRUST/trusts/987fe8", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -309,8 +309,8 @@ var ExpectedTrustsSlice = []trusts.Trust{FirstTrust, SecondTrust} // HandleListTrustsSuccessfully creates an HTTP handler at `/OS-TRUST/trusts` on the // test handler mux that responds with a list of two trusts. -func HandleListTrustsSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/OS-TRUST/trusts", func(w http.ResponseWriter, r *http.Request) { +func HandleListTrustsSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/OS-TRUST/trusts", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -323,8 +323,8 @@ func HandleListTrustsSuccessfully(t *testing.T) { // HandleListTrustRolesSuccessfully creates an HTTP handler at `/OS-TRUST/trusts/987fe8/roles` on the // test handler mux that responds with a list trust roles. -func HandleListTrustRolesSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/OS-TRUST/trusts/987fe8/roles", func(w http.ResponseWriter, r *http.Request) { +func HandleListTrustRolesSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/OS-TRUST/trusts/987fe8/roles", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -337,8 +337,8 @@ func HandleListTrustRolesSuccessfully(t *testing.T) { // HandleGetTrustRoleSuccessfully creates an HTTP handler at `/OS-TRUST/trusts/987fe8/roles/c1648e` on the // test handler mux that responds with a trust role details. -func HandleGetTrustRoleSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/OS-TRUST/trusts/987fe8/roles/c1648e", func(w http.ResponseWriter, r *http.Request) { +func HandleGetTrustRoleSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/OS-TRUST/trusts/987fe8/roles/c1648e", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -351,8 +351,8 @@ func HandleGetTrustRoleSuccessfully(t *testing.T) { // HandleCheckTrustRoleSuccessfully creates an HTTP handler at `/OS-TRUST/trusts/987fe8/roles/c1648e` on the // test handler mux that responds with a list trust roles. -func HandleCheckTrustRoleSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/OS-TRUST/trusts/987fe8/roles/c1648e", func(w http.ResponseWriter, r *http.Request) { +func HandleCheckTrustRoleSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/OS-TRUST/trusts/987fe8/roles/c1648e", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "HEAD") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/identity/v3/trusts/testing/requests_test.go b/openstack/identity/v3/trusts/testing/requests_test.go index 0b2d8149cb..8f11e92855 100644 --- a/openstack/identity/v3/trusts/testing/requests_test.go +++ b/openstack/identity/v3/trusts/testing/requests_test.go @@ -12,12 +12,12 @@ import ( ) func TestCreateTrust(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateTrust(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCreateTrust(t, fakeServer) expiresAt := time.Date(2019, 12, 1, 14, 0, 0, 0, time.UTC) - result, err := trusts.Create(context.TODO(), client.ServiceClient(), trusts.CreateOpts{ + result, err := trusts.Create(context.TODO(), client.ServiceClient(fakeServer), trusts.CreateOpts{ ExpiresAt: &expiresAt, AllowRedelegation: true, ProjectID: "9b71012f5a4a4aef9193f1995fe159b2", @@ -35,11 +35,11 @@ func TestCreateTrust(t *testing.T) { } func TestCreateTrustNoExpire(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateTrustNoExpire(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCreateTrustNoExpire(t, fakeServer) - result, err := trusts.Create(context.TODO(), client.ServiceClient(), trusts.CreateOpts{ + result, err := trusts.Create(context.TODO(), client.ServiceClient(fakeServer), trusts.CreateOpts{ AllowRedelegation: true, ProjectID: "9b71012f5a4a4aef9193f1995fe159b2", Roles: []trusts.Role{ @@ -56,30 +56,30 @@ func TestCreateTrustNoExpire(t *testing.T) { } func TestDeleteTrust(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDeleteTrust(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDeleteTrust(t, fakeServer) - res := trusts.Delete(context.TODO(), client.ServiceClient(), "3422b7c113894f5d90665e1a79655e23") + res := trusts.Delete(context.TODO(), client.ServiceClient(fakeServer), "3422b7c113894f5d90665e1a79655e23") th.AssertNoErr(t, res.Err) } func TestGetTrust(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetTrustSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetTrustSuccessfully(t, fakeServer) - res := trusts.Get(context.TODO(), client.ServiceClient(), "987fe8") + res := trusts.Get(context.TODO(), client.ServiceClient(fakeServer), "987fe8") th.AssertNoErr(t, res.Err) } func TestListTrusts(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListTrustsSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListTrustsSuccessfully(t, fakeServer) count := 0 - err := trusts.List(client.ServiceClient(), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := trusts.List(client.ServiceClient(fakeServer), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := trusts.ExtractTrusts(page) @@ -94,11 +94,11 @@ func TestListTrusts(t *testing.T) { } func TestListTrustsAllPages(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListTrustsSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListTrustsSuccessfully(t, fakeServer) - allPages, err := trusts.List(client.ServiceClient(), nil).AllPages(context.TODO()) + allPages, err := trusts.List(client.ServiceClient(fakeServer), nil).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := trusts.ExtractTrusts(allPages) th.AssertNoErr(t, err) @@ -106,13 +106,13 @@ func TestListTrustsAllPages(t *testing.T) { } func TestListTrustsFiltered(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListTrustsSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListTrustsSuccessfully(t, fakeServer) trustsListOpts := trusts.ListOpts{ TrustorUserID: "86c0d5", } - allPages, err := trusts.List(client.ServiceClient(), trustsListOpts).AllPages(context.TODO()) + allPages, err := trusts.List(client.ServiceClient(fakeServer), trustsListOpts).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := trusts.ExtractTrusts(allPages) th.AssertNoErr(t, err) @@ -120,12 +120,12 @@ func TestListTrustsFiltered(t *testing.T) { } func TestListTrustRoles(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListTrustRolesSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListTrustRolesSuccessfully(t, fakeServer) count := 0 - err := trusts.ListRoles(client.ServiceClient(), "987fe8").EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := trusts.ListRoles(client.ServiceClient(fakeServer), "987fe8").EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := trusts.ExtractRoles(page) @@ -140,11 +140,11 @@ func TestListTrustRoles(t *testing.T) { } func TestListTrustRolesAllPages(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListTrustRolesSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListTrustRolesSuccessfully(t, fakeServer) - allPages, err := trusts.ListRoles(client.ServiceClient(), "987fe8").AllPages(context.TODO()) + allPages, err := trusts.ListRoles(client.ServiceClient(fakeServer), "987fe8").AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := trusts.ExtractRoles(allPages) th.AssertNoErr(t, err) @@ -152,21 +152,21 @@ func TestListTrustRolesAllPages(t *testing.T) { } func TestGetTrustRole(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetTrustRoleSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetTrustRoleSuccessfully(t, fakeServer) - role, err := trusts.GetRole(context.TODO(), client.ServiceClient(), "987fe8", "c1648e").Extract() + role, err := trusts.GetRole(context.TODO(), client.ServiceClient(fakeServer), "987fe8", "c1648e").Extract() th.AssertNoErr(t, err) th.AssertEquals(t, FirstRole, *role) } func TestCheckTrustRole(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCheckTrustRoleSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCheckTrustRoleSuccessfully(t, fakeServer) - err := trusts.CheckRole(context.TODO(), client.ServiceClient(), "987fe8", "c1648e").ExtractErr() + err := trusts.CheckRole(context.TODO(), client.ServiceClient(fakeServer), "987fe8", "c1648e").ExtractErr() th.AssertNoErr(t, err) } diff --git a/openstack/identity/v3/users/testing/fixtures_test.go b/openstack/identity/v3/users/testing/fixtures_test.go index fbabad6eeb..8d409be0b9 100644 --- a/openstack/identity/v3/users/testing/fixtures_test.go +++ b/openstack/identity/v3/users/testing/fixtures_test.go @@ -374,8 +374,8 @@ var ExpectedProjectsSlice = []projects.Project{FirstProject, SecondProject} // HandleListUsersSuccessfully creates an HTTP handler at `/users` on the // test handler mux that responds with a list of two users. -func HandleListUsersSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/users", func(w http.ResponseWriter, r *http.Request) { +func HandleListUsersSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/users", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -388,8 +388,8 @@ func HandleListUsersSuccessfully(t *testing.T) { // HandleGetUserSuccessfully creates an HTTP handler at `/users` on the // test handler mux that responds with a single user. -func HandleGetUserSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/users/9fe1d3", func(w http.ResponseWriter, r *http.Request) { +func HandleGetUserSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/users/9fe1d3", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -402,8 +402,8 @@ func HandleGetUserSuccessfully(t *testing.T) { // HandleCreateUserSuccessfully creates an HTTP handler at `/users` on the // test handler mux that tests user creation. -func HandleCreateUserSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/users", func(w http.ResponseWriter, r *http.Request) { +func HandleCreateUserSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/users", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, CreateRequest) @@ -415,8 +415,8 @@ func HandleCreateUserSuccessfully(t *testing.T) { // HandleCreateNoOptionsUserSuccessfully creates an HTTP handler at `/users` on the // test handler mux that tests user creation. -func HandleCreateNoOptionsUserSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/users", func(w http.ResponseWriter, r *http.Request) { +func HandleCreateNoOptionsUserSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/users", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, CreateNoOptionsRequest) @@ -428,8 +428,8 @@ func HandleCreateNoOptionsUserSuccessfully(t *testing.T) { // HandleUpdateUserSuccessfully creates an HTTP handler at `/users` on the // test handler mux that tests user update. -func HandleUpdateUserSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/users/9fe1d3", func(w http.ResponseWriter, r *http.Request) { +func HandleUpdateUserSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/users/9fe1d3", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PATCH") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, UpdateRequest) @@ -441,8 +441,8 @@ func HandleUpdateUserSuccessfully(t *testing.T) { // HandleChangeUserPasswordSuccessfully creates an HTTP handler at `/users` on the // test handler mux that tests change user password. -func HandleChangeUserPasswordSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/users/9fe1d3/password", func(w http.ResponseWriter, r *http.Request) { +func HandleChangeUserPasswordSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/users/9fe1d3/password", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, ChangePasswordRequest) @@ -453,8 +453,8 @@ func HandleChangeUserPasswordSuccessfully(t *testing.T) { // HandleDeleteUserSuccessfully creates an HTTP handler at `/users` on the // test handler mux that tests user deletion. -func HandleDeleteUserSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/users/9fe1d3", func(w http.ResponseWriter, r *http.Request) { +func HandleDeleteUserSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/users/9fe1d3", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -464,8 +464,8 @@ func HandleDeleteUserSuccessfully(t *testing.T) { // HandleListUserGroupsSuccessfully creates an HTTP handler at /users/{userID}/groups // on the test handler mux that respons with a list of two groups -func HandleListUserGroupsSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/users/9fe1d3/groups", func(w http.ResponseWriter, r *http.Request) { +func HandleListUserGroupsSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/users/9fe1d3/groups", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -478,8 +478,8 @@ func HandleListUserGroupsSuccessfully(t *testing.T) { // HandleAddToGroupSuccessfully creates an HTTP handler at /groups/{groupID}/users/{userID} // on the test handler mux that tests adding user to group. -func HandleAddToGroupSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/groups/ea167b/users/9fe1d3", func(w http.ResponseWriter, r *http.Request) { +func HandleAddToGroupSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/groups/ea167b/users/9fe1d3", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -489,8 +489,8 @@ func HandleAddToGroupSuccessfully(t *testing.T) { // HandleIsMemberOfGroupSuccessfully creates an HTTP handler at /groups/{groupID}/users/{userID} // on the test handler mux that tests checking whether user belongs to group. -func HandleIsMemberOfGroupSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/groups/ea167b/users/9fe1d3", func(w http.ResponseWriter, r *http.Request) { +func HandleIsMemberOfGroupSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/groups/ea167b/users/9fe1d3", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "HEAD") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -500,8 +500,8 @@ func HandleIsMemberOfGroupSuccessfully(t *testing.T) { // HandleRemoveFromGroupSuccessfully creates an HTTP handler at /groups/{groupID}/users/{userID} // on the test handler mux that tests removing user from group. -func HandleRemoveFromGroupSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/groups/ea167b/users/9fe1d3", func(w http.ResponseWriter, r *http.Request) { +func HandleRemoveFromGroupSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/groups/ea167b/users/9fe1d3", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -511,8 +511,8 @@ func HandleRemoveFromGroupSuccessfully(t *testing.T) { // HandleListUserProjectsSuccessfully creates an HTTP handler at /users/{userID}/projects // on the test handler mux that respons wit a list of two projects -func HandleListUserProjectsSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/users/9fe1d3/projects", func(w http.ResponseWriter, r *http.Request) { +func HandleListUserProjectsSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/users/9fe1d3/projects", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -525,8 +525,8 @@ func HandleListUserProjectsSuccessfully(t *testing.T) { // HandleListInGroupSuccessfully creates an HTTP handler at /groups/{groupID}/users // on the test handler mux that response with a list of two users -func HandleListInGroupSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/groups/ea167b/users", func(w http.ResponseWriter, r *http.Request) { +func HandleListInGroupSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/groups/ea167b/users", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/identity/v3/users/testing/requests_test.go b/openstack/identity/v3/users/testing/requests_test.go index cb890808ee..12ed9323d7 100644 --- a/openstack/identity/v3/users/testing/requests_test.go +++ b/openstack/identity/v3/users/testing/requests_test.go @@ -13,12 +13,12 @@ import ( ) func TestListUsers(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListUsersSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListUsersSuccessfully(t, fakeServer) count := 0 - err := users.List(client.ServiceClient(), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := users.List(client.ServiceClient(fakeServer), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := users.ExtractUsers(page) @@ -33,11 +33,11 @@ func TestListUsers(t *testing.T) { } func TestListUsersAllPages(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListUsersSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListUsersSuccessfully(t, fakeServer) - allPages, err := users.List(client.ServiceClient(), nil).AllPages(context.TODO()) + allPages, err := users.List(client.ServiceClient(fakeServer), nil).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := users.ExtractUsers(allPages) th.AssertNoErr(t, err) @@ -79,20 +79,20 @@ func TestListUsersFiltersCheck(t *testing.T) { } func TestGetUser(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetUserSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetUserSuccessfully(t, fakeServer) - actual, err := users.Get(context.TODO(), client.ServiceClient(), "9fe1d3").Extract() + actual, err := users.Get(context.TODO(), client.ServiceClient(fakeServer), "9fe1d3").Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, SecondUser, *actual) th.AssertEquals(t, SecondUser.Extra["email"], "jsmith@example.com") } func TestCreateUser(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateUserSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCreateUserSuccessfully(t, fakeServer) iTrue := true createOpts := users.CreateOpts{ @@ -113,15 +113,15 @@ func TestCreateUser(t *testing.T) { }, } - actual, err := users.Create(context.TODO(), client.ServiceClient(), createOpts).Extract() + actual, err := users.Create(context.TODO(), client.ServiceClient(fakeServer), createOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, SecondUser, *actual) } func TestCreateNoOptionsUser(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateNoOptionsUserSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCreateNoOptionsUserSuccessfully(t, fakeServer) iTrue := true createOpts := users.CreateOpts{ @@ -135,15 +135,15 @@ func TestCreateNoOptionsUser(t *testing.T) { }, } - actual, err := users.Create(context.TODO(), client.ServiceClient(), createOpts).Extract() + actual, err := users.Create(context.TODO(), client.ServiceClient(fakeServer), createOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, SecondUserNoOptions, *actual) } func TestUpdateUser(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleUpdateUserSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleUpdateUserSuccessfully(t, fakeServer) iFalse := false updateOpts := users.UpdateOpts{ @@ -156,39 +156,39 @@ func TestUpdateUser(t *testing.T) { }, } - actual, err := users.Update(context.TODO(), client.ServiceClient(), "9fe1d3", updateOpts).Extract() + actual, err := users.Update(context.TODO(), client.ServiceClient(fakeServer), "9fe1d3", updateOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, SecondUserUpdated, *actual) } func TestChangeUserPassword(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleChangeUserPasswordSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleChangeUserPasswordSuccessfully(t, fakeServer) changePasswordOpts := users.ChangePasswordOpts{ OriginalPassword: "secretsecret", Password: "new_secretsecret", } - res := users.ChangePassword(context.TODO(), client.ServiceClient(), "9fe1d3", changePasswordOpts) + res := users.ChangePassword(context.TODO(), client.ServiceClient(fakeServer), "9fe1d3", changePasswordOpts) th.AssertNoErr(t, res.Err) } func TestDeleteUser(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDeleteUserSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDeleteUserSuccessfully(t, fakeServer) - res := users.Delete(context.TODO(), client.ServiceClient(), "9fe1d3") + res := users.Delete(context.TODO(), client.ServiceClient(fakeServer), "9fe1d3") th.AssertNoErr(t, res.Err) } func TestListUserGroups(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListUserGroupsSuccessfully(t) - allPages, err := users.ListGroups(client.ServiceClient(), "9fe1d3").AllPages(context.TODO()) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListUserGroupsSuccessfully(t, fakeServer) + allPages, err := users.ListGroups(client.ServiceClient(fakeServer), "9fe1d3").AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := groups.ExtractGroups(allPages) th.AssertNoErr(t, err) @@ -196,35 +196,35 @@ func TestListUserGroups(t *testing.T) { } func TestAddToGroup(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleAddToGroupSuccessfully(t) - res := users.AddToGroup(context.TODO(), client.ServiceClient(), "ea167b", "9fe1d3") + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleAddToGroupSuccessfully(t, fakeServer) + res := users.AddToGroup(context.TODO(), client.ServiceClient(fakeServer), "ea167b", "9fe1d3") th.AssertNoErr(t, res.Err) } func TestIsMemberOfGroup(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleIsMemberOfGroupSuccessfully(t) - ok, err := users.IsMemberOfGroup(context.TODO(), client.ServiceClient(), "ea167b", "9fe1d3").Extract() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleIsMemberOfGroupSuccessfully(t, fakeServer) + ok, err := users.IsMemberOfGroup(context.TODO(), client.ServiceClient(fakeServer), "ea167b", "9fe1d3").Extract() th.AssertNoErr(t, err) th.AssertEquals(t, true, ok) } func TestRemoveFromGroup(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleRemoveFromGroupSuccessfully(t) - res := users.RemoveFromGroup(context.TODO(), client.ServiceClient(), "ea167b", "9fe1d3") + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleRemoveFromGroupSuccessfully(t, fakeServer) + res := users.RemoveFromGroup(context.TODO(), client.ServiceClient(fakeServer), "ea167b", "9fe1d3") th.AssertNoErr(t, res.Err) } func TestListUserProjects(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListUserProjectsSuccessfully(t) - allPages, err := users.ListProjects(client.ServiceClient(), "9fe1d3").AllPages(context.TODO()) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListUserProjectsSuccessfully(t, fakeServer) + allPages, err := users.ListProjects(client.ServiceClient(fakeServer), "9fe1d3").AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := projects.ExtractProjects(allPages) th.AssertNoErr(t, err) @@ -232,16 +232,16 @@ func TestListUserProjects(t *testing.T) { } func TestListInGroup(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListInGroupSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListInGroupSuccessfully(t, fakeServer) iTrue := true listOpts := users.ListOpts{ Enabled: &iTrue, } - allPages, err := users.ListInGroup(client.ServiceClient(), "ea167b", listOpts).AllPages(context.TODO()) + allPages, err := users.ListInGroup(client.ServiceClient(fakeServer), "ea167b", listOpts).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := users.ExtractUsers(allPages) th.AssertNoErr(t, err) diff --git a/openstack/image/v2/imagedata/testing/fixtures_test.go b/openstack/image/v2/imagedata/testing/fixtures_test.go index 38179965cc..d9af6c1702 100644 --- a/openstack/image/v2/imagedata/testing/fixtures_test.go +++ b/openstack/image/v2/imagedata/testing/fixtures_test.go @@ -10,8 +10,8 @@ import ( ) // HandlePutImageDataSuccessfully setup -func HandlePutImageDataSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/images/da3b75d9-3f4a-40e7-8a2c-bfab23927dea/file", func(w http.ResponseWriter, r *http.Request) { +func HandlePutImageDataSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/images/da3b75d9-3f4a-40e7-8a2c-bfab23927dea/file", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -27,8 +27,8 @@ func HandlePutImageDataSuccessfully(t *testing.T) { } // HandleStageImageDataSuccessfully setup -func HandleStageImageDataSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/images/da3b75d9-3f4a-40e7-8a2c-bfab23927dea/stage", func(w http.ResponseWriter, r *http.Request) { +func HandleStageImageDataSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/images/da3b75d9-3f4a-40e7-8a2c-bfab23927dea/stage", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -44,8 +44,8 @@ func HandleStageImageDataSuccessfully(t *testing.T) { } // HandleGetImageDataSuccessfully setup -func HandleGetImageDataSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/images/da3b75d9-3f4a-40e7-8a2c-bfab23927dea/file", func(w http.ResponseWriter, r *http.Request) { +func HandleGetImageDataSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/images/da3b75d9-3f4a-40e7-8a2c-bfab23927dea/file", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/image/v2/imagedata/testing/requests_test.go b/openstack/image/v2/imagedata/testing/requests_test.go index 3596dded66..ad4dba86f1 100644 --- a/openstack/image/v2/imagedata/testing/requests_test.go +++ b/openstack/image/v2/imagedata/testing/requests_test.go @@ -12,14 +12,14 @@ import ( ) func TestUpload(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandlePutImageDataSuccessfully(t) + HandlePutImageDataSuccessfully(t, fakeServer) err := imagedata.Upload( context.TODO(), - client.ServiceClient(), + client.ServiceClient(fakeServer), "da3b75d9-3f4a-40e7-8a2c-bfab23927dea", readSeekerOfBytes([]byte{5, 3, 7, 24})).ExtractErr() @@ -27,14 +27,14 @@ func TestUpload(t *testing.T) { } func TestStage(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleStageImageDataSuccessfully(t) + HandleStageImageDataSuccessfully(t, fakeServer) err := imagedata.Stage( context.TODO(), - client.ServiceClient(), + client.ServiceClient(fakeServer), "da3b75d9-3f4a-40e7-8a2c-bfab23927dea", readSeekerOfBytes([]byte{5, 3, 7, 24})).ExtractErr() @@ -88,12 +88,12 @@ func (rs *RS) Seek(offset int64, whence int) (int64, error) { } func TestDownload(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleGetImageDataSuccessfully(t) + HandleGetImageDataSuccessfully(t, fakeServer) - rdr, err := imagedata.Download(context.TODO(), client.ServiceClient(), "da3b75d9-3f4a-40e7-8a2c-bfab23927dea").Extract() + rdr, err := imagedata.Download(context.TODO(), client.ServiceClient(fakeServer), "da3b75d9-3f4a-40e7-8a2c-bfab23927dea").Extract() th.AssertNoErr(t, err) defer rdr.Close() diff --git a/openstack/image/v2/imageimport/testing/requests_test.go b/openstack/image/v2/imageimport/testing/requests_test.go index 7db88a1d5d..05bcc9cafd 100644 --- a/openstack/image/v2/imageimport/testing/requests_test.go +++ b/openstack/image/v2/imageimport/testing/requests_test.go @@ -12,10 +12,10 @@ import ( ) func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/info/import", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/info/import", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -30,7 +30,7 @@ func TestGet(t *testing.T) { string(imageimport.WebDownloadMethod), } - s, err := imageimport.Get(context.TODO(), client.ServiceClient()).Extract() + s, err := imageimport.Get(context.TODO(), client.ServiceClient(fakeServer)).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, s.ImportMethods.Description, "Import methods available.") @@ -39,10 +39,10 @@ func TestGet(t *testing.T) { } func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/images/da3b75d9-3f4a-40e7-8a2c-bfab23927dea/import", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/images/da3b75d9-3f4a-40e7-8a2c-bfab23927dea/import", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, ImportCreateRequest) @@ -56,6 +56,6 @@ func TestCreate(t *testing.T) { Name: imageimport.WebDownloadMethod, URI: "http://download.cirros-cloud.net/0.4.0/cirros-0.4.0-x86_64-disk.img", } - err := imageimport.Create(context.TODO(), client.ServiceClient(), "da3b75d9-3f4a-40e7-8a2c-bfab23927dea", opts).ExtractErr() + err := imageimport.Create(context.TODO(), client.ServiceClient(fakeServer), "da3b75d9-3f4a-40e7-8a2c-bfab23927dea", opts).ExtractErr() th.AssertNoErr(t, err) } diff --git a/openstack/image/v2/images/testing/fixtures_test.go b/openstack/image/v2/images/testing/fixtures_test.go index d36d6b15d6..0ec25214d1 100644 --- a/openstack/image/v2/images/testing/fixtures_test.go +++ b/openstack/image/v2/images/testing/fixtures_test.go @@ -17,7 +17,7 @@ type imageEntry struct { } // HandleImageListSuccessfully test setup -func HandleImageListSuccessfully(t *testing.T) { +func HandleImageListSuccessfully(t *testing.T, fakeServer th.FakeServer) { images := make([]imageEntry, 3) @@ -99,7 +99,7 @@ func HandleImageListSuccessfully(t *testing.T) { "hw_scsi_model": "virtio-scsi" }`} - th.Mux.HandleFunc("/images", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/images", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -160,8 +160,8 @@ func HandleImageListSuccessfully(t *testing.T) { } // HandleImageCreationSuccessfully test setup -func HandleImageCreationSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/images", func(w http.ResponseWriter, r *http.Request) { +func HandleImageCreationSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/images", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, `{ @@ -206,8 +206,8 @@ func HandleImageCreationSuccessfully(t *testing.T) { // HandleImageCreationSuccessfullyNulls test setup // JSON null values could be also returned according to behaviour https://bugs.launchpad.net/glance/+bug/1481512 -func HandleImageCreationSuccessfullyNulls(t *testing.T) { - th.Mux.HandleFunc("/images", func(w http.ResponseWriter, r *http.Request) { +func HandleImageCreationSuccessfullyNulls(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/images", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, `{ @@ -251,8 +251,8 @@ func HandleImageCreationSuccessfullyNulls(t *testing.T) { } // HandleImageGetSuccessfully test setup -func HandleImageGetSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/images/1bea47ed-f6a9-463b-b423-14b9cca9ad27", func(w http.ResponseWriter, r *http.Request) { +func HandleImageGetSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/images/1bea47ed-f6a9-463b-b423-14b9cca9ad27", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -287,8 +287,8 @@ func HandleImageGetSuccessfully(t *testing.T) { } // HandleImageDeleteSuccessfully test setup -func HandleImageDeleteSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/images/1bea47ed-f6a9-463b-b423-14b9cca9ad27", func(w http.ResponseWriter, r *http.Request) { +func HandleImageDeleteSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/images/1bea47ed-f6a9-463b-b423-14b9cca9ad27", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -297,8 +297,8 @@ func HandleImageDeleteSuccessfully(t *testing.T) { } // HandleImageUpdateSuccessfully setup -func HandleImageUpdateSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/images/da3b75d9-3f4a-40e7-8a2c-bfab23927dea", func(w http.ResponseWriter, r *http.Request) { +func HandleImageUpdateSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/images/da3b75d9-3f4a-40e7-8a2c-bfab23927dea", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PATCH") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -380,8 +380,8 @@ func HandleImageUpdateSuccessfully(t *testing.T) { } // HandleImageListByTagsSuccessfully tests a list operation with tags. -func HandleImageListByTagsSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/images", func(w http.ResponseWriter, r *http.Request) { +func HandleImageListByTagsSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/images", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -422,8 +422,8 @@ func HandleImageListByTagsSuccessfully(t *testing.T) { } // HandleImageUpdatePropertiesSuccessfully setup -func HandleImageUpdatePropertiesSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/images/da3b75d9-3f4a-40e7-8a2c-bfab23927dea", func(w http.ResponseWriter, r *http.Request) { +func HandleImageUpdatePropertiesSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/images/da3b75d9-3f4a-40e7-8a2c-bfab23927dea", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PATCH") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/image/v2/images/testing/requests_test.go b/openstack/image/v2/images/testing/requests_test.go index d3e363b79d..90c9833be1 100644 --- a/openstack/image/v2/images/testing/requests_test.go +++ b/openstack/image/v2/images/testing/requests_test.go @@ -12,14 +12,14 @@ import ( ) func TestListImage(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleImageListSuccessfully(t) + HandleImageListSuccessfully(t, fakeServer) t.Logf("Id\tName\tOwner\tChecksum\tSizeBytes") - pager := images.List(client.ServiceClient(), images.ListOpts{Limit: 1}) + pager := images.List(client.ServiceClient(fakeServer), images.ListOpts{Limit: 1}) t.Logf("Pager state %v", pager) count, pages := 0, 0 err := pager.EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { @@ -45,12 +45,12 @@ func TestListImage(t *testing.T) { } func TestAllPagesImage(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleImageListSuccessfully(t) + HandleImageListSuccessfully(t, fakeServer) - pages, err := images.List(client.ServiceClient(), nil).AllPages(context.TODO()) + pages, err := images.List(client.ServiceClient(fakeServer), nil).AllPages(context.TODO()) th.AssertNoErr(t, err) images, err := images.ExtractImages(pages) th.AssertNoErr(t, err) @@ -58,15 +58,15 @@ func TestAllPagesImage(t *testing.T) { } func TestCreateImage(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleImageCreationSuccessfully(t) + HandleImageCreationSuccessfully(t, fakeServer) id := "e7db3b45-8db7-47ad-8109-3fb55c2c24fd" name := "Ubuntu 12.10" - actualImage, err := images.Create(context.TODO(), client.ServiceClient(), images.CreateOpts{ + actualImage, err := images.Create(context.TODO(), client.ServiceClient(fakeServer), images.CreateOpts{ ID: id, Name: name, Properties: map[string]string{ @@ -119,15 +119,15 @@ func TestCreateImage(t *testing.T) { } func TestCreateImageNulls(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleImageCreationSuccessfullyNulls(t) + HandleImageCreationSuccessfullyNulls(t, fakeServer) id := "e7db3b45-8db7-47ad-8109-3fb55c2c24fd" name := "Ubuntu 12.10" - actualImage, err := images.Create(context.TODO(), client.ServiceClient(), images.CreateOpts{ + actualImage, err := images.Create(context.TODO(), client.ServiceClient(fakeServer), images.CreateOpts{ ID: id, Name: name, Tags: []string{"ubuntu", "quantal"}, @@ -188,12 +188,12 @@ func TestCreateImageNulls(t *testing.T) { } func TestGetImage(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleImageGetSuccessfully(t) + HandleImageGetSuccessfully(t, fakeServer) - actualImage, err := images.Get(context.TODO(), client.ServiceClient(), "1bea47ed-f6a9-463b-b423-14b9cca9ad27").Extract() + actualImage, err := images.Get(context.TODO(), client.ServiceClient(fakeServer), "1bea47ed-f6a9-463b-b423-14b9cca9ad27").Extract() th.AssertNoErr(t, err) @@ -246,22 +246,22 @@ func TestGetImage(t *testing.T) { } func TestDeleteImage(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleImageDeleteSuccessfully(t) + HandleImageDeleteSuccessfully(t, fakeServer) - result := images.Delete(context.TODO(), client.ServiceClient(), "1bea47ed-f6a9-463b-b423-14b9cca9ad27") + result := images.Delete(context.TODO(), client.ServiceClient(fakeServer), "1bea47ed-f6a9-463b-b423-14b9cca9ad27") th.AssertNoErr(t, result.Err) } func TestUpdateImage(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleImageUpdateSuccessfully(t) + HandleImageUpdateSuccessfully(t, fakeServer) - actualImage, err := images.Update(context.TODO(), client.ServiceClient(), "da3b75d9-3f4a-40e7-8a2c-bfab23927dea", images.UpdateOpts{ + actualImage, err := images.Update(context.TODO(), client.ServiceClient(fakeServer), "da3b75d9-3f4a-40e7-8a2c-bfab23927dea", images.UpdateOpts{ images.ReplaceImageName{NewName: "Fedora 17"}, images.ReplaceImageTags{NewTags: []string{"fedora", "beefy"}}, images.ReplaceImageMinDisk{NewMinDisk: 21}, @@ -342,10 +342,10 @@ func TestImageDateQuery(t *testing.T) { } func TestImageListByTags(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleImageListByTagsSuccessfully(t) + HandleImageListByTagsSuccessfully(t, fakeServer) listOpts := images.ListOpts{ Tags: []string{"foo", "bar"}, @@ -356,7 +356,7 @@ func TestImageListByTags(t *testing.T) { th.AssertNoErr(t, err) th.AssertEquals(t, expectedQueryString, actualQueryString) - pages, err := images.List(client.ServiceClient(), listOpts).AllPages(context.TODO()) + pages, err := images.List(client.ServiceClient(fakeServer), listOpts).AllPages(context.TODO()) th.AssertNoErr(t, err) allImages, err := images.ExtractImages(pages) th.AssertNoErr(t, err) @@ -410,12 +410,12 @@ func TestImageListByTags(t *testing.T) { } func TestUpdateImageProperties(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleImageUpdatePropertiesSuccessfully(t) + HandleImageUpdatePropertiesSuccessfully(t, fakeServer) - actualImage, err := images.Update(context.TODO(), client.ServiceClient(), "da3b75d9-3f4a-40e7-8a2c-bfab23927dea", images.UpdateOpts{ + actualImage, err := images.Update(context.TODO(), client.ServiceClient(fakeServer), "da3b75d9-3f4a-40e7-8a2c-bfab23927dea", images.UpdateOpts{ images.UpdateImageProperty{ Op: images.AddOp, Name: "hw_disk_bus", diff --git a/openstack/image/v2/members/testing/fixtures_test.go b/openstack/image/v2/members/testing/fixtures_test.go index cc2e60b9a7..8c2f9261a5 100644 --- a/openstack/image/v2/members/testing/fixtures_test.go +++ b/openstack/image/v2/members/testing/fixtures_test.go @@ -10,8 +10,8 @@ import ( ) // HandleCreateImageMemberSuccessfully setup -func HandleCreateImageMemberSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/images/da3b75d9-3f4a-40e7-8a2c-bfab23927dea/members", func(w http.ResponseWriter, r *http.Request) { +func HandleCreateImageMemberSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/images/da3b75d9-3f4a-40e7-8a2c-bfab23927dea/members", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -31,8 +31,8 @@ func HandleCreateImageMemberSuccessfully(t *testing.T) { } // HandleImageMemberList happy path setup -func HandleImageMemberList(t *testing.T) { - th.Mux.HandleFunc("/images/da3b75d9-3f4a-40e7-8a2c-bfab23927dea/members", func(w http.ResponseWriter, r *http.Request) { +func HandleImageMemberList(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/images/da3b75d9-3f4a-40e7-8a2c-bfab23927dea/members", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -62,8 +62,8 @@ func HandleImageMemberList(t *testing.T) { } // HandleImageMemberEmptyList happy path setup -func HandleImageMemberEmptyList(t *testing.T) { - th.Mux.HandleFunc("/images/da3b75d9-3f4a-40e7-8a2c-bfab23927dea/members", func(w http.ResponseWriter, r *http.Request) { +func HandleImageMemberEmptyList(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/images/da3b75d9-3f4a-40e7-8a2c-bfab23927dea/members", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -76,8 +76,8 @@ func HandleImageMemberEmptyList(t *testing.T) { } // HandleImageMemberDetails setup -func HandleImageMemberDetails(t *testing.T) { - th.Mux.HandleFunc("/images/da3b75d9-3f4a-40e7-8a2c-bfab23927dea/members/8989447062e04a818baf9e073fd04fa7", func(w http.ResponseWriter, r *http.Request) { +func HandleImageMemberDetails(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/images/da3b75d9-3f4a-40e7-8a2c-bfab23927dea/members/8989447062e04a818baf9e073fd04fa7", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -94,9 +94,9 @@ func HandleImageMemberDetails(t *testing.T) { } // HandleImageMemberDeleteSuccessfully setup -func HandleImageMemberDeleteSuccessfully(t *testing.T) *CallsCounter { +func HandleImageMemberDeleteSuccessfully(t *testing.T, fakeServer th.FakeServer) *CallsCounter { var counter CallsCounter - th.Mux.HandleFunc("/images/da3b75d9-3f4a-40e7-8a2c-bfab23927dea/members/8989447062e04a818baf9e073fd04fa7", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/images/da3b75d9-3f4a-40e7-8a2c-bfab23927dea/members/8989447062e04a818baf9e073fd04fa7", func(w http.ResponseWriter, r *http.Request) { counter.Counter = counter.Counter + 1 th.TestMethod(t, r, "DELETE") @@ -108,9 +108,9 @@ func HandleImageMemberDeleteSuccessfully(t *testing.T) *CallsCounter { } // HandleImageMemberUpdate setup -func HandleImageMemberUpdate(t *testing.T) *CallsCounter { +func HandleImageMemberUpdate(t *testing.T, fakeServer th.FakeServer) *CallsCounter { var counter CallsCounter - th.Mux.HandleFunc("/images/da3b75d9-3f4a-40e7-8a2c-bfab23927dea/members/8989447062e04a818baf9e073fd04fa7", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/images/da3b75d9-3f4a-40e7-8a2c-bfab23927dea/members/8989447062e04a818baf9e073fd04fa7", func(w http.ResponseWriter, r *http.Request) { counter.Counter = counter.Counter + 1 th.TestMethod(t, r, "PUT") diff --git a/openstack/image/v2/members/testing/requests_test.go b/openstack/image/v2/members/testing/requests_test.go index 0d5e84d3ab..66798c4323 100644 --- a/openstack/image/v2/members/testing/requests_test.go +++ b/openstack/image/v2/members/testing/requests_test.go @@ -15,11 +15,11 @@ const createdAtString = "2013-09-20T19:22:19Z" const updatedAtString = "2013-09-20T19:25:31Z" func TestCreateMemberSuccessfully(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleCreateImageMemberSuccessfully(t) - im, err := members.Create(context.TODO(), client.ServiceClient(), "da3b75d9-3f4a-40e7-8a2c-bfab23927dea", + HandleCreateImageMemberSuccessfully(t, fakeServer) + im, err := members.Create(context.TODO(), client.ServiceClient(fakeServer), "da3b75d9-3f4a-40e7-8a2c-bfab23927dea", "8989447062e04a818baf9e073fd04fa7").Extract() th.AssertNoErr(t, err) @@ -41,12 +41,12 @@ func TestCreateMemberSuccessfully(t *testing.T) { } func TestMemberListSuccessfully(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleImageMemberList(t) + HandleImageMemberList(t, fakeServer) - pager := members.List(client.ServiceClient(), "da3b75d9-3f4a-40e7-8a2c-bfab23927dea") + pager := members.List(client.ServiceClient(fakeServer), "da3b75d9-3f4a-40e7-8a2c-bfab23927dea") t.Logf("Pager state %v", pager) count, pages := 0, 0 err := pager.EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { @@ -71,12 +71,12 @@ func TestMemberListSuccessfully(t *testing.T) { } func TestMemberListEmpty(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleImageMemberEmptyList(t) + HandleImageMemberEmptyList(t, fakeServer) - pager := members.List(client.ServiceClient(), "da3b75d9-3f4a-40e7-8a2c-bfab23927dea") + pager := members.List(client.ServiceClient(fakeServer), "da3b75d9-3f4a-40e7-8a2c-bfab23927dea") t.Logf("Pager state %v", pager) count, pages := 0, 0 err := pager.EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { @@ -101,11 +101,11 @@ func TestMemberListEmpty(t *testing.T) { } func TestShowMemberDetails(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleImageMemberDetails(t) - md, err := members.Get(context.TODO(), client.ServiceClient(), + HandleImageMemberDetails(t, fakeServer) + md, err := members.Get(context.TODO(), client.ServiceClient(fakeServer), "da3b75d9-3f4a-40e7-8a2c-bfab23927dea", "8989447062e04a818baf9e073fd04fa7").Extract() @@ -131,23 +131,23 @@ func TestShowMemberDetails(t *testing.T) { } func TestDeleteMember(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - counter := HandleImageMemberDeleteSuccessfully(t) + counter := HandleImageMemberDeleteSuccessfully(t, fakeServer) - result := members.Delete(context.TODO(), client.ServiceClient(), "da3b75d9-3f4a-40e7-8a2c-bfab23927dea", + result := members.Delete(context.TODO(), client.ServiceClient(fakeServer), "da3b75d9-3f4a-40e7-8a2c-bfab23927dea", "8989447062e04a818baf9e073fd04fa7") th.AssertEquals(t, 1, counter.Counter) th.AssertNoErr(t, result.Err) } func TestMemberUpdateSuccessfully(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - counter := HandleImageMemberUpdate(t) - im, err := members.Update(context.TODO(), client.ServiceClient(), "da3b75d9-3f4a-40e7-8a2c-bfab23927dea", + counter := HandleImageMemberUpdate(t, fakeServer) + im, err := members.Update(context.TODO(), client.ServiceClient(fakeServer), "da3b75d9-3f4a-40e7-8a2c-bfab23927dea", "8989447062e04a818baf9e073fd04fa7", members.UpdateOpts{ Status: "accepted", diff --git a/openstack/image/v2/tasks/testing/requests_test.go b/openstack/image/v2/tasks/testing/requests_test.go index 5ddd556794..1949d07c3a 100644 --- a/openstack/image/v2/tasks/testing/requests_test.go +++ b/openstack/image/v2/tasks/testing/requests_test.go @@ -14,10 +14,10 @@ import ( ) func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/tasks", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/tasks", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -29,7 +29,7 @@ func TestList(t *testing.T) { count := 0 - err := tasks.List(client.ServiceClient(), tasks.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := tasks.List(client.ServiceClient(fakeServer), tasks.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := tasks.ExtractTasks(page) if err != nil { @@ -54,10 +54,10 @@ func TestList(t *testing.T) { } func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/tasks/1252f636-1246-4319-bfba-c47cde0efbe0", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/tasks/1252f636-1246-4319-bfba-c47cde0efbe0", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -67,7 +67,7 @@ func TestGet(t *testing.T) { fmt.Fprint(w, TasksGetResult) }) - s, err := tasks.Get(context.TODO(), client.ServiceClient(), "1252f636-1246-4319-bfba-c47cde0efbe0").Extract() + s, err := tasks.Get(context.TODO(), client.ServiceClient(fakeServer), "1252f636-1246-4319-bfba-c47cde0efbe0").Extract() th.AssertNoErr(t, err) th.AssertEquals(t, s.Status, string(tasks.TaskStatusPending)) @@ -91,10 +91,10 @@ func TestGet(t *testing.T) { } func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/tasks", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/tasks", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, TaskCreateRequest) @@ -116,7 +116,7 @@ func TestCreate(t *testing.T) { "import_from": "https://cloud-images.ubuntu.com/bionic/current/bionic-server-cloudimg-amd64.img", }, } - s, err := tasks.Create(context.TODO(), client.ServiceClient(), opts).Extract() + s, err := tasks.Create(context.TODO(), client.ServiceClient(fakeServer), opts).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, s.Status, string(tasks.TaskStatusPending)) diff --git a/openstack/keymanager/v1/acls/testing/fixtures_test.go b/openstack/keymanager/v1/acls/testing/fixtures_test.go index 89b6ea7d4d..cc2624985b 100644 --- a/openstack/keymanager/v1/acls/testing/fixtures_test.go +++ b/openstack/keymanager/v1/acls/testing/fixtures_test.go @@ -67,8 +67,8 @@ const UpdateRequest = ` // HandleGetSecretACLSuccessfully creates an HTTP handler at `/secrets/uuid/acl` // on the test handler mux that responds with an acl. -func HandleGetSecretACLSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/secrets/1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c/acl", func(w http.ResponseWriter, r *http.Request) { +func HandleGetSecretACLSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/secrets/1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c/acl", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -81,8 +81,8 @@ func HandleGetSecretACLSuccessfully(t *testing.T) { // HandleGetContainerACLSuccessfully creates an HTTP handler at `/secrets/uuid/acl` // on the test handler mux that responds with an acl. -func HandleGetContainerACLSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/containers/1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c/acl", func(w http.ResponseWriter, r *http.Request) { +func HandleGetContainerACLSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/containers/1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c/acl", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -95,8 +95,8 @@ func HandleGetContainerACLSuccessfully(t *testing.T) { // HandleSetSecretACLSuccessfully creates an HTTP handler at `/secrets` on the // test handler mux that tests secret creation. -func HandleSetSecretACLSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/secrets/1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c/acl", func(w http.ResponseWriter, r *http.Request) { +func HandleSetSecretACLSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/secrets/1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c/acl", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, SetRequest) @@ -108,8 +108,8 @@ func HandleSetSecretACLSuccessfully(t *testing.T) { // HandleSetContainerACLSuccessfully creates an HTTP handler at `/secrets` on the // test handler mux that tests secret creation. -func HandleSetContainerACLSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/containers/1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c/acl", func(w http.ResponseWriter, r *http.Request) { +func HandleSetContainerACLSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/containers/1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c/acl", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, SetRequest) @@ -121,8 +121,8 @@ func HandleSetContainerACLSuccessfully(t *testing.T) { // HandleUpdateSecretACLSuccessfully creates an HTTP handler at `/secrets` on the // test handler mux that tests secret creation. -func HandleUpdateSecretACLSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/secrets/1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c/acl", func(w http.ResponseWriter, r *http.Request) { +func HandleUpdateSecretACLSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/secrets/1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c/acl", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PATCH") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, UpdateRequest) @@ -134,8 +134,8 @@ func HandleUpdateSecretACLSuccessfully(t *testing.T) { // HandleUpdateContainerACLSuccessfully creates an HTTP handler at `/secrets` on the // test handler mux that tests secret creation. -func HandleUpdateContainerACLSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/containers/1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c/acl", func(w http.ResponseWriter, r *http.Request) { +func HandleUpdateContainerACLSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/containers/1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c/acl", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PATCH") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, UpdateRequest) @@ -147,8 +147,8 @@ func HandleUpdateContainerACLSuccessfully(t *testing.T) { // HandleDeleteSecretACLSuccessfully creates an HTTP handler at `/secrets` on the // test handler mux that tests secret deletion. -func HandleDeleteSecretACLSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/secrets/1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c/acl", func(w http.ResponseWriter, r *http.Request) { +func HandleDeleteSecretACLSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/secrets/1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c/acl", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -158,8 +158,8 @@ func HandleDeleteSecretACLSuccessfully(t *testing.T) { // HandleDeleteContainerACLSuccessfully creates an HTTP handler at `/secrets` on the // test handler mux that tests secret deletion. -func HandleDeleteContainerACLSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/containers/1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c/acl", func(w http.ResponseWriter, r *http.Request) { +func HandleDeleteContainerACLSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/containers/1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c/acl", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/keymanager/v1/acls/testing/requests_test.go b/openstack/keymanager/v1/acls/testing/requests_test.go index 3367381520..6b8237fb06 100644 --- a/openstack/keymanager/v1/acls/testing/requests_test.go +++ b/openstack/keymanager/v1/acls/testing/requests_test.go @@ -10,29 +10,29 @@ import ( ) func TestGetSecretACL(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetSecretACLSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetSecretACLSuccessfully(t, fakeServer) - actual, err := acls.GetSecretACL(context.TODO(), client.ServiceClient(), "1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c").Extract() + actual, err := acls.GetSecretACL(context.TODO(), client.ServiceClient(fakeServer), "1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c").Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, ExpectedACL, *actual) } func TestGetContainerACL(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetContainerACLSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetContainerACLSuccessfully(t, fakeServer) - actual, err := acls.GetContainerACL(context.TODO(), client.ServiceClient(), "1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c").Extract() + actual, err := acls.GetContainerACL(context.TODO(), client.ServiceClient(fakeServer), "1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c").Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, ExpectedACL, *actual) } func TestSetSecretACL(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleSetSecretACLSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleSetSecretACLSuccessfully(t, fakeServer) users := []string{"GG27dVwR9gBMnsOaRoJ1DFJmZfdVjIdW"} iFalse := false @@ -44,15 +44,15 @@ func TestSetSecretACL(t *testing.T) { }, } - actual, err := acls.SetSecretACL(context.TODO(), client.ServiceClient(), "1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c", setOpts).Extract() + actual, err := acls.SetSecretACL(context.TODO(), client.ServiceClient(fakeServer), "1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c", setOpts).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, ExpectedSecretACLRef, *actual) } func TestSetContainerACL(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleSetContainerACLSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleSetContainerACLSuccessfully(t, fakeServer) users := []string{"GG27dVwR9gBMnsOaRoJ1DFJmZfdVjIdW"} iFalse := false @@ -64,33 +64,33 @@ func TestSetContainerACL(t *testing.T) { }, } - actual, err := acls.SetContainerACL(context.TODO(), client.ServiceClient(), "1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c", setOpts).Extract() + actual, err := acls.SetContainerACL(context.TODO(), client.ServiceClient(fakeServer), "1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c", setOpts).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, ExpectedContainerACLRef, *actual) } func TestDeleteSecretACL(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDeleteSecretACLSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDeleteSecretACLSuccessfully(t, fakeServer) - res := acls.DeleteSecretACL(context.TODO(), client.ServiceClient(), "1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c") + res := acls.DeleteSecretACL(context.TODO(), client.ServiceClient(fakeServer), "1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c") th.AssertNoErr(t, res.Err) } func TestDeleteContainerACL(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDeleteContainerACLSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDeleteContainerACLSuccessfully(t, fakeServer) - res := acls.DeleteContainerACL(context.TODO(), client.ServiceClient(), "1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c") + res := acls.DeleteContainerACL(context.TODO(), client.ServiceClient(fakeServer), "1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c") th.AssertNoErr(t, res.Err) } func TestUpdateSecretACL(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleUpdateSecretACLSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleUpdateSecretACLSuccessfully(t, fakeServer) newUsers := []string{} updateOpts := acls.SetOpts{ @@ -100,15 +100,15 @@ func TestUpdateSecretACL(t *testing.T) { }, } - actual, err := acls.UpdateSecretACL(context.TODO(), client.ServiceClient(), "1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c", updateOpts).Extract() + actual, err := acls.UpdateSecretACL(context.TODO(), client.ServiceClient(fakeServer), "1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c", updateOpts).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, ExpectedSecretACLRef, *actual) } func TestUpdateContainerACL(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleUpdateContainerACLSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleUpdateContainerACLSuccessfully(t, fakeServer) newUsers := []string{} updateOpts := acls.SetOpts{ @@ -118,7 +118,7 @@ func TestUpdateContainerACL(t *testing.T) { }, } - actual, err := acls.UpdateContainerACL(context.TODO(), client.ServiceClient(), "1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c", updateOpts).Extract() + actual, err := acls.UpdateContainerACL(context.TODO(), client.ServiceClient(fakeServer), "1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c", updateOpts).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, ExpectedContainerACLRef, *actual) } diff --git a/openstack/keymanager/v1/containers/testing/fixtures_test.go b/openstack/keymanager/v1/containers/testing/fixtures_test.go index d290a5a9a6..a253e0bfda 100644 --- a/openstack/keymanager/v1/containers/testing/fixtures_test.go +++ b/openstack/keymanager/v1/containers/testing/fixtures_test.go @@ -227,8 +227,8 @@ const DeleteConsumerRequest = ` // HandleListContainersSuccessfully creates an HTTP handler at `/containers` on the // test handler mux that responds with a list of two containers. -func HandleListContainersSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/containers", func(w http.ResponseWriter, r *http.Request) { +func HandleListContainersSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/containers", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -241,8 +241,8 @@ func HandleListContainersSuccessfully(t *testing.T) { // HandleGetContainerSuccessfully creates an HTTP handler at `/containers` on the // test handler mux that responds with a single resource. -func HandleGetContainerSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/containers/dfdb88f3-4ddb-4525-9da6-066453caa9b0", func(w http.ResponseWriter, r *http.Request) { +func HandleGetContainerSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/containers/dfdb88f3-4ddb-4525-9da6-066453caa9b0", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -255,8 +255,8 @@ func HandleGetContainerSuccessfully(t *testing.T) { // HandleCreateContainerSuccessfully creates an HTTP handler at `/containers` on the // test handler mux that tests resource creation. -func HandleCreateContainerSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/containers", func(w http.ResponseWriter, r *http.Request) { +func HandleCreateContainerSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/containers", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, CreateRequest) @@ -268,8 +268,8 @@ func HandleCreateContainerSuccessfully(t *testing.T) { // HandleDeleteContainerSuccessfully creates an HTTP handler at `/containers` on the // test handler mux that tests resource deletion. -func HandleDeleteContainerSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/containers/dfdb88f3-4ddb-4525-9da6-066453caa9b0", func(w http.ResponseWriter, r *http.Request) { +func HandleDeleteContainerSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/containers/dfdb88f3-4ddb-4525-9da6-066453caa9b0", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -280,8 +280,8 @@ func HandleDeleteContainerSuccessfully(t *testing.T) { // HandleListConsumersSuccessfully creates an HTTP handler at // `/containers/uuid/consumers` on the test handler mux that responds with // a list of consumers. -func HandleListConsumersSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/containers/dfdb88f3-4ddb-4525-9da6-066453caa9b0/consumers", func(w http.ResponseWriter, r *http.Request) { +func HandleListConsumersSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/containers/dfdb88f3-4ddb-4525-9da6-066453caa9b0/consumers", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -295,8 +295,8 @@ func HandleListConsumersSuccessfully(t *testing.T) { // HandleCreateConsumerSuccessfully creates an HTTP handler at // `/containers/uuid/consumers` on the test handler mux that tests resource // creation. -func HandleCreateConsumerSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/containers/dfdb88f3-4ddb-4525-9da6-066453caa9b0/consumers", func(w http.ResponseWriter, r *http.Request) { +func HandleCreateConsumerSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/containers/dfdb88f3-4ddb-4525-9da6-066453caa9b0/consumers", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, CreateConsumerRequest) @@ -309,8 +309,8 @@ func HandleCreateConsumerSuccessfully(t *testing.T) { // HandleDeleteConsumerSuccessfully creates an HTTP handler at // `/containers/uuid/consumers` on the test handler mux that tests resource // deletion. -func HandleDeleteConsumerSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/containers/dfdb88f3-4ddb-4525-9da6-066453caa9b0/consumers", func(w http.ResponseWriter, r *http.Request) { +func HandleDeleteConsumerSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/containers/dfdb88f3-4ddb-4525-9da6-066453caa9b0/consumers", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, CreateConsumerRequest) diff --git a/openstack/keymanager/v1/containers/testing/requests_test.go b/openstack/keymanager/v1/containers/testing/requests_test.go index 44ed27b217..83fd23502c 100644 --- a/openstack/keymanager/v1/containers/testing/requests_test.go +++ b/openstack/keymanager/v1/containers/testing/requests_test.go @@ -11,12 +11,12 @@ import ( ) func TestListContainers(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListContainersSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListContainersSuccessfully(t, fakeServer) count := 0 - err := containers.List(client.ServiceClient(), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := containers.List(client.ServiceClient(fakeServer), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := containers.ExtractContainers(page) @@ -31,11 +31,11 @@ func TestListContainers(t *testing.T) { } func TestListContainersAllPages(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListContainersSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListContainersSuccessfully(t, fakeServer) - allPages, err := containers.List(client.ServiceClient(), nil).AllPages(context.TODO()) + allPages, err := containers.List(client.ServiceClient(fakeServer), nil).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := containers.ExtractContainers(allPages) th.AssertNoErr(t, err) @@ -43,19 +43,19 @@ func TestListContainersAllPages(t *testing.T) { } func TestGetContainer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetContainerSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetContainerSuccessfully(t, fakeServer) - actual, err := containers.Get(context.TODO(), client.ServiceClient(), "dfdb88f3-4ddb-4525-9da6-066453caa9b0").Extract() + actual, err := containers.Get(context.TODO(), client.ServiceClient(fakeServer), "dfdb88f3-4ddb-4525-9da6-066453caa9b0").Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, FirstContainer, *actual) } func TestCreateContainer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateContainerSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCreateContainerSuccessfully(t, fakeServer) createOpts := containers.CreateOpts{ Type: containers.GenericContainer, @@ -68,27 +68,27 @@ func TestCreateContainer(t *testing.T) { }, } - actual, err := containers.Create(context.TODO(), client.ServiceClient(), createOpts).Extract() + actual, err := containers.Create(context.TODO(), client.ServiceClient(fakeServer), createOpts).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, FirstContainer, *actual) } func TestDeleteContainer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDeleteContainerSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDeleteContainerSuccessfully(t, fakeServer) - res := containers.Delete(context.TODO(), client.ServiceClient(), "dfdb88f3-4ddb-4525-9da6-066453caa9b0") + res := containers.Delete(context.TODO(), client.ServiceClient(fakeServer), "dfdb88f3-4ddb-4525-9da6-066453caa9b0") th.AssertNoErr(t, res.Err) } func TestListConsumers(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListConsumersSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListConsumersSuccessfully(t, fakeServer) count := 0 - err := containers.ListConsumers(client.ServiceClient(), "dfdb88f3-4ddb-4525-9da6-066453caa9b0", nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := containers.ListConsumers(client.ServiceClient(fakeServer), "dfdb88f3-4ddb-4525-9da6-066453caa9b0", nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := containers.ExtractConsumers(page) @@ -103,11 +103,11 @@ func TestListConsumers(t *testing.T) { } func TestListConsumersAllPages(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListConsumersSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListConsumersSuccessfully(t, fakeServer) - allPages, err := containers.ListConsumers(client.ServiceClient(), "dfdb88f3-4ddb-4525-9da6-066453caa9b0", nil).AllPages(context.TODO()) + allPages, err := containers.ListConsumers(client.ServiceClient(fakeServer), "dfdb88f3-4ddb-4525-9da6-066453caa9b0", nil).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := containers.ExtractConsumers(allPages) th.AssertNoErr(t, err) @@ -115,31 +115,31 @@ func TestListConsumersAllPages(t *testing.T) { } func TestCreateConsumer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateConsumerSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCreateConsumerSuccessfully(t, fakeServer) createOpts := containers.CreateConsumerOpts{ Name: "CONSUMER-LZILN1zq", URL: "http://example.com", } - actual, err := containers.CreateConsumer(context.TODO(), client.ServiceClient(), "dfdb88f3-4ddb-4525-9da6-066453caa9b0", createOpts).Extract() + actual, err := containers.CreateConsumer(context.TODO(), client.ServiceClient(fakeServer), "dfdb88f3-4ddb-4525-9da6-066453caa9b0", createOpts).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, ExpectedCreatedConsumer, *actual) } func TestDeleteConsumer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDeleteConsumerSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDeleteConsumerSuccessfully(t, fakeServer) deleteOpts := containers.DeleteConsumerOpts{ Name: "CONSUMER-LZILN1zq", URL: "http://example.com", } - actual, err := containers.DeleteConsumer(context.TODO(), client.ServiceClient(), "dfdb88f3-4ddb-4525-9da6-066453caa9b0", deleteOpts).Extract() + actual, err := containers.DeleteConsumer(context.TODO(), client.ServiceClient(fakeServer), "dfdb88f3-4ddb-4525-9da6-066453caa9b0", deleteOpts).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, FirstContainer, *actual) } diff --git a/openstack/keymanager/v1/orders/testing/fixtures_test.go b/openstack/keymanager/v1/orders/testing/fixtures_test.go index 7eb14e0edf..40d55c21f4 100644 --- a/openstack/keymanager/v1/orders/testing/fixtures_test.go +++ b/openstack/keymanager/v1/orders/testing/fixtures_test.go @@ -135,8 +135,8 @@ var ExpectedOrdersSlice = []orders.Order{FirstOrder, SecondOrder} // HandleListOrdersSuccessfully creates an HTTP handler at `/orders` on the // test handler mux that responds with a list of two orders. -func HandleListOrdersSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/orders", func(w http.ResponseWriter, r *http.Request) { +func HandleListOrdersSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/orders", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -149,8 +149,8 @@ func HandleListOrdersSuccessfully(t *testing.T) { // HandleGetOrderSuccessfully creates an HTTP handler at `/orders` on the // test handler mux that responds with a single resource. -func HandleGetOrderSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/orders/46f73695-82bb-447a-bf96-6635f0fb0ce7", func(w http.ResponseWriter, r *http.Request) { +func HandleGetOrderSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/orders/46f73695-82bb-447a-bf96-6635f0fb0ce7", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -163,8 +163,8 @@ func HandleGetOrderSuccessfully(t *testing.T) { // HandleCreateOrderSuccessfully creates an HTTP handler at `/orders` on the // test handler mux that tests resource creation. -func HandleCreateOrderSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/orders", func(w http.ResponseWriter, r *http.Request) { +func HandleCreateOrderSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/orders", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, CreateRequest) @@ -176,8 +176,8 @@ func HandleCreateOrderSuccessfully(t *testing.T) { // HandleDeleteOrderSuccessfully creates an HTTP handler at `/orders` on the // test handler mux that tests resource deletion. -func HandleDeleteOrderSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/orders/46f73695-82bb-447a-bf96-6635f0fb0ce7", func(w http.ResponseWriter, r *http.Request) { +func HandleDeleteOrderSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/orders/46f73695-82bb-447a-bf96-6635f0fb0ce7", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/keymanager/v1/orders/testing/requests_test.go b/openstack/keymanager/v1/orders/testing/requests_test.go index df2b10d9c1..f3545313df 100644 --- a/openstack/keymanager/v1/orders/testing/requests_test.go +++ b/openstack/keymanager/v1/orders/testing/requests_test.go @@ -11,12 +11,12 @@ import ( ) func TestListOrders(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListOrdersSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListOrdersSuccessfully(t, fakeServer) count := 0 - err := orders.List(client.ServiceClient(), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := orders.List(client.ServiceClient(fakeServer), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := orders.ExtractOrders(page) @@ -31,11 +31,11 @@ func TestListOrders(t *testing.T) { } func TestListOrdersAllPages(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListOrdersSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListOrdersSuccessfully(t, fakeServer) - allPages, err := orders.List(client.ServiceClient(), nil).AllPages(context.TODO()) + allPages, err := orders.List(client.ServiceClient(fakeServer), nil).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := orders.ExtractOrders(allPages) th.AssertNoErr(t, err) @@ -43,19 +43,19 @@ func TestListOrdersAllPages(t *testing.T) { } func TestGetOrder(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetOrderSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetOrderSuccessfully(t, fakeServer) - actual, err := orders.Get(context.TODO(), client.ServiceClient(), "46f73695-82bb-447a-bf96-6635f0fb0ce7").Extract() + actual, err := orders.Get(context.TODO(), client.ServiceClient(fakeServer), "46f73695-82bb-447a-bf96-6635f0fb0ce7").Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, SecondOrder, *actual) } func TestCreateOrder(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateOrderSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCreateOrderSuccessfully(t, fakeServer) createOpts := orders.CreateOpts{ Type: orders.KeyOrder, @@ -67,16 +67,16 @@ func TestCreateOrder(t *testing.T) { }, } - actual, err := orders.Create(context.TODO(), client.ServiceClient(), createOpts).Extract() + actual, err := orders.Create(context.TODO(), client.ServiceClient(fakeServer), createOpts).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, SecondOrder, *actual) } func TestDeleteOrder(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDeleteOrderSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDeleteOrderSuccessfully(t, fakeServer) - res := orders.Delete(context.TODO(), client.ServiceClient(), "46f73695-82bb-447a-bf96-6635f0fb0ce7") + res := orders.Delete(context.TODO(), client.ServiceClient(fakeServer), "46f73695-82bb-447a-bf96-6635f0fb0ce7") th.AssertNoErr(t, res.Err) } diff --git a/openstack/keymanager/v1/secrets/testing/fixtures_test.go b/openstack/keymanager/v1/secrets/testing/fixtures_test.go index ed0e9ffad0..e20732515d 100644 --- a/openstack/keymanager/v1/secrets/testing/fixtures_test.go +++ b/openstack/keymanager/v1/secrets/testing/fixtures_test.go @@ -190,8 +190,8 @@ var ExpectedMetadatum = secrets.Metadatum{ // HandleListSecretsSuccessfully creates an HTTP handler at `/secrets` on the // test handler mux that responds with a list of two secrets. -func HandleListSecretsSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/secrets", func(w http.ResponseWriter, r *http.Request) { +func HandleListSecretsSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/secrets", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -204,8 +204,8 @@ func HandleListSecretsSuccessfully(t *testing.T) { // HandleGetSecretSuccessfully creates an HTTP handler at `/secrets` on the // test handler mux that responds with a single secret. -func HandleGetSecretSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/secrets/1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c", func(w http.ResponseWriter, r *http.Request) { +func HandleGetSecretSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/secrets/1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -218,8 +218,8 @@ func HandleGetSecretSuccessfully(t *testing.T) { // HandleGetPayloadSuccessfully creates an HTTP handler at `/secrets` on the // test handler mux that responds with a single secret. -func HandleGetPayloadSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/secrets/1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c/payload", func(w http.ResponseWriter, r *http.Request) { +func HandleGetPayloadSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/secrets/1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c/payload", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -231,8 +231,8 @@ func HandleGetPayloadSuccessfully(t *testing.T) { // HandleCreateSecretSuccessfully creates an HTTP handler at `/secrets` on the // test handler mux that tests secret creation. -func HandleCreateSecretSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/secrets", func(w http.ResponseWriter, r *http.Request) { +func HandleCreateSecretSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/secrets", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, CreateRequest) @@ -244,8 +244,8 @@ func HandleCreateSecretSuccessfully(t *testing.T) { // HandleDeleteSecretSuccessfully creates an HTTP handler at `/secrets` on the // test handler mux that tests secret deletion. -func HandleDeleteSecretSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/secrets/1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c", func(w http.ResponseWriter, r *http.Request) { +func HandleDeleteSecretSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/secrets/1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -255,8 +255,8 @@ func HandleDeleteSecretSuccessfully(t *testing.T) { // HandleUpdateSecretSuccessfully creates an HTTP handler at `/secrets` on the // test handler mux that tests secret updates. -func HandleUpdateSecretSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/secrets/1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c", func(w http.ResponseWriter, r *http.Request) { +func HandleUpdateSecretSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/secrets/1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestBody(t, r, `foobar`) @@ -269,8 +269,8 @@ func HandleUpdateSecretSuccessfully(t *testing.T) { // HandleGetMetadataSuccessfully creates an HTTP handler at // `/secrets/uuid/metadata` on the test handler mux that responds with // retrieved metadata. -func HandleGetMetadataSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/secrets/1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c/metadata", func(w http.ResponseWriter, r *http.Request) { +func HandleGetMetadataSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/secrets/1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c/metadata", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -284,8 +284,8 @@ func HandleGetMetadataSuccessfully(t *testing.T) { // HandleCreateMetadataSuccessfully creates an HTTP handler at // `/secrets/uuid/metadata` on the test handler mux that responds with // a metadata reference URL. -func HandleCreateMetadataSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/secrets/1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c/metadata", func(w http.ResponseWriter, r *http.Request) { +func HandleCreateMetadataSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/secrets/1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c/metadata", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -300,8 +300,8 @@ func HandleCreateMetadataSuccessfully(t *testing.T) { // HandleGetMetadatumSuccessfully creates an HTTP handler at // `/secrets/uuid/metadata/foo` on the test handler mux that responds with a // single metadatum. -func HandleGetMetadatumSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/secrets/1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c/metadata/foo", func(w http.ResponseWriter, r *http.Request) { +func HandleGetMetadatumSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/secrets/1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c/metadata/foo", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -315,8 +315,8 @@ func HandleGetMetadatumSuccessfully(t *testing.T) { // HandleCreateMetadatumSuccessfully creates an HTTP handler at // `/secrets/uuid/metadata` on the test handler mux that responds with // a single created metadata. -func HandleCreateMetadatumSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/secrets/1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c/metadata", func(w http.ResponseWriter, r *http.Request) { +func HandleCreateMetadatumSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/secrets/1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c/metadata", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -331,8 +331,8 @@ func HandleCreateMetadatumSuccessfully(t *testing.T) { // HandleUpdateMetadatumSuccessfully creates an HTTP handler at // `/secrets/uuid/metadata/foo` on the test handler mux that responds with a // single updated metadatum. -func HandleUpdateMetadatumSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/secrets/1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c/metadata/foo", func(w http.ResponseWriter, r *http.Request) { +func HandleUpdateMetadatumSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/secrets/1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c/metadata/foo", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "Accept", "application/json") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -347,8 +347,8 @@ func HandleUpdateMetadatumSuccessfully(t *testing.T) { // HandleDeleteMetadatumSuccessfully creates an HTTP handler at // `/secrets/uuid/metadata/key` on the test handler mux that tests metadata // deletion. -func HandleDeleteMetadatumSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/secrets/1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c/metadata/foo", func(w http.ResponseWriter, r *http.Request) { +func HandleDeleteMetadatumSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/secrets/1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c/metadata/foo", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/keymanager/v1/secrets/testing/requests_test.go b/openstack/keymanager/v1/secrets/testing/requests_test.go index 0458354bc5..92475da63f 100644 --- a/openstack/keymanager/v1/secrets/testing/requests_test.go +++ b/openstack/keymanager/v1/secrets/testing/requests_test.go @@ -12,12 +12,12 @@ import ( ) func TestListSecrets(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListSecretsSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListSecretsSuccessfully(t, fakeServer) count := 0 - err := secrets.List(client.ServiceClient(), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := secrets.List(client.ServiceClient(fakeServer), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := secrets.ExtractSecrets(page) @@ -32,11 +32,11 @@ func TestListSecrets(t *testing.T) { } func TestListSecretsAllPages(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListSecretsSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListSecretsSuccessfully(t, fakeServer) - allPages, err := secrets.List(client.ServiceClient(), nil).AllPages(context.TODO()) + allPages, err := secrets.List(client.ServiceClient(fakeServer), nil).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := secrets.ExtractSecrets(allPages) th.AssertNoErr(t, err) @@ -44,19 +44,19 @@ func TestListSecretsAllPages(t *testing.T) { } func TestGetSecret(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetSecretSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetSecretSuccessfully(t, fakeServer) - actual, err := secrets.Get(context.TODO(), client.ServiceClient(), "1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c").Extract() + actual, err := secrets.Get(context.TODO(), client.ServiceClient(fakeServer), "1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c").Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, FirstSecret, *actual) } func TestCreateSecret(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateSecretSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCreateSecretSuccessfully(t, fakeServer) expiration := time.Date(2028, 6, 21, 2, 49, 48, 0, time.UTC) createOpts := secrets.CreateOpts{ @@ -70,39 +70,39 @@ func TestCreateSecret(t *testing.T) { Expiration: &expiration, } - actual, err := secrets.Create(context.TODO(), client.ServiceClient(), createOpts).Extract() + actual, err := secrets.Create(context.TODO(), client.ServiceClient(fakeServer), createOpts).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, ExpectedCreateResult, *actual) } func TestDeleteSecret(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDeleteSecretSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDeleteSecretSuccessfully(t, fakeServer) - res := secrets.Delete(context.TODO(), client.ServiceClient(), "1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c") + res := secrets.Delete(context.TODO(), client.ServiceClient(fakeServer), "1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c") th.AssertNoErr(t, res.Err) } func TestUpdateSecret(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleUpdateSecretSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleUpdateSecretSuccessfully(t, fakeServer) updateOpts := secrets.UpdateOpts{ Payload: "foobar", } - err := secrets.Update(context.TODO(), client.ServiceClient(), "1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c", updateOpts).ExtractErr() + err := secrets.Update(context.TODO(), client.ServiceClient(fakeServer), "1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c", updateOpts).ExtractErr() th.AssertNoErr(t, err) } func TestGetPayloadSecret(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetPayloadSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetPayloadSuccessfully(t, fakeServer) - res := secrets.GetPayload(context.TODO(), client.ServiceClient(), "1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c", nil) + res := secrets.GetPayload(context.TODO(), client.ServiceClient(fakeServer), "1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c", nil) th.AssertNoErr(t, res.Err) payload, err := res.Extract() th.AssertNoErr(t, err) @@ -110,74 +110,74 @@ func TestGetPayloadSecret(t *testing.T) { } func TestGetMetadataSuccessfully(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetMetadataSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetMetadataSuccessfully(t, fakeServer) - actual, err := secrets.GetMetadata(context.TODO(), client.ServiceClient(), "1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c").Extract() + actual, err := secrets.GetMetadata(context.TODO(), client.ServiceClient(fakeServer), "1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c").Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, ExpectedMetadata, actual) } func TestCreateMetadataSuccessfully(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateMetadataSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCreateMetadataSuccessfully(t, fakeServer) createOpts := secrets.MetadataOpts{ "foo": "bar", "something": "something else", } - actual, err := secrets.CreateMetadata(context.TODO(), client.ServiceClient(), "1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c", createOpts).Extract() + actual, err := secrets.CreateMetadata(context.TODO(), client.ServiceClient(fakeServer), "1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c", createOpts).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, ExpectedCreateMetadataResult, actual) } func TestGetMetadatumSuccessfully(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetMetadatumSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetMetadatumSuccessfully(t, fakeServer) - actual, err := secrets.GetMetadatum(context.TODO(), client.ServiceClient(), "1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c", "foo").Extract() + actual, err := secrets.GetMetadatum(context.TODO(), client.ServiceClient(fakeServer), "1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c", "foo").Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, ExpectedMetadatum, *actual) } func TestCreateMetadatumSuccessfully(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateMetadatumSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCreateMetadatumSuccessfully(t, fakeServer) createOpts := secrets.MetadatumOpts{ Key: "foo", Value: "bar", } - err := secrets.CreateMetadatum(context.TODO(), client.ServiceClient(), "1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c", createOpts).ExtractErr() + err := secrets.CreateMetadatum(context.TODO(), client.ServiceClient(fakeServer), "1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c", createOpts).ExtractErr() th.AssertNoErr(t, err) } func TestUpdateMetadatumSuccessfully(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleUpdateMetadatumSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleUpdateMetadatumSuccessfully(t, fakeServer) updateOpts := secrets.MetadatumOpts{ Key: "foo", Value: "bar", } - actual, err := secrets.UpdateMetadatum(context.TODO(), client.ServiceClient(), "1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c", updateOpts).Extract() + actual, err := secrets.UpdateMetadatum(context.TODO(), client.ServiceClient(fakeServer), "1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c", updateOpts).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, ExpectedMetadatum, *actual) } func TestDeleteMetadatumSuccessfully(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDeleteMetadatumSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDeleteMetadatumSuccessfully(t, fakeServer) - err := secrets.DeleteMetadatum(context.TODO(), client.ServiceClient(), "1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c", "foo").ExtractErr() + err := secrets.DeleteMetadatum(context.TODO(), client.ServiceClient(fakeServer), "1b8068c4-3bb6-4be6-8f1e-da0d1ea0b67c", "foo").ExtractErr() th.AssertNoErr(t, err) } diff --git a/openstack/loadbalancer/v2/amphorae/testing/fixtures_test.go b/openstack/loadbalancer/v2/amphorae/testing/fixtures_test.go index 049f0697bf..7c18ccea4e 100644 --- a/openstack/loadbalancer/v2/amphorae/testing/fixtures_test.go +++ b/openstack/loadbalancer/v2/amphorae/testing/fixtures_test.go @@ -138,8 +138,8 @@ var SecondAmphora = amphorae.Amphora{ var ExpectedAmphoraeSlice = []amphorae.Amphora{FirstAmphora, SecondAmphora} // HandleAmphoraListSuccessfully sets up the test server to respond to a amphorae List request. -func HandleAmphoraListSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v2.0/octavia/amphorae", func(w http.ResponseWriter, r *http.Request) { +func HandleAmphoraListSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/octavia/amphorae", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -160,8 +160,8 @@ func HandleAmphoraListSuccessfully(t *testing.T) { } // HandleAmphoraGetSuccessfully sets up the test server to respond to am amphora Get request. -func HandleAmphoraGetSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v2.0/octavia/amphorae/45f40289-0551-483a-b089-47214bc2a8a4", func(w http.ResponseWriter, r *http.Request) { +func HandleAmphoraGetSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/octavia/amphorae/45f40289-0551-483a-b089-47214bc2a8a4", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -171,8 +171,8 @@ func HandleAmphoraGetSuccessfully(t *testing.T) { } // HandleAmphoraFailoverSuccessfully sets up the test server to respond to an amphora failover request. -func HandleAmphoraFailoverSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v2.0/octavia/amphorae/36e08a3e-a78f-4b40-a229-1e7e23eee1ab/failover", func(w http.ResponseWriter, r *http.Request) { +func HandleAmphoraFailoverSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/octavia/amphorae/36e08a3e-a78f-4b40-a229-1e7e23eee1ab/failover", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/loadbalancer/v2/amphorae/testing/requests_test.go b/openstack/loadbalancer/v2/amphorae/testing/requests_test.go index bc5feed401..bd65f0d2f6 100644 --- a/openstack/loadbalancer/v2/amphorae/testing/requests_test.go +++ b/openstack/loadbalancer/v2/amphorae/testing/requests_test.go @@ -11,12 +11,12 @@ import ( ) func TestListAmphorae(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleAmphoraListSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleAmphoraListSuccessfully(t, fakeServer) pages := 0 - err := amphorae.List(fake.ServiceClient(), amphorae.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := amphorae.List(fake.ServiceClient(fakeServer), amphorae.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := amphorae.ExtractAmphorae(page) @@ -39,11 +39,11 @@ func TestListAmphorae(t *testing.T) { } func TestListAllAmphorae(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleAmphoraListSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleAmphoraListSuccessfully(t, fakeServer) - allPages, err := amphorae.List(fake.ServiceClient(), amphorae.ListOpts{}).AllPages(context.TODO()) + allPages, err := amphorae.List(fake.ServiceClient(fakeServer), amphorae.ListOpts{}).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := amphorae.ExtractAmphorae(allPages) th.AssertNoErr(t, err) @@ -52,11 +52,11 @@ func TestListAllAmphorae(t *testing.T) { } func TestGetAmphora(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleAmphoraGetSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleAmphoraGetSuccessfully(t, fakeServer) - client := fake.ServiceClient() + client := fake.ServiceClient(fakeServer) actual, err := amphorae.Get(context.TODO(), client, "45f40289-0551-483a-b089-47214bc2a8a4").Extract() if err != nil { t.Fatalf("Unexpected Get error: %v", err) @@ -66,10 +66,10 @@ func TestGetAmphora(t *testing.T) { } func TestFailoverAmphora(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleAmphoraFailoverSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleAmphoraFailoverSuccessfully(t, fakeServer) - res := amphorae.Failover(context.TODO(), fake.ServiceClient(), "36e08a3e-a78f-4b40-a229-1e7e23eee1ab") + res := amphorae.Failover(context.TODO(), fake.ServiceClient(fakeServer), "36e08a3e-a78f-4b40-a229-1e7e23eee1ab") th.AssertNoErr(t, res.Err) } diff --git a/openstack/loadbalancer/v2/apiversions/testing/fixture.go b/openstack/loadbalancer/v2/apiversions/testing/fixture.go index b427378d95..61db7b7d02 100644 --- a/openstack/loadbalancer/v2/apiversions/testing/fixture.go +++ b/openstack/loadbalancer/v2/apiversions/testing/fixture.go @@ -80,8 +80,8 @@ var OctaviaAllAPIVersionResults = []apiversions.APIVersion{ }, } -func MockListResponse(t *testing.T) { - th.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { +func MockListResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/loadbalancer/v2/apiversions/testing/requests_test.go b/openstack/loadbalancer/v2/apiversions/testing/requests_test.go index c0e3aa181c..4a8da72dc1 100644 --- a/openstack/loadbalancer/v2/apiversions/testing/requests_test.go +++ b/openstack/loadbalancer/v2/apiversions/testing/requests_test.go @@ -10,12 +10,12 @@ import ( ) func TestListVersions(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockListResponse(t) + MockListResponse(t, fakeServer) - allVersions, err := apiversions.List(client.ServiceClient()).AllPages(context.TODO()) + allVersions, err := apiversions.List(client.ServiceClient(fakeServer)).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := apiversions.ExtractAPIVersions(allVersions) diff --git a/openstack/loadbalancer/v2/flavorprofiles/testing/fixtures.go b/openstack/loadbalancer/v2/flavorprofiles/testing/fixtures.go index 3558a21919..2ef66175ba 100644 --- a/openstack/loadbalancer/v2/flavorprofiles/testing/fixtures.go +++ b/openstack/loadbalancer/v2/flavorprofiles/testing/fixtures.go @@ -82,8 +82,8 @@ var ( } ) -func HandleFlavorProfileListSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v2.0/lbaas/flavorprofiles", func(w http.ResponseWriter, r *http.Request) { +func HandleFlavorProfileListSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/lbaas/flavorprofiles", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -103,8 +103,8 @@ func HandleFlavorProfileListSuccessfully(t *testing.T) { }) } -func HandleFlavorProfileCreationSuccessfully(t *testing.T, response string) { - th.Mux.HandleFunc("/v2.0/lbaas/flavorprofiles", func(w http.ResponseWriter, r *http.Request) { +func HandleFlavorProfileCreationSuccessfully(t *testing.T, fakeServer th.FakeServer, response string) { + fakeServer.Mux.HandleFunc("/v2.0/lbaas/flavorprofiles", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, `{ @@ -121,8 +121,8 @@ func HandleFlavorProfileCreationSuccessfully(t *testing.T, response string) { }) } -func HandleFlavorProfileGetSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v2.0/lbaas/flavorprofiles/dcd65be5-f117-4260-ab3d-b32cc5bd1272", func(w http.ResponseWriter, r *http.Request) { +func HandleFlavorProfileGetSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/lbaas/flavorprofiles/dcd65be5-f117-4260-ab3d-b32cc5bd1272", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -131,8 +131,8 @@ func HandleFlavorProfileGetSuccessfully(t *testing.T) { }) } -func HandleFlavorProfileDeletionSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v2.0/lbaas/flavorprofiles/dcd65be5-f117-4260-ab3d-b32cc5bd1272", func(w http.ResponseWriter, r *http.Request) { +func HandleFlavorProfileDeletionSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/lbaas/flavorprofiles/dcd65be5-f117-4260-ab3d-b32cc5bd1272", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -140,8 +140,8 @@ func HandleFlavorProfileDeletionSuccessfully(t *testing.T) { }) } -func HandleFlavorProfileUpdateSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v2.0/lbaas/flavorprofiles/dcd65be5-f117-4260-ab3d-b32cc5bd1272", func(w http.ResponseWriter, r *http.Request) { +func HandleFlavorProfileUpdateSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/lbaas/flavorprofiles/dcd65be5-f117-4260-ab3d-b32cc5bd1272", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") diff --git a/openstack/loadbalancer/v2/flavorprofiles/testing/requests_test.go b/openstack/loadbalancer/v2/flavorprofiles/testing/requests_test.go index d81434134f..bc4b480384 100644 --- a/openstack/loadbalancer/v2/flavorprofiles/testing/requests_test.go +++ b/openstack/loadbalancer/v2/flavorprofiles/testing/requests_test.go @@ -12,12 +12,12 @@ import ( ) func TestListFlavorProfiles(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleFlavorProfileListSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleFlavorProfileListSuccessfully(t, fakeServer) pages := 0 - err := flavorprofiles.List(fake.ServiceClient(), flavorprofiles.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := flavorprofiles.List(fake.ServiceClient(fakeServer), flavorprofiles.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := flavorprofiles.ExtractFlavorProfiles(page) @@ -42,11 +42,11 @@ func TestListFlavorProfiles(t *testing.T) { } func TestListAllFlavorProfiles(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleFlavorProfileListSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleFlavorProfileListSuccessfully(t, fakeServer) - allPages, err := flavorprofiles.List(fake.ServiceClient(), flavorprofiles.ListOpts{}).AllPages(context.TODO()) + allPages, err := flavorprofiles.List(fake.ServiceClient(fakeServer), flavorprofiles.ListOpts{}).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := flavorprofiles.ExtractFlavorProfiles(allPages) th.AssertNoErr(t, err) @@ -55,11 +55,11 @@ func TestListAllFlavorProfiles(t *testing.T) { } func TestCreateFlavorProfile(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleFlavorProfileCreationSuccessfully(t, SingleFlavorProfileBody) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleFlavorProfileCreationSuccessfully(t, fakeServer, SingleFlavorProfileBody) - actual, err := flavorprofiles.Create(context.TODO(), fake.ServiceClient(), flavorprofiles.CreateOpts{ + actual, err := flavorprofiles.Create(context.TODO(), fake.ServiceClient(fakeServer), flavorprofiles.CreateOpts{ Name: "amphora-test", ProviderName: "amphora", FlavorData: "{\"loadbalancer_topology\": \"ACTIVE_STANDBY\"}", @@ -70,21 +70,21 @@ func TestCreateFlavorProfile(t *testing.T) { } func TestRequiredCreateOpts(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - res := flavorprofiles.Create(context.TODO(), fake.ServiceClient(), flavorprofiles.CreateOpts{}) + res := flavorprofiles.Create(context.TODO(), fake.ServiceClient(fakeServer), flavorprofiles.CreateOpts{}) if res.Err == nil { t.Fatalf("Expected error, got none") } } func TestGetFlavorProfiles(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleFlavorProfileGetSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleFlavorProfileGetSuccessfully(t, fakeServer) - client := fake.ServiceClient() + client := fake.ServiceClient(fakeServer) actual, err := flavorprofiles.Get(context.TODO(), client, "dcd65be5-f117-4260-ab3d-b32cc5bd1272").Extract() if err != nil { t.Fatalf("Unexpected Get error: %v", err) @@ -94,20 +94,20 @@ func TestGetFlavorProfiles(t *testing.T) { } func TestDeleteFlavorProfile(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleFlavorProfileDeletionSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleFlavorProfileDeletionSuccessfully(t, fakeServer) - res := flavorprofiles.Delete(context.TODO(), fake.ServiceClient(), "dcd65be5-f117-4260-ab3d-b32cc5bd1272") + res := flavorprofiles.Delete(context.TODO(), fake.ServiceClient(fakeServer), "dcd65be5-f117-4260-ab3d-b32cc5bd1272") th.AssertNoErr(t, res.Err) } func TestUpdateFlavorProfile(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleFlavorProfileUpdateSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleFlavorProfileUpdateSuccessfully(t, fakeServer) - client := fake.ServiceClient() + client := fake.ServiceClient(fakeServer) actual, err := flavorprofiles.Update(context.TODO(), client, "dcd65be5-f117-4260-ab3d-b32cc5bd1272", flavorprofiles.UpdateOpts{ Name: "amphora-test-updated", ProviderName: "amphora", diff --git a/openstack/loadbalancer/v2/flavors/testing/fixtures.go b/openstack/loadbalancer/v2/flavors/testing/fixtures.go index 1ec935c156..ed031f6e58 100644 --- a/openstack/loadbalancer/v2/flavors/testing/fixtures.go +++ b/openstack/loadbalancer/v2/flavors/testing/fixtures.go @@ -90,8 +90,8 @@ var ( } ) -func HandleFlavorListSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v2.0/lbaas/flavors", func(w http.ResponseWriter, r *http.Request) { +func HandleFlavorListSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/lbaas/flavors", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -111,8 +111,8 @@ func HandleFlavorListSuccessfully(t *testing.T) { }) } -func HandleFlavorCreationSuccessfully(t *testing.T, response string) { - th.Mux.HandleFunc("/v2.0/lbaas/flavors", func(w http.ResponseWriter, r *http.Request) { +func HandleFlavorCreationSuccessfully(t *testing.T, fakeServer th.FakeServer, response string) { + fakeServer.Mux.HandleFunc("/v2.0/lbaas/flavors", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, `{ @@ -130,8 +130,8 @@ func HandleFlavorCreationSuccessfully(t *testing.T, response string) { }) } -func HandleFlavorGetSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v2.0/lbaas/flavors/5548c807-e6e8-43d7-9ea4-b38d34dd74a0", func(w http.ResponseWriter, r *http.Request) { +func HandleFlavorGetSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/lbaas/flavors/5548c807-e6e8-43d7-9ea4-b38d34dd74a0", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -140,8 +140,8 @@ func HandleFlavorGetSuccessfully(t *testing.T) { }) } -func HandleFlavorDeletionSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v2.0/lbaas/flavors/5548c807-e6e8-43d7-9ea4-b38d34dd74a0", func(w http.ResponseWriter, r *http.Request) { +func HandleFlavorDeletionSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/lbaas/flavors/5548c807-e6e8-43d7-9ea4-b38d34dd74a0", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -149,8 +149,8 @@ func HandleFlavorDeletionSuccessfully(t *testing.T) { }) } -func HandleFlavorUpdateSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v2.0/lbaas/flavors/5548c807-e6e8-43d7-9ea4-b38d34dd74a0", func(w http.ResponseWriter, r *http.Request) { +func HandleFlavorUpdateSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/lbaas/flavors/5548c807-e6e8-43d7-9ea4-b38d34dd74a0", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") diff --git a/openstack/loadbalancer/v2/flavors/testing/requests_test.go b/openstack/loadbalancer/v2/flavors/testing/requests_test.go index 20e5e853b0..09c239f3a4 100644 --- a/openstack/loadbalancer/v2/flavors/testing/requests_test.go +++ b/openstack/loadbalancer/v2/flavors/testing/requests_test.go @@ -15,12 +15,12 @@ import ( ) func TestListFlavors(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleFlavorListSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleFlavorListSuccessfully(t, fakeServer) pages := 0 - err := flavors.List(fake.ServiceClient(), flavors.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := flavors.List(fake.ServiceClient(fakeServer), flavors.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := flavors.ExtractFlavors(page) @@ -45,8 +45,8 @@ func TestListFlavors(t *testing.T) { } func TestListFlavorsEnabled(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() func() { testCases := []string{ @@ -56,7 +56,7 @@ func TestListFlavorsEnabled(t *testing.T) { } cases := 0 - th.Mux.HandleFunc("/v2.0/lbaas/flavors", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/lbaas/flavors", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -81,7 +81,7 @@ func TestListFlavorsEnabled(t *testing.T) { nilBool, } for _, filter := range filters { - allPages, err := flavors.List(fake.ServiceClient(), flavors.ListOpts{Enabled: filter}).AllPages(context.TODO()) + allPages, err := flavors.List(fake.ServiceClient(fakeServer), flavors.ListOpts{Enabled: filter}).AllPages(context.TODO()) th.AssertNoErr(t, err) _, err = flavors.ExtractFlavors(allPages) th.AssertNoErr(t, err) @@ -89,11 +89,11 @@ func TestListFlavorsEnabled(t *testing.T) { } func TestListAllFlavors(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleFlavorListSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleFlavorListSuccessfully(t, fakeServer) - allPages, err := flavors.List(fake.ServiceClient(), flavors.ListOpts{}).AllPages(context.TODO()) + allPages, err := flavors.List(fake.ServiceClient(fakeServer), flavors.ListOpts{}).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := flavors.ExtractFlavors(allPages) th.AssertNoErr(t, err) @@ -102,11 +102,11 @@ func TestListAllFlavors(t *testing.T) { } func TestCreateFlavor(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleFlavorCreationSuccessfully(t, SingleFlavorBody) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleFlavorCreationSuccessfully(t, fakeServer, SingleFlavorBody) - actual, err := flavors.Create(context.TODO(), fake.ServiceClient(), flavors.CreateOpts{ + actual, err := flavors.Create(context.TODO(), fake.ServiceClient(fakeServer), flavors.CreateOpts{ Name: "Basic", Description: "A basic standalone Octavia load balancer.", Enabled: true, @@ -118,21 +118,21 @@ func TestCreateFlavor(t *testing.T) { } func TestRequiredCreateOpts(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - res := flavors.Create(context.TODO(), fake.ServiceClient(), flavors.CreateOpts{}) + res := flavors.Create(context.TODO(), fake.ServiceClient(fakeServer), flavors.CreateOpts{}) if res.Err == nil { t.Fatalf("Expected error, got none") } } func TestGetFlavor(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleFlavorGetSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleFlavorGetSuccessfully(t, fakeServer) - client := fake.ServiceClient() + client := fake.ServiceClient(fakeServer) actual, err := flavors.Get(context.TODO(), client, "5548c807-e6e8-43d7-9ea4-b38d34dd74a0").Extract() if err != nil { t.Fatalf("Unexpected Get error: %v", err) @@ -142,20 +142,20 @@ func TestGetFlavor(t *testing.T) { } func TestDeleteFlavor(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleFlavorDeletionSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleFlavorDeletionSuccessfully(t, fakeServer) - res := flavors.Delete(context.TODO(), fake.ServiceClient(), "5548c807-e6e8-43d7-9ea4-b38d34dd74a0") + res := flavors.Delete(context.TODO(), fake.ServiceClient(fakeServer), "5548c807-e6e8-43d7-9ea4-b38d34dd74a0") th.AssertNoErr(t, res.Err) } func TestUpdateFlavor(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleFlavorUpdateSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleFlavorUpdateSuccessfully(t, fakeServer) - client := fake.ServiceClient() + client := fake.ServiceClient(fakeServer) actual, err := flavors.Update(context.TODO(), client, "5548c807-e6e8-43d7-9ea4-b38d34dd74a0", flavors.UpdateOpts{ Name: "Basic v2", Description: "Rename flavor", diff --git a/openstack/loadbalancer/v2/l7policies/testing/fixtures_test.go b/openstack/loadbalancer/v2/l7policies/testing/fixtures_test.go index 56b35cd0e0..98efa14b88 100644 --- a/openstack/loadbalancer/v2/l7policies/testing/fixtures_test.go +++ b/openstack/loadbalancer/v2/l7policies/testing/fixtures_test.go @@ -116,8 +116,8 @@ var ( // HandleL7PolicyCreationSuccessfully sets up the test server to respond to a l7policy creation request // with a given response. -func HandleL7PolicyCreationSuccessfully(t *testing.T, response string) { - th.Mux.HandleFunc("/v2.0/lbaas/l7policies", func(w http.ResponseWriter, r *http.Request) { +func HandleL7PolicyCreationSuccessfully(t *testing.T, fakeServer th.FakeServer, response string) { + fakeServer.Mux.HandleFunc("/v2.0/lbaas/l7policies", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, `{ @@ -206,8 +206,8 @@ const PostUpdateL7PolicyNullRedirectURLBody = ` ` // HandleL7PolicyListSuccessfully sets up the test server to respond to a l7policy List request. -func HandleL7PolicyListSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v2.0/lbaas/l7policies", func(w http.ResponseWriter, r *http.Request) { +func HandleL7PolicyListSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/lbaas/l7policies", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -228,8 +228,8 @@ func HandleL7PolicyListSuccessfully(t *testing.T) { } // HandleL7PolicyGetSuccessfully sets up the test server to respond to a l7policy Get request. -func HandleL7PolicyGetSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v2.0/lbaas/l7policies/8a1412f0-4c32-4257-8b07-af4770b604fd", func(w http.ResponseWriter, r *http.Request) { +func HandleL7PolicyGetSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/lbaas/l7policies/8a1412f0-4c32-4257-8b07-af4770b604fd", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -239,8 +239,8 @@ func HandleL7PolicyGetSuccessfully(t *testing.T) { } // HandleL7PolicyDeletionSuccessfully sets up the test server to respond to a l7policy deletion request. -func HandleL7PolicyDeletionSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v2.0/lbaas/l7policies/8a1412f0-4c32-4257-8b07-af4770b604fd", func(w http.ResponseWriter, r *http.Request) { +func HandleL7PolicyDeletionSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/lbaas/l7policies/8a1412f0-4c32-4257-8b07-af4770b604fd", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -249,8 +249,8 @@ func HandleL7PolicyDeletionSuccessfully(t *testing.T) { } // HandleL7PolicyUpdateSuccessfully sets up the test server to respond to a l7policy Update request. -func HandleL7PolicyUpdateSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v2.0/lbaas/l7policies/8a1412f0-4c32-4257-8b07-af4770b604fd", func(w http.ResponseWriter, r *http.Request) { +func HandleL7PolicyUpdateSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/lbaas/l7policies/8a1412f0-4c32-4257-8b07-af4770b604fd", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -268,8 +268,8 @@ func HandleL7PolicyUpdateSuccessfully(t *testing.T) { } // HandleL7PolicyUpdateNullRedirectURLSuccessfully sets up the test server to respond to a l7policy Update request. -func HandleL7PolicyUpdateNullRedirectURLSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v2.0/lbaas/l7policies/8a1412f0-4c32-4257-8b07-af4770b604fd", func(w http.ResponseWriter, r *http.Request) { +func HandleL7PolicyUpdateNullRedirectURLSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/lbaas/l7policies/8a1412f0-4c32-4257-8b07-af4770b604fd", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -303,8 +303,8 @@ const SingleRuleBody = ` // HandleRuleCreationSuccessfully sets up the test server to respond to a rule creation request // with a given response. -func HandleRuleCreationSuccessfully(t *testing.T, response string) { - th.Mux.HandleFunc("/v2.0/lbaas/l7policies/8a1412f0-4c32-4257-8b07-af4770b604fd/rules", func(w http.ResponseWriter, r *http.Request) { +func HandleRuleCreationSuccessfully(t *testing.T, fakeServer th.FakeServer, response string) { + fakeServer.Mux.HandleFunc("/v2.0/lbaas/l7policies/8a1412f0-4c32-4257-8b07-af4770b604fd/rules", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, `{ @@ -350,8 +350,8 @@ const RulesListBody = ` ` // HandleRuleListSuccessfully sets up the test server to respond to a rule List request. -func HandleRuleListSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v2.0/lbaas/l7policies/8a1412f0-4c32-4257-8b07-af4770b604fd/rules", func(w http.ResponseWriter, r *http.Request) { +func HandleRuleListSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/lbaas/l7policies/8a1412f0-4c32-4257-8b07-af4770b604fd/rules", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -372,8 +372,8 @@ func HandleRuleListSuccessfully(t *testing.T) { } // HandleRuleGetSuccessfully sets up the test server to respond to a rule Get request. -func HandleRuleGetSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v2.0/lbaas/l7policies/8a1412f0-4c32-4257-8b07-af4770b604fd/rules/16621dbb-a736-4888-a57a-3ecd53df784c", func(w http.ResponseWriter, r *http.Request) { +func HandleRuleGetSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/lbaas/l7policies/8a1412f0-4c32-4257-8b07-af4770b604fd/rules/16621dbb-a736-4888-a57a-3ecd53df784c", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -383,8 +383,8 @@ func HandleRuleGetSuccessfully(t *testing.T) { } // HandleRuleDeletionSuccessfully sets up the test server to respond to a rule deletion request. -func HandleRuleDeletionSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v2.0/lbaas/l7policies/8a1412f0-4c32-4257-8b07-af4770b604fd/rules/16621dbb-a736-4888-a57a-3ecd53df784c", func(w http.ResponseWriter, r *http.Request) { +func HandleRuleDeletionSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/lbaas/l7policies/8a1412f0-4c32-4257-8b07-af4770b604fd/rules/16621dbb-a736-4888-a57a-3ecd53df784c", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -409,8 +409,8 @@ const PostUpdateRuleBody = ` ` // HandleRuleUpdateSuccessfully sets up the test server to respond to a rule Update request. -func HandleRuleUpdateSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v2.0/lbaas/l7policies/8a1412f0-4c32-4257-8b07-af4770b604fd/rules/16621dbb-a736-4888-a57a-3ecd53df784c", func(w http.ResponseWriter, r *http.Request) { +func HandleRuleUpdateSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/lbaas/l7policies/8a1412f0-4c32-4257-8b07-af4770b604fd/rules/16621dbb-a736-4888-a57a-3ecd53df784c", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") diff --git a/openstack/loadbalancer/v2/l7policies/testing/requests_test.go b/openstack/loadbalancer/v2/l7policies/testing/requests_test.go index 4ccfd1701c..324515152c 100644 --- a/openstack/loadbalancer/v2/l7policies/testing/requests_test.go +++ b/openstack/loadbalancer/v2/l7policies/testing/requests_test.go @@ -11,11 +11,11 @@ import ( ) func TestCreateL7Policy(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleL7PolicyCreationSuccessfully(t, SingleL7PolicyBody) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleL7PolicyCreationSuccessfully(t, fakeServer, SingleL7PolicyBody) - actual, err := l7policies.Create(context.TODO(), fake.ServiceClient(), l7policies.CreateOpts{ + actual, err := l7policies.Create(context.TODO(), fake.ServiceClient(fakeServer), l7policies.CreateOpts{ Name: "redirect-example.com", ListenerID: "023f2e34-7806-443b-bfae-16c324569a3d", Action: l7policies.ActionRedirectToURL, @@ -27,17 +27,17 @@ func TestCreateL7Policy(t *testing.T) { } func TestRequiredL7PolicyCreateOpts(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() // no param specified. - res := l7policies.Create(context.TODO(), fake.ServiceClient(), l7policies.CreateOpts{}) + res := l7policies.Create(context.TODO(), fake.ServiceClient(fakeServer), l7policies.CreateOpts{}) if res.Err == nil { t.Fatalf("Expected error, got none") } // Action is invalid. - res = l7policies.Create(context.TODO(), fake.ServiceClient(), l7policies.CreateOpts{ + res = l7policies.Create(context.TODO(), fake.ServiceClient(fakeServer), l7policies.CreateOpts{ ListenerID: "023f2e34-7806-443b-bfae-16c324569a3d", Action: l7policies.Action("invalid"), }) @@ -47,12 +47,12 @@ func TestRequiredL7PolicyCreateOpts(t *testing.T) { } func TestListL7Policies(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleL7PolicyListSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleL7PolicyListSuccessfully(t, fakeServer) pages := 0 - err := l7policies.List(fake.ServiceClient(), l7policies.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := l7policies.List(fake.ServiceClient(fakeServer), l7policies.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := l7policies.ExtractL7Policies(page) @@ -77,11 +77,11 @@ func TestListL7Policies(t *testing.T) { } func TestListAllL7Policies(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleL7PolicyListSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleL7PolicyListSuccessfully(t, fakeServer) - allPages, err := l7policies.List(fake.ServiceClient(), l7policies.ListOpts{}).AllPages(context.TODO()) + allPages, err := l7policies.List(fake.ServiceClient(fakeServer), l7policies.ListOpts{}).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := l7policies.ExtractL7Policies(allPages) th.AssertNoErr(t, err) @@ -90,11 +90,11 @@ func TestListAllL7Policies(t *testing.T) { } func TestGetL7Policy(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleL7PolicyGetSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleL7PolicyGetSuccessfully(t, fakeServer) - client := fake.ServiceClient() + client := fake.ServiceClient(fakeServer) actual, err := l7policies.Get(context.TODO(), client, "8a1412f0-4c32-4257-8b07-af4770b604fd").Extract() if err != nil { t.Fatalf("Unexpected Get error: %v", err) @@ -104,20 +104,20 @@ func TestGetL7Policy(t *testing.T) { } func TestDeleteL7Policy(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleL7PolicyDeletionSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleL7PolicyDeletionSuccessfully(t, fakeServer) - res := l7policies.Delete(context.TODO(), fake.ServiceClient(), "8a1412f0-4c32-4257-8b07-af4770b604fd") + res := l7policies.Delete(context.TODO(), fake.ServiceClient(fakeServer), "8a1412f0-4c32-4257-8b07-af4770b604fd") th.AssertNoErr(t, res.Err) } func TestUpdateL7Policy(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleL7PolicyUpdateSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleL7PolicyUpdateSuccessfully(t, fakeServer) - client := fake.ServiceClient() + client := fake.ServiceClient(fakeServer) newName := "NewL7PolicyName" redirectURL := "http://www.new-example.com" actual, err := l7policies.Update(context.TODO(), client, "8a1412f0-4c32-4257-8b07-af4770b604fd", @@ -134,11 +134,11 @@ func TestUpdateL7Policy(t *testing.T) { } func TestUpdateL7PolicyNullRedirectURL(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleL7PolicyUpdateNullRedirectURLSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleL7PolicyUpdateNullRedirectURLSuccessfully(t, fakeServer) - client := fake.ServiceClient() + client := fake.ServiceClient(fakeServer) newName := "NewL7PolicyName" redirectURL := "" actual, err := l7policies.Update(context.TODO(), client, "8a1412f0-4c32-4257-8b07-af4770b604fd", @@ -154,10 +154,10 @@ func TestUpdateL7PolicyNullRedirectURL(t *testing.T) { } func TestUpdateL7PolicyWithInvalidOpts(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - res := l7policies.Update(context.TODO(), fake.ServiceClient(), "8a1412f0-4c32-4257-8b07-af4770b604fd", l7policies.UpdateOpts{ + res := l7policies.Update(context.TODO(), fake.ServiceClient(fakeServer), "8a1412f0-4c32-4257-8b07-af4770b604fd", l7policies.UpdateOpts{ Action: l7policies.Action("invalid"), }) if res.Err == nil { @@ -166,11 +166,11 @@ func TestUpdateL7PolicyWithInvalidOpts(t *testing.T) { } func TestCreateRule(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleRuleCreationSuccessfully(t, SingleRuleBody) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleRuleCreationSuccessfully(t, fakeServer, SingleRuleBody) - actual, err := l7policies.CreateRule(context.TODO(), fake.ServiceClient(), "8a1412f0-4c32-4257-8b07-af4770b604fd", l7policies.CreateRuleOpts{ + actual, err := l7policies.CreateRule(context.TODO(), fake.ServiceClient(fakeServer), "8a1412f0-4c32-4257-8b07-af4770b604fd", l7policies.CreateRuleOpts{ RuleType: l7policies.TypePath, CompareType: l7policies.CompareTypeRegex, Value: "/images*", @@ -181,20 +181,20 @@ func TestCreateRule(t *testing.T) { } func TestRequiredRuleCreateOpts(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - res := l7policies.CreateRule(context.TODO(), fake.ServiceClient(), "", l7policies.CreateRuleOpts{}) + res := l7policies.CreateRule(context.TODO(), fake.ServiceClient(fakeServer), "", l7policies.CreateRuleOpts{}) if res.Err == nil { t.Fatalf("Expected error, got none") } - res = l7policies.CreateRule(context.TODO(), fake.ServiceClient(), "8a1412f0-4c32-4257-8b07-af4770b604fd", l7policies.CreateRuleOpts{ + res = l7policies.CreateRule(context.TODO(), fake.ServiceClient(fakeServer), "8a1412f0-4c32-4257-8b07-af4770b604fd", l7policies.CreateRuleOpts{ RuleType: l7policies.TypePath, }) if res.Err == nil { t.Fatalf("Expected error, but got none") } - res = l7policies.CreateRule(context.TODO(), fake.ServiceClient(), "8a1412f0-4c32-4257-8b07-af4770b604fd", l7policies.CreateRuleOpts{ + res = l7policies.CreateRule(context.TODO(), fake.ServiceClient(fakeServer), "8a1412f0-4c32-4257-8b07-af4770b604fd", l7policies.CreateRuleOpts{ RuleType: l7policies.RuleType("invalid"), CompareType: l7policies.CompareTypeRegex, Value: "/images*", @@ -202,7 +202,7 @@ func TestRequiredRuleCreateOpts(t *testing.T) { if res.Err == nil { t.Fatalf("Expected error, but got none") } - res = l7policies.CreateRule(context.TODO(), fake.ServiceClient(), "8a1412f0-4c32-4257-8b07-af4770b604fd", l7policies.CreateRuleOpts{ + res = l7policies.CreateRule(context.TODO(), fake.ServiceClient(fakeServer), "8a1412f0-4c32-4257-8b07-af4770b604fd", l7policies.CreateRuleOpts{ RuleType: l7policies.TypePath, CompareType: l7policies.CompareType("invalid"), Value: "/images*", @@ -213,12 +213,12 @@ func TestRequiredRuleCreateOpts(t *testing.T) { } func TestListRules(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleRuleListSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleRuleListSuccessfully(t, fakeServer) pages := 0 - err := l7policies.ListRules(fake.ServiceClient(), "8a1412f0-4c32-4257-8b07-af4770b604fd", l7policies.ListRulesOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := l7policies.ListRules(fake.ServiceClient(fakeServer), "8a1412f0-4c32-4257-8b07-af4770b604fd", l7policies.ListRulesOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := l7policies.ExtractRules(page) @@ -243,11 +243,11 @@ func TestListRules(t *testing.T) { } func TestListAllRules(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleRuleListSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleRuleListSuccessfully(t, fakeServer) - allPages, err := l7policies.ListRules(fake.ServiceClient(), "8a1412f0-4c32-4257-8b07-af4770b604fd", l7policies.ListRulesOpts{}).AllPages(context.TODO()) + allPages, err := l7policies.ListRules(fake.ServiceClient(fakeServer), "8a1412f0-4c32-4257-8b07-af4770b604fd", l7policies.ListRulesOpts{}).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := l7policies.ExtractRules(allPages) @@ -257,11 +257,11 @@ func TestListAllRules(t *testing.T) { } func TestGetRule(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleRuleGetSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleRuleGetSuccessfully(t, fakeServer) - client := fake.ServiceClient() + client := fake.ServiceClient(fakeServer) actual, err := l7policies.GetRule(context.TODO(), client, "8a1412f0-4c32-4257-8b07-af4770b604fd", "16621dbb-a736-4888-a57a-3ecd53df784c").Extract() if err != nil { t.Fatalf("Unexpected Get error: %v", err) @@ -271,20 +271,20 @@ func TestGetRule(t *testing.T) { } func TestDeleteRule(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleRuleDeletionSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleRuleDeletionSuccessfully(t, fakeServer) - res := l7policies.DeleteRule(context.TODO(), fake.ServiceClient(), "8a1412f0-4c32-4257-8b07-af4770b604fd", "16621dbb-a736-4888-a57a-3ecd53df784c") + res := l7policies.DeleteRule(context.TODO(), fake.ServiceClient(fakeServer), "8a1412f0-4c32-4257-8b07-af4770b604fd", "16621dbb-a736-4888-a57a-3ecd53df784c") th.AssertNoErr(t, res.Err) } func TestUpdateRule(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleRuleUpdateSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleRuleUpdateSuccessfully(t, fakeServer) - client := fake.ServiceClient() + client := fake.ServiceClient(fakeServer) invert := false key := "" actual, err := l7policies.UpdateRule(context.TODO(), client, "8a1412f0-4c32-4257-8b07-af4770b604fd", "16621dbb-a736-4888-a57a-3ecd53df784c", l7policies.UpdateRuleOpts{ @@ -302,17 +302,17 @@ func TestUpdateRule(t *testing.T) { } func TestUpdateRuleWithInvalidOpts(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - res := l7policies.UpdateRule(context.TODO(), fake.ServiceClient(), "", "", l7policies.UpdateRuleOpts{ + res := l7policies.UpdateRule(context.TODO(), fake.ServiceClient(fakeServer), "", "", l7policies.UpdateRuleOpts{ RuleType: l7policies.RuleType("invalid"), }) if res.Err == nil { t.Fatalf("Expected error, got none") } - res = l7policies.UpdateRule(context.TODO(), fake.ServiceClient(), "", "", l7policies.UpdateRuleOpts{ + res = l7policies.UpdateRule(context.TODO(), fake.ServiceClient(fakeServer), "", "", l7policies.UpdateRuleOpts{ CompareType: l7policies.CompareType("invalid"), }) if res.Err == nil { diff --git a/openstack/loadbalancer/v2/listeners/testing/fixtures_test.go b/openstack/loadbalancer/v2/listeners/testing/fixtures_test.go index 9f85649411..9cc5d3a0a2 100644 --- a/openstack/loadbalancer/v2/listeners/testing/fixtures_test.go +++ b/openstack/loadbalancer/v2/listeners/testing/fixtures_test.go @@ -206,8 +206,8 @@ var ( ) // HandleListenerListSuccessfully sets up the test server to respond to a listener List request. -func HandleListenerListSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v2.0/lbaas/listeners", func(w http.ResponseWriter, r *http.Request) { +func HandleListenerListSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/lbaas/listeners", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -229,8 +229,8 @@ func HandleListenerListSuccessfully(t *testing.T) { // HandleListenerCreationSuccessfully sets up the test server to respond to a listener creation request // with a given response. -func HandleListenerCreationSuccessfully(t *testing.T, response string) { - th.Mux.HandleFunc("/v2.0/lbaas/listeners", func(w http.ResponseWriter, r *http.Request) { +func HandleListenerCreationSuccessfully(t *testing.T, fakeServer th.FakeServer, response string) { + fakeServer.Mux.HandleFunc("/v2.0/lbaas/listeners", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, `{ @@ -260,8 +260,8 @@ func HandleListenerCreationSuccessfully(t *testing.T, response string) { } // HandleListenerGetSuccessfully sets up the test server to respond to a listener Get request. -func HandleListenerGetSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v2.0/lbaas/listeners/4ec89087-d057-4e2c-911f-60a3b47ee304", func(w http.ResponseWriter, r *http.Request) { +func HandleListenerGetSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/lbaas/listeners/4ec89087-d057-4e2c-911f-60a3b47ee304", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -271,8 +271,8 @@ func HandleListenerGetSuccessfully(t *testing.T) { } // HandleListenerDeletionSuccessfully sets up the test server to respond to a listener deletion request. -func HandleListenerDeletionSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v2.0/lbaas/listeners/4ec89087-d057-4e2c-911f-60a3b47ee304", func(w http.ResponseWriter, r *http.Request) { +func HandleListenerDeletionSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/lbaas/listeners/4ec89087-d057-4e2c-911f-60a3b47ee304", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -281,8 +281,8 @@ func HandleListenerDeletionSuccessfully(t *testing.T) { } // HandleListenerUpdateSuccessfully sets up the test server to respond to a listener Update request. -func HandleListenerUpdateSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v2.0/lbaas/listeners/4ec89087-d057-4e2c-911f-60a3b47ee304", func(w http.ResponseWriter, r *http.Request) { +func HandleListenerUpdateSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/lbaas/listeners/4ec89087-d057-4e2c-911f-60a3b47ee304", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -309,8 +309,8 @@ func HandleListenerUpdateSuccessfully(t *testing.T) { } // HandleListenerGetStatsTree sets up the test server to respond to a listener Get stats tree request. -func HandleListenerGetStatsTree(t *testing.T) { - th.Mux.HandleFunc("/v2.0/lbaas/listeners/4ec89087-d057-4e2c-911f-60a3b47ee304/stats", func(w http.ResponseWriter, r *http.Request) { +func HandleListenerGetStatsTree(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/lbaas/listeners/4ec89087-d057-4e2c-911f-60a3b47ee304/stats", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") diff --git a/openstack/loadbalancer/v2/listeners/testing/requests_test.go b/openstack/loadbalancer/v2/listeners/testing/requests_test.go index 019b2c9f65..346aa86135 100644 --- a/openstack/loadbalancer/v2/listeners/testing/requests_test.go +++ b/openstack/loadbalancer/v2/listeners/testing/requests_test.go @@ -12,12 +12,12 @@ import ( ) func TestListListeners(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListenerListSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListenerListSuccessfully(t, fakeServer) pages := 0 - err := listeners.List(fake.ServiceClient(), listeners.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := listeners.List(fake.ServiceClient(fakeServer), listeners.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := listeners.ExtractListeners(page) @@ -42,11 +42,11 @@ func TestListListeners(t *testing.T) { } func TestListAllListeners(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListenerListSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListenerListSuccessfully(t, fakeServer) - allPages, err := listeners.List(fake.ServiceClient(), listeners.ListOpts{}).AllPages(context.TODO()) + allPages, err := listeners.List(fake.ServiceClient(fakeServer), listeners.ListOpts{}).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := listeners.ExtractListeners(allPages) th.AssertNoErr(t, err) @@ -55,11 +55,11 @@ func TestListAllListeners(t *testing.T) { } func TestCreateListener(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListenerCreationSuccessfully(t, SingleListenerBody) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListenerCreationSuccessfully(t, fakeServer, SingleListenerBody) - actual, err := listeners.Create(context.TODO(), fake.ServiceClient(), listeners.CreateOpts{ + actual, err := listeners.Create(context.TODO(), fake.ServiceClient(fakeServer), listeners.CreateOpts{ Protocol: "TCP", Name: "db", LoadbalancerID: "79e05663-7f03-45d2-a092-8b94062f22ab", @@ -77,37 +77,37 @@ func TestCreateListener(t *testing.T) { } func TestRequiredCreateOpts(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - res := listeners.Create(context.TODO(), fake.ServiceClient(), listeners.CreateOpts{}) + res := listeners.Create(context.TODO(), fake.ServiceClient(fakeServer), listeners.CreateOpts{}) if res.Err == nil { t.Fatalf("Expected error, got none") } - res = listeners.Create(context.TODO(), fake.ServiceClient(), listeners.CreateOpts{Name: "foo"}) + res = listeners.Create(context.TODO(), fake.ServiceClient(fakeServer), listeners.CreateOpts{Name: "foo"}) if res.Err == nil { t.Fatalf("Expected error, got none") } - res = listeners.Create(context.TODO(), fake.ServiceClient(), listeners.CreateOpts{Name: "foo", ProjectID: "bar"}) + res = listeners.Create(context.TODO(), fake.ServiceClient(fakeServer), listeners.CreateOpts{Name: "foo", ProjectID: "bar"}) if res.Err == nil { t.Fatalf("Expected error, got none") } - res = listeners.Create(context.TODO(), fake.ServiceClient(), listeners.CreateOpts{Name: "foo", ProjectID: "bar", Protocol: "bar"}) + res = listeners.Create(context.TODO(), fake.ServiceClient(fakeServer), listeners.CreateOpts{Name: "foo", ProjectID: "bar", Protocol: "bar"}) if res.Err == nil { t.Fatalf("Expected error, got none") } - res = listeners.Create(context.TODO(), fake.ServiceClient(), listeners.CreateOpts{Name: "foo", ProjectID: "bar", Protocol: "bar", ProtocolPort: 80}) + res = listeners.Create(context.TODO(), fake.ServiceClient(fakeServer), listeners.CreateOpts{Name: "foo", ProjectID: "bar", Protocol: "bar", ProtocolPort: 80}) if res.Err == nil { t.Fatalf("Expected error, got none") } } func TestGetListener(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListenerGetSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListenerGetSuccessfully(t, fakeServer) - client := fake.ServiceClient() + client := fake.ServiceClient(fakeServer) actual, err := listeners.Get(context.TODO(), client, "4ec89087-d057-4e2c-911f-60a3b47ee304").Extract() if err != nil { t.Fatalf("Unexpected Get error: %v", err) @@ -117,20 +117,20 @@ func TestGetListener(t *testing.T) { } func TestDeleteListener(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListenerDeletionSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListenerDeletionSuccessfully(t, fakeServer) - res := listeners.Delete(context.TODO(), fake.ServiceClient(), "4ec89087-d057-4e2c-911f-60a3b47ee304") + res := listeners.Delete(context.TODO(), fake.ServiceClient(fakeServer), "4ec89087-d057-4e2c-911f-60a3b47ee304") th.AssertNoErr(t, res.Err) } func TestUpdateListener(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListenerUpdateSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListenerUpdateSuccessfully(t, fakeServer) - client := fake.ServiceClient() + client := fake.ServiceClient(fakeServer) i1001 := 1001 i181000 := 181000 name := "NewListenerName" @@ -159,11 +159,11 @@ func TestUpdateListener(t *testing.T) { } func TestGetListenerStatsTree(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListenerGetStatsTree(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListenerGetStatsTree(t, fakeServer) - client := fake.ServiceClient() + client := fake.ServiceClient(fakeServer) actual, err := listeners.GetStats(context.TODO(), client, "4ec89087-d057-4e2c-911f-60a3b47ee304").Extract() if err != nil { t.Fatalf("Unexpected Get error: %v", err) diff --git a/openstack/loadbalancer/v2/loadbalancers/testing/fixtures_test.go b/openstack/loadbalancer/v2/loadbalancers/testing/fixtures_test.go index 76ef3ec2a7..a9e7f0a621 100644 --- a/openstack/loadbalancer/v2/loadbalancers/testing/fixtures_test.go +++ b/openstack/loadbalancer/v2/loadbalancers/testing/fixtures_test.go @@ -441,8 +441,8 @@ var ( ) // HandleLoadbalancerListSuccessfully sets up the test server to respond to a loadbalancer List request. -func HandleLoadbalancerListSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v2.0/lbaas/loadbalancers", func(w http.ResponseWriter, r *http.Request) { +func HandleLoadbalancerListSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/lbaas/loadbalancers", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -464,8 +464,8 @@ func HandleLoadbalancerListSuccessfully(t *testing.T) { // HandleFullyPopulatedLoadbalancerCreationSuccessfully sets up the test server to respond to a // fully populated loadbalancer creation request with a given response. -func HandleFullyPopulatedLoadbalancerCreationSuccessfully(t *testing.T, response string) { - th.Mux.HandleFunc("/v2.0/lbaas/loadbalancers", func(w http.ResponseWriter, r *http.Request) { +func HandleFullyPopulatedLoadbalancerCreationSuccessfully(t *testing.T, fakeServer th.FakeServer, response string) { + fakeServer.Mux.HandleFunc("/v2.0/lbaas/loadbalancers", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, `{ @@ -539,8 +539,8 @@ func HandleFullyPopulatedLoadbalancerCreationSuccessfully(t *testing.T, response // HandleLoadbalancerCreationSuccessfully sets up the test server to respond to a loadbalancer creation request // with a given response. -func HandleLoadbalancerCreationSuccessfully(t *testing.T, response string) { - th.Mux.HandleFunc("/v2.0/lbaas/loadbalancers", func(w http.ResponseWriter, r *http.Request) { +func HandleLoadbalancerCreationSuccessfully(t *testing.T, fakeServer th.FakeServer, response string) { + fakeServer.Mux.HandleFunc("/v2.0/lbaas/loadbalancers", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, `{ @@ -564,8 +564,8 @@ func HandleLoadbalancerCreationSuccessfully(t *testing.T, response string) { } // HandleLoadbalancerGetSuccessfully sets up the test server to respond to a loadbalancer Get request. -func HandleLoadbalancerGetSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v2.0/lbaas/loadbalancers/36e08a3e-a78f-4b40-a229-1e7e23eee1ab", func(w http.ResponseWriter, r *http.Request) { +func HandleLoadbalancerGetSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/lbaas/loadbalancers/36e08a3e-a78f-4b40-a229-1e7e23eee1ab", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -575,8 +575,8 @@ func HandleLoadbalancerGetSuccessfully(t *testing.T) { } // HandleLoadbalancerGetStatusesTree sets up the test server to respond to a loadbalancer Get statuses tree request. -func HandleLoadbalancerGetStatusesTree(t *testing.T) { - th.Mux.HandleFunc("/v2.0/lbaas/loadbalancers/36e08a3e-a78f-4b40-a229-1e7e23eee1ab/status", func(w http.ResponseWriter, r *http.Request) { +func HandleLoadbalancerGetStatusesTree(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/lbaas/loadbalancers/36e08a3e-a78f-4b40-a229-1e7e23eee1ab/status", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -586,8 +586,8 @@ func HandleLoadbalancerGetStatusesTree(t *testing.T) { } // HandleLoadbalancerDeletionSuccessfully sets up the test server to respond to a loadbalancer deletion request. -func HandleLoadbalancerDeletionSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v2.0/lbaas/loadbalancers/36e08a3e-a78f-4b40-a229-1e7e23eee1ab", func(w http.ResponseWriter, r *http.Request) { +func HandleLoadbalancerDeletionSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/lbaas/loadbalancers/36e08a3e-a78f-4b40-a229-1e7e23eee1ab", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -596,8 +596,8 @@ func HandleLoadbalancerDeletionSuccessfully(t *testing.T) { } // HandleLoadbalancerUpdateSuccessfully sets up the test server to respond to a loadbalancer Update request. -func HandleLoadbalancerUpdateSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v2.0/lbaas/loadbalancers/36e08a3e-a78f-4b40-a229-1e7e23eee1ab", func(w http.ResponseWriter, r *http.Request) { +func HandleLoadbalancerUpdateSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/lbaas/loadbalancers/36e08a3e-a78f-4b40-a229-1e7e23eee1ab", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -614,8 +614,8 @@ func HandleLoadbalancerUpdateSuccessfully(t *testing.T) { } // HandleLoadbalancerGetStatsTree sets up the test server to respond to a loadbalancer Get stats tree request. -func HandleLoadbalancerGetStatsTree(t *testing.T) { - th.Mux.HandleFunc("/v2.0/lbaas/loadbalancers/36e08a3e-a78f-4b40-a229-1e7e23eee1ab/stats", func(w http.ResponseWriter, r *http.Request) { +func HandleLoadbalancerGetStatsTree(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/lbaas/loadbalancers/36e08a3e-a78f-4b40-a229-1e7e23eee1ab/stats", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -625,8 +625,8 @@ func HandleLoadbalancerGetStatsTree(t *testing.T) { } // HandleLoadbalancerFailoverSuccessfully sets up the test server to respond to a loadbalancer failover request. -func HandleLoadbalancerFailoverSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v2.0/lbaas/loadbalancers/36e08a3e-a78f-4b40-a229-1e7e23eee1ab/failover", func(w http.ResponseWriter, r *http.Request) { +func HandleLoadbalancerFailoverSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/lbaas/loadbalancers/36e08a3e-a78f-4b40-a229-1e7e23eee1ab/failover", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/loadbalancer/v2/loadbalancers/testing/requests_test.go b/openstack/loadbalancer/v2/loadbalancers/testing/requests_test.go index 04fe8549d3..64a3ddc83f 100644 --- a/openstack/loadbalancer/v2/loadbalancers/testing/requests_test.go +++ b/openstack/loadbalancer/v2/loadbalancers/testing/requests_test.go @@ -17,12 +17,12 @@ import ( ) func TestListLoadbalancers(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleLoadbalancerListSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleLoadbalancerListSuccessfully(t, fakeServer) pages := 0 - err := loadbalancers.List(fake.ServiceClient(), loadbalancers.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := loadbalancers.List(fake.ServiceClient(fakeServer), loadbalancers.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := loadbalancers.ExtractLoadBalancers(page) @@ -47,11 +47,11 @@ func TestListLoadbalancers(t *testing.T) { } func TestListAllLoadbalancers(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleLoadbalancerListSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleLoadbalancerListSuccessfully(t, fakeServer) - allPages, err := loadbalancers.List(fake.ServiceClient(), loadbalancers.ListOpts{}).AllPages(context.TODO()) + allPages, err := loadbalancers.List(fake.ServiceClient(fakeServer), loadbalancers.ListOpts{}).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := loadbalancers.ExtractLoadBalancers(allPages) th.AssertNoErr(t, err) @@ -60,11 +60,11 @@ func TestListAllLoadbalancers(t *testing.T) { } func TestCreateLoadbalancer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleLoadbalancerCreationSuccessfully(t, SingleLoadbalancerBody) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleLoadbalancerCreationSuccessfully(t, fakeServer, SingleLoadbalancerBody) - actual, err := loadbalancers.Create(context.TODO(), fake.ServiceClient(), loadbalancers.CreateOpts{ + actual, err := loadbalancers.Create(context.TODO(), fake.ServiceClient(fakeServer), loadbalancers.CreateOpts{ Name: "db_lb", AdminStateUp: gophercloud.Enabled, VipPortID: "2bf413c8-41a9-4477-b505-333d5cbe8b55", @@ -86,11 +86,11 @@ func TestCreateLoadbalancer(t *testing.T) { } func TestCreateFullyPopulatedLoadbalancer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleFullyPopulatedLoadbalancerCreationSuccessfully(t, PostFullyPopulatedLoadbalancerBody) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleFullyPopulatedLoadbalancerCreationSuccessfully(t, fakeServer, PostFullyPopulatedLoadbalancerBody) - actual, err := loadbalancers.Create(context.TODO(), fake.ServiceClient(), loadbalancers.CreateOpts{ + actual, err := loadbalancers.Create(context.TODO(), fake.ServiceClient(fakeServer), loadbalancers.CreateOpts{ Name: "db_lb", AdminStateUp: gophercloud.Enabled, VipPortID: "2bf413c8-41a9-4477-b505-333d5cbe8b55", @@ -144,11 +144,11 @@ func TestCreateFullyPopulatedLoadbalancer(t *testing.T) { } func TestGetLoadbalancer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleLoadbalancerGetSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleLoadbalancerGetSuccessfully(t, fakeServer) - client := fake.ServiceClient() + client := fake.ServiceClient(fakeServer) actual, err := loadbalancers.Get(context.TODO(), client, "36e08a3e-a78f-4b40-a229-1e7e23eee1ab").Extract() if err != nil { t.Fatalf("Unexpected Get error: %v", err) @@ -158,11 +158,11 @@ func TestGetLoadbalancer(t *testing.T) { } func TestGetLoadbalancerStatusesTree(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleLoadbalancerGetStatusesTree(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleLoadbalancerGetStatusesTree(t, fakeServer) - client := fake.ServiceClient() + client := fake.ServiceClient(fakeServer) actual, err := loadbalancers.GetStatuses(context.TODO(), client, "36e08a3e-a78f-4b40-a229-1e7e23eee1ab").Extract() if err != nil { t.Fatalf("Unexpected Get error: %v", err) @@ -172,20 +172,20 @@ func TestGetLoadbalancerStatusesTree(t *testing.T) { } func TestDeleteLoadbalancer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleLoadbalancerDeletionSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleLoadbalancerDeletionSuccessfully(t, fakeServer) - res := loadbalancers.Delete(context.TODO(), fake.ServiceClient(), "36e08a3e-a78f-4b40-a229-1e7e23eee1ab", nil) + res := loadbalancers.Delete(context.TODO(), fake.ServiceClient(fakeServer), "36e08a3e-a78f-4b40-a229-1e7e23eee1ab", nil) th.AssertNoErr(t, res.Err) } func TestUpdateLoadbalancer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleLoadbalancerUpdateSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleLoadbalancerUpdateSuccessfully(t, fakeServer) - client := fake.ServiceClient() + client := fake.ServiceClient(fakeServer) name := "NewLoadbalancerName" tags := []string{"test"} actual, err := loadbalancers.Update(context.TODO(), client, "36e08a3e-a78f-4b40-a229-1e7e23eee1ab", loadbalancers.UpdateOpts{ @@ -200,11 +200,11 @@ func TestUpdateLoadbalancer(t *testing.T) { } func TestCascadingDeleteLoadbalancer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleLoadbalancerDeletionSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleLoadbalancerDeletionSuccessfully(t, fakeServer) - sc := fake.ServiceClient() + sc := fake.ServiceClient(fakeServer) deleteOpts := loadbalancers.DeleteOpts{ Cascade: true, } @@ -218,11 +218,11 @@ func TestCascadingDeleteLoadbalancer(t *testing.T) { } func TestGetLoadbalancerStatsTree(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleLoadbalancerGetStatsTree(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleLoadbalancerGetStatsTree(t, fakeServer) - client := fake.ServiceClient() + client := fake.ServiceClient(fakeServer) actual, err := loadbalancers.GetStats(context.TODO(), client, "36e08a3e-a78f-4b40-a229-1e7e23eee1ab").Extract() if err != nil { t.Fatalf("Unexpected Get error: %v", err) @@ -232,10 +232,10 @@ func TestGetLoadbalancerStatsTree(t *testing.T) { } func TestFailoverLoadbalancer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleLoadbalancerFailoverSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleLoadbalancerFailoverSuccessfully(t, fakeServer) - res := loadbalancers.Failover(context.TODO(), fake.ServiceClient(), "36e08a3e-a78f-4b40-a229-1e7e23eee1ab") + res := loadbalancers.Failover(context.TODO(), fake.ServiceClient(fakeServer), "36e08a3e-a78f-4b40-a229-1e7e23eee1ab") th.AssertNoErr(t, res.Err) } diff --git a/openstack/loadbalancer/v2/monitors/testing/fixtures_test.go b/openstack/loadbalancer/v2/monitors/testing/fixtures_test.go index b56d44dbe6..039da6708e 100644 --- a/openstack/loadbalancer/v2/monitors/testing/fixtures_test.go +++ b/openstack/loadbalancer/v2/monitors/testing/fixtures_test.go @@ -150,8 +150,8 @@ var ( ) // HandleHealthmonitorListSuccessfully sets up the test server to respond to a healthmonitor List request. -func HandleHealthmonitorListSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v2.0/lbaas/healthmonitors", func(w http.ResponseWriter, r *http.Request) { +func HandleHealthmonitorListSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/lbaas/healthmonitors", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -173,8 +173,8 @@ func HandleHealthmonitorListSuccessfully(t *testing.T) { // HandleHealthmonitorCreationSuccessfully sets up the test server to respond to a healthmonitor creation request // with a given response. -func HandleHealthmonitorCreationSuccessfully(t *testing.T, response string) { - th.Mux.HandleFunc("/v2.0/lbaas/healthmonitors", func(w http.ResponseWriter, r *http.Request) { +func HandleHealthmonitorCreationSuccessfully(t *testing.T, fakeServer th.FakeServer, response string) { + fakeServer.Mux.HandleFunc("/v2.0/lbaas/healthmonitors", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, `{ @@ -201,8 +201,8 @@ func HandleHealthmonitorCreationSuccessfully(t *testing.T, response string) { } // HandleHealthmonitorGetSuccessfully sets up the test server to respond to a healthmonitor Get request. -func HandleHealthmonitorGetSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v2.0/lbaas/healthmonitors/5d4b5228-33b0-4e60-b225-9b727c1a20e7", func(w http.ResponseWriter, r *http.Request) { +func HandleHealthmonitorGetSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/lbaas/healthmonitors/5d4b5228-33b0-4e60-b225-9b727c1a20e7", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -212,8 +212,8 @@ func HandleHealthmonitorGetSuccessfully(t *testing.T) { } // HandleHealthmonitorDeletionSuccessfully sets up the test server to respond to a healthmonitor deletion request. -func HandleHealthmonitorDeletionSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v2.0/lbaas/healthmonitors/5d4b5228-33b0-4e60-b225-9b727c1a20e7", func(w http.ResponseWriter, r *http.Request) { +func HandleHealthmonitorDeletionSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/lbaas/healthmonitors/5d4b5228-33b0-4e60-b225-9b727c1a20e7", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -222,8 +222,8 @@ func HandleHealthmonitorDeletionSuccessfully(t *testing.T) { } // HandleHealthmonitorUpdateSuccessfully sets up the test server to respond to a healthmonitor Update request. -func HandleHealthmonitorUpdateSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v2.0/lbaas/healthmonitors/5d4b5228-33b0-4e60-b225-9b727c1a20e7", func(w http.ResponseWriter, r *http.Request) { +func HandleHealthmonitorUpdateSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/lbaas/healthmonitors/5d4b5228-33b0-4e60-b225-9b727c1a20e7", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") diff --git a/openstack/loadbalancer/v2/monitors/testing/requests_test.go b/openstack/loadbalancer/v2/monitors/testing/requests_test.go index 952b7fef03..25f2c96c53 100644 --- a/openstack/loadbalancer/v2/monitors/testing/requests_test.go +++ b/openstack/loadbalancer/v2/monitors/testing/requests_test.go @@ -11,12 +11,12 @@ import ( ) func TestListHealthmonitors(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleHealthmonitorListSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleHealthmonitorListSuccessfully(t, fakeServer) pages := 0 - err := monitors.List(fake.ServiceClient(), monitors.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := monitors.List(fake.ServiceClient(fakeServer), monitors.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := monitors.ExtractMonitors(page) @@ -41,11 +41,11 @@ func TestListHealthmonitors(t *testing.T) { } func TestListAllHealthmonitors(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleHealthmonitorListSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleHealthmonitorListSuccessfully(t, fakeServer) - allPages, err := monitors.List(fake.ServiceClient(), monitors.ListOpts{}).AllPages(context.TODO()) + allPages, err := monitors.List(fake.ServiceClient(fakeServer), monitors.ListOpts{}).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := monitors.ExtractMonitors(allPages) th.AssertNoErr(t, err) @@ -54,11 +54,11 @@ func TestListAllHealthmonitors(t *testing.T) { } func TestCreateHealthmonitor(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleHealthmonitorCreationSuccessfully(t, SingleHealthmonitorBody) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleHealthmonitorCreationSuccessfully(t, fakeServer, SingleHealthmonitorBody) - actual, err := monitors.Create(context.TODO(), fake.ServiceClient(), monitors.CreateOpts{ + actual, err := monitors.Create(context.TODO(), fake.ServiceClient(fakeServer), monitors.CreateOpts{ Type: "HTTP", DomainName: "www.example.com", Name: "db", @@ -79,25 +79,25 @@ func TestCreateHealthmonitor(t *testing.T) { } func TestRequiredCreateOpts(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - res := monitors.Create(context.TODO(), fake.ServiceClient(), monitors.CreateOpts{}) + res := monitors.Create(context.TODO(), fake.ServiceClient(fakeServer), monitors.CreateOpts{}) if res.Err == nil { t.Fatalf("Expected error, got none") } - res = monitors.Create(context.TODO(), fake.ServiceClient(), monitors.CreateOpts{Type: monitors.TypeHTTP}) + res = monitors.Create(context.TODO(), fake.ServiceClient(fakeServer), monitors.CreateOpts{Type: monitors.TypeHTTP}) if res.Err == nil { t.Fatalf("Expected error, got none") } } func TestGetHealthmonitor(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleHealthmonitorGetSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleHealthmonitorGetSuccessfully(t, fakeServer) - client := fake.ServiceClient() + client := fake.ServiceClient(fakeServer) actual, err := monitors.Get(context.TODO(), client, "5d4b5228-33b0-4e60-b225-9b727c1a20e7").Extract() if err != nil { t.Fatalf("Unexpected Get error: %v", err) @@ -107,20 +107,20 @@ func TestGetHealthmonitor(t *testing.T) { } func TestDeleteHealthmonitor(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleHealthmonitorDeletionSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleHealthmonitorDeletionSuccessfully(t, fakeServer) - res := monitors.Delete(context.TODO(), fake.ServiceClient(), "5d4b5228-33b0-4e60-b225-9b727c1a20e7") + res := monitors.Delete(context.TODO(), fake.ServiceClient(fakeServer), "5d4b5228-33b0-4e60-b225-9b727c1a20e7") th.AssertNoErr(t, res.Err) } func TestUpdateHealthmonitor(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleHealthmonitorUpdateSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleHealthmonitorUpdateSuccessfully(t, fakeServer) - client := fake.ServiceClient() + client := fake.ServiceClient(fakeServer) name := "NewHealthmonitorName" actual, err := monitors.Update(context.TODO(), client, "5d4b5228-33b0-4e60-b225-9b727c1a20e7", monitors.UpdateOpts{ Name: &name, @@ -139,10 +139,10 @@ func TestUpdateHealthmonitor(t *testing.T) { } func TestDelayMustBeGreaterOrEqualThanTimeout(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - _, err := monitors.Create(context.TODO(), fake.ServiceClient(), monitors.CreateOpts{ + _, err := monitors.Create(context.TODO(), fake.ServiceClient(fakeServer), monitors.CreateOpts{ Type: "HTTP", PoolID: "d459f7d8-c6ee-439d-8713-d3fc08aeed8d", Delay: 1, @@ -156,7 +156,7 @@ func TestDelayMustBeGreaterOrEqualThanTimeout(t *testing.T) { t.Fatalf("Expected error, got none") } - _, err = monitors.Update(context.TODO(), fake.ServiceClient(), "453105b9-1754-413f-aab1-55f1af620750", monitors.UpdateOpts{ + _, err = monitors.Update(context.TODO(), fake.ServiceClient(fakeServer), "453105b9-1754-413f-aab1-55f1af620750", monitors.UpdateOpts{ Delay: 1, Timeout: 10, }).Extract() diff --git a/openstack/loadbalancer/v2/pools/testing/fixtures_test.go b/openstack/loadbalancer/v2/pools/testing/fixtures_test.go index bcc582a638..a2073952bb 100644 --- a/openstack/loadbalancer/v2/pools/testing/fixtures_test.go +++ b/openstack/loadbalancer/v2/pools/testing/fixtures_test.go @@ -133,8 +133,8 @@ var ( ) // HandlePoolListSuccessfully sets up the test server to respond to a pool List request. -func HandlePoolListSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v2.0/lbaas/pools", func(w http.ResponseWriter, r *http.Request) { +func HandlePoolListSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/lbaas/pools", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -156,8 +156,8 @@ func HandlePoolListSuccessfully(t *testing.T) { // HandlePoolCreationSuccessfully sets up the test server to respond to a pool creation request // with a given response. -func HandlePoolCreationSuccessfully(t *testing.T, response string) { - th.Mux.HandleFunc("/v2.0/lbaas/pools", func(w http.ResponseWriter, r *http.Request) { +func HandlePoolCreationSuccessfully(t *testing.T, fakeServer th.FakeServer, response string) { + fakeServer.Mux.HandleFunc("/v2.0/lbaas/pools", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, `{ @@ -177,8 +177,8 @@ func HandlePoolCreationSuccessfully(t *testing.T, response string) { } // HandlePoolGetSuccessfully sets up the test server to respond to a pool Get request. -func HandlePoolGetSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v2.0/lbaas/pools/c3741b06-df4d-4715-b142-276b6bce75ab", func(w http.ResponseWriter, r *http.Request) { +func HandlePoolGetSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/lbaas/pools/c3741b06-df4d-4715-b142-276b6bce75ab", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -188,8 +188,8 @@ func HandlePoolGetSuccessfully(t *testing.T) { } // HandlePoolDeletionSuccessfully sets up the test server to respond to a pool deletion request. -func HandlePoolDeletionSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v2.0/lbaas/pools/c3741b06-df4d-4715-b142-276b6bce75ab", func(w http.ResponseWriter, r *http.Request) { +func HandlePoolDeletionSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/lbaas/pools/c3741b06-df4d-4715-b142-276b6bce75ab", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -198,8 +198,8 @@ func HandlePoolDeletionSuccessfully(t *testing.T) { } // HandlePoolUpdateSuccessfully sets up the test server to respond to a pool Update request. -func HandlePoolUpdateSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v2.0/lbaas/pools/c3741b06-df4d-4715-b142-276b6bce75ab", func(w http.ResponseWriter, r *http.Request) { +func HandlePoolUpdateSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/lbaas/pools/c3741b06-df4d-4715-b142-276b6bce75ab", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -330,8 +330,8 @@ var ( ) // HandleMemberListSuccessfully sets up the test server to respond to a member List request. -func HandleMemberListSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v2.0/lbaas/pools/332abe93-f488-41ba-870b-2ac66be7f853/members", func(w http.ResponseWriter, r *http.Request) { +func HandleMemberListSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/lbaas/pools/332abe93-f488-41ba-870b-2ac66be7f853/members", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -353,8 +353,8 @@ func HandleMemberListSuccessfully(t *testing.T) { // HandleMemberCreationSuccessfully sets up the test server to respond to a member creation request // with a given response. -func HandleMemberCreationSuccessfully(t *testing.T, response string) { - th.Mux.HandleFunc("/v2.0/lbaas/pools/332abe93-f488-41ba-870b-2ac66be7f853/members", func(w http.ResponseWriter, r *http.Request) { +func HandleMemberCreationSuccessfully(t *testing.T, fakeServer th.FakeServer, response string) { + fakeServer.Mux.HandleFunc("/v2.0/lbaas/pools/332abe93-f488-41ba-870b-2ac66be7f853/members", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, `{ @@ -375,8 +375,8 @@ func HandleMemberCreationSuccessfully(t *testing.T, response string) { } // HandleMemberGetSuccessfully sets up the test server to respond to a member Get request. -func HandleMemberGetSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v2.0/lbaas/pools/332abe93-f488-41ba-870b-2ac66be7f853/members/2a280670-c202-4b0b-a562-34077415aabf", func(w http.ResponseWriter, r *http.Request) { +func HandleMemberGetSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/lbaas/pools/332abe93-f488-41ba-870b-2ac66be7f853/members/2a280670-c202-4b0b-a562-34077415aabf", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -386,8 +386,8 @@ func HandleMemberGetSuccessfully(t *testing.T) { } // HandleMemberDeletionSuccessfully sets up the test server to respond to a member deletion request. -func HandleMemberDeletionSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v2.0/lbaas/pools/332abe93-f488-41ba-870b-2ac66be7f853/members/2a280670-c202-4b0b-a562-34077415aabf", func(w http.ResponseWriter, r *http.Request) { +func HandleMemberDeletionSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/lbaas/pools/332abe93-f488-41ba-870b-2ac66be7f853/members/2a280670-c202-4b0b-a562-34077415aabf", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -396,8 +396,8 @@ func HandleMemberDeletionSuccessfully(t *testing.T) { } // HandleMemberUpdateSuccessfully sets up the test server to respond to a member Update request. -func HandleMemberUpdateSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v2.0/lbaas/pools/332abe93-f488-41ba-870b-2ac66be7f853/members/2a280670-c202-4b0b-a562-34077415aabf", func(w http.ResponseWriter, r *http.Request) { +func HandleMemberUpdateSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/lbaas/pools/332abe93-f488-41ba-870b-2ac66be7f853/members/2a280670-c202-4b0b-a562-34077415aabf", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -414,8 +414,8 @@ func HandleMemberUpdateSuccessfully(t *testing.T) { } // HandleMembersUpdateSuccessfully sets up the test server to respond to a batch member Update request. -func HandleMembersUpdateSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v2.0/lbaas/pools/332abe93-f488-41ba-870b-2ac66be7f853/members", func(w http.ResponseWriter, r *http.Request) { +func HandleMembersUpdateSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/lbaas/pools/332abe93-f488-41ba-870b-2ac66be7f853/members", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -444,8 +444,8 @@ func HandleMembersUpdateSuccessfully(t *testing.T) { } // HandleEmptyMembersUpdateSuccessfully sets up the test server to respond to an empty batch member Update request. -func HandleEmptyMembersUpdateSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v2.0/lbaas/pools/332abe93-f488-41ba-870b-2ac66be7f853/members", func(w http.ResponseWriter, r *http.Request) { +func HandleEmptyMembersUpdateSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/lbaas/pools/332abe93-f488-41ba-870b-2ac66be7f853/members", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") diff --git a/openstack/loadbalancer/v2/pools/testing/requests_test.go b/openstack/loadbalancer/v2/pools/testing/requests_test.go index fe40e09471..17ae976617 100644 --- a/openstack/loadbalancer/v2/pools/testing/requests_test.go +++ b/openstack/loadbalancer/v2/pools/testing/requests_test.go @@ -11,12 +11,12 @@ import ( ) func TestListPools(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandlePoolListSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandlePoolListSuccessfully(t, fakeServer) pages := 0 - err := pools.List(fake.ServiceClient(), pools.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := pools.List(fake.ServiceClient(fakeServer), pools.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := pools.ExtractPools(page) @@ -41,11 +41,11 @@ func TestListPools(t *testing.T) { } func TestListAllPools(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandlePoolListSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandlePoolListSuccessfully(t, fakeServer) - allPages, err := pools.List(fake.ServiceClient(), pools.ListOpts{}).AllPages(context.TODO()) + allPages, err := pools.List(fake.ServiceClient(fakeServer), pools.ListOpts{}).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := pools.ExtractPools(allPages) th.AssertNoErr(t, err) @@ -54,11 +54,11 @@ func TestListAllPools(t *testing.T) { } func TestCreatePool(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandlePoolCreationSuccessfully(t, SinglePoolBody) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandlePoolCreationSuccessfully(t, fakeServer, SinglePoolBody) - actual, err := pools.Create(context.TODO(), fake.ServiceClient(), pools.CreateOpts{ + actual, err := pools.Create(context.TODO(), fake.ServiceClient(fakeServer), pools.CreateOpts{ LBMethod: pools.LBMethodRoundRobin, Protocol: "HTTP", Name: "Example pool", @@ -71,11 +71,11 @@ func TestCreatePool(t *testing.T) { } func TestGetPool(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandlePoolGetSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandlePoolGetSuccessfully(t, fakeServer) - client := fake.ServiceClient() + client := fake.ServiceClient(fakeServer) actual, err := pools.Get(context.TODO(), client, "c3741b06-df4d-4715-b142-276b6bce75ab").Extract() if err != nil { t.Fatalf("Unexpected Get error: %v", err) @@ -85,20 +85,20 @@ func TestGetPool(t *testing.T) { } func TestDeletePool(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandlePoolDeletionSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandlePoolDeletionSuccessfully(t, fakeServer) - res := pools.Delete(context.TODO(), fake.ServiceClient(), "c3741b06-df4d-4715-b142-276b6bce75ab") + res := pools.Delete(context.TODO(), fake.ServiceClient(fakeServer), "c3741b06-df4d-4715-b142-276b6bce75ab") th.AssertNoErr(t, res.Err) } func TestUpdatePool(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandlePoolUpdateSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandlePoolUpdateSuccessfully(t, fakeServer) - client := fake.ServiceClient() + client := fake.ServiceClient(fakeServer) name := "NewPoolName" actual, err := pools.Update(context.TODO(), client, "c3741b06-df4d-4715-b142-276b6bce75ab", pools.UpdateOpts{ Name: &name, @@ -112,14 +112,14 @@ func TestUpdatePool(t *testing.T) { } func TestRequiredPoolCreateOpts(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - res := pools.Create(context.TODO(), fake.ServiceClient(), pools.CreateOpts{}) + res := pools.Create(context.TODO(), fake.ServiceClient(fakeServer), pools.CreateOpts{}) if res.Err == nil { t.Fatalf("Expected error, got none") } - res = pools.Create(context.TODO(), fake.ServiceClient(), pools.CreateOpts{ + res = pools.Create(context.TODO(), fake.ServiceClient(fakeServer), pools.CreateOpts{ LBMethod: pools.LBMethod("invalid"), Protocol: pools.ProtocolHTTPS, LoadbalancerID: "69055154-f603-4a28-8951-7cc2d9e54a9a", @@ -128,7 +128,7 @@ func TestRequiredPoolCreateOpts(t *testing.T) { t.Fatalf("Expected error, but got none") } - res = pools.Create(context.TODO(), fake.ServiceClient(), pools.CreateOpts{ + res = pools.Create(context.TODO(), fake.ServiceClient(fakeServer), pools.CreateOpts{ LBMethod: pools.LBMethodRoundRobin, Protocol: pools.Protocol("invalid"), LoadbalancerID: "69055154-f603-4a28-8951-7cc2d9e54a9a", @@ -137,7 +137,7 @@ func TestRequiredPoolCreateOpts(t *testing.T) { t.Fatalf("Expected error, but got none") } - res = pools.Create(context.TODO(), fake.ServiceClient(), pools.CreateOpts{ + res = pools.Create(context.TODO(), fake.ServiceClient(fakeServer), pools.CreateOpts{ LBMethod: pools.LBMethodRoundRobin, Protocol: pools.ProtocolHTTPS, }) @@ -147,12 +147,12 @@ func TestRequiredPoolCreateOpts(t *testing.T) { } func TestListMembers(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleMemberListSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleMemberListSuccessfully(t, fakeServer) pages := 0 - err := pools.ListMembers(fake.ServiceClient(), "332abe93-f488-41ba-870b-2ac66be7f853", pools.ListMembersOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := pools.ListMembers(fake.ServiceClient(fakeServer), "332abe93-f488-41ba-870b-2ac66be7f853", pools.ListMembersOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := pools.ExtractMembers(page) @@ -177,11 +177,11 @@ func TestListMembers(t *testing.T) { } func TestListAllMembers(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleMemberListSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleMemberListSuccessfully(t, fakeServer) - allPages, err := pools.ListMembers(fake.ServiceClient(), "332abe93-f488-41ba-870b-2ac66be7f853", pools.ListMembersOpts{}).AllPages(context.TODO()) + allPages, err := pools.ListMembers(fake.ServiceClient(fakeServer), "332abe93-f488-41ba-870b-2ac66be7f853", pools.ListMembersOpts{}).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := pools.ExtractMembers(allPages) th.AssertNoErr(t, err) @@ -190,12 +190,12 @@ func TestListAllMembers(t *testing.T) { } func TestCreateMember(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleMemberCreationSuccessfully(t, SingleMemberBody) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleMemberCreationSuccessfully(t, fakeServer, SingleMemberBody) weight := 10 - actual, err := pools.CreateMember(context.TODO(), fake.ServiceClient(), "332abe93-f488-41ba-870b-2ac66be7f853", pools.CreateMemberOpts{ + actual, err := pools.CreateMember(context.TODO(), fake.ServiceClient(fakeServer), "332abe93-f488-41ba-870b-2ac66be7f853", pools.CreateMemberOpts{ Name: "db", SubnetID: "1981f108-3c48-48d2-b908-30f7d28532c9", ProjectID: "2ffc6e22aae24e4795f87155d24c896f", @@ -209,33 +209,33 @@ func TestCreateMember(t *testing.T) { } func TestRequiredMemberCreateOpts(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - res := pools.CreateMember(context.TODO(), fake.ServiceClient(), "", pools.CreateMemberOpts{}) + res := pools.CreateMember(context.TODO(), fake.ServiceClient(fakeServer), "", pools.CreateMemberOpts{}) if res.Err == nil { t.Fatalf("Expected error, got none") } - res = pools.CreateMember(context.TODO(), fake.ServiceClient(), "", pools.CreateMemberOpts{Address: "1.2.3.4", ProtocolPort: 80}) + res = pools.CreateMember(context.TODO(), fake.ServiceClient(fakeServer), "", pools.CreateMemberOpts{Address: "1.2.3.4", ProtocolPort: 80}) if res.Err == nil { t.Fatalf("Expected error, but got none") } - res = pools.CreateMember(context.TODO(), fake.ServiceClient(), "332abe93-f488-41ba-870b-2ac66be7f853", pools.CreateMemberOpts{ProtocolPort: 80}) + res = pools.CreateMember(context.TODO(), fake.ServiceClient(fakeServer), "332abe93-f488-41ba-870b-2ac66be7f853", pools.CreateMemberOpts{ProtocolPort: 80}) if res.Err == nil { t.Fatalf("Expected error, but got none") } - res = pools.CreateMember(context.TODO(), fake.ServiceClient(), "332abe93-f488-41ba-870b-2ac66be7f853", pools.CreateMemberOpts{Address: "1.2.3.4"}) + res = pools.CreateMember(context.TODO(), fake.ServiceClient(fakeServer), "332abe93-f488-41ba-870b-2ac66be7f853", pools.CreateMemberOpts{Address: "1.2.3.4"}) if res.Err == nil { t.Fatalf("Expected error, but got none") } } func TestGetMember(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleMemberGetSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleMemberGetSuccessfully(t, fakeServer) - client := fake.ServiceClient() + client := fake.ServiceClient(fakeServer) actual, err := pools.GetMember(context.TODO(), client, "332abe93-f488-41ba-870b-2ac66be7f853", "2a280670-c202-4b0b-a562-34077415aabf").Extract() if err != nil { t.Fatalf("Unexpected Get error: %v", err) @@ -245,21 +245,21 @@ func TestGetMember(t *testing.T) { } func TestDeleteMember(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleMemberDeletionSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleMemberDeletionSuccessfully(t, fakeServer) - res := pools.DeleteMember(context.TODO(), fake.ServiceClient(), "332abe93-f488-41ba-870b-2ac66be7f853", "2a280670-c202-4b0b-a562-34077415aabf") + res := pools.DeleteMember(context.TODO(), fake.ServiceClient(fakeServer), "332abe93-f488-41ba-870b-2ac66be7f853", "2a280670-c202-4b0b-a562-34077415aabf") th.AssertNoErr(t, res.Err) } func TestUpdateMember(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleMemberUpdateSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleMemberUpdateSuccessfully(t, fakeServer) weight := 4 - client := fake.ServiceClient() + client := fake.ServiceClient(fakeServer) name := "newMemberName" actual, err := pools.UpdateMember(context.TODO(), client, "332abe93-f488-41ba-870b-2ac66be7f853", "2a280670-c202-4b0b-a562-34077415aabf", pools.UpdateMemberOpts{ Name: &name, @@ -273,9 +273,9 @@ func TestUpdateMember(t *testing.T) { } func TestBatchUpdateMembers(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleMembersUpdateSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleMembersUpdateSuccessfully(t, fakeServer) name_1 := "web-server-1" weight_1 := 20 @@ -299,25 +299,25 @@ func TestBatchUpdateMembers(t *testing.T) { } members := []pools.BatchUpdateMemberOpts{member1, member2} - res := pools.BatchUpdateMembers(context.TODO(), fake.ServiceClient(), "332abe93-f488-41ba-870b-2ac66be7f853", members) + res := pools.BatchUpdateMembers(context.TODO(), fake.ServiceClient(fakeServer), "332abe93-f488-41ba-870b-2ac66be7f853", members) th.AssertNoErr(t, res.Err) } func TestEmptyBatchUpdateMembers(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleEmptyMembersUpdateSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleEmptyMembersUpdateSuccessfully(t, fakeServer) - res := pools.BatchUpdateMembers(context.TODO(), fake.ServiceClient(), "332abe93-f488-41ba-870b-2ac66be7f853", []pools.BatchUpdateMemberOpts{}) + res := pools.BatchUpdateMembers(context.TODO(), fake.ServiceClient(fakeServer), "332abe93-f488-41ba-870b-2ac66be7f853", []pools.BatchUpdateMemberOpts{}) th.AssertNoErr(t, res.Err) } func TestRequiredBatchUpdateMemberOpts(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() name := "web-server-1" - res := pools.BatchUpdateMembers(context.TODO(), fake.ServiceClient(), "332abe93-f488-41ba-870b-2ac66be7f853", []pools.BatchUpdateMemberOpts{ + res := pools.BatchUpdateMembers(context.TODO(), fake.ServiceClient(fakeServer), "332abe93-f488-41ba-870b-2ac66be7f853", []pools.BatchUpdateMemberOpts{ { Name: &name, }, @@ -326,7 +326,7 @@ func TestRequiredBatchUpdateMemberOpts(t *testing.T) { t.Fatalf("Expected error, but got none") } - res = pools.BatchUpdateMembers(context.TODO(), fake.ServiceClient(), "332abe93-f488-41ba-870b-2ac66be7f853", []pools.BatchUpdateMemberOpts{ + res = pools.BatchUpdateMembers(context.TODO(), fake.ServiceClient(fakeServer), "332abe93-f488-41ba-870b-2ac66be7f853", []pools.BatchUpdateMemberOpts{ { Address: "192.0.2.17", Name: &name, @@ -336,7 +336,7 @@ func TestRequiredBatchUpdateMemberOpts(t *testing.T) { t.Fatalf("Expected error, but got none") } - res = pools.BatchUpdateMembers(context.TODO(), fake.ServiceClient(), "332abe93-f488-41ba-870b-2ac66be7f853", []pools.BatchUpdateMemberOpts{ + res = pools.BatchUpdateMembers(context.TODO(), fake.ServiceClient(fakeServer), "332abe93-f488-41ba-870b-2ac66be7f853", []pools.BatchUpdateMemberOpts{ { ProtocolPort: 80, Name: &name, diff --git a/openstack/loadbalancer/v2/providers/testing/fixtures_test.go b/openstack/loadbalancer/v2/providers/testing/fixtures_test.go index b8a857e618..78c9f7a101 100644 --- a/openstack/loadbalancer/v2/providers/testing/fixtures_test.go +++ b/openstack/loadbalancer/v2/providers/testing/fixtures_test.go @@ -38,8 +38,8 @@ var ( ) // HandleProviderListSuccessfully sets up the test server to respond to a provider List request. -func HandleProviderListSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v2.0/lbaas/providers", func(w http.ResponseWriter, r *http.Request) { +func HandleProviderListSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/lbaas/providers", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/loadbalancer/v2/providers/testing/requests_test.go b/openstack/loadbalancer/v2/providers/testing/requests_test.go index c5a5278aae..6046cde034 100644 --- a/openstack/loadbalancer/v2/providers/testing/requests_test.go +++ b/openstack/loadbalancer/v2/providers/testing/requests_test.go @@ -11,12 +11,12 @@ import ( ) func TestListProviders(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleProviderListSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleProviderListSuccessfully(t, fakeServer) pages := 0 - err := providers.List(fake.ServiceClient(), providers.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := providers.List(fake.ServiceClient(fakeServer), providers.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := providers.ExtractProviders(page) @@ -41,11 +41,11 @@ func TestListProviders(t *testing.T) { } func TestListAllProviders(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleProviderListSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleProviderListSuccessfully(t, fakeServer) - allPages, err := providers.List(fake.ServiceClient(), providers.ListOpts{}).AllPages(context.TODO()) + allPages, err := providers.List(fake.ServiceClient(fakeServer), providers.ListOpts{}).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := providers.ExtractProviders(allPages) th.AssertNoErr(t, err) diff --git a/openstack/loadbalancer/v2/quotas/testing/requests_test.go b/openstack/loadbalancer/v2/quotas/testing/requests_test.go index 6f990428fc..ccf8e51f35 100644 --- a/openstack/loadbalancer/v2/quotas/testing/requests_test.go +++ b/openstack/loadbalancer/v2/quotas/testing/requests_test.go @@ -13,10 +13,10 @@ import ( ) func TestGet_1(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/quotas/0a73845280574ad389c292f6a74afa76", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/quotas/0a73845280574ad389c292f6a74afa76", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -26,16 +26,16 @@ func TestGet_1(t *testing.T) { fmt.Fprint(w, GetResponseRaw_1) }) - q, err := quotas.Get(context.TODO(), fake.ServiceClient(), "0a73845280574ad389c292f6a74afa76").Extract() + q, err := quotas.Get(context.TODO(), fake.ServiceClient(fakeServer), "0a73845280574ad389c292f6a74afa76").Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, q, &GetResponse) } func TestGet_2(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/quotas/0a73845280574ad389c292f6a74afa76", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/quotas/0a73845280574ad389c292f6a74afa76", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -45,16 +45,16 @@ func TestGet_2(t *testing.T) { fmt.Fprint(w, GetResponseRaw_2) }) - q, err := quotas.Get(context.TODO(), fake.ServiceClient(), "0a73845280574ad389c292f6a74afa76").Extract() + q, err := quotas.Get(context.TODO(), fake.ServiceClient(fakeServer), "0a73845280574ad389c292f6a74afa76").Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, q, &GetResponse) } func TestUpdate_1(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/quotas/0a73845280574ad389c292f6a74afa76", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/quotas/0a73845280574ad389c292f6a74afa76", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -64,7 +64,7 @@ func TestUpdate_1(t *testing.T) { fmt.Fprint(w, UpdateRequestResponseRaw_1) }) - q, err := quotas.Update(context.TODO(), fake.ServiceClient(), "0a73845280574ad389c292f6a74afa76", quotas.UpdateOpts{ + q, err := quotas.Update(context.TODO(), fake.ServiceClient(fakeServer), "0a73845280574ad389c292f6a74afa76", quotas.UpdateOpts{ Loadbalancer: gophercloud.IntToPointer(20), Listener: gophercloud.IntToPointer(40), Member: gophercloud.IntToPointer(200), @@ -79,10 +79,10 @@ func TestUpdate_1(t *testing.T) { } func TestUpdate_2(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/quotas/0a73845280574ad389c292f6a74afa76", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/quotas/0a73845280574ad389c292f6a74afa76", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -92,7 +92,7 @@ func TestUpdate_2(t *testing.T) { fmt.Fprint(w, UpdateRequestResponseRaw_2) }) - q, err := quotas.Update(context.TODO(), fake.ServiceClient(), "0a73845280574ad389c292f6a74afa76", quotas.UpdateOpts{ + q, err := quotas.Update(context.TODO(), fake.ServiceClient(fakeServer), "0a73845280574ad389c292f6a74afa76", quotas.UpdateOpts{ Loadbalancer: gophercloud.IntToPointer(20), Listener: gophercloud.IntToPointer(40), Member: gophercloud.IntToPointer(200), diff --git a/openstack/loadbalancer/v2/testhelper/client.go b/openstack/loadbalancer/v2/testhelper/client.go index f32313a105..581c9803aa 100644 --- a/openstack/loadbalancer/v2/testhelper/client.go +++ b/openstack/loadbalancer/v2/testhelper/client.go @@ -2,13 +2,14 @@ package common import ( "github.com/gophercloud/gophercloud/v2" + th "github.com/gophercloud/gophercloud/v2/testhelper" "github.com/gophercloud/gophercloud/v2/testhelper/client" ) const TokenID = client.TokenID -func ServiceClient() *gophercloud.ServiceClient { - sc := client.ServiceClient() +func ServiceClient(fakeServer th.FakeServer) *gophercloud.ServiceClient { + sc := client.ServiceClient(fakeServer) sc.ResourceBase = sc.Endpoint + "v2.0/" return sc } diff --git a/openstack/messaging/v2/claims/testing/fixtures_test.go b/openstack/messaging/v2/claims/testing/fixtures_test.go index a90c7b392c..b8087d663c 100644 --- a/openstack/messaging/v2/claims/testing/fixtures_test.go +++ b/openstack/messaging/v2/claims/testing/fixtures_test.go @@ -84,8 +84,8 @@ var FirstClaim = claims.Claim{ } // HandleCreateSuccessfully configures the test server to respond to a Create request. -func HandleCreateSuccessfully(t *testing.T) { - th.Mux.HandleFunc(fmt.Sprintf("/v2/queues/%s/claims", QueueName), +func HandleCreateSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc(fmt.Sprintf("/v2/queues/%s/claims", QueueName), func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -98,8 +98,8 @@ func HandleCreateSuccessfully(t *testing.T) { } // HandleCreateNoContent configures the test server to respond to a Create request with no content. -func HandleCreateNoContent(t *testing.T) { - th.Mux.HandleFunc(fmt.Sprintf("/v2/queues/%s/claims", QueueName), +func HandleCreateNoContent(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc(fmt.Sprintf("/v2/queues/%s/claims", QueueName), func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -110,8 +110,8 @@ func HandleCreateNoContent(t *testing.T) { } // HandleGetSuccessfully configures the test server to respond to a Get request. -func HandleGetSuccessfully(t *testing.T) { - th.Mux.HandleFunc(fmt.Sprintf("/v2/queues/%s/claims/%s", QueueName, ClaimID), +func HandleGetSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc(fmt.Sprintf("/v2/queues/%s/claims/%s", QueueName, ClaimID), func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -122,8 +122,8 @@ func HandleGetSuccessfully(t *testing.T) { } // HandleUpdateSuccessfully configures the test server to respond to a Update request. -func HandleUpdateSuccessfully(t *testing.T) { - th.Mux.HandleFunc(fmt.Sprintf("/v2/queues/%s/claims/%s", QueueName, ClaimID), +func HandleUpdateSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc(fmt.Sprintf("/v2/queues/%s/claims/%s", QueueName, ClaimID), func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PATCH") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -134,8 +134,8 @@ func HandleUpdateSuccessfully(t *testing.T) { } // HandleDeleteSuccessfully configures the test server to respond to an Delete request. -func HandleDeleteSuccessfully(t *testing.T) { - th.Mux.HandleFunc(fmt.Sprintf("/v2/queues/%s/claims/%s", QueueName, ClaimID), +func HandleDeleteSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc(fmt.Sprintf("/v2/queues/%s/claims/%s", QueueName, ClaimID), func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/messaging/v2/claims/testing/requests_test.go b/openstack/messaging/v2/claims/testing/requests_test.go index 7f7a78a455..2a5bebd487 100644 --- a/openstack/messaging/v2/claims/testing/requests_test.go +++ b/openstack/messaging/v2/claims/testing/requests_test.go @@ -10,9 +10,9 @@ import ( ) func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCreateSuccessfully(t, fakeServer) createOpts := claims.CreateOpts{ TTL: 3600, @@ -20,15 +20,15 @@ func TestCreate(t *testing.T) { Limit: 10, } - actual, err := claims.Create(context.TODO(), client.ServiceClient(), QueueName, createOpts).Extract() + actual, err := claims.Create(context.TODO(), client.ServiceClient(fakeServer), QueueName, createOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, CreatedClaim, actual) } func TestCreateNoContent(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateNoContent(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCreateNoContent(t, fakeServer) createOpts := claims.CreateOpts{ TTL: 3600, @@ -36,41 +36,41 @@ func TestCreateNoContent(t *testing.T) { Limit: 10, } - actual, err := claims.Create(context.TODO(), client.ServiceClient(), QueueName, createOpts).Extract() + actual, err := claims.Create(context.TODO(), client.ServiceClient(fakeServer), QueueName, createOpts).Extract() th.AssertNoErr(t, err) var expected []claims.Messages th.CheckDeepEquals(t, expected, actual) } func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetSuccessfully(t, fakeServer) - actual, err := claims.Get(context.TODO(), client.ServiceClient(), QueueName, ClaimID).Extract() + actual, err := claims.Get(context.TODO(), client.ServiceClient(fakeServer), QueueName, ClaimID).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, &FirstClaim, actual) } func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleUpdateSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleUpdateSuccessfully(t, fakeServer) updateOpts := claims.UpdateOpts{ Grace: 1600, TTL: 1200, } - err := claims.Update(context.TODO(), client.ServiceClient(), QueueName, ClaimID, updateOpts).ExtractErr() + err := claims.Update(context.TODO(), client.ServiceClient(fakeServer), QueueName, ClaimID, updateOpts).ExtractErr() th.AssertNoErr(t, err) } func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDeleteSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDeleteSuccessfully(t, fakeServer) - err := claims.Delete(context.TODO(), client.ServiceClient(), QueueName, ClaimID).ExtractErr() + err := claims.Delete(context.TODO(), client.ServiceClient(fakeServer), QueueName, ClaimID).ExtractErr() th.AssertNoErr(t, err) } diff --git a/openstack/messaging/v2/messages/testing/fixtures_test.go b/openstack/messaging/v2/messages/testing/fixtures_test.go index ca28d7ce7a..b7f6d194a5 100644 --- a/openstack/messaging/v2/messages/testing/fixtures_test.go +++ b/openstack/messaging/v2/messages/testing/fixtures_test.go @@ -220,8 +220,8 @@ var ExpectedPopMessage = []messages.PopMessage{{ }} // HandleCreateSuccessfully configures the test server to respond to a Create request. -func HandleCreateSuccessfully(t *testing.T) { - th.Mux.HandleFunc(fmt.Sprintf("/v2/queues/%s/messages", QueueName), +func HandleCreateSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc(fmt.Sprintf("/v2/queues/%s/messages", QueueName), func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -234,8 +234,8 @@ func HandleCreateSuccessfully(t *testing.T) { } // HandleListSuccessfully configures the test server to respond to a List request. -func HandleListSuccessfully(t *testing.T) { - th.Mux.HandleFunc(fmt.Sprintf("/v2/queues/%s/messages", QueueName), +func HandleListSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc(fmt.Sprintf("/v2/queues/%s/messages", QueueName), func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -255,8 +255,8 @@ func HandleListSuccessfully(t *testing.T) { } // HandleGetMessagesSuccessfully configures the test server to respond to a GetMessages request. -func HandleGetMessagesSuccessfully(t *testing.T) { - th.Mux.HandleFunc(fmt.Sprintf("/v2/queues/%s/messages", QueueName), +func HandleGetMessagesSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc(fmt.Sprintf("/v2/queues/%s/messages", QueueName), func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -267,8 +267,8 @@ func HandleGetMessagesSuccessfully(t *testing.T) { } // HandleGetSuccessfully configures the test server to respond to a Get request. -func HandleGetSuccessfully(t *testing.T) { - th.Mux.HandleFunc(fmt.Sprintf("/v2/queues/%s/messages/%s", QueueName, MessageID), +func HandleGetSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc(fmt.Sprintf("/v2/queues/%s/messages/%s", QueueName, MessageID), func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -279,8 +279,8 @@ func HandleGetSuccessfully(t *testing.T) { } // HandleDeleteMessagesSuccessfully configures the test server to respond to a Delete request. -func HandleDeleteMessagesSuccessfully(t *testing.T) { - th.Mux.HandleFunc(fmt.Sprintf("/v2/queues/%s/messages", QueueName), +func HandleDeleteMessagesSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc(fmt.Sprintf("/v2/queues/%s/messages", QueueName), func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -291,8 +291,8 @@ func HandleDeleteMessagesSuccessfully(t *testing.T) { } // HandlePopSuccessfully configures the test server to respond to a Pop request. -func HandlePopSuccessfully(t *testing.T) { - th.Mux.HandleFunc(fmt.Sprintf("/v2/queues/%s/messages", QueueName), +func HandlePopSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc(fmt.Sprintf("/v2/queues/%s/messages", QueueName), func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -304,8 +304,8 @@ func HandlePopSuccessfully(t *testing.T) { } // HandleGetSuccessfully configures the test server to respond to a Get request. -func HandleDeleteSuccessfully(t *testing.T) { - th.Mux.HandleFunc(fmt.Sprintf("/v2/queues/%s/messages/%s", QueueName, MessageID), +func HandleDeleteSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc(fmt.Sprintf("/v2/queues/%s/messages/%s", QueueName, MessageID), func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/messaging/v2/messages/testing/requests_test.go b/openstack/messaging/v2/messages/testing/requests_test.go index 9d31d5812f..cd09f1b486 100644 --- a/openstack/messaging/v2/messages/testing/requests_test.go +++ b/openstack/messaging/v2/messages/testing/requests_test.go @@ -11,16 +11,16 @@ import ( ) func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListSuccessfully(t, fakeServer) listOpts := messages.ListOpts{ Limit: 1, } count := 0 - err := messages.List(client.ServiceClient(), QueueName, listOpts).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := messages.List(client.ServiceClient(fakeServer), QueueName, listOpts).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { actual, err := messages.ExtractMessages(page) th.AssertNoErr(t, err) @@ -35,9 +35,9 @@ func TestList(t *testing.T) { } func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCreateSuccessfully(t, fakeServer) createOpts := messages.BatchCreateOpts{ messages.CreateOpts{ @@ -57,71 +57,71 @@ func TestCreate(t *testing.T) { }, } - actual, err := messages.Create(context.TODO(), client.ServiceClient(), QueueName, createOpts).Extract() + actual, err := messages.Create(context.TODO(), client.ServiceClient(fakeServer), QueueName, createOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, ExpectedResources, actual) } func TestGetMessages(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetMessagesSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetMessagesSuccessfully(t, fakeServer) getMessagesOpts := messages.GetMessagesOpts{ IDs: []string{"9988776655"}, } - actual, err := messages.GetMessages(context.TODO(), client.ServiceClient(), QueueName, getMessagesOpts).Extract() + actual, err := messages.GetMessages(context.TODO(), client.ServiceClient(fakeServer), QueueName, getMessagesOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, ExpectedMessagesSet, actual) } func TestGetMessage(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetSuccessfully(t, fakeServer) - actual, err := messages.Get(context.TODO(), client.ServiceClient(), QueueName, MessageID).Extract() + actual, err := messages.Get(context.TODO(), client.ServiceClient(fakeServer), QueueName, MessageID).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, FirstMessage, actual) } func TestDeleteMessages(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDeleteMessagesSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDeleteMessagesSuccessfully(t, fakeServer) deleteMessagesOpts := messages.DeleteMessagesOpts{ IDs: []string{"9988776655"}, } - err := messages.DeleteMessages(context.TODO(), client.ServiceClient(), QueueName, deleteMessagesOpts).ExtractErr() + err := messages.DeleteMessages(context.TODO(), client.ServiceClient(fakeServer), QueueName, deleteMessagesOpts).ExtractErr() th.AssertNoErr(t, err) } func TestPopMessages(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandlePopSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandlePopSuccessfully(t, fakeServer) popMessagesOpts := messages.PopMessagesOpts{ Pop: 1, } - actual, err := messages.PopMessages(context.TODO(), client.ServiceClient(), QueueName, popMessagesOpts).Extract() + actual, err := messages.PopMessages(context.TODO(), client.ServiceClient(fakeServer), QueueName, popMessagesOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, ExpectedPopMessage, actual) } func TestDeleteMessage(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDeleteSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDeleteSuccessfully(t, fakeServer) deleteOpts := messages.DeleteOpts{ ClaimID: "12345", } - err := messages.Delete(context.TODO(), client.ServiceClient(), QueueName, MessageID, deleteOpts).ExtractErr() + err := messages.Delete(context.TODO(), client.ServiceClient(fakeServer), QueueName, MessageID, deleteOpts).ExtractErr() th.AssertNoErr(t, err) } diff --git a/openstack/messaging/v2/queues/testing/fixtures_test.go b/openstack/messaging/v2/queues/testing/fixtures_test.go index bd9f71187d..c0d62f3e7b 100644 --- a/openstack/messaging/v2/queues/testing/fixtures_test.go +++ b/openstack/messaging/v2/queues/testing/fixtures_test.go @@ -215,8 +215,8 @@ var ExpectedShare = queues.QueueShare{ } // HandleListSuccessfully configures the test server to respond to a List request. -func HandleListSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v2/queues", +func HandleListSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2/queues", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -236,8 +236,8 @@ func HandleListSuccessfully(t *testing.T) { } // HandleCreateSuccessfully configures the test server to respond to a Create request. -func HandleCreateSuccessfully(t *testing.T) { - th.Mux.HandleFunc(fmt.Sprintf("/v2/queues/%s", QueueName), +func HandleCreateSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc(fmt.Sprintf("/v2/queues/%s", QueueName), func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -248,8 +248,8 @@ func HandleCreateSuccessfully(t *testing.T) { } // HandleUpdateSuccessfully configures the test server to respond to an Update request. -func HandleUpdateSuccessfully(t *testing.T) { - th.Mux.HandleFunc(fmt.Sprintf("/v2/queues/%s", QueueName), +func HandleUpdateSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc(fmt.Sprintf("/v2/queues/%s", QueueName), func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PATCH") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -261,8 +261,8 @@ func HandleUpdateSuccessfully(t *testing.T) { } // HandleGetSuccessfully configures the test server to respond to a Get request. -func HandleGetSuccessfully(t *testing.T) { - th.Mux.HandleFunc(fmt.Sprintf("/v2/queues/%s", QueueName), +func HandleGetSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc(fmt.Sprintf("/v2/queues/%s", QueueName), func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -273,8 +273,8 @@ func HandleGetSuccessfully(t *testing.T) { } // HandleDeleteSuccessfully configures the test server to respond to a Delete request. -func HandleDeleteSuccessfully(t *testing.T) { - th.Mux.HandleFunc(fmt.Sprintf("/v2/queues/%s", QueueName), +func HandleDeleteSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc(fmt.Sprintf("/v2/queues/%s", QueueName), func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -283,8 +283,8 @@ func HandleDeleteSuccessfully(t *testing.T) { } // HandleGetSuccessfully configures the test server to respond to a Get request. -func HandleGetStatsSuccessfully(t *testing.T) { - th.Mux.HandleFunc(fmt.Sprintf("/v2/queues/%s/stats", QueueName), +func HandleGetStatsSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc(fmt.Sprintf("/v2/queues/%s/stats", QueueName), func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -295,8 +295,8 @@ func HandleGetStatsSuccessfully(t *testing.T) { } // HandleShareSuccessfully configures the test server to respond to a Share request. -func HandleShareSuccessfully(t *testing.T) { - th.Mux.HandleFunc(fmt.Sprintf("/v2/queues/%s/share", QueueName), +func HandleShareSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc(fmt.Sprintf("/v2/queues/%s/share", QueueName), func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -308,8 +308,8 @@ func HandleShareSuccessfully(t *testing.T) { } // HandlePurgeSuccessfully configures the test server to respond to a Purge request. -func HandlePurgeSuccessfully(t *testing.T) { - th.Mux.HandleFunc(fmt.Sprintf("/v2/queues/%s/purge", QueueName), +func HandlePurgeSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc(fmt.Sprintf("/v2/queues/%s/purge", QueueName), func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/messaging/v2/queues/testing/requests_test.go b/openstack/messaging/v2/queues/testing/requests_test.go index adbb003fc4..8f882cf12c 100644 --- a/openstack/messaging/v2/queues/testing/requests_test.go +++ b/openstack/messaging/v2/queues/testing/requests_test.go @@ -11,9 +11,9 @@ import ( ) func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListSuccessfully(t, fakeServer) listOpts := queues.ListOpts{ Limit: 1, @@ -21,7 +21,7 @@ func TestList(t *testing.T) { } count := 0 - err := queues.List(client.ServiceClient(), listOpts).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := queues.List(client.ServiceClient(fakeServer), listOpts).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { actual, err := queues.ExtractQueues(page) th.AssertNoErr(t, err) countField, err := page.(queues.QueuePage).GetCount() @@ -39,9 +39,9 @@ func TestList(t *testing.T) { } func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCreateSuccessfully(t, fakeServer) var enableEncrypted *bool = new(bool) createOpts := queues.CreateOpts{ @@ -56,14 +56,14 @@ func TestCreate(t *testing.T) { Extra: map[string]any{"description": "Queue for unit testing."}, } - err := queues.Create(context.TODO(), client.ServiceClient(), createOpts).ExtractErr() + err := queues.Create(context.TODO(), client.ServiceClient(fakeServer), createOpts).ExtractErr() th.AssertNoErr(t, err) } func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleUpdateSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleUpdateSuccessfully(t, fakeServer) updateOpts := queues.BatchUpdateOpts{ queues.UpdateOpts{ @@ -76,44 +76,44 @@ func TestUpdate(t *testing.T) { Extra: map[string]any{"description": "Update queue description"}, } - actual, err := queues.Update(context.TODO(), client.ServiceClient(), QueueName, updateOpts).Extract() + actual, err := queues.Update(context.TODO(), client.ServiceClient(fakeServer), QueueName, updateOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, updatedQueueResult, actual) } func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetSuccessfully(t, fakeServer) - actual, err := queues.Get(context.TODO(), client.ServiceClient(), QueueName).Extract() + actual, err := queues.Get(context.TODO(), client.ServiceClient(fakeServer), QueueName).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, QueueDetails, actual) } func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDeleteSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDeleteSuccessfully(t, fakeServer) - err := queues.Delete(context.TODO(), client.ServiceClient(), QueueName).ExtractErr() + err := queues.Delete(context.TODO(), client.ServiceClient(fakeServer), QueueName).ExtractErr() th.AssertNoErr(t, err) } func TestGetStat(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetStatsSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetStatsSuccessfully(t, fakeServer) - actual, err := queues.GetStats(context.TODO(), client.ServiceClient(), QueueName).Extract() + actual, err := queues.GetStats(context.TODO(), client.ServiceClient(fakeServer), QueueName).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, ExpectedStats, actual) } func TestShare(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleShareSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleShareSuccessfully(t, fakeServer) shareOpts := queues.ShareOpts{ Paths: []queues.SharePath{queues.PathMessages, queues.PathClaims, queues.PathSubscriptions}, @@ -121,20 +121,20 @@ func TestShare(t *testing.T) { Expires: "2016-09-01T00:00:00", } - actual, err := queues.Share(context.TODO(), client.ServiceClient(), QueueName, shareOpts).Extract() + actual, err := queues.Share(context.TODO(), client.ServiceClient(fakeServer), QueueName, shareOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, ExpectedShare, actual) } func TestPurge(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandlePurgeSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandlePurgeSuccessfully(t, fakeServer) purgeOpts := queues.PurgeOpts{ ResourceTypes: []queues.PurgeResource{queues.ResourceMessages, queues.ResourceSubscriptions}, } - err := queues.Purge(context.TODO(), client.ServiceClient(), QueueName, purgeOpts).ExtractErr() + err := queues.Purge(context.TODO(), client.ServiceClient(fakeServer), QueueName, purgeOpts).ExtractErr() th.AssertNoErr(t, err) } diff --git a/openstack/networking/v2/apiversions/testing/requests_test.go b/openstack/networking/v2/apiversions/testing/requests_test.go index 4e54283f92..842b439c45 100644 --- a/openstack/networking/v2/apiversions/testing/requests_test.go +++ b/openstack/networking/v2/apiversions/testing/requests_test.go @@ -13,10 +13,10 @@ import ( ) func TestListVersions(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -42,7 +42,7 @@ func TestListVersions(t *testing.T) { count := 0 - err := apiversions.ListVersions(client.ServiceClient()).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := apiversions.ListVersions(client.ServiceClient(fakeServer)).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := apiversions.ExtractAPIVersions(page) if err != nil { @@ -69,14 +69,14 @@ func TestListVersions(t *testing.T) { } func TestNonJSONCannotBeExtractedIntoAPIVersions(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) }) - err := apiversions.ListVersions(client.ServiceClient()).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := apiversions.ListVersions(client.ServiceClient(fakeServer)).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { if _, err := apiversions.ExtractAPIVersions(page); err == nil { t.Fatalf("Expected error, got nil") } @@ -86,10 +86,10 @@ func TestNonJSONCannotBeExtractedIntoAPIVersions(t *testing.T) { } func TestAPIInfo(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -136,7 +136,7 @@ func TestAPIInfo(t *testing.T) { count := 0 - err := apiversions.ListVersionResources(client.ServiceClient(), "v2.0").EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := apiversions.ListVersionResources(client.ServiceClient(fakeServer), "v2.0").EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := apiversions.ExtractVersionResources(page) if err != nil { @@ -171,14 +171,14 @@ func TestAPIInfo(t *testing.T) { } func TestNonJSONCannotBeExtractedIntoAPIVersionResources(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) }) - err := apiversions.ListVersionResources(client.ServiceClient(), "v2.0").EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := apiversions.ListVersionResources(client.ServiceClient(fakeServer), "v2.0").EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { if _, err := apiversions.ExtractVersionResources(page); err == nil { t.Fatalf("Expected error, got nil") } diff --git a/openstack/networking/v2/common/common_tests.go b/openstack/networking/v2/common/common_tests.go index f32313a105..581c9803aa 100644 --- a/openstack/networking/v2/common/common_tests.go +++ b/openstack/networking/v2/common/common_tests.go @@ -2,13 +2,14 @@ package common import ( "github.com/gophercloud/gophercloud/v2" + th "github.com/gophercloud/gophercloud/v2/testhelper" "github.com/gophercloud/gophercloud/v2/testhelper/client" ) const TokenID = client.TokenID -func ServiceClient() *gophercloud.ServiceClient { - sc := client.ServiceClient() +func ServiceClient(fakeServer th.FakeServer) *gophercloud.ServiceClient { + sc := client.ServiceClient(fakeServer) sc.ResourceBase = sc.Endpoint + "v2.0/" return sc } diff --git a/openstack/networking/v2/extensions/agents/testing/requests_test.go b/openstack/networking/v2/extensions/agents/testing/requests_test.go index 41380edac7..e5b5888c43 100644 --- a/openstack/networking/v2/extensions/agents/testing/requests_test.go +++ b/openstack/networking/v2/extensions/agents/testing/requests_test.go @@ -15,10 +15,10 @@ import ( ) func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/agents", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/agents", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -30,7 +30,7 @@ func TestList(t *testing.T) { count := 0 - err := agents.List(fake.ServiceClient(), agents.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := agents.List(fake.ServiceClient(fakeServer), agents.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := agents.ExtractAgents(page) @@ -56,10 +56,10 @@ func TestList(t *testing.T) { } func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/agents/43583cf5-472e-4dc8-af5b-6aed4c94ee3a", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/agents/43583cf5-472e-4dc8-af5b-6aed4c94ee3a", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -69,7 +69,7 @@ func TestGet(t *testing.T) { fmt.Fprint(w, AgentsGetResult) }) - s, err := agents.Get(context.TODO(), fake.ServiceClient(), "43583cf5-472e-4dc8-af5b-6aed4c94ee3a").Extract() + s, err := agents.Get(context.TODO(), fake.ServiceClient(fakeServer), "43583cf5-472e-4dc8-af5b-6aed4c94ee3a").Extract() th.AssertNoErr(t, err) th.AssertEquals(t, s.ID, "43583cf5-472e-4dc8-af5b-6aed4c94ee3a") @@ -93,10 +93,10 @@ func TestGet(t *testing.T) { } func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/agents/43583cf5-472e-4dc8-af5b-6aed4c94ee3a", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/agents/43583cf5-472e-4dc8-af5b-6aed4c94ee3a", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -115,17 +115,17 @@ func TestUpdate(t *testing.T) { Description: &description, AdminStateUp: &iTrue, } - s, err := agents.Update(context.TODO(), fake.ServiceClient(), "43583cf5-472e-4dc8-af5b-6aed4c94ee3a", updateOpts).Extract() + s, err := agents.Update(context.TODO(), fake.ServiceClient(fakeServer), "43583cf5-472e-4dc8-af5b-6aed4c94ee3a", updateOpts).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, *s, Agent) } func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/agents/43583cf5-472e-4dc8-af5b-6aed4c94ee3a", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/agents/43583cf5-472e-4dc8-af5b-6aed4c94ee3a", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -134,15 +134,15 @@ func TestDelete(t *testing.T) { w.WriteHeader(http.StatusNoContent) }) - err := agents.Delete(context.TODO(), fake.ServiceClient(), "43583cf5-472e-4dc8-af5b-6aed4c94ee3a").ExtractErr() + err := agents.Delete(context.TODO(), fake.ServiceClient(fakeServer), "43583cf5-472e-4dc8-af5b-6aed4c94ee3a").ExtractErr() th.AssertNoErr(t, err) } func TestListDHCPNetworks(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/agents/43583cf5-472e-4dc8-af5b-6aed4c94ee3a/dhcp-networks", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/agents/43583cf5-472e-4dc8-af5b-6aed4c94ee3a/dhcp-networks", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -152,7 +152,7 @@ func TestListDHCPNetworks(t *testing.T) { fmt.Fprint(w, AgentDHCPNetworksListResult) }) - s, err := agents.ListDHCPNetworks(context.TODO(), fake.ServiceClient(), "43583cf5-472e-4dc8-af5b-6aed4c94ee3a").Extract() + s, err := agents.ListDHCPNetworks(context.TODO(), fake.ServiceClient(fakeServer), "43583cf5-472e-4dc8-af5b-6aed4c94ee3a").Extract() th.AssertNoErr(t, err) var nilSlice []string @@ -171,10 +171,10 @@ func TestListDHCPNetworks(t *testing.T) { } func TestScheduleDHCPNetwork(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/agents/43583cf5-472e-4dc8-af5b-6aed4c94ee3a/dhcp-networks", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/agents/43583cf5-472e-4dc8-af5b-6aed4c94ee3a/dhcp-networks", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -188,15 +188,15 @@ func TestScheduleDHCPNetwork(t *testing.T) { opts := &agents.ScheduleDHCPNetworkOpts{ NetworkID: "1ae075ca-708b-4e66-b4a7-b7698632f05f", } - err := agents.ScheduleDHCPNetwork(context.TODO(), fake.ServiceClient(), "43583cf5-472e-4dc8-af5b-6aed4c94ee3a", opts).ExtractErr() + err := agents.ScheduleDHCPNetwork(context.TODO(), fake.ServiceClient(fakeServer), "43583cf5-472e-4dc8-af5b-6aed4c94ee3a", opts).ExtractErr() th.AssertNoErr(t, err) } func TestRemoveDHCPNetwork(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/agents/43583cf5-472e-4dc8-af5b-6aed4c94ee3a/dhcp-networks/1ae075ca-708b-4e66-b4a7-b7698632f05f", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/agents/43583cf5-472e-4dc8-af5b-6aed4c94ee3a/dhcp-networks/1ae075ca-708b-4e66-b4a7-b7698632f05f", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -205,17 +205,17 @@ func TestRemoveDHCPNetwork(t *testing.T) { w.WriteHeader(http.StatusNoContent) }) - err := agents.RemoveDHCPNetwork(context.TODO(), fake.ServiceClient(), "43583cf5-472e-4dc8-af5b-6aed4c94ee3a", "1ae075ca-708b-4e66-b4a7-b7698632f05f").ExtractErr() + err := agents.RemoveDHCPNetwork(context.TODO(), fake.ServiceClient(fakeServer), "43583cf5-472e-4dc8-af5b-6aed4c94ee3a", "1ae075ca-708b-4e66-b4a7-b7698632f05f").ExtractErr() th.AssertNoErr(t, err) } func TestListBGPSpeakers(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() agentID := "30d76012-46de-4215-aaa1-a1630d01d891" - th.Mux.HandleFunc("/v2.0/agents/"+agentID+"/bgp-drinstances", + fakeServer.Mux.HandleFunc("/v2.0/agents/"+agentID+"/bgp-drinstances", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -227,7 +227,7 @@ func TestListBGPSpeakers(t *testing.T) { }) count := 0 - err := agents.ListBGPSpeakers(fake.ServiceClient(), agentID).EachPage( + err := agents.ListBGPSpeakers(fake.ServiceClient(fakeServer), agentID).EachPage( context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ @@ -248,13 +248,13 @@ func TestListBGPSpeakers(t *testing.T) { } func TestScheduleBGPSpeaker(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() agentID := "30d76012-46de-4215-aaa1-a1630d01d891" speakerID := "8edb2c68-0654-49a9-b3fe-030f92e3ddf6" - th.Mux.HandleFunc("/v2.0/agents/"+agentID+"/bgp-drinstances", + fakeServer.Mux.HandleFunc("/v2.0/agents/"+agentID+"/bgp-drinstances", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -268,18 +268,18 @@ func TestScheduleBGPSpeaker(t *testing.T) { var opts agents.ScheduleBGPSpeakerOpts opts.SpeakerID = speakerID - err := agents.ScheduleBGPSpeaker(context.TODO(), fake.ServiceClient(), agentID, opts).ExtractErr() + err := agents.ScheduleBGPSpeaker(context.TODO(), fake.ServiceClient(fakeServer), agentID, opts).ExtractErr() th.AssertNoErr(t, err) } func TestRemoveBGPSpeaker(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() agentID := "30d76012-46de-4215-aaa1-a1630d01d891" speakerID := "8edb2c68-0654-49a9-b3fe-030f92e3ddf6" - th.Mux.HandleFunc("/v2.0/agents/"+agentID+"/bgp-drinstances/"+speakerID, + fakeServer.Mux.HandleFunc("/v2.0/agents/"+agentID+"/bgp-drinstances/"+speakerID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -289,16 +289,16 @@ func TestRemoveBGPSpeaker(t *testing.T) { w.WriteHeader(http.StatusNoContent) }) - err := agents.RemoveBGPSpeaker(context.TODO(), fake.ServiceClient(), agentID, speakerID).ExtractErr() + err := agents.RemoveBGPSpeaker(context.TODO(), fake.ServiceClient(fakeServer), agentID, speakerID).ExtractErr() th.AssertNoErr(t, err) } func TestListDRAgentHostingBGPSpeakers(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() speakerID := "3f511b1b-d541-45f1-aa98-2e44e8183d4c" - th.Mux.HandleFunc("/v2.0/bgp-speakers/"+speakerID+"/bgp-dragents", + fakeServer.Mux.HandleFunc("/v2.0/bgp-speakers/"+speakerID+"/bgp-dragents", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -309,7 +309,7 @@ func TestListDRAgentHostingBGPSpeakers(t *testing.T) { }) count := 0 - err := agents.ListDRAgentHostingBGPSpeakers(fake.ServiceClient(), speakerID).EachPage( + err := agents.ListDRAgentHostingBGPSpeakers(fake.ServiceClient(fakeServer), speakerID).EachPage( context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ @@ -332,10 +332,10 @@ func TestListDRAgentHostingBGPSpeakers(t *testing.T) { } func TestListL3Routers(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/agents/43583cf5-472e-4dc8-af5b-6aed4c94ee3a/l3-routers", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/agents/43583cf5-472e-4dc8-af5b-6aed4c94ee3a/l3-routers", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -345,7 +345,7 @@ func TestListL3Routers(t *testing.T) { fmt.Fprint(w, AgentL3RoutersListResult) }) - s, err := agents.ListL3Routers(context.TODO(), fake.ServiceClient(), "43583cf5-472e-4dc8-af5b-6aed4c94ee3a").Extract() + s, err := agents.ListL3Routers(context.TODO(), fake.ServiceClient(fakeServer), "43583cf5-472e-4dc8-af5b-6aed4c94ee3a").Extract() th.AssertNoErr(t, err) routes := []routers.Route{ @@ -390,10 +390,10 @@ func TestListL3Routers(t *testing.T) { } func TestScheduleL3Router(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/agents/43583cf5-472e-4dc8-af5b-6aed4c94ee3a/l3-routers", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/agents/43583cf5-472e-4dc8-af5b-6aed4c94ee3a/l3-routers", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -407,15 +407,15 @@ func TestScheduleL3Router(t *testing.T) { opts := &agents.ScheduleL3RouterOpts{ RouterID: "43e66290-79a4-415d-9eb9-7ff7919839e1", } - err := agents.ScheduleL3Router(context.TODO(), fake.ServiceClient(), "43583cf5-472e-4dc8-af5b-6aed4c94ee3a", opts).ExtractErr() + err := agents.ScheduleL3Router(context.TODO(), fake.ServiceClient(fakeServer), "43583cf5-472e-4dc8-af5b-6aed4c94ee3a", opts).ExtractErr() th.AssertNoErr(t, err) } func TestRemoveL3Router(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/agents/43583cf5-472e-4dc8-af5b-6aed4c94ee3a/l3-routers/43e66290-79a4-415d-9eb9-7ff7919839e1", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/agents/43583cf5-472e-4dc8-af5b-6aed4c94ee3a/l3-routers/43e66290-79a4-415d-9eb9-7ff7919839e1", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -424,6 +424,6 @@ func TestRemoveL3Router(t *testing.T) { w.WriteHeader(http.StatusNoContent) }) - err := agents.RemoveL3Router(context.TODO(), fake.ServiceClient(), "43583cf5-472e-4dc8-af5b-6aed4c94ee3a", "43e66290-79a4-415d-9eb9-7ff7919839e1").ExtractErr() + err := agents.RemoveL3Router(context.TODO(), fake.ServiceClient(fakeServer), "43583cf5-472e-4dc8-af5b-6aed4c94ee3a", "43e66290-79a4-415d-9eb9-7ff7919839e1").ExtractErr() th.AssertNoErr(t, err) } diff --git a/openstack/networking/v2/extensions/attributestags/testing/requests_test.go b/openstack/networking/v2/extensions/attributestags/testing/requests_test.go index 5f20bdff5f..dc35bd12dc 100644 --- a/openstack/networking/v2/extensions/attributestags/testing/requests_test.go +++ b/openstack/networking/v2/extensions/attributestags/testing/requests_test.go @@ -12,10 +12,10 @@ import ( ) func TestReplaceAll(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/networks/fakeid/tags", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/networks/fakeid/tags", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -31,17 +31,17 @@ func TestReplaceAll(t *testing.T) { opts := attributestags.ReplaceAllOpts{ Tags: []string{"abc", "xyz"}, } - res, err := attributestags.ReplaceAll(context.TODO(), fake.ServiceClient(), "networks", "fakeid", opts).Extract() + res, err := attributestags.ReplaceAll(context.TODO(), fake.ServiceClient(fakeServer), "networks", "fakeid", opts).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, res, []string{"abc", "xyz"}) } func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/networks/fakeid/tags", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/networks/fakeid/tags", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -51,17 +51,17 @@ func TestList(t *testing.T) { fmt.Fprint(w, attributestagsListResult) }) - res, err := attributestags.List(context.TODO(), fake.ServiceClient(), "networks", "fakeid").Extract() + res, err := attributestags.List(context.TODO(), fake.ServiceClient(fakeServer), "networks", "fakeid").Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, res, []string{"abc", "xyz"}) } func TestDeleteAll(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/networks/fakeid/tags", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/networks/fakeid/tags", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -69,15 +69,15 @@ func TestDeleteAll(t *testing.T) { w.WriteHeader(http.StatusNoContent) }) - err := attributestags.DeleteAll(context.TODO(), fake.ServiceClient(), "networks", "fakeid").ExtractErr() + err := attributestags.DeleteAll(context.TODO(), fake.ServiceClient(fakeServer), "networks", "fakeid").ExtractErr() th.AssertNoErr(t, err) } func TestAdd(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/networks/fakeid/tags/atag", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/networks/fakeid/tags/atag", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -85,15 +85,15 @@ func TestAdd(t *testing.T) { w.WriteHeader(http.StatusCreated) }) - err := attributestags.Add(context.TODO(), fake.ServiceClient(), "networks", "fakeid", "atag").ExtractErr() + err := attributestags.Add(context.TODO(), fake.ServiceClient(fakeServer), "networks", "fakeid", "atag").ExtractErr() th.AssertNoErr(t, err) } func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/networks/fakeid/tags/atag", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/networks/fakeid/tags/atag", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -101,15 +101,15 @@ func TestDelete(t *testing.T) { w.WriteHeader(http.StatusNoContent) }) - err := attributestags.Delete(context.TODO(), fake.ServiceClient(), "networks", "fakeid", "atag").ExtractErr() + err := attributestags.Delete(context.TODO(), fake.ServiceClient(fakeServer), "networks", "fakeid", "atag").ExtractErr() th.AssertNoErr(t, err) } func TestConfirmTrue(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/networks/fakeid/tags/atag", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/networks/fakeid/tags/atag", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -117,16 +117,16 @@ func TestConfirmTrue(t *testing.T) { w.WriteHeader(http.StatusNoContent) }) - exists, err := attributestags.Confirm(context.TODO(), fake.ServiceClient(), "networks", "fakeid", "atag").Extract() + exists, err := attributestags.Confirm(context.TODO(), fake.ServiceClient(fakeServer), "networks", "fakeid", "atag").Extract() th.AssertNoErr(t, err) th.AssertEquals(t, true, exists) } func TestConfirmFalse(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/networks/fakeid/tags/atag", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/networks/fakeid/tags/atag", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -134,6 +134,6 @@ func TestConfirmFalse(t *testing.T) { w.WriteHeader(http.StatusNotFound) }) - exists, _ := attributestags.Confirm(context.TODO(), fake.ServiceClient(), "networks", "fakeid", "atag").Extract() + exists, _ := attributestags.Confirm(context.TODO(), fake.ServiceClient(fakeServer), "networks", "fakeid", "atag").Extract() th.AssertEquals(t, false, exists) } diff --git a/openstack/networking/v2/extensions/bgp/peers/testing/requests_test.go b/openstack/networking/v2/extensions/bgp/peers/testing/requests_test.go index f24a0a1a0c..8f4040ba06 100644 --- a/openstack/networking/v2/extensions/bgp/peers/testing/requests_test.go +++ b/openstack/networking/v2/extensions/bgp/peers/testing/requests_test.go @@ -13,10 +13,10 @@ import ( ) func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/bgp-peers", + fakeServer.Mux.HandleFunc("/v2.0/bgp-peers", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -27,7 +27,7 @@ func TestList(t *testing.T) { }) count := 0 - err := peers.List(fake.ServiceClient()).EachPage( + err := peers.List(fake.ServiceClient(fakeServer)).EachPage( context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ @@ -45,11 +45,11 @@ func TestList(t *testing.T) { } func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() bgpPeerID := "afacc0e8-6b66-44e4-be53-a1ef16033ceb" - th.Mux.HandleFunc("/v2.0/bgp-peers/"+bgpPeerID, func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/bgp-peers/"+bgpPeerID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.Header().Add("Content-Type", "application/json") @@ -57,16 +57,16 @@ func TestGet(t *testing.T) { fmt.Fprint(w, GetBGPPeerResult) }) - s, err := peers.Get(context.TODO(), fake.ServiceClient(), bgpPeerID).Extract() + s, err := peers.Get(context.TODO(), fake.ServiceClient(fakeServer), bgpPeerID).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, *s, BGPPeer1) } func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/bgp-peers", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/bgp-peers", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -84,7 +84,7 @@ func TestCreate(t *testing.T) { opts.Name = "gophercloud-testing-bgp-peer" opts.PeerIP = "192.168.0.1" - r, err := peers.Create(context.TODO(), fake.ServiceClient(), opts).Extract() + r, err := peers.Create(context.TODO(), fake.ServiceClient(fakeServer), opts).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, r.AuthType, opts.AuthType) th.AssertEquals(t, r.RemoteAS, opts.RemoteAS) @@ -93,10 +93,10 @@ func TestCreate(t *testing.T) { func TestDelete(t *testing.T) { bgpPeerID := "afacc0e8-6b66-44e4-be53-a1ef16033ceb" - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/bgp-peers/"+bgpPeerID, func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/bgp-peers/"+bgpPeerID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -105,16 +105,16 @@ func TestDelete(t *testing.T) { w.WriteHeader(http.StatusNoContent) }) - err := peers.Delete(context.TODO(), fake.ServiceClient(), bgpPeerID).ExtractErr() + err := peers.Delete(context.TODO(), fake.ServiceClient(fakeServer), bgpPeerID).ExtractErr() th.AssertNoErr(t, err) } func TestUpdate(t *testing.T) { bgpPeerID := "afacc0e8-6b66-44e4-be53-a1ef16033ceb" - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/bgp-peers/"+bgpPeerID, func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/bgp-peers/"+bgpPeerID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -131,7 +131,7 @@ func TestUpdate(t *testing.T) { opts.Name = "test-rename-bgp-peer" opts.Password = "superStrong" - r, err := peers.Update(context.TODO(), fake.ServiceClient(), bgpPeerID, opts).Extract() + r, err := peers.Update(context.TODO(), fake.ServiceClient(fakeServer), bgpPeerID, opts).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, r.Name, opts.Name) } diff --git a/openstack/networking/v2/extensions/bgp/speakers/testing/requests_test.go b/openstack/networking/v2/extensions/bgp/speakers/testing/requests_test.go index 0ace6b2403..edcf11637b 100644 --- a/openstack/networking/v2/extensions/bgp/speakers/testing/requests_test.go +++ b/openstack/networking/v2/extensions/bgp/speakers/testing/requests_test.go @@ -13,10 +13,10 @@ import ( ) func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/bgp-speakers", + fakeServer.Mux.HandleFunc("/v2.0/bgp-speakers", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -27,7 +27,7 @@ func TestList(t *testing.T) { }) count := 0 - err := speakers.List(fake.ServiceClient()).EachPage( + err := speakers.List(fake.ServiceClient(fakeServer)).EachPage( context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ @@ -45,11 +45,11 @@ func TestList(t *testing.T) { } func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() bgpSpeakerID := "ab01ade1-ae62-43c9-8a1f-3c24225b96d8" - th.Mux.HandleFunc("/v2.0/bgp-speakers/"+bgpSpeakerID, func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/bgp-speakers/"+bgpSpeakerID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.Header().Add("Content-Type", "application/json") @@ -57,16 +57,16 @@ func TestGet(t *testing.T) { fmt.Fprint(w, GetBGPSpeakerResult) }) - s, err := speakers.Get(context.TODO(), fake.ServiceClient(), bgpSpeakerID).Extract() + s, err := speakers.Get(context.TODO(), fake.ServiceClient(fakeServer), bgpSpeakerID).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, *s, BGPSpeaker1) } func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/bgp-speakers", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/bgp-speakers", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -85,7 +85,7 @@ func TestCreate(t *testing.T) { LocalAS: "2000", Networks: []string{}, } - r, err := speakers.Create(context.TODO(), fake.ServiceClient(), opts).Extract() + r, err := speakers.Create(context.TODO(), fake.ServiceClient(fakeServer), opts).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, r.Name, opts.Name) th.AssertEquals(t, r.LocalAS, 2000) @@ -96,11 +96,11 @@ func TestCreate(t *testing.T) { } func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() bgpSpeakerID := "ab01ade1-ae62-43c9-8a1f-3c24225b96d8" - th.Mux.HandleFunc("/v2.0/bgp-speakers/"+bgpSpeakerID, func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/bgp-speakers/"+bgpSpeakerID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -109,16 +109,16 @@ func TestDelete(t *testing.T) { w.WriteHeader(http.StatusNoContent) }) - err := speakers.Delete(context.TODO(), fake.ServiceClient(), bgpSpeakerID).ExtractErr() + err := speakers.Delete(context.TODO(), fake.ServiceClient(fakeServer), bgpSpeakerID).ExtractErr() th.AssertNoErr(t, err) } func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() bgpSpeakerID := "ab01ade1-ae62-43c9-8a1f-3c24225b96d8" - th.Mux.HandleFunc("/v2.0/bgp-speakers/"+bgpSpeakerID, func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/bgp-speakers/"+bgpSpeakerID, func(w http.ResponseWriter, r *http.Request) { if r.Method == "GET" { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -146,7 +146,7 @@ func TestUpdate(t *testing.T) { AdvertiseFloatingIPHostRoutes: true, } - r, err := speakers.Update(context.TODO(), fake.ServiceClient(), bgpSpeakerID, opts).Extract() + r, err := speakers.Update(context.TODO(), fake.ServiceClient(fakeServer), bgpSpeakerID, opts).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, r.Name, opts.Name) th.AssertEquals(t, r.AdvertiseTenantNetworks, opts.AdvertiseTenantNetworks) @@ -154,12 +154,12 @@ func TestUpdate(t *testing.T) { } func TestAddBGPPeer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() bgpSpeakerID := "ab01ade1-ae62-43c9-8a1f-3c24225b96d8" bgpPeerID := "f5884c7c-71d5-43a3-88b4-1742e97674aa" - th.Mux.HandleFunc("/v2.0/bgp-speakers/"+bgpSpeakerID+"/add_bgp_peer", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/bgp-speakers/"+bgpSpeakerID+"/add_bgp_peer", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -172,18 +172,18 @@ func TestAddBGPPeer(t *testing.T) { }) opts := speakers.AddBGPPeerOpts{BGPPeerID: bgpPeerID} - r, err := speakers.AddBGPPeer(context.TODO(), fake.ServiceClient(), bgpSpeakerID, opts).Extract() + r, err := speakers.AddBGPPeer(context.TODO(), fake.ServiceClient(fakeServer), bgpSpeakerID, opts).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, bgpPeerID, r.BGPPeerID) } func TestRemoveBGPPeer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() bgpSpeakerID := "ab01ade1-ae62-43c9-8a1f-3c24225b96d8" bgpPeerID := "f5884c7c-71d5-43a3-88b4-1742e97674aa" - th.Mux.HandleFunc("/v2.0/bgp-speakers/"+bgpSpeakerID+"/remove_bgp_peer", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/bgp-speakers/"+bgpSpeakerID+"/remove_bgp_peer", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -193,16 +193,16 @@ func TestRemoveBGPPeer(t *testing.T) { }) opts := speakers.RemoveBGPPeerOpts{BGPPeerID: bgpPeerID} - err := speakers.RemoveBGPPeer(context.TODO(), fake.ServiceClient(), bgpSpeakerID, opts).ExtractErr() + err := speakers.RemoveBGPPeer(context.TODO(), fake.ServiceClient(fakeServer), bgpSpeakerID, opts).ExtractErr() th.AssertNoErr(t, err) } func TestGetAdvertisedRoutes(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() bgpSpeakerID := "ab01ade1-ae62-43c9-8a1f-3c24225b96d8" - th.Mux.HandleFunc("/v2.0/bgp-speakers/"+bgpSpeakerID+"/get_advertised_routes", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/bgp-speakers/"+bgpSpeakerID+"/get_advertised_routes", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.Header().Add("Content-Type", "application/json") @@ -211,7 +211,7 @@ func TestGetAdvertisedRoutes(t *testing.T) { }) count := 0 - err := speakers.GetAdvertisedRoutes(fake.ServiceClient(), bgpSpeakerID).EachPage( + err := speakers.GetAdvertisedRoutes(fake.ServiceClient(fakeServer), bgpSpeakerID).EachPage( context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ @@ -235,12 +235,12 @@ func TestGetAdvertisedRoutes(t *testing.T) { } func TestAddGatewayNetwork(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() bgpSpeakerID := "ab01ade1-ae62-43c9-8a1f-3c24225b96d8" networkID := "ac13bb26-6219-49c3-a880-08847f6830b7" - th.Mux.HandleFunc("/v2.0/bgp-speakers/"+bgpSpeakerID+"/add_gateway_network", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/bgp-speakers/"+bgpSpeakerID+"/add_gateway_network", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -253,18 +253,18 @@ func TestAddGatewayNetwork(t *testing.T) { }) opts := speakers.AddGatewayNetworkOpts{NetworkID: networkID} - r, err := speakers.AddGatewayNetwork(context.TODO(), fake.ServiceClient(), bgpSpeakerID, opts).Extract() + r, err := speakers.AddGatewayNetwork(context.TODO(), fake.ServiceClient(fakeServer), bgpSpeakerID, opts).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, r.NetworkID, networkID) } func TestRemoveGatewayNetwork(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() bgpSpeakerID := "ab01ade1-ae62-43c9-8a1f-3c24225b96d8" networkID := "ac13bb26-6219-49c3-a880-08847f6830b7" - th.Mux.HandleFunc("/v2.0/bgp-speakers/"+bgpSpeakerID+"/remove_gateway_network", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/bgp-speakers/"+bgpSpeakerID+"/remove_gateway_network", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -277,6 +277,6 @@ func TestRemoveGatewayNetwork(t *testing.T) { }) opts := speakers.RemoveGatewayNetworkOpts{NetworkID: networkID} - err := speakers.RemoveGatewayNetwork(context.TODO(), fake.ServiceClient(), bgpSpeakerID, opts).ExtractErr() + err := speakers.RemoveGatewayNetwork(context.TODO(), fake.ServiceClient(fakeServer), bgpSpeakerID, opts).ExtractErr() th.AssertNoErr(t, err) } diff --git a/openstack/networking/v2/extensions/bgpvpns/testing/requests_test.go b/openstack/networking/v2/extensions/bgpvpns/testing/requests_test.go index aacc57aa90..095fc5056c 100644 --- a/openstack/networking/v2/extensions/bgpvpns/testing/requests_test.go +++ b/openstack/networking/v2/extensions/bgpvpns/testing/requests_test.go @@ -13,8 +13,8 @@ import ( ) func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() filterProjectID := []string{"b7549121395844bea941bb92feb3fad9"} fields := []string{"id", "name"} @@ -22,7 +22,7 @@ func TestList(t *testing.T) { Fields: fields, ProjectID: filterProjectID[0], } - th.Mux.HandleFunc("/v2.0/bgpvpn/bgpvpns", + fakeServer.Mux.HandleFunc("/v2.0/bgpvpn/bgpvpns", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -39,7 +39,7 @@ func TestList(t *testing.T) { }) count := 0 - err := bgpvpns.List(fake.ServiceClient(), listOpts).EachPage( + err := bgpvpns.List(fake.ServiceClient(fakeServer), listOpts).EachPage( context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ @@ -58,11 +58,11 @@ func TestList(t *testing.T) { } func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() bgpVpnID := "460ac411-3dfb-45bb-8116-ed1a7233d143" - th.Mux.HandleFunc("/v2.0/bgpvpn/bgpvpns/"+bgpVpnID, func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/bgpvpn/bgpvpns/"+bgpVpnID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.Header().Add("Content-Type", "application/json") @@ -70,16 +70,16 @@ func TestGet(t *testing.T) { fmt.Fprint(w, GetBGPVPNResult) }) - r, err := bgpvpns.Get(context.TODO(), fake.ServiceClient(), bgpVpnID).Extract() + r, err := bgpvpns.Get(context.TODO(), fake.ServiceClient(fakeServer), bgpVpnID).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, GetBGPVPN, *r) } func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/bgpvpn/bgpvpns", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/bgpvpn/bgpvpns", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -110,17 +110,17 @@ func TestCreate(t *testing.T) { VNI: 1000, } - r, err := bgpvpns.Create(context.TODO(), fake.ServiceClient(), opts).Extract() + r, err := bgpvpns.Create(context.TODO(), fake.ServiceClient(fakeServer), opts).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, CreateBGPVPN, *r) } func TestDelete(t *testing.T) { bgpVpnID := "0f9d472a-908f-40f5-8574-b4e8a63ccbf0" - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/bgpvpn/bgpvpns/"+bgpVpnID, func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/bgpvpn/bgpvpns/"+bgpVpnID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -129,16 +129,16 @@ func TestDelete(t *testing.T) { w.WriteHeader(http.StatusNoContent) }) - err := bgpvpns.Delete(context.TODO(), fake.ServiceClient(), bgpVpnID).ExtractErr() + err := bgpvpns.Delete(context.TODO(), fake.ServiceClient(fakeServer), bgpVpnID).ExtractErr() th.AssertNoErr(t, err) } func TestUpdate(t *testing.T) { bgpVpnID := "4d627abf-06dd-45ab-920b-8e61422bb984" - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/bgpvpn/bgpvpns/"+bgpVpnID, func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/bgpvpn/bgpvpns/"+bgpVpnID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -161,21 +161,21 @@ func TestUpdate(t *testing.T) { ExportTargets: &emptyTarget, } - r, err := bgpvpns.Update(context.TODO(), fake.ServiceClient(), bgpVpnID, opts).Extract() + r, err := bgpvpns.Update(context.TODO(), fake.ServiceClient(fakeServer), bgpVpnID, opts).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, *opts.Name, r.Name) } func TestListNetworkAssociations(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() bgpVpnID := "460ac411-3dfb-45bb-8116-ed1a7233d143" fields := []string{"id", "name"} listOpts := bgpvpns.ListNetworkAssociationsOpts{ Fields: fields, } - th.Mux.HandleFunc("/v2.0/bgpvpn/bgpvpns/"+bgpVpnID+"/network_associations", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/bgpvpn/bgpvpns/"+bgpVpnID+"/network_associations", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -190,7 +190,7 @@ func TestListNetworkAssociations(t *testing.T) { }) count := 0 - err := bgpvpns.ListNetworkAssociations(fake.ServiceClient(), bgpVpnID, listOpts).EachPage( + err := bgpvpns.ListNetworkAssociations(fake.ServiceClient(fakeServer), bgpVpnID, listOpts).EachPage( context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ @@ -211,11 +211,11 @@ func TestListNetworkAssociations(t *testing.T) { } func TestCreateNetworkAssociation(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() bgpVpnID := "460ac411-3dfb-45bb-8116-ed1a7233d143" - th.Mux.HandleFunc("/v2.0/bgpvpn/bgpvpns/"+bgpVpnID+"/network_associations", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/bgpvpn/bgpvpns/"+bgpVpnID+"/network_associations", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -229,18 +229,18 @@ func TestCreateNetworkAssociation(t *testing.T) { opts := bgpvpns.CreateNetworkAssociationOpts{ NetworkID: "8c5d88dc-60ac-4b02-a65a-36b65888ddcd", } - r, err := bgpvpns.CreateNetworkAssociation(context.TODO(), fake.ServiceClient(), bgpVpnID, opts).Extract() + r, err := bgpvpns.CreateNetworkAssociation(context.TODO(), fake.ServiceClient(fakeServer), bgpVpnID, opts).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, CreateNetworkAssociation, *r) } func TestGetNetworkAssociation(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() bgpVpnID := "460ac411-3dfb-45bb-8116-ed1a7233d143" networkAssociationID := "73238ca1-e05d-4c7a-b4d4-70407b4b8730" - th.Mux.HandleFunc("/v2.0/bgpvpn/bgpvpns/"+bgpVpnID+"/network_associations/"+networkAssociationID, func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/bgpvpn/bgpvpns/"+bgpVpnID+"/network_associations/"+networkAssociationID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.Header().Add("Content-Type", "application/json") @@ -248,37 +248,37 @@ func TestGetNetworkAssociation(t *testing.T) { fmt.Fprint(w, GetNetworkAssociationResult) }) - r, err := bgpvpns.GetNetworkAssociation(context.TODO(), fake.ServiceClient(), bgpVpnID, networkAssociationID).Extract() + r, err := bgpvpns.GetNetworkAssociation(context.TODO(), fake.ServiceClient(fakeServer), bgpVpnID, networkAssociationID).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, GetNetworkAssociation, *r) } func TestDeleteNetworkAssociation(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() bgpVpnID := "460ac411-3dfb-45bb-8116-ed1a7233d143" networkAssociationID := "73238ca1-e05d-4c7a-b4d4-70407b4b8730" - th.Mux.HandleFunc("/v2.0/bgpvpn/bgpvpns/"+bgpVpnID+"/network_associations/"+networkAssociationID, func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/bgpvpn/bgpvpns/"+bgpVpnID+"/network_associations/"+networkAssociationID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.WriteHeader(http.StatusNoContent) }) - err := bgpvpns.DeleteNetworkAssociation(context.TODO(), fake.ServiceClient(), bgpVpnID, networkAssociationID).ExtractErr() + err := bgpvpns.DeleteNetworkAssociation(context.TODO(), fake.ServiceClient(fakeServer), bgpVpnID, networkAssociationID).ExtractErr() th.AssertNoErr(t, err) } func TestListRouterAssociations(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() bgpVpnID := "460ac411-3dfb-45bb-8116-ed1a7233d143" fields := []string{"id", "name"} listOpts := bgpvpns.ListRouterAssociationsOpts{ Fields: fields, } - th.Mux.HandleFunc("/v2.0/bgpvpn/bgpvpns/"+bgpVpnID+"/router_associations", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/bgpvpn/bgpvpns/"+bgpVpnID+"/router_associations", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -293,7 +293,7 @@ func TestListRouterAssociations(t *testing.T) { }) count := 0 - err := bgpvpns.ListRouterAssociations(fake.ServiceClient(), bgpVpnID, listOpts).EachPage( + err := bgpvpns.ListRouterAssociations(fake.ServiceClient(fakeServer), bgpVpnID, listOpts).EachPage( context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ @@ -314,11 +314,11 @@ func TestListRouterAssociations(t *testing.T) { } func TestCreateRouterAssociation(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() bgpVpnID := "460ac411-3dfb-45bb-8116-ed1a7233d143" - th.Mux.HandleFunc("/v2.0/bgpvpn/bgpvpns/"+bgpVpnID+"/router_associations", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/bgpvpn/bgpvpns/"+bgpVpnID+"/router_associations", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -332,18 +332,18 @@ func TestCreateRouterAssociation(t *testing.T) { opts := bgpvpns.CreateRouterAssociationOpts{ RouterID: "8c5d88dc-60ac-4b02-a65a-36b65888ddcd", } - r, err := bgpvpns.CreateRouterAssociation(context.TODO(), fake.ServiceClient(), bgpVpnID, opts).Extract() + r, err := bgpvpns.CreateRouterAssociation(context.TODO(), fake.ServiceClient(fakeServer), bgpVpnID, opts).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, CreateRouterAssociation, *r) } func TestGetRouterAssociation(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() bgpVpnID := "460ac411-3dfb-45bb-8116-ed1a7233d143" routerAssociationID := "73238ca1-e05d-4c7a-b4d4-70407b4b8730" - th.Mux.HandleFunc("/v2.0/bgpvpn/bgpvpns/"+bgpVpnID+"/router_associations/"+routerAssociationID, func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/bgpvpn/bgpvpns/"+bgpVpnID+"/router_associations/"+routerAssociationID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.Header().Add("Content-Type", "application/json") @@ -351,7 +351,7 @@ func TestGetRouterAssociation(t *testing.T) { fmt.Fprint(w, GetRouterAssociationResult) }) - r, err := bgpvpns.GetRouterAssociation(context.TODO(), fake.ServiceClient(), bgpVpnID, routerAssociationID).Extract() + r, err := bgpvpns.GetRouterAssociation(context.TODO(), fake.ServiceClient(fakeServer), bgpVpnID, routerAssociationID).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, GetRouterAssociation, *r) } @@ -359,10 +359,10 @@ func TestGetRouterAssociation(t *testing.T) { func TestUpdateRouterAssociation(t *testing.T) { bgpVpnID := "4d627abf-06dd-45ab-920b-8e61422bb984" routerAssociationID := "73238ca1-e05d-4c7a-b4d4-70407b4b8730" - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/bgpvpn/bgpvpns/"+bgpVpnID+"/router_associations/"+routerAssociationID, func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/bgpvpn/bgpvpns/"+bgpVpnID+"/router_associations/"+routerAssociationID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -376,37 +376,37 @@ func TestUpdateRouterAssociation(t *testing.T) { opts := bgpvpns.UpdateRouterAssociationOpts{ AdvertiseExtraRoutes: new(bool), } - r, err := bgpvpns.UpdateRouterAssociation(context.TODO(), fake.ServiceClient(), bgpVpnID, routerAssociationID, opts).Extract() + r, err := bgpvpns.UpdateRouterAssociation(context.TODO(), fake.ServiceClient(fakeServer), bgpVpnID, routerAssociationID, opts).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, UpdateRouterAssociation, *r) } func TestDeleteRouterAssociation(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() bgpVpnID := "460ac411-3dfb-45bb-8116-ed1a7233d143" routerAssociationID := "73238ca1-e05d-4c7a-b4d4-70407b4b8730" - th.Mux.HandleFunc("/v2.0/bgpvpn/bgpvpns/"+bgpVpnID+"/router_associations/"+routerAssociationID, func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/bgpvpn/bgpvpns/"+bgpVpnID+"/router_associations/"+routerAssociationID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.WriteHeader(http.StatusNoContent) }) - err := bgpvpns.DeleteRouterAssociation(context.TODO(), fake.ServiceClient(), bgpVpnID, routerAssociationID).ExtractErr() + err := bgpvpns.DeleteRouterAssociation(context.TODO(), fake.ServiceClient(fakeServer), bgpVpnID, routerAssociationID).ExtractErr() th.AssertNoErr(t, err) } func TestListPortAssociations(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() bgpVpnID := "460ac411-3dfb-45bb-8116-ed1a7233d143" fields := []string{"id", "name"} listOpts := bgpvpns.ListPortAssociationsOpts{ Fields: fields, } - th.Mux.HandleFunc("/v2.0/bgpvpn/bgpvpns/"+bgpVpnID+"/port_associations", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/bgpvpn/bgpvpns/"+bgpVpnID+"/port_associations", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -421,7 +421,7 @@ func TestListPortAssociations(t *testing.T) { }) count := 0 - err := bgpvpns.ListPortAssociations(fake.ServiceClient(), bgpVpnID, listOpts).EachPage( + err := bgpvpns.ListPortAssociations(fake.ServiceClient(fakeServer), bgpVpnID, listOpts).EachPage( context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ @@ -442,11 +442,11 @@ func TestListPortAssociations(t *testing.T) { } func TestCreatePortAssociation(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() bgpVpnID := "460ac411-3dfb-45bb-8116-ed1a7233d143" - th.Mux.HandleFunc("/v2.0/bgpvpn/bgpvpns/"+bgpVpnID+"/port_associations", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/bgpvpn/bgpvpns/"+bgpVpnID+"/port_associations", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -460,18 +460,18 @@ func TestCreatePortAssociation(t *testing.T) { opts := bgpvpns.CreatePortAssociationOpts{ PortID: "8c5d88dc-60ac-4b02-a65a-36b65888ddcd", } - r, err := bgpvpns.CreatePortAssociation(context.TODO(), fake.ServiceClient(), bgpVpnID, opts).Extract() + r, err := bgpvpns.CreatePortAssociation(context.TODO(), fake.ServiceClient(fakeServer), bgpVpnID, opts).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, CreatePortAssociation, *r) } func TestGetPortAssociation(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() bgpVpnID := "460ac411-3dfb-45bb-8116-ed1a7233d143" portAssociationID := "73238ca1-e05d-4c7a-b4d4-70407b4b8730" - th.Mux.HandleFunc("/v2.0/bgpvpn/bgpvpns/"+bgpVpnID+"/port_associations/"+portAssociationID, func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/bgpvpn/bgpvpns/"+bgpVpnID+"/port_associations/"+portAssociationID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.Header().Add("Content-Type", "application/json") @@ -479,7 +479,7 @@ func TestGetPortAssociation(t *testing.T) { fmt.Fprint(w, GetPortAssociationResult) }) - r, err := bgpvpns.GetPortAssociation(context.TODO(), fake.ServiceClient(), bgpVpnID, portAssociationID).Extract() + r, err := bgpvpns.GetPortAssociation(context.TODO(), fake.ServiceClient(fakeServer), bgpVpnID, portAssociationID).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, GetPortAssociation, *r) } @@ -487,10 +487,10 @@ func TestGetPortAssociation(t *testing.T) { func TestUpdatePortAssociation(t *testing.T) { bgpVpnID := "4d627abf-06dd-45ab-920b-8e61422bb984" portAssociationID := "73238ca1-e05d-4c7a-b4d4-70407b4b8730" - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/bgpvpn/bgpvpns/"+bgpVpnID+"/port_associations/"+portAssociationID, func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/bgpvpn/bgpvpns/"+bgpVpnID+"/port_associations/"+portAssociationID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -504,23 +504,23 @@ func TestUpdatePortAssociation(t *testing.T) { opts := bgpvpns.UpdatePortAssociationOpts{ AdvertiseFixedIPs: new(bool), } - r, err := bgpvpns.UpdatePortAssociation(context.TODO(), fake.ServiceClient(), bgpVpnID, portAssociationID, opts).Extract() + r, err := bgpvpns.UpdatePortAssociation(context.TODO(), fake.ServiceClient(fakeServer), bgpVpnID, portAssociationID, opts).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, UpdatePortAssociation, *r) } func TestDeletePortAssociation(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() bgpVpnID := "460ac411-3dfb-45bb-8116-ed1a7233d143" portAssociationID := "73238ca1-e05d-4c7a-b4d4-70407b4b8730" - th.Mux.HandleFunc("/v2.0/bgpvpn/bgpvpns/"+bgpVpnID+"/port_associations/"+portAssociationID, func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/bgpvpn/bgpvpns/"+bgpVpnID+"/port_associations/"+portAssociationID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.WriteHeader(http.StatusNoContent) }) - err := bgpvpns.DeletePortAssociation(context.TODO(), fake.ServiceClient(), bgpVpnID, portAssociationID).ExtractErr() + err := bgpvpns.DeletePortAssociation(context.TODO(), fake.ServiceClient(fakeServer), bgpVpnID, portAssociationID).ExtractErr() th.AssertNoErr(t, err) } diff --git a/openstack/networking/v2/extensions/dns/testing/fixtures_test.go b/openstack/networking/v2/extensions/dns/testing/fixtures_test.go index 85679382de..5f3dbd9935 100644 --- a/openstack/networking/v2/extensions/dns/testing/fixtures_test.go +++ b/openstack/networking/v2/extensions/dns/testing/fixtures_test.go @@ -68,8 +68,8 @@ const NetworkUpdateResponse = ` } }` -func PortHandleListSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v2.0/ports", func(w http.ResponseWriter, r *http.Request) { +func PortHandleListSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/ports", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -82,8 +82,8 @@ func PortHandleListSuccessfully(t *testing.T) { }) } -func PortHandleGet(t *testing.T) { - th.Mux.HandleFunc("/v2.0/ports/46d4bfb9-b26e-41f3-bd2e-e6dcc1ccedb2", func(w http.ResponseWriter, r *http.Request) { +func PortHandleGet(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/ports/46d4bfb9-b26e-41f3-bd2e-e6dcc1ccedb2", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -94,8 +94,8 @@ func PortHandleGet(t *testing.T) { }) } -func PortHandleCreate(t *testing.T) { - th.Mux.HandleFunc("/v2.0/ports", func(w http.ResponseWriter, r *http.Request) { +func PortHandleCreate(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/ports", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -157,8 +157,8 @@ func PortHandleCreate(t *testing.T) { }) } -func PortHandleUpdate(t *testing.T) { - th.Mux.HandleFunc("/v2.0/ports/65c0ee9f-d634-4522-8954-51021b570b0d", func(w http.ResponseWriter, r *http.Request) { +func PortHandleUpdate(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/ports/65c0ee9f-d634-4522-8954-51021b570b0d", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -219,8 +219,8 @@ func PortHandleUpdate(t *testing.T) { }) } -func FloatingIPHandleList(t *testing.T) { - th.Mux.HandleFunc("/v2.0/floatingips", func(w http.ResponseWriter, r *http.Request) { +func FloatingIPHandleList(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/floatingips", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -233,8 +233,8 @@ func FloatingIPHandleList(t *testing.T) { }) } -func FloatingIPHandleGet(t *testing.T) { - th.Mux.HandleFunc("/v2.0/floatingips/2f95fd2b-9f6a-4e8e-9e9a-2cbe286cbf9e", func(w http.ResponseWriter, r *http.Request) { +func FloatingIPHandleGet(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/floatingips/2f95fd2b-9f6a-4e8e-9e9a-2cbe286cbf9e", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -245,8 +245,8 @@ func FloatingIPHandleGet(t *testing.T) { }) } -func FloatingIPHandleCreate(t *testing.T) { - th.Mux.HandleFunc("/v2.0/floatingips", func(w http.ResponseWriter, r *http.Request) { +func FloatingIPHandleCreate(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/floatingips", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -268,8 +268,8 @@ func FloatingIPHandleCreate(t *testing.T) { }) } -func NetworkHandleList(t *testing.T) { - th.Mux.HandleFunc("/v2.0/networks", func(w http.ResponseWriter, r *http.Request) { +func NetworkHandleList(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/networks", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -282,8 +282,8 @@ func NetworkHandleList(t *testing.T) { }) } -func NetworkHandleGet(t *testing.T) { - th.Mux.HandleFunc("/v2.0/networks/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { +func NetworkHandleGet(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/networks/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -294,8 +294,8 @@ func NetworkHandleGet(t *testing.T) { }) } -func NetworkHandleCreate(t *testing.T) { - th.Mux.HandleFunc("/v2.0/networks", func(w http.ResponseWriter, r *http.Request) { +func NetworkHandleCreate(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/networks", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -308,8 +308,8 @@ func NetworkHandleCreate(t *testing.T) { }) } -func NetworkHandleUpdate(t *testing.T) { - th.Mux.HandleFunc("/v2.0/networks/db193ab3-96e3-4cb3-8fc5-05f4296d0324", func(w http.ResponseWriter, r *http.Request) { +func NetworkHandleUpdate(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/networks/db193ab3-96e3-4cb3-8fc5-05f4296d0324", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") diff --git a/openstack/networking/v2/extensions/dns/testing/requests_test.go b/openstack/networking/v2/extensions/dns/testing/requests_test.go index 3174c8c791..886be44891 100644 --- a/openstack/networking/v2/extensions/dns/testing/requests_test.go +++ b/openstack/networking/v2/extensions/dns/testing/requests_test.go @@ -32,10 +32,10 @@ var createdTime, _ = time.Parse(time.RFC3339, "2019-06-30T04:15:37Z") var updatedTime, _ = time.Parse(time.RFC3339, "2019-06-30T05:18:49Z") func TestPortList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - PortHandleListSuccessfully(t) + PortHandleListSuccessfully(t, fakeServer) var actual []PortDNS @@ -79,7 +79,7 @@ func TestPortList(t *testing.T) { DNSName: "test-port", } - allPages, err := ports.List(fake.ServiceClient(), listOptsBuilder).AllPages(context.TODO()) + allPages, err := ports.List(fake.ServiceClient(fakeServer), listOptsBuilder).AllPages(context.TODO()) th.AssertNoErr(t, err) err = ports.ExtractPortsInto(allPages, &actual) @@ -89,14 +89,14 @@ func TestPortList(t *testing.T) { } func TestPortGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - PortHandleGet(t) + PortHandleGet(t, fakeServer) var s PortDNS - err := ports.Get(context.TODO(), fake.ServiceClient(), "46d4bfb9-b26e-41f3-bd2e-e6dcc1ccedb2").ExtractInto(&s) + err := ports.Get(context.TODO(), fake.ServiceClient(fakeServer), "46d4bfb9-b26e-41f3-bd2e-e6dcc1ccedb2").ExtractInto(&s) th.AssertNoErr(t, err) th.AssertEquals(t, s.Status, "ACTIVE") @@ -124,10 +124,10 @@ func TestPortGet(t *testing.T) { } func TestPortCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - PortHandleCreate(t) + PortHandleCreate(t, fakeServer) var s PortDNS @@ -147,7 +147,7 @@ func TestPortCreate(t *testing.T) { DNSName: "test-port", } - err := ports.Create(context.TODO(), fake.ServiceClient(), createOpts).ExtractInto(&s) + err := ports.Create(context.TODO(), fake.ServiceClient(fakeServer), createOpts).ExtractInto(&s) th.AssertNoErr(t, err) th.AssertEquals(t, s.Status, "DOWN") @@ -174,20 +174,20 @@ func TestPortCreate(t *testing.T) { } func TestPortRequiredCreateOpts(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - res := ports.Create(context.TODO(), fake.ServiceClient(), dns.PortCreateOptsExt{CreateOptsBuilder: ports.CreateOpts{}}) + res := ports.Create(context.TODO(), fake.ServiceClient(fakeServer), dns.PortCreateOptsExt{CreateOptsBuilder: ports.CreateOpts{}}) if res.Err == nil { t.Fatalf("Expected error, got none") } } func TestPortUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - PortHandleUpdate(t) + PortHandleUpdate(t, fakeServer) var s PortDNS @@ -206,7 +206,7 @@ func TestPortUpdate(t *testing.T) { DNSName: &dnsName, } - err := ports.Update(context.TODO(), fake.ServiceClient(), "65c0ee9f-d634-4522-8954-51021b570b0d", updateOpts).ExtractInto(&s) + err := ports.Update(context.TODO(), fake.ServiceClient(fakeServer), "65c0ee9f-d634-4522-8954-51021b570b0d", updateOpts).ExtractInto(&s) th.AssertNoErr(t, err) th.AssertEquals(t, s.Name, "new_port_name") @@ -225,13 +225,13 @@ func TestPortUpdate(t *testing.T) { } func TestFloatingIPGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - FloatingIPHandleGet(t) + FloatingIPHandleGet(t, fakeServer) var actual FloatingIPDNS - err := floatingips.Get(context.TODO(), fake.ServiceClient(), "2f95fd2b-9f6a-4e8e-9e9a-2cbe286cbf9e").ExtractInto(&actual) + err := floatingips.Get(context.TODO(), fake.ServiceClient(fakeServer), "2f95fd2b-9f6a-4e8e-9e9a-2cbe286cbf9e").ExtractInto(&actual) th.AssertNoErr(t, err) expected := FloatingIPDNS{ @@ -257,10 +257,10 @@ func TestFloatingIPGet(t *testing.T) { } func TestFloatingIPCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - FloatingIPHandleCreate(t) + FloatingIPHandleCreate(t, fakeServer) var actual FloatingIPDNS @@ -274,7 +274,7 @@ func TestFloatingIPCreate(t *testing.T) { DNSDomain: "local.", } - err := floatingips.Create(context.TODO(), fake.ServiceClient(), options).ExtractInto(&actual) + err := floatingips.Create(context.TODO(), fake.ServiceClient(fakeServer), options).ExtractInto(&actual) th.AssertNoErr(t, err) expected := FloatingIPDNS{ @@ -300,14 +300,14 @@ func TestFloatingIPCreate(t *testing.T) { } func TestNetworkGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - NetworkHandleGet(t) + NetworkHandleGet(t, fakeServer) var actual NetworkDNS - err := networks.Get(context.TODO(), fake.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22").ExtractInto(&actual) + err := networks.Get(context.TODO(), fake.ServiceClient(fakeServer), "d32019d3-bc6e-4319-9c1d-6722fc136a22").ExtractInto(&actual) th.AssertNoErr(t, err) expected := NetworkDNS{ @@ -331,10 +331,10 @@ func TestNetworkGet(t *testing.T) { } func TestNetworkCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - NetworkHandleCreate(t) + NetworkHandleCreate(t, fakeServer) var actual NetworkDNS @@ -345,7 +345,7 @@ func TestNetworkCreate(t *testing.T) { DNSDomain: "local.", } - err := networks.Create(context.TODO(), fake.ServiceClient(), createOpts).ExtractInto(&actual) + err := networks.Create(context.TODO(), fake.ServiceClient(fakeServer), createOpts).ExtractInto(&actual) th.AssertNoErr(t, err) expected := NetworkDNS{ @@ -369,10 +369,10 @@ func TestNetworkCreate(t *testing.T) { } func TestNetworkUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - NetworkHandleUpdate(t) + NetworkHandleUpdate(t, fakeServer) var actual NetworkDNS @@ -383,7 +383,7 @@ func TestNetworkUpdate(t *testing.T) { DNSDomain: new(string), } - err := networks.Update(context.TODO(), fake.ServiceClient(), "db193ab3-96e3-4cb3-8fc5-05f4296d0324", updateOpts).ExtractInto(&actual) + err := networks.Update(context.TODO(), fake.ServiceClient(fakeServer), "db193ab3-96e3-4cb3-8fc5-05f4296d0324", updateOpts).ExtractInto(&actual) th.AssertNoErr(t, err) expected := NetworkDNS{ diff --git a/openstack/networking/v2/extensions/external/testing/results_test.go b/openstack/networking/v2/extensions/external/testing/results_test.go index bf5c02d636..8de68e70e5 100644 --- a/openstack/networking/v2/extensions/external/testing/results_test.go +++ b/openstack/networking/v2/extensions/external/testing/results_test.go @@ -14,10 +14,10 @@ import ( ) func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/networks", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/networks", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -33,7 +33,7 @@ func TestList(t *testing.T) { } var actual []NetworkWithExternalExt - allPages, err := networks.List(fake.ServiceClient(), networks.ListOpts{}).AllPages(context.TODO()) + allPages, err := networks.List(fake.ServiceClient(fakeServer), networks.ListOpts{}).AllPages(context.TODO()) th.AssertNoErr(t, err) err = networks.ExtractNetworksInto(allPages, &actual) @@ -44,10 +44,10 @@ func TestList(t *testing.T) { } func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/networks/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/networks/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -62,7 +62,7 @@ func TestGet(t *testing.T) { external.NetworkExternalExt } - err := networks.Get(context.TODO(), fake.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22").ExtractInto(&s) + err := networks.Get(context.TODO(), fake.ServiceClient(fakeServer), "d32019d3-bc6e-4319-9c1d-6722fc136a22").ExtractInto(&s) th.AssertNoErr(t, err) th.AssertEquals(t, "d32019d3-bc6e-4319-9c1d-6722fc136a22", s.ID) @@ -70,10 +70,10 @@ func TestGet(t *testing.T) { } func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/networks", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/networks", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -98,17 +98,17 @@ func TestCreate(t *testing.T) { External: &iFalse, } - _, err := networks.Create(context.TODO(), fake.ServiceClient(), externalCreateOpts).Extract() + _, err := networks.Create(context.TODO(), fake.ServiceClient(fakeServer), externalCreateOpts).Extract() th.AssertNoErr(t, err) th.AssertNoErr(t, err) } func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/networks/4e8e5957-649f-477b-9e5b-f1f75b21c03c", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/networks/4e8e5957-649f-477b-9e5b-f1f75b21c03c", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -135,6 +135,6 @@ func TestUpdate(t *testing.T) { External: &iFalse, } - _, err := networks.Update(context.TODO(), fake.ServiceClient(), "4e8e5957-649f-477b-9e5b-f1f75b21c03c", externalUpdateOpts).Extract() + _, err := networks.Update(context.TODO(), fake.ServiceClient(fakeServer), "4e8e5957-649f-477b-9e5b-f1f75b21c03c", externalUpdateOpts).Extract() th.AssertNoErr(t, err) } diff --git a/openstack/networking/v2/extensions/fwaas_v2/groups/testing/requests_test.go b/openstack/networking/v2/extensions/fwaas_v2/groups/testing/requests_test.go index 540f80aaf4..2e903b6477 100644 --- a/openstack/networking/v2/extensions/fwaas_v2/groups/testing/requests_test.go +++ b/openstack/networking/v2/extensions/fwaas_v2/groups/testing/requests_test.go @@ -13,10 +13,10 @@ import ( ) func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/fwaas/firewall_groups", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/fwaas/firewall_groups", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -68,7 +68,7 @@ func TestList(t *testing.T) { count := 0 - err := groups.List(fake.ServiceClient(), groups.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := groups.List(fake.ServiceClient(fakeServer), groups.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := groups.ExtractGroups(page) if err != nil { @@ -126,10 +126,10 @@ func TestList(t *testing.T) { } func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/fwaas/firewall_groups/6bfb0f10-07f7-4a40-b534-bad4b4ca3428", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/fwaas/firewall_groups/6bfb0f10-07f7-4a40-b534-bad4b4ca3428", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -157,7 +157,7 @@ func TestGet(t *testing.T) { `) }) - group, err := groups.Get(context.TODO(), fake.ServiceClient(), "6bfb0f10-07f7-4a40-b534-bad4b4ca3428").Extract() + group, err := groups.Get(context.TODO(), fake.ServiceClient(fakeServer), "6bfb0f10-07f7-4a40-b534-bad4b4ca3428").Extract() th.AssertNoErr(t, err) th.AssertEquals(t, "6bfb0f10-07f7-4a40-b534-bad4b4ca3428", group.ID) @@ -175,10 +175,10 @@ func TestGet(t *testing.T) { } func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/fwaas/firewall_groups", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/fwaas/firewall_groups", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -230,15 +230,15 @@ func TestCreate(t *testing.T) { }, } - _, err := groups.Create(context.TODO(), fake.ServiceClient(), options).Extract() + _, err := groups.Create(context.TODO(), fake.ServiceClient(fakeServer), options).Extract() th.AssertNoErr(t, err) } func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/fwaas/firewall_groups/6bfb0f10-07f7-4a40-b534-bad4b4ca3428", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/fwaas/firewall_groups/6bfb0f10-07f7-4a40-b534-bad4b4ca3428", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -295,15 +295,15 @@ func TestUpdate(t *testing.T) { AdminStateUp: &adminStateUp, } - _, err := groups.Update(context.TODO(), fake.ServiceClient(), "6bfb0f10-07f7-4a40-b534-bad4b4ca3428", options).Extract() + _, err := groups.Update(context.TODO(), fake.ServiceClient(fakeServer), "6bfb0f10-07f7-4a40-b534-bad4b4ca3428", options).Extract() th.AssertNoErr(t, err) } func TestRemoveIngressPolicy(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/fwaas/firewall_groups/6bfb0f10-07f7-4a40-b534-bad4b4ca3428", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/fwaas/firewall_groups/6bfb0f10-07f7-4a40-b534-bad4b4ca3428", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -341,17 +341,17 @@ func TestRemoveIngressPolicy(t *testing.T) { `) }) - removeIngressPolicy, err := groups.RemoveIngressPolicy(context.TODO(), fake.ServiceClient(), "6bfb0f10-07f7-4a40-b534-bad4b4ca3428").Extract() + removeIngressPolicy, err := groups.RemoveIngressPolicy(context.TODO(), fake.ServiceClient(fakeServer), "6bfb0f10-07f7-4a40-b534-bad4b4ca3428").Extract() th.AssertNoErr(t, err) th.AssertEquals(t, removeIngressPolicy.IngressFirewallPolicyID, "") th.AssertEquals(t, removeIngressPolicy.EgressFirewallPolicyID, "43a11f3a-ddac-4129-9469-02b9df26548e") } func TestRemoveEgressPolicy(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/fwaas/firewall_groups/6bfb0f10-07f7-4a40-b534-bad4b4ca3428", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/fwaas/firewall_groups/6bfb0f10-07f7-4a40-b534-bad4b4ca3428", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -389,22 +389,22 @@ func TestRemoveEgressPolicy(t *testing.T) { `) }) - removeEgressPolicy, err := groups.RemoveEgressPolicy(context.TODO(), fake.ServiceClient(), "6bfb0f10-07f7-4a40-b534-bad4b4ca3428").Extract() + removeEgressPolicy, err := groups.RemoveEgressPolicy(context.TODO(), fake.ServiceClient(fakeServer), "6bfb0f10-07f7-4a40-b534-bad4b4ca3428").Extract() th.AssertNoErr(t, err) th.AssertEquals(t, removeEgressPolicy.IngressFirewallPolicyID, "e3f11142-3792-454b-8d3e-91ac1bf127b4") th.AssertEquals(t, removeEgressPolicy.EgressFirewallPolicyID, "") } func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/fwaas/firewall_groups/4ec89077-d057-4a2b-911f-60a3b47ee304", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/fwaas/firewall_groups/4ec89077-d057-4a2b-911f-60a3b47ee304", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.WriteHeader(http.StatusNoContent) }) - res := groups.Delete(context.TODO(), fake.ServiceClient(), "4ec89077-d057-4a2b-911f-60a3b47ee304") + res := groups.Delete(context.TODO(), fake.ServiceClient(fakeServer), "4ec89077-d057-4a2b-911f-60a3b47ee304") th.AssertNoErr(t, res.Err) } diff --git a/openstack/networking/v2/extensions/fwaas_v2/policies/testing/requests_test.go b/openstack/networking/v2/extensions/fwaas_v2/policies/testing/requests_test.go index 217c062f4c..6fb8318214 100644 --- a/openstack/networking/v2/extensions/fwaas_v2/policies/testing/requests_test.go +++ b/openstack/networking/v2/extensions/fwaas_v2/policies/testing/requests_test.go @@ -14,10 +14,10 @@ import ( ) func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/fwaas/firewall_policies", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/fwaas/firewall_policies", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -59,7 +59,7 @@ func TestList(t *testing.T) { count := 0 - err := policies.List(fake.ServiceClient(), policies.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := policies.List(fake.ServiceClient(fakeServer), policies.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := policies.ExtractPolicies(page) if err != nil { @@ -107,10 +107,10 @@ func TestList(t *testing.T) { } func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/fwaas/firewall_policies", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/fwaas/firewall_policies", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -166,15 +166,15 @@ func TestCreate(t *testing.T) { }, } - _, err := policies.Create(context.TODO(), fake.ServiceClient(), options).Extract() + _, err := policies.Create(context.TODO(), fake.ServiceClient(fakeServer), options).Extract() th.AssertNoErr(t, err) } func TestInsertRule(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/fwaas/firewall_policies/e3c78ab6-e827-4297-8d68-739063865a8b/insert_rule", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/fwaas/firewall_policies/e3c78ab6-e827-4297-8d68-739063865a8b/insert_rule", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -211,7 +211,7 @@ func TestInsertRule(t *testing.T) { InsertBefore: "3062ed90-1fb0-4c25-af3d-318dff2143ae", } - policy, err := policies.InsertRule(context.TODO(), fake.ServiceClient(), "e3c78ab6-e827-4297-8d68-739063865a8b", options).Extract() + policy, err := policies.InsertRule(context.TODO(), fake.ServiceClient(fakeServer), "e3c78ab6-e827-4297-8d68-739063865a8b", options).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, "TESTACC-2LnMayeG", policy.Name) th.AssertEquals(t, 2, len(policy.Rules)) @@ -224,8 +224,8 @@ func TestInsertRule(t *testing.T) { } func TestInsertRuleWithInvalidParameters(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() //invalid opts, its not allowed to specify InsertBefore and InsertAfter together options := policies.InsertRuleOpts{ @@ -234,7 +234,7 @@ func TestInsertRuleWithInvalidParameters(t *testing.T) { InsertAfter: "2", } - _, err := policies.InsertRule(context.TODO(), fake.ServiceClient(), "0", options).Extract() + _, err := policies.InsertRule(context.TODO(), fake.ServiceClient(fakeServer), "0", options).Extract() // expect to fail with an gophercloud error th.AssertErr(t, err) @@ -242,10 +242,10 @@ func TestInsertRuleWithInvalidParameters(t *testing.T) { } func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/fwaas/firewall_policies/f2b08c1e-aa81-4668-8ae1-1401bcb0576c", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/fwaas/firewall_policies/f2b08c1e-aa81-4668-8ae1-1401bcb0576c", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -271,7 +271,7 @@ func TestGet(t *testing.T) { `) }) - policy, err := policies.Get(context.TODO(), fake.ServiceClient(), "f2b08c1e-aa81-4668-8ae1-1401bcb0576c").Extract() + policy, err := policies.Get(context.TODO(), fake.ServiceClient(fakeServer), "f2b08c1e-aa81-4668-8ae1-1401bcb0576c").Extract() th.AssertNoErr(t, err) th.AssertEquals(t, "www", policy.Name) @@ -286,10 +286,10 @@ func TestGet(t *testing.T) { } func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/fwaas/firewall_policies/f2b08c1e-aa81-4668-8ae1-1401bcb0576c", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/fwaas/firewall_policies/f2b08c1e-aa81-4668-8ae1-1401bcb0576c", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -341,29 +341,29 @@ func TestUpdate(t *testing.T) { }, } - _, err := policies.Update(context.TODO(), fake.ServiceClient(), "f2b08c1e-aa81-4668-8ae1-1401bcb0576c", options).Extract() + _, err := policies.Update(context.TODO(), fake.ServiceClient(fakeServer), "f2b08c1e-aa81-4668-8ae1-1401bcb0576c", options).Extract() th.AssertNoErr(t, err) } func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/fwaas/firewall_policies/4ec89077-d057-4a2b-911f-60a3b47ee304", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/fwaas/firewall_policies/4ec89077-d057-4a2b-911f-60a3b47ee304", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.WriteHeader(http.StatusNoContent) }) - res := policies.Delete(context.TODO(), fake.ServiceClient(), "4ec89077-d057-4a2b-911f-60a3b47ee304") + res := policies.Delete(context.TODO(), fake.ServiceClient(fakeServer), "4ec89077-d057-4a2b-911f-60a3b47ee304") th.AssertNoErr(t, res.Err) } func TestRemoveRule(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/fwaas/firewall_policies/9fed8075-06ee-463f-83a6-d4118791b02f/remove_rule", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/fwaas/firewall_policies/9fed8075-06ee-463f-83a6-d4118791b02f/remove_rule", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -393,7 +393,7 @@ func TestRemoveRule(t *testing.T) { `) }) - policy, err := policies.RemoveRule(context.TODO(), fake.ServiceClient(), "9fed8075-06ee-463f-83a6-d4118791b02f", "9fed8075-06ee-463f-83a6-d4118791b02f").Extract() + policy, err := policies.RemoveRule(context.TODO(), fake.ServiceClient(fakeServer), "9fed8075-06ee-463f-83a6-d4118791b02f", "9fed8075-06ee-463f-83a6-d4118791b02f").Extract() th.AssertNoErr(t, err) th.AssertEquals(t, "9fed8075-06ee-463f-83a6-d4118791b02f", policy.ID) diff --git a/openstack/networking/v2/extensions/fwaas_v2/rules/testing/requests_test.go b/openstack/networking/v2/extensions/fwaas_v2/rules/testing/requests_test.go index f251c563c0..78419e4b81 100644 --- a/openstack/networking/v2/extensions/fwaas_v2/rules/testing/requests_test.go +++ b/openstack/networking/v2/extensions/fwaas_v2/rules/testing/requests_test.go @@ -14,10 +14,10 @@ import ( ) func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/fwaas/firewall_rules", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/fwaas/firewall_rules", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -68,7 +68,7 @@ func TestList(t *testing.T) { count := 0 - err := rules.List(fake.ServiceClient(), rules.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := rules.List(fake.ServiceClient(fakeServer), rules.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := rules.ExtractRules(page) if err != nil { @@ -124,10 +124,10 @@ func TestList(t *testing.T) { } } func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/fwaas/firewall_rules", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/fwaas/firewall_rules", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -185,15 +185,15 @@ func TestCreate(t *testing.T) { Action: "allow", } - _, err := rules.Create(context.TODO(), fake.ServiceClient(), options).Extract() + _, err := rules.Create(context.TODO(), fake.ServiceClient(fakeServer), options).Extract() th.AssertNoErr(t, err) } func TestCreateAnyProtocol(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/fwaas/firewall_rules", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/fwaas/firewall_rules", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -249,15 +249,15 @@ func TestCreateAnyProtocol(t *testing.T) { Action: "allow", } - _, err := rules.Create(context.TODO(), fake.ServiceClient(), options).Extract() + _, err := rules.Create(context.TODO(), fake.ServiceClient(fakeServer), options).Extract() th.AssertNoErr(t, err) } func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/fwaas/firewall_rules/f03bd950-6c56-4f5e-a307-45967078f507", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/fwaas/firewall_rules/f03bd950-6c56-4f5e-a307-45967078f507", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -288,7 +288,7 @@ func TestGet(t *testing.T) { `) }) - rule, err := rules.Get(context.TODO(), fake.ServiceClient(), "f03bd950-6c56-4f5e-a307-45967078f507").Extract() + rule, err := rules.Get(context.TODO(), fake.ServiceClient(fakeServer), "f03bd950-6c56-4f5e-a307-45967078f507").Extract() th.AssertNoErr(t, err) th.AssertEquals(t, "tcp", rule.Protocol) @@ -308,10 +308,10 @@ func TestGet(t *testing.T) { } func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/fwaas/firewall_rules/f03bd950-6c56-4f5e-a307-45967078f507", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/fwaas/firewall_rules/f03bd950-6c56-4f5e-a307-45967078f507", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -372,20 +372,20 @@ func TestUpdate(t *testing.T) { Enabled: gophercloud.Disabled, } - _, err := rules.Update(context.TODO(), fake.ServiceClient(), "f03bd950-6c56-4f5e-a307-45967078f507", options).Extract() + _, err := rules.Update(context.TODO(), fake.ServiceClient(fakeServer), "f03bd950-6c56-4f5e-a307-45967078f507", options).Extract() th.AssertNoErr(t, err) } func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/fwaas/firewall_rules/4ec89077-d057-4a2b-911f-60a3b47ee304", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/fwaas/firewall_rules/4ec89077-d057-4a2b-911f-60a3b47ee304", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.WriteHeader(http.StatusNoContent) }) - res := rules.Delete(context.TODO(), fake.ServiceClient(), "4ec89077-d057-4a2b-911f-60a3b47ee304") + res := rules.Delete(context.TODO(), fake.ServiceClient(fakeServer), "4ec89077-d057-4a2b-911f-60a3b47ee304") th.AssertNoErr(t, res.Err) } diff --git a/openstack/networking/v2/extensions/layer3/addressscopes/testing/requests_test.go b/openstack/networking/v2/extensions/layer3/addressscopes/testing/requests_test.go index 815a0c0f08..10738657bb 100644 --- a/openstack/networking/v2/extensions/layer3/addressscopes/testing/requests_test.go +++ b/openstack/networking/v2/extensions/layer3/addressscopes/testing/requests_test.go @@ -13,10 +13,10 @@ import ( ) func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/address-scopes", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/address-scopes", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -28,7 +28,7 @@ func TestList(t *testing.T) { count := 0 - err := addressscopes.List(fake.ServiceClient(), addressscopes.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := addressscopes.List(fake.ServiceClient(fakeServer), addressscopes.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := addressscopes.ExtractAddressScopes(page) if err != nil { @@ -53,10 +53,10 @@ func TestList(t *testing.T) { } func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/address-scopes/9cc35860-522a-4d35-974d-51d4b011801e", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/address-scopes/9cc35860-522a-4d35-974d-51d4b011801e", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -66,7 +66,7 @@ func TestGet(t *testing.T) { fmt.Fprint(w, AddressScopesGetResult) }) - s, err := addressscopes.Get(context.TODO(), fake.ServiceClient(), "9cc35860-522a-4d35-974d-51d4b011801e").Extract() + s, err := addressscopes.Get(context.TODO(), fake.ServiceClient(fakeServer), "9cc35860-522a-4d35-974d-51d4b011801e").Extract() th.AssertNoErr(t, err) th.AssertEquals(t, s.ID, "9cc35860-522a-4d35-974d-51d4b011801e") @@ -78,10 +78,10 @@ func TestGet(t *testing.T) { } func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/address-scopes", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/address-scopes", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -99,7 +99,7 @@ func TestCreate(t *testing.T) { Shared: true, Name: "test0", } - s, err := addressscopes.Create(context.TODO(), fake.ServiceClient(), opts).Extract() + s, err := addressscopes.Create(context.TODO(), fake.ServiceClient(fakeServer), opts).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, s.Name, "test0") @@ -111,10 +111,10 @@ func TestCreate(t *testing.T) { } func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/address-scopes/9cc35860-522a-4d35-974d-51d4b011801e", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/address-scopes/9cc35860-522a-4d35-974d-51d4b011801e", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -133,7 +133,7 @@ func TestUpdate(t *testing.T) { Name: &newName, Shared: &shared, } - s, err := addressscopes.Update(context.TODO(), fake.ServiceClient(), "9cc35860-522a-4d35-974d-51d4b011801e", updateOpts).Extract() + s, err := addressscopes.Update(context.TODO(), fake.ServiceClient(fakeServer), "9cc35860-522a-4d35-974d-51d4b011801e", updateOpts).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, s.Name, "test1") @@ -141,15 +141,15 @@ func TestUpdate(t *testing.T) { } func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/address-scopes/9cc35860-522a-4d35-974d-51d4b011801e", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/address-scopes/9cc35860-522a-4d35-974d-51d4b011801e", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.WriteHeader(http.StatusNoContent) }) - res := addressscopes.Delete(context.TODO(), fake.ServiceClient(), "9cc35860-522a-4d35-974d-51d4b011801e") + res := addressscopes.Delete(context.TODO(), fake.ServiceClient(fakeServer), "9cc35860-522a-4d35-974d-51d4b011801e") th.AssertNoErr(t, res.Err) } diff --git a/openstack/networking/v2/extensions/layer3/extraroutes/testing/requests_test.go b/openstack/networking/v2/extensions/layer3/extraroutes/testing/requests_test.go index 35d7516e1c..ec1676290d 100644 --- a/openstack/networking/v2/extensions/layer3/extraroutes/testing/requests_test.go +++ b/openstack/networking/v2/extensions/layer3/extraroutes/testing/requests_test.go @@ -13,10 +13,10 @@ import ( ) func TestAddExtraRoutes(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/routers/4e8e5957-649f-477b-9e5b-f1f75b21c03c/add_extraroutes", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/routers/4e8e5957-649f-477b-9e5b-f1f75b21c03c/add_extraroutes", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -63,7 +63,7 @@ func TestAddExtraRoutes(t *testing.T) { } options := extraroutes.Opts{Routes: &r} - n, err := extraroutes.Add(context.TODO(), fake.ServiceClient(), "4e8e5957-649f-477b-9e5b-f1f75b21c03c", options).Extract() + n, err := extraroutes.Add(context.TODO(), fake.ServiceClient(fakeServer), "4e8e5957-649f-477b-9e5b-f1f75b21c03c", options).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, n.Routes, []routers.Route{ @@ -87,10 +87,10 @@ func TestAddExtraRoutes(t *testing.T) { } func TestRemoveExtraRoutes(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/routers/4e8e5957-649f-477b-9e5b-f1f75b21c03c/remove_extraroutes", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/routers/4e8e5957-649f-477b-9e5b-f1f75b21c03c/remove_extraroutes", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -135,7 +135,7 @@ func TestRemoveExtraRoutes(t *testing.T) { } options := extraroutes.Opts{Routes: &r} - n, err := extraroutes.Remove(context.TODO(), fake.ServiceClient(), "4e8e5957-649f-477b-9e5b-f1f75b21c03c", options).Extract() + n, err := extraroutes.Remove(context.TODO(), fake.ServiceClient(fakeServer), "4e8e5957-649f-477b-9e5b-f1f75b21c03c", options).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, n.Routes, []routers.Route{ diff --git a/openstack/networking/v2/extensions/layer3/floatingips/testing/requests_test.go b/openstack/networking/v2/extensions/layer3/floatingips/testing/requests_test.go index 7b213110d7..4447b04ad4 100644 --- a/openstack/networking/v2/extensions/layer3/floatingips/testing/requests_test.go +++ b/openstack/networking/v2/extensions/layer3/floatingips/testing/requests_test.go @@ -14,10 +14,10 @@ import ( ) func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/floatingips", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/floatingips", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -29,7 +29,7 @@ func TestList(t *testing.T) { count := 0 - err := floatingips.List(fake.ServiceClient(), floatingips.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := floatingips.List(fake.ServiceClient(fakeServer), floatingips.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := floatingips.ExtractFloatingIPs(page) if err != nil { @@ -82,16 +82,16 @@ func TestList(t *testing.T) { } func TestInvalidNextPageURLs(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/floatingips", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/floatingips", func(w http.ResponseWriter, r *http.Request) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) fmt.Fprint(w, `{"floatingips": [{}], "floatingips_links": {}}`) }) - err := floatingips.List(fake.ServiceClient(), floatingips.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := floatingips.List(fake.ServiceClient(fakeServer), floatingips.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { _, err := floatingips.ExtractFloatingIPs(page) if err != nil { return false, err @@ -102,25 +102,25 @@ func TestInvalidNextPageURLs(t *testing.T) { } func TestRequiredCreateOpts(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - res1 := floatingips.Create(context.TODO(), fake.ServiceClient(), floatingips.CreateOpts{FloatingNetworkID: ""}) + res1 := floatingips.Create(context.TODO(), fake.ServiceClient(fakeServer), floatingips.CreateOpts{FloatingNetworkID: ""}) if res1.Err == nil { t.Fatalf("Expected error, got none") } - res2 := floatingips.Create(context.TODO(), fake.ServiceClient(), floatingips.CreateOpts{FloatingNetworkID: "foo", PortID: ""}) + res2 := floatingips.Create(context.TODO(), fake.ServiceClient(fakeServer), floatingips.CreateOpts{FloatingNetworkID: "foo", PortID: ""}) if res2.Err == nil { t.Fatalf("Expected error, got none") } } func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/floatingips", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/floatingips", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -159,7 +159,7 @@ func TestCreate(t *testing.T) { PortID: "ce705c24-c1ef-408a-bda3-7bbd946164ab", } - ip, err := floatingips.Create(context.TODO(), fake.ServiceClient(), options).Extract() + ip, err := floatingips.Create(context.TODO(), fake.ServiceClient(fakeServer), options).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, "2f245a7b-796b-4f26-9cf9-9e82d248fda7", ip.ID) @@ -173,10 +173,10 @@ func TestCreate(t *testing.T) { } func TestCreateEmptyPort(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/floatingips", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/floatingips", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -212,7 +212,7 @@ func TestCreateEmptyPort(t *testing.T) { FloatingNetworkID: "376da547-b977-4cfe-9cba-275c80debf57", } - ip, err := floatingips.Create(context.TODO(), fake.ServiceClient(), options).Extract() + ip, err := floatingips.Create(context.TODO(), fake.ServiceClient(fakeServer), options).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, "2f245a7b-796b-4f26-9cf9-9e82d248fda7", ip.ID) @@ -226,10 +226,10 @@ func TestCreateEmptyPort(t *testing.T) { } func TestCreateWithSubnetID(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/floatingips", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/floatingips", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -268,7 +268,7 @@ func TestCreateWithSubnetID(t *testing.T) { SubnetID: "37adf01c-24db-467a-b845-7ab1e8216c01", } - ip, err := floatingips.Create(context.TODO(), fake.ServiceClient(), options).Extract() + ip, err := floatingips.Create(context.TODO(), fake.ServiceClient(fakeServer), options).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, "2f245a7b-796b-4f26-9cf9-9e82d248fda7", ip.ID) @@ -282,10 +282,10 @@ func TestCreateWithSubnetID(t *testing.T) { } func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/floatingips/2f245a7b-796b-4f26-9cf9-9e82d248fda7", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/floatingips/2f245a7b-796b-4f26-9cf9-9e82d248fda7", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -310,7 +310,7 @@ func TestGet(t *testing.T) { `) }) - ip, err := floatingips.Get(context.TODO(), fake.ServiceClient(), "2f245a7b-796b-4f26-9cf9-9e82d248fda7").Extract() + ip, err := floatingips.Get(context.TODO(), fake.ServiceClient(fakeServer), "2f245a7b-796b-4f26-9cf9-9e82d248fda7").Extract() th.AssertNoErr(t, err) th.AssertEquals(t, "90f742b1-6d17-487b-ba95-71881dbc0b64", ip.FloatingNetworkID) @@ -326,10 +326,10 @@ func TestGet(t *testing.T) { } func TestAssociate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/floatingips/2f245a7b-796b-4f26-9cf9-9e82d248fda7", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/floatingips/2f245a7b-796b-4f26-9cf9-9e82d248fda7", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -361,17 +361,17 @@ func TestAssociate(t *testing.T) { }) portID := "423abc8d-2991-4a55-ba98-2aaea84cc72e" - ip, err := floatingips.Update(context.TODO(), fake.ServiceClient(), "2f245a7b-796b-4f26-9cf9-9e82d248fda7", floatingips.UpdateOpts{PortID: &portID}).Extract() + ip, err := floatingips.Update(context.TODO(), fake.ServiceClient(fakeServer), "2f245a7b-796b-4f26-9cf9-9e82d248fda7", floatingips.UpdateOpts{PortID: &portID}).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, portID, ip.PortID) } func TestDisassociate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/floatingips/2f245a7b-796b-4f26-9cf9-9e82d248fda7", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/floatingips/2f245a7b-796b-4f26-9cf9-9e82d248fda7", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -402,7 +402,7 @@ func TestDisassociate(t *testing.T) { `) }) - ip, err := floatingips.Update(context.TODO(), fake.ServiceClient(), "2f245a7b-796b-4f26-9cf9-9e82d248fda7", floatingips.UpdateOpts{PortID: new(string)}).Extract() + ip, err := floatingips.Update(context.TODO(), fake.ServiceClient(fakeServer), "2f245a7b-796b-4f26-9cf9-9e82d248fda7", floatingips.UpdateOpts{PortID: new(string)}).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, "", ip.FixedIP) @@ -410,15 +410,15 @@ func TestDisassociate(t *testing.T) { } func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/floatingips/2f245a7b-796b-4f26-9cf9-9e82d248fda7", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/floatingips/2f245a7b-796b-4f26-9cf9-9e82d248fda7", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.WriteHeader(http.StatusNoContent) }) - res := floatingips.Delete(context.TODO(), fake.ServiceClient(), "2f245a7b-796b-4f26-9cf9-9e82d248fda7") + res := floatingips.Delete(context.TODO(), fake.ServiceClient(fakeServer), "2f245a7b-796b-4f26-9cf9-9e82d248fda7") th.AssertNoErr(t, res.Err) } diff --git a/openstack/networking/v2/extensions/layer3/portforwarding/testing/requests_test.go b/openstack/networking/v2/extensions/layer3/portforwarding/testing/requests_test.go index dc2aa8c49b..57f7fce6c8 100644 --- a/openstack/networking/v2/extensions/layer3/portforwarding/testing/requests_test.go +++ b/openstack/networking/v2/extensions/layer3/portforwarding/testing/requests_test.go @@ -13,10 +13,10 @@ import ( ) func TestPortForwardingList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/floatingips/2f95fd2b-9f6a-4e8e-9e9a-2cbe286cbf9e/port_forwardings", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/floatingips/2f95fd2b-9f6a-4e8e-9e9a-2cbe286cbf9e/port_forwardings", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -28,7 +28,7 @@ func TestPortForwardingList(t *testing.T) { count := 0 - err := portforwarding.List(fake.ServiceClient(), portforwarding.ListOpts{}, "2f95fd2b-9f6a-4e8e-9e9a-2cbe286cbf9e").EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := portforwarding.List(fake.ServiceClient(fakeServer), portforwarding.ListOpts{}, "2f95fd2b-9f6a-4e8e-9e9a-2cbe286cbf9e").EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := portforwarding.ExtractPortForwardings(page) if err != nil { @@ -67,10 +67,10 @@ func TestPortForwardingList(t *testing.T) { } func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/floatingips/2f95fd2b-9f6a-4e8e-9e9a-2cbe286cbf9e/port_forwardings", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/floatingips/2f95fd2b-9f6a-4e8e-9e9a-2cbe286cbf9e/port_forwardings", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -112,7 +112,7 @@ func TestCreate(t *testing.T) { InternalPortID: "1238be08-a2a8-4b8d-addf-fb5e2250e480", } - pf, err := portforwarding.Create(context.TODO(), fake.ServiceClient(), "2f95fd2b-9f6a-4e8e-9e9a-2cbe286cbf9e", options).Extract() + pf, err := portforwarding.Create(context.TODO(), fake.ServiceClient(fakeServer), "2f95fd2b-9f6a-4e8e-9e9a-2cbe286cbf9e", options).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, "725ade3c-9760-4880-8080-8fc2dbab9acc", pf.ID) @@ -124,10 +124,10 @@ func TestCreate(t *testing.T) { } func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/floatingips/2f245a7b-796b-4f26-9cf9-9e82d248fda7/port_forwardings/725ade3c-9760-4880-8080-8fc2dbab9acc", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/floatingips/2f245a7b-796b-4f26-9cf9-9e82d248fda7/port_forwardings/725ade3c-9760-4880-8080-8fc2dbab9acc", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -148,7 +148,7 @@ func TestGet(t *testing.T) { `) }) - pf, err := portforwarding.Get(context.TODO(), fake.ServiceClient(), "2f245a7b-796b-4f26-9cf9-9e82d248fda7", "725ade3c-9760-4880-8080-8fc2dbab9acc").Extract() + pf, err := portforwarding.Get(context.TODO(), fake.ServiceClient(fakeServer), "2f245a7b-796b-4f26-9cf9-9e82d248fda7", "725ade3c-9760-4880-8080-8fc2dbab9acc").Extract() th.AssertNoErr(t, err) th.AssertEquals(t, "tcp", pf.Protocol) @@ -160,24 +160,24 @@ func TestGet(t *testing.T) { } func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/floatingips/2f245a7b-796b-4f26-9cf9-9e82d248fda7/port_forwardings/725ade3c-9760-4880-8080-8fc2dbab9acc", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/floatingips/2f245a7b-796b-4f26-9cf9-9e82d248fda7/port_forwardings/725ade3c-9760-4880-8080-8fc2dbab9acc", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.WriteHeader(http.StatusNoContent) }) - res := portforwarding.Delete(context.TODO(), fake.ServiceClient(), "2f245a7b-796b-4f26-9cf9-9e82d248fda7", "725ade3c-9760-4880-8080-8fc2dbab9acc") + res := portforwarding.Delete(context.TODO(), fake.ServiceClient(fakeServer), "2f245a7b-796b-4f26-9cf9-9e82d248fda7", "725ade3c-9760-4880-8080-8fc2dbab9acc") th.AssertNoErr(t, res.Err) } func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/floatingips/2f245a7b-796b-4f26-9cf9-9e82d248fda7/port_forwardings/725ade3c-9760-4880-8080-8fc2dbab9acc", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/floatingips/2f245a7b-796b-4f26-9cf9-9e82d248fda7/port_forwardings/725ade3c-9760-4880-8080-8fc2dbab9acc", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -221,7 +221,7 @@ func TestUpdate(t *testing.T) { ExternalPort: updatedExternalPort, } - actual, err := portforwarding.Update(context.TODO(), fake.ServiceClient(), "2f245a7b-796b-4f26-9cf9-9e82d248fda7", "725ade3c-9760-4880-8080-8fc2dbab9acc", options).Extract() + actual, err := portforwarding.Update(context.TODO(), fake.ServiceClient(fakeServer), "2f245a7b-796b-4f26-9cf9-9e82d248fda7", "725ade3c-9760-4880-8080-8fc2dbab9acc", options).Extract() th.AssertNoErr(t, err) expected := portforwarding.PortForwarding{ Protocol: "udp", diff --git a/openstack/networking/v2/extensions/layer3/routers/testing/requests_test.go b/openstack/networking/v2/extensions/layer3/routers/testing/requests_test.go index 679d30aa28..f66dda4e06 100644 --- a/openstack/networking/v2/extensions/layer3/routers/testing/requests_test.go +++ b/openstack/networking/v2/extensions/layer3/routers/testing/requests_test.go @@ -14,10 +14,10 @@ import ( ) func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/routers", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/routers", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -70,7 +70,7 @@ func TestList(t *testing.T) { count := 0 - err := routers.List(fake.ServiceClient(), routers.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := routers.List(fake.ServiceClient(fakeServer), routers.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := routers.ExtractRouters(page) if err != nil { @@ -127,10 +127,10 @@ func TestList(t *testing.T) { } func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/routers", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/routers", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -199,7 +199,7 @@ func TestCreate(t *testing.T) { GatewayInfo: &gwi, AvailabilityZoneHints: []string{"zone1", "zone2"}, } - r, err := routers.Create(context.TODO(), fake.ServiceClient(), options).Extract() + r, err := routers.Create(context.TODO(), fake.ServiceClient(fakeServer), options).Extract() th.AssertNoErr(t, err) gwi.ExternalFixedIPs = []routers.ExternalFixedIP{{ @@ -214,10 +214,10 @@ func TestCreate(t *testing.T) { } func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/routers/a07eea83-7710-4860-931b-5fe220fae533", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/routers/a07eea83-7710-4860-931b-5fe220fae533", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -252,7 +252,7 @@ func TestGet(t *testing.T) { `) }) - n, err := routers.Get(context.TODO(), fake.ServiceClient(), "a07eea83-7710-4860-931b-5fe220fae533").Extract() + n, err := routers.Get(context.TODO(), fake.ServiceClient(fakeServer), "a07eea83-7710-4860-931b-5fe220fae533").Extract() th.AssertNoErr(t, err) th.AssertEquals(t, n.Status, "ACTIVE") @@ -272,10 +272,10 @@ func TestGet(t *testing.T) { } func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/routers/4e8e5957-649f-477b-9e5b-f1f75b21c03c", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/routers/4e8e5957-649f-477b-9e5b-f1f75b21c03c", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -335,7 +335,7 @@ func TestUpdate(t *testing.T) { r := []routers.Route{{DestinationCIDR: "40.0.1.0/24", NextHop: "10.1.0.10"}} options := routers.UpdateOpts{Name: "new_name", GatewayInfo: &gwi, Routes: &r} - n, err := routers.Update(context.TODO(), fake.ServiceClient(), "4e8e5957-649f-477b-9e5b-f1f75b21c03c", options).Extract() + n, err := routers.Update(context.TODO(), fake.ServiceClient(fakeServer), "4e8e5957-649f-477b-9e5b-f1f75b21c03c", options).Extract() th.AssertNoErr(t, err) gwi.ExternalFixedIPs = []routers.ExternalFixedIP{ @@ -348,10 +348,10 @@ func TestUpdate(t *testing.T) { } func TestUpdateWithoutRoutes(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/routers/4e8e5957-649f-477b-9e5b-f1f75b21c03c", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/routers/4e8e5957-649f-477b-9e5b-f1f75b21c03c", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -395,7 +395,7 @@ func TestUpdateWithoutRoutes(t *testing.T) { options := routers.UpdateOpts{Name: "new_name"} - n, err := routers.Update(context.TODO(), fake.ServiceClient(), "4e8e5957-649f-477b-9e5b-f1f75b21c03c", options).Extract() + n, err := routers.Update(context.TODO(), fake.ServiceClient(fakeServer), "4e8e5957-649f-477b-9e5b-f1f75b21c03c", options).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, n.Name, "new_name") @@ -403,10 +403,10 @@ func TestUpdateWithoutRoutes(t *testing.T) { } func TestAllRoutesRemoved(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/routers/4e8e5957-649f-477b-9e5b-f1f75b21c03c", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/routers/4e8e5957-649f-477b-9e5b-f1f75b21c03c", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -443,31 +443,31 @@ func TestAllRoutesRemoved(t *testing.T) { r := []routers.Route{} options := routers.UpdateOpts{Routes: &r} - n, err := routers.Update(context.TODO(), fake.ServiceClient(), "4e8e5957-649f-477b-9e5b-f1f75b21c03c", options).Extract() + n, err := routers.Update(context.TODO(), fake.ServiceClient(fakeServer), "4e8e5957-649f-477b-9e5b-f1f75b21c03c", options).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, n.Routes, []routers.Route{}) } func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/routers/4e8e5957-649f-477b-9e5b-f1f75b21c03c", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/routers/4e8e5957-649f-477b-9e5b-f1f75b21c03c", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.WriteHeader(http.StatusNoContent) }) - res := routers.Delete(context.TODO(), fake.ServiceClient(), "4e8e5957-649f-477b-9e5b-f1f75b21c03c") + res := routers.Delete(context.TODO(), fake.ServiceClient(fakeServer), "4e8e5957-649f-477b-9e5b-f1f75b21c03c") th.AssertNoErr(t, res.Err) } func TestAddInterface(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/routers/4e8e5957-649f-477b-9e5b-f1f75b21c03c/add_router_interface", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/routers/4e8e5957-649f-477b-9e5b-f1f75b21c03c/add_router_interface", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -492,7 +492,7 @@ func TestAddInterface(t *testing.T) { }) opts := routers.AddInterfaceOpts{SubnetID: "a2f1f29d-571b-4533-907f-5803ab96ead1"} - res, err := routers.AddInterface(context.TODO(), fake.ServiceClient(), "4e8e5957-649f-477b-9e5b-f1f75b21c03c", opts).Extract() + res, err := routers.AddInterface(context.TODO(), fake.ServiceClient(fakeServer), "4e8e5957-649f-477b-9e5b-f1f75b21c03c", opts).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, "0d32a837-8069-4ec3-84c4-3eef3e10b188", res.SubnetID) @@ -502,24 +502,24 @@ func TestAddInterface(t *testing.T) { } func TestAddInterfaceRequiredOpts(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - _, err := routers.AddInterface(context.TODO(), fake.ServiceClient(), "foo", routers.AddInterfaceOpts{}).Extract() + _, err := routers.AddInterface(context.TODO(), fake.ServiceClient(fakeServer), "foo", routers.AddInterfaceOpts{}).Extract() if err == nil { t.Fatalf("Expected error, got none") } - _, err = routers.AddInterface(context.TODO(), fake.ServiceClient(), "foo", routers.AddInterfaceOpts{SubnetID: "bar", PortID: "baz"}).Extract() + _, err = routers.AddInterface(context.TODO(), fake.ServiceClient(fakeServer), "foo", routers.AddInterfaceOpts{SubnetID: "bar", PortID: "baz"}).Extract() if err == nil { t.Fatalf("Expected error, got none") } } func TestRemoveInterface(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/routers/4e8e5957-649f-477b-9e5b-f1f75b21c03c/remove_router_interface", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/routers/4e8e5957-649f-477b-9e5b-f1f75b21c03c/remove_router_interface", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -544,7 +544,7 @@ func TestRemoveInterface(t *testing.T) { }) opts := routers.RemoveInterfaceOpts{SubnetID: "a2f1f29d-571b-4533-907f-5803ab96ead1"} - res, err := routers.RemoveInterface(context.TODO(), fake.ServiceClient(), "4e8e5957-649f-477b-9e5b-f1f75b21c03c", opts).Extract() + res, err := routers.RemoveInterface(context.TODO(), fake.ServiceClient(fakeServer), "4e8e5957-649f-477b-9e5b-f1f75b21c03c", opts).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, "0d32a837-8069-4ec3-84c4-3eef3e10b188", res.SubnetID) @@ -554,10 +554,10 @@ func TestRemoveInterface(t *testing.T) { } func TestListL3Agents(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/routers/fa3a4aaa-c73f-48aa-a603-8c8bf642b7c0/l3-agents", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/routers/fa3a4aaa-c73f-48aa-a603-8c8bf642b7c0/l3-agents", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -626,7 +626,7 @@ func TestListL3Agents(t *testing.T) { `) }) - l3AgentsPages, err := routers.ListL3Agents(fake.ServiceClient(), "fa3a4aaa-c73f-48aa-a603-8c8bf642b7c0").AllPages(context.TODO()) + l3AgentsPages, err := routers.ListL3Agents(fake.ServiceClient(fakeServer), "fa3a4aaa-c73f-48aa-a603-8c8bf642b7c0").AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := routers.ExtractL3Agents(l3AgentsPages) th.AssertNoErr(t, err) diff --git a/openstack/networking/v2/extensions/mtu/testing/results_test.go b/openstack/networking/v2/extensions/mtu/testing/results_test.go index 916bbc00f8..99b2b2e745 100644 --- a/openstack/networking/v2/extensions/mtu/testing/results_test.go +++ b/openstack/networking/v2/extensions/mtu/testing/results_test.go @@ -19,10 +19,10 @@ type NetworkMTU struct { } func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/networks", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/networks", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -38,7 +38,7 @@ func TestList(t *testing.T) { } var actual []NetworkWithMTUExt - allPages, err := networks.List(fake.ServiceClient(), networks.ListOpts{}).AllPages(context.TODO()) + allPages, err := networks.List(fake.ServiceClient(fakeServer), networks.ListOpts{}).AllPages(context.TODO()) th.AssertNoErr(t, err) err = networks.ExtractNetworksInto(allPages, &actual) @@ -49,10 +49,10 @@ func TestList(t *testing.T) { } func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/networks/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/networks/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -64,7 +64,7 @@ func TestGet(t *testing.T) { var s NetworkMTU - err := networks.Get(context.TODO(), fake.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22").ExtractInto(&s) + err := networks.Get(context.TODO(), fake.ServiceClient(fakeServer), "d32019d3-bc6e-4319-9c1d-6722fc136a22").ExtractInto(&s) th.AssertNoErr(t, err) th.AssertEquals(t, "d32019d3-bc6e-4319-9c1d-6722fc136a22", s.ID) @@ -72,10 +72,10 @@ func TestGet(t *testing.T) { } func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/networks", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/networks", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -101,7 +101,7 @@ func TestCreate(t *testing.T) { var s NetworkMTU - err := networks.Create(context.TODO(), fake.ServiceClient(), mtuCreateOpts).ExtractInto(&s) + err := networks.Create(context.TODO(), fake.ServiceClient(fakeServer), mtuCreateOpts).ExtractInto(&s) th.AssertNoErr(t, err) th.AssertEquals(t, "db193ab3-96e3-4cb3-8fc5-05f4296d0324", s.ID) @@ -110,10 +110,10 @@ func TestCreate(t *testing.T) { } func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/networks/4e8e5957-649f-477b-9e5b-f1f75b21c03c", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/networks/4e8e5957-649f-477b-9e5b-f1f75b21c03c", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -142,7 +142,7 @@ func TestUpdate(t *testing.T) { var s NetworkMTU - err := networks.Update(context.TODO(), fake.ServiceClient(), "4e8e5957-649f-477b-9e5b-f1f75b21c03c", mtuUpdateOpts).ExtractInto(&s) + err := networks.Update(context.TODO(), fake.ServiceClient(fakeServer), "4e8e5957-649f-477b-9e5b-f1f75b21c03c", mtuUpdateOpts).ExtractInto(&s) th.AssertNoErr(t, err) th.AssertEquals(t, "4e8e5957-649f-477b-9e5b-f1f75b21c03c", s.ID) diff --git a/openstack/networking/v2/extensions/networkipavailabilities/testing/requests_test.go b/openstack/networking/v2/extensions/networkipavailabilities/testing/requests_test.go index cdd6d8d4e2..349d4784dd 100644 --- a/openstack/networking/v2/extensions/networkipavailabilities/testing/requests_test.go +++ b/openstack/networking/v2/extensions/networkipavailabilities/testing/requests_test.go @@ -14,10 +14,10 @@ import ( ) func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/network-ip-availabilities", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/network-ip-availabilities", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -29,7 +29,7 @@ func TestList(t *testing.T) { count := 0 - err := networkipavailabilities.List(fake.ServiceClient(), networkipavailabilities.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := networkipavailabilities.List(fake.ServiceClient(fakeServer), networkipavailabilities.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := networkipavailabilities.ExtractNetworkIPAvailabilities(page) if err != nil { @@ -55,10 +55,10 @@ func TestList(t *testing.T) { } func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/network-ip-availabilities/cf11ab78-2302-49fa-870f-851a08c7afb8", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/network-ip-availabilities/cf11ab78-2302-49fa-870f-851a08c7afb8", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -68,7 +68,7 @@ func TestGet(t *testing.T) { fmt.Fprint(w, NetworkIPAvailabilityGetResult) }) - s, err := networkipavailabilities.Get(context.TODO(), fake.ServiceClient(), "cf11ab78-2302-49fa-870f-851a08c7afb8").Extract() + s, err := networkipavailabilities.Get(context.TODO(), fake.ServiceClient(fakeServer), "cf11ab78-2302-49fa-870f-851a08c7afb8").Extract() th.AssertNoErr(t, err) th.AssertEquals(t, s.NetworkID, "cf11ab78-2302-49fa-870f-851a08c7afb8") diff --git a/openstack/networking/v2/extensions/portsbinding/testing/fixtures_test.go b/openstack/networking/v2/extensions/portsbinding/testing/fixtures_test.go index 44e2b5db9b..2a639214dd 100644 --- a/openstack/networking/v2/extensions/portsbinding/testing/fixtures_test.go +++ b/openstack/networking/v2/extensions/portsbinding/testing/fixtures_test.go @@ -10,8 +10,8 @@ import ( th "github.com/gophercloud/gophercloud/v2/testhelper" ) -func HandleListSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/v2.0/ports", func(w http.ResponseWriter, r *http.Request) { +func HandleListSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/ports", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -22,8 +22,8 @@ func HandleListSuccessfully(t *testing.T) { }) } -func HandleGet(t *testing.T) { - th.Mux.HandleFunc("/v2.0/ports/46d4bfb9-b26e-41f3-bd2e-e6dcc1ccedb2", func(w http.ResponseWriter, r *http.Request) { +func HandleGet(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/ports/46d4bfb9-b26e-41f3-bd2e-e6dcc1ccedb2", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -34,8 +34,8 @@ func HandleGet(t *testing.T) { }) } -func HandleCreate(t *testing.T) { - th.Mux.HandleFunc("/v2.0/ports", func(w http.ResponseWriter, r *http.Request) { +func HandleCreate(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/ports", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -92,8 +92,8 @@ func HandleCreate(t *testing.T) { }) } -func HandleUpdate(t *testing.T) { - th.Mux.HandleFunc("/v2.0/ports/65c0ee9f-d634-4522-8954-51021b570b0d", func(w http.ResponseWriter, r *http.Request) { +func HandleUpdate(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/ports/65c0ee9f-d634-4522-8954-51021b570b0d", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") diff --git a/openstack/networking/v2/extensions/portsbinding/testing/requests_test.go b/openstack/networking/v2/extensions/portsbinding/testing/requests_test.go index e613c1ea52..e48981fd06 100644 --- a/openstack/networking/v2/extensions/portsbinding/testing/requests_test.go +++ b/openstack/networking/v2/extensions/portsbinding/testing/requests_test.go @@ -12,10 +12,10 @@ import ( ) func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleListSuccessfully(t) + HandleListSuccessfully(t, fakeServer) type PortWithExt struct { ports.Port @@ -52,7 +52,7 @@ func TestList(t *testing.T) { }, } - allPages, err := ports.List(fake.ServiceClient(), ports.ListOpts{}).AllPages(context.TODO()) + allPages, err := ports.List(fake.ServiceClient(fakeServer), ports.ListOpts{}).AllPages(context.TODO()) th.AssertNoErr(t, err) err = ports.ExtractPortsInto(allPages, &actual) @@ -62,17 +62,17 @@ func TestList(t *testing.T) { } func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleGet(t) + HandleGet(t, fakeServer) var s struct { ports.Port portsbinding.PortsBindingExt } - err := ports.Get(context.TODO(), fake.ServiceClient(), "46d4bfb9-b26e-41f3-bd2e-e6dcc1ccedb2").ExtractInto(&s) + err := ports.Get(context.TODO(), fake.ServiceClient(fakeServer), "46d4bfb9-b26e-41f3-bd2e-e6dcc1ccedb2").ExtractInto(&s) th.AssertNoErr(t, err) th.AssertEquals(t, s.Status, "ACTIVE") @@ -96,10 +96,10 @@ func TestGet(t *testing.T) { } func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleCreate(t) + HandleCreate(t, fakeServer) var s struct { ports.Port @@ -123,7 +123,7 @@ func TestCreate(t *testing.T) { VNICType: "normal", } - err := ports.Create(context.TODO(), fake.ServiceClient(), createOpts).ExtractInto(&s) + err := ports.Create(context.TODO(), fake.ServiceClient(fakeServer), createOpts).ExtractInto(&s) th.AssertNoErr(t, err) th.AssertEquals(t, s.Status, "DOWN") @@ -143,20 +143,20 @@ func TestCreate(t *testing.T) { } func TestRequiredCreateOpts(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - res := ports.Create(context.TODO(), fake.ServiceClient(), portsbinding.CreateOptsExt{CreateOptsBuilder: ports.CreateOpts{}}) + res := ports.Create(context.TODO(), fake.ServiceClient(fakeServer), portsbinding.CreateOptsExt{CreateOptsBuilder: ports.CreateOpts{}}) if res.Err == nil { t.Fatalf("Expected error, got none") } } func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleUpdate(t) + HandleUpdate(t, fakeServer) var s struct { ports.Port @@ -179,7 +179,7 @@ func TestUpdate(t *testing.T) { VNICType: "normal", } - err := ports.Update(context.TODO(), fake.ServiceClient(), "65c0ee9f-d634-4522-8954-51021b570b0d", updateOpts).ExtractInto(&s) + err := ports.Update(context.TODO(), fake.ServiceClient(fakeServer), "65c0ee9f-d634-4522-8954-51021b570b0d", updateOpts).ExtractInto(&s) th.AssertNoErr(t, err) th.AssertEquals(t, s.Name, "new_port_name") diff --git a/openstack/networking/v2/extensions/provider/testing/results_test.go b/openstack/networking/v2/extensions/provider/testing/results_test.go index acbf9f7a1f..c8f7874b9d 100644 --- a/openstack/networking/v2/extensions/provider/testing/results_test.go +++ b/openstack/networking/v2/extensions/provider/testing/results_test.go @@ -15,10 +15,10 @@ import ( ) func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/networks", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/networks", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -34,7 +34,7 @@ func TestList(t *testing.T) { } var actual []NetworkWithExt - allPages, err := networks.List(fake.ServiceClient(), networks.ListOpts{}).AllPages(context.TODO()) + allPages, err := networks.List(fake.ServiceClient(fakeServer), networks.ListOpts{}).AllPages(context.TODO()) th.AssertNoErr(t, err) err = networks.ExtractNetworksInto(allPages, &actual) @@ -50,10 +50,10 @@ func TestList(t *testing.T) { } func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/networks/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/networks/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -68,7 +68,7 @@ func TestGet(t *testing.T) { provider.NetworkProviderExt } - err := networks.Get(context.TODO(), fake.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22").ExtractInto(&s) + err := networks.Get(context.TODO(), fake.ServiceClient(fakeServer), "d32019d3-bc6e-4319-9c1d-6722fc136a22").ExtractInto(&s) th.AssertNoErr(t, err) th.AssertEquals(t, "d32019d3-bc6e-4319-9c1d-6722fc136a22", s.ID) @@ -78,10 +78,10 @@ func TestGet(t *testing.T) { } func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/networks", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/networks", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -100,7 +100,7 @@ func TestCreate(t *testing.T) { } options := networks.CreateOpts{Name: "private", AdminStateUp: gophercloud.Enabled} - err := networks.Create(context.TODO(), fake.ServiceClient(), options).ExtractInto(&s) + err := networks.Create(context.TODO(), fake.ServiceClient(fakeServer), options).ExtractInto(&s) th.AssertNoErr(t, err) th.AssertEquals(t, "db193ab3-96e3-4cb3-8fc5-05f4296d0324", s.ID) @@ -110,10 +110,10 @@ func TestCreate(t *testing.T) { } func TestCreateWithMultipleProvider(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/networks", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/networks", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -185,13 +185,13 @@ func TestCreateWithMultipleProvider(t *testing.T) { Segments: segments, } - _, err := networks.Create(context.TODO(), fake.ServiceClient(), providerCreateOpts).Extract() + _, err := networks.Create(context.TODO(), fake.ServiceClient(fakeServer), providerCreateOpts).Extract() th.AssertNoErr(t, err) } func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() iTrue := true name := "new_network_name" @@ -204,7 +204,7 @@ func TestUpdate(t *testing.T) { Segments: &segments, } - th.Mux.HandleFunc("/v2.0/networks/4e8e5957-649f-477b-9e5b-f1f75b21c03c", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/networks/4e8e5957-649f-477b-9e5b-f1f75b21c03c", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -235,7 +235,7 @@ func TestUpdate(t *testing.T) { provider.NetworkProviderExt } - err := networks.Update(context.TODO(), fake.ServiceClient(), "4e8e5957-649f-477b-9e5b-f1f75b21c03c", providerUpdateOpts).ExtractInto(&s) + err := networks.Update(context.TODO(), fake.ServiceClient(fakeServer), "4e8e5957-649f-477b-9e5b-f1f75b21c03c", providerUpdateOpts).ExtractInto(&s) th.AssertNoErr(t, err) th.AssertEquals(t, "4e8e5957-649f-477b-9e5b-f1f75b21c03c", s.ID) diff --git a/openstack/networking/v2/extensions/qos/policies/testing/requests_test.go b/openstack/networking/v2/extensions/qos/policies/testing/requests_test.go index 4ad4cf3088..4b84d773b8 100644 --- a/openstack/networking/v2/extensions/qos/policies/testing/requests_test.go +++ b/openstack/networking/v2/extensions/qos/policies/testing/requests_test.go @@ -16,10 +16,10 @@ import ( ) func TestGetPort(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/ports/65c0ee9f-d634-4522-8954-51021b570b0d", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/ports/65c0ee9f-d634-4522-8954-51021b570b0d", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -34,7 +34,7 @@ func TestGetPort(t *testing.T) { ports.Port policies.QoSPolicyExt } - err := ports.Get(context.TODO(), fake.ServiceClient(), "65c0ee9f-d634-4522-8954-51021b570b0d").ExtractInto(&p) + err := ports.Get(context.TODO(), fake.ServiceClient(fakeServer), "65c0ee9f-d634-4522-8954-51021b570b0d").ExtractInto(&p) th.AssertNoErr(t, err) th.AssertEquals(t, p.ID, "65c0ee9f-d634-4522-8954-51021b570b0d") @@ -42,10 +42,10 @@ func TestGetPort(t *testing.T) { } func TestCreatePort(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/ports", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/ports", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -70,7 +70,7 @@ func TestCreatePort(t *testing.T) { CreateOptsBuilder: portCreateOpts, QoSPolicyID: "591e0597-39a6-4665-8149-2111d8de9a08", } - err := ports.Create(context.TODO(), fake.ServiceClient(), createOpts).ExtractInto(&p) + err := ports.Create(context.TODO(), fake.ServiceClient(fakeServer), createOpts).ExtractInto(&p) th.AssertNoErr(t, err) th.AssertEquals(t, p.NetworkID, "a87cc70a-3e15-4acf-8205-9b711a3531b7") @@ -80,10 +80,10 @@ func TestCreatePort(t *testing.T) { } func TestUpdatePortWithPolicy(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/ports/65c0ee9f-d634-4522-8954-51021b570b0d", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/ports/65c0ee9f-d634-4522-8954-51021b570b0d", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -108,7 +108,7 @@ func TestUpdatePortWithPolicy(t *testing.T) { UpdateOptsBuilder: portUpdateOpts, QoSPolicyID: &policyID, } - err := ports.Update(context.TODO(), fake.ServiceClient(), "65c0ee9f-d634-4522-8954-51021b570b0d", updateOpts).ExtractInto(&p) + err := ports.Update(context.TODO(), fake.ServiceClient(fakeServer), "65c0ee9f-d634-4522-8954-51021b570b0d", updateOpts).ExtractInto(&p) th.AssertNoErr(t, err) th.AssertEquals(t, p.NetworkID, "a87cc70a-3e15-4acf-8205-9b711a3531b7") @@ -118,10 +118,10 @@ func TestUpdatePortWithPolicy(t *testing.T) { } func TestUpdatePortWithoutPolicy(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/ports/65c0ee9f-d634-4522-8954-51021b570b0d", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/ports/65c0ee9f-d634-4522-8954-51021b570b0d", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -146,7 +146,7 @@ func TestUpdatePortWithoutPolicy(t *testing.T) { UpdateOptsBuilder: portUpdateOpts, QoSPolicyID: &policyID, } - err := ports.Update(context.TODO(), fake.ServiceClient(), "65c0ee9f-d634-4522-8954-51021b570b0d", updateOpts).ExtractInto(&p) + err := ports.Update(context.TODO(), fake.ServiceClient(fakeServer), "65c0ee9f-d634-4522-8954-51021b570b0d", updateOpts).ExtractInto(&p) th.AssertNoErr(t, err) th.AssertEquals(t, p.NetworkID, "a87cc70a-3e15-4acf-8205-9b711a3531b7") @@ -156,10 +156,10 @@ func TestUpdatePortWithoutPolicy(t *testing.T) { } func TestGetNetwork(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/networks/65c0ee9f-d634-4522-8954-51021b570b0d", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/networks/65c0ee9f-d634-4522-8954-51021b570b0d", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -174,7 +174,7 @@ func TestGetNetwork(t *testing.T) { networks.Network policies.QoSPolicyExt } - err := networks.Get(context.TODO(), fake.ServiceClient(), "65c0ee9f-d634-4522-8954-51021b570b0d").ExtractInto(&n) + err := networks.Get(context.TODO(), fake.ServiceClient(fakeServer), "65c0ee9f-d634-4522-8954-51021b570b0d").ExtractInto(&n) th.AssertNoErr(t, err) th.AssertEquals(t, n.ID, "65c0ee9f-d634-4522-8954-51021b570b0d") @@ -182,10 +182,10 @@ func TestGetNetwork(t *testing.T) { } func TestCreateNetwork(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/networks", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/networks", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -210,7 +210,7 @@ func TestCreateNetwork(t *testing.T) { CreateOptsBuilder: networkCreateOpts, QoSPolicyID: "591e0597-39a6-4665-8149-2111d8de9a08", } - err := networks.Create(context.TODO(), fake.ServiceClient(), createOpts).ExtractInto(&n) + err := networks.Create(context.TODO(), fake.ServiceClient(fakeServer), createOpts).ExtractInto(&n) th.AssertNoErr(t, err) th.AssertEquals(t, n.TenantID, "4fd44f30292945e481c7b8a0c8908869") @@ -219,10 +219,10 @@ func TestCreateNetwork(t *testing.T) { } func TestUpdateNetworkWithPolicy(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/networks/65c0ee9f-d634-4522-8954-51021b570b0d", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/networks/65c0ee9f-d634-4522-8954-51021b570b0d", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -250,7 +250,7 @@ func TestUpdateNetworkWithPolicy(t *testing.T) { UpdateOptsBuilder: networkUpdateOpts, QoSPolicyID: &policyID, } - err := networks.Update(context.TODO(), fake.ServiceClient(), "65c0ee9f-d634-4522-8954-51021b570b0d", updateOpts).ExtractInto(&n) + err := networks.Update(context.TODO(), fake.ServiceClient(fakeServer), "65c0ee9f-d634-4522-8954-51021b570b0d", updateOpts).ExtractInto(&n) th.AssertNoErr(t, err) th.AssertEquals(t, n.TenantID, "4fd44f30292945e481c7b8a0c8908869") @@ -260,10 +260,10 @@ func TestUpdateNetworkWithPolicy(t *testing.T) { } func TestUpdateNetworkWithoutPolicy(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/networks/65c0ee9f-d634-4522-8954-51021b570b0d", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/networks/65c0ee9f-d634-4522-8954-51021b570b0d", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -288,7 +288,7 @@ func TestUpdateNetworkWithoutPolicy(t *testing.T) { UpdateOptsBuilder: networkUpdateOpts, QoSPolicyID: &policyID, } - err := networks.Update(context.TODO(), fake.ServiceClient(), "65c0ee9f-d634-4522-8954-51021b570b0d", updateOpts).ExtractInto(&n) + err := networks.Update(context.TODO(), fake.ServiceClient(fakeServer), "65c0ee9f-d634-4522-8954-51021b570b0d", updateOpts).ExtractInto(&n) th.AssertNoErr(t, err) th.AssertEquals(t, n.TenantID, "4fd44f30292945e481c7b8a0c8908869") @@ -297,10 +297,10 @@ func TestUpdateNetworkWithoutPolicy(t *testing.T) { } func TestListPolicies(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/qos/policies", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/qos/policies", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -312,7 +312,7 @@ func TestListPolicies(t *testing.T) { count := 0 - err := policies.List(fake.ServiceClient(), policies.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := policies.List(fake.ServiceClient(fakeServer), policies.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := policies.ExtractPolicies(page) if err != nil { @@ -337,10 +337,10 @@ func TestListPolicies(t *testing.T) { } func TestGetPolicy(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/qos/policies/30a57f4a-336b-4382-8275-d708babd2241", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/qos/policies/30a57f4a-336b-4382-8275-d708babd2241", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -350,7 +350,7 @@ func TestGetPolicy(t *testing.T) { fmt.Fprint(w, GetPolicyResponse) }) - p, err := policies.Get(context.TODO(), fake.ServiceClient(), "30a57f4a-336b-4382-8275-d708babd2241").Extract() + p, err := policies.Get(context.TODO(), fake.ServiceClient(fakeServer), "30a57f4a-336b-4382-8275-d708babd2241").Extract() th.AssertNoErr(t, err) th.AssertEquals(t, "bw-limiter", p.Name) @@ -374,10 +374,10 @@ func TestGetPolicy(t *testing.T) { } func TestCreatePolicy(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/qos/policies", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/qos/policies", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -396,7 +396,7 @@ func TestCreatePolicy(t *testing.T) { IsDefault: true, Description: "use-me", } - p, err := policies.Create(context.TODO(), fake.ServiceClient(), opts).Extract() + p, err := policies.Create(context.TODO(), fake.ServiceClient(fakeServer), opts).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, "shared-default-policy", p.Name) @@ -412,10 +412,10 @@ func TestCreatePolicy(t *testing.T) { } func TestUpdatePolicy(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/qos/policies/d6ae28ce-fcb5-4180-aa62-d260a27e09ae", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/qos/policies/d6ae28ce-fcb5-4180-aa62-d260a27e09ae", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -435,7 +435,7 @@ func TestUpdatePolicy(t *testing.T) { Shared: &shared, Description: &description, } - p, err := policies.Update(context.TODO(), fake.ServiceClient(), "d6ae28ce-fcb5-4180-aa62-d260a27e09ae", opts).Extract() + p, err := policies.Update(context.TODO(), fake.ServiceClient(fakeServer), "d6ae28ce-fcb5-4180-aa62-d260a27e09ae", opts).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, "new-name", p.Name) @@ -451,15 +451,15 @@ func TestUpdatePolicy(t *testing.T) { } func TestDeletePolicy(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/qos/policies/d6ae28ce-fcb5-4180-aa62-d260a27e09ae", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/qos/policies/d6ae28ce-fcb5-4180-aa62-d260a27e09ae", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.WriteHeader(http.StatusNoContent) }) - res := policies.Delete(context.TODO(), fake.ServiceClient(), "d6ae28ce-fcb5-4180-aa62-d260a27e09ae") + res := policies.Delete(context.TODO(), fake.ServiceClient(fakeServer), "d6ae28ce-fcb5-4180-aa62-d260a27e09ae") th.AssertNoErr(t, res.Err) } diff --git a/openstack/networking/v2/extensions/qos/rules/doc.go b/openstack/networking/v2/extensions/qos/rules/doc.go index f1c2d2672a..f7d3b744ad 100644 --- a/openstack/networking/v2/extensions/qos/rules/doc.go +++ b/openstack/networking/v2/extensions/qos/rules/doc.go @@ -76,7 +76,7 @@ Example of Deleting a single BandwidthLimitRule policyID := "501005fa-3b56-4061-aaca-3f24995112e1" ruleID := "30a57f4a-336b-4382-8275-d708babd2241" - err := rules.DeleteBandwidthLimitRule(fake.ServiceClient(), "501005fa-3b56-4061-aaca-3f24995112e1", "30a57f4a-336b-4382-8275-d708babd2241").ExtractErr() + err := rules.DeleteBandwidthLimitRule(fake.ServiceClient(fakeServer), "501005fa-3b56-4061-aaca-3f24995112e1", "30a57f4a-336b-4382-8275-d708babd2241").ExtractErr() if err != nil { panic(err) } @@ -151,7 +151,7 @@ Example of Deleting a single DSCPMarkingRule policyID := "501005fa-3b56-4061-aaca-3f24995112e1" ruleID := "30a57f4a-336b-4382-8275-d708babd2241" - err := rules.DeleteDSCPMarkingRule(fake.ServiceClient(), "501005fa-3b56-4061-aaca-3f24995112e1", "30a57f4a-336b-4382-8275-d708babd2241").ExtractErr() + err := rules.DeleteDSCPMarkingRule(fake.ServiceClient(fakeServer), "501005fa-3b56-4061-aaca-3f24995112e1", "30a57f4a-336b-4382-8275-d708babd2241").ExtractErr() if err != nil { panic(err) } @@ -228,7 +228,7 @@ Example of Deleting a single MinimumBandwidthRule policyID := "501005fa-3b56-4061-aaca-3f24995112e1" ruleID := "30a57f4a-336b-4382-8275-d708babd2241" - err := rules.DeleteMinimumBandwidthRule(fake.ServiceClient(), "501005fa-3b56-4061-aaca-3f24995112e1", "30a57f4a-336b-4382-8275-d708babd2241").ExtractErr() + err := rules.DeleteMinimumBandwidthRule(fake.ServiceClient(fakeServer), "501005fa-3b56-4061-aaca-3f24995112e1", "30a57f4a-336b-4382-8275-d708babd2241").ExtractErr() if err != nil { panic(err) } diff --git a/openstack/networking/v2/extensions/qos/rules/testing/requests_test.go b/openstack/networking/v2/extensions/qos/rules/testing/requests_test.go index 20de755132..0c6402d1b6 100644 --- a/openstack/networking/v2/extensions/qos/rules/testing/requests_test.go +++ b/openstack/networking/v2/extensions/qos/rules/testing/requests_test.go @@ -13,10 +13,10 @@ import ( ) func TestListBandwidthLimitRule(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/qos/policies/501005fa-3b56-4061-aaca-3f24995112e1/bandwidth_limit_rules", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/qos/policies/501005fa-3b56-4061-aaca-3f24995112e1/bandwidth_limit_rules", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -29,7 +29,7 @@ func TestListBandwidthLimitRule(t *testing.T) { count := 0 err := rules.ListBandwidthLimitRules( - fake.ServiceClient(), + fake.ServiceClient(fakeServer), "501005fa-3b56-4061-aaca-3f24995112e1", rules.BandwidthLimitRulesListOpts{}, ).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { @@ -61,10 +61,10 @@ func TestListBandwidthLimitRule(t *testing.T) { } func TestGetBandwidthLimitRule(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/qos/policies/501005fa-3b56-4061-aaca-3f24995112e1/bandwidth_limit_rules/30a57f4a-336b-4382-8275-d708babd2241", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/qos/policies/501005fa-3b56-4061-aaca-3f24995112e1/bandwidth_limit_rules/30a57f4a-336b-4382-8275-d708babd2241", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -74,7 +74,7 @@ func TestGetBandwidthLimitRule(t *testing.T) { fmt.Fprint(w, BandwidthLimitRulesGetResult) }) - r, err := rules.GetBandwidthLimitRule(context.TODO(), fake.ServiceClient(), "501005fa-3b56-4061-aaca-3f24995112e1", "30a57f4a-336b-4382-8275-d708babd2241").ExtractBandwidthLimitRule() + r, err := rules.GetBandwidthLimitRule(context.TODO(), fake.ServiceClient(fakeServer), "501005fa-3b56-4061-aaca-3f24995112e1", "30a57f4a-336b-4382-8275-d708babd2241").ExtractBandwidthLimitRule() th.AssertNoErr(t, err) th.AssertEquals(t, r.ID, "30a57f4a-336b-4382-8275-d708babd2241") @@ -84,10 +84,10 @@ func TestGetBandwidthLimitRule(t *testing.T) { } func TestCreateBandwidthLimitRule(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/qos/policies/501005fa-3b56-4061-aaca-3f24995112e1/bandwidth_limit_rules", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/qos/policies/501005fa-3b56-4061-aaca-3f24995112e1/bandwidth_limit_rules", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -104,7 +104,7 @@ func TestCreateBandwidthLimitRule(t *testing.T) { MaxKBps: 2000, MaxBurstKBps: 200, } - r, err := rules.CreateBandwidthLimitRule(context.TODO(), fake.ServiceClient(), "501005fa-3b56-4061-aaca-3f24995112e1", opts).ExtractBandwidthLimitRule() + r, err := rules.CreateBandwidthLimitRule(context.TODO(), fake.ServiceClient(fakeServer), "501005fa-3b56-4061-aaca-3f24995112e1", opts).ExtractBandwidthLimitRule() th.AssertNoErr(t, err) th.AssertEquals(t, 200, r.MaxBurstKBps) @@ -112,10 +112,10 @@ func TestCreateBandwidthLimitRule(t *testing.T) { } func TestUpdateBandwidthLimitRule(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/qos/policies/501005fa-3b56-4061-aaca-3f24995112e1/bandwidth_limit_rules/30a57f4a-336b-4382-8275-d708babd2241", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/qos/policies/501005fa-3b56-4061-aaca-3f24995112e1/bandwidth_limit_rules/30a57f4a-336b-4382-8275-d708babd2241", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -134,7 +134,7 @@ func TestUpdateBandwidthLimitRule(t *testing.T) { MaxKBps: &maxKBps, MaxBurstKBps: &maxBurstKBps, } - r, err := rules.UpdateBandwidthLimitRule(context.TODO(), fake.ServiceClient(), "501005fa-3b56-4061-aaca-3f24995112e1", "30a57f4a-336b-4382-8275-d708babd2241", opts).ExtractBandwidthLimitRule() + r, err := rules.UpdateBandwidthLimitRule(context.TODO(), fake.ServiceClient(fakeServer), "501005fa-3b56-4061-aaca-3f24995112e1", "30a57f4a-336b-4382-8275-d708babd2241", opts).ExtractBandwidthLimitRule() th.AssertNoErr(t, err) th.AssertEquals(t, 0, r.MaxBurstKBps) @@ -142,24 +142,24 @@ func TestUpdateBandwidthLimitRule(t *testing.T) { } func TestDeleteBandwidthLimitRule(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/qos/policies/501005fa-3b56-4061-aaca-3f24995112e1/bandwidth_limit_rules/30a57f4a-336b-4382-8275-d708babd2241", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/qos/policies/501005fa-3b56-4061-aaca-3f24995112e1/bandwidth_limit_rules/30a57f4a-336b-4382-8275-d708babd2241", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.WriteHeader(http.StatusNoContent) }) - res := rules.DeleteBandwidthLimitRule(context.TODO(), fake.ServiceClient(), "501005fa-3b56-4061-aaca-3f24995112e1", "30a57f4a-336b-4382-8275-d708babd2241") + res := rules.DeleteBandwidthLimitRule(context.TODO(), fake.ServiceClient(fakeServer), "501005fa-3b56-4061-aaca-3f24995112e1", "30a57f4a-336b-4382-8275-d708babd2241") th.AssertNoErr(t, res.Err) } func TestListDSCPMarkingRule(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/qos/policies/501005fa-3b56-4061-aaca-3f24995112e1/dscp_marking_rules", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/qos/policies/501005fa-3b56-4061-aaca-3f24995112e1/dscp_marking_rules", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -172,7 +172,7 @@ func TestListDSCPMarkingRule(t *testing.T) { count := 0 err := rules.ListDSCPMarkingRules( - fake.ServiceClient(), + fake.ServiceClient(fakeServer), "501005fa-3b56-4061-aaca-3f24995112e1", rules.DSCPMarkingRulesListOpts{}, ).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { @@ -202,10 +202,10 @@ func TestListDSCPMarkingRule(t *testing.T) { } func TestGetDSCPMarkingRule(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/qos/policies/501005fa-3b56-4061-aaca-3f24995112e1/dscp_marking_rules/30a57f4a-336b-4382-8275-d708babd2241", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/qos/policies/501005fa-3b56-4061-aaca-3f24995112e1/dscp_marking_rules/30a57f4a-336b-4382-8275-d708babd2241", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -215,7 +215,7 @@ func TestGetDSCPMarkingRule(t *testing.T) { fmt.Fprint(w, DSCPMarkingRuleGetResult) }) - r, err := rules.GetDSCPMarkingRule(context.TODO(), fake.ServiceClient(), "501005fa-3b56-4061-aaca-3f24995112e1", "30a57f4a-336b-4382-8275-d708babd2241").ExtractDSCPMarkingRule() + r, err := rules.GetDSCPMarkingRule(context.TODO(), fake.ServiceClient(fakeServer), "501005fa-3b56-4061-aaca-3f24995112e1", "30a57f4a-336b-4382-8275-d708babd2241").ExtractDSCPMarkingRule() th.AssertNoErr(t, err) th.AssertEquals(t, r.ID, "30a57f4a-336b-4382-8275-d708babd2241") @@ -223,10 +223,10 @@ func TestGetDSCPMarkingRule(t *testing.T) { } func TestCreateDSCPMarkingRule(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/qos/policies/501005fa-3b56-4061-aaca-3f24995112e1/dscp_marking_rules", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/qos/policies/501005fa-3b56-4061-aaca-3f24995112e1/dscp_marking_rules", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -242,7 +242,7 @@ func TestCreateDSCPMarkingRule(t *testing.T) { opts := rules.CreateDSCPMarkingRuleOpts{ DSCPMark: 20, } - r, err := rules.CreateDSCPMarkingRule(context.TODO(), fake.ServiceClient(), "501005fa-3b56-4061-aaca-3f24995112e1", opts).ExtractDSCPMarkingRule() + r, err := rules.CreateDSCPMarkingRule(context.TODO(), fake.ServiceClient(fakeServer), "501005fa-3b56-4061-aaca-3f24995112e1", opts).ExtractDSCPMarkingRule() th.AssertNoErr(t, err) th.AssertEquals(t, "30a57f4a-336b-4382-8275-d708babd2241", r.ID) @@ -250,10 +250,10 @@ func TestCreateDSCPMarkingRule(t *testing.T) { } func TestUpdateDSCPMarkingRule(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/qos/policies/501005fa-3b56-4061-aaca-3f24995112e1/dscp_marking_rules/30a57f4a-336b-4382-8275-d708babd2241", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/qos/policies/501005fa-3b56-4061-aaca-3f24995112e1/dscp_marking_rules/30a57f4a-336b-4382-8275-d708babd2241", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -270,7 +270,7 @@ func TestUpdateDSCPMarkingRule(t *testing.T) { opts := rules.UpdateDSCPMarkingRuleOpts{ DSCPMark: &dscpMark, } - r, err := rules.UpdateDSCPMarkingRule(context.TODO(), fake.ServiceClient(), "501005fa-3b56-4061-aaca-3f24995112e1", "30a57f4a-336b-4382-8275-d708babd2241", opts).ExtractDSCPMarkingRule() + r, err := rules.UpdateDSCPMarkingRule(context.TODO(), fake.ServiceClient(fakeServer), "501005fa-3b56-4061-aaca-3f24995112e1", "30a57f4a-336b-4382-8275-d708babd2241", opts).ExtractDSCPMarkingRule() th.AssertNoErr(t, err) th.AssertEquals(t, "30a57f4a-336b-4382-8275-d708babd2241", r.ID) @@ -278,24 +278,24 @@ func TestUpdateDSCPMarkingRule(t *testing.T) { } func TestDeleteDSCPMarkingRule(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/qos/policies/501005fa-3b56-4061-aaca-3f24995112e1/dscp_marking_rules/30a57f4a-336b-4382-8275-d708babd2241", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/qos/policies/501005fa-3b56-4061-aaca-3f24995112e1/dscp_marking_rules/30a57f4a-336b-4382-8275-d708babd2241", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.WriteHeader(http.StatusNoContent) }) - res := rules.DeleteDSCPMarkingRule(context.TODO(), fake.ServiceClient(), "501005fa-3b56-4061-aaca-3f24995112e1", "30a57f4a-336b-4382-8275-d708babd2241") + res := rules.DeleteDSCPMarkingRule(context.TODO(), fake.ServiceClient(fakeServer), "501005fa-3b56-4061-aaca-3f24995112e1", "30a57f4a-336b-4382-8275-d708babd2241") th.AssertNoErr(t, res.Err) } func TestListMinimumBandwidthRule(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/qos/policies/501005fa-3b56-4061-aaca-3f24995112e1/minimum_bandwidth_rules", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/qos/policies/501005fa-3b56-4061-aaca-3f24995112e1/minimum_bandwidth_rules", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -308,7 +308,7 @@ func TestListMinimumBandwidthRule(t *testing.T) { count := 0 err := rules.ListMinimumBandwidthRules( - fake.ServiceClient(), + fake.ServiceClient(fakeServer), "501005fa-3b56-4061-aaca-3f24995112e1", rules.MinimumBandwidthRulesListOpts{}, ).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { @@ -339,10 +339,10 @@ func TestListMinimumBandwidthRule(t *testing.T) { } func TestGetMinimumBandwidthRule(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/qos/policies/501005fa-3b56-4061-aaca-3f24995112e1/minimum_bandwidth_rules/30a57f4a-336b-4382-8275-d708babd2241", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/qos/policies/501005fa-3b56-4061-aaca-3f24995112e1/minimum_bandwidth_rules/30a57f4a-336b-4382-8275-d708babd2241", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -352,7 +352,7 @@ func TestGetMinimumBandwidthRule(t *testing.T) { fmt.Fprint(w, MinimumBandwidthRulesGetResult) }) - r, err := rules.GetMinimumBandwidthRule(context.TODO(), fake.ServiceClient(), "501005fa-3b56-4061-aaca-3f24995112e1", "30a57f4a-336b-4382-8275-d708babd2241").ExtractMinimumBandwidthRule() + r, err := rules.GetMinimumBandwidthRule(context.TODO(), fake.ServiceClient(fakeServer), "501005fa-3b56-4061-aaca-3f24995112e1", "30a57f4a-336b-4382-8275-d708babd2241").ExtractMinimumBandwidthRule() th.AssertNoErr(t, err) th.AssertEquals(t, r.ID, "30a57f4a-336b-4382-8275-d708babd2241") @@ -361,10 +361,10 @@ func TestGetMinimumBandwidthRule(t *testing.T) { } func TestCreateMinimumBandwidthRule(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/qos/policies/501005fa-3b56-4061-aaca-3f24995112e1/minimum_bandwidth_rules", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/qos/policies/501005fa-3b56-4061-aaca-3f24995112e1/minimum_bandwidth_rules", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -380,17 +380,17 @@ func TestCreateMinimumBandwidthRule(t *testing.T) { opts := rules.CreateMinimumBandwidthRuleOpts{ MinKBps: 2000, } - r, err := rules.CreateMinimumBandwidthRule(context.TODO(), fake.ServiceClient(), "501005fa-3b56-4061-aaca-3f24995112e1", opts).ExtractMinimumBandwidthRule() + r, err := rules.CreateMinimumBandwidthRule(context.TODO(), fake.ServiceClient(fakeServer), "501005fa-3b56-4061-aaca-3f24995112e1", opts).ExtractMinimumBandwidthRule() th.AssertNoErr(t, err) th.AssertEquals(t, 2000, r.MinKBps) } func TestUpdateMinimumBandwidthRule(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/qos/policies/501005fa-3b56-4061-aaca-3f24995112e1/minimum_bandwidth_rules/30a57f4a-336b-4382-8275-d708babd2241", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/qos/policies/501005fa-3b56-4061-aaca-3f24995112e1/minimum_bandwidth_rules/30a57f4a-336b-4382-8275-d708babd2241", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -407,22 +407,22 @@ func TestUpdateMinimumBandwidthRule(t *testing.T) { opts := rules.UpdateMinimumBandwidthRuleOpts{ MinKBps: &minKBps, } - r, err := rules.UpdateMinimumBandwidthRule(context.TODO(), fake.ServiceClient(), "501005fa-3b56-4061-aaca-3f24995112e1", "30a57f4a-336b-4382-8275-d708babd2241", opts).ExtractMinimumBandwidthRule() + r, err := rules.UpdateMinimumBandwidthRule(context.TODO(), fake.ServiceClient(fakeServer), "501005fa-3b56-4061-aaca-3f24995112e1", "30a57f4a-336b-4382-8275-d708babd2241", opts).ExtractMinimumBandwidthRule() th.AssertNoErr(t, err) th.AssertEquals(t, 500, r.MinKBps) } func TestDeleteMinimumBandwidthRule(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/qos/policies/501005fa-3b56-4061-aaca-3f24995112e1/minimum_bandwidth_rules/30a57f4a-336b-4382-8275-d708babd2241", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/qos/policies/501005fa-3b56-4061-aaca-3f24995112e1/minimum_bandwidth_rules/30a57f4a-336b-4382-8275-d708babd2241", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.WriteHeader(http.StatusNoContent) }) - res := rules.DeleteMinimumBandwidthRule(context.TODO(), fake.ServiceClient(), "501005fa-3b56-4061-aaca-3f24995112e1", "30a57f4a-336b-4382-8275-d708babd2241") + res := rules.DeleteMinimumBandwidthRule(context.TODO(), fake.ServiceClient(fakeServer), "501005fa-3b56-4061-aaca-3f24995112e1", "30a57f4a-336b-4382-8275-d708babd2241") th.AssertNoErr(t, res.Err) } diff --git a/openstack/networking/v2/extensions/qos/ruletypes/testing/requests_test.go b/openstack/networking/v2/extensions/qos/ruletypes/testing/requests_test.go index 03a3fddab1..7d2bfc5835 100644 --- a/openstack/networking/v2/extensions/qos/ruletypes/testing/requests_test.go +++ b/openstack/networking/v2/extensions/qos/ruletypes/testing/requests_test.go @@ -12,10 +12,10 @@ import ( ) func TestListRuleTypes(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -25,7 +25,7 @@ func TestListRuleTypes(t *testing.T) { fmt.Fprint(w, ListRuleTypesResponse) }) - page, err := ruletypes.ListRuleTypes(client.ServiceClient()).AllPages(context.TODO()) + page, err := ruletypes.ListRuleTypes(client.ServiceClient(fakeServer)).AllPages(context.TODO()) if err != nil { t.Errorf("Failed to list rule types pages: %v", err) return @@ -42,10 +42,10 @@ func TestListRuleTypes(t *testing.T) { } func TestGetRuleType(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/qos/rule-types/bandwidth_limit", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/qos/rule-types/bandwidth_limit", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -56,7 +56,7 @@ func TestGetRuleType(t *testing.T) { th.AssertNoErr(t, err) }) - r, err := ruletypes.GetRuleType(context.TODO(), client.ServiceClient(), "bandwidth_limit").Extract() + r, err := ruletypes.GetRuleType(context.TODO(), client.ServiceClient(fakeServer), "bandwidth_limit").Extract() th.AssertNoErr(t, err) th.AssertEquals(t, "bandwidth_limit", r.Type) diff --git a/openstack/networking/v2/extensions/quotas/testing/requests_test.go b/openstack/networking/v2/extensions/quotas/testing/requests_test.go index a5714d17fe..597edd4853 100644 --- a/openstack/networking/v2/extensions/quotas/testing/requests_test.go +++ b/openstack/networking/v2/extensions/quotas/testing/requests_test.go @@ -13,10 +13,10 @@ import ( ) func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/quotas/0a73845280574ad389c292f6a74afa76", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/quotas/0a73845280574ad389c292f6a74afa76", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -26,16 +26,16 @@ func TestGet(t *testing.T) { fmt.Fprint(w, GetResponseRaw) }) - q, err := quotas.Get(context.TODO(), fake.ServiceClient(), "0a73845280574ad389c292f6a74afa76").Extract() + q, err := quotas.Get(context.TODO(), fake.ServiceClient(fakeServer), "0a73845280574ad389c292f6a74afa76").Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, q, &GetResponse) } func TestGetDetail(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/quotas/0a73845280574ad389c292f6a74afa76/details.json", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/quotas/0a73845280574ad389c292f6a74afa76/details.json", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -45,16 +45,16 @@ func TestGetDetail(t *testing.T) { fmt.Fprint(w, GetDetailedResponseRaw) }) - q, err := quotas.GetDetail(context.TODO(), fake.ServiceClient(), "0a73845280574ad389c292f6a74afa76").Extract() + q, err := quotas.GetDetail(context.TODO(), fake.ServiceClient(fakeServer), "0a73845280574ad389c292f6a74afa76").Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, q, &GetDetailResponse) } func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/quotas/0a73845280574ad389c292f6a74afa76", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/quotas/0a73845280574ad389c292f6a74afa76", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -64,7 +64,7 @@ func TestUpdate(t *testing.T) { fmt.Fprint(w, UpdateRequestResponseRaw) }) - q, err := quotas.Update(context.TODO(), fake.ServiceClient(), "0a73845280574ad389c292f6a74afa76", quotas.UpdateOpts{ + q, err := quotas.Update(context.TODO(), fake.ServiceClient(fakeServer), "0a73845280574ad389c292f6a74afa76", quotas.UpdateOpts{ FloatingIP: gophercloud.IntToPointer(0), Network: gophercloud.IntToPointer(-1), Port: gophercloud.IntToPointer(5), diff --git a/openstack/networking/v2/extensions/rbacpolicies/testing/requests_test.go b/openstack/networking/v2/extensions/rbacpolicies/testing/requests_test.go index 9fc04412f4..68cba4a15d 100644 --- a/openstack/networking/v2/extensions/rbacpolicies/testing/requests_test.go +++ b/openstack/networking/v2/extensions/rbacpolicies/testing/requests_test.go @@ -13,10 +13,10 @@ import ( ) func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/rbac-policies", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/rbac-policies", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -34,17 +34,17 @@ func TestCreate(t *testing.T) { TargetTenant: "6e547a3bcfe44702889fdeff3c3520c3", ObjectID: "240d22bf-bd17-4238-9758-25f72610ecdc", } - rbacResult, err := rbacpolicies.Create(context.TODO(), fake.ServiceClient(), options).Extract() + rbacResult, err := rbacpolicies.Create(context.TODO(), fake.ServiceClient(fakeServer), options).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, &rbacPolicy1, rbacResult) } func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/rbac-policies/2cf7523a-93b5-4e69-9360-6c6bf986bb7c", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/rbac-policies/2cf7523a-93b5-4e69-9360-6c6bf986bb7c", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -54,16 +54,16 @@ func TestGet(t *testing.T) { fmt.Fprint(w, GetResponse) }) - n, err := rbacpolicies.Get(context.TODO(), fake.ServiceClient(), "2cf7523a-93b5-4e69-9360-6c6bf986bb7c").Extract() + n, err := rbacpolicies.Get(context.TODO(), fake.ServiceClient(fakeServer), "2cf7523a-93b5-4e69-9360-6c6bf986bb7c").Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, &rbacPolicy1, n) } func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/rbac-policies", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/rbac-policies", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -73,7 +73,7 @@ func TestList(t *testing.T) { fmt.Fprint(w, ListResponse) }) - client := fake.ServiceClient() + client := fake.ServiceClient(fakeServer) count := 0 err := rbacpolicies.List(client, rbacpolicies.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { @@ -96,10 +96,10 @@ func TestList(t *testing.T) { } func TestListWithAllPages(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/rbac-policies", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/rbac-policies", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -109,7 +109,7 @@ func TestListWithAllPages(t *testing.T) { fmt.Fprint(w, ListResponse) }) - client := fake.ServiceClient() + client := fake.ServiceClient(fakeServer) type newRBACPolicy struct { rbacpolicies.RBACPolicy @@ -132,24 +132,24 @@ func TestListWithAllPages(t *testing.T) { } func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/rbac-policies/71d55b18-d2f8-4c76-a5e6-e0a3dd114361", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/rbac-policies/71d55b18-d2f8-4c76-a5e6-e0a3dd114361", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.WriteHeader(http.StatusNoContent) }) - res := rbacpolicies.Delete(context.TODO(), fake.ServiceClient(), "71d55b18-d2f8-4c76-a5e6-e0a3dd114361").ExtractErr() + res := rbacpolicies.Delete(context.TODO(), fake.ServiceClient(fakeServer), "71d55b18-d2f8-4c76-a5e6-e0a3dd114361").ExtractErr() th.AssertNoErr(t, res) } func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/rbac-policies/2cf7523a-93b5-4e69-9360-6c6bf986bb7c", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/rbac-policies/2cf7523a-93b5-4e69-9360-6c6bf986bb7c", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -163,7 +163,7 @@ func TestUpdate(t *testing.T) { }) options := rbacpolicies.UpdateOpts{TargetTenant: "9d766060b6354c9e8e2da44cab0e8f38"} - rbacResult, err := rbacpolicies.Update(context.TODO(), fake.ServiceClient(), "2cf7523a-93b5-4e69-9360-6c6bf986bb7c", options).Extract() + rbacResult, err := rbacpolicies.Update(context.TODO(), fake.ServiceClient(fakeServer), "2cf7523a-93b5-4e69-9360-6c6bf986bb7c", options).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, rbacResult.TargetTenant, "9d766060b6354c9e8e2da44cab0e8f38") diff --git a/openstack/networking/v2/extensions/security/addressgroups/testing/requests_test.go b/openstack/networking/v2/extensions/security/addressgroups/testing/requests_test.go index 1b974a1497..24abf1cb72 100644 --- a/openstack/networking/v2/extensions/security/addressgroups/testing/requests_test.go +++ b/openstack/networking/v2/extensions/security/addressgroups/testing/requests_test.go @@ -13,10 +13,10 @@ import ( ) func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/address-groups", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/address-groups", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -28,7 +28,7 @@ func TestList(t *testing.T) { count := 0 - err := addressgroups.List(fake.ServiceClient(), addressgroups.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := addressgroups.List(fake.ServiceClient(fakeServer), addressgroups.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := addressgroups.ExtractGroups(page) if err != nil { @@ -60,10 +60,10 @@ func TestList(t *testing.T) { } func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/address-groups", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/address-groups", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -82,22 +82,25 @@ func TestCreate(t *testing.T) { "132.168.4.12/24", }, } - _, err := addressgroups.Create(context.TODO(), fake.ServiceClient(), opts).Extract() + _, err := addressgroups.Create(context.TODO(), fake.ServiceClient(fakeServer), opts).Extract() th.AssertNoErr(t, err) } func TestRequiredCreateOpts(t *testing.T) { - _, err := addressgroups.Create(context.TODO(), fake.ServiceClient(), addressgroups.CreateOpts{Name: "ADDR_GP_1"}).Extract() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + _, err := addressgroups.Create(context.TODO(), fake.ServiceClient(fakeServer), addressgroups.CreateOpts{Name: "ADDR_GP_1"}).Extract() if err == nil { t.Fatalf("Expected error, got none") } } func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/address-groups/8722e0e0-9cc9-4490-9660-8c9a5732fbb0", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/address-groups/8722e0e0-9cc9-4490-9660-8c9a5732fbb0", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -107,7 +110,7 @@ func TestGet(t *testing.T) { fmt.Fprintf(w, AddressGroupGetResponse) }) - sr, err := addressgroups.Get(context.TODO(), fake.ServiceClient(), "8722e0e0-9cc9-4490-9660-8c9a5732fbb0").Extract() + sr, err := addressgroups.Get(context.TODO(), fake.ServiceClient(fakeServer), "8722e0e0-9cc9-4490-9660-8c9a5732fbb0").Extract() th.AssertNoErr(t, err) th.AssertEquals(t, "", sr.Description) th.AssertEquals(t, "8722e0e0-9cc9-4490-9660-8c9a5732fbb0", sr.ID) @@ -117,10 +120,10 @@ func TestGet(t *testing.T) { } func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/address-groups/8722e0e0-9cc9-4490-9660-8c9a5732fbb0", + fakeServer.Mux.HandleFunc("/v2.0/address-groups/8722e0e0-9cc9-4490-9660-8c9a5732fbb0", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -140,7 +143,7 @@ func TestUpdate(t *testing.T) { Name: &name, Description: &description, } - ag, err := addressgroups.Update(context.TODO(), fake.ServiceClient(), "8722e0e0-9cc9-4490-9660-8c9a5732fbb0", opts).Extract() + ag, err := addressgroups.Update(context.TODO(), fake.ServiceClient(fakeServer), "8722e0e0-9cc9-4490-9660-8c9a5732fbb0", opts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, []string{"192.168.4.1/32"}, ag.Addresses) @@ -151,10 +154,10 @@ func TestUpdate(t *testing.T) { } func TestAddAddresses(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/address-groups/8722e0e0-9cc9-4490-9660-8c9a5732fbb0/add_addresses", + fakeServer.Mux.HandleFunc("/v2.0/address-groups/8722e0e0-9cc9-4490-9660-8c9a5732fbb0/add_addresses", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -171,7 +174,7 @@ func TestAddAddresses(t *testing.T) { opts := addressgroups.UpdateAddressesOpts{ Addresses: []string{"192.168.4.1/32"}, } - ag, err := addressgroups.AddAddresses(context.TODO(), fake.ServiceClient(), "8722e0e0-9cc9-4490-9660-8c9a5732fbb0", opts).Extract() + ag, err := addressgroups.AddAddresses(context.TODO(), fake.ServiceClient(fakeServer), "8722e0e0-9cc9-4490-9660-8c9a5732fbb0", opts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, []string{"132.168.4.12/24", "192.168.4.1/32"}, ag.Addresses) @@ -180,10 +183,10 @@ func TestAddAddresses(t *testing.T) { } func TestRemoveAddresses(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/address-groups/8722e0e0-9cc9-4490-9660-8c9a5732fbb0/remove_addresses", + fakeServer.Mux.HandleFunc("/v2.0/address-groups/8722e0e0-9cc9-4490-9660-8c9a5732fbb0/remove_addresses", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -200,7 +203,7 @@ func TestRemoveAddresses(t *testing.T) { opts := addressgroups.UpdateAddressesOpts{ Addresses: []string{"192.168.4.1/32"}, } - ag, err := addressgroups.RemoveAddresses(context.TODO(), fake.ServiceClient(), "8722e0e0-9cc9-4490-9660-8c9a5732fbb0", opts).Extract() + ag, err := addressgroups.RemoveAddresses(context.TODO(), fake.ServiceClient(fakeServer), "8722e0e0-9cc9-4490-9660-8c9a5732fbb0", opts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, []string{"132.168.4.12/24"}, ag.Addresses) @@ -209,16 +212,16 @@ func TestRemoveAddresses(t *testing.T) { } func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/address-groups/4ec89087-d057-4e2c-911f-60a3b47ee304", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/address-groups/4ec89087-d057-4e2c-911f-60a3b47ee304", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.WriteHeader(http.StatusNoContent) }) - err := addressgroups.Delete(context.TODO(), fake.ServiceClient(), "4ec89087-d057-4e2c-911f-60a3b47ee304").ExtractErr() + err := addressgroups.Delete(context.TODO(), fake.ServiceClient(fakeServer), "4ec89087-d057-4e2c-911f-60a3b47ee304").ExtractErr() th.AssertNoErr(t, err) } diff --git a/openstack/networking/v2/extensions/security/groups/testing/requests_test.go b/openstack/networking/v2/extensions/security/groups/testing/requests_test.go index f816f0d6d2..320e537e00 100644 --- a/openstack/networking/v2/extensions/security/groups/testing/requests_test.go +++ b/openstack/networking/v2/extensions/security/groups/testing/requests_test.go @@ -14,10 +14,10 @@ import ( ) func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/security-groups", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/security-groups", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -29,7 +29,7 @@ func TestList(t *testing.T) { count := 0 - err := groups.List(fake.ServiceClient(), groups.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := groups.List(fake.ServiceClient(fakeServer), groups.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := groups.ExtractGroups(page) if err != nil { @@ -51,10 +51,10 @@ func TestList(t *testing.T) { } func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/security-groups", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/security-groups", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -68,15 +68,15 @@ func TestCreate(t *testing.T) { }) opts := groups.CreateOpts{Name: "new-webservers", Description: "security group for webservers"} - _, err := groups.Create(context.TODO(), fake.ServiceClient(), opts).Extract() + _, err := groups.Create(context.TODO(), fake.ServiceClient(fakeServer), opts).Extract() th.AssertNoErr(t, err) } func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/security-groups/2076db17-a522-4506-91de-c6dd8e837028", + fakeServer.Mux.HandleFunc("/v2.0/security-groups/2076db17-a522-4506-91de-c6dd8e837028", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -91,7 +91,7 @@ func TestUpdate(t *testing.T) { }) opts := groups.UpdateOpts{Name: "newer-webservers"} - sg, err := groups.Update(context.TODO(), fake.ServiceClient(), "2076db17-a522-4506-91de-c6dd8e837028", opts).Extract() + sg, err := groups.Update(context.TODO(), fake.ServiceClient(fakeServer), "2076db17-a522-4506-91de-c6dd8e837028", opts).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, "newer-webservers", sg.Name) @@ -102,10 +102,10 @@ func TestUpdate(t *testing.T) { } func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/security-groups/85cc3048-abc3-43cc-89b3-377341426ac5", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/security-groups/85cc3048-abc3-43cc-89b3-377341426ac5", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -115,7 +115,7 @@ func TestGet(t *testing.T) { fmt.Fprint(w, SecurityGroupGetResponse) }) - sg, err := groups.Get(context.TODO(), fake.ServiceClient(), "85cc3048-abc3-43cc-89b3-377341426ac5").Extract() + sg, err := groups.Get(context.TODO(), fake.ServiceClient(fakeServer), "85cc3048-abc3-43cc-89b3-377341426ac5").Extract() th.AssertNoErr(t, err) th.AssertEquals(t, "default", sg.Description) @@ -128,15 +128,15 @@ func TestGet(t *testing.T) { } func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/security-groups/4ec89087-d057-4e2c-911f-60a3b47ee304", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/security-groups/4ec89087-d057-4e2c-911f-60a3b47ee304", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.WriteHeader(http.StatusNoContent) }) - res := groups.Delete(context.TODO(), fake.ServiceClient(), "4ec89087-d057-4e2c-911f-60a3b47ee304") + res := groups.Delete(context.TODO(), fake.ServiceClient(fakeServer), "4ec89087-d057-4e2c-911f-60a3b47ee304") th.AssertNoErr(t, res.Err) } diff --git a/openstack/networking/v2/extensions/security/rules/testing/requests_test.go b/openstack/networking/v2/extensions/security/rules/testing/requests_test.go index d705eaf018..256ce3d858 100644 --- a/openstack/networking/v2/extensions/security/rules/testing/requests_test.go +++ b/openstack/networking/v2/extensions/security/rules/testing/requests_test.go @@ -13,10 +13,10 @@ import ( ) func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/security-group-rules", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/security-group-rules", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -57,7 +57,7 @@ func TestList(t *testing.T) { count := 0 - err := rules.List(fake.ServiceClient(), rules.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := rules.List(fake.ServiceClient(fakeServer), rules.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := rules.ExtractRules(page) if err != nil { @@ -105,10 +105,10 @@ func TestList(t *testing.T) { } func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/security-group-rules", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/security-group-rules", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -160,15 +160,15 @@ func TestCreate(t *testing.T) { RemoteGroupID: "85cc3048-abc3-43cc-89b3-377341426ac5", SecGroupID: "a7734e61-b545-452d-a3cd-0189cbd9747a", } - _, err := rules.Create(context.TODO(), fake.ServiceClient(), opts).Extract() + _, err := rules.Create(context.TODO(), fake.ServiceClient(fakeServer), opts).Extract() th.AssertNoErr(t, err) } func TestCreateAnyProtocol(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/security-group-rules", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/security-group-rules", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -218,15 +218,15 @@ func TestCreateAnyProtocol(t *testing.T) { RemoteGroupID: "85cc3048-abc3-43cc-89b3-377341426ac5", SecGroupID: "a7734e61-b545-452d-a3cd-0189cbd9747a", } - _, err := rules.Create(context.TODO(), fake.ServiceClient(), opts).Extract() + _, err := rules.Create(context.TODO(), fake.ServiceClient(fakeServer), opts).Extract() th.AssertNoErr(t, err) } func TestCreateBulk(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/security-group-rules", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/security-group-rules", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -313,37 +313,37 @@ func TestCreateBulk(t *testing.T) { SecGroupID: "a7734e61-b545-452d-a3cd-0189cbd9747a", }, } - _, err := rules.CreateBulk(context.TODO(), fake.ServiceClient(), opts).Extract() + _, err := rules.CreateBulk(context.TODO(), fake.ServiceClient(fakeServer), opts).Extract() th.AssertNoErr(t, err) } func TestRequiredCreateOpts(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - res := rules.Create(context.TODO(), fake.ServiceClient(), rules.CreateOpts{Direction: rules.DirIngress}) + res := rules.Create(context.TODO(), fake.ServiceClient(fakeServer), rules.CreateOpts{Direction: rules.DirIngress}) if res.Err == nil { t.Fatalf("Expected error, got none") } - res = rules.Create(context.TODO(), fake.ServiceClient(), rules.CreateOpts{Direction: rules.DirIngress, EtherType: rules.EtherType4}) + res = rules.Create(context.TODO(), fake.ServiceClient(fakeServer), rules.CreateOpts{Direction: rules.DirIngress, EtherType: rules.EtherType4}) if res.Err == nil { t.Fatalf("Expected error, got none") } - res = rules.Create(context.TODO(), fake.ServiceClient(), rules.CreateOpts{Direction: rules.DirIngress, EtherType: rules.EtherType4}) + res = rules.Create(context.TODO(), fake.ServiceClient(fakeServer), rules.CreateOpts{Direction: rules.DirIngress, EtherType: rules.EtherType4}) if res.Err == nil { t.Fatalf("Expected error, got none") } - res = rules.Create(context.TODO(), fake.ServiceClient(), rules.CreateOpts{Direction: rules.DirIngress, EtherType: rules.EtherType4, SecGroupID: "something", Protocol: "foo"}) + res = rules.Create(context.TODO(), fake.ServiceClient(fakeServer), rules.CreateOpts{Direction: rules.DirIngress, EtherType: rules.EtherType4, SecGroupID: "something", Protocol: "foo"}) if res.Err == nil { t.Fatalf("Expected error, got none") } } func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/security-group-rules/3c0e45ff-adaf-4124-b083-bf390e5482ff", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/security-group-rules/3c0e45ff-adaf-4124-b083-bf390e5482ff", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -368,7 +368,7 @@ func TestGet(t *testing.T) { `) }) - sr, err := rules.Get(context.TODO(), fake.ServiceClient(), "3c0e45ff-adaf-4124-b083-bf390e5482ff").Extract() + sr, err := rules.Get(context.TODO(), fake.ServiceClient(fakeServer), "3c0e45ff-adaf-4124-b083-bf390e5482ff").Extract() th.AssertNoErr(t, err) th.AssertEquals(t, "egress", sr.Direction) @@ -384,15 +384,15 @@ func TestGet(t *testing.T) { } func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/security-group-rules/4ec89087-d057-4e2c-911f-60a3b47ee304", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/security-group-rules/4ec89087-d057-4e2c-911f-60a3b47ee304", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.WriteHeader(http.StatusNoContent) }) - res := rules.Delete(context.TODO(), fake.ServiceClient(), "4ec89087-d057-4e2c-911f-60a3b47ee304") + res := rules.Delete(context.TODO(), fake.ServiceClient(fakeServer), "4ec89087-d057-4e2c-911f-60a3b47ee304") th.AssertNoErr(t, res.Err) } diff --git a/openstack/networking/v2/extensions/subnetpools/testing/requests_test.go b/openstack/networking/v2/extensions/subnetpools/testing/requests_test.go index 2d8df70180..8520ef1103 100644 --- a/openstack/networking/v2/extensions/subnetpools/testing/requests_test.go +++ b/openstack/networking/v2/extensions/subnetpools/testing/requests_test.go @@ -14,10 +14,10 @@ import ( ) func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/subnetpools", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/subnetpools", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -29,7 +29,7 @@ func TestList(t *testing.T) { count := 0 - err := subnetpools.List(fake.ServiceClient(), subnetpools.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := subnetpools.List(fake.ServiceClient(fakeServer), subnetpools.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := subnetpools.ExtractSubnetPools(page) if err != nil { @@ -56,10 +56,10 @@ func TestList(t *testing.T) { } func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/subnetpools/0a738452-8057-4ad3-89c2-92f6a74afa76", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/subnetpools/0a738452-8057-4ad3-89c2-92f6a74afa76", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -69,7 +69,7 @@ func TestGet(t *testing.T) { fmt.Fprint(w, SubnetPoolGetResult) }) - s, err := subnetpools.Get(context.TODO(), fake.ServiceClient(), "0a738452-8057-4ad3-89c2-92f6a74afa76").Extract() + s, err := subnetpools.Get(context.TODO(), fake.ServiceClient(fakeServer), "0a738452-8057-4ad3-89c2-92f6a74afa76").Extract() th.AssertNoErr(t, err) th.AssertEquals(t, s.ID, "0a738452-8057-4ad3-89c2-92f6a74afa76") @@ -93,10 +93,10 @@ func TestGet(t *testing.T) { th.AssertEquals(t, s.RevisionNumber, 2) } func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/subnetpools", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/subnetpools", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -120,7 +120,7 @@ func TestCreate(t *testing.T) { AddressScopeID: "3d4e2e2a-552b-42ad-a16d-820bbf3edaf3", Description: "ipv4 prefixes", } - s, err := subnetpools.Create(context.TODO(), fake.ServiceClient(), opts).Extract() + s, err := subnetpools.Create(context.TODO(), fake.ServiceClient(fakeServer), opts).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, s.Name, "my_ipv4_pool") @@ -135,10 +135,10 @@ func TestCreate(t *testing.T) { } func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/subnetpools/099546ca-788d-41e5-a76d-17d8cd282d3e", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/subnetpools/099546ca-788d-41e5-a76d-17d8cd282d3e", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -164,7 +164,7 @@ func TestUpdate(t *testing.T) { DefaultQuota: &nullInt, Description: &nullString, } - n, err := subnetpools.Update(context.TODO(), fake.ServiceClient(), "099546ca-788d-41e5-a76d-17d8cd282d3e", updateOpts).Extract() + n, err := subnetpools.Update(context.TODO(), fake.ServiceClient(fakeServer), "099546ca-788d-41e5-a76d-17d8cd282d3e", updateOpts).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, n.Name, "new_subnetpool_name") @@ -181,15 +181,15 @@ func TestUpdate(t *testing.T) { } func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/subnetpools/099546ca-788d-41e5-a76d-17d8cd282d3e", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/subnetpools/099546ca-788d-41e5-a76d-17d8cd282d3e", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.WriteHeader(http.StatusNoContent) }) - res := subnetpools.Delete(context.TODO(), fake.ServiceClient(), "099546ca-788d-41e5-a76d-17d8cd282d3e") + res := subnetpools.Delete(context.TODO(), fake.ServiceClient(fakeServer), "099546ca-788d-41e5-a76d-17d8cd282d3e") th.AssertNoErr(t, res.Err) } diff --git a/openstack/networking/v2/extensions/testing/delegate_test.go b/openstack/networking/v2/extensions/testing/delegate_test.go index 9f3421f272..95fa8461d3 100644 --- a/openstack/networking/v2/extensions/testing/delegate_test.go +++ b/openstack/networking/v2/extensions/testing/delegate_test.go @@ -14,10 +14,10 @@ import ( ) func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/extensions", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/extensions", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -41,7 +41,7 @@ func TestList(t *testing.T) { count := 0 - err := extensions.List(fake.ServiceClient()).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := extensions.List(fake.ServiceClient(fakeServer)).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := extensions.ExtractExtensions(page) if err != nil { @@ -73,10 +73,10 @@ func TestList(t *testing.T) { } func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/extensions/agent", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/extensions/agent", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -97,7 +97,7 @@ func TestGet(t *testing.T) { `) }) - ext, err := extensions.Get(context.TODO(), fake.ServiceClient(), "agent").Extract() + ext, err := extensions.Get(context.TODO(), fake.ServiceClient(fakeServer), "agent").Extract() th.AssertNoErr(t, err) th.AssertEquals(t, ext.Updated, "2013-02-03T10:00:00-00:00") diff --git a/openstack/networking/v2/extensions/trunk_details/testing/requests_test.go b/openstack/networking/v2/extensions/trunk_details/testing/requests_test.go index cca584c6d1..fdbd4329f2 100644 --- a/openstack/networking/v2/extensions/trunk_details/testing/requests_test.go +++ b/openstack/networking/v2/extensions/trunk_details/testing/requests_test.go @@ -13,12 +13,12 @@ import ( ) func TestServerWithUsageExt(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() const portIDFixture = "dc3e8758-ee96-402d-94b0-4be5e9396c82" - th.Mux.HandleFunc("/ports/"+portIDFixture, func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/ports/"+portIDFixture, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -32,7 +32,7 @@ func TestServerWithUsageExt(t *testing.T) { } // Extract basic fields. - err := ports.Get(context.TODO(), client.ServiceClient(), portIDFixture).ExtractInto(&portExt) + err := ports.Get(context.TODO(), client.ServiceClient(fakeServer), portIDFixture).ExtractInto(&portExt) th.AssertNoErr(t, err) th.AssertEquals(t, portExt.TrunkDetails.TrunkID, "f170c831-8c55-4ceb-ad13-75eab4a121e5") diff --git a/openstack/networking/v2/extensions/trunks/testing/requests_test.go b/openstack/networking/v2/extensions/trunks/testing/requests_test.go index 81e6bef8c2..955a549f57 100644 --- a/openstack/networking/v2/extensions/trunks/testing/requests_test.go +++ b/openstack/networking/v2/extensions/trunks/testing/requests_test.go @@ -13,10 +13,10 @@ import ( ) func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/trunks", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/trunks", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -46,12 +46,12 @@ func TestCreate(t *testing.T) { }, }, } - _, err := trunks.Create(context.TODO(), fake.ServiceClient(), options).Extract() + _, err := trunks.Create(context.TODO(), fake.ServiceClient(fakeServer), options).Extract() if err == nil { t.Fatalf("Failed to detect missing parent PortID field") } options.PortID = "c373d2fa-3d3b-4492-924c-aff54dea19b6" - n, err := trunks.Create(context.TODO(), fake.ServiceClient(), options).Extract() + n, err := trunks.Create(context.TODO(), fake.ServiceClient(fakeServer), options).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, n.Status, "ACTIVE") @@ -61,10 +61,10 @@ func TestCreate(t *testing.T) { } func TestCreateNoSubports(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/trunks", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/trunks", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -83,7 +83,7 @@ func TestCreateNoSubports(t *testing.T) { AdminStateUp: &iTrue, PortID: "c373d2fa-3d3b-4492-924c-aff54dea19b6", } - n, err := trunks.Create(context.TODO(), fake.ServiceClient(), options).Extract() + n, err := trunks.Create(context.TODO(), fake.ServiceClient(fakeServer), options).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, n.Status, "ACTIVE") @@ -91,24 +91,24 @@ func TestCreateNoSubports(t *testing.T) { } func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/trunks/f6a9718c-5a64-43e3-944f-4deccad8e78c", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/trunks/f6a9718c-5a64-43e3-944f-4deccad8e78c", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.WriteHeader(http.StatusNoContent) }) - res := trunks.Delete(context.TODO(), fake.ServiceClient(), "f6a9718c-5a64-43e3-944f-4deccad8e78c") + res := trunks.Delete(context.TODO(), fake.ServiceClient(fakeServer), "f6a9718c-5a64-43e3-944f-4deccad8e78c") th.AssertNoErr(t, res.Err) } func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/trunks", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/trunks", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -118,7 +118,7 @@ func TestList(t *testing.T) { fmt.Fprint(w, ListResponse) }) - client := fake.ServiceClient() + client := fake.ServiceClient(fakeServer) count := 0 err := trunks.List(client, trunks.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { @@ -143,10 +143,10 @@ func TestList(t *testing.T) { } func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/trunks/f6a9718c-5a64-43e3-944f-4deccad8e78c", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/trunks/f6a9718c-5a64-43e3-944f-4deccad8e78c", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -156,7 +156,7 @@ func TestGet(t *testing.T) { fmt.Fprint(w, GetResponse) }) - n, err := trunks.Get(context.TODO(), fake.ServiceClient(), "f6a9718c-5a64-43e3-944f-4deccad8e78c").Extract() + n, err := trunks.Get(context.TODO(), fake.ServiceClient(fakeServer), "f6a9718c-5a64-43e3-944f-4deccad8e78c").Extract() th.AssertNoErr(t, err) expectedTrunks, err := ExpectedTrunkSlice() th.AssertNoErr(t, err) @@ -164,10 +164,10 @@ func TestGet(t *testing.T) { } func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/trunks/f6a9718c-5a64-43e3-944f-4deccad8e78c", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/trunks/f6a9718c-5a64-43e3-944f-4deccad8e78c", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -188,7 +188,7 @@ func TestUpdate(t *testing.T) { AdminStateUp: &iFalse, Description: &description, } - n, err := trunks.Update(context.TODO(), fake.ServiceClient(), "f6a9718c-5a64-43e3-944f-4deccad8e78c", options).Extract() + n, err := trunks.Update(context.TODO(), fake.ServiceClient(fakeServer), "f6a9718c-5a64-43e3-944f-4deccad8e78c", options).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, n.Name, name) @@ -197,10 +197,10 @@ func TestUpdate(t *testing.T) { } func TestGetSubports(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/trunks/f6a9718c-5a64-43e3-944f-4deccad8e78c/get_subports", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/trunks/f6a9718c-5a64-43e3-944f-4deccad8e78c/get_subports", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -210,7 +210,7 @@ func TestGetSubports(t *testing.T) { fmt.Fprint(w, ListSubportsResponse) }) - client := fake.ServiceClient() + client := fake.ServiceClient(fakeServer) subports, err := trunks.GetSubports(context.TODO(), client, "f6a9718c-5a64-43e3-944f-4deccad8e78c").Extract() th.AssertNoErr(t, err) @@ -248,10 +248,10 @@ func TestMissingFields(t *testing.T) { } func TestAddSubports(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/trunks/f6a9718c-5a64-43e3-944f-4deccad8e78c/add_subports", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/trunks/f6a9718c-5a64-43e3-944f-4deccad8e78c/add_subports", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -262,7 +262,7 @@ func TestAddSubports(t *testing.T) { fmt.Fprint(w, AddSubportsResponse) }) - client := fake.ServiceClient() + client := fake.ServiceClient(fakeServer) opts := trunks.AddSubportsOpts{ Subports: ExpectedSubports, @@ -276,10 +276,10 @@ func TestAddSubports(t *testing.T) { } func TestRemoveSubports(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/trunks/f6a9718c-5a64-43e3-944f-4deccad8e78c/remove_subports", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/trunks/f6a9718c-5a64-43e3-944f-4deccad8e78c/remove_subports", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -290,7 +290,7 @@ func TestRemoveSubports(t *testing.T) { fmt.Fprint(w, RemoveSubportsResponse) }) - client := fake.ServiceClient() + client := fake.ServiceClient(fakeServer) opts := trunks.RemoveSubportsOpts{ Subports: []trunks.RemoveSubport{ diff --git a/openstack/networking/v2/extensions/vlantransparent/testing/requests_test.go b/openstack/networking/v2/extensions/vlantransparent/testing/requests_test.go index dc5d55043a..1850f4db0a 100644 --- a/openstack/networking/v2/extensions/vlantransparent/testing/requests_test.go +++ b/openstack/networking/v2/extensions/vlantransparent/testing/requests_test.go @@ -13,10 +13,10 @@ import ( ) func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/networks", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/networks", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -32,7 +32,7 @@ func TestList(t *testing.T) { } var actual []networkVLANTransparentExt - allPages, err := networks.List(fake.ServiceClient(), networks.ListOpts{}).AllPages(context.TODO()) + allPages, err := networks.List(fake.ServiceClient(fakeServer), networks.ListOpts{}).AllPages(context.TODO()) th.AssertNoErr(t, err) err = networks.ExtractNetworksInto(allPages, &actual) @@ -49,10 +49,10 @@ func TestList(t *testing.T) { } func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/networks/db193ab3-96e3-4cb3-8fc5-05f4296d0324", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/networks/db193ab3-96e3-4cb3-8fc5-05f4296d0324", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -67,7 +67,7 @@ func TestGet(t *testing.T) { vlantransparent.TransparentExt } - err := networks.Get(context.TODO(), fake.ServiceClient(), "db193ab3-96e3-4cb3-8fc5-05f4296d0324").ExtractInto(&s) + err := networks.Get(context.TODO(), fake.ServiceClient(fakeServer), "db193ab3-96e3-4cb3-8fc5-05f4296d0324").ExtractInto(&s) th.AssertNoErr(t, err) th.AssertEquals(t, "db193ab3-96e3-4cb3-8fc5-05f4296d0324", s.ID) @@ -81,10 +81,10 @@ func TestGet(t *testing.T) { } func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/networks", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/networks", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -112,7 +112,7 @@ func TestCreate(t *testing.T) { vlantransparent.TransparentExt } - err := networks.Create(context.TODO(), fake.ServiceClient(), vlanTransparentCreateOpts).ExtractInto(&s) + err := networks.Create(context.TODO(), fake.ServiceClient(fakeServer), vlanTransparentCreateOpts).ExtractInto(&s) th.AssertNoErr(t, err) th.AssertEquals(t, "db193ab3-96e3-4cb3-8fc5-05f4296d0324", s.ID) @@ -126,10 +126,10 @@ func TestCreate(t *testing.T) { } func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/networks/4e8e5957-649f-477b-9e5b-f1f75b21c03c", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/networks/4e8e5957-649f-477b-9e5b-f1f75b21c03c", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -159,7 +159,7 @@ func TestUpdate(t *testing.T) { vlantransparent.TransparentExt } - err := networks.Update(context.TODO(), fake.ServiceClient(), "4e8e5957-649f-477b-9e5b-f1f75b21c03c", vlanTransparentUpdateOpts).ExtractInto(&s) + err := networks.Update(context.TODO(), fake.ServiceClient(fakeServer), "4e8e5957-649f-477b-9e5b-f1f75b21c03c", vlanTransparentUpdateOpts).ExtractInto(&s) th.AssertNoErr(t, err) th.AssertEquals(t, "db193ab3-96e3-4cb3-8fc5-05f4296d0324", s.ID) diff --git a/openstack/networking/v2/extensions/vpnaas/endpointgroups/testing/requests_test.go b/openstack/networking/v2/extensions/vpnaas/endpointgroups/testing/requests_test.go index dbf3ba515e..c7620500e1 100644 --- a/openstack/networking/v2/extensions/vpnaas/endpointgroups/testing/requests_test.go +++ b/openstack/networking/v2/extensions/vpnaas/endpointgroups/testing/requests_test.go @@ -13,10 +13,10 @@ import ( ) func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/vpn/endpoint-groups", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/vpn/endpoint-groups", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -62,7 +62,7 @@ func TestCreate(t *testing.T) { "10.3.0.0/24", }, } - actual, err := endpointgroups.Create(context.TODO(), fake.ServiceClient(), options).Extract() + actual, err := endpointgroups.Create(context.TODO(), fake.ServiceClient(fakeServer), options).Extract() th.AssertNoErr(t, err) expected := endpointgroups.EndpointGroup{ Name: "peers", @@ -80,10 +80,10 @@ func TestCreate(t *testing.T) { } func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/vpn/endpoint-groups/5c561d9d-eaea-45f6-ae3e-08d1a7080828", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/vpn/endpoint-groups/5c561d9d-eaea-45f6-ae3e-08d1a7080828", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -108,7 +108,7 @@ func TestGet(t *testing.T) { `) }) - actual, err := endpointgroups.Get(context.TODO(), fake.ServiceClient(), "5c561d9d-eaea-45f6-ae3e-08d1a7080828").Extract() + actual, err := endpointgroups.Get(context.TODO(), fake.ServiceClient(fakeServer), "5c561d9d-eaea-45f6-ae3e-08d1a7080828").Extract() th.AssertNoErr(t, err) expected := endpointgroups.EndpointGroup{ Name: "peers", @@ -126,10 +126,10 @@ func TestGet(t *testing.T) { } func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/vpn/endpoint-groups", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/vpn/endpoint-groups", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.Header().Add("Content-Type", "application/json") @@ -157,7 +157,7 @@ func TestList(t *testing.T) { count := 0 - err := endpointgroups.List(fake.ServiceClient(), endpointgroups.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := endpointgroups.List(fake.ServiceClient(fakeServer), endpointgroups.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := endpointgroups.ExtractEndpointGroups(page) if err != nil { @@ -190,24 +190,24 @@ func TestList(t *testing.T) { } func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/vpn/endpoint-groups/5c561d9d-eaea-45f6-ae3e-08d1a7080828", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/vpn/endpoint-groups/5c561d9d-eaea-45f6-ae3e-08d1a7080828", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.WriteHeader(http.StatusNoContent) }) - res := endpointgroups.Delete(context.TODO(), fake.ServiceClient(), "5c561d9d-eaea-45f6-ae3e-08d1a7080828") + res := endpointgroups.Delete(context.TODO(), fake.ServiceClient(fakeServer), "5c561d9d-eaea-45f6-ae3e-08d1a7080828") th.AssertNoErr(t, res.Err) } func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/vpn/endpoint-groups/5c561d9d-eaea-45f6-ae3e-08d1a7080828", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/vpn/endpoint-groups/5c561d9d-eaea-45f6-ae3e-08d1a7080828", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -249,7 +249,7 @@ func TestUpdate(t *testing.T) { Description: &updatedDescription, } - actual, err := endpointgroups.Update(context.TODO(), fake.ServiceClient(), "5c561d9d-eaea-45f6-ae3e-08d1a7080828", options).Extract() + actual, err := endpointgroups.Update(context.TODO(), fake.ServiceClient(fakeServer), "5c561d9d-eaea-45f6-ae3e-08d1a7080828", options).Extract() th.AssertNoErr(t, err) expected := endpointgroups.EndpointGroup{ Name: "updatedname", diff --git a/openstack/networking/v2/extensions/vpnaas/ikepolicies/testing/requests_test.go b/openstack/networking/v2/extensions/vpnaas/ikepolicies/testing/requests_test.go index e8e63dfde7..60b8939a60 100644 --- a/openstack/networking/v2/extensions/vpnaas/ikepolicies/testing/requests_test.go +++ b/openstack/networking/v2/extensions/vpnaas/ikepolicies/testing/requests_test.go @@ -13,10 +13,10 @@ import ( ) func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/vpn/ikepolicies", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/vpn/ikepolicies", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -64,7 +64,7 @@ func TestCreate(t *testing.T) { IKEVersion: ikepolicies.IKEVersionv2, } - actual, err := ikepolicies.Create(context.TODO(), fake.ServiceClient(), options).Extract() + actual, err := ikepolicies.Create(context.TODO(), fake.ServiceClient(fakeServer), options).Extract() th.AssertNoErr(t, err) expectedLifetime := ikepolicies.Lifetime{ Units: "seconds", @@ -87,10 +87,10 @@ func TestCreate(t *testing.T) { } func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/vpn/ikepolicies/5c561d9d-eaea-45f6-ae3e-08d1a7080828", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/vpn/ikepolicies/5c561d9d-eaea-45f6-ae3e-08d1a7080828", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -119,7 +119,7 @@ func TestGet(t *testing.T) { `) }) - actual, err := ikepolicies.Get(context.TODO(), fake.ServiceClient(), "5c561d9d-eaea-45f6-ae3e-08d1a7080828").Extract() + actual, err := ikepolicies.Get(context.TODO(), fake.ServiceClient(fakeServer), "5c561d9d-eaea-45f6-ae3e-08d1a7080828").Extract() th.AssertNoErr(t, err) expectedLifetime := ikepolicies.Lifetime{ Units: "seconds", @@ -142,24 +142,24 @@ func TestGet(t *testing.T) { } func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/vpn/ikepolicies/5c561d9d-eaea-45f6-ae3e-08d1a7080828", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/vpn/ikepolicies/5c561d9d-eaea-45f6-ae3e-08d1a7080828", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.WriteHeader(http.StatusNoContent) }) - res := ikepolicies.Delete(context.TODO(), fake.ServiceClient(), "5c561d9d-eaea-45f6-ae3e-08d1a7080828") + res := ikepolicies.Delete(context.TODO(), fake.ServiceClient(fakeServer), "5c561d9d-eaea-45f6-ae3e-08d1a7080828") th.AssertNoErr(t, res.Err) } func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/vpn/ikepolicies", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/vpn/ikepolicies", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.Header().Add("Content-Type", "application/json") @@ -191,7 +191,7 @@ func TestList(t *testing.T) { count := 0 - err := ikepolicies.List(fake.ServiceClient(), ikepolicies.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := ikepolicies.List(fake.ServiceClient(fakeServer), ikepolicies.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := ikepolicies.ExtractPolicies(page) if err != nil { @@ -230,10 +230,10 @@ func TestList(t *testing.T) { } func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/vpn/ikepolicies/5c561d9d-eaea-45f6-ae3e-08d1a7080828", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/vpn/ikepolicies/5c561d9d-eaea-45f6-ae3e-08d1a7080828", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -285,7 +285,7 @@ func TestUpdate(t *testing.T) { }, } - actual, err := ikepolicies.Update(context.TODO(), fake.ServiceClient(), "5c561d9d-eaea-45f6-ae3e-08d1a7080828", options).Extract() + actual, err := ikepolicies.Update(context.TODO(), fake.ServiceClient(fakeServer), "5c561d9d-eaea-45f6-ae3e-08d1a7080828", options).Extract() th.AssertNoErr(t, err) expectedLifetime := ikepolicies.Lifetime{ Units: "seconds", diff --git a/openstack/networking/v2/extensions/vpnaas/ipsecpolicies/testing/requests_test.go b/openstack/networking/v2/extensions/vpnaas/ipsecpolicies/testing/requests_test.go index 35c09a4ad5..27435c51a6 100644 --- a/openstack/networking/v2/extensions/vpnaas/ipsecpolicies/testing/requests_test.go +++ b/openstack/networking/v2/extensions/vpnaas/ipsecpolicies/testing/requests_test.go @@ -13,10 +13,10 @@ import ( ) func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/vpn/ipsecpolicies", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/vpn/ipsecpolicies", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -78,7 +78,7 @@ func TestCreate(t *testing.T) { Lifetime: &lifetime, Description: "", } - actual, err := ipsecpolicies.Create(context.TODO(), fake.ServiceClient(), options).Extract() + actual, err := ipsecpolicies.Create(context.TODO(), fake.ServiceClient(fakeServer), options).Extract() th.AssertNoErr(t, err) expectedLifetime := ipsecpolicies.Lifetime{ Units: "seconds", @@ -101,10 +101,10 @@ func TestCreate(t *testing.T) { } func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/vpn/ipsecpolicies/5c561d9d-eaea-45f6-ae3e-08d1a7080828", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/vpn/ipsecpolicies/5c561d9d-eaea-45f6-ae3e-08d1a7080828", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -133,7 +133,7 @@ func TestGet(t *testing.T) { `) }) - actual, err := ipsecpolicies.Get(context.TODO(), fake.ServiceClient(), "5c561d9d-eaea-45f6-ae3e-08d1a7080828").Extract() + actual, err := ipsecpolicies.Get(context.TODO(), fake.ServiceClient(fakeServer), "5c561d9d-eaea-45f6-ae3e-08d1a7080828").Extract() th.AssertNoErr(t, err) expectedLifetime := ipsecpolicies.Lifetime{ Units: "seconds", @@ -156,24 +156,24 @@ func TestGet(t *testing.T) { } func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/vpn/ipsecpolicies/5c561d9d-eaea-45f6-ae3e-08d1a7080828", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/vpn/ipsecpolicies/5c561d9d-eaea-45f6-ae3e-08d1a7080828", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.WriteHeader(http.StatusNoContent) }) - res := ipsecpolicies.Delete(context.TODO(), fake.ServiceClient(), "5c561d9d-eaea-45f6-ae3e-08d1a7080828") + res := ipsecpolicies.Delete(context.TODO(), fake.ServiceClient(fakeServer), "5c561d9d-eaea-45f6-ae3e-08d1a7080828") th.AssertNoErr(t, res.Err) } func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/vpn/ipsecpolicies", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/vpn/ipsecpolicies", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -206,7 +206,7 @@ func TestList(t *testing.T) { count := 0 - err := ipsecpolicies.List(fake.ServiceClient(), ipsecpolicies.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := ipsecpolicies.List(fake.ServiceClient(fakeServer), ipsecpolicies.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := ipsecpolicies.ExtractPolicies(page) if err != nil { @@ -245,10 +245,10 @@ func TestList(t *testing.T) { } func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/vpn/ipsecpolicies/5c561d9d-eaea-45f6-ae3e-08d1a7080828", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/vpn/ipsecpolicies/5c561d9d-eaea-45f6-ae3e-08d1a7080828", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -300,7 +300,7 @@ func TestUpdate(t *testing.T) { }, } - actual, err := ipsecpolicies.Update(context.TODO(), fake.ServiceClient(), "5c561d9d-eaea-45f6-ae3e-08d1a7080828", options).Extract() + actual, err := ipsecpolicies.Update(context.TODO(), fake.ServiceClient(fakeServer), "5c561d9d-eaea-45f6-ae3e-08d1a7080828", options).Extract() th.AssertNoErr(t, err) expectedLifetime := ipsecpolicies.Lifetime{ Units: "seconds", diff --git a/openstack/networking/v2/extensions/vpnaas/services/testing/requests_test.go b/openstack/networking/v2/extensions/vpnaas/services/testing/requests_test.go index c0a33e8d0f..84c14a05f8 100644 --- a/openstack/networking/v2/extensions/vpnaas/services/testing/requests_test.go +++ b/openstack/networking/v2/extensions/vpnaas/services/testing/requests_test.go @@ -14,10 +14,10 @@ import ( ) func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/vpn/vpnservices", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/vpn/vpnservices", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -62,7 +62,7 @@ func TestCreate(t *testing.T) { AdminStateUp: gophercloud.Enabled, RouterID: "66e3b16c-8ce5-40fb-bb49-ab6d8dc3f2aa", } - actual, err := services.Create(context.TODO(), fake.ServiceClient(), options).Extract() + actual, err := services.Create(context.TODO(), fake.ServiceClient(fakeServer), options).Extract() th.AssertNoErr(t, err) expected := services.Service{ RouterID: "66e3b16c-8ce5-40fb-bb49-ab6d8dc3f2aa", @@ -81,10 +81,10 @@ func TestCreate(t *testing.T) { } func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/vpn/vpnservices", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/vpn/vpnservices", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -111,7 +111,7 @@ func TestList(t *testing.T) { count := 0 - err := services.List(fake.ServiceClient(), services.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := services.List(fake.ServiceClient(fakeServer), services.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := services.ExtractServices(page) if err != nil { @@ -144,10 +144,10 @@ func TestList(t *testing.T) { } func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/vpn/vpnservices/5c561d9d-eaea-45f6-ae3e-08d1a7080828", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/vpn/vpnservices/5c561d9d-eaea-45f6-ae3e-08d1a7080828", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -171,7 +171,7 @@ func TestGet(t *testing.T) { `) }) - actual, err := services.Get(context.TODO(), fake.ServiceClient(), "5c561d9d-eaea-45f6-ae3e-08d1a7080828").Extract() + actual, err := services.Get(context.TODO(), fake.ServiceClient(fakeServer), "5c561d9d-eaea-45f6-ae3e-08d1a7080828").Extract() th.AssertNoErr(t, err) expected := services.Service{ Status: "PENDING_CREATE", @@ -188,23 +188,23 @@ func TestGet(t *testing.T) { } func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/vpn/vpnservices/5c561d9d-eaea-45f6-ae3e-08d1a7080828", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/vpn/vpnservices/5c561d9d-eaea-45f6-ae3e-08d1a7080828", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.WriteHeader(http.StatusNoContent) }) - res := services.Delete(context.TODO(), fake.ServiceClient(), "5c561d9d-eaea-45f6-ae3e-08d1a7080828") + res := services.Delete(context.TODO(), fake.ServiceClient(fakeServer), "5c561d9d-eaea-45f6-ae3e-08d1a7080828") th.AssertNoErr(t, res.Err) } func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/vpn/vpnservices/5c561d9d-eaea-45f6-ae3e-08d1a7080828", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/vpn/vpnservices/5c561d9d-eaea-45f6-ae3e-08d1a7080828", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -249,7 +249,7 @@ func TestUpdate(t *testing.T) { AdminStateUp: gophercloud.Disabled, } - actual, err := services.Update(context.TODO(), fake.ServiceClient(), "5c561d9d-eaea-45f6-ae3e-08d1a7080828", options).Extract() + actual, err := services.Update(context.TODO(), fake.ServiceClient(fakeServer), "5c561d9d-eaea-45f6-ae3e-08d1a7080828", options).Extract() th.AssertNoErr(t, err) expected := services.Service{ RouterID: "66e3b16c-8ce5-40fb-bb49-ab6d8dc3f2aa", diff --git a/openstack/networking/v2/extensions/vpnaas/siteconnections/testing/requests_test.go b/openstack/networking/v2/extensions/vpnaas/siteconnections/testing/requests_test.go index 58279b75d5..689e153ad1 100644 --- a/openstack/networking/v2/extensions/vpnaas/siteconnections/testing/requests_test.go +++ b/openstack/networking/v2/extensions/vpnaas/siteconnections/testing/requests_test.go @@ -14,10 +14,10 @@ import ( ) func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/vpn/ipsec-site-connections", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/vpn/ipsec-site-connections", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -92,7 +92,7 @@ func TestCreate(t *testing.T) { PeerAddress: "172.24.4.233", PeerID: "172.24.4.233", } - actual, err := siteconnections.Create(context.TODO(), fake.ServiceClient(), options).Extract() + actual, err := siteconnections.Create(context.TODO(), fake.ServiceClient(fakeServer), options).Extract() th.AssertNoErr(t, err) expectedDPD := siteconnections.DPD{ Action: "hold", @@ -126,24 +126,24 @@ func TestCreate(t *testing.T) { } func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/vpn/ipsec-site-connections/5c561d9d-eaea-45f6-ae3e-08d1a7080828", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/vpn/ipsec-site-connections/5c561d9d-eaea-45f6-ae3e-08d1a7080828", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.WriteHeader(http.StatusNoContent) }) - res := siteconnections.Delete(context.TODO(), fake.ServiceClient(), "5c561d9d-eaea-45f6-ae3e-08d1a7080828") + res := siteconnections.Delete(context.TODO(), fake.ServiceClient(fakeServer), "5c561d9d-eaea-45f6-ae3e-08d1a7080828") th.AssertNoErr(t, res.Err) } func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/vpn/ipsec-site-connections/5c561d9d-eaea-45f6-ae3e-08d1a7080828", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/vpn/ipsec-site-connections/5c561d9d-eaea-45f6-ae3e-08d1a7080828", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -183,7 +183,7 @@ func TestGet(t *testing.T) { `) }) - actual, err := siteconnections.Get(context.TODO(), fake.ServiceClient(), "5c561d9d-eaea-45f6-ae3e-08d1a7080828").Extract() + actual, err := siteconnections.Get(context.TODO(), fake.ServiceClient(fakeServer), "5c561d9d-eaea-45f6-ae3e-08d1a7080828").Extract() th.AssertNoErr(t, err) expectedDPD := siteconnections.DPD{ Action: "hold", @@ -217,10 +217,10 @@ func TestGet(t *testing.T) { } func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/vpn/ipsec-site-connections", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/vpn/ipsec-site-connections", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -263,7 +263,7 @@ func TestList(t *testing.T) { count := 0 - err := siteconnections.List(fake.ServiceClient(), siteconnections.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := siteconnections.List(fake.ServiceClient(fakeServer), siteconnections.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := siteconnections.ExtractConnections(page) if err != nil { @@ -314,10 +314,10 @@ func TestList(t *testing.T) { } func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/vpn/ipsec-site-connections/5c561d9d-eaea-45f6-ae3e-08d1a7080828", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/vpn/ipsec-site-connections/5c561d9d-eaea-45f6-ae3e-08d1a7080828", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -379,7 +379,7 @@ func TestUpdate(t *testing.T) { PSK: "updatedsecret", } - actual, err := siteconnections.Update(context.TODO(), fake.ServiceClient(), "5c561d9d-eaea-45f6-ae3e-08d1a7080828", options).Extract() + actual, err := siteconnections.Update(context.TODO(), fake.ServiceClient(fakeServer), "5c561d9d-eaea-45f6-ae3e-08d1a7080828", options).Extract() th.AssertNoErr(t, err) expectedDPD := siteconnections.DPD{ diff --git a/openstack/networking/v2/networks/testing/requests_test.go b/openstack/networking/v2/networks/testing/requests_test.go index f4e905a64f..bd87758699 100644 --- a/openstack/networking/v2/networks/testing/requests_test.go +++ b/openstack/networking/v2/networks/testing/requests_test.go @@ -15,10 +15,10 @@ import ( ) func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/networks", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/networks", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -28,7 +28,7 @@ func TestList(t *testing.T) { fmt.Fprint(w, ListResponse) }) - client := fake.ServiceClient() + client := fake.ServiceClient(fakeServer) count := 0 err := networks.List(client, networks.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { @@ -52,10 +52,10 @@ func TestList(t *testing.T) { } func TestListWithExtensions(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/networks", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/networks", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -65,7 +65,7 @@ func TestListWithExtensions(t *testing.T) { fmt.Fprint(w, ListResponse) }) - client := fake.ServiceClient() + client := fake.ServiceClient(fakeServer) type networkWithExt struct { networks.Network @@ -91,10 +91,10 @@ func TestListWithExtensions(t *testing.T) { } func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/networks/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/networks/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -104,7 +104,7 @@ func TestGet(t *testing.T) { fmt.Fprint(w, GetResponse) }) - n, err := networks.Get(context.TODO(), fake.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22").Extract() + n, err := networks.Get(context.TODO(), fake.ServiceClient(fakeServer), "d32019d3-bc6e-4319-9c1d-6722fc136a22").Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, &Network1, n) th.AssertEquals(t, n.CreatedAt.Format(time.RFC3339), "2019-06-30T04:15:37Z") @@ -112,10 +112,10 @@ func TestGet(t *testing.T) { } func TestGetWithExtensions(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/networks/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/networks/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -130,7 +130,7 @@ func TestGetWithExtensions(t *testing.T) { portsecurity.PortSecurityExt } - err := networks.Get(context.TODO(), fake.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22").ExtractInto(&networkWithExtensions) + err := networks.Get(context.TODO(), fake.ServiceClient(fakeServer), "d32019d3-bc6e-4319-9c1d-6722fc136a22").ExtractInto(&networkWithExtensions) th.AssertNoErr(t, err) th.AssertEquals(t, networkWithExtensions.Status, "ACTIVE") @@ -138,10 +138,10 @@ func TestGetWithExtensions(t *testing.T) { } func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/networks", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/networks", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -155,7 +155,7 @@ func TestCreate(t *testing.T) { iTrue := true options := networks.CreateOpts{Name: "private", AdminStateUp: &iTrue} - n, err := networks.Create(context.TODO(), fake.ServiceClient(), options).Extract() + n, err := networks.Create(context.TODO(), fake.ServiceClient(fakeServer), options).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, n.Status, "ACTIVE") @@ -165,10 +165,10 @@ func TestCreate(t *testing.T) { } func TestCreateWithOptionalFields(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/networks", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/networks", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -187,15 +187,15 @@ func TestCreateWithOptionalFields(t *testing.T) { TenantID: "12345", AvailabilityZoneHints: []string{"zone1", "zone2"}, } - _, err := networks.Create(context.TODO(), fake.ServiceClient(), options).Extract() + _, err := networks.Create(context.TODO(), fake.ServiceClient(fakeServer), options).Extract() th.AssertNoErr(t, err) } func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/networks/4e8e5957-649f-477b-9e5b-f1f75b21c03c", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/networks/4e8e5957-649f-477b-9e5b-f1f75b21c03c", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -211,7 +211,7 @@ func TestUpdate(t *testing.T) { iTrue, iFalse := true, false name := "new_network_name" options := networks.UpdateOpts{Name: &name, AdminStateUp: &iFalse, Shared: &iTrue} - n, err := networks.Update(context.TODO(), fake.ServiceClient(), "4e8e5957-649f-477b-9e5b-f1f75b21c03c", options).Extract() + n, err := networks.Update(context.TODO(), fake.ServiceClient(fakeServer), "4e8e5957-649f-477b-9e5b-f1f75b21c03c", options).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, n.Name, "new_network_name") @@ -223,10 +223,10 @@ func TestUpdate(t *testing.T) { } func TestUpdateRevision(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/networks/4e8e5957-649f-477b-9e5b-f1f75b21c03c", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/networks/4e8e5957-649f-477b-9e5b-f1f75b21c03c", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -240,7 +240,7 @@ func TestUpdateRevision(t *testing.T) { fmt.Fprint(w, UpdateResponse) }) - th.Mux.HandleFunc("/v2.0/networks/4e8e5957-649f-477b-9e5b-f1f75b21c03d", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/networks/4e8e5957-649f-477b-9e5b-f1f75b21c03d", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -257,34 +257,34 @@ func TestUpdateRevision(t *testing.T) { iTrue, iFalse := true, false name := "new_network_name" options := networks.UpdateOpts{Name: &name, AdminStateUp: &iFalse, Shared: &iTrue} - _, err := networks.Update(context.TODO(), fake.ServiceClient(), "4e8e5957-649f-477b-9e5b-f1f75b21c03c", options).Extract() + _, err := networks.Update(context.TODO(), fake.ServiceClient(fakeServer), "4e8e5957-649f-477b-9e5b-f1f75b21c03c", options).Extract() th.AssertNoErr(t, err) revisionNumber := 42 options.RevisionNumber = &revisionNumber - _, err = networks.Update(context.TODO(), fake.ServiceClient(), "4e8e5957-649f-477b-9e5b-f1f75b21c03d", options).Extract() + _, err = networks.Update(context.TODO(), fake.ServiceClient(fakeServer), "4e8e5957-649f-477b-9e5b-f1f75b21c03d", options).Extract() th.AssertNoErr(t, err) } func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/networks/4e8e5957-649f-477b-9e5b-f1f75b21c03c", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/networks/4e8e5957-649f-477b-9e5b-f1f75b21c03c", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.WriteHeader(http.StatusNoContent) }) - res := networks.Delete(context.TODO(), fake.ServiceClient(), "4e8e5957-649f-477b-9e5b-f1f75b21c03c") + res := networks.Delete(context.TODO(), fake.ServiceClient(fakeServer), "4e8e5957-649f-477b-9e5b-f1f75b21c03c") th.AssertNoErr(t, res.Err) } func TestCreatePortSecurity(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/networks", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/networks", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -309,7 +309,7 @@ func TestCreatePortSecurity(t *testing.T) { PortSecurityEnabled: &iFalse, } - err := networks.Create(context.TODO(), fake.ServiceClient(), createOpts).ExtractInto(&networkWithExtensions) + err := networks.Create(context.TODO(), fake.ServiceClient(fakeServer), createOpts).ExtractInto(&networkWithExtensions) th.AssertNoErr(t, err) th.AssertEquals(t, networkWithExtensions.Status, "ACTIVE") @@ -317,10 +317,10 @@ func TestCreatePortSecurity(t *testing.T) { } func TestUpdatePortSecurity(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/networks/4e8e5957-649f-477b-9e5b-f1f75b21c03c", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/networks/4e8e5957-649f-477b-9e5b-f1f75b21c03c", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -345,7 +345,7 @@ func TestUpdatePortSecurity(t *testing.T) { PortSecurityEnabled: &iFalse, } - err := networks.Update(context.TODO(), fake.ServiceClient(), "4e8e5957-649f-477b-9e5b-f1f75b21c03c", updateOpts).ExtractInto(&networkWithExtensions) + err := networks.Update(context.TODO(), fake.ServiceClient(fakeServer), "4e8e5957-649f-477b-9e5b-f1f75b21c03c", updateOpts).ExtractInto(&networkWithExtensions) th.AssertNoErr(t, err) th.AssertEquals(t, networkWithExtensions.Name, "private") diff --git a/openstack/networking/v2/ports/testing/requests_test.go b/openstack/networking/v2/ports/testing/requests_test.go index f1950b4edc..ac1a2cd79a 100644 --- a/openstack/networking/v2/ports/testing/requests_test.go +++ b/openstack/networking/v2/ports/testing/requests_test.go @@ -17,10 +17,10 @@ import ( ) func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/ports", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/ports", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -32,7 +32,7 @@ func TestList(t *testing.T) { count := 0 - err := ports.List(fake.ServiceClient(), ports.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := ports.List(fake.ServiceClient(fakeServer), ports.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := ports.ExtractPorts(page) if err != nil { @@ -76,10 +76,10 @@ func TestList(t *testing.T) { } func TestListWithExtensions(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/ports", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/ports", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -96,7 +96,7 @@ func TestListWithExtensions(t *testing.T) { var allPorts []portWithExt - allPages, err := ports.List(fake.ServiceClient(), ports.ListOpts{}).AllPages(context.TODO()) + allPages, err := ports.List(fake.ServiceClient(fakeServer), ports.ListOpts{}).AllPages(context.TODO()) th.AssertNoErr(t, err) err = ports.ExtractPortsInto(allPages, &allPorts) @@ -107,10 +107,10 @@ func TestListWithExtensions(t *testing.T) { } func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/ports/46d4bfb9-b26e-41f3-bd2e-e6dcc1ccedb2", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/ports/46d4bfb9-b26e-41f3-bd2e-e6dcc1ccedb2", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -120,7 +120,7 @@ func TestGet(t *testing.T) { fmt.Fprint(w, GetResponse) }) - n, err := ports.Get(context.TODO(), fake.ServiceClient(), "46d4bfb9-b26e-41f3-bd2e-e6dcc1ccedb2").Extract() + n, err := ports.Get(context.TODO(), fake.ServiceClient(fakeServer), "46d4bfb9-b26e-41f3-bd2e-e6dcc1ccedb2").Extract() th.AssertNoErr(t, err) th.AssertEquals(t, n.Status, "ACTIVE") @@ -142,10 +142,10 @@ func TestGet(t *testing.T) { } func TestGetWithExtensions(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/ports/46d4bfb9-b26e-41f3-bd2e-e6dcc1ccedb2", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/ports/46d4bfb9-b26e-41f3-bd2e-e6dcc1ccedb2", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -160,7 +160,7 @@ func TestGetWithExtensions(t *testing.T) { portsecurity.PortSecurityExt } - err := ports.Get(context.TODO(), fake.ServiceClient(), "46d4bfb9-b26e-41f3-bd2e-e6dcc1ccedb2").ExtractInto(&portWithExtensions) + err := ports.Get(context.TODO(), fake.ServiceClient(fakeServer), "46d4bfb9-b26e-41f3-bd2e-e6dcc1ccedb2").ExtractInto(&portWithExtensions) th.AssertNoErr(t, err) th.AssertEquals(t, portWithExtensions.Status, "ACTIVE") @@ -168,10 +168,10 @@ func TestGetWithExtensions(t *testing.T) { } func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/ports", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/ports", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -197,7 +197,7 @@ func TestCreate(t *testing.T) { {IPAddress: "10.0.0.4", MACAddress: "fa:16:3e:c9:cb:f0"}, }, } - n, err := ports.Create(context.TODO(), fake.ServiceClient(), options).Extract() + n, err := ports.Create(context.TODO(), fake.ServiceClient(fakeServer), options).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, n.Status, "DOWN") @@ -218,10 +218,10 @@ func TestCreate(t *testing.T) { } func TestCreateOmitSecurityGroups(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/ports", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/ports", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -246,7 +246,7 @@ func TestCreateOmitSecurityGroups(t *testing.T) { {IPAddress: "10.0.0.4", MACAddress: "fa:16:3e:c9:cb:f0"}, }, } - n, err := ports.Create(context.TODO(), fake.ServiceClient(), options).Extract() + n, err := ports.Create(context.TODO(), fake.ServiceClient(fakeServer), options).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, n.Status, "DOWN") @@ -267,10 +267,10 @@ func TestCreateOmitSecurityGroups(t *testing.T) { } func TestCreateWithNoSecurityGroup(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/ports", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/ports", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -296,7 +296,7 @@ func TestCreateWithNoSecurityGroup(t *testing.T) { {IPAddress: "10.0.0.4", MACAddress: "fa:16:3e:c9:cb:f0"}, }, } - n, err := ports.Create(context.TODO(), fake.ServiceClient(), options).Extract() + n, err := ports.Create(context.TODO(), fake.ServiceClient(fakeServer), options).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, n.Status, "DOWN") @@ -316,10 +316,10 @@ func TestCreateWithNoSecurityGroup(t *testing.T) { } func TestCreateWithPropagateUplinkStatus(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/ports", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/ports", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -343,7 +343,7 @@ func TestCreateWithPropagateUplinkStatus(t *testing.T) { }, PropagateUplinkStatus: &propagateUplinkStatus, } - n, err := ports.Create(context.TODO(), fake.ServiceClient(), options).Extract() + n, err := ports.Create(context.TODO(), fake.ServiceClient(fakeServer), options).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, n.Status, "DOWN") @@ -361,10 +361,10 @@ func TestCreateWithPropagateUplinkStatus(t *testing.T) { } func TestCreateWithValueSpecs(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/ports", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/ports", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -393,7 +393,7 @@ func TestCreateWithValueSpecs(t *testing.T) { "test": "value", }, } - n, err := ports.Create(context.TODO(), fake.ServiceClient(), options).Extract() + n, err := ports.Create(context.TODO(), fake.ServiceClient(fakeServer), options).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, n.Status, "DOWN") @@ -414,10 +414,10 @@ func TestCreateWithValueSpecs(t *testing.T) { } func TestCreateWithInvalidValueSpecs(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/ports", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/ports", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -449,7 +449,7 @@ func TestCreateWithInvalidValueSpecs(t *testing.T) { } // We expect an error here since we used a fobidden key in the value specs. - _, err := ports.Create(context.TODO(), fake.ServiceClient(), options).Extract() + _, err := ports.Create(context.TODO(), fake.ServiceClient(fakeServer), options).Extract() th.AssertErr(t, err) options.ValueSpecs = &map[string]string{ @@ -458,25 +458,25 @@ func TestCreateWithInvalidValueSpecs(t *testing.T) { } // We expect an error here since the value specs would overwrite an existing field. - _, err = ports.Create(context.TODO(), fake.ServiceClient(), options).Extract() + _, err = ports.Create(context.TODO(), fake.ServiceClient(fakeServer), options).Extract() th.AssertErr(t, err) } func TestRequiredCreateOpts(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - res := ports.Create(context.TODO(), fake.ServiceClient(), ports.CreateOpts{}) + res := ports.Create(context.TODO(), fake.ServiceClient(fakeServer), ports.CreateOpts{}) if res.Err == nil { t.Fatalf("Expected error, got none") } } func TestCreatePortSecurity(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/ports", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/ports", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -513,7 +513,7 @@ func TestCreatePortSecurity(t *testing.T) { PortSecurityEnabled: &iFalse, } - err := ports.Create(context.TODO(), fake.ServiceClient(), createOpts).ExtractInto(&portWithExt) + err := ports.Create(context.TODO(), fake.ServiceClient(fakeServer), createOpts).ExtractInto(&portWithExt) th.AssertNoErr(t, err) th.AssertEquals(t, portWithExt.Status, "DOWN") @@ -521,10 +521,10 @@ func TestCreatePortSecurity(t *testing.T) { } func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/ports/65c0ee9f-d634-4522-8954-51021b570b0d", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/ports/65c0ee9f-d634-4522-8954-51021b570b0d", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -549,7 +549,7 @@ func TestUpdate(t *testing.T) { }, } - s, err := ports.Update(context.TODO(), fake.ServiceClient(), "65c0ee9f-d634-4522-8954-51021b570b0d", options).Extract() + s, err := ports.Update(context.TODO(), fake.ServiceClient(fakeServer), "65c0ee9f-d634-4522-8954-51021b570b0d", options).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, s.Name, "new_port_name") @@ -563,10 +563,10 @@ func TestUpdate(t *testing.T) { } func TestUpdateOmitSecurityGroups(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/ports/65c0ee9f-d634-4522-8954-51021b570b0d", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/ports/65c0ee9f-d634-4522-8954-51021b570b0d", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -590,7 +590,7 @@ func TestUpdateOmitSecurityGroups(t *testing.T) { }, } - s, err := ports.Update(context.TODO(), fake.ServiceClient(), "65c0ee9f-d634-4522-8954-51021b570b0d", options).Extract() + s, err := ports.Update(context.TODO(), fake.ServiceClient(fakeServer), "65c0ee9f-d634-4522-8954-51021b570b0d", options).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, s.Name, "new_port_name") @@ -604,10 +604,10 @@ func TestUpdateOmitSecurityGroups(t *testing.T) { } func TestUpdatePropagateUplinkStatus(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/ports/65c0ee9f-d634-4522-8954-51021b570b0d", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/ports/65c0ee9f-d634-4522-8954-51021b570b0d", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -625,17 +625,17 @@ func TestUpdatePropagateUplinkStatus(t *testing.T) { PropagateUplinkStatus: &propagateUplinkStatus, } - s, err := ports.Update(context.TODO(), fake.ServiceClient(), "65c0ee9f-d634-4522-8954-51021b570b0d", options).Extract() + s, err := ports.Update(context.TODO(), fake.ServiceClient(fakeServer), "65c0ee9f-d634-4522-8954-51021b570b0d", options).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, s.PropagateUplinkStatus, propagateUplinkStatus) } func TestUpdateValueSpecs(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/ports/65c0ee9f-d634-4522-8954-51021b570b0d", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/ports/65c0ee9f-d634-4522-8954-51021b570b0d", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -654,15 +654,15 @@ func TestUpdateValueSpecs(t *testing.T) { }, } - _, err := ports.Update(context.TODO(), fake.ServiceClient(), "65c0ee9f-d634-4522-8954-51021b570b0d", options).Extract() + _, err := ports.Update(context.TODO(), fake.ServiceClient(fakeServer), "65c0ee9f-d634-4522-8954-51021b570b0d", options).Extract() th.AssertNoErr(t, err) } func TestUpdatePortSecurity(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/ports/65c0ee9f-d634-4522-8954-51021b570b0d", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/ports/65c0ee9f-d634-4522-8954-51021b570b0d", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -687,7 +687,7 @@ func TestUpdatePortSecurity(t *testing.T) { PortSecurityEnabled: &iFalse, } - err := ports.Update(context.TODO(), fake.ServiceClient(), "65c0ee9f-d634-4522-8954-51021b570b0d", updateOpts).ExtractInto(&portWithExt) + err := ports.Update(context.TODO(), fake.ServiceClient(fakeServer), "65c0ee9f-d634-4522-8954-51021b570b0d", updateOpts).ExtractInto(&portWithExt) th.AssertNoErr(t, err) th.AssertEquals(t, portWithExt.Status, "DOWN") @@ -696,10 +696,10 @@ func TestUpdatePortSecurity(t *testing.T) { } func TestUpdateRevision(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/ports/65c0ee9f-d634-4522-8954-51021b570b0d", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/ports/65c0ee9f-d634-4522-8954-51021b570b0d", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -712,7 +712,7 @@ func TestUpdateRevision(t *testing.T) { fmt.Fprint(w, UpdateResponse) }) - th.Mux.HandleFunc("/v2.0/ports/65c0ee9f-d634-4522-8954-51021b570b0e", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/ports/65c0ee9f-d634-4522-8954-51021b570b0e", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -737,20 +737,20 @@ func TestUpdateRevision(t *testing.T) { {IPAddress: "10.0.0.4", MACAddress: "fa:16:3e:c9:cb:f0"}, }, } - _, err := ports.Update(context.TODO(), fake.ServiceClient(), "65c0ee9f-d634-4522-8954-51021b570b0d", options).Extract() + _, err := ports.Update(context.TODO(), fake.ServiceClient(fakeServer), "65c0ee9f-d634-4522-8954-51021b570b0d", options).Extract() th.AssertNoErr(t, err) revisionNumber := 42 options.RevisionNumber = &revisionNumber - _, err = ports.Update(context.TODO(), fake.ServiceClient(), "65c0ee9f-d634-4522-8954-51021b570b0e", options).Extract() + _, err = ports.Update(context.TODO(), fake.ServiceClient(fakeServer), "65c0ee9f-d634-4522-8954-51021b570b0e", options).Extract() th.AssertNoErr(t, err) } func TestRemoveSecurityGroups(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/ports/65c0ee9f-d634-4522-8954-51021b570b0d", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/ports/65c0ee9f-d634-4522-8954-51021b570b0d", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -775,7 +775,7 @@ func TestRemoveSecurityGroups(t *testing.T) { }, } - s, err := ports.Update(context.TODO(), fake.ServiceClient(), "65c0ee9f-d634-4522-8954-51021b570b0d", options).Extract() + s, err := ports.Update(context.TODO(), fake.ServiceClient(fakeServer), "65c0ee9f-d634-4522-8954-51021b570b0d", options).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, s.Name, "new_port_name") @@ -789,10 +789,10 @@ func TestRemoveSecurityGroups(t *testing.T) { } func TestRemoveAllowedAddressPairs(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/ports/65c0ee9f-d634-4522-8954-51021b570b0d", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/ports/65c0ee9f-d634-4522-8954-51021b570b0d", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -815,7 +815,7 @@ func TestRemoveAllowedAddressPairs(t *testing.T) { AllowedAddressPairs: &[]ports.AddressPair{}, } - s, err := ports.Update(context.TODO(), fake.ServiceClient(), "65c0ee9f-d634-4522-8954-51021b570b0d", options).Extract() + s, err := ports.Update(context.TODO(), fake.ServiceClient(fakeServer), "65c0ee9f-d634-4522-8954-51021b570b0d", options).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, s.Name, "new_port_name") @@ -827,10 +827,10 @@ func TestRemoveAllowedAddressPairs(t *testing.T) { } func TestDontUpdateAllowedAddressPairs(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/ports/65c0ee9f-d634-4522-8954-51021b570b0d", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/ports/65c0ee9f-d634-4522-8954-51021b570b0d", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -852,7 +852,7 @@ func TestDontUpdateAllowedAddressPairs(t *testing.T) { SecurityGroups: &[]string{"f0ac4394-7e4a-4409-9701-ba8be283dbc3"}, } - s, err := ports.Update(context.TODO(), fake.ServiceClient(), "65c0ee9f-d634-4522-8954-51021b570b0d", options).Extract() + s, err := ports.Update(context.TODO(), fake.ServiceClient(fakeServer), "65c0ee9f-d634-4522-8954-51021b570b0d", options).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, s.Name, "new_port_name") @@ -866,24 +866,24 @@ func TestDontUpdateAllowedAddressPairs(t *testing.T) { } func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/ports/65c0ee9f-d634-4522-8954-51021b570b0d", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/ports/65c0ee9f-d634-4522-8954-51021b570b0d", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.WriteHeader(http.StatusNoContent) }) - res := ports.Delete(context.TODO(), fake.ServiceClient(), "65c0ee9f-d634-4522-8954-51021b570b0d") + res := ports.Delete(context.TODO(), fake.ServiceClient(fakeServer), "65c0ee9f-d634-4522-8954-51021b570b0d") th.AssertNoErr(t, res.Err) } func TestGetWithExtraDHCPOpts(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/ports/46d4bfb9-b26e-41f3-bd2e-e6dcc1ccedb2", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/ports/46d4bfb9-b26e-41f3-bd2e-e6dcc1ccedb2", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -898,7 +898,7 @@ func TestGetWithExtraDHCPOpts(t *testing.T) { extradhcpopts.ExtraDHCPOptsExt } - err := ports.Get(context.TODO(), fake.ServiceClient(), "46d4bfb9-b26e-41f3-bd2e-e6dcc1ccedb2").ExtractInto(&s) + err := ports.Get(context.TODO(), fake.ServiceClient(fakeServer), "46d4bfb9-b26e-41f3-bd2e-e6dcc1ccedb2").ExtractInto(&s) th.AssertNoErr(t, err) th.AssertEquals(t, s.Status, "ACTIVE") @@ -923,10 +923,10 @@ func TestGetWithExtraDHCPOpts(t *testing.T) { } func TestCreateWithExtraDHCPOpts(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/ports", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/ports", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -964,7 +964,7 @@ func TestCreateWithExtraDHCPOpts(t *testing.T) { extradhcpopts.ExtraDHCPOptsExt } - err := ports.Create(context.TODO(), fake.ServiceClient(), createOpts).ExtractInto(&s) + err := ports.Create(context.TODO(), fake.ServiceClient(fakeServer), createOpts).ExtractInto(&s) th.AssertNoErr(t, err) th.AssertEquals(t, s.Status, "DOWN") @@ -986,10 +986,10 @@ func TestCreateWithExtraDHCPOpts(t *testing.T) { } func TestUpdateWithExtraDHCPOpts(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/ports/65c0ee9f-d634-4522-8954-51021b570b0d", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/ports/65c0ee9f-d634-4522-8954-51021b570b0d", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -1029,7 +1029,7 @@ func TestUpdateWithExtraDHCPOpts(t *testing.T) { extradhcpopts.ExtraDHCPOptsExt } - err := ports.Update(context.TODO(), fake.ServiceClient(), "65c0ee9f-d634-4522-8954-51021b570b0d", updateOpts).ExtractInto(&s) + err := ports.Update(context.TODO(), fake.ServiceClient(fakeServer), "65c0ee9f-d634-4522-8954-51021b570b0d", updateOpts).ExtractInto(&s) th.AssertNoErr(t, err) th.AssertEquals(t, s.Status, "DOWN") diff --git a/openstack/networking/v2/subnets/testing/requests_test.go b/openstack/networking/v2/subnets/testing/requests_test.go index 3ae42f2942..fd8c810db3 100644 --- a/openstack/networking/v2/subnets/testing/requests_test.go +++ b/openstack/networking/v2/subnets/testing/requests_test.go @@ -13,10 +13,10 @@ import ( ) func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/subnets", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/subnets", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -28,7 +28,7 @@ func TestList(t *testing.T) { count := 0 - err := subnets.List(fake.ServiceClient(), subnets.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := subnets.List(fake.ServiceClient(fakeServer), subnets.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := subnets.ExtractSubnets(page) if err != nil { @@ -55,10 +55,10 @@ func TestList(t *testing.T) { } func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/subnets/54d6f61d-db07-451c-9ab3-b9609b6b6f0b", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/subnets/54d6f61d-db07-451c-9ab3-b9609b6b6f0b", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -68,7 +68,7 @@ func TestGet(t *testing.T) { fmt.Fprint(w, SubnetGetResult) }) - s, err := subnets.Get(context.TODO(), fake.ServiceClient(), "54d6f61d-db07-451c-9ab3-b9609b6b6f0b").Extract() + s, err := subnets.Get(context.TODO(), fake.ServiceClient(fakeServer), "54d6f61d-db07-451c-9ab3-b9609b6b6f0b").Extract() th.AssertNoErr(t, err) th.AssertEquals(t, s.Name, "my_subnet") @@ -91,10 +91,10 @@ func TestGet(t *testing.T) { } func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/subnets", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/subnets", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -128,7 +128,7 @@ func TestCreate(t *testing.T) { }, SubnetPoolID: "b80340c7-9960-4f67-a99c-02501656284b", } - s, err := subnets.Create(context.TODO(), fake.ServiceClient(), opts).Extract() + s, err := subnets.Create(context.TODO(), fake.ServiceClient(fakeServer), opts).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, s.Name, "") @@ -153,10 +153,10 @@ func TestCreate(t *testing.T) { } func TestCreateNoGateway(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/subnets", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/subnets", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -183,7 +183,7 @@ func TestCreateNoGateway(t *testing.T) { }, DNSNameservers: []string{}, } - s, err := subnets.Create(context.TODO(), fake.ServiceClient(), opts).Extract() + s, err := subnets.Create(context.TODO(), fake.ServiceClient(fakeServer), opts).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, s.Name, "") @@ -204,10 +204,10 @@ func TestCreateNoGateway(t *testing.T) { } func TestCreateDefaultGateway(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/subnets", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/subnets", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -232,7 +232,7 @@ func TestCreateDefaultGateway(t *testing.T) { }, DNSNameservers: []string{}, } - s, err := subnets.Create(context.TODO(), fake.ServiceClient(), opts).Extract() + s, err := subnets.Create(context.TODO(), fake.ServiceClient(fakeServer), opts).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, s.Name, "") @@ -253,10 +253,10 @@ func TestCreateDefaultGateway(t *testing.T) { } func TestCreateIPv6RaAddressMode(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/subnets", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/subnets", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -278,7 +278,7 @@ func TestCreateIPv6RaAddressMode(t *testing.T) { IPv6AddressMode: "slaac", IPv6RAMode: "slaac", } - s, err := subnets.Create(context.TODO(), fake.ServiceClient(), opts).Extract() + s, err := subnets.Create(context.TODO(), fake.ServiceClient(fakeServer), opts).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, s.Name, "") @@ -294,10 +294,10 @@ func TestCreateIPv6RaAddressMode(t *testing.T) { } func TestCreateWithNoCIDR(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/subnets", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/subnets", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -319,7 +319,7 @@ func TestCreateWithNoCIDR(t *testing.T) { }, SubnetPoolID: "b80340c7-9960-4f67-a99c-02501656284b", } - s, err := subnets.Create(context.TODO(), fake.ServiceClient(), opts).Extract() + s, err := subnets.Create(context.TODO(), fake.ServiceClient(fakeServer), opts).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, s.Name, "") @@ -343,10 +343,10 @@ func TestCreateWithNoCIDR(t *testing.T) { } func TestCreateWithPrefixlen(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/subnets", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/subnets", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -369,7 +369,7 @@ func TestCreateWithPrefixlen(t *testing.T) { SubnetPoolID: "b80340c7-9960-4f67-a99c-02501656284b", Prefixlen: 12, } - s, err := subnets.Create(context.TODO(), fake.ServiceClient(), opts).Extract() + s, err := subnets.Create(context.TODO(), fake.ServiceClient(fakeServer), opts).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, s.Name, "") @@ -393,30 +393,30 @@ func TestCreateWithPrefixlen(t *testing.T) { } func TestRequiredCreateOpts(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - res := subnets.Create(context.TODO(), fake.ServiceClient(), subnets.CreateOpts{}) + res := subnets.Create(context.TODO(), fake.ServiceClient(fakeServer), subnets.CreateOpts{}) if res.Err == nil { t.Fatalf("Expected error, got none") } - res = subnets.Create(context.TODO(), fake.ServiceClient(), subnets.CreateOpts{NetworkID: "foo"}) + res = subnets.Create(context.TODO(), fake.ServiceClient(fakeServer), subnets.CreateOpts{NetworkID: "foo"}) if res.Err == nil { t.Fatalf("Expected error, got none") } - res = subnets.Create(context.TODO(), fake.ServiceClient(), subnets.CreateOpts{NetworkID: "foo", CIDR: "bar", IPVersion: 40}) + res = subnets.Create(context.TODO(), fake.ServiceClient(fakeServer), subnets.CreateOpts{NetworkID: "foo", CIDR: "bar", IPVersion: 40}) if res.Err == nil { t.Fatalf("Expected error, got none") } } func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/subnets/08eae331-0402-425a-923c-34f7cfe39c1b", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/subnets/08eae331-0402-425a-923c-34f7cfe39c1b", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -438,7 +438,7 @@ func TestUpdate(t *testing.T) { {NextHop: "bar"}, }, } - s, err := subnets.Update(context.TODO(), fake.ServiceClient(), "08eae331-0402-425a-923c-34f7cfe39c1b", opts).Extract() + s, err := subnets.Update(context.TODO(), fake.ServiceClient(fakeServer), "08eae331-0402-425a-923c-34f7cfe39c1b", opts).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, s.Name, "my_new_subnet") @@ -446,10 +446,10 @@ func TestUpdate(t *testing.T) { } func TestUpdateGateway(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/subnets/08eae331-0402-425a-923c-34f7cfe39c1b", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/subnets/08eae331-0402-425a-923c-34f7cfe39c1b", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -468,7 +468,7 @@ func TestUpdateGateway(t *testing.T) { Name: &name, GatewayIP: &gatewayIP, } - s, err := subnets.Update(context.TODO(), fake.ServiceClient(), "08eae331-0402-425a-923c-34f7cfe39c1b", opts).Extract() + s, err := subnets.Update(context.TODO(), fake.ServiceClient(fakeServer), "08eae331-0402-425a-923c-34f7cfe39c1b", opts).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, s.Name, "my_new_subnet") @@ -477,10 +477,10 @@ func TestUpdateGateway(t *testing.T) { } func TestUpdateRemoveGateway(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/subnets/08eae331-0402-425a-923c-34f7cfe39c1b", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/subnets/08eae331-0402-425a-923c-34f7cfe39c1b", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -499,7 +499,7 @@ func TestUpdateRemoveGateway(t *testing.T) { Name: &name, GatewayIP: &noGateway, } - s, err := subnets.Update(context.TODO(), fake.ServiceClient(), "08eae331-0402-425a-923c-34f7cfe39c1b", opts).Extract() + s, err := subnets.Update(context.TODO(), fake.ServiceClient(fakeServer), "08eae331-0402-425a-923c-34f7cfe39c1b", opts).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, s.Name, "my_new_subnet") @@ -508,10 +508,10 @@ func TestUpdateRemoveGateway(t *testing.T) { } func TestUpdateHostRoutes(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/subnets/08eae331-0402-425a-923c-34f7cfe39c1b", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/subnets/08eae331-0402-425a-923c-34f7cfe39c1b", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -536,7 +536,7 @@ func TestUpdateHostRoutes(t *testing.T) { Name: &name, HostRoutes: &HostRoutes, } - s, err := subnets.Update(context.TODO(), fake.ServiceClient(), "08eae331-0402-425a-923c-34f7cfe39c1b", opts).Extract() + s, err := subnets.Update(context.TODO(), fake.ServiceClient(fakeServer), "08eae331-0402-425a-923c-34f7cfe39c1b", opts).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, s.Name, "my_new_subnet") @@ -545,10 +545,10 @@ func TestUpdateHostRoutes(t *testing.T) { } func TestUpdateRemoveHostRoutes(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/subnets/08eae331-0402-425a-923c-34f7cfe39c1b", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/subnets/08eae331-0402-425a-923c-34f7cfe39c1b", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -565,7 +565,7 @@ func TestUpdateRemoveHostRoutes(t *testing.T) { opts := subnets.UpdateOpts{ HostRoutes: &noHostRoutes, } - s, err := subnets.Update(context.TODO(), fake.ServiceClient(), "08eae331-0402-425a-923c-34f7cfe39c1b", opts).Extract() + s, err := subnets.Update(context.TODO(), fake.ServiceClient(fakeServer), "08eae331-0402-425a-923c-34f7cfe39c1b", opts).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, s.Name, "my_new_subnet") @@ -574,10 +574,10 @@ func TestUpdateRemoveHostRoutes(t *testing.T) { } func TestUpdateAllocationPool(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/subnets/08eae331-0402-425a-923c-34f7cfe39c1b", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/subnets/08eae331-0402-425a-923c-34f7cfe39c1b", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -600,7 +600,7 @@ func TestUpdateAllocationPool(t *testing.T) { }, }, } - s, err := subnets.Update(context.TODO(), fake.ServiceClient(), "08eae331-0402-425a-923c-34f7cfe39c1b", opts).Extract() + s, err := subnets.Update(context.TODO(), fake.ServiceClient(fakeServer), "08eae331-0402-425a-923c-34f7cfe39c1b", opts).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, s.Name, "my_new_subnet") @@ -614,10 +614,10 @@ func TestUpdateAllocationPool(t *testing.T) { } func TestUpdateRevision(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/subnets/08eae331-0402-425a-923c-34f7cfe39c1b", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/subnets/08eae331-0402-425a-923c-34f7cfe39c1b", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -631,7 +631,7 @@ func TestUpdateRevision(t *testing.T) { fmt.Fprint(w, SubnetUpdateResponse) }) - th.Mux.HandleFunc("/v2.0/subnets/08eae331-0402-425a-923c-34f7cfe39c1c", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/subnets/08eae331-0402-425a-923c-34f7cfe39c1c", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -654,25 +654,25 @@ func TestUpdateRevision(t *testing.T) { {NextHop: "bar"}, }, } - _, err := subnets.Update(context.TODO(), fake.ServiceClient(), "08eae331-0402-425a-923c-34f7cfe39c1b", opts).Extract() + _, err := subnets.Update(context.TODO(), fake.ServiceClient(fakeServer), "08eae331-0402-425a-923c-34f7cfe39c1b", opts).Extract() th.AssertNoErr(t, err) revisionNumber := 42 opts.RevisionNumber = &revisionNumber - _, err = subnets.Update(context.TODO(), fake.ServiceClient(), "08eae331-0402-425a-923c-34f7cfe39c1c", opts).Extract() + _, err = subnets.Update(context.TODO(), fake.ServiceClient(fakeServer), "08eae331-0402-425a-923c-34f7cfe39c1c", opts).Extract() th.AssertNoErr(t, err) } func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/subnets/08eae331-0402-425a-923c-34f7cfe39c1b", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/subnets/08eae331-0402-425a-923c-34f7cfe39c1b", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.WriteHeader(http.StatusNoContent) }) - res := subnets.Delete(context.TODO(), fake.ServiceClient(), "08eae331-0402-425a-923c-34f7cfe39c1b") + res := subnets.Delete(context.TODO(), fake.ServiceClient(fakeServer), "08eae331-0402-425a-923c-34f7cfe39c1b") th.AssertNoErr(t, res.Err) } diff --git a/openstack/objectstorage/v1/accounts/testing/fixtures.go b/openstack/objectstorage/v1/accounts/testing/fixtures.go index 06948268db..5e97d2de64 100644 --- a/openstack/objectstorage/v1/accounts/testing/fixtures.go +++ b/openstack/objectstorage/v1/accounts/testing/fixtures.go @@ -10,8 +10,8 @@ import ( // HandleGetAccountSuccessfully creates an HTTP handler at `/` on the test handler mux that // responds with a `Get` response. -func HandleGetAccountSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { +func HandleGetAccountSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "HEAD") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -29,8 +29,8 @@ func HandleGetAccountSuccessfully(t *testing.T) { // HandleGetAccountNoQuotaSuccessfully creates an HTTP handler at `/` on the // test handler mux that responds with a `Get` response. -func HandleGetAccountNoQuotaSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { +func HandleGetAccountNoQuotaSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "HEAD") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -46,8 +46,8 @@ func HandleGetAccountNoQuotaSuccessfully(t *testing.T) { // HandleUpdateAccountSuccessfully creates an HTTP handler at `/` on the test handler mux that // responds with a `Update` response. -func HandleUpdateAccountSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { +func HandleUpdateAccountSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "X-Account-Meta-Gophercloud-Test", "accounts") diff --git a/openstack/objectstorage/v1/accounts/testing/requests_test.go b/openstack/objectstorage/v1/accounts/testing/requests_test.go index 7bb5ad7986..19067efbb7 100644 --- a/openstack/objectstorage/v1/accounts/testing/requests_test.go +++ b/openstack/objectstorage/v1/accounts/testing/requests_test.go @@ -11,9 +11,9 @@ import ( ) func TestUpdateAccount(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleUpdateAccountSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleUpdateAccountSuccessfully(t, fakeServer) options := &accounts.UpdateOpts{ Metadata: map[string]string{"gophercloud-test": "accounts"}, @@ -21,7 +21,7 @@ func TestUpdateAccount(t *testing.T) { ContentType: new(string), DetectContentType: new(bool), } - res := accounts.Update(context.TODO(), client.ServiceClient(), options) + res := accounts.Update(context.TODO(), client.ServiceClient(fakeServer), options) th.AssertNoErr(t, res.Err) expected := &accounts.UpdateHeader{ @@ -33,12 +33,12 @@ func TestUpdateAccount(t *testing.T) { } func TestGetAccount(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetAccountSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetAccountSuccessfully(t, fakeServer) expectedMetadata := map[string]string{"Subject": "books", "Quota-Bytes": "42", "Temp-Url-Key": "testsecret"} - res := accounts.Get(context.TODO(), client.ServiceClient(), &accounts.GetOpts{}) + res := accounts.Get(context.TODO(), client.ServiceClient(fakeServer), &accounts.GetOpts{}) th.AssertNoErr(t, res.Err) actualMetadata, _ := res.ExtractMetadata() th.CheckDeepEquals(t, expectedMetadata, actualMetadata) @@ -60,12 +60,12 @@ func TestGetAccount(t *testing.T) { } func TestGetAccountNoQuota(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetAccountNoQuotaSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetAccountNoQuotaSuccessfully(t, fakeServer) expectedMetadata := map[string]string{"Subject": "books"} - res := accounts.Get(context.TODO(), client.ServiceClient(), &accounts.GetOpts{}) + res := accounts.Get(context.TODO(), client.ServiceClient(fakeServer), &accounts.GetOpts{}) th.AssertNoErr(t, res.Err) actualMetadata, _ := res.ExtractMetadata() th.CheckDeepEquals(t, expectedMetadata, actualMetadata) diff --git a/openstack/objectstorage/v1/containers/testing/fixtures.go b/openstack/objectstorage/v1/containers/testing/fixtures.go index 224ea2d8ed..8e35743a7c 100644 --- a/openstack/objectstorage/v1/containers/testing/fixtures.go +++ b/openstack/objectstorage/v1/containers/testing/fixtures.go @@ -43,8 +43,8 @@ var ExpectedListNames = []string{"janeausten", "marktwain"} // HandleListContainerInfoSuccessfully creates an HTTP handler at `/` on the test handler mux that // responds with a `List` response when full info is requested. -func HandleListContainerInfoSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { +func HandleListContainerInfoSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -87,8 +87,8 @@ func HandleListContainerInfoSuccessfully(t *testing.T) { // HandleListZeroContainerNames204 creates an HTTP handler at `/` on the test handler mux that // responds with "204 No Content" when container names are requested. This happens on some, but not all, // objectstorage instances. This case is peculiar in that the server sends no `content-type` header. -func HandleListZeroContainerNames204(t *testing.T) { - th.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { +func HandleListZeroContainerNames204(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -99,8 +99,8 @@ func HandleListZeroContainerNames204(t *testing.T) { // HandleCreateContainerSuccessfully creates an HTTP handler at `/testContainer` on the test handler mux that // responds with a `Create` response. -func HandleCreateContainerSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/testContainer", func(w http.ResponseWriter, r *http.Request) { +func HandleCreateContainerSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/testContainer", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -117,7 +117,7 @@ func HandleCreateContainerSuccessfully(t *testing.T) { // HandleDeleteContainerSuccessfully creates an HTTP handler at `/testContainer` on the test handler mux that // responds with a `Delete` response. -func HandleDeleteContainerSuccessfully(t *testing.T, options ...option) { +func HandleDeleteContainerSuccessfully(t *testing.T, fakeServer th.FakeServer, options ...option) { ho := handlerOptions{ path: "/testContainer", } @@ -125,7 +125,7 @@ func HandleDeleteContainerSuccessfully(t *testing.T, options ...option) { apply(&ho) } - th.Mux.HandleFunc(ho.path, func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc(ho.path, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -145,8 +145,8 @@ const bulkDeleteResponse = ` // HandleBulkDeleteSuccessfully creates an HTTP handler at `/` on the test // handler mux that responds with a `Delete` response. -func HandleBulkDeleteSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { +func HandleBulkDeleteSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -164,7 +164,7 @@ func HandleBulkDeleteSuccessfully(t *testing.T) { // HandleUpdateContainerSuccessfully creates an HTTP handler at `/testContainer` on the test handler mux that // responds with a `Update` response. -func HandleUpdateContainerSuccessfully(t *testing.T, options ...option) { +func HandleUpdateContainerSuccessfully(t *testing.T, fakeServer th.FakeServer, options ...option) { ho := handlerOptions{ path: "/testContainer", } @@ -172,7 +172,7 @@ func HandleUpdateContainerSuccessfully(t *testing.T, options ...option) { apply(&ho) } - th.Mux.HandleFunc(ho.path, func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc(ho.path, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -187,7 +187,7 @@ func HandleUpdateContainerSuccessfully(t *testing.T, options ...option) { // HandleUpdateContainerVersioningOn creates an HTTP handler at `/testVersioning` on the test handler mux that // responds with a `Update` response. -func HandleUpdateContainerVersioningOn(t *testing.T, options ...option) { +func HandleUpdateContainerVersioningOn(t *testing.T, fakeServer th.FakeServer, options ...option) { ho := handlerOptions{ path: "/testVersioning", } @@ -195,7 +195,7 @@ func HandleUpdateContainerVersioningOn(t *testing.T, options ...option) { apply(&ho) } - th.Mux.HandleFunc(ho.path, func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc(ho.path, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -211,7 +211,7 @@ func HandleUpdateContainerVersioningOn(t *testing.T, options ...option) { // HandleUpdateContainerVersioningOff creates an HTTP handler at `/testVersioning` on the test handler mux that // responds with a `Update` response. -func HandleUpdateContainerVersioningOff(t *testing.T, options ...option) { +func HandleUpdateContainerVersioningOff(t *testing.T, fakeServer th.FakeServer, options ...option) { ho := handlerOptions{ path: "/testVersioning", } @@ -219,7 +219,7 @@ func HandleUpdateContainerVersioningOff(t *testing.T, options ...option) { apply(&ho) } - th.Mux.HandleFunc(ho.path, func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc(ho.path, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -235,7 +235,7 @@ func HandleUpdateContainerVersioningOff(t *testing.T, options ...option) { // HandleGetContainerSuccessfully creates an HTTP handler at `/testContainer` on the test handler mux that // responds with a `Get` response. -func HandleGetContainerSuccessfully(t *testing.T, options ...option) { +func HandleGetContainerSuccessfully(t *testing.T, fakeServer th.FakeServer, options ...option) { ho := handlerOptions{ path: "/testContainer", } @@ -243,7 +243,7 @@ func HandleGetContainerSuccessfully(t *testing.T, options ...option) { apply(&ho) } - th.Mux.HandleFunc(ho.path, func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc(ho.path, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "HEAD") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") diff --git a/openstack/objectstorage/v1/containers/testing/requests_test.go b/openstack/objectstorage/v1/containers/testing/requests_test.go index a286e3f5f7..5fcc669ba6 100644 --- a/openstack/objectstorage/v1/containers/testing/requests_test.go +++ b/openstack/objectstorage/v1/containers/testing/requests_test.go @@ -31,25 +31,25 @@ func TestContainerNames(t *testing.T) { } { t.Run(tc.name, func(t *testing.T) { t.Run("create", func(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateContainerSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCreateContainerSuccessfully(t, fakeServer) - _, err := containers.Create(context.TODO(), client.ServiceClient(), tc.containerName, nil).Extract() + _, err := containers.Create(context.TODO(), client.ServiceClient(fakeServer), tc.containerName, nil).Extract() th.CheckErr(t, err, &tc.expectedError) }) t.Run("delete", func(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDeleteContainerSuccessfully(t, WithPath("/")) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDeleteContainerSuccessfully(t, fakeServer, WithPath("/")) - res := containers.Delete(context.TODO(), client.ServiceClient(), tc.containerName) + res := containers.Delete(context.TODO(), client.ServiceClient(fakeServer), tc.containerName) th.CheckErr(t, res.Err, &tc.expectedError) }) t.Run("update", func(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleUpdateContainerSuccessfully(t, WithPath("/")) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleUpdateContainerSuccessfully(t, fakeServer, WithPath("/")) contentType := "text/plain" options := &containers.UpdateOpts{ @@ -60,15 +60,15 @@ func TestContainerNames(t *testing.T) { ContainerSyncKey: new(string), ContentType: &contentType, } - res := containers.Update(context.TODO(), client.ServiceClient(), tc.containerName, options) + res := containers.Update(context.TODO(), client.ServiceClient(fakeServer), tc.containerName, options) th.CheckErr(t, res.Err, &tc.expectedError) }) t.Run("get", func(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetContainerSuccessfully(t, WithPath("/")) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetContainerSuccessfully(t, fakeServer, WithPath("/")) - res := containers.Get(context.TODO(), client.ServiceClient(), tc.containerName, nil) + res := containers.Get(context.TODO(), client.ServiceClient(fakeServer), tc.containerName, nil) _, err := res.ExtractMetadata() th.CheckErr(t, err, &tc.expectedError) @@ -80,12 +80,12 @@ func TestContainerNames(t *testing.T) { } func TestListContainerInfo(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListContainerInfoSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListContainerInfoSuccessfully(t, fakeServer) count := 0 - err := containers.List(client.ServiceClient(), &containers.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := containers.List(client.ServiceClient(fakeServer), &containers.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := containers.ExtractInfo(page) th.AssertNoErr(t, err) @@ -99,11 +99,11 @@ func TestListContainerInfo(t *testing.T) { } func TestListAllContainerInfo(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListContainerInfoSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListContainerInfoSuccessfully(t, fakeServer) - allPages, err := containers.List(client.ServiceClient(), &containers.ListOpts{}).AllPages(context.TODO()) + allPages, err := containers.List(client.ServiceClient(fakeServer), &containers.ListOpts{}).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := containers.ExtractInfo(allPages) th.AssertNoErr(t, err) @@ -111,12 +111,12 @@ func TestListAllContainerInfo(t *testing.T) { } func TestListContainerNames(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListContainerInfoSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListContainerInfoSuccessfully(t, fakeServer) count := 0 - err := containers.List(client.ServiceClient(), &containers.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := containers.List(client.ServiceClient(fakeServer), &containers.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := containers.ExtractNames(page) if err != nil { @@ -133,11 +133,11 @@ func TestListContainerNames(t *testing.T) { } func TestListAllContainerNames(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListContainerInfoSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListContainerInfoSuccessfully(t, fakeServer) - allPages, err := containers.List(client.ServiceClient(), &containers.ListOpts{}).AllPages(context.TODO()) + allPages, err := containers.List(client.ServiceClient(fakeServer), &containers.ListOpts{}).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := containers.ExtractNames(allPages) th.AssertNoErr(t, err) @@ -145,11 +145,11 @@ func TestListAllContainerNames(t *testing.T) { } func TestListZeroContainerNames(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListZeroContainerNames204(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListZeroContainerNames204(t, fakeServer) - allPages, err := containers.List(client.ServiceClient(), &containers.ListOpts{}).AllPages(context.TODO()) + allPages, err := containers.List(client.ServiceClient(fakeServer), &containers.ListOpts{}).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := containers.ExtractNames(allPages) th.AssertNoErr(t, err) @@ -157,12 +157,12 @@ func TestListZeroContainerNames(t *testing.T) { } func TestCreateContainer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateContainerSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCreateContainerSuccessfully(t, fakeServer) options := containers.CreateOpts{ContentType: "application/json", Metadata: map[string]string{"foo": "bar"}} - res := containers.Create(context.TODO(), client.ServiceClient(), "testContainer", options) + res := containers.Create(context.TODO(), client.ServiceClient(fakeServer), "testContainer", options) th.CheckEquals(t, "bar", res.Header["X-Container-Meta-Foo"][0]) expected := &containers.CreateHeader{ @@ -177,18 +177,18 @@ func TestCreateContainer(t *testing.T) { } func TestDeleteContainer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDeleteContainerSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDeleteContainerSuccessfully(t, fakeServer) - res := containers.Delete(context.TODO(), client.ServiceClient(), "testContainer") + res := containers.Delete(context.TODO(), client.ServiceClient(fakeServer), "testContainer") th.AssertNoErr(t, res.Err) } func TestBulkDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleBulkDeleteSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleBulkDeleteSuccessfully(t, fakeServer) expected := containers.BulkDeleteResponse{ ResponseStatus: "foo", @@ -197,15 +197,15 @@ func TestBulkDelete(t *testing.T) { Errors: [][]string{}, } - resp, err := containers.BulkDelete(context.TODO(), client.ServiceClient(), []string{"testContainer1", "testContainer2"}).Extract() + resp, err := containers.BulkDelete(context.TODO(), client.ServiceClient(fakeServer), []string{"testContainer1", "testContainer2"}).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, expected, *resp) } func TestUpdateContainer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleUpdateContainerSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleUpdateContainerSuccessfully(t, fakeServer) contentType := "text/plain" options := &containers.UpdateOpts{ @@ -216,19 +216,19 @@ func TestUpdateContainer(t *testing.T) { ContainerSyncKey: new(string), ContentType: &contentType, } - res := containers.Update(context.TODO(), client.ServiceClient(), "testContainer", options) + res := containers.Update(context.TODO(), client.ServiceClient(fakeServer), "testContainer", options) th.AssertNoErr(t, res.Err) } func TestGetContainer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetContainerSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetContainerSuccessfully(t, fakeServer) getOpts := containers.GetOpts{ Newest: true, } - res := containers.Get(context.TODO(), client.ServiceClient(), "testContainer", getOpts) + res := containers.Get(context.TODO(), client.ServiceClient(fakeServer), "testContainer", getOpts) _, err := res.ExtractMetadata() th.AssertNoErr(t, err) @@ -253,9 +253,9 @@ func TestGetContainer(t *testing.T) { } func TestUpdateContainerVersioningOff(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleUpdateContainerVersioningOff(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleUpdateContainerVersioningOff(t, fakeServer) contentType := "text/plain" options := &containers.UpdateOpts{ @@ -267,14 +267,14 @@ func TestUpdateContainerVersioningOff(t *testing.T) { ContentType: &contentType, VersionsEnabled: new(bool), } - _, err := containers.Update(context.TODO(), client.ServiceClient(), "testVersioning", options).Extract() + _, err := containers.Update(context.TODO(), client.ServiceClient(fakeServer), "testVersioning", options).Extract() th.AssertNoErr(t, err) } func TestUpdateContainerVersioningOn(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleUpdateContainerVersioningOn(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleUpdateContainerVersioningOn(t, fakeServer) iTrue := true contentType := "text/plain" @@ -287,6 +287,6 @@ func TestUpdateContainerVersioningOn(t *testing.T) { ContentType: &contentType, VersionsEnabled: &iTrue, } - _, err := containers.Update(context.TODO(), client.ServiceClient(), "testVersioning", options).Extract() + _, err := containers.Update(context.TODO(), client.ServiceClient(fakeServer), "testVersioning", options).Extract() th.AssertNoErr(t, err) } diff --git a/openstack/objectstorage/v1/objects/testing/fixtures_test.go b/openstack/objectstorage/v1/objects/testing/fixtures_test.go index c1d23d8cc1..b6c6f78144 100644 --- a/openstack/objectstorage/v1/objects/testing/fixtures_test.go +++ b/openstack/objectstorage/v1/objects/testing/fixtures_test.go @@ -27,7 +27,7 @@ func WithPath(s string) option { // HandleDownloadObjectSuccessfully creates an HTTP handler at `/testContainer/testObject` on the test handler mux that // responds with a `Download` response. -func HandleDownloadObjectSuccessfully(t *testing.T, options ...option) { +func HandleDownloadObjectSuccessfully(t *testing.T, fakeServer th.FakeServer, options ...option) { ho := handlerOptions{ path: "/testContainer/testObject", } @@ -35,7 +35,7 @@ func HandleDownloadObjectSuccessfully(t *testing.T, options ...option) { apply(&ho) } - th.Mux.HandleFunc(ho.path, func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc(ho.path, func(w http.ResponseWriter, r *http.Request) { date := time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC) th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -98,7 +98,7 @@ var ExpectedListNames = []string{"goodbye", "hello"} // HandleListObjectsInfoSuccessfully creates an HTTP handler at `/testContainer` on the test handler mux that // responds with a `List` response when full info is requested. -func HandleListObjectsInfoSuccessfully(t *testing.T, options ...option) { +func HandleListObjectsInfoSuccessfully(t *testing.T, fakeServer th.FakeServer, options ...option) { ho := handlerOptions{ path: "/testContainer", } @@ -106,7 +106,7 @@ func HandleListObjectsInfoSuccessfully(t *testing.T, options ...option) { apply(&ho) } - th.Mux.HandleFunc(ho.path, func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc(ho.path, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -144,8 +144,8 @@ func HandleListObjectsInfoSuccessfully(t *testing.T, options ...option) { // HandleListSubdirSuccessfully creates an HTTP handler at `/testContainer` on the test handler mux that // responds with a `List` response when full info is requested. -func HandleListSubdirSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/testContainer", func(w http.ResponseWriter, r *http.Request) { +func HandleListSubdirSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/testContainer", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -173,8 +173,8 @@ func HandleListSubdirSuccessfully(t *testing.T) { // HandleListZeroObjectNames204 creates an HTTP handler at `/testContainer` on the test handler mux that // responds with "204 No Content" when object names are requested. This happens on some, but not all, objectstorage // instances. This case is peculiar in that the server sends no `content-type` header. -func HandleListZeroObjectNames204(t *testing.T) { - th.Mux.HandleFunc("/testContainer", func(w http.ResponseWriter, r *http.Request) { +func HandleListZeroObjectNames204(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/testContainer", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -185,7 +185,7 @@ func HandleListZeroObjectNames204(t *testing.T) { // HandleCreateTextObjectSuccessfully creates an HTTP handler at `/testContainer/testObject` on the test handler mux // that responds with a `Create` response. A Content-Type of "text/plain" is expected. -func HandleCreateTextObjectSuccessfully(t *testing.T, content string, options ...option) { +func HandleCreateTextObjectSuccessfully(t *testing.T, fakeServer th.FakeServer, content string, options ...option) { ho := handlerOptions{ path: "/testContainer/testObject", } @@ -193,7 +193,7 @@ func HandleCreateTextObjectSuccessfully(t *testing.T, content string, options .. apply(&ho) } - th.Mux.HandleFunc(ho.path, func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc(ho.path, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "text/plain") @@ -212,8 +212,8 @@ func HandleCreateTextObjectSuccessfully(t *testing.T, content string, options .. // HandleCreateTextWithCacheControlSuccessfully creates an HTTP handler at `/testContainer/testObject` on the test handler // mux that responds with a `Create` response. A Cache-Control of `max-age="3600", public` is expected. -func HandleCreateTextWithCacheControlSuccessfully(t *testing.T, content string) { - th.Mux.HandleFunc("/testContainer/testObject", func(w http.ResponseWriter, r *http.Request) { +func HandleCreateTextWithCacheControlSuccessfully(t *testing.T, fakeServer th.FakeServer, content string) { + fakeServer.Mux.HandleFunc("/testContainer/testObject", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Cache-Control", `max-age="3600", public`) @@ -233,8 +233,8 @@ func HandleCreateTextWithCacheControlSuccessfully(t *testing.T, content string) // HandleCreateTypelessObjectSuccessfully creates an HTTP handler at `/testContainer/testObject` on the test handler // mux that responds with a `Create` response. No Content-Type header may be present in the request, so that server- // side content-type detection will be triggered properly. -func HandleCreateTypelessObjectSuccessfully(t *testing.T, content string) { - th.Mux.HandleFunc("/testContainer/testObject", func(w http.ResponseWriter, r *http.Request) { +func HandleCreateTypelessObjectSuccessfully(t *testing.T, fakeServer th.FakeServer, content string) { + fakeServer.Mux.HandleFunc("/testContainer/testObject", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -256,8 +256,8 @@ func HandleCreateTypelessObjectSuccessfully(t *testing.T, content string) { // HandleCopyObjectSuccessfully creates an HTTP handler at `/testContainer/testObject` on the test handler mux that // responds with a `Copy` response. -func HandleCopyObjectSuccessfully(t *testing.T, destination string) { - th.Mux.HandleFunc("/testContainer/testObject", func(w http.ResponseWriter, r *http.Request) { +func HandleCopyObjectSuccessfully(t *testing.T, fakeServer th.FakeServer, destination string) { + fakeServer.Mux.HandleFunc("/testContainer/testObject", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "COPY") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -268,8 +268,8 @@ func HandleCopyObjectSuccessfully(t *testing.T, destination string) { // HandleCopyObjectSuccessfully creates an HTTP handler at `/testContainer/testObject` on the test handler mux that // responds with a `Copy` response. -func HandleCopyObjectVersionSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/testContainer/testObject", func(w http.ResponseWriter, r *http.Request) { +func HandleCopyObjectVersionSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/testContainer/testObject", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "COPY") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -282,7 +282,7 @@ func HandleCopyObjectVersionSuccessfully(t *testing.T) { // HandleDeleteObjectSuccessfully creates an HTTP handler at `/testContainer/testObject` on the test handler mux that // responds with a `Delete` response. -func HandleDeleteObjectSuccessfully(t *testing.T, options ...option) { +func HandleDeleteObjectSuccessfully(t *testing.T, fakeServer th.FakeServer, options ...option) { ho := handlerOptions{ path: "/testContainer/testObject", } @@ -290,7 +290,7 @@ func HandleDeleteObjectSuccessfully(t *testing.T, options ...option) { apply(&ho) } - th.Mux.HandleFunc(ho.path, func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc(ho.path, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -310,8 +310,8 @@ const bulkDeleteResponse = ` // HandleBulkDeleteSuccessfully creates an HTTP handler at `/` on the test // handler mux that responds with a `BulkDelete` response. -func HandleBulkDeleteSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { +func HandleBulkDeleteSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -329,7 +329,7 @@ func HandleBulkDeleteSuccessfully(t *testing.T) { // HandleUpdateObjectSuccessfully creates an HTTP handler at `/testContainer/testObject` on the test handler mux that // responds with a `Update` response. -func HandleUpdateObjectSuccessfully(t *testing.T, options ...option) { +func HandleUpdateObjectSuccessfully(t *testing.T, fakeServer th.FakeServer, options ...option) { ho := handlerOptions{ path: "/testContainer/testObject", } @@ -337,7 +337,7 @@ func HandleUpdateObjectSuccessfully(t *testing.T, options ...option) { apply(&ho) } - th.Mux.HandleFunc(ho.path, func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc(ho.path, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -355,7 +355,7 @@ func HandleUpdateObjectSuccessfully(t *testing.T, options ...option) { // HandleGetObjectSuccessfully creates an HTTP handler at `/testContainer/testObject` on the test handler mux that // responds with a `Get` response. -func HandleGetObjectSuccessfully(t *testing.T, options ...option) { +func HandleGetObjectSuccessfully(t *testing.T, fakeServer th.FakeServer, options ...option) { ho := handlerOptions{ path: "/testContainer/testObject", } @@ -363,7 +363,7 @@ func HandleGetObjectSuccessfully(t *testing.T, options ...option) { apply(&ho) } - th.Mux.HandleFunc(ho.path, func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc(ho.path, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "HEAD") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") diff --git a/openstack/objectstorage/v1/objects/testing/requests_test.go b/openstack/objectstorage/v1/objects/testing/requests_test.go index a6399f6a53..d131f1bdcd 100644 --- a/openstack/objectstorage/v1/objects/testing/requests_test.go +++ b/openstack/objectstorage/v1/objects/testing/requests_test.go @@ -39,69 +39,68 @@ func TestContainerNames(t *testing.T) { } { t.Run(tc.name, func(t *testing.T) { t.Run("list", func(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListObjectsInfoSuccessfully(t, WithPath("/")) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListObjectsInfoSuccessfully(t, fakeServer, WithPath("/")) - _, err := objects.List(client.ServiceClient(), tc.containerName, nil).AllPages(context.TODO()) + _, err := objects.List(client.ServiceClient(fakeServer), tc.containerName, nil).AllPages(context.TODO()) th.CheckErr(t, err, &tc.expectedError) }) t.Run("download", func(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDownloadObjectSuccessfully(t, WithPath("/")) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDownloadObjectSuccessfully(t, fakeServer, WithPath("/")) - _, err := objects.Download(context.TODO(), client.ServiceClient(), tc.containerName, "testObject", nil).Extract() + _, err := objects.Download(context.TODO(), client.ServiceClient(fakeServer), tc.containerName, "testObject", nil).Extract() th.CheckErr(t, err, &tc.expectedError) }) t.Run("create", func(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() content := "Ceci n'est pas une pipe" - HandleCreateTextObjectSuccessfully(t, content, WithPath("/")) + HandleCreateTextObjectSuccessfully(t, fakeServer, content, WithPath("/")) - res := objects.Create(context.TODO(), client.ServiceClient(), tc.containerName, "testObject", &objects.CreateOpts{ + res := objects.Create(context.TODO(), client.ServiceClient(fakeServer), tc.containerName, "testObject", &objects.CreateOpts{ ContentType: "text/plain", Content: strings.NewReader(content), }) th.CheckErr(t, res.Err, &tc.expectedError) }) t.Run("delete", func(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDeleteObjectSuccessfully(t, WithPath("/")) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDeleteObjectSuccessfully(t, fakeServer, WithPath("/")) - res := objects.Delete(context.TODO(), client.ServiceClient(), tc.containerName, "testObject", nil) + res := objects.Delete(context.TODO(), client.ServiceClient(fakeServer), tc.containerName, "testObject", nil) th.CheckErr(t, res.Err, &tc.expectedError) }) t.Run("get", func(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetObjectSuccessfully(t, WithPath("/")) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetObjectSuccessfully(t, fakeServer, WithPath("/")) - _, err := objects.Get(context.TODO(), client.ServiceClient(), tc.containerName, "testObject", nil).ExtractMetadata() + _, err := objects.Get(context.TODO(), client.ServiceClient(fakeServer), tc.containerName, "testObject", nil).ExtractMetadata() th.CheckErr(t, err, &tc.expectedError) }) t.Run("update", func(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleUpdateObjectSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleUpdateObjectSuccessfully(t, fakeServer) - res := objects.Update(context.TODO(), client.ServiceClient(), tc.containerName, "testObject", &objects.UpdateOpts{ + res := objects.Update(context.TODO(), client.ServiceClient(fakeServer), tc.containerName, "testObject", &objects.UpdateOpts{ Metadata: map[string]string{"Gophercloud-Test": "objects"}, }) th.CheckErr(t, res.Err, &tc.expectedError) }) t.Run("createTempURL", func(t *testing.T) { port := 33200 - th.SetupHTTP() - th.SetupPersistentPortHTTP(t, port) - defer th.TeardownHTTP() + fakeServer := th.SetupPersistentPortHTTP(t, port) + defer fakeServer.Teardown() // Handle fetching of secret key inside of CreateTempURL - containerTesting.HandleGetContainerSuccessfully(t) - accountTesting.HandleGetAccountSuccessfully(t) - client := client.ServiceClient() + containerTesting.HandleGetContainerSuccessfully(t, fakeServer) + accountTesting.HandleGetAccountSuccessfully(t, fakeServer) + client := client.ServiceClient(fakeServer) // Append v1/ to client endpoint URL to be compliant with tempURL generator client.Endpoint = client.Endpoint + "v1/" @@ -114,11 +113,11 @@ func TestContainerNames(t *testing.T) { th.CheckErr(t, err, &tc.expectedError) }) t.Run("bulk-delete", func(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleBulkDeleteSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleBulkDeleteSuccessfully(t, fakeServer) - res := objects.BulkDelete(context.TODO(), client.ServiceClient(), tc.containerName, []string{"testObject"}) + res := objects.BulkDelete(context.TODO(), client.ServiceClient(fakeServer), tc.containerName, []string{"testObject"}) th.CheckErr(t, res.Err, &tc.expectedError) }) }) @@ -126,11 +125,11 @@ func TestContainerNames(t *testing.T) { } func TestDownloadReader(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDownloadObjectSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDownloadObjectSuccessfully(t, fakeServer) - response := objects.Download(context.TODO(), client.ServiceClient(), "testContainer", "testObject", nil) + response := objects.Download(context.TODO(), client.ServiceClient(fakeServer), "testContainer", "testObject", nil) defer response.Body.Close() // Check reader @@ -141,11 +140,11 @@ func TestDownloadReader(t *testing.T) { } func TestDownloadExtraction(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDownloadObjectSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDownloadObjectSuccessfully(t, fakeServer) - response := objects.Download(context.TODO(), client.ServiceClient(), "testContainer", "testObject", nil) + response := objects.Download(context.TODO(), client.ServiceClient(fakeServer), "testContainer", "testObject", nil) // Check []byte extraction bytes, err := response.ExtractContent() @@ -165,34 +164,34 @@ func TestDownloadExtraction(t *testing.T) { } func TestDownloadWithLastModified(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDownloadObjectSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDownloadObjectSuccessfully(t, fakeServer) options1 := &objects.DownloadOpts{ IfUnmodifiedSince: time.Date(2009, time.November, 10, 22, 59, 59, 0, time.UTC), } - response1 := objects.Download(context.TODO(), client.ServiceClient(), "testContainer", "testObject", options1) + response1 := objects.Download(context.TODO(), client.ServiceClient(fakeServer), "testContainer", "testObject", options1) _, err1 := response1.Extract() th.AssertErr(t, err1) options2 := &objects.DownloadOpts{ IfModifiedSince: time.Date(2009, time.November, 10, 23, 0, 1, 0, time.UTC), } - response2 := objects.Download(context.TODO(), client.ServiceClient(), "testContainer", "testObject", options2) + response2 := objects.Download(context.TODO(), client.ServiceClient(fakeServer), "testContainer", "testObject", options2) content, err2 := response2.ExtractContent() th.AssertNoErr(t, err2) th.AssertEquals(t, 0, len(content)) } func TestListObjectInfo(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListObjectsInfoSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListObjectsInfoSuccessfully(t, fakeServer) count := 0 options := &objects.ListOpts{} - err := objects.List(client.ServiceClient(), "testContainer", options).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := objects.List(client.ServiceClient(fakeServer), "testContainer", options).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := objects.ExtractInfo(page) th.AssertNoErr(t, err) @@ -206,13 +205,13 @@ func TestListObjectInfo(t *testing.T) { } func TestListObjectSubdir(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListSubdirSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListSubdirSuccessfully(t, fakeServer) count := 0 options := &objects.ListOpts{Prefix: "", Delimiter: "/"} - err := objects.List(client.ServiceClient(), "testContainer", options).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := objects.List(client.ServiceClient(fakeServer), "testContainer", options).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := objects.ExtractInfo(page) th.AssertNoErr(t, err) @@ -226,14 +225,14 @@ func TestListObjectSubdir(t *testing.T) { } func TestListObjectNames(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListObjectsInfoSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListObjectsInfoSuccessfully(t, fakeServer) // Check without delimiter. count := 0 options := &objects.ListOpts{} - err := objects.List(client.ServiceClient(), "testContainer", options).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := objects.List(client.ServiceClient(fakeServer), "testContainer", options).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := objects.ExtractNames(page) if err != nil { @@ -251,7 +250,7 @@ func TestListObjectNames(t *testing.T) { // Check with delimiter. count = 0 options = &objects.ListOpts{Delimiter: "/"} - err = objects.List(client.ServiceClient(), "testContainer", options).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err = objects.List(client.ServiceClient(fakeServer), "testContainer", options).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := objects.ExtractNames(page) if err != nil { @@ -268,13 +267,13 @@ func TestListObjectNames(t *testing.T) { } func TestListZeroObjectNames204(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListZeroObjectNames204(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListZeroObjectNames204(t, fakeServer) count := 0 options := &objects.ListOpts{} - err := objects.List(client.ServiceClient(), "testContainer", options).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := objects.List(client.ServiceClient(fakeServer), "testContainer", options).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := objects.ExtractNames(page) if err != nil { @@ -291,100 +290,100 @@ func TestListZeroObjectNames204(t *testing.T) { } func TestCreateObject(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() content := "Did gyre and gimble in the wabe" - HandleCreateTextObjectSuccessfully(t, content) + HandleCreateTextObjectSuccessfully(t, fakeServer, content) options := &objects.CreateOpts{ContentType: "text/plain", Content: strings.NewReader(content)} - res := objects.Create(context.TODO(), client.ServiceClient(), "testContainer", "testObject", options) + res := objects.Create(context.TODO(), client.ServiceClient(fakeServer), "testContainer", "testObject", options) th.AssertNoErr(t, res.Err) } func TestCreateObjectWithCacheControl(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() content := "All mimsy were the borogoves" - HandleCreateTextWithCacheControlSuccessfully(t, content) + HandleCreateTextWithCacheControlSuccessfully(t, fakeServer, content) options := &objects.CreateOpts{ CacheControl: `max-age="3600", public`, Content: strings.NewReader(content), } - res := objects.Create(context.TODO(), client.ServiceClient(), "testContainer", "testObject", options) + res := objects.Create(context.TODO(), client.ServiceClient(fakeServer), "testContainer", "testObject", options) th.AssertNoErr(t, res.Err) } func TestCreateObjectWithoutContentType(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() content := "The sky was the color of television, tuned to a dead channel." - HandleCreateTypelessObjectSuccessfully(t, content) + HandleCreateTypelessObjectSuccessfully(t, fakeServer, content) - res := objects.Create(context.TODO(), client.ServiceClient(), "testContainer", "testObject", &objects.CreateOpts{Content: strings.NewReader(content)}) + res := objects.Create(context.TODO(), client.ServiceClient(fakeServer), "testContainer", "testObject", &objects.CreateOpts{Content: strings.NewReader(content)}) th.AssertNoErr(t, res.Err) } func TestCopyObject(t *testing.T) { t.Run("simple", func(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCopyObjectSuccessfully(t, "/newTestContainer/newTestObject") + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCopyObjectSuccessfully(t, fakeServer, "/newTestContainer/newTestObject") options := &objects.CopyOpts{Destination: "/newTestContainer/newTestObject"} - res := objects.Copy(context.TODO(), client.ServiceClient(), "testContainer", "testObject", options) + res := objects.Copy(context.TODO(), client.ServiceClient(fakeServer), "testContainer", "testObject", options) th.AssertNoErr(t, res.Err) }) t.Run("slash", func(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCopyObjectSuccessfully(t, "/newTestContainer/path%2Fto%2FnewTestObject") + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCopyObjectSuccessfully(t, fakeServer, "/newTestContainer/path%2Fto%2FnewTestObject") options := &objects.CopyOpts{Destination: "/newTestContainer/path/to/newTestObject"} - res := objects.Copy(context.TODO(), client.ServiceClient(), "testContainer", "testObject", options) + res := objects.Copy(context.TODO(), client.ServiceClient(fakeServer), "testContainer", "testObject", options) th.AssertNoErr(t, res.Err) }) t.Run("emojis", func(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCopyObjectSuccessfully(t, "/newTestContainer/new%F0%9F%98%8ATest%2C%3B%22O%28bject%21_%E7%AF%84") + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCopyObjectSuccessfully(t, fakeServer, "/newTestContainer/new%F0%9F%98%8ATest%2C%3B%22O%28bject%21_%E7%AF%84") options := &objects.CopyOpts{Destination: "/newTestContainer/new😊Test,;\"O(bject!_範"} - res := objects.Copy(context.TODO(), client.ServiceClient(), "testContainer", "testObject", options) + res := objects.Copy(context.TODO(), client.ServiceClient(fakeServer), "testContainer", "testObject", options) th.AssertNoErr(t, res.Err) }) } func TestCopyObjectVersion(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCopyObjectVersionSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCopyObjectVersionSuccessfully(t, fakeServer) options := &objects.CopyOpts{Destination: "/newTestContainer/newTestObject", ObjectVersionID: "123456788"} - res, err := objects.Copy(context.TODO(), client.ServiceClient(), "testContainer", "testObject", options).Extract() + res, err := objects.Copy(context.TODO(), client.ServiceClient(fakeServer), "testContainer", "testObject", options).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, "123456789", res.ObjectVersionID) } func TestDeleteObject(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDeleteObjectSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDeleteObjectSuccessfully(t, fakeServer) - res := objects.Delete(context.TODO(), client.ServiceClient(), "testContainer", "testObject", nil) + res := objects.Delete(context.TODO(), client.ServiceClient(fakeServer), "testContainer", "testObject", nil) th.AssertNoErr(t, res.Err) } func TestBulkDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleBulkDeleteSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleBulkDeleteSuccessfully(t, fakeServer) expected := objects.BulkDeleteResponse{ ResponseStatus: "foo", @@ -393,15 +392,15 @@ func TestBulkDelete(t *testing.T) { Errors: [][]string{}, } - resp, err := objects.BulkDelete(context.TODO(), client.ServiceClient(), "testContainer", []string{"testObject1", "testObject2"}).Extract() + resp, err := objects.BulkDelete(context.TODO(), client.ServiceClient(fakeServer), "testContainer", []string{"testObject1", "testObject2"}).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, expected, *resp) } func TestUpateObjectMetadata(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleUpdateObjectSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleUpdateObjectSuccessfully(t, fakeServer) s := new(string) i := new(int64) @@ -414,24 +413,24 @@ func TestUpateObjectMetadata(t *testing.T) { DeleteAt: i, DetectContentType: new(bool), } - res := objects.Update(context.TODO(), client.ServiceClient(), "testContainer", "testObject", options) + res := objects.Update(context.TODO(), client.ServiceClient(fakeServer), "testContainer", "testObject", options) th.AssertNoErr(t, res.Err) } func TestGetObject(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetObjectSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetObjectSuccessfully(t, fakeServer) expected := map[string]string{"Gophercloud-Test": "objects"} - actual, err := objects.Get(context.TODO(), client.ServiceClient(), "testContainer", "testObject", nil).ExtractMetadata() + actual, err := objects.Get(context.TODO(), client.ServiceClient(fakeServer), "testContainer", "testObject", nil).ExtractMetadata() th.AssertNoErr(t, err) th.CheckDeepEquals(t, expected, actual) getOpts := objects.GetOpts{ Newest: true, } - actualHeaders, err := objects.Get(context.TODO(), client.ServiceClient(), "testContainer", "testObject", getOpts).Extract() + actualHeaders, err := objects.Get(context.TODO(), client.ServiceClient(fakeServer), "testContainer", "testObject", getOpts).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, true, actualHeaders.StaticLargeObject) } @@ -505,14 +504,13 @@ func TestObjectCreateParamsWithSeek(t *testing.T) { func TestCreateTempURL(t *testing.T) { port := 33200 - th.SetupHTTP() - th.SetupPersistentPortHTTP(t, port) - defer th.TeardownHTTP() + fakeServer := th.SetupPersistentPortHTTP(t, port) + defer fakeServer.Teardown() // Handle fetching of secret key inside of CreateTempURL - containerTesting.HandleGetContainerSuccessfully(t) - accountTesting.HandleGetAccountSuccessfully(t) - client := client.ServiceClient() + containerTesting.HandleGetContainerSuccessfully(t, fakeServer) + accountTesting.HandleGetAccountSuccessfully(t, fakeServer) + client := client.ServiceClient(fakeServer) // Append v1/ to client endpoint URL to be compliant with tempURL generator client.Endpoint = client.Endpoint + "v1/" diff --git a/openstack/objectstorage/v1/swauth/testing/fixtures_test.go b/openstack/objectstorage/v1/swauth/testing/fixtures_test.go index 01bbfd1a84..796132da3e 100644 --- a/openstack/objectstorage/v1/swauth/testing/fixtures_test.go +++ b/openstack/objectstorage/v1/swauth/testing/fixtures_test.go @@ -16,8 +16,8 @@ var AuthResult = swauth.AuthResult{ } // HandleAuthSuccessfully configures the test server to respond to an Auth request. -func HandleAuthSuccessfully(t *testing.T, authOpts swauth.AuthOpts) { - th.Mux.HandleFunc("/auth/v1.0", func(w http.ResponseWriter, r *http.Request) { +func HandleAuthSuccessfully(t *testing.T, fakeServer th.FakeServer, authOpts swauth.AuthOpts) { + fakeServer.Mux.HandleFunc("/auth/v1.0", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-User", authOpts.User) th.TestHeader(t, r, "X-Auth-Key", authOpts.Key) diff --git a/openstack/objectstorage/v1/swauth/testing/requests_test.go b/openstack/objectstorage/v1/swauth/testing/requests_test.go index cd095d0c17..066da28498 100644 --- a/openstack/objectstorage/v1/swauth/testing/requests_test.go +++ b/openstack/objectstorage/v1/swauth/testing/requests_test.go @@ -15,11 +15,11 @@ func TestAuth(t *testing.T) { Key: "testing", } - th.SetupHTTP() - defer th.TeardownHTTP() - HandleAuthSuccessfully(t, authOpts) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleAuthSuccessfully(t, fakeServer, authOpts) - providerClient, err := openstack.NewClient(th.Endpoint()) + providerClient, err := openstack.NewClient(fakeServer.Endpoint()) th.AssertNoErr(t, err) swiftClient, err := swauth.NewObjectStorageV1(context.TODO(), providerClient, authOpts) diff --git a/openstack/orchestration/v1/apiversions/testing/requests_test.go b/openstack/orchestration/v1/apiversions/testing/requests_test.go index 9edae2d541..80613508c1 100644 --- a/openstack/orchestration/v1/apiversions/testing/requests_test.go +++ b/openstack/orchestration/v1/apiversions/testing/requests_test.go @@ -14,10 +14,10 @@ import ( ) func TestListVersions(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -43,7 +43,7 @@ func TestListVersions(t *testing.T) { count := 0 - err := apiversions.ListVersions(client.ServiceClient()).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := apiversions.ListVersions(client.ServiceClient(fakeServer)).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := apiversions.ExtractAPIVersions(page) if err != nil { @@ -76,14 +76,14 @@ func TestListVersions(t *testing.T) { } func TestNonJSONCannotBeExtractedIntoAPIVersions(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) }) - err := apiversions.ListVersions(client.ServiceClient()).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := apiversions.ListVersions(client.ServiceClient(fakeServer)).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { if _, err := apiversions.ExtractAPIVersions(page); err == nil { t.Fatalf("Expected error, got nil") } diff --git a/openstack/orchestration/v1/buildinfo/testing/fixtures_test.go b/openstack/orchestration/v1/buildinfo/testing/fixtures_test.go index f05c9898ba..8a89455e5f 100644 --- a/openstack/orchestration/v1/buildinfo/testing/fixtures_test.go +++ b/openstack/orchestration/v1/buildinfo/testing/fixtures_test.go @@ -33,8 +33,8 @@ const GetOutput = ` // HandleGetSuccessfully creates an HTTP handler at `/build_info` // on the test handler mux that responds with a `Get` response. -func HandleGetSuccessfully(t *testing.T, output string) { - th.Mux.HandleFunc("/build_info", func(w http.ResponseWriter, r *http.Request) { +func HandleGetSuccessfully(t *testing.T, fakeServer th.FakeServer, output string) { + fakeServer.Mux.HandleFunc("/build_info", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") diff --git a/openstack/orchestration/v1/buildinfo/testing/requests_test.go b/openstack/orchestration/v1/buildinfo/testing/requests_test.go index 241b6dde7d..9780033255 100644 --- a/openstack/orchestration/v1/buildinfo/testing/requests_test.go +++ b/openstack/orchestration/v1/buildinfo/testing/requests_test.go @@ -10,11 +10,11 @@ import ( ) func TestGetTemplate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetSuccessfully(t, GetOutput) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetSuccessfully(t, fakeServer, GetOutput) - actual, err := buildinfo.Get(context.TODO(), client.ServiceClient()).Extract() + actual, err := buildinfo.Get(context.TODO(), client.ServiceClient(fakeServer)).Extract() th.AssertNoErr(t, err) expected := GetExpected diff --git a/openstack/orchestration/v1/resourcetypes/testing/fixtures_test.go b/openstack/orchestration/v1/resourcetypes/testing/fixtures_test.go index 3c170b1984..4883edd8d8 100644 --- a/openstack/orchestration/v1/resourcetypes/testing/fixtures_test.go +++ b/openstack/orchestration/v1/resourcetypes/testing/fixtures_test.go @@ -75,8 +75,8 @@ var FilteredListExpected = []resourcetypes.ResourceTypeSummary{ // HandleListSuccessfully creates an HTTP handler at `/resource_types` // on the test handler mux that responds with a `List` response. -func HandleListSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/resource_types", +func HandleListSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/resource_types", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -324,8 +324,8 @@ const GetSchemaOutput = ` // HandleGetSchemaSuccessfully creates an HTTP handler at // `/resource_types/OS::Test::TestServer` on the test handler mux that // responds with a `GetSchema` response. -func HandleGetSchemaSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/resource_types/OS::Test::TestServer", +func HandleGetSchemaSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/resource_types/OS::Test::TestServer", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -370,8 +370,8 @@ const GenerateTemplateOutput = ` // HandleGenerateTemplateSuccessfully creates an HTTP handler at // `/resource_types/OS::Heat::None/template` on the test handler mux that // responds with a template. -func HandleGenerateTemplateSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/resource_types/OS::Heat::None/template", +func HandleGenerateTemplateSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/resource_types/OS::Heat::None/template", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/orchestration/v1/resourcetypes/testing/requests_test.go b/openstack/orchestration/v1/resourcetypes/testing/requests_test.go index ccccdf87e0..6a0fb4356d 100644 --- a/openstack/orchestration/v1/resourcetypes/testing/requests_test.go +++ b/openstack/orchestration/v1/resourcetypes/testing/requests_test.go @@ -10,11 +10,11 @@ import ( ) func TestBasicListResourceTypes(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListSuccessfully(t, fakeServer) - result := resourcetypes.List(context.TODO(), client.ServiceClient(), nil) + result := resourcetypes.List(context.TODO(), client.ServiceClient(fakeServer), nil) th.AssertNoErr(t, result.Err) actual, err := result.Extract() @@ -24,11 +24,11 @@ func TestBasicListResourceTypes(t *testing.T) { } func TestFullListResourceTypes(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListSuccessfully(t, fakeServer) - result := resourcetypes.List(context.TODO(), client.ServiceClient(), resourcetypes.ListOpts{ + result := resourcetypes.List(context.TODO(), client.ServiceClient(fakeServer), resourcetypes.ListOpts{ WithDescription: true, }) th.AssertNoErr(t, result.Err) @@ -40,11 +40,11 @@ func TestFullListResourceTypes(t *testing.T) { } func TestFilteredListResourceTypes(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListSuccessfully(t, fakeServer) - result := resourcetypes.List(context.TODO(), client.ServiceClient(), resourcetypes.ListOpts{ + result := resourcetypes.List(context.TODO(), client.ServiceClient(fakeServer), resourcetypes.ListOpts{ NameRegex: listFilterRegex, WithDescription: true, }) @@ -57,11 +57,11 @@ func TestFilteredListResourceTypes(t *testing.T) { } func TestGetSchema(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetSchemaSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetSchemaSuccessfully(t, fakeServer) - result := resourcetypes.GetSchema(context.TODO(), client.ServiceClient(), "OS::Test::TestServer") + result := resourcetypes.GetSchema(context.TODO(), client.ServiceClient(fakeServer), "OS::Test::TestServer") th.AssertNoErr(t, result.Err) actual, err := result.Extract() @@ -71,11 +71,11 @@ func TestGetSchema(t *testing.T) { } func TestGenerateTemplate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGenerateTemplateSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGenerateTemplateSuccessfully(t, fakeServer) - result := resourcetypes.GenerateTemplate(context.TODO(), client.ServiceClient(), "OS::Heat::None", nil) + result := resourcetypes.GenerateTemplate(context.TODO(), client.ServiceClient(fakeServer), "OS::Heat::None", nil) th.AssertNoErr(t, result.Err) actual, err := result.Extract() diff --git a/openstack/orchestration/v1/stackevents/testing/fixtures_test.go b/openstack/orchestration/v1/stackevents/testing/fixtures_test.go index 0f45487d14..d450ca559e 100644 --- a/openstack/orchestration/v1/stackevents/testing/fixtures_test.go +++ b/openstack/orchestration/v1/stackevents/testing/fixtures_test.go @@ -120,8 +120,8 @@ const FindOutput = ` // HandleFindSuccessfully creates an HTTP handler at `/stacks/postman_stack/events` // on the test handler mux that responds with a `Find` response. -func HandleFindSuccessfully(t *testing.T, output string) { - th.Mux.HandleFunc("/stacks/postman_stack/events", func(w http.ResponseWriter, r *http.Request) { +func HandleFindSuccessfully(t *testing.T, fakeServer th.FakeServer, output string) { + fakeServer.Mux.HandleFunc("/stacks/postman_stack/events", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -237,8 +237,8 @@ const ListOutput = ` // HandleListSuccessfully creates an HTTP handler at `/stacks/hello_world/49181cd6-169a-4130-9455-31185bbfc5bf/events` // on the test handler mux that responds with a `List` response. -func HandleListSuccessfully(t *testing.T, output string) { - th.Mux.HandleFunc("/stacks/hello_world/49181cd6-169a-4130-9455-31185bbfc5bf/events", func(w http.ResponseWriter, r *http.Request) { +func HandleListSuccessfully(t *testing.T, fakeServer th.FakeServer, output string) { + fakeServer.Mux.HandleFunc("/stacks/hello_world/49181cd6-169a-4130-9455-31185bbfc5bf/events", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -364,8 +364,8 @@ const ListResourceEventsOutput = ` // HandleListResourceEventsSuccessfully creates an HTTP handler at `/stacks/hello_world/49181cd6-169a-4130-9455-31185bbfc5bf/resources/my_resource/events` // on the test handler mux that responds with a `ListResourceEvents` response. -func HandleListResourceEventsSuccessfully(t *testing.T, output string) { - th.Mux.HandleFunc("/stacks/hello_world/49181cd6-169a-4130-9455-31185bbfc5bf/resources/my_resource/events", func(w http.ResponseWriter, r *http.Request) { +func HandleListResourceEventsSuccessfully(t *testing.T, fakeServer th.FakeServer, output string) { + fakeServer.Mux.HandleFunc("/stacks/hello_world/49181cd6-169a-4130-9455-31185bbfc5bf/resources/my_resource/events", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -441,8 +441,8 @@ const GetOutput = ` // HandleGetSuccessfully creates an HTTP handler at `/stacks/hello_world/49181cd6-169a-4130-9455-31185bbfc5bf/resources/my_resource/events/93940999-7d40-44ae-8de4-19624e7b8d18` // on the test handler mux that responds with a `Get` response. -func HandleGetSuccessfully(t *testing.T, output string) { - th.Mux.HandleFunc("/stacks/hello_world/49181cd6-169a-4130-9455-31185bbfc5bf/resources/my_resource/events/93940999-7d40-44ae-8de4-19624e7b8d18", func(w http.ResponseWriter, r *http.Request) { +func HandleGetSuccessfully(t *testing.T, fakeServer th.FakeServer, output string) { + fakeServer.Mux.HandleFunc("/stacks/hello_world/49181cd6-169a-4130-9455-31185bbfc5bf/resources/my_resource/events/93940999-7d40-44ae-8de4-19624e7b8d18", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") diff --git a/openstack/orchestration/v1/stackevents/testing/requests_test.go b/openstack/orchestration/v1/stackevents/testing/requests_test.go index 17471c9b49..d1c60abf3a 100644 --- a/openstack/orchestration/v1/stackevents/testing/requests_test.go +++ b/openstack/orchestration/v1/stackevents/testing/requests_test.go @@ -11,11 +11,11 @@ import ( ) func TestFindEvents(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleFindSuccessfully(t, FindOutput) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleFindSuccessfully(t, fakeServer, FindOutput) - actual, err := stackevents.Find(context.TODO(), client.ServiceClient(), "postman_stack").Extract() + actual, err := stackevents.Find(context.TODO(), client.ServiceClient(fakeServer), "postman_stack").Extract() th.AssertNoErr(t, err) expected := FindExpected @@ -23,12 +23,12 @@ func TestFindEvents(t *testing.T) { } func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListSuccessfully(t, ListOutput) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListSuccessfully(t, fakeServer, ListOutput) count := 0 - err := stackevents.List(client.ServiceClient(), "hello_world", "49181cd6-169a-4130-9455-31185bbfc5bf", nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := stackevents.List(client.ServiceClient(fakeServer), "hello_world", "49181cd6-169a-4130-9455-31185bbfc5bf", nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := stackevents.ExtractEvents(page) th.AssertNoErr(t, err) @@ -42,12 +42,12 @@ func TestList(t *testing.T) { } func TestListResourceEvents(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListResourceEventsSuccessfully(t, ListResourceEventsOutput) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListResourceEventsSuccessfully(t, fakeServer, ListResourceEventsOutput) count := 0 - err := stackevents.ListResourceEvents(client.ServiceClient(), "hello_world", "49181cd6-169a-4130-9455-31185bbfc5bf", "my_resource", nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := stackevents.ListResourceEvents(client.ServiceClient(fakeServer), "hello_world", "49181cd6-169a-4130-9455-31185bbfc5bf", "my_resource", nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := stackevents.ExtractResourceEvents(page) th.AssertNoErr(t, err) @@ -61,11 +61,11 @@ func TestListResourceEvents(t *testing.T) { } func TestGetEvent(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetSuccessfully(t, GetOutput) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetSuccessfully(t, fakeServer, GetOutput) - actual, err := stackevents.Get(context.TODO(), client.ServiceClient(), "hello_world", "49181cd6-169a-4130-9455-31185bbfc5bf", "my_resource", "93940999-7d40-44ae-8de4-19624e7b8d18").Extract() + actual, err := stackevents.Get(context.TODO(), client.ServiceClient(fakeServer), "hello_world", "49181cd6-169a-4130-9455-31185bbfc5bf", "my_resource", "93940999-7d40-44ae-8de4-19624e7b8d18").Extract() th.AssertNoErr(t, err) expected := GetExpected diff --git a/openstack/orchestration/v1/stackresources/testing/fixtures_test.go b/openstack/orchestration/v1/stackresources/testing/fixtures_test.go index 55edb88bc0..45800807f3 100644 --- a/openstack/orchestration/v1/stackresources/testing/fixtures_test.go +++ b/openstack/orchestration/v1/stackresources/testing/fixtures_test.go @@ -74,8 +74,8 @@ const FindOutput = ` // HandleFindSuccessfully creates an HTTP handler at `/stacks/hello_world/resources` // on the test handler mux that responds with a `Find` response. -func HandleFindSuccessfully(t *testing.T, output string) { - th.Mux.HandleFunc("/stacks/hello_world/resources", func(w http.ResponseWriter, r *http.Request) { +func HandleFindSuccessfully(t *testing.T, fakeServer th.FakeServer, output string) { + fakeServer.Mux.HandleFunc("/stacks/hello_world/resources", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -144,8 +144,8 @@ const ListOutput = `{ // HandleListSuccessfully creates an HTTP handler at `/stacks/hello_world/49181cd6-169a-4130-9455-31185bbfc5bf/resources` // on the test handler mux that responds with a `List` response. -func HandleListSuccessfully(t *testing.T, output string) { - th.Mux.HandleFunc("/stacks/hello_world/49181cd6-169a-4130-9455-31185bbfc5bf/resources", func(w http.ResponseWriter, r *http.Request) { +func HandleListSuccessfully(t *testing.T, fakeServer th.FakeServer, output string) { + fakeServer.Mux.HandleFunc("/stacks/hello_world/49181cd6-169a-4130-9455-31185bbfc5bf/resources", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -219,8 +219,8 @@ const GetOutput = ` // HandleGetSuccessfully creates an HTTP handler at `/stacks/teststack/0b1771bd-9336-4f2b-ae86-a80f971faf1e/resources/wordpress_instance` // on the test handler mux that responds with a `Get` response. -func HandleGetSuccessfully(t *testing.T, output string) { - th.Mux.HandleFunc("/stacks/teststack/0b1771bd-9336-4f2b-ae86-a80f971faf1e/resources/wordpress_instance", func(w http.ResponseWriter, r *http.Request) { +func HandleGetSuccessfully(t *testing.T, fakeServer th.FakeServer, output string) { + fakeServer.Mux.HandleFunc("/stacks/teststack/0b1771bd-9336-4f2b-ae86-a80f971faf1e/resources/wordpress_instance", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -248,8 +248,8 @@ const MetadataOutput = ` // HandleMetadataSuccessfully creates an HTTP handler at `/stacks/teststack/0b1771bd-9336-4f2b-ae86-a80f971faf1e/resources/wordpress_instance/metadata` // on the test handler mux that responds with a `Metadata` response. -func HandleMetadataSuccessfully(t *testing.T, output string) { - th.Mux.HandleFunc("/stacks/teststack/0b1771bd-9336-4f2b-ae86-a80f971faf1e/resources/wordpress_instance/metadata", func(w http.ResponseWriter, r *http.Request) { +func HandleMetadataSuccessfully(t *testing.T, fakeServer th.FakeServer, output string) { + fakeServer.Mux.HandleFunc("/stacks/teststack/0b1771bd-9336-4f2b-ae86-a80f971faf1e/resources/wordpress_instance/metadata", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -301,8 +301,8 @@ const ListTypesOutput = ` // HandleListTypesSuccessfully creates an HTTP handler at `/resource_types` // on the test handler mux that responds with a `ListTypes` response. -func HandleListTypesSuccessfully(t *testing.T, output string) { - th.Mux.HandleFunc("/resource_types", func(w http.ResponseWriter, r *http.Request) { +func HandleListTypesSuccessfully(t *testing.T, fakeServer th.FakeServer, output string) { + fakeServer.Mux.HandleFunc("/resource_types", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -362,8 +362,8 @@ const GetSchemaOutput = ` // HandleGetSchemaSuccessfully creates an HTTP handler at `/resource_types/OS::Heat::AResourceName` // on the test handler mux that responds with a `Schema` response. -func HandleGetSchemaSuccessfully(t *testing.T, output string) { - th.Mux.HandleFunc("/resource_types/OS::Heat::AResourceName", func(w http.ResponseWriter, r *http.Request) { +func HandleGetSchemaSuccessfully(t *testing.T, fakeServer th.FakeServer, output string) { + fakeServer.Mux.HandleFunc("/resource_types/OS::Heat::AResourceName", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -432,8 +432,8 @@ const GetTemplateOutput = ` // HandleGetTemplateSuccessfully creates an HTTP handler at `/resource_types/OS::Heat::AResourceName/template` // on the test handler mux that responds with a `Template` response. -func HandleGetTemplateSuccessfully(t *testing.T, output string) { - th.Mux.HandleFunc("/resource_types/OS::Heat::AResourceName/template", func(w http.ResponseWriter, r *http.Request) { +func HandleGetTemplateSuccessfully(t *testing.T, fakeServer th.FakeServer, output string) { + fakeServer.Mux.HandleFunc("/resource_types/OS::Heat::AResourceName/template", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -446,8 +446,8 @@ func HandleGetTemplateSuccessfully(t *testing.T, output string) { // HandleMarkUnhealthySuccessfully creates an HTTP handler at `/stacks/teststack/0b1771bd-9336-4f2b-ae86-a80f971faf1e/resources/wordpress_instance` // on the test handler mux that responds with a `MarkUnhealthy` response. -func HandleMarkUnhealthySuccessfully(t *testing.T) { - th.Mux.HandleFunc("/stacks/teststack/0b1771bd-9336-4f2b-ae86-a80f971faf1e/resources/wordpress_instance", func(w http.ResponseWriter, r *http.Request) { +func HandleMarkUnhealthySuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/stacks/teststack/0b1771bd-9336-4f2b-ae86-a80f971faf1e/resources/wordpress_instance", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PATCH") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") diff --git a/openstack/orchestration/v1/stackresources/testing/requests_test.go b/openstack/orchestration/v1/stackresources/testing/requests_test.go index e3f6e1510b..2852716bd8 100644 --- a/openstack/orchestration/v1/stackresources/testing/requests_test.go +++ b/openstack/orchestration/v1/stackresources/testing/requests_test.go @@ -12,11 +12,11 @@ import ( ) func TestFindResources(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleFindSuccessfully(t, FindOutput) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleFindSuccessfully(t, fakeServer, FindOutput) - actual, err := stackresources.Find(context.TODO(), client.ServiceClient(), "hello_world").Extract() + actual, err := stackresources.Find(context.TODO(), client.ServiceClient(fakeServer), "hello_world").Extract() th.AssertNoErr(t, err) expected := FindExpected @@ -24,12 +24,12 @@ func TestFindResources(t *testing.T) { } func TestListResources(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListSuccessfully(t, ListOutput) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListSuccessfully(t, fakeServer, ListOutput) count := 0 - err := stackresources.List(client.ServiceClient(), "hello_world", "49181cd6-169a-4130-9455-31185bbfc5bf", nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := stackresources.List(client.ServiceClient(fakeServer), "hello_world", "49181cd6-169a-4130-9455-31185bbfc5bf", nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := stackresources.ExtractResources(page) th.AssertNoErr(t, err) @@ -43,11 +43,11 @@ func TestListResources(t *testing.T) { } func TestGetResource(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetSuccessfully(t, GetOutput) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetSuccessfully(t, fakeServer, GetOutput) - actual, err := stackresources.Get(context.TODO(), client.ServiceClient(), "teststack", "0b1771bd-9336-4f2b-ae86-a80f971faf1e", "wordpress_instance").Extract() + actual, err := stackresources.Get(context.TODO(), client.ServiceClient(fakeServer), "teststack", "0b1771bd-9336-4f2b-ae86-a80f971faf1e", "wordpress_instance").Extract() th.AssertNoErr(t, err) expected := GetExpected @@ -55,11 +55,11 @@ func TestGetResource(t *testing.T) { } func TestResourceMetadata(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleMetadataSuccessfully(t, MetadataOutput) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleMetadataSuccessfully(t, fakeServer, MetadataOutput) - actual, err := stackresources.Metadata(context.TODO(), client.ServiceClient(), "teststack", "0b1771bd-9336-4f2b-ae86-a80f971faf1e", "wordpress_instance").Extract() + actual, err := stackresources.Metadata(context.TODO(), client.ServiceClient(fakeServer), "teststack", "0b1771bd-9336-4f2b-ae86-a80f971faf1e", "wordpress_instance").Extract() th.AssertNoErr(t, err) expected := MetadataExpected @@ -67,12 +67,12 @@ func TestResourceMetadata(t *testing.T) { } func TestListResourceTypes(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListTypesSuccessfully(t, ListTypesOutput) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListTypesSuccessfully(t, fakeServer, ListTypesOutput) count := 0 - err := stackresources.ListTypes(client.ServiceClient()).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := stackresources.ListTypes(client.ServiceClient(fakeServer)).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := stackresources.ExtractResourceTypes(page) th.AssertNoErr(t, err) @@ -89,11 +89,11 @@ func TestListResourceTypes(t *testing.T) { } func TestGetResourceSchema(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetSchemaSuccessfully(t, GetSchemaOutput) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetSchemaSuccessfully(t, fakeServer, GetSchemaOutput) - actual, err := stackresources.Schema(context.TODO(), client.ServiceClient(), "OS::Heat::AResourceName").Extract() + actual, err := stackresources.Schema(context.TODO(), client.ServiceClient(fakeServer), "OS::Heat::AResourceName").Extract() th.AssertNoErr(t, err) expected := GetSchemaExpected @@ -101,11 +101,11 @@ func TestGetResourceSchema(t *testing.T) { } func TestGetResourceTemplate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetTemplateSuccessfully(t, GetTemplateOutput) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetTemplateSuccessfully(t, fakeServer, GetTemplateOutput) - actual, err := stackresources.Template(context.TODO(), client.ServiceClient(), "OS::Heat::AResourceName").Extract() + actual, err := stackresources.Template(context.TODO(), client.ServiceClient(fakeServer), "OS::Heat::AResourceName").Extract() th.AssertNoErr(t, err) expected := GetTemplateExpected @@ -113,14 +113,14 @@ func TestGetResourceTemplate(t *testing.T) { } func TestMarkUnhealthyResource(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleMarkUnhealthySuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleMarkUnhealthySuccessfully(t, fakeServer) markUnhealthyOpts := &stackresources.MarkUnhealthyOpts{ MarkUnhealthy: true, ResourceStatusReason: "Kubelet.Ready is Unknown more than 10 mins.", } - err := stackresources.MarkUnhealthy(context.TODO(), client.ServiceClient(), "teststack", "0b1771bd-9336-4f2b-ae86-a80f971faf1e", "wordpress_instance", markUnhealthyOpts).ExtractErr() + err := stackresources.MarkUnhealthy(context.TODO(), client.ServiceClient(fakeServer), "teststack", "0b1771bd-9336-4f2b-ae86-a80f971faf1e", "wordpress_instance", markUnhealthyOpts).ExtractErr() th.AssertNoErr(t, err) } diff --git a/openstack/orchestration/v1/stacks/environment_test.go b/openstack/orchestration/v1/stacks/environment_test.go index b69e527050..c3b900543a 100644 --- a/openstack/orchestration/v1/stacks/environment_test.go +++ b/openstack/orchestration/v1/stacks/environment_test.go @@ -71,8 +71,8 @@ func TestIgnoreIfEnvironment(t *testing.T) { } func TestGetRRFileContents(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() environmentContent := ` heat_template_version: 2013-05-23 @@ -129,10 +129,10 @@ service_db: th.AssertNoErr(t, err) // Serve "my_env.yaml" and "my_db.yaml" - fakeEnvURL := th.ServeFile(t, baseurl, "my_env.yaml", "application/json", environmentContent) - fakeDBURL := th.ServeFile(t, baseurl, "my_db.yaml", "application/json", dbContent) + fakeEnvURL := fakeServer.ServeFile(t, baseurl, "my_env.yaml", "application/json", environmentContent) + fakeDBURL := fakeServer.ServeFile(t, baseurl, "my_db.yaml", "application/json", dbContent) - client := fakeClient{BaseClient: getHTTPClient()} + client := fakeClient{BaseClient: getHTTPClient(), FakeServer: fakeServer} env := new(Environment) env.Bin = []byte(`{"resource_registry": {"My::WP::Server": "my_env.yaml", "resources": {"my_db_server": {"OS::DBInstance": "my_db.yaml"}}}}`) env.client = client diff --git a/openstack/orchestration/v1/stacks/template_test.go b/openstack/orchestration/v1/stacks/template_test.go index 9ab257d70d..1f304e0cb5 100644 --- a/openstack/orchestration/v1/stacks/template_test.go +++ b/openstack/orchestration/v1/stacks/template_test.go @@ -111,14 +111,14 @@ var myNovaExpected = map[string]any{ } func TestGetFileContentsWithType(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() baseurl, err := getBasePath() th.AssertNoErr(t, err) - fakeURL := th.ServeFile(t, baseurl, "my_nova.yaml", "application/json", myNovaContent) + fakeURL := fakeServer.ServeFile(t, baseurl, "my_nova.yaml", "application/json", myNovaContent) - client := fakeClient{BaseClient: getHTTPClient()} + client := fakeClient{BaseClient: getHTTPClient(), FakeServer: fakeServer} te := new(Template) te.Bin = []byte(`heat_template_version: 2015-04-30 resources: @@ -148,15 +148,15 @@ resources: } func TestGetFileContentsWithFile(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() baseurl, err := getBasePath() th.AssertNoErr(t, err) somefile := `Welcome!` - fakeURL := th.ServeFile(t, baseurl, "somefile", "text/plain", somefile) + fakeURL := fakeServer.ServeFile(t, baseurl, "somefile", "text/plain", somefile) - client := fakeClient{BaseClient: getHTTPClient()} + client := fakeClient{BaseClient: getHTTPClient(), FakeServer: fakeServer} te := new(Template) // Note: We include the path that should be replaced also as a not-to-be-replaced // keyword ("path: somefile" below) to validate that no updates happen outside of @@ -195,13 +195,13 @@ resources: } func TestGetFileContentsComposeRelativePath(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() baseurl, err := getBasePath() th.AssertNoErr(t, err) novaPath := strings.Join([]string{"templates", "my_nova.yaml"}, "/") - novaURL := th.ServeFile(t, baseurl, novaPath, "application/json", myNovaContent) + novaURL := fakeServer.ServeFile(t, baseurl, novaPath, "application/json", myNovaContent) mySubStackContent := `heat_template_version: 2015-04-30 resources: @@ -237,9 +237,9 @@ resources: }, } subStacksPath := strings.Join([]string{"substacks", "my_substack.yaml"}, "/") - subStackURL := th.ServeFile(t, baseurl, subStacksPath, "application/json", mySubStackContent) + subStackURL := fakeServer.ServeFile(t, baseurl, subStacksPath, "application/json", mySubStackContent) - client := fakeClient{BaseClient: getHTTPClient()} + client := fakeClient{BaseClient: getHTTPClient(), FakeServer: fakeServer} te := new(Template) te.Bin = []byte(`heat_template_version: 2015-04-30 resources: diff --git a/openstack/orchestration/v1/stacks/testing/fixtures_test.go b/openstack/orchestration/v1/stacks/testing/fixtures_test.go index bdb773e54b..4b293dbf89 100644 --- a/openstack/orchestration/v1/stacks/testing/fixtures_test.go +++ b/openstack/orchestration/v1/stacks/testing/fixtures_test.go @@ -42,8 +42,8 @@ const CreateOutput = ` // HandleCreateSuccessfully creates an HTTP handler at `/stacks` on the test handler mux // that responds with a `Create` response. -func HandleCreateSuccessfully(t *testing.T, output string) { - th.Mux.HandleFunc("/stacks", func(w http.ResponseWriter, r *http.Request) { +func HandleCreateSuccessfully(t *testing.T, fakeServer th.FakeServer, output string) { + fakeServer.Mux.HandleFunc("/stacks", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -129,8 +129,8 @@ const FullListOutput = ` // HandleListSuccessfully creates an HTTP handler at `/stacks` on the test handler mux // that responds with a `List` response. -func HandleListSuccessfully(t *testing.T, output string) { - th.Mux.HandleFunc("/stacks", func(w http.ResponseWriter, r *http.Request) { +func HandleListSuccessfully(t *testing.T, fakeServer th.FakeServer, output string) { + fakeServer.Mux.HandleFunc("/stacks", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -213,8 +213,8 @@ const GetOutput = ` // HandleGetSuccessfully creates an HTTP handler at `/stacks/postman_stack/16ef0584-4458-41eb-87c8-0dc8d5f66c87` // on the test handler mux that responds with a `Get` response. -func HandleGetSuccessfully(t *testing.T, output string) { - th.Mux.HandleFunc("/stacks/postman_stack/16ef0584-4458-41eb-87c8-0dc8d5f66c87", func(w http.ResponseWriter, r *http.Request) { +func HandleGetSuccessfully(t *testing.T, fakeServer th.FakeServer, output string) { + fakeServer.Mux.HandleFunc("/stacks/postman_stack/16ef0584-4458-41eb-87c8-0dc8d5f66c87", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -225,8 +225,8 @@ func HandleGetSuccessfully(t *testing.T, output string) { }) } -func HandleFindSuccessfully(t *testing.T, output string) { - th.Mux.HandleFunc("/stacks/16ef0584-4458-41eb-87c8-0dc8d5f66c87", func(w http.ResponseWriter, r *http.Request) { +func HandleFindSuccessfully(t *testing.T, fakeServer th.FakeServer, output string) { + fakeServer.Mux.HandleFunc("/stacks/16ef0584-4458-41eb-87c8-0dc8d5f66c87", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -239,8 +239,8 @@ func HandleFindSuccessfully(t *testing.T, output string) { // HandleUpdateSuccessfully creates an HTTP handler at `/stacks/postman_stack/16ef0584-4458-41eb-87c8-0dc8d5f66c87` // on the test handler mux that responds with an `Update` response. -func HandleUpdateSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/stacks/gophercloud-test-stack-2/db6977b2-27aa-4775-9ae7-6213212d4ada", func(w http.ResponseWriter, r *http.Request) { +func HandleUpdateSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/stacks/gophercloud-test-stack-2/db6977b2-27aa-4775-9ae7-6213212d4ada", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -252,8 +252,8 @@ func HandleUpdateSuccessfully(t *testing.T) { // HandleUpdatePatchSuccessfully creates an HTTP handler at `/stacks/postman_stack/16ef0584-4458-41eb-87c8-0dc8d5f66c87` // on the test handler mux that responds with an `Update` response. -func HandleUpdatePatchSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/stacks/gophercloud-test-stack-2/db6977b2-27aa-4775-9ae7-6213212d4ada", func(w http.ResponseWriter, r *http.Request) { +func HandleUpdatePatchSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/stacks/gophercloud-test-stack-2/db6977b2-27aa-4775-9ae7-6213212d4ada", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PATCH") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -265,8 +265,8 @@ func HandleUpdatePatchSuccessfully(t *testing.T) { // HandleDeleteSuccessfully creates an HTTP handler at `/stacks/postman_stack/16ef0584-4458-41eb-87c8-0dc8d5f66c87` // on the test handler mux that responds with a `Delete` response. -func HandleDeleteSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/stacks/gophercloud-test-stack-2/db6977b2-27aa-4775-9ae7-6213212d4ada", func(w http.ResponseWriter, r *http.Request) { +func HandleDeleteSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/stacks/gophercloud-test-stack-2/db6977b2-27aa-4775-9ae7-6213212d4ada", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -301,8 +301,8 @@ var PreviewExpected = &stacks.PreviewedStack{ // HandlePreviewSuccessfully creates an HTTP handler at `/stacks/preview` // on the test handler mux that responds with a `Preview` response. -func HandlePreviewSuccessfully(t *testing.T, output string) { - th.Mux.HandleFunc("/stacks/preview", func(w http.ResponseWriter, r *http.Request) { +func HandlePreviewSuccessfully(t *testing.T, fakeServer th.FakeServer, output string) { + fakeServer.Mux.HandleFunc("/stacks/preview", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -424,8 +424,8 @@ const AbandonOutput = ` // HandleAbandonSuccessfully creates an HTTP handler at `/stacks/postman_stack/16ef0584-4458-41eb-87c8-0dc8d5f66c87/abandon` // on the test handler mux that responds with an `Abandon` response. -func HandleAbandonSuccessfully(t *testing.T, output string) { - th.Mux.HandleFunc("/stacks/postman_stack/16ef0584-4458-41eb-87c8-0dc8d5f66c8/abandon", func(w http.ResponseWriter, r *http.Request) { +func HandleAbandonSuccessfully(t *testing.T, fakeServer th.FakeServer, output string) { + fakeServer.Mux.HandleFunc("/stacks/postman_stack/16ef0584-4458-41eb-87c8-0dc8d5f66c8/abandon", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") diff --git a/openstack/orchestration/v1/stacks/testing/requests_test.go b/openstack/orchestration/v1/stacks/testing/requests_test.go index e7b6de1595..6c373315ec 100644 --- a/openstack/orchestration/v1/stacks/testing/requests_test.go +++ b/openstack/orchestration/v1/stacks/testing/requests_test.go @@ -12,9 +12,9 @@ import ( ) func TestCreateStack(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateSuccessfully(t, CreateOutput) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCreateSuccessfully(t, fakeServer, CreateOutput) template := new(stacks.Template) template.Bin = []byte(` { @@ -33,7 +33,7 @@ func TestCreateStack(t *testing.T) { TemplateOpts: template, DisableRollback: gophercloud.Disabled, } - actual, err := stacks.Create(context.TODO(), client.ServiceClient(), createOpts).Extract() + actual, err := stacks.Create(context.TODO(), client.ServiceClient(fakeServer), createOpts).Extract() th.AssertNoErr(t, err) expected := CreateExpected @@ -41,9 +41,9 @@ func TestCreateStack(t *testing.T) { } func TestCreateStackMissingRequiredInOpts(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateSuccessfully(t, CreateOutput) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCreateSuccessfully(t, fakeServer, CreateOutput) template := new(stacks.Template) template.Bin = []byte(` { @@ -59,14 +59,14 @@ func TestCreateStackMissingRequiredInOpts(t *testing.T) { createOpts := stacks.CreateOpts{ DisableRollback: gophercloud.Disabled, } - r := stacks.Create(context.TODO(), client.ServiceClient(), createOpts) + r := stacks.Create(context.TODO(), client.ServiceClient(fakeServer), createOpts) th.AssertEquals(t, "error creating the options map: Missing input for argument [Name]", r.Err.Error()) } func TestAdoptStack(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateSuccessfully(t, CreateOutput) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCreateSuccessfully(t, fakeServer, CreateOutput) template := new(stacks.Template) template.Bin = []byte(` { @@ -102,7 +102,7 @@ func TestAdoptStack(t *testing.T) { TemplateOpts: template, DisableRollback: gophercloud.Disabled, } - actual, err := stacks.Adopt(context.TODO(), client.ServiceClient(), adoptOpts).Extract() + actual, err := stacks.Adopt(context.TODO(), client.ServiceClient(fakeServer), adoptOpts).Extract() th.AssertNoErr(t, err) expected := CreateExpected @@ -110,12 +110,12 @@ func TestAdoptStack(t *testing.T) { } func TestListStack(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListSuccessfully(t, FullListOutput) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListSuccessfully(t, fakeServer, FullListOutput) count := 0 - err := stacks.List(client.ServiceClient(), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := stacks.List(client.ServiceClient(fakeServer), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := stacks.ExtractStacks(page) th.AssertNoErr(t, err) @@ -129,11 +129,11 @@ func TestListStack(t *testing.T) { } func TestGetStack(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetSuccessfully(t, GetOutput) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetSuccessfully(t, fakeServer, GetOutput) - actual, err := stacks.Get(context.TODO(), client.ServiceClient(), "postman_stack", "16ef0584-4458-41eb-87c8-0dc8d5f66c87").Extract() + actual, err := stacks.Get(context.TODO(), client.ServiceClient(fakeServer), "postman_stack", "16ef0584-4458-41eb-87c8-0dc8d5f66c87").Extract() th.AssertNoErr(t, err) expected := GetExpected @@ -141,11 +141,11 @@ func TestGetStack(t *testing.T) { } func TestFindStack(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleFindSuccessfully(t, GetOutput) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleFindSuccessfully(t, fakeServer, GetOutput) - actual, err := stacks.Find(context.TODO(), client.ServiceClient(), "16ef0584-4458-41eb-87c8-0dc8d5f66c87").Extract() + actual, err := stacks.Find(context.TODO(), client.ServiceClient(fakeServer), "16ef0584-4458-41eb-87c8-0dc8d5f66c87").Extract() th.AssertNoErr(t, err) expected := GetExpected @@ -153,9 +153,9 @@ func TestFindStack(t *testing.T) { } func TestUpdateStack(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleUpdateSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleUpdateSuccessfully(t, fakeServer) template := new(stacks.Template) template.Bin = []byte(` @@ -172,14 +172,14 @@ func TestUpdateStack(t *testing.T) { updateOpts := &stacks.UpdateOpts{ TemplateOpts: template, } - err := stacks.Update(context.TODO(), client.ServiceClient(), "gophercloud-test-stack-2", "db6977b2-27aa-4775-9ae7-6213212d4ada", updateOpts).ExtractErr() + err := stacks.Update(context.TODO(), client.ServiceClient(fakeServer), "gophercloud-test-stack-2", "db6977b2-27aa-4775-9ae7-6213212d4ada", updateOpts).ExtractErr() th.AssertNoErr(t, err) } func TestUpdateStackNoTemplate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleUpdateSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleUpdateSuccessfully(t, fakeServer) parameters := make(map[string]any) parameters["flavor"] = "m1.tiny" @@ -189,14 +189,14 @@ func TestUpdateStackNoTemplate(t *testing.T) { } expected := stacks.ErrTemplateRequired{} - err := stacks.Update(context.TODO(), client.ServiceClient(), "gophercloud-test-stack-2", "db6977b2-27aa-4775-9ae7-6213212d4ada", updateOpts).ExtractErr() + err := stacks.Update(context.TODO(), client.ServiceClient(fakeServer), "gophercloud-test-stack-2", "db6977b2-27aa-4775-9ae7-6213212d4ada", updateOpts).ExtractErr() th.AssertEquals(t, expected, err) } func TestUpdatePatchStack(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleUpdatePatchSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleUpdatePatchSuccessfully(t, fakeServer) parameters := make(map[string]any) parameters["flavor"] = "m1.tiny" @@ -204,23 +204,23 @@ func TestUpdatePatchStack(t *testing.T) { updateOpts := &stacks.UpdateOpts{ Parameters: parameters, } - err := stacks.UpdatePatch(context.TODO(), client.ServiceClient(), "gophercloud-test-stack-2", "db6977b2-27aa-4775-9ae7-6213212d4ada", updateOpts).ExtractErr() + err := stacks.UpdatePatch(context.TODO(), client.ServiceClient(fakeServer), "gophercloud-test-stack-2", "db6977b2-27aa-4775-9ae7-6213212d4ada", updateOpts).ExtractErr() th.AssertNoErr(t, err) } func TestDeleteStack(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDeleteSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDeleteSuccessfully(t, fakeServer) - err := stacks.Delete(context.TODO(), client.ServiceClient(), "gophercloud-test-stack-2", "db6977b2-27aa-4775-9ae7-6213212d4ada").ExtractErr() + err := stacks.Delete(context.TODO(), client.ServiceClient(fakeServer), "gophercloud-test-stack-2", "db6977b2-27aa-4775-9ae7-6213212d4ada").ExtractErr() th.AssertNoErr(t, err) } func TestPreviewStack(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandlePreviewSuccessfully(t, GetOutput) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandlePreviewSuccessfully(t, fakeServer, GetOutput) template := new(stacks.Template) template.Bin = []byte(` @@ -240,7 +240,7 @@ func TestPreviewStack(t *testing.T) { TemplateOpts: template, DisableRollback: gophercloud.Disabled, } - actual, err := stacks.Preview(context.TODO(), client.ServiceClient(), previewOpts).Extract() + actual, err := stacks.Preview(context.TODO(), client.ServiceClient(fakeServer), previewOpts).Extract() th.AssertNoErr(t, err) expected := PreviewExpected @@ -248,11 +248,11 @@ func TestPreviewStack(t *testing.T) { } func TestAbandonStack(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleAbandonSuccessfully(t, AbandonOutput) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleAbandonSuccessfully(t, fakeServer, AbandonOutput) - actual, err := stacks.Abandon(context.TODO(), client.ServiceClient(), "postman_stack", "16ef0584-4458-41eb-87c8-0dc8d5f66c8").Extract() + actual, err := stacks.Abandon(context.TODO(), client.ServiceClient(fakeServer), "postman_stack", "16ef0584-4458-41eb-87c8-0dc8d5f66c8").Extract() th.AssertNoErr(t, err) expected := AbandonExpected diff --git a/openstack/orchestration/v1/stacks/utils_test.go b/openstack/orchestration/v1/stacks/utils_test.go index b7dd86bf0e..bb90993702 100644 --- a/openstack/orchestration/v1/stacks/utils_test.go +++ b/openstack/orchestration/v1/stacks/utils_test.go @@ -44,34 +44,35 @@ func TestGetHTTPClient(t *testing.T) { // Implement a fakeclient that can be used to mock out HTTP requests type fakeClient struct { BaseClient Client + FakeServer th.FakeServer } // this client's Get method first changes the URL given to point to // testhelper's (th) endpoints. This is done because the http Mux does not seem // to work for fqdns with the `file` scheme func (c fakeClient) Get(url string) (*http.Response, error) { - newurl := strings.Replace(url, "file://", th.Endpoint(), 1) + newurl := strings.Replace(url, "file://", c.FakeServer.Endpoint(), 1) return c.BaseClient.Get(newurl) } // test the fetch function func TestFetch(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() baseurl, err := getBasePath() th.AssertNoErr(t, err) fakeURL := strings.Join([]string{baseurl, "file.yaml"}, "/") urlparsed, err := url.Parse(fakeURL) th.AssertNoErr(t, err) - th.Mux.HandleFunc(urlparsed.Path, func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc(urlparsed.Path, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") w.Header().Set("Content-Type", "application/jason") w.WriteHeader(http.StatusOK) fmt.Fprint(w, "Fee-fi-fo-fum") }) - client := fakeClient{BaseClient: getHTTPClient()} + client := fakeClient{BaseClient: getHTTPClient(), FakeServer: fakeServer} te := TE{ URL: "file.yaml", client: client, diff --git a/openstack/orchestration/v1/stacktemplates/testing/fixtures_test.go b/openstack/orchestration/v1/stacktemplates/testing/fixtures_test.go index 5d5da59dfc..7ee957aeb6 100644 --- a/openstack/orchestration/v1/stacktemplates/testing/fixtures_test.go +++ b/openstack/orchestration/v1/stacktemplates/testing/fixtures_test.go @@ -40,8 +40,8 @@ const GetOutput = ` // HandleGetSuccessfully creates an HTTP handler at `/stacks/postman_stack/16ef0584-4458-41eb-87c8-0dc8d5f66c87/template` // on the test handler mux that responds with a `Get` response. -func HandleGetSuccessfully(t *testing.T, output string) { - th.Mux.HandleFunc("/stacks/postman_stack/16ef0584-4458-41eb-87c8-0dc8d5f66c87/template", func(w http.ResponseWriter, r *http.Request) { +func HandleGetSuccessfully(t *testing.T, fakeServer th.FakeServer, output string) { + fakeServer.Mux.HandleFunc("/stacks/postman_stack/16ef0584-4458-41eb-87c8-0dc8d5f66c87/template", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -83,8 +83,8 @@ const ValidateOutput = ` // HandleValidateSuccessfully creates an HTTP handler at `/validate` // on the test handler mux that responds with a `Validate` response. -func HandleValidateSuccessfully(t *testing.T, output string) { - th.Mux.HandleFunc("/validate", func(w http.ResponseWriter, r *http.Request) { +func HandleValidateSuccessfully(t *testing.T, fakeServer th.FakeServer, output string) { + fakeServer.Mux.HandleFunc("/validate", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") diff --git a/openstack/orchestration/v1/stacktemplates/testing/requests_test.go b/openstack/orchestration/v1/stacktemplates/testing/requests_test.go index f703d7bd61..3e2eae944b 100644 --- a/openstack/orchestration/v1/stacktemplates/testing/requests_test.go +++ b/openstack/orchestration/v1/stacktemplates/testing/requests_test.go @@ -10,11 +10,11 @@ import ( ) func TestGetTemplate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetSuccessfully(t, GetOutput) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetSuccessfully(t, fakeServer, GetOutput) - actual, err := stacktemplates.Get(context.TODO(), client.ServiceClient(), "postman_stack", "16ef0584-4458-41eb-87c8-0dc8d5f66c87").Extract() + actual, err := stacktemplates.Get(context.TODO(), client.ServiceClient(fakeServer), "postman_stack", "16ef0584-4458-41eb-87c8-0dc8d5f66c87").Extract() th.AssertNoErr(t, err) expected := GetExpected @@ -22,9 +22,9 @@ func TestGetTemplate(t *testing.T) { } func TestValidateTemplate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleValidateSuccessfully(t, ValidateOutput) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleValidateSuccessfully(t, fakeServer, ValidateOutput) opts := stacktemplates.ValidateOpts{ Template: `{ @@ -51,7 +51,7 @@ func TestValidateTemplate(t *testing.T) { } }`, } - actual, err := stacktemplates.Validate(context.TODO(), client.ServiceClient(), opts).Extract() + actual, err := stacktemplates.Validate(context.TODO(), client.ServiceClient(fakeServer), opts).Extract() th.AssertNoErr(t, err) expected := ValidateExpected diff --git a/openstack/placement/v1/resourceproviders/testing/fixtures_test.go b/openstack/placement/v1/resourceproviders/testing/fixtures_test.go index 6c5556736c..7ddc91b240 100644 --- a/openstack/placement/v1/resourceproviders/testing/fixtures_test.go +++ b/openstack/placement/v1/resourceproviders/testing/fixtures_test.go @@ -268,8 +268,8 @@ var ExpectedTraits = resourceproviders.ResourceProviderTraits{ }, } -func HandleResourceProviderList(t *testing.T) { - th.Mux.HandleFunc("/resource_providers", +func HandleResourceProviderList(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/resource_providers", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -281,8 +281,8 @@ func HandleResourceProviderList(t *testing.T) { }) } -func HandleResourceProviderCreate(t *testing.T) { - th.Mux.HandleFunc("/resource_providers", func(w http.ResponseWriter, r *http.Request) { +func HandleResourceProviderCreate(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/resource_providers", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -293,8 +293,8 @@ func HandleResourceProviderCreate(t *testing.T) { }) } -func HandleResourceProviderGet(t *testing.T) { - th.Mux.HandleFunc("/resource_providers/99c09379-6e52-4ef8-9a95-b9ce6f68452e", func(w http.ResponseWriter, r *http.Request) { +func HandleResourceProviderGet(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/resource_providers/99c09379-6e52-4ef8-9a95-b9ce6f68452e", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -305,16 +305,16 @@ func HandleResourceProviderGet(t *testing.T) { }) } -func HandleResourceProviderDelete(t *testing.T) { - th.Mux.HandleFunc("/resource_providers/b99b3ab4-3aa6-4fba-b827-69b88b9c544a", func(w http.ResponseWriter, r *http.Request) { +func HandleResourceProviderDelete(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/resource_providers/b99b3ab4-3aa6-4fba-b827-69b88b9c544a", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusNoContent) }) } -func HandleResourceProviderUpdate(t *testing.T) { - th.Mux.HandleFunc("/resource_providers/4e8e5957-649f-477b-9e5b-f1f75b21c03c", func(w http.ResponseWriter, r *http.Request) { +func HandleResourceProviderUpdate(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/resource_providers/4e8e5957-649f-477b-9e5b-f1f75b21c03c", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -328,10 +328,10 @@ func HandleResourceProviderUpdate(t *testing.T) { }) } -func HandleResourceProviderGetUsages(t *testing.T) { +func HandleResourceProviderGetUsages(t *testing.T, fakeServer th.FakeServer) { usageTestUrl := fmt.Sprintf("/resource_providers/%s/usages", ResourceProviderTestID) - th.Mux.HandleFunc(usageTestUrl, + fakeServer.Mux.HandleFunc(usageTestUrl, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -343,10 +343,10 @@ func HandleResourceProviderGetUsages(t *testing.T) { }) } -func HandleResourceProviderGetInventories(t *testing.T) { +func HandleResourceProviderGetInventories(t *testing.T, fakeServer th.FakeServer) { inventoriesTestUrl := fmt.Sprintf("/resource_providers/%s/inventories", ResourceProviderTestID) - th.Mux.HandleFunc(inventoriesTestUrl, + fakeServer.Mux.HandleFunc(inventoriesTestUrl, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -358,10 +358,10 @@ func HandleResourceProviderGetInventories(t *testing.T) { }) } -func HandleResourceProviderGetAllocations(t *testing.T) { +func HandleResourceProviderGetAllocations(t *testing.T, fakeServer th.FakeServer) { allocationsTestUrl := fmt.Sprintf("/resource_providers/%s/allocations", ResourceProviderTestID) - th.Mux.HandleFunc(allocationsTestUrl, + fakeServer.Mux.HandleFunc(allocationsTestUrl, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -373,10 +373,10 @@ func HandleResourceProviderGetAllocations(t *testing.T) { }) } -func HandleResourceProviderGetTraits(t *testing.T) { +func HandleResourceProviderGetTraits(t *testing.T, fakeServer th.FakeServer) { traitsTestUrl := fmt.Sprintf("/resource_providers/%s/traits", ResourceProviderTestID) - th.Mux.HandleFunc(traitsTestUrl, + fakeServer.Mux.HandleFunc(traitsTestUrl, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/placement/v1/resourceproviders/testing/requests_test.go b/openstack/placement/v1/resourceproviders/testing/requests_test.go index 6e6ac3c777..1336126ecb 100644 --- a/openstack/placement/v1/resourceproviders/testing/requests_test.go +++ b/openstack/placement/v1/resourceproviders/testing/requests_test.go @@ -12,13 +12,13 @@ import ( ) func TestListResourceProviders(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleResourceProviderList(t) + HandleResourceProviderList(t, fakeServer) count := 0 - err := resourceproviders.List(client.ServiceClient(), resourceproviders.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := resourceproviders.List(client.ServiceClient(fakeServer), resourceproviders.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := resourceproviders.ExtractResourceProviders(page) @@ -39,10 +39,10 @@ func TestListResourceProviders(t *testing.T) { } func TestCreateResourceProvider(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleResourceProviderCreate(t) + HandleResourceProviderCreate(t, fakeServer) expected := ExpectedResourceProvider1 @@ -52,41 +52,41 @@ func TestCreateResourceProvider(t *testing.T) { ParentProviderUUID: ExpectedResourceProvider1.ParentProviderUUID, } - actual, err := resourceproviders.Create(context.TODO(), client.ServiceClient(), opts).Extract() + actual, err := resourceproviders.Create(context.TODO(), client.ServiceClient(fakeServer), opts).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, &expected, actual) } func TestGetResourceProvider(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleResourceProviderGet(t) + HandleResourceProviderGet(t, fakeServer) expected := ExpectedResourceProvider1 - actual, err := resourceproviders.Get(context.TODO(), client.ServiceClient(), ExpectedResourceProvider1.UUID).Extract() + actual, err := resourceproviders.Get(context.TODO(), client.ServiceClient(fakeServer), ExpectedResourceProvider1.UUID).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, &expected, actual) } func TestDeleteResourceProvider(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleResourceProviderDelete(t) + HandleResourceProviderDelete(t, fakeServer) - res := resourceproviders.Delete(context.TODO(), client.ServiceClient(), "b99b3ab4-3aa6-4fba-b827-69b88b9c544a") + res := resourceproviders.Delete(context.TODO(), client.ServiceClient(fakeServer), "b99b3ab4-3aa6-4fba-b827-69b88b9c544a") th.AssertNoErr(t, res.Err) } func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleResourceProviderUpdate(t) + HandleResourceProviderUpdate(t, fakeServer) name := "new_name" parentProviderUUID := "b99b3ab4-3aa6-4fba-b827-69b88b9c544a" @@ -95,7 +95,7 @@ func TestUpdate(t *testing.T) { Name: &name, ParentProviderUUID: &parentProviderUUID, } - rp, err := resourceproviders.Update(context.TODO(), client.ServiceClient(), "4e8e5957-649f-477b-9e5b-f1f75b21c03c", options).Extract() + rp, err := resourceproviders.Update(context.TODO(), client.ServiceClient(fakeServer), "4e8e5957-649f-477b-9e5b-f1f75b21c03c", options).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, rp.Name, name) @@ -103,45 +103,45 @@ func TestUpdate(t *testing.T) { } func TestGetResourceProvidersUsages(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleResourceProviderGetUsages(t) + HandleResourceProviderGetUsages(t, fakeServer) - actual, err := resourceproviders.GetUsages(context.TODO(), client.ServiceClient(), ResourceProviderTestID).Extract() + actual, err := resourceproviders.GetUsages(context.TODO(), client.ServiceClient(fakeServer), ResourceProviderTestID).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, ExpectedUsages, *actual) } func TestGetResourceProvidersInventories(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleResourceProviderGetInventories(t) + HandleResourceProviderGetInventories(t, fakeServer) - actual, err := resourceproviders.GetInventories(context.TODO(), client.ServiceClient(), ResourceProviderTestID).Extract() + actual, err := resourceproviders.GetInventories(context.TODO(), client.ServiceClient(fakeServer), ResourceProviderTestID).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, ExpectedInventories, *actual) } func TestGetResourceProvidersAllocations(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleResourceProviderGetAllocations(t) + HandleResourceProviderGetAllocations(t, fakeServer) - actual, err := resourceproviders.GetAllocations(context.TODO(), client.ServiceClient(), ResourceProviderTestID).Extract() + actual, err := resourceproviders.GetAllocations(context.TODO(), client.ServiceClient(fakeServer), ResourceProviderTestID).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, ExpectedAllocations, *actual) } func TestGetResourceProvidersTraits(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - HandleResourceProviderGetTraits(t) + HandleResourceProviderGetTraits(t, fakeServer) - actual, err := resourceproviders.GetTraits(context.TODO(), client.ServiceClient(), ResourceProviderTestID).Extract() + actual, err := resourceproviders.GetTraits(context.TODO(), client.ServiceClient(fakeServer), ResourceProviderTestID).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, ExpectedTraits, *actual) } diff --git a/openstack/sharedfilesystems/apiversions/testing/fixtures_test.go b/openstack/sharedfilesystems/apiversions/testing/fixtures_test.go index 37826cab70..ed60efd6f3 100644 --- a/openstack/sharedfilesystems/apiversions/testing/fixtures_test.go +++ b/openstack/sharedfilesystems/apiversions/testing/fixtures_test.go @@ -178,8 +178,8 @@ var ManilaAllAPIVersionResults = []apiversions.APIVersion{ ManilaAPIVersion2Result, } -func MockListResponse(t *testing.T) { - th.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { +func MockListResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -190,8 +190,8 @@ func MockListResponse(t *testing.T) { }) } -func MockGetResponse(t *testing.T) { - th.Mux.HandleFunc("/v2/", func(w http.ResponseWriter, r *http.Request) { +func MockGetResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2/", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -202,8 +202,8 @@ func MockGetResponse(t *testing.T) { }) } -func MockGetNoResponse(t *testing.T) { - th.Mux.HandleFunc("/v2/", func(w http.ResponseWriter, r *http.Request) { +func MockGetNoResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2/", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -214,8 +214,8 @@ func MockGetNoResponse(t *testing.T) { }) } -func MockGetMultipleResponses(t *testing.T) { - th.Mux.HandleFunc("/v2/", func(w http.ResponseWriter, r *http.Request) { +func MockGetMultipleResponses(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2/", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/sharedfilesystems/apiversions/testing/requests_test.go b/openstack/sharedfilesystems/apiversions/testing/requests_test.go index 1e09f7daac..ab2d2a184f 100644 --- a/openstack/sharedfilesystems/apiversions/testing/requests_test.go +++ b/openstack/sharedfilesystems/apiversions/testing/requests_test.go @@ -10,12 +10,12 @@ import ( ) func TestListAPIVersions(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockListResponse(t) + MockListResponse(t, fakeServer) - allVersions, err := apiversions.List(client.ServiceClient()).AllPages(context.TODO()) + allVersions, err := apiversions.List(client.ServiceClient(fakeServer)).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := apiversions.ExtractAPIVersions(allVersions) @@ -25,33 +25,33 @@ func TestListAPIVersions(t *testing.T) { } func TestGetAPIVersion(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockGetResponse(t) + MockGetResponse(t, fakeServer) - actual, err := apiversions.Get(context.TODO(), client.ServiceClient(), "v2").Extract() + actual, err := apiversions.Get(context.TODO(), client.ServiceClient(fakeServer), "v2").Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, ManilaAPIVersion2Result, *actual) } func TestGetNoAPIVersion(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockGetNoResponse(t) + MockGetNoResponse(t, fakeServer) - _, err := apiversions.Get(context.TODO(), client.ServiceClient(), "v2").Extract() + _, err := apiversions.Get(context.TODO(), client.ServiceClient(fakeServer), "v2").Extract() th.AssertEquals(t, err.Error(), "Unable to find requested API version") } func TestGetMultipleAPIVersion(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockGetMultipleResponses(t) + MockGetMultipleResponses(t, fakeServer) - _, err := apiversions.Get(context.TODO(), client.ServiceClient(), "v2").Extract() + _, err := apiversions.Get(context.TODO(), client.ServiceClient(fakeServer), "v2").Extract() th.AssertEquals(t, err.Error(), "Found 2 API versions") } diff --git a/openstack/sharedfilesystems/v2/availabilityzones/testing/fixtures_test.go b/openstack/sharedfilesystems/v2/availabilityzones/testing/fixtures_test.go index 3097260664..5523f8a025 100644 --- a/openstack/sharedfilesystems/v2/availabilityzones/testing/fixtures_test.go +++ b/openstack/sharedfilesystems/v2/availabilityzones/testing/fixtures_test.go @@ -9,8 +9,8 @@ import ( "github.com/gophercloud/gophercloud/v2/testhelper/client" ) -func MockListResponse(t *testing.T) { - th.Mux.HandleFunc("/os-availability-zone", func(w http.ResponseWriter, r *http.Request) { +func MockListResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/os-availability-zone", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/sharedfilesystems/v2/availabilityzones/testing/requests_test.go b/openstack/sharedfilesystems/v2/availabilityzones/testing/requests_test.go index 8d69781c3d..e487b21e28 100644 --- a/openstack/sharedfilesystems/v2/availabilityzones/testing/requests_test.go +++ b/openstack/sharedfilesystems/v2/availabilityzones/testing/requests_test.go @@ -12,12 +12,12 @@ import ( // Verifies that availability zones can be listed correctly func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockListResponse(t) + MockListResponse(t, fakeServer) - allPages, err := availabilityzones.List(client.ServiceClient()).AllPages(context.TODO()) + allPages, err := availabilityzones.List(client.ServiceClient(fakeServer)).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := availabilityzones.ExtractAvailabilityZones(allPages) th.AssertNoErr(t, err) diff --git a/openstack/sharedfilesystems/v2/errors/testing/fixtures_test.go b/openstack/sharedfilesystems/v2/errors/testing/fixtures_test.go index 88a091f30d..5d70a12829 100644 --- a/openstack/sharedfilesystems/v2/errors/testing/fixtures_test.go +++ b/openstack/sharedfilesystems/v2/errors/testing/fixtures_test.go @@ -28,8 +28,8 @@ var createResponse = `{ }` // MockCreateResponse creates a mock response -func MockCreateResponse(t *testing.T) { - th.Mux.HandleFunc(shareEndpoint, func(w http.ResponseWriter, r *http.Request) { +func MockCreateResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc(shareEndpoint, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") diff --git a/openstack/sharedfilesystems/v2/errors/testing/request_test.go b/openstack/sharedfilesystems/v2/errors/testing/request_test.go index f405721d7f..cc3d987348 100644 --- a/openstack/sharedfilesystems/v2/errors/testing/request_test.go +++ b/openstack/sharedfilesystems/v2/errors/testing/request_test.go @@ -11,13 +11,13 @@ import ( ) func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockCreateResponse(t) + MockCreateResponse(t, fakeServer) options := &shares.CreateOpts{Size: 1, Name: "my_test_share", ShareProto: "NFS", SnapshotID: "70bfbebc-d3ff-4528-8bbb-58422daa280b"} - _, err := shares.Create(context.TODO(), client.ServiceClient(), options).Extract() + _, err := shares.Create(context.TODO(), client.ServiceClient(fakeServer), options).Extract() if err == nil { t.Fatal("Expected error") diff --git a/openstack/sharedfilesystems/v2/messages/testing/fixtures_test.go b/openstack/sharedfilesystems/v2/messages/testing/fixtures_test.go index 72e2cbd77d..8b1f1fa024 100644 --- a/openstack/sharedfilesystems/v2/messages/testing/fixtures_test.go +++ b/openstack/sharedfilesystems/v2/messages/testing/fixtures_test.go @@ -9,16 +9,16 @@ import ( "github.com/gophercloud/gophercloud/v2/testhelper/client" ) -func MockDeleteResponse(t *testing.T) { - th.Mux.HandleFunc("/messages/messageID", func(w http.ResponseWriter, r *http.Request) { +func MockDeleteResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/messages/messageID", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusAccepted) }) } -func MockListResponse(t *testing.T) { - th.Mux.HandleFunc("/messages", func(w http.ResponseWriter, r *http.Request) { +func MockListResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/messages", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -59,8 +59,8 @@ func MockListResponse(t *testing.T) { }) } -func MockFilteredListResponse(t *testing.T) { - th.Mux.HandleFunc("/messages", func(w http.ResponseWriter, r *http.Request) { +func MockFilteredListResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/messages", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -88,8 +88,8 @@ func MockFilteredListResponse(t *testing.T) { }) } -func MockGetResponse(t *testing.T) { - th.Mux.HandleFunc("/messages/2076373e-13a7-4b84-9e67-15ce8cceaff8", func(w http.ResponseWriter, r *http.Request) { +func MockGetResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/messages/2076373e-13a7-4b84-9e67-15ce8cceaff8", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/sharedfilesystems/v2/messages/testing/requests_test.go b/openstack/sharedfilesystems/v2/messages/testing/requests_test.go index 75b0b57dc3..1206d090c3 100644 --- a/openstack/sharedfilesystems/v2/messages/testing/requests_test.go +++ b/openstack/sharedfilesystems/v2/messages/testing/requests_test.go @@ -12,23 +12,23 @@ import ( // Verifies that message deletion works func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockDeleteResponse(t) + MockDeleteResponse(t, fakeServer) - res := messages.Delete(context.TODO(), client.ServiceClient(), "messageID") + res := messages.Delete(context.TODO(), client.ServiceClient(fakeServer), "messageID") th.AssertNoErr(t, res.Err) } // Verifies that messages can be listed correctly func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockListResponse(t) + MockListResponse(t, fakeServer) - allPages, err := messages.List(client.ServiceClient(), &messages.ListOpts{}).AllPages(context.TODO()) + allPages, err := messages.List(client.ServiceClient(fakeServer), &messages.ListOpts{}).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := messages.ExtractMessages(allPages) th.AssertNoErr(t, err) @@ -66,16 +66,16 @@ func TestList(t *testing.T) { // Verifies that messages list can be called with query parameters func TestFilteredList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockFilteredListResponse(t) + MockFilteredListResponse(t, fakeServer) options := &messages.ListOpts{ RequestID: "req-21767eee-22ca-40a4-b6c0-ae7d35cd434f", } - allPages, err := messages.List(client.ServiceClient(), options).AllPages(context.TODO()) + allPages, err := messages.List(client.ServiceClient(fakeServer), options).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := messages.ExtractMessages(allPages) th.AssertNoErr(t, err) @@ -100,10 +100,10 @@ func TestFilteredList(t *testing.T) { // Verifies that it is possible to get a message func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockGetResponse(t) + MockGetResponse(t, fakeServer) expected := messages.Message{ ResourceID: "4336d74f-3bdc-4f27-9657-c01ec63680bf", @@ -119,7 +119,7 @@ func TestGet(t *testing.T) { ActionID: "002", } - n, err := messages.Get(context.TODO(), client.ServiceClient(), "2076373e-13a7-4b84-9e67-15ce8cceaff8").Extract() + n, err := messages.Get(context.TODO(), client.ServiceClient(fakeServer), "2076373e-13a7-4b84-9e67-15ce8cceaff8").Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, &expected, n) diff --git a/openstack/sharedfilesystems/v2/replicas/testing/fixtures_test.go b/openstack/sharedfilesystems/v2/replicas/testing/fixtures_test.go index c62f2c1725..5e14cb28d4 100644 --- a/openstack/sharedfilesystems/v2/replicas/testing/fixtures_test.go +++ b/openstack/sharedfilesystems/v2/replicas/testing/fixtures_test.go @@ -38,8 +38,8 @@ var createResponse = `{ ` // MockCreateResponse creates a mock response -func MockCreateResponse(t *testing.T) { - th.Mux.HandleFunc(shareEndpoint, func(w http.ResponseWriter, r *http.Request) { +func MockCreateResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc(shareEndpoint, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -53,8 +53,8 @@ func MockCreateResponse(t *testing.T) { } // MockDeleteResponse creates a mock delete response -func MockDeleteResponse(t *testing.T) { - th.Mux.HandleFunc(shareEndpoint+"/"+replicaID, func(w http.ResponseWriter, r *http.Request) { +func MockDeleteResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc(shareEndpoint+"/"+replicaID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "X-OpenStack-Manila-API-Version", "2.11") @@ -69,8 +69,8 @@ var promoteRequest = `{ } ` -func MockPromoteResponse(t *testing.T) { - th.Mux.HandleFunc(shareEndpoint+"/"+replicaID+"/action", func(w http.ResponseWriter, r *http.Request) { +func MockPromoteResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc(shareEndpoint+"/"+replicaID+"/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -86,8 +86,8 @@ var resyncRequest = `{ } ` -func MockResyncResponse(t *testing.T) { - th.Mux.HandleFunc(shareEndpoint+"/"+replicaID+"/action", func(w http.ResponseWriter, r *http.Request) { +func MockResyncResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc(shareEndpoint+"/"+replicaID+"/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -105,8 +105,8 @@ var resetStatusRequest = `{ } ` -func MockResetStatusResponse(t *testing.T) { - th.Mux.HandleFunc(shareEndpoint+"/"+replicaID+"/action", func(w http.ResponseWriter, r *http.Request) { +func MockResetStatusResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc(shareEndpoint+"/"+replicaID+"/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -124,8 +124,8 @@ var resetStateRequest = `{ } ` -func MockResetStateResponse(t *testing.T) { - th.Mux.HandleFunc(shareEndpoint+"/"+replicaID+"/action", func(w http.ResponseWriter, r *http.Request) { +func MockResetStateResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc(shareEndpoint+"/"+replicaID+"/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -141,8 +141,8 @@ var deleteRequest = `{ } ` -func MockForceDeleteResponse(t *testing.T) { - th.Mux.HandleFunc(shareEndpoint+"/"+replicaID+"/action", func(w http.ResponseWriter, r *http.Request) { +func MockForceDeleteResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc(shareEndpoint+"/"+replicaID+"/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -169,8 +169,8 @@ var getResponse = `{ ` // MockGetResponse creates a mock get response -func MockGetResponse(t *testing.T) { - th.Mux.HandleFunc(shareEndpoint+"/"+replicaID, func(w http.ResponseWriter, r *http.Request) { +func MockGetResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc(shareEndpoint+"/"+replicaID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "X-OpenStack-Manila-API-Version", "2.11") @@ -206,8 +206,8 @@ var listResponse = `{ var listEmptyResponse = `{"share_replicas": []}` // MockListResponse creates a mock detailed-list response -func MockListResponse(t *testing.T) { - th.Mux.HandleFunc(shareEndpoint, func(w http.ResponseWriter, r *http.Request) { +func MockListResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc(shareEndpoint, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "X-OpenStack-Manila-API-Version", "2.11") @@ -275,8 +275,8 @@ var listDetailResponse = `{ var listDetailEmptyResponse = `{"share_replicas": []}` // MockListDetailResponse creates a mock detailed-list response -func MockListDetailResponse(t *testing.T) { - th.Mux.HandleFunc(shareEndpoint+"/detail", func(w http.ResponseWriter, r *http.Request) { +func MockListDetailResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc(shareEndpoint+"/detail", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "X-OpenStack-Manila-API-Version", "2.11") @@ -323,8 +323,8 @@ var listExportLocationsResponse = `{ ` // MockListExportLocationsResponse creates a mock get export locations response -func MockListExportLocationsResponse(t *testing.T) { - th.Mux.HandleFunc(shareEndpoint+"/"+replicaID+"/export-locations", func(w http.ResponseWriter, r *http.Request) { +func MockListExportLocationsResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc(shareEndpoint+"/"+replicaID+"/export-locations", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") @@ -348,8 +348,8 @@ var getExportLocationResponse = `{ ` // MockGetExportLocationResponse creates a mock get export location response -func MockGetExportLocationResponse(t *testing.T) { - th.Mux.HandleFunc(shareEndpoint+"/"+replicaID+"/export-locations/ae73e762-e8b9-4aad-aad3-23afb7cd6825", func(w http.ResponseWriter, r *http.Request) { +func MockGetExportLocationResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc(shareEndpoint+"/"+replicaID+"/export-locations/ae73e762-e8b9-4aad-aad3-23afb7cd6825", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") diff --git a/openstack/sharedfilesystems/v2/replicas/testing/request_test.go b/openstack/sharedfilesystems/v2/replicas/testing/request_test.go index 167bc2c879..f083ad664d 100644 --- a/openstack/sharedfilesystems/v2/replicas/testing/request_test.go +++ b/openstack/sharedfilesystems/v2/replicas/testing/request_test.go @@ -11,24 +11,24 @@ import ( "github.com/gophercloud/gophercloud/v2/testhelper/client" ) -func getClient(microVersion string) *gophercloud.ServiceClient { - c := client.ServiceClient() +func getClient(fakeServer th.FakeServer, microVersion string) *gophercloud.ServiceClient { + c := client.ServiceClient(fakeServer) c.Type = "sharev2" c.Microversion = microVersion return c } func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockCreateResponse(t) + MockCreateResponse(t, fakeServer) options := &replicas.CreateOpts{ ShareID: "65a34695-f9e5-4eea-b48d-a0b261d82943", AvailabilityZone: "zone-1", } - actual, err := replicas.Create(context.TODO(), getClient("2.11"), options).Extract() + actual, err := replicas.Create(context.TODO(), getClient(fakeServer, "2.11"), options).Extract() expected := &replicas.Replica{ ID: "3b9c33e8-b136-45c6-84a6-019c8db1d550", @@ -44,32 +44,32 @@ func TestCreate(t *testing.T) { } func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockDeleteResponse(t) + MockDeleteResponse(t, fakeServer) - result := replicas.Delete(context.TODO(), getClient("2.11"), replicaID) + result := replicas.Delete(context.TODO(), getClient(fakeServer, "2.11"), replicaID) th.AssertNoErr(t, result.Err) } func TestForceDeleteSuccess(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockForceDeleteResponse(t) + MockForceDeleteResponse(t, fakeServer) - err := replicas.ForceDelete(context.TODO(), getClient("2.11"), replicaID).ExtractErr() + err := replicas.ForceDelete(context.TODO(), getClient(fakeServer, "2.11"), replicaID).ExtractErr() th.AssertNoErr(t, err) } func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockGetResponse(t) + MockGetResponse(t, fakeServer) - actual, err := replicas.Get(context.TODO(), getClient("2.11"), replicaID).Extract() + actual, err := replicas.Get(context.TODO(), getClient(fakeServer, "2.11"), replicaID).Extract() expected := &replicas.Replica{ AvailabilityZone: "zone-1", @@ -88,15 +88,15 @@ func TestGet(t *testing.T) { } func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockListResponse(t) + MockListResponse(t, fakeServer) listOpts := &replicas.ListOpts{ ShareID: "65a34695-f9e5-4eea-b48d-a0b261d82943", } - allPages, err := replicas.List(getClient("2.11"), listOpts).AllPages(context.TODO()) + allPages, err := replicas.List(getClient(fakeServer, "2.11"), listOpts).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := replicas.ExtractReplicas(allPages) @@ -127,15 +127,15 @@ func TestList(t *testing.T) { } func TestListDetail(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockListDetailResponse(t) + MockListDetailResponse(t, fakeServer) listOpts := &replicas.ListOpts{ ShareID: "65a34695-f9e5-4eea-b48d-a0b261d82943", } - allPages, err := replicas.ListDetail(getClient("2.11"), listOpts).AllPages(context.TODO()) + allPages, err := replicas.ListDetail(getClient(fakeServer, "2.11"), listOpts).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := replicas.ExtractReplicas(allPages) @@ -181,12 +181,12 @@ func TestListDetail(t *testing.T) { } func TestListExportLocationsSuccess(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockListExportLocationsResponse(t) + MockListExportLocationsResponse(t, fakeServer) - actual, err := replicas.ListExportLocations(context.TODO(), getClient("2.47"), replicaID).Extract() + actual, err := replicas.ListExportLocations(context.TODO(), getClient(fakeServer, "2.47"), replicaID).Extract() expected := []replicas.ExportLocation{ { @@ -210,12 +210,12 @@ func TestListExportLocationsSuccess(t *testing.T) { } func TestGetExportLocationSuccess(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockGetExportLocationResponse(t) + MockGetExportLocationResponse(t, fakeServer) - s, err := replicas.GetExportLocation(context.TODO(), getClient("2.47"), replicaID, "ae73e762-e8b9-4aad-aad3-23afb7cd6825").Extract() + s, err := replicas.GetExportLocation(context.TODO(), getClient(fakeServer, "2.47"), replicaID, "ae73e762-e8b9-4aad-aad3-23afb7cd6825").Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, s, &replicas.ExportLocation{ @@ -230,41 +230,41 @@ func TestGetExportLocationSuccess(t *testing.T) { } func TestResetStatusSuccess(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockResetStatusResponse(t) + MockResetStatusResponse(t, fakeServer) - err := replicas.ResetStatus(context.TODO(), getClient("2.11"), replicaID, &replicas.ResetStatusOpts{Status: "available"}).ExtractErr() + err := replicas.ResetStatus(context.TODO(), getClient(fakeServer, "2.11"), replicaID, &replicas.ResetStatusOpts{Status: "available"}).ExtractErr() th.AssertNoErr(t, err) } func TestResetStateSuccess(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockResetStateResponse(t) + MockResetStateResponse(t, fakeServer) - err := replicas.ResetState(context.TODO(), getClient("2.11"), replicaID, &replicas.ResetStateOpts{State: "active"}).ExtractErr() + err := replicas.ResetState(context.TODO(), getClient(fakeServer, "2.11"), replicaID, &replicas.ResetStateOpts{State: "active"}).ExtractErr() th.AssertNoErr(t, err) } func TestResyncSuccess(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockResyncResponse(t) + MockResyncResponse(t, fakeServer) - err := replicas.Resync(context.TODO(), getClient("2.11"), replicaID).ExtractErr() + err := replicas.Resync(context.TODO(), getClient(fakeServer, "2.11"), replicaID).ExtractErr() th.AssertNoErr(t, err) } func TestPromoteSuccess(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockPromoteResponse(t) + MockPromoteResponse(t, fakeServer) - err := replicas.Promote(context.TODO(), getClient("2.11"), replicaID, &replicas.PromoteOpts{QuiesceWaitTime: 30}).ExtractErr() + err := replicas.Promote(context.TODO(), getClient(fakeServer, "2.11"), replicaID, &replicas.PromoteOpts{QuiesceWaitTime: 30}).ExtractErr() th.AssertNoErr(t, err) } diff --git a/openstack/sharedfilesystems/v2/schedulerstats/testing/fixtures_test.go b/openstack/sharedfilesystems/v2/schedulerstats/testing/fixtures_test.go index fdd861d9c8..ed4b325da4 100644 --- a/openstack/sharedfilesystems/v2/schedulerstats/testing/fixtures_test.go +++ b/openstack/sharedfilesystems/v2/schedulerstats/testing/fixtures_test.go @@ -264,8 +264,8 @@ var ( } ) -func HandlePoolsListSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/scheduler-stats/pools", func(w http.ResponseWriter, r *http.Request) { +func HandlePoolsListSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/scheduler-stats/pools", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -277,7 +277,7 @@ func HandlePoolsListSuccessfully(t *testing.T) { fmt.Fprint(w, PoolsListBody) }) - th.Mux.HandleFunc("/scheduler-stats/pools/detail", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/scheduler-stats/pools/detail", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/sharedfilesystems/v2/schedulerstats/testing/requests_test.go b/openstack/sharedfilesystems/v2/schedulerstats/testing/requests_test.go index d6b826ed74..057f4458ab 100644 --- a/openstack/sharedfilesystems/v2/schedulerstats/testing/requests_test.go +++ b/openstack/sharedfilesystems/v2/schedulerstats/testing/requests_test.go @@ -11,12 +11,12 @@ import ( ) func TestListPoolsDetail(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandlePoolsListSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandlePoolsListSuccessfully(t, fakeServer) pages := 0 - err := schedulerstats.List(client.ServiceClient(), schedulerstats.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := schedulerstats.List(client.ServiceClient(fakeServer), schedulerstats.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := schedulerstats.ExtractPools(page) @@ -40,7 +40,7 @@ func TestListPoolsDetail(t *testing.T) { } pages = 0 - err = schedulerstats.ListDetail(client.ServiceClient(), schedulerstats.ListDetailOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err = schedulerstats.ListDetail(client.ServiceClient(fakeServer), schedulerstats.ListDetailOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := schedulerstats.ExtractPools(page) diff --git a/openstack/sharedfilesystems/v2/securityservices/testing/fixtures_test.go b/openstack/sharedfilesystems/v2/securityservices/testing/fixtures_test.go index 243a6a4b45..1cd713922a 100644 --- a/openstack/sharedfilesystems/v2/securityservices/testing/fixtures_test.go +++ b/openstack/sharedfilesystems/v2/securityservices/testing/fixtures_test.go @@ -9,8 +9,8 @@ import ( "github.com/gophercloud/gophercloud/v2/testhelper/client" ) -func MockCreateResponse(t *testing.T) { - th.Mux.HandleFunc("/security-services", func(w http.ResponseWriter, r *http.Request) { +func MockCreateResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/security-services", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -51,16 +51,16 @@ func MockCreateResponse(t *testing.T) { }) } -func MockDeleteResponse(t *testing.T) { - th.Mux.HandleFunc("/security-services/securityServiceID", func(w http.ResponseWriter, r *http.Request) { +func MockDeleteResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/security-services/securityServiceID", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusAccepted) }) } -func MockListResponse(t *testing.T) { - th.Mux.HandleFunc("/security-services/detail", func(w http.ResponseWriter, r *http.Request) { +func MockListResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/security-services/detail", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -105,8 +105,8 @@ func MockListResponse(t *testing.T) { }) } -func MockFilteredListResponse(t *testing.T) { - th.Mux.HandleFunc("/security-services/detail", func(w http.ResponseWriter, r *http.Request) { +func MockFilteredListResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/security-services/detail", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -136,8 +136,8 @@ func MockFilteredListResponse(t *testing.T) { }) } -func MockGetResponse(t *testing.T) { - th.Mux.HandleFunc("/security-services/3c829734-0679-4c17-9637-801da48c0d5f", func(w http.ResponseWriter, r *http.Request) { +func MockGetResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/security-services/3c829734-0679-4c17-9637-801da48c0d5f", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -164,8 +164,8 @@ func MockGetResponse(t *testing.T) { }) } -func MockUpdateResponse(t *testing.T) { - th.Mux.HandleFunc("/security-services/securityServiceID", func(w http.ResponseWriter, r *http.Request) { +func MockUpdateResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/security-services/securityServiceID", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusOK) diff --git a/openstack/sharedfilesystems/v2/securityservices/testing/requests_test.go b/openstack/sharedfilesystems/v2/securityservices/testing/requests_test.go index c4cf972827..39232ad7ae 100644 --- a/openstack/sharedfilesystems/v2/securityservices/testing/requests_test.go +++ b/openstack/sharedfilesystems/v2/securityservices/testing/requests_test.go @@ -13,10 +13,10 @@ import ( // Verifies that a security service can be created correctly func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockCreateResponse(t) + MockCreateResponse(t, fakeServer) options := &securityservices.CreateOpts{ Name: "SecServ1", @@ -27,7 +27,7 @@ func TestCreate(t *testing.T) { Type: "kerberos", } - s, err := securityservices.Create(context.TODO(), client.ServiceClient(), options).Extract() + s, err := securityservices.Create(context.TODO(), client.ServiceClient(fakeServer), options).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, s.Name, "SecServ1") @@ -40,8 +40,8 @@ func TestCreate(t *testing.T) { // Verifies that a security service cannot be created without a type func TestRequiredCreateOpts(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() options := &securityservices.CreateOpts{ Name: "SecServ1", @@ -51,7 +51,7 @@ func TestRequiredCreateOpts(t *testing.T) { Password: "***", } - _, err := securityservices.Create(context.TODO(), client.ServiceClient(), options).Extract() + _, err := securityservices.Create(context.TODO(), client.ServiceClient(fakeServer), options).Extract() if _, ok := err.(gophercloud.ErrMissingInput); !ok { t.Fatal("ErrMissingInput was expected to occur") } @@ -59,23 +59,23 @@ func TestRequiredCreateOpts(t *testing.T) { // Verifies that security service deletion works func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockDeleteResponse(t) + MockDeleteResponse(t, fakeServer) - res := securityservices.Delete(context.TODO(), client.ServiceClient(), "securityServiceID") + res := securityservices.Delete(context.TODO(), client.ServiceClient(fakeServer), "securityServiceID") th.AssertNoErr(t, res.Err) } // Verifies that security services can be listed correctly func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockListResponse(t) + MockListResponse(t, fakeServer) - allPages, err := securityservices.List(client.ServiceClient(), &securityservices.ListOpts{}).AllPages(context.TODO()) + allPages, err := securityservices.List(client.ServiceClient(fakeServer), &securityservices.ListOpts{}).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := securityservices.ExtractSecurityServices(allPages) th.AssertNoErr(t, err) @@ -118,16 +118,16 @@ func TestList(t *testing.T) { // Verifies that security services list can be called with query parameters func TestFilteredList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockFilteredListResponse(t) + MockFilteredListResponse(t, fakeServer) options := &securityservices.ListOpts{ Type: "kerberos", } - allPages, err := securityservices.List(client.ServiceClient(), options).AllPages(context.TODO()) + allPages, err := securityservices.List(client.ServiceClient(fakeServer), options).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := securityservices.ExtractSecurityServices(allPages) th.AssertNoErr(t, err) @@ -155,10 +155,10 @@ func TestFilteredList(t *testing.T) { // Verifies that it is possible to get a security service func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockGetResponse(t) + MockGetResponse(t, fakeServer) var nilTime time.Time expected := securityservices.SecurityService{ @@ -177,7 +177,7 @@ func TestGet(t *testing.T) { Password: "supersecret", } - n, err := securityservices.Get(context.TODO(), client.ServiceClient(), "3c829734-0679-4c17-9637-801da48c0d5f").Extract() + n, err := securityservices.Get(context.TODO(), client.ServiceClient(fakeServer), "3c829734-0679-4c17-9637-801da48c0d5f").Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, &expected, n) @@ -185,10 +185,10 @@ func TestGet(t *testing.T) { // Verifies that it is possible to update a security service func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockUpdateResponse(t) + MockUpdateResponse(t, fakeServer) expected := securityservices.SecurityService{ ID: "securityServiceID", Name: "SecServ2", @@ -207,7 +207,7 @@ func TestUpdate(t *testing.T) { name := "SecServ2" options := securityservices.UpdateOpts{Name: &name} - s, err := securityservices.Update(context.TODO(), client.ServiceClient(), "securityServiceID", options).Extract() + s, err := securityservices.Update(context.TODO(), client.ServiceClient(fakeServer), "securityServiceID", options).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, &expected, s) } diff --git a/openstack/sharedfilesystems/v2/services/testing/fixtures_test.go b/openstack/sharedfilesystems/v2/services/testing/fixtures_test.go index 9916b033fc..1c8bd7a57f 100644 --- a/openstack/sharedfilesystems/v2/services/testing/fixtures_test.go +++ b/openstack/sharedfilesystems/v2/services/testing/fixtures_test.go @@ -60,8 +60,8 @@ var SecondFakeService = services.Service{ } // HandleListSuccessfully configures the test server to respond to a List request. -func HandleListSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/services", func(w http.ResponseWriter, r *http.Request) { +func HandleListSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/services", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/openstack/sharedfilesystems/v2/services/testing/requests_test.go b/openstack/sharedfilesystems/v2/services/testing/requests_test.go index d4845ca09e..af5e657b46 100644 --- a/openstack/sharedfilesystems/v2/services/testing/requests_test.go +++ b/openstack/sharedfilesystems/v2/services/testing/requests_test.go @@ -11,12 +11,12 @@ import ( ) func TestListServices(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListSuccessfully(t, fakeServer) pages := 0 - err := services.List(client.ServiceClient(), services.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := services.List(client.ServiceClient(fakeServer), services.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := services.ExtractServices(page) diff --git a/openstack/sharedfilesystems/v2/shareaccessrules/testing/fixtures_test.go b/openstack/sharedfilesystems/v2/shareaccessrules/testing/fixtures_test.go index 49948ec59f..eb5a90a20b 100644 --- a/openstack/sharedfilesystems/v2/shareaccessrules/testing/fixtures_test.go +++ b/openstack/sharedfilesystems/v2/shareaccessrules/testing/fixtures_test.go @@ -33,8 +33,8 @@ var getResponse = `{ } }` -func MockGetResponse(t *testing.T) { - th.Mux.HandleFunc(shareAccessRulesEndpoint+"/"+shareAccessRuleID, func(w http.ResponseWriter, r *http.Request) { +func MockGetResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc(shareAccessRulesEndpoint+"/"+shareAccessRuleID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") diff --git a/openstack/sharedfilesystems/v2/shareaccessrules/testing/requests_test.go b/openstack/sharedfilesystems/v2/shareaccessrules/testing/requests_test.go index c5e3961cfd..d0600a183b 100644 --- a/openstack/sharedfilesystems/v2/shareaccessrules/testing/requests_test.go +++ b/openstack/sharedfilesystems/v2/shareaccessrules/testing/requests_test.go @@ -13,12 +13,12 @@ import ( ) func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockGetResponse(t) + MockGetResponse(t, fakeServer) - resp := shareaccessrules.Get(context.TODO(), client.ServiceClient(), "507bf114-36f2-4f56-8cf4-857985ca87c1") + resp := shareaccessrules.Get(context.TODO(), client.ServiceClient(fakeServer), "507bf114-36f2-4f56-8cf4-857985ca87c1") th.AssertNoErr(t, resp.Err) accessRule, err := resp.Extract() @@ -41,8 +41,8 @@ func TestGet(t *testing.T) { }, accessRule) } -func MockListResponse(t *testing.T) { - th.Mux.HandleFunc(shareAccessRulesEndpoint, func(w http.ResponseWriter, r *http.Request) { +func MockListResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc(shareAccessRulesEndpoint, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") diff --git a/openstack/sharedfilesystems/v2/sharenetworks/testing/fixtures_test.go b/openstack/sharedfilesystems/v2/sharenetworks/testing/fixtures_test.go index 8c217f4b0a..5dc89b8826 100644 --- a/openstack/sharedfilesystems/v2/sharenetworks/testing/fixtures_test.go +++ b/openstack/sharedfilesystems/v2/sharenetworks/testing/fixtures_test.go @@ -41,8 +41,8 @@ func createResp(name, description, network, subnetwork string) string { }`, name, description, network, subnetwork) } -func MockCreateResponse(t *testing.T) { - th.Mux.HandleFunc("/share-networks", func(w http.ResponseWriter, r *http.Request) { +func MockCreateResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/share-networks", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -62,16 +62,16 @@ func MockCreateResponse(t *testing.T) { }) } -func MockDeleteResponse(t *testing.T) { - th.Mux.HandleFunc("/share-networks/fa158a3d-6d9f-4187-9ca5-abbb82646eb2", func(w http.ResponseWriter, r *http.Request) { +func MockDeleteResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/share-networks/fa158a3d-6d9f-4187-9ca5-abbb82646eb2", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusAccepted) }) } -func MockListResponse(t *testing.T) { - th.Mux.HandleFunc("/share-networks/detail", func(w http.ResponseWriter, r *http.Request) { +func MockListResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/share-networks/detail", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -143,8 +143,8 @@ func MockListResponse(t *testing.T) { }) } -func MockFilteredListResponse(t *testing.T) { - th.Mux.HandleFunc("/share-networks/detail", func(w http.ResponseWriter, r *http.Request) { +func MockFilteredListResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/share-networks/detail", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -228,8 +228,8 @@ func MockFilteredListResponse(t *testing.T) { }) } -func MockGetResponse(t *testing.T) { - th.Mux.HandleFunc("/share-networks/7f950b52-6141-4a08-bbb5-bb7ffa3ea5fd", func(w http.ResponseWriter, r *http.Request) { +func MockGetResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/share-networks/7f950b52-6141-4a08-bbb5-bb7ffa3ea5fd", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -256,8 +256,8 @@ func MockGetResponse(t *testing.T) { }) } -func MockUpdateNeutronResponse(t *testing.T) { - th.Mux.HandleFunc("/share-networks/713df749-aac0-4a54-af52-10f6c991e80c", func(w http.ResponseWriter, r *http.Request) { +func MockUpdateNeutronResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/share-networks/713df749-aac0-4a54-af52-10f6c991e80c", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusOK) @@ -283,8 +283,8 @@ func MockUpdateNeutronResponse(t *testing.T) { }) } -func MockUpdateNovaResponse(t *testing.T) { - th.Mux.HandleFunc("/share-networks/713df749-aac0-4a54-af52-10f6c991e80c", func(w http.ResponseWriter, r *http.Request) { +func MockUpdateNovaResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/share-networks/713df749-aac0-4a54-af52-10f6c991e80c", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusOK) @@ -310,8 +310,8 @@ func MockUpdateNovaResponse(t *testing.T) { }) } -func MockAddSecurityServiceResponse(t *testing.T) { - th.Mux.HandleFunc("/share-networks/shareNetworkID/action", func(w http.ResponseWriter, r *http.Request) { +func MockAddSecurityServiceResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/share-networks/shareNetworkID/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusOK) @@ -336,8 +336,8 @@ func MockAddSecurityServiceResponse(t *testing.T) { }) } -func MockRemoveSecurityServiceResponse(t *testing.T) { - th.Mux.HandleFunc("/share-networks/shareNetworkID/action", func(w http.ResponseWriter, r *http.Request) { +func MockRemoveSecurityServiceResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/share-networks/shareNetworkID/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusOK) diff --git a/openstack/sharedfilesystems/v2/sharenetworks/testing/requests_test.go b/openstack/sharedfilesystems/v2/sharenetworks/testing/requests_test.go index 1cbbb6df5b..5ad5bae072 100644 --- a/openstack/sharedfilesystems/v2/sharenetworks/testing/requests_test.go +++ b/openstack/sharedfilesystems/v2/sharenetworks/testing/requests_test.go @@ -13,10 +13,10 @@ import ( // Verifies that a share network can be created correctly func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockCreateResponse(t) + MockCreateResponse(t, fakeServer) options := &sharenetworks.CreateOpts{ Name: "my_network", @@ -25,7 +25,7 @@ func TestCreate(t *testing.T) { NeutronSubnetID: "53482b62-2c84-4a53-b6ab-30d9d9800d06", } - n, err := sharenetworks.Create(context.TODO(), client.ServiceClient(), options).Extract() + n, err := sharenetworks.Create(context.TODO(), client.ServiceClient(fakeServer), options).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, n.Name, "my_network") @@ -36,23 +36,23 @@ func TestCreate(t *testing.T) { // Verifies that share network deletion works func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockDeleteResponse(t) + MockDeleteResponse(t, fakeServer) - res := sharenetworks.Delete(context.TODO(), client.ServiceClient(), "fa158a3d-6d9f-4187-9ca5-abbb82646eb2") + res := sharenetworks.Delete(context.TODO(), client.ServiceClient(fakeServer), "fa158a3d-6d9f-4187-9ca5-abbb82646eb2") th.AssertNoErr(t, res.Err) } // Verifies that share networks can be listed correctly func TestListDetail(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockListResponse(t) + MockListResponse(t, fakeServer) - allPages, err := sharenetworks.ListDetail(client.ServiceClient(), &sharenetworks.ListOpts{}).AllPages(context.TODO()) + allPages, err := sharenetworks.ListDetail(client.ServiceClient(fakeServer), &sharenetworks.ListOpts{}).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := sharenetworks.ExtractShareNetworks(allPages) @@ -112,10 +112,10 @@ func TestListDetail(t *testing.T) { // Verifies that share networks list can be called with query parameters func TestPaginatedListDetail(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockFilteredListResponse(t) + MockFilteredListResponse(t, fakeServer) options := &sharenetworks.ListOpts{ Offset: 0, @@ -124,7 +124,7 @@ func TestPaginatedListDetail(t *testing.T) { count := 0 - err := sharenetworks.ListDetail(client.ServiceClient(), options).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := sharenetworks.ListDetail(client.ServiceClient(fakeServer), options).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ _, err := sharenetworks.ExtractShareNetworks(page) if err != nil { @@ -141,10 +141,10 @@ func TestPaginatedListDetail(t *testing.T) { // Verifies that it is possible to get a share network func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockGetResponse(t) + MockGetResponse(t, fakeServer) var nilTime time.Time expected := sharenetworks.ShareNetwork{ @@ -163,7 +163,7 @@ func TestGet(t *testing.T) { ProjectID: "16e1ab15c35a457e9c2b2aa189f544e1", } - n, err := sharenetworks.Get(context.TODO(), client.ServiceClient(), "7f950b52-6141-4a08-bbb5-bb7ffa3ea5fd").Extract() + n, err := sharenetworks.Get(context.TODO(), client.ServiceClient(fakeServer), "7f950b52-6141-4a08-bbb5-bb7ffa3ea5fd").Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, &expected, n) @@ -171,10 +171,10 @@ func TestGet(t *testing.T) { // Verifies that it is possible to update a share network using neutron network func TestUpdateNeutron(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockUpdateNeutronResponse(t) + MockUpdateNeutronResponse(t, fakeServer) expected := sharenetworks.ShareNetwork{ ID: "713df749-aac0-4a54-af52-10f6c991e80c", @@ -201,17 +201,17 @@ func TestUpdateNeutron(t *testing.T) { NeutronSubnetID: "new-neutron-subnet-id", } - v, err := sharenetworks.Update(context.TODO(), client.ServiceClient(), "713df749-aac0-4a54-af52-10f6c991e80c", options).Extract() + v, err := sharenetworks.Update(context.TODO(), client.ServiceClient(fakeServer), "713df749-aac0-4a54-af52-10f6c991e80c", options).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, &expected, v) } // Verifies that it is possible to update a share network using nova network func TestUpdateNova(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockUpdateNovaResponse(t) + MockUpdateNovaResponse(t, fakeServer) expected := sharenetworks.ShareNetwork{ ID: "713df749-aac0-4a54-af52-10f6c991e80c", @@ -237,17 +237,17 @@ func TestUpdateNova(t *testing.T) { NovaNetID: "new-nova-id", } - v, err := sharenetworks.Update(context.TODO(), client.ServiceClient(), "713df749-aac0-4a54-af52-10f6c991e80c", options).Extract() + v, err := sharenetworks.Update(context.TODO(), client.ServiceClient(fakeServer), "713df749-aac0-4a54-af52-10f6c991e80c", options).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, &expected, v) } // Verifies that it is possible to add a security service to a share network func TestAddSecurityService(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockAddSecurityServiceResponse(t) + MockAddSecurityServiceResponse(t, fakeServer) var nilTime time.Time expected := sharenetworks.ShareNetwork{ @@ -267,19 +267,19 @@ func TestAddSecurityService(t *testing.T) { } options := sharenetworks.AddSecurityServiceOpts{SecurityServiceID: "securityServiceID"} - s, err := sharenetworks.AddSecurityService(context.TODO(), client.ServiceClient(), "shareNetworkID", options).Extract() + s, err := sharenetworks.AddSecurityService(context.TODO(), client.ServiceClient(fakeServer), "shareNetworkID", options).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, &expected, s) } // Verifies that it is possible to remove a security service from a share network func TestRemoveSecurityService(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockRemoveSecurityServiceResponse(t) + MockRemoveSecurityServiceResponse(t, fakeServer) options := sharenetworks.RemoveSecurityServiceOpts{SecurityServiceID: "securityServiceID"} - _, err := sharenetworks.RemoveSecurityService(context.TODO(), client.ServiceClient(), "shareNetworkID", options).Extract() + _, err := sharenetworks.RemoveSecurityService(context.TODO(), client.ServiceClient(fakeServer), "shareNetworkID", options).Extract() th.AssertNoErr(t, err) } diff --git a/openstack/sharedfilesystems/v2/shares/testing/fixtures_test.go b/openstack/sharedfilesystems/v2/shares/testing/fixtures_test.go index c27ece7a85..c7ff0d287c 100644 --- a/openstack/sharedfilesystems/v2/shares/testing/fixtures_test.go +++ b/openstack/sharedfilesystems/v2/shares/testing/fixtures_test.go @@ -75,8 +75,8 @@ var createResponse = `{ }` // MockCreateResponse creates a mock response -func MockCreateResponse(t *testing.T) { - th.Mux.HandleFunc(shareEndpoint, func(w http.ResponseWriter, r *http.Request) { +func MockCreateResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc(shareEndpoint, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -89,8 +89,8 @@ func MockCreateResponse(t *testing.T) { } // MockDeleteResponse creates a mock delete response -func MockDeleteResponse(t *testing.T) { - th.Mux.HandleFunc(shareEndpoint+"/"+shareID, func(w http.ResponseWriter, r *http.Request) { +func MockDeleteResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc(shareEndpoint+"/"+shareID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusAccepted) @@ -149,8 +149,8 @@ var updateResponse = ` } ` -func MockUpdateResponse(t *testing.T) { - th.Mux.HandleFunc(shareEndpoint+"/"+shareID, func(w http.ResponseWriter, r *http.Request) { +func MockUpdateResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc(shareEndpoint+"/"+shareID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -206,8 +206,8 @@ var getResponse = `{ }` // MockGetResponse creates a mock get response -func MockGetResponse(t *testing.T) { - th.Mux.HandleFunc(shareEndpoint+"/"+shareID, func(w http.ResponseWriter, r *http.Request) { +func MockGetResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc(shareEndpoint+"/"+shareID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusOK) @@ -263,8 +263,8 @@ var listDetailResponse = `{ var listDetailEmptyResponse = `{"shares": []}` // MockListDetailResponse creates a mock detailed-list response -func MockListDetailResponse(t *testing.T) { - th.Mux.HandleFunc(shareEndpoint+"/detail", func(w http.ResponseWriter, r *http.Request) { +func MockListDetailResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc(shareEndpoint+"/detail", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -298,8 +298,8 @@ var listExportLocationsResponse = `{ }` // MockListExportLocationsResponse creates a mock get export locations response -func MockListExportLocationsResponse(t *testing.T) { - th.Mux.HandleFunc(shareEndpoint+"/"+shareID+"/export_locations", func(w http.ResponseWriter, r *http.Request) { +func MockListExportLocationsResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc(shareEndpoint+"/"+shareID+"/export_locations", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") @@ -319,8 +319,8 @@ var getExportLocationResponse = `{ }` // MockGetExportLocationResponse creates a mock get export location response -func MockGetExportLocationResponse(t *testing.T) { - th.Mux.HandleFunc(shareEndpoint+"/"+shareID+"/export_locations/80ed63fc-83bc-4afc-b881-da4a345ac83d", func(w http.ResponseWriter, r *http.Request) { +func MockGetExportLocationResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc(shareEndpoint+"/"+shareID+"/export_locations/80ed63fc-83bc-4afc-b881-da4a345ac83d", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") @@ -350,8 +350,8 @@ var grantAccessResponse = `{ }` // MockGrantAccessResponse creates a mock grant access response -func MockGrantAccessResponse(t *testing.T) { - th.Mux.HandleFunc(shareEndpoint+"/"+shareID+"/action", func(w http.ResponseWriter, r *http.Request) { +func MockGrantAccessResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc(shareEndpoint+"/"+shareID+"/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -370,8 +370,8 @@ var revokeAccessRequest = `{ }` // MockRevokeAccessResponse creates a mock revoke access response -func MockRevokeAccessResponse(t *testing.T) { - th.Mux.HandleFunc(shareEndpoint+"/"+shareID+"/action", func(w http.ResponseWriter, r *http.Request) { +func MockRevokeAccessResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc(shareEndpoint+"/"+shareID+"/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -401,8 +401,8 @@ var listAccessRightsResponse = `{ }` // MockListAccessRightsResponse creates a mock list access response -func MockListAccessRightsResponse(t *testing.T) { - th.Mux.HandleFunc(shareEndpoint+"/"+shareID+"/action", func(w http.ResponseWriter, r *http.Request) { +func MockListAccessRightsResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc(shareEndpoint+"/"+shareID+"/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -421,8 +421,8 @@ var extendRequest = `{ }` // MockExtendResponse creates a mock extend share response -func MockExtendResponse(t *testing.T) { - th.Mux.HandleFunc(shareEndpoint+"/"+shareID+"/action", func(w http.ResponseWriter, r *http.Request) { +func MockExtendResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc(shareEndpoint+"/"+shareID+"/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -440,8 +440,8 @@ var shrinkRequest = `{ }` // MockShrinkResponse creates a mock shrink share response -func MockShrinkResponse(t *testing.T) { - th.Mux.HandleFunc(shareEndpoint+"/"+shareID+"/action", func(w http.ResponseWriter, r *http.Request) { +func MockShrinkResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc(shareEndpoint+"/"+shareID+"/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -459,8 +459,8 @@ var getMetadataResponse = `{ }` // MockGetMetadataResponse creates a mock get metadata response -func MockGetMetadataResponse(t *testing.T) { - th.Mux.HandleFunc(shareEndpoint+"/"+shareID+"/metadata", func(w http.ResponseWriter, r *http.Request) { +func MockGetMetadataResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc(shareEndpoint+"/"+shareID+"/metadata", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -477,8 +477,8 @@ var getMetadatumResponse = `{ }` // MockGetMetadatumResponse creates a mock get metadatum response -func MockGetMetadatumResponse(t *testing.T, key string) { - th.Mux.HandleFunc(shareEndpoint+"/"+shareID+"/metadata/"+key, func(w http.ResponseWriter, r *http.Request) { +func MockGetMetadatumResponse(t *testing.T, fakeServer th.FakeServer, key string) { + fakeServer.Mux.HandleFunc(shareEndpoint+"/"+shareID+"/metadata/"+key, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") @@ -501,8 +501,8 @@ var setMetadataResponse = `{ }` // MockSetMetadataResponse creates a mock set metadata response -func MockSetMetadataResponse(t *testing.T) { - th.Mux.HandleFunc(shareEndpoint+"/"+shareID+"/metadata", func(w http.ResponseWriter, r *http.Request) { +func MockSetMetadataResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc(shareEndpoint+"/"+shareID+"/metadata", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -527,8 +527,8 @@ var updateMetadataResponse = `{ }` // MockUpdateMetadataResponse creates a mock update metadata response -func MockUpdateMetadataResponse(t *testing.T) { - th.Mux.HandleFunc(shareEndpoint+"/"+shareID+"/metadata", func(w http.ResponseWriter, r *http.Request) { +func MockUpdateMetadataResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc(shareEndpoint+"/"+shareID+"/metadata", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -541,8 +541,8 @@ func MockUpdateMetadataResponse(t *testing.T) { } // MockDeleteMetadatumResponse creates a mock unset metadata response -func MockDeleteMetadatumResponse(t *testing.T, key string) { - th.Mux.HandleFunc(shareEndpoint+"/"+shareID+"/metadata/"+key, func(w http.ResponseWriter, r *http.Request) { +func MockDeleteMetadatumResponse(t *testing.T, fakeServer th.FakeServer, key string) { + fakeServer.Mux.HandleFunc(shareEndpoint+"/"+shareID+"/metadata/"+key, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusOK) @@ -556,8 +556,8 @@ var revertRequest = `{ }` // MockRevertResponse creates a mock revert share response -func MockRevertResponse(t *testing.T) { - th.Mux.HandleFunc(shareEndpoint+"/"+shareID+"/action", func(w http.ResponseWriter, r *http.Request) { +func MockRevertResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc(shareEndpoint+"/"+shareID+"/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -575,8 +575,8 @@ var resetStatusRequest = `{ }` // MockResetStatusResponse creates a mock reset status share response -func MockResetStatusResponse(t *testing.T) { - th.Mux.HandleFunc(shareEndpoint+"/"+shareID+"/action", func(w http.ResponseWriter, r *http.Request) { +func MockResetStatusResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc(shareEndpoint+"/"+shareID+"/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -592,8 +592,8 @@ var forceDeleteRequest = `{ }` // MockForceDeleteResponse creates a mock force delete share response -func MockForceDeleteResponse(t *testing.T) { - th.Mux.HandleFunc(shareEndpoint+"/"+shareID+"/action", func(w http.ResponseWriter, r *http.Request) { +func MockForceDeleteResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc(shareEndpoint+"/"+shareID+"/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -609,8 +609,8 @@ var unmanageRequest = `{ }` // MockUnmanageResponse creates a mock unmanage share response -func MockUnmanageResponse(t *testing.T) { - th.Mux.HandleFunc(shareEndpoint+"/"+shareID+"/action", func(w http.ResponseWriter, r *http.Request) { +func MockUnmanageResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc(shareEndpoint+"/"+shareID+"/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") diff --git a/openstack/sharedfilesystems/v2/shares/testing/request_test.go b/openstack/sharedfilesystems/v2/shares/testing/request_test.go index 396c73a795..809a39316b 100644 --- a/openstack/sharedfilesystems/v2/shares/testing/request_test.go +++ b/openstack/sharedfilesystems/v2/shares/testing/request_test.go @@ -11,10 +11,10 @@ import ( ) func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockCreateResponse(t) + MockCreateResponse(t, fakeServer) options := &shares.CreateOpts{ Size: 1, @@ -25,7 +25,7 @@ func TestCreate(t *testing.T) { DifferentHost: "e268f4aa-d571-43dd-9ab3-f49ad06ffaef", }, } - n, err := shares.Create(context.TODO(), client.ServiceClient(), options).Extract() + n, err := shares.Create(context.TODO(), client.ServiceClient(fakeServer), options).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, n.Name, "my_test_share") @@ -36,10 +36,10 @@ func TestCreate(t *testing.T) { } func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockUpdateResponse(t) + MockUpdateResponse(t, fakeServer) name := "my_new_test_share" description := "" @@ -49,7 +49,7 @@ func TestUpdate(t *testing.T) { DisplayDescription: &description, IsPublic: &iFalse, } - n, err := shares.Update(context.TODO(), client.ServiceClient(), shareID, options).Extract() + n, err := shares.Update(context.TODO(), client.ServiceClient(fakeServer), shareID, options).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, n.Name, "my_new_test_share") @@ -58,22 +58,22 @@ func TestUpdate(t *testing.T) { } func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockDeleteResponse(t) + MockDeleteResponse(t, fakeServer) - result := shares.Delete(context.TODO(), client.ServiceClient(), shareID) + result := shares.Delete(context.TODO(), client.ServiceClient(fakeServer), shareID) th.AssertNoErr(t, result.Err) } func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockGetResponse(t) + MockGetResponse(t, fakeServer) - s, err := shares.Get(context.TODO(), client.ServiceClient(), shareID).Extract() + s, err := shares.Get(context.TODO(), client.ServiceClient(fakeServer), shareID).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, s, &shares.Share{ AvailabilityZone: "nova", @@ -118,12 +118,12 @@ func TestGet(t *testing.T) { } func TestListDetail(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockListDetailResponse(t) + MockListDetailResponse(t, fakeServer) - allPages, err := shares.ListDetail(client.ServiceClient(), &shares.ListOpts{}).AllPages(context.TODO()) + allPages, err := shares.ListDetail(client.ServiceClient(fakeServer), &shares.ListOpts{}).AllPages(context.TODO()) th.AssertNoErr(t, err) @@ -175,12 +175,12 @@ func TestListDetail(t *testing.T) { } func TestListExportLocationsSuccess(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockListExportLocationsResponse(t) + MockListExportLocationsResponse(t, fakeServer) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) // Client c must have Microversion set; minimum supported microversion for List Export Locations is 2.9 c.Microversion = "2.9" @@ -199,12 +199,12 @@ func TestListExportLocationsSuccess(t *testing.T) { } func TestGetExportLocationSuccess(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockGetExportLocationResponse(t) + MockGetExportLocationResponse(t, fakeServer) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) // Client c must have Microversion set; minimum supported microversion for Get Export Location is 2.9 c.Microversion = "2.9" @@ -221,12 +221,12 @@ func TestGetExportLocationSuccess(t *testing.T) { } func TestGrantAcessSuccess(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockGrantAccessResponse(t) + MockGrantAccessResponse(t, fakeServer) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) // Client c must have Microversion set; minimum supported microversion for Grant Access is 2.7 c.Microversion = "2.7" @@ -250,12 +250,12 @@ func TestGrantAcessSuccess(t *testing.T) { } func TestRevokeAccessSuccess(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockRevokeAccessResponse(t) + MockRevokeAccessResponse(t, fakeServer) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) // Client c must have Microversion set; minimum supported microversion for Revoke Access is 2.7 c.Microversion = "2.7" @@ -266,12 +266,12 @@ func TestRevokeAccessSuccess(t *testing.T) { } func TestListAccessRightsSuccess(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockListAccessRightsResponse(t) + MockListAccessRightsResponse(t, fakeServer) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) // Client c must have Microversion set; minimum supported microversion for Grant Access is 2.7 c.Microversion = "2.7" @@ -292,12 +292,12 @@ func TestListAccessRightsSuccess(t *testing.T) { } func TestExtendSuccess(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockExtendResponse(t) + MockExtendResponse(t, fakeServer) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) // Client c must have Microversion set; minimum supported microversion for Grant Access is 2.7 c.Microversion = "2.7" @@ -306,12 +306,12 @@ func TestExtendSuccess(t *testing.T) { } func TestShrinkSuccess(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockShrinkResponse(t) + MockShrinkResponse(t, fakeServer) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) // Client c must have Microversion set; minimum supported microversion for Grant Access is 2.7 c.Microversion = "2.7" @@ -320,12 +320,12 @@ func TestShrinkSuccess(t *testing.T) { } func TestGetMetadataSuccess(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockGetMetadataResponse(t) + MockGetMetadataResponse(t, fakeServer) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) actual, err := shares.GetMetadata(context.TODO(), c, shareID).Extract() th.AssertNoErr(t, err) @@ -333,12 +333,12 @@ func TestGetMetadataSuccess(t *testing.T) { } func TestGetMetadatumSuccess(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockGetMetadatumResponse(t, "foo") + MockGetMetadatumResponse(t, fakeServer, "foo") - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) actual, err := shares.GetMetadatum(context.TODO(), c, shareID, "foo").Extract() th.AssertNoErr(t, err) @@ -346,12 +346,12 @@ func TestGetMetadatumSuccess(t *testing.T) { } func TestSetMetadataSuccess(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockSetMetadataResponse(t) + MockSetMetadataResponse(t, fakeServer) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) actual, err := shares.SetMetadata(context.TODO(), c, shareID, &shares.SetMetadataOpts{Metadata: map[string]string{"foo": "bar"}}).Extract() th.AssertNoErr(t, err) @@ -359,12 +359,12 @@ func TestSetMetadataSuccess(t *testing.T) { } func TestUpdateMetadataSuccess(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockUpdateMetadataResponse(t) + MockUpdateMetadataResponse(t, fakeServer) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) actual, err := shares.UpdateMetadata(context.TODO(), c, shareID, &shares.UpdateMetadataOpts{Metadata: map[string]string{"foo": "bar"}}).Extract() th.AssertNoErr(t, err) @@ -372,24 +372,24 @@ func TestUpdateMetadataSuccess(t *testing.T) { } func TestUnsetMetadataSuccess(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockDeleteMetadatumResponse(t, "foo") + MockDeleteMetadatumResponse(t, fakeServer, "foo") - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) err := shares.DeleteMetadatum(context.TODO(), c, shareID, "foo").ExtractErr() th.AssertNoErr(t, err) } func TestRevertSuccess(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockRevertResponse(t) + MockRevertResponse(t, fakeServer) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) // Client c must have Microversion set; minimum supported microversion for Revert is 2.27 c.Microversion = "2.27" @@ -398,12 +398,12 @@ func TestRevertSuccess(t *testing.T) { } func TestResetStatusSuccess(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockResetStatusResponse(t) + MockResetStatusResponse(t, fakeServer) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) // Client c must have Microversion set; minimum supported microversion for ResetStatus is 2.7 c.Microversion = "2.7" @@ -412,12 +412,12 @@ func TestResetStatusSuccess(t *testing.T) { } func TestForceDeleteSuccess(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockForceDeleteResponse(t) + MockForceDeleteResponse(t, fakeServer) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) // Client c must have Microversion set; minimum supported microversion for ForceDelete is 2.7 c.Microversion = "2.7" @@ -426,12 +426,12 @@ func TestForceDeleteSuccess(t *testing.T) { } func TestUnmanageSuccess(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockUnmanageResponse(t) + MockUnmanageResponse(t, fakeServer) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) // Client c must have Microversion set; minimum supported microversion for Unmanage is 2.7 c.Microversion = "2.7" diff --git a/openstack/sharedfilesystems/v2/sharetransfers/testing/fixtures_test.go b/openstack/sharedfilesystems/v2/sharetransfers/testing/fixtures_test.go index 342c4c5101..3175e10ef5 100644 --- a/openstack/sharedfilesystems/v2/sharetransfers/testing/fixtures_test.go +++ b/openstack/sharedfilesystems/v2/sharetransfers/testing/fixtures_test.go @@ -139,8 +139,8 @@ var AcceptResponse = sharetransfers.Transfer{ }, } -func HandleCreateTransfer(t *testing.T) { - th.Mux.HandleFunc("/share-transfers", func(w http.ResponseWriter, r *http.Request) { +func HandleCreateTransfer(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/share-transfers", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") @@ -151,8 +151,8 @@ func HandleCreateTransfer(t *testing.T) { }) } -func HandleAcceptTransfer(t *testing.T) { - th.Mux.HandleFunc("/share-transfers/b8913bfd-a4d3-4ec5-bd8b-fe2dbeef9f4f/accept", func(w http.ResponseWriter, r *http.Request) { +func HandleAcceptTransfer(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/share-transfers/b8913bfd-a4d3-4ec5-bd8b-fe2dbeef9f4f/accept", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") @@ -162,8 +162,8 @@ func HandleAcceptTransfer(t *testing.T) { }) } -func HandleDeleteTransfer(t *testing.T) { - th.Mux.HandleFunc("/share-transfers/b8913bfd-a4d3-4ec5-bd8b-fe2dbeef9f4f", func(w http.ResponseWriter, r *http.Request) { +func HandleDeleteTransfer(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/share-transfers/b8913bfd-a4d3-4ec5-bd8b-fe2dbeef9f4f", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -171,8 +171,8 @@ func HandleDeleteTransfer(t *testing.T) { }) } -func HandleListTransfers(t *testing.T) { - th.Mux.HandleFunc("/share-transfers", func(w http.ResponseWriter, r *http.Request) { +func HandleListTransfers(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/share-transfers", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") @@ -183,8 +183,8 @@ func HandleListTransfers(t *testing.T) { }) } -func HandleListTransfersDetail(t *testing.T) { - th.Mux.HandleFunc("/share-transfers/detail", func(w http.ResponseWriter, r *http.Request) { +func HandleListTransfersDetail(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/share-transfers/detail", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") @@ -195,8 +195,8 @@ func HandleListTransfersDetail(t *testing.T) { }) } -func HandleGetTransfer(t *testing.T) { - th.Mux.HandleFunc("/share-transfers/b8913bfd-a4d3-4ec5-bd8b-fe2dbeef9f4f", func(w http.ResponseWriter, r *http.Request) { +func HandleGetTransfer(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/share-transfers/b8913bfd-a4d3-4ec5-bd8b-fe2dbeef9f4f", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") diff --git a/openstack/sharedfilesystems/v2/sharetransfers/testing/requests_test.go b/openstack/sharedfilesystems/v2/sharetransfers/testing/requests_test.go index a0a2fefcfa..06a81ed9fc 100644 --- a/openstack/sharedfilesystems/v2/sharetransfers/testing/requests_test.go +++ b/openstack/sharedfilesystems/v2/sharetransfers/testing/requests_test.go @@ -11,43 +11,43 @@ import ( ) func TestCreateTransfer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateTransfer(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCreateTransfer(t, fakeServer) - actual, err := sharetransfers.Create(context.TODO(), client.ServiceClient(), TransferRequest).Extract() + actual, err := sharetransfers.Create(context.TODO(), client.ServiceClient(fakeServer), TransferRequest).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, TransferResponse, *actual) } func TestAcceptTransfer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleAcceptTransfer(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleAcceptTransfer(t, fakeServer) - err := sharetransfers.Accept(context.TODO(), client.ServiceClient(), TransferResponse.ID, AcceptRequest).ExtractErr() + err := sharetransfers.Accept(context.TODO(), client.ServiceClient(fakeServer), TransferResponse.ID, AcceptRequest).ExtractErr() th.AssertNoErr(t, err) } func TestDeleteTransfer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDeleteTransfer(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDeleteTransfer(t, fakeServer) - err := sharetransfers.Delete(context.TODO(), client.ServiceClient(), TransferResponse.ID).ExtractErr() + err := sharetransfers.Delete(context.TODO(), client.ServiceClient(fakeServer), TransferResponse.ID).ExtractErr() th.AssertNoErr(t, err) } func TestListTransfers(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListTransfers(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListTransfers(t, fakeServer) expectedResponse := TransferListResponse expectedResponse[0].AuthKey = "" count := 0 - err := sharetransfers.List(client.ServiceClient(), &sharetransfers.ListOpts{AllTenants: true}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := sharetransfers.List(client.ServiceClient(fakeServer), &sharetransfers.ListOpts{AllTenants: true}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := sharetransfers.ExtractTransfers(page) @@ -62,15 +62,15 @@ func TestListTransfers(t *testing.T) { } func TestListTransfersDetail(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListTransfersDetail(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListTransfersDetail(t, fakeServer) expectedResponse := TransferListResponse expectedResponse[0].AuthKey = "" count := 0 - err := sharetransfers.ListDetail(client.ServiceClient(), &sharetransfers.ListOpts{AllTenants: true}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := sharetransfers.ListDetail(client.ServiceClient(fakeServer), &sharetransfers.ListOpts{AllTenants: true}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := sharetransfers.ExtractTransfers(page) @@ -85,14 +85,14 @@ func TestListTransfersDetail(t *testing.T) { } func TestListTransfersAllPages(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListTransfers(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListTransfers(t, fakeServer) expectedResponse := TransferListResponse expectedResponse[0].AuthKey = "" - allPages, err := sharetransfers.List(client.ServiceClient(), &sharetransfers.ListOpts{AllTenants: true}).AllPages(context.TODO()) + allPages, err := sharetransfers.List(client.ServiceClient(fakeServer), &sharetransfers.ListOpts{AllTenants: true}).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := sharetransfers.ExtractTransfers(allPages) th.AssertNoErr(t, err) @@ -100,14 +100,14 @@ func TestListTransfersAllPages(t *testing.T) { } func TestGetTransfer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetTransfer(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetTransfer(t, fakeServer) expectedResponse := TransferResponse expectedResponse.AuthKey = "" - actual, err := sharetransfers.Get(context.TODO(), client.ServiceClient(), TransferResponse.ID).Extract() + actual, err := sharetransfers.Get(context.TODO(), client.ServiceClient(fakeServer), TransferResponse.ID).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, expectedResponse, *actual) } diff --git a/openstack/sharedfilesystems/v2/sharetypes/testing/fixtures_test.go b/openstack/sharedfilesystems/v2/sharetypes/testing/fixtures_test.go index 2330f8a12c..6acf017b87 100644 --- a/openstack/sharedfilesystems/v2/sharetypes/testing/fixtures_test.go +++ b/openstack/sharedfilesystems/v2/sharetypes/testing/fixtures_test.go @@ -9,8 +9,8 @@ import ( "github.com/gophercloud/gophercloud/v2/testhelper/client" ) -func MockCreateResponse(t *testing.T) { - th.Mux.HandleFunc("/types", func(w http.ResponseWriter, r *http.Request) { +func MockCreateResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/types", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -60,16 +60,16 @@ func MockCreateResponse(t *testing.T) { }) } -func MockDeleteResponse(t *testing.T) { - th.Mux.HandleFunc("/types/shareTypeID", func(w http.ResponseWriter, r *http.Request) { +func MockDeleteResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/types/shareTypeID", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusAccepted) }) } -func MockListResponse(t *testing.T) { - th.Mux.HandleFunc("/types", func(w http.ResponseWriter, r *http.Request) { +func MockListResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/types", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -134,8 +134,8 @@ func MockListResponse(t *testing.T) { }) } -func MockGetDefaultResponse(t *testing.T) { - th.Mux.HandleFunc("/types/default", func(w http.ResponseWriter, r *http.Request) { +func MockGetDefaultResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/types/default", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -165,8 +165,8 @@ func MockGetDefaultResponse(t *testing.T) { }) } -func MockGetExtraSpecsResponse(t *testing.T) { - th.Mux.HandleFunc("/types/shareTypeID/extra_specs", func(w http.ResponseWriter, r *http.Request) { +func MockGetExtraSpecsResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/types/shareTypeID/extra_specs", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -183,8 +183,8 @@ func MockGetExtraSpecsResponse(t *testing.T) { }) } -func MockSetExtraSpecsResponse(t *testing.T) { - th.Mux.HandleFunc("/types/shareTypeID/extra_specs", func(w http.ResponseWriter, r *http.Request) { +func MockSetExtraSpecsResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/types/shareTypeID/extra_specs", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -208,16 +208,16 @@ func MockSetExtraSpecsResponse(t *testing.T) { }) } -func MockUnsetExtraSpecsResponse(t *testing.T) { - th.Mux.HandleFunc("/types/shareTypeID/extra_specs/my_key", func(w http.ResponseWriter, r *http.Request) { +func MockUnsetExtraSpecsResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/types/shareTypeID/extra_specs/my_key", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusAccepted) }) } -func MockShowAccessResponse(t *testing.T) { - th.Mux.HandleFunc("/types/shareTypeID/share_type_access", func(w http.ResponseWriter, r *http.Request) { +func MockShowAccessResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/types/shareTypeID/share_type_access", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -239,8 +239,8 @@ func MockShowAccessResponse(t *testing.T) { }) } -func MockAddAccessResponse(t *testing.T) { - th.Mux.HandleFunc("/types/shareTypeID/action", func(w http.ResponseWriter, r *http.Request) { +func MockAddAccessResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/types/shareTypeID/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -255,8 +255,8 @@ func MockAddAccessResponse(t *testing.T) { }) } -func MockRemoveAccessResponse(t *testing.T) { - th.Mux.HandleFunc("/types/shareTypeID/action", func(w http.ResponseWriter, r *http.Request) { +func MockRemoveAccessResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/types/shareTypeID/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") diff --git a/openstack/sharedfilesystems/v2/sharetypes/testing/requests_test.go b/openstack/sharedfilesystems/v2/sharetypes/testing/requests_test.go index 4490a44c7d..7e1af98caf 100644 --- a/openstack/sharedfilesystems/v2/sharetypes/testing/requests_test.go +++ b/openstack/sharedfilesystems/v2/sharetypes/testing/requests_test.go @@ -12,10 +12,10 @@ import ( // Verifies that a share type can be created correctly func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockCreateResponse(t) + MockCreateResponse(t, fakeServer) snapshotSupport := true extraSpecs := sharetypes.ExtraSpecsOpts{ @@ -29,7 +29,7 @@ func TestCreate(t *testing.T) { ExtraSpecs: extraSpecs, } - st, err := sharetypes.Create(context.TODO(), client.ServiceClient(), options).Extract() + st, err := sharetypes.Create(context.TODO(), client.ServiceClient(fakeServer), options).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, st.Name, "my_new_share_type") @@ -38,14 +38,14 @@ func TestCreate(t *testing.T) { // Verifies that a share type can't be created if the required parameters are missing func TestRequiredCreateOpts(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() options := &sharetypes.CreateOpts{ Name: "my_new_share_type", } - _, err := sharetypes.Create(context.TODO(), client.ServiceClient(), options).Extract() + _, err := sharetypes.Create(context.TODO(), client.ServiceClient(fakeServer), options).Extract() if _, ok := err.(gophercloud.ErrMissingInput); !ok { t.Fatal("ErrMissingInput was expected to occur") } @@ -58,7 +58,7 @@ func TestRequiredCreateOpts(t *testing.T) { ExtraSpecs: extraSpecs, } - _, err = sharetypes.Create(context.TODO(), client.ServiceClient(), options).Extract() + _, err = sharetypes.Create(context.TODO(), client.ServiceClient(fakeServer), options).Extract() if _, ok := err.(gophercloud.ErrMissingInput); !ok { t.Fatal("ErrMissingInput was expected to occur") } @@ -66,22 +66,22 @@ func TestRequiredCreateOpts(t *testing.T) { // Verifies that share type deletion works func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockDeleteResponse(t) - res := sharetypes.Delete(context.TODO(), client.ServiceClient(), "shareTypeID") + MockDeleteResponse(t, fakeServer) + res := sharetypes.Delete(context.TODO(), client.ServiceClient(fakeServer), "shareTypeID") th.AssertNoErr(t, res.Err) } // Verifies that share types can be listed correctly func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockListResponse(t) + MockListResponse(t, fakeServer) - allPages, err := sharetypes.List(client.ServiceClient(), &sharetypes.ListOpts{}).AllPages(context.TODO()) + allPages, err := sharetypes.List(client.ServiceClient(fakeServer), &sharetypes.ListOpts{}).AllPages(context.TODO()) th.AssertNoErr(t, err) actual, err := sharetypes.ExtractShareTypes(allPages) th.AssertNoErr(t, err) @@ -107,10 +107,10 @@ func TestList(t *testing.T) { // Verifies that it is possible to get the default share type func TestGetDefault(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockGetDefaultResponse(t) + MockGetDefaultResponse(t, fakeServer) expected := sharetypes.ShareType{ ID: "be27425c-f807-4500-a056-d00721db45cf", @@ -119,19 +119,19 @@ func TestGetDefault(t *testing.T) { RequiredExtraSpecs: map[string]any(nil), } - actual, err := sharetypes.GetDefault(context.TODO(), client.ServiceClient()).Extract() + actual, err := sharetypes.GetDefault(context.TODO(), client.ServiceClient(fakeServer)).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, &expected, actual) } // Verifies that it is possible to get the extra specifications for a share type func TestGetExtraSpecs(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockGetExtraSpecsResponse(t) + MockGetExtraSpecsResponse(t, fakeServer) - st, err := sharetypes.GetExtraSpecs(context.TODO(), client.ServiceClient(), "shareTypeID").Extract() + st, err := sharetypes.GetExtraSpecs(context.TODO(), client.ServiceClient(fakeServer), "shareTypeID").Extract() th.AssertNoErr(t, err) th.AssertEquals(t, st["snapshot_support"], "True") @@ -141,16 +141,16 @@ func TestGetExtraSpecs(t *testing.T) { // Verifies that an extra specs can be added to a share type func TestSetExtraSpecs(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockSetExtraSpecsResponse(t) + MockSetExtraSpecsResponse(t, fakeServer) options := &sharetypes.SetExtraSpecsOpts{ ExtraSpecs: map[string]any{"my_key": "my_value"}, } - es, err := sharetypes.SetExtraSpecs(context.TODO(), client.ServiceClient(), "shareTypeID", options).Extract() + es, err := sharetypes.SetExtraSpecs(context.TODO(), client.ServiceClient(fakeServer), "shareTypeID", options).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, es["my_key"], "my_value") @@ -158,20 +158,20 @@ func TestSetExtraSpecs(t *testing.T) { // Verifies that an extra specification can be unset for a share type func TestUnsetExtraSpecs(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockUnsetExtraSpecsResponse(t) - res := sharetypes.UnsetExtraSpecs(context.TODO(), client.ServiceClient(), "shareTypeID", "my_key") + MockUnsetExtraSpecsResponse(t, fakeServer) + res := sharetypes.UnsetExtraSpecs(context.TODO(), client.ServiceClient(fakeServer), "shareTypeID", "my_key") th.AssertNoErr(t, res.Err) } // Verifies that it is possible to see the access for a share type func TestShowAccess(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockShowAccessResponse(t) + MockShowAccessResponse(t, fakeServer) expected := []sharetypes.ShareTypeAccess{ { @@ -184,7 +184,7 @@ func TestShowAccess(t *testing.T) { }, } - shareType, err := sharetypes.ShowAccess(context.TODO(), client.ServiceClient(), "shareTypeID").Extract() + shareType, err := sharetypes.ShowAccess(context.TODO(), client.ServiceClient(fakeServer), "shareTypeID").Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, expected, shareType) @@ -192,30 +192,30 @@ func TestShowAccess(t *testing.T) { // Verifies that an access can be added to a share type func TestAddAccess(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockAddAccessResponse(t) + MockAddAccessResponse(t, fakeServer) options := &sharetypes.AccessOpts{ Project: "e1284adea3ee4d2482af5ed214f3ad90", } - err := sharetypes.AddAccess(context.TODO(), client.ServiceClient(), "shareTypeID", options).ExtractErr() + err := sharetypes.AddAccess(context.TODO(), client.ServiceClient(fakeServer), "shareTypeID", options).ExtractErr() th.AssertNoErr(t, err) } // Verifies that an access can be removed from a share type func TestRemoveAccess(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockRemoveAccessResponse(t) + MockRemoveAccessResponse(t, fakeServer) options := &sharetypes.AccessOpts{ Project: "e1284adea3ee4d2482af5ed214f3ad90", } - err := sharetypes.RemoveAccess(context.TODO(), client.ServiceClient(), "shareTypeID", options).ExtractErr() + err := sharetypes.RemoveAccess(context.TODO(), client.ServiceClient(fakeServer), "shareTypeID", options).ExtractErr() th.AssertNoErr(t, err) } diff --git a/openstack/sharedfilesystems/v2/snapshots/testing/fixtures_test.go b/openstack/sharedfilesystems/v2/snapshots/testing/fixtures_test.go index 2175dd4739..dc18cf7c91 100644 --- a/openstack/sharedfilesystems/v2/snapshots/testing/fixtures_test.go +++ b/openstack/sharedfilesystems/v2/snapshots/testing/fixtures_test.go @@ -50,8 +50,8 @@ var createResponse = `{ }` // MockCreateResponse creates a mock response -func MockCreateResponse(t *testing.T) { - th.Mux.HandleFunc(snapshotEndpoint, func(w http.ResponseWriter, r *http.Request) { +func MockCreateResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc(snapshotEndpoint, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -64,8 +64,8 @@ func MockCreateResponse(t *testing.T) { } // MockDeleteResponse creates a mock delete response -func MockDeleteResponse(t *testing.T) { - th.Mux.HandleFunc(snapshotEndpoint+"/"+snapshotID, func(w http.ResponseWriter, r *http.Request) { +func MockDeleteResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc(snapshotEndpoint+"/"+snapshotID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusAccepted) @@ -105,8 +105,8 @@ var updateResponse = `{ } }` -func MockUpdateResponse(t *testing.T) { - th.Mux.HandleFunc(snapshotEndpoint+"/"+snapshotID, func(w http.ResponseWriter, r *http.Request) { +func MockUpdateResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc(snapshotEndpoint+"/"+snapshotID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -145,8 +145,8 @@ var getResponse = `{ }` // MockGetResponse creates a mock get response -func MockGetResponse(t *testing.T) { - th.Mux.HandleFunc(snapshotEndpoint+"/"+snapshotID, func(w http.ResponseWriter, r *http.Request) { +func MockGetResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc(snapshotEndpoint+"/"+snapshotID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusOK) @@ -185,8 +185,8 @@ var listDetailResponse = `{ var listDetailEmptyResponse = `{"snapshots": []}` // MockListDetailResponse creates a mock detailed-list response -func MockListDetailResponse(t *testing.T) { - th.Mux.HandleFunc(snapshotEndpoint+"/detail", func(w http.ResponseWriter, r *http.Request) { +func MockListDetailResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc(snapshotEndpoint+"/detail", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -214,8 +214,8 @@ var resetStatusRequest = `{ }` // MockResetStatusResponse creates a mock reset status snapshot response -func MockResetStatusResponse(t *testing.T) { - th.Mux.HandleFunc(snapshotEndpoint+"/"+snapshotID+"/action", func(w http.ResponseWriter, r *http.Request) { +func MockResetStatusResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc(snapshotEndpoint+"/"+snapshotID+"/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -231,8 +231,8 @@ var forceDeleteRequest = `{ }` // MockForceDeleteResponse creates a mock force delete snapshot response -func MockForceDeleteResponse(t *testing.T) { - th.Mux.HandleFunc(snapshotEndpoint+"/"+snapshotID+"/action", func(w http.ResponseWriter, r *http.Request) { +func MockForceDeleteResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc(snapshotEndpoint+"/"+snapshotID+"/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") diff --git a/openstack/sharedfilesystems/v2/snapshots/testing/request_test.go b/openstack/sharedfilesystems/v2/snapshots/testing/request_test.go index 759ad0d78d..29330e177f 100644 --- a/openstack/sharedfilesystems/v2/snapshots/testing/request_test.go +++ b/openstack/sharedfilesystems/v2/snapshots/testing/request_test.go @@ -11,13 +11,13 @@ import ( ) func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockCreateResponse(t) + MockCreateResponse(t, fakeServer) options := &snapshots.CreateOpts{ShareID: shareID, Name: "test snapshot", Description: "test description"} - n, err := snapshots.Create(context.TODO(), client.ServiceClient(), options).Extract() + n, err := snapshots.Create(context.TODO(), client.ServiceClient(fakeServer), options).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, n.Name, "test snapshot") @@ -28,10 +28,10 @@ func TestCreate(t *testing.T) { } func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockUpdateResponse(t) + MockUpdateResponse(t, fakeServer) name := "my_new_test_snapshot" description := "" @@ -39,7 +39,7 @@ func TestUpdate(t *testing.T) { DisplayName: &name, DisplayDescription: &description, } - n, err := snapshots.Update(context.TODO(), client.ServiceClient(), snapshotID, options).Extract() + n, err := snapshots.Update(context.TODO(), client.ServiceClient(fakeServer), snapshotID, options).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, n.Name, "my_new_test_snapshot") @@ -47,22 +47,22 @@ func TestUpdate(t *testing.T) { } func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockDeleteResponse(t) + MockDeleteResponse(t, fakeServer) - result := snapshots.Delete(context.TODO(), client.ServiceClient(), snapshotID) + result := snapshots.Delete(context.TODO(), client.ServiceClient(fakeServer), snapshotID) th.AssertNoErr(t, result.Err) } func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockGetResponse(t) + MockGetResponse(t, fakeServer) - s, err := snapshots.Get(context.TODO(), client.ServiceClient(), snapshotID).Extract() + s, err := snapshots.Get(context.TODO(), client.ServiceClient(fakeServer), snapshotID).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, s, &snapshots.Snapshot{ ID: snapshotID, @@ -89,12 +89,12 @@ func TestGet(t *testing.T) { } func TestListDetail(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockListDetailResponse(t) + MockListDetailResponse(t, fakeServer) - allPages, err := snapshots.ListDetail(client.ServiceClient(), &snapshots.ListOpts{}).AllPages(context.TODO()) + allPages, err := snapshots.ListDetail(client.ServiceClient(fakeServer), &snapshots.ListOpts{}).AllPages(context.TODO()) th.AssertNoErr(t, err) @@ -128,24 +128,24 @@ func TestListDetail(t *testing.T) { } func TestResetStatusSuccess(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockResetStatusResponse(t) + MockResetStatusResponse(t, fakeServer) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) err := snapshots.ResetStatus(context.TODO(), c, snapshotID, &snapshots.ResetStatusOpts{Status: "error"}).ExtractErr() th.AssertNoErr(t, err) } func TestForceDeleteSuccess(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - MockForceDeleteResponse(t) + MockForceDeleteResponse(t, fakeServer) - c := client.ServiceClient() + c := client.ServiceClient(fakeServer) err := snapshots.ForceDelete(context.TODO(), c, snapshotID).ExtractErr() th.AssertNoErr(t, err) diff --git a/openstack/testing/client_test.go b/openstack/testing/client_test.go index 75192a524c..214c68ccd3 100644 --- a/openstack/testing/client_test.go +++ b/openstack/testing/client_test.go @@ -14,10 +14,10 @@ import ( const ID = "0123456789" func TestAuthenticatedClientV3(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, ` { "versions": { @@ -39,10 +39,10 @@ func TestAuthenticatedClientV3(t *testing.T) { ] } } - `, th.Endpoint()+"v3/", th.Endpoint()+"v2.0/") + `, fakeServer.Endpoint()+"v3/", fakeServer.Endpoint()+"v2.0/") }) - th.Mux.HandleFunc("/v3/auth/tokens", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v3/auth/tokens", func(w http.ResponseWriter, r *http.Request) { w.Header().Add("X-Subject-Token", ID) w.WriteHeader(http.StatusCreated) @@ -54,7 +54,7 @@ func TestAuthenticatedClientV3(t *testing.T) { Password: "secret", DomainName: "default", TenantName: "project", - IdentityEndpoint: th.Endpoint(), + IdentityEndpoint: fakeServer.Endpoint(), } client, err := openstack.AuthenticatedClient(context.TODO(), options) th.AssertNoErr(t, err) @@ -62,10 +62,10 @@ func TestAuthenticatedClientV3(t *testing.T) { } func TestAuthenticatedClientV2(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, ` { "versions": { @@ -87,10 +87,10 @@ func TestAuthenticatedClientV2(t *testing.T) { ] } } - `, th.Endpoint()+"v3/", th.Endpoint()+"v2.0/") + `, fakeServer.Endpoint()+"v3/", fakeServer.Endpoint()+"v2.0/") }) - th.Mux.HandleFunc("/v2.0/tokens", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/tokens", func(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, ` { "access": { @@ -157,7 +157,7 @@ func TestAuthenticatedClientV2(t *testing.T) { options := gophercloud.AuthOptions{ Username: "me", Password: "secret", - IdentityEndpoint: th.Endpoint(), + IdentityEndpoint: fakeServer.Endpoint(), } client, err := openstack.AuthenticatedClient(context.TODO(), options) th.AssertNoErr(t, err) @@ -165,10 +165,10 @@ func TestAuthenticatedClientV2(t *testing.T) { } func TestIdentityAdminV3Client(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, ` { "versions": { @@ -190,10 +190,10 @@ func TestIdentityAdminV3Client(t *testing.T) { ] } } - `, th.Endpoint()+"v3/", th.Endpoint()+"v2.0/") + `, fakeServer.Endpoint()+"v3/", fakeServer.Endpoint()+"v2.0/") }) - th.Mux.HandleFunc("/v3/auth/tokens", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v3/auth/tokens", func(w http.ResponseWriter, r *http.Request) { w.Header().Add("X-Subject-Token", ID) w.WriteHeader(http.StatusCreated) @@ -282,7 +282,7 @@ func TestIdentityAdminV3Client(t *testing.T) { Username: "me", Password: "secret", DomainID: "12345", - IdentityEndpoint: th.Endpoint(), + IdentityEndpoint: fakeServer.Endpoint(), } pc, err := openstack.AuthenticatedClient(context.TODO(), options) th.AssertNoErr(t, err) diff --git a/openstack/utils/testing/choose_version_test.go b/openstack/utils/testing/choose_version_test.go index c237e4e036..e1a813ea1a 100644 --- a/openstack/utils/testing/choose_version_test.go +++ b/openstack/utils/testing/choose_version_test.go @@ -12,8 +12,8 @@ import ( th "github.com/gophercloud/gophercloud/v2/testhelper" ) -func setupVersionHandler() { - th.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { +func setupVersionHandler(fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, ` { "versions": { @@ -35,10 +35,10 @@ func setupVersionHandler() { ] } } - `, th.Server.URL, th.Server.URL) + `, fakeServer.Server.URL, fakeServer.Server.URL) }) // Compute v2.1 API - th.Mux.HandleFunc("/compute/v2.1/", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/compute/v2.1/", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, ` { "version": { @@ -66,10 +66,10 @@ func setupVersionHandler() { ] } } - `, th.Server.URL) + `, fakeServer.Server.URL) }) // Compute v2 API - th.Mux.HandleFunc("/compute/v2/", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/compute/v2/", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, ` { "version": { @@ -97,10 +97,10 @@ func setupVersionHandler() { ] } } - `, th.Server.URL) + `, fakeServer.Server.URL) }) // Ironic API - th.Mux.HandleFunc("/ironic/v1/", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/ironic/v1/", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, ` { "name": "OpenStack Ironic API", @@ -132,10 +132,10 @@ func setupVersionHandler() { } ] } - `, th.Server.URL, th.Server.URL) + `, fakeServer.Server.URL, fakeServer.Server.URL) }) // Ironic multi-version - th.Mux.HandleFunc("/ironic/v1.2/", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/ironic/v1.2/", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, ` { "name": "OpenStack Ironic API", @@ -179,20 +179,20 @@ func setupVersionHandler() { } ] } - `, th.Server.URL, th.Server.URL, th.Server.URL) + `, fakeServer.Server.URL, fakeServer.Server.URL, fakeServer.Server.URL) }) } func TestChooseVersion(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - setupVersionHandler() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + setupVersionHandler(fakeServer) v2 := &utils.Version{ID: "v2.0", Priority: 2, Suffix: "blarg"} v3 := &utils.Version{ID: "v3.0", Priority: 3, Suffix: "hargl"} c := &gophercloud.ProviderClient{ - IdentityBase: th.Endpoint(), + IdentityBase: fakeServer.Endpoint(), IdentityEndpoint: "", } v, endpoint, err := utils.ChooseVersion(context.TODO(), c, []*utils.Version{v2, v3}) @@ -205,23 +205,23 @@ func TestChooseVersion(t *testing.T) { t.Errorf("Expected %#v to win, but %#v did instead", v3, v) } - expected := th.Endpoint() + "v3.0/" + expected := fakeServer.Endpoint() + "v3.0/" if endpoint != expected { t.Errorf("Expected endpoint [%s], but was [%s] instead", expected, endpoint) } } func TestChooseVersionOpinionatedLink(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - setupVersionHandler() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + setupVersionHandler(fakeServer) v2 := &utils.Version{ID: "v2.0", Priority: 2, Suffix: "nope"} v3 := &utils.Version{ID: "v3.0", Priority: 3, Suffix: "northis"} c := &gophercloud.ProviderClient{ - IdentityBase: th.Endpoint(), - IdentityEndpoint: th.Endpoint() + "v2.0/", + IdentityBase: fakeServer.Endpoint(), + IdentityEndpoint: fakeServer.Endpoint() + "v2.0/", } v, endpoint, err := utils.ChooseVersion(context.TODO(), c, []*utils.Version{v2, v3}) if err != nil { @@ -232,22 +232,22 @@ func TestChooseVersionOpinionatedLink(t *testing.T) { t.Errorf("Expected %#v to win, but %#v did instead", v2, v) } - expected := th.Endpoint() + "v2.0/" + expected := fakeServer.Endpoint() + "v2.0/" if endpoint != expected { t.Errorf("Expected endpoint [%s], but was [%s] instead", expected, endpoint) } } func TestChooseVersionFromSuffix(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() v2 := &utils.Version{ID: "v2.0", Priority: 2, Suffix: "/v2.0/"} v3 := &utils.Version{ID: "v3.0", Priority: 3, Suffix: "/v3.0/"} c := &gophercloud.ProviderClient{ - IdentityBase: th.Endpoint(), - IdentityEndpoint: th.Endpoint() + "v2.0/", + IdentityBase: fakeServer.Endpoint(), + IdentityEndpoint: fakeServer.Endpoint() + "v2.0/", } v, endpoint, err := utils.ChooseVersion(context.TODO(), c, []*utils.Version{v2, v3}) if err != nil { @@ -258,7 +258,7 @@ func TestChooseVersionFromSuffix(t *testing.T) { t.Errorf("Expected %#v to win, but %#v did instead", v2, v) } - expected := th.Endpoint() + "v2.0/" + expected := fakeServer.Endpoint() + "v2.0/" if endpoint != expected { t.Errorf("Expected endpoint [%s], but was [%s] instead", expected, endpoint) } @@ -272,33 +272,33 @@ type getSupportedServiceMicroversions struct { } func TestGetSupportedVersions(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - setupVersionHandler() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + setupVersionHandler(fakeServer) tests := []getSupportedServiceMicroversions{ { // v2 does not support microversions and returns error - Endpoint: th.Endpoint() + "compute/v2/", + Endpoint: fakeServer.Endpoint() + "compute/v2/", ExpectedMax: "", ExpectedMin: "", ExpectedErr: true, }, { - Endpoint: th.Endpoint() + "compute/v2.1/", + Endpoint: fakeServer.Endpoint() + "compute/v2.1/", ExpectedMax: "2.90", ExpectedMin: "2.1", ExpectedErr: false, }, { - Endpoint: th.Endpoint() + "ironic/v1/", + Endpoint: fakeServer.Endpoint() + "ironic/v1/", ExpectedMax: "1.87", ExpectedMin: "1.1", ExpectedErr: false, }, { // This endpoint returns multiple versions, which is not supported - Endpoint: th.Endpoint() + "ironic/v1.2/", + Endpoint: fakeServer.Endpoint() + "ironic/v1.2/", ExpectedMax: "not-relevant", ExpectedMin: "not-relevant", ExpectedErr: true, @@ -307,8 +307,8 @@ func TestGetSupportedVersions(t *testing.T) { for _, test := range tests { c := &gophercloud.ProviderClient{ - IdentityBase: th.Endpoint(), - IdentityEndpoint: th.Endpoint() + "v2.0/", + IdentityBase: fakeServer.Endpoint(), + IdentityEndpoint: fakeServer.Endpoint() + "v2.0/", } client := &gophercloud.ServiceClient{ diff --git a/openstack/workflow/v2/crontriggers/testing/requests_test.go b/openstack/workflow/v2/crontriggers/testing/requests_test.go index ec2b2bf738..0926f97482 100644 --- a/openstack/workflow/v2/crontriggers/testing/requests_test.go +++ b/openstack/workflow/v2/crontriggers/testing/requests_test.go @@ -16,10 +16,10 @@ import ( ) func TestCreateCronTrigger(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/cron_triggers", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/cron_triggers", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusCreated) @@ -58,7 +58,7 @@ func TestCreateCronTrigger(t *testing.T) { }, } - actual, err := crontriggers.Create(context.TODO(), client.ServiceClient(), opts).Extract() + actual, err := crontriggers.Create(context.TODO(), client.ServiceClient(fakeServer), opts).Extract() if err != nil { t.Fatalf("Unable to create cron trigger: %v", err) } @@ -89,24 +89,24 @@ func TestCreateCronTrigger(t *testing.T) { } func TestDeleteCronTrigger(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/cron_triggers/0520ffd8-f7f1-4f2e-845b-55d953a1cf46", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/cron_triggers/0520ffd8-f7f1-4f2e-845b-55d953a1cf46", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusAccepted) }) - res := crontriggers.Delete(context.TODO(), client.ServiceClient(), "0520ffd8-f7f1-4f2e-845b-55d953a1cf46") + res := crontriggers.Delete(context.TODO(), client.ServiceClient(fakeServer), "0520ffd8-f7f1-4f2e-845b-55d953a1cf46") th.AssertNoErr(t, res.Err) } func TestGetCronTrigger(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - th.Mux.HandleFunc("/cron_triggers/0520ffd8-f7f1-4f2e-845b-55d953a1cf46", func(w http.ResponseWriter, r *http.Request) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + fakeServer.Mux.HandleFunc("/cron_triggers/0520ffd8-f7f1-4f2e-845b-55d953a1cf46", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-token", client.TokenID) w.Header().Add("Content-Type", "application/json") @@ -129,7 +129,7 @@ func TestGetCronTrigger(t *testing.T) { } `) }) - actual, err := crontriggers.Get(context.TODO(), client.ServiceClient(), "0520ffd8-f7f1-4f2e-845b-55d953a1cf46").Extract() + actual, err := crontriggers.Get(context.TODO(), client.ServiceClient(fakeServer), "0520ffd8-f7f1-4f2e-845b-55d953a1cf46").Extract() if err != nil { t.Fatalf("Unable to get cron trigger: %v", err) } @@ -161,9 +161,9 @@ func TestGetCronTrigger(t *testing.T) { } func TestListCronTriggers(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - th.Mux.HandleFunc("/cron_triggers", func(w http.ResponseWriter, r *http.Request) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + fakeServer.Mux.HandleFunc("/cron_triggers", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") @@ -193,7 +193,7 @@ func TestListCronTriggers(t *testing.T) { } ], "next": "%s/cron_triggers?marker=0520ffd8-f7f1-4f2e-845b-55d953a1cf46" - }`, th.Server.URL) + }`, fakeServer.Server.URL) case "0520ffd8-f7f1-4f2e-845b-55d953a1cf46": fmt.Fprint(w, `{ "cron_triggers": [] }`) default: @@ -202,7 +202,7 @@ func TestListCronTriggers(t *testing.T) { }) pages := 0 // Get all cron triggers - err := crontriggers.List(client.ServiceClient(), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := crontriggers.List(client.ServiceClient(fakeServer), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := crontriggers.ExtractCronTriggers(page) if err != nil { diff --git a/openstack/workflow/v2/executions/testing/requests_test.go b/openstack/workflow/v2/executions/testing/requests_test.go index 0d2c57de2f..6ba94a9aa1 100644 --- a/openstack/workflow/v2/executions/testing/requests_test.go +++ b/openstack/workflow/v2/executions/testing/requests_test.go @@ -16,10 +16,10 @@ import ( ) func TestCreateExecution(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/executions", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/executions", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusCreated) @@ -54,7 +54,7 @@ func TestCreateExecution(t *testing.T) { Description: "description", } - actual, err := executions.Create(context.TODO(), client.ServiceClient(), opts).Extract() + actual, err := executions.Create(context.TODO(), client.ServiceClient(fakeServer), opts).Extract() if err != nil { t.Fatalf("Unable to create execution: %v", err) } @@ -84,10 +84,10 @@ func TestCreateExecution(t *testing.T) { } func TestGetExecution(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/executions/50bb59f1-eb77-4017-a77f-6d575b002667", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/executions/50bb59f1-eb77-4017-a77f-6d575b002667", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-token", client.TokenID) @@ -113,7 +113,7 @@ func TestGetExecution(t *testing.T) { `) }) - actual, err := executions.Get(context.TODO(), client.ServiceClient(), "50bb59f1-eb77-4017-a77f-6d575b002667").Extract() + actual, err := executions.Get(context.TODO(), client.ServiceClient(fakeServer), "50bb59f1-eb77-4017-a77f-6d575b002667").Extract() if err != nil { t.Fatalf("Unable to get execution: %v", err) } @@ -143,21 +143,21 @@ func TestGetExecution(t *testing.T) { } func TestDeleteExecution(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - th.Mux.HandleFunc("/executions/1", func(w http.ResponseWriter, r *http.Request) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + fakeServer.Mux.HandleFunc("/executions/1", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusAccepted) }) - res := executions.Delete(context.TODO(), client.ServiceClient(), "1") + res := executions.Delete(context.TODO(), client.ServiceClient(fakeServer), "1") th.AssertNoErr(t, res.Err) } func TestListExecutions(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - th.Mux.HandleFunc("/executions", func(w http.ResponseWriter, r *http.Request) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + fakeServer.Mux.HandleFunc("/executions", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") @@ -187,7 +187,7 @@ func TestListExecutions(t *testing.T) { } ], "next": "%s/executions?marker=50bb59f1-eb77-4017-a77f-6d575b002667" - }`, th.Server.URL) + }`, fakeServer.Server.URL) case "50bb59f1-eb77-4017-a77f-6d575b002667": fmt.Fprint(w, `{ "executions": [] }`) default: @@ -196,7 +196,7 @@ func TestListExecutions(t *testing.T) { }) pages := 0 // Get all executions - err := executions.List(client.ServiceClient(), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := executions.List(client.ServiceClient(fakeServer), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := executions.ExtractExecutions(page) if err != nil { diff --git a/openstack/workflow/v2/workflows/doc.go b/openstack/workflow/v2/workflows/doc.go index 52638a3469..bc82714a6b 100644 --- a/openstack/workflow/v2/workflows/doc.go +++ b/openstack/workflow/v2/workflows/doc.go @@ -65,7 +65,7 @@ Create a workflow Delete a workflow - res := workflows.Delete(fake.ServiceClient(), "604a3a1e-94e3-4066-a34a-aa56873ef236") + res := workflows.Delete(fake.ServiceClient(fakeServer), "604a3a1e-94e3-4066-a34a-aa56873ef236") if res.Err != nil { panic(res.Err) } diff --git a/openstack/workflow/v2/workflows/testing/requests_test.go b/openstack/workflow/v2/workflows/testing/requests_test.go index ff8d51cc23..d194631b34 100644 --- a/openstack/workflow/v2/workflows/testing/requests_test.go +++ b/openstack/workflow/v2/workflows/testing/requests_test.go @@ -17,8 +17,8 @@ import ( ) func TestCreateWorkflow(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() definition := `--- version: '2.0' @@ -33,7 +33,7 @@ workflow_echo: test: action: std.echo output="<% $.msg %>"` - th.Mux.HandleFunc("/workflows", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/workflows", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "text/plain") @@ -70,7 +70,7 @@ workflow_echo: Definition: strings.NewReader(definition), } - actual, err := workflows.Create(context.TODO(), client.ServiceClient(), opts).Extract() + actual, err := workflows.Create(context.TODO(), client.ServiceClient(fakeServer), opts).Extract() if err != nil { t.Fatalf("Unable to create workflow: %v", err) } @@ -97,24 +97,24 @@ workflow_echo: } func TestDeleteWorkflow(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/workflows/604a3a1e-94e3-4066-a34a-aa56873ef236", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/workflows/604a3a1e-94e3-4066-a34a-aa56873ef236", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.WriteHeader(http.StatusAccepted) }) - res := workflows.Delete(context.TODO(), client.ServiceClient(), "604a3a1e-94e3-4066-a34a-aa56873ef236") + res := workflows.Delete(context.TODO(), client.ServiceClient(fakeServer), "604a3a1e-94e3-4066-a34a-aa56873ef236") th.AssertNoErr(t, res.Err) } func TestGetWorkflow(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - th.Mux.HandleFunc("/workflows/1", func(w http.ResponseWriter, r *http.Request) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + fakeServer.Mux.HandleFunc("/workflows/1", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-token", client.TokenID) w.Header().Add("Content-Type", "application/json") @@ -133,7 +133,7 @@ func TestGetWorkflow(t *testing.T) { } `) }) - actual, err := workflows.Get(context.TODO(), client.ServiceClient(), "1").Extract() + actual, err := workflows.Get(context.TODO(), client.ServiceClient(fakeServer), "1").Extract() if err != nil { t.Fatalf("Unable to get workflow: %v", err) } @@ -157,9 +157,9 @@ func TestGetWorkflow(t *testing.T) { } func TestListWorkflows(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - th.Mux.HandleFunc("/workflows", func(w http.ResponseWriter, r *http.Request) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + fakeServer.Mux.HandleFunc("/workflows", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) w.Header().Add("Content-Type", "application/json") @@ -185,7 +185,7 @@ func TestListWorkflows(t *testing.T) { "updated_at": "2018-09-12 15:48:17" } ] - }`, th.Server.URL) + }`, fakeServer.Server.URL) case "604a3a1e-94e3-4066-a34a-aa56873ef236": fmt.Fprint(w, `{ "workflows": [] }`) default: @@ -194,7 +194,7 @@ func TestListWorkflows(t *testing.T) { }) pages := 0 // Get all workflows - err := workflows.List(client.ServiceClient(), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := workflows.List(client.ServiceClient(fakeServer), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { pages++ actual, err := workflows.ExtractWorkflows(page) if err != nil { diff --git a/pagination/testing/linked_test.go b/pagination/testing/linked_test.go index 30f4bdbd31..ec0476c7dd 100644 --- a/pagination/testing/linked_test.go +++ b/pagination/testing/linked_test.go @@ -31,36 +31,36 @@ func ExtractLinkedInts(r pagination.Page) ([]int, error) { return s.Ints, err } -func createLinked() pagination.Pager { - th.SetupHTTP() - - th.Mux.HandleFunc("/page1", func(w http.ResponseWriter, r *http.Request) { +func createLinked(fakeServer th.FakeServer) pagination.Pager { + fakeServer.Mux.HandleFunc("/page1", func(w http.ResponseWriter, r *http.Request) { w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, `{ "ints": [1, 2, 3], "links": { "next": "%s/page2" } }`, th.Server.URL) + fmt.Fprintf(w, `{ "ints": [1, 2, 3], "links": { "next": "%s/page2" } }`, fakeServer.Server.URL) }) - th.Mux.HandleFunc("/page2", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/page2", func(w http.ResponseWriter, r *http.Request) { w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, `{ "ints": [4, 5, 6], "links": { "next": "%s/page3" } }`, th.Server.URL) + fmt.Fprintf(w, `{ "ints": [4, 5, 6], "links": { "next": "%s/page3" } }`, fakeServer.Server.URL) }) - th.Mux.HandleFunc("/page3", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/page3", func(w http.ResponseWriter, r *http.Request) { w.Header().Add("Content-Type", "application/json") fmt.Fprint(w, `{ "ints": [7, 8, 9], "links": { "next": null } }`) }) - client := client.ServiceClient() + client := client.ServiceClient(fakeServer) createPage := func(r pagination.PageResult) pagination.Page { return LinkedPageResult{pagination.LinkedPageBase{PageResult: r}} } - return pagination.NewPager(client, th.Server.URL+"/page1", createPage) + return pagination.NewPager(client, fakeServer.Server.URL+"/page1", createPage) } func TestEnumerateLinked(t *testing.T) { - pager := createLinked() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + pager := createLinked(fakeServer) callCount := 0 err := pager.EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { @@ -101,8 +101,10 @@ func TestEnumerateLinked(t *testing.T) { } func TestAllPagesLinked(t *testing.T) { - pager := createLinked() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + pager := createLinked(fakeServer) page, err := pager.AllPages(context.TODO()) th.AssertNoErr(t, err) diff --git a/pagination/testing/marker_test.go b/pagination/testing/marker_test.go index 312ba5ac0a..4c9441f370 100644 --- a/pagination/testing/marker_test.go +++ b/pagination/testing/marker_test.go @@ -37,10 +37,8 @@ func (r MarkerPageResult) LastMarker() (string, error) { return results[len(results)-1], nil } -func createMarkerPaged(t *testing.T) pagination.Pager { - th.SetupHTTP() - - th.Mux.HandleFunc("/page", func(w http.ResponseWriter, r *http.Request) { +func createMarkerPaged(t *testing.T, fakeServer th.FakeServer) pagination.Pager { + fakeServer.Mux.HandleFunc("/page", func(w http.ResponseWriter, r *http.Request) { if err := r.ParseForm(); err != nil { t.Errorf("Failed to parse request form %v", err) } @@ -59,7 +57,7 @@ func createMarkerPaged(t *testing.T) pagination.Pager { } }) - client := client.ServiceClient() + client := client.ServiceClient(fakeServer) createPage := func(r pagination.PageResult) pagination.Page { p := MarkerPageResult{pagination.MarkerPageBase{PageResult: r}} @@ -67,7 +65,7 @@ func createMarkerPaged(t *testing.T) pagination.Pager { return p } - return pagination.NewPager(client, th.Server.URL+"/page", createPage) + return pagination.NewPager(client, fakeServer.Server.URL+"/page", createPage) } func ExtractMarkerStrings(page pagination.Page) ([]string, error) { @@ -83,8 +81,10 @@ func ExtractMarkerStrings(page pagination.Page) ([]string, error) { } func TestEnumerateMarker(t *testing.T) { - pager := createMarkerPaged(t) - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + pager := createMarkerPaged(t, fakeServer) callCount := 0 err := pager.EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { @@ -118,8 +118,10 @@ func TestEnumerateMarker(t *testing.T) { } func TestAllPagesMarker(t *testing.T) { - pager := createMarkerPaged(t) - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + pager := createMarkerPaged(t, fakeServer) page, err := pager.AllPages(context.TODO()) th.AssertNoErr(t, err) diff --git a/pagination/testing/single_test.go b/pagination/testing/single_test.go index 3988e8af5d..4a7f010dc0 100644 --- a/pagination/testing/single_test.go +++ b/pagination/testing/single_test.go @@ -33,11 +33,10 @@ func ExtractSingleInts(r pagination.Page) ([]int, error) { return s.Ints, err } -func setupSinglePaged() pagination.Pager { - th.SetupHTTP() - client := client.ServiceClient() +func setupSinglePaged(fakeServer th.FakeServer) pagination.Pager { + client := client.ServiceClient(fakeServer) - th.Mux.HandleFunc("/only", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/only", func(w http.ResponseWriter, r *http.Request) { w.Header().Add("Content-Type", "application/json") fmt.Fprint(w, `{ "ints": [1, 2, 3] }`) }) @@ -46,13 +45,15 @@ func setupSinglePaged() pagination.Pager { return SinglePageResult{pagination.SinglePageBase(r)} } - return pagination.NewPager(client, th.Server.URL+"/only", createPage) + return pagination.NewPager(client, fakeServer.Server.URL+"/only", createPage) } func TestEnumerateSinglePaged(t *testing.T) { callCount := 0 - pager := setupSinglePaged() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + pager := setupSinglePaged(fakeServer) err := pager.EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { callCount++ @@ -68,8 +69,10 @@ func TestEnumerateSinglePaged(t *testing.T) { } func TestAllPagesSingle(t *testing.T) { - pager := setupSinglePaged() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + pager := setupSinglePaged(fakeServer) page, err := pager.AllPages(context.TODO()) th.AssertNoErr(t, err) diff --git a/testhelper/client/fake.go b/testhelper/client/fake.go index 29514b0a65..f6ae0b05e4 100644 --- a/testhelper/client/fake.go +++ b/testhelper/client/fake.go @@ -9,9 +9,9 @@ import ( const TokenID = "cbc36478b0bd8e67e89469c7749d4127" // ServiceClient returns a generic service client for use in tests. -func ServiceClient() *gophercloud.ServiceClient { +func ServiceClient(fakeServer th.FakeServer) *gophercloud.ServiceClient { return &gophercloud.ServiceClient{ ProviderClient: &gophercloud.ProviderClient{TokenID: TokenID}, - Endpoint: th.Endpoint(), + Endpoint: fakeServer.Endpoint(), } } diff --git a/testhelper/fixture/helper.go b/testhelper/fixture/helper.go index 7c84378770..1967b0f48d 100644 --- a/testhelper/fixture/helper.go +++ b/testhelper/fixture/helper.go @@ -9,8 +9,8 @@ import ( "github.com/gophercloud/gophercloud/v2/testhelper/client" ) -func SetupHandler(t *testing.T, url, method, requestBody, responseBody string, status int) { - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { +func SetupHandler(t *testing.T, fakeServer th.FakeServer, url, method, requestBody, responseBody string, status int) { + fakeServer.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, method) th.TestHeader(t, r, "X-Auth-Token", client.TokenID) diff --git a/testhelper/http_responses.go b/testhelper/http_responses.go index 28ecb1e53e..f57645e441 100644 --- a/testhelper/http_responses.go +++ b/testhelper/http_responses.go @@ -13,48 +13,28 @@ import ( "testing" ) -var ( +type FakeServer struct { // Mux is a multiplexer that can be used to register handlers. Mux *http.ServeMux // Server is an in-memory HTTP server for testing. Server *httptest.Server -) - -// SetupPersistentPortHTTP prepares the Mux and Server listening specific port. -func SetupPersistentPortHTTP(t *testing.T, port int) { - l, err := net.Listen("tcp", fmt.Sprintf("127.0.0.1:%d", port)) - if err != nil { - t.Errorf("Failed to listen to 127.0.0.1:%d: %s", port, err) - } - Mux = http.NewServeMux() - Server = httptest.NewUnstartedServer(Mux) - Server.Listener = l - Server.Start() -} - -// SetupHTTP prepares the Mux and Server. -func SetupHTTP() { - Mux = http.NewServeMux() - Server = httptest.NewServer(Mux) } -// TeardownHTTP releases HTTP-related resources. -func TeardownHTTP() { - Server.Close() +func (fakeServer FakeServer) Teardown() { + fakeServer.Server.Close() } -// Endpoint returns a fake endpoint that will actually target the Mux. -func Endpoint() string { - return Server.URL + "/" +func (fakeServer FakeServer) Endpoint() string { + return fakeServer.Server.URL + "/" } // Serves a static content at baseURL/relPath -func ServeFile(t *testing.T, baseURL, relPath, contentType, content string) string { +func (fakeServer FakeServer) ServeFile(t *testing.T, baseURL, relPath, contentType, content string) string { rawURL := strings.Join([]string{baseURL, relPath}, "/") parsedURL, err := url.Parse(rawURL) AssertNoErr(t, err) - Mux.HandleFunc(parsedURL.Path, func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc(parsedURL.Path, func(w http.ResponseWriter, r *http.Request) { TestMethod(t, r, "GET") w.Header().Set("Content-Type", contentType) w.WriteHeader(http.StatusOK) @@ -64,6 +44,34 @@ func ServeFile(t *testing.T, baseURL, relPath, contentType, content string) stri return rawURL } +// SetupPersistentPortHTTP prepares the Mux and Server listening specific port. +func SetupPersistentPortHTTP(t *testing.T, port int) FakeServer { + mux := http.NewServeMux() + server := httptest.NewUnstartedServer(mux) + l, err := net.Listen("tcp", fmt.Sprintf("127.0.0.1:%d", port)) + if err != nil { + t.Errorf("Failed to listen to 127.0.0.1:%d: %s", port, err) + } + server.Listener = l + server.Start() + + return FakeServer{ + Mux: mux, + Server: server, + } +} + +// SetupHTTP prepares the Mux and Server. +func SetupHTTP() FakeServer { + mux := http.NewServeMux() + server := httptest.NewServer(mux) + + return FakeServer{ + Mux: mux, + Server: server, + } +} + // TestFormValues ensures that all the URL parameters given to the http.Request are the same as values. func TestFormValues(t *testing.T, r *http.Request, values map[string]string) { want := url.Values{} diff --git a/testing/provider_client_test.go b/testing/provider_client_test.go index 44fc37756c..900d53021a 100644 --- a/testing/provider_client_test.go +++ b/testing/provider_client_test.go @@ -79,10 +79,10 @@ func TestConcurrentReauth(t *testing.T) { return nil } - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/route", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/route", func(w http.ResponseWriter, r *http.Request) { if r.Header.Get("X-Auth-Token") != postreauthTok { w.WriteHeader(http.StatusUnauthorized) info.mut.Lock() @@ -113,7 +113,7 @@ func TestConcurrentReauth(t *testing.T) { wg.Add(1) go func() { defer wg.Done() - resp, err := p.Request(context.TODO(), "GET", fmt.Sprintf("%s/route", th.Endpoint()), reqopts) + resp, err := p.Request(context.TODO(), "GET", fmt.Sprintf("%s/route", fakeServer.Endpoint()), reqopts) th.CheckNoErr(t, err) if resp == nil { t.Errorf("got a nil response") @@ -171,10 +171,10 @@ func TestReauthEndLoop(t *testing.T) { return nil } - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/route", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/route", func(w http.ResponseWriter, r *http.Request) { // route always return 401 w.WriteHeader(http.StatusUnauthorized) }) @@ -190,7 +190,7 @@ func TestReauthEndLoop(t *testing.T) { wg.Add(1) go func() { defer wg.Done() - _, err := p.Request(context.TODO(), "GET", fmt.Sprintf("%s/route", th.Endpoint()), reqopts) + _, err := p.Request(context.TODO(), "GET", fmt.Sprintf("%s/route", fakeServer.Endpoint()), reqopts) mut.Lock() defer mut.Unlock() @@ -256,10 +256,10 @@ func TestRequestThatCameDuringReauthWaitsUntilItIsCompleted(t *testing.T) { return nil } - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/route", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/route", func(w http.ResponseWriter, r *http.Request) { if r.Header.Get("X-Auth-Token") != postreauthTok { info.mut.Lock() info.failedAuths++ @@ -293,7 +293,7 @@ func TestRequestThatCameDuringReauthWaitsUntilItIsCompleted(t *testing.T) { if i != 0 { <-info.reauthCh } - resp, err := p.Request(context.TODO(), "GET", fmt.Sprintf("%s/route", th.Endpoint()), reqopts) + resp, err := p.Request(context.TODO(), "GET", fmt.Sprintf("%s/route", fakeServer.Endpoint()), reqopts) th.CheckNoErr(t, err) if resp == nil { t.Errorf("got a nil response") @@ -339,13 +339,13 @@ func TestRequestReauthsAtMostOnce(t *testing.T) { return nil } - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() requestCounter := 0 var requestCounterMutex sync.Mutex - th.Mux.HandleFunc("/route", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/route", func(w http.ResponseWriter, r *http.Request) { requestCounterMutex.Lock() requestCounter++ //avoid infinite loop @@ -363,7 +363,7 @@ func TestRequestReauthsAtMostOnce(t *testing.T) { // the part before the colon), but when encountering another 401 response, we // did not attempt reauthentication again and just passed that 401 response to // the caller as ErrDefault401. - _, err := p.Request(context.TODO(), "GET", th.Endpoint()+"/route", &gophercloud.RequestOpts{}) + _, err := p.Request(context.TODO(), "GET", fakeServer.Endpoint()+"/route", &gophercloud.RequestOpts{}) expectedErrorRx := regexp.MustCompile(`^Successfully re-authenticated, but got error executing request: Expected HTTP response code \[200\] when accessing \[GET http://[^/]*//route\], but got 401 instead: unauthorized$`) if !expectedErrorRx.MatchString(err.Error()) { t.Errorf("expected error that looks like %q, but got %q", expectedErrorRx.String(), err.Error()) @@ -501,17 +501,17 @@ func TestRequestRetry(t *testing.T) { p.RetryBackoffFunc = retryBackoffTest(&retryCounter, t) - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/route", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/route", func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Retry-After", "1") //always reply 429 http.Error(w, "retry later", http.StatusTooManyRequests) }) - _, err := p.Request(context.TODO(), "GET", th.Endpoint()+"/route", &gophercloud.RequestOpts{}) + _, err := p.Request(context.TODO(), "GET", fakeServer.Endpoint()+"/route", &gophercloud.RequestOpts{}) if err == nil { t.Fatal("expecting error, got nil") } @@ -528,17 +528,17 @@ func TestRequestRetryHTTPDate(t *testing.T) { p.RetryBackoffFunc = retryBackoffTest(&retryCounter, t) - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/route", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/route", func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Retry-After", time.Now().Add(1*time.Second).UTC().Format(http.TimeFormat)) //always reply 429 http.Error(w, "retry later", http.StatusTooManyRequests) }) - _, err := p.Request(context.TODO(), "GET", th.Endpoint()+"/route", &gophercloud.RequestOpts{}) + _, err := p.Request(context.TODO(), "GET", fakeServer.Endpoint()+"/route", &gophercloud.RequestOpts{}) if err == nil { t.Fatal("expecting error, got nil") } @@ -555,17 +555,17 @@ func TestRequestRetryError(t *testing.T) { p.RetryBackoffFunc = retryBackoffTest(&retryCounter, t) - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/route", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/route", func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Retry-After", "foo bar") //always reply 429 http.Error(w, "retry later", http.StatusTooManyRequests) }) - _, err := p.Request(context.TODO(), "GET", th.Endpoint()+"/route", &gophercloud.RequestOpts{}) + _, err := p.Request(context.TODO(), "GET", fakeServer.Endpoint()+"/route", &gophercloud.RequestOpts{}) if err == nil { t.Fatal("expecting error, got nil") } @@ -582,15 +582,15 @@ func TestRequestRetrySuccess(t *testing.T) { p.RetryBackoffFunc = retryBackoffTest(&retryCounter, t) - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/route", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/route", func(w http.ResponseWriter, r *http.Request) { //always reply 200 http.Error(w, "retry later", http.StatusOK) }) - _, err := p.Request(context.TODO(), "GET", th.Endpoint()+"/route", &gophercloud.RequestOpts{}) + _, err := p.Request(context.TODO(), "GET", fakeServer.Endpoint()+"/route", &gophercloud.RequestOpts{}) if err != nil { t.Fatal(err) } @@ -614,17 +614,17 @@ func TestRequestRetryContext(t *testing.T) { p.RetryBackoffFunc = retryBackoffTest(&retryCounter, t) - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/route", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/route", func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Retry-After", "1") //always reply 429 http.Error(w, "retry later", http.StatusTooManyRequests) }) - _, err := p.Request(ctx, "GET", th.Endpoint()+"/route", &gophercloud.RequestOpts{}) + _, err := p.Request(ctx, "GET", fakeServer.Endpoint()+"/route", &gophercloud.RequestOpts{}) if err == nil { t.Fatal("expecting error, got nil") } @@ -643,11 +643,11 @@ func TestRequestGeneralRetry(t *testing.T) { return nil } - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() count := 0 - th.Mux.HandleFunc("/route", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/route", func(w http.ResponseWriter, r *http.Request) { if count < 3 { http.Error(w, "bad gateway", http.StatusBadGateway) count += 1 @@ -656,7 +656,7 @@ func TestRequestGeneralRetry(t *testing.T) { } }) - _, err := p.Request(context.TODO(), "GET", th.Endpoint()+"/route", &gophercloud.RequestOpts{}) + _, err := p.Request(context.TODO(), "GET", fakeServer.Endpoint()+"/route", &gophercloud.RequestOpts{}) if err != nil { t.Fatal("expecting nil, got err") } @@ -671,11 +671,11 @@ func TestRequestGeneralRetryAbort(t *testing.T) { return err } - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() count := 0 - th.Mux.HandleFunc("/route", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/route", func(w http.ResponseWriter, r *http.Request) { if count < 3 { http.Error(w, "bad gateway", http.StatusBadGateway) count += 1 @@ -684,7 +684,7 @@ func TestRequestGeneralRetryAbort(t *testing.T) { } }) - _, err := p.Request(context.TODO(), "GET", th.Endpoint()+"/route", &gophercloud.RequestOpts{}) + _, err := p.Request(context.TODO(), "GET", fakeServer.Endpoint()+"/route", &gophercloud.RequestOpts{}) if err == nil { t.Fatal("expecting err, got nil") } diff --git a/testing/service_client_test.go b/testing/service_client_test.go index 6253b698d2..6d409d20e3 100644 --- a/testing/service_client_test.go +++ b/testing/service_client_test.go @@ -18,9 +18,9 @@ func TestServiceURL(t *testing.T) { } func TestMoreHeaders(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - th.Mux.HandleFunc("/route", func(w http.ResponseWriter, r *http.Request) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + fakeServer.Mux.HandleFunc("/route", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) }) @@ -29,7 +29,7 @@ func TestMoreHeaders(t *testing.T) { "custom": "header", } c.ProviderClient = new(gophercloud.ProviderClient) - resp, err := c.Get(context.TODO(), fmt.Sprintf("%s/route", th.Endpoint()), nil, nil) + resp, err := c.Get(context.TODO(), fmt.Sprintf("%s/route", fakeServer.Endpoint()), nil, nil) th.AssertNoErr(t, err) th.AssertEquals(t, resp.Request.Header.Get("custom"), "header") } From edf832fc2fd4f413a0ecbbd835cde6601f9804e1 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Tue, 20 May 2025 17:41:41 +0100 Subject: [PATCH 160/353] Randomize test order for unit tests I don't know why this isn't the default behavior, but relying on test order is a bad idea (TM) that we should do our best to avoid. Signed-off-by: Stephen Finucane (cherry picked from commit 9251e9993d63acc49bec6edd7667bd25a830bf03) --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 7aa2ac3e9f..c63adb8d03 100644 --- a/Makefile +++ b/Makefile @@ -36,11 +36,11 @@ format: .PHONY: format unit: - $(GO_TEST) ./... + $(GO_TEST) -shuffle on ./... .PHONY: unit coverage: - $(GO_TEST) -covermode count -coverprofile cover.out -coverpkg=./... ./... + $(GO_TEST) -shuffle on -covermode count -coverprofile cover.out -coverpkg=./... ./... .PHONY: coverage acceptance: acceptance-basic acceptance-baremetal acceptance-blockstorage acceptance-compute acceptance-container acceptance-containerinfra acceptance-db acceptance-dns acceptance-identity acceptance-image acceptance-keymanager acceptance-loadbalancer acceptance-messaging acceptance-networking acceptance-objectstorage acceptance-orchestration acceptance-placement acceptance-sharedfilesystems acceptance-workflow From 25b00f32d3b323c3ca6bfbfb936acf84f1fdf4ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sandro=20J=C3=A4ckel?= Date: Tue, 15 Feb 2022 11:07:19 +0100 Subject: [PATCH 161/353] dns: add support for /v2/quotas Co-Authored-By: Pierre Prinetti --- .../openstack/dns/v2/quotas_test.go | 52 +++++++++++++++ openstack/dns/v2/quotas/doc.go | 28 +++++++++ openstack/dns/v2/quotas/requests.go | 49 +++++++++++++++ openstack/dns/v2/quotas/results.go | 28 +++++++++ openstack/dns/v2/quotas/testing/doc.go | 2 + .../dns/v2/quotas/testing/fixtures_test.go | 63 +++++++++++++++++++ .../dns/v2/quotas/testing/requests_test.go | 35 +++++++++++ openstack/dns/v2/quotas/urls.go | 7 +++ 8 files changed, 264 insertions(+) create mode 100644 internal/acceptance/openstack/dns/v2/quotas_test.go create mode 100644 openstack/dns/v2/quotas/doc.go create mode 100644 openstack/dns/v2/quotas/requests.go create mode 100644 openstack/dns/v2/quotas/results.go create mode 100644 openstack/dns/v2/quotas/testing/doc.go create mode 100644 openstack/dns/v2/quotas/testing/fixtures_test.go create mode 100644 openstack/dns/v2/quotas/testing/requests_test.go create mode 100644 openstack/dns/v2/quotas/urls.go diff --git a/internal/acceptance/openstack/dns/v2/quotas_test.go b/internal/acceptance/openstack/dns/v2/quotas_test.go new file mode 100644 index 0000000000..673d9c9761 --- /dev/null +++ b/internal/acceptance/openstack/dns/v2/quotas_test.go @@ -0,0 +1,52 @@ +//go:build acceptance || dns || quotas + +package v2 + +import ( + "context" + "testing" + + "github.com/gophercloud/gophercloud/v2/internal/acceptance/clients" + identity "github.com/gophercloud/gophercloud/v2/internal/acceptance/openstack/identity/v3" + "github.com/gophercloud/gophercloud/v2/internal/acceptance/tools" + "github.com/gophercloud/gophercloud/v2/openstack/dns/v2/quotas" + th "github.com/gophercloud/gophercloud/v2/testhelper" +) + +func TestQuotaGetUpdate(t *testing.T) { + clients.RequireAdmin(t) + + client, err := clients.NewDNSV2Client() + th.AssertNoErr(t, err) + + identityClient, err := clients.NewIdentityV3Client() + th.AssertNoErr(t, err) + + project, err := identity.CreateProject(t, identityClient, nil) + th.AssertNoErr(t, err) + defer identity.DeleteProject(t, identityClient, project.ID) + + // use DNS specific header to set the project ID + client.MoreHeaders = map[string]string{ + "X-Auth-Sudo-Tenant-ID": project.ID, + } + + // test Get Quota + quota, err := quotas.Get(context.TODO(), client, project.ID).Extract() + th.AssertNoErr(t, err) + + tools.PrintResource(t, quota) + + // test Update Quota + zones := 9 + updateOpts := quotas.UpdateOpts{ + Zones: &zones, + } + res, err := quotas.Update(context.TODO(), client, project.ID, updateOpts).Extract() + th.AssertNoErr(t, err) + + tools.PrintResource(t, res) + + quota.Zones = zones + th.AssertDeepEquals(t, *quota, *res) +} diff --git a/openstack/dns/v2/quotas/doc.go b/openstack/dns/v2/quotas/doc.go new file mode 100644 index 0000000000..a0c6973ea3 --- /dev/null +++ b/openstack/dns/v2/quotas/doc.go @@ -0,0 +1,28 @@ +/* +Package quotas provides the ability to retrieve DNS quotas through the Designate API. + +Example to Get a Quota Set + + projectID = "23d5d3f79dfa4f73b72b8b0b0063ec55" + quotasInfo, err := quotas.Get(context.TODO(), dnsClient, projectID).Extract() + if err != nil { + log.Fatal(err) + } + + fmt.Printf("quotas: %#v\n", quotasInfo) + +Example to Update a Quota Set + + projectID = "23d5d3f79dfa4f73b72b8b0b0063ec55" + zones := 10 + quota := "as.UpdateOpts{ + Zones: &zones, + } + quotasInfo, err := quotas.Update(context.TODO(), dnsClient, projectID, quota).Extract() + if err != nil { + log.Fatal(err) + } + + fmt.Printf("quotas: %#v\n", quotasInfo) +*/ +package quotas diff --git a/openstack/dns/v2/quotas/requests.go b/openstack/dns/v2/quotas/requests.go new file mode 100644 index 0000000000..25a8ac2381 --- /dev/null +++ b/openstack/dns/v2/quotas/requests.go @@ -0,0 +1,49 @@ +package quotas + +import ( + "context" + + "github.com/gophercloud/gophercloud/v2" +) + +// Get returns information about the quota for a given project ID. +func Get(ctx context.Context, client *gophercloud.ServiceClient, projectID string) (r Result) { + resp, err := client.Get(ctx, URL(client, projectID), &r.Body, nil) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} + +// UpdateOptsBuilder allows extensions to add additional parameters to the +// Update request. +type UpdateOptsBuilder interface { + ToQuotaUpdateMap() (map[string]interface{}, error) +} + +// UpdateOpts represents options used to update the DNS Quotas. +type UpdateOpts struct { + APIExporterSize *int `json:"api_export_size,omitempty"` + RecordsetRecords *int `json:"recordset_records,omitempty"` + ZoneRecords *int `json:"zone_records,omitempty"` + ZoneRecordsets *int `json:"zone_recordsets,omitempty"` + Zones *int `json:"zones,omitempty"` +} + +// ToQuotaUpdateMap builds a request body from UpdateOpts. +func (opts UpdateOpts) ToQuotaUpdateMap() (map[string]interface{}, error) { + return gophercloud.BuildRequestBody(opts, "") +} + +// Update accepts a UpdateOpts struct and updates an existing DNS Quotas using the +// values provided. +func Update(ctx context.Context, c *gophercloud.ServiceClient, projectID string, opts UpdateOptsBuilder) (r Result) { + b, err := opts.ToQuotaUpdateMap() + if err != nil { + r.Err = err + return + } + resp, err := c.Patch(ctx, URL(c, projectID), b, &r.Body, &gophercloud.RequestOpts{ + OkCodes: []int{200}, + }) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} diff --git a/openstack/dns/v2/quotas/results.go b/openstack/dns/v2/quotas/results.go new file mode 100644 index 0000000000..cd9c5da69d --- /dev/null +++ b/openstack/dns/v2/quotas/results.go @@ -0,0 +1,28 @@ +package quotas + +import ( + "github.com/gophercloud/gophercloud/v2" +) + +// Extract interprets a GetResult, CreateResult or UpdateResult as a Quota. +// An error is returned if the original call or the extraction failed. +func (r Result) Extract() (*Quota, error) { + var s *Quota + err := r.ExtractInto(&s) + return s, err +} + +// ListResult is the result of a Create request. Call its Extract method +// to interpret the result as a Zone. +type Result struct { + gophercloud.Result +} + +// Quota represents a quotas on the system. +type Quota struct { + APIExporterSize int `json:"api_export_size"` + RecordsetRecords int `json:"recordset_records"` + ZoneRecords int `json:"zone_records"` + ZoneRecordsets int `json:"zone_recordsets"` + Zones int `json:"zones"` +} diff --git a/openstack/dns/v2/quotas/testing/doc.go b/openstack/dns/v2/quotas/testing/doc.go new file mode 100644 index 0000000000..b9b6286d75 --- /dev/null +++ b/openstack/dns/v2/quotas/testing/doc.go @@ -0,0 +1,2 @@ +// zones unit tests +package testing diff --git a/openstack/dns/v2/quotas/testing/fixtures_test.go b/openstack/dns/v2/quotas/testing/fixtures_test.go new file mode 100644 index 0000000000..a1058bdf00 --- /dev/null +++ b/openstack/dns/v2/quotas/testing/fixtures_test.go @@ -0,0 +1,63 @@ +package testing + +import ( + "fmt" + "net/http" + "testing" + + th "github.com/gophercloud/gophercloud/v2/testhelper" + "github.com/gophercloud/gophercloud/v2/testhelper/client" + + "github.com/gophercloud/gophercloud/v2/openstack/dns/v2/quotas" +) + +// List Output is a sample response to a List call. +const QuotaOutput = ` +{ + "api_export_size": 1000, + "recordset_records": 20, + "zone_records": 500, + "zone_recordsets": 500, + "zones": 100 +} +` + +// UpdateQuotaRequest is a sample request body for updating quotas. +const UpdateQuotaRequest = ` +{ + "zones": 100 +} +` + +var ( + Quota = "as.Quota{ + APIExporterSize: 1000, + RecordsetRecords: 20, + ZoneRecords: 500, + ZoneRecordsets: 500, + Zones: 100, + } +) + +// HandleGetSuccessfully configures the test server to respond to a Get request. +func HandleGetSuccessfully(t *testing.T) { + th.Mux.HandleFunc("/quotas/a86dba58-0043-4cc6-a1bb-69d5e86f3ca3", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.Header().Add("Content-Type", "application/json") + fmt.Fprint(w, QuotaOutput) + }) +} + +// HandleUpdateSuccessfully configures the test server to respond to an Update request. +func HandleUpdateSuccessfully(t *testing.T) { + th.Mux.HandleFunc("/quotas/a86dba58-0043-4cc6-a1bb-69d5e86f3ca3", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "PATCH") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.TestJSONRequest(t, r, UpdateQuotaRequest) + + w.Header().Add("Content-Type", "application/json") + fmt.Fprint(w, QuotaOutput) + }) +} diff --git a/openstack/dns/v2/quotas/testing/requests_test.go b/openstack/dns/v2/quotas/testing/requests_test.go new file mode 100644 index 0000000000..c60c5e2ad1 --- /dev/null +++ b/openstack/dns/v2/quotas/testing/requests_test.go @@ -0,0 +1,35 @@ +package testing + +import ( + "context" + "testing" + + "github.com/gophercloud/gophercloud/v2/openstack/dns/v2/quotas" + th "github.com/gophercloud/gophercloud/v2/testhelper" + "github.com/gophercloud/gophercloud/v2/testhelper/client" +) + +func TestGet(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + HandleGetSuccessfully(t) + + actual, err := quotas.Get(context.TODO(), client.ServiceClient(), "a86dba58-0043-4cc6-a1bb-69d5e86f3ca3").Extract() + th.AssertNoErr(t, err) + th.CheckDeepEquals(t, Quota, actual) +} + +func TestUpdate(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + HandleUpdateSuccessfully(t) + + zones := 100 + updateOpts := quotas.UpdateOpts{ + Zones: &zones, + } + + actual, err := quotas.Update(context.TODO(), client.ServiceClient(), "a86dba58-0043-4cc6-a1bb-69d5e86f3ca3", updateOpts).Extract() + th.AssertNoErr(t, err) + th.CheckDeepEquals(t, Quota, actual) +} diff --git a/openstack/dns/v2/quotas/urls.go b/openstack/dns/v2/quotas/urls.go new file mode 100644 index 0000000000..e60ba18292 --- /dev/null +++ b/openstack/dns/v2/quotas/urls.go @@ -0,0 +1,7 @@ +package quotas + +import "github.com/gophercloud/gophercloud/v2" + +func URL(c *gophercloud.ServiceClient, projectID string) string { + return c.ServiceURL("quotas", projectID) +} From 5477f7f3329fe3b15f1b1c133e820117a7abdfca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?p=C3=BDrus?= Date: Fri, 13 Jun 2025 13:47:00 +0200 Subject: [PATCH 162/353] neutron: add segments extension package --- .../v2/extensions/segments/segments.go | 48 +++++++ .../v2/extensions/segments/segments_test.go | 58 ++++++++ .../v2/extensions/segments/requests.go | 125 +++++++++++++++++ .../v2/extensions/segments/results.go | 78 +++++++++++ .../extensions/segments/testing/fixtures.go | 116 ++++++++++++++++ .../segments/testing/requests_test.go | 127 ++++++++++++++++++ .../networking/v2/extensions/segments/urls.go | 13 ++ 7 files changed, 565 insertions(+) create mode 100644 internal/acceptance/openstack/networking/v2/extensions/segments/segments.go create mode 100644 internal/acceptance/openstack/networking/v2/extensions/segments/segments_test.go create mode 100644 openstack/networking/v2/extensions/segments/requests.go create mode 100644 openstack/networking/v2/extensions/segments/results.go create mode 100644 openstack/networking/v2/extensions/segments/testing/fixtures.go create mode 100644 openstack/networking/v2/extensions/segments/testing/requests_test.go create mode 100644 openstack/networking/v2/extensions/segments/urls.go diff --git a/internal/acceptance/openstack/networking/v2/extensions/segments/segments.go b/internal/acceptance/openstack/networking/v2/extensions/segments/segments.go new file mode 100644 index 0000000000..e7f9c6ccad --- /dev/null +++ b/internal/acceptance/openstack/networking/v2/extensions/segments/segments.go @@ -0,0 +1,48 @@ +package segments + +import ( + "context" + "testing" + + "github.com/gophercloud/gophercloud/v2" + "github.com/gophercloud/gophercloud/v2/internal/acceptance/tools" + "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/extensions/segments" + th "github.com/gophercloud/gophercloud/v2/testhelper" +) + +func CreateSegment(t *testing.T, client *gophercloud.ServiceClient, networkID string) (*segments.Segment, error) { + name := tools.RandomString("TESTACC-SEGMENT-", 8) + desc := "test segment description" + + opts := segments.CreateOpts{ + NetworkID: networkID, + NetworkType: "geneve", + Name: name, + Description: desc, + } + + segment, err := segments.Create(context.TODO(), client, opts).Extract() + if err != nil { + return nil, err + } + + tools.PrintResource(t, segment) + + th.AssertEquals(t, segment.Name, name) + th.AssertEquals(t, segment.Description, desc) + th.AssertEquals(t, segment.NetworkType, "geneve") + th.AssertEquals(t, segment.NetworkID, networkID) + + return segment, nil +} + +func DeleteSegment(t *testing.T, client *gophercloud.ServiceClient, segmentID string) { + t.Logf("Attempting to delete segment %s", segmentID) + + err := segments.Delete(context.TODO(), client, segmentID).ExtractErr() + if err != nil { + t.Fatalf("Failed to delete segment %s: %v", segmentID, err) + } + + t.Logf("Deleted segment %s", segmentID) +} diff --git a/internal/acceptance/openstack/networking/v2/extensions/segments/segments_test.go b/internal/acceptance/openstack/networking/v2/extensions/segments/segments_test.go new file mode 100644 index 0000000000..8caff205bb --- /dev/null +++ b/internal/acceptance/openstack/networking/v2/extensions/segments/segments_test.go @@ -0,0 +1,58 @@ +//go:build acceptance || networking || segments + +package segments + +import ( + "context" + "testing" + + "github.com/gophercloud/gophercloud/v2/internal/acceptance/clients" + networking "github.com/gophercloud/gophercloud/v2/internal/acceptance/openstack/networking/v2" + "github.com/gophercloud/gophercloud/v2/internal/acceptance/tools" + "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/extensions/segments" + th "github.com/gophercloud/gophercloud/v2/testhelper" +) + +func TestSegmentCRUD(t *testing.T) { + clients.RequireAdmin(t) + + client, err := clients.NewNetworkV2Client() + th.AssertNoErr(t, err) + + // Skip these tests if we don't have the required extension + networking.RequireNeutronExtension(t, client, "segment") + + network, err := networking.CreateNetwork(t, client) + th.AssertNoErr(t, err) + defer networking.DeleteNetwork(t, client, network.ID) + + segment, err := CreateSegment(t, client, network.ID) + th.AssertNoErr(t, err) + defer DeleteSegment(t, client, segment.ID) + + // Get + segGet, err := segments.Get(context.TODO(), client, segment.ID).Extract() + th.AssertNoErr(t, err) + th.AssertEquals(t, segment.ID, segGet.ID) + + // Update + newName := tools.RandomString("UPDATED-SEGMENT-", 8) + newDesc := "updated description" + updateOpts := segments.UpdateOpts{ + Name: &newName, + Description: &newDesc, + } + segUpdated, err := segments.Update(context.TODO(), client, segment.ID, updateOpts).Extract() + th.AssertNoErr(t, err) + th.AssertEquals(t, newName, segUpdated.Name) + th.AssertEquals(t, newDesc, segUpdated.Description) + + // List + allPages, err := segments.List(client, nil).AllPages(context.TODO()) + th.AssertNoErr(t, err) + allSegments, err := segments.ExtractSegments(allPages) + th.AssertNoErr(t, err) + th.AssertIntGreaterOrEqual(t, len(allSegments), 1) + t.Logf("Found %d segments", len(allSegments)) + tools.PrintResource(t, allSegments) +} diff --git a/openstack/networking/v2/extensions/segments/requests.go b/openstack/networking/v2/extensions/segments/requests.go new file mode 100644 index 0000000000..926c5d854d --- /dev/null +++ b/openstack/networking/v2/extensions/segments/requests.go @@ -0,0 +1,125 @@ +package segments + +import ( + "context" + + "github.com/gophercloud/gophercloud/v2" + "github.com/gophercloud/gophercloud/v2/pagination" +) + +// ListOpts allows filtering when listing segments. +type ListOpts struct { + Name string `q:"name"` + Description string `q:"description"` + NetworkID string `q:"network_id"` + PhysicalNetwork string `q:"physical_network"` + NetworkType string `q:"network_type"` + SegmentationID int `q:"segmentation_id"` + RevisionNumber int `q:"revision_number"` + SortDir string `q:"sort_dir"` + SortKey string `q:"sort_key"` + Fields string `q:"fields"` +} + +// ListOptsBuilder interface for listing. +type ListOptsBuilder interface { + ToSegmentListQuery() (string, error) +} + +func (opts ListOpts) ToSegmentListQuery() (string, error) { + q, err := gophercloud.BuildQueryString(opts) + if err != nil { + return "", err + } + return q.String(), nil +} + +// List all segments. +func List(c *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { + url := rootURL(c) + if opts != nil { + query, err := opts.ToSegmentListQuery() + if err != nil { + return pagination.Pager{Err: err} + } + url += query + } + return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page { + return SegmentPage{LinkedPageBase: pagination.LinkedPageBase{PageResult: r}} + }) +} + +// CreateOptsBuilder allows extensions to add additional parameters. +type CreateOptsBuilder interface { + ToSegmentCreateMap() (map[string]any, error) +} + +// CreateOpts contains the fields needed for creating a segment. +type CreateOpts struct { + Name string `json:"name,omitempty"` + Description string `json:"description,omitempty"` + NetworkID string `json:"network_id" required:"true"` + NetworkType string `json:"network_type" required:"true"` + PhysicalNetwork string `json:"physical_network,omitempty"` + SegmentationID int `json:"segmentation_id,omitempty"` +} + +func (opts CreateOpts) ToSegmentCreateMap() (map[string]any, error) { + return gophercloud.BuildRequestBody(opts, "segment") +} + +// Create a new segment. +func Create(ctx context.Context, c *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { + b, err := opts.ToSegmentCreateMap() + if err != nil { + r.Err = err + return + } + resp, err := c.Post(ctx, rootURL(c), b, &r.Body, nil) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} + +// Get retrieves a segment by ID. +func Get(ctx context.Context, c *gophercloud.ServiceClient, id string) (r GetResult) { + resp, err := c.Get(ctx, resourceURL(c, id), &r.Body, nil) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} + +// Delete removes a segment by ID. +func Delete(ctx context.Context, c *gophercloud.ServiceClient, id string) (r DeleteResult) { + resp, err := c.Delete(ctx, resourceURL(c, id), nil) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} + +// UpdateOpts contains fields to update a segment. +type UpdateOpts struct { + Name *string `json:"name,omitempty"` + Description *string `json:"description,omitempty"` + SegmentationID *int `json:"segmentation_id,omitempty"` +} + +// UpdateOptsBuilder is the interface for update options. +type UpdateOptsBuilder interface { + ToSegmentUpdateMap() (map[string]any, error) +} + +func (opts UpdateOpts) ToSegmentUpdateMap() (map[string]any, error) { + return gophercloud.BuildRequestBody(opts, "segment") +} + +// Update a segment. +func Update(ctx context.Context, c *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) { + b, err := opts.ToSegmentUpdateMap() + if err != nil { + r.Err = err + return + } + resp, err := c.Put(ctx, resourceURL(c, id), b, &r.Body, &gophercloud.RequestOpts{ + OkCodes: []int{200}, + }) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} diff --git a/openstack/networking/v2/extensions/segments/results.go b/openstack/networking/v2/extensions/segments/results.go new file mode 100644 index 0000000000..8e940c60a3 --- /dev/null +++ b/openstack/networking/v2/extensions/segments/results.go @@ -0,0 +1,78 @@ +package segments + +import ( + "time" + + "github.com/gophercloud/gophercloud/v2" + "github.com/gophercloud/gophercloud/v2/pagination" +) + +// Segment model +type Segment struct { + ID string `json:"id"` + Name string `json:"name"` + Description string `json:"description"` + NetworkID string `json:"network_id"` + NetworkType string `json:"network_type"` + PhysicalNetwork string `json:"physical_network"` + SegmentationID int `json:"segmentation_id"` + RevisionNumber int `json:"revision_number"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` +} + +// SegmentPage wraps a page of segments. +type SegmentPage struct { + pagination.LinkedPageBase +} + +func (r SegmentPage) IsEmpty() (bool, error) { + if r.StatusCode == 204 { + return true, nil + } + + is, err := ExtractSegments(r) + return len(is) == 0, err +} + +func ExtractSegments(r pagination.Page) ([]Segment, error) { + var s []Segment + err := ExtractSegmentsInto(r, &s) + return s, err +} + +// ExtractSegmentsInto extracts the elements into a slice of Segment structs. +func ExtractSegmentsInto(r pagination.Page, v any) error { + return r.(SegmentPage).ExtractIntoSlicePtr(v, "segments") +} + +// Segment results +type commonResult struct { + gophercloud.Result +} + +func (r commonResult) Extract() (*Segment, error) { + var s Segment + err := r.ExtractInto(&s) + return &s, err +} + +func (r commonResult) ExtractInto(v any) error { + return r.ExtractIntoStructPtr(v, "segment") +} + +type GetResult struct { + commonResult +} + +type CreateResult struct { + commonResult +} + +type UpdateResult struct { + commonResult +} + +type DeleteResult struct { + gophercloud.ErrResult +} diff --git a/openstack/networking/v2/extensions/segments/testing/fixtures.go b/openstack/networking/v2/extensions/segments/testing/fixtures.go new file mode 100644 index 0000000000..1394fa9aea --- /dev/null +++ b/openstack/networking/v2/extensions/segments/testing/fixtures.go @@ -0,0 +1,116 @@ +package testing + +import ( + "time" + + "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/extensions/segments" +) + +var ( + SegmentID1 = "a5e3a494-26ee-4fde-ad26-2d846c47072e" + SegmentID2 = "e75ff709-fd25-47f8-ad89-aa6404d74fa8" + + Segment1 = segments.Segment{ + ID: "a5e3a494-26ee-4fde-ad26-2d846c47072e", + NetworkID: "f35f300f-8c26-4d51-a0b0-84e2fff14307", + Name: "seg1", + Description: "desc", + PhysicalNetwork: "public", + NetworkType: "flat", + SegmentationID: 0, + RevisionNumber: 1, + CreatedAt: time.Date(2025, 6, 13, 10, 36, 52, 0, time.UTC), + UpdatedAt: time.Date(2025, 6, 13, 10, 36, 52, 0, time.UTC), + } + + Segment2 = segments.Segment{ + ID: "e75ff709-fd25-47f8-ad89-aa6404d74fa8", + NetworkID: "7a7f34de-4dcc-4211-85da-a3afefc8f990", + Name: "", + Description: "", + PhysicalNetwork: "", + NetworkType: "geneve", + SegmentationID: 35745, + RevisionNumber: 0, + CreatedAt: time.Date(2025, 6, 13, 10, 36, 45, 0, time.UTC), + UpdatedAt: time.Date(2025, 6, 13, 10, 36, 45, 0, time.UTC), + } + + SegmentsListBody = ` +{ + "segments": [ + { + "id": "a5e3a494-26ee-4fde-ad26-2d846c47072e", + "network_id": "f35f300f-8c26-4d51-a0b0-84e2fff14307", + "name": "seg1", + "description": "desc", + "physical_network": "public", + "network_type": "flat", + "segmentation_id": null, + "created_at": "2025-06-13T10:36:52Z", + "updated_at": "2025-06-13T10:36:52Z", + "revision_number": 1 + }, + { + "id": "e75ff709-fd25-47f8-ad89-aa6404d74fa8", + "network_id": "7a7f34de-4dcc-4211-85da-a3afefc8f990", + "name": null, + "description": null, + "physical_network": null, + "network_type": "geneve", + "segmentation_id": 35745, + "created_at": "2025-06-13T10:36:45Z", + "updated_at": "2025-06-13T10:36:45Z", + "revision_number": 0 + } + ] +}` + + createRequest = `{ + "segment": { + "network_id":"f35f300f-8c26-4d51-a0b0-84e2fff14307", + "network_type":"flat", + "physical_network":"public", + "name":"seg1", + "description":"desc" + } +}` + + createResponse = `{ + "segment": { + "id":"a5e3a494-26ee-4fde-ad26-2d846c47072e", + "network_id":"f35f300f-8c26-4d51-a0b0-84e2fff14307", + "name":"seg1", + "description":"desc", + "physical_network":"public", + "network_type":"flat", + "segmentation_id":null, + "created_at": "2025-06-13T10:36:52Z", + "updated_at": "2025-06-13T10:36:52Z", + "revision_number":1 + } +} +` + + updateRequest = `{ + "segment": { + "name":"new-name", + "description":"new-desc" + } +}` + + updateResponse = `{ + "segment": { + "id":"a5e3a494-26ee-4fde-ad26-2d846c47072e", + "network_id":"f35f300f-8c26-4d51-a0b0-84e2fff14307", + "name":"new-name", + "description":"new-desc", + "physical_network":"public", + "network_type":"flat", + "segmentation_id":null, + "created_at": "2025-06-13T10:36:52Z", + "updated_at": "2025-06-13T10:36:52Z", + "revision_number":1 + } +}` +) diff --git a/openstack/networking/v2/extensions/segments/testing/requests_test.go b/openstack/networking/v2/extensions/segments/testing/requests_test.go new file mode 100644 index 0000000000..1db0d341ab --- /dev/null +++ b/openstack/networking/v2/extensions/segments/testing/requests_test.go @@ -0,0 +1,127 @@ +package testing + +import ( + "context" + "net/http" + "testing" + + fake "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/common" + "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/extensions/segments" + "github.com/gophercloud/gophercloud/v2/pagination" + th "github.com/gophercloud/gophercloud/v2/testhelper" +) + +func TestGetSegment(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + + th.Mux.HandleFunc("/v2.0/segments/"+SegmentID1, func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + _, err := w.Write([]byte(createResponse)) + th.AssertNoErr(t, err) + }) + + res, err := segments.Get(context.TODO(), fake.ServiceClient(), SegmentID1).Extract() + th.AssertNoErr(t, err) + th.CheckDeepEquals(t, Segment1, *res) +} + +func TestListSegments(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + + th.Mux.HandleFunc("/v2.0/segments", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + _, err := w.Write([]byte(SegmentsListBody)) + th.AssertNoErr(t, err) + }) + + count := 0 + pager := segments.List(fake.ServiceClient(), nil) + err := pager.EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + count++ + actual, err := segments.ExtractSegments(page) + th.AssertNoErr(t, err) + th.CheckDeepEquals(t, []segments.Segment{Segment1, Segment2}, actual) + return true, nil + }) + th.AssertNoErr(t, err) + if count != 1 { + t.Errorf("Expected 1 page, got %d", count) + } +} + +func TestCreateSegment(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + + th.Mux.HandleFunc("/v2.0/segments", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "POST") + th.TestHeader(t, r, "Content-Type", "application/json") + th.TestJSONRequest(t, r, createRequest) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusCreated) + _, err := w.Write([]byte(createResponse)) + th.AssertNoErr(t, err) + }) + + opts := segments.CreateOpts{ + NetworkID: Segment1.NetworkID, + NetworkType: "flat", + PhysicalNetwork: "public", + Name: "seg1", + Description: "desc", + } + actual, err := segments.Create(context.TODO(), fake.ServiceClient(), opts).Extract() + th.AssertNoErr(t, err) + + th.CheckDeepEquals(t, Segment1, *actual) +} + +func TestUpdateSegment(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + + th.Mux.HandleFunc("/v2.0/segments/"+SegmentID1, func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "PUT") + th.TestJSONRequest(t, r, updateRequest) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + _, err := w.Write([]byte(updateResponse)) + th.AssertNoErr(t, err) + }) + + newName := "new-name" + newDesc := "new-desc" + opts := segments.UpdateOpts{ + Name: &newName, + Description: &newDesc, + } + actual, err := segments.Update(context.TODO(), fake.ServiceClient(), SegmentID1, opts).Extract() + th.AssertNoErr(t, err) + + expected := Segment1 + expected.Name = newName + expected.Description = newDesc + + th.CheckDeepEquals(t, expected, *actual) +} + +func TestDeleteSegment(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + + th.Mux.HandleFunc("/v2.0/segments/"+SegmentID1, func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "DELETE") + w.WriteHeader(http.StatusNoContent) + }) + + err := segments.Delete(context.TODO(), fake.ServiceClient(), SegmentID1).ExtractErr() + th.AssertNoErr(t, err) +} diff --git a/openstack/networking/v2/extensions/segments/urls.go b/openstack/networking/v2/extensions/segments/urls.go new file mode 100644 index 0000000000..6694927c58 --- /dev/null +++ b/openstack/networking/v2/extensions/segments/urls.go @@ -0,0 +1,13 @@ +package segments + +import "github.com/gophercloud/gophercloud/v2" + +const urlBaase = "segments" + +func rootURL(c *gophercloud.ServiceClient) string { + return c.ServiceURL(urlBaase) +} + +func resourceURL(c *gophercloud.ServiceClient, id string) string { + return c.ServiceURL(urlBaase, id) +} From 79c64b0e9d8ec45a1e546ad8ce669347116b509d Mon Sep 17 00:00:00 2001 From: hops Date: Fri, 27 Jun 2025 12:48:41 +0200 Subject: [PATCH 163/353] nova: add support for hostname updates --- .../openstack/compute/v2/servers_test.go | 37 +++++++++++++++++++ openstack/compute/v2/servers/requests.go | 6 +++ .../v2/servers/testing/fixtures_test.go | 14 +++++++ .../v2/servers/testing/requests_test.go | 15 ++++++++ 4 files changed, 72 insertions(+) diff --git a/internal/acceptance/openstack/compute/v2/servers_test.go b/internal/acceptance/openstack/compute/v2/servers_test.go index 0c5d034491..2e5a21d498 100644 --- a/internal/acceptance/openstack/compute/v2/servers_test.go +++ b/internal/acceptance/openstack/compute/v2/servers_test.go @@ -631,3 +631,40 @@ func TestServerNoNetworkCreateDestroy(t *testing.T) { t.Fatalf("Instance must not be a member of specified network") } } + +func TestServersUpdateHostname(t *testing.T) { + clients.RequireLong(t) + + client, err := clients.NewComputeV2Client() + th.AssertNoErr(t, err) + client.Microversion = "2.90" + + server, err := CreateMicroversionServer(t, client) + th.AssertNoErr(t, err) + defer DeleteServer(t, client, server) + + alternateHostname := tools.RandomString("ACPTTEST", 16) + for alternateHostname == *server.Hostname { + alternateHostname = tools.RandomString("ACPTTEST", 16) + } + + t.Logf("Attempting to change the server's hostname to %s.", alternateHostname) + + updateOpts := servers.UpdateOpts{ + Hostname: &alternateHostname, + } + + updated, err := servers.Update(context.TODO(), client, server.ID, updateOpts).Extract() + th.AssertNoErr(t, err) + + th.AssertEquals(t, server.ID, updated.ID) + + err = tools.WaitFor(func(ctx context.Context) (bool, error) { + latest, err := servers.Get(ctx, client, updated.ID).Extract() + if err != nil { + return false, err + } + return *latest.Hostname == alternateHostname, nil + }) + th.AssertNoErr(t, err) +} diff --git a/openstack/compute/v2/servers/requests.go b/openstack/compute/v2/servers/requests.go index 44e8cccaeb..34e4e00d41 100644 --- a/openstack/compute/v2/servers/requests.go +++ b/openstack/compute/v2/servers/requests.go @@ -651,6 +651,12 @@ type UpdateOpts struct { // AccessIPv6 provides a new IPv6 address for the instance. AccessIPv6 string `json:"accessIPv6,omitempty"` + + // Hostname changes the hostname of the server. + // Requires microversion 2.90 or later. + // Note: This information is published via the metadata service and requires + // application such as cloud-init to propagate it through to the instance. + Hostname *string `json:"hostname,omitempty"` } // ToServerUpdateMap formats an UpdateOpts structure into a request body. diff --git a/openstack/compute/v2/servers/testing/fixtures_test.go b/openstack/compute/v2/servers/testing/fixtures_test.go index a9c3980d88..9d517f46b5 100644 --- a/openstack/compute/v2/servers/testing/fixtures_test.go +++ b/openstack/compute/v2/servers/testing/fixtures_test.go @@ -1338,3 +1338,17 @@ func HandleServerWithTagsCreationSuccessfully(t *testing.T) { fmt.Fprint(w, SingleServerWithTagsBody) }) } + +// HandleServerHostnameUpdateSuccessfully sets up the test server to respond to a server update +// request changing the hostname. +func HandleServerHostnameUpdateSuccessfully(t *testing.T) { + th.Mux.HandleFunc("/servers/1234asdf", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "PUT") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.TestHeader(t, r, "Accept", "application/json") + th.TestHeader(t, r, "Content-Type", "application/json") + th.TestJSONRequest(t, r, `{ "server": { "hostname": "new-hostname" } }`) + + fmt.Fprint(w, SingleServerBody) + }) +} diff --git a/openstack/compute/v2/servers/testing/requests_test.go b/openstack/compute/v2/servers/testing/requests_test.go index 66a33dd688..fd15e20a09 100644 --- a/openstack/compute/v2/servers/testing/requests_test.go +++ b/openstack/compute/v2/servers/testing/requests_test.go @@ -1182,3 +1182,18 @@ func TestCreateServerWithHypervisorHostname(t *testing.T) { th.AssertNoErr(t, err) th.CheckJSONEquals(t, expected, actual) } + +func TestUpdateServerHostname(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + HandleServerHostnameUpdateSuccessfully(t) + + client := client.ServiceClient() + newHostname := "new-hostname" + actual, err := servers.Update(context.TODO(), client, "1234asdf", servers.UpdateOpts{Hostname: &newHostname}).Extract() + if err != nil { + t.Fatalf("Unexpected Update error: %v", err) + } + + th.CheckDeepEquals(t, ServerDerp, *actual) +} From a776073256a161d061f7020c7f64f9367fcf2eb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?p=C3=BDrus?= Date: Wed, 2 Jul 2025 10:12:40 +0200 Subject: [PATCH 164/353] neutron: allow omission of subnet_id for IP address --- openstack/networking/v2/extensions/layer3/routers/results.go | 2 +- openstack/networking/v2/ports/results.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/openstack/networking/v2/extensions/layer3/routers/results.go b/openstack/networking/v2/extensions/layer3/routers/results.go index 14845524c0..25b29c2755 100644 --- a/openstack/networking/v2/extensions/layer3/routers/results.go +++ b/openstack/networking/v2/extensions/layer3/routers/results.go @@ -21,7 +21,7 @@ type GatewayInfo struct { // router. type ExternalFixedIP struct { IPAddress string `json:"ip_address,omitempty"` - SubnetID string `json:"subnet_id"` + SubnetID string `json:"subnet_id,omitempty"` } // Route is a possible route in a router. diff --git a/openstack/networking/v2/ports/results.go b/openstack/networking/v2/ports/results.go index 74a0fa3b49..db223d48c1 100644 --- a/openstack/networking/v2/ports/results.go +++ b/openstack/networking/v2/ports/results.go @@ -49,7 +49,7 @@ type DeleteResult struct { // IP is a sub-struct that represents an individual IP. type IP struct { - SubnetID string `json:"subnet_id"` + SubnetID string `json:"subnet_id,omitempty"` IPAddress string `json:"ip_address,omitempty"` } From 4da4b4c24152319945d2cca9d09cb8d82cd8347d Mon Sep 17 00:00:00 2001 From: VoigtS Date: Tue, 8 Jul 2025 13:06:41 +0200 Subject: [PATCH 165/353] blockstorage: add isPublic query option for volume types --- openstack/blockstorage/v3/volumetypes/requests.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openstack/blockstorage/v3/volumetypes/requests.go b/openstack/blockstorage/v3/volumetypes/requests.go index d419d75d9b..e90991f861 100644 --- a/openstack/blockstorage/v3/volumetypes/requests.go +++ b/openstack/blockstorage/v3/volumetypes/requests.go @@ -73,6 +73,9 @@ type ListOptsBuilder interface { // ListOpts holds options for listing Volume Types. It is passed to the volumetypes.List // function. type ListOpts struct { + // Specifies whether to request public or private types. + // Set to "none" to retrieve both types. Defaults to public only. + IsPublic string `q:"is_public"` // Comma-separated list of sort keys and optional sort directions in the // form of [:]. Sort string `q:"sort"` From 6525e5cdd30581c7fc8eb8fb7de1a4fe6adc099c Mon Sep 17 00:00:00 2001 From: VoigtS Date: Wed, 9 Jul 2025 17:06:05 +0200 Subject: [PATCH 166/353] fixes from review: Adjust IsPublic type to utilize a string enum Add test cases --- .../blockstorage/v3/volumetypes/requests.go | 34 +++++++++++----- .../v3/volumetypes/testing/fixtures_test.go | 12 ++++++ .../v3/volumetypes/testing/requests_test.go | 40 +++++++++++++++++++ 3 files changed, 76 insertions(+), 10 deletions(-) diff --git a/openstack/blockstorage/v3/volumetypes/requests.go b/openstack/blockstorage/v3/volumetypes/requests.go index e90991f861..8849c394fb 100644 --- a/openstack/blockstorage/v3/volumetypes/requests.go +++ b/openstack/blockstorage/v3/volumetypes/requests.go @@ -73,9 +73,9 @@ type ListOptsBuilder interface { // ListOpts holds options for listing Volume Types. It is passed to the volumetypes.List // function. type ListOpts struct { - // Specifies whether to request public or private types. - // Set to "none" to retrieve both types. Defaults to public only. - IsPublic string `q:"is_public"` + // Specifies whether the query should include public or private Volume Types. + // By default, it queries both types. + IsPublic visibility `q:"is_public"` // Comma-separated list of sort keys and optional sort directions in the // form of [:]. Sort string `q:"sort"` @@ -87,8 +87,22 @@ type ListOpts struct { Marker string `q:"marker"` } +type visibility string + +const ( + // VisibilityDefault enables querying both public and private Volume Types. + VisibilityDefault visibility = "None" + // VisibilityPublic restricts the query to only public Volume Types. + VisibilityPublic visibility = "true" + // VisibilityPrivate restricts the query to only private Volume Types. + VisibilityPrivate visibility = "false" +) + // ToVolumeTypeListQuery formats a ListOpts into a query string. func (opts ListOpts) ToVolumeTypeListQuery() (string, error) { + if opts.IsPublic == "" { + opts.IsPublic = VisibilityDefault + } q, err := gophercloud.BuildQueryString(opts) return q.String(), err } @@ -96,14 +110,14 @@ func (opts ListOpts) ToVolumeTypeListQuery() (string, error) { // List returns Volume types. func List(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { url := listURL(client) - - if opts != nil { - query, err := opts.ToVolumeTypeListQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query + if opts == nil { + opts = ListOpts{} + } + query, err := opts.ToVolumeTypeListQuery() + if err != nil { + return pagination.Pager{Err: err} } + url += query return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { return VolumeTypePage{pagination.LinkedPageBase{PageResult: r}} diff --git a/openstack/blockstorage/v3/volumetypes/testing/fixtures_test.go b/openstack/blockstorage/v3/volumetypes/testing/fixtures_test.go index c7eb37893e..4678aea627 100644 --- a/openstack/blockstorage/v3/volumetypes/testing/fixtures_test.go +++ b/openstack/blockstorage/v3/volumetypes/testing/fixtures_test.go @@ -377,3 +377,15 @@ func MockEncryptionGetSpecResponse(t *testing.T) { `) }) } + +func HandleListIsPublicParam(t *testing.T, values map[string]string) { + th.Mux.HandleFunc("/types", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestFormValues(t, r, values) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + fmt.Fprint(w, `{"volume_types": []}`) + }) +} diff --git a/openstack/blockstorage/v3/volumetypes/testing/requests_test.go b/openstack/blockstorage/v3/volumetypes/testing/requests_test.go index f222be2395..8a4669f46c 100644 --- a/openstack/blockstorage/v3/volumetypes/testing/requests_test.go +++ b/openstack/blockstorage/v3/volumetypes/testing/requests_test.go @@ -122,6 +122,46 @@ func TestUpdate(t *testing.T) { th.CheckEquals(t, true, v.IsPublic) } +func TestListIsPublicParam(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + result := make(map[string]string) + HandleListIsPublicParam(t, result) + + // An empty ListOpts should query both public and private volume types by default. + result["is_public"] = "None" + err := volumetypes.List(client.ServiceClient(), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + return true, nil + }) + th.AssertNoErr(t, err) + + err = volumetypes.List(client.ServiceClient(), volumetypes.ListOpts{IsPublic: volumetypes.VisibilityDefault}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + return true, nil + }) + th.AssertNoErr(t, err) + + // Specific visibility queries + result["is_public"] = "true" + err = volumetypes.List(client.ServiceClient(), volumetypes.ListOpts{IsPublic: volumetypes.VisibilityPublic}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + return true, nil + }) + th.AssertNoErr(t, err) + + result["is_public"] = "false" + err = volumetypes.List(client.ServiceClient(), volumetypes.ListOpts{IsPublic: volumetypes.VisibilityPrivate}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + return true, nil + }) + th.AssertNoErr(t, err) + + // Specific visibility query while ensuring other options are still considered. + result["is_public"] = "None" + result["sort"] = "asc" + err = volumetypes.List(client.ServiceClient(), volumetypes.ListOpts{IsPublic: volumetypes.VisibilityDefault, Sort: "asc"}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + return true, nil + }) + th.AssertNoErr(t, err) +} + func TestVolumeTypeExtraSpecsList(t *testing.T) { th.SetupHTTP() defer th.TeardownHTTP() From c3a6a069c3d532f337512b023570b2f2f5456387 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Tue, 15 Jul 2025 13:56:13 +0100 Subject: [PATCH 167/353] Fix pagination for messaging client Conflicts: openstack/messaging/v2/messages/results.go openstack/messaging/v2/queues/results.go NOTE(stephenfin): Conflicts are due to absence of commit 06c6b07702ad36440ae70cde0193be299cd52a37, which is a lint-only change that we don't want to backport here. Signed-off-by: Stephen Finucane (cherry picked from commit b60bf67f5bd5e2a8abc54b9ac21369268ff1cb5d) --- openstack/messaging/v2/messages/requests.go | 5 ++++- openstack/messaging/v2/messages/results.go | 3 ++- openstack/messaging/v2/messages/urls.go | 10 ++++++---- openstack/messaging/v2/queues/requests.go | 5 ++++- openstack/messaging/v2/queues/results.go | 3 ++- openstack/messaging/v2/queues/urls.go | 10 ++++++---- 6 files changed, 24 insertions(+), 12 deletions(-) diff --git a/openstack/messaging/v2/messages/requests.go b/openstack/messaging/v2/messages/requests.go index 04810c3cce..e0a12f2542 100644 --- a/openstack/messaging/v2/messages/requests.go +++ b/openstack/messaging/v2/messages/requests.go @@ -48,7 +48,10 @@ func List(client *gophercloud.ServiceClient, queueName string, opts ListOptsBuil } pager := pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { - return MessagePage{pagination.LinkedPageBase{PageResult: r}} + return MessagePage{ + serviceURL: client.ServiceURL(), + LinkedPageBase: pagination.LinkedPageBase{PageResult: r}, + } }) return pager } diff --git a/openstack/messaging/v2/messages/results.go b/openstack/messaging/v2/messages/results.go index a0b76a7373..67e4048ef2 100644 --- a/openstack/messaging/v2/messages/results.go +++ b/openstack/messaging/v2/messages/results.go @@ -12,6 +12,7 @@ type CreateResult struct { // MessagePage contains a single page of all clusters from a ListDetails call. type MessagePage struct { + serviceURL string pagination.LinkedPageBase } @@ -127,5 +128,5 @@ func (r MessagePage) NextPageURL() (string, error) { if err != nil { return "", err } - return nextPageURL(r.URL.String(), next) + return nextPageURL(r.serviceURL, next) } diff --git a/openstack/messaging/v2/messages/urls.go b/openstack/messaging/v2/messages/urls.go index b5ba4235b2..8b0f5f667b 100644 --- a/openstack/messaging/v2/messages/urls.go +++ b/openstack/messaging/v2/messages/urls.go @@ -35,9 +35,9 @@ func messageURL(client *gophercloud.ServiceClient, queueName string, messageID s return client.ServiceURL(apiVersion, apiName, queueName, "messages", messageID) } -// Builds next page full url based on current url. -func nextPageURL(currentURL string, next string) (string, error) { - base, err := url.Parse(currentURL) +// builds next page full url based on service endpoint +func nextPageURL(serviceURL, next string) (string, error) { + base, err := url.Parse(serviceURL) if err != nil { return "", err } @@ -45,5 +45,7 @@ func nextPageURL(currentURL string, next string) (string, error) { if err != nil { return "", err } - return base.ResolveReference(rel).String(), nil + combined := base.JoinPath(rel.Path) + combined.RawQuery = rel.RawQuery + return combined.String(), nil } diff --git a/openstack/messaging/v2/queues/requests.go b/openstack/messaging/v2/queues/requests.go index 2344921a89..7fc55531e9 100644 --- a/openstack/messaging/v2/queues/requests.go +++ b/openstack/messaging/v2/queues/requests.go @@ -49,7 +49,10 @@ func List(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pa } pager := pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { - return QueuePage{pagination.LinkedPageBase{PageResult: r}} + return QueuePage{ + serviceURL: client.ServiceURL(), + LinkedPageBase: pagination.LinkedPageBase{PageResult: r}, + } }) return pager diff --git a/openstack/messaging/v2/queues/results.go b/openstack/messaging/v2/queues/results.go index 8190ddfa52..4d1250ea2f 100644 --- a/openstack/messaging/v2/queues/results.go +++ b/openstack/messaging/v2/queues/results.go @@ -14,6 +14,7 @@ type commonResult struct { // QueuePage contains a single page of all queues from a List operation. type QueuePage struct { + serviceURL string pagination.LinkedPageBase } @@ -173,7 +174,7 @@ func (r QueuePage) NextPageURL() (string, error) { if err != nil { return "", err } - return nextPageURL(r.URL.String(), next) + return nextPageURL(r.serviceURL, next) } // GetCount value if it request was supplied `WithCount` param diff --git a/openstack/messaging/v2/queues/urls.go b/openstack/messaging/v2/queues/urls.go index 9a89bfceab..d98f740b8d 100644 --- a/openstack/messaging/v2/queues/urls.go +++ b/openstack/messaging/v2/queues/urls.go @@ -47,9 +47,9 @@ func purgeURL(client *gophercloud.ServiceClient, queueName string) string { return client.ServiceURL(apiVersion, apiName, queueName, "purge") } -// builds next page full url based on current url -func nextPageURL(currentURL string, next string) (string, error) { - base, err := url.Parse(currentURL) +// builds next page full url based on service endpoint +func nextPageURL(serviceURL string, next string) (string, error) { + base, err := url.Parse(serviceURL) if err != nil { return "", err } @@ -57,5 +57,7 @@ func nextPageURL(currentURL string, next string) (string, error) { if err != nil { return "", err } - return base.ResolveReference(rel).String(), nil + combined := base.JoinPath(rel.Path) + combined.RawQuery = rel.RawQuery + return combined.String(), nil } From 192ad2631c054ef0da144d5a740373ac6e706d63 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Tue, 15 Jul 2025 15:27:32 +0100 Subject: [PATCH 168/353] Set low limit for messaging list tests As a regression test. Signed-off-by: Stephen Finucane (cherry picked from commit a76f08e0ebcb31e057a6e4e58aa1e45da5498d66) --- internal/acceptance/openstack/messaging/v2/message_test.go | 3 ++- internal/acceptance/openstack/messaging/v2/queue_test.go | 6 ++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/internal/acceptance/openstack/messaging/v2/message_test.go b/internal/acceptance/openstack/messaging/v2/message_test.go index fed1dc6db8..650fa18415 100644 --- a/internal/acceptance/openstack/messaging/v2/message_test.go +++ b/internal/acceptance/openstack/messaging/v2/message_test.go @@ -38,7 +38,8 @@ func TestListMessages(t *testing.T) { client, err = clients.NewMessagingV2Client(clientID) th.AssertNoErr(t, err) - listOpts := messages.ListOpts{} + // We use limit=1 to regression test https://github.com/gophercloud/gophercloud/issues/3336 + listOpts := messages.ListOpts{Limit: 1} pager := messages.List(client, createdQueueName, listOpts) err = pager.EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { diff --git a/internal/acceptance/openstack/messaging/v2/queue_test.go b/internal/acceptance/openstack/messaging/v2/queue_test.go index a259fd5fb9..cbeb64ae41 100644 --- a/internal/acceptance/openstack/messaging/v2/queue_test.go +++ b/internal/acceptance/openstack/messaging/v2/queue_test.go @@ -74,10 +74,8 @@ func TestListQueues(t *testing.T) { th.AssertNoErr(t, err) defer DeleteQueue(t, client, secondQueueName) - listOpts := queues.ListOpts{ - Limit: 10, - Detailed: true, - } + // We use limit=1 to regression test https://github.com/gophercloud/gophercloud/issues/3336 + listOpts := queues.ListOpts{Limit: 1, Detailed: true} pager := queues.List(client, listOpts) err = pager.EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { From 74b19097b1d40c47caf65709d178f78c92866c79 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Tue, 17 Jun 2025 16:01:34 +0100 Subject: [PATCH 169/353] tests: Fix TestVLANTransparentCRUD test The 'vlan-transparent' extension is now enabled by default [1]. This is highlighting a bug in the aforementioned test: namely, that we are trying to update an attribute which is read-only [2]. Remove the update step of the job and fix the test. [1] https://github.com/openstack/neutron/commit/11ff4f2f981969cf56ffcafa0a2f9a8fe11eabce [2] https://github.com/openstack/neutron-lib/blob/fd011c955dfae1072555c69b6ba742b85f041736/neutron_lib/api/definitions/vlantransparent.py#L49 Signed-off-by: Stephen Finucane --- .../vlantransparent/vlantransparent.go | 30 ------------------- .../vlantransparent/vlantransparent_test.go | 6 +--- 2 files changed, 1 insertion(+), 35 deletions(-) diff --git a/internal/acceptance/openstack/networking/v2/extensions/vlantransparent/vlantransparent.go b/internal/acceptance/openstack/networking/v2/extensions/vlantransparent/vlantransparent.go index 87aa2d4e8d..ec3dde26bd 100644 --- a/internal/acceptance/openstack/networking/v2/extensions/vlantransparent/vlantransparent.go +++ b/internal/acceptance/openstack/networking/v2/extensions/vlantransparent/vlantransparent.go @@ -75,33 +75,3 @@ func CreateVLANTransparentNetwork(t *testing.T, client *gophercloud.ServiceClien return &network, nil } - -// UpdateVLANTransparentNetwork will update a network with the -// "vlan-transparent" extension. An error will be returned if the network could -// not be updated. -func UpdateVLANTransparentNetwork(t *testing.T, client *gophercloud.ServiceClient, networkID string) (*VLANTransparentNetwork, error) { - networkName := tools.RandomString("TESTACC-NEW-", 6) - networkUpdateOpts := networks.UpdateOpts{ - Name: &networkName, - } - - iFalse := false - updateOpts := vlantransparent.UpdateOptsExt{ - UpdateOptsBuilder: &networkUpdateOpts, - VLANTransparent: &iFalse, - } - - t.Logf("Attempting to update a VLAN-transparent network: %s", networkID) - - var network VLANTransparentNetwork - err := networks.Update(context.TODO(), client, networkID, updateOpts).ExtractInto(&network) - if err != nil { - return nil, err - } - - t.Logf("Successfully updated the network.") - - th.AssertEquals(t, networkName, network.Name) - - return &network, nil -} diff --git a/internal/acceptance/openstack/networking/v2/extensions/vlantransparent/vlantransparent_test.go b/internal/acceptance/openstack/networking/v2/extensions/vlantransparent/vlantransparent_test.go index b36d01c071..25adfef7ed 100644 --- a/internal/acceptance/openstack/networking/v2/extensions/vlantransparent/vlantransparent_test.go +++ b/internal/acceptance/openstack/networking/v2/extensions/vlantransparent/vlantransparent_test.go @@ -25,11 +25,7 @@ func TestVLANTransparentCRUD(t *testing.T) { tools.PrintResource(t, network) - // Update the created VLAN transparent network. - newNetwork, err := UpdateVLANTransparentNetwork(t, client, network.ID) - th.AssertNoErr(t, err) - - tools.PrintResource(t, newNetwork) + // The vlan_transparent field is read-only so no update test // Check that the created VLAN transparent network exists. vlanTransparentNetworks, err := ListVLANTransparentNetworks(t, client) From 112497084a2aec1858b8fc624b10f9018e35aa0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?p=C3=BDrus?= Date: Wed, 16 Jul 2025 23:14:01 +0200 Subject: [PATCH 170/353] [v2] tests: fix tests for recent PR backports --- .../v2/servers/testing/fixtures_test.go | 4 +- .../v2/servers/testing/requests_test.go | 8 ++-- .../dns/v2/quotas/testing/fixtures_test.go | 8 ++-- .../dns/v2/quotas/testing/requests_test.go | 16 ++++---- .../segments/testing/requests_test.go | 40 +++++++++---------- 5 files changed, 38 insertions(+), 38 deletions(-) diff --git a/openstack/compute/v2/servers/testing/fixtures_test.go b/openstack/compute/v2/servers/testing/fixtures_test.go index 7bb9812a4a..5c5153887a 100644 --- a/openstack/compute/v2/servers/testing/fixtures_test.go +++ b/openstack/compute/v2/servers/testing/fixtures_test.go @@ -1341,8 +1341,8 @@ func HandleServerWithTagsCreationSuccessfully(t *testing.T, fakeServer th.FakeSe // HandleServerHostnameUpdateSuccessfully sets up the test server to respond to a server update // request changing the hostname. -func HandleServerHostnameUpdateSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/servers/1234asdf", func(w http.ResponseWriter, r *http.Request) { +func HandleServerHostnameUpdateSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/servers/1234asdf", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Accept", "application/json") diff --git a/openstack/compute/v2/servers/testing/requests_test.go b/openstack/compute/v2/servers/testing/requests_test.go index 53b6992acc..aca94bd59b 100644 --- a/openstack/compute/v2/servers/testing/requests_test.go +++ b/openstack/compute/v2/servers/testing/requests_test.go @@ -1184,11 +1184,11 @@ func TestCreateServerWithHypervisorHostname(t *testing.T) { } func TestUpdateServerHostname(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleServerHostnameUpdateSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleServerHostnameUpdateSuccessfully(t, fakeServer) - client := client.ServiceClient() + client := client.ServiceClient(fakeServer) newHostname := "new-hostname" actual, err := servers.Update(context.TODO(), client, "1234asdf", servers.UpdateOpts{Hostname: &newHostname}).Extract() if err != nil { diff --git a/openstack/dns/v2/quotas/testing/fixtures_test.go b/openstack/dns/v2/quotas/testing/fixtures_test.go index a1058bdf00..9702547e3d 100644 --- a/openstack/dns/v2/quotas/testing/fixtures_test.go +++ b/openstack/dns/v2/quotas/testing/fixtures_test.go @@ -40,8 +40,8 @@ var ( ) // HandleGetSuccessfully configures the test server to respond to a Get request. -func HandleGetSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/quotas/a86dba58-0043-4cc6-a1bb-69d5e86f3ca3", func(w http.ResponseWriter, r *http.Request) { +func HandleGetSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/quotas/a86dba58-0043-4cc6-a1bb-69d5e86f3ca3", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) @@ -51,8 +51,8 @@ func HandleGetSuccessfully(t *testing.T) { } // HandleUpdateSuccessfully configures the test server to respond to an Update request. -func HandleUpdateSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/quotas/a86dba58-0043-4cc6-a1bb-69d5e86f3ca3", func(w http.ResponseWriter, r *http.Request) { +func HandleUpdateSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/quotas/a86dba58-0043-4cc6-a1bb-69d5e86f3ca3", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PATCH") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestJSONRequest(t, r, UpdateQuotaRequest) diff --git a/openstack/dns/v2/quotas/testing/requests_test.go b/openstack/dns/v2/quotas/testing/requests_test.go index c60c5e2ad1..d753e58392 100644 --- a/openstack/dns/v2/quotas/testing/requests_test.go +++ b/openstack/dns/v2/quotas/testing/requests_test.go @@ -10,26 +10,26 @@ import ( ) func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetSuccessfully(t, fakeServer) - actual, err := quotas.Get(context.TODO(), client.ServiceClient(), "a86dba58-0043-4cc6-a1bb-69d5e86f3ca3").Extract() + actual, err := quotas.Get(context.TODO(), client.ServiceClient(fakeServer), "a86dba58-0043-4cc6-a1bb-69d5e86f3ca3").Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, Quota, actual) } func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleUpdateSuccessfully(t) + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleUpdateSuccessfully(t, fakeServer) zones := 100 updateOpts := quotas.UpdateOpts{ Zones: &zones, } - actual, err := quotas.Update(context.TODO(), client.ServiceClient(), "a86dba58-0043-4cc6-a1bb-69d5e86f3ca3", updateOpts).Extract() + actual, err := quotas.Update(context.TODO(), client.ServiceClient(fakeServer), "a86dba58-0043-4cc6-a1bb-69d5e86f3ca3", updateOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, Quota, actual) } diff --git a/openstack/networking/v2/extensions/segments/testing/requests_test.go b/openstack/networking/v2/extensions/segments/testing/requests_test.go index 1db0d341ab..08388a72cc 100644 --- a/openstack/networking/v2/extensions/segments/testing/requests_test.go +++ b/openstack/networking/v2/extensions/segments/testing/requests_test.go @@ -12,10 +12,10 @@ import ( ) func TestGetSegment(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/segments/"+SegmentID1, func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/segments/"+SegmentID1, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -23,16 +23,16 @@ func TestGetSegment(t *testing.T) { th.AssertNoErr(t, err) }) - res, err := segments.Get(context.TODO(), fake.ServiceClient(), SegmentID1).Extract() + res, err := segments.Get(context.TODO(), fake.ServiceClient(fakeServer), SegmentID1).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, Segment1, *res) } func TestListSegments(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/segments", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/segments", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -41,7 +41,7 @@ func TestListSegments(t *testing.T) { }) count := 0 - pager := segments.List(fake.ServiceClient(), nil) + pager := segments.List(fake.ServiceClient(fakeServer), nil) err := pager.EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := segments.ExtractSegments(page) @@ -56,10 +56,10 @@ func TestListSegments(t *testing.T) { } func TestCreateSegment(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/segments", func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/segments", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "Content-Type", "application/json") th.TestJSONRequest(t, r, createRequest) @@ -77,17 +77,17 @@ func TestCreateSegment(t *testing.T) { Name: "seg1", Description: "desc", } - actual, err := segments.Create(context.TODO(), fake.ServiceClient(), opts).Extract() + actual, err := segments.Create(context.TODO(), fake.ServiceClient(fakeServer), opts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, Segment1, *actual) } func TestUpdateSegment(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/segments/"+SegmentID1, func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/segments/"+SegmentID1, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestJSONRequest(t, r, updateRequest) @@ -103,7 +103,7 @@ func TestUpdateSegment(t *testing.T) { Name: &newName, Description: &newDesc, } - actual, err := segments.Update(context.TODO(), fake.ServiceClient(), SegmentID1, opts).Extract() + actual, err := segments.Update(context.TODO(), fake.ServiceClient(fakeServer), SegmentID1, opts).Extract() th.AssertNoErr(t, err) expected := Segment1 @@ -114,14 +114,14 @@ func TestUpdateSegment(t *testing.T) { } func TestDeleteSegment(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() - th.Mux.HandleFunc("/v2.0/segments/"+SegmentID1, func(w http.ResponseWriter, r *http.Request) { + fakeServer.Mux.HandleFunc("/v2.0/segments/"+SegmentID1, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") w.WriteHeader(http.StatusNoContent) }) - err := segments.Delete(context.TODO(), fake.ServiceClient(), SegmentID1).ExtractErr() + err := segments.Delete(context.TODO(), fake.ServiceClient(fakeServer), SegmentID1).ExtractErr() th.AssertNoErr(t, err) } From c11c33bfcc7d229e6138f8e933c68839a18da5b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?p=C3=BDrus?= Date: Fri, 18 Jul 2025 12:10:37 +0200 Subject: [PATCH 171/353] tests: shorten GH-A job names and use go-version-file: 'go.mod' for go version source --- .github/workflows/functional-baremetal.yaml | 5 +++-- .github/workflows/functional-basic.yaml | 5 +++-- .github/workflows/functional-blockstorage.yaml | 5 +++-- .github/workflows/functional-compute.yaml | 5 +++-- .github/workflows/functional-containerinfra.yaml | 5 +++-- .github/workflows/functional-dns.yaml | 5 +++-- .github/workflows/functional-fwaas_v2.yaml | 5 +++-- .github/workflows/functional-identity.yaml | 5 +++-- .github/workflows/functional-image.yaml | 5 +++-- .github/workflows/functional-keymanager.yaml | 5 +++-- .github/workflows/functional-loadbalancer.yaml | 5 +++-- .github/workflows/functional-messaging.yaml | 5 +++-- .github/workflows/functional-networking.yaml | 5 +++-- .github/workflows/functional-objectstorage.yaml | 5 +++-- .github/workflows/functional-orchestration.yaml | 5 +++-- .github/workflows/functional-placement.yaml | 5 +++-- .github/workflows/functional-sharedfilesystems.yaml | 5 +++-- .github/workflows/functional-workflow.yaml | 5 +++-- 18 files changed, 54 insertions(+), 36 deletions(-) diff --git a/.github/workflows/functional-baremetal.yaml b/.github/workflows/functional-baremetal.yaml index 48adb28279..f4f9ed8166 100644 --- a/.github/workflows/functional-baremetal.yaml +++ b/.github/workflows/functional-baremetal.yaml @@ -25,7 +25,7 @@ jobs: ubuntu_version: "22.04" additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} - name: Deploy OpenStack ${{ matrix.name }} with Ironic and run baremetal acceptance tests + name: Ironic on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud uses: actions/checkout@v4 @@ -73,7 +73,8 @@ jobs: - name: Checkout go uses: actions/setup-go@v5 with: - go-version: '^1.22' + go-version-file: 'go.mod' + cache: true - name: Run Gophercloud acceptance tests run: | source ${{ github.workspace }}/script/stackenv diff --git a/.github/workflows/functional-basic.yaml b/.github/workflows/functional-basic.yaml index 9310200cf2..f188735441 100644 --- a/.github/workflows/functional-basic.yaml +++ b/.github/workflows/functional-basic.yaml @@ -27,7 +27,7 @@ jobs: ubuntu_version: "22.04" additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} - name: Deploy OpenStack ${{ matrix.name }} with defaults and run basic acceptance tests + name: basic tests on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud uses: actions/checkout@v4 @@ -39,7 +39,8 @@ jobs: - name: Checkout go uses: actions/setup-go@v5 with: - go-version: '^1.22' + go-version-file: 'go.mod' + cache: true - name: Run Gophercloud acceptance tests run: | source ${{ github.workspace }}/script/stackenv diff --git a/.github/workflows/functional-blockstorage.yaml b/.github/workflows/functional-blockstorage.yaml index 7fa73c2ab1..996ba7fd9f 100644 --- a/.github/workflows/functional-blockstorage.yaml +++ b/.github/workflows/functional-blockstorage.yaml @@ -25,7 +25,7 @@ jobs: ubuntu_version: "22.04" additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} - name: Deploy OpenStack ${{ matrix.name }} with Cinder and run blockstorage acceptance tests + name: Cinder on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud uses: actions/checkout@v4 @@ -39,7 +39,8 @@ jobs: - name: Checkout go uses: actions/setup-go@v5 with: - go-version: '^1.22' + go-version-file: 'go.mod' + cache: true - name: Run Gophercloud acceptance tests run: | source ${{ github.workspace }}/script/stackenv diff --git a/.github/workflows/functional-compute.yaml b/.github/workflows/functional-compute.yaml index e279edb138..5265e25860 100644 --- a/.github/workflows/functional-compute.yaml +++ b/.github/workflows/functional-compute.yaml @@ -25,7 +25,7 @@ jobs: ubuntu_version: "22.04" additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} - name: Deploy OpenStack ${{ matrix.name }} with Nova and run compute acceptance tests + name: Nova on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud uses: actions/checkout@v4 @@ -39,7 +39,8 @@ jobs: - name: Checkout go uses: actions/setup-go@v5 with: - go-version: '^1.22' + go-version-file: 'go.mod' + cache: true - name: Run Gophercloud acceptance tests run: | source ${{ github.workspace }}/script/stackenv diff --git a/.github/workflows/functional-containerinfra.yaml b/.github/workflows/functional-containerinfra.yaml index f331301cdb..00bcb0a830 100644 --- a/.github/workflows/functional-containerinfra.yaml +++ b/.github/workflows/functional-containerinfra.yaml @@ -40,7 +40,7 @@ jobs: MAGNUMCLIENT_BRANCH=stable/2024.1 additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} - name: Deploy OpenStack ${{ matrix.name }} with Magnum and run containerinfra acceptance tests + name: Magnum on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud uses: actions/checkout@v4 @@ -60,7 +60,8 @@ jobs: - name: Checkout go uses: actions/setup-go@v5 with: - go-version: '^1.22' + go-version-file: 'go.mod' + cache: true - name: Run Gophercloud acceptance tests run: | source ${{ github.workspace }}/script/stackenv diff --git a/.github/workflows/functional-dns.yaml b/.github/workflows/functional-dns.yaml index beb2e1ac5e..e03f309cea 100644 --- a/.github/workflows/functional-dns.yaml +++ b/.github/workflows/functional-dns.yaml @@ -31,7 +31,7 @@ jobs: ubuntu_version: "22.04" additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} - name: Deploy OpenStack ${{ matrix.name }} with Designate and run dns acceptance tests + name: Designate on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud uses: actions/checkout@v4 @@ -47,7 +47,8 @@ jobs: - name: Checkout go uses: actions/setup-go@v5 with: - go-version: '^1.22' + go-version-file: 'go.mod' + cache: true - name: Run Gophercloud acceptance tests run: | source ${{ github.workspace }}/script/stackenv diff --git a/.github/workflows/functional-fwaas_v2.yaml b/.github/workflows/functional-fwaas_v2.yaml index 2481b0d21d..77857180f8 100644 --- a/.github/workflows/functional-fwaas_v2.yaml +++ b/.github/workflows/functional-fwaas_v2.yaml @@ -29,7 +29,7 @@ jobs: ubuntu_version: "22.04" additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} - name: Deploy OpenStack ${{ matrix.name }} with enabled FWaaS_v2 and run networking acceptance tests + name: FWaaS_v2 on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud uses: actions/checkout@v4 @@ -60,7 +60,8 @@ jobs: - name: Checkout go uses: actions/setup-go@v5 with: - go-version: '^1.22' + go-version-file: 'go.mod' + cache: true - name: Run Gophercloud acceptance tests run: | source ${{ github.workspace }}/script/stackenv diff --git a/.github/workflows/functional-identity.yaml b/.github/workflows/functional-identity.yaml index 688655d6f5..a21921e1b2 100644 --- a/.github/workflows/functional-identity.yaml +++ b/.github/workflows/functional-identity.yaml @@ -25,7 +25,7 @@ jobs: ubuntu_version: "22.04" additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} - name: Deploy OpenStack ${{ matrix.name }} with Keystone and run identity acceptance tests + name: Keystone on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud uses: actions/checkout@v4 @@ -37,7 +37,8 @@ jobs: - name: Checkout go uses: actions/setup-go@v5 with: - go-version: '^1.22' + go-version-file: 'go.mod' + cache: true - name: Run Gophercloud acceptance tests run: | source ${{ github.workspace }}/script/stackenv diff --git a/.github/workflows/functional-image.yaml b/.github/workflows/functional-image.yaml index 20697896e2..1b75aee919 100644 --- a/.github/workflows/functional-image.yaml +++ b/.github/workflows/functional-image.yaml @@ -25,7 +25,7 @@ jobs: ubuntu_version: "22.04" additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} - name: Deploy OpenStack ${{ matrix.name }} with Glance and run image acceptance tests + name: Glance on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud uses: actions/checkout@v4 @@ -37,7 +37,8 @@ jobs: - name: Checkout go uses: actions/setup-go@v5 with: - go-version: '^1.22' + go-version-file: 'go.mod' + cache: true - name: Run Gophercloud acceptance tests run: | source ${{ github.workspace }}/script/stackenv diff --git a/.github/workflows/functional-keymanager.yaml b/.github/workflows/functional-keymanager.yaml index ca046de8b0..ff34e5ac14 100644 --- a/.github/workflows/functional-keymanager.yaml +++ b/.github/workflows/functional-keymanager.yaml @@ -31,7 +31,7 @@ jobs: ubuntu_version: "22.04" additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} - name: Deploy OpenStack ${{ matrix.name }} with Barbican and run keymanager acceptance tests + name: Barbican on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud uses: actions/checkout@v4 @@ -47,7 +47,8 @@ jobs: - name: Checkout go uses: actions/setup-go@v5 with: - go-version: '^1.22' + go-version-file: 'go.mod' + cache: true - name: Run Gophercloud acceptance tests run: | source ${{ github.workspace }}/script/stackenv diff --git a/.github/workflows/functional-loadbalancer.yaml b/.github/workflows/functional-loadbalancer.yaml index 5ea8b7842b..ea1832ca28 100644 --- a/.github/workflows/functional-loadbalancer.yaml +++ b/.github/workflows/functional-loadbalancer.yaml @@ -31,7 +31,7 @@ jobs: ubuntu_version: "22.04" additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} - name: Deploy OpenStack ${{ matrix.name }} with Octavia and run loadbalancer acceptance tests + name: Octavia on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud uses: actions/checkout@v4 @@ -48,7 +48,8 @@ jobs: - name: Checkout go uses: actions/setup-go@v5 with: - go-version: '^1.22' + go-version-file: 'go.mod' + cache: true - name: Run Gophercloud acceptance tests run: | source ${{ github.workspace }}/script/stackenv diff --git a/.github/workflows/functional-messaging.yaml b/.github/workflows/functional-messaging.yaml index 5e89e6f33e..79cc2eec0e 100644 --- a/.github/workflows/functional-messaging.yaml +++ b/.github/workflows/functional-messaging.yaml @@ -25,7 +25,7 @@ jobs: ubuntu_version: "22.04" additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} - name: Deploy OpenStack ${{ matrix.name }} with Zaqar and run messaging acceptance tests + name: Zaqar on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud uses: actions/checkout@v4 @@ -40,7 +40,8 @@ jobs: - name: Checkout go uses: actions/setup-go@v5 with: - go-version: '^1.22' + go-version-file: 'go.mod' + cache: true - name: Run Gophercloud acceptance tests run: | source ${{ github.workspace }}/script/stackenv diff --git a/.github/workflows/functional-networking.yaml b/.github/workflows/functional-networking.yaml index 1b5b1edb1e..6435cec16e 100644 --- a/.github/workflows/functional-networking.yaml +++ b/.github/workflows/functional-networking.yaml @@ -25,7 +25,7 @@ jobs: ubuntu_version: "22.04" additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} - name: Deploy OpenStack ${{ matrix.name }} with Neutron and run networking acceptance tests + name: Neutron on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud uses: actions/checkout@v4 @@ -55,7 +55,8 @@ jobs: - name: Checkout go uses: actions/setup-go@v5 with: - go-version: '^1.22' + go-version-file: 'go.mod' + cache: true - name: Run Gophercloud acceptance tests run: | source ${{ github.workspace }}/script/stackenv diff --git a/.github/workflows/functional-objectstorage.yaml b/.github/workflows/functional-objectstorage.yaml index 180a79caf1..a1178b71b2 100644 --- a/.github/workflows/functional-objectstorage.yaml +++ b/.github/workflows/functional-objectstorage.yaml @@ -25,7 +25,7 @@ jobs: ubuntu_version: "22.04" additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} - name: Deploy OpenStack ${{ matrix.name }} with Swift and run objectstorage acceptance tests + name: Swift on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud uses: actions/checkout@v4 @@ -43,7 +43,8 @@ jobs: - name: Checkout go uses: actions/setup-go@v5 with: - go-version: '^1.22' + go-version-file: 'go.mod' + cache: true - name: Run Gophercloud acceptance tests run: | source ${{ github.workspace }}/script/stackenv diff --git a/.github/workflows/functional-orchestration.yaml b/.github/workflows/functional-orchestration.yaml index 8d147b1569..613f6639cc 100644 --- a/.github/workflows/functional-orchestration.yaml +++ b/.github/workflows/functional-orchestration.yaml @@ -25,7 +25,7 @@ jobs: ubuntu_version: "22.04" additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} - name: Deploy OpenStack ${{ matrix.name }} with Heat and run orchestration acceptance tests + name: Heat on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud uses: actions/checkout@v4 @@ -39,7 +39,8 @@ jobs: - name: Checkout go uses: actions/setup-go@v5 with: - go-version: '^1.22' + go-version-file: 'go.mod' + cache: true - name: Run Gophercloud acceptance tests run: | source ${{ github.workspace }}/script/stackenv diff --git a/.github/workflows/functional-placement.yaml b/.github/workflows/functional-placement.yaml index de02e307fe..dff74c01b7 100644 --- a/.github/workflows/functional-placement.yaml +++ b/.github/workflows/functional-placement.yaml @@ -25,7 +25,7 @@ jobs: ubuntu_version: "22.04" additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} - name: Deploy OpenStack ${{ matrix.name }} with Placement and run placement acceptance tests + name: Placement on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud uses: actions/checkout@v4 @@ -37,7 +37,8 @@ jobs: - name: Checkout go uses: actions/setup-go@v5 with: - go-version: '^1.22' + go-version-file: 'go.mod' + cache: true - name: Run Gophercloud acceptance tests run: | source ${{ github.workspace }}/script/stackenv diff --git a/.github/workflows/functional-sharedfilesystems.yaml b/.github/workflows/functional-sharedfilesystems.yaml index f56bcd066f..d6dd13206e 100644 --- a/.github/workflows/functional-sharedfilesystems.yaml +++ b/.github/workflows/functional-sharedfilesystems.yaml @@ -31,7 +31,7 @@ jobs: ubuntu_version: "22.04" additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} - name: Deploy OpenStack ${{ matrix.name }} with Manila and run sharedfilesystems acceptance tests + name: Manila on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud uses: actions/checkout@v4 @@ -61,7 +61,8 @@ jobs: - name: Checkout go uses: actions/setup-go@v5 with: - go-version: '^1.22' + go-version-file: 'go.mod' + cache: true - name: Run Gophercloud acceptance tests run: | source ${{ github.workspace }}/script/stackenv diff --git a/.github/workflows/functional-workflow.yaml b/.github/workflows/functional-workflow.yaml index 2d48495f24..e23b34252e 100644 --- a/.github/workflows/functional-workflow.yaml +++ b/.github/workflows/functional-workflow.yaml @@ -28,7 +28,7 @@ jobs: mistral_plugin_version: "stable/2024.1" additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} - name: Deploy OpenStack ${{ matrix.name }} with Mistral and run workflow acceptance tests + name: Mistral on Deploy OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud uses: actions/checkout@v4 @@ -42,7 +42,8 @@ jobs: - name: Checkout go uses: actions/setup-go@v5 with: - go-version: '^1.22' + go-version-file: 'go.mod' + cache: true - name: Run Gophercloud acceptance tests run: | source ${{ github.workspace }}/script/stackenv From df58d7008f2b87f309a4a4f94f2aa697e052844c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?p=C3=BDrus?= Date: Fri, 18 Jul 2025 12:23:43 +0200 Subject: [PATCH 172/353] tests: use go.mod as a version source in other workflows --- .github/workflows/codeql-analysis.yaml | 9 +++++---- .github/workflows/lint.yaml | 4 +--- .github/workflows/unit.yaml | 11 +++-------- 3 files changed, 9 insertions(+), 15 deletions(-) diff --git a/.github/workflows/codeql-analysis.yaml b/.github/workflows/codeql-analysis.yaml index b9492ca444..8efeaf761c 100644 --- a/.github/workflows/codeql-analysis.yaml +++ b/.github/workflows/codeql-analysis.yaml @@ -17,13 +17,14 @@ jobs: language: [ 'go' ] steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Setup Go uses: actions/setup-go@v5 with: - go-version: "1.22" - - - name: Checkout repository - uses: actions/checkout@v4 + go-version-file: 'go.mod' + cache: true - name: Initialize CodeQL uses: github/codeql-action/init@v3 diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index ed7399819d..be44ea86bc 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -16,8 +16,6 @@ jobs: - name: Run linters run: | make lint - # TODO: Use 'go mod tidy -diff' instead once go 1.23 is out - # https://github.com/golang/go/issues/27005 - name: Ensure go.mod is up-to-date run: | - if [ $(go mod tidy && git diff | wc -l) -gt 0 ]; then git diff && exit 1; fi + if [ $(go mod tidy -diff | wc -l) -gt 0 ]; then git diff && exit 1; fi diff --git a/.github/workflows/unit.yaml b/.github/workflows/unit.yaml index abab3a5237..ae3b2f0059 100644 --- a/.github/workflows/unit.yaml +++ b/.github/workflows/unit.yaml @@ -12,17 +12,14 @@ jobs: runs-on: ubuntu-latest strategy: fail-fast: false - matrix: - go-version: - - "1.22.3" - - "1" steps: - name: Checkout Gophercloud uses: actions/checkout@v4 - - name: Setup Go ${{ matrix.go-version }} + - name: Setup Go uses: actions/setup-go@v5 with: - go-version: ${{ matrix.go-version }} + go-version-file: 'go.mod' + cache: true - name: Setup environment run: | # Changing into a different directory to avoid polluting go.sum with "go get" @@ -37,7 +34,6 @@ jobs: uses: coverallsapp/github-action@v2 with: file: cover.out - flag-name: Go-${{ matrix.go-version }} parallel: true finish: permissions: @@ -50,4 +46,3 @@ jobs: uses: coverallsapp/github-action@v2 with: parallel-finished: true - carryforward: Go-${{ join(matrix.go-version.*, '-') }} From fcf7c1d353410adeb63e40a74bd56c25023fd5e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?p=C3=BDrus?= Date: Wed, 16 Jul 2025 13:42:15 +0200 Subject: [PATCH 173/353] core: clone service type aliases instead of referencing global slice --- endpoint_search.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/endpoint_search.go b/endpoint_search.go index 8818e769b8..159a02c2dd 100644 --- a/endpoint_search.go +++ b/endpoint_search.go @@ -111,7 +111,7 @@ func (eo *EndpointOpts) ApplyDefaults(t string) { if len(eo.Aliases) == 0 { if aliases, ok := ServiceTypeAliases[eo.Type]; ok { // happy path: user requested a service type by its official name - eo.Aliases = aliases + eo.Aliases = slices.Clone(aliases) } else { // unhappy path: user requested a service type by its alias or an // invalid/unsupported service type @@ -121,7 +121,7 @@ func (eo *EndpointOpts) ApplyDefaults(t string) { // we intentionally override the service type, even if it // was explicitly requested by the user eo.Type = t - eo.Aliases = aliases + eo.Aliases = slices.Clone(aliases) } } } From 083b44aea431d3100a6fc2457d234179de8f19ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?p=C3=BDrus?= Date: Tue, 22 Jul 2025 14:35:40 +0200 Subject: [PATCH 174/353] [v2] tests: fix volumetypes unit tests --- .../v3/volumetypes/testing/fixtures_test.go | 6 +++--- .../v3/volumetypes/testing/requests_test.go | 16 ++++++++-------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/openstack/blockstorage/v3/volumetypes/testing/fixtures_test.go b/openstack/blockstorage/v3/volumetypes/testing/fixtures_test.go index f2da8d0630..f1cacd21de 100644 --- a/openstack/blockstorage/v3/volumetypes/testing/fixtures_test.go +++ b/openstack/blockstorage/v3/volumetypes/testing/fixtures_test.go @@ -378,10 +378,10 @@ func MockEncryptionGetSpecResponse(t *testing.T, fakeServer th.FakeServer) { }) } -func HandleListIsPublicParam(t *testing.T, values map[string]string) { - th.Mux.HandleFunc("/types", func(w http.ResponseWriter, r *http.Request) { +func HandleListIsPublicParam(t *testing.T, fakeServer th.FakeServer, values map[string]string) { + fakeServer.Mux.HandleFunc("/types", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestFormValues(t, r, values) w.Header().Add("Content-Type", "application/json") diff --git a/openstack/blockstorage/v3/volumetypes/testing/requests_test.go b/openstack/blockstorage/v3/volumetypes/testing/requests_test.go index ccc7650d00..2ed84d144e 100644 --- a/openstack/blockstorage/v3/volumetypes/testing/requests_test.go +++ b/openstack/blockstorage/v3/volumetypes/testing/requests_test.go @@ -123,32 +123,32 @@ func TestUpdate(t *testing.T) { } func TestListIsPublicParam(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() result := make(map[string]string) - HandleListIsPublicParam(t, result) + HandleListIsPublicParam(t, fakeServer, result) // An empty ListOpts should query both public and private volume types by default. result["is_public"] = "None" - err := volumetypes.List(client.ServiceClient(), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err := volumetypes.List(client.ServiceClient(fakeServer), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { return true, nil }) th.AssertNoErr(t, err) - err = volumetypes.List(client.ServiceClient(), volumetypes.ListOpts{IsPublic: volumetypes.VisibilityDefault}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err = volumetypes.List(client.ServiceClient(fakeServer), volumetypes.ListOpts{IsPublic: volumetypes.VisibilityDefault}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { return true, nil }) th.AssertNoErr(t, err) // Specific visibility queries result["is_public"] = "true" - err = volumetypes.List(client.ServiceClient(), volumetypes.ListOpts{IsPublic: volumetypes.VisibilityPublic}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err = volumetypes.List(client.ServiceClient(fakeServer), volumetypes.ListOpts{IsPublic: volumetypes.VisibilityPublic}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { return true, nil }) th.AssertNoErr(t, err) result["is_public"] = "false" - err = volumetypes.List(client.ServiceClient(), volumetypes.ListOpts{IsPublic: volumetypes.VisibilityPrivate}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err = volumetypes.List(client.ServiceClient(fakeServer), volumetypes.ListOpts{IsPublic: volumetypes.VisibilityPrivate}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { return true, nil }) th.AssertNoErr(t, err) @@ -156,7 +156,7 @@ func TestListIsPublicParam(t *testing.T) { // Specific visibility query while ensuring other options are still considered. result["is_public"] = "None" result["sort"] = "asc" - err = volumetypes.List(client.ServiceClient(), volumetypes.ListOpts{IsPublic: volumetypes.VisibilityDefault, Sort: "asc"}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + err = volumetypes.List(client.ServiceClient(fakeServer), volumetypes.ListOpts{IsPublic: volumetypes.VisibilityDefault, Sort: "asc"}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { return true, nil }) th.AssertNoErr(t, err) From 804e6c1ca5807252b22ad43ef2a9595ccf59ff1a Mon Sep 17 00:00:00 2001 From: Fabian Wiesel Date: Tue, 22 Jul 2025 10:19:18 +0200 Subject: [PATCH 175/353] Implement update & delete traits on resource provider MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This implements #2420. The relevant server side code can be found here: https://github.com/openstack/placement/blob/stable/2025.1/placement/handlers/trait.py#L216-L274 Co-authored-by: pýrus --- .../v1/resourceproviders/requests.go | 35 +++++++++++++++++++ .../testing/fixtures_test.go | 26 ++++++++++++++ .../testing/requests_test.go | 22 ++++++++++++ 3 files changed, 83 insertions(+) diff --git a/openstack/placement/v1/resourceproviders/requests.go b/openstack/placement/v1/resourceproviders/requests.go index 5c5075e445..f0dfa9d66f 100644 --- a/openstack/placement/v1/resourceproviders/requests.go +++ b/openstack/placement/v1/resourceproviders/requests.go @@ -175,3 +175,38 @@ func GetTraits(ctx context.Context, client *gophercloud.ServiceClient, resourceP _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) return } + +// UpdateTraitsOptsBuilder allows extensions to add additional parameters to the +// UpdateTraits request. +type UpdateTraitsOptsBuilder interface { + ToResourceProviderUpdateTraitsMap() (map[string]any, error) +} + +// UpdateTraitsOpts represents options used to update traits of a resource provider. +type UpdateTraitsOpts = ResourceProviderTraits + +// ToResourceProviderUpdateTraitsMap constructs a request body from UpdateTraitsOpts. +func (opts UpdateTraitsOpts) ToResourceProviderUpdateTraitsMap() (map[string]any, error) { + return gophercloud.BuildRequestBody(opts, "") +} + +func UpdateTraits(ctx context.Context, client *gophercloud.ServiceClient, resourceProviderID string, opts UpdateTraitsOptsBuilder) (r GetTraitsResult) { + b, err := opts.ToResourceProviderUpdateTraitsMap() + if err != nil { + r.Err = err + return + } + resp, err := client.Put(ctx, getResourceProviderTraitsURL(client, resourceProviderID), b, &r.Body, &gophercloud.RequestOpts{ + OkCodes: []int{200}, + }) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} + +func DeleteTraits(ctx context.Context, client *gophercloud.ServiceClient, resourceProviderID string) (r DeleteResult) { + resp, err := client.Delete(ctx, getResourceProviderTraitsURL(client, resourceProviderID), &gophercloud.RequestOpts{ + OkCodes: []int{204}, + }) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} diff --git a/openstack/placement/v1/resourceproviders/testing/fixtures_test.go b/openstack/placement/v1/resourceproviders/testing/fixtures_test.go index 7ddc91b240..6ac4b8ca73 100644 --- a/openstack/placement/v1/resourceproviders/testing/fixtures_test.go +++ b/openstack/placement/v1/resourceproviders/testing/fixtures_test.go @@ -387,3 +387,29 @@ func HandleResourceProviderGetTraits(t *testing.T, fakeServer th.FakeServer) { fmt.Fprint(w, TraitsBody) }) } + +func HandleResourceProviderPutTraits(t *testing.T, fakeServer th.FakeServer) { + traitsTestUrl := fmt.Sprintf("/resource_providers/%s/traits", ResourceProviderTestID) + + fakeServer.Mux.HandleFunc(traitsTestUrl, + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "PUT") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + + fmt.Fprint(w, TraitsBody) + }) +} + +func HandleResourceProviderDeleteTraits(t *testing.T, fakeServer th.FakeServer) { + traitsTestUrl := fmt.Sprintf("/resource_providers/%s/traits", ResourceProviderTestID) + + fakeServer.Mux.HandleFunc(traitsTestUrl, + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "DELETE") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + w.WriteHeader(http.StatusNoContent) + }) +} diff --git a/openstack/placement/v1/resourceproviders/testing/requests_test.go b/openstack/placement/v1/resourceproviders/testing/requests_test.go index 1336126ecb..4633c81136 100644 --- a/openstack/placement/v1/resourceproviders/testing/requests_test.go +++ b/openstack/placement/v1/resourceproviders/testing/requests_test.go @@ -145,3 +145,25 @@ func TestGetResourceProvidersTraits(t *testing.T) { th.AssertNoErr(t, err) th.AssertDeepEquals(t, ExpectedTraits, *actual) } + +func TestUpdateResourceProvidersTraits(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleResourceProviderPutTraits(t, fakeServer) + + opts := resourceproviders.UpdateTraitsOpts(ExpectedTraits) + actual, err := resourceproviders.UpdateTraits(context.TODO(), client.ServiceClient(fakeServer), ResourceProviderTestID, opts).Extract() + th.AssertNoErr(t, err) + th.AssertDeepEquals(t, ExpectedTraits, *actual) +} + +func TestDeleteResourceProvidersTraits(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleResourceProviderDeleteTraits(t, fakeServer) + + err := resourceproviders.DeleteTraits(context.TODO(), client.ServiceClient(fakeServer), ResourceProviderTestID).ExtractErr() + th.AssertNoErr(t, err) +} From 44d4bee9c58fec55a26f4ec4047517548638fa2c Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Tue, 15 Jul 2025 15:01:30 +0100 Subject: [PATCH 176/353] script: Improve getenvvar helper * Handle multiple clouds.yaml files * Use OS_CLOUDS if set * Add uv dependencies metadata header Signed-off-by: Stephen Finucane --- script/getenvvar | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/script/getenvvar b/script/getenvvar index dbaa08f445..5d630f6ddf 100755 --- a/script/getenvvar +++ b/script/getenvvar @@ -1,4 +1,10 @@ #!/usr/bin/env python3 +# /// script +# requires-python = ">=3.13" +# dependencies = [ +# "pyyaml>=6", +# ] +# /// """ Set environment variables required for the CI jobs by inspection of the @@ -14,22 +20,40 @@ To unset them: """ import argparse +import os from pathlib import Path import sys import yaml -p = Path('~/.config/openstack/clouds.yaml').expanduser() parser = argparse.ArgumentParser() parser.add_argument( 'cloud', + default=os.getenv('OS_CLOUD'), + nargs='?', help="Cloud to export credentials for", ) args = parser.parse_args() -with p.open() as fh: - data = yaml.safe_load(fh) +for p in ( + Path('clouds.yaml'), + Path('~/.config/openstack/clouds.yaml').expanduser(), + Path('/etc/openstack/clouds.yaml'), +): + if not p.exists(): + continue + + with p.open() as fh: + data = yaml.safe_load(fh) + break +else: + print('Could not find clouds.yaml file', file=sys.stderr) + sys.exit(1) + +if not args.cloud: + print('Need to provide cloud argument or set OS_CLOUD', file=sys.stderr) + sys.exit(1) if args.cloud not in data.get('clouds', {}) or {}: print(f'Could not find cloud {args.cloud} in {str(p)}', file=sys.stderr) From 8c1ed4a7be1dd0c352c366c52f57059a9215db87 Mon Sep 17 00:00:00 2001 From: Fabian Wiesel Date: Thu, 31 Jul 2025 12:34:18 +0200 Subject: [PATCH 177/353] Implement hypervisors.GetExt: Get with Query parameter This introduces a new function GetExt in order to avoid breaking backwards compatibility. Implements #3479 --- openstack/compute/v2/hypervisors/requests.go | 35 ++++- .../v2/hypervisors/testing/fixtures_test.go | 120 ++++++++++++++++++ .../v2/hypervisors/testing/requests_test.go | 12 ++ 3 files changed, 166 insertions(+), 1 deletion(-) diff --git a/openstack/compute/v2/hypervisors/requests.go b/openstack/compute/v2/hypervisors/requests.go index b17dd35781..2483d73407 100644 --- a/openstack/compute/v2/hypervisors/requests.go +++ b/openstack/compute/v2/hypervisors/requests.go @@ -66,9 +66,42 @@ func GetStatistics(ctx context.Context, client *gophercloud.ServiceClient) (r St return } +// GetOptsBuilder allows extensions to add additional parameters to the +// Get request. +type GetOptsBuilder interface { + ToHypervisorGetQuery() (string, error) +} + +// GetOpts allows the opt-in to add the servers to the response +type GetOpts struct { + // WithServers is a bool to include all servers which belong to the hypervisor + // This requires microversion 2.53 or later + WithServers *bool `q:"with_servers"` +} + +// ToHypervisorGetQuery formats a GetOpts into a query string. +func (opts GetOpts) ToHypervisorGetQuery() (string, error) { + q, err := gophercloud.BuildQueryString(opts) + return q.String(), err +} + // Get makes a request against the API to get details for specific hypervisor. func Get(ctx context.Context, client *gophercloud.ServiceClient, hypervisorID string) (r HypervisorResult) { - resp, err := client.Get(ctx, hypervisorsGetURL(client, hypervisorID), &r.Body, &gophercloud.RequestOpts{ + return GetExt(ctx, client, hypervisorID, nil) +} + +// Show makes a request against the API to get details for specific hypervisor with optional query parameters +func GetExt(ctx context.Context, client *gophercloud.ServiceClient, hypervisorID string, opts GetOptsBuilder) (r HypervisorResult) { + url := hypervisorsGetURL(client, hypervisorID) + if opts != nil { + query, err := opts.ToHypervisorGetQuery() + if err != nil { + return HypervisorResult{gophercloud.Result{Err: err}} + } + url += query + } + + resp, err := client.Get(ctx, url, &r.Body, &gophercloud.RequestOpts{ OkCodes: []int{200}, }) _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) diff --git a/openstack/compute/v2/hypervisors/testing/fixtures_test.go b/openstack/compute/v2/hypervisors/testing/fixtures_test.go index ebfd816c03..166c415106 100644 --- a/openstack/compute/v2/hypervisors/testing/fixtures_test.go +++ b/openstack/compute/v2/hypervisors/testing/fixtures_test.go @@ -329,6 +329,62 @@ const HypervisorGetBody = ` } ` +// HypervisorGetPost253Body represents a raw hypervisor GET result with Pike+ +// release with optional server list +const HypervisorGetPost253Body = ` +{ + "hypervisor":{ + "cpu_info":{ + "arch":"x86_64", + "model":"Nehalem", + "vendor":"Intel", + "features":[ + "pge", + "clflush" + ], + "topology":{ + "cores":1, + "threads":1, + "sockets":4 + } + }, + "current_workload":0, + "status":"enabled", + "state":"up", + "servers": [ + { + "name": "test_server1", + "uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" + }, + { + "name": "test_server2", + "uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb" + } + ], + "disk_available_least":0, + "host_ip":"1.1.1.1", + "free_disk_gb":1028, + "free_ram_mb":7680, + "hypervisor_hostname":"fake-mini", + "hypervisor_type":"fake", + "hypervisor_version":2002000, + "id":"c48f6247-abe4-4a24-824e-ea39e108874f", + "local_gb":1028, + "local_gb_used":0, + "memory_mb":8192, + "memory_mb_used":512, + "running_vms":2, + "service":{ + "host":"e6a37ee802d74863ab8b91ade8f12a67", + "id":"9c2566e7-7a54-4777-a1ae-c2662f0c407c", + "disabled_reason":null + }, + "vcpus":1, + "vcpus_used":0 + } +} +` + // HypervisorGetEmptyCPUInfoBody represents a raw hypervisor GET result with // no cpu_info const HypervisorGetEmptyCPUInfoBody = ` @@ -487,6 +543,56 @@ var ( VCPUsUsed: 0, } + HypervisorFakeWithServers = hypervisors.Hypervisor{ + CPUInfo: hypervisors.CPUInfo{ + Arch: "x86_64", + Model: "Nehalem", + Vendor: "Intel", + Features: []string{ + "pge", + "clflush", + }, + Topology: hypervisors.Topology{ + Cores: 1, + Threads: 1, + Sockets: 4, + }, + }, + CurrentWorkload: 0, + Status: "enabled", + State: "up", + Servers: &[]hypervisors.Server{ + { + Name: "test_server1", + UUID: "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa", + }, + { + Name: "test_server2", + UUID: "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb", + }, + }, + DiskAvailableLeast: 0, + HostIP: "1.1.1.1", + FreeDiskGB: 1028, + FreeRamMB: 7680, + HypervisorHostname: "fake-mini", + HypervisorType: "fake", + HypervisorVersion: 2002000, + ID: "c48f6247-abe4-4a24-824e-ea39e108874f", + LocalGB: 1028, + LocalGBUsed: 0, + MemoryMB: 8192, + MemoryMBUsed: 512, + RunningVMs: 2, + Service: hypervisors.Service{ + Host: "e6a37ee802d74863ab8b91ade8f12a67", + ID: "9c2566e7-7a54-4777-a1ae-c2662f0c407c", + DisabledReason: "", + }, + VCPUs: 1, + VCPUsUsed: 0, + } + HypervisorFakeWithParameters = hypervisors.Hypervisor{ CPUInfo: hypervisors.CPUInfo{ Arch: "x86_64", @@ -676,6 +782,20 @@ func HandleHypervisorGetSuccessfully(t *testing.T, fakeServer th.FakeServer) { }) } +func HandleHypervisorGetPost253Successfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/os-hypervisors/"+HypervisorFake.ID, func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.Header().Add("Content-Type", "application/json") + if r.URL.Query().Get("with_servers") == "true" { + fmt.Fprint(w, HypervisorGetPost253Body) + } else { + fmt.Fprint(w, HypervisorGetBody) + } + }) +} + func HandleHypervisorGetEmptyCPUInfoSuccessfully(t *testing.T, fakeServer th.FakeServer) { fakeServer.Mux.HandleFunc("/os-hypervisors/"+HypervisorFake.ID, func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") diff --git a/openstack/compute/v2/hypervisors/testing/requests_test.go b/openstack/compute/v2/hypervisors/testing/requests_test.go index a2b2183e48..c6c7d9141f 100644 --- a/openstack/compute/v2/hypervisors/testing/requests_test.go +++ b/openstack/compute/v2/hypervisors/testing/requests_test.go @@ -135,6 +135,18 @@ func TestGetHypervisor(t *testing.T) { th.CheckDeepEquals(t, &expected, actual) } +func TestGetWithServersHypervisor(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleHypervisorGetPost253Successfully(t, fakeServer) + + expected := HypervisorFakeWithServers + withServers := true + actual, err := hypervisors.GetExt(context.TODO(), client.ServiceClient(fakeServer), expected.ID, hypervisors.GetOpts{WithServers: &withServers}).Extract() + th.AssertNoErr(t, err) + th.CheckDeepEquals(t, &expected, actual) +} + func TestGetHypervisorEmptyCPUInfo(t *testing.T) { fakeServer := th.SetupHTTP() defer fakeServer.Teardown() From 7dd3c689db49d6c6b2e48bdcc3877b9898b1a054 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Wed, 16 Apr 2025 13:00:26 +0100 Subject: [PATCH 178/353] trivial: Simplify endpoint filtering We do not need to check the validity of the provided opts more than once so don't. We can also simplify our handling of multiple endpoints (though not as much as we'd like in the v2 case, due to forthcoming patches). Signed-off-by: Stephen Finucane (cherry picked from commit 43294956db79da1ba7e02f169494ebd29a3040be) --- openstack/endpoint_location.go | 90 +++++++++++++++------------------- 1 file changed, 39 insertions(+), 51 deletions(-) diff --git a/openstack/endpoint_location.go b/openstack/endpoint_location.go index 14cff0d755..f7950067b1 100644 --- a/openstack/endpoint_location.go +++ b/openstack/endpoint_location.go @@ -20,39 +20,33 @@ available on your OpenStack deployment. */ func V2EndpointURL(catalog *tokens2.ServiceCatalog, opts gophercloud.EndpointOpts) (string, error) { // Extract Endpoints from the catalog entries that match the requested Type, Name if provided, and Region if provided. - var endpoints = make([]tokens2.Endpoint, 0, 1) + // + // If multiple endpoints are found, we return the first result and disregard the rest. + // This behavior matches the Python library. See GH-1764. for _, entry := range catalog.Entries { if (slices.Contains(opts.Types(), entry.Type)) && (opts.Name == "" || entry.Name == opts.Name) { for _, endpoint := range entry.Endpoints { - if opts.Region == "" || endpoint.Region == opts.Region { - endpoints = append(endpoints, endpoint) + if opts.Region != "" && endpoint.Region != opts.Region { + continue } - } - } - } - // If multiple endpoints were found, use the first result - // and disregard the other endpoints. - // - // This behavior matches the Python library. See GH-1764. - if len(endpoints) > 1 { - endpoints = endpoints[0:1] - } + var endpointURL string + switch opts.Availability { + case gophercloud.AvailabilityPublic: + endpointURL = gophercloud.NormalizeURL(endpoint.PublicURL) + case gophercloud.AvailabilityInternal: + endpointURL = gophercloud.NormalizeURL(endpoint.InternalURL) + case gophercloud.AvailabilityAdmin: + endpointURL = gophercloud.NormalizeURL(endpoint.AdminURL) + default: + err := &ErrInvalidAvailabilityProvided{} + err.Argument = "Availability" + err.Value = opts.Availability + return "", err + } - // Extract the appropriate URL from the matching Endpoint. - for _, endpoint := range endpoints { - switch opts.Availability { - case gophercloud.AvailabilityPublic: - return gophercloud.NormalizeURL(endpoint.PublicURL), nil - case gophercloud.AvailabilityInternal: - return gophercloud.NormalizeURL(endpoint.InternalURL), nil - case gophercloud.AvailabilityAdmin: - return gophercloud.NormalizeURL(endpoint.AdminURL), nil - default: - err := &ErrInvalidAvailabilityProvided{} - err.Argument = "Availability" - err.Value = opts.Availability - return "", err + return endpointURL, nil + } } } @@ -72,41 +66,35 @@ will also often need to specify a Name and/or a Region depending on what's available on your OpenStack deployment. */ func V3EndpointURL(catalog *tokens3.ServiceCatalog, opts gophercloud.EndpointOpts) (string, error) { + if opts.Availability != gophercloud.AvailabilityAdmin && + opts.Availability != gophercloud.AvailabilityPublic && + opts.Availability != gophercloud.AvailabilityInternal { + err := &ErrInvalidAvailabilityProvided{} + err.Argument = "Availability" + err.Value = opts.Availability + return "", err + } + // Extract Endpoints from the catalog entries that match the requested Type, Interface, // Name if provided, and Region if provided. - var endpoints = make([]tokens3.Endpoint, 0, 1) + // + // If multiple endpoints are found, we return the first result and disregard the rest. + // This behavior matches the Python library. See GH-1764. for _, entry := range catalog.Entries { if (slices.Contains(opts.Types(), entry.Type)) && (opts.Name == "" || entry.Name == opts.Name) { for _, endpoint := range entry.Endpoints { - if opts.Availability != gophercloud.AvailabilityAdmin && - opts.Availability != gophercloud.AvailabilityPublic && - opts.Availability != gophercloud.AvailabilityInternal { - err := &ErrInvalidAvailabilityProvided{} - err.Argument = "Availability" - err.Value = opts.Availability - return "", err + if opts.Availability != gophercloud.Availability(endpoint.Interface) { + continue } - if (opts.Availability == gophercloud.Availability(endpoint.Interface)) && - (opts.Region == "" || endpoint.Region == opts.Region || endpoint.RegionID == opts.Region) { - endpoints = append(endpoints, endpoint) + if opts.Region != "" && endpoint.Region != opts.Region && endpoint.RegionID != opts.Region { + continue } + + return gophercloud.NormalizeURL(endpoint.URL), nil } } } - // If multiple endpoints were found, use the first result - // and disregard the other endpoints. - // - // This behavior matches the Python library. See GH-1764. - if len(endpoints) > 1 { - endpoints = endpoints[0:1] - } - - // Extract the URL from the matching Endpoint. - for _, endpoint := range endpoints { - return gophercloud.NormalizeURL(endpoint.URL), nil - } - // Report an error if there were no matching endpoints. err := &gophercloud.ErrEndpointNotFound{} return "", err From b9eb818da157f9c20d797379067cb47ad301f684 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Wed, 16 Apr 2025 12:54:16 +0100 Subject: [PATCH 179/353] Add EndpointOpts.Version field We will use this to do proper discovery across multiple versions. Signed-off-by: Stephen Finucane (cherry picked from commit bae4c6fb02ad91b171e18c951e2b0076cf47b1e2) --- endpoint_search.go | 5 +++++ openstack/client.go | 50 ++++++++++++++++++++++++++------------------- 2 files changed, 34 insertions(+), 21 deletions(-) diff --git a/endpoint_search.go b/endpoint_search.go index 159a02c2dd..34d76a1b8d 100644 --- a/endpoint_search.go +++ b/endpoint_search.go @@ -79,6 +79,11 @@ type EndpointOpts struct { // Required only for services that span multiple regions. Region string + // Version [optional] is the major version of the service required. It it not + // a microversion. Use this to ensure the correct endpoint is selected when + // multiple API versions are available. + Version int + // Availability [optional] is the visibility of the endpoint to be returned. // Valid types include the constants AvailabilityPublic, AvailabilityInternal, // or AvailabilityAdmin from this package. diff --git a/openstack/client.go b/openstack/client.go index 122a3ee699..df8044024f 100644 --- a/openstack/client.go +++ b/openstack/client.go @@ -2,6 +2,7 @@ package openstack import ( "context" + "errors" "fmt" "reflect" "strings" @@ -345,13 +346,20 @@ func NewIdentityV3(client *gophercloud.ProviderClient, eo gophercloud.EndpointOp } // TODO(stephenfin): Allow passing aliases to all New${SERVICE}V${VERSION} methods in v3 -func initClientOpts(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts, clientType string) (*gophercloud.ServiceClient, error) { +func initClientOpts(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts, clientType string, version int) (*gophercloud.ServiceClient, error) { sc := new(gophercloud.ServiceClient) + eo.ApplyDefaults(clientType) + if eo.Version != 0 && eo.Version != version { + return sc, errors.New("Conflict between requested service major version and manually set version") + } + eo.Version = version + url, err := client.EndpointLocator(eo) if err != nil { return sc, err } + sc.ProviderClient = client sc.Endpoint = url sc.Type = clientType @@ -361,7 +369,7 @@ func initClientOpts(client *gophercloud.ProviderClient, eo gophercloud.EndpointO // NewBareMetalV1 creates a ServiceClient that may be used with the v1 // bare metal package. func NewBareMetalV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { - sc, err := initClientOpts(client, eo, "baremetal") + sc, err := initClientOpts(client, eo, "baremetal", 1) if !strings.HasSuffix(strings.TrimSuffix(sc.Endpoint, "/"), "v1") { sc.ResourceBase = sc.Endpoint + "v1/" } @@ -371,25 +379,25 @@ func NewBareMetalV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointO // NewBareMetalIntrospectionV1 creates a ServiceClient that may be used with the v1 // bare metal introspection package. func NewBareMetalIntrospectionV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { - return initClientOpts(client, eo, "baremetal-introspection") + return initClientOpts(client, eo, "baremetal-introspection", 1) } // NewObjectStorageV1 creates a ServiceClient that may be used with the v1 // object storage package. func NewObjectStorageV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { - return initClientOpts(client, eo, "object-store") + return initClientOpts(client, eo, "object-store", 1) } // NewComputeV2 creates a ServiceClient that may be used with the v2 compute // package. func NewComputeV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { - return initClientOpts(client, eo, "compute") + return initClientOpts(client, eo, "compute", 2) } // NewNetworkV2 creates a ServiceClient that may be used with the v2 network // package. func NewNetworkV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { - sc, err := initClientOpts(client, eo, "network") + sc, err := initClientOpts(client, eo, "network", 2) sc.ResourceBase = sc.Endpoint + "v2.0/" return sc, err } @@ -398,40 +406,40 @@ func NewNetworkV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpt // NewBlockStorageV1 creates a ServiceClient that may be used to access the v1 // block storage service. func NewBlockStorageV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { - return initClientOpts(client, eo, "volume") + return initClientOpts(client, eo, "volume", 1) } // NewBlockStorageV2 creates a ServiceClient that may be used to access the v2 // block storage service. func NewBlockStorageV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { - return initClientOpts(client, eo, "block-storage") + return initClientOpts(client, eo, "block-storage", 2) } // NewBlockStorageV3 creates a ServiceClient that may be used to access the v3 block storage service. func NewBlockStorageV3(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { - return initClientOpts(client, eo, "block-storage") + return initClientOpts(client, eo, "block-storage", 3) } // NewSharedFileSystemV2 creates a ServiceClient that may be used to access the v2 shared file system service. func NewSharedFileSystemV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { - return initClientOpts(client, eo, "shared-file-system") + return initClientOpts(client, eo, "shared-file-system", 2) } // NewOrchestrationV1 creates a ServiceClient that may be used to access the v1 // orchestration service. func NewOrchestrationV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { - return initClientOpts(client, eo, "orchestration") + return initClientOpts(client, eo, "orchestration", 1) } // NewDBV1 creates a ServiceClient that may be used to access the v1 DB service. func NewDBV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { - return initClientOpts(client, eo, "database") + return initClientOpts(client, eo, "database", 1) } // NewDNSV2 creates a ServiceClient that may be used to access the v2 DNS // service. func NewDNSV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { - sc, err := initClientOpts(client, eo, "dns") + sc, err := initClientOpts(client, eo, "dns", 2) sc.ResourceBase = sc.Endpoint + "v2/" return sc, err } @@ -439,7 +447,7 @@ func NewDNSV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) ( // NewImageV2 creates a ServiceClient that may be used to access the v2 image // service. func NewImageV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { - sc, err := initClientOpts(client, eo, "image") + sc, err := initClientOpts(client, eo, "image", 2) sc.ResourceBase = sc.Endpoint + "v2/" return sc, err } @@ -447,7 +455,7 @@ func NewImageV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) // NewLoadBalancerV2 creates a ServiceClient that may be used to access the v2 // load balancer service. func NewLoadBalancerV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { - sc, err := initClientOpts(client, eo, "load-balancer") + sc, err := initClientOpts(client, eo, "load-balancer", 2) // Fixes edge case having an OpenStack lb endpoint with trailing version number. endpoint := strings.Replace(sc.Endpoint, "v2.0/", "", -1) @@ -459,20 +467,20 @@ func NewLoadBalancerV2(client *gophercloud.ProviderClient, eo gophercloud.Endpoi // NewMessagingV2 creates a ServiceClient that may be used with the v2 messaging // service. func NewMessagingV2(client *gophercloud.ProviderClient, clientID string, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { - sc, err := initClientOpts(client, eo, "message") + sc, err := initClientOpts(client, eo, "message", 2) sc.MoreHeaders = map[string]string{"Client-ID": clientID} return sc, err } // NewContainerV1 creates a ServiceClient that may be used with v1 container package func NewContainerV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { - return initClientOpts(client, eo, "application-container") + return initClientOpts(client, eo, "application-container", 1) } // NewKeyManagerV1 creates a ServiceClient that may be used with the v1 key // manager service. func NewKeyManagerV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { - sc, err := initClientOpts(client, eo, "key-manager") + sc, err := initClientOpts(client, eo, "key-manager", 1) sc.ResourceBase = sc.Endpoint + "v1/" return sc, err } @@ -480,15 +488,15 @@ func NewKeyManagerV1(client *gophercloud.ProviderClient, eo gophercloud.Endpoint // NewContainerInfraV1 creates a ServiceClient that may be used with the v1 container infra management // package. func NewContainerInfraV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { - return initClientOpts(client, eo, "container-infrastructure-management") + return initClientOpts(client, eo, "container-infrastructure-management", 1) } // NewWorkflowV2 creates a ServiceClient that may be used with the v2 workflow management package. func NewWorkflowV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { - return initClientOpts(client, eo, "workflow") + return initClientOpts(client, eo, "workflow", 2) } // NewPlacementV1 creates a ServiceClient that may be used with the placement package. func NewPlacementV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { - return initClientOpts(client, eo, "placement") + return initClientOpts(client, eo, "placement", 1) } From 515534905ddc24e4978ad6f5792506ba85950dd7 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Thu, 17 Apr 2025 18:02:36 +0100 Subject: [PATCH 180/353] Add BaseVersionedEndpoint helper This retrieves the base endpoint without stripping the version information. This is helpful for service catalog entries that include project IDs, like those historically preferred by Cinder for some reason. Signed-off-by: Stephen Finucane (cherry picked from commit 2bf97ce67e243b954f24a35a1ffaa4ad478fd676) --- openstack/utils/base_endpoint.go | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/openstack/utils/base_endpoint.go b/openstack/utils/base_endpoint.go index 40080f7af2..f219c0bf4d 100644 --- a/openstack/utils/base_endpoint.go +++ b/openstack/utils/base_endpoint.go @@ -6,9 +6,7 @@ import ( "strings" ) -// BaseEndpoint will return a URL without the /vX.Y -// portion of the URL. -func BaseEndpoint(endpoint string) (string, error) { +func parseEndpoint(endpoint string, includeVersion bool) (string, error) { u, err := url.Parse(endpoint) if err != nil { return "", err @@ -21,8 +19,23 @@ func BaseEndpoint(endpoint string) (string, error) { if version := versionRe.FindString(path); version != "" { versionIndex := strings.Index(path, version) + if includeVersion { + versionIndex += len(version) + } u.Path = path[:versionIndex] } return u.String(), nil } + +// BaseEndpoint will return a URL without the /vX.Y +// portion of the URL. +func BaseEndpoint(endpoint string) (string, error) { + return parseEndpoint(endpoint, false) +} + +// BaseVersionedEndpoint will return a URL with the /vX.Y portion of the URL, +// if present, but without a project ID or similar +func BaseVersionedEndpoint(endpoint string) (string, error) { + return parseEndpoint(endpoint, true) +} From 7db8ba04569c5196c5e6abeb7f85f94ff7213886 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Thu, 17 Apr 2025 15:55:08 +0100 Subject: [PATCH 181/353] Add new service discovery helper This is an re-implementation of GetSupportedMicroversions that supports use with a ProviderClient and an explicit endpoint URL, allowing us to use this during discovery. Signed-off-by: Stephen Finucane (cherry picked from commit 8cbcb2f8d1b9e0166381ceb26db38b8adb157977) --- openstack/utils/choose_version.go | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/openstack/utils/choose_version.go b/openstack/utils/choose_version.go index 6c720e57ef..ff5d93dd15 100644 --- a/openstack/utils/choose_version.go +++ b/openstack/utils/choose_version.go @@ -122,8 +122,8 @@ type SupportedMicroversions struct { MinMinor int } -// GetSupportedMicroversions returns the minimum and maximum microversion that is supported by the ServiceClient Endpoint. -func GetSupportedMicroversions(ctx context.Context, client *gophercloud.ServiceClient) (SupportedMicroversions, error) { +// GetServiceVersions returns the minimum and maximum microversion that is supported by the ServiceClient Endpoint. +func GetServiceVersions(ctx context.Context, client *gophercloud.ProviderClient, endpointURL string) (SupportedMicroversions, error) { type valueResp struct { ID string `json:"id"` Status string `json:"status"` @@ -138,8 +138,9 @@ func GetSupportedMicroversions(ctx context.Context, client *gophercloud.ServiceC var minVersion, maxVersion string var supportedMicroversions SupportedMicroversions var resp response - _, err := client.Get(ctx, client.Endpoint, &resp, &gophercloud.RequestOpts{ - OkCodes: []int{200, 300}, + _, err := client.Request(ctx, "GET", endpointURL, &gophercloud.RequestOpts{ + JSONResponse: &resp, + OkCodes: []int{200, 300}, }) if err != nil { @@ -161,7 +162,7 @@ func GetSupportedMicroversions(ctx context.Context, client *gophercloud.ServiceC // Return early if the endpoint does not support microversions if minVersion == "" && maxVersion == "" { - return supportedMicroversions, fmt.Errorf("microversions not supported by ServiceClient Endpoint") + return supportedMicroversions, fmt.Errorf("microversions not supported by endpoint") } supportedMicroversions.MinMajor, supportedMicroversions.MinMinor, err = ParseMicroversion(minVersion) @@ -177,6 +178,11 @@ func GetSupportedMicroversions(ctx context.Context, client *gophercloud.ServiceC return supportedMicroversions, nil } +// GetSupportedMicroversions returns the minimum and maximum microversion that is supported by the ServiceClient Endpoint. +func GetSupportedMicroversions(ctx context.Context, client *gophercloud.ServiceClient) (SupportedMicroversions, error) { + return GetServiceVersions(ctx, client.ProviderClient, client.Endpoint) +} + // RequireMicroversion checks that the required microversion is supported and // returns a ServiceClient with the microversion set. func RequireMicroversion(ctx context.Context, client gophercloud.ServiceClient, required string) (gophercloud.ServiceClient, error) { From 471e1ca82fa5c3badf5839ca26b42bff4a7e863f Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Thu, 17 Apr 2025 15:40:55 +0100 Subject: [PATCH 182/353] Add V2Endpoint, V3Endpoint helpers For now these are exact duplicates of the V2EndpointURL and V3EndpointURL helpers but with different names. diff -u openstack/endpoint_location.go openstack/endpoint.go This is done to ease review. We will introduce further differences shortly. Signed-off-by: Stephen Finucane (cherry picked from commit ed23d9b62c9e962377220626b6a27af6b27c4438) --- openstack/endpoint.go | 101 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 openstack/endpoint.go diff --git a/openstack/endpoint.go b/openstack/endpoint.go new file mode 100644 index 0000000000..2b6478cffc --- /dev/null +++ b/openstack/endpoint.go @@ -0,0 +1,101 @@ +package openstack + +import ( + "slices" + + "github.com/gophercloud/gophercloud/v2" + tokens2 "github.com/gophercloud/gophercloud/v2/openstack/identity/v2/tokens" + tokens3 "github.com/gophercloud/gophercloud/v2/openstack/identity/v3/tokens" +) + +/* +V2Endpoint discovers the endpoint URL for a specific service from a +ServiceCatalog acquired during the v2 identity service. + +The specified EndpointOpts are used to identify a unique, unambiguous endpoint +to return. It's an error both when multiple endpoints match the provided +criteria and when none do. The minimum that can be specified is a Type, but you +will also often need to specify a Name and/or a Region depending on what's +available on your OpenStack deployment. +*/ +func V2Endpoint(catalog *tokens2.ServiceCatalog, opts gophercloud.EndpointOpts) (string, error) { + // Extract Endpoints from the catalog entries that match the requested Type, Name if provided, and Region if provided. + // + // If multiple endpoints are found, we return the first result and disregard the rest. + // This behavior matches the Python library. See GH-1764. + for _, entry := range catalog.Entries { + if (slices.Contains(opts.Types(), entry.Type)) && (opts.Name == "" || entry.Name == opts.Name) { + for _, endpoint := range entry.Endpoints { + if opts.Region != "" && endpoint.Region != opts.Region { + continue + } + + var endpointURL string + switch opts.Availability { + case gophercloud.AvailabilityPublic: + endpointURL = gophercloud.NormalizeURL(endpoint.PublicURL) + case gophercloud.AvailabilityInternal: + endpointURL = gophercloud.NormalizeURL(endpoint.InternalURL) + case gophercloud.AvailabilityAdmin: + endpointURL = gophercloud.NormalizeURL(endpoint.AdminURL) + default: + err := &ErrInvalidAvailabilityProvided{} + err.Argument = "Availability" + err.Value = opts.Availability + return "", err + } + + return endpointURL, nil + } + } + } + + // Report an error if there were no matching endpoints. + err := &gophercloud.ErrEndpointNotFound{} + return "", err +} + +/* +V3Endpoint discovers the endpoint URL for a specific service from a Catalog +acquired during the v3 identity service. + +The specified EndpointOpts are used to identify a unique, unambiguous endpoint +to return. It's an error both when multiple endpoints match the provided +criteria and when none do. The minimum that can be specified is a Type, but you +will also often need to specify a Name and/or a Region depending on what's +available on your OpenStack deployment. +*/ +func V3Endpoint(catalog *tokens3.ServiceCatalog, opts gophercloud.EndpointOpts) (string, error) { + if opts.Availability != gophercloud.AvailabilityAdmin && + opts.Availability != gophercloud.AvailabilityPublic && + opts.Availability != gophercloud.AvailabilityInternal { + err := &ErrInvalidAvailabilityProvided{} + err.Argument = "Availability" + err.Value = opts.Availability + return "", err + } + + // Extract Endpoints from the catalog entries that match the requested Type, Interface, + // Name if provided, and Region if provided. + // + // If multiple endpoints are found, we return the first result and disregard the rest. + // This behavior matches the Python library. See GH-1764. + for _, entry := range catalog.Entries { + if (slices.Contains(opts.Types(), entry.Type)) && (opts.Name == "" || entry.Name == opts.Name) { + for _, endpoint := range entry.Endpoints { + if opts.Availability != gophercloud.Availability(endpoint.Interface) { + continue + } + if opts.Region != "" && endpoint.Region != opts.Region && endpoint.RegionID != opts.Region { + continue + } + + return gophercloud.NormalizeURL(endpoint.URL), nil + } + } + } + + // Report an error if there were no matching endpoints. + err := &gophercloud.ErrEndpointNotFound{} + return "", err +} From 61ea27914a917aad545dfa80f531785e912cc76f Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Thu, 17 Apr 2025 16:34:51 +0100 Subject: [PATCH 183/353] Add endpoint discovery support This is simpler than expected. Effectively, for each potential endpoint, we retrieve the version document from the root URL and parse the version information, if any, from it, comparing it against the version expected. Signed-off-by: Stephen Finucane (cherry picked from commit f28c96333f8138ce23a28c5c28fbbf1ca1eb480a) --- openstack/endpoint.go | 45 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/openstack/endpoint.go b/openstack/endpoint.go index 2b6478cffc..edbc3bda76 100644 --- a/openstack/endpoint.go +++ b/openstack/endpoint.go @@ -1,13 +1,34 @@ package openstack import ( + "context" "slices" "github.com/gophercloud/gophercloud/v2" tokens2 "github.com/gophercloud/gophercloud/v2/openstack/identity/v2/tokens" tokens3 "github.com/gophercloud/gophercloud/v2/openstack/identity/v3/tokens" + "github.com/gophercloud/gophercloud/v2/openstack/utils" ) +func endpointSupportsVersion(ctx context.Context, client *gophercloud.ProviderClient, serviceType, endpointURL string, expectedVersion int) (bool, error) { + // Swift doesn't support version discovery :( + if expectedVersion == 0 || serviceType == "object-store" { + return true, nil + } + + endpointURL, err := utils.BaseVersionedEndpoint(endpointURL) + if err != nil { + return false, err + } + + supportedMicroversions, err := utils.GetServiceVersions(ctx, client, endpointURL) + if err != nil { + return false, err + } + + return supportedMicroversions.MinMajor == 0 || supportedMicroversions.MinMajor == expectedVersion, nil +} + /* V2Endpoint discovers the endpoint URL for a specific service from a ServiceCatalog acquired during the v2 identity service. @@ -18,7 +39,7 @@ criteria and when none do. The minimum that can be specified is a Type, but you will also often need to specify a Name and/or a Region depending on what's available on your OpenStack deployment. */ -func V2Endpoint(catalog *tokens2.ServiceCatalog, opts gophercloud.EndpointOpts) (string, error) { +func V2Endpoint(ctx context.Context, client *gophercloud.ProviderClient, catalog *tokens2.ServiceCatalog, opts gophercloud.EndpointOpts) (string, error) { // Extract Endpoints from the catalog entries that match the requested Type, Name if provided, and Region if provided. // // If multiple endpoints are found, we return the first result and disregard the rest. @@ -45,6 +66,14 @@ func V2Endpoint(catalog *tokens2.ServiceCatalog, opts gophercloud.EndpointOpts) return "", err } + endpointSupportsVersion, err := endpointSupportsVersion(ctx, client, entry.Type, endpointURL, opts.Version) + if err != nil { + return "", err + } + if !endpointSupportsVersion { + continue + } + return endpointURL, nil } } @@ -65,7 +94,7 @@ criteria and when none do. The minimum that can be specified is a Type, but you will also often need to specify a Name and/or a Region depending on what's available on your OpenStack deployment. */ -func V3Endpoint(catalog *tokens3.ServiceCatalog, opts gophercloud.EndpointOpts) (string, error) { +func V3Endpoint(ctx context.Context, client *gophercloud.ProviderClient, catalog *tokens3.ServiceCatalog, opts gophercloud.EndpointOpts) (string, error) { if opts.Availability != gophercloud.AvailabilityAdmin && opts.Availability != gophercloud.AvailabilityPublic && opts.Availability != gophercloud.AvailabilityInternal { @@ -90,7 +119,17 @@ func V3Endpoint(catalog *tokens3.ServiceCatalog, opts gophercloud.EndpointOpts) continue } - return gophercloud.NormalizeURL(endpoint.URL), nil + endpointURL := gophercloud.NormalizeURL(endpoint.URL) + + endpointSupportsVersion, err := endpointSupportsVersion(ctx, client, entry.Type, endpointURL, opts.Version) + if err != nil { + return "", err + } + if !endpointSupportsVersion { + continue + } + + return endpointURL, nil } } } From aec6900b176d5a66692674c0f145541d8582a2fd Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Thu, 17 Apr 2025 16:50:17 +0100 Subject: [PATCH 184/353] Add implied version check Avoid unnecessary lookups for when we are encoding the version in our service type. Signed-off-by: Stephen Finucane (cherry picked from commit 07d1ee0ee6f3008c43d3427e24e87c2a8ec54658) --- openstack/endpoint.go | 44 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/openstack/endpoint.go b/openstack/endpoint.go index edbc3bda76..3f7cee0f48 100644 --- a/openstack/endpoint.go +++ b/openstack/endpoint.go @@ -2,7 +2,9 @@ package openstack import ( "context" + "regexp" "slices" + "strconv" "github.com/gophercloud/gophercloud/v2" tokens2 "github.com/gophercloud/gophercloud/v2/openstack/identity/v2/tokens" @@ -10,12 +12,54 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/utils" ) +var versionedServiceTypeAliasRegexp = regexp.MustCompile(`^.*v(\d)$`) + +func extractServiceTypeVersion(serviceType string) int { + matches := versionedServiceTypeAliasRegexp.FindAllStringSubmatch(serviceType, 1) + if matches != nil { + // no point converting to an int + ret, err := strconv.Atoi(matches[0][1]) + if err != nil { + return 0 + } + return ret + } + return 0 +} + func endpointSupportsVersion(ctx context.Context, client *gophercloud.ProviderClient, serviceType, endpointURL string, expectedVersion int) (bool, error) { // Swift doesn't support version discovery :( if expectedVersion == 0 || serviceType == "object-store" { return true, nil } + // Repeating verbatim from keystoneauth1 [1]: + // + // > The sins of our fathers become the blood on our hands. + // > If a user requests an old-style service type such as volumev2, then they + // > are inherently requesting the major API version 2. It's not a good + // > interface, but it's the one that was imposed on the world years ago + // > because the client libraries all hid the version discovery document. + // > In order to be able to ensure that a user who requests volumev2 does not + // > get a block-storage endpoint that only provides v3 of the block-storage + // > service, we need to pull the version out of the service_type. The + // > service-types-authority will prevent the growth of new monstrosities such + // > as this, but in order to move forward without breaking people, we have + // > to just cry in the corner while striking ourselves with thorned branches. + // > That said, for sure only do this hack for officially known service_types. + // + // So yeah, what mordred said. + // + // https://github.com/openstack/keystoneauth/blob/5.10.0/keystoneauth1/discover.py#L270-L290 + impliedVersion := extractServiceTypeVersion(serviceType) + if impliedVersion != 0 && impliedVersion != expectedVersion { + return false, nil + } + + // NOTE(stephenfin) In addition to the above, keystoneauth also supports a URL + // hack whereby it will extract the version from the URL. We may wish to + // implement this too. + endpointURL, err := utils.BaseVersionedEndpoint(endpointURL) if err != nil { return false, err From 47ec4ae6c40cb80339442f9bf489b9fe7aa90337 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Thu, 17 Apr 2025 16:37:45 +0100 Subject: [PATCH 185/353] Switch clients to versioned endpoint discovery helpers And deprecate the old ones since they are no longer used. Signed-off-by: Stephen Finucane (cherry picked from commit 8139f993585dffe71a96975fe842f8b2a1cbd626) --- openstack/client.go | 4 ++-- openstack/endpoint_location.go | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/openstack/client.go b/openstack/client.go index df8044024f..00dfca6ae7 100644 --- a/openstack/client.go +++ b/openstack/client.go @@ -163,7 +163,7 @@ func v2auth(ctx context.Context, client *gophercloud.ProviderClient, endpoint st } } client.EndpointLocator = func(opts gophercloud.EndpointOpts) (string, error) { - return V2EndpointURL(catalog, opts) + return V2Endpoint(ctx, client, catalog, opts) } return nil @@ -284,7 +284,7 @@ func v3auth(ctx context.Context, client *gophercloud.ProviderClient, endpoint st } } client.EndpointLocator = func(opts gophercloud.EndpointOpts) (string, error) { - return V3EndpointURL(catalog, opts) + return V3Endpoint(ctx, client, catalog, opts) } return nil diff --git a/openstack/endpoint_location.go b/openstack/endpoint_location.go index f7950067b1..573c1f06f4 100644 --- a/openstack/endpoint_location.go +++ b/openstack/endpoint_location.go @@ -8,6 +8,8 @@ import ( tokens3 "github.com/gophercloud/gophercloud/v2/openstack/identity/v3/tokens" ) +// TODO(stephenfin): Remove this module in v3. The functions below are no longer used. + /* V2EndpointURL discovers the endpoint URL for a specific service from a ServiceCatalog acquired during the v2 identity service. From c3ab2c3154e9ec5cae01af9439db847c58b6f299 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Mon, 16 Jun 2025 16:54:26 +0100 Subject: [PATCH 186/353] Move discovery logic to its own file Signed-off-by: Stephen Finucane (cherry picked from commit 82c2ca03afe89d3f528c342aae952d15a68c52bc) --- openstack/utils/choose_version.go | 128 +------ openstack/utils/discovery.go | 136 +++++++ .../utils/testing/choose_version_test.go | 334 ------------------ openstack/utils/testing/discovery_test.go | 172 +++++++++ openstack/utils/testing/fixtures_test.go | 179 ++++++++++ 5 files changed, 488 insertions(+), 461 deletions(-) create mode 100644 openstack/utils/discovery.go create mode 100644 openstack/utils/testing/discovery_test.go create mode 100644 openstack/utils/testing/fixtures_test.go diff --git a/openstack/utils/choose_version.go b/openstack/utils/choose_version.go index ff5d93dd15..ccc56345a6 100644 --- a/openstack/utils/choose_version.go +++ b/openstack/utils/choose_version.go @@ -3,7 +3,6 @@ package utils import ( "context" "fmt" - "strconv" "strings" "github.com/gophercloud/gophercloud/v2" @@ -29,6 +28,7 @@ var goodStatus = map[string]bool{ // It returns the highest-Priority Version, OR exact match with client endpoint, // among the alternatives that are provided, as well as its corresponding endpoint. func ChooseVersion(ctx context.Context, client *gophercloud.ProviderClient, recognized []*Version) (*Version, string, error) { + // TODO(stephenfin): This could be removed since we can accomplish this with GetServiceVersions now. type linkResp struct { Href string `json:"href"` Rel string `json:"rel"` @@ -114,129 +114,3 @@ func ChooseVersion(ctx context.Context, client *gophercloud.ProviderClient, reco return highest, endpoint, nil } - -type SupportedMicroversions struct { - MaxMajor int - MaxMinor int - MinMajor int - MinMinor int -} - -// GetServiceVersions returns the minimum and maximum microversion that is supported by the ServiceClient Endpoint. -func GetServiceVersions(ctx context.Context, client *gophercloud.ProviderClient, endpointURL string) (SupportedMicroversions, error) { - type valueResp struct { - ID string `json:"id"` - Status string `json:"status"` - Version string `json:"version"` - MinVersion string `json:"min_version"` - } - - type response struct { - Version valueResp `json:"version"` - Versions []valueResp `json:"versions"` - } - var minVersion, maxVersion string - var supportedMicroversions SupportedMicroversions - var resp response - _, err := client.Request(ctx, "GET", endpointURL, &gophercloud.RequestOpts{ - JSONResponse: &resp, - OkCodes: []int{200, 300}, - }) - - if err != nil { - return supportedMicroversions, err - } - - if len(resp.Versions) > 0 { - // We are dealing with an unversioned endpoint - // We only handle the case when there is exactly one, and assume it is the correct one - if len(resp.Versions) > 1 { - return supportedMicroversions, fmt.Errorf("unversioned endpoint with multiple alternatives not supported") - } - minVersion = resp.Versions[0].MinVersion - maxVersion = resp.Versions[0].Version - } else { - minVersion = resp.Version.MinVersion - maxVersion = resp.Version.Version - } - - // Return early if the endpoint does not support microversions - if minVersion == "" && maxVersion == "" { - return supportedMicroversions, fmt.Errorf("microversions not supported by endpoint") - } - - supportedMicroversions.MinMajor, supportedMicroversions.MinMinor, err = ParseMicroversion(minVersion) - if err != nil { - return supportedMicroversions, err - } - - supportedMicroversions.MaxMajor, supportedMicroversions.MaxMinor, err = ParseMicroversion(maxVersion) - if err != nil { - return supportedMicroversions, err - } - - return supportedMicroversions, nil -} - -// GetSupportedMicroversions returns the minimum and maximum microversion that is supported by the ServiceClient Endpoint. -func GetSupportedMicroversions(ctx context.Context, client *gophercloud.ServiceClient) (SupportedMicroversions, error) { - return GetServiceVersions(ctx, client.ProviderClient, client.Endpoint) -} - -// RequireMicroversion checks that the required microversion is supported and -// returns a ServiceClient with the microversion set. -func RequireMicroversion(ctx context.Context, client gophercloud.ServiceClient, required string) (gophercloud.ServiceClient, error) { - supportedMicroversions, err := GetSupportedMicroversions(ctx, &client) - if err != nil { - return client, fmt.Errorf("unable to determine supported microversions: %w", err) - } - supported, err := supportedMicroversions.IsSupported(required) - if err != nil { - return client, err - } - if !supported { - return client, fmt.Errorf("microversion %s not supported. Supported versions: %v", required, supportedMicroversions) - } - client.Microversion = required - return client, nil -} - -// IsSupported checks if a microversion falls in the supported interval. -// It returns true if the version is within the interval and false otherwise. -func (supported SupportedMicroversions) IsSupported(version string) (bool, error) { - // Parse the version X.Y into X and Y integers that are easier to compare. - vMajor, vMinor, err := ParseMicroversion(version) - if err != nil { - return false, err - } - - // Check that the major version number is supported. - if (vMajor < supported.MinMajor) || (vMajor > supported.MaxMajor) { - return false, nil - } - - // Check that the minor version number is supported - if (vMinor <= supported.MaxMinor) && (vMinor >= supported.MinMinor) { - return true, nil - } - - return false, nil -} - -// ParseMicroversion parses the version major.minor into separate integers major and minor. -// For example, "2.53" becomes 2 and 53. -func ParseMicroversion(version string) (major int, minor int, err error) { - parts := strings.Split(version, ".") - if len(parts) != 2 { - return 0, 0, fmt.Errorf("invalid microversion format: %q", version) - } - major, err = strconv.Atoi(parts[0]) - if err != nil { - return 0, 0, err - } - minor, err = strconv.Atoi(parts[1]) - if err != nil { - return 0, 0, err - } - return major, minor, nil -} diff --git a/openstack/utils/discovery.go b/openstack/utils/discovery.go new file mode 100644 index 0000000000..061ec6d63b --- /dev/null +++ b/openstack/utils/discovery.go @@ -0,0 +1,136 @@ +package utils + +import ( + "context" + "fmt" + "strconv" + "strings" + + "github.com/gophercloud/gophercloud/v2" +) + +type SupportedMicroversions struct { + MaxMajor int + MaxMinor int + MinMajor int + MinMinor int +} + +// GetServiceVersions returns the minimum and maximum microversion that is supported by the ServiceClient Endpoint. +func GetServiceVersions(ctx context.Context, client *gophercloud.ProviderClient, endpointURL string) (SupportedMicroversions, error) { + type valueResp struct { + ID string `json:"id"` + Status string `json:"status"` + Version string `json:"version"` + MinVersion string `json:"min_version"` + } + + type response struct { + Version valueResp `json:"version"` + Versions []valueResp `json:"versions"` + } + var minVersion, maxVersion string + var supportedMicroversions SupportedMicroversions + var resp response + _, err := client.Request(ctx, "GET", endpointURL, &gophercloud.RequestOpts{ + JSONResponse: &resp, + OkCodes: []int{200, 300}, + }) + + if err != nil { + return supportedMicroversions, err + } + + if len(resp.Versions) > 0 { + // We are dealing with an unversioned endpoint + // We only handle the case when there is exactly one, and assume it is the correct one + if len(resp.Versions) > 1 { + return supportedMicroversions, fmt.Errorf("unversioned endpoint with multiple alternatives not supported") + } + minVersion = resp.Versions[0].MinVersion + maxVersion = resp.Versions[0].Version + } else { + minVersion = resp.Version.MinVersion + maxVersion = resp.Version.Version + } + + // Return early if the endpoint does not support microversions + if minVersion == "" && maxVersion == "" { + return supportedMicroversions, fmt.Errorf("microversions not supported by endpoint") + } + + supportedMicroversions.MinMajor, supportedMicroversions.MinMinor, err = ParseMicroversion(minVersion) + if err != nil { + return supportedMicroversions, err + } + + supportedMicroversions.MaxMajor, supportedMicroversions.MaxMinor, err = ParseMicroversion(maxVersion) + if err != nil { + return supportedMicroversions, err + } + + return supportedMicroversions, nil +} + +// GetSupportedMicroversions returns the minimum and maximum microversion that is supported by the ServiceClient Endpoint. +func GetSupportedMicroversions(ctx context.Context, client *gophercloud.ServiceClient) (SupportedMicroversions, error) { + return GetServiceVersions(ctx, client.ProviderClient, client.Endpoint) +} + +// RequireMicroversion checks that the required microversion is supported and +// returns a ServiceClient with the microversion set. +func RequireMicroversion(ctx context.Context, client gophercloud.ServiceClient, required string) (gophercloud.ServiceClient, error) { + supportedMicroversions, err := GetSupportedMicroversions(ctx, &client) + if err != nil { + return client, fmt.Errorf("unable to determine supported microversions: %w", err) + } + supported, err := supportedMicroversions.IsSupported(required) + if err != nil { + return client, err + } + if !supported { + return client, fmt.Errorf("microversion %s not supported. Supported versions: %v", required, supportedMicroversions) + } + client.Microversion = required + return client, nil +} + +// IsSupported checks if a microversion falls in the supported interval. +// It returns true if the version is within the interval and false otherwise. +func (supported SupportedMicroversions) IsSupported(version string) (bool, error) { + // Parse the version X.Y into X and Y integers that are easier to compare. + vMajor, vMinor, err := ParseMicroversion(version) + if err != nil { + return false, err + } + + // Check that the major version number is supported. + if (vMajor < supported.MinMajor) || (vMajor > supported.MaxMajor) { + return false, nil + } + + // Check that the minor version number is supported + if (vMinor <= supported.MaxMinor) && (vMinor >= supported.MinMinor) { + return true, nil + } + + return false, nil +} + +// ParseMicroversion parses the version major.minor into separate integers major and minor. +// For example, "2.53" becomes 2 and 53. +func ParseMicroversion(version string) (major int, minor int, err error) { + parts := strings.Split(version, ".") + if len(parts) != 2 { + return 0, 0, fmt.Errorf("invalid microversion format: %q", version) + } + major, err = strconv.Atoi(parts[0]) + if err != nil { + return 0, 0, err + } + minor, err = strconv.Atoi(parts[1]) + if err != nil { + return 0, 0, err + } + return major, minor, nil +} diff --git a/openstack/utils/testing/choose_version_test.go b/openstack/utils/testing/choose_version_test.go index e1a813ea1a..74ab30903c 100644 --- a/openstack/utils/testing/choose_version_test.go +++ b/openstack/utils/testing/choose_version_test.go @@ -2,9 +2,6 @@ package testing import ( "context" - "fmt" - "net/http" - "strings" "testing" "github.com/gophercloud/gophercloud/v2" @@ -12,177 +9,6 @@ import ( th "github.com/gophercloud/gophercloud/v2/testhelper" ) -func setupVersionHandler(fakeServer th.FakeServer) { - fakeServer.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { - fmt.Fprintf(w, ` - { - "versions": { - "values": [ - { - "status": "stable", - "id": "v3.0", - "links": [ - { "href": "%s/v3.0", "rel": "self" } - ] - }, - { - "status": "stable", - "id": "v2.0", - "links": [ - { "href": "%s/v2.0", "rel": "self" } - ] - } - ] - } - } - `, fakeServer.Server.URL, fakeServer.Server.URL) - }) - // Compute v2.1 API - fakeServer.Mux.HandleFunc("/compute/v2.1/", func(w http.ResponseWriter, r *http.Request) { - fmt.Fprintf(w, ` - { - "version": { - "id": "v2.1", - "status": "CURRENT", - "version": "2.90", - "min_version": "2.1", - "updated": "2013-07-23T11:33:21Z", - "links": [ - { - "rel": "self", - "href": "%s/compute/v2.1/" - }, - { - "rel": "describedby", - "type": "text/html", - "href": "http://docs.openstack.org/" - } - ], - "media-types": [ - { - "base": "application/json", - "type": "application/vnd.openstack.compute+json;version=2.1" - } - ] - } - } - `, fakeServer.Server.URL) - }) - // Compute v2 API - fakeServer.Mux.HandleFunc("/compute/v2/", func(w http.ResponseWriter, r *http.Request) { - fmt.Fprintf(w, ` - { - "version": { - "id": "v2.0", - "status": "SUPPORTED", - "version": "", - "min_version": "", - "updated": "2011-01-21T11:33:21Z", - "links": [ - { - "rel": "self", - "href": "%s/compute/v2/" - }, - { - "rel": "describedby", - "type": "text/html", - "href": "http://docs.openstack.org/" - } - ], - "media-types": [ - { - "base": "application/json", - "type": "application/vnd.openstack.compute+json;version=2" - } - ] - } - } - `, fakeServer.Server.URL) - }) - // Ironic API - fakeServer.Mux.HandleFunc("/ironic/v1/", func(w http.ResponseWriter, r *http.Request) { - fmt.Fprintf(w, ` - { - "name": "OpenStack Ironic API", - "description": "Ironic is an OpenStack project which enables the provision and management of baremetal machines.", - "default_version": { - "id": "v1", - "links": [ - { - "href": "%s/ironic/v1/", - "rel": "self" - } - ], - "status": "CURRENT", - "min_version": "1.1", - "version": "1.87" - }, - "versions": [ - { - "id": "v1", - "links": [ - { - "href": "%s/ironic/v1/", - "rel": "self" - } - ], - "status": "CURRENT", - "min_version": "1.1", - "version": "1.87" - } - ] - } - `, fakeServer.Server.URL, fakeServer.Server.URL) - }) - // Ironic multi-version - fakeServer.Mux.HandleFunc("/ironic/v1.2/", func(w http.ResponseWriter, r *http.Request) { - fmt.Fprintf(w, ` - { - "name": "OpenStack Ironic API", - "description": "Ironic is an OpenStack project which enables the provision and management of baremetal machines.", - "default_version": { - "id": "v1", - "links": [ - { - "href": "%s/ironic/v1/", - "rel": "self" - } - ], - "status": "CURRENT", - "min_version": "1.1", - "version": "1.87" - }, - "versions": [ - { - "id": "v1", - "links": [ - { - "href": "%s/ironic/v1/", - "rel": "self" - } - ], - "status": "CURRENT", - "min_version": "1.1", - "version": "1.87" - }, - { - "id": "v1.2", - "links": [ - { - "href": "%s/ironic/v1/", - "rel": "self" - } - ], - "status": "CURRENT", - "min_version": "1.2", - "version": "1.90" - } - ] - } - `, fakeServer.Server.URL, fakeServer.Server.URL, fakeServer.Server.URL) - }) -} - func TestChooseVersion(t *testing.T) { fakeServer := th.SetupHTTP() defer fakeServer.Teardown() @@ -263,163 +89,3 @@ func TestChooseVersionFromSuffix(t *testing.T) { t.Errorf("Expected endpoint [%s], but was [%s] instead", expected, endpoint) } } - -type getSupportedServiceMicroversions struct { - Endpoint string - ExpectedMax string - ExpectedMin string - ExpectedErr bool -} - -func TestGetSupportedVersions(t *testing.T) { - fakeServer := th.SetupHTTP() - defer fakeServer.Teardown() - setupVersionHandler(fakeServer) - - tests := []getSupportedServiceMicroversions{ - { - // v2 does not support microversions and returns error - Endpoint: fakeServer.Endpoint() + "compute/v2/", - ExpectedMax: "", - ExpectedMin: "", - ExpectedErr: true, - }, - { - Endpoint: fakeServer.Endpoint() + "compute/v2.1/", - ExpectedMax: "2.90", - ExpectedMin: "2.1", - ExpectedErr: false, - }, - { - Endpoint: fakeServer.Endpoint() + "ironic/v1/", - ExpectedMax: "1.87", - ExpectedMin: "1.1", - ExpectedErr: false, - }, - { - // This endpoint returns multiple versions, which is not supported - Endpoint: fakeServer.Endpoint() + "ironic/v1.2/", - ExpectedMax: "not-relevant", - ExpectedMin: "not-relevant", - ExpectedErr: true, - }, - } - - for _, test := range tests { - c := &gophercloud.ProviderClient{ - IdentityBase: fakeServer.Endpoint(), - IdentityEndpoint: fakeServer.Endpoint() + "v2.0/", - } - - client := &gophercloud.ServiceClient{ - ProviderClient: c, - Endpoint: test.Endpoint, - } - - supported, err := utils.GetSupportedMicroversions(context.TODO(), client) - - if test.ExpectedErr { - if err == nil { - t.Error("Expected error but got none!") - } - // Check for reasonable error message - if !strings.Contains(err.Error(), "not supported") { - t.Error("Expected error to contain 'not supported' but it did not!") - } - // No point parsing and comparing versions after error, so continue to next test case - continue - } else { - if err != nil { - t.Errorf("Expected no error but got %s", err.Error()) - } - } - - min := fmt.Sprintf("%d.%d", supported.MinMajor, supported.MinMinor) - max := fmt.Sprintf("%d.%d", supported.MaxMajor, supported.MaxMinor) - - if (min != test.ExpectedMin) || (max != test.ExpectedMax) { - t.Errorf("Expected min=%s and max=%s but got min=%s and max=%s", test.ExpectedMin, test.ExpectedMax, min, max) - } - } -} - -type microversionSupported struct { - Version string - MinVersion string - MaxVersion string - Supported bool - Error bool -} - -func TestMicroversionSupported(t *testing.T) { - tests := []microversionSupported{ - { - // Checking min version - Version: "2.1", - MinVersion: "2.1", - MaxVersion: "2.90", - Supported: true, - Error: false, - }, - { - // Checking max version - Version: "2.90", - MinVersion: "2.1", - MaxVersion: "2.90", - Supported: true, - Error: false, - }, - { - // Checking too high version - Version: "2.95", - MinVersion: "2.1", - MaxVersion: "2.90", - Supported: false, - Error: false, - }, - { - // Checking too low version - Version: "2.1", - MinVersion: "2.53", - MaxVersion: "2.90", - Supported: false, - Error: false, - }, - { - // Invalid version - Version: "2.1.53", - MinVersion: "2.53", - MaxVersion: "2.90", - Supported: false, - Error: true, - }, - } - - for _, test := range tests { - var err error - var supportedVersions utils.SupportedMicroversions - supportedVersions.MaxMajor, supportedVersions.MaxMinor, err = utils.ParseMicroversion(test.MaxVersion) - if err != nil { - t.Error("Error parsing MaxVersion!") - } - supportedVersions.MinMajor, supportedVersions.MinMinor, err = utils.ParseMicroversion(test.MinVersion) - if err != nil { - t.Error("Error parsing MinVersion!") - } - - supported, err := supportedVersions.IsSupported(test.Version) - if test.Error { - if err == nil { - t.Error("Expected error but got none!") - } - } else { - if err != nil { - t.Errorf("Expected no error but got %s", err.Error()) - } - } - if test.Supported != supported { - t.Errorf("Expected supported=%t to be %t, when version=%s, min=%s and max=%s", - supported, test.Supported, test.Version, test.MinVersion, test.MaxVersion) - } - } -} diff --git a/openstack/utils/testing/discovery_test.go b/openstack/utils/testing/discovery_test.go new file mode 100644 index 0000000000..3a7f899a5e --- /dev/null +++ b/openstack/utils/testing/discovery_test.go @@ -0,0 +1,172 @@ +package testing + +import ( + "context" + "fmt" + "strings" + "testing" + + "github.com/gophercloud/gophercloud/v2" + "github.com/gophercloud/gophercloud/v2/openstack/utils" + th "github.com/gophercloud/gophercloud/v2/testhelper" +) + +type getSupportedServiceMicroversions struct { + Endpoint string + ExpectedMax string + ExpectedMin string + ExpectedErr bool +} + +func TestGetSupportedVersions(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + setupVersionHandler(fakeServer) + + tests := []getSupportedServiceMicroversions{ + { + // v2 does not support microversions and returns error + Endpoint: fakeServer.Endpoint() + "compute/v2/", + ExpectedMax: "", + ExpectedMin: "", + ExpectedErr: true, + }, + { + Endpoint: fakeServer.Endpoint() + "compute/v2.1/", + ExpectedMax: "2.90", + ExpectedMin: "2.1", + ExpectedErr: false, + }, + { + Endpoint: fakeServer.Endpoint() + "ironic/v1/", + ExpectedMax: "1.87", + ExpectedMin: "1.1", + ExpectedErr: false, + }, + { + // This endpoint returns multiple versions, which is not supported + Endpoint: fakeServer.Endpoint() + "ironic/v1.2/", + ExpectedMax: "not-relevant", + ExpectedMin: "not-relevant", + ExpectedErr: true, + }, + } + + for _, test := range tests { + c := &gophercloud.ProviderClient{ + IdentityBase: fakeServer.Endpoint(), + IdentityEndpoint: fakeServer.Endpoint() + "v2.0/", + } + + client := &gophercloud.ServiceClient{ + ProviderClient: c, + Endpoint: test.Endpoint, + } + + supported, err := utils.GetSupportedMicroversions(context.TODO(), client) + + if test.ExpectedErr { + if err == nil { + t.Error("Expected error but got none!") + } + // Check for reasonable error message + if !strings.Contains(err.Error(), "not supported") { + t.Error("Expected error to contain 'not supported' but it did not!") + } + // No point parsing and comparing versions after error, so continue to next test case + continue + } else { + if err != nil { + t.Errorf("Expected no error but got %s", err.Error()) + } + } + + min := fmt.Sprintf("%d.%d", supported.MinMajor, supported.MinMinor) + max := fmt.Sprintf("%d.%d", supported.MaxMajor, supported.MaxMinor) + + if (min != test.ExpectedMin) || (max != test.ExpectedMax) { + t.Errorf("Expected min=%s and max=%s but got min=%s and max=%s", test.ExpectedMin, test.ExpectedMax, min, max) + } + } +} + +type microversionSupported struct { + Version string + MinVersion string + MaxVersion string + Supported bool + Error bool +} + +func TestMicroversionSupported(t *testing.T) { + tests := []microversionSupported{ + { + // Checking min version + Version: "2.1", + MinVersion: "2.1", + MaxVersion: "2.90", + Supported: true, + Error: false, + }, + { + // Checking max version + Version: "2.90", + MinVersion: "2.1", + MaxVersion: "2.90", + Supported: true, + Error: false, + }, + { + // Checking too high version + Version: "2.95", + MinVersion: "2.1", + MaxVersion: "2.90", + Supported: false, + Error: false, + }, + { + // Checking too low version + Version: "2.1", + MinVersion: "2.53", + MaxVersion: "2.90", + Supported: false, + Error: false, + }, + { + // Invalid version + Version: "2.1.53", + MinVersion: "2.53", + MaxVersion: "2.90", + Supported: false, + Error: true, + }, + } + + for _, test := range tests { + var err error + var supportedVersions utils.SupportedMicroversions + supportedVersions.MaxMajor, supportedVersions.MaxMinor, err = utils.ParseMicroversion(test.MaxVersion) + if err != nil { + t.Error("Error parsing MaxVersion!") + } + supportedVersions.MinMajor, supportedVersions.MinMinor, err = utils.ParseMicroversion(test.MinVersion) + if err != nil { + t.Error("Error parsing MinVersion!") + } + + supported, err := supportedVersions.IsSupported(test.Version) + if test.Error { + if err == nil { + t.Error("Expected error but got none!") + } + } else { + if err != nil { + t.Errorf("Expected no error but got %s", err.Error()) + } + } + if test.Supported != supported { + t.Errorf("Expected supported=%t to be %t, when version=%s, min=%s and max=%s", + supported, test.Supported, test.Version, test.MinVersion, test.MaxVersion) + } + } +} diff --git a/openstack/utils/testing/fixtures_test.go b/openstack/utils/testing/fixtures_test.go new file mode 100644 index 0000000000..b0204edf63 --- /dev/null +++ b/openstack/utils/testing/fixtures_test.go @@ -0,0 +1,179 @@ +package testing + +import ( + "fmt" + "net/http" + + th "github.com/gophercloud/gophercloud/v2/testhelper" +) + +func setupVersionHandler(fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + fmt.Fprintf(w, ` + { + "versions": { + "values": [ + { + "status": "stable", + "id": "v3.0", + "links": [ + { "href": "%s/v3.0", "rel": "self" } + ] + }, + { + "status": "stable", + "id": "v2.0", + "links": [ + { "href": "%s/v2.0", "rel": "self" } + ] + } + ] + } + } + `, fakeServer.Server.URL, fakeServer.Server.URL) + }) + // Compute v2.1 API + fakeServer.Mux.HandleFunc("/compute/v2.1/", func(w http.ResponseWriter, r *http.Request) { + fmt.Fprintf(w, ` + { + "version": { + "id": "v2.1", + "status": "CURRENT", + "version": "2.90", + "min_version": "2.1", + "updated": "2013-07-23T11:33:21Z", + "links": [ + { + "rel": "self", + "href": "%s/compute/v2.1/" + }, + { + "rel": "describedby", + "type": "text/html", + "href": "http://docs.openstack.org/" + } + ], + "media-types": [ + { + "base": "application/json", + "type": "application/vnd.openstack.compute+json;version=2.1" + } + ] + } + } + `, fakeServer.Server.URL) + }) + // Compute v2 API + fakeServer.Mux.HandleFunc("/compute/v2/", func(w http.ResponseWriter, r *http.Request) { + fmt.Fprintf(w, ` + { + "version": { + "id": "v2.0", + "status": "SUPPORTED", + "version": "", + "min_version": "", + "updated": "2011-01-21T11:33:21Z", + "links": [ + { + "rel": "self", + "href": "%s/compute/v2/" + }, + { + "rel": "describedby", + "type": "text/html", + "href": "http://docs.openstack.org/" + } + ], + "media-types": [ + { + "base": "application/json", + "type": "application/vnd.openstack.compute+json;version=2" + } + ] + } + } + `, fakeServer.Server.URL) + }) + // Ironic API + fakeServer.Mux.HandleFunc("/ironic/v1/", func(w http.ResponseWriter, r *http.Request) { + fmt.Fprintf(w, ` + { + "name": "OpenStack Ironic API", + "description": "Ironic is an OpenStack project which enables the provision and management of baremetal machines.", + "default_version": { + "id": "v1", + "links": [ + { + "href": "%s/ironic/v1/", + "rel": "self" + } + ], + "status": "CURRENT", + "min_version": "1.1", + "version": "1.87" + }, + "versions": [ + { + "id": "v1", + "links": [ + { + "href": "%s/ironic/v1/", + "rel": "self" + } + ], + "status": "CURRENT", + "min_version": "1.1", + "version": "1.87" + } + ] + } + `, fakeServer.Server.URL, fakeServer.Server.URL) + }) + // Ironic multi-version + fakeServer.Mux.HandleFunc("/ironic/v1.2/", func(w http.ResponseWriter, r *http.Request) { + fmt.Fprintf(w, ` + { + "name": "OpenStack Ironic API", + "description": "Ironic is an OpenStack project which enables the provision and management of baremetal machines.", + "default_version": { + "id": "v1", + "links": [ + { + "href": "%s/ironic/v1/", + "rel": "self" + } + ], + "status": "CURRENT", + "min_version": "1.1", + "version": "1.87" + }, + "versions": [ + { + "id": "v1", + "links": [ + { + "href": "%s/ironic/v1/", + "rel": "self" + } + ], + "status": "CURRENT", + "min_version": "1.1", + "version": "1.87" + }, + { + "id": "v1.2", + "links": [ + { + "href": "%s/ironic/v1/", + "rel": "self" + } + ], + "status": "CURRENT", + "min_version": "1.2", + "version": "1.90" + } + ] + } + `, fakeServer.Server.URL, fakeServer.Server.URL, fakeServer.Server.URL) + }) +} From c50e1af2377ef4fc5bf7326cedb4456b2cd4b3a0 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Mon, 16 Jun 2025 18:23:02 +0100 Subject: [PATCH 187/353] Rework discovery tests Ahead of the addition of some new tests. Signed-off-by: Stephen Finucane (cherry picked from commit 774a8b851a25de9b55d9d40cb2db383975d3681d) --- .../utils/testing/choose_version_test.go | 4 +- openstack/utils/testing/discovery_test.go | 223 ++++++++---------- openstack/utils/testing/fixtures_test.go | 75 +++--- 3 files changed, 137 insertions(+), 165 deletions(-) diff --git a/openstack/utils/testing/choose_version_test.go b/openstack/utils/testing/choose_version_test.go index 74ab30903c..860984f0a5 100644 --- a/openstack/utils/testing/choose_version_test.go +++ b/openstack/utils/testing/choose_version_test.go @@ -12,7 +12,7 @@ import ( func TestChooseVersion(t *testing.T) { fakeServer := th.SetupHTTP() defer fakeServer.Teardown() - setupVersionHandler(fakeServer) + setupIdentityVersionHandler(fakeServer) v2 := &utils.Version{ID: "v2.0", Priority: 2, Suffix: "blarg"} v3 := &utils.Version{ID: "v3.0", Priority: 3, Suffix: "hargl"} @@ -40,7 +40,7 @@ func TestChooseVersion(t *testing.T) { func TestChooseVersionOpinionatedLink(t *testing.T) { fakeServer := th.SetupHTTP() defer fakeServer.Teardown() - setupVersionHandler(fakeServer) + setupIdentityVersionHandler(fakeServer) v2 := &utils.Version{ID: "v2.0", Priority: 2, Suffix: "nope"} v3 := &utils.Version{ID: "v3.0", Priority: 3, Suffix: "northis"} diff --git a/openstack/utils/testing/discovery_test.go b/openstack/utils/testing/discovery_test.go index 3a7f899a5e..97dd32c2d8 100644 --- a/openstack/utils/testing/discovery_test.go +++ b/openstack/utils/testing/discovery_test.go @@ -2,7 +2,6 @@ package testing import ( "context" - "fmt" "strings" "testing" @@ -11,162 +10,144 @@ import ( th "github.com/gophercloud/gophercloud/v2/testhelper" ) -type getSupportedServiceMicroversions struct { - Endpoint string - ExpectedMax string - ExpectedMin string - ExpectedErr bool -} - -func TestGetSupportedVersions(t *testing.T) { +func TestGetSupportedMicroversions(t *testing.T) { fakeServer := th.SetupHTTP() defer fakeServer.Teardown() - setupVersionHandler(fakeServer) + setupMultiServiceVersionHandler(fakeServer) - tests := []getSupportedServiceMicroversions{ + tests := []struct { + name string + endpoint string + expectedVersions utils.SupportedMicroversions + expectedErr string + }{ { // v2 does not support microversions and returns error - Endpoint: fakeServer.Endpoint() + "compute/v2/", - ExpectedMax: "", - ExpectedMin: "", - ExpectedErr: true, + name: "compute legacy endpoint", + endpoint: fakeServer.Endpoint() + "compute/v2/", + expectedErr: "not supported", }, { - Endpoint: fakeServer.Endpoint() + "compute/v2.1/", - ExpectedMax: "2.90", - ExpectedMin: "2.1", - ExpectedErr: false, + name: "compute versioned endpoint", + endpoint: fakeServer.Endpoint() + "compute/v2.1/", + expectedVersions: utils.SupportedMicroversions{ + MaxMajor: 2, MaxMinor: 90, MinMajor: 2, MinMinor: 1, + }, }, { - Endpoint: fakeServer.Endpoint() + "ironic/v1/", - ExpectedMax: "1.87", - ExpectedMin: "1.1", - ExpectedErr: false, + name: "baremetal versioned endpoint", + endpoint: fakeServer.Endpoint() + "baremetal/v1/", + expectedVersions: utils.SupportedMicroversions{ + MaxMajor: 1, MaxMinor: 87, MinMajor: 1, MinMinor: 1, + }, }, { // This endpoint returns multiple versions, which is not supported - Endpoint: fakeServer.Endpoint() + "ironic/v1.2/", - ExpectedMax: "not-relevant", - ExpectedMin: "not-relevant", - ExpectedErr: true, + name: "fictional multi-version endpoint", + endpoint: fakeServer.Endpoint() + "multi-version/v1.2/", + expectedErr: "not supported", }, } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := &gophercloud.ProviderClient{} + client := &gophercloud.ServiceClient{ + ProviderClient: c, + Endpoint: tt.endpoint, + } - for _, test := range tests { - c := &gophercloud.ProviderClient{ - IdentityBase: fakeServer.Endpoint(), - IdentityEndpoint: fakeServer.Endpoint() + "v2.0/", - } - - client := &gophercloud.ServiceClient{ - ProviderClient: c, - Endpoint: test.Endpoint, - } - - supported, err := utils.GetSupportedMicroversions(context.TODO(), client) + actualVersions, err := utils.GetSupportedMicroversions(context.TODO(), client) - if test.ExpectedErr { - if err == nil { - t.Error("Expected error but got none!") + if tt.expectedErr != "" { + th.AssertErr(t, err) + if !strings.Contains(err.Error(), tt.expectedErr) { + t.Fatalf("Expected error to contain '%s', got '%s': %+v", tt.expectedErr, err, tt) + } + } else { + th.AssertNoErr(t, err) } - // Check for reasonable error message - if !strings.Contains(err.Error(), "not supported") { - t.Error("Expected error to contain 'not supported' but it did not!") - } - // No point parsing and comparing versions after error, so continue to next test case - continue - } else { - if err != nil { - t.Errorf("Expected no error but got %s", err.Error()) - } - } - - min := fmt.Sprintf("%d.%d", supported.MinMajor, supported.MinMinor) - max := fmt.Sprintf("%d.%d", supported.MaxMajor, supported.MaxMinor) - if (min != test.ExpectedMin) || (max != test.ExpectedMax) { - t.Errorf("Expected min=%s and max=%s but got min=%s and max=%s", test.ExpectedMin, test.ExpectedMax, min, max) - } + th.AssertDeepEquals(t, tt.expectedVersions, actualVersions) + }) } } -type microversionSupported struct { - Version string - MinVersion string - MaxVersion string - Supported bool - Error bool -} - func TestMicroversionSupported(t *testing.T) { - tests := []microversionSupported{ + tests := []struct { + name string + version string + minVersion string + maxVersion string + supported bool + expectedError bool + }{ { - // Checking min version - Version: "2.1", - MinVersion: "2.1", - MaxVersion: "2.90", - Supported: true, - Error: false, + name: "Checking min version", + version: "2.1", + minVersion: "2.1", + maxVersion: "2.90", + supported: true, + expectedError: false, }, { - // Checking max version - Version: "2.90", - MinVersion: "2.1", - MaxVersion: "2.90", - Supported: true, - Error: false, + name: "Checking max version", + version: "2.90", + minVersion: "2.1", + maxVersion: "2.90", + supported: true, + expectedError: false, }, { - // Checking too high version - Version: "2.95", - MinVersion: "2.1", - MaxVersion: "2.90", - Supported: false, - Error: false, + name: "Checking too high version", + version: "2.95", + minVersion: "2.1", + maxVersion: "2.90", + supported: false, + expectedError: false, }, { - // Checking too low version - Version: "2.1", - MinVersion: "2.53", - MaxVersion: "2.90", - Supported: false, - Error: false, + name: "Checking too low version", + version: "2.1", + minVersion: "2.53", + maxVersion: "2.90", + supported: false, + expectedError: false, }, { - // Invalid version - Version: "2.1.53", - MinVersion: "2.53", - MaxVersion: "2.90", - Supported: false, - Error: true, + name: "Invalid version", + version: "2.1.53", + minVersion: "2.53", + maxVersion: "2.90", + supported: false, + expectedError: true, }, } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var err error + var supportedVersions utils.SupportedMicroversions - for _, test := range tests { - var err error - var supportedVersions utils.SupportedMicroversions - supportedVersions.MaxMajor, supportedVersions.MaxMinor, err = utils.ParseMicroversion(test.MaxVersion) - if err != nil { - t.Error("Error parsing MaxVersion!") - } - supportedVersions.MinMajor, supportedVersions.MinMinor, err = utils.ParseMicroversion(test.MinVersion) - if err != nil { - t.Error("Error parsing MinVersion!") - } - - supported, err := supportedVersions.IsSupported(test.Version) - if test.Error { - if err == nil { - t.Error("Expected error but got none!") + supportedVersions.MaxMajor, supportedVersions.MaxMinor, err = utils.ParseMicroversion(tt.maxVersion) + if err != nil { + t.Fatal("Error parsing MaxVersion!") } - } else { + + supportedVersions.MinMajor, supportedVersions.MinMinor, err = utils.ParseMicroversion(tt.minVersion) if err != nil { - t.Errorf("Expected no error but got %s", err.Error()) + t.Fatal("Error parsing MinVersion!") + } + + supported, err := supportedVersions.IsSupported(tt.version) + if tt.expectedError { + th.AssertErr(t, err) + } else { + th.AssertNoErr(t, err) + } + + if tt.supported != supported { + t.Fatalf("Expected supported=%t to be %t, when version=%s, min=%s and max=%s", + supported, tt.supported, tt.version, tt.minVersion, tt.maxVersion) } - } - if test.Supported != supported { - t.Errorf("Expected supported=%t to be %t, when version=%s, min=%s and max=%s", - supported, test.Supported, test.Version, test.MinVersion, test.MaxVersion) - } + }) } } diff --git a/openstack/utils/testing/fixtures_test.go b/openstack/utils/testing/fixtures_test.go index b0204edf63..b9c3ed53f5 100644 --- a/openstack/utils/testing/fixtures_test.go +++ b/openstack/utils/testing/fixtures_test.go @@ -7,7 +7,7 @@ import ( th "github.com/gophercloud/gophercloud/v2/testhelper" ) -func setupVersionHandler(fakeServer th.FakeServer) { +func setupIdentityVersionHandler(fakeServer th.FakeServer) { fakeServer.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, ` { @@ -32,20 +32,23 @@ func setupVersionHandler(fakeServer th.FakeServer) { } `, fakeServer.Server.URL, fakeServer.Server.URL) }) - // Compute v2.1 API - fakeServer.Mux.HandleFunc("/compute/v2.1/", func(w http.ResponseWriter, r *http.Request) { +} + +func setupMultiServiceVersionHandler(fakeServer th.FakeServer) { + // Compute v2 API + fakeServer.Mux.HandleFunc("/compute/v2/", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, ` { "version": { - "id": "v2.1", - "status": "CURRENT", - "version": "2.90", - "min_version": "2.1", - "updated": "2013-07-23T11:33:21Z", + "id": "v2.0", + "status": "SUPPORTED", + "version": "", + "min_version": "", + "updated": "2011-01-21T11:33:21Z", "links": [ { "rel": "self", - "href": "%s/compute/v2.1/" + "href": "%s/compute/v2/" }, { "rel": "describedby", @@ -56,27 +59,27 @@ func setupVersionHandler(fakeServer th.FakeServer) { "media-types": [ { "base": "application/json", - "type": "application/vnd.openstack.compute+json;version=2.1" + "type": "application/vnd.openstack.compute+json;version=2" } ] } } `, fakeServer.Server.URL) }) - // Compute v2 API - fakeServer.Mux.HandleFunc("/compute/v2/", func(w http.ResponseWriter, r *http.Request) { + // Compute v2.1 API + fakeServer.Mux.HandleFunc("/compute/v2.1/", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, ` { "version": { - "id": "v2.0", - "status": "SUPPORTED", - "version": "", - "min_version": "", - "updated": "2011-01-21T11:33:21Z", + "id": "v2.1", + "status": "CURRENT", + "version": "2.90", + "min_version": "2.1", + "updated": "2013-07-23T11:33:21Z", "links": [ { "rel": "self", - "href": "%s/compute/v2/" + "href": "%s/compute/v2.1/" }, { "rel": "describedby", @@ -87,15 +90,15 @@ func setupVersionHandler(fakeServer th.FakeServer) { "media-types": [ { "base": "application/json", - "type": "application/vnd.openstack.compute+json;version=2" + "type": "application/vnd.openstack.compute+json;version=2.1" } ] } } `, fakeServer.Server.URL) }) - // Ironic API - fakeServer.Mux.HandleFunc("/ironic/v1/", func(w http.ResponseWriter, r *http.Request) { + // Baremetal API + fakeServer.Mux.HandleFunc("/baremetal/v1/", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, ` { "name": "OpenStack Ironic API", @@ -104,7 +107,7 @@ func setupVersionHandler(fakeServer th.FakeServer) { "id": "v1", "links": [ { - "href": "%s/ironic/v1/", + "href": "%s/baremetal/v1/", "rel": "self" } ], @@ -117,7 +120,7 @@ func setupVersionHandler(fakeServer th.FakeServer) { "id": "v1", "links": [ { - "href": "%s/ironic/v1/", + "href": "%s/baremetal/v1/", "rel": "self" } ], @@ -129,30 +132,18 @@ func setupVersionHandler(fakeServer th.FakeServer) { } `, fakeServer.Server.URL, fakeServer.Server.URL) }) - // Ironic multi-version - fakeServer.Mux.HandleFunc("/ironic/v1.2/", func(w http.ResponseWriter, r *http.Request) { + // Fictional multi-version API + fakeServer.Mux.HandleFunc("/multi-version/v1.2/", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, ` { - "name": "OpenStack Ironic API", - "description": "Ironic is an OpenStack project which enables the provision and management of baremetal machines.", - "default_version": { - "id": "v1", - "links": [ - { - "href": "%s/ironic/v1/", - "rel": "self" - } - ], - "status": "CURRENT", - "min_version": "1.1", - "version": "1.87" - }, + "name": "Multi-version API", + "description": "A fictional API with multiple microversions.", "versions": [ { "id": "v1", "links": [ { - "href": "%s/ironic/v1/", + "href": "%s/multi-version/v1/", "rel": "self" } ], @@ -164,7 +155,7 @@ func setupVersionHandler(fakeServer th.FakeServer) { "id": "v1.2", "links": [ { - "href": "%s/ironic/v1/", + "href": "%s/multi-version/v1/", "rel": "self" } ], @@ -174,6 +165,6 @@ func setupVersionHandler(fakeServer th.FakeServer) { } ] } - `, fakeServer.Server.URL, fakeServer.Server.URL, fakeServer.Server.URL) + `, fakeServer.Server.URL, fakeServer.Server.URL) }) } From a205e2152f6efece5a346e4d4fd2d24b4fc5f7d3 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Wed, 18 Jun 2025 12:26:50 +0100 Subject: [PATCH 188/353] Add tests for GetServiceVersions Right now these are effectively duplicates of the tests for GetSupportedMicroversions, which is also expanded here to test against the version documents of other services, but that will change shortly. Signed-off-by: Stephen Finucane (cherry picked from commit 9c18abd1136b83a4840b0130a390d9a40383b400) --- openstack/utils/testing/discovery_test.go | 185 ++++++++++- openstack/utils/testing/fixtures_test.go | 357 +++++++++++++++++++++- 2 files changed, 539 insertions(+), 3 deletions(-) diff --git a/openstack/utils/testing/discovery_test.go b/openstack/utils/testing/discovery_test.go index 97dd32c2d8..e2917e17e9 100644 --- a/openstack/utils/testing/discovery_test.go +++ b/openstack/utils/testing/discovery_test.go @@ -10,6 +10,126 @@ import ( th "github.com/gophercloud/gophercloud/v2/testhelper" ) +func TestGetServiceVersions(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + setupMultiServiceVersionHandler(fakeServer) + + tests := []struct { + name string + endpoint string + expectedVersions utils.SupportedMicroversions + expectedErr string + }{ + { + // FIXME(stephenfin): This is erroring because we can't handle the addition 'values' envelope + name: "identity unversioned endpoint", + endpoint: fakeServer.Endpoint() + "identity/", + expectedErr: "cannot unmarshal object", + }, + { + // FIXME(stephenfin): We should handle missing microversion info + name: "identity versioned endpoint", + endpoint: fakeServer.Endpoint() + "identity/v3/", + expectedErr: "not supported", + }, + { + // FIXME(stephenfin): We should handle missing microversion info + name: "compute unversioned endpoint", + endpoint: fakeServer.Endpoint() + "compute/", + expectedErr: "not supported", + }, + { + // FIXME(stephenfin): We should handle missing microversion info + name: "compute legacy endpoint", + endpoint: fakeServer.Endpoint() + "compute/v2/", + expectedErr: "not supported", + }, + { + name: "compute versioned endpoint", + endpoint: fakeServer.Endpoint() + "compute/v2.1/", + expectedVersions: utils.SupportedMicroversions{ + MaxMajor: 2, MaxMinor: 90, MinMajor: 2, MinMinor: 1, + }, + }, + { + // FIXME(stephenfin): This is erroring because we ignore the max_version field + name: "container-infra unversioned endpoint", + endpoint: fakeServer.Endpoint() + "container-infra/", + expectedErr: "invalid microversion format", + }, + { + // FIXME(stephenfin): We should handle missing microversion info + name: "container-infra versioned endpoint", + endpoint: fakeServer.Endpoint() + "container-infra/v1/", + expectedErr: "not supported", + }, + { + // FIXME(stephenfin): We should handle missing microversion info + name: "orchestration unversioned endpoint", + endpoint: fakeServer.Endpoint() + "heat-api/", + expectedErr: "not supported", + }, + { + // FIXME(stephenfin): We should missing version documents + name: "orchestration versioned endpoint", + endpoint: fakeServer.Endpoint() + "heat-api/v1/", + expectedErr: "Expected HTTP response code", + }, + { + // FIXME(stephenfin): We should handle missing microversion info + name: "workflow unversioned endpoint", + endpoint: fakeServer.Endpoint() + "workflow/", + expectedErr: "not supported", + }, + { + // FIXME(stephenfin): We should handle invalid version documents + name: "workflow versioned endpoint", + endpoint: fakeServer.Endpoint() + "workflow/v2/", + expectedErr: "not supported", + }, + { + name: "baremetal unversioned endpoint", + endpoint: fakeServer.Endpoint() + "baremetal/", + expectedVersions: utils.SupportedMicroversions{ + MaxMajor: 1, MaxMinor: 87, MinMajor: 1, MinMinor: 1, + }, + }, + { + name: "baremetal versioned endpoint", + endpoint: fakeServer.Endpoint() + "baremetal/v1/", + expectedVersions: utils.SupportedMicroversions{ + MaxMajor: 1, MaxMinor: 87, MinMajor: 1, MinMinor: 1, + }, + }, + { + // FIXME(stephenfin): We should handle multiple microversion info + name: "fictional multi-version endpoint", + endpoint: fakeServer.Endpoint() + "multi-version/v1.2/", + expectedErr: "not supported", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + client := &gophercloud.ProviderClient{} + + actualVersions, err := utils.GetServiceVersions(context.TODO(), client, tt.endpoint) + + if tt.expectedErr != "" { + th.AssertErr(t, err) + if !strings.Contains(err.Error(), tt.expectedErr) { + t.Errorf("Expected error to contain '%s', got '%s': %+v", tt.expectedErr, err, tt) + } + return + } else { + th.AssertNoErr(t, err) + } + + th.AssertDeepEquals(t, tt.expectedVersions, actualVersions) + }) + } +} + func TestGetSupportedMicroversions(t *testing.T) { fakeServer := th.SetupHTTP() defer fakeServer.Teardown() @@ -22,7 +142,25 @@ func TestGetSupportedMicroversions(t *testing.T) { expectedErr string }{ { - // v2 does not support microversions and returns error + // FIXME(stephenfin): This is erroring because we can't handle the addition 'values' envelope + name: "identity unversioned endpoint", + endpoint: fakeServer.Endpoint() + "identity/", + expectedErr: "cannot unmarshal object", + }, + { + // identity does not support microversions and returns error + name: "identity versioned endpoint", + endpoint: fakeServer.Endpoint() + "identity/v3/", + expectedErr: "not supported", + }, + { + // compute root API does not expose microversion info and returns error + name: "compute unversioned endpoint", + endpoint: fakeServer.Endpoint() + "compute/", + expectedErr: "not supported", + }, + { + // compute v2 does not support microversions and returns error name: "compute legacy endpoint", endpoint: fakeServer.Endpoint() + "compute/v2/", expectedErr: "not supported", @@ -34,6 +172,49 @@ func TestGetSupportedMicroversions(t *testing.T) { MaxMajor: 2, MaxMinor: 90, MinMajor: 2, MinMinor: 1, }, }, + { + // FIXME(stephenfin): This is erroring because we ignore the max_version field + name: "container-infra unversioned endpoint", + endpoint: fakeServer.Endpoint() + "container-infra/", + expectedErr: "invalid microversion format", + }, + { + // container-infra does not expose proper discovery information + name: "container-infra versioned endpoint", + endpoint: fakeServer.Endpoint() + "container-infra/v1/", + expectedErr: "not supported", + }, + { + // orchestration does not support microversions and returns error + name: "orchestration unversioned endpoint", + endpoint: fakeServer.Endpoint() + "heat-api/", + expectedErr: "not supported", + }, + { + // FIXME(stephenfin): We should handle missing version documents + name: "orchestration versioned endpoint", + endpoint: fakeServer.Endpoint() + "heat-api/v1/", + expectedErr: "Expected HTTP response code", + }, + { + // workflow does not support microversions and returns error + name: "workflow unversioned endpoint", + endpoint: fakeServer.Endpoint() + "workflow/", + expectedErr: "not supported", + }, + { + // workflow does not support microversions and returns error + name: "workflow versioned endpoint", + endpoint: fakeServer.Endpoint() + "workflow/v2/", + expectedErr: "not supported", + }, + { + name: "baremetal unversioned endpoint", + endpoint: fakeServer.Endpoint() + "baremetal/", + expectedVersions: utils.SupportedMicroversions{ + MaxMajor: 1, MaxMinor: 87, MinMajor: 1, MinMinor: 1, + }, + }, { name: "baremetal versioned endpoint", endpoint: fakeServer.Endpoint() + "baremetal/v1/", @@ -63,6 +244,8 @@ func TestGetSupportedMicroversions(t *testing.T) { if !strings.Contains(err.Error(), tt.expectedErr) { t.Fatalf("Expected error to contain '%s', got '%s': %+v", tt.expectedErr, err, tt) } + // No point parsing and comparing versions after error, so continue to next test case + return } else { th.AssertNoErr(t, err) } diff --git a/openstack/utils/testing/fixtures_test.go b/openstack/utils/testing/fixtures_test.go index b9c3ed53f5..0d4a489356 100644 --- a/openstack/utils/testing/fixtures_test.go +++ b/openstack/utils/testing/fixtures_test.go @@ -35,6 +35,93 @@ func setupIdentityVersionHandler(fakeServer th.FakeServer) { } func setupMultiServiceVersionHandler(fakeServer th.FakeServer) { + // Identity root API + fakeServer.Mux.HandleFunc("/identity/", func(w http.ResponseWriter, r *http.Request) { + fmt.Fprintf(w, ` + { + "versions": { + "values": [ + { + "id": "v3.14", + "status": "stable", + "updated": "2020-04-07T00:00:00Z", + "links": [ + { + "rel": "self", + "href": "%s/identity/v3/" + } + ], + "media-types": [ + { + "base": "application/json", + "type": "application/vnd.openstack.identity-v3+json" + } + ] + } + ] + } + } + `, fakeServer.Server.URL) + }) + // Identity v3 API + fakeServer.Mux.HandleFunc("/identity/v3/", func(w http.ResponseWriter, r *http.Request) { + fmt.Fprintf(w, ` + { + "version": { + "id": "v3.14", + "status": "stable", + "updated": "2020-04-07T00:00:00Z", + "links": [ + { + "rel": "self", + "href": "%s/identity/v3/" + } + ], + "media-types": [ + { + "base": "application/json", + "type": "application/vnd.openstack.identity-v3+json" + } + ] + } + } + `, fakeServer.Server.URL) + }) + // Compute root API + fakeServer.Mux.HandleFunc("/compute/", func(w http.ResponseWriter, r *http.Request) { + fmt.Fprintf(w, ` + { + "versions": [ + { + "id": "v2.0", + "status": "SUPPORTED", + "version": "", + "min_version": "", + "updated": "2011-01-21T11:33:21Z", + "links": [ + { + "rel": "self", + "href": "%s/compute/v2/" + } + ] + }, + { + "id": "v2.1", + "status": "CURRENT", + "version": "2.90", + "min_version": "2.1", + "updated": "2013-07-23T11:33:21Z", + "links": [ + { + "rel": "self", + "href": "%s/compute/v2.1/" + } + ] + } + ] + } + `, fakeServer.Server.URL, fakeServer.Server.URL) + }) // Compute v2 API fakeServer.Mux.HandleFunc("/compute/v2/", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, ` @@ -97,8 +184,195 @@ func setupMultiServiceVersionHandler(fakeServer th.FakeServer) { } `, fakeServer.Server.URL) }) - // Baremetal API - fakeServer.Mux.HandleFunc("/baremetal/v1/", func(w http.ResponseWriter, r *http.Request) { + // Container Infra root API + fakeServer.Mux.HandleFunc("/container-infra/", func(w http.ResponseWriter, r *http.Request) { + fmt.Fprintf(w, ` + { + "name": "OpenStack Magnum API", + "description": "Magnum is an OpenStack project which aims to provide container cluster management.", + "versions": [ + { + "id": "v1", + "links": [ + { + "href": "%s/v1/", + "rel": "self" + } + ], + "status": "CURRENT", + "max_version": "1.11", + "min_version": "1.1" + } + ] + } + `, fakeServer.Server.URL) + }) + // Container Infra v1 API + // + // NOTE(stephenfin): In reality, this returns absolute URLs, but those URLs are wrong since + // they don't respect the Host header. We're using relative URLs because (a) it's probably + // what magnum should be doing and (b) it avoids needing 17 odd arguments to Fprintf + fakeServer.Mux.HandleFunc("/container-infra/v1/", func(w http.ResponseWriter, r *http.Request) { + fmt.Fprint(w, ` + { + "id": "v1", + "media_types": [ + { + "base": "application/json", + "type": "application/vnd.openstack.magnum.v1+json" + } + ], + "links": [ + { + "href": "/v1/", + "rel": "self" + }, + { + "href": "http://docs.openstack.org/developer/magnum/dev/api-spec-v1.html", + "rel": "describedby", + "type": "text/html" + } + ], + "clustertemplates": [ + { + "href": "/v1/clustertemplates/", + "rel": "self" + }, + { + "href": "/clustertemplates/", + "rel": "bookmark" + } + ], + "clusters": [ + { + "href": "/v1/clusters/", + "rel": "self" + }, + { + "href": "/clusters/", + "rel": "bookmark" + } + ], + "quotas": [ + { + "href": "/v1/quotas/", + "rel": "self" + }, + { + "href": "/quotas/", + "rel": "bookmark" + } + ], + "certificates": [ + { + "href": "/v1/certificates/", + "rel": "self" + }, + { + "href": "/certificates/", + "rel": "bookmark" + } + ], + "mservices": [ + { + "href": "/v1/mservices/", + "rel": "self" + }, + { + "href": "/mservices/", + "rel": "bookmark" + } + ], + "stats": [ + { + "href": "/v1/stats/", + "rel": "self" + }, + { + "href": "/stats/", + "rel": "bookmark" + } + ], + "federations": [ + { + "href": "/v1/federations/", + "rel": "self" + }, + { + "href": "/federations/", + "rel": "bookmark" + } + ], + "nodegroups": [ + { + "href": "/v1/clusters/{cluster_id}/nodegroups", + "rel": "self" + }, + { + "href": "/clusters/{cluster_id}/nodegroups", + "rel": "bookmark" + } + ] + } + `, fakeServer.Server.URL) + }) + // Orchestration root API + fakeServer.Mux.HandleFunc("/heat-api/", func(w http.ResponseWriter, r *http.Request) { + fmt.Fprintf(w, ` + { + "versions": [ + { + "id": "v1.0", + "status": "CURRENT", + "links": [ + { + "rel": "self", + "href": "%s/heat-api/v1/" + } + ] + } + ] + } + `, fakeServer.Server.URL) + }) + // Orchestration v1 API (non-existent) + fakeServer.Mux.HandleFunc("/heat-api/v1/", func(w http.ResponseWriter, r *http.Request) { + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusNotFound) + }) + // Workflow root API + // + // In reality, this deploys under a port rather than a path (as of Epoxy) but we don't want to + // have to run multiple fake servers so this will do. + fakeServer.Mux.HandleFunc("/workflow/", func(w http.ResponseWriter, r *http.Request) { + fmt.Fprintf(w, ` + { + "versions": [ + { + "id": "v2.0", + "status": "CURRENT", + "links": [ + { + "href": "%s/workflow/v2", + "target": "v2", + "rel": "self" + } + ] + } + ] + } + `, fakeServer.Server.URL) + }) + // Workflow v1 API (invalid version document) + fakeServer.Mux.HandleFunc("/workflow/v2/", func(w http.ResponseWriter, r *http.Request) { + fmt.Fprintf(w, ` + { + "uri": "%s/v2" + } + `, fakeServer.Server.URL) + }) + // Baremetal root API + fakeServer.Mux.HandleFunc("/baremetal/", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, ` { "name": "OpenStack Ironic API", @@ -132,6 +406,85 @@ func setupMultiServiceVersionHandler(fakeServer th.FakeServer) { } `, fakeServer.Server.URL, fakeServer.Server.URL) }) + // Baremetal v1 API + // + // NOTE(stephenfin): In reality, this returns absolute URLs and unlike Magnum those URLs are + // correctly formatted. We're using relative URLs for many of these because, once again, it + // avoids needing loads of arguments to Fprintf + fakeServer.Mux.HandleFunc("/baremetal/v1/", func(w http.ResponseWriter, r *http.Request) { + fmt.Fprintf(w, ` + { + "id": "v1", + "links": [ + { + "href": "/baremetal/v1/", + "rel": "self" + }, + { + "href": "https://docs.openstack.org//ironic/latest/contributor//webapi.html", + "rel": "describedby", + "type": "text/html" + } + ], + "media_types": { + "base": "application/json", + "type": "application/vnd.openstack.ironic.v1+json" + }, + "chassis": [ + { + "href": "/baremetal/v1/chassis/", + "rel": "self" + }, + { + "href": "/baremetal/chassis/", + "rel": "bookmark" + } + ], + "nodes": [ + { + "href": "/baremetal/v1/nodes/", + "rel": "self" + }, + { + "href": "/baremetal/nodes/", + "rel": "bookmark" + } + ], + "ports": [ + { + "href": "/baremetal/v1/ports/", + "rel": "self" + }, + { + "href": "/baremetal/ports/", + "rel": "bookmark" + } + ], + "drivers": [ + { + "href": "/baremetal/v1/drivers/", + "rel": "self" + }, + { + "href": "/baremetal/drivers/", + "rel": "bookmark" + } + ], + "version": { + "id": "v1", + "links": [ + { + "href": "%s/baremetal/v1/", + "rel": "self" + } + ], + "status": "CURRENT", + "min_version": "1.1", + "version": "1.87" + } + } + `, fakeServer.Server.URL) + }) // Fictional multi-version API fakeServer.Mux.HandleFunc("/multi-version/v1.2/", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, ` From 875b8f4616a832033c8ed118cc1f83f3781f0078 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Wed, 18 Jun 2025 12:36:56 +0100 Subject: [PATCH 189/353] Consider API major version, not API microversion major version MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In commit f28c96333f8138ce23a28c5c28fbbf1ca1eb480a, we added support for discovering API versions. To do this, we added a dependency on the 'version' and 'min_version' headers, which are used by services with microversion support to document the maximum and minimum API versions supported, respectively. However, not all services support API microversions: services like Glance and Designate use API versions as a signal of a new feature (or, in Glance's case, as a signal that a feature is not enabled), others like Keystone just support a single version, while Neutron does its own thing with API extensions [1]. Given this fact, relying on these fields is a mistake. Instead, we should be relying on the 'id' field. Per the api-sig guidelines [2], this should be the API major version [3]. We continue parsing the microversion-related headers, since it will be useful later on if/when we want to do versioned discovery. [1] https://that.guru/blog/api-versioning-in-openstack/ [2] https://specs.openstack.org/openstack/api-sig/guidelines/discoverability.html [3] The studious among you may notice that the api-sig guidelines indicate that the maximum API microversion should be exposed via the 'max_version' header. However, in practice, virtually everyone uses 'version' instead. Why? Who knows. Best to just take these things on the chin and move on with our lives. [4] The term "major version" is a bit loaded. Consider Nova: at the time of writing, it exposes two "major versions": v2.0 and v2.1. v2.0 does not support microversions. v2.1 does. For v2.1 you therefore also have microversions to content with and at the time of writing it supports a minimum microversion of 2.1 and a maximum microversion of 2.100 (no 'v' prefix here). Normalizing these as we've done here gives us a major version of 2, a minor version of 1, a major maximum microversion of 2, a minor maximum microversion of 100, a major minimum microversion of 2, and a minor minimum microversion of 1 🤯. Signed-off-by: Stephen Finucane (cherry picked from commit 5b8928511a6e034c013c1ba220039b32a75dec01) --- openstack/endpoint.go | 10 +- openstack/utils/discovery.go | 180 ++++++++++++++++++---- openstack/utils/testing/discovery_test.go | 159 ++++++++++++++----- 3 files changed, 278 insertions(+), 71 deletions(-) diff --git a/openstack/endpoint.go b/openstack/endpoint.go index 3f7cee0f48..14ecaf3a4f 100644 --- a/openstack/endpoint.go +++ b/openstack/endpoint.go @@ -65,12 +65,18 @@ func endpointSupportsVersion(ctx context.Context, client *gophercloud.ProviderCl return false, err } - supportedMicroversions, err := utils.GetServiceVersions(ctx, client, endpointURL) + supportedVersions, err := utils.GetServiceVersions(ctx, client, endpointURL) if err != nil { return false, err } - return supportedMicroversions.MinMajor == 0 || supportedMicroversions.MinMajor == expectedVersion, nil + for _, supportedVersion := range supportedVersions { + if supportedVersion.Major == expectedVersion { + return true, nil + } + } + + return false, nil } /* diff --git a/openstack/utils/discovery.go b/openstack/utils/discovery.go index 061ec6d63b..d8c44879f0 100644 --- a/openstack/utils/discovery.go +++ b/openstack/utils/discovery.go @@ -3,78 +3,151 @@ package utils import ( "context" "fmt" + "regexp" + "sort" "strconv" "strings" "github.com/gophercloud/gophercloud/v2" ) +type Status string + +const ( + StatusCurrent Status = "CURRENT" + StatusSupported Status = "SUPPORTED" + StatusDeprecated Status = "DEPRECATED" + StatusExperimental Status = "EXPERIMENTAL" + StatusUnknown Status = "" +) + +// SupportedVersion stores a normalized form of the API version data. It handles APIs that +// support microversions as well as those that do not. +type SupportedVersion struct { + // Major is the major version number of the API + Major int + // Minor is the minor version number of the API + Minor int + // Status is the status of the API + Status Status + SupportedMicroversions +} + +// SupportedMicroversions stores a normalized form of the maximum and minimum API microversions +// supported by a given service. type SupportedMicroversions struct { + // MaxMajor is the major version number of the maximum supported API microversion MaxMajor int + // MaxMinor is the minor version number of the maximum supported API microversion MaxMinor int + // MinMajor is the major version number of the minimum supported API microversion MinMajor int + // MinMinor is the minor version number of the minimum supported API microversion MinMinor int } -// GetServiceVersions returns the minimum and maximum microversion that is supported by the ServiceClient Endpoint. -func GetServiceVersions(ctx context.Context, client *gophercloud.ProviderClient, endpointURL string) (SupportedMicroversions, error) { +// GetServiceVersions returns the versions supported by the ServiceClient Endpoint. +// If the endpoint resolves to an unversioned discovery API, this should return one or more supported versions. +// If the endpoint resolves to a versioned discovery API, this should return exactly one supported version. +func GetServiceVersions(ctx context.Context, client *gophercloud.ProviderClient, endpointURL string) ([]SupportedVersion, error) { type valueResp struct { ID string `json:"id"` Status string `json:"status"` Version string `json:"version"` MinVersion string `json:"min_version"` } - type response struct { Version valueResp `json:"version"` Versions []valueResp `json:"versions"` } - var minVersion, maxVersion string - var supportedMicroversions SupportedMicroversions + + var supportedVersions []SupportedVersion + var resp response _, err := client.Request(ctx, "GET", endpointURL, &gophercloud.RequestOpts{ JSONResponse: &resp, OkCodes: []int{200, 300}, }) - if err != nil { - return supportedMicroversions, err + return supportedVersions, err } + var versions []valueResp if len(resp.Versions) > 0 { - // We are dealing with an unversioned endpoint - // We only handle the case when there is exactly one, and assume it is the correct one - if len(resp.Versions) > 1 { - return supportedMicroversions, fmt.Errorf("unversioned endpoint with multiple alternatives not supported") - } - minVersion = resp.Versions[0].MinVersion - maxVersion = resp.Versions[0].Version + versions = resp.Versions } else { - minVersion = resp.Version.MinVersion - maxVersion = resp.Version.Version + versions = append(versions, resp.Version) } - // Return early if the endpoint does not support microversions - if minVersion == "" && maxVersion == "" { - return supportedMicroversions, fmt.Errorf("microversions not supported by endpoint") + for _, version := range versions { + majorVersion, minorVersion, err := ParseVersion(version.ID) + if err != nil { + return supportedVersions, err + } + + status, err := ParseStatus(version.Status) + if err != nil { + return supportedVersions, err + } + + supportedVersion := SupportedVersion{ + Major: majorVersion, + Minor: minorVersion, + Status: status, + } + + // Only normalize the microversion if there is a microversion to normalize + if version.MinVersion != "" && version.Version != "" { + supportedVersion.MinMajor, supportedVersion.MinMinor, err = ParseMicroversion(version.MinVersion) + if err != nil { + return supportedVersions, err + } + + supportedVersion.MaxMajor, supportedVersion.MaxMinor, err = ParseMicroversion(version.Version) + if err != nil { + return supportedVersions, err + } + } + + supportedVersions = append(supportedVersions, supportedVersion) } - supportedMicroversions.MinMajor, supportedMicroversions.MinMinor, err = ParseMicroversion(minVersion) + sort.Slice(supportedVersions, func(i, j int) bool { + return supportedVersions[i].Major > supportedVersions[j].Major || (supportedVersions[i].Major == supportedVersions[j].Major && + supportedVersions[i].Minor > supportedVersions[j].Minor) + }) + + return supportedVersions, nil +} + +// GetSupportedMicroversions returns the minimum and maximum microversion that is supported by the ServiceClient Endpoint. +func GetSupportedMicroversions(ctx context.Context, client *gophercloud.ServiceClient) (SupportedMicroversions, error) { + var supportedMicroversions SupportedMicroversions + + supportedVersions, err := GetServiceVersions(ctx, client.ProviderClient, client.Endpoint) if err != nil { return supportedMicroversions, err } - supportedMicroversions.MaxMajor, supportedMicroversions.MaxMinor, err = ParseMicroversion(maxVersion) - if err != nil { - return supportedMicroversions, err + // If there are multiple versions then we were handed an unversioned endpoint. These don't + // provide microversion information, so we need to fail. Likewise, if there are no versions + // then something has gone wrong and we also need to fail. + if len(supportedVersions) > 1 { + return supportedMicroversions, fmt.Errorf("unversioned endpoint with multiple alternatives not supported") + } else if len(supportedVersions) == 0 { + return supportedMicroversions, fmt.Errorf("microversions not supported by endpoint") } - return supportedMicroversions, nil -} + supportedMicroversions = supportedVersions[0].SupportedMicroversions -// GetSupportedMicroversions returns the minimum and maximum microversion that is supported by the ServiceClient Endpoint. -func GetSupportedMicroversions(ctx context.Context, client *gophercloud.ServiceClient) (SupportedMicroversions, error) { - return GetServiceVersions(ctx, client.ProviderClient, client.Endpoint) + if supportedMicroversions.MaxMajor == 0 && + supportedMicroversions.MaxMinor == 0 && + supportedMicroversions.MinMajor == 0 && + supportedMicroversions.MinMinor == 0 { + return supportedMicroversions, fmt.Errorf("microversions not supported by endpoint") + } + + return supportedMicroversions, err } // RequireMicroversion checks that the required microversion is supported and @@ -117,6 +190,42 @@ func (supported SupportedMicroversions) IsSupported(version string) (bool, error return false, nil } +// ParseVersion parsed the version strings v{MAJOR} and v{MAJOR}.{MINOR} into separate integers +// major and minor. +// For example, "v2.1" becomes 2 and 1, "v3" becomes 3 and 0, and "1" becomes 1 and 0. +func ParseVersion(version string) (major, minor int, err error) { + if version == "" { + return 0, 0, fmt.Errorf("empty version provided") + } + + // We use the regex indicated by the version discovery guidelines. + // + // https://specs.openstack.org/openstack/api-sig/guidelines/consuming-catalog/version-discovery.html#inferring-version + // + // However, we diverge slightly since not all services include the 'v' prefix (glares at zaqar) + versionRe := regexp.MustCompile(`^v?(?P[0-9]+)(\.(?P[0-9]+))?$`) + + match := versionRe.FindStringSubmatch(version) + if len(match) == 0 { + return 0, 0, fmt.Errorf("invalid format: %q", version) + } + + major, err = strconv.Atoi(match[versionRe.SubexpIndex("major")]) + if err != nil { + return 0, 0, err + } + + minor = 0 + if match[versionRe.SubexpIndex("minor")] != "" { + minor, err = strconv.Atoi(match[versionRe.SubexpIndex("minor")]) + if err != nil { + return 0, 0, err + } + } + + return major, minor, nil +} + // ParseMicroversion parses the version major.minor into separate integers major and minor. // For example, "2.53" becomes 2 and 53. func ParseMicroversion(version string) (major int, minor int, err error) { @@ -134,3 +243,18 @@ func ParseMicroversion(version string) (major int, minor int, err error) { } return major, minor, nil } + +func ParseStatus(status string) (Status, error) { + switch strings.ToUpper(status) { + case "CURRENT", "STABLE": // keystone uses STABLE instead of CURRENT + return StatusCurrent, nil + case "SUPPORTED": + return StatusSupported, nil + case "DEPRECATED": + return StatusDeprecated, nil + case "": + return StatusUnknown, nil + default: + return StatusUnknown, fmt.Errorf("invalid status: %q", status) + } +} diff --git a/openstack/utils/testing/discovery_test.go b/openstack/utils/testing/discovery_test.go index e2917e17e9..4b13f82213 100644 --- a/openstack/utils/testing/discovery_test.go +++ b/openstack/utils/testing/discovery_test.go @@ -18,7 +18,7 @@ func TestGetServiceVersions(t *testing.T) { tests := []struct { name string endpoint string - expectedVersions utils.SupportedMicroversions + expectedVersions []utils.SupportedVersion expectedErr string }{ { @@ -28,47 +28,88 @@ func TestGetServiceVersions(t *testing.T) { expectedErr: "cannot unmarshal object", }, { - // FIXME(stephenfin): We should handle missing microversion info - name: "identity versioned endpoint", - endpoint: fakeServer.Endpoint() + "identity/v3/", - expectedErr: "not supported", + name: "identity versioned endpoint", + endpoint: fakeServer.Endpoint() + "identity/v3/", + expectedVersions: []utils.SupportedVersion{ + { + Major: 3, + Minor: 14, + Status: utils.StatusCurrent, + }, + }, }, { - // FIXME(stephenfin): We should handle missing microversion info - name: "compute unversioned endpoint", - endpoint: fakeServer.Endpoint() + "compute/", - expectedErr: "not supported", + name: "compute unversioned endpoint", + endpoint: fakeServer.Endpoint() + "compute/", + expectedVersions: []utils.SupportedVersion{ + { + Major: 2, + Minor: 1, + Status: utils.StatusCurrent, + SupportedMicroversions: utils.SupportedMicroversions{ + MaxMajor: 2, MaxMinor: 90, MinMajor: 2, MinMinor: 1, + }, + }, + { + Major: 2, + Minor: 0, + Status: utils.StatusSupported, + }, + }, }, { - // FIXME(stephenfin): We should handle missing microversion info - name: "compute legacy endpoint", - endpoint: fakeServer.Endpoint() + "compute/v2/", - expectedErr: "not supported", + name: "compute legacy endpoint", + endpoint: fakeServer.Endpoint() + "compute/v2/", + expectedVersions: []utils.SupportedVersion{ + { + Major: 2, + Minor: 0, + Status: utils.StatusSupported, + }, + }, }, { name: "compute versioned endpoint", endpoint: fakeServer.Endpoint() + "compute/v2.1/", - expectedVersions: utils.SupportedMicroversions{ - MaxMajor: 2, MaxMinor: 90, MinMajor: 2, MinMinor: 1, + expectedVersions: []utils.SupportedVersion{ + { + Major: 2, + Minor: 1, + Status: utils.StatusCurrent, + SupportedMicroversions: utils.SupportedMicroversions{ + MaxMajor: 2, MaxMinor: 90, MinMajor: 2, MinMinor: 1, + }, + }, }, }, { - // FIXME(stephenfin): This is erroring because we ignore the max_version field - name: "container-infra unversioned endpoint", - endpoint: fakeServer.Endpoint() + "container-infra/", - expectedErr: "invalid microversion format", + // FIXME(stephenfin): The max version is wrong because we ignore the max_version field + name: "container-infra unversioned endpoint", + endpoint: fakeServer.Endpoint() + "container-infra/", + expectedVersions: []utils.SupportedVersion{ + { + Major: 1, + Minor: 0, + Status: utils.StatusCurrent, + }, + }, }, { - // FIXME(stephenfin): We should handle missing microversion info + // FIXME(stephenfin): This is broken because we don't handle the lack of an envelope name: "container-infra versioned endpoint", endpoint: fakeServer.Endpoint() + "container-infra/v1/", - expectedErr: "not supported", + expectedErr: "empty version provided", }, { - // FIXME(stephenfin): We should handle missing microversion info - name: "orchestration unversioned endpoint", - endpoint: fakeServer.Endpoint() + "heat-api/", - expectedErr: "not supported", + name: "orchestration unversioned endpoint", + endpoint: fakeServer.Endpoint() + "heat-api/", + expectedVersions: []utils.SupportedVersion{ + { + Major: 1, + Minor: 0, + Status: utils.StatusCurrent, + }, + }, }, { // FIXME(stephenfin): We should missing version documents @@ -77,36 +118,71 @@ func TestGetServiceVersions(t *testing.T) { expectedErr: "Expected HTTP response code", }, { - // FIXME(stephenfin): We should handle missing microversion info - name: "workflow unversioned endpoint", - endpoint: fakeServer.Endpoint() + "workflow/", - expectedErr: "not supported", + name: "workflow unversioned endpoint", + endpoint: fakeServer.Endpoint() + "workflow/", + expectedVersions: []utils.SupportedVersion{ + { + Major: 2, + Minor: 0, + Status: utils.StatusCurrent, + }, + }, }, { // FIXME(stephenfin): We should handle invalid version documents name: "workflow versioned endpoint", endpoint: fakeServer.Endpoint() + "workflow/v2/", - expectedErr: "not supported", + expectedErr: "empty version provided", }, { name: "baremetal unversioned endpoint", endpoint: fakeServer.Endpoint() + "baremetal/", - expectedVersions: utils.SupportedMicroversions{ - MaxMajor: 1, MaxMinor: 87, MinMajor: 1, MinMinor: 1, + expectedVersions: []utils.SupportedVersion{ + { + Major: 1, + Minor: 0, + Status: utils.StatusCurrent, + SupportedMicroversions: utils.SupportedMicroversions{ + MaxMajor: 1, MaxMinor: 87, MinMajor: 1, MinMinor: 1, + }, + }, }, }, { name: "baremetal versioned endpoint", endpoint: fakeServer.Endpoint() + "baremetal/v1/", - expectedVersions: utils.SupportedMicroversions{ - MaxMajor: 1, MaxMinor: 87, MinMajor: 1, MinMinor: 1, + expectedVersions: []utils.SupportedVersion{ + { + Major: 1, + Minor: 0, + Status: utils.StatusCurrent, + SupportedMicroversions: utils.SupportedMicroversions{ + MaxMajor: 1, MaxMinor: 87, MinMajor: 1, MinMinor: 1, + }, + }, }, }, { - // FIXME(stephenfin): We should handle multiple microversion info - name: "fictional multi-version endpoint", - endpoint: fakeServer.Endpoint() + "multi-version/v1.2/", - expectedErr: "not supported", + name: "fictional multi-version endpoint", + endpoint: fakeServer.Endpoint() + "multi-version/v1.2/", + expectedVersions: []utils.SupportedVersion{ + { + Major: 1, + Minor: 2, + Status: utils.StatusCurrent, + SupportedMicroversions: utils.SupportedMicroversions{ + MaxMajor: 1, MaxMinor: 90, MinMajor: 1, MinMinor: 2, + }, + }, + { + Major: 1, + Minor: 0, + Status: utils.StatusCurrent, + SupportedMicroversions: utils.SupportedMicroversions{ + MaxMajor: 1, MaxMinor: 87, MinMajor: 1, MinMinor: 1, + }, + }, + }, }, } for _, tt := range tests { @@ -176,13 +252,13 @@ func TestGetSupportedMicroversions(t *testing.T) { // FIXME(stephenfin): This is erroring because we ignore the max_version field name: "container-infra unversioned endpoint", endpoint: fakeServer.Endpoint() + "container-infra/", - expectedErr: "invalid microversion format", + expectedErr: "microversions not supported by endpoint", }, { // container-infra does not expose proper discovery information name: "container-infra versioned endpoint", endpoint: fakeServer.Endpoint() + "container-infra/v1/", - expectedErr: "not supported", + expectedErr: "empty version provided", }, { // orchestration does not support microversions and returns error @@ -204,9 +280,10 @@ func TestGetSupportedMicroversions(t *testing.T) { }, { // workflow does not support microversions and returns error + // FIXME(stephenfin): We should handle invalid version documents name: "workflow versioned endpoint", endpoint: fakeServer.Endpoint() + "workflow/v2/", - expectedErr: "not supported", + expectedErr: "empty version provided", }, { name: "baremetal unversioned endpoint", From 9d1e5a13223329803f5fc80b400baaa0fd223bd1 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Wed, 11 Jun 2025 19:12:57 +0100 Subject: [PATCH 190/353] Support different types of version documents While the expected format of these documents is defined by a spec [1], most services do things slightly differently. Here, we add support for the Keystone and Barbican-style documents, which embed version objects inside another object with a single 'values' key, like so: {"versions": {"values": [{"id": "v3.14", ...}]}} And the Magnum-style document, which doesn't envelope individual version objects at all: {"id": "v2", ...} These are in contrast to the format used by Nova, Cinder etc.: {"versions": [{"id": "v2", ...}]} We also add support for 'max_version' key, which is used by Magnum and is what the spec actually recommends. [1] https://specs.openstack.org/openstack/api-sig/guidelines/discoverability.html Signed-off-by: Stephen Finucane (cherry picked from commit 6e92c226f89af54321af872e9452a34f98815e9f) --- openstack/utils/discovery.go | 103 +++++++++++++++++----- openstack/utils/testing/discovery_test.go | 48 ++++++---- 2 files changed, 113 insertions(+), 38 deletions(-) diff --git a/openstack/utils/discovery.go b/openstack/utils/discovery.go index d8c44879f0..656f1ddfdd 100644 --- a/openstack/utils/discovery.go +++ b/openstack/utils/discovery.go @@ -2,6 +2,7 @@ package utils import ( "context" + "encoding/json" "fmt" "regexp" "sort" @@ -46,21 +47,84 @@ type SupportedMicroversions struct { MinMinor int } +type version struct { + ID string `json:"id"` + Status string `json:"status"` + Version string `json:"version,omitempty"` + MaxVersion string `json:"max_version,omitempty"` + MinVersion string `json:"min_version"` +} + +type response struct { + Versions []version `json:"-"` +} + +func (r *response) UnmarshalJSON(in []byte) error { + // intermediateResponse is an intermediate struct that allows us to offload the difference + // between a single version document and a multi-version document to the json parser and + // only focus on differences in the latter + type intermediateResponse struct { + ID string `json:"id"` + Version *version `json:"version"` + Versions *json.RawMessage `json:"versions"` + } + + data := intermediateResponse{} + if err := json.Unmarshal(in, &data); err != nil { + return err + } + + // case 1: we have a single enveloped version object + // + // this is the approach used by Manila for single version responses + if data.Version != nil { + r.Versions = []version{*data.Version} + return nil + } + + // case 2: we have an singly enveloped array of version objects + // + // this is the approach used by nova, cinder and glance, among others, for multi-version + // responses + if data.Versions != nil { + var versionArr []version + if err := json.Unmarshal(*data.Versions, &versionArr); err == nil { + r.Versions = versionArr + return nil + } + } + + // case 3: we have an doubly enveloped array of version objects + // + // this is the approach used by keystone and barbican, among others, for multi-version + // responses + if data.Versions != nil { + type values struct { + Values []version `json:"values"` + } + + var valuesObj values + if err := json.Unmarshal(*data.Versions, &valuesObj); err == nil { + r.Versions = valuesObj.Values + return nil + } + } + + // case 4: we have a single unenveloped version object + // + // this is the approach used by most other services for single version responses + if data.ID != "" { + r.Versions = []version{{ID: data.ID}} + return nil + } + + return fmt.Errorf("failed to unmarshal versions document: %s", in) +} + // GetServiceVersions returns the versions supported by the ServiceClient Endpoint. // If the endpoint resolves to an unversioned discovery API, this should return one or more supported versions. // If the endpoint resolves to a versioned discovery API, this should return exactly one supported version. func GetServiceVersions(ctx context.Context, client *gophercloud.ProviderClient, endpointURL string) ([]SupportedVersion, error) { - type valueResp struct { - ID string `json:"id"` - Status string `json:"status"` - Version string `json:"version"` - MinVersion string `json:"min_version"` - } - type response struct { - Version valueResp `json:"version"` - Versions []valueResp `json:"versions"` - } - var supportedVersions []SupportedVersion var resp response @@ -72,12 +136,7 @@ func GetServiceVersions(ctx context.Context, client *gophercloud.ProviderClient, return supportedVersions, err } - var versions []valueResp - if len(resp.Versions) > 0 { - versions = resp.Versions - } else { - versions = append(versions, resp.Version) - } + versions := resp.Versions for _, version := range versions { majorVersion, minorVersion, err := ParseVersion(version.ID) @@ -96,14 +155,18 @@ func GetServiceVersions(ctx context.Context, client *gophercloud.ProviderClient, Status: status, } - // Only normalize the microversion if there is a microversion to normalize - if version.MinVersion != "" && version.Version != "" { + // Only normalize the microversions if there are microversions to normalize + if (version.Version != "" || version.MaxVersion != "") && version.MinVersion != "" { supportedVersion.MinMajor, supportedVersion.MinMinor, err = ParseMicroversion(version.MinVersion) if err != nil { return supportedVersions, err } - supportedVersion.MaxMajor, supportedVersion.MaxMinor, err = ParseMicroversion(version.Version) + maxVersion := version.Version + if maxVersion == "" { + maxVersion = version.MaxVersion + } + supportedVersion.MaxMajor, supportedVersion.MaxMinor, err = ParseMicroversion(maxVersion) if err != nil { return supportedVersions, err } diff --git a/openstack/utils/testing/discovery_test.go b/openstack/utils/testing/discovery_test.go index 4b13f82213..b97722cfee 100644 --- a/openstack/utils/testing/discovery_test.go +++ b/openstack/utils/testing/discovery_test.go @@ -22,10 +22,15 @@ func TestGetServiceVersions(t *testing.T) { expectedErr string }{ { - // FIXME(stephenfin): This is erroring because we can't handle the addition 'values' envelope - name: "identity unversioned endpoint", - endpoint: fakeServer.Endpoint() + "identity/", - expectedErr: "cannot unmarshal object", + name: "identity unversioned endpoint", + endpoint: fakeServer.Endpoint() + "identity/", + expectedVersions: []utils.SupportedVersion{ + { + Major: 3, + Minor: 14, + Status: utils.StatusCurrent, + }, + }, }, { name: "identity versioned endpoint", @@ -83,7 +88,6 @@ func TestGetServiceVersions(t *testing.T) { }, }, { - // FIXME(stephenfin): The max version is wrong because we ignore the max_version field name: "container-infra unversioned endpoint", endpoint: fakeServer.Endpoint() + "container-infra/", expectedVersions: []utils.SupportedVersion{ @@ -91,14 +95,22 @@ func TestGetServiceVersions(t *testing.T) { Major: 1, Minor: 0, Status: utils.StatusCurrent, + SupportedMicroversions: utils.SupportedMicroversions{ + MaxMajor: 1, MaxMinor: 11, MinMajor: 1, MinMinor: 1, + }, }, }, }, { - // FIXME(stephenfin): This is broken because we don't handle the lack of an envelope - name: "container-infra versioned endpoint", - endpoint: fakeServer.Endpoint() + "container-infra/v1/", - expectedErr: "empty version provided", + name: "container-infra versioned endpoint", + endpoint: fakeServer.Endpoint() + "container-infra/v1/", + expectedVersions: []utils.SupportedVersion{ + { + Major: 1, + Minor: 0, + Status: utils.StatusUnknown, + }, + }, }, { name: "orchestration unversioned endpoint", @@ -132,7 +144,7 @@ func TestGetServiceVersions(t *testing.T) { // FIXME(stephenfin): We should handle invalid version documents name: "workflow versioned endpoint", endpoint: fakeServer.Endpoint() + "workflow/v2/", - expectedErr: "empty version provided", + expectedErr: "failed to unmarshal versions document", }, { name: "baremetal unversioned endpoint", @@ -218,10 +230,9 @@ func TestGetSupportedMicroversions(t *testing.T) { expectedErr string }{ { - // FIXME(stephenfin): This is erroring because we can't handle the addition 'values' envelope name: "identity unversioned endpoint", endpoint: fakeServer.Endpoint() + "identity/", - expectedErr: "cannot unmarshal object", + expectedErr: "not supported", }, { // identity does not support microversions and returns error @@ -249,16 +260,17 @@ func TestGetSupportedMicroversions(t *testing.T) { }, }, { - // FIXME(stephenfin): This is erroring because we ignore the max_version field - name: "container-infra unversioned endpoint", - endpoint: fakeServer.Endpoint() + "container-infra/", - expectedErr: "microversions not supported by endpoint", + name: "container-infra unversioned endpoint", + endpoint: fakeServer.Endpoint() + "container-infra/", + expectedVersions: utils.SupportedMicroversions{ + MaxMajor: 1, MaxMinor: 11, MinMajor: 1, MinMinor: 1, + }, }, { // container-infra does not expose proper discovery information name: "container-infra versioned endpoint", endpoint: fakeServer.Endpoint() + "container-infra/v1/", - expectedErr: "empty version provided", + expectedErr: "not supported", }, { // orchestration does not support microversions and returns error @@ -283,7 +295,7 @@ func TestGetSupportedMicroversions(t *testing.T) { // FIXME(stephenfin): We should handle invalid version documents name: "workflow versioned endpoint", endpoint: fakeServer.Endpoint() + "workflow/v2/", - expectedErr: "empty version provided", + expectedErr: "failed to unmarshal versions document", }, { name: "baremetal unversioned endpoint", From 61ce8804de35c722fa9335b431db77fbd65d30d8 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Wed, 18 Jun 2025 17:06:46 +0100 Subject: [PATCH 191/353] Infer version from URL where possible Signed-off-by: Stephen Finucane (cherry picked from commit 37ec20729bfce79ce7c1722a3e985f72063a85fe) --- openstack/endpoint.go | 2 +- openstack/utils/discovery.go | 53 ++++++++- openstack/utils/testing/discovery_test.go | 139 ++++++++++++++++------ 3 files changed, 154 insertions(+), 40 deletions(-) diff --git a/openstack/endpoint.go b/openstack/endpoint.go index 14ecaf3a4f..6178434423 100644 --- a/openstack/endpoint.go +++ b/openstack/endpoint.go @@ -65,7 +65,7 @@ func endpointSupportsVersion(ctx context.Context, client *gophercloud.ProviderCl return false, err } - supportedVersions, err := utils.GetServiceVersions(ctx, client, endpointURL) + supportedVersions, err := utils.GetServiceVersions(ctx, client, endpointURL, false) if err != nil { return false, err } diff --git a/openstack/utils/discovery.go b/openstack/utils/discovery.go index 656f1ddfdd..86d1d14c34 100644 --- a/openstack/utils/discovery.go +++ b/openstack/utils/discovery.go @@ -4,6 +4,7 @@ import ( "context" "encoding/json" "fmt" + "net/url" "regexp" "sort" "strconv" @@ -121,11 +122,55 @@ func (r *response) UnmarshalJSON(in []byte) error { return fmt.Errorf("failed to unmarshal versions document: %s", in) } +func extractVersion(endpointURL string) (int, int, error) { + u, err := url.Parse(endpointURL) + if err != nil { + return 0, 0, err + } + + parts := strings.Split(strings.TrimRight(u.Path, "/"), "/") + if len(parts) == 0 { + return 0, 0, fmt.Errorf("expected path with version, got: %s", u.Path) + } + + // first, check the nth path element for a version string + if majorVersion, minorVersion, err := ParseVersion(parts[len(parts)-1]); err == nil { + return majorVersion, minorVersion, nil + } + + // if there are no more parts, quit + if len(parts) == 1 { + // we don't return the error message directly since it might be misleading: at this point + // we might have a *malformed* version identifier rather than *no* version identifier + return 0, 0, fmt.Errorf("failed to infer version from path: %s", u.Path) + } + + // the guidelines say we should use the currently scoped project_id from the token, but we + // don't necessarily have a token yet so we speculatively look at the (n-1)th path element + // (but only that) just as keystoneauth does + // + // https://github.com/openstack/keystoneauth/blob/master/keystoneauth1/discover.py#L1534-L1545 + if majorVersion, minorVersion, err := ParseVersion(parts[len(parts)-1]); err == nil { + return majorVersion, minorVersion, err + } + + // once again, we don't return the error message directly + return 0, 0, fmt.Errorf("failed to infer version from path: %s", u.Path) +} + // GetServiceVersions returns the versions supported by the ServiceClient Endpoint. // If the endpoint resolves to an unversioned discovery API, this should return one or more supported versions. // If the endpoint resolves to a versioned discovery API, this should return exactly one supported version. -func GetServiceVersions(ctx context.Context, client *gophercloud.ProviderClient, endpointURL string) ([]SupportedVersion, error) { +func GetServiceVersions(ctx context.Context, client *gophercloud.ProviderClient, endpointURL string, discoverVersions bool) ([]SupportedVersion, error) { var supportedVersions []SupportedVersion + var endpointVersion *SupportedVersion + + if majorVersion, minorVersion, err := extractVersion(endpointURL); err == nil { + endpointVersion = &SupportedVersion{Major: majorVersion, Minor: minorVersion} + if !discoverVersions { + return append(supportedVersions, *endpointVersion), nil + } + } var resp response _, err := client.Request(ctx, "GET", endpointURL, &gophercloud.RequestOpts{ @@ -133,6 +178,10 @@ func GetServiceVersions(ctx context.Context, client *gophercloud.ProviderClient, OkCodes: []int{200, 300}, }) if err != nil { + // we weren't able to find a discovery document but we have version information from the URL + if endpointVersion != nil { + return append(supportedVersions, *endpointVersion), nil + } return supportedVersions, err } @@ -187,7 +236,7 @@ func GetServiceVersions(ctx context.Context, client *gophercloud.ProviderClient, func GetSupportedMicroversions(ctx context.Context, client *gophercloud.ServiceClient) (SupportedMicroversions, error) { var supportedMicroversions SupportedMicroversions - supportedVersions, err := GetServiceVersions(ctx, client.ProviderClient, client.Endpoint) + supportedVersions, err := GetServiceVersions(ctx, client.ProviderClient, client.Endpoint, true) if err != nil { return supportedMicroversions, err } diff --git a/openstack/utils/testing/discovery_test.go b/openstack/utils/testing/discovery_test.go index b97722cfee..76cc2aa3eb 100644 --- a/openstack/utils/testing/discovery_test.go +++ b/openstack/utils/testing/discovery_test.go @@ -18,12 +18,14 @@ func TestGetServiceVersions(t *testing.T) { tests := []struct { name string endpoint string + discoverVersions bool expectedVersions []utils.SupportedVersion expectedErr string }{ { - name: "identity unversioned endpoint", - endpoint: fakeServer.Endpoint() + "identity/", + name: "identity unversioned endpoint", + endpoint: fakeServer.Endpoint() + "identity/", + discoverVersions: true, expectedVersions: []utils.SupportedVersion{ { Major: 3, @@ -33,8 +35,10 @@ func TestGetServiceVersions(t *testing.T) { }, }, { - name: "identity versioned endpoint", - endpoint: fakeServer.Endpoint() + "identity/v3/", + name: "identity unversioned endpoint without discovery", + endpoint: fakeServer.Endpoint() + "identity/", + discoverVersions: false, + // we will still run discovery since we can't extract the version from the URL expectedVersions: []utils.SupportedVersion{ { Major: 3, @@ -44,8 +48,34 @@ func TestGetServiceVersions(t *testing.T) { }, }, { - name: "compute unversioned endpoint", - endpoint: fakeServer.Endpoint() + "compute/", + name: "identity versioned endpoint", + endpoint: fakeServer.Endpoint() + "identity/v3/", + discoverVersions: true, + expectedVersions: []utils.SupportedVersion{ + { + Major: 3, + Minor: 14, + Status: utils.StatusCurrent, + }, + }, + }, + { + name: "identity versioned endpoint without discovery", + endpoint: fakeServer.Endpoint() + "identity/v3/", + discoverVersions: false, + // we will skip discovery since we can extract a version from the URL + expectedVersions: []utils.SupportedVersion{ + { + Major: 3, + Minor: 0, + Status: utils.StatusUnknown, + }, + }, + }, + { + name: "compute unversioned endpoint", + endpoint: fakeServer.Endpoint() + "compute/", + discoverVersions: true, expectedVersions: []utils.SupportedVersion{ { Major: 2, @@ -63,8 +93,9 @@ func TestGetServiceVersions(t *testing.T) { }, }, { - name: "compute legacy endpoint", - endpoint: fakeServer.Endpoint() + "compute/v2/", + name: "compute legacy endpoint", + endpoint: fakeServer.Endpoint() + "compute/v2/", + discoverVersions: true, expectedVersions: []utils.SupportedVersion{ { Major: 2, @@ -74,8 +105,9 @@ func TestGetServiceVersions(t *testing.T) { }, }, { - name: "compute versioned endpoint", - endpoint: fakeServer.Endpoint() + "compute/v2.1/", + name: "compute versioned endpoint", + endpoint: fakeServer.Endpoint() + "compute/v2.1/", + discoverVersions: true, expectedVersions: []utils.SupportedVersion{ { Major: 2, @@ -88,8 +120,9 @@ func TestGetServiceVersions(t *testing.T) { }, }, { - name: "container-infra unversioned endpoint", - endpoint: fakeServer.Endpoint() + "container-infra/", + name: "container-infra unversioned endpoint", + endpoint: fakeServer.Endpoint() + "container-infra/", + discoverVersions: true, expectedVersions: []utils.SupportedVersion{ { Major: 1, @@ -102,8 +135,9 @@ func TestGetServiceVersions(t *testing.T) { }, }, { - name: "container-infra versioned endpoint", - endpoint: fakeServer.Endpoint() + "container-infra/v1/", + name: "container-infra versioned endpoint", + endpoint: fakeServer.Endpoint() + "container-infra/v1/", + discoverVersions: true, expectedVersions: []utils.SupportedVersion{ { Major: 1, @@ -113,8 +147,9 @@ func TestGetServiceVersions(t *testing.T) { }, }, { - name: "orchestration unversioned endpoint", - endpoint: fakeServer.Endpoint() + "heat-api/", + name: "orchestration unversioned endpoint", + endpoint: fakeServer.Endpoint() + "heat-api/", + discoverVersions: true, expectedVersions: []utils.SupportedVersion{ { Major: 1, @@ -124,14 +159,21 @@ func TestGetServiceVersions(t *testing.T) { }, }, { - // FIXME(stephenfin): We should missing version documents - name: "orchestration versioned endpoint", - endpoint: fakeServer.Endpoint() + "heat-api/v1/", - expectedErr: "Expected HTTP response code", + name: "orchestration versioned endpoint", + endpoint: fakeServer.Endpoint() + "heat-api/v1/", + discoverVersions: true, + expectedVersions: []utils.SupportedVersion{ + { + Major: 1, + Minor: 0, + Status: utils.StatusUnknown, + }, + }, }, { - name: "workflow unversioned endpoint", - endpoint: fakeServer.Endpoint() + "workflow/", + name: "workflow unversioned endpoint", + endpoint: fakeServer.Endpoint() + "workflow/", + discoverVersions: true, expectedVersions: []utils.SupportedVersion{ { Major: 2, @@ -141,14 +183,21 @@ func TestGetServiceVersions(t *testing.T) { }, }, { - // FIXME(stephenfin): We should handle invalid version documents - name: "workflow versioned endpoint", - endpoint: fakeServer.Endpoint() + "workflow/v2/", - expectedErr: "failed to unmarshal versions document", + name: "workflow versioned endpoint", + endpoint: fakeServer.Endpoint() + "workflow/v2/", + discoverVersions: true, + expectedVersions: []utils.SupportedVersion{ + { + Major: 2, + Minor: 0, + Status: utils.StatusUnknown, + }, + }, }, { - name: "baremetal unversioned endpoint", - endpoint: fakeServer.Endpoint() + "baremetal/", + name: "baremetal unversioned endpoint", + endpoint: fakeServer.Endpoint() + "baremetal/", + discoverVersions: true, expectedVersions: []utils.SupportedVersion{ { Major: 1, @@ -161,8 +210,9 @@ func TestGetServiceVersions(t *testing.T) { }, }, { - name: "baremetal versioned endpoint", - endpoint: fakeServer.Endpoint() + "baremetal/v1/", + name: "baremetal versioned endpoint", + endpoint: fakeServer.Endpoint() + "baremetal/v1/", + discoverVersions: true, expectedVersions: []utils.SupportedVersion{ { Major: 1, @@ -175,8 +225,24 @@ func TestGetServiceVersions(t *testing.T) { }, }, { - name: "fictional multi-version endpoint", - endpoint: fakeServer.Endpoint() + "multi-version/v1.2/", + name: "baremetal versioned endpoint", + endpoint: fakeServer.Endpoint() + "baremetal/v1/", + discoverVersions: true, + expectedVersions: []utils.SupportedVersion{ + { + Major: 1, + Minor: 0, + Status: utils.StatusCurrent, + SupportedMicroversions: utils.SupportedMicroversions{ + MaxMajor: 1, MaxMinor: 87, MinMajor: 1, MinMinor: 1, + }, + }, + }, + }, + { + name: "fictional multi-version endpoint", + endpoint: fakeServer.Endpoint() + "multi-version/v1.2/", + discoverVersions: true, expectedVersions: []utils.SupportedVersion{ { Major: 1, @@ -201,7 +267,7 @@ func TestGetServiceVersions(t *testing.T) { t.Run(tt.name, func(t *testing.T) { client := &gophercloud.ProviderClient{} - actualVersions, err := utils.GetServiceVersions(context.TODO(), client, tt.endpoint) + actualVersions, err := utils.GetServiceVersions(context.TODO(), client, tt.endpoint, tt.discoverVersions) if tt.expectedErr != "" { th.AssertErr(t, err) @@ -279,10 +345,10 @@ func TestGetSupportedMicroversions(t *testing.T) { expectedErr: "not supported", }, { - // FIXME(stephenfin): We should handle missing version documents + // orchestration does not support microversions and returns error name: "orchestration versioned endpoint", endpoint: fakeServer.Endpoint() + "heat-api/v1/", - expectedErr: "Expected HTTP response code", + expectedErr: "not supported", }, { // workflow does not support microversions and returns error @@ -292,10 +358,9 @@ func TestGetSupportedMicroversions(t *testing.T) { }, { // workflow does not support microversions and returns error - // FIXME(stephenfin): We should handle invalid version documents name: "workflow versioned endpoint", endpoint: fakeServer.Endpoint() + "workflow/v2/", - expectedErr: "failed to unmarshal versions document", + expectedErr: "not supported", }, { name: "baremetal unversioned endpoint", From a7234bbc5b0e619cfd7360c27264a0f47d25e694 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Wed, 11 Jun 2025 18:33:40 +0100 Subject: [PATCH 192/353] Trigger functional tests for changes to common code Signed-off-by: Stephen Finucane (cherry picked from commit b6be9847a8dd0d076a58b2207d1bd8823267d21b) --- .github/workflows/functional-baremetal.yaml | 7 +++++++ .github/workflows/functional-blockstorage.yaml | 7 +++++++ .github/workflows/functional-compute.yaml | 7 +++++++ .github/workflows/functional-containerinfra.yaml | 7 +++++++ .github/workflows/functional-dns.yaml | 7 +++++++ .github/workflows/functional-fwaas_v2.yaml | 7 +++++++ .github/workflows/functional-identity.yaml | 7 +++++++ .github/workflows/functional-image.yaml | 7 +++++++ .github/workflows/functional-keymanager.yaml | 7 +++++++ .github/workflows/functional-loadbalancer.yaml | 7 +++++++ .github/workflows/functional-messaging.yaml | 7 +++++++ .github/workflows/functional-networking.yaml | 7 +++++++ .github/workflows/functional-objectstorage.yaml | 7 +++++++ .github/workflows/functional-orchestration.yaml | 7 +++++++ .github/workflows/functional-placement.yaml | 7 +++++++ .github/workflows/functional-sharedfilesystems.yaml | 7 +++++++ .github/workflows/functional-workflow.yaml | 7 +++++++ 17 files changed, 119 insertions(+) diff --git a/.github/workflows/functional-baremetal.yaml b/.github/workflows/functional-baremetal.yaml index f4f9ed8166..48459154b2 100644 --- a/.github/workflows/functional-baremetal.yaml +++ b/.github/workflows/functional-baremetal.yaml @@ -2,6 +2,13 @@ name: functional-baremetal on: pull_request: paths: + - 'openstack/auth_env.go' + - 'openstack/client.go' + - 'openstack/endpoint.go' + - 'openstack/endpoint_location.go' + - 'openstack/config/provider_client.go' + - 'openstack/utils/choose_version.go' + - 'openstack/utils/discovery.go' - '**baremetal**' - '.github/workflows/functional-baremetal.yaml' schedule: diff --git a/.github/workflows/functional-blockstorage.yaml b/.github/workflows/functional-blockstorage.yaml index 996ba7fd9f..715ecffb92 100644 --- a/.github/workflows/functional-blockstorage.yaml +++ b/.github/workflows/functional-blockstorage.yaml @@ -2,6 +2,13 @@ name: functional-blockstorage on: pull_request: paths: + - 'openstack/auth_env.go' + - 'openstack/client.go' + - 'openstack/endpoint.go' + - 'openstack/endpoint_location.go' + - 'openstack/config/provider_client.go' + - 'openstack/utils/choose_version.go' + - 'openstack/utils/discovery.go' - '**blockstorage**' - '.github/workflows/functional-blockstorage.yaml' schedule: diff --git a/.github/workflows/functional-compute.yaml b/.github/workflows/functional-compute.yaml index 5265e25860..9d8b4be83a 100644 --- a/.github/workflows/functional-compute.yaml +++ b/.github/workflows/functional-compute.yaml @@ -2,6 +2,13 @@ name: functional-compute on: pull_request: paths: + - 'openstack/auth_env.go' + - 'openstack/client.go' + - 'openstack/endpoint.go' + - 'openstack/endpoint_location.go' + - 'openstack/config/provider_client.go' + - 'openstack/utils/choose_version.go' + - 'openstack/utils/discovery.go' - '**compute**' - '.github/workflows/functional-compute.yaml' schedule: diff --git a/.github/workflows/functional-containerinfra.yaml b/.github/workflows/functional-containerinfra.yaml index 00bcb0a830..cf41007799 100644 --- a/.github/workflows/functional-containerinfra.yaml +++ b/.github/workflows/functional-containerinfra.yaml @@ -2,6 +2,13 @@ name: functional-containerinfra on: pull_request: paths: + - 'openstack/auth_env.go' + - 'openstack/client.go' + - 'openstack/endpoint.go' + - 'openstack/endpoint_location.go' + - 'openstack/config/provider_client.go' + - 'openstack/utils/choose_version.go' + - 'openstack/utils/discovery.go' - '**containerinfra**' - '.github/workflows/functional-containerinfra.yaml' schedule: diff --git a/.github/workflows/functional-dns.yaml b/.github/workflows/functional-dns.yaml index e03f309cea..c63d045973 100644 --- a/.github/workflows/functional-dns.yaml +++ b/.github/workflows/functional-dns.yaml @@ -2,6 +2,13 @@ name: functional-dns on: pull_request: paths: + - 'openstack/auth_env.go' + - 'openstack/client.go' + - 'openstack/endpoint.go' + - 'openstack/endpoint_location.go' + - 'openstack/config/provider_client.go' + - 'openstack/utils/choose_version.go' + - 'openstack/utils/discovery.go' - '**dns**' - '.github/workflows/functional-dns.yaml' schedule: diff --git a/.github/workflows/functional-fwaas_v2.yaml b/.github/workflows/functional-fwaas_v2.yaml index 77857180f8..6724dbcb8f 100644 --- a/.github/workflows/functional-fwaas_v2.yaml +++ b/.github/workflows/functional-fwaas_v2.yaml @@ -6,6 +6,13 @@ name: functional-fwaas_v2 on: pull_request: paths: + - 'openstack/auth_env.go' + - 'openstack/client.go' + - 'openstack/endpoint.go' + - 'openstack/endpoint_location.go' + - 'openstack/config/provider_client.go' + - 'openstack/utils/choose_version.go' + - 'openstack/utils/discovery.go' - '**networking/v2/extensions/fwaas_v2**' - '.github/workflows/functional-fwaas_v2.yaml' schedule: diff --git a/.github/workflows/functional-identity.yaml b/.github/workflows/functional-identity.yaml index a21921e1b2..fe33606e70 100644 --- a/.github/workflows/functional-identity.yaml +++ b/.github/workflows/functional-identity.yaml @@ -2,6 +2,13 @@ name: functional-identity on: pull_request: paths: + - 'openstack/auth_env.go' + - 'openstack/client.go' + - 'openstack/endpoint.go' + - 'openstack/endpoint_location.go' + - 'openstack/config/provider_client.go' + - 'openstack/utils/choose_version.go' + - 'openstack/utils/discovery.go' - '**identity**' - '.github/workflows/functional-identity.yaml' schedule: diff --git a/.github/workflows/functional-image.yaml b/.github/workflows/functional-image.yaml index 1b75aee919..38af27829d 100644 --- a/.github/workflows/functional-image.yaml +++ b/.github/workflows/functional-image.yaml @@ -2,6 +2,13 @@ name: functional-image on: pull_request: paths: + - 'openstack/auth_env.go' + - 'openstack/client.go' + - 'openstack/endpoint.go' + - 'openstack/endpoint_location.go' + - 'openstack/config/provider_client.go' + - 'openstack/utils/choose_version.go' + - 'openstack/utils/discovery.go' - '**image**' - '.github/workflows/functional-image.yaml' schedule: diff --git a/.github/workflows/functional-keymanager.yaml b/.github/workflows/functional-keymanager.yaml index ff34e5ac14..62dd751f9c 100644 --- a/.github/workflows/functional-keymanager.yaml +++ b/.github/workflows/functional-keymanager.yaml @@ -2,6 +2,13 @@ name: functional-keymanager on: pull_request: paths: + - 'openstack/auth_env.go' + - 'openstack/client.go' + - 'openstack/endpoint.go' + - 'openstack/endpoint_location.go' + - 'openstack/config/provider_client.go' + - 'openstack/utils/choose_version.go' + - 'openstack/utils/discovery.go' - '**keymanager**' - '.github/workflows/functional-keymanager.yaml' schedule: diff --git a/.github/workflows/functional-loadbalancer.yaml b/.github/workflows/functional-loadbalancer.yaml index ea1832ca28..8ec64b412d 100644 --- a/.github/workflows/functional-loadbalancer.yaml +++ b/.github/workflows/functional-loadbalancer.yaml @@ -2,6 +2,13 @@ name: functional-loadbalancer on: pull_request: paths: + - 'openstack/auth_env.go' + - 'openstack/client.go' + - 'openstack/endpoint.go' + - 'openstack/endpoint_location.go' + - 'openstack/config/provider_client.go' + - 'openstack/utils/choose_version.go' + - 'openstack/utils/discovery.go' - '**loadbalancer**' - '.github/workflows/functional-loadbalancer.yaml' schedule: diff --git a/.github/workflows/functional-messaging.yaml b/.github/workflows/functional-messaging.yaml index 79cc2eec0e..aeb90cefc4 100644 --- a/.github/workflows/functional-messaging.yaml +++ b/.github/workflows/functional-messaging.yaml @@ -2,6 +2,13 @@ name: functional-messaging on: pull_request: paths: + - 'openstack/auth_env.go' + - 'openstack/client.go' + - 'openstack/endpoint.go' + - 'openstack/endpoint_location.go' + - 'openstack/config/provider_client.go' + - 'openstack/utils/choose_version.go' + - 'openstack/utils/discovery.go' - '**messaging**' - '.github/workflows/functional-messaging.yaml' schedule: diff --git a/.github/workflows/functional-networking.yaml b/.github/workflows/functional-networking.yaml index 6435cec16e..1409419986 100644 --- a/.github/workflows/functional-networking.yaml +++ b/.github/workflows/functional-networking.yaml @@ -2,6 +2,13 @@ name: functional-networking on: pull_request: paths: + - 'openstack/auth_env.go' + - 'openstack/client.go' + - 'openstack/endpoint.go' + - 'openstack/endpoint_location.go' + - 'openstack/config/provider_client.go' + - 'openstack/utils/choose_version.go' + - 'openstack/utils/discovery.go' - '**networking**' - '.github/workflows/functional-networking.yaml' schedule: diff --git a/.github/workflows/functional-objectstorage.yaml b/.github/workflows/functional-objectstorage.yaml index a1178b71b2..55497833f3 100644 --- a/.github/workflows/functional-objectstorage.yaml +++ b/.github/workflows/functional-objectstorage.yaml @@ -2,6 +2,13 @@ name: functional-objectstorage on: pull_request: paths: + - 'openstack/auth_env.go' + - 'openstack/client.go' + - 'openstack/endpoint.go' + - 'openstack/endpoint_location.go' + - 'openstack/config/provider_client.go' + - 'openstack/utils/choose_version.go' + - 'openstack/utils/discovery.go' - '**objectstorage**' - '.github/workflows/functional-objectstorage.yaml' schedule: diff --git a/.github/workflows/functional-orchestration.yaml b/.github/workflows/functional-orchestration.yaml index 613f6639cc..9dccad2d45 100644 --- a/.github/workflows/functional-orchestration.yaml +++ b/.github/workflows/functional-orchestration.yaml @@ -2,6 +2,13 @@ name: functional-orchestration on: pull_request: paths: + - 'openstack/auth_env.go' + - 'openstack/client.go' + - 'openstack/endpoint.go' + - 'openstack/endpoint_location.go' + - 'openstack/config/provider_client.go' + - 'openstack/utils/choose_version.go' + - 'openstack/utils/discovery.go' - '**orchestration**' - '.github/workflows/functional-orchestration.yaml' schedule: diff --git a/.github/workflows/functional-placement.yaml b/.github/workflows/functional-placement.yaml index dff74c01b7..800d0979da 100644 --- a/.github/workflows/functional-placement.yaml +++ b/.github/workflows/functional-placement.yaml @@ -2,6 +2,13 @@ name: functional-placement on: pull_request: paths: + - 'openstack/auth_env.go' + - 'openstack/client.go' + - 'openstack/endpoint.go' + - 'openstack/endpoint_location.go' + - 'openstack/config/provider_client.go' + - 'openstack/utils/choose_version.go' + - 'openstack/utils/discovery.go' - '**placement**' - '.github/workflows/functional-placement.yaml' schedule: diff --git a/.github/workflows/functional-sharedfilesystems.yaml b/.github/workflows/functional-sharedfilesystems.yaml index d6dd13206e..0063086ecd 100644 --- a/.github/workflows/functional-sharedfilesystems.yaml +++ b/.github/workflows/functional-sharedfilesystems.yaml @@ -2,6 +2,13 @@ name: functional-sharedfilesystems on: pull_request: paths: + - 'openstack/auth_env.go' + - 'openstack/client.go' + - 'openstack/endpoint.go' + - 'openstack/endpoint_location.go' + - 'openstack/config/provider_client.go' + - 'openstack/utils/choose_version.go' + - 'openstack/utils/discovery.go' - '**sharedfilesystems**' - '.github/workflows/functional-sharedfilesystems.yaml' schedule: diff --git a/.github/workflows/functional-workflow.yaml b/.github/workflows/functional-workflow.yaml index e23b34252e..3b678732f1 100644 --- a/.github/workflows/functional-workflow.yaml +++ b/.github/workflows/functional-workflow.yaml @@ -2,6 +2,13 @@ name: functional-workflow on: pull_request: paths: + - 'openstack/auth_env.go' + - 'openstack/client.go' + - 'openstack/endpoint.go' + - 'openstack/endpoint_location.go' + - 'openstack/config/provider_client.go' + - 'openstack/utils/choose_version.go' + - 'openstack/utils/discovery.go' - '**workflow**' - '.github/workflows/functional-workflow.yaml' schedule: From 85b0f1e9a6fe62e006754761e032c4a42bc3bbf4 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Thu, 7 Aug 2025 12:28:38 +0100 Subject: [PATCH 193/353] Use new context for endpoint locator function This is a v2-only alternative to #3442 [1] that avoids introducing a breaking function signature change while still resolving #3441 [2]. [1] https://github.com/gophercloud/gophercloud/pull/3442 [2] https://github.com/gophercloud/gophercloud/issues/3441 Signed-off-by: Stephen Finucane --- openstack/client.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openstack/client.go b/openstack/client.go index 00dfca6ae7..73ca5c56d5 100644 --- a/openstack/client.go +++ b/openstack/client.go @@ -163,7 +163,7 @@ func v2auth(ctx context.Context, client *gophercloud.ProviderClient, endpoint st } } client.EndpointLocator = func(opts gophercloud.EndpointOpts) (string, error) { - return V2Endpoint(ctx, client, catalog, opts) + return V2Endpoint(context.TODO(), client, catalog, opts) } return nil @@ -284,7 +284,7 @@ func v3auth(ctx context.Context, client *gophercloud.ProviderClient, endpoint st } } client.EndpointLocator = func(opts gophercloud.EndpointOpts) (string, error) { - return V3Endpoint(ctx, client, catalog, opts) + return V3Endpoint(context.TODO(), client, catalog, opts) } return nil From 05365ccfed88dc3cf7237fee4cf02b6272752325 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Fri, 18 Apr 2025 11:16:08 +0100 Subject: [PATCH 194/353] Add epoxy jobs We opt to run on Jammy for now due to to [1]. That's okay since Jammy is a supported host for Epoxy [2]. We should migrate once [1] has been resolved, however. [1] https://bugs.launchpad.net/ubuntu/+source/apparmor/+bug/2065685 [2] https://governance.openstack.org/tc/reference/runtimes/2025.1.html Signed-off-by: Stephen Finucane --- .github/workflows/functional-baremetal.yaml | 4 ++++ .github/workflows/functional-basic.yaml | 4 ++++ .github/workflows/functional-blockstorage.yaml | 4 ++++ .github/workflows/functional-compute.yaml | 4 ++++ .github/workflows/functional-containerinfra.yaml | 13 +++++++++++++ .github/workflows/functional-dns.yaml | 4 ++++ .github/workflows/functional-fwaas_v2.yaml | 4 ++++ .github/workflows/functional-identity.yaml | 4 ++++ .github/workflows/functional-image.yaml | 4 ++++ .github/workflows/functional-keymanager.yaml | 10 ++++++++++ .github/workflows/functional-loadbalancer.yaml | 4 ++++ .github/workflows/functional-messaging.yaml | 4 ++++ .github/workflows/functional-networking.yaml | 4 ++++ .github/workflows/functional-objectstorage.yaml | 4 ++++ .github/workflows/functional-orchestration.yaml | 4 ++++ .github/workflows/functional-placement.yaml | 4 ++++ .github/workflows/functional-sharedfilesystems.yaml | 4 ++++ .github/workflows/functional-workflow.yaml | 5 +++++ 18 files changed, 88 insertions(+) diff --git a/.github/workflows/functional-baremetal.yaml b/.github/workflows/functional-baremetal.yaml index f4f9ed8166..a1ec826ff8 100644 --- a/.github/workflows/functional-baremetal.yaml +++ b/.github/workflows/functional-baremetal.yaml @@ -16,6 +16,10 @@ jobs: openstack_version: "master" ubuntu_version: "24.04" additional_services: "openstack-cli-server" + - name: "epoxy" + openstack_version: "stable/2025.1" + ubuntu_version: "22.04" + additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" ubuntu_version: "22.04" diff --git a/.github/workflows/functional-basic.yaml b/.github/workflows/functional-basic.yaml index f188735441..b33d4c34bd 100644 --- a/.github/workflows/functional-basic.yaml +++ b/.github/workflows/functional-basic.yaml @@ -18,6 +18,10 @@ jobs: openstack_version: "master" ubuntu_version: "24.04" additional_services: "openstack-cli-server" + - name: "epoxy" + openstack_version: "stable/2025.1" + ubuntu_version: "22.04" + additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" ubuntu_version: "22.04" diff --git a/.github/workflows/functional-blockstorage.yaml b/.github/workflows/functional-blockstorage.yaml index 996ba7fd9f..bccf753042 100644 --- a/.github/workflows/functional-blockstorage.yaml +++ b/.github/workflows/functional-blockstorage.yaml @@ -16,6 +16,10 @@ jobs: openstack_version: "master" ubuntu_version: "24.04" additional_services: "openstack-cli-server" + - name: "epoxy" + openstack_version: "stable/2025.1" + ubuntu_version: "22.04" + additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" ubuntu_version: "22.04" diff --git a/.github/workflows/functional-compute.yaml b/.github/workflows/functional-compute.yaml index 5265e25860..abe668f48c 100644 --- a/.github/workflows/functional-compute.yaml +++ b/.github/workflows/functional-compute.yaml @@ -16,6 +16,10 @@ jobs: openstack_version: "master" ubuntu_version: "24.04" additional_services: "openstack-cli-server" + - name: "epoxy" + openstack_version: "stable/2025.1" + ubuntu_version: "22.04" + additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" ubuntu_version: "22.04" diff --git a/.github/workflows/functional-containerinfra.yaml b/.github/workflows/functional-containerinfra.yaml index 00bcb0a830..fec6fef6fe 100644 --- a/.github/workflows/functional-containerinfra.yaml +++ b/.github/workflows/functional-containerinfra.yaml @@ -25,6 +25,19 @@ jobs: enable_plugin magnum https://github.com/openstack/magnum master MAGNUMCLIENT_BRANCH=master additional_services: "openstack-cli-server" + - name: "epoxy" + openstack_version: "stable/2025.1" + ubuntu_version: "22.04" + devstack_conf_overrides: | + # ensure we're using a working version of setuptools + if [ -n "\$TOP_DIR" ]; then + sed -i 's/setuptools\[core\]$/setuptools[core]==79.0.1/g' \$TOP_DIR/lib/infra \$TOP_DIR/inc/python + sed -i 's/pip_install "-U" "pbr"/pip_install "-U" "pbr" "setuptools[core]==79.0.1"/g' \$TOP_DIR/lib/infra + fi + + enable_plugin magnum https://github.com/openstack/magnum stable/2025.1 + MAGNUMCLIENT_BRANCH=stable/2025.1 + additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" ubuntu_version: "22.04" diff --git a/.github/workflows/functional-dns.yaml b/.github/workflows/functional-dns.yaml index e03f309cea..1e98ecb736 100644 --- a/.github/workflows/functional-dns.yaml +++ b/.github/workflows/functional-dns.yaml @@ -22,6 +22,10 @@ jobs: sed -i 's/pip_install "-U" "pbr"/pip_install "-U" "pbr" "setuptools[core]==79.0.1"/g' \$TOP_DIR/lib/infra fi additional_services: "openstack-cli-server" + - name: "epoxy" + openstack_version: "stable/2025.1" + ubuntu_version: "22.04" + additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" ubuntu_version: "22.04" diff --git a/.github/workflows/functional-fwaas_v2.yaml b/.github/workflows/functional-fwaas_v2.yaml index 77857180f8..0d03e07567 100644 --- a/.github/workflows/functional-fwaas_v2.yaml +++ b/.github/workflows/functional-fwaas_v2.yaml @@ -20,6 +20,10 @@ jobs: openstack_version: "master" ubuntu_version: "24.04" additional_services: "openstack-cli-server" + - name: "epoxy" + openstack_version: "stable/2025.1" + ubuntu_version: "22.04" + additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" ubuntu_version: "22.04" diff --git a/.github/workflows/functional-identity.yaml b/.github/workflows/functional-identity.yaml index a21921e1b2..93a39ee1e7 100644 --- a/.github/workflows/functional-identity.yaml +++ b/.github/workflows/functional-identity.yaml @@ -16,6 +16,10 @@ jobs: openstack_version: "master" ubuntu_version: "24.04" additional_services: "openstack-cli-server" + - name: "epoxy" + openstack_version: "stable/2025.1" + ubuntu_version: "22.04" + additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" ubuntu_version: "22.04" diff --git a/.github/workflows/functional-image.yaml b/.github/workflows/functional-image.yaml index 1b75aee919..82434f9ea9 100644 --- a/.github/workflows/functional-image.yaml +++ b/.github/workflows/functional-image.yaml @@ -16,6 +16,10 @@ jobs: openstack_version: "master" ubuntu_version: "24.04" additional_services: "openstack-cli-server" + - name: "epoxy" + openstack_version: "stable/2025.1" + ubuntu_version: "22.04" + additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" ubuntu_version: "22.04" diff --git a/.github/workflows/functional-keymanager.yaml b/.github/workflows/functional-keymanager.yaml index ff34e5ac14..61ed8c4172 100644 --- a/.github/workflows/functional-keymanager.yaml +++ b/.github/workflows/functional-keymanager.yaml @@ -22,6 +22,16 @@ jobs: sed -i 's/pip_install "-U" "pbr"/pip_install "-U" "pbr" "setuptools[core]==79.0.1"/g' \$TOP_DIR/lib/infra fi additional_services: "openstack-cli-server" + - name: "epoxy" + openstack_version: "stable/2025.1" + ubuntu_version: "22.04" + devstack_conf_overrides: | + # ensure we're using a working version of setuptools + if [ -n "\$TOP_DIR" ]; then + sed -i 's/setuptools\[core\]$/setuptools[core]==79.0.1/g' \$TOP_DIR/lib/infra \$TOP_DIR/inc/python + sed -i 's/pip_install "-U" "pbr"/pip_install "-U" "pbr" "setuptools[core]==79.0.1"/g' \$TOP_DIR/lib/infra + fi + additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" ubuntu_version: "22.04" diff --git a/.github/workflows/functional-loadbalancer.yaml b/.github/workflows/functional-loadbalancer.yaml index ea1832ca28..acd1af2ff5 100644 --- a/.github/workflows/functional-loadbalancer.yaml +++ b/.github/workflows/functional-loadbalancer.yaml @@ -22,6 +22,10 @@ jobs: sed -i 's/pip_install "-U" "pbr"/pip_install "-U" "pbr" "setuptools[core]==79.0.1"/g' \$TOP_DIR/lib/infra fi additional_services: "openstack-cli-server" + - name: "epoxy" + openstack_version: "stable/2025.1" + ubuntu_version: "22.04" + additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" ubuntu_version: "22.04" diff --git a/.github/workflows/functional-messaging.yaml b/.github/workflows/functional-messaging.yaml index 79cc2eec0e..456c73fda7 100644 --- a/.github/workflows/functional-messaging.yaml +++ b/.github/workflows/functional-messaging.yaml @@ -16,6 +16,10 @@ jobs: openstack_version: "master" ubuntu_version: "24.04" additional_services: "openstack-cli-server" + - name: "epoxy" + openstack_version: "stable/2025.1" + ubuntu_version: "22.04" + additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" ubuntu_version: "22.04" diff --git a/.github/workflows/functional-networking.yaml b/.github/workflows/functional-networking.yaml index 6435cec16e..92547ac6a5 100644 --- a/.github/workflows/functional-networking.yaml +++ b/.github/workflows/functional-networking.yaml @@ -16,6 +16,10 @@ jobs: openstack_version: "master" ubuntu_version: "24.04" additional_services: "openstack-cli-server" + - name: "epoxy" + openstack_version: "stable/2025.1" + ubuntu_version: "22.04" + additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" ubuntu_version: "22.04" diff --git a/.github/workflows/functional-objectstorage.yaml b/.github/workflows/functional-objectstorage.yaml index a1178b71b2..e5b2ceea64 100644 --- a/.github/workflows/functional-objectstorage.yaml +++ b/.github/workflows/functional-objectstorage.yaml @@ -16,6 +16,10 @@ jobs: openstack_version: "master" ubuntu_version: "24.04" additional_services: "openstack-cli-server" + - name: "epoxy" + openstack_version: "stable/2025.1" + ubuntu_version: "22.04" + additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" ubuntu_version: "22.04" diff --git a/.github/workflows/functional-orchestration.yaml b/.github/workflows/functional-orchestration.yaml index 613f6639cc..842f170e1e 100644 --- a/.github/workflows/functional-orchestration.yaml +++ b/.github/workflows/functional-orchestration.yaml @@ -16,6 +16,10 @@ jobs: openstack_version: "master" ubuntu_version: "24.04" additional_services: "openstack-cli-server" + - name: "epoxy" + openstack_version: "stable/2025.1" + ubuntu_version: "22.04" + additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" ubuntu_version: "22.04" diff --git a/.github/workflows/functional-placement.yaml b/.github/workflows/functional-placement.yaml index dff74c01b7..ed4612c4e0 100644 --- a/.github/workflows/functional-placement.yaml +++ b/.github/workflows/functional-placement.yaml @@ -16,6 +16,10 @@ jobs: openstack_version: "master" ubuntu_version: "24.04" additional_services: "openstack-cli-server" + - name: "epoxy" + openstack_version: "stable/2025.1" + ubuntu_version: "22.04" + additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" ubuntu_version: "22.04" diff --git a/.github/workflows/functional-sharedfilesystems.yaml b/.github/workflows/functional-sharedfilesystems.yaml index d6dd13206e..1d5b1432c0 100644 --- a/.github/workflows/functional-sharedfilesystems.yaml +++ b/.github/workflows/functional-sharedfilesystems.yaml @@ -22,6 +22,10 @@ jobs: sed -i 's/pip_install "-U" "pbr"/pip_install "-U" "pbr" "setuptools[core]==79.0.1"/g' \$TOP_DIR/lib/infra fi additional_services: "openstack-cli-server" + - name: "epoxy" + openstack_version: "stable/2025.1" + ubuntu_version: "22.04" + additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" ubuntu_version: "22.04" diff --git a/.github/workflows/functional-workflow.yaml b/.github/workflows/functional-workflow.yaml index e23b34252e..b2ce2e368f 100644 --- a/.github/workflows/functional-workflow.yaml +++ b/.github/workflows/functional-workflow.yaml @@ -17,6 +17,11 @@ jobs: ubuntu_version: "24.04" mistral_plugin_version: "master" additional_services: "openstack-cli-server" + - name: "epoxy" + openstack_version: "stable/2025.1" + ubuntu_version: "22.04" + mistral_plugin_version: "stable/2025.1" + additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" ubuntu_version: "22.04" From 4644427a7f57050c574745d45ff1c57167c83be2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zden=C4=9Bk=20Vydra?= <80331839+vydrazde@users.noreply.github.com> Date: Wed, 6 Aug 2025 13:12:35 +0200 Subject: [PATCH 195/353] Add networking taas tapmirror create --- .../networking/v2/extensions/taas/taas.go | 44 +++++++++ .../v2/extensions/taas/tapmirrors_test.go | 39 ++++++++ .../v2/extensions/taas/tapmirrors/doc.go | 23 +++++ .../v2/extensions/taas/tapmirrors/requests.go | 67 ++++++++++++++ .../v2/extensions/taas/tapmirrors/results.go | 69 ++++++++++++++ .../taas/tapmirrors/testing/requests_test.go | 91 +++++++++++++++++++ .../v2/extensions/taas/tapmirrors/urls.go | 12 +++ 7 files changed, 345 insertions(+) create mode 100644 internal/acceptance/openstack/networking/v2/extensions/taas/taas.go create mode 100644 internal/acceptance/openstack/networking/v2/extensions/taas/tapmirrors_test.go create mode 100644 openstack/networking/v2/extensions/taas/tapmirrors/doc.go create mode 100644 openstack/networking/v2/extensions/taas/tapmirrors/requests.go create mode 100644 openstack/networking/v2/extensions/taas/tapmirrors/results.go create mode 100644 openstack/networking/v2/extensions/taas/tapmirrors/testing/requests_test.go create mode 100644 openstack/networking/v2/extensions/taas/tapmirrors/urls.go diff --git a/internal/acceptance/openstack/networking/v2/extensions/taas/taas.go b/internal/acceptance/openstack/networking/v2/extensions/taas/taas.go new file mode 100644 index 0000000000..026c5d2292 --- /dev/null +++ b/internal/acceptance/openstack/networking/v2/extensions/taas/taas.go @@ -0,0 +1,44 @@ +package taas + +import ( + "context" + "strconv" + "testing" + + "github.com/gophercloud/gophercloud/v2" + "github.com/gophercloud/gophercloud/v2/internal/acceptance/tools" + "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/extensions/taas/tapmirrors" + th "github.com/gophercloud/gophercloud/v2/testhelper" +) + +// CreateTapMirror will create a Tap Mirror with the specified portID and remoteIP. An error +// will be returned if the Tap Mirror could not be created. +func CreateTapMirror(t *testing.T, client *gophercloud.ServiceClient, portID string, remoteIP string) (*tapmirrors.TapMirror, error) { + mirrorName := tools.RandomString("TESTACC-", 8) + mirrorDescription := tools.RandomString("TESTACC-DESC-", 8) + mirrorDirectionIN := tools.RandomInt(1, 1000000) + t.Logf("Attempting to create tap mirror: %s", mirrorName) + + createopts := tapmirrors.CreateOpts{ + Name: mirrorName, + Description: mirrorDescription, + PortID: portID, + MirrorType: tapmirrors.MirrorTypeErspanv1, + RemoteIP: remoteIP, + Directions: tapmirrors.Directions{ + In: strconv.Itoa(mirrorDirectionIN), + Out: strconv.Itoa(mirrorDirectionIN + 1), + }, + } + + mirror, err := tapmirrors.Create(context.TODO(), client, createopts).Extract() + if err != nil { + return nil, err + } + + th.AssertEquals(t, mirror.Name, mirrorName) + th.AssertEquals(t, mirror.Description, mirrorDescription) + + t.Logf("Created Tap Mirror: %s", mirror.ID) + return mirror, nil +} diff --git a/internal/acceptance/openstack/networking/v2/extensions/taas/tapmirrors_test.go b/internal/acceptance/openstack/networking/v2/extensions/taas/tapmirrors_test.go new file mode 100644 index 0000000000..8fe74c0b51 --- /dev/null +++ b/internal/acceptance/openstack/networking/v2/extensions/taas/tapmirrors_test.go @@ -0,0 +1,39 @@ +//go:build acceptance || networking || taas + +package taas + +import ( + "testing" + + "github.com/gophercloud/gophercloud/v2/internal/acceptance/clients" + networking "github.com/gophercloud/gophercloud/v2/internal/acceptance/openstack/networking/v2" + "github.com/gophercloud/gophercloud/v2/internal/acceptance/tools" + th "github.com/gophercloud/gophercloud/v2/testhelper" +) + +func TestTapMirrorCRUD(t *testing.T) { + client, err := clients.NewNetworkV2Client() + th.AssertNoErr(t, err) + + // Skip these tests if we don't have the required extension + networking.RequireNeutronExtension(t, client, "taas") + + // Create Port + network, err := networking.CreateNetwork(t, client) + th.AssertNoErr(t, err) + defer networking.DeleteNetwork(t, client, network.ID) + + subnet, err := networking.CreateSubnet(t, client, network.ID) + th.AssertNoErr(t, err) + defer networking.DeleteSubnet(t, client, subnet.ID) + + port, err := networking.CreatePort(t, client, network.ID, subnet.ID) + th.AssertNoErr(t, err) + defer networking.DeletePort(t, client, port.ID) + + // Create Tap Mirror + mirror, err := CreateTapMirror(t, client, port.ID, port.FixedIPs[0].IPAddress) + th.AssertNoErr(t, err) + + tools.PrintResource(t, mirror) +} diff --git a/openstack/networking/v2/extensions/taas/tapmirrors/doc.go b/openstack/networking/v2/extensions/taas/tapmirrors/doc.go new file mode 100644 index 0000000000..481ad3db8e --- /dev/null +++ b/openstack/networking/v2/extensions/taas/tapmirrors/doc.go @@ -0,0 +1,23 @@ +/* +Package tapmirrors manages and retrieves Tap Mirrors in the OpenStack Networking Service. + +Example to Create a Tap Mirror + + createopts := tapmirrors.CreateOpts{ + Name: "tapmirror1", + Description: "Description of tapmirror1", + PortID: "a25290e9-1a54-4c26-a5b3-34458d122acc", + MirrorType: tapmirrors.MirrorTypeErspanv1, + RemoteIP: "192.168.54.217", + Directions: tapmirrors.Directions{ + In: "1", + Out: "2", + }, + } + + mirror, err := tapmirrors.Create(context.TODO(), networkClient, createopts).Extract() + if err != nil { + panic(err) + } +*/ +package tapmirrors diff --git a/openstack/networking/v2/extensions/taas/tapmirrors/requests.go b/openstack/networking/v2/extensions/taas/tapmirrors/requests.go new file mode 100644 index 0000000000..27662fc91e --- /dev/null +++ b/openstack/networking/v2/extensions/taas/tapmirrors/requests.go @@ -0,0 +1,67 @@ +package tapmirrors + +import ( + "context" + + "github.com/gophercloud/gophercloud/v2" +) + +type MirrorType string + +const ( + MirrorTypeErspanv1 MirrorType = "erspanv1" + MirrorTypeGre MirrorType = "gre" +) + +// CreateOptsBuilder allows extensions to add additional parameters to the +// Create request. +type CreateOptsBuilder interface { + ToTapMirrorCreateMap() (map[string]any, error) +} + +// CreateOpts contains all the values needed to create a new tap mirror +type CreateOpts struct { + // The name of the Tap Mirror. + Name string `json:"name"` + + // A human-readable description of the Tap Mirror. + Description string `json:"description,omitempty"` + + // The ID of the project. The caller must have an admin role in + // order to set this. Otherwise, this field is left unset + // and the caller will be the owner. + TenantID string `json:"tenant_id,omitempty"` + + // The Port ID of the Tap Mirror, this will be the source of the mirrored traffic, + // and this traffic will be tunneled into the GRE or ERSPAN v1 tunnel. + // The tunnel itself is not starting from this port. + PortID string `json:"port_id"` + + // The type of the mirroring, it can be gre or erspanv1. + MirrorType MirrorType `json:"mirror_type"` + + // The remote IP of the Tap Mirror, this will be the remote end of the GRE or ERSPAN v1 tunnel. + RemoteIP string `json:"remote_ip"` + + // A dictionary of direction and tunnel_id. Directions are IN and OUT. + // The values of the directions must be unique within the project and + // must be convertible to int. + Directions Directions `json:"directions"` +} + +// ToTapMirrorCreateMap casts a CreateOpts struct to a map. +func (opts CreateOpts) ToTapMirrorCreateMap() (map[string]any, error) { + return gophercloud.BuildRequestBody(opts, "tap_mirror") +} + +// Create accepts a CreateOpts struct and uses the values to create a new Tap Mirror. +func Create(ctx context.Context, c *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { + b, err := opts.ToTapMirrorCreateMap() + if err != nil { + r.Err = err + return + } + resp, err := c.Post(ctx, rootURL(c), b, &r.Body, nil) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} diff --git a/openstack/networking/v2/extensions/taas/tapmirrors/results.go b/openstack/networking/v2/extensions/taas/tapmirrors/results.go new file mode 100644 index 0000000000..51b1164e50 --- /dev/null +++ b/openstack/networking/v2/extensions/taas/tapmirrors/results.go @@ -0,0 +1,69 @@ +package tapmirrors + +import ( + "github.com/gophercloud/gophercloud/v2" +) + +// TapMirror represents a Tap Mirror of the networking service taas extension +type TapMirror struct { + // The ID of the Tap Mirror. + ID string `json:"id"` + + // The name of the Tap Mirror. + Name string `json:"name"` + + // A human-readable description of the Tap Mirror. + Description string `json:"description"` + + // The ID of the tenant. + TenantID string `json:"tenant_id"` + + // The ID of the project. + ProjectID string `json:"project_id"` + + // The Port ID of the Tap Mirror, this will be the source of the mirrored traffic, + // and this traffic will be tunneled into the GRE or ERSPAN v1 tunnel. + // The tunnel itself is not starting from this port. + PortID string `json:"port_id"` + + // The type of the mirroring, it can be gre or erspanv1. + MirrorType string `json:"mirror_type"` + + // The remote IP of the Tap Mirror, this will be the remote end of the GRE or ERSPAN v1 tunnel. + RemoteIP string `json:"remote_ip"` + + // A dictionary of direction and tunnel_id. Directions are In and Out. In specifies + // ingress traffic to the port will be mirrored, Out specifies egress traffic will be mirrored. + // The values of the directions are the identifiers of the ERSPAN or GRE session between + // the source and destination, these must be unique within the project and must be convertible to int. + Directions Directions `json:"directions"` +} + +type Directions struct { + // Unique identifier of the tunnel with ingress traffic. Must be convertible to int. + // Omit to not capture ingress traffic. + In string `json:"IN,omitempty"` + + // Unique identifier of the tunnel with egress traffic. Must be convertible to int. + // Omit to not capture egress traffic. + Out string `json:"OUT,omitempty"` +} + +type commonResult struct { + gophercloud.Result +} + +// Extract is a function that accepts a result and extracts a Tap Mirror. +func (r commonResult) Extract() (*TapMirror, error) { + var s struct { + TapMirror *TapMirror `json:"tap_mirror"` + } + err := r.ExtractInto(&s) + return s.TapMirror, err +} + +// CreateResult represents the result of a create operation. Call its Extract +// method to interpret it as a Tap Mirror. +type CreateResult struct { + commonResult +} diff --git a/openstack/networking/v2/extensions/taas/tapmirrors/testing/requests_test.go b/openstack/networking/v2/extensions/taas/tapmirrors/testing/requests_test.go new file mode 100644 index 0000000000..eac8d40c1e --- /dev/null +++ b/openstack/networking/v2/extensions/taas/tapmirrors/testing/requests_test.go @@ -0,0 +1,91 @@ +package testing + +import ( + "context" + "fmt" + "net/http" + "testing" + + fake "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/common" + "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/extensions/taas/tapmirrors" + + th "github.com/gophercloud/gophercloud/v2/testhelper" +) + +func TestCreate(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + fakeServer.Mux.HandleFunc("/v2.0/taas/tap_mirrors", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "POST") + th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "Content-Type", "application/json") + th.TestHeader(t, r, "Accept", "application/json") + th.TestJSONRequest(t, r, ` +{ + "tap_mirror": { + "description": "description", + "directions": { + "IN": "1", + "OUT": "2" + }, + "mirror_type": "erspanv1", + "name": "test", + "port_id": "a25290e9-1a54-4c26-a5b3-34458d122acc", + "remote_ip": "192.168.54.217" + } +} + `) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusCreated) + + fmt.Fprint(w, ` +{ + "tap_mirror": { + "id": "bd64a6e3-12b8-4092-a348-6fc7e27c298a", + "project_id": "6776f022d64443a898ee3fab89dc8c05", + "name": "test", + "description": "description", + "port_id": "a25290e9-1a54-4c26-a5b3-34458d122acc", + "directions": { + "IN": "1", + "OUT": "2" + }, + "remote_ip": "192.168.54.217", + "mirror_type": "erspanv1", + "tenant_id": "6776f022d64443a898ee3fab89dc8c05" + } +} + `) + }) + + options := tapmirrors.CreateOpts{ + Name: "test", + Description: "description", + PortID: "a25290e9-1a54-4c26-a5b3-34458d122acc", + MirrorType: tapmirrors.MirrorTypeErspanv1, + RemoteIP: "192.168.54.217", + Directions: tapmirrors.Directions{ + In: "1", + Out: "2", + }, + } + actual, err := tapmirrors.Create(context.TODO(), fake.ServiceClient(fakeServer), options).Extract() + th.AssertNoErr(t, err) + expected := tapmirrors.TapMirror{ + ID: "bd64a6e3-12b8-4092-a348-6fc7e27c298a", + TenantID: "6776f022d64443a898ee3fab89dc8c05", + ProjectID: "6776f022d64443a898ee3fab89dc8c05", + Name: "test", + Description: "description", + PortID: "a25290e9-1a54-4c26-a5b3-34458d122acc", + MirrorType: "erspanv1", + RemoteIP: "192.168.54.217", + Directions: tapmirrors.Directions{ + In: "1", + Out: "2", + }, + } + th.AssertDeepEquals(t, expected, *actual) +} diff --git a/openstack/networking/v2/extensions/taas/tapmirrors/urls.go b/openstack/networking/v2/extensions/taas/tapmirrors/urls.go new file mode 100644 index 0000000000..fc291c9573 --- /dev/null +++ b/openstack/networking/v2/extensions/taas/tapmirrors/urls.go @@ -0,0 +1,12 @@ +package tapmirrors + +import "github.com/gophercloud/gophercloud/v2" + +const ( + rootPath = "taas" + resourcePath = "tap_mirrors" +) + +func rootURL(c *gophercloud.ServiceClient) string { + return c.ServiceURL(rootPath, resourcePath) +} From d2a3e15ea96bbeef58a16fa759735b3ac19a23a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zden=C4=9Bk=20Vydra?= <80331839+vydrazde@users.noreply.github.com> Date: Thu, 7 Aug 2025 13:17:28 +0200 Subject: [PATCH 196/353] Add networking taas tapmirror list, get, update and delete --- .../networking/v2/extensions/taas/taas.go | 18 +- .../v2/extensions/taas/tapmirrors_test.go | 40 +++- .../v2/extensions/taas/tapmirrors/doc.go | 40 ++++ .../v2/extensions/taas/tapmirrors/requests.go | 88 ++++++++ .../v2/extensions/taas/tapmirrors/results.go | 60 ++++++ .../taas/tapmirrors/testing/requests_test.go | 200 ++++++++++++++++++ .../v2/extensions/taas/tapmirrors/urls.go | 4 + 7 files changed, 447 insertions(+), 3 deletions(-) diff --git a/internal/acceptance/openstack/networking/v2/extensions/taas/taas.go b/internal/acceptance/openstack/networking/v2/extensions/taas/taas.go index 026c5d2292..cbab622398 100644 --- a/internal/acceptance/openstack/networking/v2/extensions/taas/taas.go +++ b/internal/acceptance/openstack/networking/v2/extensions/taas/taas.go @@ -36,9 +36,23 @@ func CreateTapMirror(t *testing.T, client *gophercloud.ServiceClient, portID str return nil, err } - th.AssertEquals(t, mirror.Name, mirrorName) - th.AssertEquals(t, mirror.Description, mirrorDescription) + th.AssertEquals(t, mirrorName, mirror.Name) + th.AssertEquals(t, mirrorDescription, mirror.Description) t.Logf("Created Tap Mirror: %s", mirror.ID) return mirror, nil } + +// DeleteTapMirror will delete a Tap Mirror with a specified ID. A fatal error will +// occur if the delete was not successful. This works best when used as a +// deferred function. +func DeleteTapMirror(t *testing.T, client *gophercloud.ServiceClient, mirrorID string) { + t.Logf("Attempting to delete Tap Mirror: %s", mirrorID) + + err := tapmirrors.Delete(context.TODO(), client, mirrorID).ExtractErr() + if err != nil { + t.Fatalf("Unable to delete Tap Mirror %s: %v", mirrorID, err) + } + + t.Logf("Deleted Tap Mirror: %s", mirrorID) +} diff --git a/internal/acceptance/openstack/networking/v2/extensions/taas/tapmirrors_test.go b/internal/acceptance/openstack/networking/v2/extensions/taas/tapmirrors_test.go index 8fe74c0b51..b46d5ae581 100644 --- a/internal/acceptance/openstack/networking/v2/extensions/taas/tapmirrors_test.go +++ b/internal/acceptance/openstack/networking/v2/extensions/taas/tapmirrors_test.go @@ -3,14 +3,34 @@ package taas import ( + "context" "testing" "github.com/gophercloud/gophercloud/v2/internal/acceptance/clients" networking "github.com/gophercloud/gophercloud/v2/internal/acceptance/openstack/networking/v2" "github.com/gophercloud/gophercloud/v2/internal/acceptance/tools" + "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/extensions/taas/tapmirrors" th "github.com/gophercloud/gophercloud/v2/testhelper" ) +func TestTapMirrorList(t *testing.T) { + client, err := clients.NewNetworkV2Client() + th.AssertNoErr(t, err) + + // Skip these tests if we don't have the required extension + networking.RequireNeutronExtension(t, client, "taas") + + allPages, err := tapmirrors.List(client, nil).AllPages(context.TODO()) + th.AssertNoErr(t, err) + + allMirrors, err := tapmirrors.ExtractTapMirrors(allPages) + th.AssertNoErr(t, err) + + for _, mirror := range allMirrors { + tools.PrintResource(t, mirror) + } +} + func TestTapMirrorCRUD(t *testing.T) { client, err := clients.NewNetworkV2Client() th.AssertNoErr(t, err) @@ -31,9 +51,27 @@ func TestTapMirrorCRUD(t *testing.T) { th.AssertNoErr(t, err) defer networking.DeletePort(t, client, port.ID) - // Create Tap Mirror + // Create and defer Delete Tap Mirror mirror, err := CreateTapMirror(t, client, port.ID, port.FixedIPs[0].IPAddress) th.AssertNoErr(t, err) + defer DeleteTapMirror(t, client, mirror.ID) tools.PrintResource(t, mirror) + + // Get Tap Mirror + newmirror, err := tapmirrors.Get(context.TODO(), client, mirror.ID).Extract() + th.AssertNoErr(t, err) + th.AssertDeepEquals(t, mirror, newmirror) + + // Update Tap Mirror + updatedName := "TESTACC-updated name" + updatedDescription := "TESTACC-updated mirror description" + updateOpts := tapmirrors.UpdateOpts{ + Name: &updatedName, + Description: &updatedDescription, + } + updatedmirror, err := tapmirrors.Update(context.TODO(), client, mirror.ID, updateOpts).Extract() + th.AssertNoErr(t, err) + th.AssertEquals(t, updatedName, updatedmirror.Name) + th.AssertEquals(t, updatedDescription, updatedmirror.Description) } diff --git a/openstack/networking/v2/extensions/taas/tapmirrors/doc.go b/openstack/networking/v2/extensions/taas/tapmirrors/doc.go index 481ad3db8e..46e1d9966b 100644 --- a/openstack/networking/v2/extensions/taas/tapmirrors/doc.go +++ b/openstack/networking/v2/extensions/taas/tapmirrors/doc.go @@ -19,5 +19,45 @@ Example to Create a Tap Mirror if err != nil { panic(err) } + +Example to Show the details of a specific Tap Mirror by ID + + tapMirror, err := tapmirrors.Get(context.TODO(), networkClient, "f2b08c1e-aa81-4668-8ae1-1401bcb0576c").Extract() + if err != nil { + panic(err) + } + +Example to Delete a Tap Mirror + + err = tapmirrors.Delete(context.TODO(), networkClient, "5291b189-fd84-46e5-84bd-78f40c05d69c").ExtractErr() + if err != nil { + panic(err) + } + +Example to Update an Tap Mirror + + name := "updated name" + description := "updated description" + updateOps := tapmirrors.UpdateOpts{ + Description: &description, + Name: &name, + } + + updatedTapMirror, err := tapmirrors.Update(context.TODO(), networkClient, "5c561d9d-eaea-45f6-ae3e-08d1a7080828", updateOps).Extract() + if err != nil { + panic(err) + } + +Example to List Tap Mirrors + + allPages, err := tapmirrors.List(networkClient, nil).AllPages(context.TODO()) + if err != nil { + panic(err) + } + + allTapMirrors, err := tapmirrors.ExtractTapMirrors(allPages) + if err != nil { + panic(err) + } */ package tapmirrors diff --git a/openstack/networking/v2/extensions/taas/tapmirrors/requests.go b/openstack/networking/v2/extensions/taas/tapmirrors/requests.go index 27662fc91e..61887314b6 100644 --- a/openstack/networking/v2/extensions/taas/tapmirrors/requests.go +++ b/openstack/networking/v2/extensions/taas/tapmirrors/requests.go @@ -4,6 +4,7 @@ import ( "context" "github.com/gophercloud/gophercloud/v2" + "github.com/gophercloud/gophercloud/v2/pagination" ) type MirrorType string @@ -65,3 +66,90 @@ func Create(ctx context.Context, c *gophercloud.ServiceClient, opts CreateOptsBu _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) return } + +// Get retrieves a particular Tap Mirror on its ID. +func Get(ctx context.Context, c *gophercloud.ServiceClient, id string) (r GetResult) { + resp, err := c.Get(ctx, resourceURL(c, id), &r.Body, nil) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} + +// ListOptsBuilder allows extensions to add additional parameters to the +// List request. +type ListOptsBuilder interface { + ToTapMirrorListQuery() (string, error) +} + +// ListOpts allows the filtering of paginated collections through +// the API. Filtering is achieved by passing in struct field values that map to +// the Endpoint group attributes you want to see returned. +type ListOpts struct { + ProjectID string `q:"project_id"` + Name string `q:"name"` + Description string `q:"description"` + TenantID string `q:"tenant_id"` + PortID string `q:"port_id"` + MirrorType MirrorType `q:"mirror_type"` + RemoteIP string `q:"remote_ip"` +} + +// ToTapMirrorListQuery formats a ListOpts into a query string. +func (opts ListOpts) ToTapMirrorListQuery() (string, error) { + q, err := gophercloud.BuildQueryString(opts) + return q.String(), err +} + +// List returns a Pager which allows you to iterate over a collection of +// Tap Mirrors. It accepts a ListOpts struct, which allows you to filter +// the returned collection for greater efficiency. +func List(c *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { + url := rootURL(c) + if opts != nil { + query, err := opts.ToTapMirrorListQuery() + if err != nil { + return pagination.Pager{Err: err} + } + url += query + } + return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page { + return TapMirrorPage{pagination.LinkedPageBase{PageResult: r}} + }) +} + +// Delete will permanently delete a Tap Mirror based on its ID. +func Delete(ctx context.Context, c *gophercloud.ServiceClient, id string) (r DeleteResult) { + resp, err := c.Delete(ctx, resourceURL(c, id), nil) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} + +// UpdateOptsBuilder allows extensions to add additional parameters to the +// Update request. +type UpdateOptsBuilder interface { + ToTapMirrorUpdateMap() (map[string]any, error) +} + +// UpdateOpts contains the values used when updating a Tap Mirror. +type UpdateOpts struct { + Description *string `json:"description,omitempty"` + Name *string `json:"name,omitempty"` +} + +// ToTapMirrorUpdateMap casts an UpdateOpts struct to a map. +func (opts UpdateOpts) ToTapMirrorUpdateMap() (map[string]any, error) { + return gophercloud.BuildRequestBody(opts, "tap_mirror") +} + +// Update allows Tap Mirrors to be updated. +func Update(ctx context.Context, c *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) { + b, err := opts.ToTapMirrorUpdateMap() + if err != nil { + r.Err = err + return + } + resp, err := c.Put(ctx, resourceURL(c, id), b, &r.Body, &gophercloud.RequestOpts{ + OkCodes: []int{200}, + }) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} diff --git a/openstack/networking/v2/extensions/taas/tapmirrors/results.go b/openstack/networking/v2/extensions/taas/tapmirrors/results.go index 51b1164e50..fa83b876da 100644 --- a/openstack/networking/v2/extensions/taas/tapmirrors/results.go +++ b/openstack/networking/v2/extensions/taas/tapmirrors/results.go @@ -2,6 +2,7 @@ package tapmirrors import ( "github.com/gophercloud/gophercloud/v2" + "github.com/gophercloud/gophercloud/v2/pagination" ) // TapMirror represents a Tap Mirror of the networking service taas extension @@ -62,8 +63,67 @@ func (r commonResult) Extract() (*TapMirror, error) { return s.TapMirror, err } +// TapMirrorPage is the page returned by a pager when traversing over a +// collection of Policies. +type TapMirrorPage struct { + pagination.LinkedPageBase +} + +// NextPageURL is invoked when a paginated collection of Endpoint groups has +// reached the end of a page and the pager seeks to traverse over a new one. +// In order to do this, it needs to construct the next page's URL. +func (r TapMirrorPage) NextPageURL(endpointURL string) (string, error) { + var s struct { + Links []gophercloud.Link `json:"tap_mirrors_links"` + } + err := r.ExtractInto(&s) + if err != nil { + return "", err + } + return gophercloud.ExtractNextURL(s.Links) +} + +// IsEmpty checks whether an TapMirrorPage struct is empty. +func (r TapMirrorPage) IsEmpty() (bool, error) { + if r.StatusCode == 204 { + return true, nil + } + + is, err := ExtractTapMirrors(r) + return len(is) == 0, err +} + +// ExtractTapMirrors accepts a Page struct, specifically an TapMirrorPage struct, +// and extracts the elements into a slice of Tap Mirror structs. In other words, +// a generic collection is mapped into a relevant slice. +func ExtractTapMirrors(r pagination.Page) ([]TapMirror, error) { + var s struct { + TapMirrors []TapMirror `json:"tap_mirrors"` + } + err := (r.(TapMirrorPage)).ExtractInto(&s) + return s.TapMirrors, err +} + // CreateResult represents the result of a create operation. Call its Extract // method to interpret it as a Tap Mirror. type CreateResult struct { commonResult } + +// GetResult represents the result of a get operation. Call its Extract +// method to interpret it as a TapMirror. +type GetResult struct { + commonResult +} + +// DeleteResult represents the results of a Delete operation. Call its ExtractErr method +// to determine whether the operation succeeded or failed. +type DeleteResult struct { + gophercloud.ErrResult +} + +// UpdateResult represents the result of an update operation. Call its Extract method +// to interpret it as a TapMirror. +type UpdateResult struct { + commonResult +} diff --git a/openstack/networking/v2/extensions/taas/tapmirrors/testing/requests_test.go b/openstack/networking/v2/extensions/taas/tapmirrors/testing/requests_test.go index eac8d40c1e..f9819745ac 100644 --- a/openstack/networking/v2/extensions/taas/tapmirrors/testing/requests_test.go +++ b/openstack/networking/v2/extensions/taas/tapmirrors/testing/requests_test.go @@ -8,6 +8,7 @@ import ( fake "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/common" "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/extensions/taas/tapmirrors" + "github.com/gophercloud/gophercloud/v2/pagination" th "github.com/gophercloud/gophercloud/v2/testhelper" ) @@ -89,3 +90,202 @@ func TestCreate(t *testing.T) { } th.AssertDeepEquals(t, expected, *actual) } + +func TestGet(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + fakeServer.Mux.HandleFunc("/v2.0/taas/tap_mirrors/0837b488-f0e2-4689-99b3-e3ed531f9b10", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + + fmt.Fprint(w, ` +{ + "tap_mirror": { + "id": "0837b488-f0e2-4689-99b3-e3ed531f9b10", + "project_id": "6776f022d64443a898ee3fab89dc8c05", + "name": "test", + "description": "description", + "port_id": "a25290e9-1a54-4c26-a5b3-34458d122acc", + "directions": { + "IN": "1", + "OUT": "2" + }, + "remote_ip": "192.168.54.217", + "mirror_type": "erspanv1", + "tenant_id": "6776f022d64443a898ee3fab89dc8c05" + } +} + `) + }) + + actual, err := tapmirrors.Get(context.TODO(), fake.ServiceClient(fakeServer), "0837b488-f0e2-4689-99b3-e3ed531f9b10").Extract() + th.AssertNoErr(t, err) + expected := tapmirrors.TapMirror{ + ID: "0837b488-f0e2-4689-99b3-e3ed531f9b10", + TenantID: "6776f022d64443a898ee3fab89dc8c05", + ProjectID: "6776f022d64443a898ee3fab89dc8c05", + Name: "test", + Description: "description", + PortID: "a25290e9-1a54-4c26-a5b3-34458d122acc", + MirrorType: "erspanv1", + RemoteIP: "192.168.54.217", + Directions: tapmirrors.Directions{ + In: "1", + Out: "2", + }, + } + th.AssertDeepEquals(t, expected, *actual) +} + +func TestDelete(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + fakeServer.Mux.HandleFunc("/v2.0/taas/tap_mirrors/0837b488-f0e2-4689-99b3-e3ed531f9b10", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "DELETE") + th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + w.WriteHeader(http.StatusNoContent) + }) + + res := tapmirrors.Delete(context.TODO(), fake.ServiceClient(fakeServer), "0837b488-f0e2-4689-99b3-e3ed531f9b10") + th.AssertNoErr(t, res.Err) +} + +func TestList(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + fakeServer.Mux.HandleFunc("/v2.0/taas/tap_mirrors", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + + fmt.Fprint(w, ` +{ + "tap_mirrors": [ + { + "id": "0837b488-f0e2-4689-99b3-e3ed531f9b10", + "project_id": "6776f022d64443a898ee3fab89dc8c05", + "name": "test", + "description": "description", + "port_id": "a25290e9-1a54-4c26-a5b3-34458d122acc", + "directions": { + "IN": "1", + "OUT": "2" + }, + "remote_ip": "192.168.54.217", + "mirror_type": "erspanv1", + "tenant_id": "6776f022d64443a898ee3fab89dc8c05" + } + ] +} + `) + }) + + count := 0 + + err := tapmirrors.List(fake.ServiceClient(fakeServer), tapmirrors.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + count++ + actual, err := tapmirrors.ExtractTapMirrors(page) + if err != nil { + t.Errorf("Failed to extract members: %v", err) + return false, err + } + expected := []tapmirrors.TapMirror{ + { + ID: "0837b488-f0e2-4689-99b3-e3ed531f9b10", + TenantID: "6776f022d64443a898ee3fab89dc8c05", + ProjectID: "6776f022d64443a898ee3fab89dc8c05", + Name: "test", + Description: "description", + PortID: "a25290e9-1a54-4c26-a5b3-34458d122acc", + MirrorType: "erspanv1", + RemoteIP: "192.168.54.217", + Directions: tapmirrors.Directions{ + In: "1", + Out: "2", + }, + }, + } + th.CheckDeepEquals(t, expected, actual) + + return true, nil + }) + th.AssertNoErr(t, err) + + if count != 1 { + t.Errorf("Expected 1 page, got %d", count) + } +} + +func TestUpdate(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + fakeServer.Mux.HandleFunc("/v2.0/taas/tap_mirrors/d031da31-fb9b-4bd9-8d37-aaf04a12d45f", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "PUT") + th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "Content-Type", "application/json") + th.TestHeader(t, r, "Accept", "application/json") + th.TestJSONRequest(t, r, ` +{ + "tap_mirror": { + "name": "new name", + "description": "new description" + } +} + `) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + + fmt.Fprint(w, ` +{ + "tap_mirror": { + "id": "d031da31-fb9b-4bd9-8d37-aaf04a12d45f", + "project_id": "6776f022d64443a898ee3fab89dc8c05", + "name": "new name", + "description": "new description", + "port_id": "a25290e9-1a54-4c26-a5b3-34458d122acc", + "directions": { + "IN": "1", + "OUT": "2" + }, + "remote_ip": "192.168.54.217", + "mirror_type": "erspanv1", + "tenant_id": "6776f022d64443a898ee3fab89dc8c05" + } +} +`) + }) + + updatedName := "new name" + updatedDescription := "new description" + options := tapmirrors.UpdateOpts{ + Name: &updatedName, + Description: &updatedDescription, + } + + actual, err := tapmirrors.Update(context.TODO(), fake.ServiceClient(fakeServer), "d031da31-fb9b-4bd9-8d37-aaf04a12d45f", options).Extract() + th.AssertNoErr(t, err) + expected := tapmirrors.TapMirror{ + ID: "d031da31-fb9b-4bd9-8d37-aaf04a12d45f", + TenantID: "6776f022d64443a898ee3fab89dc8c05", + ProjectID: "6776f022d64443a898ee3fab89dc8c05", + Name: "new name", + Description: "new description", + PortID: "a25290e9-1a54-4c26-a5b3-34458d122acc", + MirrorType: "erspanv1", + RemoteIP: "192.168.54.217", + Directions: tapmirrors.Directions{ + In: "1", + Out: "2", + }, + } + th.AssertDeepEquals(t, expected, *actual) +} diff --git a/openstack/networking/v2/extensions/taas/tapmirrors/urls.go b/openstack/networking/v2/extensions/taas/tapmirrors/urls.go index fc291c9573..1b38a7cec3 100644 --- a/openstack/networking/v2/extensions/taas/tapmirrors/urls.go +++ b/openstack/networking/v2/extensions/taas/tapmirrors/urls.go @@ -10,3 +10,7 @@ const ( func rootURL(c *gophercloud.ServiceClient) string { return c.ServiceURL(rootPath, resourcePath) } + +func resourceURL(c *gophercloud.ServiceClient, id string) string { + return c.ServiceURL(rootPath, resourcePath, id) +} From 6c3339ad0701ed57cf72baa0047daf4f66de4e1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zden=C4=9Bk=20Vydra?= <80331839+vydrazde@users.noreply.github.com> Date: Fri, 8 Aug 2025 14:00:14 +0200 Subject: [PATCH 197/353] Change Direction value type to int --- .../networking/v2/extensions/taas/taas.go | 5 ++--- .../v2/extensions/taas/tapmirrors/requests.go | 7 ++++--- .../v2/extensions/taas/tapmirrors/results.go | 14 ++++++------- .../taas/tapmirrors/testing/requests_test.go | 20 +++++++++---------- 4 files changed, 23 insertions(+), 23 deletions(-) diff --git a/internal/acceptance/openstack/networking/v2/extensions/taas/taas.go b/internal/acceptance/openstack/networking/v2/extensions/taas/taas.go index cbab622398..3d4f3979f4 100644 --- a/internal/acceptance/openstack/networking/v2/extensions/taas/taas.go +++ b/internal/acceptance/openstack/networking/v2/extensions/taas/taas.go @@ -2,7 +2,6 @@ package taas import ( "context" - "strconv" "testing" "github.com/gophercloud/gophercloud/v2" @@ -26,8 +25,8 @@ func CreateTapMirror(t *testing.T, client *gophercloud.ServiceClient, portID str MirrorType: tapmirrors.MirrorTypeErspanv1, RemoteIP: remoteIP, Directions: tapmirrors.Directions{ - In: strconv.Itoa(mirrorDirectionIN), - Out: strconv.Itoa(mirrorDirectionIN + 1), + In: mirrorDirectionIN, + Out: mirrorDirectionIN + 1, }, } diff --git a/openstack/networking/v2/extensions/taas/tapmirrors/requests.go b/openstack/networking/v2/extensions/taas/tapmirrors/requests.go index 61887314b6..7b236374bd 100644 --- a/openstack/networking/v2/extensions/taas/tapmirrors/requests.go +++ b/openstack/networking/v2/extensions/taas/tapmirrors/requests.go @@ -44,9 +44,10 @@ type CreateOpts struct { // The remote IP of the Tap Mirror, this will be the remote end of the GRE or ERSPAN v1 tunnel. RemoteIP string `json:"remote_ip"` - // A dictionary of direction and tunnel_id. Directions are IN and OUT. - // The values of the directions must be unique within the project and - // must be convertible to int. + // A dictionary of direction and tunnel_id. Directions are In and Out. In specifies + // ingress traffic to the port will be mirrored, Out specifies egress traffic will be mirrored. + // The values of the directions are the identifiers of the ERSPAN or GRE session between + // the source and destination, these must be unique within the project. Directions Directions `json:"directions"` } diff --git a/openstack/networking/v2/extensions/taas/tapmirrors/results.go b/openstack/networking/v2/extensions/taas/tapmirrors/results.go index fa83b876da..f6ca8b1aa0 100644 --- a/openstack/networking/v2/extensions/taas/tapmirrors/results.go +++ b/openstack/networking/v2/extensions/taas/tapmirrors/results.go @@ -36,18 +36,18 @@ type TapMirror struct { // A dictionary of direction and tunnel_id. Directions are In and Out. In specifies // ingress traffic to the port will be mirrored, Out specifies egress traffic will be mirrored. // The values of the directions are the identifiers of the ERSPAN or GRE session between - // the source and destination, these must be unique within the project and must be convertible to int. + // the source and destination, these must be unique within the project. Directions Directions `json:"directions"` } type Directions struct { - // Unique identifier of the tunnel with ingress traffic. Must be convertible to int. - // Omit to not capture ingress traffic. - In string `json:"IN,omitempty"` + // Unique identifier of the tunnel with ingress traffic. Omit to not capture ingress traffic. + // Encoded as JSON string to be compatible with python tap-as-a-service client. + In int `json:"IN,omitempty,string"` - // Unique identifier of the tunnel with egress traffic. Must be convertible to int. - // Omit to not capture egress traffic. - Out string `json:"OUT,omitempty"` + // Unique identifier of the tunnel with egress traffic. Omit to not capture egress traffic. + // Encoded as JSON string to be compatible with python tap-as-a-service client. + Out int `json:"OUT,omitempty,string"` } type commonResult struct { diff --git a/openstack/networking/v2/extensions/taas/tapmirrors/testing/requests_test.go b/openstack/networking/v2/extensions/taas/tapmirrors/testing/requests_test.go index f9819745ac..7d98c403b5 100644 --- a/openstack/networking/v2/extensions/taas/tapmirrors/testing/requests_test.go +++ b/openstack/networking/v2/extensions/taas/tapmirrors/testing/requests_test.go @@ -68,8 +68,8 @@ func TestCreate(t *testing.T) { MirrorType: tapmirrors.MirrorTypeErspanv1, RemoteIP: "192.168.54.217", Directions: tapmirrors.Directions{ - In: "1", - Out: "2", + In: 1, + Out: 2, }, } actual, err := tapmirrors.Create(context.TODO(), fake.ServiceClient(fakeServer), options).Extract() @@ -84,8 +84,8 @@ func TestCreate(t *testing.T) { MirrorType: "erspanv1", RemoteIP: "192.168.54.217", Directions: tapmirrors.Directions{ - In: "1", - Out: "2", + In: 1, + Out: 2, }, } th.AssertDeepEquals(t, expected, *actual) @@ -134,8 +134,8 @@ func TestGet(t *testing.T) { MirrorType: "erspanv1", RemoteIP: "192.168.54.217", Directions: tapmirrors.Directions{ - In: "1", - Out: "2", + In: 1, + Out: 2, }, } th.AssertDeepEquals(t, expected, *actual) @@ -207,8 +207,8 @@ func TestList(t *testing.T) { MirrorType: "erspanv1", RemoteIP: "192.168.54.217", Directions: tapmirrors.Directions{ - In: "1", - Out: "2", + In: 1, + Out: 2, }, }, } @@ -283,8 +283,8 @@ func TestUpdate(t *testing.T) { MirrorType: "erspanv1", RemoteIP: "192.168.54.217", Directions: tapmirrors.Directions{ - In: "1", - Out: "2", + In: 1, + Out: 2, }, } th.AssertDeepEquals(t, expected, *actual) From d37173945f4757b28172bd19b1368afffea33495 Mon Sep 17 00:00:00 2001 From: Amir Aslan Aslan Date: Sat, 26 Jul 2025 14:34:06 +0330 Subject: [PATCH 198/353] fix: correct comment for PortRangeMax in CreateOpts to specify ICMP code --- openstack/networking/v2/extensions/security/rules/requests.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openstack/networking/v2/extensions/security/rules/requests.go b/openstack/networking/v2/extensions/security/rules/requests.go index 703007b7bb..edd253f037 100644 --- a/openstack/networking/v2/extensions/security/rules/requests.go +++ b/openstack/networking/v2/extensions/security/rules/requests.go @@ -125,7 +125,7 @@ type CreateOpts struct { // The maximum port number in the range that is matched by the security group // rule. The PortRangeMin attribute constrains the PortRangeMax attribute. If - // the protocol is ICMP, this value must be an ICMP type. + // the protocol is ICMP, this value must be an ICMP code. PortRangeMax int `json:"port_range_max,omitempty"` // The minimum port number in the range that is matched by the security group From 03e62626ba537f2a2d1b561e46fc22f51963f4a5 Mon Sep 17 00:00:00 2001 From: Thomas Morin Date: Wed, 13 Aug 2025 15:06:13 +0200 Subject: [PATCH 199/353] Networking v2: Support two time formats for subnet, router, SG rules (#3492) --- .../v2/extensions/layer3/routers/results.go | 42 +++++++++++++++++- .../layer3/routers/testing/requests_test.go | 8 ++++ .../v2/extensions/security/rules/results.go | 43 ++++++++++++++++++- .../security/rules/testing/requests_test.go | 13 ++++++ openstack/networking/v2/subnets/results.go | 43 ++++++++++++++++++- .../v2/subnets/testing/fixtures_test.go | 10 +++++ 6 files changed, 153 insertions(+), 6 deletions(-) diff --git a/openstack/networking/v2/extensions/layer3/routers/results.go b/openstack/networking/v2/extensions/layer3/routers/results.go index 25b29c2755..d657160ba2 100644 --- a/openstack/networking/v2/extensions/layer3/routers/results.go +++ b/openstack/networking/v2/extensions/layer3/routers/results.go @@ -82,10 +82,48 @@ type Router struct { RevisionNumber int `json:"revision_number"` // Timestamp when the router was created - CreatedAt time.Time `json:"created_at"` + CreatedAt time.Time `json:"-"` // Timestamp when the router was last updated - UpdatedAt time.Time `json:"updated_at"` + UpdatedAt time.Time `json:"-"` +} + +func (r *Router) UnmarshalJSON(b []byte) error { + type tmp Router + + // Support for older neutron time format + var s1 struct { + tmp + CreatedAt gophercloud.JSONRFC3339NoZ `json:"created_at"` + UpdatedAt gophercloud.JSONRFC3339NoZ `json:"updated_at"` + } + + err := json.Unmarshal(b, &s1) + if err == nil { + *r = Router(s1.tmp) + r.CreatedAt = time.Time(s1.CreatedAt) + r.UpdatedAt = time.Time(s1.UpdatedAt) + + return nil + } + + // Support for newer neutron time format + var s2 struct { + tmp + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + } + + err = json.Unmarshal(b, &s2) + if err != nil { + return err + } + + *r = Router(s2.tmp) + r.CreatedAt = time.Time(s2.CreatedAt) + r.UpdatedAt = time.Time(s2.UpdatedAt) + + return nil } // RouterPage is the page returned by a pager when traversing over a diff --git a/openstack/networking/v2/extensions/layer3/routers/testing/requests_test.go b/openstack/networking/v2/extensions/layer3/routers/testing/requests_test.go index f66dda4e06..f6cd2c0bbd 100644 --- a/openstack/networking/v2/extensions/layer3/routers/testing/requests_test.go +++ b/openstack/networking/v2/extensions/layer3/routers/testing/requests_test.go @@ -34,6 +34,8 @@ func TestList(t *testing.T) { "admin_state_up": true, "tenant_id": "6b96ff0cb17a4b859e1e575d221683d3", "distributed": false, + "created_at": "2017-12-28T07:21:40Z", + "updated_at": "2017-12-28T07:21:40Z", "id": "7177abc4-5ae9-4bb7-b0d4-89e94a4abf3b" }, { @@ -45,6 +47,8 @@ func TestList(t *testing.T) { "admin_state_up": true, "tenant_id": "33a40233088643acb66ff6eb0ebea679", "distributed": false, + "created_at": "2017-12-28T07:21:40", + "updated_at": "2017-12-28T07:21:40", "id": "a9254bdb-2613-4a13-ac4c-adc581fba50d" }, { @@ -86,6 +90,8 @@ func TestList(t *testing.T) { Distributed: false, Name: "second_routers", ID: "7177abc4-5ae9-4bb7-b0d4-89e94a4abf3b", + CreatedAt: time.Date(2017, 12, 28, 07, 21, 40, 0, time.UTC), + UpdatedAt: time.Date(2017, 12, 28, 07, 21, 40, 0, time.UTC), TenantID: "6b96ff0cb17a4b859e1e575d221683d3", }, { @@ -95,6 +101,8 @@ func TestList(t *testing.T) { Distributed: false, Name: "router1", ID: "a9254bdb-2613-4a13-ac4c-adc581fba50d", + CreatedAt: time.Date(2017, 12, 28, 07, 21, 40, 0, time.UTC), + UpdatedAt: time.Date(2017, 12, 28, 07, 21, 40, 0, time.UTC), TenantID: "33a40233088643acb66ff6eb0ebea679", }, { diff --git a/openstack/networking/v2/extensions/security/rules/results.go b/openstack/networking/v2/extensions/security/rules/results.go index 2d528bd284..03696ac203 100644 --- a/openstack/networking/v2/extensions/security/rules/results.go +++ b/openstack/networking/v2/extensions/security/rules/results.go @@ -1,6 +1,7 @@ package rules import ( + "encoding/json" "time" "github.com/gophercloud/gophercloud/v2" @@ -67,10 +68,48 @@ type SecGroupRule struct { RevisionNumber int `json:"revision_number"` // Timestamp when the rule was created - CreatedAt time.Time `json:"created_at"` + CreatedAt time.Time `json:"-"` // Timestamp when the rule was last updated - UpdatedAt time.Time `json:"updated_at"` + UpdatedAt time.Time `json:"-"` +} + +func (r *SecGroupRule) UnmarshalJSON(b []byte) error { + type tmp SecGroupRule + + // Support for older neutron time format + var s1 struct { + tmp + CreatedAt gophercloud.JSONRFC3339NoZ `json:"created_at"` + UpdatedAt gophercloud.JSONRFC3339NoZ `json:"updated_at"` + } + + err := json.Unmarshal(b, &s1) + if err == nil { + *r = SecGroupRule(s1.tmp) + r.CreatedAt = time.Time(s1.CreatedAt) + r.UpdatedAt = time.Time(s1.UpdatedAt) + + return nil + } + + // Support for newer neutron time format + var s2 struct { + tmp + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + } + + err = json.Unmarshal(b, &s2) + if err != nil { + return err + } + + *r = SecGroupRule(s2.tmp) + r.CreatedAt = time.Time(s2.CreatedAt) + r.UpdatedAt = time.Time(s2.UpdatedAt) + + return nil } // SecGroupRulePage is the page returned by a pager when traversing over a diff --git a/openstack/networking/v2/extensions/security/rules/testing/requests_test.go b/openstack/networking/v2/extensions/security/rules/testing/requests_test.go index 256ce3d858..a3b504a75b 100644 --- a/openstack/networking/v2/extensions/security/rules/testing/requests_test.go +++ b/openstack/networking/v2/extensions/security/rules/testing/requests_test.go @@ -5,6 +5,7 @@ import ( "fmt" "net/http" "testing" + "time" fake "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/common" "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/extensions/security/rules" @@ -35,6 +36,8 @@ func TestList(t *testing.T) { "protocol": null, "remote_group_id": null, "remote_ip_prefix": null, + "created_at": "2017-12-28T07:21:40Z", + "updated_at": "2017-12-28T07:21:40Z", "security_group_id": "85cc3048-abc3-43cc-89b3-377341426ac5", "tenant_id": "e4f50856753b4dc6afee5fa6b9b6c550" }, @@ -47,6 +50,8 @@ func TestList(t *testing.T) { "protocol": null, "remote_group_id": null, "remote_ip_prefix": null, + "created_at": "2017-12-28T07:21:40", + "updated_at": "2017-12-28T07:21:40", "security_group_id": "85cc3048-abc3-43cc-89b3-377341426ac5", "tenant_id": "e4f50856753b4dc6afee5fa6b9b6c550" } @@ -76,6 +81,8 @@ func TestList(t *testing.T) { Protocol: "", RemoteGroupID: "", RemoteIPPrefix: "", + CreatedAt: time.Date(2017, 12, 28, 07, 21, 40, 0, time.UTC), + UpdatedAt: time.Date(2017, 12, 28, 07, 21, 40, 0, time.UTC), SecGroupID: "85cc3048-abc3-43cc-89b3-377341426ac5", TenantID: "e4f50856753b4dc6afee5fa6b9b6c550", }, @@ -88,6 +95,8 @@ func TestList(t *testing.T) { Protocol: "", RemoteGroupID: "", RemoteIPPrefix: "", + CreatedAt: time.Date(2017, 12, 28, 07, 21, 40, 0, time.UTC), + UpdatedAt: time.Date(2017, 12, 28, 07, 21, 40, 0, time.UTC), SecGroupID: "85cc3048-abc3-43cc-89b3-377341426ac5", TenantID: "e4f50856753b4dc6afee5fa6b9b6c550", }, @@ -361,6 +370,8 @@ func TestGet(t *testing.T) { "protocol": null, "remote_group_id": null, "remote_ip_prefix": null, + "created_at": "2017-12-28T07:21:40Z", + "updated_at": "2017-12-28T07:21:40Z", "security_group_id": "85cc3048-abc3-43cc-89b3-377341426ac5", "tenant_id": "e4f50856753b4dc6afee5fa6b9b6c550" } @@ -379,6 +390,8 @@ func TestGet(t *testing.T) { th.AssertEquals(t, "", sr.Protocol) th.AssertEquals(t, "", sr.RemoteGroupID) th.AssertEquals(t, "", sr.RemoteIPPrefix) + th.AssertEquals(t, time.Date(2017, 12, 28, 07, 21, 40, 0, time.UTC), sr.UpdatedAt) + th.AssertEquals(t, time.Date(2017, 12, 28, 07, 21, 40, 0, time.UTC), sr.CreatedAt) th.AssertEquals(t, "85cc3048-abc3-43cc-89b3-377341426ac5", sr.SecGroupID) th.AssertEquals(t, "e4f50856753b4dc6afee5fa6b9b6c550", sr.TenantID) } diff --git a/openstack/networking/v2/subnets/results.go b/openstack/networking/v2/subnets/results.go index 9d9e751c97..4f0aa8408d 100644 --- a/openstack/networking/v2/subnets/results.go +++ b/openstack/networking/v2/subnets/results.go @@ -1,6 +1,7 @@ package subnets import ( + "encoding/json" "time" "github.com/gophercloud/gophercloud/v2" @@ -129,10 +130,48 @@ type Subnet struct { SegmentID string `json:"segment_id"` // Timestamp when the subnet was created - CreatedAt time.Time `json:"created_at"` + CreatedAt time.Time `json:"-"` // Timestamp when the subnet was last updated - UpdatedAt time.Time `json:"updated_at"` + UpdatedAt time.Time `json:"-"` +} + +func (r *Subnet) UnmarshalJSON(b []byte) error { + type tmp Subnet + + // Support for older neutron time format + var s1 struct { + tmp + CreatedAt gophercloud.JSONRFC3339NoZ `json:"created_at"` + UpdatedAt gophercloud.JSONRFC3339NoZ `json:"updated_at"` + } + + err := json.Unmarshal(b, &s1) + if err == nil { + *r = Subnet(s1.tmp) + r.CreatedAt = time.Time(s1.CreatedAt) + r.UpdatedAt = time.Time(s1.UpdatedAt) + + return nil + } + + // Support for newer neutron time format + var s2 struct { + tmp + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + } + + err = json.Unmarshal(b, &s2) + if err != nil { + return err + } + + *r = Subnet(s2.tmp) + r.CreatedAt = time.Time(s2.CreatedAt) + r.UpdatedAt = time.Time(s2.UpdatedAt) + + return nil } // SubnetPage is the page returned by a pager when traversing over a collection diff --git a/openstack/networking/v2/subnets/testing/fixtures_test.go b/openstack/networking/v2/subnets/testing/fixtures_test.go index a44f1cc77e..ebb005f62d 100644 --- a/openstack/networking/v2/subnets/testing/fixtures_test.go +++ b/openstack/networking/v2/subnets/testing/fixtures_test.go @@ -1,6 +1,8 @@ package testing import ( + "time" + "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/subnets" ) @@ -24,6 +26,8 @@ const SubnetListResult = ` "ip_version": 4, "gateway_ip": "10.0.0.1", "cidr": "10.0.0.0/24", + "created_at": "2017-12-28T07:21:40Z", + "updated_at": "2017-12-28T07:21:40Z", "id": "08eae331-0402-425a-923c-34f7cfe39c1b" }, { @@ -43,6 +47,8 @@ const SubnetListResult = ` "ip_version": 4, "gateway_ip": "192.0.0.1", "cidr": "192.0.0.0/8", + "created_at": "2017-12-28T07:21:40", + "updated_at": "2017-12-28T07:21:40", "id": "54d6f61d-db07-451c-9ab3-b9609b6b6f0b" }, { @@ -104,6 +110,8 @@ var Subnet1 = subnets.Subnet{ IPVersion: 4, GatewayIP: "10.0.0.1", CIDR: "10.0.0.0/24", + CreatedAt: time.Date(2017, 12, 28, 07, 21, 40, 0, time.UTC), + UpdatedAt: time.Date(2017, 12, 28, 07, 21, 40, 0, time.UTC), ID: "08eae331-0402-425a-923c-34f7cfe39c1b", } @@ -125,6 +133,8 @@ var Subnet2 = subnets.Subnet{ IPVersion: 4, GatewayIP: "192.0.0.1", CIDR: "192.0.0.0/8", + CreatedAt: time.Date(2017, 12, 28, 07, 21, 40, 0, time.UTC), + UpdatedAt: time.Date(2017, 12, 28, 07, 21, 40, 0, time.UTC), ID: "54d6f61d-db07-451c-9ab3-b9609b6b6f0b", } From 21c9bf4831ee48b28bf56abfbdb895ca03cab3dc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Aug 2025 18:04:35 +0000 Subject: [PATCH 200/353] build(deps): bump actions/checkout from 4 to 5 Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 5. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '5' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/codeql-analysis.yaml | 2 +- .github/workflows/ensure-labels.yaml | 2 +- .github/workflows/functional-baremetal.yaml | 2 +- .github/workflows/functional-basic.yaml | 2 +- .github/workflows/functional-blockstorage.yaml | 2 +- .github/workflows/functional-compute.yaml | 2 +- .github/workflows/functional-containerinfra.yaml | 2 +- .github/workflows/functional-dns.yaml | 2 +- .github/workflows/functional-fwaas_v2.yaml | 2 +- .github/workflows/functional-identity.yaml | 2 +- .github/workflows/functional-image.yaml | 2 +- .github/workflows/functional-keymanager.yaml | 2 +- .github/workflows/functional-loadbalancer.yaml | 2 +- .github/workflows/functional-messaging.yaml | 2 +- .github/workflows/functional-networking.yaml | 2 +- .github/workflows/functional-objectstorage.yaml | 2 +- .github/workflows/functional-orchestration.yaml | 2 +- .github/workflows/functional-placement.yaml | 2 +- .github/workflows/functional-sharedfilesystems.yaml | 2 +- .github/workflows/functional-workflow.yaml | 2 +- .github/workflows/label-pr.yaml | 2 +- .github/workflows/lint.yaml | 2 +- .github/workflows/unit.yaml | 2 +- 23 files changed, 23 insertions(+), 23 deletions(-) diff --git a/.github/workflows/codeql-analysis.yaml b/.github/workflows/codeql-analysis.yaml index 8efeaf761c..58952951c6 100644 --- a/.github/workflows/codeql-analysis.yaml +++ b/.github/workflows/codeql-analysis.yaml @@ -18,7 +18,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Setup Go uses: actions/setup-go@v5 diff --git a/.github/workflows/ensure-labels.yaml b/.github/workflows/ensure-labels.yaml index 4528512c0f..fbabe2bf6d 100644 --- a/.github/workflows/ensure-labels.yaml +++ b/.github/workflows/ensure-labels.yaml @@ -10,7 +10,7 @@ jobs: ensure: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: micnncim/action-label-syncer@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/functional-baremetal.yaml b/.github/workflows/functional-baremetal.yaml index a1ec826ff8..7f5c05bd5c 100644 --- a/.github/workflows/functional-baremetal.yaml +++ b/.github/workflows/functional-baremetal.yaml @@ -32,7 +32,7 @@ jobs: name: Ironic on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Work around broken dnsmasq run: sudo apt-get purge -y dnsmasq-base - name: Deploy devstack diff --git a/.github/workflows/functional-basic.yaml b/.github/workflows/functional-basic.yaml index b33d4c34bd..9ee87e2ed6 100644 --- a/.github/workflows/functional-basic.yaml +++ b/.github/workflows/functional-basic.yaml @@ -34,7 +34,7 @@ jobs: name: basic tests on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Deploy devstack uses: gophercloud/devstack-action@v0.19 with: diff --git a/.github/workflows/functional-blockstorage.yaml b/.github/workflows/functional-blockstorage.yaml index bccf753042..7443025963 100644 --- a/.github/workflows/functional-blockstorage.yaml +++ b/.github/workflows/functional-blockstorage.yaml @@ -32,7 +32,7 @@ jobs: name: Cinder on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Deploy devstack uses: gophercloud/devstack-action@v0.19 with: diff --git a/.github/workflows/functional-compute.yaml b/.github/workflows/functional-compute.yaml index abe668f48c..16dae9d6ca 100644 --- a/.github/workflows/functional-compute.yaml +++ b/.github/workflows/functional-compute.yaml @@ -32,7 +32,7 @@ jobs: name: Nova on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Deploy devstack uses: gophercloud/devstack-action@v0.19 with: diff --git a/.github/workflows/functional-containerinfra.yaml b/.github/workflows/functional-containerinfra.yaml index fec6fef6fe..73386e5f52 100644 --- a/.github/workflows/functional-containerinfra.yaml +++ b/.github/workflows/functional-containerinfra.yaml @@ -56,7 +56,7 @@ jobs: name: Magnum on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Deploy devstack uses: gophercloud/devstack-action@v0.19 with: diff --git a/.github/workflows/functional-dns.yaml b/.github/workflows/functional-dns.yaml index 1e98ecb736..cfeaddfb4f 100644 --- a/.github/workflows/functional-dns.yaml +++ b/.github/workflows/functional-dns.yaml @@ -38,7 +38,7 @@ jobs: name: Designate on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Deploy devstack uses: gophercloud/devstack-action@v0.19 with: diff --git a/.github/workflows/functional-fwaas_v2.yaml b/.github/workflows/functional-fwaas_v2.yaml index 0d03e07567..c313eafbba 100644 --- a/.github/workflows/functional-fwaas_v2.yaml +++ b/.github/workflows/functional-fwaas_v2.yaml @@ -36,7 +36,7 @@ jobs: name: FWaaS_v2 on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Create additional neutron policies run: | mkdir /tmp/neutron-policies diff --git a/.github/workflows/functional-identity.yaml b/.github/workflows/functional-identity.yaml index 93a39ee1e7..fab19ff408 100644 --- a/.github/workflows/functional-identity.yaml +++ b/.github/workflows/functional-identity.yaml @@ -32,7 +32,7 @@ jobs: name: Keystone on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Deploy devstack uses: gophercloud/devstack-action@v0.19 with: diff --git a/.github/workflows/functional-image.yaml b/.github/workflows/functional-image.yaml index 82434f9ea9..32ca290bc6 100644 --- a/.github/workflows/functional-image.yaml +++ b/.github/workflows/functional-image.yaml @@ -32,7 +32,7 @@ jobs: name: Glance on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Deploy devstack uses: gophercloud/devstack-action@v0.19 with: diff --git a/.github/workflows/functional-keymanager.yaml b/.github/workflows/functional-keymanager.yaml index 61ed8c4172..ac3bd66fa0 100644 --- a/.github/workflows/functional-keymanager.yaml +++ b/.github/workflows/functional-keymanager.yaml @@ -44,7 +44,7 @@ jobs: name: Barbican on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Deploy devstack uses: gophercloud/devstack-action@v0.19 with: diff --git a/.github/workflows/functional-loadbalancer.yaml b/.github/workflows/functional-loadbalancer.yaml index acd1af2ff5..c8dbbc4dc8 100644 --- a/.github/workflows/functional-loadbalancer.yaml +++ b/.github/workflows/functional-loadbalancer.yaml @@ -38,7 +38,7 @@ jobs: name: Octavia on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Deploy devstack uses: gophercloud/devstack-action@v0.19 with: diff --git a/.github/workflows/functional-messaging.yaml b/.github/workflows/functional-messaging.yaml index 456c73fda7..790e756985 100644 --- a/.github/workflows/functional-messaging.yaml +++ b/.github/workflows/functional-messaging.yaml @@ -32,7 +32,7 @@ jobs: name: Zaqar on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Deploy devstack uses: gophercloud/devstack-action@v0.19 with: diff --git a/.github/workflows/functional-networking.yaml b/.github/workflows/functional-networking.yaml index 92547ac6a5..126d1882cc 100644 --- a/.github/workflows/functional-networking.yaml +++ b/.github/workflows/functional-networking.yaml @@ -32,7 +32,7 @@ jobs: name: Neutron on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Create additional neutron policies run: | mkdir /tmp/neutron-policies diff --git a/.github/workflows/functional-objectstorage.yaml b/.github/workflows/functional-objectstorage.yaml index e5b2ceea64..7f6947ae07 100644 --- a/.github/workflows/functional-objectstorage.yaml +++ b/.github/workflows/functional-objectstorage.yaml @@ -32,7 +32,7 @@ jobs: name: Swift on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Deploy devstack uses: gophercloud/devstack-action@v0.19 with: diff --git a/.github/workflows/functional-orchestration.yaml b/.github/workflows/functional-orchestration.yaml index 842f170e1e..d31aa35d5a 100644 --- a/.github/workflows/functional-orchestration.yaml +++ b/.github/workflows/functional-orchestration.yaml @@ -32,7 +32,7 @@ jobs: name: Heat on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Deploy devstack uses: gophercloud/devstack-action@v0.19 with: diff --git a/.github/workflows/functional-placement.yaml b/.github/workflows/functional-placement.yaml index ed4612c4e0..b8b0476891 100644 --- a/.github/workflows/functional-placement.yaml +++ b/.github/workflows/functional-placement.yaml @@ -32,7 +32,7 @@ jobs: name: Placement on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Deploy devstack uses: gophercloud/devstack-action@v0.19 with: diff --git a/.github/workflows/functional-sharedfilesystems.yaml b/.github/workflows/functional-sharedfilesystems.yaml index 1d5b1432c0..e3c07970f2 100644 --- a/.github/workflows/functional-sharedfilesystems.yaml +++ b/.github/workflows/functional-sharedfilesystems.yaml @@ -38,7 +38,7 @@ jobs: name: Manila on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Deploy devstack uses: gophercloud/devstack-action@v0.19 with: diff --git a/.github/workflows/functional-workflow.yaml b/.github/workflows/functional-workflow.yaml index b2ce2e368f..3dd7831cd5 100644 --- a/.github/workflows/functional-workflow.yaml +++ b/.github/workflows/functional-workflow.yaml @@ -36,7 +36,7 @@ jobs: name: Mistral on Deploy OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Deploy devstack uses: gophercloud/devstack-action@v0.19 with: diff --git a/.github/workflows/label-pr.yaml b/.github/workflows/label-pr.yaml index 1a2419c7cf..fbb693113a 100644 --- a/.github/workflows/label-pr.yaml +++ b/.github/workflows/label-pr.yaml @@ -10,7 +10,7 @@ jobs: semver: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: fetch-depth: 0 ref: ${{ github.event.pull_request.head.sha }} diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index be44ea86bc..4a627ec507 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -9,7 +9,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout Gophercloud - uses: actions/checkout@v4 + uses: actions/checkout@v5 - uses: actions/setup-go@v5 with: go-version: '1' diff --git a/.github/workflows/unit.yaml b/.github/workflows/unit.yaml index ae3b2f0059..c462a6dd27 100644 --- a/.github/workflows/unit.yaml +++ b/.github/workflows/unit.yaml @@ -14,7 +14,7 @@ jobs: fail-fast: false steps: - name: Checkout Gophercloud - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Setup Go uses: actions/setup-go@v5 with: From 5c06870169339a1c35d5ecd74e23f88499ee86c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Andr=C3=A9?= Date: Thu, 14 Aug 2025 09:43:08 +0200 Subject: [PATCH 201/353] Use expected signature for NextPageURL The signature for NextPageURL() changed in main via 299f18c which caused the backport to fail. Let's use the expected signature for v2 branch. --- openstack/networking/v2/extensions/taas/tapmirrors/results.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openstack/networking/v2/extensions/taas/tapmirrors/results.go b/openstack/networking/v2/extensions/taas/tapmirrors/results.go index f6ca8b1aa0..eb60c0c5bb 100644 --- a/openstack/networking/v2/extensions/taas/tapmirrors/results.go +++ b/openstack/networking/v2/extensions/taas/tapmirrors/results.go @@ -72,7 +72,7 @@ type TapMirrorPage struct { // NextPageURL is invoked when a paginated collection of Endpoint groups has // reached the end of a page and the pager seeks to traverse over a new one. // In order to do this, it needs to construct the next page's URL. -func (r TapMirrorPage) NextPageURL(endpointURL string) (string, error) { +func (r TapMirrorPage) NextPageURL() (string, error) { var s struct { Links []gophercloud.Link `json:"tap_mirrors_links"` } From 45ade0df30fec1e5fd7ea2b50fe4cc709d03e87c Mon Sep 17 00:00:00 2001 From: Pierre Prinetti Date: Wed, 11 Jun 2025 18:20:39 +0200 Subject: [PATCH 202/353] Prepare v2.8.0 --- CHANGELOG.md | 49 ++++++++++++++++++++++++++++++++++++++++++++++ provider_client.go | 2 +- 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 73fe513468..95bc952b15 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,52 @@ +## v2.8.0 (2025-08-18) + +* [GH-3348](https://github.com/gophercloud/gophercloud/pull/3348) [v2] [networking] add ExtractRoutersInto func helper to routers +* [GH-3354](https://github.com/gophercloud/gophercloud/pull/3354) [v2] Fix a small typo +* [GH-3358](https://github.com/gophercloud/gophercloud/pull/3358) [v2] tests: fix devstack master branch tests +* [GH-3361](https://github.com/gophercloud/gophercloud/pull/3361) [v2] octavia: fix http_version type to float +* [GH-3362](https://github.com/gophercloud/gophercloud/pull/3362) [v2] tests: fix containerinfra template creation +* [GH-3367](https://github.com/gophercloud/gophercloud/pull/3367) [v2] Use Makefile for CI jobs +* [GH-3375](https://github.com/gophercloud/gophercloud/pull/3375) [v2] core: add missing Builder interfaces +* [GH-3378](https://github.com/gophercloud/gophercloud/pull/3378) [v2] tests: fix failing rabbitmq service +* [GH-3379](https://github.com/gophercloud/gophercloud/pull/3379) [v2] CI: Remove Bobcat +* [GH-3384](https://github.com/gophercloud/gophercloud/pull/3384) [v2] Move master CI jobs to Ubuntu 24.04 +* [GH-3386](https://github.com/gophercloud/gophercloud/pull/3386) [v2] tests: Fix TestBGPAgentCRUD +* [GH-3387](https://github.com/gophercloud/gophercloud/pull/3387) [v2] Update the doc of openstack.AuthOptionsFromEnv function +* [GH-3389](https://github.com/gophercloud/gophercloud/pull/3389) [v2] networking: add constants for statuses +* [GH-3391](https://github.com/gophercloud/gophercloud/pull/3391) [v2] CI: Add Epoxy +* [GH-3393](https://github.com/gophercloud/gophercloud/pull/3393) [v2] dns: implement shared zones list +* [GH-3394](https://github.com/gophercloud/gophercloud/pull/3394) [v2] acceptance: Prevent 409 when bulk-creating secgroup rules +* [GH-3396](https://github.com/gophercloud/gophercloud/pull/3396) [v2] identity: add support for string boolean in users' enabled member +* [GH-3397](https://github.com/gophercloud/gophercloud/pull/3397) [v2] Adjust List func to accept a Builder in tenants, routers and security groups packages +* [GH-3399](https://github.com/gophercloud/gophercloud/pull/3399) [v2] blockstorage: add manage-existing and unmanage api call +* [GH-3401](https://github.com/gophercloud/gophercloud/pull/3401) [v2] Added address groups to Networking extensions, with tests. +* [GH-3407](https://github.com/gophercloud/gophercloud/pull/3407) [v2] neutron: add segment_id support to subnets +* [GH-3413](https://github.com/gophercloud/gophercloud/pull/3413) [v2] build(deps): bump joelanford/go-apidiff from 0.8.2 to 0.8.3 +* [GH-3416](https://github.com/gophercloud/gophercloud/pull/3416) [v2] tests: bump devstack-action +* [GH-3422](https://github.com/gophercloud/gophercloud/pull/3422) [v2] Fix documentation for gateway_ip in subnet update +* [GH-3431](https://github.com/gophercloud/gophercloud/pull/3431) [v2] Use container-infra for OpenStack-API-Version +* [GH-3433](https://github.com/gophercloud/gophercloud/pull/3433) [v2] make: Use fixed version of gotestsum +* [GH-3434](https://github.com/gophercloud/gophercloud/pull/3434) [v2] Randomize test order for unit tests +* [GH-3435](https://github.com/gophercloud/gophercloud/pull/3435) [v2] Add versioned endpoint discovery +* [GH-3438](https://github.com/gophercloud/gophercloud/pull/3438) [v2] dns: add support for /v2/quotas +* [GH-3439](https://github.com/gophercloud/gophercloud/pull/3439) [v2] neutron: add segments extension package +* [GH-3446](https://github.com/gophercloud/gophercloud/pull/3446) nova: add support for hostname updates +* [GH-3452](https://github.com/gophercloud/gophercloud/pull/3452) [v2] neutron: allow omission of subnet_id for IP address +* [GH-3454](https://github.com/gophercloud/gophercloud/pull/3454) [v2] blockstorage: add isPublic query option for volume types +* [GH-3458](https://github.com/gophercloud/gophercloud/pull/3458) [v2] Fix pagination for messaging client +* [GH-3465](https://github.com/gophercloud/gophercloud/pull/3465) [v2] tests: Fix TestVLANTransparentCRUD test +* [GH-3466](https://github.com/gophercloud/gophercloud/pull/3466) [v2] tests: fix tests for recent PR backports +* [GH-3469](https://github.com/gophercloud/gophercloud/pull/3469) [v2] tests: shorten GH-A job names +* [GH-3473](https://github.com/gophercloud/gophercloud/pull/3473) [v2] core: clone service type aliases instead of referencing global slice +* [GH-3475](https://github.com/gophercloud/gophercloud/pull/3475) [v2] Implement update & delete traits on resource provider +* [GH-3476](https://github.com/gophercloud/gophercloud/pull/3476) [v2] tests: fix volumetypes unit tests +* [GH-3477](https://github.com/gophercloud/gophercloud/pull/3477) [v2] script: Improve getenvvar helper +* [GH-3481](https://github.com/gophercloud/gophercloud/pull/3481) [v2] Implement hypervisors.GetExt: Get with Query parameter +* [GH-3487](https://github.com/gophercloud/gophercloud/pull/3487) [v2] Add networking taas tapmirror suite +* [GH-3489](https://github.com/gophercloud/gophercloud/pull/3489) [v2] Fix incorrect ICMP field description in PortRangeMax comment +* [GH-3494](https://github.com/gophercloud/gophercloud/pull/3494) [v2] Networking v2: Support two time formats for subnet, router, SG rule (#3492) +* [GH-3495](https://github.com/gophercloud/gophercloud/pull/3495) [v2] build(deps): bump actions/checkout from 4 to 5 + ## v2.7.0 (2025-04-03) * [GH-3306](https://github.com/gophercloud/gophercloud/pull/3306) [v2] identity: Add Get endpoint by ID diff --git a/provider_client.go b/provider_client.go index 52fcd38ab3..61a18ae198 100644 --- a/provider_client.go +++ b/provider_client.go @@ -13,7 +13,7 @@ import ( // DefaultUserAgent is the default User-Agent string set in the request header. const ( - DefaultUserAgent = "gophercloud/v2.7.0" + DefaultUserAgent = "gophercloud/v2.8.0" DefaultMaxBackoffRetries = 60 ) From 1108e4c35f84df8e97331078cc10621718cce78a Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Tue, 16 Sep 2025 13:47:35 +0100 Subject: [PATCH 203/353] Trigger "hold" workflow on merge groups Things are currently timing out due to this being missing. Signed-off-by: Stephen Finucane --- .github/workflows/check-pr-labels.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/check-pr-labels.yaml b/.github/workflows/check-pr-labels.yaml index 4fbb7fc0b8..8d3cdde07b 100644 --- a/.github/workflows/check-pr-labels.yaml +++ b/.github/workflows/check-pr-labels.yaml @@ -1,5 +1,6 @@ name: Ready on: + merge_group: pull_request_target: types: - labeled From 4af44349428ecbe7edf2fb4e4d9e5ff977c09031 Mon Sep 17 00:00:00 2001 From: dlawton Date: Wed, 17 Sep 2025 11:55:23 +0100 Subject: [PATCH 204/353] Closes #2321 - Fix TestRolesCRUD by including DomainID to CreateOpts/ListOps structs. Signed-off-by: Dan Lawton --- internal/acceptance/openstack/identity/v3/roles_test.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/internal/acceptance/openstack/identity/v3/roles_test.go b/internal/acceptance/openstack/identity/v3/roles_test.go index ec69a9ba4e..b17ecd9049 100644 --- a/internal/acceptance/openstack/identity/v3/roles_test.go +++ b/internal/acceptance/openstack/identity/v3/roles_test.go @@ -58,7 +58,8 @@ func TestRolesCRUD(t *testing.T) { th.AssertNoErr(t, err) createOpts := roles.CreateOpts{ - Name: "testrole", + Name: "testrole", + DomainID: "default", Extra: map[string]any{ "description": "test role description", }, @@ -72,7 +73,9 @@ func TestRolesCRUD(t *testing.T) { tools.PrintResource(t, role) tools.PrintResource(t, role.Extra) - listOpts := roles.ListOpts{} + listOpts := roles.ListOpts{ + DomainID: "default", + } allPages, err := roles.List(client, listOpts).AllPages(context.TODO()) th.AssertNoErr(t, err) From b79a481ceb0998b0b123afb2d75bfe7a99a12b54 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 17 Sep 2025 14:18:29 +0000 Subject: [PATCH 205/353] build(deps): bump actions/labeler from 5 to 6 Bumps [actions/labeler](https://github.com/actions/labeler) from 5 to 6. - [Release notes](https://github.com/actions/labeler/releases) - [Commits](https://github.com/actions/labeler/compare/v5...v6) --- updated-dependencies: - dependency-name: actions/labeler dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/label-pr.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/label-pr.yaml b/.github/workflows/label-pr.yaml index fbb693113a..a445331b93 100644 --- a/.github/workflows/label-pr.yaml +++ b/.github/workflows/label-pr.yaml @@ -84,4 +84,4 @@ jobs: pull-requests: write runs-on: ubuntu-latest steps: - - uses: actions/labeler@v5 + - uses: actions/labeler@v6 From fa62b067965b828cd5179267a95b8be5e4941e7b Mon Sep 17 00:00:00 2001 From: Pierre Prinetti Date: Sun, 21 Sep 2025 15:47:09 +0200 Subject: [PATCH 206/353] refactor: Trivial fixes Address some gopls suggestions. The behaviour of the code is expected to remain unchanged. --- pagination/testing/doc.go | 2 -- provider_client.go | 13 +++---------- util.go | 3 --- 3 files changed, 3 insertions(+), 15 deletions(-) delete mode 100644 pagination/testing/doc.go diff --git a/pagination/testing/doc.go b/pagination/testing/doc.go deleted file mode 100644 index 0bc1eb3807..0000000000 --- a/pagination/testing/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// pagination -package testing diff --git a/provider_client.go b/provider_client.go index 61a18ae198..6d9722f188 100644 --- a/provider_client.go +++ b/provider_client.go @@ -7,6 +7,7 @@ import ( "errors" "io" "net/http" + "slices" "strings" "sync" ) @@ -437,16 +438,8 @@ func (client *ProviderClient) doRequest(ctx context.Context, method, url string, okc = defaultOkCodes(method) } - // Validate the HTTP response status. - var ok bool - for _, code := range okc { - if resp.StatusCode == code { - ok = true - break - } - } - - if !ok { + // Check the response code against the acceptable codes + if !slices.Contains(okc, resp.StatusCode) { body, _ := io.ReadAll(resp.Body) resp.Body.Close() respErr := ErrUnexpectedResponseCode{ diff --git a/util.go b/util.go index ad8a7dfaaa..d11a723b1b 100644 --- a/util.go +++ b/util.go @@ -37,9 +37,6 @@ func NormalizePathURL(basePath, rawPath string) (string, error) { absPathSys = filepath.Join(basePath, rawPath) u.Path = filepath.ToSlash(absPathSys) - if err != nil { - return "", err - } u.Scheme = "file" return u.String(), nil } From d872b54c17e8f9fa5b0fb7852d0a9634299c2abd Mon Sep 17 00:00:00 2001 From: Bram Kranendonk Date: Sat, 27 Sep 2025 13:19:35 +0200 Subject: [PATCH 207/353] Add image uploading status --- openstack/image/v2/images/types.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/openstack/image/v2/images/types.go b/openstack/image/v2/images/types.go index 147be19927..eedc13a330 100644 --- a/openstack/image/v2/images/types.go +++ b/openstack/image/v2/images/types.go @@ -13,10 +13,14 @@ const ( // been reserved for an image in the image registry. ImageStatusQueued ImageStatus = "queued" - // ImageStatusSaving denotes that an image’s raw data is currently being + // ImageStatusSaving denotes that an image's raw data is currently being // uploaded to Glance ImageStatusSaving ImageStatus = "saving" + // ImageStatusUploading denotes that an image's raw data is currently being + // uploaded to Glance through the upload process + ImageStatusUploading ImageStatus = "uploading" + // ImageStatusActive denotes an image that is fully available in Glance. ImageStatusActive ImageStatus = "active" From 8e44ee8f08e10d0a4b9b264b35f758ec1f86a5a8 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Fri, 26 Sep 2025 13:10:10 +0100 Subject: [PATCH 208/353] compute: Add host aggregate uuid field Signed-off-by: Stephen Finucane --- openstack/compute/v2/aggregates/results.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/openstack/compute/v2/aggregates/results.go b/openstack/compute/v2/aggregates/results.go index 0d4794acff..8e67edd87c 100644 --- a/openstack/compute/v2/aggregates/results.go +++ b/openstack/compute/v2/aggregates/results.go @@ -39,6 +39,10 @@ type Aggregate struct { // A boolean indicates whether this aggregate is deleted or not, // if it has not been deleted, false will appear. Deleted bool `json:"deleted"` + + // The UUID of the aggregate. + // The requires microversion 2.41 or later. + UUID string `json:"uuid"` } // UnmarshalJSON to override default From 165cf7703e12d5630512af93f74da5138e5705e4 Mon Sep 17 00:00:00 2001 From: Maximilian Meister Date: Wed, 24 Sep 2025 08:47:57 +0200 Subject: [PATCH 209/353] Enable load balancer quota deletion --- .../openstack/loadbalancer/v2/quotas_test.go | 10 ++++++++++ openstack/loadbalancer/v2/quotas/doc.go | 10 ++++++++++ openstack/loadbalancer/v2/quotas/requests.go | 6 ++++++ openstack/loadbalancer/v2/quotas/results.go | 6 ++++++ .../v2/quotas/testing/fixtures_test.go | 18 +++++++++++++++++- .../v2/quotas/testing/requests_test.go | 10 ++++++++++ openstack/loadbalancer/v2/quotas/urls.go | 4 ++++ 7 files changed, 63 insertions(+), 1 deletion(-) diff --git a/internal/acceptance/openstack/loadbalancer/v2/quotas_test.go b/internal/acceptance/openstack/loadbalancer/v2/quotas_test.go index cc778e5403..87f9d7621f 100644 --- a/internal/acceptance/openstack/loadbalancer/v2/quotas_test.go +++ b/internal/acceptance/openstack/loadbalancer/v2/quotas_test.go @@ -80,3 +80,13 @@ func TestQuotasUpdate(t *testing.T) { tools.PrintResource(t, restoredQuotas) } + +func TestQuotasDelete(t *testing.T) { + clients.RequireAdmin(t) + + client, err := clients.NewLoadBalancerV2Client() + th.AssertNoErr(t, err) + + err = quotas.Delete(context.TODO(), client, os.Getenv("OS_PROJECT_NAME")).ExtractErr() + th.AssertNoErr(t, err) +} diff --git a/openstack/loadbalancer/v2/quotas/doc.go b/openstack/loadbalancer/v2/quotas/doc.go index c2c63512c3..77c5600226 100644 --- a/openstack/loadbalancer/v2/quotas/doc.go +++ b/openstack/loadbalancer/v2/quotas/doc.go @@ -30,5 +30,15 @@ Example to Update project quotas } fmt.Printf("quotas: %#v\n", quotasInfo) + +Example to Delete project quotas + + projectID = "23d5d3f79dfa4f73b72b8b0b0063ec55" + err := quotas.Delete(context.TODO(), networkClient, projectID).ExtractErr() + if err != nil { + log.Fatal(err) + } + + fmt.Printf("Deleted quotas for project: %s\n", projectID) */ package quotas diff --git a/openstack/loadbalancer/v2/quotas/requests.go b/openstack/loadbalancer/v2/quotas/requests.go index 8b7771eea8..f07f9392e9 100644 --- a/openstack/loadbalancer/v2/quotas/requests.go +++ b/openstack/loadbalancer/v2/quotas/requests.go @@ -63,3 +63,9 @@ func Update(ctx context.Context, c *gophercloud.ServiceClient, projectID string, _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) return } + +func Delete(ctx context.Context, c *gophercloud.ServiceClient, projectID string) (r DeleteResult) { + resp, err := c.Delete(ctx, deleteURL(c, projectID), nil) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} diff --git a/openstack/loadbalancer/v2/quotas/results.go b/openstack/loadbalancer/v2/quotas/results.go index e1ef385982..5487d7a84e 100644 --- a/openstack/loadbalancer/v2/quotas/results.go +++ b/openstack/loadbalancer/v2/quotas/results.go @@ -96,3 +96,9 @@ func (r *Quota) UnmarshalJSON(b []byte) error { return nil } + +// DeleteResult is the response from a Delete operation. Call its ExtractErr +// method to determine if the request succeeded or failed. +type DeleteResult struct { + gophercloud.ErrResult +} diff --git a/openstack/loadbalancer/v2/quotas/testing/fixtures_test.go b/openstack/loadbalancer/v2/quotas/testing/fixtures_test.go index e5185b2012..e4609aa868 100644 --- a/openstack/loadbalancer/v2/quotas/testing/fixtures_test.go +++ b/openstack/loadbalancer/v2/quotas/testing/fixtures_test.go @@ -1,6 +1,13 @@ package testing -import "github.com/gophercloud/gophercloud/v2/openstack/loadbalancer/v2/quotas" +import ( + "net/http" + "testing" + + "github.com/gophercloud/gophercloud/v2/openstack/loadbalancer/v2/quotas" + fake "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/common" + th "github.com/gophercloud/gophercloud/v2/testhelper" +) const GetResponseRaw_1 = ` { @@ -77,3 +84,12 @@ var UpdateResponse = quotas.Quota{ L7Policy: 50, L7Rule: 100, } + +func MockDeleteResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/quotas/0a73845280574ad389c292f6a74afa76", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "DELETE") + th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + + w.WriteHeader(http.StatusNoContent) + }) +} diff --git a/openstack/loadbalancer/v2/quotas/testing/requests_test.go b/openstack/loadbalancer/v2/quotas/testing/requests_test.go index ccf8e51f35..ab3ba6a177 100644 --- a/openstack/loadbalancer/v2/quotas/testing/requests_test.go +++ b/openstack/loadbalancer/v2/quotas/testing/requests_test.go @@ -105,3 +105,13 @@ func TestUpdate_2(t *testing.T) { th.AssertNoErr(t, err) th.AssertDeepEquals(t, q, &UpdateResponse) } + +func TestDelete(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + MockDeleteResponse(t, fakeServer) + + res := quotas.Delete(context.TODO(), fake.ServiceClient(fakeServer), "0a73845280574ad389c292f6a74afa76") + th.AssertNoErr(t, res.Err) +} diff --git a/openstack/loadbalancer/v2/quotas/urls.go b/openstack/loadbalancer/v2/quotas/urls.go index 0365d9c8ad..545e832307 100644 --- a/openstack/loadbalancer/v2/quotas/urls.go +++ b/openstack/loadbalancer/v2/quotas/urls.go @@ -15,3 +15,7 @@ func getURL(c *gophercloud.ServiceClient, projectID string) string { func updateURL(c *gophercloud.ServiceClient, projectID string) string { return resourceURL(c, projectID) } + +func deleteURL(c *gophercloud.ServiceClient, projectID string) string { + return getURL(c, projectID) +} From 4aa1d1e2dac48cad83fed701effca1325953c831 Mon Sep 17 00:00:00 2001 From: Maximilian Meister Date: Wed, 24 Sep 2025 09:34:08 +0200 Subject: [PATCH 210/353] Enable network quota deletion --- .../networking/v2/extensions/quotas/quotas_test.go | 10 ++++++++++ openstack/networking/v2/extensions/quotas/doc.go | 10 ++++++++++ .../networking/v2/extensions/quotas/requests.go | 6 ++++++ .../networking/v2/extensions/quotas/results.go | 6 ++++++ .../v2/extensions/quotas/testing/fixtures_test.go | 14 ++++++++++++++ .../v2/extensions/quotas/testing/requests_test.go | 10 ++++++++++ openstack/networking/v2/extensions/quotas/urls.go | 4 ++++ 7 files changed, 60 insertions(+) diff --git a/internal/acceptance/openstack/networking/v2/extensions/quotas/quotas_test.go b/internal/acceptance/openstack/networking/v2/extensions/quotas/quotas_test.go index 3eaf7d232b..06b2280791 100644 --- a/internal/acceptance/openstack/networking/v2/extensions/quotas/quotas_test.go +++ b/internal/acceptance/openstack/networking/v2/extensions/quotas/quotas_test.go @@ -63,3 +63,13 @@ func TestQuotasUpdate(t *testing.T) { tools.PrintResource(t, restoredQuotas) } + +func TestQuotasDelete(t *testing.T) { + clients.RequireAdmin(t) + + client, err := clients.NewNetworkV2Client() + th.AssertNoErr(t, err) + + err = quotas.Delete(context.TODO(), client, os.Getenv("OS_PROJECT_NAME")).ExtractErr() + th.AssertNoErr(t, err) +} diff --git a/openstack/networking/v2/extensions/quotas/doc.go b/openstack/networking/v2/extensions/quotas/doc.go index fe1cc26311..5e5ec3e58a 100644 --- a/openstack/networking/v2/extensions/quotas/doc.go +++ b/openstack/networking/v2/extensions/quotas/doc.go @@ -43,5 +43,15 @@ Example to Update project quotas } fmt.Printf("quotas: %#v\n", quotasInfo) + +Example to Delete project quotas + + projectID = "23d5d3f79dfa4f73b72b8b0b0063ec55" + err := quotas.Delete(context.TODO(), networkClient, projectID).ExtractErr() + if err != nil { + log.Fatal(err) + } + + fmt.Printf("Deleted quotas for project: %s\n", projectID) */ package quotas diff --git a/openstack/networking/v2/extensions/quotas/requests.go b/openstack/networking/v2/extensions/quotas/requests.go index 859c552cef..6289368841 100644 --- a/openstack/networking/v2/extensions/quotas/requests.go +++ b/openstack/networking/v2/extensions/quotas/requests.go @@ -78,3 +78,9 @@ func Update(ctx context.Context, c *gophercloud.ServiceClient, projectID string, _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) return } + +func Delete(ctx context.Context, c *gophercloud.ServiceClient, projectID string) (r DeleteResult) { + resp, err := c.Delete(ctx, deleteURL(c, projectID), nil) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} diff --git a/openstack/networking/v2/extensions/quotas/results.go b/openstack/networking/v2/extensions/quotas/results.go index 8b1ae8a95d..7e3931220f 100644 --- a/openstack/networking/v2/extensions/quotas/results.go +++ b/openstack/networking/v2/extensions/quotas/results.go @@ -171,3 +171,9 @@ func (q *QuotaDetail) UnmarshalJSON(b []byte) error { return nil } + +// DeleteResult is the response from a Delete operation. Call its ExtractErr +// method to determine if the request succeeded or failed. +type DeleteResult struct { + gophercloud.ErrResult +} diff --git a/openstack/networking/v2/extensions/quotas/testing/fixtures_test.go b/openstack/networking/v2/extensions/quotas/testing/fixtures_test.go index a4a7703c89..1f34dead15 100644 --- a/openstack/networking/v2/extensions/quotas/testing/fixtures_test.go +++ b/openstack/networking/v2/extensions/quotas/testing/fixtures_test.go @@ -1,7 +1,12 @@ package testing import ( + "net/http" + "testing" + + fake "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/common" "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/extensions/quotas" + th "github.com/gophercloud/gophercloud/v2/testhelper" ) const GetResponseRaw = ` @@ -140,3 +145,12 @@ var UpdateResponse = quotas.Quota{ SubnetPool: 0, Trunk: 5, } + +func MockDeleteResponse(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/v2.0/quotas/0a73845280574ad389c292f6a74afa76", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "DELETE") + th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + + w.WriteHeader(http.StatusNoContent) + }) +} diff --git a/openstack/networking/v2/extensions/quotas/testing/requests_test.go b/openstack/networking/v2/extensions/quotas/testing/requests_test.go index 597edd4853..e4550c11fd 100644 --- a/openstack/networking/v2/extensions/quotas/testing/requests_test.go +++ b/openstack/networking/v2/extensions/quotas/testing/requests_test.go @@ -80,3 +80,13 @@ func TestUpdate(t *testing.T) { th.AssertNoErr(t, err) th.AssertDeepEquals(t, q, &UpdateResponse) } + +func TestDelete(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + MockDeleteResponse(t, fakeServer) + + res := quotas.Delete(context.TODO(), fake.ServiceClient(fakeServer), "0a73845280574ad389c292f6a74afa76") + th.AssertNoErr(t, res.Err) +} diff --git a/openstack/networking/v2/extensions/quotas/urls.go b/openstack/networking/v2/extensions/quotas/urls.go index 94cbe23880..726c4da8eb 100644 --- a/openstack/networking/v2/extensions/quotas/urls.go +++ b/openstack/networking/v2/extensions/quotas/urls.go @@ -24,3 +24,7 @@ func getDetailURL(c *gophercloud.ServiceClient, projectID string) string { func updateURL(c *gophercloud.ServiceClient, projectID string) string { return resourceURL(c, projectID) } + +func deleteURL(c *gophercloud.ServiceClient, projectID string) string { + return getURL(c, projectID) +} From 743f1e82ef67dd6bd282310bc4a4deb91dcf692d Mon Sep 17 00:00:00 2001 From: Maximilian Meister Date: Wed, 1 Oct 2025 08:08:57 +0200 Subject: [PATCH 211/353] Add acceptance testing hint to contribution docs Also fix broken link --- docs/contributor-tutorial/step-04-acceptance-testing.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/contributor-tutorial/step-04-acceptance-testing.md b/docs/contributor-tutorial/step-04-acceptance-testing.md index fe82717439..a6708ee5fb 100644 --- a/docs/contributor-tutorial/step-04-acceptance-testing.md +++ b/docs/contributor-tutorial/step-04-acceptance-testing.md @@ -17,9 +17,13 @@ And, to be frank, submitting untested code will inevitably cause someone else to have to spend time fixing it. If you don't have an OpenStack environment to test with, we have lots of -documentation [here](/acceptance) to help you build your own small OpenStack +documentation [here](/internal/acceptance) to help you build your own small OpenStack environment for testing. +If you add new API calls/actions e.g. also make sure to include them into the +respective [acceptance tests](/internal/acceptance/openstack) for the code to be +validated against all the supported OpenStack versions. + --- Once you've confirmed you are able to test your code, proceed to From e25f269bd1ef27e5c75be311ca8aa25dbf792f92 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Fri, 24 Oct 2025 13:16:23 +0100 Subject: [PATCH 212/353] docs: Document tested releases for acceptance tests Signed-off-by: Stephen Finucane --- docs/contributor-tutorial/step-05-pull-requests.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/contributor-tutorial/step-05-pull-requests.md b/docs/contributor-tutorial/step-05-pull-requests.md index cb340a92ca..1f5373bc57 100644 --- a/docs/contributor-tutorial/step-05-pull-requests.md +++ b/docs/contributor-tutorial/step-05-pull-requests.md @@ -99,7 +99,10 @@ generate your own fixtures using the OpenStack environment you're Since unit tests are not run against an actual OpenStack environment, acceptance tests can arguably be more important. The acceptance tests that you include in your Pull Request should confirm that your implemented code works -as intended with an actual OpenStack environment. +as intended with an actual OpenStack environment. We run our functional jobs +against all supported Skip Level Upgrade Release Process (SLURP) releases as +well as `master`. This information is sourced from +[releases.openstack.org](https://releases.openstack.org/). ### Documentation From 56a490ef4de4d0f305ca63680db6d7c275e4338d Mon Sep 17 00:00:00 2001 From: Local rebase Date: Fri, 24 Oct 2025 12:08:24 +0100 Subject: [PATCH 213/353] Identity: Add Options field to roles. Signed-off-by: Dan Lawton --- .../openstack/identity/v3/roles_test.go | 6 ++ openstack/identity/v3/roles/requests.go | 14 ++++ openstack/identity/v3/roles/results.go | 3 + .../v3/roles/testing/fixtures_test.go | 82 +++++++++++++++++-- .../v3/roles/testing/requests_test.go | 24 ++++++ 5 files changed, 122 insertions(+), 7 deletions(-) diff --git a/internal/acceptance/openstack/identity/v3/roles_test.go b/internal/acceptance/openstack/identity/v3/roles_test.go index b17ecd9049..96337dc4c1 100644 --- a/internal/acceptance/openstack/identity/v3/roles_test.go +++ b/internal/acceptance/openstack/identity/v3/roles_test.go @@ -63,6 +63,9 @@ func TestRolesCRUD(t *testing.T) { Extra: map[string]any{ "description": "test role description", }, + Options: map[roles.Option]any{ + "immutable": false, + }, } // Create Role in the default domain @@ -98,6 +101,9 @@ func TestRolesCRUD(t *testing.T) { Extra: map[string]any{ "description": "updated test role description", }, + Options: map[roles.Option]any{ + "immutable": nil, + }, } newRole, err := roles.Update(context.TODO(), client, role.ID, updateOpts).Extract() diff --git a/openstack/identity/v3/roles/requests.go b/openstack/identity/v3/roles/requests.go index 2e40e93d6d..0552dc2852 100644 --- a/openstack/identity/v3/roles/requests.go +++ b/openstack/identity/v3/roles/requests.go @@ -9,6 +9,14 @@ import ( "github.com/gophercloud/gophercloud/v2/pagination" ) +// Option is a specific option defined at the API to enable features +// on a role. +type Option string + +const ( + Immutable Option = "immutable" +) + // ListOptsBuilder allows extensions to add additional parameters to // the List request type ListOptsBuilder interface { @@ -88,6 +96,9 @@ type CreateOpts struct { // Extra is free-form extra key/value pairs to describe the role. Extra map[string]any `json:"-"` + + // Options are defined options in the API to enable certain features. + Options map[Option]any `json:"options,omitempty"` } // ToRoleCreateMap formats a CreateOpts into a create request. @@ -135,6 +146,9 @@ type UpdateOpts struct { // Extra is free-form extra key/value pairs to describe the role. Extra map[string]any `json:"-"` + + // Options are defined options in the API to enable certain features. + Options map[Option]any `json:"options,omitempty"` } // ToRoleUpdateMap formats a UpdateOpts into an update request. diff --git a/openstack/identity/v3/roles/results.go b/openstack/identity/v3/roles/results.go index 075e3cbe73..a0b45d1f03 100644 --- a/openstack/identity/v3/roles/results.go +++ b/openstack/identity/v3/roles/results.go @@ -23,6 +23,9 @@ type Role struct { // Extra is a collection of miscellaneous key/values. Extra map[string]any `json:"-"` + + // Options are a set of defined options that allow certain features for a role + Options map[Option]any `json:"options"` } func (r *Role) UnmarshalJSON(b []byte) error { diff --git a/openstack/identity/v3/roles/testing/fixtures_test.go b/openstack/identity/v3/roles/testing/fixtures_test.go index 1e8403eb64..3fa6171c1b 100644 --- a/openstack/identity/v3/roles/testing/fixtures_test.go +++ b/openstack/identity/v3/roles/testing/fixtures_test.go @@ -52,9 +52,25 @@ const GetOutput = ` "self": "https://example.com/identity/v3/roles/9fe1d3" }, "name": "support", - "extra": { - "description": "read-only support role" - } + "description": "read-only support role" + } +} +` + +// GetOutputWithOptions provides a Get result of a role with options. +const GetOutputWithOptions = ` +{ + "role": { + "domain_id": "1789d1", + "id": "9fe1d3", + "links": { + "self": "https://example.com/identity/v3/roles/9fe1d3" + }, + "name": "support", + "description": "read-only support role", + "options": { + "immutable": true + } } } ` @@ -65,8 +81,22 @@ const CreateRequest = ` "role": { "domain_id": "1789d1", "name": "support", - "description": "read-only support role" - } + "description": "read-only support role" + } +} +` + +// CreateRequestWithOptions provides the input to a Create request with Options. +const CreateRequestWithOptions = ` +{ + "role": { + "domain_id": "1789d1", + "name": "support", + "description": "read-only support role", + "options": { + "immutable": true + } + } } ` @@ -74,7 +104,10 @@ const CreateRequest = ` const UpdateRequest = ` { "role": { - "description": "admin read-only support role" + "description": "admin read-only support role", + "options": { + "immutable": false + } } } ` @@ -91,7 +124,10 @@ const UpdateOutput = ` "name": "support", "extra": { "description": "admin read-only support role" - } + }, + "options": { + "immutable": false + } } } ` @@ -324,6 +360,22 @@ var SecondRole = roles.Role{ }, } +// SecondRoleWithOptions is the second role in the List request +var SecondRoleWithOptions = roles.Role{ + DomainID: "1789d1", + ID: "9fe1d3", + Links: map[string]any{ + "self": "https://example.com/identity/v3/roles/9fe1d3", + }, + Name: "support", + Extra: map[string]any{ + "description": "read-only support role", + }, + Options: map[roles.Option]any{ + roles.Immutable: true, + }, +} + // SecondRoleUpdated is how SecondRole should look after an Update. var SecondRoleUpdated = roles.Role{ DomainID: "1789d1", @@ -335,6 +387,9 @@ var SecondRoleUpdated = roles.Role{ Extra: map[string]any{ "description": "admin read-only support role", }, + Options: map[roles.Option]any{ + roles.Immutable: false, + }, } // ExpectedRolesSlice is the slice of roles expected to be returned from ListOutput. @@ -381,6 +436,19 @@ func HandleCreateRoleSuccessfully(t *testing.T, fakeServer th.FakeServer) { }) } +// HandleCreateRoleWithOptionsSuccessfully creates an HTTP handler at `/roles` on the +// test handler mux that tests role creation. +func HandleCreateWithOptionsRoleSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/roles", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "POST") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.TestJSONRequest(t, r, CreateRequestWithOptions) + + w.WriteHeader(http.StatusCreated) + fmt.Fprint(w, GetOutputWithOptions) + }) +} + // HandleUpdateRoleSuccessfully creates an HTTP handler at `/roles` on the // test handler mux that tests role update. func HandleUpdateRoleSuccessfully(t *testing.T, fakeServer th.FakeServer) { diff --git a/openstack/identity/v3/roles/testing/requests_test.go b/openstack/identity/v3/roles/testing/requests_test.go index fb3021064a..88da0a4b44 100644 --- a/openstack/identity/v3/roles/testing/requests_test.go +++ b/openstack/identity/v3/roles/testing/requests_test.go @@ -104,6 +104,27 @@ func TestCreateRole(t *testing.T) { th.CheckDeepEquals(t, SecondRole, *actual) } +func TestCreateWithOptionsRole(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCreateWithOptionsRoleSuccessfully(t, fakeServer) + + createOpts := roles.CreateOpts{ + Name: "support", + DomainID: "1789d1", + Options: map[roles.Option]any{ + roles.Immutable: true, + }, + Extra: map[string]any{ + "description": "read-only support role", + }, + } + + actual, err := roles.Create(context.TODO(), client.ServiceClient(fakeServer), createOpts).Extract() + th.AssertNoErr(t, err) + th.CheckDeepEquals(t, SecondRoleWithOptions, *actual) +} + func TestUpdateRole(t *testing.T) { fakeServer := th.SetupHTTP() defer fakeServer.Teardown() @@ -113,6 +134,9 @@ func TestUpdateRole(t *testing.T) { Extra: map[string]any{ "description": "admin read-only support role", }, + Options: map[roles.Option]any{ + roles.Immutable: false, + }, } actual, err := roles.Update(context.TODO(), client.ServiceClient(fakeServer), "9fe1d3", updateOpts).Extract() From 339b92c59949b4e5629c0f558071f95f15757ce9 Mon Sep 17 00:00:00 2001 From: Samuel Kunkel Date: Thu, 16 Oct 2025 19:08:54 +0200 Subject: [PATCH 214/353] Add config_drive to server struct Adds config_drive to the regular server struct used for responses. (currently only part of createOpts) which leads to situation that one can create a server with a config_drive. But one can not verify / see that information in any kind of response. This fixes #3534. --- openstack/compute/v2/servers/results.go | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/openstack/compute/v2/servers/results.go b/openstack/compute/v2/servers/results.go index 385001c8dd..bfecce29ec 100644 --- a/openstack/compute/v2/servers/results.go +++ b/openstack/compute/v2/servers/results.go @@ -7,6 +7,7 @@ import ( "fmt" "net/url" "path" + "strconv" "time" "github.com/gophercloud/gophercloud/v2" @@ -283,6 +284,9 @@ type Server struct { // Locked indicates the lock status of the server // This requires microversion 2.9 or later Locked *bool `json:"locked"` + + // ConfigDrive enables metadata injection through a configuration drive. + ConfigDrive bool `json:"-"` } type AttachedVolume struct { @@ -343,6 +347,7 @@ func (r *Server) UnmarshalJSON(b []byte) error { Image any `json:"image"` LaunchedAt gophercloud.JSONRFC3339MilliNoZ `json:"OS-SRV-USG:launched_at"` TerminatedAt gophercloud.JSONRFC3339MilliNoZ `json:"OS-SRV-USG:terminated_at"` + ConfigDrive any `json:"config_drive"` } err := json.Unmarshal(b, &s) if err != nil { @@ -364,6 +369,24 @@ func (r *Server) UnmarshalJSON(b []byte) error { r.LaunchedAt = time.Time(s.LaunchedAt) r.TerminatedAt = time.Time(s.TerminatedAt) + switch t := s.ConfigDrive.(type) { + case nil: + r.ConfigDrive = false + case bool: + r.ConfigDrive = t + case string: + if t == "" { + r.ConfigDrive = false + } else { + r.ConfigDrive, err = strconv.ParseBool(t) + if err != nil { + return fmt.Errorf("failed to parse ConfigDrive %q: %v", t, err) + } + } + default: + return fmt.Errorf("unknown type for ConfigDrive: %T (value: %v)", t, t) + } + return err } From 7f73a3cb80f6921b9a57de97b4e01c4663e6cdfe Mon Sep 17 00:00:00 2001 From: dlawton Date: Fri, 10 Oct 2025 15:15:19 +0100 Subject: [PATCH 215/353] Identity: Add description field to roles. Signed-off-by: Daniel Lawton --- .../openstack/identity/v3/roles_test.go | 16 +++++++----- openstack/identity/v3/roles/requests.go | 8 +++++- openstack/identity/v3/roles/results.go | 3 +++ .../v3/roles/testing/fixtures_test.go | 25 +++++++++++++------ .../v3/roles/testing/requests_test.go | 16 ++++++------ 5 files changed, 47 insertions(+), 21 deletions(-) diff --git a/internal/acceptance/openstack/identity/v3/roles_test.go b/internal/acceptance/openstack/identity/v3/roles_test.go index 96337dc4c1..753736843a 100644 --- a/internal/acceptance/openstack/identity/v3/roles_test.go +++ b/internal/acceptance/openstack/identity/v3/roles_test.go @@ -58,10 +58,11 @@ func TestRolesCRUD(t *testing.T) { th.AssertNoErr(t, err) createOpts := roles.CreateOpts{ - Name: "testrole", - DomainID: "default", + Name: "role-test", + DomainID: "default", + Description: "test description", Extra: map[string]any{ - "description": "test role description", + "email": "testrole@example.com", }, Options: map[roles.Option]any{ "immutable": false, @@ -96,10 +97,11 @@ func TestRolesCRUD(t *testing.T) { } th.AssertEquals(t, found, true) - + description := "updated role test" updateOpts := roles.UpdateOpts{ + Description: &description, Extra: map[string]any{ - "description": "updated test role description", + "email": "updatedtestrole@example.com", }, Options: map[roles.Option]any{ "immutable": nil, @@ -112,7 +114,9 @@ func TestRolesCRUD(t *testing.T) { tools.PrintResource(t, newRole) tools.PrintResource(t, newRole.Extra) - th.AssertEquals(t, newRole.Extra["description"], "updated test role description") + th.AssertEquals(t, newRole.Description, description) + th.AssertEquals(t, newRole.Extra["email"], "updatedtestrole@example.com") + } func TestRolesFilterList(t *testing.T) { diff --git a/openstack/identity/v3/roles/requests.go b/openstack/identity/v3/roles/requests.go index 0552dc2852..260aa153ce 100644 --- a/openstack/identity/v3/roles/requests.go +++ b/openstack/identity/v3/roles/requests.go @@ -94,6 +94,9 @@ type CreateOpts struct { // DomainID is the ID of the domain the role belongs to. DomainID string `json:"domain_id,omitempty"` + // Description is the description of the new role. + Description string `json:"description,omitempty"` + // Extra is free-form extra key/value pairs to describe the role. Extra map[string]any `json:"-"` @@ -141,9 +144,12 @@ type UpdateOptsBuilder interface { // UpdateOpts provides options for updating a role. type UpdateOpts struct { - // Name is the name of the new role. + // Name is an updated name for the role. Name string `json:"name,omitempty"` + // Description is an updated description for the role. + Description *string `json:"description,omitempty"` + // Extra is free-form extra key/value pairs to describe the role. Extra map[string]any `json:"-"` diff --git a/openstack/identity/v3/roles/results.go b/openstack/identity/v3/roles/results.go index a0b45d1f03..4c51e5f601 100644 --- a/openstack/identity/v3/roles/results.go +++ b/openstack/identity/v3/roles/results.go @@ -21,6 +21,9 @@ type Role struct { // Name is the role name Name string `json:"name"` + // Description is the description of the role. + Description string `json:"description"` + // Extra is a collection of miscellaneous key/values. Extra map[string]any `json:"-"` diff --git a/openstack/identity/v3/roles/testing/fixtures_test.go b/openstack/identity/v3/roles/testing/fixtures_test.go index 3fa6171c1b..7cb374d2d7 100644 --- a/openstack/identity/v3/roles/testing/fixtures_test.go +++ b/openstack/identity/v3/roles/testing/fixtures_test.go @@ -34,8 +34,9 @@ const ListOutput = ` "self": "https://example.com/identity/v3/roles/9fe1d3" }, "name": "support", + "description": "read-only support role", "extra": { - "description": "read-only support role" + "test": "this is for the test" } } ] @@ -52,7 +53,10 @@ const GetOutput = ` "self": "https://example.com/identity/v3/roles/9fe1d3" }, "name": "support", - "description": "read-only support role" + "description": "read-only support role", + "extra": { + "test": "this is for the test" + } } } ` @@ -70,6 +74,9 @@ const GetOutputWithOptions = ` "description": "read-only support role", "options": { "immutable": true + }, + "extra": { + "test": "this is for the test" } } } @@ -81,7 +88,8 @@ const CreateRequest = ` "role": { "domain_id": "1789d1", "name": "support", - "description": "read-only support role" + "description": "read-only support role", + "test": "this is for the test" } } ` @@ -93,6 +101,7 @@ const CreateRequestWithOptions = ` "domain_id": "1789d1", "name": "support", "description": "read-only support role", + "test": "this is for the test", "options": { "immutable": true } @@ -354,9 +363,10 @@ var SecondRole = roles.Role{ Links: map[string]any{ "self": "https://example.com/identity/v3/roles/9fe1d3", }, - Name: "support", + Name: "support", + Description: "read-only support role", Extra: map[string]any{ - "description": "read-only support role", + "test": "this is for the test", }, } @@ -367,9 +377,10 @@ var SecondRoleWithOptions = roles.Role{ Links: map[string]any{ "self": "https://example.com/identity/v3/roles/9fe1d3", }, - Name: "support", + Name: "support", + Description: "read-only support role", Extra: map[string]any{ - "description": "read-only support role", + "test": "this is for the test", }, Options: map[roles.Option]any{ roles.Immutable: true, diff --git a/openstack/identity/v3/roles/testing/requests_test.go b/openstack/identity/v3/roles/testing/requests_test.go index 88da0a4b44..7ef5085904 100644 --- a/openstack/identity/v3/roles/testing/requests_test.go +++ b/openstack/identity/v3/roles/testing/requests_test.go @@ -40,7 +40,7 @@ func TestListRolesAllPages(t *testing.T) { actual, err := roles.ExtractRoles(allPages) th.AssertNoErr(t, err) th.CheckDeepEquals(t, ExpectedRolesSlice, actual) - th.AssertEquals(t, ExpectedRolesSlice[1].Extra["description"], "read-only support role") + th.AssertEquals(t, ExpectedRolesSlice[1].Extra["test"], "this is for the test") } func TestListUsersFiltersCheck(t *testing.T) { @@ -92,10 +92,11 @@ func TestCreateRole(t *testing.T) { HandleCreateRoleSuccessfully(t, fakeServer) createOpts := roles.CreateOpts{ - Name: "support", - DomainID: "1789d1", + Name: "support", + DomainID: "1789d1", + Description: "read-only support role", Extra: map[string]any{ - "description": "read-only support role", + "test": "this is for the test", }, } @@ -110,13 +111,14 @@ func TestCreateWithOptionsRole(t *testing.T) { HandleCreateWithOptionsRoleSuccessfully(t, fakeServer) createOpts := roles.CreateOpts{ - Name: "support", - DomainID: "1789d1", + Name: "support", + DomainID: "1789d1", + Description: "read-only support role", Options: map[roles.Option]any{ roles.Immutable: true, }, Extra: map[string]any{ - "description": "read-only support role", + "test": "this is for the test", }, } From faf0c0499807aef27895adee86ed53e25652edbd Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Mon, 19 May 2025 10:37:18 +0100 Subject: [PATCH 216/353] Bump Epoxy jobs to Ubuntu 24.04 (Noble) Now that the DevStack fix has landed [1]. [1] https://review.opendev.org/c/openstack/devstack/+/950289 Signed-off-by: Stephen Finucane (cherry picked from commit 811a469a51a991cbb4f57d96255bafbb434f019d) --- .github/workflows/functional-basic.yaml | 2 +- .github/workflows/functional-blockstorage.yaml | 2 +- .github/workflows/functional-compute.yaml | 2 +- .github/workflows/functional-containerinfra.yaml | 2 +- .github/workflows/functional-dns.yaml | 2 +- .github/workflows/functional-fwaas_v2.yaml | 2 +- .github/workflows/functional-identity.yaml | 2 +- .github/workflows/functional-image.yaml | 2 +- .github/workflows/functional-keymanager.yaml | 2 +- .github/workflows/functional-loadbalancer.yaml | 2 +- .github/workflows/functional-messaging.yaml | 2 +- .github/workflows/functional-networking.yaml | 2 +- .github/workflows/functional-objectstorage.yaml | 2 +- .github/workflows/functional-orchestration.yaml | 2 +- .github/workflows/functional-placement.yaml | 2 +- .github/workflows/functional-sharedfilesystems.yaml | 2 +- .github/workflows/functional-workflow.yaml | 2 +- 17 files changed, 17 insertions(+), 17 deletions(-) diff --git a/.github/workflows/functional-basic.yaml b/.github/workflows/functional-basic.yaml index 9ee87e2ed6..28dd6dc9c0 100644 --- a/.github/workflows/functional-basic.yaml +++ b/.github/workflows/functional-basic.yaml @@ -20,7 +20,7 @@ jobs: additional_services: "openstack-cli-server" - name: "epoxy" openstack_version: "stable/2025.1" - ubuntu_version: "22.04" + ubuntu_version: "24.04" additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" diff --git a/.github/workflows/functional-blockstorage.yaml b/.github/workflows/functional-blockstorage.yaml index 663213e1bc..7708e2360e 100644 --- a/.github/workflows/functional-blockstorage.yaml +++ b/.github/workflows/functional-blockstorage.yaml @@ -25,7 +25,7 @@ jobs: additional_services: "openstack-cli-server" - name: "epoxy" openstack_version: "stable/2025.1" - ubuntu_version: "22.04" + ubuntu_version: "24.04" additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" diff --git a/.github/workflows/functional-compute.yaml b/.github/workflows/functional-compute.yaml index da091393f0..86f5f0de12 100644 --- a/.github/workflows/functional-compute.yaml +++ b/.github/workflows/functional-compute.yaml @@ -25,7 +25,7 @@ jobs: additional_services: "openstack-cli-server" - name: "epoxy" openstack_version: "stable/2025.1" - ubuntu_version: "22.04" + ubuntu_version: "24.04" additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" diff --git a/.github/workflows/functional-containerinfra.yaml b/.github/workflows/functional-containerinfra.yaml index 66bbda418f..eb4d1bcb16 100644 --- a/.github/workflows/functional-containerinfra.yaml +++ b/.github/workflows/functional-containerinfra.yaml @@ -34,7 +34,7 @@ jobs: additional_services: "openstack-cli-server" - name: "epoxy" openstack_version: "stable/2025.1" - ubuntu_version: "22.04" + ubuntu_version: "24.04" devstack_conf_overrides: | # ensure we're using a working version of setuptools if [ -n "\$TOP_DIR" ]; then diff --git a/.github/workflows/functional-dns.yaml b/.github/workflows/functional-dns.yaml index fb7c325f15..2d5600dd69 100644 --- a/.github/workflows/functional-dns.yaml +++ b/.github/workflows/functional-dns.yaml @@ -31,7 +31,7 @@ jobs: additional_services: "openstack-cli-server" - name: "epoxy" openstack_version: "stable/2025.1" - ubuntu_version: "22.04" + ubuntu_version: "24.04" additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" diff --git a/.github/workflows/functional-fwaas_v2.yaml b/.github/workflows/functional-fwaas_v2.yaml index ab0b620fd3..4b0363bdfb 100644 --- a/.github/workflows/functional-fwaas_v2.yaml +++ b/.github/workflows/functional-fwaas_v2.yaml @@ -29,7 +29,7 @@ jobs: additional_services: "openstack-cli-server" - name: "epoxy" openstack_version: "stable/2025.1" - ubuntu_version: "22.04" + ubuntu_version: "24.04" additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" diff --git a/.github/workflows/functional-identity.yaml b/.github/workflows/functional-identity.yaml index 5438372081..4c235d9dcc 100644 --- a/.github/workflows/functional-identity.yaml +++ b/.github/workflows/functional-identity.yaml @@ -25,7 +25,7 @@ jobs: additional_services: "openstack-cli-server" - name: "epoxy" openstack_version: "stable/2025.1" - ubuntu_version: "22.04" + ubuntu_version: "24.04" additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" diff --git a/.github/workflows/functional-image.yaml b/.github/workflows/functional-image.yaml index b20d7584f4..a7ad202bc0 100644 --- a/.github/workflows/functional-image.yaml +++ b/.github/workflows/functional-image.yaml @@ -25,7 +25,7 @@ jobs: additional_services: "openstack-cli-server" - name: "epoxy" openstack_version: "stable/2025.1" - ubuntu_version: "22.04" + ubuntu_version: "24.04" additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" diff --git a/.github/workflows/functional-keymanager.yaml b/.github/workflows/functional-keymanager.yaml index bac49fef6e..d452b149ce 100644 --- a/.github/workflows/functional-keymanager.yaml +++ b/.github/workflows/functional-keymanager.yaml @@ -31,7 +31,7 @@ jobs: additional_services: "openstack-cli-server" - name: "epoxy" openstack_version: "stable/2025.1" - ubuntu_version: "22.04" + ubuntu_version: "24.04" devstack_conf_overrides: | # ensure we're using a working version of setuptools if [ -n "\$TOP_DIR" ]; then diff --git a/.github/workflows/functional-loadbalancer.yaml b/.github/workflows/functional-loadbalancer.yaml index b1a4f5d2d5..83b73c0b6b 100644 --- a/.github/workflows/functional-loadbalancer.yaml +++ b/.github/workflows/functional-loadbalancer.yaml @@ -31,7 +31,7 @@ jobs: additional_services: "openstack-cli-server" - name: "epoxy" openstack_version: "stable/2025.1" - ubuntu_version: "22.04" + ubuntu_version: "24.04" additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" diff --git a/.github/workflows/functional-messaging.yaml b/.github/workflows/functional-messaging.yaml index 55c0566df1..088b3c9e5a 100644 --- a/.github/workflows/functional-messaging.yaml +++ b/.github/workflows/functional-messaging.yaml @@ -25,7 +25,7 @@ jobs: additional_services: "openstack-cli-server" - name: "epoxy" openstack_version: "stable/2025.1" - ubuntu_version: "22.04" + ubuntu_version: "24.04" additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" diff --git a/.github/workflows/functional-networking.yaml b/.github/workflows/functional-networking.yaml index c8a3282ff6..3e8b39185f 100644 --- a/.github/workflows/functional-networking.yaml +++ b/.github/workflows/functional-networking.yaml @@ -25,7 +25,7 @@ jobs: additional_services: "openstack-cli-server" - name: "epoxy" openstack_version: "stable/2025.1" - ubuntu_version: "22.04" + ubuntu_version: "24.04" additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" diff --git a/.github/workflows/functional-objectstorage.yaml b/.github/workflows/functional-objectstorage.yaml index 80d2865910..0e51ef043e 100644 --- a/.github/workflows/functional-objectstorage.yaml +++ b/.github/workflows/functional-objectstorage.yaml @@ -25,7 +25,7 @@ jobs: additional_services: "openstack-cli-server" - name: "epoxy" openstack_version: "stable/2025.1" - ubuntu_version: "22.04" + ubuntu_version: "24.04" additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" diff --git a/.github/workflows/functional-orchestration.yaml b/.github/workflows/functional-orchestration.yaml index f29c5f1f00..adfcdcb8df 100644 --- a/.github/workflows/functional-orchestration.yaml +++ b/.github/workflows/functional-orchestration.yaml @@ -25,7 +25,7 @@ jobs: additional_services: "openstack-cli-server" - name: "epoxy" openstack_version: "stable/2025.1" - ubuntu_version: "22.04" + ubuntu_version: "24.04" additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" diff --git a/.github/workflows/functional-placement.yaml b/.github/workflows/functional-placement.yaml index 8ef04ac178..88c59d9b73 100644 --- a/.github/workflows/functional-placement.yaml +++ b/.github/workflows/functional-placement.yaml @@ -25,7 +25,7 @@ jobs: additional_services: "openstack-cli-server" - name: "epoxy" openstack_version: "stable/2025.1" - ubuntu_version: "22.04" + ubuntu_version: "24.04" additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" diff --git a/.github/workflows/functional-sharedfilesystems.yaml b/.github/workflows/functional-sharedfilesystems.yaml index 59b9d360e0..8843a0bc75 100644 --- a/.github/workflows/functional-sharedfilesystems.yaml +++ b/.github/workflows/functional-sharedfilesystems.yaml @@ -31,7 +31,7 @@ jobs: additional_services: "openstack-cli-server" - name: "epoxy" openstack_version: "stable/2025.1" - ubuntu_version: "22.04" + ubuntu_version: "24.04" additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" diff --git a/.github/workflows/functional-workflow.yaml b/.github/workflows/functional-workflow.yaml index 47f45bae71..9c85312219 100644 --- a/.github/workflows/functional-workflow.yaml +++ b/.github/workflows/functional-workflow.yaml @@ -26,7 +26,7 @@ jobs: additional_services: "openstack-cli-server" - name: "epoxy" openstack_version: "stable/2025.1" - ubuntu_version: "22.04" + ubuntu_version: "24.04" mistral_plugin_version: "stable/2025.1" additional_services: "openstack-cli-server" - name: "dalmatian" From 49716ec316b8d98de7ef64be165d1c58ea28d4a5 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Thu, 30 Oct 2025 12:23:39 +0000 Subject: [PATCH 217/353] Drop Caracal jobs This is now EOL. Signed-off-by: Stephen Finucane (cherry picked from commit 06ae96c3995f6d4718e0d507055aef43cf118428) --- .github/workflows/functional-baremetal.yaml | 4 ---- .github/workflows/functional-basic.yaml | 4 ---- .github/workflows/functional-blockstorage.yaml | 4 ---- .github/workflows/functional-compute.yaml | 4 ---- .github/workflows/functional-containerinfra.yaml | 7 ------- .github/workflows/functional-dns.yaml | 4 ---- .github/workflows/functional-fwaas_v2.yaml | 4 ---- .github/workflows/functional-identity.yaml | 4 ---- .github/workflows/functional-image.yaml | 4 ---- .github/workflows/functional-keymanager.yaml | 4 ---- .github/workflows/functional-loadbalancer.yaml | 4 ---- .github/workflows/functional-messaging.yaml | 4 ---- .github/workflows/functional-networking.yaml | 4 ---- .github/workflows/functional-objectstorage.yaml | 4 ---- .github/workflows/functional-orchestration.yaml | 4 ---- .github/workflows/functional-placement.yaml | 4 ---- .github/workflows/functional-sharedfilesystems.yaml | 4 ---- .github/workflows/functional-workflow.yaml | 5 ----- 18 files changed, 76 deletions(-) diff --git a/.github/workflows/functional-baremetal.yaml b/.github/workflows/functional-baremetal.yaml index bf350e9aef..87d58247f0 100644 --- a/.github/workflows/functional-baremetal.yaml +++ b/.github/workflows/functional-baremetal.yaml @@ -31,10 +31,6 @@ jobs: openstack_version: "stable/2024.2" ubuntu_version: "22.04" additional_services: "openstack-cli-server" - - name: "caracal" - openstack_version: "stable/2024.1" - ubuntu_version: "22.04" - additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Ironic on OpenStack ${{ matrix.name }} steps: diff --git a/.github/workflows/functional-basic.yaml b/.github/workflows/functional-basic.yaml index 28dd6dc9c0..0b1070793a 100644 --- a/.github/workflows/functional-basic.yaml +++ b/.github/workflows/functional-basic.yaml @@ -26,10 +26,6 @@ jobs: openstack_version: "stable/2024.2" ubuntu_version: "22.04" additional_services: "openstack-cli-server" - - name: "caracal" - openstack_version: "stable/2024.1" - ubuntu_version: "22.04" - additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: basic tests on OpenStack ${{ matrix.name }} steps: diff --git a/.github/workflows/functional-blockstorage.yaml b/.github/workflows/functional-blockstorage.yaml index 7708e2360e..02c195aad8 100644 --- a/.github/workflows/functional-blockstorage.yaml +++ b/.github/workflows/functional-blockstorage.yaml @@ -31,10 +31,6 @@ jobs: openstack_version: "stable/2024.2" ubuntu_version: "22.04" additional_services: "openstack-cli-server" - - name: "caracal" - openstack_version: "stable/2024.1" - ubuntu_version: "22.04" - additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Cinder on OpenStack ${{ matrix.name }} steps: diff --git a/.github/workflows/functional-compute.yaml b/.github/workflows/functional-compute.yaml index 86f5f0de12..536db87288 100644 --- a/.github/workflows/functional-compute.yaml +++ b/.github/workflows/functional-compute.yaml @@ -31,10 +31,6 @@ jobs: openstack_version: "stable/2024.2" ubuntu_version: "22.04" additional_services: "openstack-cli-server" - - name: "caracal" - openstack_version: "stable/2024.1" - ubuntu_version: "22.04" - additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Nova on OpenStack ${{ matrix.name }} steps: diff --git a/.github/workflows/functional-containerinfra.yaml b/.github/workflows/functional-containerinfra.yaml index eb4d1bcb16..2d7c19aa2f 100644 --- a/.github/workflows/functional-containerinfra.yaml +++ b/.github/workflows/functional-containerinfra.yaml @@ -52,13 +52,6 @@ jobs: enable_plugin magnum https://github.com/openstack/magnum stable/2024.2 MAGNUMCLIENT_BRANCH=stable/2024.2 additional_services: "openstack-cli-server" - - name: "caracal" - openstack_version: "stable/2024.1" - ubuntu_version: "22.04" - devstack_conf_overrides: | - enable_plugin magnum https://github.com/openstack/magnum stable/2024.1 - MAGNUMCLIENT_BRANCH=stable/2024.1 - additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Magnum on OpenStack ${{ matrix.name }} steps: diff --git a/.github/workflows/functional-dns.yaml b/.github/workflows/functional-dns.yaml index 2d5600dd69..7c4158c351 100644 --- a/.github/workflows/functional-dns.yaml +++ b/.github/workflows/functional-dns.yaml @@ -37,10 +37,6 @@ jobs: openstack_version: "stable/2024.2" ubuntu_version: "22.04" additional_services: "openstack-cli-server" - - name: "caracal" - openstack_version: "stable/2024.1" - ubuntu_version: "22.04" - additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Designate on OpenStack ${{ matrix.name }} steps: diff --git a/.github/workflows/functional-fwaas_v2.yaml b/.github/workflows/functional-fwaas_v2.yaml index 4b0363bdfb..80f1ed774c 100644 --- a/.github/workflows/functional-fwaas_v2.yaml +++ b/.github/workflows/functional-fwaas_v2.yaml @@ -35,10 +35,6 @@ jobs: openstack_version: "stable/2024.2" ubuntu_version: "22.04" additional_services: "openstack-cli-server" - - name: "caracal" - openstack_version: "stable/2024.1" - ubuntu_version: "22.04" - additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: FWaaS_v2 on OpenStack ${{ matrix.name }} steps: diff --git a/.github/workflows/functional-identity.yaml b/.github/workflows/functional-identity.yaml index 4c235d9dcc..7c6354ab9d 100644 --- a/.github/workflows/functional-identity.yaml +++ b/.github/workflows/functional-identity.yaml @@ -31,10 +31,6 @@ jobs: openstack_version: "stable/2024.2" ubuntu_version: "22.04" additional_services: "openstack-cli-server" - - name: "caracal" - openstack_version: "stable/2024.1" - ubuntu_version: "22.04" - additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Keystone on OpenStack ${{ matrix.name }} steps: diff --git a/.github/workflows/functional-image.yaml b/.github/workflows/functional-image.yaml index a7ad202bc0..ca6ec505e4 100644 --- a/.github/workflows/functional-image.yaml +++ b/.github/workflows/functional-image.yaml @@ -31,10 +31,6 @@ jobs: openstack_version: "stable/2024.2" ubuntu_version: "22.04" additional_services: "openstack-cli-server" - - name: "caracal" - openstack_version: "stable/2024.1" - ubuntu_version: "22.04" - additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Glance on OpenStack ${{ matrix.name }} steps: diff --git a/.github/workflows/functional-keymanager.yaml b/.github/workflows/functional-keymanager.yaml index d452b149ce..8b8ddf0280 100644 --- a/.github/workflows/functional-keymanager.yaml +++ b/.github/workflows/functional-keymanager.yaml @@ -43,10 +43,6 @@ jobs: openstack_version: "stable/2024.2" ubuntu_version: "22.04" additional_services: "openstack-cli-server" - - name: "caracal" - openstack_version: "stable/2024.1" - ubuntu_version: "22.04" - additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Barbican on OpenStack ${{ matrix.name }} steps: diff --git a/.github/workflows/functional-loadbalancer.yaml b/.github/workflows/functional-loadbalancer.yaml index 83b73c0b6b..a5673a8f3e 100644 --- a/.github/workflows/functional-loadbalancer.yaml +++ b/.github/workflows/functional-loadbalancer.yaml @@ -37,10 +37,6 @@ jobs: openstack_version: "stable/2024.2" ubuntu_version: "22.04" additional_services: "openstack-cli-server" - - name: "caracal" - openstack_version: "stable/2024.1" - ubuntu_version: "22.04" - additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Octavia on OpenStack ${{ matrix.name }} steps: diff --git a/.github/workflows/functional-messaging.yaml b/.github/workflows/functional-messaging.yaml index 088b3c9e5a..865491e98e 100644 --- a/.github/workflows/functional-messaging.yaml +++ b/.github/workflows/functional-messaging.yaml @@ -31,10 +31,6 @@ jobs: openstack_version: "stable/2024.2" ubuntu_version: "22.04" additional_services: "openstack-cli-server" - - name: "caracal" - openstack_version: "stable/2024.1" - ubuntu_version: "22.04" - additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Zaqar on OpenStack ${{ matrix.name }} steps: diff --git a/.github/workflows/functional-networking.yaml b/.github/workflows/functional-networking.yaml index 3e8b39185f..093de0c8df 100644 --- a/.github/workflows/functional-networking.yaml +++ b/.github/workflows/functional-networking.yaml @@ -31,10 +31,6 @@ jobs: openstack_version: "stable/2024.2" ubuntu_version: "22.04" additional_services: "openstack-cli-server" - - name: "caracal" - openstack_version: "stable/2024.1" - ubuntu_version: "22.04" - additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Neutron on OpenStack ${{ matrix.name }} steps: diff --git a/.github/workflows/functional-objectstorage.yaml b/.github/workflows/functional-objectstorage.yaml index 0e51ef043e..75e74a811e 100644 --- a/.github/workflows/functional-objectstorage.yaml +++ b/.github/workflows/functional-objectstorage.yaml @@ -31,10 +31,6 @@ jobs: openstack_version: "stable/2024.2" ubuntu_version: "22.04" additional_services: "openstack-cli-server" - - name: "caracal" - openstack_version: "stable/2024.1" - ubuntu_version: "22.04" - additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Swift on OpenStack ${{ matrix.name }} steps: diff --git a/.github/workflows/functional-orchestration.yaml b/.github/workflows/functional-orchestration.yaml index adfcdcb8df..9d06954c0d 100644 --- a/.github/workflows/functional-orchestration.yaml +++ b/.github/workflows/functional-orchestration.yaml @@ -31,10 +31,6 @@ jobs: openstack_version: "stable/2024.2" ubuntu_version: "22.04" additional_services: "openstack-cli-server" - - name: "caracal" - openstack_version: "stable/2024.1" - ubuntu_version: "22.04" - additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Heat on OpenStack ${{ matrix.name }} steps: diff --git a/.github/workflows/functional-placement.yaml b/.github/workflows/functional-placement.yaml index 88c59d9b73..1fa6e9c93f 100644 --- a/.github/workflows/functional-placement.yaml +++ b/.github/workflows/functional-placement.yaml @@ -31,10 +31,6 @@ jobs: openstack_version: "stable/2024.2" ubuntu_version: "22.04" additional_services: "openstack-cli-server" - - name: "caracal" - openstack_version: "stable/2024.1" - ubuntu_version: "22.04" - additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Placement on OpenStack ${{ matrix.name }} steps: diff --git a/.github/workflows/functional-sharedfilesystems.yaml b/.github/workflows/functional-sharedfilesystems.yaml index 8843a0bc75..8395d38917 100644 --- a/.github/workflows/functional-sharedfilesystems.yaml +++ b/.github/workflows/functional-sharedfilesystems.yaml @@ -37,10 +37,6 @@ jobs: openstack_version: "stable/2024.2" ubuntu_version: "22.04" additional_services: "openstack-cli-server" - - name: "caracal" - openstack_version: "stable/2024.1" - ubuntu_version: "22.04" - additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Manila on OpenStack ${{ matrix.name }} steps: diff --git a/.github/workflows/functional-workflow.yaml b/.github/workflows/functional-workflow.yaml index 9c85312219..e3ac049bea 100644 --- a/.github/workflows/functional-workflow.yaml +++ b/.github/workflows/functional-workflow.yaml @@ -34,11 +34,6 @@ jobs: ubuntu_version: "22.04" mistral_plugin_version: "stable/2024.2" additional_services: "openstack-cli-server" - - name: "caracal" - openstack_version: "stable/2024.1" - ubuntu_version: "22.04" - mistral_plugin_version: "stable/2024.1" - additional_services: "" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Mistral on Deploy OpenStack ${{ matrix.name }} steps: From 2ad301b8f5859f6a71ecb1c8c29634e61dead669 Mon Sep 17 00:00:00 2001 From: Vladimir Ermakov Date: Fri, 31 Oct 2025 10:47:00 +0100 Subject: [PATCH 218/353] compute: add cpu info topology cells entry Fix #3545 Signed-off-by: Vladimir Ermakov --- openstack/compute/v2/hypervisors/results.go | 1 + 1 file changed, 1 insertion(+) diff --git a/openstack/compute/v2/hypervisors/results.go b/openstack/compute/v2/hypervisors/results.go index 0a35dfdf0f..c73f239cd6 100644 --- a/openstack/compute/v2/hypervisors/results.go +++ b/openstack/compute/v2/hypervisors/results.go @@ -11,6 +11,7 @@ import ( // Topology represents a CPU Topology. type Topology struct { + Cells int `json:"cells"` Sockets int `json:"sockets"` Cores int `json:"cores"` Threads int `json:"threads"` From b45062ee82bc18506030d14db5df5b919c464cc3 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Thu, 30 Oct 2025 12:24:34 +0000 Subject: [PATCH 219/353] Always enable openstack-cli-server All tested versions of OpenStack now support this allowing us to simplify our jobs. Conflicts: .github/workflows/functional-baremetal.yaml .github/workflows/functional-basic.yaml .github/workflows/functional-blockstorage.yaml .github/workflows/functional-compute.yaml .github/workflows/functional-containerinfra.yaml .github/workflows/functional-dns.yaml .github/workflows/functional-fwaas_v2.yaml .github/workflows/functional-identity.yaml .github/workflows/functional-image.yaml .github/workflows/functional-keymanager.yaml .github/workflows/functional-loadbalancer.yaml .github/workflows/functional-messaging.yaml .github/workflows/functional-networking.yaml .github/workflows/functional-objectstorage.yaml .github/workflows/functional-orchestration.yaml .github/workflows/functional-placement.yaml .github/workflows/functional-sharedfilesystems.yaml .github/workflows/functional-workflow.yaml NOTE(stephenfin): Conflicts are due to a newline that is present on main but missing here. Signed-off-by: Stephen Finucane (cherry picked from commit 3260d638cc43cfa067de33d2c2790149db2cd538) --- .github/workflows/functional-baremetal.yaml | 7 ++----- .github/workflows/functional-basic.yaml | 5 +---- .github/workflows/functional-blockstorage.yaml | 5 +---- .github/workflows/functional-compute.yaml | 5 +---- .github/workflows/functional-containerinfra.yaml | 5 +---- .github/workflows/functional-dns.yaml | 5 +---- .github/workflows/functional-fwaas_v2.yaml | 5 +---- .github/workflows/functional-identity.yaml | 5 +---- .github/workflows/functional-image.yaml | 5 +---- .github/workflows/functional-keymanager.yaml | 5 +---- .github/workflows/functional-loadbalancer.yaml | 5 +---- .github/workflows/functional-messaging.yaml | 5 +---- .github/workflows/functional-networking.yaml | 5 +---- .github/workflows/functional-objectstorage.yaml | 5 +---- .github/workflows/functional-orchestration.yaml | 5 +---- .github/workflows/functional-placement.yaml | 5 +---- .github/workflows/functional-sharedfilesystems.yaml | 5 +---- .github/workflows/functional-workflow.yaml | 5 +---- 18 files changed, 19 insertions(+), 73 deletions(-) diff --git a/.github/workflows/functional-baremetal.yaml b/.github/workflows/functional-baremetal.yaml index 87d58247f0..9bc2a44a5e 100644 --- a/.github/workflows/functional-baremetal.yaml +++ b/.github/workflows/functional-baremetal.yaml @@ -22,15 +22,12 @@ jobs: - name: "master" openstack_version: "master" ubuntu_version: "24.04" - additional_services: "openstack-cli-server" - name: "epoxy" openstack_version: "stable/2025.1" - ubuntu_version: "22.04" - additional_services: "openstack-cli-server" + ubuntu_version: "24.04" - name: "dalmatian" openstack_version: "stable/2024.2" ubuntu_version: "22.04" - additional_services: "openstack-cli-server" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Ironic on OpenStack ${{ matrix.name }} steps: @@ -76,7 +73,7 @@ jobs: IRONIC_ENABLED_DEPLOY_INTERFACES=direct,fake SWIFT_ENABLE_TEMPURLS=True SWIFT_TEMPURL_KEY=secretkey - enabled_services: "ir-api,ir-cond,s-account,s-container,s-object,s-proxy,q-svc,q-agt,q-dhcp,q-l3,q-meta,-cinder,-c-sch,-c-api,-c-vol,-c-bak,-ovn,-ovn-controller,-ovn-northd,-q-ovn-metadata-agent,${{ matrix.additional_services }}" + enabled_services: "ir-api,ir-cond,s-account,s-container,s-object,s-proxy,q-svc,q-agt,q-dhcp,q-l3,q-meta,-cinder,-c-sch,-c-api,-c-vol,-c-bak,-ovn,-ovn-controller,-ovn-northd,-q-ovn-metadata-agent,openstack-cli-server" - name: Checkout go uses: actions/setup-go@v5 with: diff --git a/.github/workflows/functional-basic.yaml b/.github/workflows/functional-basic.yaml index 0b1070793a..4f0175b5df 100644 --- a/.github/workflows/functional-basic.yaml +++ b/.github/workflows/functional-basic.yaml @@ -17,15 +17,12 @@ jobs: - name: "master" openstack_version: "master" ubuntu_version: "24.04" - additional_services: "openstack-cli-server" - name: "epoxy" openstack_version: "stable/2025.1" ubuntu_version: "24.04" - additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" ubuntu_version: "22.04" - additional_services: "openstack-cli-server" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: basic tests on OpenStack ${{ matrix.name }} steps: @@ -35,7 +32,7 @@ jobs: uses: gophercloud/devstack-action@v0.19 with: branch: ${{ matrix.openstack_version }} - enabled_services: 's-account,s-container,s-object,s-proxy,${{ matrix.additional_services }}' + enabled_services: 's-account,s-container,s-object,s-proxy,openstack-cli-server' - name: Checkout go uses: actions/setup-go@v5 with: diff --git a/.github/workflows/functional-blockstorage.yaml b/.github/workflows/functional-blockstorage.yaml index 02c195aad8..fa64f8a1c0 100644 --- a/.github/workflows/functional-blockstorage.yaml +++ b/.github/workflows/functional-blockstorage.yaml @@ -22,15 +22,12 @@ jobs: - name: "master" openstack_version: "master" ubuntu_version: "24.04" - additional_services: "openstack-cli-server" - name: "epoxy" openstack_version: "stable/2025.1" ubuntu_version: "24.04" - additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" ubuntu_version: "22.04" - additional_services: "openstack-cli-server" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Cinder on OpenStack ${{ matrix.name }} steps: @@ -42,7 +39,7 @@ jobs: branch: ${{ matrix.openstack_version }} conf_overrides: | CINDER_ISCSI_HELPER=lioadm - enabled_services: "s-account,s-container,s-object,s-proxy,c-bak,${{ matrix.additional_services }}" + enabled_services: "s-account,s-container,s-object,s-proxy,c-bak,openstack-cli-server" - name: Checkout go uses: actions/setup-go@v5 with: diff --git a/.github/workflows/functional-compute.yaml b/.github/workflows/functional-compute.yaml index 536db87288..a82177740a 100644 --- a/.github/workflows/functional-compute.yaml +++ b/.github/workflows/functional-compute.yaml @@ -22,15 +22,12 @@ jobs: - name: "master" openstack_version: "master" ubuntu_version: "24.04" - additional_services: "openstack-cli-server" - name: "epoxy" openstack_version: "stable/2025.1" ubuntu_version: "24.04" - additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" ubuntu_version: "22.04" - additional_services: "openstack-cli-server" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Nova on OpenStack ${{ matrix.name }} steps: @@ -42,7 +39,7 @@ jobs: branch: ${{ matrix.openstack_version }} conf_overrides: | CINDER_ISCSI_HELPER=lioadm - enabled_services: "${{ matrix.additional_services }}" + enabled_services: "openstack-cli-server" - name: Checkout go uses: actions/setup-go@v5 with: diff --git a/.github/workflows/functional-containerinfra.yaml b/.github/workflows/functional-containerinfra.yaml index 2d7c19aa2f..088c97ae45 100644 --- a/.github/workflows/functional-containerinfra.yaml +++ b/.github/workflows/functional-containerinfra.yaml @@ -31,7 +31,6 @@ jobs: enable_plugin magnum https://github.com/openstack/magnum master MAGNUMCLIENT_BRANCH=master - additional_services: "openstack-cli-server" - name: "epoxy" openstack_version: "stable/2025.1" ubuntu_version: "24.04" @@ -44,14 +43,12 @@ jobs: enable_plugin magnum https://github.com/openstack/magnum stable/2025.1 MAGNUMCLIENT_BRANCH=stable/2025.1 - additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" ubuntu_version: "22.04" devstack_conf_overrides: | enable_plugin magnum https://github.com/openstack/magnum stable/2024.2 MAGNUMCLIENT_BRANCH=stable/2024.2 - additional_services: "openstack-cli-server" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Magnum on OpenStack ${{ matrix.name }} steps: @@ -69,7 +66,7 @@ jobs: KEYSTONE_ADMIN_ENDPOINT=true ${{ matrix.devstack_conf_overrides }} - enabled_services: "h-eng,h-api,h-api-cfn,h-api-cw,${{ matrix.additional_services }}" + enabled_services: "h-eng,h-api,h-api-cfn,h-api-cw,openstack-cli-server" - name: Checkout go uses: actions/setup-go@v5 with: diff --git a/.github/workflows/functional-dns.yaml b/.github/workflows/functional-dns.yaml index 7c4158c351..d5f3cac514 100644 --- a/.github/workflows/functional-dns.yaml +++ b/.github/workflows/functional-dns.yaml @@ -28,15 +28,12 @@ jobs: sed -i 's/setuptools\[core\]$/setuptools[core]==79.0.1/g' \$TOP_DIR/lib/infra \$TOP_DIR/inc/python sed -i 's/pip_install "-U" "pbr"/pip_install "-U" "pbr" "setuptools[core]==79.0.1"/g' \$TOP_DIR/lib/infra fi - additional_services: "openstack-cli-server" - name: "epoxy" openstack_version: "stable/2025.1" ubuntu_version: "24.04" - additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" ubuntu_version: "22.04" - additional_services: "openstack-cli-server" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Designate on OpenStack ${{ matrix.name }} steps: @@ -50,7 +47,7 @@ jobs: enable_plugin designate https://github.com/openstack/designate ${{ matrix.openstack_version }} ${{ matrix.devstack_conf_overrides }} - enabled_services: "designate,designate-central,designate-api,designate-worker,designate-producer,designate-mdns,${{ matrix.additional_services }}" + enabled_services: "designate,designate-central,designate-api,designate-worker,designate-producer,designate-mdns,openstack-cli-server" - name: Checkout go uses: actions/setup-go@v5 with: diff --git a/.github/workflows/functional-fwaas_v2.yaml b/.github/workflows/functional-fwaas_v2.yaml index 80f1ed774c..a9f603430e 100644 --- a/.github/workflows/functional-fwaas_v2.yaml +++ b/.github/workflows/functional-fwaas_v2.yaml @@ -26,15 +26,12 @@ jobs: - name: "master" openstack_version: "master" ubuntu_version: "24.04" - additional_services: "openstack-cli-server" - name: "epoxy" openstack_version: "stable/2025.1" ubuntu_version: "24.04" - additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" ubuntu_version: "22.04" - additional_services: "openstack-cli-server" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: FWaaS_v2 on OpenStack ${{ matrix.name }} steps: @@ -63,7 +60,7 @@ jobs: [[post-config|\$NEUTRON_CONF]] [oslo_policy] policy_dirs = /tmp/neutron-policies - enabled_services: 'q-svc,q-agt,q-dhcp,q-l3,q-meta,q-fwaas-v2,-cinder,-horizon,-tempest,-swift,-c-sch,-c-api,-c-vol,-c-bak,-ovn,-ovn-controller,-ovn-northd,-q-ovn-metadata-agent,${{ matrix.additional_services }}' + enabled_services: 'q-svc,q-agt,q-dhcp,q-l3,q-meta,q-fwaas-v2,-cinder,-horizon,-tempest,-swift,-c-sch,-c-api,-c-vol,-c-bak,-ovn,-ovn-controller,-ovn-northd,-q-ovn-metadata-agent,openstack-cli-server' - name: Checkout go uses: actions/setup-go@v5 with: diff --git a/.github/workflows/functional-identity.yaml b/.github/workflows/functional-identity.yaml index 7c6354ab9d..bbbe99b446 100644 --- a/.github/workflows/functional-identity.yaml +++ b/.github/workflows/functional-identity.yaml @@ -22,15 +22,12 @@ jobs: - name: "master" openstack_version: "master" ubuntu_version: "24.04" - additional_services: "openstack-cli-server" - name: "epoxy" openstack_version: "stable/2025.1" ubuntu_version: "24.04" - additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" ubuntu_version: "22.04" - additional_services: "openstack-cli-server" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Keystone on OpenStack ${{ matrix.name }} steps: @@ -40,7 +37,7 @@ jobs: uses: gophercloud/devstack-action@v0.19 with: branch: ${{ matrix.openstack_version }} - enabled_services: "${{ matrix.additional_services }}" + enabled_services: "openstack-cli-server" - name: Checkout go uses: actions/setup-go@v5 with: diff --git a/.github/workflows/functional-image.yaml b/.github/workflows/functional-image.yaml index ca6ec505e4..39a3dd681c 100644 --- a/.github/workflows/functional-image.yaml +++ b/.github/workflows/functional-image.yaml @@ -22,15 +22,12 @@ jobs: - name: "master" openstack_version: "master" ubuntu_version: "24.04" - additional_services: "openstack-cli-server" - name: "epoxy" openstack_version: "stable/2025.1" ubuntu_version: "24.04" - additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" ubuntu_version: "22.04" - additional_services: "openstack-cli-server" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Glance on OpenStack ${{ matrix.name }} steps: @@ -40,7 +37,7 @@ jobs: uses: gophercloud/devstack-action@v0.19 with: branch: ${{ matrix.openstack_version }} - enabled_services: "${{ matrix.additional_services }}" + enabled_services: "openstack-cli-server" - name: Checkout go uses: actions/setup-go@v5 with: diff --git a/.github/workflows/functional-keymanager.yaml b/.github/workflows/functional-keymanager.yaml index 8b8ddf0280..01e57bd3e7 100644 --- a/.github/workflows/functional-keymanager.yaml +++ b/.github/workflows/functional-keymanager.yaml @@ -28,7 +28,6 @@ jobs: sed -i 's/setuptools\[core\]$/setuptools[core]==79.0.1/g' \$TOP_DIR/lib/infra \$TOP_DIR/inc/python sed -i 's/pip_install "-U" "pbr"/pip_install "-U" "pbr" "setuptools[core]==79.0.1"/g' \$TOP_DIR/lib/infra fi - additional_services: "openstack-cli-server" - name: "epoxy" openstack_version: "stable/2025.1" ubuntu_version: "24.04" @@ -38,11 +37,9 @@ jobs: sed -i 's/setuptools\[core\]$/setuptools[core]==79.0.1/g' \$TOP_DIR/lib/infra \$TOP_DIR/inc/python sed -i 's/pip_install "-U" "pbr"/pip_install "-U" "pbr" "setuptools[core]==79.0.1"/g' \$TOP_DIR/lib/infra fi - additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" ubuntu_version: "22.04" - additional_services: "openstack-cli-server" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Barbican on OpenStack ${{ matrix.name }} steps: @@ -56,7 +53,7 @@ jobs: enable_plugin barbican https://github.com/openstack/barbican ${{ matrix.openstack_version }} ${{ matrix.devstack_conf_overrides }} - enabled_services: "barbican-svc,barbican-retry,barbican-keystone-listener,${{ matrix.additional_services }}" + enabled_services: "barbican-svc,barbican-retry,barbican-keystone-listener,openstack-cli-server" - name: Checkout go uses: actions/setup-go@v5 with: diff --git a/.github/workflows/functional-loadbalancer.yaml b/.github/workflows/functional-loadbalancer.yaml index a5673a8f3e..7880244f05 100644 --- a/.github/workflows/functional-loadbalancer.yaml +++ b/.github/workflows/functional-loadbalancer.yaml @@ -28,15 +28,12 @@ jobs: sed -i 's/setuptools\[core\]$/setuptools[core]==79.0.1/g' \$TOP_DIR/lib/infra \$TOP_DIR/inc/python sed -i 's/pip_install "-U" "pbr"/pip_install "-U" "pbr" "setuptools[core]==79.0.1"/g' \$TOP_DIR/lib/infra fi - additional_services: "openstack-cli-server" - name: "epoxy" openstack_version: "stable/2025.1" ubuntu_version: "24.04" - additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" ubuntu_version: "22.04" - additional_services: "openstack-cli-server" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Octavia on OpenStack ${{ matrix.name }} steps: @@ -51,7 +48,7 @@ jobs: enable_plugin neutron https://github.com/openstack/neutron ${{ matrix.openstack_version }} ${{ matrix.devstack_conf_overrides }} - enabled_services: "octavia,o-api,o-cw,o-hk,o-hm,o-da,neutron-qos,${{ matrix.additional_services }}" + enabled_services: "octavia,o-api,o-cw,o-hk,o-hm,o-da,neutron-qos,openstack-cli-server" - name: Checkout go uses: actions/setup-go@v5 with: diff --git a/.github/workflows/functional-messaging.yaml b/.github/workflows/functional-messaging.yaml index 865491e98e..0f099084a4 100644 --- a/.github/workflows/functional-messaging.yaml +++ b/.github/workflows/functional-messaging.yaml @@ -22,15 +22,12 @@ jobs: - name: "master" openstack_version: "master" ubuntu_version: "24.04" - additional_services: "openstack-cli-server" - name: "epoxy" openstack_version: "stable/2025.1" ubuntu_version: "24.04" - additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" ubuntu_version: "22.04" - additional_services: "openstack-cli-server" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Zaqar on OpenStack ${{ matrix.name }} steps: @@ -43,7 +40,7 @@ jobs: conf_overrides: | enable_plugin zaqar https://github.com/openstack/zaqar ${{ matrix.openstack_version }} ZAQARCLIENT_BRANCH=${{ matrix.openstack_version }} - enabled_services: "${{ matrix.additional_services }}" + enabled_services: "openstack-cli-server" - name: Checkout go uses: actions/setup-go@v5 with: diff --git a/.github/workflows/functional-networking.yaml b/.github/workflows/functional-networking.yaml index 093de0c8df..efe7743a10 100644 --- a/.github/workflows/functional-networking.yaml +++ b/.github/workflows/functional-networking.yaml @@ -22,15 +22,12 @@ jobs: - name: "master" openstack_version: "master" ubuntu_version: "24.04" - additional_services: "openstack-cli-server" - name: "epoxy" openstack_version: "stable/2025.1" ubuntu_version: "24.04" - additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" ubuntu_version: "22.04" - additional_services: "openstack-cli-server" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Neutron on OpenStack ${{ matrix.name }} steps: @@ -58,7 +55,7 @@ jobs: [[post-config|\$NEUTRON_CONF]] [oslo_policy] policy_dirs = /tmp/neutron-policies - enabled_services: "neutron-dns,neutron-qos,neutron-segments,neutron-trunk,neutron-uplink-status-propagation,neutron-network-segment-range,neutron-port-forwarding,${{ matrix.additional_services }}" + enabled_services: "neutron-dns,neutron-qos,neutron-segments,neutron-trunk,neutron-uplink-status-propagation,neutron-network-segment-range,neutron-port-forwarding,openstack-cli-server" - name: Checkout go uses: actions/setup-go@v5 with: diff --git a/.github/workflows/functional-objectstorage.yaml b/.github/workflows/functional-objectstorage.yaml index 75e74a811e..d1b357d3b3 100644 --- a/.github/workflows/functional-objectstorage.yaml +++ b/.github/workflows/functional-objectstorage.yaml @@ -22,15 +22,12 @@ jobs: - name: "master" openstack_version: "master" ubuntu_version: "24.04" - additional_services: "openstack-cli-server" - name: "epoxy" openstack_version: "stable/2025.1" ubuntu_version: "24.04" - additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" ubuntu_version: "22.04" - additional_services: "openstack-cli-server" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Swift on OpenStack ${{ matrix.name }} steps: @@ -46,7 +43,7 @@ jobs: [[post-config|\$SWIFT_CONFIG_PROXY_SERVER]] [filter:versioned_writes] allow_object_versioning = true - enabled_services: 's-account,s-container,s-object,s-proxy,${{ matrix.additional_services }}' + enabled_services: 's-account,s-container,s-object,s-proxy,openstack-cli-server' - name: Checkout go uses: actions/setup-go@v5 with: diff --git a/.github/workflows/functional-orchestration.yaml b/.github/workflows/functional-orchestration.yaml index 9d06954c0d..402a21c330 100644 --- a/.github/workflows/functional-orchestration.yaml +++ b/.github/workflows/functional-orchestration.yaml @@ -22,15 +22,12 @@ jobs: - name: "master" openstack_version: "master" ubuntu_version: "24.04" - additional_services: "openstack-cli-server" - name: "epoxy" openstack_version: "stable/2025.1" ubuntu_version: "24.04" - additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" ubuntu_version: "22.04" - additional_services: "openstack-cli-server" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Heat on OpenStack ${{ matrix.name }} steps: @@ -42,7 +39,7 @@ jobs: branch: ${{ matrix.openstack_version }} conf_overrides: | enable_plugin heat https://github.com/openstack/heat ${{ matrix.openstack_version }} - enabled_services: 'h-eng,h-api,h-api-cfn,h-api-cw,${{ matrix.additional_services }}' + enabled_services: 'h-eng,h-api,h-api-cfn,h-api-cw,openstack-cli-server' - name: Checkout go uses: actions/setup-go@v5 with: diff --git a/.github/workflows/functional-placement.yaml b/.github/workflows/functional-placement.yaml index 1fa6e9c93f..4b14c2a2d1 100644 --- a/.github/workflows/functional-placement.yaml +++ b/.github/workflows/functional-placement.yaml @@ -22,15 +22,12 @@ jobs: - name: "master" openstack_version: "master" ubuntu_version: "24.04" - additional_services: "openstack-cli-server" - name: "epoxy" openstack_version: "stable/2025.1" ubuntu_version: "24.04" - additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" ubuntu_version: "22.04" - additional_services: "openstack-cli-server" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Placement on OpenStack ${{ matrix.name }} steps: @@ -40,7 +37,7 @@ jobs: uses: gophercloud/devstack-action@v0.19 with: branch: ${{ matrix.openstack_version }} - enabled_services: "${{ matrix.additional_services }}" + enabled_services: "openstack-cli-server" - name: Checkout go uses: actions/setup-go@v5 with: diff --git a/.github/workflows/functional-sharedfilesystems.yaml b/.github/workflows/functional-sharedfilesystems.yaml index 8395d38917..5a9b55d417 100644 --- a/.github/workflows/functional-sharedfilesystems.yaml +++ b/.github/workflows/functional-sharedfilesystems.yaml @@ -28,15 +28,12 @@ jobs: sed -i 's/setuptools\[core\]$/setuptools[core]==79.0.1/g' \$TOP_DIR/lib/infra \$TOP_DIR/inc/python sed -i 's/pip_install "-U" "pbr"/pip_install "-U" "pbr" "setuptools[core]==79.0.1"/g' \$TOP_DIR/lib/infra fi - additional_services: "openstack-cli-server" - name: "epoxy" openstack_version: "stable/2025.1" ubuntu_version: "24.04" - additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" ubuntu_version: "22.04" - additional_services: "openstack-cli-server" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Manila on OpenStack ${{ matrix.name }} steps: @@ -64,7 +61,7 @@ jobs: MANILA_INSTALL_TEMPEST_PLUGIN_SYSTEMWIDE=false ${{ matrix.devstack_conf_overrides }} - enabled_services: "${{ matrix.additional_services }}" + enabled_services: "openstack-cli-server" - name: Checkout go uses: actions/setup-go@v5 with: diff --git a/.github/workflows/functional-workflow.yaml b/.github/workflows/functional-workflow.yaml index e3ac049bea..b690d7f07b 100644 --- a/.github/workflows/functional-workflow.yaml +++ b/.github/workflows/functional-workflow.yaml @@ -23,17 +23,14 @@ jobs: openstack_version: "master" ubuntu_version: "24.04" mistral_plugin_version: "master" - additional_services: "openstack-cli-server" - name: "epoxy" openstack_version: "stable/2025.1" ubuntu_version: "24.04" mistral_plugin_version: "stable/2025.1" - additional_services: "openstack-cli-server" - name: "dalmatian" openstack_version: "stable/2024.2" ubuntu_version: "22.04" mistral_plugin_version: "stable/2024.2" - additional_services: "openstack-cli-server" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Mistral on Deploy OpenStack ${{ matrix.name }} steps: @@ -45,7 +42,7 @@ jobs: branch: ${{ matrix.openstack_version }} conf_overrides: | enable_plugin mistral https://github.com/openstack/mistral ${{ matrix.mistral_plugin_version }} - enabled_services: "mistral,mistral-api,mistral-engine,mistral-executor,mistral-event-engine,${{ matrix.additional_services }}" + enabled_services: "mistral,mistral-api,mistral-engine,mistral-executor,mistral-event-engine,openstack-cli-server" - name: Checkout go uses: actions/setup-go@v5 with: From 389d647d5967ab78b5c5154eb2bd30743c6afb46 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Nov 2025 12:45:36 +0000 Subject: [PATCH 220/353] build(deps): bump github/codeql-action from 3 to 4 Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3 to 4. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/v3...v4) --- updated-dependencies: - dependency-name: github/codeql-action dependency-version: '4' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/codeql-analysis.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql-analysis.yaml b/.github/workflows/codeql-analysis.yaml index 58952951c6..587f803f11 100644 --- a/.github/workflows/codeql-analysis.yaml +++ b/.github/workflows/codeql-analysis.yaml @@ -27,12 +27,12 @@ jobs: cache: true - name: Initialize CodeQL - uses: github/codeql-action/init@v3 + uses: github/codeql-action/init@v4 with: languages: ${{ matrix.language }} - name: Autobuild - uses: github/codeql-action/autobuild@v3 + uses: github/codeql-action/autobuild@v4 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v3 + uses: github/codeql-action/analyze@v4 From 891f073c82c88a903582501b5f857f5f26bbc40b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Andr=C3=A9?= Date: Fri, 14 Nov 2025 08:35:03 +0100 Subject: [PATCH 221/353] Fix EC2 authentication to work with new Keystone auth requirement Keystone recently changed to require authentication for the EC2 tokens endpoint [1]. Previously, the EC2 tokens endpoint could be accessed without authentication, but now it requires a valid token. Fixes #3555 [1] https://review.opendev.org/q/Ic84b84247e05f29874e2c5636a033aaedd4de83c --- internal/acceptance/openstack/client_test.go | 3 ++- openstack/identity/v3/ec2tokens/requests.go | 6 ++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/internal/acceptance/openstack/client_test.go b/internal/acceptance/openstack/client_test.go index 3b252a2853..4e87ff8ee2 100644 --- a/internal/acceptance/openstack/client_test.go +++ b/internal/acceptance/openstack/client_test.go @@ -94,7 +94,8 @@ func TestEC2AuthMethod(t *testing.T) { defer credentials.Delete(context.TODO(), client, credential.ID) tools.PrintResource(t, credential) - newClient, err := clients.NewIdentityV3UnauthenticatedClient() + // Create a new provider client for EC2 authentication using the existing token + newClient, err := clients.NewIdentityV3Client() th.AssertNoErr(t, err) ec2AuthOptions := &ec2tokens.AuthOptions{ diff --git a/openstack/identity/v3/ec2tokens/requests.go b/openstack/identity/v3/ec2tokens/requests.go index 5b1f3d6882..1d4cb54928 100644 --- a/openstack/identity/v3/ec2tokens/requests.go +++ b/openstack/identity/v3/ec2tokens/requests.go @@ -300,8 +300,7 @@ func Create(ctx context.Context, c *gophercloud.ServiceClient, opts tokens.AuthO deleteBodyElements(b, "token") resp, err := c.Post(ctx, ec2tokensURL(c), b, &r.Body, &gophercloud.RequestOpts{ - MoreHeaders: map[string]string{"X-Auth-Token": ""}, - OkCodes: []int{200}, + OkCodes: []int{200}, }) _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) return @@ -320,8 +319,7 @@ func ValidateS3Token(ctx context.Context, c *gophercloud.ServiceClient, opts tok deleteBodyElements(b, "body_hash", "headers", "host", "params", "path", "verb") resp, err := c.Post(ctx, s3tokensURL(c), b, &r.Body, &gophercloud.RequestOpts{ - MoreHeaders: map[string]string{"X-Auth-Token": ""}, - OkCodes: []int{200}, + OkCodes: []int{200}, }) _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) return From 2c52f33cc479662ffa7abdc9e4598a9e4071b930 Mon Sep 17 00:00:00 2001 From: Winicius Silva Date: Thu, 13 Nov 2025 22:05:13 -0300 Subject: [PATCH 222/353] identity/services: add omitempty to the `type` field --- openstack/identity/v3/services/requests.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openstack/identity/v3/services/requests.go b/openstack/identity/v3/services/requests.go index c1e07908ad..8e8011da01 100644 --- a/openstack/identity/v3/services/requests.go +++ b/openstack/identity/v3/services/requests.go @@ -109,7 +109,7 @@ type UpdateOptsBuilder interface { // UpdateOpts provides options for updating a service. type UpdateOpts struct { // Type is the type of the service. - Type string `json:"type"` + Type string `json:"type,omitempty"` // Enabled is whether or not the service is enabled. Enabled *bool `json:"enabled,omitempty"` From 0f47c9954e7d1aad24c35f00f0f42d5a46fda2a1 Mon Sep 17 00:00:00 2001 From: ycalansy Date: Tue, 28 Oct 2025 17:13:09 +0000 Subject: [PATCH 223/353] fix: handle Nova create image response for microversion 2.45 and above Since microversion 2.45, the Location header is removed from the create image response. The image ID is now returned in the response body as JSON. CreateImage now reads the response body and stores it in CreateImageResult. The image ID extraction checks X-OpenStack-Nova-API-Version to determine whether to extract the ID from the Location header (< 2.45) or the response body (>= 2.45). --- openstack/compute/v2/servers/requests.go | 29 +++++++++++++++- openstack/compute/v2/servers/results.go | 34 ++++++++++++++++++- .../v2/servers/testing/fixtures_test.go | 31 +++++++++++++++-- .../v2/servers/testing/requests_test.go | 17 ++++++++-- 4 files changed, 103 insertions(+), 8 deletions(-) diff --git a/openstack/compute/v2/servers/requests.go b/openstack/compute/v2/servers/requests.go index 34e4e00d41..c0ccebfa49 100644 --- a/openstack/compute/v2/servers/requests.go +++ b/openstack/compute/v2/servers/requests.go @@ -1,10 +1,12 @@ package servers import ( + "bytes" "context" "encoding/base64" "encoding/json" "fmt" + "io" "maps" "net" "regexp" @@ -1050,10 +1052,35 @@ func CreateImage(ctx context.Context, client *gophercloud.ServiceClient, id stri r.Err = err return } + resp, err := client.Post(ctx, actionURL(client, id), b, nil, &gophercloud.RequestOpts{ - OkCodes: []int{202}, + OkCodes: []int{202}, + KeepResponseBody: true, }) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + if r.Err != nil { + return + } + defer resp.Body.Close() + + if v := r.Header.Get("Content-Type"); v != "application/json" { + return + } + + // The response body is expected to be a small JSON object containing only "image_id". + // Read it fully into memory so the response body can be closed immediately. + // If the caller doesn't read from the buffer, it can still be safely garbage collected. + + var buf bytes.Buffer + + _, r.Err = io.Copy(&buf, resp.Body) + if r.Err != nil { + return + } + + r.Body = &buf + return } diff --git a/openstack/compute/v2/servers/results.go b/openstack/compute/v2/servers/results.go index bfecce29ec..edc2740f68 100644 --- a/openstack/compute/v2/servers/results.go +++ b/openstack/compute/v2/servers/results.go @@ -11,6 +11,7 @@ import ( "time" "github.com/gophercloud/gophercloud/v2" + "github.com/gophercloud/gophercloud/v2/openstack/utils" "github.com/gophercloud/gophercloud/v2/pagination" ) @@ -133,18 +134,49 @@ func (r CreateImageResult) ExtractImageID() (string, error) { if r.Err != nil { return "", r.Err } - // Get the image id from the header + + microversion := r.Header.Get("X-OpenStack-Nova-API-Version") + + major, minor, err := utils.ParseMicroversion(microversion) + if err != nil { + return "", fmt.Errorf("failed to parse X-OpenStack-Nova-API-Version header: %s", err) + } + + // In microversions prior to 2.45, the image ID was provided in the Location header. + if major < 2 || (major == 2 && minor < 45) { + return r.extractImageIDFromLocationHeader() + } + + // Starting from 2.45, it is included in the response body. + return r.extractImageIDFromResponseBody() +} + +func (r CreateImageResult) extractImageIDFromLocationHeader() (string, error) { u, err := url.ParseRequestURI(r.Header.Get("Location")) if err != nil { return "", err } + imageID := path.Base(u.Path) if imageID == "." || imageID == "/" { return "", fmt.Errorf("Failed to parse the ID of newly created image: %s", u) } + return imageID, nil } +func (r CreateImageResult) extractImageIDFromResponseBody() (string, error) { + var response struct { + ImageID string `json:"image_id"` + } + + if err := r.ExtractInto(&response); err != nil { + return "", err + } + + return response.ImageID, nil +} + // Server represents a server/instance in the OpenStack cloud. type Server struct { // ID uniquely identifies this server amongst all other servers, diff --git a/openstack/compute/v2/servers/testing/fixtures_test.go b/openstack/compute/v2/servers/testing/fixtures_test.go index 5c5153887a..206e20a53c 100644 --- a/openstack/compute/v2/servers/testing/fixtures_test.go +++ b/openstack/compute/v2/servers/testing/fixtures_test.go @@ -1303,14 +1303,39 @@ func HandleNetworkAddressListSuccessfully(t *testing.T, fakeServer th.FakeServer }) } -// HandleCreateServerImageSuccessfully sets up the test server to respond to a TestCreateServerImage request. -func HandleCreateServerImageSuccessfully(t *testing.T, fakeServer th.FakeServer) { +// HandleCreateServerImageSuccessfullyBeforeMicroversion_2_45 sets up the test server to respond to a TestCreateServerImageBeforeMicroversion_2_45 request. +func HandleCreateServerImageSuccessfullyBeforeMicroversion_2_45(t *testing.T, fakeServer th.FakeServer) string { + imageID := "xxxx-xxxxx-xxxxx-xxxx" + fakeServer.Mux.HandleFunc("/servers/serverimage/action", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - w.Header().Add("Location", "https://0.0.0.0/images/xxxx-xxxxx-xxxxx-xxxx") + + w.Header().Set("Location", fmt.Sprintf("https://0.0.0.0/images/%s", imageID)) + w.Header().Set("X-OpenStack-Nova-API-Version", "2.44") w.WriteHeader(http.StatusAccepted) }) + + return imageID +} + +// HandleCreateServerImageSuccessfullySinceMicroversion_2_45 sets up the test server to respond to a TestCreateServerImageSinceMicroversion_2_45 request. +func HandleCreateServerImageSuccessfullySinceMicroversion_2_45(t *testing.T, fakeServer th.FakeServer) string { + imageID := "yyyy-yyyyy-yyyyy-yyyyy" + + fakeServer.Mux.HandleFunc("/servers/serverimage/action", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "POST") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.Header().Set("Content-Type", "application/json") + w.Header().Set("X-OpenStack-Nova-API-Version", "2.45") + w.WriteHeader(http.StatusAccepted) + + _, err := w.Write(fmt.Appendf(nil, `{"image_id":"%s"}`, imageID)) + th.AssertNoErr(t, err) + }) + + return imageID } // HandlePasswordGetSuccessfully sets up the test server to respond to a password Get request. diff --git a/openstack/compute/v2/servers/testing/requests_test.go b/openstack/compute/v2/servers/testing/requests_test.go index aca94bd59b..9d11e670ee 100644 --- a/openstack/compute/v2/servers/testing/requests_test.go +++ b/openstack/compute/v2/servers/testing/requests_test.go @@ -1091,13 +1091,24 @@ func TestListAddressesByNetwork(t *testing.T) { th.CheckEquals(t, 1, pages) } -func TestCreateServerImage(t *testing.T) { +func TestCreateServerImageBeforeMicroversion_2_45(t *testing.T) { fakeServer := th.SetupHTTP() defer fakeServer.Teardown() - HandleCreateServerImageSuccessfully(t, fakeServer) + expected := HandleCreateServerImageSuccessfullyBeforeMicroversion_2_45(t, fakeServer) - _, err := servers.CreateImage(context.TODO(), client.ServiceClient(fakeServer), "serverimage", servers.CreateImageOpts{Name: "test"}).ExtractImageID() + imageID, err := servers.CreateImage(context.TODO(), client.ServiceClient(fakeServer), "serverimage", servers.CreateImageOpts{Name: "test"}).ExtractImageID() th.AssertNoErr(t, err) + th.AssertEquals(t, expected, imageID) +} + +func TestCreateServerImageSinceMicroversion_2_45(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + expected := HandleCreateServerImageSuccessfullySinceMicroversion_2_45(t, fakeServer) + + imageID, err := servers.CreateImage(context.TODO(), client.ServiceClient(fakeServer), "serverimage", servers.CreateImageOpts{Name: "test"}).ExtractImageID() + th.AssertNoErr(t, err) + th.AssertEquals(t, expected, imageID) } func TestMarshalPersonality(t *testing.T) { From b87372330f6be4b2edb4d9d22404f53b2740e229 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Andr=C3=A9?= Date: Mon, 17 Nov 2025 13:49:12 +0100 Subject: [PATCH 224/353] Prepare for v2.9.0 --- CHANGELOG.md | 20 ++++++++++++++++++++ provider_client.go | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 95bc952b15..773af218e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,23 @@ +## v2.9.0 (2025-11-17) + +* [GH-3508](https://github.com/gophercloud/gophercloud/pull/3508) [v2] Trigger "hold" workflow on merge groups +* [GH-3511](https://github.com/gophercloud/gophercloud/pull/3511) [v2] Closes #2321 - Fix TestRolesCRUD by including DomainID to TestRolesCRUD +* [GH-3513](https://github.com/gophercloud/gophercloud/pull/3513) [v2] build(deps): bump actions/labeler from 5 to 6 +* [GH-3516](https://github.com/gophercloud/gophercloud/pull/3516) [v2] refactor: Trivial fixes +* [GH-3524](https://github.com/gophercloud/gophercloud/pull/3524) [v2] [glance]: Add 'uploading' status +* [GH-3525](https://github.com/gophercloud/gophercloud/pull/3525) [v2] compute: Add host aggregate uuid field +* [GH-3526](https://github.com/gophercloud/gophercloud/pull/3526) [v2] Enable deletion for network and loadbalancer quotas +* [GH-3541](https://github.com/gophercloud/gophercloud/pull/3541) [v2] docs: Document tested releases for acceptance tests +* [GH-3544](https://github.com/gophercloud/gophercloud/pull/3544) [v2] Identity V3: Add Options field to roles. +* [GH-3547](https://github.com/gophercloud/gophercloud/pull/3547) [v2] Add config_drive to server struct +* [GH-3548](https://github.com/gophercloud/gophercloud/pull/3548) [v2] Identity: Add description field to roles +* [GH-3549](https://github.com/gophercloud/gophercloud/pull/3549) [v2] compute: add cpu info topology cells entry +* [GH-3550](https://github.com/gophercloud/gophercloud/pull/3550) [v2] Migrate epoxy jobs to Ubuntu 24.04 (Noble), drop caracal jobs +* [GH-3551](https://github.com/gophercloud/gophercloud/pull/3551) [v2] build(deps): bump github/codeql-action from 3 to 4 +* [GH-3557](https://github.com/gophercloud/gophercloud/pull/3557) [v2] Fix EC2 authentication to work with new Keystone auth requirement +* [GH-3558](https://github.com/gophercloud/gophercloud/pull/3558) [v2] identity/services: add omitempty to the `type` field +* [GH-3559](https://github.com/gophercloud/gophercloud/pull/3559) [v2] fix: handle Nova create image response for microversion 2.45 and above + ## v2.8.0 (2025-08-18) * [GH-3348](https://github.com/gophercloud/gophercloud/pull/3348) [v2] [networking] add ExtractRoutersInto func helper to routers diff --git a/provider_client.go b/provider_client.go index 6d9722f188..9048e83def 100644 --- a/provider_client.go +++ b/provider_client.go @@ -14,7 +14,7 @@ import ( // DefaultUserAgent is the default User-Agent string set in the request header. const ( - DefaultUserAgent = "gophercloud/v2.8.0" + DefaultUserAgent = "gophercloud/v2.9.0" DefaultMaxBackoffRetries = 60 ) From 851d8a289bf1e0bd6cfa9e80de3e6f7e0adc32fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Andr=C3=A9?= Date: Mon, 8 Dec 2025 08:51:27 +0100 Subject: [PATCH 225/353] identity/role: restore backward compatibility for description This is a follow-up to https://github.com/gophercloud/gophercloud/pull/3532/ that restores the backward compatibility with the old behavior, where `description` was returned in the `Extra` field. We will drop this for the next major release. --- openstack/identity/v3/roles/results.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/openstack/identity/v3/roles/results.go b/openstack/identity/v3/roles/results.go index 4c51e5f601..15fe8ddc29 100644 --- a/openstack/identity/v3/roles/results.go +++ b/openstack/identity/v3/roles/results.go @@ -55,6 +55,12 @@ func (r *Role) UnmarshalJSON(b []byte) error { } if resultMap, ok := result.(map[string]any); ok { r.Extra = gophercloud.RemainingKeys(Role{}, resultMap) + + // the following code is required for backward compatibility with the + // old behavior, when description was in extra + if description, ok := resultMap["description"]; ok { + r.Extra["description"] = description + } } } From 7885c6f050e80c760836f7ab18d8a4da01dc63bb Mon Sep 17 00:00:00 2001 From: Winicius Silva Date: Wed, 26 Nov 2025 14:24:44 -0300 Subject: [PATCH 226/353] identity/service: add `name` and `description` fields --- openstack/identity/v3/services/requests.go | 12 ++++++ openstack/identity/v3/services/results.go | 19 ++++++++- .../v3/services/testing/fixtures_test.go | 40 +++++++++---------- .../v3/services/testing/requests_test.go | 19 +++++---- 4 files changed, 58 insertions(+), 32 deletions(-) diff --git a/openstack/identity/v3/services/requests.go b/openstack/identity/v3/services/requests.go index 8e8011da01..0a25c18179 100644 --- a/openstack/identity/v3/services/requests.go +++ b/openstack/identity/v3/services/requests.go @@ -15,6 +15,12 @@ type CreateOptsBuilder interface { // CreateOpts provides options used to create a service. type CreateOpts struct { + // Name is the name of the service. + Name string `json:"name,omitempty"` + + // Description is the description of the service. + Description string `json:"description,omitempty"` + // Type is the type of the service. Type string `json:"type"` @@ -108,6 +114,12 @@ type UpdateOptsBuilder interface { // UpdateOpts provides options for updating a service. type UpdateOpts struct { + // Name is an updated name for the service. + Name *string `json:"name,omitempty"` + + // Description is an update description for the service. + Description *string `json:"description,omitempty"` + // Type is the type of the service. Type string `json:"type,omitempty"` diff --git a/openstack/identity/v3/services/results.go b/openstack/identity/v3/services/results.go index 8309065000..d5d6da2ad3 100644 --- a/openstack/identity/v3/services/results.go +++ b/openstack/identity/v3/services/results.go @@ -50,6 +50,12 @@ type Service struct { // ID is the unique ID of the service. ID string `json:"id"` + // Name is the name of the service. + Name string `json:"name"` + + // Description is the description of the service. + Description string `json:"description"` + // Type is the type of the service. Type string `json:"type"` @@ -75,8 +81,6 @@ func (r *Service) UnmarshalJSON(b []byte) error { } *r = Service(s.tmp) - // Collect other fields and bundle them into Extra - // but only if a field titled "extra" wasn't sent. if s.Extra != nil { r.Extra = s.Extra } else { @@ -85,8 +89,19 @@ func (r *Service) UnmarshalJSON(b []byte) error { if err != nil { return err } + if resultMap, ok := result.(map[string]any); ok { r.Extra = gophercloud.RemainingKeys(Service{}, resultMap) + + // the following code is required for backward compatibility with the + // old behavior, when both description and name were in extra + if description, ok := resultMap["description"]; ok { + r.Extra["description"] = description + } + + if name, ok := resultMap["name"]; ok { + r.Extra["name"] = name + } } } diff --git a/openstack/identity/v3/services/testing/fixtures_test.go b/openstack/identity/v3/services/testing/fixtures_test.go index 9bd0076c58..42811a09d6 100644 --- a/openstack/identity/v3/services/testing/fixtures_test.go +++ b/openstack/identity/v3/services/testing/fixtures_test.go @@ -23,11 +23,11 @@ const ListOutput = ` "links": { "self": "https://example.com/identity/v3/services/1234" }, + "name": "service-one", "type": "identity", "enabled": false, "extra": { - "name": "service-one", - "description": "Service One" + "email": "service-one@example.com" } }, { @@ -35,11 +35,11 @@ const ListOutput = ` "links": { "self": "https://example.com/identity/v3/services/9876" }, + "name": "service-two", + "description": "Service Two", "type": "compute", "enabled": false, "extra": { - "name": "service-two", - "description": "Service Two", "email": "service@example.com" } } @@ -55,11 +55,11 @@ const GetOutput = ` "links": { "self": "https://example.com/identity/v3/services/9876" }, + "name": "service-two", + "description": "Service Two", "type": "compute", "enabled": false, "extra": { - "name": "service-two", - "description": "Service Two", "email": "service@example.com" } } @@ -96,11 +96,11 @@ const UpdateOutput = ` "links": { "self": "https://example.com/identity/v3/services/9876" }, + "name": "service-two", + "description": "Service Two Updated", "type": "compute2", "enabled": false, "extra": { - "name": "service-two", - "description": "Service Two Updated", "email": "service@example.com" } } @@ -113,11 +113,11 @@ var FirstService = services.Service{ Links: map[string]any{ "self": "https://example.com/identity/v3/services/1234", }, + Name: "service-one", Type: "identity", Enabled: false, Extra: map[string]any{ - "name": "service-one", - "description": "Service One", + "email": "service-one@example.com", }, } @@ -127,12 +127,12 @@ var SecondService = services.Service{ Links: map[string]any{ "self": "https://example.com/identity/v3/services/9876", }, - Type: "compute", - Enabled: false, + Name: "service-two", + Description: "Service Two", + Type: "compute", + Enabled: false, Extra: map[string]any{ - "name": "service-two", - "description": "Service Two", - "email": "service@example.com", + "email": "service@example.com", }, } @@ -142,12 +142,12 @@ var SecondServiceUpdated = services.Service{ Links: map[string]any{ "self": "https://example.com/identity/v3/services/9876", }, - Type: "compute2", - Enabled: false, + Name: "service-two", + Description: "Service Two Updated", + Type: "compute2", + Enabled: false, Extra: map[string]any{ - "name": "service-two", - "description": "Service Two Updated", - "email": "service@example.com", + "email": "service@example.com", }, } diff --git a/openstack/identity/v3/services/testing/requests_test.go b/openstack/identity/v3/services/testing/requests_test.go index 12c241ea9e..c88cefb322 100644 --- a/openstack/identity/v3/services/testing/requests_test.go +++ b/openstack/identity/v3/services/testing/requests_test.go @@ -17,11 +17,11 @@ func TestCreateSuccessful(t *testing.T) { HandleCreateServiceSuccessfully(t, fakeServer) createOpts := services.CreateOpts{ - Type: "compute", + Name: "service-two", + Description: "Service Two", + Type: "compute", Extra: map[string]any{ - "name": "service-two", - "description": "Service Two", - "email": "service@example.com", + "email": "service@example.com", }, } @@ -60,7 +60,7 @@ func TestListServicesAllPages(t *testing.T) { actual, err := services.ExtractServices(allPages) th.AssertNoErr(t, err) th.CheckDeepEquals(t, ExpectedServicesSlice, actual) - th.AssertEquals(t, ExpectedServicesSlice[0].Extra["name"], "service-one") + th.AssertEquals(t, ExpectedServicesSlice[0].Extra["email"], "service-one@example.com") th.AssertEquals(t, ExpectedServicesSlice[1].Extra["email"], "service@example.com") } @@ -81,16 +81,15 @@ func TestUpdateSuccessful(t *testing.T) { defer fakeServer.Teardown() HandleUpdateServiceSuccessfully(t, fakeServer) + updatedDescription := "Service Two Updated" updateOpts := services.UpdateOpts{ - Type: "compute2", - Extra: map[string]any{ - "description": "Service Two Updated", - }, + Description: &updatedDescription, + Type: "compute2", } actual, err := services.Update(context.TODO(), client.ServiceClient(fakeServer), "9876", updateOpts).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, SecondServiceUpdated, *actual) - th.AssertEquals(t, SecondServiceUpdated.Extra["description"], "Service Two Updated") + th.AssertEquals(t, SecondServiceUpdated.Description, "Service Two Updated") } func TestDeleteSuccessful(t *testing.T) { From a582e9bf733feb2983d5f00ce8645de2a4f0c44d Mon Sep 17 00:00:00 2001 From: Winicius Silva Date: Wed, 10 Dec 2025 14:31:23 -0300 Subject: [PATCH 227/353] add: description field to identity.v3.Endpoint Signed-off-by: Winicius Silva --- openstack/identity/v3/endpoints/requests.go | 6 ++++ openstack/identity/v3/endpoints/results.go | 3 ++ .../v3/endpoints/testing/requests_test.go | 32 +++++++++++++------ 3 files changed, 32 insertions(+), 9 deletions(-) diff --git a/openstack/identity/v3/endpoints/requests.go b/openstack/identity/v3/endpoints/requests.go index 4386bb9bc9..4865d8861f 100644 --- a/openstack/identity/v3/endpoints/requests.go +++ b/openstack/identity/v3/endpoints/requests.go @@ -30,6 +30,9 @@ type CreateOpts struct { // ServiceID is the ID of the service the Endpoint refers to. ServiceID string `json:"service_id" required:"true"` + + // Description is the description of the Endpoint. + Description string `json:"description,omitempty"` } // ToEndpointCreateMap builds a request body from the Endpoint Create options. @@ -121,6 +124,9 @@ type UpdateOpts struct { // ServiceID is the ID of the service the Endpoint refers to. ServiceID string `json:"service_id,omitempty"` + + // Description is an updated description of the endpoint. + Description string `json:"description,omitempty"` } // ToEndpointUpdateMap builds an update request body from the Update options. diff --git a/openstack/identity/v3/endpoints/results.go b/openstack/identity/v3/endpoints/results.go index 19d279ebc6..7dbb1c9f7d 100644 --- a/openstack/identity/v3/endpoints/results.go +++ b/openstack/identity/v3/endpoints/results.go @@ -66,6 +66,9 @@ type Endpoint struct { // Enabled is whether or not the endpoint is enabled. Enabled bool `json:"enabled"` + + // Description is the description of the Endpoint. + Description string `json:"description"` } // EndpointPage is a single page of Endpoint results. diff --git a/openstack/identity/v3/endpoints/testing/requests_test.go b/openstack/identity/v3/endpoints/testing/requests_test.go index 7c418aed88..78991fe547 100644 --- a/openstack/identity/v3/endpoints/testing/requests_test.go +++ b/openstack/identity/v3/endpoints/testing/requests_test.go @@ -26,7 +26,8 @@ func TestCreateSuccessful(t *testing.T) { "name": "the-endiest-of-points", "region": "underground", "url": "https://1.2.3.4:9000/", - "service_id": "asdfasdfasdfasdf" + "service_id": "asdfasdfasdfasdf", + "description": "Test description" } }`) @@ -42,7 +43,8 @@ func TestCreateSuccessful(t *testing.T) { "name": "the-endiest-of-points", "region": "underground", "service_id": "asdfasdfasdfasdf", - "url": "https://1.2.3.4:9000/" + "url": "https://1.2.3.4:9000/", + "description": "Test description" } }`) }) @@ -53,6 +55,7 @@ func TestCreateSuccessful(t *testing.T) { Region: "underground", URL: "https://1.2.3.4:9000/", ServiceID: "asdfasdfasdfasdf", + Description: "Test description", }).Extract() th.AssertNoErr(t, err) @@ -64,6 +67,7 @@ func TestCreateSuccessful(t *testing.T) { Region: "underground", ServiceID: "asdfasdfasdfasdf", URL: "https://1.2.3.4:9000/", + Description: "Test description", } th.AssertDeepEquals(t, expected, actual) @@ -90,7 +94,8 @@ func TestListEndpoints(t *testing.T) { "name": "the-endiest-of-points", "region": "underground", "service_id": "asdfasdfasdfasdf", - "url": "https://1.2.3.4:9000/" + "url": "https://1.2.3.4:9000/", + "description": "List endpoint1 test" }, { "id": "13", @@ -102,7 +107,8 @@ func TestListEndpoints(t *testing.T) { "name": "shhhh", "region": "underground", "service_id": "asdfasdfasdfasdf", - "url": "https://1.2.3.4:9001/" + "url": "https://1.2.3.4:9001/", + "description": "List endpoint2 test" } ], "links": { @@ -130,6 +136,7 @@ func TestListEndpoints(t *testing.T) { Region: "underground", ServiceID: "asdfasdfasdfasdf", URL: "https://1.2.3.4:9000/", + Description: "List endpoint1 test", }, { ID: "13", @@ -139,6 +146,7 @@ func TestListEndpoints(t *testing.T) { Region: "underground", ServiceID: "asdfasdfasdfasdf", URL: "https://1.2.3.4:9001/", + Description: "List endpoint2 test", }, } th.AssertDeepEquals(t, expected, actual) @@ -167,7 +175,8 @@ func TestGetEndpoint(t *testing.T) { "name": "the-endiest-of-points", "region": "underground", "service_id": "asdfasdfasdfasdf", - "url": "https://1.2.3.4:9000/" + "url": "https://1.2.3.4:9000/", + "description": "Get endpoint test" } }`) }) @@ -185,6 +194,7 @@ func TestGetEndpoint(t *testing.T) { Region: "underground", ServiceID: "asdfasdfasdfasdf", URL: "https://1.2.3.4:9000/", + Description: "Get endpoint test", } th.AssertDeepEquals(t, expected, actual) } @@ -199,7 +209,8 @@ func TestUpdateEndpoint(t *testing.T) { th.TestJSONRequest(t, r, `{ "endpoint": { "name": "renamed", - "region": "somewhere-else" + "region": "somewhere-else", + "description": "Changed description" } }`) @@ -214,14 +225,16 @@ func TestUpdateEndpoint(t *testing.T) { "name": "renamed", "region": "somewhere-else", "service_id": "asdfasdfasdfasdf", - "url": "https://1.2.3.4:9000/" + "url": "https://1.2.3.4:9000/", + "description": "Changed description" } }`) }) actual, err := endpoints.Update(context.TODO(), client.ServiceClient(fakeServer), "12", endpoints.UpdateOpts{ - Name: "renamed", - Region: "somewhere-else", + Name: "renamed", + Region: "somewhere-else", + Description: "Changed description", }).Extract() if err != nil { t.Fatalf("Unexpected error from Update: %v", err) @@ -235,6 +248,7 @@ func TestUpdateEndpoint(t *testing.T) { Region: "somewhere-else", ServiceID: "asdfasdfasdfasdf", URL: "https://1.2.3.4:9000/", + Description: "Changed description", } th.AssertDeepEquals(t, expected, actual) } From f93b371c9126526592fb5ef46eb4bda1fcfa29ea Mon Sep 17 00:00:00 2001 From: Winicius Silva Date: Thu, 11 Dec 2025 13:09:53 -0300 Subject: [PATCH 228/353] add: crud acceptance test for endpoint Signed-off-by: Winicius Silva --- .../openstack/identity/v3/endpoint_test.go | 36 +++++++++++++++ .../openstack/identity/v3/identity.go | 45 +++++++++++++++++++ 2 files changed, 81 insertions(+) diff --git a/internal/acceptance/openstack/identity/v3/endpoint_test.go b/internal/acceptance/openstack/identity/v3/endpoint_test.go index 8dd9e5bad1..6f96adb981 100644 --- a/internal/acceptance/openstack/identity/v3/endpoint_test.go +++ b/internal/acceptance/openstack/identity/v3/endpoint_test.go @@ -100,3 +100,39 @@ func TestEndpointsNavigateCatalog(t *testing.T) { tools.PrintResource(t, allEndpoints[0]) } + +func TestEndpointCRUD(t *testing.T) { + clients.RequireAdmin(t) + + client, err := clients.NewIdentityV3Client() + th.AssertNoErr(t, err) + + service, err := CreateService(t, client, &services.CreateOpts{ + Type: "endpoint-test", + Name: tools.RandomString("ACPTTEST", 8), + Extra: map[string]any{}, + }) + th.AssertNoErr(t, err) + defer DeleteService(t, client, service.ID) + + endpoint, err := CreateEndpoint(t, client, &endpoints.CreateOpts{ + Availability: gophercloud.Availability("internal"), + ServiceID: service.ID, + URL: "https://example.com", + }) + th.AssertNoErr(t, err) + defer DeleteEndpoint(t, client, endpoint.ID) + + tools.PrintResource(t, endpoint) + tools.PrintResource(t, endpoint.URL) + + newEndpoint, err := endpoints.Update(context.TODO(), client, endpoint.ID, &endpoints.UpdateOpts{ + Name: "new-endpoint", + URL: "https://example-updated.com", + Description: "Updated Endpoint", + }).Extract() + th.AssertNoErr(t, err) + + th.AssertEquals(t, newEndpoint.URL, "https://example-updated.com") + th.AssertEquals(t, newEndpoint.Description, "Updated Endpoint") +} diff --git a/internal/acceptance/openstack/identity/v3/identity.go b/internal/acceptance/openstack/identity/v3/identity.go index ab34bb7530..a71c914430 100644 --- a/internal/acceptance/openstack/identity/v3/identity.go +++ b/internal/acceptance/openstack/identity/v3/identity.go @@ -7,6 +7,7 @@ import ( "github.com/gophercloud/gophercloud/v2" "github.com/gophercloud/gophercloud/v2/internal/acceptance/tools" "github.com/gophercloud/gophercloud/v2/openstack/identity/v3/domains" + "github.com/gophercloud/gophercloud/v2/openstack/identity/v3/endpoints" "github.com/gophercloud/gophercloud/v2/openstack/identity/v3/groups" "github.com/gophercloud/gophercloud/v2/openstack/identity/v3/projects" "github.com/gophercloud/gophercloud/v2/openstack/identity/v3/regions" @@ -17,6 +18,38 @@ import ( th "github.com/gophercloud/gophercloud/v2/testhelper" ) +// CreateEndpoint will create an endpoint with a random name. It only define +// endpoint name and description, and receive from CreateOpts others parameters, +// such as URL, Availability and ServiceID. An error will be returned if the +// endpoint was unabled to be created. +func CreateEndpoint(t *testing.T, client *gophercloud.ServiceClient, c *endpoints.CreateOpts) (*endpoints.Endpoint, error) { + name := tools.RandomString("ACPTTEST", 8) + description := tools.RandomString("ACPTTEST-DESC", 8) + t.Logf("Attempting to create endpoint: %s", name) + + var createOpts endpoints.CreateOpts + if c != nil { + createOpts = *c + } else { + createOpts = endpoints.CreateOpts{} + } + + createOpts.Name = name + createOpts.Description = description + + endpoint, err := endpoints.Create(context.TODO(), client, createOpts).Extract() + if err != nil { + return endpoint, err + } + + t.Logf("Successfully created endpoint %s with ID %s", name, endpoint.ID) + + th.AssertEquals(t, endpoint.Name, name) + th.AssertEquals(t, endpoint.Description, description) + + return endpoint, nil +} + // CreateProject will create a project with a random name. // It takes an optional createOpts parameter since creating a project // has so many options. An error will be returned if the project was @@ -228,6 +261,18 @@ func CreateService(t *testing.T, client *gophercloud.ServiceClient, c *services. return service, nil } +// DeleteEndpoint will delete the specified Endpoint using its ID. A fatal error +// will occur if the endpoint failed to be deleted. This works best when using +// it as a deferred function. +func DeleteEndpoint(t *testing.T, client *gophercloud.ServiceClient, endpointID string) { + err := endpoints.Delete(context.TODO(), client, endpointID).ExtractErr() + if err != nil { + t.Fatalf("Unable to delete endpoint %s: %v", endpointID, err) + } + + t.Logf("Deleted endpoint: %s", endpointID) +} + // DeleteProject will delete a project by ID. A fatal error will occur if // the project ID failed to be deleted. This works best when using it as // a deferred function. From a113e460a30214b411a885cbca3aedfea5c061b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?p=C3=BDrus?= Date: Thu, 11 Dec 2025 11:34:22 +0100 Subject: [PATCH 229/353] keystone: add support for per page limit --- openstack/identity/v3/domains/requests.go | 3 ++ openstack/identity/v3/projects/requests.go | 3 ++ .../v3/projects/testing/fixtures_test.go | 37 ++++++++++++++++++- .../v3/projects/testing/requests_test.go | 13 +++++-- 4 files changed, 51 insertions(+), 5 deletions(-) diff --git a/openstack/identity/v3/domains/requests.go b/openstack/identity/v3/domains/requests.go index 8ce72a9b33..94bb567f3c 100644 --- a/openstack/identity/v3/domains/requests.go +++ b/openstack/identity/v3/domains/requests.go @@ -20,6 +20,9 @@ type ListOpts struct { // Name filters the response by domain name. Name string `q:"name"` + + // Limit limits the number of projects returned per page. + Limit int `q:"limit"` } // ToDomainListQuery formats a ListOpts into a query string. diff --git a/openstack/identity/v3/projects/requests.go b/openstack/identity/v3/projects/requests.go index 6fb8448a9f..5aecc94d93 100644 --- a/openstack/identity/v3/projects/requests.go +++ b/openstack/identity/v3/projects/requests.go @@ -45,6 +45,9 @@ type ListOpts struct { // NotTagsAny filters on specific project tags. At least one of the tags must be absent for the project. NotTagsAny string `q:"not-tags-any"` + // Limit limits the number of projects returned per page. + Limit int `q:"limit"` + // Filters filters the response by custom filters such as // 'name__contains=foo' Filters map[string]string `q:"-"` diff --git a/openstack/identity/v3/projects/testing/fixtures_test.go b/openstack/identity/v3/projects/testing/fixtures_test.go index 5c97fc7dd3..5782fde87c 100644 --- a/openstack/identity/v3/projects/testing/fixtures_test.go +++ b/openstack/identity/v3/projects/testing/fixtures_test.go @@ -59,7 +59,19 @@ const ListOutput = ` "parent_id": null, "tags": ["Red", "Team"], "test": "old" - }, + } + ], + "links": { + "next": "%sprojects?limit=1&marker=1234", + "self": "%sprojects?limit=1", + "previous": null + } +} +` + +const ListOutputSecondPage = ` +{ + "projects": [ { "is_domain": false, "description": "The team that is blue", @@ -73,8 +85,21 @@ const ListOutput = ` } } ], + "links": { + "next": "%sprojects?limit=1&marker=9876", + "self": "%sprojects?limit=1&marker=1234", + "previous": null + } +} +` + +const ListOutputThirdPage = ` +{ + "projects": [ + ], "links": { "next": null, + "self": "%sprojects?limit=1&marker=9876", "previous": null } } @@ -299,7 +324,15 @@ func HandleListProjectsSuccessfully(t *testing.T, fakeServer th.FakeServer) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprint(w, ListOutput) + + switch r.URL.Query().Get("marker") { + case "": + fmt.Fprintf(w, ListOutput, fakeServer.Endpoint(), fakeServer.Endpoint()) + case "1234": + fmt.Fprintf(w, ListOutputSecondPage, fakeServer.Endpoint(), fakeServer.Endpoint()) + case "9876": + fmt.Fprintf(w, ListOutputThirdPage, fakeServer.Endpoint()) + } }) } diff --git a/openstack/identity/v3/projects/testing/requests_test.go b/openstack/identity/v3/projects/testing/requests_test.go index 5ecc88e45d..ca5bebe454 100644 --- a/openstack/identity/v3/projects/testing/requests_test.go +++ b/openstack/identity/v3/projects/testing/requests_test.go @@ -35,19 +35,26 @@ func TestListProjects(t *testing.T) { defer fakeServer.Teardown() HandleListProjectsSuccessfully(t, fakeServer) + actualProjects := make([]projects.Project, 0, 2) count := 0 - err := projects.List(client.ServiceClient(fakeServer), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + opts := projects.ListOpts{ + Limit: 1, + } + err := projects.List(client.ServiceClient(fakeServer), opts).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { count++ actual, err := projects.ExtractProjects(page) th.AssertNoErr(t, err) - th.CheckDeepEquals(t, ExpectedProjectSlice, actual) + actualProjects = append(actualProjects, actual...) return true, nil }) th.AssertNoErr(t, err) - th.CheckEquals(t, count, 1) + th.CheckEquals(t, count, 2) + + th.CheckEquals(t, len(actualProjects), 2) + th.CheckDeepEquals(t, ExpectedProjectSlice, actualProjects) } func TestListGroupsFiltersCheck(t *testing.T) { From 7e3e0f914781a39b56bf261b76f3b17c23b30355 Mon Sep 17 00:00:00 2001 From: Winicius Silva Date: Thu, 11 Dec 2025 23:32:15 -0300 Subject: [PATCH 230/353] add: support for update mac_address on port --- internal/acceptance/openstack/networking/v2/ports_test.go | 3 +++ openstack/networking/v2/ports/requests.go | 1 + openstack/networking/v2/ports/testing/fixtures.go | 5 +++-- openstack/networking/v2/ports/testing/requests_test.go | 4 ++++ 4 files changed, 11 insertions(+), 2 deletions(-) diff --git a/internal/acceptance/openstack/networking/v2/ports_test.go b/internal/acceptance/openstack/networking/v2/ports_test.go index 569beeebd4..f6ff48e829 100644 --- a/internal/acceptance/openstack/networking/v2/ports_test.go +++ b/internal/acceptance/openstack/networking/v2/ports_test.go @@ -45,9 +45,11 @@ func TestPortsCRUD(t *testing.T) { // Update port newPortName := "" newPortDescription := "" + newMACAddress := "aa:bb:cc:dd:ee:ff" updateOpts := ports.UpdateOpts{ Name: &newPortName, Description: &newPortDescription, + MACAddress: &newMACAddress, } newPort, err := ports.Update(context.TODO(), client, port.ID, updateOpts).Extract() th.AssertNoErr(t, err) @@ -56,6 +58,7 @@ func TestPortsCRUD(t *testing.T) { th.AssertEquals(t, newPort.Name, newPortName) th.AssertEquals(t, newPort.Description, newPortDescription) + th.AssertEquals(t, newPort.MACAddress, newMACAddress) allPages, err := ports.List(client, nil).AllPages(context.TODO()) th.AssertNoErr(t, err) diff --git a/openstack/networking/v2/ports/requests.go b/openstack/networking/v2/ports/requests.go index bfff2dffb2..a9c5c37535 100644 --- a/openstack/networking/v2/ports/requests.go +++ b/openstack/networking/v2/ports/requests.go @@ -197,6 +197,7 @@ type UpdateOpts struct { AllowedAddressPairs *[]AddressPair `json:"allowed_address_pairs,omitempty"` PropagateUplinkStatus *bool `json:"propagate_uplink_status,omitempty"` ValueSpecs *map[string]string `json:"value_specs,omitempty"` + MACAddress *string `json:"mac_address,omitempty"` // RevisionNumber implements extension:standard-attr-revisions. If != "" it // will set revision_number=%s. If the revision number does not match, the diff --git a/openstack/networking/v2/ports/testing/fixtures.go b/openstack/networking/v2/ports/testing/fixtures.go index b4c03fd618..b11650863f 100644 --- a/openstack/networking/v2/ports/testing/fixtures.go +++ b/openstack/networking/v2/ports/testing/fixtures.go @@ -409,7 +409,8 @@ const UpdateRequest = ` ], "security_groups": [ "f0ac4394-7e4a-4409-9701-ba8be283dbc3" - ] + ], + "mac_address": "fa:16:3e:c9:cb:f4" } } ` @@ -423,7 +424,7 @@ const UpdateResponse = ` "network_id": "a87cc70a-3e15-4acf-8205-9b711a3531b7", "tenant_id": "d6700c0c9ffa4f1cb322cd4a1f3906fa", "device_owner": "", - "mac_address": "fa:16:3e:c9:cb:f0", + "mac_address": "fa:16:3e:c9:cb:f4", "fixed_ips": [ { "subnet_id": "a0304c3a-4f08-4c43-88af-d796509c97d2", diff --git a/openstack/networking/v2/ports/testing/requests_test.go b/openstack/networking/v2/ports/testing/requests_test.go index ac1a2cd79a..f69962f74b 100644 --- a/openstack/networking/v2/ports/testing/requests_test.go +++ b/openstack/networking/v2/ports/testing/requests_test.go @@ -538,6 +538,7 @@ func TestUpdate(t *testing.T) { }) name := "new_port_name" + newMACAddress := "fa:16:3e:c9:cb:f4" options := ports.UpdateOpts{ Name: &name, FixedIPs: []ports.IP{ @@ -547,6 +548,7 @@ func TestUpdate(t *testing.T) { AllowedAddressPairs: &[]ports.AddressPair{ {IPAddress: "10.0.0.4", MACAddress: "fa:16:3e:c9:cb:f0"}, }, + MACAddress: &newMACAddress, } s, err := ports.Update(context.TODO(), fake.ServiceClient(fakeServer), "65c0ee9f-d634-4522-8954-51021b570b0d", options).Extract() @@ -727,6 +729,7 @@ func TestUpdateRevision(t *testing.T) { }) name := "new_port_name" + newMACAddress := "fa:16:3e:c9:cb:f4" options := ports.UpdateOpts{ Name: &name, FixedIPs: []ports.IP{ @@ -736,6 +739,7 @@ func TestUpdateRevision(t *testing.T) { AllowedAddressPairs: &[]ports.AddressPair{ {IPAddress: "10.0.0.4", MACAddress: "fa:16:3e:c9:cb:f0"}, }, + MACAddress: &newMACAddress, } _, err := ports.Update(context.TODO(), fake.ServiceClient(fakeServer), "65c0ee9f-d634-4522-8954-51021b570b0d", options).Extract() th.AssertNoErr(t, err) From fc873f7b729156c24eaa6651bf5ff7c1d72397f9 Mon Sep 17 00:00:00 2001 From: Winicius Silva Date: Mon, 15 Dec 2025 18:55:15 -0300 Subject: [PATCH 231/353] identity.v3.Endpoint: add enabled field on creation and on update --- .../openstack/identity/v3/endpoint_test.go | 4 ++++ openstack/identity/v3/endpoints/requests.go | 14 +++++++++++--- .../v3/endpoints/testing/requests_test.go | 18 ++++++++++++------ 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/internal/acceptance/openstack/identity/v3/endpoint_test.go b/internal/acceptance/openstack/identity/v3/endpoint_test.go index 6f96adb981..7d9da99854 100644 --- a/internal/acceptance/openstack/identity/v3/endpoint_test.go +++ b/internal/acceptance/openstack/identity/v3/endpoint_test.go @@ -115,10 +115,12 @@ func TestEndpointCRUD(t *testing.T) { th.AssertNoErr(t, err) defer DeleteService(t, client, service.ID) + enabled := false endpoint, err := CreateEndpoint(t, client, &endpoints.CreateOpts{ Availability: gophercloud.Availability("internal"), ServiceID: service.ID, URL: "https://example.com", + Enabled: &enabled, }) th.AssertNoErr(t, err) defer DeleteEndpoint(t, client, endpoint.ID) @@ -126,10 +128,12 @@ func TestEndpointCRUD(t *testing.T) { tools.PrintResource(t, endpoint) tools.PrintResource(t, endpoint.URL) + enabled = true newEndpoint, err := endpoints.Update(context.TODO(), client, endpoint.ID, &endpoints.UpdateOpts{ Name: "new-endpoint", URL: "https://example-updated.com", Description: "Updated Endpoint", + Enabled: &enabled, }).Extract() th.AssertNoErr(t, err) diff --git a/openstack/identity/v3/endpoints/requests.go b/openstack/identity/v3/endpoints/requests.go index 4865d8861f..45893aa3c6 100644 --- a/openstack/identity/v3/endpoints/requests.go +++ b/openstack/identity/v3/endpoints/requests.go @@ -18,6 +18,13 @@ type CreateOpts struct { // or public), referenced by the gophercloud.Availability type. Availability gophercloud.Availability `json:"interface" required:"true"` + // Description is the description of the Endpoint. + Description string `json:"description,omitempty"` + + // Enabled indicates whether the Endpoint appears in the service + // or not. + Enabled *bool `json:"enabled,omitempty"` + // Name is the name of the Endpoint. Name string `json:"name" required:"true"` @@ -30,9 +37,6 @@ type CreateOpts struct { // ServiceID is the ID of the service the Endpoint refers to. ServiceID string `json:"service_id" required:"true"` - - // Description is the description of the Endpoint. - Description string `json:"description,omitempty"` } // ToEndpointCreateMap builds a request body from the Endpoint Create options. @@ -115,6 +119,10 @@ type UpdateOpts struct { // Name is the name of the Endpoint. Name string `json:"name,omitempty"` + // Enabled indicates whether the Endpoint appears in the service + // or not. + Enabled *bool `json:"enabled,omitempty"` + // Region is the region the Endpoint is located in. // This field can be omitted or left as a blank string. Region string `json:"region,omitempty"` diff --git a/openstack/identity/v3/endpoints/testing/requests_test.go b/openstack/identity/v3/endpoints/testing/requests_test.go index 78991fe547..07798947c6 100644 --- a/openstack/identity/v3/endpoints/testing/requests_test.go +++ b/openstack/identity/v3/endpoints/testing/requests_test.go @@ -27,7 +27,8 @@ func TestCreateSuccessful(t *testing.T) { "region": "underground", "url": "https://1.2.3.4:9000/", "service_id": "asdfasdfasdfasdf", - "description": "Test description" + "description": "Test description", + "enabled": false } }`) @@ -36,7 +37,7 @@ func TestCreateSuccessful(t *testing.T) { "endpoint": { "id": "12", "interface": "public", - "enabled": true, + "enabled": false, "links": { "self": "https://localhost:5000/v3/endpoints/12" }, @@ -49,6 +50,7 @@ func TestCreateSuccessful(t *testing.T) { }`) }) + enabled := false actual, err := endpoints.Create(context.TODO(), client.ServiceClient(fakeServer), endpoints.CreateOpts{ Availability: gophercloud.AvailabilityPublic, Name: "the-endiest-of-points", @@ -56,14 +58,15 @@ func TestCreateSuccessful(t *testing.T) { URL: "https://1.2.3.4:9000/", ServiceID: "asdfasdfasdfasdf", Description: "Test description", + Enabled: &enabled, }).Extract() th.AssertNoErr(t, err) expected := &endpoints.Endpoint{ ID: "12", Availability: gophercloud.AvailabilityPublic, - Enabled: true, Name: "the-endiest-of-points", + Enabled: false, Region: "underground", ServiceID: "asdfasdfasdfasdf", URL: "https://1.2.3.4:9000/", @@ -210,7 +213,8 @@ func TestUpdateEndpoint(t *testing.T) { "endpoint": { "name": "renamed", "region": "somewhere-else", - "description": "Changed description" + "description": "Changed description", + "enabled": false } }`) @@ -218,7 +222,7 @@ func TestUpdateEndpoint(t *testing.T) { "endpoint": { "id": "12", "interface": "public", - "enabled": true, + "enabled": false, "links": { "self": "https://localhost:5000/v3/endpoints/12" }, @@ -231,10 +235,12 @@ func TestUpdateEndpoint(t *testing.T) { }`) }) + enabled := false actual, err := endpoints.Update(context.TODO(), client.ServiceClient(fakeServer), "12", endpoints.UpdateOpts{ Name: "renamed", Region: "somewhere-else", Description: "Changed description", + Enabled: &enabled, }).Extract() if err != nil { t.Fatalf("Unexpected error from Update: %v", err) @@ -243,7 +249,7 @@ func TestUpdateEndpoint(t *testing.T) { expected := &endpoints.Endpoint{ ID: "12", Availability: gophercloud.AvailabilityPublic, - Enabled: true, + Enabled: false, Name: "renamed", Region: "somewhere-else", ServiceID: "asdfasdfasdfasdf", From bbd3eafd23d164d4a501534a518c065debf2fcb1 Mon Sep 17 00:00:00 2001 From: Chi Wai Chan Date: Thu, 18 Dec 2025 14:43:13 +0800 Subject: [PATCH 232/353] fix (image/v2/images): image v2 unmarshal issue --- openstack/image/v2/images/results.go | 10 ++++- .../image/v2/images/testing/fixtures_test.go | 43 ++++++++++++++++++- .../image/v2/images/testing/requests_test.go | 7 +-- 3 files changed, 54 insertions(+), 6 deletions(-) diff --git a/openstack/image/v2/images/results.go b/openstack/image/v2/images/results.go index 6652f0e791..3af7136326 100644 --- a/openstack/image/v2/images/results.go +++ b/openstack/image/v2/images/results.go @@ -70,7 +70,7 @@ type Image struct { // Properties is a set of key-value pairs, if any, that are associated with // the image. - Properties map[string]any + Properties map[string]any `json:"-"` // CreatedAt is the date when the image has been created. CreatedAt time.Time `json:"created_at"` @@ -102,6 +102,7 @@ func (r *Image) UnmarshalJSON(b []byte) error { type tmp Image var s struct { tmp + Properties string `json:"properties"` SizeBytes any `json:"size"` OpenStackImageImportMethods string `json:"openstack-image-import-methods"` OpenStackImageStoreIDs string `json:"openstack-image-store-ids"` @@ -123,7 +124,7 @@ func (r *Image) UnmarshalJSON(b []byte) error { return fmt.Errorf("Unknown type for SizeBytes: %v (value: %v)", reflect.TypeOf(t), t) } - // Bundle all other fields into Properties + // Bundle all other fields into Properties, except for the field named "properties" var result any err = json.Unmarshal(b, &result) if err != nil { @@ -137,6 +138,11 @@ func (r *Image) UnmarshalJSON(b []byte) error { r.Properties = gophercloud.RemainingKeys(Image{}, resultMap) } + // Add the "properties" field to the image since it's not included in above step (i.e. in remaining keys) + if s.Properties != "" { + r.Properties["properties"] = s.Properties + } + if v := strings.FieldsFunc(strings.TrimSpace(s.OpenStackImageImportMethods), splitFunc); len(v) > 0 { r.OpenStackImageImportMethods = v } diff --git a/openstack/image/v2/images/testing/fixtures_test.go b/openstack/image/v2/images/testing/fixtures_test.go index 0ec25214d1..9665e4ed55 100644 --- a/openstack/image/v2/images/testing/fixtures_test.go +++ b/openstack/image/v2/images/testing/fixtures_test.go @@ -19,7 +19,7 @@ type imageEntry struct { // HandleImageListSuccessfully test setup func HandleImageListSuccessfully(t *testing.T, fakeServer th.FakeServer) { - images := make([]imageEntry, 3) + images := make([]imageEntry, 4) images[0] = imageEntry{"cirros-0.3.4-x86_64-uec", `{ @@ -98,6 +98,46 @@ func HandleImageListSuccessfully(t *testing.T, fakeServer th.FakeServer) { "hw_disk_bus_model": "virtio-scsi", "hw_scsi_model": "virtio-scsi" }`} + images[3] = imageEntry{"ubuntu-24.04-server-cloudimg-amd64.img", + `{ + "owner_specified.openstack.md5": "", + "owner_specified.openstack.object": "images/johndoe-noble-iso-test", + "owner_specified.openstack.sha256": "", + "properties": "{'hypervisor_type': 'qemu', 'architecture': 'x86_64'}", + "additional_property": "{\"name\": \"noble\", \"size\": 100, \"hidden\": false}", + "name": "johndoe-noble-iso-test", + "disk_format": "iso", + "container_format": "bare", + "visibility": "shared", + "size": 3303444480, + "virtual_size": null, + "status": "active", + "checksum": "19fe5793f7411cfe124d9fa0c0f4d449", + "protected": false, + "min_ram": 0, + "min_disk": 0, + "owner": "dfdfed1a51504178abe8c5eeaeb8343b", + "os_hidden": false, + "os_hash_algo": "sha256", + "os_hash_value": "c3514bf0056180d09376462a7a1b4f213c1d6e8ea67fae5c25099c6fd3d8274b", + "id": "370ba8b7-3e72-4f9d-8623-7d9c95e4c28d", + "created_at": "2025-12-18T02:05:15Z", + "updated_at": "2025-12-18T02:42:05Z", + "locations": [ + { + "url": "rbd://eea9d068-c18c-11ed-8dc0-013aacb71b80/glance/370ba8b7-3e72-4f9d-8623-7d9c95e4c28d/snap", + "metadata": { + "store": "ceph" + } + } + ], + "direct_url": "rbd://eea9d068-c18c-11ed-8dc0-013aacb71b80/glance/370ba8b7-3e72-4f9d-8623-7d9c95e4c28d/snap", + "tags": [], + "self": "/v2/images/370ba8b7-3e72-4f9d-8623-7d9c95e4c28d", + "file": "/v2/images/370ba8b7-3e72-4f9d-8623-7d9c95e4c28d/file", + "schema": "/v2/schemas/image", + "stores": "ceph" + }`} fakeServer.Mux.HandleFunc("/images", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") @@ -282,6 +322,7 @@ func HandleImageGetSuccessfully(t *testing.T, fakeServer th.FakeServer) { "hw_disk_bus": "scsi", "hw_disk_bus_model": "virtio-scsi", "hw_scsi_model": "virtio-scsi" + "properties": "{\"test\": true}", }`) }) } diff --git a/openstack/image/v2/images/testing/requests_test.go b/openstack/image/v2/images/testing/requests_test.go index 90c9833be1..d98ac88ae0 100644 --- a/openstack/image/v2/images/testing/requests_test.go +++ b/openstack/image/v2/images/testing/requests_test.go @@ -40,8 +40,8 @@ func TestListImage(t *testing.T) { th.AssertNoErr(t, err) t.Logf("--------\n%d images listed on %d pages.\n", count, pages) - th.AssertEquals(t, 3, pages) - th.AssertEquals(t, 3, count) + th.AssertEquals(t, 4, pages) + th.AssertEquals(t, 4, count) } func TestAllPagesImage(t *testing.T) { @@ -54,7 +54,7 @@ func TestAllPagesImage(t *testing.T) { th.AssertNoErr(t, err) images, err := images.ExtractImages(pages) th.AssertNoErr(t, err) - th.AssertEquals(t, 3, len(images)) + th.AssertEquals(t, 4, len(images)) } func TestCreateImage(t *testing.T) { @@ -239,6 +239,7 @@ func TestGetImage(t *testing.T) { "hw_disk_bus": "scsi", "hw_disk_bus_model": "virtio-scsi", "hw_scsi_model": "virtio-scsi", + "properties": "{\"test\": true}", }, } From f36b40838c52ad3b6db07fed01a2bfdab1286db5 Mon Sep 17 00:00:00 2001 From: Chi Wai Chan Date: Fri, 19 Dec 2025 12:46:29 +0800 Subject: [PATCH 233/353] test (image/v2): improve CreateEmptyImage --- internal/acceptance/openstack/image/v2/imageservice.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/internal/acceptance/openstack/image/v2/imageservice.go b/internal/acceptance/openstack/image/v2/imageservice.go index caa832ce6b..0454a74b88 100644 --- a/internal/acceptance/openstack/image/v2/imageservice.go +++ b/internal/acceptance/openstack/image/v2/imageservice.go @@ -38,6 +38,7 @@ func CreateEmptyImage(t *testing.T, client *gophercloud.ServiceClient) (*images. Visibility: &visibility, Properties: map[string]string{ "architecture": "x86_64", + "properties": "{'hypervisor_type': 'qemu', 'architecture': 'x86_64'}", }, Tags: []string{"foo", "bar", "baz"}, } @@ -56,6 +57,7 @@ func CreateEmptyImage(t *testing.T, client *gophercloud.ServiceClient) (*images. th.CheckEquals(t, newImage.Name, name) th.CheckEquals(t, newImage.Properties["architecture"], "x86_64") + th.CheckEquals(t, newImage.Properties["properties"], "{'hypervisor_type': 'qemu', 'architecture': 'x86_64'}") return newImage, nil } From 5f68cbff36d691175b59ccd63e5dd0c8d6e98607 Mon Sep 17 00:00:00 2001 From: Chi Wai Chan Date: Fri, 19 Dec 2025 18:13:26 +0800 Subject: [PATCH 234/353] test: add missing comma --- openstack/image/v2/images/testing/fixtures_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openstack/image/v2/images/testing/fixtures_test.go b/openstack/image/v2/images/testing/fixtures_test.go index 9665e4ed55..0f47975677 100644 --- a/openstack/image/v2/images/testing/fixtures_test.go +++ b/openstack/image/v2/images/testing/fixtures_test.go @@ -321,8 +321,8 @@ func HandleImageGetSuccessfully(t *testing.T, fakeServer th.FakeServer) { "virtual_size": null, "hw_disk_bus": "scsi", "hw_disk_bus_model": "virtio-scsi", - "hw_scsi_model": "virtio-scsi" - "properties": "{\"test\": true}", + "hw_scsi_model": "virtio-scsi", + "properties": "{\"test\": true}" }`) }) } From 6469a30987461e979b41fd31db7fae8176cc655f Mon Sep 17 00:00:00 2001 From: Konstantin Eremin Date: Mon, 17 Nov 2025 08:51:08 +0300 Subject: [PATCH 235/353] Add new fields for ListOpts volumetypes Added fields: name, description extra_specs was left out as it would cause an API change. --- .../openstack/blockstorage/v3/blockstorage.go | 2 +- .../blockstorage/v3/volumetypes_test.go | 70 +++++++++- .../blockstorage/v3/volumetypes/requests.go | 4 + .../v3/volumetypes/testing/fixtures_test.go | 127 ++++++++++++++++-- .../v3/volumetypes/testing/requests_test.go | 46 +++++++ 5 files changed, 233 insertions(+), 16 deletions(-) diff --git a/internal/acceptance/openstack/blockstorage/v3/blockstorage.go b/internal/acceptance/openstack/blockstorage/v3/blockstorage.go index 62e11af9b1..23236097c7 100644 --- a/internal/acceptance/openstack/blockstorage/v3/blockstorage.go +++ b/internal/acceptance/openstack/blockstorage/v3/blockstorage.go @@ -158,7 +158,7 @@ func CreateVolumeType(t *testing.T, client *gophercloud.ServiceClient) (*volumet createOpts := volumetypes.CreateOpts{ Name: name, - ExtraSpecs: map[string]string{"volume_backend_name": "fake_backend_name"}, + ExtraSpecs: map[string]string{"volume_backend_name": "fake_backend_name", "RESKEY:availability_zones": "zone", "multiattach": " True"}, Description: description, } diff --git a/internal/acceptance/openstack/blockstorage/v3/volumetypes_test.go b/internal/acceptance/openstack/blockstorage/v3/volumetypes_test.go index f19fd033de..7fa8457b19 100644 --- a/internal/acceptance/openstack/blockstorage/v3/volumetypes_test.go +++ b/internal/acceptance/openstack/blockstorage/v3/volumetypes_test.go @@ -4,6 +4,7 @@ package v3 import ( "context" + "fmt" "testing" "github.com/gophercloud/gophercloud/v2/internal/acceptance/clients" @@ -13,7 +14,7 @@ import ( th "github.com/gophercloud/gophercloud/v2/testhelper" ) -func TestVolumeTypes(t *testing.T) { +func TestVolumeTypesCRUD(t *testing.T) { clients.RequireAdmin(t) client, err := clients.NewBlockStorageV3Client() @@ -39,9 +40,9 @@ func TestVolumeTypes(t *testing.T) { th.AssertEquals(t, found, true) + name := vt.Name + "-updated" + description := vt.Description + "-updated" isPublic := false - name := vt.Name + "-UPDATED" - description := "" updateOpts := volumetypes.UpdateOpts{ Name: &name, Description: &description, @@ -55,6 +56,69 @@ func TestVolumeTypes(t *testing.T) { th.AssertEquals(t, name, newVT.Name) th.AssertEquals(t, description, newVT.Description) th.AssertEquals(t, isPublic, newVT.IsPublic) + newVisibility := volumetypes.VisibilityPrivate + + for _, tt := range []struct { + name string + opts volumetypes.ListOpts + expectedVolumeTypes int + }{ + { + name: "Volume Type Name", + opts: volumetypes.ListOpts{ + Name: newVT.Name, + }, + expectedVolumeTypes: 1, + }, + { + name: "Description", + opts: volumetypes.ListOpts{ + Description: "create_from_gophercloud-updated", + }, + expectedVolumeTypes: 1, + }, + { + name: "Is Public", + opts: volumetypes.ListOpts{ + IsPublic: newVisibility, + }, + expectedVolumeTypes: 1, + }, + } { + t.Run(fmt.Sprintf("List volumetypes by %s", tt.name), func(t *testing.T) { + allPages, err := volumetypes.List(client, tt.opts).AllPages(context.TODO()) + th.AssertNoErr(t, err) + + allVolumeTypes, err := volumetypes.ExtractVolumeTypes(allPages) + th.AssertNoErr(t, err) + + logVolumeTypes := func() { + for _, volumetype := range allVolumeTypes { + tools.PrintResource(t, volumetype) + } + } + + if len(allVolumeTypes) != tt.expectedVolumeTypes { + if len(allVolumeTypes) == 0 { + t.Fatalf("Volume type not found") + } + } else { + if len(allVolumeTypes) > 1 { + logVolumeTypes() + t.Fatalf("Expected %d volume type but got %d", tt.expectedVolumeTypes, len(allVolumeTypes)) + } + } + func() { + for _, volumetype := range allVolumeTypes { + if volumetype.ID == newVT.ID { + return + } + } + logVolumeTypes() + t.Fatalf("Returned volume types did not contain expected volume type") + }() + }) + } } func TestVolumeTypesExtraSpecs(t *testing.T) { diff --git a/openstack/blockstorage/v3/volumetypes/requests.go b/openstack/blockstorage/v3/volumetypes/requests.go index 8849c394fb..d62db1c8b6 100644 --- a/openstack/blockstorage/v3/volumetypes/requests.go +++ b/openstack/blockstorage/v3/volumetypes/requests.go @@ -73,6 +73,10 @@ type ListOptsBuilder interface { // ListOpts holds options for listing Volume Types. It is passed to the volumetypes.List // function. type ListOpts struct { + // Name will filter by the specified volume type name. + Name string `q:"name"` + // Description will filter by the specified volume type description. + Description string `q:"description"` // Specifies whether the query should include public or private Volume Types. // By default, it queries both types. IsPublic visibility `q:"is_public"` diff --git a/openstack/blockstorage/v3/volumetypes/testing/fixtures_test.go b/openstack/blockstorage/v3/volumetypes/testing/fixtures_test.go index f1cacd21de..d305f22fbb 100644 --- a/openstack/blockstorage/v3/volumetypes/testing/fixtures_test.go +++ b/openstack/blockstorage/v3/volumetypes/testing/fixtures_test.go @@ -195,6 +195,121 @@ var UpdatedExtraSpec = map[string]string{ "capabilities": "gpu-2", } +func HandleListIsPublicParam(t *testing.T, fakeServer th.FakeServer, values map[string]string) { + fakeServer.Mux.HandleFunc("/types", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.TestFormValues(t, r, values) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + fmt.Fprint(w, `{"volume_types": []}`) + }) +} + +func HandleListWithNameFilter(t *testing.T, fakeServer th.FakeServer, values map[string]string) { + fakeServer.Mux.HandleFunc("/types", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.TestFormValues(t, r, values) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + fmt.Fprint(w, ` +{ + "volume_types": [ + { + "name": "test-type", + "qos_specs_id": null, + "os-volume-type-access:is_public": true, + "extra_specs": { + "storage_protocol": "nfs" + }, + "is_public": true, + "id": "996af3df-92fd-4814-a0ee-ba5f899aa1ec", + "description": "test" + } + ] +} +`) + }) +} + +func HandleListWithDescriptionFilter(t *testing.T, fakeServer th.FakeServer, values map[string]string) { + fakeServer.Mux.HandleFunc("/types", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.TestFormValues(t, r, values) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + fmt.Fprint(w, ` +{ + "volume_types": [ + { + "name": "test-type", + "qos_specs_id": null, + "os-volume-type-access:is_public": true, + "extra_specs": { + "multiattach": " True" + }, + "is_public": true, + "id": "ab948f0a-13ed-47c8-b9be-cade0beb0706", + "description": "test" + } + ] +} +`) + }) +} + +func HandleListWithExtraSpecsFilter(t *testing.T, fakeServer th.FakeServer, values map[string]string) { + fakeServer.Mux.HandleFunc("/types", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.TestFormValues(t, r, values) + + if err := r.ParseForm(); err != nil { + t.Errorf("Failed to parse request form %v", err) + } + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + + extraSpecsFilter := r.Form.Get("extra_specs") + + // Determine which volume type to return based on extra_specs filter. + // Note: We only test with a single extra_spec value because testing multiple + // values is not feasible due to the non-deterministic order of map keys in Go. + // The order of keys in the serialized string can vary between runs, making + // it impossible to reliably match the expected string without adding complex + // normalization code that would clutter the test. + if extraSpecsFilter == "{'storage_protocol':'nfs'}" { + // Return only nfs-type + fmt.Fprint(w, ` +{ + "volume_types": [ + { + "name": "nfs-type", + "qos_specs_id": null, + "os-volume-type-access:is_public": true, + "extra_specs": { + "storage_protocol": "nfs" + }, + "is_public": true, + "id": "6b0cfee7-48b6-41b7-9d68-0d74cbdc08de", + "description": "NFS storage type" + } + ] +} +`) + } else { + // Default: return empty list + fmt.Fprint(w, `{"volume_types": []}`) + } + }) +} + func HandleExtraSpecsListSuccessfully(t *testing.T, fakeServer th.FakeServer) { fakeServer.Mux.HandleFunc("/types/1/extra_specs", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") @@ -377,15 +492,3 @@ func MockEncryptionGetSpecResponse(t *testing.T, fakeServer th.FakeServer) { `) }) } - -func HandleListIsPublicParam(t *testing.T, fakeServer th.FakeServer, values map[string]string) { - fakeServer.Mux.HandleFunc("/types", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - th.TestFormValues(t, r, values) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - fmt.Fprint(w, `{"volume_types": []}`) - }) -} diff --git a/openstack/blockstorage/v3/volumetypes/testing/requests_test.go b/openstack/blockstorage/v3/volumetypes/testing/requests_test.go index 2ed84d144e..b64a269c59 100644 --- a/openstack/blockstorage/v3/volumetypes/testing/requests_test.go +++ b/openstack/blockstorage/v3/volumetypes/testing/requests_test.go @@ -162,6 +162,52 @@ func TestListIsPublicParam(t *testing.T) { th.AssertNoErr(t, err) } +func TestListNameParam(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + result := make(map[string]string) + HandleListWithNameFilter(t, fakeServer, result) + + result["is_public"] = "None" + result["name"] = "test-type" + allPages, err := volumetypes.List(client.ServiceClient(fakeServer), volumetypes.ListOpts{ + Name: "test-type", + }).AllPages(context.TODO()) + th.AssertNoErr(t, err) + actual, err := volumetypes.ExtractVolumeTypes(allPages) + th.AssertNoErr(t, err) + th.AssertEquals(t, 1, len(actual)) + th.AssertEquals(t, "test-type", actual[0].Name) + th.AssertEquals(t, "996af3df-92fd-4814-a0ee-ba5f899aa1ec", actual[0].ID) + th.AssertEquals(t, "test", actual[0].Description) + th.AssertEquals(t, true, actual[0].IsPublic) + th.AssertEquals(t, true, actual[0].PublicAccess) + th.AssertEquals(t, "nfs", actual[0].ExtraSpecs["storage_protocol"]) +} + +func TestListDescriptionParam(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + result := make(map[string]string) + HandleListWithDescriptionFilter(t, fakeServer, result) + + result["is_public"] = "None" + result["description"] = "test" + allPages, err := volumetypes.List(client.ServiceClient(fakeServer), volumetypes.ListOpts{ + Description: "test", + }).AllPages(context.TODO()) + th.AssertNoErr(t, err) + actual, err := volumetypes.ExtractVolumeTypes(allPages) + th.AssertNoErr(t, err) + th.AssertEquals(t, 1, len(actual)) + th.AssertEquals(t, "test", actual[0].Description) + th.AssertEquals(t, "test-type", actual[0].Name) + th.AssertEquals(t, "ab948f0a-13ed-47c8-b9be-cade0beb0706", actual[0].ID) + th.AssertEquals(t, true, actual[0].IsPublic) + th.AssertEquals(t, true, actual[0].PublicAccess) + th.AssertEquals(t, " True", actual[0].ExtraSpecs["multiattach"]) +} + func TestVolumeTypeExtraSpecsList(t *testing.T) { fakeServer := th.SetupHTTP() defer fakeServer.Teardown() From 288ff18b2fcf839e12447965fc4ac353b03f90cc Mon Sep 17 00:00:00 2001 From: Winicius Silva Date: Fri, 12 Dec 2025 11:18:21 -0300 Subject: [PATCH 236/353] identity.v3.Endpoint: make name as optional on creation --- openstack/identity/v3/endpoints/requests.go | 2 +- openstack/identity/v3/endpoints/testing/requests_test.go | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/openstack/identity/v3/endpoints/requests.go b/openstack/identity/v3/endpoints/requests.go index 45893aa3c6..8c08542848 100644 --- a/openstack/identity/v3/endpoints/requests.go +++ b/openstack/identity/v3/endpoints/requests.go @@ -26,7 +26,7 @@ type CreateOpts struct { Enabled *bool `json:"enabled,omitempty"` // Name is the name of the Endpoint. - Name string `json:"name" required:"true"` + Name string `json:"name,omitempty"` // Region is the region the Endpoint is located in. // This field can be omitted or left as a blank string. diff --git a/openstack/identity/v3/endpoints/testing/requests_test.go b/openstack/identity/v3/endpoints/testing/requests_test.go index 07798947c6..8e50467e25 100644 --- a/openstack/identity/v3/endpoints/testing/requests_test.go +++ b/openstack/identity/v3/endpoints/testing/requests_test.go @@ -23,7 +23,6 @@ func TestCreateSuccessful(t *testing.T) { th.TestJSONRequest(t, r, `{ "endpoint": { "interface": "public", - "name": "the-endiest-of-points", "region": "underground", "url": "https://1.2.3.4:9000/", "service_id": "asdfasdfasdfasdf", @@ -41,7 +40,6 @@ func TestCreateSuccessful(t *testing.T) { "links": { "self": "https://localhost:5000/v3/endpoints/12" }, - "name": "the-endiest-of-points", "region": "underground", "service_id": "asdfasdfasdfasdf", "url": "https://1.2.3.4:9000/", @@ -53,7 +51,6 @@ func TestCreateSuccessful(t *testing.T) { enabled := false actual, err := endpoints.Create(context.TODO(), client.ServiceClient(fakeServer), endpoints.CreateOpts{ Availability: gophercloud.AvailabilityPublic, - Name: "the-endiest-of-points", Region: "underground", URL: "https://1.2.3.4:9000/", ServiceID: "asdfasdfasdfasdf", @@ -65,7 +62,6 @@ func TestCreateSuccessful(t *testing.T) { expected := &endpoints.Endpoint{ ID: "12", Availability: gophercloud.AvailabilityPublic, - Name: "the-endiest-of-points", Enabled: false, Region: "underground", ServiceID: "asdfasdfasdfasdf", From 0719b09eab63875440616cfd15dee45190a1d747 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Andr=C3=A9?= Date: Mon, 5 Jan 2026 11:20:37 +0100 Subject: [PATCH 237/353] Prepare for v2.10.0 Update changelog for new release and bump version. --- CHANGELOG.md | 12 ++++++++++++ provider_client.go | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 773af218e9..d53f641b8a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,15 @@ +## v2.10.0 (2026-01-05) + +* [GH-3569](https://github.com/gophercloud/gophercloud/pull/3569) identity/role: restore backward compatibility for description +* [GH-3570](https://github.com/gophercloud/gophercloud/pull/3570) [v2] identityv3/service: add `name` and `description` fields +* [GH-3577](https://github.com/gophercloud/gophercloud/pull/3577) [v2] add: description field to identity.v3.Endpoint +* [GH-3580](https://github.com/gophercloud/gophercloud/pull/3580) [v2] keystone: add support for per page limit +* [GH-3582](https://github.com/gophercloud/gophercloud/pull/3582) [v2] network.v2.Port: add support for update mac_address +* [GH-3585](https://github.com/gophercloud/gophercloud/pull/3585) [v2] identity.v3.Endpoint: add enabled field on creation and on update +* [GH-3590](https://github.com/gophercloud/gophercloud/pull/3590) [v2] fix (image/v2/images): image v2 unmarshal issue +* [GH-3594](https://github.com/gophercloud/gophercloud/pull/3594) [v2] Add new fields for ListOpts volumetypes +* [GH-3595](https://github.com/gophercloud/gophercloud/pull/3595) [v2] identity.v3.Endpoint: make name as optional on creation + ## v2.9.0 (2025-11-17) * [GH-3508](https://github.com/gophercloud/gophercloud/pull/3508) [v2] Trigger "hold" workflow on merge groups diff --git a/provider_client.go b/provider_client.go index 9048e83def..a9bde9457c 100644 --- a/provider_client.go +++ b/provider_client.go @@ -14,7 +14,7 @@ import ( // DefaultUserAgent is the default User-Agent string set in the request header. const ( - DefaultUserAgent = "gophercloud/v2.9.0" + DefaultUserAgent = "gophercloud/v2.10.0" DefaultMaxBackoffRetries = 60 ) From 492a6dd62c643971073a44cc9bd19c1975e328c9 Mon Sep 17 00:00:00 2001 From: MahnoorAsghar Date: Thu, 8 Jan 2026 13:58:44 +0100 Subject: [PATCH 238/353] Add PCIAddress field to baremetal InterfaceType --- openstack/baremetal/inventory/types.go | 1 + 1 file changed, 1 insertion(+) diff --git a/openstack/baremetal/inventory/types.go b/openstack/baremetal/inventory/types.go index 468f32a74f..98498d530d 100644 --- a/openstack/baremetal/inventory/types.go +++ b/openstack/baremetal/inventory/types.go @@ -24,6 +24,7 @@ type InterfaceType struct { Product string `json:"product"` SpeedMbps int `json:"speed_mbps"` Vendor string `json:"vendor"` + PCIAddress string `json:"pci_address"` } type MemoryType struct { From a92612c5a6ca74b68610c62771b93b05f6cec12d Mon Sep 17 00:00:00 2001 From: Daniel Lawton Date: Thu, 22 Jan 2026 10:59:27 +0000 Subject: [PATCH 239/353] Networking V2: Added support for ML2 extension port_trusted_vif field. This allows users to create and update the 'trusted' status of a port via the ML2 extension. Includes: - Extension package definition - Request/Response structs (CreateOptsExt, UpdateOptsExt) - Unit tests and acceptance tests Signed-off-by: Daniel Lawton --- .github/workflows/functional-networking.yaml | 2 +- .../openstack/networking/v2/ports_test.go | 54 ++++ .../v2/extensions/portstrustedvif/doc.go | 74 ++++++ .../v2/extensions/portstrustedvif/requests.go | 53 ++++ .../v2/extensions/portstrustedvif/results.go | 6 + .../portstrustedvif/testing/fixtures_test.go | 161 ++++++++++++ .../portstrustedvif/testing/requests_test.go | 242 ++++++++++++++++++ 7 files changed, 591 insertions(+), 1 deletion(-) create mode 100644 openstack/networking/v2/extensions/portstrustedvif/doc.go create mode 100644 openstack/networking/v2/extensions/portstrustedvif/requests.go create mode 100644 openstack/networking/v2/extensions/portstrustedvif/results.go create mode 100644 openstack/networking/v2/extensions/portstrustedvif/testing/fixtures_test.go create mode 100644 openstack/networking/v2/extensions/portstrustedvif/testing/requests_test.go diff --git a/.github/workflows/functional-networking.yaml b/.github/workflows/functional-networking.yaml index efe7743a10..6f92da2456 100644 --- a/.github/workflows/functional-networking.yaml +++ b/.github/workflows/functional-networking.yaml @@ -49,7 +49,7 @@ jobs: enable_plugin neutron-dynamic-routing https://github.com/openstack/neutron-dynamic-routing ${{ matrix.openstack_version }} enable_plugin neutron-vpnaas https://github.com/openstack/neutron-vpnaas ${{ matrix.openstack_version }} enable_plugin networking-bgpvpn https://github.com/openstack/networking-bgpvpn.git ${{ matrix.openstack_version }} - Q_ML2_PLUGIN_EXT_DRIVERS=qos,port_security,dns_domain_keywords + Q_ML2_PLUGIN_EXT_DRIVERS=qos,port_security,dns_domain_keywords,port_trusted BGP_SCHEDULER_DRIVER=neutron_dynamic_routing.services.bgp.scheduler.bgp_dragent_scheduler.StaticScheduler [[post-config|\$NEUTRON_CONF]] diff --git a/internal/acceptance/openstack/networking/v2/ports_test.go b/internal/acceptance/openstack/networking/v2/ports_test.go index f6ff48e829..1506e4f8d6 100644 --- a/internal/acceptance/openstack/networking/v2/ports_test.go +++ b/internal/acceptance/openstack/networking/v2/ports_test.go @@ -13,6 +13,7 @@ import ( "github.com/gophercloud/gophercloud/v2/internal/acceptance/tools" "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/extensions/extradhcpopts" "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/extensions/portsecurity" + "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/extensions/portstrustedvif" "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/ports" th "github.com/gophercloud/gophercloud/v2/testhelper" ) @@ -467,6 +468,59 @@ func TestPortsWithExtraDHCPOptsCRUD(t *testing.T) { tools.PrintResource(t, newPort) } +func TestPortsTrustedVIFCRUD(t *testing.T) { + client, err := clients.NewNetworkV2Client() + if err != nil { + t.Fatalf("Unable to create a network client: %v", err) + } + + // Create Network + network, err := CreateNetwork(t, client) + if err != nil { + t.Fatalf("Unable to create network: %v", err) + } + defer DeleteNetwork(t, client, network.ID) + + // Create Subnet + subnet, err := CreateSubnet(t, client, network.ID) + if err != nil { + t.Fatalf("Unable to create subnet: %v", err) + } + defer DeleteSubnet(t, client, subnet.ID) + + // Create port + port, err := CreatePort(t, client, network.ID, subnet.ID) + if err != nil { + t.Fatalf("Unable to create port: %v", err) + } + defer DeletePort(t, client, port.ID) + + var portWithExt struct { + ports.Port + portstrustedvif.PortTrustedVIFExt + } + + err = ports.Get(context.TODO(), client, port.ID).ExtractInto(&portWithExt) + if err != nil { + t.Fatalf("Unable to create port: %v", err) + } + + tools.PrintResource(t, portWithExt) + + // Update Port Trusted VIF status as true + iTrue := true + portUpdateOpts := ports.UpdateOpts{} + updateOpts := portstrustedvif.PortUpdateOptsExt{ + UpdateOptsBuilder: portUpdateOpts, + PortTrustedVIF: &iTrue, + } + + err = ports.Update(context.TODO(), client, port.ID, updateOpts).ExtractInto(&portWithExt) + if err != nil { + t.Fatalf("Unable to update port: %v", err) + } +} + func TestPortsRevision(t *testing.T) { client, err := clients.NewNetworkV2Client() th.AssertNoErr(t, err) diff --git a/openstack/networking/v2/extensions/portstrustedvif/doc.go b/openstack/networking/v2/extensions/portstrustedvif/doc.go new file mode 100644 index 0000000000..9efedf04ad --- /dev/null +++ b/openstack/networking/v2/extensions/portstrustedvif/doc.go @@ -0,0 +1,74 @@ +/* +Package portstrustedvif provides information and interaction with the port +trusted vif extension which adds trusted attributes to the port resource +for the OpenStack Networking service. + +Example to Get a Port with a Port Trusted VIF + + var portWithPortTrustedVIFExtension struct { + ports.Port + portstrustedvif.PortTrustedVIFExt + } + + portID := "46d4bfb9-b26e-41f3-bd2e-e6dcc1ccedb2" + + err := ports.Get(context.TODO(), networkingClient, portID).ExtractInto(&portWithPortTrustedVIFExtension) + if err != nil { + panic(err) + } + + fmt.Printf("%+v\n", portWithPortTrustedVIFExtension) + +Example to Create a Port With Port Trusted VIF set as true + + var portWithPortTrustedVIFExtension struct { + ports.Port + portstrustedvif.PortTrustedVIFExt + } + + iTrue := true + networkID := "4e8e5957-649f-477b-9e5b-f1f75b21c03c" + subnetID := "a87cc70a-3e15-4acf-8205-9b711a3531b7" + + portCreateOpts := ports.CreateOpts{ + NetworkID: networkID, + FixedIPs: []ports.IP{ports.IP{SubnetID: subnetID}}, + } + + createOpts := portstrustedvif.PortCreateOptsExt{ + CreateOptsBuilder: portCreateOpts, + PortTrustedVIF: &iTrue, + } + + err := ports.Create(context.TODO(), networkingClient, createOpts).ExtractInto(&portWithPortTrustedVIFExtension) + if err != nil { + panic(err) + } + + fmt.Printf("%+v\n", portWithPortTrustedVIFExtension) + +Example to Update the status of the Port Trusted VIF to false on an Existing Port + + var portWithPortTrustedVIDExtension struct { + ports.Port + portstrustedvif.PortTrustedVIFExt + } + + iFalse := false + portID := "65c0ee9f-d634-4522-8954-51021b570b0d" + + portUpdateOpts := ports.UpdateOpts{} + updateOpts := portstrustedvif.PortUpdateOptsExt{ + UpdateOptsBuilder: portUpdateOpts, + PortTrustedVIF: &iFalse, + } + + err := ports.Update(context.TODO(), networkingClient, portID, updateOpts).ExtractInto(&portWithPortTrustedVIFExtension) + if err != nil { + panic(err) + } + + fmt.Printf("%+v\n", portWithPortTrustedVIFExtension) +*/ + +package portstrustedvif diff --git a/openstack/networking/v2/extensions/portstrustedvif/requests.go b/openstack/networking/v2/extensions/portstrustedvif/requests.go new file mode 100644 index 0000000000..c4166ce1bd --- /dev/null +++ b/openstack/networking/v2/extensions/portstrustedvif/requests.go @@ -0,0 +1,53 @@ +package portstrustedvif + +import ( + "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/ports" +) + +// PortCreateOptsExt adds port trusted VIF options to the base ports.CreateOpts. +type PortCreateOptsExt struct { + ports.CreateOptsBuilder + + // PortTrustedVIF toggles the port's trusted VIF status. + PortTrustedVIF *bool `json:"trusted,omitempty"` +} + +// To PortCreateMap casts a CreateOpts struct to a map +func (opts PortCreateOptsExt) ToPortCreateMap() (map[string]any, error) { + base, err := opts.CreateOptsBuilder.ToPortCreateMap() + if err != nil { + return nil, err + } + + port := base["port"].(map[string]any) + + if opts.PortTrustedVIF != nil { + port["trusted"] = *opts.PortTrustedVIF + } + + return base, nil +} + +// PortUpdateOptsExt adds port trusted VIF options to the base ports.UpdateOpts. +type PortUpdateOptsExt struct { + ports.UpdateOptsBuilder + + // PortTrustedVIF updates the port's trusted VIF status. + PortTrustedVIF *bool `json:"trusted,omitempty"` +} + +// ToPortUpdateMap casts a UpdateOpts struct to a map. +func (opts PortUpdateOptsExt) ToPortUpdateMap() (map[string]any, error) { + base, err := opts.UpdateOptsBuilder.ToPortUpdateMap() + if err != nil { + return nil, err + } + + port := base["port"].(map[string]any) + + if opts.PortTrustedVIF != nil { + port["trusted"] = *opts.PortTrustedVIF + } + + return base, nil +} diff --git a/openstack/networking/v2/extensions/portstrustedvif/results.go b/openstack/networking/v2/extensions/portstrustedvif/results.go new file mode 100644 index 0000000000..39cfeacfaa --- /dev/null +++ b/openstack/networking/v2/extensions/portstrustedvif/results.go @@ -0,0 +1,6 @@ +package portstrustedvif + +type PortTrustedVIFExt struct { + // PortTrustedVIF stores information about whether a SR-IOV port should be trusted + PortTrustedVIF *bool `json:"trusted"` +} diff --git a/openstack/networking/v2/extensions/portstrustedvif/testing/fixtures_test.go b/openstack/networking/v2/extensions/portstrustedvif/testing/fixtures_test.go new file mode 100644 index 0000000000..0a9df88bbe --- /dev/null +++ b/openstack/networking/v2/extensions/portstrustedvif/testing/fixtures_test.go @@ -0,0 +1,161 @@ +package testing + +const ListResponse = ` +{ + "ports": [ + { + "status": "ACTIVE", + "binding:host_id": "devstack", + "name": "", + "admin_state_up": true, + "network_id": "70c1db1f-b701-45bd-96e0-a313ee3430b3", + "tenant_id": "", + "device_owner": "network:router_gateway", + "mac_address": "fa:16:3e:58:42:ed", + "binding:vnic_type": "normal", + "fixed_ips": [ + { + "subnet_id": "008ba151-0b8c-4a67-98b5-0d2b87666062", + "ip_address": "172.24.4.2" + } + ], + "id": "d80b1a3b-4fc1-49f3-952e-1e2ab7081d8b", + "security_groups": [], + "dns_name": "test-port", + "dns_assignment": [ + { + "hostname": "test-port", + "ip_address": "172.24.4.2", + "fqdn": "test-port.openstack.local." + } + ], + "device_id": "9ae135f4-b6e0-4dad-9e91-3c223e385824", + "port_security_enabled": false, + "trusted": true, + "created_at": "2019-06-30T04:15:37", + "updated_at": "2019-06-30T05:18:49" + } + ] +} +` + +const GetPortTrustedVIFStatusResponse = ` +{ + "port": { + "status": "DOWN", + "name": "private-port", + "admin_state_up": true, + "network_id": "a87cc70a-3e15-4acf-8205-9b711a3531b7", + "tenant_id": "d6700c0c9ffa4f1cb322cd4a1f3906fa", + "device_owner": "", + "mac_address": "fa:16:3e:c9:cb:f0", + "fixed_ips": [ + { + "subnet_id": "a0304c3a-4f08-4c43-88af-d796509c97d2", + "ip_address": "10.0.0.1" + } + ], + "id": "46d4bfb9-b26e-41f3-bd2e-e6dcc1ccedb2", + "trusted": false, + "device_id": "" + } +} +` +const GetPortTrustedVIFUnsetResponse = ` +{ + "port": { + "status": "DOWN", + "name": "private-port", + "admin_state_up": true, + "network_id": "a87cc70a-3e15-4acf-8205-9b711a3531b7", + "tenant_id": "d6700c0c9ffa4f1cb322cd4a1f3906fa", + "device_owner": "", + "mac_address": "fa:16:3e:c9:cb:f0", + "fixed_ips": [ + { + "subnet_id": "a0304c3a-4f08-4c43-88af-d796509c97d2", + "ip_address": "10.0.0.1" + } + ], + "id": "46d4bfb9-b26e-41f3-bd2e-e6dcc1ccedb2", + "device_id": "" + } +} +` + +const CreatePortTrustedVIFRequest = ` +{ + "port": { + "network_id": "a87cc70a-3e15-4acf-8205-9b711a3531b7", + "name": "private-port", + "admin_state_up": true, + "fixed_ips": [ + { + "subnet_id": "a0304c3a-4f08-4c43-88af-d796509c97d2", + "ip_address": "10.0.0.2" + } + ], + "trusted": true + } +}` + +const CreatePortTrustedVIFResponse = ` +{ + "port": { + "status": "DOWN", + "name": "private-port", + "admin_state_up": true, + "network_id": "a87cc70a-3e15-4acf-8205-9b711a3531b7", + "tenant_id": "d6700c0c9ffa4f1cb322cd4a1f3906fa", + "device_owner": "", + "mac_address": "fa:16:3e:c9:cb:f0", + "fixed_ips": [ + { + "subnet_id": "a0304c3a-4f08-4c43-88af-d796509c97d2", + "ip_address": "10.0.0.2" + } + ], + "id": "65c0ee9f-d634-4522-8954-51021b570b0d", + "trusted": true, + "device_id": "" + } +}` + +const UpdatePortTrustedVIFRequest = ` +{ + "port": { + "trusted": false + } +}` + +const UpdatePortTrustedVIFResponse = ` +{ + "port": { + "status": "DOWN", + "name": "private-port", + "admin_state_up": true, + "network_id": "a87cc70a-3e15-4acf-8205-9b711a3531b7", + "tenant_id": "d6700c0c9ffa4f1cb322cd4a1f3906fa", + "device_owner": "", + "mac_address": "fa:16:3e:c9:cb:f0", + "fixed_ips": [ + { + "subnet_id": "a0304c3a-4f08-4c43-88af-d796509c97d2", + "ip_address": "10.0.0.3" + } + ], + "allowed_address_pairs": [ + { + "ip_address": "10.0.0.4", + "mac_address": "fa:16:3e:c9:cb:f0" + } + ], + "id": "65c0ee9f-d634-4522-8954-51021b570b0d", + "security_groups": [ + "f0ac4394-7e4a-4409-9701-ba8be283dbc3" + ], + "trusted": false, + "device_id": "" + } +} +` diff --git a/openstack/networking/v2/extensions/portstrustedvif/testing/requests_test.go b/openstack/networking/v2/extensions/portstrustedvif/testing/requests_test.go new file mode 100644 index 0000000000..e768dda87b --- /dev/null +++ b/openstack/networking/v2/extensions/portstrustedvif/testing/requests_test.go @@ -0,0 +1,242 @@ +package testing + +import ( + "context" + "fmt" + "net/http" + "testing" + "time" + + fake "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/common" + "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/extensions/portstrustedvif" + "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/ports" + th "github.com/gophercloud/gophercloud/v2/testhelper" +) + +func TestList(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + fakeServer.Mux.HandleFunc("/v2.0/ports", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + + fmt.Fprint(w, ListResponse) + }) + + type PortWithExt struct { + ports.Port + portstrustedvif.PortTrustedVIFExt + } + var actual []PortWithExt + + iTrue := true + expected := []PortWithExt{ + { + Port: ports.Port{ + Status: "ACTIVE", + Name: "", + AdminStateUp: true, + NetworkID: "70c1db1f-b701-45bd-96e0-a313ee3430b3", + TenantID: "", + DeviceOwner: "network:router_gateway", + MACAddress: "fa:16:3e:58:42:ed", + FixedIPs: []ports.IP{ + { + SubnetID: "008ba151-0b8c-4a67-98b5-0d2b87666062", + IPAddress: "172.24.4.2", + }, + }, + ID: "d80b1a3b-4fc1-49f3-952e-1e2ab7081d8b", + SecurityGroups: []string{}, + DeviceID: "9ae135f4-b6e0-4dad-9e91-3c223e385824", + CreatedAt: time.Date(2019, time.June, 30, 4, 15, 37, 0, time.UTC), + UpdatedAt: time.Date(2019, time.June, 30, 5, 18, 49, 0, time.UTC), + }, + PortTrustedVIFExt: portstrustedvif.PortTrustedVIFExt{ + PortTrustedVIF: &iTrue, + }, + }, + } + + allPages, err := ports.List(fake.ServiceClient(fakeServer), ports.ListOpts{}).AllPages(context.TODO()) + th.AssertNoErr(t, err) + + err = ports.ExtractPortsInto(allPages, &actual) + th.AssertNoErr(t, err) + + th.CheckDeepEquals(t, expected, actual) +} + +func TestGet(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + fakeServer.Mux.HandleFunc("/v2.0/ports/46d4bfb9-b26e-41f3-bd2e-e6dcc1ccedb2", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + + fmt.Fprint(w, GetPortTrustedVIFStatusResponse) + }) + + var s struct { + ports.Port + portstrustedvif.PortTrustedVIFExt + } + + err := ports.Get(context.TODO(), fake.ServiceClient(fakeServer), "46d4bfb9-b26e-41f3-bd2e-e6dcc1ccedb2").ExtractInto(&s) + th.AssertNoErr(t, err) + + th.AssertEquals(t, s.Status, "DOWN") + th.AssertEquals(t, s.Name, "private-port") + th.AssertEquals(t, s.AdminStateUp, true) + th.AssertEquals(t, s.NetworkID, "a87cc70a-3e15-4acf-8205-9b711a3531b7") + th.AssertEquals(t, s.TenantID, "d6700c0c9ffa4f1cb322cd4a1f3906fa") + th.AssertEquals(t, s.DeviceOwner, "") + th.AssertEquals(t, s.MACAddress, "fa:16:3e:c9:cb:f0") + th.AssertDeepEquals(t, s.FixedIPs, []ports.IP{ + {SubnetID: "a0304c3a-4f08-4c43-88af-d796509c97d2", IPAddress: "10.0.0.1"}, + }) + th.AssertEquals(t, s.ID, "46d4bfb9-b26e-41f3-bd2e-e6dcc1ccedb2") + th.AssertEquals(t, s.DeviceID, "") + + if s.PortTrustedVIF == nil { + t.Fatalf("Expected s.PortTrustedVIF to be not nil") + } + th.AssertEquals(t, *s.PortTrustedVIF, false) +} + +func TestGetUnset(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + fakeServer.Mux.HandleFunc("/v2.0/ports/46d4bfb9-b26e-41f3-bd2e-e6dcc1ccedb2", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + + fmt.Fprint(w, GetPortTrustedVIFUnsetResponse) + }) + + var s struct { + ports.Port + portstrustedvif.PortTrustedVIFExt + } + + err := ports.Get(context.TODO(), fake.ServiceClient(fakeServer), "46d4bfb9-b26e-41f3-bd2e-e6dcc1ccedb2").ExtractInto(&s) + th.AssertNoErr(t, err) + + th.AssertEquals(t, s.Status, "DOWN") + th.AssertEquals(t, s.Name, "private-port") + th.AssertEquals(t, s.AdminStateUp, true) + th.AssertEquals(t, s.NetworkID, "a87cc70a-3e15-4acf-8205-9b711a3531b7") + th.AssertEquals(t, s.TenantID, "d6700c0c9ffa4f1cb322cd4a1f3906fa") + th.AssertEquals(t, s.DeviceOwner, "") + th.AssertEquals(t, s.MACAddress, "fa:16:3e:c9:cb:f0") + th.AssertDeepEquals(t, s.FixedIPs, []ports.IP{ + {SubnetID: "a0304c3a-4f08-4c43-88af-d796509c97d2", IPAddress: "10.0.0.1"}, + }) + th.AssertEquals(t, s.ID, "46d4bfb9-b26e-41f3-bd2e-e6dcc1ccedb2") + th.AssertEquals(t, s.DeviceID, "") + + if s.PortTrustedVIF != nil { + t.Fatalf("Expected s.PortTrustedVIF to be nil") + } +} + +func TestCreateWithPortTrustedVIF(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + fakeServer.Mux.HandleFunc("/v2.0/ports", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "POST") + th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "Content-Type", "application/json") + th.TestHeader(t, r, "Accept", "application/json") + th.TestJSONRequest(t, r, CreatePortTrustedVIFRequest) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusCreated) + + fmt.Fprint(w, CreatePortTrustedVIFResponse) + }) + + var portWithExt struct { + ports.Port + portstrustedvif.PortTrustedVIFExt + } + + asu := true + portTrustedVIFStatus := true + options := ports.CreateOpts{ + Name: "private-port", + AdminStateUp: &asu, + NetworkID: "a87cc70a-3e15-4acf-8205-9b711a3531b7", + FixedIPs: []ports.IP{ + {SubnetID: "a0304c3a-4f08-4c43-88af-d796509c97d2", IPAddress: "10.0.0.2"}, + }, + } + createOpts := portstrustedvif.PortCreateOptsExt{ + CreateOptsBuilder: options, + PortTrustedVIF: &portTrustedVIFStatus, + } + err := ports.Create(context.TODO(), fake.ServiceClient(fakeServer), createOpts).ExtractInto(&portWithExt) + th.AssertNoErr(t, err) + + th.AssertEquals(t, portWithExt.Status, "DOWN") + th.AssertEquals(t, portWithExt.Name, "private-port") + th.AssertEquals(t, portWithExt.AdminStateUp, true) + th.AssertEquals(t, portWithExt.NetworkID, "a87cc70a-3e15-4acf-8205-9b711a3531b7") + th.AssertEquals(t, portWithExt.TenantID, "d6700c0c9ffa4f1cb322cd4a1f3906fa") + th.AssertEquals(t, portWithExt.DeviceOwner, "") + th.AssertEquals(t, portWithExt.MACAddress, "fa:16:3e:c9:cb:f0") + th.AssertDeepEquals(t, portWithExt.FixedIPs, []ports.IP{ + {SubnetID: "a0304c3a-4f08-4c43-88af-d796509c97d2", IPAddress: "10.0.0.2"}, + }) + th.AssertEquals(t, portWithExt.ID, "65c0ee9f-d634-4522-8954-51021b570b0d") + th.AssertEquals(t, *portWithExt.PortTrustedVIF, true) +} + +func TestUpdatePortTrustedVIF(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + fakeServer.Mux.HandleFunc("/v2.0/ports/65c0ee9f-d634-4522-8954-51021b570b0d", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "PUT") + th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "Content-Type", "application/json") + th.TestHeader(t, r, "Accept", "application/json") + th.TestJSONRequest(t, r, UpdatePortTrustedVIFRequest) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + + fmt.Fprint(w, UpdatePortTrustedVIFResponse) + }) + + var portWithExt struct { + ports.Port + portstrustedvif.PortTrustedVIFExt + } + + portTrustedVIFStatus := false + portUpdateOpts := ports.UpdateOpts{} + updateOpts := portstrustedvif.PortUpdateOptsExt{ + UpdateOptsBuilder: portUpdateOpts, + PortTrustedVIF: &portTrustedVIFStatus, + } + + err := ports.Update(context.TODO(), fake.ServiceClient(fakeServer), "65c0ee9f-d634-4522-8954-51021b570b0d", updateOpts).ExtractInto(&portWithExt) + th.AssertNoErr(t, err) + + th.AssertEquals(t, portWithExt.Name, "private-port") + th.AssertDeepEquals(t, *portWithExt.PortTrustedVIF, false) +} From 3a7790f8b63bf27252a211d1c349766a50656b5d Mon Sep 17 00:00:00 2001 From: Mohammed Al-Dokimi Date: Mon, 12 Jan 2026 17:24:03 +0000 Subject: [PATCH 240/353] networking/v2/layer3/routers: Add external gateways management Add support for managing external gateways on routers: * AddExternalGateways * UpdateExternalGateways * RemoveExternalGateways These operations extend router.external_gateway_info to support multiple external gateways on a single router. Ref: https://docs.openstack.org/api-ref/network/v2/index.html#add-external-gateways-to-router --- .../v2/extensions/layer3/routers_test.go | 91 ++++++++ .../v2/extensions/layer3/routers/doc.go | 68 ++++++ .../v2/extensions/layer3/routers/requests.go | 96 +++++++++ .../layer3/routers/testing/requests_test.go | 200 ++++++++++++++++++ .../v2/extensions/layer3/routers/urls.go | 12 ++ 5 files changed, 467 insertions(+) diff --git a/internal/acceptance/openstack/networking/v2/extensions/layer3/routers_test.go b/internal/acceptance/openstack/networking/v2/extensions/layer3/routers_test.go index 5930be2a1e..be275f2ce1 100644 --- a/internal/acceptance/openstack/networking/v2/extensions/layer3/routers_test.go +++ b/internal/acceptance/openstack/networking/v2/extensions/layer3/routers_test.go @@ -4,9 +4,11 @@ package layer3 import ( "context" + "net/http" "strings" "testing" + "github.com/gophercloud/gophercloud/v2" "github.com/gophercloud/gophercloud/v2/internal/acceptance/clients" networking "github.com/gophercloud/gophercloud/v2/internal/acceptance/openstack/networking/v2" "github.com/gophercloud/gophercloud/v2/internal/acceptance/tools" @@ -281,3 +283,92 @@ func TestLayer3RouterRevision(t *testing.T) { th.AssertEquals(t, router.Name, newName) th.AssertEquals(t, router.Description, newDescription) } + +func TestLayer3RouterExternalGateways(t *testing.T) { + clients.RequireAdmin(t) + + client, err := clients.NewNetworkV2Client() + th.AssertNoErr(t, err) + + // Skip if the external-gateway-multihoming extension is not available + networking.RequireNeutronExtension(t, client, "external-gateway-multihoming") + + // Create a router with external gateway + router, err := CreateExternalRouter(t, client) + th.AssertNoErr(t, err) + defer DeleteRouter(t, client, router.ID) + + tools.PrintResource(t, router) + + choices, err := clients.AcceptanceTestChoicesFromEnv() + th.AssertNoErr(t, err) + + // Test AddExternalGateways + t.Logf("Attempting to add external gateways to router %s", router.ID) + + addOpts := routers.AddExternalGatewaysOpts{ + ExternalGateways: []routers.GatewayInfo{ + { + NetworkID: choices.ExternalNetworkID, + }, + }, + } + + updatedRouter, err := routers.AddExternalGateways(context.TODO(), client, router.ID, addOpts).Extract() + if err != nil { + // If we get a 404, the extension might not be fully functional + if gophercloud.ResponseCodeIs(err, http.StatusNotFound) { + t.Skipf("AddExternalGateways not supported: %v", err) + } + th.AssertNoErr(t, err) + } + + t.Logf("Successfully added external gateways to router %s", router.ID) + tools.PrintResource(t, updatedRouter) + + // Test UpdateExternalGateways + t.Logf("Attempting to update external gateways of router %s", router.ID) + + enableSNAT := true + updateOpts := routers.UpdateExternalGatewaysOpts{ + ExternalGateways: []routers.GatewayInfo{ + { + NetworkID: choices.ExternalNetworkID, + EnableSNAT: &enableSNAT, + }, + }, + } + + updatedRouter, err = routers.UpdateExternalGateways(context.TODO(), client, router.ID, updateOpts).Extract() + if err != nil { + if gophercloud.ResponseCodeIs(err, http.StatusNotFound) { + t.Skipf("UpdateExternalGateways not supported: %v", err) + } + th.AssertNoErr(t, err) + } + + t.Logf("Successfully updated external gateways of router %s", router.ID) + tools.PrintResource(t, updatedRouter) + + // Test RemoveExternalGateways + t.Logf("Attempting to remove external gateways from router %s", router.ID) + + removeOpts := routers.RemoveExternalGatewaysOpts{ + ExternalGateways: []routers.GatewayInfo{ + { + NetworkID: choices.ExternalNetworkID, + }, + }, + } + + updatedRouter, err = routers.RemoveExternalGateways(context.TODO(), client, router.ID, removeOpts).Extract() + if err != nil { + if gophercloud.ResponseCodeIs(err, http.StatusNotFound) { + t.Skipf("RemoveExternalGateways not supported: %v", err) + } + th.AssertNoErr(t, err) + } + + t.Logf("Successfully removed external gateways from router %s", router.ID) + tools.PrintResource(t, updatedRouter) +} diff --git a/openstack/networking/v2/extensions/layer3/routers/doc.go b/openstack/networking/v2/extensions/layer3/routers/doc.go index 42ccbcf7cf..4faa862fc1 100644 --- a/openstack/networking/v2/extensions/layer3/routers/doc.go +++ b/openstack/networking/v2/extensions/layer3/routers/doc.go @@ -135,5 +135,73 @@ Example to List an L3 agents for a Router for _, agent := range allL3Agents { fmt.Printf("%+v\n", agent) } + +Example to Add External Gateways to a Router + +This requires the external-gateway-multihoming extension. + + routerID := "4e8e5957-649f-477b-9e5b-f1f75b21c03c" + + addOpts := routers.AddExternalGatewaysOpts{ + ExternalGateways: []routers.GatewayInfo{ + { + NetworkID: "8ca37218-28ff-41cb-9b10-039601ea7e6b", + ExternalFixedIPs: []routers.ExternalFixedIP{ + {SubnetID: "ab561bc4-1a8e-48f2-9fbd-376fcb1a1def"}, + }, + }, + }, + } + + router, err := routers.AddExternalGateways(context.TODO(), networkClient, routerID, addOpts).Extract() + if err != nil { + panic(err) + } + +Example to Update External Gateways of a Router + +This requires the external-gateway-multihoming extension. + + routerID := "4e8e5957-649f-477b-9e5b-f1f75b21c03c" + + enableSNAT := true + updateOpts := routers.UpdateExternalGatewaysOpts{ + ExternalGateways: []routers.GatewayInfo{ + { + NetworkID: "8ca37218-28ff-41cb-9b10-039601ea7e6b", + EnableSNAT: &enableSNAT, + ExternalFixedIPs: []routers.ExternalFixedIP{ + {IPAddress: "192.0.2.17", SubnetID: "ab561bc4-1a8e-48f2-9fbd-376fcb1a1def"}, + }, + }, + }, + } + + router, err := routers.UpdateExternalGateways(context.TODO(), networkClient, routerID, updateOpts).Extract() + if err != nil { + panic(err) + } + +Example to Remove External Gateways from a Router + +This requires the external-gateway-multihoming extension. + + routerID := "4e8e5957-649f-477b-9e5b-f1f75b21c03c" + + removeOpts := routers.RemoveExternalGatewaysOpts{ + ExternalGateways: []routers.GatewayInfo{ + { + NetworkID: "8ca37218-28ff-41cb-9b10-039601ea7e6b", + ExternalFixedIPs: []routers.ExternalFixedIP{ + {IPAddress: "192.0.2.17", SubnetID: "ab561bc4-1a8e-48f2-9fbd-376fcb1a1def"}, + }, + }, + }, + } + + router, err := routers.RemoveExternalGateways(context.TODO(), networkClient, routerID, removeOpts).Extract() + if err != nil { + panic(err) + } */ package routers diff --git a/openstack/networking/v2/extensions/layer3/routers/requests.go b/openstack/networking/v2/extensions/layer3/routers/requests.go index def4699db3..3e49a30f10 100644 --- a/openstack/networking/v2/extensions/layer3/routers/requests.go +++ b/openstack/networking/v2/extensions/layer3/routers/requests.go @@ -282,3 +282,99 @@ func ListL3Agents(c *gophercloud.ServiceClient, id string) (result pagination.Pa return ListL3AgentsPage{pagination.SinglePageBase(r)} }) } + +// AddExternalGatewaysOptsBuilder allows extensions to add additional parameters +// to the AddExternalGateways request. +type AddExternalGatewaysOptsBuilder interface { + ToRouterAddExternalGatewaysMap() (map[string]any, error) +} + +// AddExternalGatewaysOpts represents the options for adding external gateways +// to a router. +type AddExternalGatewaysOpts struct { + ExternalGateways []GatewayInfo `json:"external_gateways" required:"true"` +} + +// ToRouterAddExternalGatewaysMap builds a request body from AddExternalGatewaysOpts. +func (opts AddExternalGatewaysOpts) ToRouterAddExternalGatewaysMap() (map[string]any, error) { + return gophercloud.BuildRequestBody(opts, "router") +} + +// AddExternalGateways adds external gateways to a router. +// This requires the external-gateway-multihoming extension. +func AddExternalGateways(ctx context.Context, c *gophercloud.ServiceClient, id string, opts AddExternalGatewaysOptsBuilder) (r UpdateResult) { + b, err := opts.ToRouterAddExternalGatewaysMap() + if err != nil { + r.Err = err + return + } + resp, err := c.Put(ctx, addExternalGatewaysURL(c, id), b, &r.Body, &gophercloud.RequestOpts{ + OkCodes: []int{200}, + }) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} + +// UpdateExternalGatewaysOptsBuilder allows extensions to add additional +// parameters to the UpdateExternalGateways request. +type UpdateExternalGatewaysOptsBuilder interface { + ToRouterUpdateExternalGatewaysMap() (map[string]any, error) +} + +// UpdateExternalGatewaysOpts represents the options for updating external +// gateways of a router. +type UpdateExternalGatewaysOpts struct { + ExternalGateways []GatewayInfo `json:"external_gateways" required:"true"` +} + +// ToRouterUpdateExternalGatewaysMap builds a request body from UpdateExternalGatewaysOpts. +func (opts UpdateExternalGatewaysOpts) ToRouterUpdateExternalGatewaysMap() (map[string]any, error) { + return gophercloud.BuildRequestBody(opts, "router") +} + +// UpdateExternalGateways updates external gateways of a router. +// This requires the external-gateway-multihoming extension. +func UpdateExternalGateways(ctx context.Context, c *gophercloud.ServiceClient, id string, opts UpdateExternalGatewaysOptsBuilder) (r UpdateResult) { + b, err := opts.ToRouterUpdateExternalGatewaysMap() + if err != nil { + r.Err = err + return + } + resp, err := c.Put(ctx, updateExternalGatewaysURL(c, id), b, &r.Body, &gophercloud.RequestOpts{ + OkCodes: []int{200}, + }) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} + +// RemoveExternalGatewaysOptsBuilder allows extensions to add additional +// parameters to the RemoveExternalGateways request. +type RemoveExternalGatewaysOptsBuilder interface { + ToRouterRemoveExternalGatewaysMap() (map[string]any, error) +} + +// RemoveExternalGatewaysOpts represents the options for removing external +// gateways from a router. +type RemoveExternalGatewaysOpts struct { + ExternalGateways []GatewayInfo `json:"external_gateways" required:"true"` +} + +// ToRouterRemoveExternalGatewaysMap builds a request body from RemoveExternalGatewaysOpts. +func (opts RemoveExternalGatewaysOpts) ToRouterRemoveExternalGatewaysMap() (map[string]any, error) { + return gophercloud.BuildRequestBody(opts, "router") +} + +// RemoveExternalGateways removes external gateways from a router. +// This requires the external-gateway-multihoming extension. +func RemoveExternalGateways(ctx context.Context, c *gophercloud.ServiceClient, id string, opts RemoveExternalGatewaysOptsBuilder) (r UpdateResult) { + b, err := opts.ToRouterRemoveExternalGatewaysMap() + if err != nil { + r.Err = err + return + } + resp, err := c.Put(ctx, removeExternalGatewaysURL(c, id), b, &r.Body, &gophercloud.RequestOpts{ + OkCodes: []int{200}, + }) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} diff --git a/openstack/networking/v2/extensions/layer3/routers/testing/requests_test.go b/openstack/networking/v2/extensions/layer3/routers/testing/requests_test.go index f6cd2c0bbd..1125aa12c4 100644 --- a/openstack/networking/v2/extensions/layer3/routers/testing/requests_test.go +++ b/openstack/networking/v2/extensions/layer3/routers/testing/requests_test.go @@ -697,3 +697,203 @@ func TestListL3Agents(t *testing.T) { } th.CheckDeepEquals(t, expected, actual) } + +func TestAddExternalGateways(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + fakeServer.Mux.HandleFunc("/v2.0/routers/4e8e5957-649f-477b-9e5b-f1f75b21c03c/add_external_gateways", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "PUT") + th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "Content-Type", "application/json") + th.TestHeader(t, r, "Accept", "application/json") + th.TestJSONRequest(t, r, ` +{ + "router": { + "external_gateways": [ + { + "network_id": "8ca37218-28ff-41cb-9b10-039601ea7e6b", + "external_fixed_ips": [ + {"subnet_id": "ab561bc4-1a8e-48f2-9fbd-376fcb1a1def"} + ] + } + ] + } +} + `) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + + fmt.Fprint(w, ` +{ + "router": { + "status": "ACTIVE", + "external_gateway_info": { + "network_id": "8ca37218-28ff-41cb-9b10-039601ea7e6b", + "external_fixed_ips": [ + {"ip_address": "192.0.2.17", "subnet_id": "ab561bc4-1a8e-48f2-9fbd-376fcb1a1def"} + ] + }, + "name": "router1", + "admin_state_up": true, + "tenant_id": "6b96ff0cb17a4b859e1e575d221683d3", + "distributed": false, + "id": "4e8e5957-649f-477b-9e5b-f1f75b21c03c" + } +} + `) + }) + + efi := []routers.ExternalFixedIP{ + {SubnetID: "ab561bc4-1a8e-48f2-9fbd-376fcb1a1def"}, + } + opts := routers.AddExternalGatewaysOpts{ + ExternalGateways: []routers.GatewayInfo{ + { + NetworkID: "8ca37218-28ff-41cb-9b10-039601ea7e6b", + ExternalFixedIPs: efi, + }, + }, + } + + n, err := routers.AddExternalGateways(context.TODO(), fake.ServiceClient(fakeServer), "4e8e5957-649f-477b-9e5b-f1f75b21c03c", opts).Extract() + th.AssertNoErr(t, err) + + th.AssertEquals(t, n.Name, "router1") + th.AssertEquals(t, n.ID, "4e8e5957-649f-477b-9e5b-f1f75b21c03c") + th.AssertEquals(t, n.GatewayInfo.NetworkID, "8ca37218-28ff-41cb-9b10-039601ea7e6b") +} + +func TestUpdateExternalGateways(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + fakeServer.Mux.HandleFunc("/v2.0/routers/4e8e5957-649f-477b-9e5b-f1f75b21c03c/update_external_gateways", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "PUT") + th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "Content-Type", "application/json") + th.TestHeader(t, r, "Accept", "application/json") + th.TestJSONRequest(t, r, ` +{ + "router": { + "external_gateways": [ + { + "network_id": "8ca37218-28ff-41cb-9b10-039601ea7e6b", + "enable_snat": true, + "external_fixed_ips": [ + {"ip_address": "192.0.2.17", "subnet_id": "ab561bc4-1a8e-48f2-9fbd-376fcb1a1def"} + ] + } + ] + } +} + `) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + + fmt.Fprint(w, ` +{ + "router": { + "status": "ACTIVE", + "external_gateway_info": { + "network_id": "8ca37218-28ff-41cb-9b10-039601ea7e6b", + "enable_snat": true, + "external_fixed_ips": [ + {"ip_address": "192.0.2.17", "subnet_id": "ab561bc4-1a8e-48f2-9fbd-376fcb1a1def"} + ] + }, + "name": "router1", + "admin_state_up": true, + "tenant_id": "6b96ff0cb17a4b859e1e575d221683d3", + "distributed": false, + "id": "4e8e5957-649f-477b-9e5b-f1f75b21c03c" + } +} + `) + }) + + enableSNAT := true + efi := []routers.ExternalFixedIP{ + {IPAddress: "192.0.2.17", SubnetID: "ab561bc4-1a8e-48f2-9fbd-376fcb1a1def"}, + } + opts := routers.UpdateExternalGatewaysOpts{ + ExternalGateways: []routers.GatewayInfo{ + { + NetworkID: "8ca37218-28ff-41cb-9b10-039601ea7e6b", + EnableSNAT: &enableSNAT, + ExternalFixedIPs: efi, + }, + }, + } + + n, err := routers.UpdateExternalGateways(context.TODO(), fake.ServiceClient(fakeServer), "4e8e5957-649f-477b-9e5b-f1f75b21c03c", opts).Extract() + th.AssertNoErr(t, err) + + th.AssertEquals(t, n.Name, "router1") + th.AssertEquals(t, n.ID, "4e8e5957-649f-477b-9e5b-f1f75b21c03c") + th.AssertEquals(t, *n.GatewayInfo.EnableSNAT, true) +} + +func TestRemoveExternalGateways(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + fakeServer.Mux.HandleFunc("/v2.0/routers/4e8e5957-649f-477b-9e5b-f1f75b21c03c/remove_external_gateways", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "PUT") + th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "Content-Type", "application/json") + th.TestHeader(t, r, "Accept", "application/json") + th.TestJSONRequest(t, r, ` +{ + "router": { + "external_gateways": [ + { + "network_id": "8ca37218-28ff-41cb-9b10-039601ea7e6b", + "external_fixed_ips": [ + {"ip_address": "192.0.2.17", "subnet_id": "ab561bc4-1a8e-48f2-9fbd-376fcb1a1def"} + ] + } + ] + } +} + `) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + + fmt.Fprint(w, ` +{ + "router": { + "status": "ACTIVE", + "external_gateway_info": null, + "name": "router1", + "admin_state_up": true, + "tenant_id": "6b96ff0cb17a4b859e1e575d221683d3", + "distributed": false, + "id": "4e8e5957-649f-477b-9e5b-f1f75b21c03c" + } +} + `) + }) + + efi := []routers.ExternalFixedIP{ + {IPAddress: "192.0.2.17", SubnetID: "ab561bc4-1a8e-48f2-9fbd-376fcb1a1def"}, + } + opts := routers.RemoveExternalGatewaysOpts{ + ExternalGateways: []routers.GatewayInfo{ + { + NetworkID: "8ca37218-28ff-41cb-9b10-039601ea7e6b", + ExternalFixedIPs: efi, + }, + }, + } + + n, err := routers.RemoveExternalGateways(context.TODO(), fake.ServiceClient(fakeServer), "4e8e5957-649f-477b-9e5b-f1f75b21c03c", opts).Extract() + th.AssertNoErr(t, err) + + th.AssertEquals(t, n.Name, "router1") + th.AssertEquals(t, n.ID, "4e8e5957-649f-477b-9e5b-f1f75b21c03c") + th.AssertEquals(t, n.GatewayInfo.NetworkID, "") +} diff --git a/openstack/networking/v2/extensions/layer3/routers/urls.go b/openstack/networking/v2/extensions/layer3/routers/urls.go index 87815aa6ec..b07c2fdc7b 100644 --- a/openstack/networking/v2/extensions/layer3/routers/urls.go +++ b/openstack/networking/v2/extensions/layer3/routers/urls.go @@ -23,3 +23,15 @@ func removeInterfaceURL(c *gophercloud.ServiceClient, id string) string { func listl3AgentsURL(c *gophercloud.ServiceClient, id string) string { return c.ServiceURL(resourcePath, id, "l3-agents") } + +func addExternalGatewaysURL(c *gophercloud.ServiceClient, id string) string { + return c.ServiceURL(resourcePath, id, "add_external_gateways") +} + +func updateExternalGatewaysURL(c *gophercloud.ServiceClient, id string) string { + return c.ServiceURL(resourcePath, id, "update_external_gateways") +} + +func removeExternalGatewaysURL(c *gophercloud.ServiceClient, id string) string { + return c.ServiceURL(resourcePath, id, "remove_external_gateways") +} From d5cbeef4133b88c5c3ae19965f0dece5d0940520 Mon Sep 17 00:00:00 2001 From: Mohammed Al-Dokimi Date: Sun, 18 Jan 2026 01:06:53 +0000 Subject: [PATCH 241/353] networking/v2/layer3/routers: Fix acceptance tests and linting --- .../v2/extensions/layer3/routers_test.go | 30 ++++++++++++++++--- .../v2/extensions/layer3/routers/doc.go | 12 ++------ 2 files changed, 29 insertions(+), 13 deletions(-) diff --git a/internal/acceptance/openstack/networking/v2/extensions/layer3/routers_test.go b/internal/acceptance/openstack/networking/v2/extensions/layer3/routers_test.go index be275f2ce1..9aefcb6630 100644 --- a/internal/acceptance/openstack/networking/v2/extensions/layer3/routers_test.go +++ b/internal/acceptance/openstack/networking/v2/extensions/layer3/routers_test.go @@ -327,14 +327,25 @@ func TestLayer3RouterExternalGateways(t *testing.T) { tools.PrintResource(t, updatedRouter) // Test UpdateExternalGateways + // Note: UpdateExternalGateways requires external_fixed_ips to identify which gateway to update t.Logf("Attempting to update external gateways of router %s", router.ID) - enableSNAT := true + // Get current external_fixed_ips from the router to identify the gateway + currentFixedIPs := make([]routers.ExternalFixedIP, len(updatedRouter.GatewayInfo.ExternalFixedIPs)) + for i, ip := range updatedRouter.GatewayInfo.ExternalFixedIPs { + currentFixedIPs[i] = routers.ExternalFixedIP{ + IPAddress: ip.IPAddress, + SubnetID: ip.SubnetID, + } + } + + enableSNAT := false updateOpts := routers.UpdateExternalGatewaysOpts{ ExternalGateways: []routers.GatewayInfo{ { - NetworkID: choices.ExternalNetworkID, - EnableSNAT: &enableSNAT, + NetworkID: updatedRouter.GatewayInfo.NetworkID, + EnableSNAT: &enableSNAT, + ExternalFixedIPs: currentFixedIPs, }, }, } @@ -351,12 +362,23 @@ func TestLayer3RouterExternalGateways(t *testing.T) { tools.PrintResource(t, updatedRouter) // Test RemoveExternalGateways + // Note: RemoveExternalGateways requires external_fixed_ips to identify which gateway to remove t.Logf("Attempting to remove external gateways from router %s", router.ID) + // Get current external_fixed_ips from the updated router + currentFixedIPs = make([]routers.ExternalFixedIP, len(updatedRouter.GatewayInfo.ExternalFixedIPs)) + for i, ip := range updatedRouter.GatewayInfo.ExternalFixedIPs { + currentFixedIPs[i] = routers.ExternalFixedIP{ + IPAddress: ip.IPAddress, + SubnetID: ip.SubnetID, + } + } + removeOpts := routers.RemoveExternalGatewaysOpts{ ExternalGateways: []routers.GatewayInfo{ { - NetworkID: choices.ExternalNetworkID, + NetworkID: updatedRouter.GatewayInfo.NetworkID, + ExternalFixedIPs: currentFixedIPs, }, }, } diff --git a/openstack/networking/v2/extensions/layer3/routers/doc.go b/openstack/networking/v2/extensions/layer3/routers/doc.go index 4faa862fc1..772c9e3bbf 100644 --- a/openstack/networking/v2/extensions/layer3/routers/doc.go +++ b/openstack/networking/v2/extensions/layer3/routers/doc.go @@ -136,9 +136,7 @@ Example to List an L3 agents for a Router fmt.Printf("%+v\n", agent) } -Example to Add External Gateways to a Router - -This requires the external-gateway-multihoming extension. +Example to Add External Gateways to a Router: This requires the external-gateway-multihoming extension. routerID := "4e8e5957-649f-477b-9e5b-f1f75b21c03c" @@ -158,9 +156,7 @@ This requires the external-gateway-multihoming extension. panic(err) } -Example to Update External Gateways of a Router - -This requires the external-gateway-multihoming extension. +Example to Update External Gateways of a Router: This requires the external-gateway-multihoming extension. routerID := "4e8e5957-649f-477b-9e5b-f1f75b21c03c" @@ -182,9 +178,7 @@ This requires the external-gateway-multihoming extension. panic(err) } -Example to Remove External Gateways from a Router - -This requires the external-gateway-multihoming extension. +Example to Remove External Gateways from a Router: This requires the external-gateway-multihoming extension. routerID := "4e8e5957-649f-477b-9e5b-f1f75b21c03c" From 6b322318d703506601f6f6323a3b8604035180bf Mon Sep 17 00:00:00 2001 From: Mohammed Al-Dokimi Date: Thu, 22 Jan 2026 19:19:54 +0000 Subject: [PATCH 242/353] networking/v2/layer3/routers: Remove 404 failuer skipping --- .../v2/extensions/layer3/routers_test.go | 24 +++---------------- 1 file changed, 3 insertions(+), 21 deletions(-) diff --git a/internal/acceptance/openstack/networking/v2/extensions/layer3/routers_test.go b/internal/acceptance/openstack/networking/v2/extensions/layer3/routers_test.go index 9aefcb6630..e6519472c6 100644 --- a/internal/acceptance/openstack/networking/v2/extensions/layer3/routers_test.go +++ b/internal/acceptance/openstack/networking/v2/extensions/layer3/routers_test.go @@ -4,11 +4,9 @@ package layer3 import ( "context" - "net/http" "strings" "testing" - "github.com/gophercloud/gophercloud/v2" "github.com/gophercloud/gophercloud/v2/internal/acceptance/clients" networking "github.com/gophercloud/gophercloud/v2/internal/acceptance/openstack/networking/v2" "github.com/gophercloud/gophercloud/v2/internal/acceptance/tools" @@ -315,13 +313,7 @@ func TestLayer3RouterExternalGateways(t *testing.T) { } updatedRouter, err := routers.AddExternalGateways(context.TODO(), client, router.ID, addOpts).Extract() - if err != nil { - // If we get a 404, the extension might not be fully functional - if gophercloud.ResponseCodeIs(err, http.StatusNotFound) { - t.Skipf("AddExternalGateways not supported: %v", err) - } - th.AssertNoErr(t, err) - } + th.AssertNoErr(t, err) t.Logf("Successfully added external gateways to router %s", router.ID) tools.PrintResource(t, updatedRouter) @@ -351,12 +343,7 @@ func TestLayer3RouterExternalGateways(t *testing.T) { } updatedRouter, err = routers.UpdateExternalGateways(context.TODO(), client, router.ID, updateOpts).Extract() - if err != nil { - if gophercloud.ResponseCodeIs(err, http.StatusNotFound) { - t.Skipf("UpdateExternalGateways not supported: %v", err) - } - th.AssertNoErr(t, err) - } + th.AssertNoErr(t, err) t.Logf("Successfully updated external gateways of router %s", router.ID) tools.PrintResource(t, updatedRouter) @@ -384,12 +371,7 @@ func TestLayer3RouterExternalGateways(t *testing.T) { } updatedRouter, err = routers.RemoveExternalGateways(context.TODO(), client, router.ID, removeOpts).Extract() - if err != nil { - if gophercloud.ResponseCodeIs(err, http.StatusNotFound) { - t.Skipf("RemoveExternalGateways not supported: %v", err) - } - th.AssertNoErr(t, err) - } + th.AssertNoErr(t, err) t.Logf("Successfully removed external gateways from router %s", router.ID) tools.PrintResource(t, updatedRouter) From 248e84138920884d1d77963549fa1f0386c52b72 Mon Sep 17 00:00:00 2001 From: eshulman2 Date: Mon, 2 Feb 2026 16:03:09 +0200 Subject: [PATCH 243/353] Use jimmy amphora in octavia job To avoid kvm error in nested virtualization use older amphora image --- .github/workflows/functional-loadbalancer.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/functional-loadbalancer.yaml b/.github/workflows/functional-loadbalancer.yaml index 7880244f05..b486082a44 100644 --- a/.github/workflows/functional-loadbalancer.yaml +++ b/.github/workflows/functional-loadbalancer.yaml @@ -23,6 +23,8 @@ jobs: openstack_version: "master" ubuntu_version: "24.04" devstack_conf_overrides: | + LIBVIRT_CPU_MODE=host-passthrough + OCTAVIA_AMP_DISTRIBUTION_RELEASE_ID=jammy # ensure we're using a working version of setuptools if [ -n "\$TOP_DIR" ]; then sed -i 's/setuptools\[core\]$/setuptools[core]==79.0.1/g' \$TOP_DIR/lib/infra \$TOP_DIR/inc/python From 0b1000b4d91b714a2a8b8bd28a1903ac69a6f87c Mon Sep 17 00:00:00 2001 From: Jacob Anders Date: Wed, 28 Jan 2026 20:07:17 +1000 Subject: [PATCH 244/353] baremetal: Add Health field to Node Add support for the node health field which reports hardware health status from the BMC. Requires Ironic API microversion 1.109. Partially implements metal3-io#2888 Signed-off-by: Jacob Anders Assisted-by: Claude-4.5-opus-high Co-authored-by: Cursor --- openstack/baremetal/v1/nodes/requests.go | 4 ++++ openstack/baremetal/v1/nodes/results.go | 5 +++++ openstack/baremetal/v1/nodes/testing/fixtures_test.go | 3 +++ 3 files changed, 12 insertions(+) diff --git a/openstack/baremetal/v1/nodes/requests.go b/openstack/baremetal/v1/nodes/requests.go index 6268f5037e..89ba6a5b16 100644 --- a/openstack/baremetal/v1/nodes/requests.go +++ b/openstack/baremetal/v1/nodes/requests.go @@ -113,6 +113,10 @@ type ListOpts struct { // Filter the list with the specified fault. Fault string `q:"fault"` + // Filter the list with the specified health status. + // Requires microversion 1.109 or later. + Health string `q:"health"` + // One or more fields to be returned in the response. Fields []string `q:"fields" format:"comma-separated"` diff --git a/openstack/baremetal/v1/nodes/results.go b/openstack/baremetal/v1/nodes/results.go index b33517a388..13e09df573 100644 --- a/openstack/baremetal/v1/nodes/results.go +++ b/openstack/baremetal/v1/nodes/results.go @@ -139,6 +139,11 @@ type Node struct { // node. There are other possible types, e.g., “clean failure” and “rescue abort failure”. Fault string `json:"fault"` + // Health indicates the hardware health status reported by the BMC. + // Possible values are "OK", "Warning", "Critical", or empty if not available. + // This field is read-only and requires microversion 1.109 or later. + Health string `json:"health"` + // Error from the most recent (last) transaction that started but failed to finish. LastError string `json:"last_error"` diff --git a/openstack/baremetal/v1/nodes/testing/fixtures_test.go b/openstack/baremetal/v1/nodes/testing/fixtures_test.go index 064351ea87..84a6cccb96 100644 --- a/openstack/baremetal/v1/nodes/testing/fixtures_test.go +++ b/openstack/baremetal/v1/nodes/testing/fixtures_test.go @@ -102,6 +102,7 @@ const NodeListDetailBody = ` "extra": {}, "fault": null, "firmware_interface": "no-firmware", + "health": "OK", "inspect_interface": "no-inspect", "inspection_finished_at": null, "inspection_started_at": null, @@ -417,6 +418,7 @@ const SingleNodeBody = ` "extra": {}, "fault": null, "firmware_interface": "no-firmware", + "health": "OK", "inspect_interface": "no-inspect", "inspection_finished_at": null, "inspection_started_at": null, @@ -939,6 +941,7 @@ var ( Maintenance: false, MaintenanceReason: "", Fault: "", + Health: "OK", LastError: "", Reservation: "", Driver: "ipmi", From 42c2f683b22c51ba2e5235fb430c6c1edcbea4a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Andr=C3=A9?= Date: Thu, 12 Feb 2026 15:03:38 +0100 Subject: [PATCH 245/353] CI: Fix fwaas jobs They were configured to run the whole networking test suite without devstack being configured for it. Furthermore, it's redundant with the networking job. Restore the job to only run the fwaas_v2 tests as it was previous to commit 90cded10439a88581c9cd5afbbca206bc20c3230. --- .github/workflows/functional-fwaas_v2.yaml | 2 +- Makefile | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/functional-fwaas_v2.yaml b/.github/workflows/functional-fwaas_v2.yaml index a9f603430e..7e75ce8405 100644 --- a/.github/workflows/functional-fwaas_v2.yaml +++ b/.github/workflows/functional-fwaas_v2.yaml @@ -69,7 +69,7 @@ jobs: - name: Run Gophercloud acceptance tests run: | source ${{ github.workspace }}/script/stackenv - make acceptance-networking + make acceptance-fwaas env: DEVSTACK_PATH: ${{ github.workspace }}/devstack OS_BRANCH: ${{ matrix.openstack_version }} diff --git a/Makefile b/Makefile index c63adb8d03..0db87a3d62 100644 --- a/Makefile +++ b/Makefile @@ -78,6 +78,10 @@ acceptance-dns: $(GO_TEST) -timeout $(TIMEOUT) -tags "fixtures acceptance" ./internal/acceptance/openstack/dns/... .PHONY: acceptance-dns +acceptance-fwaas: + $(GO_TEST) -timeout $(TIMEOUT) -tags "fixtures acceptance" ./internal/acceptance/openstack/networking/v2/extensions/fwaas_v2/... +.PHONY: acceptance-fwaas + acceptance-identity: $(GO_TEST) -timeout $(TIMEOUT) -tags "fixtures acceptance" ./internal/acceptance/openstack/identity/... .PHONY: acceptance-identity From aa98ce2e4a8613375041ee9af34c78e2d77298ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Andr=C3=A9?= Date: Thu, 12 Feb 2026 11:15:22 +0100 Subject: [PATCH 246/353] [v2] Bump go Bump to to a supported version. --- .github/workflows/label-pr.yaml | 3 ++- .github/workflows/lint.yaml | 3 ++- go.mod | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/label-pr.yaml b/.github/workflows/label-pr.yaml index a445331b93..0e38e980f0 100644 --- a/.github/workflows/label-pr.yaml +++ b/.github/workflows/label-pr.yaml @@ -26,7 +26,8 @@ jobs: - uses: actions/setup-go@v5 with: - go-version: '1' + go-version-file: 'go.mod' + cache: true - name: Checking Go API Compatibility id: go-apidiff diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 4a627ec507..a5b02146f7 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -12,7 +12,8 @@ jobs: uses: actions/checkout@v5 - uses: actions/setup-go@v5 with: - go-version: '1' + go-version-file: 'go.mod' + cache: true - name: Run linters run: | make lint diff --git a/go.mod b/go.mod index ac4634f884..eb560fd4f4 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/gophercloud/gophercloud/v2 -go 1.22 +go 1.25.7 require ( golang.org/x/crypto v0.33.0 From 3e8a6cdb19bcabd94cf9b0417181ea60f09e34d4 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Fri, 16 May 2025 10:53:40 +0100 Subject: [PATCH 247/353] Bump golangci-lint to latest version Done by bumping the version in the Makefile and running the 'golangci-lint migrate' command via podman as we do in the Makefile. podman run -t --rm -v $PWD:/app -w /app \ golangci/golangci-lint:v2.1.6 \ golangci-lint migrate This yields a number of news error from staticcheck, listed below, which we temporarily ignore pending a fix. S1038: should use fmt.Fprintf instead of fmt.Fprint(fmt.Sprintf(...)) ST1005: error strings should not be capitalized ST1005: error strings should not end with punctuation or newlines ST1017: don't use Yoda conditions ST1019: package ".*" is being imported more than once ST1019(related information): other import of ".*" ST1023: should omit type .* from declaration; it will be inferred from the right-hand side QF1011: could omit type .* from declaration; it will be inferred from the right-hand side QF1001: could apply De Morgan's law QF1003: could use tagged switch on .* QF1004: could use strings.ReplaceAll instead QF1008: could remove embedded field ".*" from selector Signed-off-by: Stephen Finucane --- .golangci.yaml | 77 ++++++++++++++++++++++++++++++++++++++++++-------- Makefile | 2 +- 2 files changed, 66 insertions(+), 13 deletions(-) diff --git a/.golangci.yaml b/.golangci.yaml index 828a099a40..d11ed705a8 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -1,19 +1,72 @@ ---- +version: "2" linters: - disable-all: true + default: none enable: - errcheck - - gofmt - - goimports - govet - staticcheck - unparam - unused - -issues: - exclude: - - SA1006 # printf-style function with dynamic format string and no further arguments should use print-style function instead (staticcheck) - exclude-rules: - - linters: - - staticcheck - text: 'SA1019: (x509.EncryptPEMBlock|strings.Title)' + exclusions: + generated: lax + presets: + - comments + - common-false-positives + - legacy + - std-error-handling + rules: + - linters: + - staticcheck + text: "S1038: should use fmt.Fprintf instead of fmt.Fprint" + - linters: + - staticcheck + text: "SA1019: (x509.EncryptPEMBlock|strings.Title)" + - linters: + - staticcheck + text: "ST1005: error strings should not be capitalized" + - linters: + - staticcheck + text: "ST1005: error strings should not end with punctuation or newlines" + - linters: + - staticcheck + text: "ST1017: don't use Yoda conditions" + - linters: + - staticcheck + text: "ST1019: package \".*\" is being imported more than once" + - linters: + - staticcheck + text: "ST1019\\(related information\\): other import of \".*\"" + - linters: + - staticcheck + text: "ST1023: should omit type .* from declaration; it will be inferred from the right-hand side" + - linters: + - staticcheck + text: "QF1001: could apply De Morgan's law" + - linters: + - staticcheck + text: "QF1003: could use tagged switch on .*" + - linters: + - staticcheck + text: "QF1004: could use strings.ReplaceAll instead" + - linters: + - staticcheck + text: "QF1011: could omit type .* from declaration; it will be inferred from the right-hand side" + - linters: + - staticcheck + text: "could remove embedded field \".*\" from selector" + - path: (.+)\.go$ + text: SA1006 + paths: + - third_party$ + - builtin$ + - examples$ +formatters: + enable: + - gofmt + - goimports + exclusions: + generated: lax + paths: + - third_party$ + - builtin$ + - examples$ diff --git a/Makefile b/Makefile index 0db87a3d62..586ffa9def 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ undefine GOFLAGS -GOLANGCI_LINT_VERSION?=v1.62.2 +GOLANGCI_LINT_VERSION?=v2.1.6 GOTESTSUM_VERSION?=v1.12.2 GO_TEST?=go run gotest.tools/gotestsum@$(GOTESTSUM_VERSION) --format testname -- TIMEOUT := "60m" From 649dcd5ac6e91eb2264cc4ead00d09bdcec46889 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Wed, 24 Sep 2025 16:34:28 +0100 Subject: [PATCH 248/353] Bump golangci-lint, gotestsum Signed-off-by: Stephen Finucane --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 586ffa9def..79411c0026 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ undefine GOFLAGS -GOLANGCI_LINT_VERSION?=v2.1.6 -GOTESTSUM_VERSION?=v1.12.2 +GOLANGCI_LINT_VERSION?=v2.5.0 +GOTESTSUM_VERSION?=v1.13.0 GO_TEST?=go run gotest.tools/gotestsum@$(GOTESTSUM_VERSION) --format testname -- TIMEOUT := "60m" From 57f2484ac0cd27bfa4caf83701d867746d17bb5d Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Fri, 16 May 2025 11:13:31 +0100 Subject: [PATCH 249/353] lint: Remove duplicate imports Signed-off-by: Stephen Finucane --- .golangci.yaml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.golangci.yaml b/.golangci.yaml index d11ed705a8..8dddf0772b 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -30,12 +30,6 @@ linters: - linters: - staticcheck text: "ST1017: don't use Yoda conditions" - - linters: - - staticcheck - text: "ST1019: package \".*\" is being imported more than once" - - linters: - - staticcheck - text: "ST1019\\(related information\\): other import of \".*\"" - linters: - staticcheck text: "ST1023: should omit type .* from declaration; it will be inferred from the right-hand side" From def9a2dd0d3014f48b5515fe37daa841c88c091a Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Fri, 16 May 2025 11:14:04 +0100 Subject: [PATCH 250/353] lint: Remove unnecessary explicit type declarations Signed-off-by: Stephen Finucane --- .golangci.yaml | 6 ------ internal/acceptance/openstack/identity/v3/domains_test.go | 6 +++--- internal/acceptance/openstack/identity/v3/projects_test.go | 2 +- internal/acceptance/openstack/identity/v3/users_test.go | 2 +- openstack/identity/v3/domains/doc.go | 4 ++-- openstack/identity/v3/services/doc.go | 2 +- openstack/messaging/v2/queues/testing/requests_test.go | 2 +- .../v2/extensions/agents/testing/requests_test.go | 2 +- .../v2/extensions/external/testing/requests_test.go | 2 +- 9 files changed, 11 insertions(+), 17 deletions(-) diff --git a/.golangci.yaml b/.golangci.yaml index 8dddf0772b..0fa4d35f6e 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -30,9 +30,6 @@ linters: - linters: - staticcheck text: "ST1017: don't use Yoda conditions" - - linters: - - staticcheck - text: "ST1023: should omit type .* from declaration; it will be inferred from the right-hand side" - linters: - staticcheck text: "QF1001: could apply De Morgan's law" @@ -42,9 +39,6 @@ linters: - linters: - staticcheck text: "QF1004: could use strings.ReplaceAll instead" - - linters: - - staticcheck - text: "QF1011: could omit type .* from declaration; it will be inferred from the right-hand side" - linters: - staticcheck text: "could remove embedded field \".*\" from selector" diff --git a/internal/acceptance/openstack/identity/v3/domains_test.go b/internal/acceptance/openstack/identity/v3/domains_test.go index 3d1208ae9c..28cbea7f70 100644 --- a/internal/acceptance/openstack/identity/v3/domains_test.go +++ b/internal/acceptance/openstack/identity/v3/domains_test.go @@ -35,7 +35,7 @@ func TestDomainsList(t *testing.T) { client, err := clients.NewIdentityV3Client() th.AssertNoErr(t, err) - var iTrue bool = true + var iTrue = true listOpts := domains.ListOpts{ Enabled: &iTrue, } @@ -78,7 +78,7 @@ func TestDomainsCRUD(t *testing.T) { client, err := clients.NewIdentityV3Client() th.AssertNoErr(t, err) - var iTrue bool = true + var iTrue = true var description = "Testing Domain" createOpts := domains.CreateOpts{ Description: description, @@ -93,7 +93,7 @@ func TestDomainsCRUD(t *testing.T) { th.AssertEquals(t, domain.Description, description) - var iFalse bool = false + var iFalse = false description = "" updateOpts := domains.UpdateOpts{ Description: &description, diff --git a/internal/acceptance/openstack/identity/v3/projects_test.go b/internal/acceptance/openstack/identity/v3/projects_test.go index 528a30b2a7..12bac084fe 100644 --- a/internal/acceptance/openstack/identity/v3/projects_test.go +++ b/internal/acceptance/openstack/identity/v3/projects_test.go @@ -35,7 +35,7 @@ func TestProjectsList(t *testing.T) { client, err := clients.NewIdentityV3Client() th.AssertNoErr(t, err) - var iTrue bool = true + var iTrue = true listOpts := projects.ListOpts{ Enabled: &iTrue, } diff --git a/internal/acceptance/openstack/identity/v3/users_test.go b/internal/acceptance/openstack/identity/v3/users_test.go index 9b2e63bfdf..31b04b7512 100644 --- a/internal/acceptance/openstack/identity/v3/users_test.go +++ b/internal/acceptance/openstack/identity/v3/users_test.go @@ -20,7 +20,7 @@ func TestUsersList(t *testing.T) { client, err := clients.NewIdentityV3Client() th.AssertNoErr(t, err) - var iTrue bool = true + var iTrue = true listOpts := users.ListOpts{ Enabled: &iTrue, } diff --git a/openstack/identity/v3/domains/doc.go b/openstack/identity/v3/domains/doc.go index 618b2f6d42..34611f5c18 100644 --- a/openstack/identity/v3/domains/doc.go +++ b/openstack/identity/v3/domains/doc.go @@ -3,7 +3,7 @@ Package domains manages and retrieves Domains in the OpenStack Identity Service. Example to List Domains - var iTrue bool = true + var iTrue = true listOpts := domains.ListOpts{ Enabled: &iTrue, } @@ -38,7 +38,7 @@ Example to Update a Domain domainID := "0fe36e73809d46aeae6705c39077b1b3" - var iFalse bool = false + var iFalse = false updateOpts := domains.UpdateOpts{ Enabled: &iFalse, } diff --git a/openstack/identity/v3/services/doc.go b/openstack/identity/v3/services/doc.go index 3d980b4349..51659f9fa7 100644 --- a/openstack/identity/v3/services/doc.go +++ b/openstack/identity/v3/services/doc.go @@ -41,7 +41,7 @@ Example to Update a Service serviceID := "3c7bbe9a6ecb453ca1789586291380ed" - var iFalse bool = false + var iFalse = false updateOpts := services.UpdateOpts{ Enabled: &iFalse, Extra: map[string]any{ diff --git a/openstack/messaging/v2/queues/testing/requests_test.go b/openstack/messaging/v2/queues/testing/requests_test.go index 8f882cf12c..d64c374561 100644 --- a/openstack/messaging/v2/queues/testing/requests_test.go +++ b/openstack/messaging/v2/queues/testing/requests_test.go @@ -42,7 +42,7 @@ func TestCreate(t *testing.T) { fakeServer := th.SetupHTTP() defer fakeServer.Teardown() HandleCreateSuccessfully(t, fakeServer) - var enableEncrypted *bool = new(bool) + var enableEncrypted = new(bool) createOpts := queues.CreateOpts{ QueueName: QueueName, diff --git a/openstack/networking/v2/extensions/agents/testing/requests_test.go b/openstack/networking/v2/extensions/agents/testing/requests_test.go index e5b5888c43..a48d629eb5 100644 --- a/openstack/networking/v2/extensions/agents/testing/requests_test.go +++ b/openstack/networking/v2/extensions/agents/testing/requests_test.go @@ -355,7 +355,7 @@ func TestListL3Routers(t *testing.T) { }, } - var snat bool = true + var snat = true gw := routers.GatewayInfo{ EnableSNAT: &snat, NetworkID: "ae34051f-aa6c-4c75-abf5-50dc9ac99ef3", diff --git a/openstack/networking/v2/extensions/external/testing/requests_test.go b/openstack/networking/v2/extensions/external/testing/requests_test.go index aa60ee4424..6b6c3017dc 100644 --- a/openstack/networking/v2/extensions/external/testing/requests_test.go +++ b/openstack/networking/v2/extensions/external/testing/requests_test.go @@ -9,7 +9,7 @@ import ( ) func TestListExternal(t *testing.T) { - var iTrue bool = true + var iTrue = true networkListOpts := networks.ListOpts{ ID: "d32019d3-bc6e-4319-9c1d-6722fc136a22", From 63e1388027587c746db84ff479ad314261e36ef2 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Fri, 16 May 2025 11:19:00 +0100 Subject: [PATCH 251/353] lint: Simplify conditionals Signed-off-by: Stephen Finucane --- .golangci.yaml | 6 ------ internal/acceptance/clients/conditions.go | 4 ++-- .../networking/v2/extensions/agents/agents_test.go | 4 ++-- openstack/image/v2/members/testing/requests_test.go | 3 --- openstack/networking/v2/extensions/agents/results.go | 2 +- openstack/orchestration/v1/stacks/template.go | 2 +- openstack/orchestration/v1/stacks/utils.go | 2 +- params.go | 2 +- testhelper/convenience.go | 4 ++-- 9 files changed, 10 insertions(+), 19 deletions(-) diff --git a/.golangci.yaml b/.golangci.yaml index 0fa4d35f6e..28bf5ecf15 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -27,12 +27,6 @@ linters: - linters: - staticcheck text: "ST1005: error strings should not end with punctuation or newlines" - - linters: - - staticcheck - text: "ST1017: don't use Yoda conditions" - - linters: - - staticcheck - text: "QF1001: could apply De Morgan's law" - linters: - staticcheck text: "QF1003: could use tagged switch on .*" diff --git a/internal/acceptance/clients/conditions.go b/internal/acceptance/clients/conditions.go index 6077f4bdef..f5eaa578b3 100644 --- a/internal/acceptance/clients/conditions.go +++ b/internal/acceptance/clients/conditions.go @@ -94,7 +94,7 @@ func IsCurrentAbove(t *testing.T, release string) bool { if isReleaseNumeral(current) && !isReleaseNumeral(release) { return true } - if current > release && !(!isReleaseNumeral(current) && isReleaseNumeral(release)) { + if current > release && (isReleaseNumeral(current) || !isReleaseNumeral(release)) { return true } } @@ -118,7 +118,7 @@ func IsCurrentBelow(t *testing.T, release string) bool { if isReleaseNumeral(release) && !isReleaseNumeral(current) { return true } - if release > current && !(!isReleaseNumeral(release) && isReleaseNumeral(current)) { + if release > current && (isReleaseNumeral(release) || !isReleaseNumeral(current)) { return true } } diff --git a/internal/acceptance/openstack/networking/v2/extensions/agents/agents_test.go b/internal/acceptance/openstack/networking/v2/extensions/agents/agents_test.go index 796e78b76b..a75c53d37c 100644 --- a/internal/acceptance/openstack/networking/v2/extensions/agents/agents_test.go +++ b/internal/acceptance/openstack/networking/v2/extensions/agents/agents_test.go @@ -165,7 +165,7 @@ func TestBGPAgentCRUD(t *testing.T) { agentConf := bgpAgent.Configurations numOfSpeakers := int(agentConf["bgp_speakers"].(float64)) t.Logf("Agent %s has %d speaker(s)", agentID, numOfSpeakers) - return 1 == numOfSpeakers, nil + return numOfSpeakers == 1, nil }, timeout) th.AssertNoErr(t, err) @@ -201,7 +201,7 @@ func TestBGPAgentCRUD(t *testing.T) { agentConf := bgpAgent.Configurations numOfSpeakers := int(agentConf["bgp_speakers"].(float64)) t.Logf("Agent %s has %d speaker(s)", bgpAgent.ID, numOfSpeakers) - return 0 == numOfSpeakers, nil + return numOfSpeakers == 0, nil }, timeout) th.AssertNoErr(t, err) } diff --git a/openstack/image/v2/members/testing/requests_test.go b/openstack/image/v2/members/testing/requests_test.go index 66798c4323..6ad8f61836 100644 --- a/openstack/image/v2/members/testing/requests_test.go +++ b/openstack/image/v2/members/testing/requests_test.go @@ -110,9 +110,6 @@ func TestShowMemberDetails(t *testing.T) { "8989447062e04a818baf9e073fd04fa7").Extract() th.AssertNoErr(t, err) - if md == nil { - t.Fatalf("Expected non-nil value for md") - } createdAt, err := time.Parse(time.RFC3339, "2013-11-26T07:21:21Z") th.AssertNoErr(t, err) diff --git a/openstack/networking/v2/extensions/agents/results.go b/openstack/networking/v2/extensions/agents/results.go index 166702009d..4e13e212ba 100644 --- a/openstack/networking/v2/extensions/agents/results.go +++ b/openstack/networking/v2/extensions/agents/results.go @@ -205,7 +205,7 @@ func (r ListBGPSpeakersResult) IsEmpty() (bool, error) { } speakers, err := ExtractBGPSpeakers(r) - return 0 == len(speakers), err + return len(speakers) == 0, err } // ExtractBGPSpeakers inteprets the ListBGPSpeakersResult into an array of BGP speakers diff --git a/openstack/orchestration/v1/stacks/template.go b/openstack/orchestration/v1/stacks/template.go index 75eb6a97cf..af49c612a0 100644 --- a/openstack/orchestration/v1/stacks/template.go +++ b/openstack/orchestration/v1/stacks/template.go @@ -202,7 +202,7 @@ func ignoreIfTemplate(key string, value any) bool { return true } // `.template` and `.yaml` are allowed suffixes for template URLs when referred to by `type` - if key == "type" && !(strings.HasSuffix(valueString, ".template") || strings.HasSuffix(valueString, ".yaml")) { + if key == "type" && !strings.HasSuffix(valueString, ".template") && !strings.HasSuffix(valueString, ".yaml") { return true } return false diff --git a/openstack/orchestration/v1/stacks/utils.go b/openstack/orchestration/v1/stacks/utils.go index 56bc48d041..228335388f 100644 --- a/openstack/orchestration/v1/stacks/utils.go +++ b/openstack/orchestration/v1/stacks/utils.go @@ -80,7 +80,7 @@ func (t *TE) Fetch() error { if err != nil { return err } - if !(resp.StatusCode >= 200 && resp.StatusCode < 300) { + if resp.StatusCode < 200 || resp.StatusCode >= 300 { return fmt.Errorf("error fetching %s: %s", t.URL, resp.Status) } t.Bin = body diff --git a/params.go b/params.go index 4a2ed6c942..f7135b2dfa 100644 --- a/params.go +++ b/params.go @@ -109,7 +109,7 @@ func BuildRequestBody(opts any, parent string) (map[string]any, error) { } xorFieldIsZero = isZero(xorField) } - if !(zero != xorFieldIsZero) { + if zero == xorFieldIsZero { err := ErrMissingInput{} err.Argument = fmt.Sprintf("%s/%s", f.Name, xorTag) err.Info = fmt.Sprintf("Exactly one of %s and %s must be provided", f.Name, xorTag) diff --git a/testhelper/convenience.go b/testhelper/convenience.go index 1ea727045f..57fa558fd1 100644 --- a/testhelper/convenience.go +++ b/testhelper/convenience.go @@ -433,7 +433,7 @@ func CheckErr(t *testing.T, e error, expected ...any) { func AssertIntLesserOrEqual(t *testing.T, v1 int, v2 int) { t.Helper() - if !(v1 <= v2) { + if v1 > v2 { logFatal(t, fmt.Sprintf("The first value \"%v\" is greater than the second value \"%v\"", v1, v2)) } } @@ -442,7 +442,7 @@ func AssertIntLesserOrEqual(t *testing.T, v1 int, v2 int) { func AssertIntGreaterOrEqual(t *testing.T, v1 int, v2 int) { t.Helper() - if !(v1 >= v2) { + if v1 < v2 { logFatal(t, fmt.Sprintf("The first value \"%v\" is lesser than the second value \"%v\"", v1, v2)) } } From 6e1a9b95094ca0e84a19cfd8cfbf4d4d93563bc4 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Fri, 16 May 2025 11:26:20 +0100 Subject: [PATCH 252/353] lint: Prefer switch statements over conditional ladders Signed-off-by: Stephen Finucane --- .golangci.yaml | 3 --- openstack/image/v2/imagedata/testing/requests_test.go | 9 +++++---- .../v2/extensions/bgp/speakers/testing/requests_test.go | 7 ++++--- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/.golangci.yaml b/.golangci.yaml index 28bf5ecf15..054ab275e2 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -27,9 +27,6 @@ linters: - linters: - staticcheck text: "ST1005: error strings should not end with punctuation or newlines" - - linters: - - staticcheck - text: "QF1003: could use tagged switch on .*" - linters: - staticcheck text: "QF1004: could use strings.ReplaceAll instead" diff --git a/openstack/image/v2/imagedata/testing/requests_test.go b/openstack/image/v2/imagedata/testing/requests_test.go index ad4dba86f1..3a5c26706c 100644 --- a/openstack/image/v2/imagedata/testing/requests_test.go +++ b/openstack/image/v2/imagedata/testing/requests_test.go @@ -74,13 +74,14 @@ func min(a int, b int) int { func (rs *RS) Seek(offset int64, whence int) (int64, error) { var offsetInt = int(offset) - if whence == 0 { + switch whence { + case 0: rs.offset = offsetInt - } else if whence == 1 { + case 1: rs.offset = rs.offset + offsetInt - } else if whence == 2 { + case 2: rs.offset = len(rs.bs) - offsetInt - } else { + default: return 0, fmt.Errorf("For parameter `whence`, expected value in {0,1,2} but got: %#v", whence) } diff --git a/openstack/networking/v2/extensions/bgp/speakers/testing/requests_test.go b/openstack/networking/v2/extensions/bgp/speakers/testing/requests_test.go index edcf11637b..2970094f30 100644 --- a/openstack/networking/v2/extensions/bgp/speakers/testing/requests_test.go +++ b/openstack/networking/v2/extensions/bgp/speakers/testing/requests_test.go @@ -119,13 +119,14 @@ func TestUpdate(t *testing.T) { bgpSpeakerID := "ab01ade1-ae62-43c9-8a1f-3c24225b96d8" fakeServer.Mux.HandleFunc("/v2.0/bgp-speakers/"+bgpSpeakerID, func(w http.ResponseWriter, r *http.Request) { - if r.Method == "GET" { + switch r.Method { + case "GET": th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) fmt.Fprint(w, GetBGPSpeakerResult) - } else if r.Method == "PUT" { + case "PUT": th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") @@ -135,7 +136,7 @@ func TestUpdate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) fmt.Fprint(w, UpdateBGPSpeakerResponse) - } else { + default: panic("Unexpected Request") } }) From df0588e06e04acd7524c3f625fffc6c111c7c5af Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Fri, 16 May 2025 11:32:13 +0100 Subject: [PATCH 253/353] lint: Prefer strings.ReplaceAll to string.Replace with n=-1 Signed-off-by: Stephen Finucane --- .golangci.yaml | 3 --- openstack/client.go | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/.golangci.yaml b/.golangci.yaml index 054ab275e2..553f2f253c 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -27,9 +27,6 @@ linters: - linters: - staticcheck text: "ST1005: error strings should not end with punctuation or newlines" - - linters: - - staticcheck - text: "QF1004: could use strings.ReplaceAll instead" - linters: - staticcheck text: "could remove embedded field \".*\" from selector" diff --git a/openstack/client.go b/openstack/client.go index 73ca5c56d5..b43938949b 100644 --- a/openstack/client.go +++ b/openstack/client.go @@ -458,7 +458,7 @@ func NewLoadBalancerV2(client *gophercloud.ProviderClient, eo gophercloud.Endpoi sc, err := initClientOpts(client, eo, "load-balancer", 2) // Fixes edge case having an OpenStack lb endpoint with trailing version number. - endpoint := strings.Replace(sc.Endpoint, "v2.0/", "", -1) + endpoint := strings.ReplaceAll(sc.Endpoint, "v2.0/", "") sc.ResourceBase = endpoint + "v2.0/" return sc, err From 78426b48a301470b018fd4beb830506052ec14b0 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Fri, 16 May 2025 11:33:02 +0100 Subject: [PATCH 254/353] lint: Remove embedded fields from selectors This looks complicated, but it's just a whole lot of sed invocations. Signed-off-by: Stephen Finucane Conflicts: openstack/baremetal/v1/portgroups/results.go openstack/messaging/v2/messages/results.go openstack/messaging/v2/queues/results.go --- .golangci.yaml | 3 --- docs/FAQ.md | 2 +- .../openstack/identity/v3/oauth1_test.go | 2 +- .../extensions/trunk_details/trunks_test.go | 16 ++++++------- .../objectstorage/v1/objects_test.go | 4 ++-- openstack/baremetal/v1/allocations/results.go | 4 ++-- openstack/baremetal/v1/conductors/results.go | 4 ++-- openstack/baremetal/v1/drivers/results.go | 4 ++-- openstack/baremetal/v1/nodes/results.go | 4 ++-- .../v1/nodes/testing/results_test.go | 10 ++++---- openstack/baremetal/v1/ports/results.go | 4 ++-- .../v1/introspection/results.go | 4 ++-- openstack/blockstorage/v2/backups/results.go | 10 ++++---- .../blockstorage/v2/transfers/results.go | 4 ++-- openstack/blockstorage/v2/volumes/results.go | 4 ++-- .../blockstorage/v3/attachments/results.go | 4 ++-- openstack/blockstorage/v3/backups/results.go | 10 ++++---- .../v3/manageablevolumes/results.go | 2 +- openstack/blockstorage/v3/qos/results.go | 2 +- .../blockstorage/v3/transfers/results.go | 4 ++-- openstack/blockstorage/v3/volumes/results.go | 4 ++-- .../blockstorage/v3/volumetypes/results.go | 6 ++--- .../compute/v2/instanceactions/results.go | 4 ++-- openstack/compute/v2/servers/results.go | 4 ++-- .../v2/extensions/bgp/peers/results.go | 4 ++-- .../v2/extensions/bgp/speakers/results.go | 8 +++---- .../v2/extensions/bgpvpns/requests.go | 8 +++---- .../v2/extensions/bgpvpns/results.go | 24 +++++++++---------- .../extensions/layer3/floatingips/results.go | 4 ++-- .../layer3/portforwarding/results.go | 2 +- .../v2/extensions/layer3/routers/results.go | 2 +- .../v2/extensions/qos/policies/results.go | 2 +- .../v2/extensions/qos/rules/results.go | 6 ++--- .../v2/extensions/rbacpolicies/results.go | 4 ++-- .../trunk_details/testing/requests_test.go | 6 ++--- openstack/networking/v2/networks/results.go | 4 ++-- openstack/networking/v2/ports/results.go | 4 ++-- .../objectstorage/v1/containers/requests.go | 2 +- .../objectstorage/v1/objects/requests.go | 2 +- openstack/objectstorage/v1/objects/results.go | 2 +- .../orchestration/v1/stackevents/requests.go | 4 ++-- .../sharedfilesystems/v2/replicas/requests.go | 4 ++-- .../sharedfilesystems/v2/replicas/results.go | 4 ++-- .../v2/sharenetworks/requests.go | 2 +- .../v2/sharenetworks/results.go | 2 +- .../sharedfilesystems/v2/shares/requests.go | 2 +- .../sharedfilesystems/v2/shares/results.go | 2 +- .../v2/sharetransfers/requests.go | 4 ++-- .../v2/sharetransfers/results.go | 6 ++--- .../v2/snapshots/requests.go | 2 +- .../sharedfilesystems/v2/snapshots/results.go | 2 +- pagination/testing/marker_test.go | 2 +- 52 files changed, 118 insertions(+), 121 deletions(-) diff --git a/.golangci.yaml b/.golangci.yaml index 553f2f253c..6469415c8c 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -27,9 +27,6 @@ linters: - linters: - staticcheck text: "ST1005: error strings should not end with punctuation or newlines" - - linters: - - staticcheck - text: "could remove embedded field \".*\" from selector" - path: (.+)\.go$ text: SA1006 paths: diff --git a/docs/FAQ.md b/docs/FAQ.md index bb37db8019..bc42ae6cbb 100644 --- a/docs/FAQ.md +++ b/docs/FAQ.md @@ -8,7 +8,7 @@ Please see our dedicated document [here](MICROVERSIONS.md). You can implement custom logging and/or limit re-auth attempts by creating a custom HTTP client like the following and setting it as the provider client's HTTP Client (via the -`gophercloud.ProviderClient.HTTPClient` field): +`gophercloud.HTTPClient` field): ```go //... diff --git a/internal/acceptance/openstack/identity/v3/oauth1_test.go b/internal/acceptance/openstack/identity/v3/oauth1_test.go index 125fdd0588..2e5b9b25fe 100644 --- a/internal/acceptance/openstack/identity/v3/oauth1_test.go +++ b/internal/acceptance/openstack/identity/v3/oauth1_test.go @@ -215,7 +215,7 @@ func oauth1MethodTest(t *testing.T, client *gophercloud.ServiceClient, consumer tokens.Token oauth1.TokenExt } - tokenRes := tokens.Get(context.TODO(), newClient, newClient.ProviderClient.TokenID) + tokenRes := tokens.Get(context.TODO(), newClient, newClient.TokenID) err = tokenRes.ExtractInto(&token) th.AssertNoErr(t, err) oauth1Roles, err := tokenRes.ExtractRoles() diff --git a/internal/acceptance/openstack/networking/v2/extensions/trunk_details/trunks_test.go b/internal/acceptance/openstack/networking/v2/extensions/trunk_details/trunks_test.go index 3a9870d35b..e38404888f 100644 --- a/internal/acceptance/openstack/networking/v2/extensions/trunk_details/trunks_test.go +++ b/internal/acceptance/openstack/networking/v2/extensions/trunk_details/trunks_test.go @@ -79,8 +79,8 @@ func TestListPortWithSubports(t *testing.T) { th.AssertEquals(t, 1, len(allPorts)) port := allPorts[0] - th.AssertEquals(t, trunk.ID, port.TrunkDetails.TrunkID) - th.AssertEquals(t, 2, len(port.TrunkDetails.SubPorts)) + th.AssertEquals(t, trunk.ID, port.TrunkID) + th.AssertEquals(t, 2, len(port.SubPorts)) // Note that MAC address is not (currently) returned in list queries. We // exclude it from the comparison here in case it's ever added. MAC @@ -92,18 +92,18 @@ func TestListPortWithSubports(t *testing.T) { SegmentationID: 1, SegmentationType: "vlan", PortID: subport1.ID, - }, port.TrunkDetails.SubPorts[0].Subport) + }, port.SubPorts[0].Subport) th.AssertDeepEquals(t, trunks.Subport{ SegmentationID: 2, SegmentationType: "vlan", PortID: subport2.ID, - }, port.TrunkDetails.SubPorts[1].Subport) + }, port.SubPorts[1].Subport) // Test GET port with trunk details err = ports.Get(context.TODO(), client, parentPort.ID).ExtractInto(&port) th.AssertNoErr(t, err) - th.AssertEquals(t, trunk.ID, port.TrunkDetails.TrunkID) - th.AssertEquals(t, 2, len(port.TrunkDetails.SubPorts)) + th.AssertEquals(t, trunk.ID, port.TrunkID) + th.AssertEquals(t, 2, len(port.SubPorts)) th.AssertDeepEquals(t, trunk_details.Subport{ Subport: trunks.Subport{ SegmentationID: 1, @@ -111,7 +111,7 @@ func TestListPortWithSubports(t *testing.T) { PortID: subport1.ID, }, MACAddress: subport1.MACAddress, - }, port.TrunkDetails.SubPorts[0]) + }, port.SubPorts[0]) th.AssertDeepEquals(t, trunk_details.Subport{ Subport: trunks.Subport{ SegmentationID: 2, @@ -119,5 +119,5 @@ func TestListPortWithSubports(t *testing.T) { PortID: subport2.ID, }, MACAddress: subport2.MACAddress, - }, port.TrunkDetails.SubPorts[1]) + }, port.SubPorts[1]) } diff --git a/internal/acceptance/openstack/objectstorage/v1/objects_test.go b/internal/acceptance/openstack/objectstorage/v1/objects_test.go index 5fcf806936..90753baeb8 100644 --- a/internal/acceptance/openstack/objectstorage/v1/objects_test.go +++ b/internal/acceptance/openstack/objectstorage/v1/objects_test.go @@ -100,7 +100,7 @@ func TestObjects(t *testing.T) { }) th.AssertNoErr(t, err) - resp, err := client.ProviderClient.HTTPClient.Get(objURLs[i]) + resp, err := client.HTTPClient.Get(objURLs[i]) th.AssertNoErr(t, err) if resp.StatusCode != http.StatusOK { resp.Body.Close() @@ -121,7 +121,7 @@ func TestObjects(t *testing.T) { }) th.AssertNoErr(t, err) - resp, err = client.ProviderClient.HTTPClient.Get(objURLs[i]) + resp, err = client.HTTPClient.Get(objURLs[i]) th.AssertNoErr(t, err) if resp.StatusCode != http.StatusOK { resp.Body.Close() diff --git a/openstack/baremetal/v1/allocations/results.go b/openstack/baremetal/v1/allocations/results.go index 932862e283..cc05ed68ce 100644 --- a/openstack/baremetal/v1/allocations/results.go +++ b/openstack/baremetal/v1/allocations/results.go @@ -56,11 +56,11 @@ func (r allocationResult) Extract() (*Allocation, error) { } func (r allocationResult) ExtractInto(v any) error { - return r.Result.ExtractIntoStructPtr(v, "") + return r.ExtractIntoStructPtr(v, "") } func ExtractAllocationsInto(r pagination.Page, v any) error { - return r.(AllocationPage).Result.ExtractIntoSlicePtr(v, "allocations") + return r.(AllocationPage).ExtractIntoSlicePtr(v, "allocations") } // AllocationPage abstracts the raw results of making a List() request against diff --git a/openstack/baremetal/v1/conductors/results.go b/openstack/baremetal/v1/conductors/results.go index 5431106108..005669af9f 100644 --- a/openstack/baremetal/v1/conductors/results.go +++ b/openstack/baremetal/v1/conductors/results.go @@ -19,11 +19,11 @@ func (r conductorResult) Extract() (*Conductor, error) { } func (r conductorResult) ExtractInto(v any) error { - return r.Result.ExtractIntoStructPtr(v, "") + return r.ExtractIntoStructPtr(v, "") } func ExtractConductorInto(r pagination.Page, v any) error { - return r.(ConductorPage).Result.ExtractIntoSlicePtr(v, "conductors") + return r.(ConductorPage).ExtractIntoSlicePtr(v, "conductors") } // Conductor represents a conductor in the OpenStack Bare Metal API. diff --git a/openstack/baremetal/v1/drivers/results.go b/openstack/baremetal/v1/drivers/results.go index 4905fa902b..d3ebc6555b 100644 --- a/openstack/baremetal/v1/drivers/results.go +++ b/openstack/baremetal/v1/drivers/results.go @@ -17,11 +17,11 @@ func (r driverResult) Extract() (*Driver, error) { } func (r driverResult) ExtractInto(v any) error { - return r.Result.ExtractIntoStructPtr(v, "") + return r.ExtractIntoStructPtr(v, "") } func ExtractDriversInto(r pagination.Page, v any) error { - return r.(DriverPage).Result.ExtractIntoSlicePtr(v, "drivers") + return r.(DriverPage).ExtractIntoSlicePtr(v, "drivers") } // Driver represents a driver in the OpenStack Bare Metal API. diff --git a/openstack/baremetal/v1/nodes/results.go b/openstack/baremetal/v1/nodes/results.go index b33517a388..abc669c579 100644 --- a/openstack/baremetal/v1/nodes/results.go +++ b/openstack/baremetal/v1/nodes/results.go @@ -47,11 +47,11 @@ func (r ValidateResult) Extract() (*NodeValidation, error) { } func (r nodeResult) ExtractInto(v any) error { - return r.Result.ExtractIntoStructPtr(v, "") + return r.ExtractIntoStructPtr(v, "") } func ExtractNodesInto(r pagination.Page, v any) error { - return r.(NodePage).Result.ExtractIntoSlicePtr(v, "nodes") + return r.(NodePage).ExtractIntoSlicePtr(v, "nodes") } // Extract interprets a BIOSSettingsResult as an array of BIOSSetting structs, if possible. diff --git a/openstack/baremetal/v1/nodes/testing/results_test.go b/openstack/baremetal/v1/nodes/testing/results_test.go index acdb59e774..f7b99d827f 100644 --- a/openstack/baremetal/v1/nodes/testing/results_test.go +++ b/openstack/baremetal/v1/nodes/testing/results_test.go @@ -13,7 +13,7 @@ import ( func TestStandardPluginData(t *testing.T) { var pluginData nodes.PluginData - err := pluginData.RawMessage.UnmarshalJSON([]byte(invtest.StandardPluginDataSample)) + err := pluginData.UnmarshalJSON([]byte(invtest.StandardPluginDataSample)) th.AssertNoErr(t, err) parsedData, err := pluginData.AsStandardData() @@ -28,7 +28,7 @@ func TestStandardPluginData(t *testing.T) { func TestInspectorPluginData(t *testing.T) { var pluginData nodes.PluginData - err := pluginData.RawMessage.UnmarshalJSON([]byte(insptest.IntrospectionDataJSONSample)) + err := pluginData.UnmarshalJSON([]byte(insptest.IntrospectionDataJSONSample)) th.AssertNoErr(t, err) parsedData, err := pluginData.AsInspectorData() @@ -43,7 +43,7 @@ func TestInspectorPluginData(t *testing.T) { func TestGuessFormatUnknownDefaultsToIronic(t *testing.T) { var pluginData nodes.PluginData - err := pluginData.RawMessage.UnmarshalJSON([]byte("{}")) + err := pluginData.UnmarshalJSON([]byte("{}")) th.AssertNoErr(t, err) irData, inspData, err := pluginData.GuessFormat() @@ -54,7 +54,7 @@ func TestGuessFormatUnknownDefaultsToIronic(t *testing.T) { func TestGuessFormatErrors(t *testing.T) { var pluginData nodes.PluginData - err := pluginData.RawMessage.UnmarshalJSON([]byte("\"banana\"")) + err := pluginData.UnmarshalJSON([]byte("\"banana\"")) th.AssertNoErr(t, err) irData, inspData, err := pluginData.GuessFormat() @@ -65,7 +65,7 @@ func TestGuessFormatErrors(t *testing.T) { failsInspectorConversion := `{ "interfaces": "banana" }` - err = pluginData.RawMessage.UnmarshalJSON([]byte(failsInspectorConversion)) + err = pluginData.UnmarshalJSON([]byte(failsInspectorConversion)) th.AssertNoErr(t, err) irData, inspData, err = pluginData.GuessFormat() diff --git a/openstack/baremetal/v1/ports/results.go b/openstack/baremetal/v1/ports/results.go index b1ec5cca81..1537a45bea 100644 --- a/openstack/baremetal/v1/ports/results.go +++ b/openstack/baremetal/v1/ports/results.go @@ -18,11 +18,11 @@ func (r portResult) Extract() (*Port, error) { } func (r portResult) ExtractInto(v any) error { - return r.Result.ExtractIntoStructPtr(v, "") + return r.ExtractIntoStructPtr(v, "") } func ExtractPortsInto(r pagination.Page, v any) error { - return r.(PortPage).Result.ExtractIntoSlicePtr(v, "ports") + return r.(PortPage).ExtractIntoSlicePtr(v, "ports") } // Port represents a port in the OpenStack Bare Metal API. diff --git a/openstack/baremetalintrospection/v1/introspection/results.go b/openstack/baremetalintrospection/v1/introspection/results.go index 00e0287bc4..c7740940a1 100644 --- a/openstack/baremetalintrospection/v1/introspection/results.go +++ b/openstack/baremetalintrospection/v1/introspection/results.go @@ -22,13 +22,13 @@ func (r introspectionResult) Extract() (*Introspection, error) { // ExtractInto will extract a response body into an Introspection struct. func (r introspectionResult) ExtractInto(v any) error { - return r.Result.ExtractIntoStructPtr(v, "") + return r.ExtractIntoStructPtr(v, "") } // ExtractIntrospectionsInto will extract a collection of introspectResult pages into a // slice of Introspection entities. func ExtractIntrospectionsInto(r pagination.Page, v any) error { - return r.(IntrospectionPage).Result.ExtractIntoSlicePtr(v, "introspection") + return r.(IntrospectionPage).ExtractIntoSlicePtr(v, "introspection") } // ExtractIntrospections interprets the results of a single page from a diff --git a/openstack/blockstorage/v2/backups/results.go b/openstack/blockstorage/v2/backups/results.go index 77620de917..fb204b9f61 100644 --- a/openstack/blockstorage/v2/backups/results.go +++ b/openstack/blockstorage/v2/backups/results.go @@ -156,11 +156,11 @@ func (r commonResult) Extract() (*Backup, error) { } func (r commonResult) ExtractInto(v any) error { - return r.Result.ExtractIntoStructPtr(v, "backup") + return r.ExtractIntoStructPtr(v, "backup") } func ExtractBackupsInto(r pagination.Page, v any) error { - return r.(BackupPage).Result.ExtractIntoSlicePtr(v, "backups") + return r.(BackupPage).ExtractIntoSlicePtr(v, "backups") } // RestoreResult contains the response body and error from a restore request. @@ -189,7 +189,7 @@ func (r RestoreResult) Extract() (*Restore, error) { } func (r RestoreResult) ExtractInto(v any) error { - return r.Result.ExtractIntoStructPtr(v, "restore") + return r.ExtractIntoStructPtr(v, "restore") } // ExportResult contains the response body and error from an export request. @@ -214,7 +214,7 @@ func (r ExportResult) Extract() (*BackupRecord, error) { } func (r ExportResult) ExtractInto(v any) error { - return r.Result.ExtractIntoStructPtr(v, "backup-record") + return r.ExtractIntoStructPtr(v, "backup-record") } // ImportResponse struct contains the response of the Backup Import action. @@ -236,7 +236,7 @@ func (r ImportResult) Extract() (*ImportResponse, error) { } func (r ImportResult) ExtractInto(v any) error { - return r.Result.ExtractIntoStructPtr(v, "backup") + return r.ExtractIntoStructPtr(v, "backup") } // ImportBackup contains all the information to import a Cinder Backup. diff --git a/openstack/blockstorage/v2/transfers/results.go b/openstack/blockstorage/v2/transfers/results.go index 42885c27ef..5dce9179ff 100644 --- a/openstack/blockstorage/v2/transfers/results.go +++ b/openstack/blockstorage/v2/transfers/results.go @@ -49,7 +49,7 @@ func (r commonResult) Extract() (*Transfer, error) { // ExtractInto converts our response data into a transfer struct func (r commonResult) ExtractInto(v any) error { - return r.Result.ExtractIntoStructPtr(v, "transfer") + return r.ExtractIntoStructPtr(v, "transfer") } // CreateResult contains the response body and error from a Create request. @@ -76,7 +76,7 @@ func ExtractTransfers(r pagination.Page) ([]Transfer, error) { // ExtractTransfersInto similar to ExtractInto but operates on a `list` of transfers func ExtractTransfersInto(r pagination.Page, v any) error { - return r.(TransferPage).Result.ExtractIntoSlicePtr(v, "transfers") + return r.(TransferPage).ExtractIntoSlicePtr(v, "transfers") } // TransferPage is a pagination.pager that is returned from a call to the List function. diff --git a/openstack/blockstorage/v2/volumes/results.go b/openstack/blockstorage/v2/volumes/results.go index 061309e991..abc3d46821 100644 --- a/openstack/blockstorage/v2/volumes/results.go +++ b/openstack/blockstorage/v2/volumes/results.go @@ -147,11 +147,11 @@ func (r commonResult) Extract() (*Volume, error) { } func (r commonResult) ExtractInto(v any) error { - return r.Result.ExtractIntoStructPtr(v, "volume") + return r.ExtractIntoStructPtr(v, "volume") } func ExtractVolumesInto(r pagination.Page, v any) error { - return r.(VolumePage).Result.ExtractIntoSlicePtr(v, "volumes") + return r.(VolumePage).ExtractIntoSlicePtr(v, "volumes") } // CreateResult contains the response body and error from a Create request. diff --git a/openstack/blockstorage/v3/attachments/results.go b/openstack/blockstorage/v3/attachments/results.go index 8c572047ae..0ef8a66074 100644 --- a/openstack/blockstorage/v3/attachments/results.go +++ b/openstack/blockstorage/v3/attachments/results.go @@ -89,13 +89,13 @@ func (r commonResult) Extract() (*Attachment, error) { // ExtractInto converts our response data into a attachment struct. func (r commonResult) ExtractInto(a any) error { - return r.Result.ExtractIntoStructPtr(a, "attachment") + return r.ExtractIntoStructPtr(a, "attachment") } // ExtractAttachmentsInto similar to ExtractInto but operates on a List of // attachments. func ExtractAttachmentsInto(r pagination.Page, a any) error { - return r.(AttachmentPage).Result.ExtractIntoSlicePtr(a, "attachments") + return r.(AttachmentPage).ExtractIntoSlicePtr(a, "attachments") } // CreateResult contains the response body and error from a Create request. diff --git a/openstack/blockstorage/v3/backups/results.go b/openstack/blockstorage/v3/backups/results.go index 77620de917..fb204b9f61 100644 --- a/openstack/blockstorage/v3/backups/results.go +++ b/openstack/blockstorage/v3/backups/results.go @@ -156,11 +156,11 @@ func (r commonResult) Extract() (*Backup, error) { } func (r commonResult) ExtractInto(v any) error { - return r.Result.ExtractIntoStructPtr(v, "backup") + return r.ExtractIntoStructPtr(v, "backup") } func ExtractBackupsInto(r pagination.Page, v any) error { - return r.(BackupPage).Result.ExtractIntoSlicePtr(v, "backups") + return r.(BackupPage).ExtractIntoSlicePtr(v, "backups") } // RestoreResult contains the response body and error from a restore request. @@ -189,7 +189,7 @@ func (r RestoreResult) Extract() (*Restore, error) { } func (r RestoreResult) ExtractInto(v any) error { - return r.Result.ExtractIntoStructPtr(v, "restore") + return r.ExtractIntoStructPtr(v, "restore") } // ExportResult contains the response body and error from an export request. @@ -214,7 +214,7 @@ func (r ExportResult) Extract() (*BackupRecord, error) { } func (r ExportResult) ExtractInto(v any) error { - return r.Result.ExtractIntoStructPtr(v, "backup-record") + return r.ExtractIntoStructPtr(v, "backup-record") } // ImportResponse struct contains the response of the Backup Import action. @@ -236,7 +236,7 @@ func (r ImportResult) Extract() (*ImportResponse, error) { } func (r ImportResult) ExtractInto(v any) error { - return r.Result.ExtractIntoStructPtr(v, "backup") + return r.ExtractIntoStructPtr(v, "backup") } // ImportBackup contains all the information to import a Cinder Backup. diff --git a/openstack/blockstorage/v3/manageablevolumes/results.go b/openstack/blockstorage/v3/manageablevolumes/results.go index 317ed21fb3..bb8ec9f7e3 100644 --- a/openstack/blockstorage/v3/manageablevolumes/results.go +++ b/openstack/blockstorage/v3/manageablevolumes/results.go @@ -18,5 +18,5 @@ func (r ManageExistingResult) Extract() (*volumes.Volume, error) { // ExtractInto converts our response data into a volume struct func (r ManageExistingResult) ExtractInto(v any) error { - return r.Result.ExtractIntoStructPtr(v, "volume") + return r.ExtractIntoStructPtr(v, "volume") } diff --git a/openstack/blockstorage/v3/qos/results.go b/openstack/blockstorage/v3/qos/results.go index 314bf878ca..53765f3af1 100644 --- a/openstack/blockstorage/v3/qos/results.go +++ b/openstack/blockstorage/v3/qos/results.go @@ -30,7 +30,7 @@ func (r commonResult) Extract() (*QoS, error) { // ExtractInto converts our response data into a QoS struct func (r commonResult) ExtractInto(qos any) error { - return r.Result.ExtractIntoStructPtr(qos, "qos_specs") + return r.ExtractIntoStructPtr(qos, "qos_specs") } // CreateResult contains the response body and error from a Create request. diff --git a/openstack/blockstorage/v3/transfers/results.go b/openstack/blockstorage/v3/transfers/results.go index 42885c27ef..5dce9179ff 100644 --- a/openstack/blockstorage/v3/transfers/results.go +++ b/openstack/blockstorage/v3/transfers/results.go @@ -49,7 +49,7 @@ func (r commonResult) Extract() (*Transfer, error) { // ExtractInto converts our response data into a transfer struct func (r commonResult) ExtractInto(v any) error { - return r.Result.ExtractIntoStructPtr(v, "transfer") + return r.ExtractIntoStructPtr(v, "transfer") } // CreateResult contains the response body and error from a Create request. @@ -76,7 +76,7 @@ func ExtractTransfers(r pagination.Page) ([]Transfer, error) { // ExtractTransfersInto similar to ExtractInto but operates on a `list` of transfers func ExtractTransfersInto(r pagination.Page, v any) error { - return r.(TransferPage).Result.ExtractIntoSlicePtr(v, "transfers") + return r.(TransferPage).ExtractIntoSlicePtr(v, "transfers") } // TransferPage is a pagination.pager that is returned from a call to the List function. diff --git a/openstack/blockstorage/v3/volumes/results.go b/openstack/blockstorage/v3/volumes/results.go index e99ef5e197..b32c836161 100644 --- a/openstack/blockstorage/v3/volumes/results.go +++ b/openstack/blockstorage/v3/volumes/results.go @@ -154,12 +154,12 @@ func (r commonResult) Extract() (*Volume, error) { // ExtractInto converts our response data into a volume struct func (r commonResult) ExtractInto(v any) error { - return r.Result.ExtractIntoStructPtr(v, "volume") + return r.ExtractIntoStructPtr(v, "volume") } // ExtractVolumesInto similar to ExtractInto but operates on a `list` of volumes func ExtractVolumesInto(r pagination.Page, v any) error { - return r.(VolumePage).Result.ExtractIntoSlicePtr(v, "volumes") + return r.(VolumePage).ExtractIntoSlicePtr(v, "volumes") } // CreateResult contains the response body and error from a Create request. diff --git a/openstack/blockstorage/v3/volumetypes/results.go b/openstack/blockstorage/v3/volumetypes/results.go index 9d5dce56ee..11f03b4c94 100644 --- a/openstack/blockstorage/v3/volumetypes/results.go +++ b/openstack/blockstorage/v3/volumetypes/results.go @@ -69,12 +69,12 @@ func (r commonResult) Extract() (*VolumeType, error) { // ExtractInto converts our response data into a volume type struct func (r commonResult) ExtractInto(v any) error { - return r.Result.ExtractIntoStructPtr(v, "volume_type") + return r.ExtractIntoStructPtr(v, "volume_type") } // ExtractVolumeTypesInto similar to ExtractInto but operates on a `list` of volume types func ExtractVolumeTypesInto(r pagination.Page, v any) error { - return r.(VolumeTypePage).Result.ExtractIntoSlicePtr(v, "volume_types") + return r.(VolumeTypePage).ExtractIntoSlicePtr(v, "volume_types") } // GetResult contains the response body and error from a Get request. @@ -228,7 +228,7 @@ func (r encryptionResult) Extract() (*EncryptionType, error) { // ExtractInto converts our response data into a volume type struct func (r encryptionResult) ExtractInto(v any) error { - return r.Result.ExtractIntoStructPtr(v, "encryption") + return r.ExtractIntoStructPtr(v, "encryption") } type CreateEncryptionResult struct { diff --git a/openstack/compute/v2/instanceactions/results.go b/openstack/compute/v2/instanceactions/results.go index 2015be88c2..8ebc060542 100644 --- a/openstack/compute/v2/instanceactions/results.go +++ b/openstack/compute/v2/instanceactions/results.go @@ -186,9 +186,9 @@ func (r InstanceActionResult) Extract() (InstanceActionDetail, error) { } func (r InstanceActionResult) ExtractInto(v any) error { - return r.Result.ExtractIntoStructPtr(v, "instanceAction") + return r.ExtractIntoStructPtr(v, "instanceAction") } func ExtractInstanceActionsInto(r pagination.Page, v any) error { - return r.(InstanceActionPage).Result.ExtractIntoSlicePtr(v, "instanceActions") + return r.(InstanceActionPage).ExtractIntoSlicePtr(v, "instanceActions") } diff --git a/openstack/compute/v2/servers/results.go b/openstack/compute/v2/servers/results.go index edc2740f68..153efb6acd 100644 --- a/openstack/compute/v2/servers/results.go +++ b/openstack/compute/v2/servers/results.go @@ -27,11 +27,11 @@ func (r serverResult) Extract() (*Server, error) { } func (r serverResult) ExtractInto(v any) error { - return r.Result.ExtractIntoStructPtr(v, "server") + return r.ExtractIntoStructPtr(v, "server") } func ExtractServersInto(r pagination.Page, v any) error { - return r.(ServerPage).Result.ExtractIntoSlicePtr(v, "servers") + return r.(ServerPage).ExtractIntoSlicePtr(v, "servers") } // CreateResult is the response from a Create operation. Call its Extract diff --git a/openstack/networking/v2/extensions/bgp/peers/results.go b/openstack/networking/v2/extensions/bgp/peers/results.go index afd771b1e4..ac07c91c81 100644 --- a/openstack/networking/v2/extensions/bgp/peers/results.go +++ b/openstack/networking/v2/extensions/bgp/peers/results.go @@ -19,7 +19,7 @@ func (r commonResult) Extract() (*BGPPeer, error) { } func (r commonResult) ExtractInto(v any) error { - return r.Result.ExtractIntoStructPtr(v, jroot) + return r.ExtractIntoStructPtr(v, jroot) } // BGP peer @@ -72,7 +72,7 @@ func ExtractBGPPeers(r pagination.Page) ([]BGPPeer, error) { } func ExtractBGPPeersInto(r pagination.Page, v any) error { - return r.(BGPPeerPage).Result.ExtractIntoSlicePtr(v, "bgp_peers") + return r.(BGPPeerPage).ExtractIntoSlicePtr(v, "bgp_peers") } // GetResult represents the result of a get operation. Call its Extract diff --git a/openstack/networking/v2/extensions/bgp/speakers/results.go b/openstack/networking/v2/extensions/bgp/speakers/results.go index 93c967ca47..3c8b312537 100644 --- a/openstack/networking/v2/extensions/bgp/speakers/results.go +++ b/openstack/networking/v2/extensions/bgp/speakers/results.go @@ -19,7 +19,7 @@ func (r commonResult) Extract() (*BGPSpeaker, error) { } func (r commonResult) ExtractInto(v any) error { - return r.Result.ExtractIntoStructPtr(v, jroot) + return r.ExtractIntoStructPtr(v, jroot) } // BGPSpeaker BGP Speaker @@ -84,7 +84,7 @@ func ExtractBGPSpeakers(r pagination.Page) ([]BGPSpeaker, error) { // a list of BGPSpeaker and the later should be used to store the result that would be // extracted from the former. func ExtractBGPSpeakersInto(r pagination.Page, v any) error { - return r.(BGPSpeakerPage).Result.ExtractIntoSlicePtr(v, "bgp_speakers") + return r.(BGPSpeakerPage).ExtractIntoSlicePtr(v, "bgp_speakers") } // GetResult represents the result of a get operation. Call its Extract @@ -124,7 +124,7 @@ func (r AddBGPPeerResult) Extract() (*AddBGPPeerOpts, error) { } func (r AddBGPPeerResult) ExtractInto(v any) error { - return r.Result.ExtractIntoStructPtr(v, "") + return r.ExtractIntoStructPtr(v, "") } // RemoveBGPPeerResult represent the response of the PUT /v2.0/bgp-speakers/{bgp-speaker-id}/remove-bgp-peer @@ -167,7 +167,7 @@ func ExtractAdvertisedRoutes(r pagination.Page) ([]AdvertisedRoute, error) { // ExtractAdvertisedRoutesInto extract the advertised routes from the first param into the 2nd func ExtractAdvertisedRoutesInto(r pagination.Page, v any) error { - return r.(AdvertisedRoutePage).Result.ExtractIntoSlicePtr(v, "advertised_routes") + return r.(AdvertisedRoutePage).ExtractIntoSlicePtr(v, "advertised_routes") } // AddGatewayNetworkResult represents the data that would be PUT to diff --git a/openstack/networking/v2/extensions/bgpvpns/requests.go b/openstack/networking/v2/extensions/bgpvpns/requests.go index 374b4daf5b..9e6c02717f 100644 --- a/openstack/networking/v2/extensions/bgpvpns/requests.go +++ b/openstack/networking/v2/extensions/bgpvpns/requests.go @@ -43,7 +43,7 @@ func List(c *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { url += query return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page { p := BGPVPNPage{pagination.MarkerPageBase{PageResult: r}} - p.MarkerPageBase.Owner = p + p.Owner = p return p }) } @@ -169,7 +169,7 @@ func ListNetworkAssociations(c *gophercloud.ServiceClient, id string, opts ListN url += query return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page { p := NetworkAssociationPage{pagination.MarkerPageBase{PageResult: r}} - p.MarkerPageBase.Owner = p + p.Owner = p return p }) } @@ -258,7 +258,7 @@ func ListRouterAssociations(c *gophercloud.ServiceClient, id string, opts ListRo url += query return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page { p := RouterAssociationPage{pagination.MarkerPageBase{PageResult: r}} - p.MarkerPageBase.Owner = p + p.Owner = p return p }) } @@ -380,7 +380,7 @@ func ListPortAssociations(c *gophercloud.ServiceClient, id string, opts ListPort url += query return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page { p := PortAssociationPage{pagination.MarkerPageBase{PageResult: r}} - p.MarkerPageBase.Owner = p + p.Owner = p return p }) } diff --git a/openstack/networking/v2/extensions/bgpvpns/results.go b/openstack/networking/v2/extensions/bgpvpns/results.go index df0587568c..5aef69b98a 100644 --- a/openstack/networking/v2/extensions/bgpvpns/results.go +++ b/openstack/networking/v2/extensions/bgpvpns/results.go @@ -23,7 +23,7 @@ func (r commonResult) Extract() (*BGPVPN, error) { } func (r commonResult) ExtractInto(v any) error { - return r.Result.ExtractIntoStructPtr(v, "bgpvpn") + return r.ExtractIntoStructPtr(v, "bgpvpn") } // BGPVPN represents an MPLS network with which Neutron routers and/or networks @@ -115,7 +115,7 @@ func (r BGPVPNPage) LastMarker() (string, error) { return invalidMarker, nil } - u, err := url.Parse(r.URL.String()) + u, err := url.Parse(r.String()) if err != nil { return invalidMarker, err } @@ -150,7 +150,7 @@ func ExtractBGPVPNs(r pagination.Page) ([]BGPVPN, error) { } func ExtractBGPVPNsInto(r pagination.Page, v any) error { - return r.(BGPVPNPage).Result.ExtractIntoSlicePtr(v, "bgpvpns") + return r.(BGPVPNPage).ExtractIntoSlicePtr(v, "bgpvpns") } // GetResult represents the result of a get operation. Call its Extract @@ -189,7 +189,7 @@ func (r commonNetworkAssociationResult) Extract() (*NetworkAssociation, error) { } func (r commonNetworkAssociationResult) ExtractInto(v any) error { - return r.Result.ExtractIntoStructPtr(v, "network_association") + return r.ExtractIntoStructPtr(v, "network_association") } // NetworkAssociation represents a BGP VPN network association object. @@ -233,7 +233,7 @@ func (r NetworkAssociationPage) LastMarker() (string, error) { return invalidMarker, nil } - u, err := url.Parse(r.URL.String()) + u, err := url.Parse(r.String()) if err != nil { return invalidMarker, err } @@ -264,7 +264,7 @@ func ExtractNetworkAssociations(r pagination.Page) ([]NetworkAssociation, error) } func ExtractNetworkAssociationsInto(r pagination.Page, v interface{}) error { - return r.(NetworkAssociationPage).Result.ExtractIntoSlicePtr(v, "network_associations") + return r.(NetworkAssociationPage).ExtractIntoSlicePtr(v, "network_associations") } // CreateNetworkAssociationResult represents the result of a create operation. Call its Extract @@ -297,7 +297,7 @@ func (r commonRouterAssociationResult) Extract() (*RouterAssociation, error) { } func (r commonRouterAssociationResult) ExtractInto(v any) error { - return r.Result.ExtractIntoStructPtr(v, "router_association") + return r.ExtractIntoStructPtr(v, "router_association") } // RouterAssociation represents a BGP VPN router association object. @@ -342,7 +342,7 @@ func (r RouterAssociationPage) LastMarker() (string, error) { return invalidMarker, nil } - u, err := url.Parse(r.URL.String()) + u, err := url.Parse(r.String()) if err != nil { return invalidMarker, err } @@ -373,7 +373,7 @@ func ExtractRouterAssociations(r pagination.Page) ([]RouterAssociation, error) { } func ExtractRouterAssociationsInto(r pagination.Page, v interface{}) error { - return r.(RouterAssociationPage).Result.ExtractIntoSlicePtr(v, "router_associations") + return r.(RouterAssociationPage).ExtractIntoSlicePtr(v, "router_associations") } // CreateRouterAssociationResult represents the result of a create operation. Call its Extract @@ -412,7 +412,7 @@ func (r commonPortAssociationResult) Extract() (*PortAssociation, error) { } func (r commonPortAssociationResult) ExtractInto(v any) error { - return r.Result.ExtractIntoStructPtr(v, "port_association") + return r.ExtractIntoStructPtr(v, "port_association") } // PortAssociation represents a BGP VPN port association object. @@ -458,7 +458,7 @@ func (r PortAssociationPage) LastMarker() (string, error) { return invalidMarker, nil } - u, err := url.Parse(r.URL.String()) + u, err := url.Parse(r.String()) if err != nil { return invalidMarker, err } @@ -489,7 +489,7 @@ func ExtractPortAssociations(r pagination.Page) ([]PortAssociation, error) { } func ExtractPortAssociationsInto(r pagination.Page, v interface{}) error { - return r.(PortAssociationPage).Result.ExtractIntoSlicePtr(v, "port_associations") + return r.(PortAssociationPage).ExtractIntoSlicePtr(v, "port_associations") } // CreatePortAssociationResult represents the result of a create operation. Call its Extract diff --git a/openstack/networking/v2/extensions/layer3/floatingips/results.go b/openstack/networking/v2/extensions/layer3/floatingips/results.go index 7ea6160032..89fd5cf9cd 100644 --- a/openstack/networking/v2/extensions/layer3/floatingips/results.go +++ b/openstack/networking/v2/extensions/layer3/floatingips/results.go @@ -111,7 +111,7 @@ func (r commonResult) Extract() (*FloatingIP, error) { } func (r commonResult) ExtractInto(v any) error { - return r.Result.ExtractIntoStructPtr(v, "floatingip") + return r.ExtractIntoStructPtr(v, "floatingip") } // CreateResult represents the result of a create operation. Call its Extract @@ -180,5 +180,5 @@ func ExtractFloatingIPs(r pagination.Page) ([]FloatingIP, error) { } func ExtractFloatingIPsInto(r pagination.Page, v any) error { - return r.(FloatingIPPage).Result.ExtractIntoSlicePtr(v, "floatingips") + return r.(FloatingIPPage).ExtractIntoSlicePtr(v, "floatingips") } diff --git a/openstack/networking/v2/extensions/layer3/portforwarding/results.go b/openstack/networking/v2/extensions/layer3/portforwarding/results.go index 89e71efd0e..c2ed860231 100644 --- a/openstack/networking/v2/extensions/layer3/portforwarding/results.go +++ b/openstack/networking/v2/extensions/layer3/portforwarding/results.go @@ -67,7 +67,7 @@ func (r commonResult) Extract() (*PortForwarding, error) { } func (r commonResult) ExtractInto(v any) error { - return r.Result.ExtractIntoStructPtr(v, "port_forwarding") + return r.ExtractIntoStructPtr(v, "port_forwarding") } // PortForwardingPage is the page returned by a pager when traversing over a diff --git a/openstack/networking/v2/extensions/layer3/routers/results.go b/openstack/networking/v2/extensions/layer3/routers/results.go index d657160ba2..38b3a565da 100644 --- a/openstack/networking/v2/extensions/layer3/routers/results.go +++ b/openstack/networking/v2/extensions/layer3/routers/results.go @@ -167,7 +167,7 @@ func ExtractRouters(r pagination.Page) ([]Router, error) { // ExtractRoutersInto extracts the elements into a slice of Router structs. func ExtractRoutersInto(r pagination.Page, v any) error { - return r.(RouterPage).Result.ExtractIntoSlicePtr(v, "routers") + return r.(RouterPage).ExtractIntoSlicePtr(v, "routers") } type commonResult struct { diff --git a/openstack/networking/v2/extensions/qos/policies/results.go b/openstack/networking/v2/extensions/qos/policies/results.go index c35853bac8..6a8a92a46f 100644 --- a/openstack/networking/v2/extensions/qos/policies/results.go +++ b/openstack/networking/v2/extensions/qos/policies/results.go @@ -127,5 +127,5 @@ func ExtractPolicies(r pagination.Page) ([]Policy, error) { // ExtractPoliciesInto extracts the elements into a slice of RBAC Policy structs. func ExtractPolicysInto(r pagination.Page, v any) error { - return r.(PolicyPage).Result.ExtractIntoSlicePtr(v, "policies") + return r.(PolicyPage).ExtractIntoSlicePtr(v, "policies") } diff --git a/openstack/networking/v2/extensions/qos/rules/results.go b/openstack/networking/v2/extensions/qos/rules/results.go index cb2ee24887..241e8f800b 100644 --- a/openstack/networking/v2/extensions/qos/rules/results.go +++ b/openstack/networking/v2/extensions/qos/rules/results.go @@ -88,7 +88,7 @@ func ExtractBandwidthLimitRules(r pagination.Page) ([]BandwidthLimitRule, error) // ExtractBandwidthLimitRulesInto extracts the elements into a slice of RBAC Policy structs. func ExtractBandwidthLimitRulesInto(r pagination.Page, v any) error { - return r.(BandwidthLimitRulePage).Result.ExtractIntoSlicePtr(v, "bandwidth_limit_rules") + return r.(BandwidthLimitRulePage).ExtractIntoSlicePtr(v, "bandwidth_limit_rules") } // Extract is a function that accepts a result and extracts a DSCPMarkingRule. @@ -164,7 +164,7 @@ func ExtractDSCPMarkingRules(r pagination.Page) ([]DSCPMarkingRule, error) { // ExtractDSCPMarkingRulesInto extracts the elements into a slice of RBAC Policy structs. func ExtractDSCPMarkingRulesInto(r pagination.Page, v any) error { - return r.(DSCPMarkingRulePage).Result.ExtractIntoSlicePtr(v, "dscp_marking_rules") + return r.(DSCPMarkingRulePage).ExtractIntoSlicePtr(v, "dscp_marking_rules") } // Extract is a function that accepts a result and extracts a BandwidthLimitRule. @@ -243,5 +243,5 @@ func ExtractMinimumBandwidthRules(r pagination.Page) ([]MinimumBandwidthRule, er // ExtractMinimumBandwidthRulesInto extracts the elements into a slice of RBAC Policy structs. func ExtractMinimumBandwidthRulesInto(r pagination.Page, v any) error { - return r.(MinimumBandwidthRulePage).Result.ExtractIntoSlicePtr(v, "minimum_bandwidth_rules") + return r.(MinimumBandwidthRulePage).ExtractIntoSlicePtr(v, "minimum_bandwidth_rules") } diff --git a/openstack/networking/v2/extensions/rbacpolicies/results.go b/openstack/networking/v2/extensions/rbacpolicies/results.go index abbd044b91..9550b8d15b 100644 --- a/openstack/networking/v2/extensions/rbacpolicies/results.go +++ b/openstack/networking/v2/extensions/rbacpolicies/results.go @@ -17,7 +17,7 @@ func (r commonResult) Extract() (*RBACPolicy, error) { } func (r commonResult) ExtractInto(v any) error { - return r.Result.ExtractIntoStructPtr(v, "rbac_policy") + return r.ExtractIntoStructPtr(v, "rbac_policy") } // CreateResult represents the result of a create operation. Call its Extract @@ -101,5 +101,5 @@ func ExtractRBACPolicies(r pagination.Page) ([]RBACPolicy, error) { // ExtractRBACPolicesInto extracts the elements into a slice of RBAC Policy structs. func ExtractRBACPolicesInto(r pagination.Page, v any) error { - return r.(RBACPolicyPage).Result.ExtractIntoSlicePtr(v, "rbac_policies") + return r.(RBACPolicyPage).ExtractIntoSlicePtr(v, "rbac_policies") } diff --git a/openstack/networking/v2/extensions/trunk_details/testing/requests_test.go b/openstack/networking/v2/extensions/trunk_details/testing/requests_test.go index fdbd4329f2..f9f3c74ab7 100644 --- a/openstack/networking/v2/extensions/trunk_details/testing/requests_test.go +++ b/openstack/networking/v2/extensions/trunk_details/testing/requests_test.go @@ -35,9 +35,9 @@ func TestServerWithUsageExt(t *testing.T) { err := ports.Get(context.TODO(), client.ServiceClient(fakeServer), portIDFixture).ExtractInto(&portExt) th.AssertNoErr(t, err) - th.AssertEquals(t, portExt.TrunkDetails.TrunkID, "f170c831-8c55-4ceb-ad13-75eab4a121e5") - th.AssertEquals(t, len(portExt.TrunkDetails.SubPorts), 1) - subPort := portExt.TrunkDetails.SubPorts[0] + th.AssertEquals(t, portExt.TrunkID, "f170c831-8c55-4ceb-ad13-75eab4a121e5") + th.AssertEquals(t, len(portExt.SubPorts), 1) + subPort := portExt.SubPorts[0] th.AssertEquals(t, subPort.SegmentationID, 100) th.AssertEquals(t, subPort.SegmentationType, "vlan") th.AssertEquals(t, subPort.PortID, "20c673d8-7f9d-4570-b662-148d9ddcc5bd") diff --git a/openstack/networking/v2/networks/results.go b/openstack/networking/v2/networks/results.go index 53927bf0c0..d4b97c1a20 100644 --- a/openstack/networking/v2/networks/results.go +++ b/openstack/networking/v2/networks/results.go @@ -20,7 +20,7 @@ func (r commonResult) Extract() (*Network, error) { } func (r commonResult) ExtractInto(v any) error { - return r.Result.ExtractIntoStructPtr(v, "network") + return r.ExtractIntoStructPtr(v, "network") } // CreateResult represents the result of a create operation. Call its Extract @@ -173,5 +173,5 @@ func ExtractNetworks(r pagination.Page) ([]Network, error) { } func ExtractNetworksInto(r pagination.Page, v any) error { - return r.(NetworkPage).Result.ExtractIntoSlicePtr(v, "networks") + return r.(NetworkPage).ExtractIntoSlicePtr(v, "networks") } diff --git a/openstack/networking/v2/ports/results.go b/openstack/networking/v2/ports/results.go index db223d48c1..83cc941389 100644 --- a/openstack/networking/v2/ports/results.go +++ b/openstack/networking/v2/ports/results.go @@ -20,7 +20,7 @@ func (r commonResult) Extract() (*Port, error) { } func (r commonResult) ExtractInto(v any) error { - return r.Result.ExtractIntoStructPtr(v, "port") + return r.ExtractIntoStructPtr(v, "port") } // CreateResult represents the result of a create operation. Call its Extract @@ -202,5 +202,5 @@ func ExtractPorts(r pagination.Page) ([]Port, error) { } func ExtractPortsInto(r pagination.Page, v any) error { - return r.(PortPage).Result.ExtractIntoSlicePtr(v, "ports") + return r.(PortPage).ExtractIntoSlicePtr(v, "ports") } diff --git a/openstack/objectstorage/v1/containers/requests.go b/openstack/objectstorage/v1/containers/requests.go index f4714d6ff6..2d00b659ca 100644 --- a/openstack/objectstorage/v1/containers/requests.go +++ b/openstack/objectstorage/v1/containers/requests.go @@ -54,7 +54,7 @@ func List(c *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { pager := pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page { p := ContainerPage{pagination.MarkerPageBase{PageResult: r}} - p.MarkerPageBase.Owner = p + p.Owner = p return p }) pager.Headers = headers diff --git a/openstack/objectstorage/v1/objects/requests.go b/openstack/objectstorage/v1/objects/requests.go index abc56f4773..464f94eeb7 100644 --- a/openstack/objectstorage/v1/objects/requests.go +++ b/openstack/objectstorage/v1/objects/requests.go @@ -91,7 +91,7 @@ func List(c *gophercloud.ServiceClient, containerName string, opts ListOptsBuild pager := pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page { p := ObjectPage{pagination.MarkerPageBase{PageResult: r}} - p.MarkerPageBase.Owner = p + p.Owner = p return p }) pager.Headers = headers diff --git a/openstack/objectstorage/v1/objects/results.go b/openstack/objectstorage/v1/objects/results.go index e98c542960..d7849e9ecb 100644 --- a/openstack/objectstorage/v1/objects/results.go +++ b/openstack/objectstorage/v1/objects/results.go @@ -496,7 +496,7 @@ func extractLastMarker(r pagination.Page) (string, error) { casted := r.(ObjectPage) // If a delimiter was requested, check if a subdir exists. - queryParams, err := url.ParseQuery(casted.URL.RawQuery) + queryParams, err := url.ParseQuery(casted.RawQuery) if err != nil { return "", err } diff --git a/openstack/orchestration/v1/stackevents/requests.go b/openstack/orchestration/v1/stackevents/requests.go index 71836e0541..7166387ec0 100644 --- a/openstack/orchestration/v1/stackevents/requests.go +++ b/openstack/orchestration/v1/stackevents/requests.go @@ -116,7 +116,7 @@ func List(client *gophercloud.ServiceClient, stackName, stackID string, opts Lis } return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { p := EventPage{pagination.MarkerPageBase{PageResult: r}} - p.MarkerPageBase.Owner = p + p.Owner = p return p }) } @@ -173,7 +173,7 @@ func ListResourceEvents(client *gophercloud.ServiceClient, stackName, stackID, r } return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { p := EventPage{pagination.MarkerPageBase{PageResult: r}} - p.MarkerPageBase.Owner = p + p.Owner = p return p }) } diff --git a/openstack/sharedfilesystems/v2/replicas/requests.go b/openstack/sharedfilesystems/v2/replicas/requests.go index 415e67b37d..6e29fd783c 100644 --- a/openstack/sharedfilesystems/v2/replicas/requests.go +++ b/openstack/sharedfilesystems/v2/replicas/requests.go @@ -90,7 +90,7 @@ func List(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pa return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { p := ReplicaPage{pagination.MarkerPageBase{PageResult: r}} - p.MarkerPageBase.Owner = p + p.Owner = p return p }) } @@ -108,7 +108,7 @@ func ListDetail(client *gophercloud.ServiceClient, opts ListOptsBuilder) paginat return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { p := ReplicaPage{pagination.MarkerPageBase{PageResult: r}} - p.MarkerPageBase.Owner = p + p.Owner = p return p }) } diff --git a/openstack/sharedfilesystems/v2/replicas/results.go b/openstack/sharedfilesystems/v2/replicas/results.go index 7b75117747..8de27928f4 100644 --- a/openstack/sharedfilesystems/v2/replicas/results.go +++ b/openstack/sharedfilesystems/v2/replicas/results.go @@ -109,7 +109,7 @@ func (r ReplicaPage) LastMarker() (string, error) { return invalidMarker, nil } - u, err := url.Parse(r.URL.String()) + u, err := url.Parse(r.String()) if err != nil { return invalidMarker, err } @@ -160,7 +160,7 @@ func ExtractReplicas(r pagination.Page) ([]Replica, error) { // ExtractReplicasInto similar to ExtractReplicas but operates on a `list` of // replicas. func ExtractReplicasInto(r pagination.Page, v any) error { - return r.(ReplicaPage).Result.ExtractIntoSlicePtr(v, "share_replicas") + return r.(ReplicaPage).ExtractIntoSlicePtr(v, "share_replicas") } // DeleteResult contains the response body and error from a Delete request. diff --git a/openstack/sharedfilesystems/v2/sharenetworks/requests.go b/openstack/sharedfilesystems/v2/sharenetworks/requests.go index 6df73b5eed..c340e3ed43 100644 --- a/openstack/sharedfilesystems/v2/sharenetworks/requests.go +++ b/openstack/sharedfilesystems/v2/sharenetworks/requests.go @@ -116,7 +116,7 @@ func ListDetail(client *gophercloud.ServiceClient, opts ListOptsBuilder) paginat return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { p := ShareNetworkPage{pagination.MarkerPageBase{PageResult: r}} - p.MarkerPageBase.Owner = p + p.Owner = p return p }) } diff --git a/openstack/sharedfilesystems/v2/sharenetworks/results.go b/openstack/sharedfilesystems/v2/sharenetworks/results.go index 5d3537c007..6ffbae151e 100644 --- a/openstack/sharedfilesystems/v2/sharenetworks/results.go +++ b/openstack/sharedfilesystems/v2/sharenetworks/results.go @@ -94,7 +94,7 @@ func (r ShareNetworkPage) LastMarker() (string, error) { return maxInt, nil } - u, err := url.Parse(r.URL.String()) + u, err := url.Parse(r.String()) if err != nil { return maxInt, err } diff --git a/openstack/sharedfilesystems/v2/shares/requests.go b/openstack/sharedfilesystems/v2/shares/requests.go index 5d680a642b..4cf7621331 100644 --- a/openstack/sharedfilesystems/v2/shares/requests.go +++ b/openstack/sharedfilesystems/v2/shares/requests.go @@ -181,7 +181,7 @@ func ListDetail(client *gophercloud.ServiceClient, opts ListOptsBuilder) paginat return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { p := SharePage{pagination.MarkerPageBase{PageResult: r}} - p.MarkerPageBase.Owner = p + p.Owner = p return p }) } diff --git a/openstack/sharedfilesystems/v2/shares/results.go b/openstack/sharedfilesystems/v2/shares/results.go index 7c1b621327..650b9c3262 100644 --- a/openstack/sharedfilesystems/v2/shares/results.go +++ b/openstack/sharedfilesystems/v2/shares/results.go @@ -148,7 +148,7 @@ func (r SharePage) LastMarker() (string, error) { return invalidMarker, nil } - u, err := url.Parse(r.URL.String()) + u, err := url.Parse(r.String()) if err != nil { return invalidMarker, err } diff --git a/openstack/sharedfilesystems/v2/sharetransfers/requests.go b/openstack/sharedfilesystems/v2/sharetransfers/requests.go index 88b1950eb2..dd06d01f36 100644 --- a/openstack/sharedfilesystems/v2/sharetransfers/requests.go +++ b/openstack/sharedfilesystems/v2/sharetransfers/requests.go @@ -144,7 +144,7 @@ func List(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pa return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { p := TransferPage{pagination.MarkerPageBase{PageResult: r}} - p.MarkerPageBase.Owner = p + p.Owner = p return p }) } @@ -163,7 +163,7 @@ func ListDetail(client *gophercloud.ServiceClient, opts ListOptsBuilder) paginat return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { p := TransferPage{pagination.MarkerPageBase{PageResult: r}} - p.MarkerPageBase.Owner = p + p.Owner = p return p }) } diff --git a/openstack/sharedfilesystems/v2/sharetransfers/results.go b/openstack/sharedfilesystems/v2/sharetransfers/results.go index 264951383d..faa65b1903 100644 --- a/openstack/sharedfilesystems/v2/sharetransfers/results.go +++ b/openstack/sharedfilesystems/v2/sharetransfers/results.go @@ -62,7 +62,7 @@ func (r commonResult) Extract() (*Transfer, error) { // ExtractInto converts our response data into a transfer struct. func (r commonResult) ExtractInto(v any) error { - return r.Result.ExtractIntoStructPtr(v, "transfer") + return r.ExtractIntoStructPtr(v, "transfer") } // CreateResult contains the response body and error from a Create request. @@ -94,7 +94,7 @@ func ExtractTransfers(r pagination.Page) ([]Transfer, error) { // ExtractTransfersInto similar to ExtractInto but operates on a `list` of transfers func ExtractTransfersInto(r pagination.Page, v any) error { - return r.(TransferPage).Result.ExtractIntoSlicePtr(v, "transfers") + return r.(TransferPage).ExtractIntoSlicePtr(v, "transfers") } // TransferPage is a pagination.pager that is returned from a call to the List function. @@ -129,7 +129,7 @@ func (r TransferPage) LastMarker() (string, error) { return invalidMarker, nil } - u, err := url.Parse(r.URL.String()) + u, err := url.Parse(r.String()) if err != nil { return invalidMarker, err } diff --git a/openstack/sharedfilesystems/v2/snapshots/requests.go b/openstack/sharedfilesystems/v2/snapshots/requests.go index db043f1131..7b61dc4260 100644 --- a/openstack/sharedfilesystems/v2/snapshots/requests.go +++ b/openstack/sharedfilesystems/v2/snapshots/requests.go @@ -110,7 +110,7 @@ func ListDetail(client *gophercloud.ServiceClient, opts ListOptsBuilder) paginat return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { p := SnapshotPage{pagination.MarkerPageBase{PageResult: r}} - p.MarkerPageBase.Owner = p + p.Owner = p return p }) } diff --git a/openstack/sharedfilesystems/v2/snapshots/results.go b/openstack/sharedfilesystems/v2/snapshots/results.go index 9cd1b65236..e780c8f73c 100644 --- a/openstack/sharedfilesystems/v2/snapshots/results.go +++ b/openstack/sharedfilesystems/v2/snapshots/results.go @@ -107,7 +107,7 @@ func (r SnapshotPage) LastMarker() (string, error) { return invalidMarker, nil } - u, err := url.Parse(r.URL.String()) + u, err := url.Parse(r.String()) if err != nil { return invalidMarker, err } diff --git a/pagination/testing/marker_test.go b/pagination/testing/marker_test.go index 4c9441f370..a17d8687d3 100644 --- a/pagination/testing/marker_test.go +++ b/pagination/testing/marker_test.go @@ -61,7 +61,7 @@ func createMarkerPaged(t *testing.T, fakeServer th.FakeServer) pagination.Pager createPage := func(r pagination.PageResult) pagination.Page { p := MarkerPageResult{pagination.MarkerPageBase{PageResult: r}} - p.MarkerPageBase.Owner = p + p.Owner = p return p } From b1d6b71bf8207c21f14e531d96127630d2577e20 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Fri, 16 May 2025 11:42:35 +0100 Subject: [PATCH 255/353] lint: Prefer fmt.Fprintf over fmt.Fprint(..., fmt.Sprintf(...)) Signed-off-by: Stephen Finucane --- .golangci.yaml | 3 --- .../networking/v2/extensions/dns/testing/fixtures_test.go | 4 ++-- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/.golangci.yaml b/.golangci.yaml index 6469415c8c..a0fe9b2006 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -15,9 +15,6 @@ linters: - legacy - std-error-handling rules: - - linters: - - staticcheck - text: "S1038: should use fmt.Fprintf instead of fmt.Fprint" - linters: - staticcheck text: "SA1019: (x509.EncryptPEMBlock|strings.Title)" diff --git a/openstack/networking/v2/extensions/dns/testing/fixtures_test.go b/openstack/networking/v2/extensions/dns/testing/fixtures_test.go index 5f3dbd9935..f09a1033c6 100644 --- a/openstack/networking/v2/extensions/dns/testing/fixtures_test.go +++ b/openstack/networking/v2/extensions/dns/testing/fixtures_test.go @@ -241,7 +241,7 @@ func FloatingIPHandleGet(t *testing.T, fakeServer th.FakeServer) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprint(w, fmt.Sprintf(`{"floatingip": %s}`, floatingiptest.FipDNS)) + fmt.Fprintf(w, `{"floatingip": %s}`, floatingiptest.FipDNS) }) } @@ -264,7 +264,7 @@ func FloatingIPHandleCreate(t *testing.T, fakeServer th.FakeServer) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprint(w, fmt.Sprintf(`{"floatingip": %s}`, floatingiptest.FipDNS)) + fmt.Fprintf(w, `{"floatingip": %s}`, floatingiptest.FipDNS) }) } From 374f756529d75fae4880ea60f957fd4010de81aa Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Fri, 16 May 2025 11:48:11 +0100 Subject: [PATCH 256/353] lint: Use lowercase error strings More sed, along with some manual fixups. sed -i 's/fmt.Errorf("\([A-Z]\)/fmt.Errorf("\L\1/' \ $(ag 'fmt.Errorf\("[A-Z]' -l) sed -i 's/fmt.Errorf("\(.*\)\.")/fmt.Errorf("\1")/' \ $(ag 'fmt.Errorf\(' -l) sed -i 's/errors.New("\([A-Z]\)/errors.New("\L\1/' \ $(ag 'errors.New\("[A-Z]' -l) sed -i 's/errors.New("\(.*\)\.")/errors.New("\1")/' \ $(ag 'errors.New\(' -l) (yes, that could have a one-liner but $complexity) Signed-off-by: Stephen Finucane --- .golangci.yaml | 6 ------ docs/FAQ.md | 2 +- internal/acceptance/clients/clients.go | 6 ++---- .../openstack/blockstorage/v2/blockstorage.go | 4 ++-- .../openstack/blockstorage/v3/blockstorage.go | 4 ++-- .../blockstorage/v3/volumeattachments.go | 2 +- .../openstack/compute/v2/aggregates_test.go | 2 +- .../acceptance/openstack/compute/v2/compute.go | 4 ++-- .../openstack/compute/v2/hypervisors_test.go | 2 +- .../openstack/compute/v2/quotaset_test.go | 4 ++-- .../openstack/container/v1/capsules.go | 4 ++-- .../containerinfra/v1/containerinfra.go | 2 +- internal/acceptance/openstack/db/v1/db.go | 2 +- .../openstack/keymanager/v1/keymanager.go | 4 ++-- .../openstack/loadbalancer/v2/loadbalancer.go | 18 +++++++++--------- .../orchestration/v1/orchestration.go | 2 +- .../openstack/sharedfilesystems/v2/replicas.go | 8 ++++---- .../openstack/sharedfilesystems/v2/shares.go | 8 ++++---- .../sharedfilesystems/v2/snapshots.go | 4 ++-- .../openstack/workflow/v2/execution.go | 2 +- openstack/baremetal/httpbasic/requests.go | 2 +- .../httpbasic/testing/requests_test.go | 2 +- openstack/baremetal/inventory/plugindata.go | 2 +- .../httpbasic/requests.go | 2 +- .../httpbasic/testing/requests_test.go | 2 +- openstack/blockstorage/noauth/requests.go | 2 +- .../v2/quotasets/testing/requests_test.go | 2 +- .../v3/quotasets/testing/requests_test.go | 2 +- openstack/client.go | 4 ++-- openstack/compute/v2/hypervisors/results.go | 6 +++--- .../v2/quotasets/testing/requests_test.go | 2 +- openstack/compute/v2/servers/results.go | 6 +++--- openstack/container/v1/capsules/results.go | 2 +- openstack/identity/v3/users/results.go | 4 ++-- .../v2/imagedata/testing/requests_test.go | 2 +- openstack/image/v2/images/results.go | 2 +- .../networking/v2/extensions/quotas/results.go | 2 +- .../objectstorage/v1/containers/results.go | 2 +- openstack/objectstorage/v1/objects/results.go | 4 ++-- .../sharedfilesystems/v2/errors/errors.go | 2 +- openstack/utils/choose_version.go | 6 +++--- pagination/pager.go | 2 +- params.go | 12 ++++++------ results.go | 16 ++++++++-------- testing/provider_client_test.go | 2 +- testing/util_test.go | 6 +++--- 46 files changed, 90 insertions(+), 98 deletions(-) diff --git a/.golangci.yaml b/.golangci.yaml index a0fe9b2006..b138f3161c 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -18,12 +18,6 @@ linters: - linters: - staticcheck text: "SA1019: (x509.EncryptPEMBlock|strings.Title)" - - linters: - - staticcheck - text: "ST1005: error strings should not be capitalized" - - linters: - - staticcheck - text: "ST1005: error strings should not end with punctuation or newlines" - path: (.+)\.go$ text: SA1006 paths: diff --git a/docs/FAQ.md b/docs/FAQ.md index bc42ae6cbb..bfd0bc7bc8 100644 --- a/docs/FAQ.md +++ b/docs/FAQ.md @@ -41,7 +41,7 @@ func (lrt *LogRoundTripper) RoundTrip(request *http.Request) (*http.Response, er if response.StatusCode == http.StatusUnauthorized { if lrt.numReauthAttempts == 3 { - return response, fmt.Errorf("Tried to re-authenticate 3 times with no success.") + return response, fmt.Errorf("tried to re-authenticate 3 times with no success") } lrt.numReauthAttempts++ } diff --git a/internal/acceptance/clients/clients.go b/internal/acceptance/clients/clients.go index f981ffcea2..6c36391488 100644 --- a/internal/acceptance/clients/clients.go +++ b/internal/acceptance/clients/clients.go @@ -108,13 +108,11 @@ func AcceptanceTestChoicesFromEnv() (*AcceptanceTestChoices, error) { } if len(missing) > 0 { - text := "You're missing some important setup:\n * These environment variables must be provided: %s\n" - return nil, fmt.Errorf(text, strings.Join(missing, ", ")) + return nil, fmt.Errorf("you're missing some important setup:\n * These environment variables must be provided: %s", strings.Join(missing, ", ")) } if notDistinct != "" { - text := "You're missing some important setup:\n * %s\n" - return nil, fmt.Errorf(text, notDistinct) + return nil, fmt.Errorf("you're missing some important setup:\n * %s", notDistinct) } return &AcceptanceTestChoices{ diff --git a/internal/acceptance/openstack/blockstorage/v2/blockstorage.go b/internal/acceptance/openstack/blockstorage/v2/blockstorage.go index 9c22a2a4f8..f920a615c1 100644 --- a/internal/acceptance/openstack/blockstorage/v2/blockstorage.go +++ b/internal/acceptance/openstack/blockstorage/v2/blockstorage.go @@ -455,7 +455,7 @@ func SetBootable(t *testing.T, client *gophercloud.ServiceClient, volume *volume } if strings.ToLower(vol.Bootable) != "true" { - return fmt.Errorf("Volume bootable status is %q, expected 'true'", vol.Bootable) + return fmt.Errorf("volume bootable status is %q, expected 'true'", vol.Bootable) } bootableOpts = volumes.BootableOpts{ @@ -473,7 +473,7 @@ func SetBootable(t *testing.T, client *gophercloud.ServiceClient, volume *volume } if strings.ToLower(vol.Bootable) == "true" { - return fmt.Errorf("Volume bootable status is %q, expected 'false'", vol.Bootable) + return fmt.Errorf("volume bootable status is %q, expected 'false'", vol.Bootable) } return nil diff --git a/internal/acceptance/openstack/blockstorage/v3/blockstorage.go b/internal/acceptance/openstack/blockstorage/v3/blockstorage.go index 23236097c7..ecf7266d98 100644 --- a/internal/acceptance/openstack/blockstorage/v3/blockstorage.go +++ b/internal/acceptance/openstack/blockstorage/v3/blockstorage.go @@ -673,7 +673,7 @@ func SetBootable(t *testing.T, client *gophercloud.ServiceClient, volume *volume } if strings.ToLower(vol.Bootable) != "true" { - return fmt.Errorf("Volume bootable status is %q, expected 'true'", vol.Bootable) + return fmt.Errorf("volume bootable status is %q, expected 'true'", vol.Bootable) } bootableOpts = volumes.BootableOpts{ @@ -691,7 +691,7 @@ func SetBootable(t *testing.T, client *gophercloud.ServiceClient, volume *volume } if strings.ToLower(vol.Bootable) == "true" { - return fmt.Errorf("Volume bootable status is %q, expected 'false'", vol.Bootable) + return fmt.Errorf("volume bootable status is %q, expected 'false'", vol.Bootable) } return nil diff --git a/internal/acceptance/openstack/blockstorage/v3/volumeattachments.go b/internal/acceptance/openstack/blockstorage/v3/volumeattachments.go index 4bd531a856..ce47111e85 100644 --- a/internal/acceptance/openstack/blockstorage/v3/volumeattachments.go +++ b/internal/acceptance/openstack/blockstorage/v3/volumeattachments.go @@ -72,7 +72,7 @@ func CreateVolumeAttachment(t *testing.T, client *gophercloud.ServiceClient, vol } if allAttachments[0].ID != attachment.ID { - return fmt.Errorf("Attachment IDs from get and list are not equal: %q != %q", allAttachments[0].ID, attachment.ID) + return fmt.Errorf("attachment IDs from get and list are not equal: %q != %q", allAttachments[0].ID, attachment.ID) } t.Logf("Attached volume %s to server %s within %q attachment", volume.ID, server.ID, attachment.ID) diff --git a/internal/acceptance/openstack/compute/v2/aggregates_test.go b/internal/acceptance/openstack/compute/v2/aggregates_test.go index 88ac3a3365..2bc2ec7273 100644 --- a/internal/acceptance/openstack/compute/v2/aggregates_test.go +++ b/internal/acceptance/openstack/compute/v2/aggregates_test.go @@ -146,5 +146,5 @@ func getHypervisor(t *testing.T, client *gophercloud.ServiceClient) (string, err return host, nil } - return "", fmt.Errorf("Unable to get hypervisor") + return "", fmt.Errorf("unable to get hypervisor") } diff --git a/internal/acceptance/openstack/compute/v2/compute.go b/internal/acceptance/openstack/compute/v2/compute.go index 4a5ec655a2..0145c98558 100644 --- a/internal/acceptance/openstack/compute/v2/compute.go +++ b/internal/acceptance/openstack/compute/v2/compute.go @@ -890,7 +890,7 @@ func GetNetworkIDFromNetworks(t *testing.T, client *gophercloud.ServiceClient, n } } - return "", fmt.Errorf("Failed to obtain network ID for network %s", networkName) + return "", fmt.Errorf("failed to obtain network ID for network %s", networkName) } // ImportPublicKey will create a KeyPair with a random name and a specified @@ -954,7 +954,7 @@ func WaitForComputeStatus(client *gophercloud.ServiceClient, server *servers.Ser } if latest.Status == "ERROR" { - return false, fmt.Errorf("Instance in ERROR state") + return false, fmt.Errorf("instance in ERROR state") } return false, nil diff --git a/internal/acceptance/openstack/compute/v2/hypervisors_test.go b/internal/acceptance/openstack/compute/v2/hypervisors_test.go index dae1bbcdbc..861fa7e02c 100644 --- a/internal/acceptance/openstack/compute/v2/hypervisors_test.go +++ b/internal/acceptance/openstack/compute/v2/hypervisors_test.go @@ -121,5 +121,5 @@ func getHypervisorID(t *testing.T, client *gophercloud.ServiceClient) (string, e return allHypervisors[0].ID, nil } - return "", fmt.Errorf("Unable to get hypervisor ID") + return "", fmt.Errorf("unable to get hypervisor ID") } diff --git a/internal/acceptance/openstack/compute/v2/quotaset_test.go b/internal/acceptance/openstack/compute/v2/quotaset_test.go index 53d94b538e..d2da0c4193 100644 --- a/internal/acceptance/openstack/compute/v2/quotaset_test.go +++ b/internal/acceptance/openstack/compute/v2/quotaset_test.go @@ -45,7 +45,7 @@ func getProjectID(t *testing.T, client *gophercloud.ServiceClient) (string, erro return project.ID, nil } - return "", fmt.Errorf("Unable to get project ID") + return "", fmt.Errorf("unable to get project ID") } func getProjectIDByName(t *testing.T, client *gophercloud.ServiceClient, name string) (string, error) { @@ -61,7 +61,7 @@ func getProjectIDByName(t *testing.T, client *gophercloud.ServiceClient, name st } } - return "", fmt.Errorf("Unable to get project ID") + return "", fmt.Errorf("unable to get project ID") } // What will be sent as desired Quotas to the Server diff --git a/internal/acceptance/openstack/container/v1/capsules.go b/internal/acceptance/openstack/container/v1/capsules.go index b4f48fc903..6ad33c0c6d 100644 --- a/internal/acceptance/openstack/container/v1/capsules.go +++ b/internal/acceptance/openstack/container/v1/capsules.go @@ -36,11 +36,11 @@ func WaitForCapsuleStatus(client *gophercloud.ServiceClient, uuid, status string } if newStatus == "Failed" { - return false, fmt.Errorf("Capsule in FAILED state") + return false, fmt.Errorf("capsule in FAILED state") } if newStatus == "Error" { - return false, fmt.Errorf("Capsule in ERROR state") + return false, fmt.Errorf("capsule in ERROR state") } return false, nil diff --git a/internal/acceptance/openstack/containerinfra/v1/containerinfra.go b/internal/acceptance/openstack/containerinfra/v1/containerinfra.go index 84ee98e87d..24f8c1959b 100644 --- a/internal/acceptance/openstack/containerinfra/v1/containerinfra.go +++ b/internal/acceptance/openstack/containerinfra/v1/containerinfra.go @@ -203,7 +203,7 @@ func WaitForCluster(client *gophercloud.ServiceClient, clusterID string, status } if strings.Contains(cluster.Status, "FAILED") { - return false, fmt.Errorf("Cluster %s FAILED. Status=%s StatusReason=%s", clusterID, cluster.Status, cluster.StatusReason) + return false, fmt.Errorf("cluster %s FAILED. Status=%s StatusReason=%s", clusterID, cluster.Status, cluster.StatusReason) } return false, nil diff --git a/internal/acceptance/openstack/db/v1/db.go b/internal/acceptance/openstack/db/v1/db.go index abc92553a0..fe529a0133 100644 --- a/internal/acceptance/openstack/db/v1/db.go +++ b/internal/acceptance/openstack/db/v1/db.go @@ -138,7 +138,7 @@ func WaitForInstanceStatus( } if latest.Status == "ERROR" { - return false, fmt.Errorf("Instance in ERROR state") + return false, fmt.Errorf("instance in ERROR state") } return false, nil diff --git a/internal/acceptance/openstack/keymanager/v1/keymanager.go b/internal/acceptance/openstack/keymanager/v1/keymanager.go index a44b57a4bf..87a965eb5c 100644 --- a/internal/acceptance/openstack/keymanager/v1/keymanager.go +++ b/internal/acceptance/openstack/keymanager/v1/keymanager.go @@ -646,7 +646,7 @@ func DeleteSecret(t *testing.T, client *gophercloud.ServiceClient, id string) { func ParseID(ref string) (string, error) { parts := strings.Split(ref, "/") if len(parts) < 2 { - return "", fmt.Errorf("Could not parse %s", ref) + return "", fmt.Errorf("could not parse %s", ref) } return parts[len(parts)-1], nil @@ -757,7 +757,7 @@ func WaitForOrder(client *gophercloud.ServiceClient, orderID string) error { } if order.Status == "ERROR" { - return false, fmt.Errorf("Order %s in ERROR state", orderID) + return false, fmt.Errorf("order %s in ERROR state", orderID) } return false, nil diff --git a/internal/acceptance/openstack/loadbalancer/v2/loadbalancer.go b/internal/acceptance/openstack/loadbalancer/v2/loadbalancer.go index db067a81c1..5691d47263 100644 --- a/internal/acceptance/openstack/loadbalancer/v2/loadbalancer.go +++ b/internal/acceptance/openstack/loadbalancer/v2/loadbalancer.go @@ -46,7 +46,7 @@ func CreateListener(t *testing.T, client *gophercloud.ServiceClient, lb *loadbal t.Logf("Successfully created listener %s", listenerName) if err := WaitForLoadBalancerState(client, lb.ID, "ACTIVE"); err != nil { - return listener, fmt.Errorf("Timed out waiting for loadbalancer to become active: %s", err) + return listener, fmt.Errorf("timed out waiting for loadbalancer to become active: %s", err) } th.AssertEquals(t, listener.Name, listenerName) @@ -98,7 +98,7 @@ func CreateListenerHTTP(t *testing.T, client *gophercloud.ServiceClient, lb *loa t.Logf("Successfully created listener %s", listenerName) if err := WaitForLoadBalancerState(client, lb.ID, "ACTIVE"); err != nil { - return listener, fmt.Errorf("Timed out waiting for loadbalancer to become active: %s", err) + return listener, fmt.Errorf("timed out waiting for loadbalancer to become active: %s", err) } th.AssertEquals(t, listener.Name, listenerName) @@ -317,7 +317,7 @@ func CreateMember(t *testing.T, client *gophercloud.ServiceClient, lb *loadbalan t.Logf("Successfully created member %s", memberName) if err := WaitForLoadBalancerState(client, lb.ID, "ACTIVE"); err != nil { - return member, fmt.Errorf("Timed out waiting for loadbalancer to become active: %s", err) + return member, fmt.Errorf("timed out waiting for loadbalancer to become active: %s", err) } th.AssertEquals(t, member.Name, memberName) @@ -351,7 +351,7 @@ func CreateMonitor(t *testing.T, client *gophercloud.ServiceClient, lb *loadbala t.Logf("Successfully created monitor: %s", monitorName) if err := WaitForLoadBalancerState(client, lb.ID, "ACTIVE"); err != nil { - return monitor, fmt.Errorf("Timed out waiting for loadbalancer to become active: %s", err) + return monitor, fmt.Errorf("timed out waiting for loadbalancer to become active: %s", err) } th.AssertEquals(t, monitor.Name, monitorName) @@ -390,7 +390,7 @@ func CreatePool(t *testing.T, client *gophercloud.ServiceClient, lb *loadbalance t.Logf("Successfully created pool %s", poolName) if err := WaitForLoadBalancerState(client, lb.ID, "ACTIVE"); err != nil { - return pool, fmt.Errorf("Timed out waiting for loadbalancer to become active: %s", err) + return pool, fmt.Errorf("timed out waiting for loadbalancer to become active: %s", err) } th.AssertEquals(t, pool.Name, poolName) @@ -427,7 +427,7 @@ func CreatePoolHTTP(t *testing.T, client *gophercloud.ServiceClient, lb *loadbal t.Logf("Successfully created pool %s", poolName) if err := WaitForLoadBalancerState(client, lb.ID, "ACTIVE"); err != nil { - return pool, fmt.Errorf("Timed out waiting for loadbalancer to become active: %s", err) + return pool, fmt.Errorf("timed out waiting for loadbalancer to become active: %s", err) } th.AssertEquals(t, pool.Name, poolName) @@ -465,7 +465,7 @@ func CreateL7Policy(t *testing.T, client *gophercloud.ServiceClient, listener *l t.Logf("Successfully created l7 policy %s", policyName) if err := WaitForLoadBalancerState(client, lb.ID, "ACTIVE"); err != nil { - return policy, fmt.Errorf("Timed out waiting for loadbalancer to become active: %s", err) + return policy, fmt.Errorf("timed out waiting for loadbalancer to become active: %s", err) } th.AssertEquals(t, policy.Name, policyName) @@ -497,7 +497,7 @@ func CreateL7Rule(t *testing.T, client *gophercloud.ServiceClient, policyID stri t.Logf("Successfully created l7 rule for policy %s", policyID) if err := WaitForLoadBalancerState(client, lb.ID, "ACTIVE"); err != nil { - return rule, fmt.Errorf("Timed out waiting for loadbalancer to become active: %s", err) + return rule, fmt.Errorf("timed out waiting for loadbalancer to become active: %s", err) } th.AssertEquals(t, rule.RuleType, string(l7policies.TypePath)) @@ -685,7 +685,7 @@ func WaitForLoadBalancerState(client *gophercloud.ServiceClient, lbID, status st } if current.ProvisioningStatus == "ERROR" { - return false, fmt.Errorf("Load balancer is in ERROR state") + return false, fmt.Errorf("load balancer is in ERROR state") } return false, nil diff --git a/internal/acceptance/openstack/orchestration/v1/orchestration.go b/internal/acceptance/openstack/orchestration/v1/orchestration.go index 3d45311fef..e6245ad83d 100644 --- a/internal/acceptance/openstack/orchestration/v1/orchestration.go +++ b/internal/acceptance/openstack/orchestration/v1/orchestration.go @@ -108,7 +108,7 @@ func WaitForStackStatus(client *gophercloud.ServiceClient, stackName, stackID, s } if latest.Status == "ERROR" { - return false, fmt.Errorf("Stack in ERROR state") + return false, fmt.Errorf("stack in ERROR state") } return false, nil diff --git a/internal/acceptance/openstack/sharedfilesystems/v2/replicas.go b/internal/acceptance/openstack/sharedfilesystems/v2/replicas.go index 6a2d31d08a..8a3b88815f 100644 --- a/internal/acceptance/openstack/sharedfilesystems/v2/replicas.go +++ b/internal/acceptance/openstack/sharedfilesystems/v2/replicas.go @@ -95,7 +95,7 @@ func waitForReplicaStatus(t *testing.T, c *gophercloud.ServiceClient, id, status } if strings.Contains(current.Status, "error") { - return true, fmt.Errorf("An error occurred, wrong status: %s", current.Status) + return true, fmt.Errorf("an error occurred, wrong status: %s", current.Status) } return false, nil @@ -104,7 +104,7 @@ func waitForReplicaStatus(t *testing.T, c *gophercloud.ServiceClient, id, status if err != nil { mErr := PrintMessages(t, c, id) if mErr != nil { - return fmt.Errorf("Replica status is '%s' and unable to get manila messages: %s", err, mErr) + return fmt.Errorf("replica status is '%s' and unable to get manila messages: %s", err, mErr) } } @@ -127,7 +127,7 @@ func waitForReplicaState(t *testing.T, c *gophercloud.ServiceClient, id, state s } if strings.Contains(current.State, "error") { - return true, fmt.Errorf("An error occurred, wrong state: %s", current.State) + return true, fmt.Errorf("an error occurred, wrong state: %s", current.State) } return false, nil @@ -136,7 +136,7 @@ func waitForReplicaState(t *testing.T, c *gophercloud.ServiceClient, id, state s if err != nil { mErr := PrintMessages(t, c, id) if mErr != nil { - return fmt.Errorf("Replica state is '%s' and unable to get manila messages: %s", err, mErr) + return fmt.Errorf("replica state is '%s' and unable to get manila messages: %s", err, mErr) } } diff --git a/internal/acceptance/openstack/sharedfilesystems/v2/shares.go b/internal/acceptance/openstack/sharedfilesystems/v2/shares.go index afb699627c..eacceebf1e 100644 --- a/internal/acceptance/openstack/sharedfilesystems/v2/shares.go +++ b/internal/acceptance/openstack/sharedfilesystems/v2/shares.go @@ -120,12 +120,12 @@ func PrintMessages(t *testing.T, c *gophercloud.ServiceClient, id string) error allPages, err := messages.List(c, messages.ListOpts{ResourceID: id}).AllPages(context.TODO()) if err != nil { - return fmt.Errorf("Unable to retrieve messages: %v", err) + return fmt.Errorf("unable to retrieve messages: %v", err) } allMessages, err := messages.ExtractMessages(allPages) if err != nil { - return fmt.Errorf("Unable to extract messages: %v", err) + return fmt.Errorf("unable to extract messages: %v", err) } for _, message := range allMessages { @@ -159,7 +159,7 @@ func waitForStatus(t *testing.T, c *gophercloud.ServiceClient, id, status string } if strings.Contains(current.Status, "error") { - return true, fmt.Errorf("An error occurred, wrong status: %s", current.Status) + return true, fmt.Errorf("an error occurred, wrong status: %s", current.Status) } return false, nil @@ -168,7 +168,7 @@ func waitForStatus(t *testing.T, c *gophercloud.ServiceClient, id, status string if err != nil { mErr := PrintMessages(t, c, id) if mErr != nil { - return current, fmt.Errorf("Share status is '%s' and unable to get manila messages: %s", err, mErr) + return current, fmt.Errorf("share status is '%s' and unable to get manila messages: %s", err, mErr) } } diff --git a/internal/acceptance/openstack/sharedfilesystems/v2/snapshots.go b/internal/acceptance/openstack/sharedfilesystems/v2/snapshots.go index 4fb3128f29..9c5ccb7949 100644 --- a/internal/acceptance/openstack/sharedfilesystems/v2/snapshots.go +++ b/internal/acceptance/openstack/sharedfilesystems/v2/snapshots.go @@ -90,7 +90,7 @@ func waitForSnapshotStatus(t *testing.T, c *gophercloud.ServiceClient, id, statu } if strings.Contains(current.Status, "error") { - return true, fmt.Errorf("An error occurred, wrong status: %s", current.Status) + return true, fmt.Errorf("an error occurred, wrong status: %s", current.Status) } return false, nil @@ -99,7 +99,7 @@ func waitForSnapshotStatus(t *testing.T, c *gophercloud.ServiceClient, id, statu if err != nil { mErr := PrintMessages(t, c, id) if mErr != nil { - return fmt.Errorf("Snapshot status is '%s' and unable to get manila messages: %s", err, mErr) + return fmt.Errorf("snapshot status is '%s' and unable to get manila messages: %s", err, mErr) } } diff --git a/internal/acceptance/openstack/workflow/v2/execution.go b/internal/acceptance/openstack/workflow/v2/execution.go index d2c2a71970..9a3eccaa9d 100644 --- a/internal/acceptance/openstack/workflow/v2/execution.go +++ b/internal/acceptance/openstack/workflow/v2/execution.go @@ -48,7 +48,7 @@ func CreateExecution(t *testing.T, client *gophercloud.ServiceClient, workflow * } if latest.State == "ERROR" { - return false, fmt.Errorf("Execution in ERROR state") + return false, fmt.Errorf("execution in ERROR state") } return false, nil diff --git a/openstack/baremetal/httpbasic/requests.go b/openstack/baremetal/httpbasic/requests.go index 3b13dd4637..6eb65eff14 100644 --- a/openstack/baremetal/httpbasic/requests.go +++ b/openstack/baremetal/httpbasic/requests.go @@ -20,7 +20,7 @@ func initClientOpts(client *gophercloud.ProviderClient, eo EndpointOpts) (*gophe return nil, fmt.Errorf("IronicEndpoint is required") } if eo.IronicUser == "" || eo.IronicUserPassword == "" { - return nil, fmt.Errorf("User and Password are required") + return nil, fmt.Errorf("IronicUser and IronicUserPassword are required") } token := []byte(eo.IronicUser + ":" + eo.IronicUserPassword) diff --git a/openstack/baremetal/httpbasic/testing/requests_test.go b/openstack/baremetal/httpbasic/testing/requests_test.go index d8c9faf5ba..9618a1b1df 100644 --- a/openstack/baremetal/httpbasic/testing/requests_test.go +++ b/openstack/baremetal/httpbasic/testing/requests_test.go @@ -24,7 +24,7 @@ func TestHttpBasic(t *testing.T) { IronicEndpoint: "http://ironic:6385/v1", }) _ = errTest1 - th.AssertEquals(t, "User and Password are required", err.Error()) + th.AssertEquals(t, "IronicUser and IronicUserPassword are required", err.Error()) errTest2, err := httpbasic.NewBareMetalHTTPBasic(httpbasic.EndpointOpts{ IronicUser: "myUser", diff --git a/openstack/baremetal/inventory/plugindata.go b/openstack/baremetal/inventory/plugindata.go index 3c4666eb34..4cbd8214e7 100644 --- a/openstack/baremetal/inventory/plugindata.go +++ b/openstack/baremetal/inventory/plugindata.go @@ -54,7 +54,7 @@ func (r *LLDPTLVType) UnmarshalJSON(data []byte) error { } if len(list) != 2 { - return fmt.Errorf("Invalid LLDP TLV key-value pair") + return fmt.Errorf("invalid LLDP TLV key-value pair") } fieldtype, ok := list[0].(float64) diff --git a/openstack/baremetalintrospection/httpbasic/requests.go b/openstack/baremetalintrospection/httpbasic/requests.go index 473e92c372..023ef67046 100644 --- a/openstack/baremetalintrospection/httpbasic/requests.go +++ b/openstack/baremetalintrospection/httpbasic/requests.go @@ -20,7 +20,7 @@ func initClientOpts(client *gophercloud.ProviderClient, eo EndpointOpts) (*gophe return nil, fmt.Errorf("IronicInspectorEndpoint is required") } if eo.IronicInspectorUser == "" || eo.IronicInspectorUserPassword == "" { - return nil, fmt.Errorf("User and Password are required") + return nil, fmt.Errorf("IronicInspectorUser and IronicInspectorUserPassword are required") } token := []byte(eo.IronicInspectorUser + ":" + eo.IronicInspectorUserPassword) diff --git a/openstack/baremetalintrospection/httpbasic/testing/requests_test.go b/openstack/baremetalintrospection/httpbasic/testing/requests_test.go index df091e0cc9..bceb8c5d8c 100644 --- a/openstack/baremetalintrospection/httpbasic/testing/requests_test.go +++ b/openstack/baremetalintrospection/httpbasic/testing/requests_test.go @@ -23,7 +23,7 @@ func TestNoAuth(t *testing.T) { IronicInspectorEndpoint: "http://ironic:5050/v1", }) _ = errTest1 - th.AssertEquals(t, "User and Password are required", err.Error()) + th.AssertEquals(t, "IronicInspectorUser and IronicInspectorUserPassword are required", err.Error()) errTest2, err := httpbasic.NewBareMetalIntrospectionHTTPBasic(httpbasic.EndpointOpts{ IronicInspectorUser: "myUser", diff --git a/openstack/blockstorage/noauth/requests.go b/openstack/blockstorage/noauth/requests.go index cf887553f0..e9d1a156b1 100644 --- a/openstack/blockstorage/noauth/requests.go +++ b/openstack/blockstorage/noauth/requests.go @@ -39,7 +39,7 @@ func initClientOpts(client *gophercloud.ProviderClient, eo EndpointOpts, clientT token := strings.Split(client.TokenID, ":") if len(token) != 2 { - return nil, fmt.Errorf("Malformed noauth token") + return nil, fmt.Errorf("malformed noauth token") } endpoint := fmt.Sprintf("%s%s", gophercloud.NormalizeURL(eo.CinderEndpoint), token[1]) diff --git a/openstack/blockstorage/v2/quotasets/testing/requests_test.go b/openstack/blockstorage/v2/quotasets/testing/requests_test.go index aacd86aa75..11f6288919 100644 --- a/openstack/blockstorage/v2/quotasets/testing/requests_test.go +++ b/openstack/blockstorage/v2/quotasets/testing/requests_test.go @@ -57,7 +57,7 @@ func TestPartialUpdate(t *testing.T) { type ErrorUpdateOpts quotasets.UpdateOpts func (opts ErrorUpdateOpts) ToBlockStorageQuotaUpdateMap() (map[string]any, error) { - return nil, errors.New("This is an error") + return nil, errors.New("this is an error") } func TestErrorInToBlockStorageQuotaUpdateMap(t *testing.T) { diff --git a/openstack/blockstorage/v3/quotasets/testing/requests_test.go b/openstack/blockstorage/v3/quotasets/testing/requests_test.go index c8f7bb579c..f50c5a9441 100644 --- a/openstack/blockstorage/v3/quotasets/testing/requests_test.go +++ b/openstack/blockstorage/v3/quotasets/testing/requests_test.go @@ -57,7 +57,7 @@ func TestPartialUpdate(t *testing.T) { type ErrorUpdateOpts quotasets.UpdateOpts func (opts ErrorUpdateOpts) ToBlockStorageQuotaUpdateMap() (map[string]any, error) { - return nil, errors.New("This is an error") + return nil, errors.New("this is an error") } func TestErrorInToBlockStorageQuotaUpdateMap(t *testing.T) { diff --git a/openstack/client.go b/openstack/client.go index b43938949b..a0e84a1e80 100644 --- a/openstack/client.go +++ b/openstack/client.go @@ -105,7 +105,7 @@ func Authenticate(ctx context.Context, client *gophercloud.ProviderClient, optio return v3auth(ctx, client, endpoint, &options, gophercloud.EndpointOpts{}) default: // The switch statement must be out of date from the versions list. - return fmt.Errorf("Unrecognized identity version: %s", chosen.ID) + return fmt.Errorf("unrecognized identity version: %s", chosen.ID) } } @@ -351,7 +351,7 @@ func initClientOpts(client *gophercloud.ProviderClient, eo gophercloud.EndpointO eo.ApplyDefaults(clientType) if eo.Version != 0 && eo.Version != version { - return sc, errors.New("Conflict between requested service major version and manually set version") + return sc, errors.New("conflict between requested service major version and manually set version") } eo.Version = version diff --git a/openstack/compute/v2/hypervisors/results.go b/openstack/compute/v2/hypervisors/results.go index c73f239cd6..9b337eb518 100644 --- a/openstack/compute/v2/hypervisors/results.go +++ b/openstack/compute/v2/hypervisors/results.go @@ -195,7 +195,7 @@ func (r *Hypervisor) UnmarshalJSON(b []byte) error { case float64: r.HypervisorVersion = int(t) default: - return fmt.Errorf("Hypervisor version has unexpected type: %T", t) + return fmt.Errorf("HypervisorVersion has unexpected type: %T", t) } // free_disk_gb doesn't exist after api version 2.87 @@ -206,7 +206,7 @@ func (r *Hypervisor) UnmarshalJSON(b []byte) error { case float64: r.FreeDiskGB = int(t) default: - return fmt.Errorf("Free disk GB has unexpected type: %T", t) + return fmt.Errorf("FreeDiskGB has unexpected type: %T", t) } } @@ -218,7 +218,7 @@ func (r *Hypervisor) UnmarshalJSON(b []byte) error { case float64: r.LocalGB = int(t) default: - return fmt.Errorf("Local GB has unexpected type: %T", t) + return fmt.Errorf("LocalGB has unexpected type: %T", t) } } diff --git a/openstack/compute/v2/quotasets/testing/requests_test.go b/openstack/compute/v2/quotasets/testing/requests_test.go index c46afd343d..5b17b5777d 100644 --- a/openstack/compute/v2/quotasets/testing/requests_test.go +++ b/openstack/compute/v2/quotasets/testing/requests_test.go @@ -59,7 +59,7 @@ func TestDelete(t *testing.T) { type ErrorUpdateOpts quotasets.UpdateOpts func (opts ErrorUpdateOpts) ToComputeQuotaUpdateMap() (map[string]any, error) { - return nil, errors.New("This is an error") + return nil, errors.New("this is an error") } func TestErrorInToComputeQuotaUpdateMap(t *testing.T) { diff --git a/openstack/compute/v2/servers/results.go b/openstack/compute/v2/servers/results.go index 153efb6acd..b11b9b236b 100644 --- a/openstack/compute/v2/servers/results.go +++ b/openstack/compute/v2/servers/results.go @@ -119,11 +119,11 @@ func decryptPassword(encryptedPassword string, privateKey *rsa.PrivateKey) (stri n, err := base64.StdEncoding.Decode(b64EncryptedPassword, []byte(encryptedPassword)) if err != nil { - return "", fmt.Errorf("Failed to base64 decode encrypted password: %s", err) + return "", fmt.Errorf("failed to base64 decode encrypted password: %s", err) } password, err := rsa.DecryptPKCS1v15(nil, privateKey, b64EncryptedPassword[0:n]) if err != nil { - return "", fmt.Errorf("Failed to decrypt password: %s", err) + return "", fmt.Errorf("failed to decrypt password: %s", err) } return string(password), nil @@ -159,7 +159,7 @@ func (r CreateImageResult) extractImageIDFromLocationHeader() (string, error) { imageID := path.Base(u.Path) if imageID == "." || imageID == "/" { - return "", fmt.Errorf("Failed to parse the ID of newly created image: %s", u) + return "", fmt.Errorf("failed to parse the ID of newly created image: %s", u) } return imageID, nil diff --git a/openstack/container/v1/capsules/results.go b/openstack/container/v1/capsules/results.go index c417bb2038..7c8a2fc178 100644 --- a/openstack/container/v1/capsules/results.go +++ b/openstack/container/v1/capsules/results.go @@ -258,7 +258,7 @@ func (r CapsulePage) IsEmpty() (bool, error) { return len(v) == 0, nil } - return false, fmt.Errorf("Unable to determine Capsule type") + return false, fmt.Errorf("unable to determine Capsule type") } // ExtractCapsulesBase accepts a Page struct, specifically a CapsulePage struct, diff --git a/openstack/identity/v3/users/results.go b/openstack/identity/v3/users/results.go index d9e7aaab66..18d3f46e1d 100644 --- a/openstack/identity/v3/users/results.go +++ b/openstack/identity/v3/users/results.go @@ -67,10 +67,10 @@ func (r *User) UnmarshalJSON(b []byte) error { case string: r.Enabled, err = strconv.ParseBool(t) if err != nil { - return fmt.Errorf("Failed to parse Enabled %q: %v", t, err) + return fmt.Errorf("failed to parse Enabled %q: %v", t, err) } default: - return fmt.Errorf("Unknown type for Enabled: %T (value: %v)", t, t) + return fmt.Errorf("unknown type for Enabled: %T (value: %v)", t, t) } // Collect other fields and bundle them into Extra diff --git a/openstack/image/v2/imagedata/testing/requests_test.go b/openstack/image/v2/imagedata/testing/requests_test.go index 3a5c26706c..63294a1323 100644 --- a/openstack/image/v2/imagedata/testing/requests_test.go +++ b/openstack/image/v2/imagedata/testing/requests_test.go @@ -82,7 +82,7 @@ func (rs *RS) Seek(offset int64, whence int) (int64, error) { case 2: rs.offset = len(rs.bs) - offsetInt default: - return 0, fmt.Errorf("For parameter `whence`, expected value in {0,1,2} but got: %#v", whence) + return 0, fmt.Errorf("for parameter `whence`, expected value in {0,1,2} but got: %#v", whence) } return int64(rs.offset), nil diff --git a/openstack/image/v2/images/results.go b/openstack/image/v2/images/results.go index 3af7136326..0e0eac21a0 100644 --- a/openstack/image/v2/images/results.go +++ b/openstack/image/v2/images/results.go @@ -121,7 +121,7 @@ func (r *Image) UnmarshalJSON(b []byte) error { case float64: r.SizeBytes = int64(t) default: - return fmt.Errorf("Unknown type for SizeBytes: %v (value: %v)", reflect.TypeOf(t), t) + return fmt.Errorf("unknown type for SizeBytes: %v (value: %v)", reflect.TypeOf(t), t) } // Bundle all other fields into Properties, except for the field named "properties" diff --git a/openstack/networking/v2/extensions/quotas/results.go b/openstack/networking/v2/extensions/quotas/results.go index 7e3931220f..5fa10cf21d 100644 --- a/openstack/networking/v2/extensions/quotas/results.go +++ b/openstack/networking/v2/extensions/quotas/results.go @@ -166,7 +166,7 @@ func (q *QuotaDetail) UnmarshalJSON(b []byte) error { return err } default: - return fmt.Errorf("reserved has unexpected type: %T", t) + return fmt.Errorf("Reserved has unexpected type: %T", t) //nolint:staticcheck } return nil diff --git a/openstack/objectstorage/v1/containers/results.go b/openstack/objectstorage/v1/containers/results.go index fddfa26bf1..ddbdfca623 100644 --- a/openstack/objectstorage/v1/containers/results.go +++ b/openstack/objectstorage/v1/containers/results.go @@ -89,7 +89,7 @@ func ExtractNames(page pagination.Page) ([]string, error) { return names, nil default: - return nil, fmt.Errorf("Cannot extract names from response with content-type: [%s]", ct) + return nil, fmt.Errorf("cannot extract names from response with content-type: [%s]", ct) } } diff --git a/openstack/objectstorage/v1/objects/results.go b/openstack/objectstorage/v1/objects/results.go index d7849e9ecb..387516994b 100644 --- a/openstack/objectstorage/v1/objects/results.go +++ b/openstack/objectstorage/v1/objects/results.go @@ -133,7 +133,7 @@ func ExtractNames(r pagination.Page) ([]string, error) { case strings.HasPrefix(ct, "text/html"): return []string{}, nil default: - return nil, fmt.Errorf("Cannot extract names from response with content-type: [%s]", ct) + return nil, fmt.Errorf("cannot extract names from response with content-type: [%s]", ct) } } @@ -542,6 +542,6 @@ func extractLastMarker(r pagination.Page) (string, error) { case strings.HasPrefix(ct, "text/html"): return "", nil default: - return "", fmt.Errorf("Cannot extract names from response with content-type: [%s]", ct) + return "", fmt.Errorf("cannot extract names from response with content-type: [%s]", ct) } } diff --git a/openstack/sharedfilesystems/v2/errors/errors.go b/openstack/sharedfilesystems/v2/errors/errors.go index f01d6bd588..34324b08ba 100644 --- a/openstack/sharedfilesystems/v2/errors/errors.go +++ b/openstack/sharedfilesystems/v2/errors/errors.go @@ -21,6 +21,6 @@ func ExtractErrorInto(rawError error, errorDetails *ErrorDetails) (err error) { if errors.As(rawError, &codeError) { return json.Unmarshal(codeError.Body, errorDetails) } else { - return errors.New("Unable to extract detailed error message") + return errors.New("unable to extract detailed error message") } } diff --git a/openstack/utils/choose_version.go b/openstack/utils/choose_version.go index ccc56345a6..b9298ad844 100644 --- a/openstack/utils/choose_version.go +++ b/openstack/utils/choose_version.go @@ -89,7 +89,7 @@ func ChooseVersion(ctx context.Context, client *gophercloud.ProviderClient, reco // Prefer a version that exactly matches the provided endpoint. if href == identityEndpoint { if href == "" { - return nil, "", fmt.Errorf("Endpoint missing in version %s response from %s", value.ID, client.IdentityBase) + return nil, "", fmt.Errorf("endpoint missing in version %s response from %s", value.ID, client.IdentityBase) } return version, href, nil } @@ -106,10 +106,10 @@ func ChooseVersion(ctx context.Context, client *gophercloud.ProviderClient, reco } if highest == nil { - return nil, "", fmt.Errorf("No supported version available from endpoint %s", client.IdentityBase) + return nil, "", fmt.Errorf("no supported version available from endpoint %s", client.IdentityBase) } if endpoint == "" { - return nil, "", fmt.Errorf("Endpoint missing in version %s response from %s", highest.ID, client.IdentityBase) + return nil, "", fmt.Errorf("endpoint missing in version %s response from %s", highest.ID, client.IdentityBase) } return highest, endpoint, nil diff --git a/pagination/pager.go b/pagination/pager.go index 3581012566..2eed649f78 100644 --- a/pagination/pager.go +++ b/pagination/pager.go @@ -13,7 +13,7 @@ import ( var ( // ErrPageNotAvailable is returned from a Pager when a next or previous page is requested, but does not exist. - ErrPageNotAvailable = errors.New("The requested page does not exist.") + ErrPageNotAvailable = errors.New("the requested page does not exist") ) // Page must be satisfied by the result type of any resource collection. diff --git a/params.go b/params.go index f7135b2dfa..e282033683 100644 --- a/params.go +++ b/params.go @@ -219,12 +219,12 @@ func BuildRequestBody(opts any, parent string) (map[string]any, error) { optsMaps[i] = b } if parent == "" { - return nil, fmt.Errorf("Parent is required when passing an array or a slice.") + return nil, fmt.Errorf("parent is required when passing an array or a slice") } return map[string]any{parent: optsMaps}, nil } // Return an error if we can't work with the underlying type of 'opts' - return nil, fmt.Errorf("Options type is not a struct, a slice, or an array.") + return nil, fmt.Errorf("options type is not a struct, a slice, or an array") } // EnabledState is a convenience type, mostly used in Create and Update @@ -429,7 +429,7 @@ func BuildQueryString(opts any) (*url.URL, error) { } else { // if the field has a 'required' tag, it can't have a zero-value if requiredTag := f.Tag.Get("required"); requiredTag == "true" { - return &url.URL{}, fmt.Errorf("Required query parameter [%s] not set.", f.Name) + return &url.URL{}, fmt.Errorf("required query parameter [%s] not set", f.Name) } } } @@ -438,7 +438,7 @@ func BuildQueryString(opts any) (*url.URL, error) { return &url.URL{RawQuery: params.Encode()}, nil } // Return an error if the underlying type of 'opts' isn't a struct. - return nil, fmt.Errorf("Options type is not a struct.") + return nil, fmt.Errorf("options type is not a struct") } /* @@ -509,7 +509,7 @@ func BuildHeaders(opts any) (map[string]string, error) { } else { // if the field has a 'required' tag, it can't have a zero-value if requiredTag := f.Tag.Get("required"); requiredTag == "true" { - return optsMap, fmt.Errorf("Required header [%s] not set.", f.Name) + return optsMap, fmt.Errorf("required header [%s] not set", f.Name) } } } @@ -518,7 +518,7 @@ func BuildHeaders(opts any) (map[string]string, error) { return optsMap, nil } // Return an error if the underlying type of 'opts' isn't a struct. - return optsMap, fmt.Errorf("Options type is not a struct.") + return optsMap, fmt.Errorf("options type is not a struct") } // IDSliceToQueryString takes a slice of elements and converts them into a query diff --git a/results.go b/results.go index b12c15a026..d5b947b7f0 100644 --- a/results.go +++ b/results.go @@ -185,23 +185,23 @@ func (r Result) ExtractIntoStructPtr(to any, label string) error { } if to == nil { - return fmt.Errorf("Expected pointer, got %T", to) + return fmt.Errorf("expected pointer, got %T", to) } t := reflect.TypeOf(to) if k := t.Kind(); k != reflect.Ptr { - return fmt.Errorf("Expected pointer, got %v", k) + return fmt.Errorf("expected pointer, got %v", k) } if reflect.ValueOf(to).IsNil() { - return fmt.Errorf("Expected pointer, got %T", to) + return fmt.Errorf("expected pointer, got %T", to) } switch t.Elem().Kind() { case reflect.Struct: return r.extractIntoPtr(to, label) default: - return fmt.Errorf("Expected pointer to struct, got: %v", t) + return fmt.Errorf("expected pointer to struct, got: %v", t) } } @@ -220,23 +220,23 @@ func (r Result) ExtractIntoSlicePtr(to any, label string) error { } if to == nil { - return fmt.Errorf("Expected pointer, got %T", to) + return fmt.Errorf("expected pointer, got %T", to) } t := reflect.TypeOf(to) if k := t.Kind(); k != reflect.Ptr { - return fmt.Errorf("Expected pointer, got %v", k) + return fmt.Errorf("expected pointer, got %v", k) } if reflect.ValueOf(to).IsNil() { - return fmt.Errorf("Expected pointer, got %T", to) + return fmt.Errorf("expected pointer, got %T", to) } switch t.Elem().Kind() { case reflect.Slice: return r.extractIntoPtr(to, label) default: - return fmt.Errorf("Expected pointer to slice, got: %v", t) + return fmt.Errorf("expected pointer to slice, got: %v", t) } } diff --git a/testing/provider_client_test.go b/testing/provider_client_test.go index 900d53021a..7e9cb7be44 100644 --- a/testing/provider_client_test.go +++ b/testing/provider_client_test.go @@ -161,7 +161,7 @@ func TestReauthEndLoop(t *testing.T) { if info.reauthAttempts > 5 { info.maxReauthReached = true - return fmt.Errorf("Max reauthentication attempts reached") + return fmt.Errorf("max reauthentication attempts reached") } p.SetThrowaway(true) p.AuthenticatedHeaders() diff --git a/testing/util_test.go b/testing/util_test.go index 6b6b425f45..93fa2efb8f 100644 --- a/testing/util_test.go +++ b/testing/util_test.go @@ -47,9 +47,9 @@ func TestWaitForError(t *testing.T) { defer cancel() err := gophercloud.WaitFor(ctx, func(context.Context) (bool, error) { - return false, errors.New("Error has occurred") + return false, errors.New("error has occurred") }) - th.AssertEquals(t, "Error has occurred", err.Error()) + th.AssertEquals(t, "error has occurred", err.Error()) } func TestWaitForPredicateExceed(t *testing.T) { @@ -67,7 +67,7 @@ func TestWaitForPredicateExceed(t *testing.T) { return true, ctx.Err() case <-time.After(4 * time.Second): - return false, errors.New("Just wasting time") + return false, errors.New("just wasting time") } }) th.AssertErrIs(t, err, context.DeadlineExceeded) From 040daad2d42fe742cea394c992292be79883c4f3 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Fri, 16 May 2025 12:02:04 +0100 Subject: [PATCH 257/353] lint: Remove non-constant format string in calls I'm not sure why this was disabled, but undisable it. Signed-off-by: Stephen Finucane --- .golangci.yaml | 2 -- .../security/addressgroups/testing/requests_test.go | 12 ++++++------ 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/.golangci.yaml b/.golangci.yaml index b138f3161c..2de1155c03 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -18,8 +18,6 @@ linters: - linters: - staticcheck text: "SA1019: (x509.EncryptPEMBlock|strings.Title)" - - path: (.+)\.go$ - text: SA1006 paths: - third_party$ - builtin$ diff --git a/openstack/networking/v2/extensions/security/addressgroups/testing/requests_test.go b/openstack/networking/v2/extensions/security/addressgroups/testing/requests_test.go index 24abf1cb72..37f8184dc2 100644 --- a/openstack/networking/v2/extensions/security/addressgroups/testing/requests_test.go +++ b/openstack/networking/v2/extensions/security/addressgroups/testing/requests_test.go @@ -23,7 +23,7 @@ func TestList(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, AddressGroupListResponse) + fmt.Fprint(w, AddressGroupListResponse) }) count := 0 @@ -73,7 +73,7 @@ func TestCreate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, AddressGroupCreateResponse) + fmt.Fprint(w, AddressGroupCreateResponse) }) opts := addressgroups.CreateOpts{ @@ -107,7 +107,7 @@ func TestGet(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, AddressGroupGetResponse) + fmt.Fprint(w, AddressGroupGetResponse) }) sr, err := addressgroups.Get(context.TODO(), fake.ServiceClient(fakeServer), "8722e0e0-9cc9-4490-9660-8c9a5732fbb0").Extract() @@ -134,7 +134,7 @@ func TestUpdate(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, AddressGroupUpdateResponse) + fmt.Fprint(w, AddressGroupUpdateResponse) }) name := "ADDR_GP_2" @@ -168,7 +168,7 @@ func TestAddAddresses(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, AddressGroupAddAddressesResponse) + fmt.Fprint(w, AddressGroupAddAddressesResponse) }) opts := addressgroups.UpdateAddressesOpts{ @@ -197,7 +197,7 @@ func TestRemoveAddresses(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, AddressGroupRemoveAddressesResponse) + fmt.Fprint(w, AddressGroupRemoveAddressesResponse) }) opts := addressgroups.UpdateAddressesOpts{ From 54e5cc74ae34233bd98fc97faf49caf436cf9c02 Mon Sep 17 00:00:00 2001 From: Omer Date: Mon, 1 Dec 2025 14:10:50 +0200 Subject: [PATCH 258/353] Add TSIG key support for OpenStack DNS v2 API Implement TSIG (Transaction SIGnature) key management for the Designate DNS service, enabling authentication of DNS transactions between servers for zone transfers and dynamic updates. Fixes #3622 Signed-off-by: Omer --- internal/acceptance/openstack/dns/v2/dns.go | 46 ++++ .../openstack/dns/v2/tsigkeys_test.go | 56 +++++ openstack/dns/v2/tsigkeys/doc.go | 72 ++++++ openstack/dns/v2/tsigkeys/requests.go | 158 ++++++++++++ openstack/dns/v2/tsigkeys/results.go | 119 ++++++++++ openstack/dns/v2/tsigkeys/testing/doc.go | 2 + .../dns/v2/tsigkeys/testing/fixtures_test.go | 224 ++++++++++++++++++ .../dns/v2/tsigkeys/testing/requests_test.go | 98 ++++++++ openstack/dns/v2/tsigkeys/urls.go | 13 + 9 files changed, 788 insertions(+) create mode 100644 internal/acceptance/openstack/dns/v2/tsigkeys_test.go create mode 100644 openstack/dns/v2/tsigkeys/doc.go create mode 100644 openstack/dns/v2/tsigkeys/requests.go create mode 100644 openstack/dns/v2/tsigkeys/results.go create mode 100644 openstack/dns/v2/tsigkeys/testing/doc.go create mode 100644 openstack/dns/v2/tsigkeys/testing/fixtures_test.go create mode 100644 openstack/dns/v2/tsigkeys/testing/requests_test.go create mode 100644 openstack/dns/v2/tsigkeys/urls.go diff --git a/internal/acceptance/openstack/dns/v2/dns.go b/internal/acceptance/openstack/dns/v2/dns.go index 9adb61882d..596ce75431 100644 --- a/internal/acceptance/openstack/dns/v2/dns.go +++ b/internal/acceptance/openstack/dns/v2/dns.go @@ -9,6 +9,7 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/dns/v2/recordsets" transferAccepts "github.com/gophercloud/gophercloud/v2/openstack/dns/v2/transfer/accept" transferRequests "github.com/gophercloud/gophercloud/v2/openstack/dns/v2/transfer/request" + "github.com/gophercloud/gophercloud/v2/openstack/dns/v2/tsigkeys" "github.com/gophercloud/gophercloud/v2/openstack/dns/v2/zones" th "github.com/gophercloud/gophercloud/v2/testhelper" ) @@ -308,3 +309,48 @@ func WaitForZoneStatus(client *gophercloud.ServiceClient, zone *zones.Zone, stat return false, nil }) } + +// CreateTSIGKey will create a TSIG key with a random name. An error will +// be returned if the TSIG key was unable to be created. +func CreateTSIGKey(t *testing.T, client *gophercloud.ServiceClient) (*tsigkeys.TSIGKey, error) { + keyName := tools.RandomString("ACPTTEST", 8) + + t.Logf("Attempting to create TSIG key: %s", keyName) + createOpts := tsigkeys.CreateOpts{ + Name: keyName, + Algorithm: "hmac-sha256", + Secret: "example-test-secret-key==", + Scope: "POOL", + // Default pool ID from designate/conf/central.py + ResourceID: "794ccc2c-d751-44fe-b57f-8894c9f5c842", + } + + tsigkey, err := tsigkeys.Create(context.TODO(), client, createOpts).Extract() + if err != nil { + return tsigkey, err + } + + newTSIGKey, err := tsigkeys.Get(context.TODO(), client, tsigkey.ID).Extract() + if err != nil { + return tsigkey, err + } + + t.Logf("Created TSIG key: %s", keyName) + + th.AssertEquals(t, newTSIGKey.Name, keyName) + th.AssertEquals(t, newTSIGKey.Algorithm, "hmac-sha256") + + return newTSIGKey, nil +} + +// DeleteTSIGKey will delete a specified TSIG key. A fatal error will occur if +// the TSIG key failed to be deleted. This works best when used as a deferred +// function. +func DeleteTSIGKey(t *testing.T, client *gophercloud.ServiceClient, tsigkey *tsigkeys.TSIGKey) { + err := tsigkeys.Delete(context.TODO(), client, tsigkey.ID).ExtractErr() + if err != nil { + t.Fatalf("Unable to delete TSIG key %s: %v", tsigkey.ID, err) + } + + t.Logf("Deleted TSIG key: %s", tsigkey.ID) +} diff --git a/internal/acceptance/openstack/dns/v2/tsigkeys_test.go b/internal/acceptance/openstack/dns/v2/tsigkeys_test.go new file mode 100644 index 0000000000..e07b695be2 --- /dev/null +++ b/internal/acceptance/openstack/dns/v2/tsigkeys_test.go @@ -0,0 +1,56 @@ +//go:build acceptance || dns || tsigkeys + +package v2 + +import ( + "context" + "testing" + + "github.com/gophercloud/gophercloud/v2/internal/acceptance/clients" + "github.com/gophercloud/gophercloud/v2/internal/acceptance/tools" + "github.com/gophercloud/gophercloud/v2/openstack/dns/v2/tsigkeys" + th "github.com/gophercloud/gophercloud/v2/testhelper" +) + +func TestTSIGKeysCRUD(t *testing.T) { + clients.RequireAdmin(t) + + client, err := clients.NewDNSV2Client() + th.AssertNoErr(t, err) + + tsigkey, err := CreateTSIGKey(t, client) + th.AssertNoErr(t, err) + defer DeleteTSIGKey(t, client, tsigkey) + + tools.PrintResource(t, &tsigkey) + + allPages, err := tsigkeys.List(client, nil).AllPages(context.TODO()) + th.AssertNoErr(t, err) + + allTSIGKeys, err := tsigkeys.ExtractTSIGKeys(allPages) + th.AssertNoErr(t, err) + + var found bool + for _, k := range allTSIGKeys { + tools.PrintResource(t, &k) + + if tsigkey.Name == k.Name { + found = true + } + } + + th.AssertEquals(t, found, true) + + updateOpts := tsigkeys.UpdateOpts{ + Name: tsigkey.Name + "-updated", + Secret: "updated-test-secret-key==", + } + + newTSIGKey, err := tsigkeys.Update(context.TODO(), client, tsigkey.ID, updateOpts).Extract() + th.AssertNoErr(t, err) + + tools.PrintResource(t, &newTSIGKey) + + th.AssertEquals(t, newTSIGKey.Name, tsigkey.Name+"-updated") + th.AssertEquals(t, newTSIGKey.Secret, "updated-test-secret-key==") +} diff --git a/openstack/dns/v2/tsigkeys/doc.go b/openstack/dns/v2/tsigkeys/doc.go new file mode 100644 index 0000000000..7e99c6dbe4 --- /dev/null +++ b/openstack/dns/v2/tsigkeys/doc.go @@ -0,0 +1,72 @@ +/* +Package tsigkeys provides information and interaction with the TSIG key API +resource for the OpenStack DNS service. + +TSIG (Transaction SIGnature) keys are used to authenticate DNS transactions +between servers, such as zone transfers and dynamic updates. + +Example to List TSIG Keys + + listOpts := tsigkeys.ListOpts{ + Scope: "POOL", + } + + allPages, err := tsigkeys.List(dnsClient, listOpts).AllPages(context.TODO()) + if err != nil { + panic(err) + } + + allTSIGKeys, err := tsigkeys.ExtractTSIGKeys(allPages) + if err != nil { + panic(err) + } + + for _, tsigkey := range allTSIGKeys { + fmt.Printf("%+v\n", tsigkey) + } + +Example to Create a TSIG Key + + createOpts := tsigkeys.CreateOpts{ + Name: "mytsigkey", + Algorithm: "hmac-sha256", + Secret: "example-secret-key-value==", + Scope: "POOL", + ResourceID: "pool-id-here", + } + + tsigkey, err := tsigkeys.Create(context.TODO(), dnsClient, createOpts).Extract() + if err != nil { + panic(err) + } + +Example to Get a TSIG Key + + tsigkeyID := "99d10f68-5623-4491-91a0-6daafa32b60e" + tsigkey, err := tsigkeys.Get(context.TODO(), dnsClient, tsigkeyID).Extract() + if err != nil { + panic(err) + } + +Example to Update a TSIG Key + + tsigkeyID := "99d10f68-5623-4491-91a0-6daafa32b60e" + updateOpts := tsigkeys.UpdateOpts{ + Name: "updatedname", + Secret: "updated-secret-key-value==", + } + + tsigkey, err := tsigkeys.Update(context.TODO(), dnsClient, tsigkeyID, updateOpts).Extract() + if err != nil { + panic(err) + } + +Example to Delete a TSIG Key + + tsigkeyID := "99d10f68-5623-4491-91a0-6daafa32b60e" + err := tsigkeys.Delete(context.TODO(), dnsClient, tsigkeyID).ExtractErr() + if err != nil { + panic(err) + } +*/ +package tsigkeys diff --git a/openstack/dns/v2/tsigkeys/requests.go b/openstack/dns/v2/tsigkeys/requests.go new file mode 100644 index 0000000000..2f8b0a4aa5 --- /dev/null +++ b/openstack/dns/v2/tsigkeys/requests.go @@ -0,0 +1,158 @@ +package tsigkeys + +import ( + "context" + + "github.com/gophercloud/gophercloud/v2" + "github.com/gophercloud/gophercloud/v2/pagination" +) + +// ListOptsBuilder allows extensions to add parameters to the List request. +type ListOptsBuilder interface { + ToTSIGKeyListQuery() (string, error) +} + +// ListOpts allows the filtering and sorting of paginated collections through +// the API. Filtering is achieved by passing in struct field values that map to +// the server attributes you want to see returned. Marker and Limit are used +// for pagination. +// https://docs.openstack.org/api-ref/dns/ +type ListOpts struct { + // Integer value for the limit of values to return. + Limit int `q:"limit"` + + // UUID of the TSIG key at which you want to set a marker. + Marker string `q:"marker"` + + // Name of the TSIG key. + Name string `q:"name"` + + // Algorithm used by the TSIG key. + Algorithm string `q:"algorithm"` + + // Scope of the TSIG key (ZONE or POOL). + Scope string `q:"scope"` +} + +// ToTSIGKeyListQuery formats a ListOpts into a query string. +func (opts ListOpts) ToTSIGKeyListQuery() (string, error) { + q, err := gophercloud.BuildQueryString(opts) + return q.String(), err +} + +// List implements a TSIG key List request. +func List(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { + url := baseURL(client) + if opts != nil { + query, err := opts.ToTSIGKeyListQuery() + if err != nil { + return pagination.Pager{Err: err} + } + url += query + } + return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { + return TSIGKeyPage{pagination.LinkedPageBase{PageResult: r}} + }) +} + +// Get returns information about a TSIG key, given its ID. +func Get(ctx context.Context, client *gophercloud.ServiceClient, tsigkeyID string) (r GetResult) { + resp, err := client.Get(ctx, tsigkeyURL(client, tsigkeyID), &r.Body, nil) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} + +// CreateOptsBuilder allows extensions to add additional attributes to the +// Create request. +type CreateOptsBuilder interface { + ToTSIGKeyCreateMap() (map[string]any, error) +} + +// CreateOpts specifies the attributes used to create a TSIG key. +type CreateOpts struct { + // Name of the TSIG key. + Name string `json:"name" required:"true"` + + // Algorithm is the TSIG algorithm (e.g., hmac-sha256, hmac-sha512). + Algorithm string `json:"algorithm" required:"true"` + + // Secret is the base64-encoded secret key. + Secret string `json:"secret" required:"true"` + + // Scope defines the scope of the TSIG key (ZONE or POOL). + Scope string `json:"scope" required:"true"` + + // ResourceID is the ID of the resource (zone or pool) this key is associated with. + ResourceID string `json:"resource_id" required:"true"` +} + +// ToTSIGKeyCreateMap formats a CreateOpts structure into a request body. +func (opts CreateOpts) ToTSIGKeyCreateMap() (map[string]any, error) { + return gophercloud.BuildRequestBody(opts, "") +} + +// Create implements a TSIG key create request. +func Create(ctx context.Context, client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { + b, err := opts.ToTSIGKeyCreateMap() + if err != nil { + r.Err = err + return + } + resp, err := client.Post(ctx, baseURL(client), &b, &r.Body, &gophercloud.RequestOpts{ + OkCodes: []int{201}, + }) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} + +// UpdateOptsBuilder allows extensions to add additional attributes to the +// Update request. +type UpdateOptsBuilder interface { + ToTSIGKeyUpdateMap() (map[string]any, error) +} + +// UpdateOpts specifies the attributes to update a TSIG key. +type UpdateOpts struct { + // Name of the TSIG key. + Name string `json:"name,omitempty"` + + // Algorithm is the TSIG algorithm. + Algorithm string `json:"algorithm,omitempty"` + + // Secret is the base64-encoded secret key. + Secret string `json:"secret,omitempty"` + + // Scope defines the scope of the TSIG key. + Scope string `json:"scope,omitempty"` + + // ResourceID is the ID of the resource this key is associated with. + ResourceID string `json:"resource_id,omitempty"` +} + +// ToTSIGKeyUpdateMap formats an UpdateOpts structure into a request body. +func (opts UpdateOpts) ToTSIGKeyUpdateMap() (map[string]any, error) { + return gophercloud.BuildRequestBody(opts, "") +} + +// Update implements a TSIG key update request. +func Update(ctx context.Context, client *gophercloud.ServiceClient, tsigkeyID string, opts UpdateOptsBuilder) (r UpdateResult) { + b, err := opts.ToTSIGKeyUpdateMap() + if err != nil { + r.Err = err + return + } + resp, err := client.Patch(ctx, tsigkeyURL(client, tsigkeyID), &b, &r.Body, &gophercloud.RequestOpts{ + OkCodes: []int{200}, + }) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} + +// Delete implements a TSIG key delete request. +func Delete(ctx context.Context, client *gophercloud.ServiceClient, tsigkeyID string) (r DeleteResult) { + resp, err := client.Delete(ctx, tsigkeyURL(client, tsigkeyID), &gophercloud.RequestOpts{ + OkCodes: []int{204}, + }) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} diff --git a/openstack/dns/v2/tsigkeys/results.go b/openstack/dns/v2/tsigkeys/results.go new file mode 100644 index 0000000000..02382e9b7a --- /dev/null +++ b/openstack/dns/v2/tsigkeys/results.go @@ -0,0 +1,119 @@ +package tsigkeys + +import ( + "encoding/json" + "time" + + "github.com/gophercloud/gophercloud/v2" + "github.com/gophercloud/gophercloud/v2/pagination" +) + +type commonResult struct { + gophercloud.Result +} + +// Extract interprets a GetResult, CreateResult or UpdateResult as a TSIGKey. +// An error is returned if the original call or the extraction failed. +func (r commonResult) Extract() (*TSIGKey, error) { + var s *TSIGKey + err := r.ExtractInto(&s) + return s, err +} + +// CreateResult is the result of a Create request. Call its Extract method +// to interpret the result as a TSIGKey. +type CreateResult struct { + commonResult +} + +// GetResult is the result of a Get request. Call its Extract method +// to interpret the result as a TSIGKey. +type GetResult struct { + commonResult +} + +// UpdateResult is the result of an Update request. Call its Extract method +// to interpret the result as a TSIGKey. +type UpdateResult struct { + commonResult +} + +// DeleteResult is the result of a Delete request. Call its ExtractErr method +// to determine if the request succeeded or failed. +type DeleteResult struct { + gophercloud.ErrResult +} + +// TSIGKeyPage is a single page of TSIGKey results. +type TSIGKeyPage struct { + pagination.LinkedPageBase +} + +// IsEmpty returns true if the page contains no results. +func (r TSIGKeyPage) IsEmpty() (bool, error) { + if r.StatusCode == 204 { + return true, nil + } + + s, err := ExtractTSIGKeys(r) + return len(s) == 0, err +} + +// ExtractTSIGKeys extracts a slice of TSIGKeys from a List result. +func ExtractTSIGKeys(r pagination.Page) ([]TSIGKey, error) { + var s struct { + TSIGKeys []TSIGKey `json:"tsigkeys"` + } + err := (r.(TSIGKeyPage)).ExtractInto(&s) + return s.TSIGKeys, err +} + +// TSIGKey represents a TSIG key for DNS transaction authentication. +type TSIGKey struct { + // ID uniquely identifies this TSIG key. + ID string `json:"id"` + + // Name is the name of the TSIG key. + Name string `json:"name"` + + // Algorithm is the TSIG algorithm used (e.g., hmac-sha256, hmac-sha512). + Algorithm string `json:"algorithm"` + + // Secret is the base64-encoded secret key. + Secret string `json:"secret"` + + // Scope defines the scope of the TSIG key (ZONE or POOL). + Scope string `json:"scope"` + + // ResourceID is the ID of the resource (zone or pool) this key is associated with. + ResourceID string `json:"resource_id"` + + // CreatedAt is the date when the TSIG key was created. + CreatedAt time.Time `json:"-"` + + // UpdatedAt is the date when the TSIG key was last updated. + UpdatedAt time.Time `json:"-"` + + // Links includes HTTP references to the itself. + Links map[string]any `json:"links"` +} + +func (r *TSIGKey) UnmarshalJSON(b []byte) error { + type tmp TSIGKey + var s struct { + tmp + CreatedAt gophercloud.JSONRFC3339MilliNoZ `json:"created_at"` + UpdatedAt gophercloud.JSONRFC3339MilliNoZ `json:"updated_at"` + } + + err := json.Unmarshal(b, &s) + if err != nil { + return err + } + *r = TSIGKey(s.tmp) + + r.CreatedAt = time.Time(s.CreatedAt) + r.UpdatedAt = time.Time(s.UpdatedAt) + + return nil +} diff --git a/openstack/dns/v2/tsigkeys/testing/doc.go b/openstack/dns/v2/tsigkeys/testing/doc.go new file mode 100644 index 0000000000..6f54fc2d97 --- /dev/null +++ b/openstack/dns/v2/tsigkeys/testing/doc.go @@ -0,0 +1,2 @@ +// tsigkeys unit tests +package testing diff --git a/openstack/dns/v2/tsigkeys/testing/fixtures_test.go b/openstack/dns/v2/tsigkeys/testing/fixtures_test.go new file mode 100644 index 0000000000..dc15e74197 --- /dev/null +++ b/openstack/dns/v2/tsigkeys/testing/fixtures_test.go @@ -0,0 +1,224 @@ +package testing + +import ( + "fmt" + "net/http" + "testing" + "time" + + "github.com/gophercloud/gophercloud/v2" + "github.com/gophercloud/gophercloud/v2/openstack/dns/v2/tsigkeys" + th "github.com/gophercloud/gophercloud/v2/testhelper" + "github.com/gophercloud/gophercloud/v2/testhelper/client" +) + +// ListOutput is a sample response to a List call. +const ListOutput = ` +{ + "links": { + "self": "http://example.com:9001/v2/tsigkeys" + }, + "metadata": { + "total_count": 2 + }, + "tsigkeys": [ + { + "id": "8add45a3-0f29-489f-854e-7609baf8d7a1", + "name": "poolsecondarykey", + "algorithm": "hmac-sha256", + "secret": "my-base64-secret-example==", + "scope": "POOL", + "resource_id": "adcc2fb6-7984-4453-a6f9-2cc2a24a38bb", + "created_at": "2025-08-13T15:54:18.000000", + "updated_at": null, + "links": { + "self": "http://127.0.0.1:9001/v2/tsigkeys/8add45a3-0f29-489f-854e-7609baf8d7a1" + } + }, + { + "id": "9bef46b4-1f3a-59a0-965f-8710caf9e8b2", + "name": "zonekey", + "algorithm": "hmac-sha512", + "secret": "another-base64-secret-example==", + "scope": "ZONE", + "resource_id": "c4d5e6f7-8a9b-0c1d-2e3f-4a5b6c7d8e9f", + "created_at": "2025-08-14T10:30:45.000000", + "updated_at": "2025-08-15T14:22:33.000000", + "links": { + "self": "http://127.0.0.1:9001/v2/tsigkeys/9bef46b4-1f3a-59a0-965f-8710caf9e8b2" + } + } + ] +} +` + +// GetOutput is a sample response to a Get call. +const GetOutput = ` +{ + "id": "8add45a3-0f29-489f-854e-7609baf8d7a1", + "name": "poolsecondarykey", + "algorithm": "hmac-sha256", + "secret": "my-base64-secret-example==", + "scope": "POOL", + "resource_id": "adcc2fb6-7984-4453-a6f9-2cc2a24a38bb", + "created_at": "2025-08-13T15:54:18.000000", + "updated_at": null, + "links": { + "self": "http://127.0.0.1:9001/v2/tsigkeys/8add45a3-0f29-489f-854e-7609baf8d7a1" + } +} +` + +// FirstTSIGKeyCreatedAt is the created at time for the first TSIG key +var FirstTSIGKeyCreatedAt, _ = time.Parse(gophercloud.RFC3339MilliNoZ, "2025-08-13T15:54:18.000000") + +// FirstTSIGKey is the first result in ListOutput +var FirstTSIGKey = tsigkeys.TSIGKey{ + ID: "8add45a3-0f29-489f-854e-7609baf8d7a1", + Name: "poolsecondarykey", + Algorithm: "hmac-sha256", + Secret: "my-base64-secret-example==", + Scope: "POOL", + ResourceID: "adcc2fb6-7984-4453-a6f9-2cc2a24a38bb", + CreatedAt: FirstTSIGKeyCreatedAt, + Links: map[string]any{ + "self": "http://127.0.0.1:9001/v2/tsigkeys/8add45a3-0f29-489f-854e-7609baf8d7a1", + }, +} + +var SecondTSIGKeyCreatedAt, _ = time.Parse(gophercloud.RFC3339MilliNoZ, "2025-08-14T10:30:45.000000") +var SecondTSIGKeyUpdatedAt, _ = time.Parse(gophercloud.RFC3339MilliNoZ, "2025-08-15T14:22:33.000000") + +var SecondTSIGKey = tsigkeys.TSIGKey{ + ID: "9bef46b4-1f3a-59a0-965f-8710caf9e8b2", + Name: "zonekey", + Algorithm: "hmac-sha512", + Secret: "another-base64-secret-example==", + Scope: "ZONE", + ResourceID: "c4d5e6f7-8a9b-0c1d-2e3f-4a5b6c7d8e9f", + CreatedAt: SecondTSIGKeyCreatedAt, + UpdatedAt: SecondTSIGKeyUpdatedAt, + Links: map[string]any{ + "self": "http://127.0.0.1:9001/v2/tsigkeys/9bef46b4-1f3a-59a0-965f-8710caf9e8b2", + }, +} + +// ExpectedTSIGKeysSlice is the slice of results that should be parsed +// from ListOutput, in the expected order. +var ExpectedTSIGKeysSlice = []tsigkeys.TSIGKey{FirstTSIGKey, SecondTSIGKey} + +// HandleListSuccessfully configures the test server to respond to a List request. +func HandleListSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/tsigkeys", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.Header().Add("Content-Type", "application/json") + fmt.Fprint(w, ListOutput) + }) +} + +// HandleGetSuccessfully configures the test server to respond to a Get request. +func HandleGetSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/tsigkeys/8add45a3-0f29-489f-854e-7609baf8d7a1", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.Header().Add("Content-Type", "application/json") + fmt.Fprint(w, GetOutput) + }) +} + +// CreateTSIGKeyRequest is a sample request to create a TSIG key. +const CreateTSIGKeyRequest = ` +{ + "name": "poolsecondarykey", + "algorithm": "hmac-sha256", + "secret": "my-base64-secret-example==", + "scope": "POOL", + "resource_id": "adcc2fb6-7984-4453-a6f9-2cc2a24a38bb" +} +` + +// CreateTSIGKeyResponse is a sample response to a create request. +const CreateTSIGKeyResponse = ` +{ + "id": "8add45a3-0f29-489f-854e-7609baf8d7a1", + "name": "poolsecondarykey", + "algorithm": "hmac-sha256", + "secret": "my-base64-secret-example==", + "scope": "POOL", + "resource_id": "adcc2fb6-7984-4453-a6f9-2cc2a24a38bb", + "created_at": "2025-08-13T15:54:18.000000", + "updated_at": null, + "links": { + "self": "http://127.0.0.1:9001/v2/tsigkeys/8add45a3-0f29-489f-854e-7609baf8d7a1" + } +} +` + +// CreatedTSIGKey is the expected created TSIG key +var CreatedTSIGKey = FirstTSIGKey + +// HandleCreateSuccessfully configures the test server to respond to a Create request. +func HandleCreateSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/tsigkeys", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "POST") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.TestJSONRequest(t, r, CreateTSIGKeyRequest) + + w.WriteHeader(http.StatusCreated) + w.Header().Add("Content-Type", "application/json") + fmt.Fprint(w, CreateTSIGKeyResponse) + }) +} + +// UpdateTSIGKeyRequest is a sample request to update a TSIG key. +const UpdateTSIGKeyRequest = ` +{ + "name": "updatedsecondarykey", + "secret": "new-base64-secret-example==" +} +` + +// UpdateTSIGKeyResponse is a sample response to update a TSIG key. +const UpdateTSIGKeyResponse = ` +{ + "id": "8add45a3-0f29-489f-854e-7609baf8d7a1", + "name": "updatedsecondarykey", + "algorithm": "hmac-sha256", + "secret": "new-base64-secret-example==", + "scope": "POOL", + "resource_id": "adcc2fb6-7984-4453-a6f9-2cc2a24a38bb", + "created_at": "2025-08-13T15:54:18.000000", + "updated_at": "2025-08-16T09:15:22.000000", + "links": { + "self": "http://127.0.0.1:9001/v2/tsigkeys/8add45a3-0f29-489f-854e-7609baf8d7a1" + } +} +` + +// HandleUpdateSuccessfully configures the test server to respond to an Update request. +func HandleUpdateSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/tsigkeys/8add45a3-0f29-489f-854e-7609baf8d7a1", + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "PATCH") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.TestJSONRequest(t, r, UpdateTSIGKeyRequest) + + w.WriteHeader(http.StatusOK) + w.Header().Add("Content-Type", "application/json") + fmt.Fprint(w, UpdateTSIGKeyResponse) + }) +} + +// HandleDeleteSuccessfully configures the test server to respond to a Delete request. +func HandleDeleteSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/tsigkeys/8add45a3-0f29-489f-854e-7609baf8d7a1", + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "DELETE") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.WriteHeader(http.StatusNoContent) + }) +} diff --git a/openstack/dns/v2/tsigkeys/testing/requests_test.go b/openstack/dns/v2/tsigkeys/testing/requests_test.go new file mode 100644 index 0000000000..3bc163d5b4 --- /dev/null +++ b/openstack/dns/v2/tsigkeys/testing/requests_test.go @@ -0,0 +1,98 @@ +package testing + +import ( + "context" + "testing" + + "github.com/gophercloud/gophercloud/v2/openstack/dns/v2/tsigkeys" + "github.com/gophercloud/gophercloud/v2/pagination" + th "github.com/gophercloud/gophercloud/v2/testhelper" + "github.com/gophercloud/gophercloud/v2/testhelper/client" +) + +func TestList(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListSuccessfully(t, fakeServer) + + count := 0 + err := tsigkeys.List(client.ServiceClient(fakeServer), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + count++ + actual, err := tsigkeys.ExtractTSIGKeys(page) + th.AssertNoErr(t, err) + th.CheckDeepEquals(t, ExpectedTSIGKeysSlice, actual) + + return true, nil + }) + th.AssertNoErr(t, err) + th.CheckEquals(t, 1, count) +} + +func TestListAllPages(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListSuccessfully(t, fakeServer) + + allPages, err := tsigkeys.List(client.ServiceClient(fakeServer), nil).AllPages(context.TODO()) + th.AssertNoErr(t, err) + allTSIGKeys, err := tsigkeys.ExtractTSIGKeys(allPages) + th.AssertNoErr(t, err) + th.CheckEquals(t, 2, len(allTSIGKeys)) +} + +func TestGet(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleGetSuccessfully(t, fakeServer) + + actual, err := tsigkeys.Get(context.TODO(), client.ServiceClient(fakeServer), "8add45a3-0f29-489f-854e-7609baf8d7a1").Extract() + th.AssertNoErr(t, err) + th.CheckDeepEquals(t, &FirstTSIGKey, actual) +} + +func TestCreate(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCreateSuccessfully(t, fakeServer) + + createOpts := tsigkeys.CreateOpts{ + Name: "poolsecondarykey", + Algorithm: "hmac-sha256", + Secret: "my-base64-secret-example==", + Scope: "POOL", + ResourceID: "adcc2fb6-7984-4453-a6f9-2cc2a24a38bb", + } + + actual, err := tsigkeys.Create(context.TODO(), client.ServiceClient(fakeServer), createOpts).Extract() + th.AssertNoErr(t, err) + th.CheckDeepEquals(t, &CreatedTSIGKey, actual) +} + +func TestUpdate(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleUpdateSuccessfully(t, fakeServer) + + updateOpts := tsigkeys.UpdateOpts{ + Name: "updatedsecondarykey", + Secret: "new-base64-secret-example==", + } + + UpdatedTSIGKey := CreatedTSIGKey + UpdatedTSIGKey.Name = "updatedsecondarykey" + UpdatedTSIGKey.Secret = "new-base64-secret-example==" + + actual, err := tsigkeys.Update(context.TODO(), client.ServiceClient(fakeServer), UpdatedTSIGKey.ID, updateOpts).Extract() + th.AssertNoErr(t, err) + th.CheckEquals(t, UpdatedTSIGKey.Name, actual.Name) + th.CheckEquals(t, UpdatedTSIGKey.Secret, actual.Secret) +} + +func TestDelete(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDeleteSuccessfully(t, fakeServer) + + err := tsigkeys.Delete(context.TODO(), client.ServiceClient(fakeServer), "8add45a3-0f29-489f-854e-7609baf8d7a1").ExtractErr() + th.AssertNoErr(t, err) +} diff --git a/openstack/dns/v2/tsigkeys/urls.go b/openstack/dns/v2/tsigkeys/urls.go new file mode 100644 index 0000000000..f7c4b0cfe3 --- /dev/null +++ b/openstack/dns/v2/tsigkeys/urls.go @@ -0,0 +1,13 @@ +package tsigkeys + +import "github.com/gophercloud/gophercloud/v2" + +// baseURL returns the base URL for TSIG keys. +func baseURL(c *gophercloud.ServiceClient) string { + return c.ServiceURL("tsigkeys") +} + +// tsigkeyURL returns the URL for a specific TSIG key. +func tsigkeyURL(c *gophercloud.ServiceClient, tsigkeyID string) string { + return c.ServiceURL("tsigkeys", tsigkeyID) +} From 69dcfc307bc0de4289e5c541cd3d0b7a51c04dfe Mon Sep 17 00:00:00 2001 From: Bertrand Lanson Date: Tue, 3 Mar 2026 21:14:23 +0100 Subject: [PATCH 259/353] fix: networkipavailabilities: handle scientific notation in IP counts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Go's JSON decoder converts large integers to float64 when decoding into interface{}, which causes values ≥ 1e21 to be re-encoded in scientific notation. big.Int cannot parse that notation, crashing any List() call that includes a network with a large IPv6 prefix such as /56 or shorter. Signed-off-by: Bertrand Lanson --- .../networkipavailabilities/results.go | 62 ++++++++++++++++--- .../testing/fixtures_test.go | 14 +++-- 2 files changed, 61 insertions(+), 15 deletions(-) diff --git a/openstack/networking/v2/extensions/networkipavailabilities/results.go b/openstack/networking/v2/extensions/networkipavailabilities/results.go index b37617f9d1..e29810972a 100644 --- a/openstack/networking/v2/extensions/networkipavailabilities/results.go +++ b/openstack/networking/v2/extensions/networkipavailabilities/results.go @@ -2,6 +2,7 @@ package networkipavailabilities import ( "encoding/json" + "fmt" "math/big" "github.com/gophercloud/gophercloud/v2" @@ -52,12 +53,35 @@ type NetworkIPAvailability struct { UsedIPs string `json:"-"` } +// Go's encoding/json decodes all JSON numbers into float64 when the target is +// interface{}. For large integers (abs >= 1e21), re-encoding that float64 +// produces scientific notation (e.g. "1.1805916207174113e+21"), which +// big.Int.UnmarshalJSON cannot parse. This function handles both plain integer +// and scientific notation forms. +func parseBigIntFromNumber(n json.Number) (*big.Int, error) { + s := string(n) + + // Fast path: plain integer notation + bi := new(big.Int) + if _, ok := bi.SetString(s, 10); ok { + return bi, nil + } + + // Slow path: scientific notation from float64 round-trip + bf := new(big.Float).SetPrec(256) + if _, _, err := bf.Parse(s, 10); err != nil { + return nil, fmt.Errorf("networkipavailabilities: cannot parse %q as an integer: %w", s, err) + } + result, _ := bf.Int(nil) + return result, nil +} + func (r *NetworkIPAvailability) UnmarshalJSON(b []byte) error { type tmp NetworkIPAvailability var s struct { tmp - TotalIPs big.Int `json:"total_ips"` - UsedIPs big.Int `json:"used_ips"` + TotalIPs json.Number `json:"total_ips"` + UsedIPs json.Number `json:"used_ips"` } err := json.Unmarshal(b, &s) @@ -66,10 +90,19 @@ func (r *NetworkIPAvailability) UnmarshalJSON(b []byte) error { } *r = NetworkIPAvailability(s.tmp) - r.TotalIPs = s.TotalIPs.String() - r.UsedIPs = s.UsedIPs.String() + totalIPs, err := parseBigIntFromNumber(s.TotalIPs) + if err != nil { + return err + } + r.TotalIPs = totalIPs.String() - return err + usedIPs, err := parseBigIntFromNumber(s.UsedIPs) + if err != nil { + return err + } + r.UsedIPs = usedIPs.String() + + return nil } // SubnetIPAvailability represents availability details for a single subnet. @@ -97,8 +130,8 @@ func (r *SubnetIPAvailability) UnmarshalJSON(b []byte) error { type tmp SubnetIPAvailability var s struct { tmp - TotalIPs big.Int `json:"total_ips"` - UsedIPs big.Int `json:"used_ips"` + TotalIPs json.Number `json:"total_ips"` + UsedIPs json.Number `json:"used_ips"` } err := json.Unmarshal(b, &s) @@ -107,10 +140,19 @@ func (r *SubnetIPAvailability) UnmarshalJSON(b []byte) error { } *r = SubnetIPAvailability(s.tmp) - r.TotalIPs = s.TotalIPs.String() - r.UsedIPs = s.UsedIPs.String() + totalIPs, err := parseBigIntFromNumber(s.TotalIPs) + if err != nil { + return err + } + r.TotalIPs = totalIPs.String() + + usedIPs, err := parseBigIntFromNumber(s.UsedIPs) + if err != nil { + return err + } + r.UsedIPs = usedIPs.String() - return err + return nil } // NetworkIPAvailabilityPage stores a single page of NetworkIPAvailabilities diff --git a/openstack/networking/v2/extensions/networkipavailabilities/testing/fixtures_test.go b/openstack/networking/v2/extensions/networkipavailabilities/testing/fixtures_test.go index 58900db23c..475511cce2 100644 --- a/openstack/networking/v2/extensions/networkipavailabilities/testing/fixtures_test.go +++ b/openstack/networking/v2/extensions/networkipavailabilities/testing/fixtures_test.go @@ -15,11 +15,11 @@ const NetworkIPAvailabilityListResult = ` "project_id": "fb57277ef2f84a0e85b9018ec2dedbf7", "subnet_ip_availability": [ { - "cidr": "fdbc:bf53:567e::/64", + "cidr": "fdbc:bf53:567e::/56", "ip_version": 6, "subnet_id": "497ac4d3-0b92-42cf-82de-71302ab2b656", "subnet_name": "ipv6-private-subnet", - "total_ips": 18446744073709552000, + "total_ips": 4722366482869645213696, "used_ips": 2 }, { @@ -69,10 +69,14 @@ var NetworkIPAvailability1 = networkipavailabilities.NetworkIPAvailability{ { SubnetID: "497ac4d3-0b92-42cf-82de-71302ab2b656", SubnetName: "ipv6-private-subnet", - CIDR: "fdbc:bf53:567e::/64", + CIDR: "fdbc:bf53:567e::/56", IPVersion: int(gophercloud.IPv6), - TotalIPs: "18446744073709552000", - UsedIPs: "2", + // 4722366482869645213696 is 2^72 (a /56 IPv6 subnet). + // After gophercloud's float64 round-trip (numbers >= 1e21 are + // re-encoded in scientific notation), the value loses the last + // few digits of precision but no longer crashes. + TotalIPs: "4722366482869645000000", + UsedIPs: "2", }, { SubnetID: "521f47e7-c4fb-452c-b71a-851da38cc571", From f57066b2481ffb30ca4ecaf4b714b54527d6554e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Andr=C3=A9?= Date: Wed, 4 Mar 2026 11:47:24 +0100 Subject: [PATCH 260/353] Prepare v2.11.0 --- CHANGELOG.md | 12 ++++++++++++ provider_client.go | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d53f641b8a..388e8c50b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,15 @@ +## v2.11.0 (2026-03-04) + +* [GH-3602](https://github.com/gophercloud/gophercloud/pull/3602) [v2] Add PCIAddress field to baremetal InterfaceType +* [GH-3610](https://github.com/gophercloud/gophercloud/pull/3610) [v2] Networking V2: Added support for ML2 extension port_trusted_vif +* [GH-3611](https://github.com/gophercloud/gophercloud/pull/3611) [v2] networking/v2/layer3/routers: Add external gateways management +* [GH-3625](https://github.com/gophercloud/gophercloud/pull/3625) [v2] Use jimmy amphora in octavia job +* [GH-3629](https://github.com/gophercloud/gophercloud/pull/3629) [v2] Add a new Ironic field representing node health to Gophercloud +* [GH-3630](https://github.com/gophercloud/gophercloud/pull/3630) [v2] Bump go +* [GH-3632](https://github.com/gophercloud/gophercloud/pull/3632) [v2] CI: Fix fwaas jobs +* [GH-3633](https://github.com/gophercloud/gophercloud/pull/3633) [v2] Add TSIG key support for OpenStack DNS v2 API +* [GH-3640](https://github.com/gophercloud/gophercloud/pull/3640) [v2] fix: networkipavailabilities: handle scientific notation in IP counts + ## v2.10.0 (2026-01-05) * [GH-3569](https://github.com/gophercloud/gophercloud/pull/3569) identity/role: restore backward compatibility for description diff --git a/provider_client.go b/provider_client.go index a9bde9457c..26e2d8874c 100644 --- a/provider_client.go +++ b/provider_client.go @@ -14,7 +14,7 @@ import ( // DefaultUserAgent is the default User-Agent string set in the request header. const ( - DefaultUserAgent = "gophercloud/v2.10.0" + DefaultUserAgent = "gophercloud/v2.11.0" DefaultMaxBackoffRetries = 60 ) From 74c31fc519afdb8a27fe557d1f7b00465b672246 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Andr=C3=A9?= Date: Tue, 10 Mar 2026 09:20:14 +0100 Subject: [PATCH 261/353] Do not specify go patch version There's no good reason for this, and makes it harder to consume. --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index eb560fd4f4..94309249a1 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/gophercloud/gophercloud/v2 -go 1.25.7 +go 1.25.0 require ( golang.org/x/crypto v0.33.0 From b29b4a42427132eb357b64943b52498283de79df Mon Sep 17 00:00:00 2001 From: jlarriba Date: Tue, 10 Mar 2026 13:07:45 +0100 Subject: [PATCH 262/353] Fix clouds.yaml search path to use XDG convention on all platforms os.UserConfigDir() returns ~/Library/Application Support on macOS, which doesn't match the OpenStack standard. Use XDG_CONFIG_HOME with a ~/.config fallback instead. --- openstack/config/clouds/clouds.go | 12 ++- openstack/config/clouds/clouds_test.go | 113 +++++++++++++++++++++++++ 2 files changed, 122 insertions(+), 3 deletions(-) diff --git a/openstack/config/clouds/clouds.go b/openstack/config/clouds/clouds.go index 1466058097..73dd70931c 100644 --- a/openstack/config/clouds/clouds.go +++ b/openstack/config/clouds/clouds.go @@ -81,9 +81,15 @@ func Parse(opts ...ParseOption) (gophercloud.AuthOptions, gophercloud.EndpointOp if err != nil { return gophercloud.AuthOptions{}, gophercloud.EndpointOpts{}, nil, fmt.Errorf("failed to get the current working directory: %w", err) } - userConfig, err := os.UserConfigDir() - if err != nil { - return gophercloud.AuthOptions{}, gophercloud.EndpointOpts{}, nil, fmt.Errorf("failed to get the user config directory: %w", err) + // Use XDG_CONFIG_HOME or fall back to ~/.config, matching the + // OpenStack convention for clouds.yaml location on all platforms. + userConfig := os.Getenv("XDG_CONFIG_HOME") + if userConfig == "" { + homeDir, err := os.UserHomeDir() + if err != nil { + return gophercloud.AuthOptions{}, gophercloud.EndpointOpts{}, nil, fmt.Errorf("failed to get the user home directory: %w", err) + } + userConfig = path.Join(homeDir, ".config") } options.locations = []string{path.Join(cwd, "clouds.yaml"), path.Join(userConfig, "openstack", "clouds.yaml"), path.Join("/etc", "openstack", "clouds.yaml")} } diff --git a/openstack/config/clouds/clouds_test.go b/openstack/config/clouds/clouds_test.go index 384aea92d8..bd705833af 100644 --- a/openstack/config/clouds/clouds_test.go +++ b/openstack/config/clouds/clouds_test.go @@ -173,6 +173,119 @@ func TestParse(t *testing.T) { } }) + t.Run("uses XDG_CONFIG_HOME for clouds.yaml location", func(t *testing.T) { + const cloudsYAML = `clouds: + gophercloud-test: + auth: + auth_url: https://example.com/xdg-config:13000` + + // Create a temp dir to use as XDG_CONFIG_HOME with clouds.yaml inside. + xdgDir, err := os.MkdirTemp(os.TempDir(), tempDirPrefix) + if err != nil { + t.Fatalf("unable to create a temporary directory: %v", err) + } + defer rmTmpDirOrPanic(xdgDir) + + openstackDir := path.Join(xdgDir, "openstack") + if err := os.MkdirAll(openstackDir, 0755); err != nil { + t.Fatalf("unable to create openstack config directory: %v", err) + } + if err := os.WriteFile(path.Join(openstackDir, "clouds.yaml"), []byte(cloudsYAML), 0644); err != nil { + t.Fatalf("unable to create a mock clouds.yaml file: %v", err) + } + + // Change to an empty temp dir so cwd has no clouds.yaml. + emptyDir, err := os.MkdirTemp(os.TempDir(), tempDirPrefix) + if err != nil { + t.Fatalf("unable to create a temporary directory: %v", err) + } + defer rmTmpDirOrPanic(emptyDir) + + cwd, err := os.Getwd() + if err != nil { + t.Fatalf("unable to determine the current working directory: %v", err) + } + if err := os.Chdir(emptyDir); err != nil { + t.Fatalf("unable to move to a temporary directory: %v", err) + } + defer func() { + if err := os.Chdir(cwd); err != nil { + panic("unable to reset the current working directory: " + err.Error()) + } + }() + + t.Setenv("XDG_CONFIG_HOME", xdgDir) + t.Setenv("OS_CLIENT_CONFIG_FILE", "") + + ao, _, _, err := clouds.Parse( + clouds.WithCloudName("gophercloud-test"), + ) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + + if got := ao.IdentityEndpoint; got != "https://example.com/xdg-config:13000" { + t.Errorf("unexpected identity endpoint: %q", got) + } + }) + + t.Run("falls back to ~/.config when XDG_CONFIG_HOME is not set", func(t *testing.T) { + const cloudsYAML = `clouds: + gophercloud-test: + auth: + auth_url: https://example.com/home-config:13000` + + // Create a temp dir to use as HOME with clouds.yaml in .config/openstack/. + homeDir, err := os.MkdirTemp(os.TempDir(), tempDirPrefix) + if err != nil { + t.Fatalf("unable to create a temporary directory: %v", err) + } + defer rmTmpDirOrPanic(homeDir) + + openstackDir := path.Join(homeDir, ".config", "openstack") + if err := os.MkdirAll(openstackDir, 0755); err != nil { + t.Fatalf("unable to create openstack config directory: %v", err) + } + if err := os.WriteFile(path.Join(openstackDir, "clouds.yaml"), []byte(cloudsYAML), 0644); err != nil { + t.Fatalf("unable to create a mock clouds.yaml file: %v", err) + } + + // Change to an empty temp dir so cwd has no clouds.yaml. + emptyDir, err := os.MkdirTemp(os.TempDir(), tempDirPrefix) + if err != nil { + t.Fatalf("unable to create a temporary directory: %v", err) + } + defer rmTmpDirOrPanic(emptyDir) + + cwd, err := os.Getwd() + if err != nil { + t.Fatalf("unable to determine the current working directory: %v", err) + } + if err := os.Chdir(emptyDir); err != nil { + t.Fatalf("unable to move to a temporary directory: %v", err) + } + defer func() { + if err := os.Chdir(cwd); err != nil { + panic("unable to reset the current working directory: " + err.Error()) + } + }() + + t.Setenv("XDG_CONFIG_HOME", "") + t.Setenv("HOME", homeDir) + t.Setenv("OS_CLIENT_CONFIG_FILE", "") + + ao, _, _, err := clouds.Parse( + clouds.WithCloudName("gophercloud-test"), + ) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + + if got := ao.IdentityEndpoint; got != "https://example.com/home-config:13000" { + t.Errorf("unexpected identity endpoint: %q", got) + } + }) + t.Run("falls back to the next location if clouds.yaml is not found", func(t *testing.T) { const cloudsYAML1 = `clouds: gophercloud-test: From b878e840aff3889f7bb62ca6fcd30c5b2bc9a5b0 Mon Sep 17 00:00:00 2001 From: Juan Larriba Date: Mon, 23 Mar 2026 11:09:25 +0100 Subject: [PATCH 263/353] Use jammy amphora in octavia epoxy job --- .github/workflows/functional-loadbalancer.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/functional-loadbalancer.yaml b/.github/workflows/functional-loadbalancer.yaml index b486082a44..4a3a15a4de 100644 --- a/.github/workflows/functional-loadbalancer.yaml +++ b/.github/workflows/functional-loadbalancer.yaml @@ -33,6 +33,9 @@ jobs: - name: "epoxy" openstack_version: "stable/2025.1" ubuntu_version: "24.04" + devstack_conf_overrides: | + LIBVIRT_CPU_MODE=host-passthrough + OCTAVIA_AMP_DISTRIBUTION_RELEASE_ID=jammy - name: "dalmatian" openstack_version: "stable/2024.2" ubuntu_version: "22.04" From 208809b795ad7f3592a170d29143635d6252ff66 Mon Sep 17 00:00:00 2001 From: Dominik Danelski Date: Wed, 25 Mar 2026 13:18:31 +0100 Subject: [PATCH 264/353] Implement READ operations on Placement traits Related: #526 API reference: https://docs.openstack.org/api-ref/placement/#traits Code reference: https://github.com/openstack/placement/blob/stable/2025.1/placement/handlers/trait.py#L108-L124 https://github.com/openstack/placement/blob/stable/2025.1/placement/handlers/trait.py#L152-L178 Signed-off-by: Dominik Danelski --- .../openstack/placement/v1/traits_test.go | 98 ++++++++++++++++ openstack/placement/v1/traits/doc.go | 42 +++++++ openstack/placement/v1/traits/requests.go | 60 ++++++++++ openstack/placement/v1/traits/results.go | 38 ++++++ openstack/placement/v1/traits/testing/doc.go | 2 + .../v1/traits/testing/fixtures_test.go | 108 ++++++++++++++++++ .../v1/traits/testing/requests_test.go | 101 ++++++++++++++++ openstack/placement/v1/traits/urls.go | 15 +++ 8 files changed, 464 insertions(+) create mode 100644 internal/acceptance/openstack/placement/v1/traits_test.go create mode 100644 openstack/placement/v1/traits/doc.go create mode 100644 openstack/placement/v1/traits/requests.go create mode 100644 openstack/placement/v1/traits/results.go create mode 100644 openstack/placement/v1/traits/testing/doc.go create mode 100644 openstack/placement/v1/traits/testing/fixtures_test.go create mode 100644 openstack/placement/v1/traits/testing/requests_test.go create mode 100644 openstack/placement/v1/traits/urls.go diff --git a/internal/acceptance/openstack/placement/v1/traits_test.go b/internal/acceptance/openstack/placement/v1/traits_test.go new file mode 100644 index 0000000000..3099da80df --- /dev/null +++ b/internal/acceptance/openstack/placement/v1/traits_test.go @@ -0,0 +1,98 @@ +//go:build acceptance || placement || traits + +package v1 + +import ( + "context" + "net/http" + "slices" + "strings" + "testing" + + "github.com/gophercloud/gophercloud/v2" + "github.com/gophercloud/gophercloud/v2/internal/acceptance/clients" + "github.com/gophercloud/gophercloud/v2/openstack/placement/v1/traits" + th "github.com/gophercloud/gophercloud/v2/testhelper" +) + +func TestTraitsList(t *testing.T) { + // The Traits API requires microversion 1.6 or later + clients.SkipRelease(t, "stable/mitaka") + clients.SkipRelease(t, "stable/newton") + clients.SkipRelease(t, "stable/ocata") + + client, err := clients.NewPlacementV1Client() + th.AssertNoErr(t, err) + + client.Microversion = "1.6" + + allPages, err := traits.List(client, traits.ListOpts{}).AllPages(context.TODO()) + th.AssertNoErr(t, err) + + allTraits, err := traits.ExtractTraits(allPages) + th.AssertNoErr(t, err) + + // Ensure COMPUTE_NODE is in the list + // os-traits never removes traits, so this should always pass + th.AssertEquals(t, true, slices.Contains(allTraits, "COMPUTE_NODE")) +} + +func TestTraitGet(t *testing.T) { + // The Traits API requires microversion 1.6 or later + clients.SkipRelease(t, "stable/mitaka") + clients.SkipRelease(t, "stable/newton") + clients.SkipRelease(t, "stable/ocata") + + client, err := clients.NewPlacementV1Client() + th.AssertNoErr(t, err) + + client.Microversion = "1.6" + + // Verify that Get confirms the existence of the COMPUTE_NODE trait + // os-traits never removes traits, so this should always pass + err = traits.Get(context.TODO(), client, "COMPUTE_NODE").ExtractErr() + th.AssertNoErr(t, err) +} + +func TestTraitGetNegative(t *testing.T) { + // The Traits API requires microversion 1.6 or later + clients.SkipRelease(t, "stable/mitaka") + clients.SkipRelease(t, "stable/newton") + clients.SkipRelease(t, "stable/ocata") + + client, err := clients.NewPlacementV1Client() + th.AssertNoErr(t, err) + + client.Microversion = "1.6" + + // Verify that Get returns an error for a non-existent trait + err = traits.Get(context.TODO(), client, "CUSTOM_NON_EXISTENT_TRAIT").ExtractErr() + th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusNotFound)) +} + +func TestTraitsListFiltering(t *testing.T) { + // The Traits API requires microversion 1.6 or later + clients.SkipRelease(t, "stable/mitaka") + clients.SkipRelease(t, "stable/newton") + clients.SkipRelease(t, "stable/ocata") + + client, err := clients.NewPlacementV1Client() + th.AssertNoErr(t, err) + + client.Microversion = "1.6" + + // os-traits never removes traits, so this should always pass + listOpts := traits.ListOpts{ + Name: "startswith:HW_", + } + + allPages, err := traits.List(client, listOpts).AllPages(context.TODO()) + th.AssertNoErr(t, err) + + filteredTraits, err := traits.ExtractTraits(allPages) + th.AssertNoErr(t, err) + + for _, trait := range filteredTraits { + th.AssertEquals(t, true, strings.HasPrefix(trait, "HW_")) + } +} diff --git a/openstack/placement/v1/traits/doc.go b/openstack/placement/v1/traits/doc.go new file mode 100644 index 0000000000..e11afc158e --- /dev/null +++ b/openstack/placement/v1/traits/doc.go @@ -0,0 +1,42 @@ +/* +Package traits lists traits from the OpenStack Placement service. + +Traits API requests are available starting from microversion 1.6. + +Example to list traits + + placementClient.Microversion = "1.6" + + allPages, err := traits.List(placementClient, traits.ListOpts{}).AllPages(context.TODO()) + if err != nil { + panic(err) + } + + allTraits, err := traits.ExtractTraits(allPages) + if err != nil { + panic(err) + } + + for _, t := range allTraits { + fmt.Println(t) + } + +Example to check if a trait exists + + placementClient.Microversion = "1.6" + + traitName := "CUSTOM_HW_FPGA_CLASS1" + err := traits.Get(context.TODO(), placementClient, traitName).ExtractErr() + if err != nil { + if gophercloud.ResponseCodeIs(err, http.StatusNotFound) { + // 404 Not Found - The trait does not exist + fmt.Println("Trait does not exist.") + } else { + // Another error occurred + panic(err) + } + } else { + fmt.Println("Trait exists!") + } +*/ +package traits diff --git a/openstack/placement/v1/traits/requests.go b/openstack/placement/v1/traits/requests.go new file mode 100644 index 0000000000..82fd8a0dbb --- /dev/null +++ b/openstack/placement/v1/traits/requests.go @@ -0,0 +1,60 @@ +package traits + +import ( + "context" + + "github.com/gophercloud/gophercloud/v2" + "github.com/gophercloud/gophercloud/v2/pagination" +) + +// ListOptsBuilder allows extensions to add additional parameters to +// the List request. +type ListOptsBuilder interface { + ToTraitListQuery() (string, error) +} + +// ListOpts allows the filtering of traits. Filtering is achieved by passing in struct +// field values that map to the trait attributes you want to see returned. +type ListOpts struct { + // Name is a string used to filter traits by name. + // It supports startswith operator to filter the traits whose name begins with + // a specific prefix, e.g. name=startswith:CUSTOM + // in operator filters the traits whose name is in the specified list, + // e.g. name=in:HW_CPU_X86_AVX,HW_CPU_X86_SSE,HW_CPU_X86_INVALID_FEATURE + Name string `q:"name"` + + // Associated is a boolean used to filter traits by whether they are associated with + // at least one resource provider. + Associated *bool `q:"associated"` +} + +// ToTraitListQuery formats a ListOpts into a query string. +func (opts ListOpts) ToTraitListQuery() (string, error) { + q, err := gophercloud.BuildQueryString(opts) + return q.String(), err +} + +// List retrieves a list of traits. +func List(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { + url := listURL(client) + + if opts != nil { + query, err := opts.ToTraitListQuery() + if err != nil { + return pagination.Pager{Err: err} + } + url += query + } + return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { + return TraitsPage{pagination.SinglePageBase(r)} + }) +} + +// Get confirms the existence of a trait. +func Get(ctx context.Context, client *gophercloud.ServiceClient, traitName string) (r GetResult) { + resp, err := client.Get(ctx, getURL(client, traitName), nil, &gophercloud.RequestOpts{ + OkCodes: []int{204}, + }) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} diff --git a/openstack/placement/v1/traits/results.go b/openstack/placement/v1/traits/results.go new file mode 100644 index 0000000000..5e638cf226 --- /dev/null +++ b/openstack/placement/v1/traits/results.go @@ -0,0 +1,38 @@ +package traits + +import ( + "github.com/gophercloud/gophercloud/v2" + "github.com/gophercloud/gophercloud/v2/pagination" +) + +// GetResult is the response from a Get operation. Call its ExtractErr to +// determine if the request succeeded or failed. +type GetResult struct { + gophercloud.ErrResult +} + +// TraitsPage contains a single page of all traits from a List call. +type TraitsPage struct { + pagination.SinglePageBase +} + +// IsEmpty satisfies the IsEmpty method of the Page interface. It returns true +// if a List contains no results. +func (r TraitsPage) IsEmpty() (bool, error) { + if r.StatusCode == 204 { + return true, nil + } + + traits, err := ExtractTraits(r) + return len(traits) == 0, err +} + +// ExtractTraits takes a List result and extracts the collection of traits +// returned by the API. +func ExtractTraits(p pagination.Page) ([]string, error) { + var s struct { + Traits []string `json:"traits"` + } + err := (p.(TraitsPage)).ExtractInto(&s) + return s.Traits, err +} diff --git a/openstack/placement/v1/traits/testing/doc.go b/openstack/placement/v1/traits/testing/doc.go new file mode 100644 index 0000000000..3231ffdf0e --- /dev/null +++ b/openstack/placement/v1/traits/testing/doc.go @@ -0,0 +1,2 @@ +// placement traits +package testing diff --git a/openstack/placement/v1/traits/testing/fixtures_test.go b/openstack/placement/v1/traits/testing/fixtures_test.go new file mode 100644 index 0000000000..6c37649d18 --- /dev/null +++ b/openstack/placement/v1/traits/testing/fixtures_test.go @@ -0,0 +1,108 @@ +package testing + +import ( + "fmt" + "net/http" + "testing" + + th "github.com/gophercloud/gophercloud/v2/testhelper" + "github.com/gophercloud/gophercloud/v2/testhelper/client" +) + +const PresentTrait = "CUSTOM_HW_FPGA_CLASS1" +const AbsentTrait = "NON_EXISTENT_TRAIT" + +const TraitsListResultAll = ` +{ + "traits": [ + "CUSTOM_HW_FPGA_CLASS1", + "CUSTOM_HW_FPGA_CLASS2", + "HW_CPU_X86_AVX" + ] +}` + +const TraitsListFilteredCustomResult = ` +{ + "traits": [ + "CUSTOM_HW_FPGA_CLASS1", + "CUSTOM_HW_FPGA_CLASS2" + ] +}` + +const TraitsListFilteredAssociatedResult = TraitsListResultAll + +var ExpectedTraitsListResultAll = []string{ + "CUSTOM_HW_FPGA_CLASS1", + "CUSTOM_HW_FPGA_CLASS2", + "HW_CPU_X86_AVX", +} + +var ExpectedTraitsListFilteredNameResult = []string{ + "CUSTOM_HW_FPGA_CLASS1", + "CUSTOM_HW_FPGA_CLASS2", +} + +var ExpectedTraitsListFilteredAssociatedResult = ExpectedTraitsListResultAll + +func HandleListTraitsAll(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/traits", + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + + fmt.Fprint(w, TraitsListResultAll) + }) +} + +func HandleListTraitsFilteredName(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/traits", + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + th.TestFormValues(t, r, map[string]string{"name": "startswith:CUSTOM"}) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + + fmt.Fprint(w, TraitsListFilteredCustomResult) + }) +} + +func HandleListTraitsFilteredAssociated(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/traits", + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + th.TestFormValues(t, r, map[string]string{"associated": "true"}) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + + fmt.Fprint(w, TraitsListFilteredAssociatedResult) + }) +} + +func HandleGetTraitSuccess(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/traits/"+PresentTrait, + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.WriteHeader(http.StatusNoContent) + }) +} + +func HandleGetTraitNotFound(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/traits/"+AbsentTrait, + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.WriteHeader(http.StatusNotFound) + }) +} diff --git a/openstack/placement/v1/traits/testing/requests_test.go b/openstack/placement/v1/traits/testing/requests_test.go new file mode 100644 index 0000000000..39642afb91 --- /dev/null +++ b/openstack/placement/v1/traits/testing/requests_test.go @@ -0,0 +1,101 @@ +package testing + +import ( + "context" + "net/http" + "testing" + + "github.com/gophercloud/gophercloud/v2" + "github.com/gophercloud/gophercloud/v2/openstack/placement/v1/traits" + + "github.com/gophercloud/gophercloud/v2/pagination" + th "github.com/gophercloud/gophercloud/v2/testhelper" + "github.com/gophercloud/gophercloud/v2/testhelper/client" +) + +func TestListTraitsAll(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleListTraitsAll(t, fakeServer) + + count := 0 + err := traits.List(client.ServiceClient(fakeServer), traits.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + count++ + + actual, err := traits.ExtractTraits(page) + th.AssertNoErr(t, err) + th.AssertDeepEquals(t, ExpectedTraitsListResultAll, actual) + + return true, nil + }) + + th.AssertNoErr(t, err) + + th.AssertEquals(t, 1, count) +} + +func TestListTraitsFilteredName(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleListTraitsFilteredName(t, fakeServer) + + count := 0 + err := traits.List(client.ServiceClient(fakeServer), traits.ListOpts{Name: "startswith:CUSTOM"}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + count++ + + actual, err := traits.ExtractTraits(page) + th.AssertNoErr(t, err) + th.AssertDeepEquals(t, ExpectedTraitsListFilteredNameResult, actual) + + return true, nil + }) + + th.AssertNoErr(t, err) + + th.AssertEquals(t, 1, count) +} + +func TestListTraitsFilteredAssociated(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleListTraitsFilteredAssociated(t, fakeServer) + + count := 0 + associated := true + err := traits.List(client.ServiceClient(fakeServer), traits.ListOpts{Associated: &associated}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + count++ + + actual, err := traits.ExtractTraits(page) + th.AssertNoErr(t, err) + th.AssertDeepEquals(t, ExpectedTraitsListFilteredAssociatedResult, actual) + + return true, nil + }) + + th.AssertNoErr(t, err) + + th.AssertEquals(t, 1, count) +} + +func TestGetTraitSuccess(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleGetTraitSuccess(t, fakeServer) + + err := traits.Get(context.TODO(), client.ServiceClient(fakeServer), PresentTrait).ExtractErr() + th.AssertNoErr(t, err) +} + +func TestGetTraitNotFound(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleGetTraitNotFound(t, fakeServer) + + err := traits.Get(context.TODO(), client.ServiceClient(fakeServer), AbsentTrait).ExtractErr() + th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusNotFound)) +} diff --git a/openstack/placement/v1/traits/urls.go b/openstack/placement/v1/traits/urls.go new file mode 100644 index 0000000000..a6ea7757a1 --- /dev/null +++ b/openstack/placement/v1/traits/urls.go @@ -0,0 +1,15 @@ +package traits + +import "github.com/gophercloud/gophercloud/v2" + +const ( + apiName = "traits" +) + +func listURL(client *gophercloud.ServiceClient) string { + return client.ServiceURL(apiName) +} + +func getURL(client *gophercloud.ServiceClient, traitName string) string { + return client.ServiceURL(apiName, traitName) +} From 8e86d1e0a85f8307f0019b320ec9fa1f7eca3483 Mon Sep 17 00:00:00 2001 From: Dominik Danelski Date: Fri, 27 Mar 2026 13:11:08 +0100 Subject: [PATCH 265/353] Use SkipReleasesBelow instead of SkipRelease in traits_test Signed-off-by: Dominik Danelski --- .../openstack/placement/v1/traits_test.go | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/internal/acceptance/openstack/placement/v1/traits_test.go b/internal/acceptance/openstack/placement/v1/traits_test.go index 3099da80df..15775f5281 100644 --- a/internal/acceptance/openstack/placement/v1/traits_test.go +++ b/internal/acceptance/openstack/placement/v1/traits_test.go @@ -17,9 +17,7 @@ import ( func TestTraitsList(t *testing.T) { // The Traits API requires microversion 1.6 or later - clients.SkipRelease(t, "stable/mitaka") - clients.SkipRelease(t, "stable/newton") - clients.SkipRelease(t, "stable/ocata") + clients.SkipReleasesBelow(t, "stable/pike") client, err := clients.NewPlacementV1Client() th.AssertNoErr(t, err) @@ -39,9 +37,7 @@ func TestTraitsList(t *testing.T) { func TestTraitGet(t *testing.T) { // The Traits API requires microversion 1.6 or later - clients.SkipRelease(t, "stable/mitaka") - clients.SkipRelease(t, "stable/newton") - clients.SkipRelease(t, "stable/ocata") + clients.SkipReleasesBelow(t, "stable/pike") client, err := clients.NewPlacementV1Client() th.AssertNoErr(t, err) @@ -56,9 +52,7 @@ func TestTraitGet(t *testing.T) { func TestTraitGetNegative(t *testing.T) { // The Traits API requires microversion 1.6 or later - clients.SkipRelease(t, "stable/mitaka") - clients.SkipRelease(t, "stable/newton") - clients.SkipRelease(t, "stable/ocata") + clients.SkipReleasesBelow(t, "stable/pike") client, err := clients.NewPlacementV1Client() th.AssertNoErr(t, err) @@ -72,9 +66,7 @@ func TestTraitGetNegative(t *testing.T) { func TestTraitsListFiltering(t *testing.T) { // The Traits API requires microversion 1.6 or later - clients.SkipRelease(t, "stable/mitaka") - clients.SkipRelease(t, "stable/newton") - clients.SkipRelease(t, "stable/ocata") + clients.SkipReleasesBelow(t, "stable/pike") client, err := clients.NewPlacementV1Client() th.AssertNoErr(t, err) From c69acc4374366aca5d6ad34f8cb57550ceeeb481 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Andr=C3=A9?= Date: Tue, 31 Mar 2026 16:26:23 +0200 Subject: [PATCH 266/353] ci: fix unsound condition in label-issue workflow The condition was comparing the string representations of two separate expression expansions with a literal == operator, which always evaluates to true in GitHub Actions. Move the comparison inside a single expression to perform an actual equality check. Reported by zizmor (excessive-permissions / unpinned-uses were flagged on the same pass). --- .github/workflows/label-issue.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/label-issue.yaml b/.github/workflows/label-issue.yaml index 45ab4cbe34..cb5e84e897 100644 --- a/.github/workflows/label-issue.yaml +++ b/.github/workflows/label-issue.yaml @@ -7,7 +7,7 @@ on: jobs: clear_needinfo: name: Clear needinfo - if: ${{ github.event.issue.user.login }} == ${{ github.event.comment.user.login }} + if: ${{ github.event.issue.user.login == github.event.comment.user.login }} runs-on: ubuntu-latest permissions: issues: write From 87609fdbbe7dcac495226ec08698182cc6542ed4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Andr=C3=A9?= Date: Tue, 31 Mar 2026 16:27:40 +0200 Subject: [PATCH 267/353] ci: add persist-credentials: false to all checkout steps Prevent the GITHUB_TOKEN from being persisted in the local git config after checkout. This limits the blast radius if a subsequent step is compromised, since the token will not be available through the git credential helper. Reported by zizmor (artipacked). --- .github/workflows/codeql-analysis.yaml | 2 ++ .github/workflows/ensure-labels.yaml | 2 ++ .github/workflows/functional-baremetal.yaml | 2 ++ .github/workflows/functional-basic.yaml | 2 ++ .github/workflows/functional-blockstorage.yaml | 2 ++ .github/workflows/functional-compute.yaml | 2 ++ .github/workflows/functional-containerinfra.yaml | 2 ++ .github/workflows/functional-dns.yaml | 2 ++ .github/workflows/functional-fwaas_v2.yaml | 2 ++ .github/workflows/functional-identity.yaml | 2 ++ .github/workflows/functional-image.yaml | 2 ++ .github/workflows/functional-keymanager.yaml | 2 ++ .github/workflows/functional-loadbalancer.yaml | 2 ++ .github/workflows/functional-messaging.yaml | 2 ++ .github/workflows/functional-networking.yaml | 2 ++ .github/workflows/functional-objectstorage.yaml | 2 ++ .github/workflows/functional-orchestration.yaml | 2 ++ .github/workflows/functional-placement.yaml | 2 ++ .github/workflows/functional-sharedfilesystems.yaml | 2 ++ .github/workflows/functional-workflow.yaml | 2 ++ .github/workflows/label-pr.yaml | 1 + .github/workflows/lint.yaml | 2 ++ .github/workflows/unit.yaml | 2 ++ 23 files changed, 45 insertions(+) diff --git a/.github/workflows/codeql-analysis.yaml b/.github/workflows/codeql-analysis.yaml index 587f803f11..816fbef02f 100644 --- a/.github/workflows/codeql-analysis.yaml +++ b/.github/workflows/codeql-analysis.yaml @@ -19,6 +19,8 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v5 + with: + persist-credentials: false - name: Setup Go uses: actions/setup-go@v5 diff --git a/.github/workflows/ensure-labels.yaml b/.github/workflows/ensure-labels.yaml index fbabe2bf6d..85fac061d8 100644 --- a/.github/workflows/ensure-labels.yaml +++ b/.github/workflows/ensure-labels.yaml @@ -11,6 +11,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v5 + with: + persist-credentials: false - uses: micnncim/action-label-syncer@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/functional-baremetal.yaml b/.github/workflows/functional-baremetal.yaml index 9bc2a44a5e..13a8146f87 100644 --- a/.github/workflows/functional-baremetal.yaml +++ b/.github/workflows/functional-baremetal.yaml @@ -33,6 +33,8 @@ jobs: steps: - name: Checkout Gophercloud uses: actions/checkout@v5 + with: + persist-credentials: false - name: Work around broken dnsmasq run: sudo apt-get purge -y dnsmasq-base - name: Deploy devstack diff --git a/.github/workflows/functional-basic.yaml b/.github/workflows/functional-basic.yaml index 4f0175b5df..2a384b0ea4 100644 --- a/.github/workflows/functional-basic.yaml +++ b/.github/workflows/functional-basic.yaml @@ -28,6 +28,8 @@ jobs: steps: - name: Checkout Gophercloud uses: actions/checkout@v5 + with: + persist-credentials: false - name: Deploy devstack uses: gophercloud/devstack-action@v0.19 with: diff --git a/.github/workflows/functional-blockstorage.yaml b/.github/workflows/functional-blockstorage.yaml index fa64f8a1c0..7d8fac4d67 100644 --- a/.github/workflows/functional-blockstorage.yaml +++ b/.github/workflows/functional-blockstorage.yaml @@ -33,6 +33,8 @@ jobs: steps: - name: Checkout Gophercloud uses: actions/checkout@v5 + with: + persist-credentials: false - name: Deploy devstack uses: gophercloud/devstack-action@v0.19 with: diff --git a/.github/workflows/functional-compute.yaml b/.github/workflows/functional-compute.yaml index a82177740a..e0db371bde 100644 --- a/.github/workflows/functional-compute.yaml +++ b/.github/workflows/functional-compute.yaml @@ -33,6 +33,8 @@ jobs: steps: - name: Checkout Gophercloud uses: actions/checkout@v5 + with: + persist-credentials: false - name: Deploy devstack uses: gophercloud/devstack-action@v0.19 with: diff --git a/.github/workflows/functional-containerinfra.yaml b/.github/workflows/functional-containerinfra.yaml index 088c97ae45..dfa01b56ca 100644 --- a/.github/workflows/functional-containerinfra.yaml +++ b/.github/workflows/functional-containerinfra.yaml @@ -54,6 +54,8 @@ jobs: steps: - name: Checkout Gophercloud uses: actions/checkout@v5 + with: + persist-credentials: false - name: Deploy devstack uses: gophercloud/devstack-action@v0.19 with: diff --git a/.github/workflows/functional-dns.yaml b/.github/workflows/functional-dns.yaml index d5f3cac514..f3fda3a51e 100644 --- a/.github/workflows/functional-dns.yaml +++ b/.github/workflows/functional-dns.yaml @@ -39,6 +39,8 @@ jobs: steps: - name: Checkout Gophercloud uses: actions/checkout@v5 + with: + persist-credentials: false - name: Deploy devstack uses: gophercloud/devstack-action@v0.19 with: diff --git a/.github/workflows/functional-fwaas_v2.yaml b/.github/workflows/functional-fwaas_v2.yaml index 7e75ce8405..4f14e717f7 100644 --- a/.github/workflows/functional-fwaas_v2.yaml +++ b/.github/workflows/functional-fwaas_v2.yaml @@ -37,6 +37,8 @@ jobs: steps: - name: Checkout Gophercloud uses: actions/checkout@v5 + with: + persist-credentials: false - name: Create additional neutron policies run: | mkdir /tmp/neutron-policies diff --git a/.github/workflows/functional-identity.yaml b/.github/workflows/functional-identity.yaml index bbbe99b446..4731983dd3 100644 --- a/.github/workflows/functional-identity.yaml +++ b/.github/workflows/functional-identity.yaml @@ -33,6 +33,8 @@ jobs: steps: - name: Checkout Gophercloud uses: actions/checkout@v5 + with: + persist-credentials: false - name: Deploy devstack uses: gophercloud/devstack-action@v0.19 with: diff --git a/.github/workflows/functional-image.yaml b/.github/workflows/functional-image.yaml index 39a3dd681c..95e8483cae 100644 --- a/.github/workflows/functional-image.yaml +++ b/.github/workflows/functional-image.yaml @@ -33,6 +33,8 @@ jobs: steps: - name: Checkout Gophercloud uses: actions/checkout@v5 + with: + persist-credentials: false - name: Deploy devstack uses: gophercloud/devstack-action@v0.19 with: diff --git a/.github/workflows/functional-keymanager.yaml b/.github/workflows/functional-keymanager.yaml index 01e57bd3e7..2aaae3cf4f 100644 --- a/.github/workflows/functional-keymanager.yaml +++ b/.github/workflows/functional-keymanager.yaml @@ -45,6 +45,8 @@ jobs: steps: - name: Checkout Gophercloud uses: actions/checkout@v5 + with: + persist-credentials: false - name: Deploy devstack uses: gophercloud/devstack-action@v0.19 with: diff --git a/.github/workflows/functional-loadbalancer.yaml b/.github/workflows/functional-loadbalancer.yaml index 4a3a15a4de..596b584346 100644 --- a/.github/workflows/functional-loadbalancer.yaml +++ b/.github/workflows/functional-loadbalancer.yaml @@ -44,6 +44,8 @@ jobs: steps: - name: Checkout Gophercloud uses: actions/checkout@v5 + with: + persist-credentials: false - name: Deploy devstack uses: gophercloud/devstack-action@v0.19 with: diff --git a/.github/workflows/functional-messaging.yaml b/.github/workflows/functional-messaging.yaml index 0f099084a4..7d7aced3fe 100644 --- a/.github/workflows/functional-messaging.yaml +++ b/.github/workflows/functional-messaging.yaml @@ -33,6 +33,8 @@ jobs: steps: - name: Checkout Gophercloud uses: actions/checkout@v5 + with: + persist-credentials: false - name: Deploy devstack uses: gophercloud/devstack-action@v0.19 with: diff --git a/.github/workflows/functional-networking.yaml b/.github/workflows/functional-networking.yaml index 6f92da2456..5503d2ca1c 100644 --- a/.github/workflows/functional-networking.yaml +++ b/.github/workflows/functional-networking.yaml @@ -33,6 +33,8 @@ jobs: steps: - name: Checkout Gophercloud uses: actions/checkout@v5 + with: + persist-credentials: false - name: Create additional neutron policies run: | mkdir /tmp/neutron-policies diff --git a/.github/workflows/functional-objectstorage.yaml b/.github/workflows/functional-objectstorage.yaml index d1b357d3b3..b7eace3aa9 100644 --- a/.github/workflows/functional-objectstorage.yaml +++ b/.github/workflows/functional-objectstorage.yaml @@ -33,6 +33,8 @@ jobs: steps: - name: Checkout Gophercloud uses: actions/checkout@v5 + with: + persist-credentials: false - name: Deploy devstack uses: gophercloud/devstack-action@v0.19 with: diff --git a/.github/workflows/functional-orchestration.yaml b/.github/workflows/functional-orchestration.yaml index 402a21c330..f5388cd0e5 100644 --- a/.github/workflows/functional-orchestration.yaml +++ b/.github/workflows/functional-orchestration.yaml @@ -33,6 +33,8 @@ jobs: steps: - name: Checkout Gophercloud uses: actions/checkout@v5 + with: + persist-credentials: false - name: Deploy devstack uses: gophercloud/devstack-action@v0.19 with: diff --git a/.github/workflows/functional-placement.yaml b/.github/workflows/functional-placement.yaml index 4b14c2a2d1..039b56122d 100644 --- a/.github/workflows/functional-placement.yaml +++ b/.github/workflows/functional-placement.yaml @@ -33,6 +33,8 @@ jobs: steps: - name: Checkout Gophercloud uses: actions/checkout@v5 + with: + persist-credentials: false - name: Deploy devstack uses: gophercloud/devstack-action@v0.19 with: diff --git a/.github/workflows/functional-sharedfilesystems.yaml b/.github/workflows/functional-sharedfilesystems.yaml index 5a9b55d417..716b0745d0 100644 --- a/.github/workflows/functional-sharedfilesystems.yaml +++ b/.github/workflows/functional-sharedfilesystems.yaml @@ -39,6 +39,8 @@ jobs: steps: - name: Checkout Gophercloud uses: actions/checkout@v5 + with: + persist-credentials: false - name: Deploy devstack uses: gophercloud/devstack-action@v0.19 with: diff --git a/.github/workflows/functional-workflow.yaml b/.github/workflows/functional-workflow.yaml index b690d7f07b..2a25d2f827 100644 --- a/.github/workflows/functional-workflow.yaml +++ b/.github/workflows/functional-workflow.yaml @@ -36,6 +36,8 @@ jobs: steps: - name: Checkout Gophercloud uses: actions/checkout@v5 + with: + persist-credentials: false - name: Deploy devstack uses: gophercloud/devstack-action@v0.19 with: diff --git a/.github/workflows/label-pr.yaml b/.github/workflows/label-pr.yaml index 0e38e980f0..4ed751a437 100644 --- a/.github/workflows/label-pr.yaml +++ b/.github/workflows/label-pr.yaml @@ -15,6 +15,7 @@ jobs: fetch-depth: 0 ref: ${{ github.event.pull_request.head.sha }} token: ${{ secrets.GITHUB_TOKEN }} + persist-credentials: false - name: Rebase the PR against origin/github.base_ref to ensure actual API compatibility run: | diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index a5b02146f7..a1484a9042 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -10,6 +10,8 @@ jobs: steps: - name: Checkout Gophercloud uses: actions/checkout@v5 + with: + persist-credentials: false - uses: actions/setup-go@v5 with: go-version-file: 'go.mod' diff --git a/.github/workflows/unit.yaml b/.github/workflows/unit.yaml index c462a6dd27..ab1a61fed0 100644 --- a/.github/workflows/unit.yaml +++ b/.github/workflows/unit.yaml @@ -15,6 +15,8 @@ jobs: steps: - name: Checkout Gophercloud uses: actions/checkout@v5 + with: + persist-credentials: false - name: Setup Go uses: actions/setup-go@v5 with: From c3826f74c68957755d4a7117fbd0d72af6cd81d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Andr=C3=A9?= Date: Tue, 31 Mar 2026 16:29:01 +0200 Subject: [PATCH 268/353] ci: add explicit permissions to all workflow jobs Apply the principle of least privilege by adding explicit permissions blocks to every job that was relying on default (overly broad) permissions. Each job now declares only the permissions it needs. Reported by zizmor (excessive-permissions). --- .github/workflows/backport_v1.yaml | 4 ++++ .github/workflows/check-pr-labels.yaml | 1 + .github/workflows/ensure-labels.yaml | 3 +++ .github/workflows/functional-baremetal.yaml | 2 ++ .github/workflows/functional-basic.yaml | 2 ++ .github/workflows/functional-blockstorage.yaml | 2 ++ .github/workflows/functional-compute.yaml | 2 ++ .github/workflows/functional-containerinfra.yaml | 2 ++ .github/workflows/functional-dns.yaml | 2 ++ .github/workflows/functional-fwaas_v2.yaml | 2 ++ .github/workflows/functional-identity.yaml | 2 ++ .github/workflows/functional-image.yaml | 2 ++ .github/workflows/functional-keymanager.yaml | 2 ++ .github/workflows/functional-loadbalancer.yaml | 2 ++ .github/workflows/functional-messaging.yaml | 2 ++ .github/workflows/functional-networking.yaml | 2 ++ .github/workflows/functional-objectstorage.yaml | 2 ++ .github/workflows/functional-orchestration.yaml | 2 ++ .github/workflows/functional-placement.yaml | 2 ++ .github/workflows/functional-sharedfilesystems.yaml | 2 ++ .github/workflows/functional-workflow.yaml | 2 ++ .github/workflows/label-pr.yaml | 4 ++++ 22 files changed, 48 insertions(+) diff --git a/.github/workflows/backport_v1.yaml b/.github/workflows/backport_v1.yaml index 40714a4582..3af4654b80 100644 --- a/.github/workflows/backport_v1.yaml +++ b/.github/workflows/backport_v1.yaml @@ -9,6 +9,10 @@ on: jobs: backporting: name: "Backporting" + permissions: + contents: read + issues: write + pull-requests: write # Only react to merged PRs for security reasons. # See https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target. if: > diff --git a/.github/workflows/check-pr-labels.yaml b/.github/workflows/check-pr-labels.yaml index 8d3cdde07b..2b30487abd 100644 --- a/.github/workflows/check-pr-labels.yaml +++ b/.github/workflows/check-pr-labels.yaml @@ -11,6 +11,7 @@ on: jobs: hold: + permissions: {} if: github.event.pull_request.merged == false runs-on: ubuntu-latest steps: diff --git a/.github/workflows/ensure-labels.yaml b/.github/workflows/ensure-labels.yaml index 85fac061d8..3cc41fe738 100644 --- a/.github/workflows/ensure-labels.yaml +++ b/.github/workflows/ensure-labels.yaml @@ -8,6 +8,9 @@ on: - .github/workflows/ensure-labels.yaml jobs: ensure: + permissions: + contents: read + issues: write runs-on: ubuntu-latest steps: - uses: actions/checkout@v5 diff --git a/.github/workflows/functional-baremetal.yaml b/.github/workflows/functional-baremetal.yaml index 13a8146f87..98887a11b0 100644 --- a/.github/workflows/functional-baremetal.yaml +++ b/.github/workflows/functional-baremetal.yaml @@ -15,6 +15,8 @@ on: - cron: '0 0 */3 * *' jobs: functional-baremetal: + permissions: + contents: read strategy: fail-fast: false matrix: diff --git a/.github/workflows/functional-basic.yaml b/.github/workflows/functional-basic.yaml index 2a384b0ea4..d61683d708 100644 --- a/.github/workflows/functional-basic.yaml +++ b/.github/workflows/functional-basic.yaml @@ -10,6 +10,8 @@ on: - cron: '0 0 */3 * *' jobs: functional-basic: + permissions: + contents: read strategy: fail-fast: false matrix: diff --git a/.github/workflows/functional-blockstorage.yaml b/.github/workflows/functional-blockstorage.yaml index 7d8fac4d67..4cea8e6a88 100644 --- a/.github/workflows/functional-blockstorage.yaml +++ b/.github/workflows/functional-blockstorage.yaml @@ -15,6 +15,8 @@ on: - cron: '0 0 */3 * *' jobs: functional-blockstorage: + permissions: + contents: read strategy: fail-fast: false matrix: diff --git a/.github/workflows/functional-compute.yaml b/.github/workflows/functional-compute.yaml index e0db371bde..b6b281dd4e 100644 --- a/.github/workflows/functional-compute.yaml +++ b/.github/workflows/functional-compute.yaml @@ -15,6 +15,8 @@ on: - cron: '0 0 */3 * *' jobs: functional-compute: + permissions: + contents: read strategy: fail-fast: false matrix: diff --git a/.github/workflows/functional-containerinfra.yaml b/.github/workflows/functional-containerinfra.yaml index dfa01b56ca..7d1ecff615 100644 --- a/.github/workflows/functional-containerinfra.yaml +++ b/.github/workflows/functional-containerinfra.yaml @@ -15,6 +15,8 @@ on: - cron: '0 0 */3 * *' jobs: functional-containerinfra: + permissions: + contents: read strategy: fail-fast: false matrix: diff --git a/.github/workflows/functional-dns.yaml b/.github/workflows/functional-dns.yaml index f3fda3a51e..67661b4909 100644 --- a/.github/workflows/functional-dns.yaml +++ b/.github/workflows/functional-dns.yaml @@ -15,6 +15,8 @@ on: - cron: '0 0 */3 * *' jobs: functional-dns: + permissions: + contents: read strategy: fail-fast: false matrix: diff --git a/.github/workflows/functional-fwaas_v2.yaml b/.github/workflows/functional-fwaas_v2.yaml index 4f14e717f7..64e83a01e1 100644 --- a/.github/workflows/functional-fwaas_v2.yaml +++ b/.github/workflows/functional-fwaas_v2.yaml @@ -19,6 +19,8 @@ on: - cron: '0 0 */3 * *' jobs: functional-fwaas_v2: + permissions: + contents: read strategy: fail-fast: false matrix: diff --git a/.github/workflows/functional-identity.yaml b/.github/workflows/functional-identity.yaml index 4731983dd3..a2f9bd2617 100644 --- a/.github/workflows/functional-identity.yaml +++ b/.github/workflows/functional-identity.yaml @@ -15,6 +15,8 @@ on: - cron: '0 0 */3 * *' jobs: functional-identity: + permissions: + contents: read strategy: fail-fast: false matrix: diff --git a/.github/workflows/functional-image.yaml b/.github/workflows/functional-image.yaml index 95e8483cae..67c8486eb8 100644 --- a/.github/workflows/functional-image.yaml +++ b/.github/workflows/functional-image.yaml @@ -15,6 +15,8 @@ on: - cron: '0 0 */3 * *' jobs: functional-image: + permissions: + contents: read strategy: fail-fast: false matrix: diff --git a/.github/workflows/functional-keymanager.yaml b/.github/workflows/functional-keymanager.yaml index 2aaae3cf4f..768612537d 100644 --- a/.github/workflows/functional-keymanager.yaml +++ b/.github/workflows/functional-keymanager.yaml @@ -15,6 +15,8 @@ on: - cron: '0 0 */3 * *' jobs: functional-keymanager: + permissions: + contents: read strategy: fail-fast: false matrix: diff --git a/.github/workflows/functional-loadbalancer.yaml b/.github/workflows/functional-loadbalancer.yaml index 596b584346..7372853db1 100644 --- a/.github/workflows/functional-loadbalancer.yaml +++ b/.github/workflows/functional-loadbalancer.yaml @@ -15,6 +15,8 @@ on: - cron: '0 0 */3 * *' jobs: functional-loadbalancer: + permissions: + contents: read strategy: fail-fast: false matrix: diff --git a/.github/workflows/functional-messaging.yaml b/.github/workflows/functional-messaging.yaml index 7d7aced3fe..750ca5b0e0 100644 --- a/.github/workflows/functional-messaging.yaml +++ b/.github/workflows/functional-messaging.yaml @@ -15,6 +15,8 @@ on: - cron: '0 0 */3 * *' jobs: functional-messaging: + permissions: + contents: read strategy: fail-fast: false matrix: diff --git a/.github/workflows/functional-networking.yaml b/.github/workflows/functional-networking.yaml index 5503d2ca1c..9a9557af77 100644 --- a/.github/workflows/functional-networking.yaml +++ b/.github/workflows/functional-networking.yaml @@ -15,6 +15,8 @@ on: - cron: '0 0 */3 * *' jobs: functional-networking: + permissions: + contents: read strategy: fail-fast: false matrix: diff --git a/.github/workflows/functional-objectstorage.yaml b/.github/workflows/functional-objectstorage.yaml index b7eace3aa9..e3770a7a7c 100644 --- a/.github/workflows/functional-objectstorage.yaml +++ b/.github/workflows/functional-objectstorage.yaml @@ -15,6 +15,8 @@ on: - cron: '0 0 */3 * *' jobs: functional-objectstorage: + permissions: + contents: read strategy: fail-fast: false matrix: diff --git a/.github/workflows/functional-orchestration.yaml b/.github/workflows/functional-orchestration.yaml index f5388cd0e5..92a4d7ec73 100644 --- a/.github/workflows/functional-orchestration.yaml +++ b/.github/workflows/functional-orchestration.yaml @@ -15,6 +15,8 @@ on: - cron: '0 0 */3 * *' jobs: functional-orchestration: + permissions: + contents: read strategy: fail-fast: false matrix: diff --git a/.github/workflows/functional-placement.yaml b/.github/workflows/functional-placement.yaml index 039b56122d..ac8cca6795 100644 --- a/.github/workflows/functional-placement.yaml +++ b/.github/workflows/functional-placement.yaml @@ -15,6 +15,8 @@ on: - cron: '0 0 */3 * *' jobs: functional-placement: + permissions: + contents: read strategy: fail-fast: false matrix: diff --git a/.github/workflows/functional-sharedfilesystems.yaml b/.github/workflows/functional-sharedfilesystems.yaml index 716b0745d0..86916163b6 100644 --- a/.github/workflows/functional-sharedfilesystems.yaml +++ b/.github/workflows/functional-sharedfilesystems.yaml @@ -15,6 +15,8 @@ on: - cron: '0 0 */3 * *' jobs: functional-sharedfilesystems: + permissions: + contents: read strategy: fail-fast: false matrix: diff --git a/.github/workflows/functional-workflow.yaml b/.github/workflows/functional-workflow.yaml index 2a25d2f827..4bf9ced4be 100644 --- a/.github/workflows/functional-workflow.yaml +++ b/.github/workflows/functional-workflow.yaml @@ -15,6 +15,8 @@ on: - cron: '0 0 */3 * *' jobs: functional-workflow: + permissions: + contents: read strategy: fail-fast: false matrix: diff --git a/.github/workflows/label-pr.yaml b/.github/workflows/label-pr.yaml index 4ed751a437..a3fb34b1b6 100644 --- a/.github/workflows/label-pr.yaml +++ b/.github/workflows/label-pr.yaml @@ -8,6 +8,10 @@ on: jobs: semver: + permissions: + contents: read + issues: write + pull-requests: write runs-on: ubuntu-latest steps: - uses: actions/checkout@v5 From f6b64a32b07ff6d571e83d106cfb1a97cb4af59d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Andr=C3=A9?= Date: Tue, 31 Mar 2026 16:29:26 +0200 Subject: [PATCH 269/353] ci: fix template injection vulnerabilities in workflow run blocks Replace ${{ env.* }} expressions in shell run blocks with native shell variable references ($VAR), and pass ${{ github.base_ref }} through an env variable instead of expanding it directly in a shell command. This prevents potential code injection through template expansion. Reported by zizmor (template-injection). --- .github/workflows/label-pr.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/label-pr.yaml b/.github/workflows/label-pr.yaml index a3fb34b1b6..24895bc0f6 100644 --- a/.github/workflows/label-pr.yaml +++ b/.github/workflows/label-pr.yaml @@ -25,9 +25,10 @@ jobs: run: | git config --global user.email "localrebase@gophercloud.io" git config --global user.name "Local rebase" - git rebase -i origin/${{ github.base_ref }} + git rebase -i origin/$BASE_REF env: GIT_SEQUENCE_EDITOR: '/usr/bin/true' + BASE_REF: ${{ github.base_ref }} - uses: actions/setup-go@v5 with: From 2a7977a8c3d1f8c9424d59164e6c056c1d2866a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Andr=C3=A9?= Date: Tue, 31 Mar 2026 16:31:02 +0200 Subject: [PATCH 270/353] ci: pin all GitHub Actions to SHA hashes Replace mutable version tags with immutable commit SHA references for all GitHub Actions used in workflows. This prevents a compromised or hijacked action tag from injecting malicious code into CI runs. Reported by zizmor (unpinned-uses). --- .github/workflows/backport_v1.yaml | 4 ++-- .github/workflows/codeql-analysis.yaml | 10 +++++----- .github/workflows/ensure-labels.yaml | 4 ++-- .github/workflows/functional-baremetal.yaml | 8 ++++---- .github/workflows/functional-basic.yaml | 8 ++++---- .github/workflows/functional-blockstorage.yaml | 8 ++++---- .github/workflows/functional-compute.yaml | 8 ++++---- .github/workflows/functional-containerinfra.yaml | 8 ++++---- .github/workflows/functional-dns.yaml | 8 ++++---- .github/workflows/functional-fwaas_v2.yaml | 8 ++++---- .github/workflows/functional-identity.yaml | 8 ++++---- .github/workflows/functional-image.yaml | 8 ++++---- .github/workflows/functional-keymanager.yaml | 8 ++++---- .github/workflows/functional-loadbalancer.yaml | 8 ++++---- .github/workflows/functional-messaging.yaml | 8 ++++---- .github/workflows/functional-networking.yaml | 8 ++++---- .github/workflows/functional-objectstorage.yaml | 8 ++++---- .github/workflows/functional-orchestration.yaml | 8 ++++---- .github/workflows/functional-placement.yaml | 8 ++++---- .github/workflows/functional-sharedfilesystems.yaml | 8 ++++---- .github/workflows/functional-workflow.yaml | 8 ++++---- .github/workflows/greetings.yaml | 2 +- .github/workflows/label-pr.yaml | 8 ++++---- .github/workflows/lint.yaml | 4 ++-- .github/workflows/unit.yaml | 8 ++++---- 25 files changed, 92 insertions(+), 92 deletions(-) diff --git a/.github/workflows/backport_v1.yaml b/.github/workflows/backport_v1.yaml index 3af4654b80..bd880d774f 100644 --- a/.github/workflows/backport_v1.yaml +++ b/.github/workflows/backport_v1.yaml @@ -29,7 +29,7 @@ jobs: steps: - name: Generate a token from the gophercloud-backport-bot github-app id: generate_token - uses: getsentry/action-github-app-token@d4b5da6c5e37703f8c3b3e43abb5705b46e159cc + uses: getsentry/action-github-app-token@a0061014b82a6a5d6aeeb3b824aced47e3c3a7ef with: app_id: ${{ secrets.BACKPORT_APP_ID }} private_key: ${{ secrets.BACKPORT_APP_PRIVATE_KEY }} @@ -40,7 +40,7 @@ jobs: || contains(github.event.pull_request.labels.*.name, 'semver:minor') || contains(github.event.label.name, 'semver:patch') || contains(github.event.label.name, 'semver:minor') - uses: kiegroup/git-backporting@c22286f85e0a14ebb66755b381163ab9cd8310fa + uses: kiegroup/git-backporting@08da0b07ef2330d189f6074ec8db736b3aa9f465 # v4.9.1 with: target-branch: v1 pull-request: ${{ github.event.pull_request.url }} diff --git a/.github/workflows/codeql-analysis.yaml b/.github/workflows/codeql-analysis.yaml index 816fbef02f..12d4008b74 100644 --- a/.github/workflows/codeql-analysis.yaml +++ b/.github/workflows/codeql-analysis.yaml @@ -18,23 +18,23 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v5 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: persist-credentials: false - name: Setup Go - uses: actions/setup-go@v5 + uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 with: go-version-file: 'go.mod' cache: true - name: Initialize CodeQL - uses: github/codeql-action/init@v4 + uses: github/codeql-action/init@38697555549f1db7851b81482ff19f1fa5c4fedc # v4 with: languages: ${{ matrix.language }} - name: Autobuild - uses: github/codeql-action/autobuild@v4 + uses: github/codeql-action/autobuild@38697555549f1db7851b81482ff19f1fa5c4fedc # v4 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v4 + uses: github/codeql-action/analyze@38697555549f1db7851b81482ff19f1fa5c4fedc # v4 diff --git a/.github/workflows/ensure-labels.yaml b/.github/workflows/ensure-labels.yaml index 3cc41fe738..9ccc6df3d6 100644 --- a/.github/workflows/ensure-labels.yaml +++ b/.github/workflows/ensure-labels.yaml @@ -13,10 +13,10 @@ jobs: issues: write runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: persist-credentials: false - - uses: micnncim/action-label-syncer@v1 + - uses: micnncim/action-label-syncer@3abd5ab72fda571e69fffd97bd4e0033dd5f495c # v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: diff --git a/.github/workflows/functional-baremetal.yaml b/.github/workflows/functional-baremetal.yaml index 98887a11b0..ec5645a098 100644 --- a/.github/workflows/functional-baremetal.yaml +++ b/.github/workflows/functional-baremetal.yaml @@ -34,13 +34,13 @@ jobs: name: Ironic on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud - uses: actions/checkout@v5 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: persist-credentials: false - name: Work around broken dnsmasq run: sudo apt-get purge -y dnsmasq-base - name: Deploy devstack - uses: gophercloud/devstack-action@v0.19 + uses: gophercloud/devstack-action@60ca1042045c0c9e3e001c64575d381654ffcba1 # v0.19 with: branch: ${{ matrix.openstack_version }} conf_overrides: | @@ -79,7 +79,7 @@ jobs: SWIFT_TEMPURL_KEY=secretkey enabled_services: "ir-api,ir-cond,s-account,s-container,s-object,s-proxy,q-svc,q-agt,q-dhcp,q-l3,q-meta,-cinder,-c-sch,-c-api,-c-vol,-c-bak,-ovn,-ovn-controller,-ovn-northd,-q-ovn-metadata-agent,openstack-cli-server" - name: Checkout go - uses: actions/setup-go@v5 + uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 with: go-version-file: 'go.mod' cache: true @@ -96,7 +96,7 @@ jobs: if: failure() - name: Upload logs artifacts on failure if: failure() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: functional-baremetal-${{ matrix.name }}-${{ github.run_id }} path: /tmp/devstack-logs/* diff --git a/.github/workflows/functional-basic.yaml b/.github/workflows/functional-basic.yaml index d61683d708..fb92290488 100644 --- a/.github/workflows/functional-basic.yaml +++ b/.github/workflows/functional-basic.yaml @@ -29,16 +29,16 @@ jobs: name: basic tests on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud - uses: actions/checkout@v5 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: persist-credentials: false - name: Deploy devstack - uses: gophercloud/devstack-action@v0.19 + uses: gophercloud/devstack-action@60ca1042045c0c9e3e001c64575d381654ffcba1 # v0.19 with: branch: ${{ matrix.openstack_version }} enabled_services: 's-account,s-container,s-object,s-proxy,openstack-cli-server' - name: Checkout go - uses: actions/setup-go@v5 + uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 with: go-version-file: 'go.mod' cache: true @@ -54,7 +54,7 @@ jobs: if: failure() - name: Upload logs artifacts on failure if: failure() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: functional-basic-${{ matrix.name }}-${{ github.run_id }} path: /tmp/devstack-logs/* diff --git a/.github/workflows/functional-blockstorage.yaml b/.github/workflows/functional-blockstorage.yaml index 4cea8e6a88..e01de55edd 100644 --- a/.github/workflows/functional-blockstorage.yaml +++ b/.github/workflows/functional-blockstorage.yaml @@ -34,18 +34,18 @@ jobs: name: Cinder on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud - uses: actions/checkout@v5 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: persist-credentials: false - name: Deploy devstack - uses: gophercloud/devstack-action@v0.19 + uses: gophercloud/devstack-action@60ca1042045c0c9e3e001c64575d381654ffcba1 # v0.19 with: branch: ${{ matrix.openstack_version }} conf_overrides: | CINDER_ISCSI_HELPER=lioadm enabled_services: "s-account,s-container,s-object,s-proxy,c-bak,openstack-cli-server" - name: Checkout go - uses: actions/setup-go@v5 + uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 with: go-version-file: 'go.mod' cache: true @@ -61,7 +61,7 @@ jobs: if: failure() - name: Upload logs artifacts on failure if: failure() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: functional-blockstorage-${{ matrix.name }}-${{ github.run_id }} path: /tmp/devstack-logs/* diff --git a/.github/workflows/functional-compute.yaml b/.github/workflows/functional-compute.yaml index b6b281dd4e..7c64092b28 100644 --- a/.github/workflows/functional-compute.yaml +++ b/.github/workflows/functional-compute.yaml @@ -34,18 +34,18 @@ jobs: name: Nova on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud - uses: actions/checkout@v5 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: persist-credentials: false - name: Deploy devstack - uses: gophercloud/devstack-action@v0.19 + uses: gophercloud/devstack-action@60ca1042045c0c9e3e001c64575d381654ffcba1 # v0.19 with: branch: ${{ matrix.openstack_version }} conf_overrides: | CINDER_ISCSI_HELPER=lioadm enabled_services: "openstack-cli-server" - name: Checkout go - uses: actions/setup-go@v5 + uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 with: go-version-file: 'go.mod' cache: true @@ -61,7 +61,7 @@ jobs: if: failure() - name: Upload logs artifacts on failure if: failure() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: functional-compute-${{ matrix.name }}-${{ github.run_id }} path: /tmp/devstack-logs/* diff --git a/.github/workflows/functional-containerinfra.yaml b/.github/workflows/functional-containerinfra.yaml index 7d1ecff615..c12d4a2caf 100644 --- a/.github/workflows/functional-containerinfra.yaml +++ b/.github/workflows/functional-containerinfra.yaml @@ -55,11 +55,11 @@ jobs: name: Magnum on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud - uses: actions/checkout@v5 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: persist-credentials: false - name: Deploy devstack - uses: gophercloud/devstack-action@v0.19 + uses: gophercloud/devstack-action@60ca1042045c0c9e3e001c64575d381654ffcba1 # v0.19 with: branch: ${{ matrix.openstack_version }} conf_overrides: | @@ -72,7 +72,7 @@ jobs: ${{ matrix.devstack_conf_overrides }} enabled_services: "h-eng,h-api,h-api-cfn,h-api-cw,openstack-cli-server" - name: Checkout go - uses: actions/setup-go@v5 + uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 with: go-version-file: 'go.mod' cache: true @@ -88,7 +88,7 @@ jobs: if: failure() - name: Upload logs artifacts on failure if: failure() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: functional-containerinfra-${{ matrix.name }}-${{ github.run_id }} path: /tmp/devstack-logs/* diff --git a/.github/workflows/functional-dns.yaml b/.github/workflows/functional-dns.yaml index 67661b4909..59826c9693 100644 --- a/.github/workflows/functional-dns.yaml +++ b/.github/workflows/functional-dns.yaml @@ -40,11 +40,11 @@ jobs: name: Designate on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud - uses: actions/checkout@v5 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: persist-credentials: false - name: Deploy devstack - uses: gophercloud/devstack-action@v0.19 + uses: gophercloud/devstack-action@60ca1042045c0c9e3e001c64575d381654ffcba1 # v0.19 with: branch: ${{ matrix.openstack_version }} conf_overrides: | @@ -53,7 +53,7 @@ jobs: ${{ matrix.devstack_conf_overrides }} enabled_services: "designate,designate-central,designate-api,designate-worker,designate-producer,designate-mdns,openstack-cli-server" - name: Checkout go - uses: actions/setup-go@v5 + uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 with: go-version-file: 'go.mod' cache: true @@ -69,7 +69,7 @@ jobs: if: failure() - name: Upload logs artifacts on failure if: failure() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: functional-dns-${{ matrix.name }}-${{ github.run_id }} path: /tmp/devstack-logs/* diff --git a/.github/workflows/functional-fwaas_v2.yaml b/.github/workflows/functional-fwaas_v2.yaml index 64e83a01e1..b074a859f0 100644 --- a/.github/workflows/functional-fwaas_v2.yaml +++ b/.github/workflows/functional-fwaas_v2.yaml @@ -38,7 +38,7 @@ jobs: name: FWaaS_v2 on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud - uses: actions/checkout@v5 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: persist-credentials: false - name: Create additional neutron policies @@ -50,7 +50,7 @@ jobs: "update_port:binding:profile": "rule:admin_only or rule:service_api" EOF - name: Deploy devstack - uses: gophercloud/devstack-action@v0.19 + uses: gophercloud/devstack-action@60ca1042045c0c9e3e001c64575d381654ffcba1 # v0.19 with: branch: ${{ matrix.openstack_version }} conf_overrides: | @@ -66,7 +66,7 @@ jobs: policy_dirs = /tmp/neutron-policies enabled_services: 'q-svc,q-agt,q-dhcp,q-l3,q-meta,q-fwaas-v2,-cinder,-horizon,-tempest,-swift,-c-sch,-c-api,-c-vol,-c-bak,-ovn,-ovn-controller,-ovn-northd,-q-ovn-metadata-agent,openstack-cli-server' - name: Checkout go - uses: actions/setup-go@v5 + uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 with: go-version-file: 'go.mod' cache: true @@ -82,7 +82,7 @@ jobs: if: failure() - name: Upload logs artifacts on failure if: failure() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: functional-fwaas_v2-${{ matrix.name }}-${{ github.run_id }} path: /tmp/devstack-logs/* diff --git a/.github/workflows/functional-identity.yaml b/.github/workflows/functional-identity.yaml index a2f9bd2617..cf7e577932 100644 --- a/.github/workflows/functional-identity.yaml +++ b/.github/workflows/functional-identity.yaml @@ -34,16 +34,16 @@ jobs: name: Keystone on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud - uses: actions/checkout@v5 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: persist-credentials: false - name: Deploy devstack - uses: gophercloud/devstack-action@v0.19 + uses: gophercloud/devstack-action@60ca1042045c0c9e3e001c64575d381654ffcba1 # v0.19 with: branch: ${{ matrix.openstack_version }} enabled_services: "openstack-cli-server" - name: Checkout go - uses: actions/setup-go@v5 + uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 with: go-version-file: 'go.mod' cache: true @@ -59,7 +59,7 @@ jobs: if: failure() - name: Upload logs artifacts on failure if: failure() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: functional-identity-${{ matrix.name }}-${{ github.run_id }} path: /tmp/devstack-logs/* diff --git a/.github/workflows/functional-image.yaml b/.github/workflows/functional-image.yaml index 67c8486eb8..33b93ee4cb 100644 --- a/.github/workflows/functional-image.yaml +++ b/.github/workflows/functional-image.yaml @@ -34,16 +34,16 @@ jobs: name: Glance on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud - uses: actions/checkout@v5 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: persist-credentials: false - name: Deploy devstack - uses: gophercloud/devstack-action@v0.19 + uses: gophercloud/devstack-action@60ca1042045c0c9e3e001c64575d381654ffcba1 # v0.19 with: branch: ${{ matrix.openstack_version }} enabled_services: "openstack-cli-server" - name: Checkout go - uses: actions/setup-go@v5 + uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 with: go-version-file: 'go.mod' cache: true @@ -59,7 +59,7 @@ jobs: if: failure() - name: Upload logs artifacts on failure if: failure() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: functional-image-${{ matrix.name }}-${{ github.run_id }} path: /tmp/devstack-logs/* diff --git a/.github/workflows/functional-keymanager.yaml b/.github/workflows/functional-keymanager.yaml index 768612537d..4858e6eaee 100644 --- a/.github/workflows/functional-keymanager.yaml +++ b/.github/workflows/functional-keymanager.yaml @@ -46,11 +46,11 @@ jobs: name: Barbican on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud - uses: actions/checkout@v5 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: persist-credentials: false - name: Deploy devstack - uses: gophercloud/devstack-action@v0.19 + uses: gophercloud/devstack-action@60ca1042045c0c9e3e001c64575d381654ffcba1 # v0.19 with: branch: ${{ matrix.openstack_version }} conf_overrides: | @@ -59,7 +59,7 @@ jobs: ${{ matrix.devstack_conf_overrides }} enabled_services: "barbican-svc,barbican-retry,barbican-keystone-listener,openstack-cli-server" - name: Checkout go - uses: actions/setup-go@v5 + uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 with: go-version-file: 'go.mod' cache: true @@ -75,7 +75,7 @@ jobs: if: failure() - name: Upload logs artifacts on failure if: failure() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: functional-keymanager-${{ matrix.name }}-${{ github.run_id }} path: /tmp/devstack-logs/* diff --git a/.github/workflows/functional-loadbalancer.yaml b/.github/workflows/functional-loadbalancer.yaml index 7372853db1..53a947f907 100644 --- a/.github/workflows/functional-loadbalancer.yaml +++ b/.github/workflows/functional-loadbalancer.yaml @@ -45,11 +45,11 @@ jobs: name: Octavia on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud - uses: actions/checkout@v5 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: persist-credentials: false - name: Deploy devstack - uses: gophercloud/devstack-action@v0.19 + uses: gophercloud/devstack-action@60ca1042045c0c9e3e001c64575d381654ffcba1 # v0.19 with: branch: ${{ matrix.openstack_version }} conf_overrides: | @@ -59,7 +59,7 @@ jobs: ${{ matrix.devstack_conf_overrides }} enabled_services: "octavia,o-api,o-cw,o-hk,o-hm,o-da,neutron-qos,openstack-cli-server" - name: Checkout go - uses: actions/setup-go@v5 + uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 with: go-version-file: 'go.mod' cache: true @@ -75,7 +75,7 @@ jobs: if: failure() - name: Upload logs artifacts on failure if: failure() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: functional-loadbalancer-${{ matrix.name }}-${{ github.run_id }} path: /tmp/devstack-logs/* diff --git a/.github/workflows/functional-messaging.yaml b/.github/workflows/functional-messaging.yaml index 750ca5b0e0..3e8fb62649 100644 --- a/.github/workflows/functional-messaging.yaml +++ b/.github/workflows/functional-messaging.yaml @@ -34,11 +34,11 @@ jobs: name: Zaqar on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud - uses: actions/checkout@v5 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: persist-credentials: false - name: Deploy devstack - uses: gophercloud/devstack-action@v0.19 + uses: gophercloud/devstack-action@60ca1042045c0c9e3e001c64575d381654ffcba1 # v0.19 with: branch: ${{ matrix.openstack_version }} conf_overrides: | @@ -46,7 +46,7 @@ jobs: ZAQARCLIENT_BRANCH=${{ matrix.openstack_version }} enabled_services: "openstack-cli-server" - name: Checkout go - uses: actions/setup-go@v5 + uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 with: go-version-file: 'go.mod' cache: true @@ -62,7 +62,7 @@ jobs: if: failure() - name: Upload logs artifacts on failure if: failure() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: functional-messaging-${{ matrix.name }}-${{ github.run_id }} path: /tmp/devstack-logs/* diff --git a/.github/workflows/functional-networking.yaml b/.github/workflows/functional-networking.yaml index 9a9557af77..9201f2f117 100644 --- a/.github/workflows/functional-networking.yaml +++ b/.github/workflows/functional-networking.yaml @@ -34,7 +34,7 @@ jobs: name: Neutron on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud - uses: actions/checkout@v5 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: persist-credentials: false - name: Create additional neutron policies @@ -46,7 +46,7 @@ jobs: "update_port:binding:profile": "rule:admin_only or rule:service_api" EOF - name: Deploy devstack - uses: gophercloud/devstack-action@v0.19 + uses: gophercloud/devstack-action@60ca1042045c0c9e3e001c64575d381654ffcba1 # v0.19 with: branch: ${{ matrix.openstack_version }} conf_overrides: | @@ -61,7 +61,7 @@ jobs: policy_dirs = /tmp/neutron-policies enabled_services: "neutron-dns,neutron-qos,neutron-segments,neutron-trunk,neutron-uplink-status-propagation,neutron-network-segment-range,neutron-port-forwarding,openstack-cli-server" - name: Checkout go - uses: actions/setup-go@v5 + uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 with: go-version-file: 'go.mod' cache: true @@ -77,7 +77,7 @@ jobs: if: failure() - name: Upload logs artifacts on failure if: failure() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: functional-networking-${{ matrix.name }}-${{ github.run_id }} path: /tmp/devstack-logs/* diff --git a/.github/workflows/functional-objectstorage.yaml b/.github/workflows/functional-objectstorage.yaml index e3770a7a7c..7449a71477 100644 --- a/.github/workflows/functional-objectstorage.yaml +++ b/.github/workflows/functional-objectstorage.yaml @@ -34,11 +34,11 @@ jobs: name: Swift on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud - uses: actions/checkout@v5 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: persist-credentials: false - name: Deploy devstack - uses: gophercloud/devstack-action@v0.19 + uses: gophercloud/devstack-action@60ca1042045c0c9e3e001c64575d381654ffcba1 # v0.19 with: branch: ${{ matrix.openstack_version }} conf_overrides: | @@ -49,7 +49,7 @@ jobs: allow_object_versioning = true enabled_services: 's-account,s-container,s-object,s-proxy,openstack-cli-server' - name: Checkout go - uses: actions/setup-go@v5 + uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 with: go-version-file: 'go.mod' cache: true @@ -65,7 +65,7 @@ jobs: if: failure() - name: Upload logs artifacts on failure if: failure() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: functional-objectstorage-${{ matrix.name }}-${{ github.run_id }} path: /tmp/devstack-logs/* diff --git a/.github/workflows/functional-orchestration.yaml b/.github/workflows/functional-orchestration.yaml index 92a4d7ec73..e5970db41a 100644 --- a/.github/workflows/functional-orchestration.yaml +++ b/.github/workflows/functional-orchestration.yaml @@ -34,18 +34,18 @@ jobs: name: Heat on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud - uses: actions/checkout@v5 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: persist-credentials: false - name: Deploy devstack - uses: gophercloud/devstack-action@v0.19 + uses: gophercloud/devstack-action@60ca1042045c0c9e3e001c64575d381654ffcba1 # v0.19 with: branch: ${{ matrix.openstack_version }} conf_overrides: | enable_plugin heat https://github.com/openstack/heat ${{ matrix.openstack_version }} enabled_services: 'h-eng,h-api,h-api-cfn,h-api-cw,openstack-cli-server' - name: Checkout go - uses: actions/setup-go@v5 + uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 with: go-version-file: 'go.mod' cache: true @@ -61,7 +61,7 @@ jobs: if: failure() - name: Upload logs artifacts on failure if: failure() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: functional-orchestration-${{ matrix.name }}-${{ github.run_id }} path: /tmp/devstack-logs/* diff --git a/.github/workflows/functional-placement.yaml b/.github/workflows/functional-placement.yaml index ac8cca6795..ce5a76f9e0 100644 --- a/.github/workflows/functional-placement.yaml +++ b/.github/workflows/functional-placement.yaml @@ -34,16 +34,16 @@ jobs: name: Placement on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud - uses: actions/checkout@v5 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: persist-credentials: false - name: Deploy devstack - uses: gophercloud/devstack-action@v0.19 + uses: gophercloud/devstack-action@60ca1042045c0c9e3e001c64575d381654ffcba1 # v0.19 with: branch: ${{ matrix.openstack_version }} enabled_services: "openstack-cli-server" - name: Checkout go - uses: actions/setup-go@v5 + uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 with: go-version-file: 'go.mod' cache: true @@ -59,7 +59,7 @@ jobs: if: failure() - name: Upload logs artifacts on failure if: failure() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: functional-placement-${{ matrix.name }}-${{ github.run_id }} path: /tmp/devstack-logs/* diff --git a/.github/workflows/functional-sharedfilesystems.yaml b/.github/workflows/functional-sharedfilesystems.yaml index 86916163b6..7185c5cd76 100644 --- a/.github/workflows/functional-sharedfilesystems.yaml +++ b/.github/workflows/functional-sharedfilesystems.yaml @@ -40,11 +40,11 @@ jobs: name: Manila on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud - uses: actions/checkout@v5 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: persist-credentials: false - name: Deploy devstack - uses: gophercloud/devstack-action@v0.19 + uses: gophercloud/devstack-action@60ca1042045c0c9e3e001c64575d381654ffcba1 # v0.19 with: branch: ${{ matrix.openstack_version }} conf_overrides: | @@ -67,7 +67,7 @@ jobs: ${{ matrix.devstack_conf_overrides }} enabled_services: "openstack-cli-server" - name: Checkout go - uses: actions/setup-go@v5 + uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 with: go-version-file: 'go.mod' cache: true @@ -83,7 +83,7 @@ jobs: if: failure() - name: Upload logs artifacts on failure if: failure() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: functional-sharedfilesystems-${{ matrix.name }}-${{ github.run_id }} path: /tmp/devstack-logs/* diff --git a/.github/workflows/functional-workflow.yaml b/.github/workflows/functional-workflow.yaml index 4bf9ced4be..2ae9b8682c 100644 --- a/.github/workflows/functional-workflow.yaml +++ b/.github/workflows/functional-workflow.yaml @@ -37,18 +37,18 @@ jobs: name: Mistral on Deploy OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud - uses: actions/checkout@v5 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: persist-credentials: false - name: Deploy devstack - uses: gophercloud/devstack-action@v0.19 + uses: gophercloud/devstack-action@60ca1042045c0c9e3e001c64575d381654ffcba1 # v0.19 with: branch: ${{ matrix.openstack_version }} conf_overrides: | enable_plugin mistral https://github.com/openstack/mistral ${{ matrix.mistral_plugin_version }} enabled_services: "mistral,mistral-api,mistral-engine,mistral-executor,mistral-event-engine,openstack-cli-server" - name: Checkout go - uses: actions/setup-go@v5 + uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 with: go-version-file: 'go.mod' cache: true @@ -64,7 +64,7 @@ jobs: if: failure() - name: Upload logs artifacts on failure if: failure() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: functional-workflow-${{ matrix.name }}-${{ github.run_id }} path: /tmp/devstack-logs/* diff --git a/.github/workflows/greetings.yaml b/.github/workflows/greetings.yaml index 7bd51ee5e8..8627b90a6d 100644 --- a/.github/workflows/greetings.yaml +++ b/.github/workflows/greetings.yaml @@ -9,7 +9,7 @@ jobs: issues: write pull-requests: write steps: - - uses: actions/first-interaction@v1 + - uses: actions/first-interaction@2ec0f0fd78838633cd1c1342e4536d49ef72be54 # v1 with: repo-token: ${{ secrets.GITHUB_TOKEN }} issue-message: | diff --git a/.github/workflows/label-pr.yaml b/.github/workflows/label-pr.yaml index 24895bc0f6..1cd77d9222 100644 --- a/.github/workflows/label-pr.yaml +++ b/.github/workflows/label-pr.yaml @@ -14,7 +14,7 @@ jobs: pull-requests: write runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: fetch-depth: 0 ref: ${{ github.event.pull_request.head.sha }} @@ -30,7 +30,7 @@ jobs: GIT_SEQUENCE_EDITOR: '/usr/bin/true' BASE_REF: ${{ github.base_ref }} - - uses: actions/setup-go@v5 + - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 with: go-version-file: 'go.mod' cache: true @@ -40,7 +40,7 @@ jobs: # if semver=major, this will return RC=1, so let's ignore the failure so label # can be set later. We check for actual errors in the next step. continue-on-error: true - uses: joelanford/go-apidiff@60c4206be8f84348ebda2a3e0c3ac9cb54b8f685 + uses: joelanford/go-apidiff@60c4206be8f84348ebda2a3e0c3ac9cb54b8f685 # v0.8.3 # go-apidiff returns RC=1 when semver=major, which makes the workflow to return # a failure. Instead let's just return a failure if go-apidiff failed to run. @@ -91,4 +91,4 @@ jobs: pull-requests: write runs-on: ubuntu-latest steps: - - uses: actions/labeler@v6 + - uses: actions/labeler@634933edcd8ababfe52f92936142cc22ac488b1b # v6 diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index a1484a9042..a2577fa289 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -9,10 +9,10 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout Gophercloud - uses: actions/checkout@v5 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: persist-credentials: false - - uses: actions/setup-go@v5 + - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 with: go-version-file: 'go.mod' cache: true diff --git a/.github/workflows/unit.yaml b/.github/workflows/unit.yaml index ab1a61fed0..9c31223208 100644 --- a/.github/workflows/unit.yaml +++ b/.github/workflows/unit.yaml @@ -14,11 +14,11 @@ jobs: fail-fast: false steps: - name: Checkout Gophercloud - uses: actions/checkout@v5 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: persist-credentials: false - name: Setup Go - uses: actions/setup-go@v5 + uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 with: go-version-file: 'go.mod' cache: true @@ -33,7 +33,7 @@ jobs: make unit make coverage - name: Check coverage - uses: coverallsapp/github-action@v2 + uses: coverallsapp/github-action@5cbfd81b66ca5d10c19b062c04de0199c215fb6e # v2 with: file: cover.out parallel: true @@ -45,6 +45,6 @@ jobs: runs-on: ubuntu-latest steps: - name: Store coverage results - uses: coverallsapp/github-action@v2 + uses: coverallsapp/github-action@5cbfd81b66ca5d10c19b062c04de0199c215fb6e # v2 with: parallel-finished: true From fad15d9db164d7c974cdd840e599fd7a232d0188 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Andr=C3=A9?= Date: Tue, 31 Mar 2026 16:31:22 +0200 Subject: [PATCH 271/353] ci: suppress secrets-outside-env warnings in backport workflow The backport bot token action requires secrets to be passed through the 'with' block (not environment variables) because it's a composite action input. Add zizmor ignore comments to suppress the false-positive warnings. Reported by zizmor (secrets-outside-env). --- .github/workflows/backport_v1.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/backport_v1.yaml b/.github/workflows/backport_v1.yaml index bd880d774f..a40e904918 100644 --- a/.github/workflows/backport_v1.yaml +++ b/.github/workflows/backport_v1.yaml @@ -31,8 +31,8 @@ jobs: id: generate_token uses: getsentry/action-github-app-token@a0061014b82a6a5d6aeeb3b824aced47e3c3a7ef with: - app_id: ${{ secrets.BACKPORT_APP_ID }} - private_key: ${{ secrets.BACKPORT_APP_PRIVATE_KEY }} + app_id: ${{ secrets.BACKPORT_APP_ID }} # zizmor: ignore[secrets-outside-env] + private_key: ${{ secrets.BACKPORT_APP_PRIVATE_KEY }} # zizmor: ignore[secrets-outside-env] - name: Backporting if: > From bbd9a44f57e50490a0e1a06ef76a66d3d5fc3cc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Andr=C3=A9?= Date: Tue, 31 Mar 2026 16:31:31 +0200 Subject: [PATCH 272/353] ci: replace pull_request_target with pull_request in check-pr-labels This workflow only reads label metadata from the event payload and does not need write access to the repository. Using pull_request instead of pull_request_target avoids granting unnecessary elevated privileges. Reported by zizmor (dangerous-triggers). --- .github/workflows/check-pr-labels.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/check-pr-labels.yaml b/.github/workflows/check-pr-labels.yaml index 2b30487abd..a81d2b223a 100644 --- a/.github/workflows/check-pr-labels.yaml +++ b/.github/workflows/check-pr-labels.yaml @@ -1,7 +1,7 @@ name: Ready on: merge_group: - pull_request_target: + pull_request: types: - labeled - opened From bd8bf0568eff3a4d9e843445971252545a3897e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Andr=C3=A9?= Date: Tue, 31 Mar 2026 16:31:44 +0200 Subject: [PATCH 273/353] ci: suppress dangerous-triggers warning in backport workflow The backport workflow legitimately uses pull_request_target because it needs write access to create backport PRs. It is safe because it only runs on merged PRs (guarded by an if condition) and never checks out or executes PR code. Reported by zizmor (dangerous-triggers). --- .github/workflows/backport_v1.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/backport_v1.yaml b/.github/workflows/backport_v1.yaml index a40e904918..eb8875545f 100644 --- a/.github/workflows/backport_v1.yaml +++ b/.github/workflows/backport_v1.yaml @@ -1,7 +1,9 @@ name: Pull Request backporting on: - pull_request_target: + # Safe: only runs on merged PRs, does not checkout PR code, and + # needs secrets to generate the backport bot token. + pull_request_target: # zizmor: ignore[dangerous-triggers] types: - closed - labeled From 609db9c7d93359d73c542091d0d4d7a5d36f2d85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Andr=C3=A9?= Date: Tue, 31 Mar 2026 16:32:42 +0200 Subject: [PATCH 274/353] ci: split semver analysis from label-pr to fix dangerous-triggers Move the Go API compatibility analysis (semver check) into a separate 'Semver analysis' workflow that runs on the unprivileged pull_request trigger. The label-pr workflow now picks up the results via a workflow_run trigger, which only fires after the analysis completes. This eliminates the need for pull_request_target in the semver analysis, removing the dangerous-triggers finding. The semver-label job uses the GitHub API to look up the PR number from the head commit SHA, then applies the appropriate semver and backport labels. Reported by zizmor (dangerous-triggers). --- .github/workflows/label-pr.yaml | 142 ++++++++++++++++++++------------ .github/workflows/semver.yaml | 62 ++++++++++++++ 2 files changed, 150 insertions(+), 54 deletions(-) create mode 100644 .github/workflows/semver.yaml diff --git a/.github/workflows/label-pr.yaml b/.github/workflows/label-pr.yaml index 1cd77d9222..3e3137d4a0 100644 --- a/.github/workflows/label-pr.yaml +++ b/.github/workflows/label-pr.yaml @@ -1,94 +1,128 @@ name: Label PR on: - pull_request_target: + # Safe: the edits job does not checkout or execute any PR code. + # It only runs the pinned actions/labeler action which reads event + # metadata and the base branch .github/labeler.yml configuration. + pull_request_target: # zizmor: ignore[dangerous-triggers] types: - opened - synchronize - reopened + # Safe: the semver-label job never checks out or executes PR code. + # It only reads a data artifact produced by the unprivileged + # "Semver analysis" workflow and uses the GitHub API to apply labels. + workflow_run: # zizmor: ignore[dangerous-triggers] + workflows: ["Semver analysis"] + types: + - completed + +permissions: {} jobs: - semver: + semver-label: + if: github.event_name == 'workflow_run' + runs-on: ubuntu-latest permissions: - contents: read + actions: read issues: write pull-requests: write - runs-on: ubuntu-latest steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - with: - fetch-depth: 0 - ref: ${{ github.event.pull_request.head.sha }} - token: ${{ secrets.GITHUB_TOKEN }} - persist-credentials: false + - name: Get PR number and base ref + id: pr + run: | + PR_DATA=$(gh api "repos/$REPO/commits/$HEAD_SHA/pulls" --jq '.[0] | {number, base_ref: .base.ref}') + PR_NUMBER=$(echo "$PR_DATA" | jq -r '.number') + BASE_REF=$(echo "$PR_DATA" | jq -r '.base_ref') + if [ -z "$PR_NUMBER" ] || [ "$PR_NUMBER" = "null" ]; then + echo "Could not determine PR number" >&2 + exit 1 + fi + echo "number=$PR_NUMBER" >> "$GITHUB_OUTPUT" + echo "base-ref=$BASE_REF" >> "$GITHUB_OUTPUT" + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + REPO: ${{ github.repository }} + HEAD_SHA: ${{ github.event.workflow_run.head_sha }} - - name: Rebase the PR against origin/github.base_ref to ensure actual API compatibility + - name: Report failure + if: github.event.workflow_run.conclusion == 'failure' run: | - git config --global user.email "localrebase@gophercloud.io" - git config --global user.name "Local rebase" - git rebase -i origin/$BASE_REF + gh pr edit "$NUMBER" --remove-label "semver:major,semver:minor,semver:patch,backport-v2,backport-v1" + gh issue comment "$NUMBER" --body "$BODY" env: - GIT_SEQUENCE_EDITOR: '/usr/bin/true' - BASE_REF: ${{ github.base_ref }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_REPO: ${{ github.repository }} + NUMBER: ${{ steps.pr.outputs.number }} + BODY: > + Failed to assess the semver bump. See [logs](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.event.workflow_run.id }}) for details. - - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 + - name: Download semver results + if: github.event.workflow_run.conclusion == 'success' + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - go-version-file: 'go.mod' - cache: true + name: semver-results + run-id: ${{ github.event.workflow_run.id }} + github-token: ${{ secrets.GITHUB_TOKEN }} - - name: Checking Go API Compatibility - id: go-apidiff - # if semver=major, this will return RC=1, so let's ignore the failure so label - # can be set later. We check for actual errors in the next step. - continue-on-error: true - uses: joelanford/go-apidiff@60c4206be8f84348ebda2a3e0c3ac9cb54b8f685 # v0.8.3 - - # go-apidiff returns RC=1 when semver=major, which makes the workflow to return - # a failure. Instead let's just return a failure if go-apidiff failed to run. - - name: Return an error if Go API Compatibility couldn't be verified - if: steps.go-apidiff.outcome != 'success' && steps.go-apidiff.outputs.semver-type != 'major' - run: exit 1 + - name: Read semver type + if: github.event.workflow_run.conclusion == 'success' + id: semver + run: echo "type=$(cat semver-type)" >> "$GITHUB_OUTPUT" - name: Add label semver:patch - if: steps.go-apidiff.outputs.semver-type == 'patch' - run: gh pr edit "$NUMBER" --add-label "semver:patch" --remove-label "semver:major,semver:minor" + if: github.event.workflow_run.conclusion == 'success' && steps.semver.outputs.type == 'patch' + run: | + LABELS="semver:patch" + REMOVE_LABELS="semver:major,semver:minor" + + # Only add backport-v2 if not already targeting v2 or lower + if [[ "$BASE_REF" != "v2" && "$BASE_REF" != "v1" ]]; then + LABELS="$LABELS,backport-v2" + else + REMOVE_LABELS="$REMOVE_LABELS,backport-v2" + fi + + gh pr edit "$NUMBER" --add-label "$LABELS" --remove-label "$REMOVE_LABELS" env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} GH_REPO: ${{ github.repository }} - NUMBER: ${{ github.event.pull_request.number }} + NUMBER: ${{ steps.pr.outputs.number }} + BASE_REF: ${{ steps.pr.outputs.base-ref }} - name: Add label semver:minor - if: steps.go-apidiff.outputs.semver-type == 'minor' - run: gh pr edit "$NUMBER" --add-label "semver:minor" --remove-label "semver:major,semver:patch" - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - GH_REPO: ${{ github.repository }} - NUMBER: ${{ github.event.pull_request.number }} + if: github.event.workflow_run.conclusion == 'success' && steps.semver.outputs.type == 'minor' + run: | + LABELS="semver:minor" + REMOVE_LABELS="semver:major,semver:patch" - - name: Add label semver:major - if: steps.go-apidiff.outputs.semver-type == 'major' - run: gh pr edit "$NUMBER" --add-label "semver:major" --remove-label "semver:minor,semver:patch" + # Only add backport-v2 if not already targeting v2 or lower + if [[ "$BASE_REF" != "v2" && "$BASE_REF" != "v1" ]]; then + LABELS="$LABELS,backport-v2" + REMOVE_LABELS="$REMOVE_LABELS,backport-v1" + else + REMOVE_LABELS="$REMOVE_LABELS,backport-v2,backport-v1" + fi + + gh pr edit "$NUMBER" --add-label "$LABELS" --remove-label "$REMOVE_LABELS" env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} GH_REPO: ${{ github.repository }} - NUMBER: ${{ github.event.pull_request.number }} + NUMBER: ${{ steps.pr.outputs.number }} + BASE_REF: ${{ steps.pr.outputs.base-ref }} - - name: Report failure - if: failure() - run: | - gh pr edit "$NUMBER" --remove-label "semver:major,semver:minor,semver:patch" - gh issue comment "$NUMBER" --body "$BODY" - exit 1 + - name: Add label semver:major + if: github.event.workflow_run.conclusion == 'success' && steps.semver.outputs.type == 'major' + run: gh pr edit "$NUMBER" --add-label "semver:major" --remove-label "semver:minor,semver:patch,backport-v2,backport-v1" env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} GH_REPO: ${{ github.repository }} - NUMBER: ${{ github.event.pull_request.number }} - BODY: > - Failed to assess the semver bump. See [logs](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) for details. + NUMBER: ${{ steps.pr.outputs.number }} edits: + if: github.event_name == 'pull_request_target' + runs-on: ubuntu-latest permissions: contents: read pull-requests: write - runs-on: ubuntu-latest steps: - uses: actions/labeler@634933edcd8ababfe52f92936142cc22ac488b1b # v6 diff --git a/.github/workflows/semver.yaml b/.github/workflows/semver.yaml new file mode 100644 index 0000000000..b5b548cab9 --- /dev/null +++ b/.github/workflows/semver.yaml @@ -0,0 +1,62 @@ +name: Semver analysis +on: + pull_request: + types: + - opened + - synchronize + - reopened + +permissions: + contents: read + +jobs: + analyze: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + with: + fetch-depth: 0 + ref: ${{ github.event.pull_request.head.sha }} + persist-credentials: false + + - name: Rebase the PR against base ref to ensure actual API compatibility + run: | + git config --global user.email "localrebase@gophercloud.io" + git config --global user.name "Local rebase" + git rebase -i origin/$BASE_REF + env: + GIT_SEQUENCE_EDITOR: '/usr/bin/true' + BASE_REF: ${{ github.base_ref }} + + - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 + with: + go-version-file: 'go.mod' + cache: true + + - name: Checking Go API Compatibility + id: go-apidiff + # if semver=major, this will return RC=1, so let's ignore the failure so label + # can be set later. We check for actual errors in the next step. + continue-on-error: true + uses: joelanford/go-apidiff@60c4206be8f84348ebda2a3e0c3ac9cb54b8f685 # v0.8.3 + + # go-apidiff returns RC=1 when semver=major, which makes the workflow to return + # a failure. Instead let's just return a failure if go-apidiff failed to run. + - name: Return an error if Go API Compatibility couldn't be verified + if: steps.go-apidiff.outcome != 'success' && steps.go-apidiff.outputs.semver-type != 'major' + run: exit 1 + + - name: Save semver result + if: always() + run: | + mkdir -p semver-results + echo "$SEMVER_TYPE" > semver-results/semver-type + env: + SEMVER_TYPE: ${{ steps.go-apidiff.outputs.semver-type }} + + - name: Upload semver results + if: always() + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + with: + name: semver-results + path: semver-results/ From c39427bfb7089839b9300806f5772682b3c0e455 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Andr=C3=A9?= Date: Tue, 31 Mar 2026 16:33:38 +0200 Subject: [PATCH 275/353] ci: pass PR number and base ref through artifact instead of API The commits/:sha/pulls API endpoint does not return results for fork PRs because the commit does not exist in the base repository. Instead, include the PR number and base ref in the artifact uploaded by the semver analysis workflow, where they are always available from the pull_request event context. This fixes up commit 609db9c7d. --- .github/workflows/label-pr.yaml | 52 ++++++++++++--------------------- .github/workflows/semver.yaml | 4 +++ 2 files changed, 22 insertions(+), 34 deletions(-) diff --git a/.github/workflows/label-pr.yaml b/.github/workflows/label-pr.yaml index 3e3137d4a0..de5d9a52b0 100644 --- a/.github/workflows/label-pr.yaml +++ b/.github/workflows/label-pr.yaml @@ -27,22 +27,19 @@ jobs: issues: write pull-requests: write steps: - - name: Get PR number and base ref - id: pr + - name: Download semver results + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: semver-results + run-id: ${{ github.event.workflow_run.id }} + github-token: ${{ secrets.GITHUB_TOKEN }} + + - name: Read semver results + id: semver run: | - PR_DATA=$(gh api "repos/$REPO/commits/$HEAD_SHA/pulls" --jq '.[0] | {number, base_ref: .base.ref}') - PR_NUMBER=$(echo "$PR_DATA" | jq -r '.number') - BASE_REF=$(echo "$PR_DATA" | jq -r '.base_ref') - if [ -z "$PR_NUMBER" ] || [ "$PR_NUMBER" = "null" ]; then - echo "Could not determine PR number" >&2 - exit 1 - fi - echo "number=$PR_NUMBER" >> "$GITHUB_OUTPUT" - echo "base-ref=$BASE_REF" >> "$GITHUB_OUTPUT" - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - REPO: ${{ github.repository }} - HEAD_SHA: ${{ github.event.workflow_run.head_sha }} + echo "type=$(cat semver-type)" >> "$GITHUB_OUTPUT" + echo "pr-number=$(cat pr-number)" >> "$GITHUB_OUTPUT" + echo "base-ref=$(cat base-ref)" >> "$GITHUB_OUTPUT" - name: Report failure if: github.event.workflow_run.conclusion == 'failure' @@ -52,23 +49,10 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} GH_REPO: ${{ github.repository }} - NUMBER: ${{ steps.pr.outputs.number }} + NUMBER: ${{ steps.semver.outputs.pr-number }} BODY: > Failed to assess the semver bump. See [logs](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.event.workflow_run.id }}) for details. - - name: Download semver results - if: github.event.workflow_run.conclusion == 'success' - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 - with: - name: semver-results - run-id: ${{ github.event.workflow_run.id }} - github-token: ${{ secrets.GITHUB_TOKEN }} - - - name: Read semver type - if: github.event.workflow_run.conclusion == 'success' - id: semver - run: echo "type=$(cat semver-type)" >> "$GITHUB_OUTPUT" - - name: Add label semver:patch if: github.event.workflow_run.conclusion == 'success' && steps.semver.outputs.type == 'patch' run: | @@ -86,8 +70,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} GH_REPO: ${{ github.repository }} - NUMBER: ${{ steps.pr.outputs.number }} - BASE_REF: ${{ steps.pr.outputs.base-ref }} + NUMBER: ${{ steps.semver.outputs.pr-number }} + BASE_REF: ${{ steps.semver.outputs.base-ref }} - name: Add label semver:minor if: github.event.workflow_run.conclusion == 'success' && steps.semver.outputs.type == 'minor' @@ -107,8 +91,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} GH_REPO: ${{ github.repository }} - NUMBER: ${{ steps.pr.outputs.number }} - BASE_REF: ${{ steps.pr.outputs.base-ref }} + NUMBER: ${{ steps.semver.outputs.pr-number }} + BASE_REF: ${{ steps.semver.outputs.base-ref }} - name: Add label semver:major if: github.event.workflow_run.conclusion == 'success' && steps.semver.outputs.type == 'major' @@ -116,7 +100,7 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} GH_REPO: ${{ github.repository }} - NUMBER: ${{ steps.pr.outputs.number }} + NUMBER: ${{ steps.semver.outputs.pr-number }} edits: if: github.event_name == 'pull_request_target' diff --git a/.github/workflows/semver.yaml b/.github/workflows/semver.yaml index b5b548cab9..af9ff9643d 100644 --- a/.github/workflows/semver.yaml +++ b/.github/workflows/semver.yaml @@ -51,8 +51,12 @@ jobs: run: | mkdir -p semver-results echo "$SEMVER_TYPE" > semver-results/semver-type + echo "$PR_NUMBER" > semver-results/pr-number + echo "$BASE_REF" > semver-results/base-ref env: SEMVER_TYPE: ${{ steps.go-apidiff.outputs.semver-type }} + PR_NUMBER: ${{ github.event.pull_request.number }} + BASE_REF: ${{ github.base_ref }} - name: Upload semver results if: always() From 676047da96c86bf0d1b849614222194d0070a91d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Andr=C3=A9?= Date: Tue, 31 Mar 2026 16:36:24 +0200 Subject: [PATCH 276/353] ci: remove dependabot.yaml from v2 branch Dependabot reads its configuration from the default branch (main) only. Having a copy on v2 is unnecessary and potentially confusing. --- .github/dependabot.yaml | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 .github/dependabot.yaml diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml deleted file mode 100644 index 2b5c704536..0000000000 --- a/.github/dependabot.yaml +++ /dev/null @@ -1,12 +0,0 @@ -version: 2 -updates: -- package-ecosystem: gomod - directory: "/" - schedule: - interval: daily - open-pull-requests-limit: 10 -- package-ecosystem: "github-actions" - directory: "/" - schedule: - interval: daily - open-pull-requests-limit: 10 From 63c0cceab60b25d4a4a4db50e783761721ab8703 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Andr=C3=A9?= Date: Tue, 31 Mar 2026 16:43:54 +0200 Subject: [PATCH 277/353] ci: remove greetings workflow This workflow was already removed from the main branch. The first-interaction greeting bot is no longer needed since the repository now uses issue and PR templates to guide contributors. This also resolves the last zizmor dangerous-triggers finding. --- .github/workflows/greetings.yaml | 24 ------------------------ 1 file changed, 24 deletions(-) delete mode 100644 .github/workflows/greetings.yaml diff --git a/.github/workflows/greetings.yaml b/.github/workflows/greetings.yaml deleted file mode 100644 index 8627b90a6d..0000000000 --- a/.github/workflows/greetings.yaml +++ /dev/null @@ -1,24 +0,0 @@ -name: Greetings - -on: [pull_request_target, issues] - -jobs: - greeting: - runs-on: ubuntu-latest - permissions: - issues: write - pull-requests: write - steps: - - uses: actions/first-interaction@2ec0f0fd78838633cd1c1342e4536d49ef72be54 # v1 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - issue-message: | - Thank you for reporting your first issue! Be sure that we will be looking at it, but keep in mind - this sometimes takes a while. - Please let the maintainers know if your issue has not got enough attention after a few days. - If any doubt, please consult our issue [tutorial](https://github.com/gophercloud/gophercloud/blob/master/docs/contributor-tutorial/step-02-issues.md). - pr-message: | - Thank you for submitting your first PR! Be sure that we will be looking at it but keep in mind - this sometimes takes a while. - Please let the maintainers know if your PR has not got enough attention after a few days. - If any doubt, please consult our PR [tutorial](https://github.com/gophercloud/gophercloud/blob/master/docs/contributor-tutorial/step-05-pull-requests.md). From aaff179b25556cf57a5039ab09457141dc177903 Mon Sep 17 00:00:00 2001 From: Dominik Danelski Date: Tue, 31 Mar 2026 15:02:02 +0200 Subject: [PATCH 278/353] Update acceptance README to remove mentions of Packstack Fixes #3667 --- internal/acceptance/README.md | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/internal/acceptance/README.md b/internal/acceptance/README.md index febf394f10..2010e368dc 100644 --- a/internal/acceptance/README.md +++ b/internal/acceptance/README.md @@ -18,16 +18,8 @@ environment. Additionally, you may incur bandwidth and service charges for the resources used, as mentioned in the note above. Therefore, it is usually best to first practice running acceptance tests in -an isolated test environment. Two options to easily create a testing -environment are [DevStack](https://docs.openstack.org/devstack/latest/) -and [PackStack](https://www.rdoproject.org/install/packstack/). - -The following blog posts detail how to create reusable PackStack environments. -These posts were written with Gophercloud in mind: - -* http://terrarum.net/blog/building-openstack-environments.html -* http://terrarum.net/blog/building-openstack-environments-2.html -* http://terrarum.net/blog/building-openstack-environments-3.html +an isolated test environment. The best option to easily create a testing +environment is [DevStack](https://docs.openstack.org/devstack/latest/). ### Step 2. Set environment variables From 74bec7268e743d2bb90cc21710524998b8e661fe Mon Sep 17 00:00:00 2001 From: Dominik Danelski Date: Thu, 26 Mar 2026 19:39:01 +0100 Subject: [PATCH 279/353] Implement CREATE operation on Placement traits Related: #526 API reference: https://docs.openstack.org/api-ref/placement/#traits Code reference: https://github.com/openstack/placement/blob/stable/2025.1/placement/handlers/trait.py#L67-L103 Signed-off-by: Dominik Danelski --- .../openstack/placement/v1/traits_test.go | 59 +++++++++++++++++++ openstack/placement/v1/traits/doc.go | 13 ++++ openstack/placement/v1/traits/requests.go | 29 +++++++++ openstack/placement/v1/traits/results.go | 6 ++ .../v1/traits/testing/fixtures_test.go | 32 ++++++++++ .../v1/traits/testing/requests_test.go | 30 ++++++++++ openstack/placement/v1/traits/urls.go | 4 ++ 7 files changed, 173 insertions(+) diff --git a/internal/acceptance/openstack/placement/v1/traits_test.go b/internal/acceptance/openstack/placement/v1/traits_test.go index 15775f5281..180a85282a 100644 --- a/internal/acceptance/openstack/placement/v1/traits_test.go +++ b/internal/acceptance/openstack/placement/v1/traits_test.go @@ -11,6 +11,7 @@ import ( "github.com/gophercloud/gophercloud/v2" "github.com/gophercloud/gophercloud/v2/internal/acceptance/clients" + "github.com/gophercloud/gophercloud/v2/internal/acceptance/tools" "github.com/gophercloud/gophercloud/v2/openstack/placement/v1/traits" th "github.com/gophercloud/gophercloud/v2/testhelper" ) @@ -88,3 +89,61 @@ func TestTraitsListFiltering(t *testing.T) { th.AssertEquals(t, true, strings.HasPrefix(trait, "HW_")) } } + +func TestTraitsCreateSuccess(t *testing.T) { + // The Traits API requires microversion 1.6 or later + clients.SkipReleasesBelow(t, "stable/pike") + + client, err := clients.NewPlacementV1Client() + th.AssertNoErr(t, err) + + client.Microversion = "1.6" + + traitName := strings.ToUpper(tools.RandomString("CUSTOM_", 8)) + createOpts := traits.CreateOpts{} + + err = traits.Create(context.TODO(), client, traitName, createOpts).ExtractErr() + th.AssertNoErr(t, err) + + // Assert that the trait now exists + err = traits.Get(context.TODO(), client, traitName).ExtractErr() + th.AssertNoErr(t, err) +} + +func TestTraitsCreateDuplicate(t *testing.T) { + // The Traits API requires microversion 1.6 or later + clients.SkipReleasesBelow(t, "stable/pike") + + client, err := clients.NewPlacementV1Client() + th.AssertNoErr(t, err) + + client.Microversion = "1.6" + + traitName := strings.ToUpper(tools.RandomString("CUSTOM_", 8)) + createOpts := traits.CreateOpts{} + + // Create the trait for the first time + err = traits.Create(context.TODO(), client, traitName, createOpts).ExtractErr() + th.AssertNoErr(t, err) + + // Creating the same trait again results in 204 (no error) + err = traits.Create(context.TODO(), client, traitName, createOpts).ExtractErr() + th.AssertNoErr(t, err) +} + +// Test of creating a trait name that cannot be created in an API +func TestTraitsCreateInvalidName(t *testing.T) { + // The Traits API requires microversion 1.6 or later + clients.SkipReleasesBelow(t, "stable/pike") + + client, err := clients.NewPlacementV1Client() + th.AssertNoErr(t, err) + + client.Microversion = "1.6" + + traitName := "HW_WE_CANNOT_CREATE_THIS_TRAIT" + createOpts := traits.CreateOpts{} + + err = traits.Create(context.TODO(), client, traitName, createOpts).ExtractErr() + th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusBadRequest)) +} diff --git a/openstack/placement/v1/traits/doc.go b/openstack/placement/v1/traits/doc.go index e11afc158e..215f8bd9a4 100644 --- a/openstack/placement/v1/traits/doc.go +++ b/openstack/placement/v1/traits/doc.go @@ -38,5 +38,18 @@ Example to check if a trait exists } else { fmt.Println("Trait exists!") } + +Example to create a trait + + placementClient.Microversion = "1.6" + + traitName := "CUSTOM_HW_FPGA_CLASS1" + createOpts := traits.CreateOpts{} + err := traits.Create(context.TODO(), placementClient, traitName, createOpts).ExtractErr() + if err != nil { + panic(err) + } else { + fmt.Println("Trait created successfully!") + } */ package traits diff --git a/openstack/placement/v1/traits/requests.go b/openstack/placement/v1/traits/requests.go index 82fd8a0dbb..67f21a6f02 100644 --- a/openstack/placement/v1/traits/requests.go +++ b/openstack/placement/v1/traits/requests.go @@ -58,3 +58,32 @@ func Get(ctx context.Context, client *gophercloud.ServiceClient, traitName strin _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) return } + +// CreateOptsBuilder allows extensions to add additional parameters to +// the Create request. +type CreateOptsBuilder interface { + ToTraitCreateMap() (map[string]any, error) +} + +// CreateOpts provides options used to create a trait. +type CreateOpts struct { +} + +// ToTraitCreateMap formats a CreateOpts into a create request. +func (opts CreateOpts) ToTraitCreateMap() (map[string]any, error) { + return gophercloud.BuildRequestBody(opts, "") +} + +// Create creates a new trait. +func Create(ctx context.Context, client *gophercloud.ServiceClient, traitName string, opts CreateOptsBuilder) (r CreateResult) { + b, err := opts.ToTraitCreateMap() + if err != nil { + r.Err = err + return + } + resp, err := client.Put(ctx, createURL(client, traitName), b, nil, &gophercloud.RequestOpts{ + OkCodes: []int{201, 204}, + }) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} diff --git a/openstack/placement/v1/traits/results.go b/openstack/placement/v1/traits/results.go index 5e638cf226..0718b64601 100644 --- a/openstack/placement/v1/traits/results.go +++ b/openstack/placement/v1/traits/results.go @@ -16,6 +16,12 @@ type TraitsPage struct { pagination.SinglePageBase } +// CreateResult is the response from a Create operation. Call its ExtractErr to +// determine if the request succeeded or failed. +type CreateResult struct { + gophercloud.ErrResult +} + // IsEmpty satisfies the IsEmpty method of the Page interface. It returns true // if a List contains no results. func (r TraitsPage) IsEmpty() (bool, error) { diff --git a/openstack/placement/v1/traits/testing/fixtures_test.go b/openstack/placement/v1/traits/testing/fixtures_test.go index 6c37649d18..9a22bcb7d2 100644 --- a/openstack/placement/v1/traits/testing/fixtures_test.go +++ b/openstack/placement/v1/traits/testing/fixtures_test.go @@ -11,6 +11,7 @@ import ( const PresentTrait = "CUSTOM_HW_FPGA_CLASS1" const AbsentTrait = "NON_EXISTENT_TRAIT" +const CustomTraitToCreate = "CUSTOM_TRAIT_TO_CREATE" const TraitsListResultAll = ` { @@ -106,3 +107,34 @@ func HandleGetTraitNotFound(t *testing.T, fakeServer th.FakeServer) { w.WriteHeader(http.StatusNotFound) }) } + +func HandleCreateTraitSuccess(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/traits/"+CustomTraitToCreate, + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "PUT") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.WriteHeader(http.StatusCreated) + }) +} + +func HandleCreateTraitThatAlreadyExists(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/traits/"+PresentTrait, + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "PUT") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.WriteHeader(http.StatusNoContent) + }) +} + +// Trait names created via the API must be prefixed with CUSTOM_. +func HandleCreateTraitInvalidName(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/traits/"+AbsentTrait, + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "PUT") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.WriteHeader(http.StatusBadRequest) + }) +} diff --git a/openstack/placement/v1/traits/testing/requests_test.go b/openstack/placement/v1/traits/testing/requests_test.go index 39642afb91..f3ba58f127 100644 --- a/openstack/placement/v1/traits/testing/requests_test.go +++ b/openstack/placement/v1/traits/testing/requests_test.go @@ -99,3 +99,33 @@ func TestGetTraitNotFound(t *testing.T) { err := traits.Get(context.TODO(), client.ServiceClient(fakeServer), AbsentTrait).ExtractErr() th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusNotFound)) } + +func TestCreateTraitSuccess(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleCreateTraitSuccess(t, fakeServer) + + err := traits.Create(context.TODO(), client.ServiceClient(fakeServer), CustomTraitToCreate, traits.CreateOpts{}).ExtractErr() + th.AssertNoErr(t, err) +} + +func TestCreateTraitThatAlreadyExists(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleCreateTraitThatAlreadyExists(t, fakeServer) + + err := traits.Create(context.TODO(), client.ServiceClient(fakeServer), PresentTrait, traits.CreateOpts{}).ExtractErr() + th.AssertNoErr(t, err) +} + +func TestCreateTraitInvalidName(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleCreateTraitInvalidName(t, fakeServer) + + err := traits.Create(context.TODO(), client.ServiceClient(fakeServer), AbsentTrait, traits.CreateOpts{}).ExtractErr() + th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusBadRequest)) +} diff --git a/openstack/placement/v1/traits/urls.go b/openstack/placement/v1/traits/urls.go index a6ea7757a1..2211abb309 100644 --- a/openstack/placement/v1/traits/urls.go +++ b/openstack/placement/v1/traits/urls.go @@ -13,3 +13,7 @@ func listURL(client *gophercloud.ServiceClient) string { func getURL(client *gophercloud.ServiceClient, traitName string) string { return client.ServiceURL(apiName, traitName) } + +func createURL(client *gophercloud.ServiceClient, traitName string) string { + return client.ServiceURL(apiName, traitName) +} From cfb35ff12320af30b435b0c9798c7ed766033d5e Mon Sep 17 00:00:00 2001 From: Dominik Danelski Date: Mon, 30 Mar 2026 12:58:55 +0200 Subject: [PATCH 280/353] Update traits doc to include a wider range of available operations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Martin André --- openstack/placement/v1/traits/doc.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openstack/placement/v1/traits/doc.go b/openstack/placement/v1/traits/doc.go index 215f8bd9a4..f6c88a62fb 100644 --- a/openstack/placement/v1/traits/doc.go +++ b/openstack/placement/v1/traits/doc.go @@ -1,5 +1,5 @@ /* -Package traits lists traits from the OpenStack Placement service. +Package traits manages traits from the OpenStack Placement service. Traits API requests are available starting from microversion 1.6. From 48da04e9a6af2e3ac35c3f50505e07f62ff9e04e Mon Sep 17 00:00:00 2001 From: Dominik Danelski Date: Mon, 30 Mar 2026 17:12:44 +0200 Subject: [PATCH 281/353] Simplify trait PUT operation, remove CreateOptsBuilder It's useless, as API doesn't take any arguments at the moment. That's unlikely to change in the near future. Signed-off-by: Dominik Danelski --- .../openstack/placement/v1/traits_test.go | 11 ++++----- openstack/placement/v1/traits/doc.go | 3 +-- openstack/placement/v1/traits/requests.go | 24 ++----------------- .../v1/traits/testing/requests_test.go | 6 ++--- 4 files changed, 10 insertions(+), 34 deletions(-) diff --git a/internal/acceptance/openstack/placement/v1/traits_test.go b/internal/acceptance/openstack/placement/v1/traits_test.go index 180a85282a..8ceeb42aee 100644 --- a/internal/acceptance/openstack/placement/v1/traits_test.go +++ b/internal/acceptance/openstack/placement/v1/traits_test.go @@ -100,9 +100,8 @@ func TestTraitsCreateSuccess(t *testing.T) { client.Microversion = "1.6" traitName := strings.ToUpper(tools.RandomString("CUSTOM_", 8)) - createOpts := traits.CreateOpts{} - err = traits.Create(context.TODO(), client, traitName, createOpts).ExtractErr() + err = traits.Create(context.TODO(), client, traitName).ExtractErr() th.AssertNoErr(t, err) // Assert that the trait now exists @@ -120,14 +119,13 @@ func TestTraitsCreateDuplicate(t *testing.T) { client.Microversion = "1.6" traitName := strings.ToUpper(tools.RandomString("CUSTOM_", 8)) - createOpts := traits.CreateOpts{} // Create the trait for the first time - err = traits.Create(context.TODO(), client, traitName, createOpts).ExtractErr() + err = traits.Create(context.TODO(), client, traitName).ExtractErr() th.AssertNoErr(t, err) // Creating the same trait again results in 204 (no error) - err = traits.Create(context.TODO(), client, traitName, createOpts).ExtractErr() + err = traits.Create(context.TODO(), client, traitName).ExtractErr() th.AssertNoErr(t, err) } @@ -142,8 +140,7 @@ func TestTraitsCreateInvalidName(t *testing.T) { client.Microversion = "1.6" traitName := "HW_WE_CANNOT_CREATE_THIS_TRAIT" - createOpts := traits.CreateOpts{} - err = traits.Create(context.TODO(), client, traitName, createOpts).ExtractErr() + err = traits.Create(context.TODO(), client, traitName).ExtractErr() th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusBadRequest)) } diff --git a/openstack/placement/v1/traits/doc.go b/openstack/placement/v1/traits/doc.go index f6c88a62fb..91c7a8888e 100644 --- a/openstack/placement/v1/traits/doc.go +++ b/openstack/placement/v1/traits/doc.go @@ -44,8 +44,7 @@ Example to create a trait placementClient.Microversion = "1.6" traitName := "CUSTOM_HW_FPGA_CLASS1" - createOpts := traits.CreateOpts{} - err := traits.Create(context.TODO(), placementClient, traitName, createOpts).ExtractErr() + err := traits.Create(context.TODO(), placementClient, traitName).ExtractErr() if err != nil { panic(err) } else { diff --git a/openstack/placement/v1/traits/requests.go b/openstack/placement/v1/traits/requests.go index 67f21a6f02..2a106ff013 100644 --- a/openstack/placement/v1/traits/requests.go +++ b/openstack/placement/v1/traits/requests.go @@ -59,29 +59,9 @@ func Get(ctx context.Context, client *gophercloud.ServiceClient, traitName strin return } -// CreateOptsBuilder allows extensions to add additional parameters to -// the Create request. -type CreateOptsBuilder interface { - ToTraitCreateMap() (map[string]any, error) -} - -// CreateOpts provides options used to create a trait. -type CreateOpts struct { -} - -// ToTraitCreateMap formats a CreateOpts into a create request. -func (opts CreateOpts) ToTraitCreateMap() (map[string]any, error) { - return gophercloud.BuildRequestBody(opts, "") -} - // Create creates a new trait. -func Create(ctx context.Context, client *gophercloud.ServiceClient, traitName string, opts CreateOptsBuilder) (r CreateResult) { - b, err := opts.ToTraitCreateMap() - if err != nil { - r.Err = err - return - } - resp, err := client.Put(ctx, createURL(client, traitName), b, nil, &gophercloud.RequestOpts{ +func Create(ctx context.Context, client *gophercloud.ServiceClient, traitName string) (r CreateResult) { + resp, err := client.Put(ctx, createURL(client, traitName), nil, nil, &gophercloud.RequestOpts{ OkCodes: []int{201, 204}, }) _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) diff --git a/openstack/placement/v1/traits/testing/requests_test.go b/openstack/placement/v1/traits/testing/requests_test.go index f3ba58f127..9f5b63663d 100644 --- a/openstack/placement/v1/traits/testing/requests_test.go +++ b/openstack/placement/v1/traits/testing/requests_test.go @@ -106,7 +106,7 @@ func TestCreateTraitSuccess(t *testing.T) { HandleCreateTraitSuccess(t, fakeServer) - err := traits.Create(context.TODO(), client.ServiceClient(fakeServer), CustomTraitToCreate, traits.CreateOpts{}).ExtractErr() + err := traits.Create(context.TODO(), client.ServiceClient(fakeServer), CustomTraitToCreate).ExtractErr() th.AssertNoErr(t, err) } @@ -116,7 +116,7 @@ func TestCreateTraitThatAlreadyExists(t *testing.T) { HandleCreateTraitThatAlreadyExists(t, fakeServer) - err := traits.Create(context.TODO(), client.ServiceClient(fakeServer), PresentTrait, traits.CreateOpts{}).ExtractErr() + err := traits.Create(context.TODO(), client.ServiceClient(fakeServer), PresentTrait).ExtractErr() th.AssertNoErr(t, err) } @@ -126,6 +126,6 @@ func TestCreateTraitInvalidName(t *testing.T) { HandleCreateTraitInvalidName(t, fakeServer) - err := traits.Create(context.TODO(), client.ServiceClient(fakeServer), AbsentTrait, traits.CreateOpts{}).ExtractErr() + err := traits.Create(context.TODO(), client.ServiceClient(fakeServer), AbsentTrait).ExtractErr() th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusBadRequest)) } From 598f1983168dba389a57ea40f94f4746d7183b8c Mon Sep 17 00:00:00 2001 From: Dominik Danelski Date: Thu, 26 Mar 2026 22:28:27 +0100 Subject: [PATCH 282/353] Implement DELETE operation on Placement traits Related: #526 API reference: https://docs.openstack.org/api-ref/placement/#traits Code reference: https://github.com/openstack/placement/blob/stable/2025.1/placement/handlers/trait.py#L129-L146 Signed-off-by: Dominik Danelski --- .../openstack/placement/v1/traits_test.go | 56 +++++++++++++++++++ openstack/placement/v1/traits/doc.go | 12 ++++ openstack/placement/v1/traits/requests.go | 9 +++ openstack/placement/v1/traits/results.go | 6 ++ .../v1/traits/testing/fixtures_test.go | 42 ++++++++++++++ .../v1/traits/testing/requests_test.go | 40 +++++++++++++ openstack/placement/v1/traits/urls.go | 4 ++ 7 files changed, 169 insertions(+) diff --git a/internal/acceptance/openstack/placement/v1/traits_test.go b/internal/acceptance/openstack/placement/v1/traits_test.go index 8ceeb42aee..0bea5ef944 100644 --- a/internal/acceptance/openstack/placement/v1/traits_test.go +++ b/internal/acceptance/openstack/placement/v1/traits_test.go @@ -144,3 +144,59 @@ func TestTraitsCreateInvalidName(t *testing.T) { err = traits.Create(context.TODO(), client, traitName).ExtractErr() th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusBadRequest)) } + +func TestTraitsDeleteSuccess(t *testing.T) { + // The Traits API requires microversion 1.6 or later + clients.SkipReleasesBelow(t, "stable/pike") + + client, err := clients.NewPlacementV1Client() + th.AssertNoErr(t, err) + + client.Microversion = "1.6" + + traitName := strings.ToUpper(tools.RandomString("CUSTOM_", 8)) + + // Prepare: Create the trait + err = traits.Create(context.TODO(), client, traitName).ExtractErr() + th.AssertNoErr(t, err) + + // Act: Delete the trait + err = traits.Delete(context.TODO(), client, traitName).ExtractErr() + th.AssertNoErr(t, err) + + // Assert: The trait no longer exists + err = traits.Get(context.TODO(), client, traitName).ExtractErr() + th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusNotFound)) +} + +func TestTraitsDeleteNotFound(t *testing.T) { + // The Traits API requires microversion 1.6 or later + clients.SkipReleasesBelow(t, "stable/pike") + + client, err := clients.NewPlacementV1Client() + th.AssertNoErr(t, err) + + client.Microversion = "1.6" + + traitName := strings.ToUpper(tools.RandomString("CUSTOM_", 8)) + + err = traits.Delete(context.TODO(), client, traitName).ExtractErr() + th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusNotFound)) +} + +// API does allow manipulation solely of custom traits, +// so trying to delete a standard trait should fail. +func TestTraitsDeleteStandardTraitFailure(t *testing.T) { + // The Traits API requires microversion 1.6 or later + clients.SkipReleasesBelow(t, "stable/pike") + + client, err := clients.NewPlacementV1Client() + th.AssertNoErr(t, err) + + client.Microversion = "1.6" + + traitName := "COMPUTE_NODE" + + err = traits.Delete(context.TODO(), client, traitName).ExtractErr() + th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusBadRequest)) +} diff --git a/openstack/placement/v1/traits/doc.go b/openstack/placement/v1/traits/doc.go index 91c7a8888e..d2774d9f29 100644 --- a/openstack/placement/v1/traits/doc.go +++ b/openstack/placement/v1/traits/doc.go @@ -50,5 +50,17 @@ Example to create a trait } else { fmt.Println("Trait created successfully!") } + +Example to delete a trait + + placementClient.Microversion = "1.6" + + traitName := "CUSTOM_HW_FPGA_CLASS1" + err := traits.Delete(context.TODO(), placementClient, traitName).ExtractErr() + if err != nil { + panic(err) + } else { + fmt.Println("Trait deleted successfully!") + } */ package traits diff --git a/openstack/placement/v1/traits/requests.go b/openstack/placement/v1/traits/requests.go index 2a106ff013..99e9b58434 100644 --- a/openstack/placement/v1/traits/requests.go +++ b/openstack/placement/v1/traits/requests.go @@ -67,3 +67,12 @@ func Create(ctx context.Context, client *gophercloud.ServiceClient, traitName st _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) return } + +// Delete deletes the trait specified by name. +func Delete(ctx context.Context, client *gophercloud.ServiceClient, traitName string) (r DeleteResult) { + resp, err := client.Delete(ctx, deleteURL(client, traitName), &gophercloud.RequestOpts{ + OkCodes: []int{204}, + }) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} diff --git a/openstack/placement/v1/traits/results.go b/openstack/placement/v1/traits/results.go index 0718b64601..085de1daf0 100644 --- a/openstack/placement/v1/traits/results.go +++ b/openstack/placement/v1/traits/results.go @@ -22,6 +22,12 @@ type CreateResult struct { gophercloud.ErrResult } +// DeleteResult is the response from a Delete operation. Call its ExtractErr to +// determine if the request succeeded or failed. +type DeleteResult struct { + gophercloud.ErrResult +} + // IsEmpty satisfies the IsEmpty method of the Page interface. It returns true // if a List contains no results. func (r TraitsPage) IsEmpty() (bool, error) { diff --git a/openstack/placement/v1/traits/testing/fixtures_test.go b/openstack/placement/v1/traits/testing/fixtures_test.go index 9a22bcb7d2..3a8eb9446a 100644 --- a/openstack/placement/v1/traits/testing/fixtures_test.go +++ b/openstack/placement/v1/traits/testing/fixtures_test.go @@ -12,6 +12,8 @@ import ( const PresentTrait = "CUSTOM_HW_FPGA_CLASS1" const AbsentTrait = "NON_EXISTENT_TRAIT" const CustomTraitToCreate = "CUSTOM_TRAIT_TO_CREATE" +const CustomTraitToDelete = CustomTraitToCreate +const StandardHardwareTrait = "HW_CPU_X86_AVX" const TraitsListResultAll = ` { @@ -138,3 +140,43 @@ func HandleCreateTraitInvalidName(t *testing.T, fakeServer th.FakeServer) { w.WriteHeader(http.StatusBadRequest) }) } + +func HandleDeleteTraitSuccess(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/traits/"+CustomTraitToDelete, + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "DELETE") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.WriteHeader(http.StatusNoContent) + }) +} + +func HandleDeleteTraitNotFound(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/traits/"+AbsentTrait, + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "DELETE") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.WriteHeader(http.StatusNotFound) + }) +} + +func HandleDeleteStandardTraitFailure(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/traits/"+StandardHardwareTrait, + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "DELETE") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.WriteHeader(http.StatusBadRequest) + }) +} + +func HandleDeleteTraitInUseFailure(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/traits/"+PresentTrait, + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "DELETE") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.WriteHeader(http.StatusConflict) + }) +} diff --git a/openstack/placement/v1/traits/testing/requests_test.go b/openstack/placement/v1/traits/testing/requests_test.go index 9f5b63663d..ecd08005d4 100644 --- a/openstack/placement/v1/traits/testing/requests_test.go +++ b/openstack/placement/v1/traits/testing/requests_test.go @@ -129,3 +129,43 @@ func TestCreateTraitInvalidName(t *testing.T) { err := traits.Create(context.TODO(), client.ServiceClient(fakeServer), AbsentTrait).ExtractErr() th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusBadRequest)) } + +func TestDeleteTraitSuccess(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleDeleteTraitSuccess(t, fakeServer) + + err := traits.Delete(context.TODO(), client.ServiceClient(fakeServer), CustomTraitToDelete).ExtractErr() + th.AssertNoErr(t, err) +} + +func TestDeleteTraitNotFound(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleDeleteTraitNotFound(t, fakeServer) + + err := traits.Delete(context.TODO(), client.ServiceClient(fakeServer), AbsentTrait).ExtractErr() + th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusNotFound)) +} + +func TestDeleteStandardTraitFailure(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleDeleteStandardTraitFailure(t, fakeServer) + + err := traits.Delete(context.TODO(), client.ServiceClient(fakeServer), StandardHardwareTrait).ExtractErr() + th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusBadRequest)) +} + +func TestDeleteTraitInUseFailure(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleDeleteTraitInUseFailure(t, fakeServer) + + err := traits.Delete(context.TODO(), client.ServiceClient(fakeServer), PresentTrait).ExtractErr() + th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusConflict)) +} diff --git a/openstack/placement/v1/traits/urls.go b/openstack/placement/v1/traits/urls.go index 2211abb309..2baba47c49 100644 --- a/openstack/placement/v1/traits/urls.go +++ b/openstack/placement/v1/traits/urls.go @@ -17,3 +17,7 @@ func getURL(client *gophercloud.ServiceClient, traitName string) string { func createURL(client *gophercloud.ServiceClient, traitName string) string { return client.ServiceURL(apiName, traitName) } + +func deleteURL(client *gophercloud.ServiceClient, traitName string) string { + return client.ServiceURL(apiName, traitName) +} From b7c7fcce6721d25e30b312b6d3a5746dee15680a Mon Sep 17 00:00:00 2001 From: Dominik Danelski Date: Tue, 31 Mar 2026 17:47:24 +0200 Subject: [PATCH 283/353] Implement resource_classes GET operations Related #526 API reference: https://docs.openstack.org/api-ref/placement/#resource-classes Code reference: https://github.com/openstack/placement/blob/stable/2025.1/placement/handlers/resource_class.py#L34-L39 https://github.com/openstack/placement/blob/stable/2025.1/placement/handlers/resource_class.py#L42-L52 Signed-off-by: Dominik Danelski --- .../placement/v1/resourceclasses_test.go | 65 ++++++++++ openstack/placement/v1/resourceclasses/doc.go | 36 ++++++ .../placement/v1/resourceclasses/requests.go | 24 ++++ .../placement/v1/resourceclasses/results.go | 62 +++++++++ .../v1/resourceclasses/testing/doc.go | 2 + .../resourceclasses/testing/fixtures_test.go | 118 ++++++++++++++++++ .../resourceclasses/testing/requests_test.go | 47 +++++++ .../placement/v1/resourceclasses/urls.go | 13 ++ 8 files changed, 367 insertions(+) create mode 100644 internal/acceptance/openstack/placement/v1/resourceclasses_test.go create mode 100644 openstack/placement/v1/resourceclasses/doc.go create mode 100644 openstack/placement/v1/resourceclasses/requests.go create mode 100644 openstack/placement/v1/resourceclasses/results.go create mode 100644 openstack/placement/v1/resourceclasses/testing/doc.go create mode 100644 openstack/placement/v1/resourceclasses/testing/fixtures_test.go create mode 100644 openstack/placement/v1/resourceclasses/testing/requests_test.go create mode 100644 openstack/placement/v1/resourceclasses/urls.go diff --git a/internal/acceptance/openstack/placement/v1/resourceclasses_test.go b/internal/acceptance/openstack/placement/v1/resourceclasses_test.go new file mode 100644 index 0000000000..81673417bf --- /dev/null +++ b/internal/acceptance/openstack/placement/v1/resourceclasses_test.go @@ -0,0 +1,65 @@ +//go:build acceptance || placement || resourceclasses + +package v1 + +import ( + "context" + "net/http" + "slices" + "testing" + + "github.com/gophercloud/gophercloud/v2" + "github.com/gophercloud/gophercloud/v2/internal/acceptance/clients" + "github.com/gophercloud/gophercloud/v2/openstack/placement/v1/resourceclasses" + th "github.com/gophercloud/gophercloud/v2/testhelper" +) + +func TestResourceClassesList(t *testing.T) { + // Resource classes were introduced in 1.2 + clients.SkipReleasesBelow(t, "stable/ocata") + + client, err := clients.NewPlacementV1Client() + th.AssertNoErr(t, err) + + client.Microversion = "1.2" + + allPages, err := resourceclasses.List(client).AllPages(context.TODO()) + th.AssertNoErr(t, err) + + allResourceClasses, err := resourceclasses.ExtractResourceClasses(allPages) + th.AssertNoErr(t, err) + + // Ensure VCPU is in the list + th.AssertEquals(t, true, slices.ContainsFunc(allResourceClasses, func(rc resourceclasses.ResourceClass) bool { + return rc.Name == "VCPU" + })) +} + +func TestResourceClassGetSuccess(t *testing.T) { + // Resource classes were introduced in 1.2 + clients.SkipReleasesBelow(t, "stable/ocata") + + client, err := clients.NewPlacementV1Client() + th.AssertNoErr(t, err) + + client.Microversion = "1.2" + + // VCPU is a standard resource class + rc, err := resourceclasses.Get(context.TODO(), client, "VCPU").Extract() + th.AssertNoErr(t, err) + + th.AssertEquals(t, "VCPU", rc.Name) +} + +func TestResourceClassGetNegative(t *testing.T) { + // Resource classes were introduced in 1.2 + clients.SkipReleasesBelow(t, "stable/ocata") + + client, err := clients.NewPlacementV1Client() + th.AssertNoErr(t, err) + + client.Microversion = "1.2" + + _, err = resourceclasses.Get(context.TODO(), client, "NON_EXISTENT_RC").Extract() + th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusNotFound)) +} diff --git a/openstack/placement/v1/resourceclasses/doc.go b/openstack/placement/v1/resourceclasses/doc.go new file mode 100644 index 0000000000..27f7c31ac8 --- /dev/null +++ b/openstack/placement/v1/resourceclasses/doc.go @@ -0,0 +1,36 @@ +/* +Package resourceclasses manages resource classes from the OpenStack Placement service. + +Resource Class API requests are available starting from microversion 1.2. + +Example to list resource classes + + placementClient.Microversion = "1.2" + + allPages, err := resourceclasses.List(placementClient).AllPages(context.TODO()) + if err != nil { + panic(err) + } + + allResourceClasses, err := resourceclasses.ExtractResourceClasses(allPages) + if err != nil { + panic(err) + } + + for _, rc := range allResourceClasses { + fmt.Printf("%+v\n", rc) + } + +Example to Get a resource class + + placementClient.Microversion = "1.2" + + resourceClassName := "VCPU" + resourceClass, err := resourceclasses.Get(context.TODO(), placementClient, resourceClassName).Extract() + if err != nil { + panic(err) + } + + fmt.Printf("%+v\n", resourceClass) +*/ +package resourceclasses diff --git a/openstack/placement/v1/resourceclasses/requests.go b/openstack/placement/v1/resourceclasses/requests.go new file mode 100644 index 0000000000..d497224aaf --- /dev/null +++ b/openstack/placement/v1/resourceclasses/requests.go @@ -0,0 +1,24 @@ +package resourceclasses + +import ( + "context" + + "github.com/gophercloud/gophercloud/v2" + "github.com/gophercloud/gophercloud/v2/pagination" +) + +// List retrieves a list of resource classes. +func List(client *gophercloud.ServiceClient) pagination.Pager { + url := listURL(client) + + return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { + return ResourceClassesPage{pagination.SinglePageBase(r)} + }) +} + +// Get retrieves the resource class with the provided name. +func Get(ctx context.Context, client *gophercloud.ServiceClient, name string) (r GetResult) { + resp, err := client.Get(ctx, getURL(client, name), &r.Body, nil) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} diff --git a/openstack/placement/v1/resourceclasses/results.go b/openstack/placement/v1/resourceclasses/results.go new file mode 100644 index 0000000000..85ed0a4e80 --- /dev/null +++ b/openstack/placement/v1/resourceclasses/results.go @@ -0,0 +1,62 @@ +package resourceclasses + +import ( + "github.com/gophercloud/gophercloud/v2" + "github.com/gophercloud/gophercloud/v2/pagination" +) + +type Link struct { + Href string `json:"href"` + Rel string `json:"rel"` +} + +type ResourceClass struct { + Name string `json:"name"` + + // Links is a list of links associated with the resource class. + Links []Link `json:"links"` +} + +// resourceClassResult is the response of a base ResourceClass result. +type resourceClassResult struct { + gophercloud.Result +} + +// Extract interprets any resourceClassResult-base result as a ResourceClass. +func (r resourceClassResult) Extract() (*ResourceClass, error) { + var s ResourceClass + err := r.ExtractInto(&s) + return &s, err +} + +// GetResult represents the result of a Get operation. Call its Extract +// method to interpret it as a ResourceClass. +type GetResult struct { + resourceClassResult +} + +// ResourceClassesPage contains a single page of all resource classes from a List call. +type ResourceClassesPage struct { + pagination.SinglePageBase +} + +// IsEmpty satisfies the IsEmpty method of the Page interface. It returns true +// if a List contains no results. +func (r ResourceClassesPage) IsEmpty() (bool, error) { + if r.StatusCode == 204 { + return true, nil + } + + resourceClasses, err := ExtractResourceClasses(r) + return len(resourceClasses) == 0, err +} + +// ExtractResourceClasses takes a List result and extracts the collection of resource classes +// returned by the API. +func ExtractResourceClasses(p pagination.Page) ([]ResourceClass, error) { + var s struct { + ResourceClasses []ResourceClass `json:"resource_classes"` + } + err := (p.(ResourceClassesPage)).ExtractInto(&s) + return s.ResourceClasses, err +} diff --git a/openstack/placement/v1/resourceclasses/testing/doc.go b/openstack/placement/v1/resourceclasses/testing/doc.go new file mode 100644 index 0000000000..2a3dd0b663 --- /dev/null +++ b/openstack/placement/v1/resourceclasses/testing/doc.go @@ -0,0 +1,2 @@ +// Package testing contains resourceclasses unit tests. +package testing diff --git a/openstack/placement/v1/resourceclasses/testing/fixtures_test.go b/openstack/placement/v1/resourceclasses/testing/fixtures_test.go new file mode 100644 index 0000000000..b13e355244 --- /dev/null +++ b/openstack/placement/v1/resourceclasses/testing/fixtures_test.go @@ -0,0 +1,118 @@ +package testing + +import ( + "fmt" + "net/http" + "testing" + + "github.com/gophercloud/gophercloud/v2/openstack/placement/v1/resourceclasses" + th "github.com/gophercloud/gophercloud/v2/testhelper" + "github.com/gophercloud/gophercloud/v2/testhelper/client" +) + +const PresentResourceClass = "CUSTOM_RESOURCE_CLASS" +const AbsentResourceClass = "NON_EXISTENT_RC" + +const ResourceClassGetResult = ` +{ + "links": [ + { + "href": "/placement/resource_classes/CUSTOM_RESOURCE_CLASS", + "rel": "self" + } + ], + "name": "CUSTOM_RESOURCE_CLASS" +} +` + +const ResourceClassesListResult = ` +{ + "resource_classes": [ + { + "name": "VCPU", + "links": [ + { + "href": "/resource_classes/VCPU", + "rel": "self" + } + ] + }, + { + "name": "CUSTOM_RESOURCE_CLASS", + "links": [ + { + "href": "/placement/resource_classes/CUSTOM_RESOURCE_CLASS", + "rel": "self" + } + ] + } + ] +} +` + +var ExpectedResourceClass = resourceclasses.ResourceClass{ + Name: "CUSTOM_RESOURCE_CLASS", + Links: []resourceclasses.Link{ + { + Href: "/placement/resource_classes/CUSTOM_RESOURCE_CLASS", + Rel: "self", + }, + }, +} + +var ExpectedResourceClassesList = []resourceclasses.ResourceClass{ + { + Name: "VCPU", + Links: []resourceclasses.Link{ + { + Href: "/resource_classes/VCPU", + Rel: "self", + }, + }, + }, + { + Name: "CUSTOM_RESOURCE_CLASS", + Links: []resourceclasses.Link{ + { + Href: "/placement/resource_classes/CUSTOM_RESOURCE_CLASS", + Rel: "self", + }, + }, + }, +} + +func HandleListResourceClasses(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/resource_classes", + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + + fmt.Fprint(w, ResourceClassesListResult) + }) +} + +func HandleGetResourceClassSuccess(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/resource_classes/"+PresentResourceClass, + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + + fmt.Fprint(w, ResourceClassGetResult) + }) +} + +func HandleGetResourceClassNotFound(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/resource_classes/"+AbsentResourceClass, + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.WriteHeader(http.StatusNotFound) + }) +} diff --git a/openstack/placement/v1/resourceclasses/testing/requests_test.go b/openstack/placement/v1/resourceclasses/testing/requests_test.go new file mode 100644 index 0000000000..4bb1f29f3c --- /dev/null +++ b/openstack/placement/v1/resourceclasses/testing/requests_test.go @@ -0,0 +1,47 @@ +package testing + +import ( + "context" + "net/http" + "testing" + + "github.com/gophercloud/gophercloud/v2" + "github.com/gophercloud/gophercloud/v2/openstack/placement/v1/resourceclasses" + th "github.com/gophercloud/gophercloud/v2/testhelper" + "github.com/gophercloud/gophercloud/v2/testhelper/client" +) + +func TestListResourceClasses(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleListResourceClasses(t, fakeServer) + + allPages, err := resourceclasses.List(client.ServiceClient(fakeServer)).AllPages(context.TODO()) + th.AssertNoErr(t, err) + + actual, err := resourceclasses.ExtractResourceClasses(allPages) + th.AssertNoErr(t, err) + th.AssertDeepEquals(t, ExpectedResourceClassesList, actual) +} + +func TestGetResourceClassSuccess(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleGetResourceClassSuccess(t, fakeServer) + + actual, err := resourceclasses.Get(context.TODO(), client.ServiceClient(fakeServer), PresentResourceClass).Extract() + th.AssertNoErr(t, err) + th.AssertDeepEquals(t, &ExpectedResourceClass, actual) +} + +func TestGetResourceClassNotFound(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleGetResourceClassNotFound(t, fakeServer) + + _, err := resourceclasses.Get(context.TODO(), client.ServiceClient(fakeServer), AbsentResourceClass).Extract() + th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusNotFound)) +} diff --git a/openstack/placement/v1/resourceclasses/urls.go b/openstack/placement/v1/resourceclasses/urls.go new file mode 100644 index 0000000000..0fec96e30c --- /dev/null +++ b/openstack/placement/v1/resourceclasses/urls.go @@ -0,0 +1,13 @@ +package resourceclasses + +import ( + "github.com/gophercloud/gophercloud/v2" +) + +func listURL(client *gophercloud.ServiceClient) string { + return client.ServiceURL("resource_classes") +} + +func getURL(client *gophercloud.ServiceClient, name string) string { + return client.ServiceURL("resource_classes", name) +} From a1124b2c6b4920c93c249eaf42c8bc62dc912140 Mon Sep 17 00:00:00 2001 From: Dominik Danelski Date: Tue, 31 Mar 2026 21:18:38 +0200 Subject: [PATCH 284/353] Implement resource_classes CREATE operations Related #526 API reference: https://docs.openstack.org/api-ref/placement/#resource-classes Code reference: https://github.com/openstack/placement/blob/stable/2025.1/placement/handlers/resource_class.py#L58-L85 https://github.com/openstack/placement/blob/stable/2025.1/placement/handlers/resource_class.py#L209-L240 Signed-off-by: Dominik Danelski --- .../placement/v1/resourceclasses_test.go | 94 +++++++++++++++++++ openstack/placement/v1/resourceclasses/doc.go | 22 +++++ .../placement/v1/resourceclasses/requests.go | 40 ++++++++ .../placement/v1/resourceclasses/results.go | 12 +++ .../resourceclasses/testing/fixtures_test.go | 53 +++++++++++ .../resourceclasses/testing/requests_test.go | 58 ++++++++++++ .../placement/v1/resourceclasses/urls.go | 8 ++ 7 files changed, 287 insertions(+) diff --git a/internal/acceptance/openstack/placement/v1/resourceclasses_test.go b/internal/acceptance/openstack/placement/v1/resourceclasses_test.go index 81673417bf..d2ea98fb51 100644 --- a/internal/acceptance/openstack/placement/v1/resourceclasses_test.go +++ b/internal/acceptance/openstack/placement/v1/resourceclasses_test.go @@ -6,10 +6,12 @@ import ( "context" "net/http" "slices" + "strings" "testing" "github.com/gophercloud/gophercloud/v2" "github.com/gophercloud/gophercloud/v2/internal/acceptance/clients" + "github.com/gophercloud/gophercloud/v2/internal/acceptance/tools" "github.com/gophercloud/gophercloud/v2/openstack/placement/v1/resourceclasses" th "github.com/gophercloud/gophercloud/v2/testhelper" ) @@ -63,3 +65,95 @@ func TestResourceClassGetNegative(t *testing.T) { _, err = resourceclasses.Get(context.TODO(), client, "NON_EXISTENT_RC").Extract() th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusNotFound)) } + +func TestResourceClassCreateByPostSuccess(t *testing.T) { + // Resource classes were introduced in 1.2 + clients.SkipReleasesBelow(t, "stable/ocata") + + client, err := clients.NewPlacementV1Client() + th.AssertNoErr(t, err) + + client.Microversion = "1.2" + + name := strings.ToUpper(tools.RandomString("CUSTOM_", 8)) + createOpts := resourceclasses.CreateOpts{ + Name: name, + } + + // Act: Create a resource class using POST + err = resourceclasses.Create(context.TODO(), client, createOpts).ExtractErr() + th.AssertNoErr(t, err) + + // Assert: The resource class exists + rc, err := resourceclasses.Get(context.TODO(), client, name).Extract() + th.AssertNoErr(t, err) + th.AssertEquals(t, name, rc.Name) +} + +func TestResourceClassCreateByPostDuplicate(t *testing.T) { + // Resource classes were introduced in 1.2 + clients.SkipReleasesBelow(t, "stable/ocata") + + client, err := clients.NewPlacementV1Client() + th.AssertNoErr(t, err) + + client.Microversion = "1.2" + + name := strings.ToUpper(tools.RandomString("CUSTOM_", 8)) + createOpts := resourceclasses.CreateOpts{ + Name: name, + } + + // Act: Create a resource class using POST + err = resourceclasses.Create(context.TODO(), client, createOpts).ExtractErr() + th.AssertNoErr(t, err) + + // Act: Try to create the same resource class again + err = resourceclasses.Create(context.TODO(), client, createOpts).ExtractErr() + // Assert: The error is a conflict + th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusConflict)) +} + +func TestResourceClassCreateByUpdateSuccess(t *testing.T) { + // Creating by Update (PUT) requires microversion 1.7 or later + clients.SkipReleasesBelow(t, "stable/pike") + + client, err := clients.NewPlacementV1Client() + th.AssertNoErr(t, err) + + client.Microversion = "1.7" + + name := strings.ToUpper(tools.RandomString("CUSTOM_", 8)) + + // Act: Create a resource class using PUT (Update) + err = resourceclasses.Update(context.TODO(), client, name).ExtractErr() + // No error, with 201 returned + th.AssertNoErr(t, err) + + // Act: Try to create the same resource class again + err = resourceclasses.Update(context.TODO(), client, name).ExtractErr() + // No error, with 204 returned + th.AssertNoErr(t, err) + + // Assert: The resource class exists + rc, err := resourceclasses.Get(context.TODO(), client, name).Extract() + th.AssertNoErr(t, err) + th.AssertEquals(t, name, rc.Name) +} + +func TestResourceClassCreateByUpdateNonCustomName(t *testing.T) { + // Creating by Update (PUT) requires microversion 1.7 or later + clients.SkipReleasesBelow(t, "stable/pike") + + client, err := clients.NewPlacementV1Client() + th.AssertNoErr(t, err) + + client.Microversion = "1.7" + + name := "CANNOT_CREATE_THIS" + + // Act: Try to create a resource class with a non-custom name using PUT (Update) + err = resourceclasses.Update(context.TODO(), client, name).ExtractErr() + // Assert: We get 400 + th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusBadRequest)) +} diff --git a/openstack/placement/v1/resourceclasses/doc.go b/openstack/placement/v1/resourceclasses/doc.go index 27f7c31ac8..53eae204c9 100644 --- a/openstack/placement/v1/resourceclasses/doc.go +++ b/openstack/placement/v1/resourceclasses/doc.go @@ -32,5 +32,27 @@ Example to Get a resource class } fmt.Printf("%+v\n", resourceClass) + +Example to Create a resource class using POST + + placementClient.Microversion = "1.2" + + createOpts := resourceclasses.CreateOpts{ + Name: "CUSTOM_RESOURCE_CLASS", + } + + err := resourceclasses.Create(context.TODO(), placementClient, createOpts).ExtractErr() + if err != nil { + panic(err) + } + +Example to ensure the existence of a resource class using PUT (idempotent creation) + + placementClient.Microversion = "1.7" + + err := resourceclasses.Update(context.TODO(), placementClient, "CUSTOM_RESOURCE_CLASS").ExtractErr() + if err != nil { + panic(err) + } */ package resourceclasses diff --git a/openstack/placement/v1/resourceclasses/requests.go b/openstack/placement/v1/resourceclasses/requests.go index d497224aaf..4fccd33c9c 100644 --- a/openstack/placement/v1/resourceclasses/requests.go +++ b/openstack/placement/v1/resourceclasses/requests.go @@ -22,3 +22,43 @@ func Get(ctx context.Context, client *gophercloud.ServiceClient, name string) (r _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) return } + +// CreateOptsBuilder allows extensions to add additional parameters to +// the Create request. +type CreateOptsBuilder interface { + ToResourceClassCreateMap() (map[string]any, error) +} + +// CreateOpts represents the attributes of a new resource class. +type CreateOpts struct { + Name string `json:"name" required:"true"` +} + +// ToResourceClassCreateMap formats a CreateOpts into a create request. +func (opts CreateOpts) ToResourceClassCreateMap() (map[string]any, error) { + return gophercloud.BuildRequestBody(opts, "") +} + +// Create creates a new resource class. +func Create(ctx context.Context, client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { + b, err := opts.ToResourceClassCreateMap() + if err != nil { + r.Err = err + return + } + resp, err := client.Post(ctx, createURL(client), b, nil, &gophercloud.RequestOpts{ + OkCodes: []int{201}, + }) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} + +// Update ensures the existence of a custom resource class with the +// provided name (can be safely called multiple times). +func Update(ctx context.Context, client *gophercloud.ServiceClient, name string) (r UpdateResult) { + resp, err := client.Put(ctx, updateURL(client, name), nil, nil, &gophercloud.RequestOpts{ + OkCodes: []int{201, 204}, + }) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} diff --git a/openstack/placement/v1/resourceclasses/results.go b/openstack/placement/v1/resourceclasses/results.go index 85ed0a4e80..cbd5501b9c 100644 --- a/openstack/placement/v1/resourceclasses/results.go +++ b/openstack/placement/v1/resourceclasses/results.go @@ -35,6 +35,18 @@ type GetResult struct { resourceClassResult } +// CreateResult is the response from a Create operation. Call its ExtractErr to +// determine if the request succeeded or failed. +type CreateResult struct { + gophercloud.ErrResult +} + +// UpdateResult is the response from an Update operation. Call its ExtractErr to +// determine if the request succeeded or failed. +type UpdateResult struct { + gophercloud.ErrResult +} + // ResourceClassesPage contains a single page of all resource classes from a List call. type ResourceClassesPage struct { pagination.SinglePageBase diff --git a/openstack/placement/v1/resourceclasses/testing/fixtures_test.go b/openstack/placement/v1/resourceclasses/testing/fixtures_test.go index b13e355244..7b0819cdef 100644 --- a/openstack/placement/v1/resourceclasses/testing/fixtures_test.go +++ b/openstack/placement/v1/resourceclasses/testing/fixtures_test.go @@ -12,6 +12,7 @@ import ( const PresentResourceClass = "CUSTOM_RESOURCE_CLASS" const AbsentResourceClass = "NON_EXISTENT_RC" +const NewResourceClass = "CUSTOM_NEW_RC" const ResourceClassGetResult = ` { @@ -116,3 +117,55 @@ func HandleGetResourceClassNotFound(t *testing.T, fakeServer th.FakeServer) { w.WriteHeader(http.StatusNotFound) }) } + +func HandleCreateResourceClassSuccess(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/resource_classes", + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "POST") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.TestJSONRequest(t, r, `{"name": "CUSTOM_NEW_RC"}`) + + w.WriteHeader(http.StatusCreated) + }) +} + +func HandleCreateResourceClassConflict(t *testing.T, fakeServer th.FakeServer) { + // We simulate a conflict by trying to create a resource class that already exists. + fakeServer.Mux.HandleFunc("/resource_classes", + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "POST") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.WriteHeader(http.StatusConflict) + }) +} + +func HandleUpdateResourceClassSuccess(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/resource_classes/"+NewResourceClass, + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "PUT") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.WriteHeader(http.StatusCreated) + }) +} + +func HandleUpdateResourceClassExists(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/resource_classes/"+PresentResourceClass, + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "PUT") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.WriteHeader(http.StatusNoContent) + }) +} + +func HandleUpdateResourceClassNonCustom(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/resource_classes/VCPU", + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "PUT") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.WriteHeader(http.StatusBadRequest) + }) +} diff --git a/openstack/placement/v1/resourceclasses/testing/requests_test.go b/openstack/placement/v1/resourceclasses/testing/requests_test.go index 4bb1f29f3c..e1a821f0de 100644 --- a/openstack/placement/v1/resourceclasses/testing/requests_test.go +++ b/openstack/placement/v1/resourceclasses/testing/requests_test.go @@ -45,3 +45,61 @@ func TestGetResourceClassNotFound(t *testing.T) { _, err := resourceclasses.Get(context.TODO(), client.ServiceClient(fakeServer), AbsentResourceClass).Extract() th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusNotFound)) } + +func TestCreateResourceClassSuccess(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleCreateResourceClassSuccess(t, fakeServer) + + createOpts := resourceclasses.CreateOpts{ + Name: NewResourceClass, + } + + err := resourceclasses.Create(context.TODO(), client.ServiceClient(fakeServer), createOpts).ExtractErr() + th.AssertNoErr(t, err) +} + +func TestCreateResourceClassConflict(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleCreateResourceClassConflict(t, fakeServer) + + createOpts := resourceclasses.CreateOpts{ + Name: PresentResourceClass, + } + + err := resourceclasses.Create(context.TODO(), client.ServiceClient(fakeServer), createOpts).ExtractErr() + th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusConflict)) +} + +func TestUpdateResourceClassCreateSuccess(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleUpdateResourceClassSuccess(t, fakeServer) + + err := resourceclasses.Update(context.TODO(), client.ServiceClient(fakeServer), NewResourceClass).ExtractErr() + th.AssertNoErr(t, err) +} + +func TestUpdateResourceClassExists(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleUpdateResourceClassExists(t, fakeServer) + + err := resourceclasses.Update(context.TODO(), client.ServiceClient(fakeServer), PresentResourceClass).ExtractErr() + th.AssertNoErr(t, err) +} + +func TestUpdateResourceClassNonCustom(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleUpdateResourceClassNonCustom(t, fakeServer) + + err := resourceclasses.Update(context.TODO(), client.ServiceClient(fakeServer), "VCPU").ExtractErr() + th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusBadRequest)) +} diff --git a/openstack/placement/v1/resourceclasses/urls.go b/openstack/placement/v1/resourceclasses/urls.go index 0fec96e30c..3dc3f82d19 100644 --- a/openstack/placement/v1/resourceclasses/urls.go +++ b/openstack/placement/v1/resourceclasses/urls.go @@ -8,6 +8,14 @@ func listURL(client *gophercloud.ServiceClient) string { return client.ServiceURL("resource_classes") } +func createURL(client *gophercloud.ServiceClient) string { + return client.ServiceURL("resource_classes") +} + func getURL(client *gophercloud.ServiceClient, name string) string { return client.ServiceURL("resource_classes", name) } + +func updateURL(client *gophercloud.ServiceClient, name string) string { + return client.ServiceURL("resource_classes", name) +} From eeb3c8bac409cceb2446a29dbcd04e0b6aecd042 Mon Sep 17 00:00:00 2001 From: Dominik Danelski Date: Tue, 31 Mar 2026 22:10:49 +0200 Subject: [PATCH 285/353] Implement resource_classes DELETE operation Related #526 API reference: https://docs.openstack.org/api-ref/placement/#resource-classes Code reference: https://github.com/openstack/placement/blob/stable/2025.1/placement/handlers/resource_class.py#L90-L110 Signed-off-by: Dominik Danelski --- .../placement/v1/resourceclasses_test.go | 62 +++++++++++++++++++ openstack/placement/v1/resourceclasses/doc.go | 9 +++ .../placement/v1/resourceclasses/requests.go | 9 +++ .../placement/v1/resourceclasses/results.go | 6 ++ .../resourceclasses/testing/fixtures_test.go | 30 +++++++++ .../resourceclasses/testing/requests_test.go | 31 ++++++++++ .../placement/v1/resourceclasses/urls.go | 4 ++ 7 files changed, 151 insertions(+) diff --git a/internal/acceptance/openstack/placement/v1/resourceclasses_test.go b/internal/acceptance/openstack/placement/v1/resourceclasses_test.go index d2ea98fb51..13f7663e40 100644 --- a/internal/acceptance/openstack/placement/v1/resourceclasses_test.go +++ b/internal/acceptance/openstack/placement/v1/resourceclasses_test.go @@ -157,3 +157,65 @@ func TestResourceClassCreateByUpdateNonCustomName(t *testing.T) { // Assert: We get 400 th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusBadRequest)) } + +func TestResourceClassDeleteSuccess(t *testing.T) { + // Resource classes were introduced in 1.2 + clients.SkipReleasesBelow(t, "stable/ocata") + + client, err := clients.NewPlacementV1Client() + th.AssertNoErr(t, err) + + client.Microversion = "1.2" + + name := strings.ToUpper(tools.RandomString("CUSTOM_", 8)) + createOpts := resourceclasses.CreateOpts{ + Name: name, + } + + // Arrange: Create a resource class to delete + err = resourceclasses.Create(context.TODO(), client, createOpts).ExtractErr() + th.AssertNoErr(t, err) + + // Arrange: Sanity check, the newly created resource class exists + rc, err := resourceclasses.Get(context.TODO(), client, name).Extract() + th.AssertNoErr(t, err) + th.AssertEquals(t, name, rc.Name) + + // Act: Delete the resource class + err = resourceclasses.Delete(context.TODO(), client, name).ExtractErr() + th.AssertNoErr(t, err) + + // Assert: The resource class no longer exists + _, err = resourceclasses.Get(context.TODO(), client, name).Extract() + th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusNotFound)) +} + +func TestResourceClassDeleteNotFound(t *testing.T) { + // Resource classes were introduced in 1.2 + clients.SkipReleasesBelow(t, "stable/ocata") + + client, err := clients.NewPlacementV1Client() + th.AssertNoErr(t, err) + + client.Microversion = "1.2" + + // Act: Try to delete a non-existent resource class + err = resourceclasses.Delete(context.TODO(), client, "CUSTOM_NON_EXISTENT_RC").ExtractErr() + // Assert: We get 404 + th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusNotFound)) +} + +func TestResourceClassDeleteStandardClass(t *testing.T) { + // Resource classes were introduced in 1.2 + clients.SkipReleasesBelow(t, "stable/ocata") + + client, err := clients.NewPlacementV1Client() + th.AssertNoErr(t, err) + + client.Microversion = "1.2" + + // Act: Try to delete a standard resource class + err = resourceclasses.Delete(context.TODO(), client, "VCPU").ExtractErr() + // Assert: We get 400 + th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusBadRequest)) +} diff --git a/openstack/placement/v1/resourceclasses/doc.go b/openstack/placement/v1/resourceclasses/doc.go index 53eae204c9..b1535af4ae 100644 --- a/openstack/placement/v1/resourceclasses/doc.go +++ b/openstack/placement/v1/resourceclasses/doc.go @@ -54,5 +54,14 @@ Example to ensure the existence of a resource class using PUT (idempotent creati if err != nil { panic(err) } + +Example to delete a resource class + + placementClient.Microversion = "1.2" + + err := resourceclasses.Delete(context.TODO(), placementClient, "CUSTOM_RESOURCE_CLASS").ExtractErr() + if err != nil { + panic(err) + } */ package resourceclasses diff --git a/openstack/placement/v1/resourceclasses/requests.go b/openstack/placement/v1/resourceclasses/requests.go index 4fccd33c9c..8621eddce5 100644 --- a/openstack/placement/v1/resourceclasses/requests.go +++ b/openstack/placement/v1/resourceclasses/requests.go @@ -62,3 +62,12 @@ func Update(ctx context.Context, client *gophercloud.ServiceClient, name string) _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) return } + +// Delete deletes the resource class with the provided name. +func Delete(ctx context.Context, client *gophercloud.ServiceClient, name string) (r DeleteResult) { + resp, err := client.Delete(ctx, deleteURL(client, name), &gophercloud.RequestOpts{ + OkCodes: []int{204}, + }) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} diff --git a/openstack/placement/v1/resourceclasses/results.go b/openstack/placement/v1/resourceclasses/results.go index cbd5501b9c..61131c372e 100644 --- a/openstack/placement/v1/resourceclasses/results.go +++ b/openstack/placement/v1/resourceclasses/results.go @@ -47,6 +47,12 @@ type UpdateResult struct { gophercloud.ErrResult } +// DeleteResult is the response from a Delete operation. Call its ExtractErr to +// determine if the request succeeded or failed. +type DeleteResult struct { + gophercloud.ErrResult +} + // ResourceClassesPage contains a single page of all resource classes from a List call. type ResourceClassesPage struct { pagination.SinglePageBase diff --git a/openstack/placement/v1/resourceclasses/testing/fixtures_test.go b/openstack/placement/v1/resourceclasses/testing/fixtures_test.go index 7b0819cdef..cfd5de8847 100644 --- a/openstack/placement/v1/resourceclasses/testing/fixtures_test.go +++ b/openstack/placement/v1/resourceclasses/testing/fixtures_test.go @@ -169,3 +169,33 @@ func HandleUpdateResourceClassNonCustom(t *testing.T, fakeServer th.FakeServer) w.WriteHeader(http.StatusBadRequest) }) } + +func HandleDeleteResourceClassSuccess(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/resource_classes/"+PresentResourceClass, + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "DELETE") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.WriteHeader(http.StatusNoContent) + }) +} + +func HandleDeleteResourceClassNotFound(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/resource_classes/"+AbsentResourceClass, + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "DELETE") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.WriteHeader(http.StatusNotFound) + }) +} + +func HandleDeleteResourceClassStandardClass(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/resource_classes/VCPU", + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "DELETE") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.WriteHeader(http.StatusBadRequest) + }) +} diff --git a/openstack/placement/v1/resourceclasses/testing/requests_test.go b/openstack/placement/v1/resourceclasses/testing/requests_test.go index e1a821f0de..9ff18e6a71 100644 --- a/openstack/placement/v1/resourceclasses/testing/requests_test.go +++ b/openstack/placement/v1/resourceclasses/testing/requests_test.go @@ -103,3 +103,34 @@ func TestUpdateResourceClassNonCustom(t *testing.T) { err := resourceclasses.Update(context.TODO(), client.ServiceClient(fakeServer), "VCPU").ExtractErr() th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusBadRequest)) } + +func TestDeleteResourceClassSuccess(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleDeleteResourceClassSuccess(t, fakeServer) + + err := resourceclasses.Delete(context.TODO(), client.ServiceClient(fakeServer), PresentResourceClass).ExtractErr() + th.AssertNoErr(t, err) +} + +func TestDeleteResourceClassNotFound(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleDeleteResourceClassNotFound(t, fakeServer) + + err := resourceclasses.Delete(context.TODO(), client.ServiceClient(fakeServer), AbsentResourceClass).ExtractErr() + th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusNotFound)) +} + +func TestDeleteResourceClassStandardClass(t *testing.T) { + // Removing standard resource classes is not allowed. + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleDeleteResourceClassStandardClass(t, fakeServer) + + err := resourceclasses.Delete(context.TODO(), client.ServiceClient(fakeServer), "VCPU").ExtractErr() + th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusBadRequest)) +} diff --git a/openstack/placement/v1/resourceclasses/urls.go b/openstack/placement/v1/resourceclasses/urls.go index 3dc3f82d19..85d9f77041 100644 --- a/openstack/placement/v1/resourceclasses/urls.go +++ b/openstack/placement/v1/resourceclasses/urls.go @@ -19,3 +19,7 @@ func getURL(client *gophercloud.ServiceClient, name string) string { func updateURL(client *gophercloud.ServiceClient, name string) string { return client.ServiceURL("resource_classes", name) } + +func deleteURL(client *gophercloud.ServiceClient, name string) string { + return client.ServiceURL("resource_classes", name) +} From 5bbe3e6bde1a957cd6e1e27e72689b0b197900ae Mon Sep 17 00:00:00 2001 From: jlarriba Date: Mon, 23 Feb 2026 15:30:41 +0100 Subject: [PATCH 286/353] Add metric-storage (Aetos) v1 service support Aetos is a Keystone-authenticated reverse proxy for Prometheus that enforces multi-tenant RBAC on all Prometheus queries. This adds Go bindings for the Prometheus HTTP API exposed under /api/v1/ with OpenStack authentication. Supported operations: Query, Labels, LabelValues, Series, Targets, RuntimeInfo, CleanTombstones, DeleteSeries, Snapshot. --- .github/workflows/functional-metric.yaml | 105 ++++++ Makefile | 6 +- internal/acceptance/clients/clients.go | 21 ++ .../openstack/metric/v1/metrics_test.go | 80 +++++ .../acceptance/openstack/metric/v1/pkg.go | 4 + openstack/client.go | 8 + openstack/metric/v1/metrics/doc.go | 59 ++++ openstack/metric/v1/metrics/requests.go | 263 ++++++++++++++ openstack/metric/v1/metrics/results.go | 298 ++++++++++++++++ openstack/metric/v1/metrics/testing/doc.go | 2 + .../v1/metrics/testing/fixtures_test.go | 327 ++++++++++++++++++ .../v1/metrics/testing/requests_test.go | 109 ++++++ openstack/metric/v1/metrics/urls.go | 39 +++ 13 files changed, 1320 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/functional-metric.yaml create mode 100644 internal/acceptance/openstack/metric/v1/metrics_test.go create mode 100644 internal/acceptance/openstack/metric/v1/pkg.go create mode 100644 openstack/metric/v1/metrics/doc.go create mode 100644 openstack/metric/v1/metrics/requests.go create mode 100644 openstack/metric/v1/metrics/results.go create mode 100644 openstack/metric/v1/metrics/testing/doc.go create mode 100644 openstack/metric/v1/metrics/testing/fixtures_test.go create mode 100644 openstack/metric/v1/metrics/testing/requests_test.go create mode 100644 openstack/metric/v1/metrics/urls.go diff --git a/.github/workflows/functional-metric.yaml b/.github/workflows/functional-metric.yaml new file mode 100644 index 0000000000..8f60039792 --- /dev/null +++ b/.github/workflows/functional-metric.yaml @@ -0,0 +1,105 @@ +name: functional-metric +on: + merge_group: + pull_request: + schedule: + - cron: '0 0 */3 * *' +jobs: + functional-metric: + permissions: + contents: read + strategy: + fail-fast: false + matrix: + include: + - name: "master" + openstack_version: "master" + ubuntu_version: "24.04" + devstack_conf_overrides: | + # ensure we're using a working version of setuptools + if [ -n "\$TOP_DIR" ]; then + sed -i 's/setuptools\[core\]$/setuptools[core]==79.0.1/g' \$TOP_DIR/lib/infra \$TOP_DIR/inc/python + sed -i 's/pip_install "-U" "pbr"/pip_install "-U" "pbr" "setuptools[core]==79.0.1"/g' \$TOP_DIR/lib/infra + fi + runs-on: ubuntu-${{ matrix.ubuntu_version }} + name: Aetos on OpenStack ${{ matrix.name }} + steps: + - name: Checkout Gophercloud + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + with: + persist-credentials: false + + - name: Check changed files + uses: ./.github/actions/file-filter + id: changed-files + with: + patterns: | + openstack/auth_env.go + openstack/client.go + openstack/endpoint.go + openstack/endpoint_location.go + openstack/config/provider_client.go + openstack/utils/choose_version.go + openstack/utils/discovery.go + **metric** + .github/workflows/functional-metric.yaml + + - name: Skip tests for unrelated changed-files + if: ${{ ! fromJSON(steps.changed-files.outputs.matches) }} + run: | + echo "No relevant files changed - skipping tests for ${{ matrix.name }}" + echo "TESTS_SKIPPED=true" >> $GITHUB_ENV + + - name: Deploy devstack + if: ${{ fromJSON(steps.changed-files.outputs.matches) }} + uses: gophercloud/devstack-action@60ca1042045c0c9e3e001c64575d381654ffcba1 # v0.19 + with: + branch: ${{ matrix.openstack_version }} + conf_overrides: | + enable_plugin devstack-plugin-prometheus https://opendev.org/openstack/devstack-plugin-prometheus ${{ matrix.openstack_version }} + enable_plugin ceilometer https://opendev.org/openstack/ceilometer ${{ matrix.openstack_version }} + CEILOMETER_BACKEND=sg-core + PROMETHEUS_CUSTOM_SCRAPE_TARGETS="localhost:3000" + enable_plugin sg-core https://github.com/openstack-k8s-operators/sg-core main + enable_plugin aetos https://opendev.org/openstack/aetos ${{ matrix.openstack_version }} + + ${{ matrix.devstack_conf_overrides }} + enabled_services: "prometheus,node_exporter,openstack_exporter,ceilometer-acompute,ceilometer-acentral,ceilometer-anotification,sg-core,aetos,openstack-cli-server" + + - name: Checkout go + if: ${{ fromJSON(steps.changed-files.outputs.matches) }} + uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 + with: + go-version-file: 'go.mod' + cache: true + + - name: Run Gophercloud acceptance tests + if: ${{ fromJSON(steps.changed-files.outputs.matches) }} + run: | + source ${{ github.workspace }}/script/stackenv + make acceptance-metric + echo "TESTS_RUN=true" >> $GITHUB_ENV + env: + DEVSTACK_PATH: ${{ github.workspace }}/devstack + OS_BRANCH: ${{ matrix.openstack_version }} + + - name: Generate logs on failure + run: ./script/collectlogs + if: ${{ failure() && fromJSON(steps.changed-files.outputs.matches) }} + + - name: Upload logs artifacts on failure + if: ${{ failure() && fromJSON(steps.changed-files.outputs.matches) }} + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + with: + name: functional-metric-${{ matrix.name }}-${{ github.run_id }} + path: /tmp/devstack-logs/* + + - name: Set job status + run: | + if [[ "$TESTS_SKIPPED" == "true" || "$TESTS_RUN" == "true" ]]; then + echo "Job completed successfully (either ran tests or skipped appropriately)" + exit 0 + else + echo "Job failed - neither tests ran nor were properly skipped" + exit 1 + fi diff --git a/Makefile b/Makefile index 79411c0026..6b9d043cf2 100644 --- a/Makefile +++ b/Makefile @@ -43,7 +43,7 @@ coverage: $(GO_TEST) -shuffle on -covermode count -coverprofile cover.out -coverpkg=./... ./... .PHONY: coverage -acceptance: acceptance-basic acceptance-baremetal acceptance-blockstorage acceptance-compute acceptance-container acceptance-containerinfra acceptance-db acceptance-dns acceptance-identity acceptance-image acceptance-keymanager acceptance-loadbalancer acceptance-messaging acceptance-networking acceptance-objectstorage acceptance-orchestration acceptance-placement acceptance-sharedfilesystems acceptance-workflow +acceptance: acceptance-basic acceptance-baremetal acceptance-blockstorage acceptance-compute acceptance-container acceptance-containerinfra acceptance-db acceptance-dns acceptance-identity acceptance-image acceptance-keymanager acceptance-loadbalancer acceptance-messaging acceptance-metric acceptance-networking acceptance-objectstorage acceptance-orchestration acceptance-placement acceptance-sharedfilesystems acceptance-workflow .PHONY: acceptance acceptance-basic: @@ -102,6 +102,10 @@ acceptance-messaging: $(GO_TEST) -timeout $(TIMEOUT) -tags "fixtures acceptance" ./internal/acceptance/openstack/messaging/... .PHONY: acceptance-messaging +acceptance-metric: + $(GO_TEST) -timeout $(TIMEOUT) -tags "fixtures acceptance" ./internal/acceptance/openstack/metric/... +.PHONY: acceptance-metric + acceptance-networking: $(GO_TEST) -timeout $(TIMEOUT) -tags "fixtures acceptance" ./internal/acceptance/openstack/networking/... .PHONY: acceptance-networking diff --git a/internal/acceptance/clients/clients.go b/internal/acceptance/clients/clients.go index 6c36391488..9e258dfe51 100644 --- a/internal/acceptance/clients/clients.go +++ b/internal/acceptance/clients/clients.go @@ -585,6 +585,27 @@ func NewMessagingV2Client(clientID string) (*gophercloud.ServiceClient, error) { }) } +// NewMetricV1Client returns a *ServiceClient for making calls +// to the OpenStack Metric v1 API. An error will be returned +// if authentication or client creation was not possible. +func NewMetricV1Client() (*gophercloud.ServiceClient, error) { + ao, err := openstack.AuthOptionsFromEnv() + if err != nil { + return nil, err + } + + client, err := openstack.AuthenticatedClient(context.TODO(), ao) + if err != nil { + return nil, err + } + + client = configureDebug(client) + + return openstack.NewMetricV1(context.TODO(), client, gophercloud.EndpointOpts{ + Region: os.Getenv("OS_REGION_NAME"), + }) +} + // NewContainerV1Client returns a *ServiceClient for making calls // to the OpenStack Container V1 API. An error will be returned // if authentication or client creation was not possible. diff --git a/internal/acceptance/openstack/metric/v1/metrics_test.go b/internal/acceptance/openstack/metric/v1/metrics_test.go new file mode 100644 index 0000000000..6fee465d62 --- /dev/null +++ b/internal/acceptance/openstack/metric/v1/metrics_test.go @@ -0,0 +1,80 @@ +//go:build acceptance || metric || metrics + +package v1 + +import ( + "context" + "testing" + + "github.com/gophercloud/gophercloud/v2/internal/acceptance/clients" + "github.com/gophercloud/gophercloud/v2/internal/acceptance/tools" + "github.com/gophercloud/gophercloud/v2/openstack/metric/v1/metrics" + th "github.com/gophercloud/gophercloud/v2/testhelper" +) + +func TestMetricQuery(t *testing.T) { + client, err := clients.NewMetricV1Client() + th.AssertNoErr(t, err) + + result, err := metrics.Query(context.TODO(), client, metrics.QueryOpts{ + Query: "up", + }).Extract() + th.AssertNoErr(t, err) + + tools.PrintResource(t, result) + th.AssertEquals(t, result.ResultType, "vector") +} + +func TestMetricLabels(t *testing.T) { + client, err := clients.NewMetricV1Client() + th.AssertNoErr(t, err) + + result, err := metrics.Labels(context.TODO(), client, nil).Extract() + th.AssertNoErr(t, err) + + tools.PrintResource(t, result) + if len(result) == 0 { + t.Fatal("expected at least one label") + } +} + +func TestMetricLabelValues(t *testing.T) { + client, err := clients.NewMetricV1Client() + th.AssertNoErr(t, err) + + result, err := metrics.LabelValues(context.TODO(), client, "__name__", nil).Extract() + th.AssertNoErr(t, err) + + tools.PrintResource(t, result) + if len(result) == 0 { + t.Fatal("expected at least one label value") + } +} + +func TestMetricSeries(t *testing.T) { + client, err := clients.NewMetricV1Client() + th.AssertNoErr(t, err) + + result, err := metrics.Series(context.TODO(), client, metrics.SeriesOpts{ + Match: []string{`{__name__="up"}`}, + }).Extract() + th.AssertNoErr(t, err) + + tools.PrintResource(t, result) + if len(result) == 0 { + t.Fatal("expected at least one series") + } +} + +func TestMetricRuntimeInfo(t *testing.T) { + client, err := clients.NewMetricV1Client() + th.AssertNoErr(t, err) + + result, err := metrics.RuntimeInfo(context.TODO(), client).Extract() + th.AssertNoErr(t, err) + + tools.PrintResource(t, result) + if result.StorageRetention == "" { + t.Fatal("expected non-empty StorageRetention") + } +} diff --git a/internal/acceptance/openstack/metric/v1/pkg.go b/internal/acceptance/openstack/metric/v1/pkg.go new file mode 100644 index 0000000000..05e9b4a1ab --- /dev/null +++ b/internal/acceptance/openstack/metric/v1/pkg.go @@ -0,0 +1,4 @@ +//go:build acceptance || metric + +// Package v1 contains acceptance tests for the OpenStack metric-storage v1 service. +package v1 diff --git a/openstack/client.go b/openstack/client.go index a0e84a1e80..d1026b16b2 100644 --- a/openstack/client.go +++ b/openstack/client.go @@ -464,6 +464,14 @@ func NewLoadBalancerV2(client *gophercloud.ProviderClient, eo gophercloud.Endpoi return sc, err } +// NewMetricV1 creates a ServiceClient that may be used with the v1 metric-storage +// service (Aetos). +func NewMetricV1(ctx context.Context, client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { + sc, err := initClientOpts(ctx, client, eo, "metric-storage", 1) + sc.ResourceBase = sc.Endpoint + "api/v1/" + return sc, err +} + // NewMessagingV2 creates a ServiceClient that may be used with the v2 messaging // service. func NewMessagingV2(client *gophercloud.ProviderClient, clientID string, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { diff --git a/openstack/metric/v1/metrics/doc.go b/openstack/metric/v1/metrics/doc.go new file mode 100644 index 0000000000..410dc07735 --- /dev/null +++ b/openstack/metric/v1/metrics/doc.go @@ -0,0 +1,59 @@ +/* +Package metrics provides interaction with the Prometheus HTTP API through the +OpenStack Aetos service (metric-storage). + +Aetos acts as a Keystone-authenticated reverse proxy for Prometheus, enforcing +multi-tenant RBAC on all Prometheus queries. It exposes the Prometheus HTTP API +under /api/v1/ with OpenStack authentication. + +Example to Create a Metric Service Client + + metricClient, err := openstack.NewMetricV1(ctx, providerClient, gophercloud.EndpointOpts{ + Region: "RegionOne", + }) + if err != nil { + panic(err) + } + +Example to Query Metrics + + opts := metrics.QueryOpts{ + Query: "up", + } + + result, err := metrics.Query(ctx, metricClient, opts).Extract() + if err != nil { + panic(err) + } + + for _, v := range result.Result { + fmt.Printf("%s: %v\n", v.Metric["__name__"], v.Value) + } + +Example to List Label Names + + labels, err := metrics.Labels(ctx, metricClient, nil).Extract() + if err != nil { + panic(err) + } + + for _, label := range labels { + fmt.Println(label) + } + +Example to Find Series by Label Matchers + + opts := metrics.SeriesOpts{ + Match: []string{"up", `process_start_time_seconds{job="prometheus"}`}, + } + + series, err := metrics.Series(ctx, metricClient, opts).Extract() + if err != nil { + panic(err) + } + + for _, s := range series { + fmt.Printf("%v\n", s) + } +*/ +package metrics diff --git a/openstack/metric/v1/metrics/requests.go b/openstack/metric/v1/metrics/requests.go new file mode 100644 index 0000000000..0fdc9624fb --- /dev/null +++ b/openstack/metric/v1/metrics/requests.go @@ -0,0 +1,263 @@ +package metrics + +import ( + "context" + + "github.com/gophercloud/gophercloud/v2" +) + +// QueryOptsBuilder allows extensions to add parameters to the Query request. +type QueryOptsBuilder interface { + ToMetricQueryQuery() (string, error) +} + +// QueryOpts contains the options for a Prometheus instant query. +type QueryOpts struct { + // Query is the PromQL query string. + Query string `q:"query" required:"true"` + + // Time is the evaluation timestamp (RFC3339 or Unix timestamp). + Time string `q:"time"` + + // Timeout is the evaluation timeout. + Timeout string `q:"timeout"` +} + +// ToMetricQueryQuery formats QueryOpts into a query string. +func (opts QueryOpts) ToMetricQueryQuery() (string, error) { + q, err := gophercloud.BuildQueryString(opts) + return q.String(), err +} + +// Query performs a Prometheus instant query. +func Query(ctx context.Context, client *gophercloud.ServiceClient, opts QueryOptsBuilder) (r QueryResult) { + url := queryURL(client) + if opts != nil { + query, err := opts.ToMetricQueryQuery() + if err != nil { + r.Err = err + return + } + url += query + } + resp, err := client.Get(ctx, url, &r.Body, nil) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} + +// LabelsOptsBuilder allows extensions to add parameters to the Labels request. +type LabelsOptsBuilder interface { + ToMetricLabelsQuery() (string, error) +} + +// LabelsOpts contains the options for listing label names. +type LabelsOpts struct { + // Match is a list of series selectors to filter labels by. + Match []string `q:"match[]"` + + // Start is the start timestamp (RFC3339 or Unix timestamp). + Start string `q:"start"` + + // End is the end timestamp (RFC3339 or Unix timestamp). + End string `q:"end"` +} + +// ToMetricLabelsQuery formats LabelsOpts into a query string. +func (opts LabelsOpts) ToMetricLabelsQuery() (string, error) { + q, err := gophercloud.BuildQueryString(opts) + return q.String(), err +} + +// Labels returns a list of label names. +func Labels(ctx context.Context, client *gophercloud.ServiceClient, opts LabelsOptsBuilder) (r LabelsResult) { + url := labelsURL(client) + if opts != nil { + query, err := opts.ToMetricLabelsQuery() + if err != nil { + r.Err = err + return + } + url += query + } + resp, err := client.Get(ctx, url, &r.Body, nil) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} + +// LabelValuesOptsBuilder allows extensions to add parameters to the LabelValues request. +type LabelValuesOptsBuilder interface { + ToMetricLabelValuesQuery() (string, error) +} + +// LabelValuesOpts contains the options for listing label values. +type LabelValuesOpts struct { + // Match is a list of series selectors to filter label values by. + Match []string `q:"match[]"` + + // Start is the start timestamp (RFC3339 or Unix timestamp). + Start string `q:"start"` + + // End is the end timestamp (RFC3339 or Unix timestamp). + End string `q:"end"` +} + +// ToMetricLabelValuesQuery formats LabelValuesOpts into a query string. +func (opts LabelValuesOpts) ToMetricLabelValuesQuery() (string, error) { + q, err := gophercloud.BuildQueryString(opts) + return q.String(), err +} + +// LabelValues returns a list of label values for a given label name. +func LabelValues(ctx context.Context, client *gophercloud.ServiceClient, name string, opts LabelValuesOptsBuilder) (r LabelValuesResult) { + url := labelValuesURL(client, name) + if opts != nil { + query, err := opts.ToMetricLabelValuesQuery() + if err != nil { + r.Err = err + return + } + url += query + } + resp, err := client.Get(ctx, url, &r.Body, nil) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} + +// SeriesOptsBuilder allows extensions to add parameters to the Series request. +type SeriesOptsBuilder interface { + ToMetricSeriesQuery() (string, error) +} + +// SeriesOpts contains the options for finding series by label matchers. +type SeriesOpts struct { + // Match is a list of series selectors. At least one must be provided. + Match []string `q:"match[]" required:"true"` + + // Start is the start timestamp (RFC3339 or Unix timestamp). + Start string `q:"start"` + + // End is the end timestamp (RFC3339 or Unix timestamp). + End string `q:"end"` +} + +// ToMetricSeriesQuery formats SeriesOpts into a query string. +func (opts SeriesOpts) ToMetricSeriesQuery() (string, error) { + q, err := gophercloud.BuildQueryString(opts) + return q.String(), err +} + +// Series returns the list of time series that match certain label sets. +func Series(ctx context.Context, client *gophercloud.ServiceClient, opts SeriesOptsBuilder) (r SeriesResult) { + url := seriesURL(client) + if opts != nil { + query, err := opts.ToMetricSeriesQuery() + if err != nil { + r.Err = err + return + } + url += query + } + resp, err := client.Get(ctx, url, &r.Body, nil) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} + +// TargetsOptsBuilder allows extensions to add parameters to the Targets request. +type TargetsOptsBuilder interface { + ToMetricTargetsQuery() (string, error) +} + +// TargetsOpts contains the options for listing targets. +type TargetsOpts struct { + // State filters targets by state ("active", "dropped", "any"). + State string `q:"state"` +} + +// ToMetricTargetsQuery formats TargetsOpts into a query string. +func (opts TargetsOpts) ToMetricTargetsQuery() (string, error) { + q, err := gophercloud.BuildQueryString(opts) + return q.String(), err +} + +// Targets returns an overview of the current state of Prometheus target discovery. +func Targets(ctx context.Context, client *gophercloud.ServiceClient, opts TargetsOptsBuilder) (r TargetsResult) { + url := targetsURL(client) + if opts != nil { + query, err := opts.ToMetricTargetsQuery() + if err != nil { + r.Err = err + return + } + url += query + } + resp, err := client.Get(ctx, url, &r.Body, nil) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} + +// RuntimeInfo returns runtime information about the Prometheus server. +func RuntimeInfo(ctx context.Context, client *gophercloud.ServiceClient) (r RuntimeInfoResult) { + resp, err := client.Get(ctx, runtimeInfoURL(client), &r.Body, nil) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} + +// CleanTombstones removes deleted data from disk and cleans up the existing tombstones. +func CleanTombstones(ctx context.Context, client *gophercloud.ServiceClient) (r CleanTombstonesResult) { + resp, err := client.Post(ctx, cleanTombstonesURL(client), nil, nil, &gophercloud.RequestOpts{ + OkCodes: []int{204}, + }) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} + +// DeleteSeriesOptsBuilder allows extensions to add parameters to the DeleteSeries request. +type DeleteSeriesOptsBuilder interface { + ToMetricDeleteSeriesQuery() (string, error) +} + +// DeleteSeriesOpts contains the options for deleting time series. +type DeleteSeriesOpts struct { + // Match is a list of series selectors. At least one must be provided. + Match []string `q:"match[]" required:"true"` + + // Start is the start timestamp (RFC3339 or Unix timestamp). + Start string `q:"start"` + + // End is the end timestamp (RFC3339 or Unix timestamp). + End string `q:"end"` +} + +// ToMetricDeleteSeriesQuery formats DeleteSeriesOpts into a query string. +func (opts DeleteSeriesOpts) ToMetricDeleteSeriesQuery() (string, error) { + q, err := gophercloud.BuildQueryString(opts) + return q.String(), err +} + +// DeleteSeries deletes data for a selection of series in a time range. +func DeleteSeries(ctx context.Context, client *gophercloud.ServiceClient, opts DeleteSeriesOptsBuilder) (r DeleteSeriesResult) { + url := deleteSeriesURL(client) + if opts != nil { + query, err := opts.ToMetricDeleteSeriesQuery() + if err != nil { + r.Err = err + return + } + url += query + } + resp, err := client.Post(ctx, url, nil, nil, &gophercloud.RequestOpts{ + OkCodes: []int{204}, + }) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} + +// Snapshot creates a snapshot of all current data into snapshots/- +// under the TSDB's data directory and returns the directory as response. +func Snapshot(ctx context.Context, client *gophercloud.ServiceClient) (r SnapshotResult) { + resp, err := client.Post(ctx, snapshotURL(client), nil, &r.Body, &gophercloud.RequestOpts{ + OkCodes: []int{200}, + }) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} diff --git a/openstack/metric/v1/metrics/results.go b/openstack/metric/v1/metrics/results.go new file mode 100644 index 0000000000..c4c6463ecf --- /dev/null +++ b/openstack/metric/v1/metrics/results.go @@ -0,0 +1,298 @@ +package metrics + +import ( + "encoding/json" + "fmt" + + "github.com/gophercloud/gophercloud/v2" +) + +// prometheusResponse is the common envelope for all Prometheus HTTP API responses. +type prometheusResponse struct { + Status string `json:"status"` + Data json.RawMessage `json:"data"` + ErrorType string `json:"errorType"` + Error string `json:"error"` +} + +// checkResponse unmarshals the Prometheus envelope and returns an error if +// the response status is "error". +func checkResponse(body any) (*prometheusResponse, error) { + b, err := json.Marshal(body) + if err != nil { + return nil, err + } + var resp prometheusResponse + if err := json.Unmarshal(b, &resp); err != nil { + return nil, err + } + if resp.Status == "error" { + return &resp, fmt.Errorf("prometheus %s: %s", resp.ErrorType, resp.Error) + } + return &resp, nil +} + +// QueryResult is the result of a Query request. +type QueryResult struct { + gophercloud.Result +} + +// Extract interprets a QueryResult as QueryData. +func (r QueryResult) Extract() (*QueryData, error) { + if r.Err != nil { + return nil, r.Err + } + resp, err := checkResponse(r.Body) + if err != nil { + return nil, err + } + var data QueryData + if err := json.Unmarshal(resp.Data, &data); err != nil { + return nil, err + } + return &data, nil +} + +// LabelsResult is the result of a Labels request. +type LabelsResult struct { + gophercloud.Result +} + +// Extract interprets a LabelsResult as a slice of label name strings. +func (r LabelsResult) Extract() ([]string, error) { + if r.Err != nil { + return nil, r.Err + } + resp, err := checkResponse(r.Body) + if err != nil { + return nil, err + } + var data []string + if err := json.Unmarshal(resp.Data, &data); err != nil { + return nil, err + } + return data, nil +} + +// LabelValuesResult is the result of a LabelValues request. +type LabelValuesResult struct { + gophercloud.Result +} + +// Extract interprets a LabelValuesResult as a slice of label value strings. +func (r LabelValuesResult) Extract() ([]string, error) { + if r.Err != nil { + return nil, r.Err + } + resp, err := checkResponse(r.Body) + if err != nil { + return nil, err + } + var data []string + if err := json.Unmarshal(resp.Data, &data); err != nil { + return nil, err + } + return data, nil +} + +// SeriesResult is the result of a Series request. +type SeriesResult struct { + gophercloud.Result +} + +// Extract interprets a SeriesResult as a slice of label-set maps. +func (r SeriesResult) Extract() ([]map[string]string, error) { + if r.Err != nil { + return nil, r.Err + } + resp, err := checkResponse(r.Body) + if err != nil { + return nil, err + } + var data []map[string]string + if err := json.Unmarshal(resp.Data, &data); err != nil { + return nil, err + } + return data, nil +} + +// TargetsResult is the result of a Targets request. +type TargetsResult struct { + gophercloud.Result +} + +// Extract interprets a TargetsResult as TargetsData. +func (r TargetsResult) Extract() (*TargetsData, error) { + if r.Err != nil { + return nil, r.Err + } + resp, err := checkResponse(r.Body) + if err != nil { + return nil, err + } + var data TargetsData + if err := json.Unmarshal(resp.Data, &data); err != nil { + return nil, err + } + return &data, nil +} + +// RuntimeInfoResult is the result of a RuntimeInfo request. +type RuntimeInfoResult struct { + gophercloud.Result +} + +// Extract interprets a RuntimeInfoResult as RuntimeInfoData. +func (r RuntimeInfoResult) Extract() (*RuntimeInfoData, error) { + if r.Err != nil { + return nil, r.Err + } + resp, err := checkResponse(r.Body) + if err != nil { + return nil, err + } + var data RuntimeInfoData + if err := json.Unmarshal(resp.Data, &data); err != nil { + return nil, err + } + return &data, nil +} + +// CleanTombstonesResult is the result of a CleanTombstones request. +type CleanTombstonesResult struct { + gophercloud.ErrResult +} + +// DeleteSeriesResult is the result of a DeleteSeries request. +type DeleteSeriesResult struct { + gophercloud.ErrResult +} + +// SnapshotResult is the result of a Snapshot request. +type SnapshotResult struct { + gophercloud.Result +} + +// Extract interprets a SnapshotResult as SnapshotData. +func (r SnapshotResult) Extract() (*SnapshotData, error) { + if r.Err != nil { + return nil, r.Err + } + resp, err := checkResponse(r.Body) + if err != nil { + return nil, err + } + var data SnapshotData + if err := json.Unmarshal(resp.Data, &data); err != nil { + return nil, err + } + return &data, nil +} + +// QueryData represents the data field of a Prometheus instant query response. +type QueryData struct { + // ResultType is the type of result (e.g., "vector", "matrix", "scalar", "string"). + ResultType string `json:"resultType"` + + // Result is the list of metric values returned by the query. + Result []MetricValue `json:"result"` +} + +// MetricValue represents a single metric result with its labels and value. +type MetricValue struct { + // Metric contains the label set identifying this metric. + Metric map[string]string `json:"metric"` + + // Value contains a single sample value as [timestamp, "string_value"]. + Value []any `json:"value"` +} + +// TargetsData represents the data field of a Prometheus targets response. +type TargetsData struct { + // ActiveTargets is the list of currently active scrape targets. + ActiveTargets []ActiveTarget `json:"activeTargets"` + + // DroppedTargets is the list of targets that were dropped during relabeling. + DroppedTargets []DroppedTarget `json:"droppedTargets"` +} + +// ActiveTarget represents an active Prometheus scrape target. +type ActiveTarget struct { + // DiscoveredLabels are the unmodified labels from service discovery. + DiscoveredLabels map[string]string `json:"discoveredLabels"` + + // Labels are the labels after relabeling. + Labels map[string]string `json:"labels"` + + // ScrapePool is the name of the scrape configuration. + ScrapePool string `json:"scrapePool"` + + // ScrapeURL is the URL being scraped. + ScrapeURL string `json:"scrapeUrl"` + + // GlobalURL is the URL as available from other Prometheus instances. + GlobalURL string `json:"globalUrl"` + + // LastError is the last error encountered during scraping. + LastError string `json:"lastError"` + + // LastScrape is the time of the last scrape. + LastScrape string `json:"lastScrape"` + + // LastScrapeDuration is the duration of the last scrape in seconds. + LastScrapeDuration float64 `json:"lastScrapeDuration"` + + // Health is the health status of the target ("up", "down", "unknown"). + Health string `json:"health"` + + // ScrapeInterval is the configured scrape interval. + ScrapeInterval string `json:"scrapeInterval"` + + // ScrapeTimeout is the configured scrape timeout. + ScrapeTimeout string `json:"scrapeTimeout"` +} + +// DroppedTarget represents a target that was dropped during relabeling. +type DroppedTarget struct { + // DiscoveredLabels are the unmodified labels from service discovery. + DiscoveredLabels map[string]string `json:"discoveredLabels"` +} + +// RuntimeInfoData represents the data field of a Prometheus runtime info response. +type RuntimeInfoData struct { + // StartTime is when the Prometheus server started. + StartTime string `json:"startTime"` + + // CWD is the current working directory of the Prometheus server. + CWD string `json:"CWD"` + + // ReloadConfigSuccess indicates if the last config reload was successful. + ReloadConfigSuccess bool `json:"reloadConfigSuccess"` + + // LastConfigTime is the time of the last config reload. + LastConfigTime string `json:"lastConfigTime"` + + // CorruptionCount is the number of WAL corruptions encountered. + CorruptionCount int `json:"corruptionCount"` + + // GoroutineCount is the number of goroutines. + GoroutineCount int `json:"goroutineCount"` + + // GOMAXPROCS is the configured GOMAXPROCS value. + GOMAXPROCS int `json:"GOMAXPROCS"` + + // GOGC is the configured GOGC value. + GOGC string `json:"GOGC"` + + // GODEBUG is the configured GODEBUG value. + GODEBUG string `json:"GODEBUG"` + + // StorageRetention is the configured storage retention. + StorageRetention string `json:"storageRetention"` +} + +// SnapshotData represents the data field of a Prometheus snapshot response. +type SnapshotData struct { + // Name is the filename of the snapshot created. + Name string `json:"name"` +} diff --git a/openstack/metric/v1/metrics/testing/doc.go b/openstack/metric/v1/metrics/testing/doc.go new file mode 100644 index 0000000000..c1ca16c942 --- /dev/null +++ b/openstack/metric/v1/metrics/testing/doc.go @@ -0,0 +1,2 @@ +// metrics unit tests +package testing diff --git a/openstack/metric/v1/metrics/testing/fixtures_test.go b/openstack/metric/v1/metrics/testing/fixtures_test.go new file mode 100644 index 0000000000..7da259fc61 --- /dev/null +++ b/openstack/metric/v1/metrics/testing/fixtures_test.go @@ -0,0 +1,327 @@ +package testing + +import ( + "fmt" + "net/http" + "testing" + + "github.com/gophercloud/gophercloud/v2" + "github.com/gophercloud/gophercloud/v2/openstack/metric/v1/metrics" + th "github.com/gophercloud/gophercloud/v2/testhelper" + "github.com/gophercloud/gophercloud/v2/testhelper/client" +) + +// serviceClient returns a ServiceClient with ResourceBase set to include api/v1/. +func serviceClient(fakeServer th.FakeServer) *gophercloud.ServiceClient { + sc := client.ServiceClient(fakeServer) + sc.ResourceBase = sc.Endpoint + "api/v1/" + return sc +} + +// QueryOutput is a sample response to a Query call. +const QueryOutput = ` +{ + "status": "success", + "data": { + "resultType": "vector", + "result": [ + { + "metric": { + "__name__": "up", + "instance": "localhost:9090", + "job": "prometheus" + }, + "value": [1435781451.781, "1"] + } + ] + } +} +` + +// ExpectedQueryData is the expected result from QueryOutput. +var ExpectedQueryData = &metrics.QueryData{ + ResultType: "vector", + Result: []metrics.MetricValue{ + { + Metric: map[string]string{ + "__name__": "up", + "instance": "localhost:9090", + "job": "prometheus", + }, + Value: []any{1435781451.781, "1"}, + }, + }, +} + +// LabelsOutput is a sample response to a Labels call. +const LabelsOutput = ` +{ + "status": "success", + "data": ["__name__", "instance", "job"] +} +` + +// ExpectedLabels is the expected result from LabelsOutput. +var ExpectedLabels = []string{"__name__", "instance", "job"} + +// LabelValuesOutput is a sample response to a LabelValues call. +const LabelValuesOutput = ` +{ + "status": "success", + "data": ["node", "prometheus"] +} +` + +// ExpectedLabelValues is the expected result from LabelValuesOutput. +var ExpectedLabelValues = []string{"node", "prometheus"} + +// SeriesOutput is a sample response to a Series call. +const SeriesOutput = ` +{ + "status": "success", + "data": [ + { + "__name__": "up", + "instance": "localhost:9090", + "job": "prometheus" + }, + { + "__name__": "up", + "instance": "localhost:9100", + "job": "node" + } + ] +} +` + +// ExpectedSeries is the expected result from SeriesOutput. +var ExpectedSeries = []map[string]string{ + { + "__name__": "up", + "instance": "localhost:9090", + "job": "prometheus", + }, + { + "__name__": "up", + "instance": "localhost:9100", + "job": "node", + }, +} + +// TargetsOutput is a sample response to a Targets call. +const TargetsOutput = ` +{ + "status": "success", + "data": { + "activeTargets": [ + { + "discoveredLabels": { + "__address__": "localhost:9090", + "__scheme__": "http", + "job": "prometheus" + }, + "labels": { + "instance": "localhost:9090", + "job": "prometheus" + }, + "scrapePool": "prometheus", + "scrapeUrl": "http://localhost:9090/metrics", + "globalUrl": "http://localhost:9090/metrics", + "lastError": "", + "lastScrape": "2025-08-20T10:30:00.000Z", + "lastScrapeDuration": 0.003145, + "health": "up", + "scrapeInterval": "15s", + "scrapeTimeout": "10s" + } + ], + "droppedTargets": [ + { + "discoveredLabels": { + "__address__": "localhost:9091", + "job": "dropped" + } + } + ] + } +} +` + +// ExpectedTargetsData is the expected result from TargetsOutput. +var ExpectedTargetsData = &metrics.TargetsData{ + ActiveTargets: []metrics.ActiveTarget{ + { + DiscoveredLabels: map[string]string{ + "__address__": "localhost:9090", + "__scheme__": "http", + "job": "prometheus", + }, + Labels: map[string]string{ + "instance": "localhost:9090", + "job": "prometheus", + }, + ScrapePool: "prometheus", + ScrapeURL: "http://localhost:9090/metrics", + GlobalURL: "http://localhost:9090/metrics", + LastError: "", + LastScrape: "2025-08-20T10:30:00.000Z", + LastScrapeDuration: 0.003145, + Health: "up", + ScrapeInterval: "15s", + ScrapeTimeout: "10s", + }, + }, + DroppedTargets: []metrics.DroppedTarget{ + { + DiscoveredLabels: map[string]string{ + "__address__": "localhost:9091", + "job": "dropped", + }, + }, + }, +} + +// RuntimeInfoOutput is a sample response to a RuntimeInfo call. +const RuntimeInfoOutput = ` +{ + "status": "success", + "data": { + "startTime": "2025-08-20T10:00:00.000Z", + "CWD": "/prometheus", + "reloadConfigSuccess": true, + "lastConfigTime": "2025-08-20T10:00:00.000Z", + "corruptionCount": 0, + "goroutineCount": 42, + "GOMAXPROCS": 4, + "GOGC": "", + "GODEBUG": "", + "storageRetention": "15d" + } +} +` + +// ExpectedRuntimeInfoData is the expected result from RuntimeInfoOutput. +var ExpectedRuntimeInfoData = &metrics.RuntimeInfoData{ + StartTime: "2025-08-20T10:00:00.000Z", + CWD: "/prometheus", + ReloadConfigSuccess: true, + LastConfigTime: "2025-08-20T10:00:00.000Z", + CorruptionCount: 0, + GoroutineCount: 42, + GOMAXPROCS: 4, + GOGC: "", + GODEBUG: "", + StorageRetention: "15d", +} + +// SnapshotOutput is a sample response to a Snapshot call. +const SnapshotOutput = ` +{ + "status": "success", + "data": { + "name": "20250820T100000Z-abcdef1234567890" + } +} +` + +// ExpectedSnapshotData is the expected result from SnapshotOutput. +var ExpectedSnapshotData = &metrics.SnapshotData{ + Name: "20250820T100000Z-abcdef1234567890", +} + +// HandleQuerySuccessfully configures the test server to respond to a Query request. +func HandleQuerySuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/api/v1/query", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.Header().Add("Content-Type", "application/json") + fmt.Fprint(w, QueryOutput) + }) +} + +// HandleLabelsSuccessfully configures the test server to respond to a Labels request. +func HandleLabelsSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/api/v1/labels", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.Header().Add("Content-Type", "application/json") + fmt.Fprint(w, LabelsOutput) + }) +} + +// HandleLabelValuesSuccessfully configures the test server to respond to a LabelValues request. +func HandleLabelValuesSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/api/v1/label/job/values", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.Header().Add("Content-Type", "application/json") + fmt.Fprint(w, LabelValuesOutput) + }) +} + +// HandleSeriesSuccessfully configures the test server to respond to a Series request. +func HandleSeriesSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/api/v1/series", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.Header().Add("Content-Type", "application/json") + fmt.Fprint(w, SeriesOutput) + }) +} + +// HandleTargetsSuccessfully configures the test server to respond to a Targets request. +func HandleTargetsSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/api/v1/targets", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.Header().Add("Content-Type", "application/json") + fmt.Fprint(w, TargetsOutput) + }) +} + +// HandleRuntimeInfoSuccessfully configures the test server to respond to a RuntimeInfo request. +func HandleRuntimeInfoSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/api/v1/status/runtimeinfo", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.Header().Add("Content-Type", "application/json") + fmt.Fprint(w, RuntimeInfoOutput) + }) +} + +// HandleCleanTombstonesSuccessfully configures the test server to respond to a CleanTombstones request. +func HandleCleanTombstonesSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/api/v1/admin/tsdb/clean_tombstones", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "POST") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.WriteHeader(http.StatusNoContent) + }) +} + +// HandleDeleteSeriesSuccessfully configures the test server to respond to a DeleteSeries request. +func HandleDeleteSeriesSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/api/v1/admin/tsdb/delete_series", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "POST") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.WriteHeader(http.StatusNoContent) + }) +} + +// HandleSnapshotSuccessfully configures the test server to respond to a Snapshot request. +func HandleSnapshotSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/api/v1/admin/tsdb/snapshot", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "POST") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.Header().Add("Content-Type", "application/json") + fmt.Fprint(w, SnapshotOutput) + }) +} diff --git a/openstack/metric/v1/metrics/testing/requests_test.go b/openstack/metric/v1/metrics/testing/requests_test.go new file mode 100644 index 0000000000..3311250643 --- /dev/null +++ b/openstack/metric/v1/metrics/testing/requests_test.go @@ -0,0 +1,109 @@ +package testing + +import ( + "context" + "testing" + + "github.com/gophercloud/gophercloud/v2/openstack/metric/v1/metrics" + th "github.com/gophercloud/gophercloud/v2/testhelper" +) + +func TestQuery(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleQuerySuccessfully(t, fakeServer) + + opts := metrics.QueryOpts{ + Query: "up", + } + + actual, err := metrics.Query(context.TODO(), serviceClient(fakeServer), opts).Extract() + th.AssertNoErr(t, err) + th.CheckDeepEquals(t, ExpectedQueryData, actual) +} + +func TestLabels(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleLabelsSuccessfully(t, fakeServer) + + actual, err := metrics.Labels(context.TODO(), serviceClient(fakeServer), nil).Extract() + th.AssertNoErr(t, err) + th.CheckDeepEquals(t, ExpectedLabels, actual) +} + +func TestLabelValues(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleLabelValuesSuccessfully(t, fakeServer) + + actual, err := metrics.LabelValues(context.TODO(), serviceClient(fakeServer), "job", nil).Extract() + th.AssertNoErr(t, err) + th.CheckDeepEquals(t, ExpectedLabelValues, actual) +} + +func TestSeries(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleSeriesSuccessfully(t, fakeServer) + + opts := metrics.SeriesOpts{ + Match: []string{"up"}, + } + + actual, err := metrics.Series(context.TODO(), serviceClient(fakeServer), opts).Extract() + th.AssertNoErr(t, err) + th.CheckDeepEquals(t, ExpectedSeries, actual) +} + +func TestTargets(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleTargetsSuccessfully(t, fakeServer) + + actual, err := metrics.Targets(context.TODO(), serviceClient(fakeServer), nil).Extract() + th.AssertNoErr(t, err) + th.CheckDeepEquals(t, ExpectedTargetsData, actual) +} + +func TestRuntimeInfo(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleRuntimeInfoSuccessfully(t, fakeServer) + + actual, err := metrics.RuntimeInfo(context.TODO(), serviceClient(fakeServer)).Extract() + th.AssertNoErr(t, err) + th.CheckDeepEquals(t, ExpectedRuntimeInfoData, actual) +} + +func TestCleanTombstones(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCleanTombstonesSuccessfully(t, fakeServer) + + err := metrics.CleanTombstones(context.TODO(), serviceClient(fakeServer)).ExtractErr() + th.AssertNoErr(t, err) +} + +func TestDeleteSeries(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDeleteSeriesSuccessfully(t, fakeServer) + + opts := metrics.DeleteSeriesOpts{ + Match: []string{"up"}, + } + + err := metrics.DeleteSeries(context.TODO(), serviceClient(fakeServer), opts).ExtractErr() + th.AssertNoErr(t, err) +} + +func TestSnapshot(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleSnapshotSuccessfully(t, fakeServer) + + actual, err := metrics.Snapshot(context.TODO(), serviceClient(fakeServer)).Extract() + th.AssertNoErr(t, err) + th.CheckDeepEquals(t, ExpectedSnapshotData, actual) +} diff --git a/openstack/metric/v1/metrics/urls.go b/openstack/metric/v1/metrics/urls.go new file mode 100644 index 0000000000..856f84da5b --- /dev/null +++ b/openstack/metric/v1/metrics/urls.go @@ -0,0 +1,39 @@ +package metrics + +import "github.com/gophercloud/gophercloud/v2" + +func queryURL(c *gophercloud.ServiceClient) string { + return c.ServiceURL("query") +} + +func labelsURL(c *gophercloud.ServiceClient) string { + return c.ServiceURL("labels") +} + +func labelValuesURL(c *gophercloud.ServiceClient, name string) string { + return c.ServiceURL("label", name, "values") +} + +func seriesURL(c *gophercloud.ServiceClient) string { + return c.ServiceURL("series") +} + +func targetsURL(c *gophercloud.ServiceClient) string { + return c.ServiceURL("targets") +} + +func runtimeInfoURL(c *gophercloud.ServiceClient) string { + return c.ServiceURL("status", "runtimeinfo") +} + +func cleanTombstonesURL(c *gophercloud.ServiceClient) string { + return c.ServiceURL("admin", "tsdb", "clean_tombstones") +} + +func deleteSeriesURL(c *gophercloud.ServiceClient) string { + return c.ServiceURL("admin", "tsdb", "delete_series") +} + +func snapshotURL(c *gophercloud.ServiceClient) string { + return c.ServiceURL("admin", "tsdb", "snapshot") +} From ec8f9471e24f053cb5cec30569a08d2d3415b2be Mon Sep 17 00:00:00 2001 From: Dominik Danelski Date: Wed, 1 Apr 2026 20:12:12 +0200 Subject: [PATCH 287/353] Implement UPDATE operations on Placement resource providers inventories Related: #526 API reference: https://docs.openstack.org/api-ref/placement/#update-resource-provider-inventories https://docs.openstack.org/api-ref/placement/#update-resource-provider-inventory Code reference: https://opendev.org/openstack/placement/src/branch/stable/2026.1/placement/handlers/inventory.py#L257-L277 https://opendev.org/openstack/placement/src/branch/stable/2026.1/placement/handlers/inventory.py#L280-L307 Signed-off-by: Dominik Danelski --- .../placement/v1/resourceproviders_test.go | 147 ++++++++++++++++++ .../placement/v1/resourceproviders/doc.go | 51 ++++++ .../v1/resourceproviders/requests.go | 58 +++++++ .../placement/v1/resourceproviders/results.go | 18 +++ .../testing/fixtures_test.go | 132 ++++++++++++++++ .../testing/requests_test.go | 48 ++++++ .../placement/v1/resourceproviders/urls.go | 4 + 7 files changed, 458 insertions(+) diff --git a/internal/acceptance/openstack/placement/v1/resourceproviders_test.go b/internal/acceptance/openstack/placement/v1/resourceproviders_test.go index bd6c3f1fa4..b23cb318ae 100644 --- a/internal/acceptance/openstack/placement/v1/resourceproviders_test.go +++ b/internal/acceptance/openstack/placement/v1/resourceproviders_test.go @@ -4,14 +4,19 @@ package v1 import ( "context" + "net/http" "testing" + "github.com/gophercloud/gophercloud/v2" "github.com/gophercloud/gophercloud/v2/internal/acceptance/clients" "github.com/gophercloud/gophercloud/v2/internal/acceptance/tools" "github.com/gophercloud/gophercloud/v2/openstack/placement/v1/resourceproviders" th "github.com/gophercloud/gophercloud/v2/testhelper" ) +const InventoryResourceClass = "VCPU" +const NonExistentRPUUID = "00000000-0000-0000-0000-000000000000" + func TestResourceProviderList(t *testing.T) { clients.RequireAdmin(t) @@ -100,6 +105,148 @@ func TestResourceProviderInventories(t *testing.T) { tools.PrintResource(t, usage) } +func TestResourceProviderUpdateInventory(t *testing.T) { + clients.RequireAdmin(t) + + client, err := clients.NewPlacementV1Client() + th.AssertNoErr(t, err) + + resourceProvider, err := CreateResourceProvider(t, client) + th.AssertNoErr(t, err) + defer DeleteResourceProvider(t, client, resourceProvider.UUID) + + // Arrange: Get the current inventory to retrieve the generation + inventories, err := resourceproviders.GetInventories(context.TODO(), client, resourceProvider.UUID).Extract() + th.AssertNoErr(t, err) + + // Arrange: The resource class on this provider must exist first + seedOpts := resourceproviders.UpdateInventoriesOpts{ + ResourceProviderGeneration: inventories.ResourceProviderGeneration, + Inventories: map[string]resourceproviders.Inventory{ + InventoryResourceClass: { + AllocationRatio: 1.0, + MaxUnit: 4, + MinUnit: 1, + Reserved: 0, + StepSize: 1, + Total: 4, + }, + }, + } + + seededInventories, err := resourceproviders.UpdateInventories(context.TODO(), client, resourceProvider.UUID, seedOpts).Extract() + th.AssertNoErr(t, err) + + expectedInventory := resourceproviders.Inventory{ + AllocationRatio: 1.0, + MaxUnit: 8, + MinUnit: 1, + Reserved: 0, + StepSize: 1, + Total: 8, + } + + updateOpts := resourceproviders.UpdateInventoryOpts{ + ResourceProviderGeneration: seededInventories.ResourceProviderGeneration, + Inventory: expectedInventory, + } + + _, err = resourceproviders.UpdateInventory(context.TODO(), client, resourceProvider.UUID, InventoryResourceClass, updateOpts).Extract() + th.AssertNoErr(t, err) + + updatedInventories, err := resourceproviders.GetInventories(context.TODO(), client, resourceProvider.UUID).Extract() + th.AssertNoErr(t, err) + + actualInventory, ok := updatedInventories.Inventories[InventoryResourceClass] + th.AssertEquals(t, true, ok) + th.AssertDeepEquals(t, expectedInventory, actualInventory) +} + +func TestResourceProviderUpdateInventoryNotFound(t *testing.T) { + clients.RequireAdmin(t) + + client, err := clients.NewPlacementV1Client() + th.AssertNoErr(t, err) + + updateOpts := resourceproviders.UpdateInventoryOpts{ + ResourceProviderGeneration: 0, + Inventory: resourceproviders.Inventory{ + AllocationRatio: 1.0, + MaxUnit: 1, + MinUnit: 1, + Reserved: 0, + StepSize: 1, + Total: 1, + }, + } + + _, err = resourceproviders.UpdateInventory(context.TODO(), client, NonExistentRPUUID, InventoryResourceClass, updateOpts).Extract() + th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusNotFound)) +} + +func TestResourceProviderUpdateInventories(t *testing.T) { + clients.RequireAdmin(t) + + client, err := clients.NewPlacementV1Client() + th.AssertNoErr(t, err) + + resourceProvider, err := CreateResourceProvider(t, client) + th.AssertNoErr(t, err) + defer DeleteResourceProvider(t, client, resourceProvider.UUID) + + // Arrange: Get the current inventory to retrieve the generation + inventories, err := resourceproviders.GetInventories(context.TODO(), client, resourceProvider.UUID).Extract() + th.AssertNoErr(t, err) + + expectedInventories := map[string]resourceproviders.Inventory{ + "DISK_GB": { + AllocationRatio: 1.0, + MaxUnit: 100, + MinUnit: 1, + Reserved: 0, + StepSize: 1, + Total: 100, + }, + } + + updateOpts := resourceproviders.UpdateInventoriesOpts{ + ResourceProviderGeneration: inventories.ResourceProviderGeneration, + Inventories: expectedInventories, + } + + _, err = resourceproviders.UpdateInventories(context.TODO(), client, resourceProvider.UUID, updateOpts).Extract() + th.AssertNoErr(t, err) + + updatedInventories, err := resourceproviders.GetInventories(context.TODO(), client, resourceProvider.UUID).Extract() + th.AssertNoErr(t, err) + + th.AssertDeepEquals(t, expectedInventories, updatedInventories.Inventories) +} + +func TestResourceProviderUpdateInventoriesNotFound(t *testing.T) { + clients.RequireAdmin(t) + + client, err := clients.NewPlacementV1Client() + th.AssertNoErr(t, err) + + updateOpts := resourceproviders.UpdateInventoriesOpts{ + ResourceProviderGeneration: 0, + Inventories: map[string]resourceproviders.Inventory{ + InventoryResourceClass: { + AllocationRatio: 1.0, + MaxUnit: 1, + MinUnit: 1, + Reserved: 0, + StepSize: 1, + Total: 1, + }, + }, + } + + _, err = resourceproviders.UpdateInventories(context.TODO(), client, NonExistentRPUUID, updateOpts).Extract() + th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusNotFound)) +} + func TestResourceProviderTraits(t *testing.T) { clients.RequireAdmin(t) diff --git a/openstack/placement/v1/resourceproviders/doc.go b/openstack/placement/v1/resourceproviders/doc.go index d659558f15..729222ab9b 100644 --- a/openstack/placement/v1/resourceproviders/doc.go +++ b/openstack/placement/v1/resourceproviders/doc.go @@ -75,6 +75,57 @@ Example to get resource providers inventories panic(err) } +Example to update (replace) all resource provider inventories + + inventories, err := resourceproviders.GetInventories(context.TODO(), placementClient, resourceProviderID).Extract() + if err != nil { + panic(err) + } + + updateInventoriesOpts := resourceproviders.UpdateInventoriesOpts{ + ResourceProviderGeneration: inventories.ResourceProviderGeneration, + Inventories: map[string]resourceproviders.Inventory{ + "VCPU": { + Total: 4, + Reserved: 0, + MinUnit: 1, + MaxUnit: 4, + StepSize: 1, + AllocationRatio: 16.0, + }, + }, + } + + rp, err = resourceproviders.UpdateInventories(context.TODO(), placementClient, resourceProviderID, updateInventoriesOpts).Extract() + if err != nil { + panic(err) + } + +Example to update one existing resource provider inventory + + inventories, err := resourceproviders.GetInventories(context.TODO(), placementClient, resourceProviderID).Extract() + if err != nil { + panic(err) + } + + // UpdateInventory updates an existing resource class inventory. + updateInventoryOpts := resourceproviders.UpdateInventoryOpts{ + ResourceProviderGeneration: inventories.ResourceProviderGeneration, + Inventory: resourceproviders.Inventory{ + Total: 4, + Reserved: 0, + MinUnit: 1, + MaxUnit: 4, + StepSize: 1, + AllocationRatio: 16.0, + }, + } + + rpInventory, err := resourceproviders.UpdateInventory(context.TODO(), placementClient, resourceProviderID, "VCPU", updateInventoryOpts).Extract() + if err != nil { + panic(err) + } + Example to get resource providers traits rp, err := resourceproviders.GetTraits(context.TODO(), placementClient, resourceProviderID).Extract() diff --git a/openstack/placement/v1/resourceproviders/requests.go b/openstack/placement/v1/resourceproviders/requests.go index f0dfa9d66f..1ef7690ad1 100644 --- a/openstack/placement/v1/resourceproviders/requests.go +++ b/openstack/placement/v1/resourceproviders/requests.go @@ -164,6 +164,64 @@ func GetInventories(ctx context.Context, client *gophercloud.ServiceClient, reso return } +// UpdateInventoriesOptsBuilder allows extensions to add additional parameters to the +// UpdateInventories request. +type UpdateInventoriesOptsBuilder interface { + ToResourceProviderUpdateInventoriesMap() (map[string]any, error) +} + +// UpdateInventoriesOpts represents options used to update all inventories of a resource provider. +type UpdateInventoriesOpts = ResourceProviderInventories + +// ToResourceProviderUpdateInventoriesMap constructs a request body from UpdateInventoriesOpts. +func (opts UpdateInventoriesOpts) ToResourceProviderUpdateInventoriesMap() (map[string]any, error) { + return gophercloud.BuildRequestBody(opts, "") +} + +// UpdateInventories updates all inventories of a resource provider. +func UpdateInventories(ctx context.Context, client *gophercloud.ServiceClient, resourceProviderID string, opts UpdateInventoriesOptsBuilder) (r GetInventoriesResult) { + b, err := opts.ToResourceProviderUpdateInventoriesMap() + if err != nil { + r.Err = err + return + } + + resp, err := client.Put(ctx, getResourceProviderInventoriesURL(client, resourceProviderID), b, &r.Body, &gophercloud.RequestOpts{ + OkCodes: []int{200}, + }) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} + +// UpdateInventoryOptsBuilder allows extensions to add additional parameters to the +// UpdateInventory request. +type UpdateInventoryOptsBuilder interface { + ToResourceProviderUpdateInventoryMap() (map[string]any, error) +} + +// UpdateInventoryOpts represents options used to update one inventory of a resource provider. +type UpdateInventoryOpts = ResourceProviderInventory + +// ToResourceProviderUpdateInventoryMap constructs a request body from UpdateInventoryOpts. +func (opts UpdateInventoryOpts) ToResourceProviderUpdateInventoryMap() (map[string]any, error) { + return gophercloud.BuildRequestBody(opts, "") +} + +// UpdateInventory updates one inventory of a resource provider. +func UpdateInventory(ctx context.Context, client *gophercloud.ServiceClient, resourceProviderID, resourceClass string, opts UpdateInventoryOptsBuilder) (r UpdateInventoryResult) { + b, err := opts.ToResourceProviderUpdateInventoryMap() + if err != nil { + r.Err = err + return + } + + resp, err := client.Put(ctx, updateResourceProviderInventoryURL(client, resourceProviderID, resourceClass), b, &r.Body, &gophercloud.RequestOpts{ + OkCodes: []int{200}, + }) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} + func GetAllocations(ctx context.Context, client *gophercloud.ServiceClient, resourceProviderID string) (r GetAllocationsResult) { resp, err := client.Get(ctx, getResourceProviderAllocationsURL(client, resourceProviderID), &r.Body, nil) _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) diff --git a/openstack/placement/v1/resourceproviders/results.go b/openstack/placement/v1/resourceproviders/results.go index 19b71103e1..4c00bad016 100644 --- a/openstack/placement/v1/resourceproviders/results.go +++ b/openstack/placement/v1/resourceproviders/results.go @@ -56,6 +56,11 @@ type ResourceProviderInventories struct { Inventories map[string]Inventory `json:"inventories"` } +type ResourceProviderInventory struct { + ResourceProviderGeneration int `json:"resource_provider_generation"` + Inventory +} + type ResourceProviderAllocations struct { ResourceProviderGeneration int `json:"resource_provider_generation"` Allocations map[string]Allocation `json:"allocations"` @@ -153,6 +158,19 @@ func (r GetInventoriesResult) Extract() (*ResourceProviderInventories, error) { return &s, err } +// UpdateInventoryResult is the response of an Update inventory operation. Call its Extract method +// to interpret it as a ResourceProviderInventory. +type UpdateInventoryResult struct { + gophercloud.Result +} + +// Extract interprets a UpdateInventoryResult as a ResourceProviderInventory. +func (r UpdateInventoryResult) Extract() (*ResourceProviderInventory, error) { + var s ResourceProviderInventory + err := r.ExtractInto(&s) + return &s, err +} + // GetAllocationsResult is the response of a Get allocations operations. Call its Extract method // to interpret it as a ResourceProviderAllocations. type GetAllocationsResult struct { diff --git a/openstack/placement/v1/resourceproviders/testing/fixtures_test.go b/openstack/placement/v1/resourceproviders/testing/fixtures_test.go index 6ac4b8ca73..f50a7f4547 100644 --- a/openstack/placement/v1/resourceproviders/testing/fixtures_test.go +++ b/openstack/placement/v1/resourceproviders/testing/fixtures_test.go @@ -12,6 +12,8 @@ import ( ) const ResourceProviderTestID = "99c09379-6e52-4ef8-9a95-b9ce6f68452e" +const PresentInventoryResourceClass = "VCPU" +const NonExistentRPID = "00000000-0000-0000-0000-000000000000" const ResourceProvidersBody = ` { @@ -128,6 +130,62 @@ const InventoriesBody = ` } ` +const UpdateInventoriesRequest = ` +{ + "resource_provider_generation": 7, + "inventories": { + "DISK_GB": { + "allocation_ratio": 1.0, + "max_unit": 35, + "min_unit": 1, + "reserved": 0, + "step_size": 1, + "total": 35 + }, + "MEMORY_MB": { + "allocation_ratio": 1.5, + "max_unit": 5825, + "min_unit": 1, + "reserved": 512, + "step_size": 1, + "total": 5825 + }, + "VCPU": { + "allocation_ratio": 16.0, + "max_unit": 4, + "min_unit": 1, + "reserved": 0, + "step_size": 1, + "total": 4 + } + } +} +` + +const InventoryBody = ` +{ + "resource_provider_generation": 7, + "allocation_ratio": 16.0, + "max_unit": 4, + "min_unit": 1, + "reserved": 0, + "step_size": 1, + "total": 4 +} +` + +const UpdateInventoryRequest = ` +{ + "resource_provider_generation": 7, + "allocation_ratio": 16.0, + "max_unit": 4, + "min_unit": 1, + "reserved": 0, + "step_size": 1, + "total": 4 +} +` + const AllocationsBody = ` { "allocations": { @@ -236,6 +294,18 @@ var ExpectedInventories = resourceproviders.ResourceProviderInventories{ }, } +var ExpectedInventory = resourceproviders.ResourceProviderInventory{ + ResourceProviderGeneration: 7, + Inventory: resourceproviders.Inventory{ + AllocationRatio: 16.0, + MaxUnit: 4, + MinUnit: 1, + Reserved: 0, + StepSize: 1, + Total: 4, + }, +} + var ExpectedAllocations = resourceproviders.ResourceProviderAllocations{ ResourceProviderGeneration: 12, Allocations: map[string]resourceproviders.Allocation{ @@ -358,6 +428,68 @@ func HandleResourceProviderGetInventories(t *testing.T, fakeServer th.FakeServer }) } +func HandleResourceProviderPutInventories(t *testing.T, fakeServer th.FakeServer) { + inventoriesTestURL := fmt.Sprintf("/resource_providers/%s/inventories", ResourceProviderTestID) + + fakeServer.Mux.HandleFunc(inventoriesTestURL, + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "PUT") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.TestHeader(t, r, "Content-Type", "application/json") + th.TestHeader(t, r, "Accept", "application/json") + th.TestJSONRequest(t, r, UpdateInventoriesRequest) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + + fmt.Fprint(w, InventoriesBody) + }) +} + +func HandleResourceProviderPutInventoriesNotFound(t *testing.T, fakeServer th.FakeServer) { + inventoriesNotFoundURL := fmt.Sprintf("/resource_providers/%s/inventories", NonExistentRPID) + + fakeServer.Mux.HandleFunc(inventoriesNotFoundURL, + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "PUT") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusNotFound) + fmt.Fprint(w, `{"errors":[{"status":404,"title":"Not Found"}]}`) + }) +} + +func HandleResourceProviderPutInventory(t *testing.T, fakeServer th.FakeServer) { + inventoryTestURL := fmt.Sprintf("/resource_providers/%s/inventories/%s", ResourceProviderTestID, PresentInventoryResourceClass) + + fakeServer.Mux.HandleFunc(inventoryTestURL, + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "PUT") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.TestHeader(t, r, "Content-Type", "application/json") + th.TestHeader(t, r, "Accept", "application/json") + th.TestJSONRequest(t, r, UpdateInventoryRequest) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + + fmt.Fprint(w, InventoryBody) + }) +} + +func HandleResourceProviderPutInventoryNotFound(t *testing.T, fakeServer th.FakeServer) { + inventoryNotFoundURL := fmt.Sprintf("/resource_providers/%s/inventories/%s", NonExistentRPID, PresentInventoryResourceClass) + + fakeServer.Mux.HandleFunc(inventoryNotFoundURL, + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "PUT") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusNotFound) + fmt.Fprint(w, `{"errors":[{"status":404,"title":"Not Found"}]}`) + }) +} + func HandleResourceProviderGetAllocations(t *testing.T, fakeServer th.FakeServer) { allocationsTestUrl := fmt.Sprintf("/resource_providers/%s/allocations", ResourceProviderTestID) diff --git a/openstack/placement/v1/resourceproviders/testing/requests_test.go b/openstack/placement/v1/resourceproviders/testing/requests_test.go index 4633c81136..67546d1930 100644 --- a/openstack/placement/v1/resourceproviders/testing/requests_test.go +++ b/openstack/placement/v1/resourceproviders/testing/requests_test.go @@ -2,8 +2,10 @@ package testing import ( "context" + "net/http" "testing" + "github.com/gophercloud/gophercloud/v2" "github.com/gophercloud/gophercloud/v2/openstack/placement/v1/resourceproviders" "github.com/gophercloud/gophercloud/v2/pagination" @@ -124,6 +126,52 @@ func TestGetResourceProvidersInventories(t *testing.T) { th.AssertDeepEquals(t, ExpectedInventories, *actual) } +func TestUpdateResourceProvidersInventories(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleResourceProviderPutInventories(t, fakeServer) + + opts := resourceproviders.UpdateInventoriesOpts(ExpectedInventories) + actual, err := resourceproviders.UpdateInventories(context.TODO(), client.ServiceClient(fakeServer), ResourceProviderTestID, opts).Extract() + th.AssertNoErr(t, err) + th.AssertDeepEquals(t, ExpectedInventories, *actual) +} + +func TestUpdateResourceProvidersInventoriesNotFound(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleResourceProviderPutInventoriesNotFound(t, fakeServer) + + opts := resourceproviders.UpdateInventoriesOpts(ExpectedInventories) + _, err := resourceproviders.UpdateInventories(context.TODO(), client.ServiceClient(fakeServer), NonExistentRPID, opts).Extract() + th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusNotFound)) +} + +func TestUpdateResourceProviderInventory(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleResourceProviderPutInventory(t, fakeServer) + + opts := resourceproviders.UpdateInventoryOpts(ExpectedInventory) + actual, err := resourceproviders.UpdateInventory(context.TODO(), client.ServiceClient(fakeServer), ResourceProviderTestID, PresentInventoryResourceClass, opts).Extract() + th.AssertNoErr(t, err) + th.AssertDeepEquals(t, ExpectedInventory, *actual) +} + +func TestUpdateResourceProviderInventoryNotFound(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleResourceProviderPutInventoryNotFound(t, fakeServer) + + opts := resourceproviders.UpdateInventoryOpts(ExpectedInventory) + _, err := resourceproviders.UpdateInventory(context.TODO(), client.ServiceClient(fakeServer), NonExistentRPID, PresentInventoryResourceClass, opts).Extract() + th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusNotFound)) +} + func TestGetResourceProvidersAllocations(t *testing.T) { fakeServer := th.SetupHTTP() defer fakeServer.Teardown() diff --git a/openstack/placement/v1/resourceproviders/urls.go b/openstack/placement/v1/resourceproviders/urls.go index 037149b684..5fe326e4bc 100644 --- a/openstack/placement/v1/resourceproviders/urls.go +++ b/openstack/placement/v1/resourceproviders/urls.go @@ -30,6 +30,10 @@ func getResourceProviderInventoriesURL(client *gophercloud.ServiceClient, resour return client.ServiceURL(apiName, resourceProviderID, "inventories") } +func updateResourceProviderInventoryURL(client *gophercloud.ServiceClient, resourceProviderID, resourceClass string) string { + return client.ServiceURL(apiName, resourceProviderID, "inventories", resourceClass) +} + func getResourceProviderAllocationsURL(client *gophercloud.ServiceClient, resourceProviderID string) string { return client.ServiceURL(apiName, resourceProviderID, "allocations") } From 6241e6972d0645d873a9a0453f5ff200904202fd Mon Sep 17 00:00:00 2001 From: Dominik Danelski Date: Wed, 1 Apr 2026 18:16:46 +0200 Subject: [PATCH 288/353] Implement resource providers inventory GET Related #526 API reference: https://docs.openstack.org/api-ref/placement/#show-resource-provider-inventory Code reference: https://opendev.org/openstack/placement/src/branch/stable/2026.1/placement/handlers/inventory.py#L280-L307 Signed-off-by: Dominik Danelski --- .../placement/v1/resourceproviders_test.go | 67 +++++++++++++++++++ .../placement/v1/resourceproviders/doc.go | 7 ++ .../v1/resourceproviders/requests.go | 6 ++ .../placement/v1/resourceproviders/results.go | 13 ++++ .../testing/fixtures_test.go | 27 ++++++++ .../testing/requests_test.go | 21 ++++++ .../placement/v1/resourceproviders/urls.go | 4 ++ 7 files changed, 145 insertions(+) diff --git a/internal/acceptance/openstack/placement/v1/resourceproviders_test.go b/internal/acceptance/openstack/placement/v1/resourceproviders_test.go index b23cb318ae..c1aa52ea94 100644 --- a/internal/acceptance/openstack/placement/v1/resourceproviders_test.go +++ b/internal/acceptance/openstack/placement/v1/resourceproviders_test.go @@ -15,6 +15,7 @@ import ( ) const InventoryResourceClass = "VCPU" +const MissingInventoryResourceClass = "NO_SUCH_CLASS" const NonExistentRPUUID = "00000000-0000-0000-0000-000000000000" func TestResourceProviderList(t *testing.T) { @@ -105,6 +106,72 @@ func TestResourceProviderInventories(t *testing.T) { tools.PrintResource(t, usage) } +func TestResourceProviderInventory(t *testing.T) { + clients.RequireAdmin(t) + + client, err := clients.NewPlacementV1Client() + th.AssertNoErr(t, err) + + resourceProvider, err := CreateResourceProvider(t, client) + th.AssertNoErr(t, err) + defer DeleteResourceProvider(t, client, resourceProvider.UUID) + + inventories, err := resourceproviders.GetInventories(context.TODO(), client, resourceProvider.UUID).Extract() + th.AssertNoErr(t, err) + + seededInventories, err := resourceproviders.UpdateInventories(context.TODO(), client, resourceProvider.UUID, resourceproviders.UpdateInventoriesOpts{ + ResourceProviderGeneration: inventories.ResourceProviderGeneration, + Inventories: map[string]resourceproviders.Inventory{ + InventoryResourceClass: { + AllocationRatio: 1.0, + MaxUnit: 4, + MinUnit: 1, + Reserved: 0, + StepSize: 1, + Total: 4, + }, + }, + }).Extract() + th.AssertNoErr(t, err) + + inventory, err := resourceproviders.GetInventory(context.TODO(), client, resourceProvider.UUID, InventoryResourceClass).Extract() + th.AssertNoErr(t, err) + th.AssertEquals(t, seededInventories.ResourceProviderGeneration, inventory.ResourceProviderGeneration) + th.AssertDeepEquals(t, seededInventories.Inventories[InventoryResourceClass], inventory.Inventory) +} + +func TestResourceProviderInventoryNotFound(t *testing.T) { + clients.RequireAdmin(t) + + client, err := clients.NewPlacementV1Client() + th.AssertNoErr(t, err) + + resourceProvider, err := CreateResourceProvider(t, client) + th.AssertNoErr(t, err) + defer DeleteResourceProvider(t, client, resourceProvider.UUID) + + inventories, err := resourceproviders.GetInventories(context.TODO(), client, resourceProvider.UUID).Extract() + th.AssertNoErr(t, err) + + _, err = resourceproviders.UpdateInventories(context.TODO(), client, resourceProvider.UUID, resourceproviders.UpdateInventoriesOpts{ + ResourceProviderGeneration: inventories.ResourceProviderGeneration, + Inventories: map[string]resourceproviders.Inventory{ + InventoryResourceClass: { + AllocationRatio: 1.0, + MaxUnit: 4, + MinUnit: 1, + Reserved: 0, + StepSize: 1, + Total: 4, + }, + }, + }).Extract() + th.AssertNoErr(t, err) + + _, err = resourceproviders.GetInventory(context.TODO(), client, resourceProvider.UUID, MissingInventoryResourceClass).Extract() + th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusNotFound)) +} + func TestResourceProviderUpdateInventory(t *testing.T) { clients.RequireAdmin(t) diff --git a/openstack/placement/v1/resourceproviders/doc.go b/openstack/placement/v1/resourceproviders/doc.go index 729222ab9b..4a1270794a 100644 --- a/openstack/placement/v1/resourceproviders/doc.go +++ b/openstack/placement/v1/resourceproviders/doc.go @@ -75,6 +75,13 @@ Example to get resource providers inventories panic(err) } +Example to get one resource provider inventory + + rpInventory, err := resourceproviders.GetInventory(context.TODO(), placementClient, resourceProviderID, "VCPU").Extract() + if err != nil { + panic(err) + } + Example to update (replace) all resource provider inventories inventories, err := resourceproviders.GetInventories(context.TODO(), placementClient, resourceProviderID).Extract() diff --git a/openstack/placement/v1/resourceproviders/requests.go b/openstack/placement/v1/resourceproviders/requests.go index 1ef7690ad1..2985d63794 100644 --- a/openstack/placement/v1/resourceproviders/requests.go +++ b/openstack/placement/v1/resourceproviders/requests.go @@ -164,6 +164,12 @@ func GetInventories(ctx context.Context, client *gophercloud.ServiceClient, reso return } +func GetInventory(ctx context.Context, client *gophercloud.ServiceClient, resourceProviderID, resourceClass string) (r GetInventoryResult) { + resp, err := client.Get(ctx, getResourceProviderInventoryURL(client, resourceProviderID, resourceClass), &r.Body, nil) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} + // UpdateInventoriesOptsBuilder allows extensions to add additional parameters to the // UpdateInventories request. type UpdateInventoriesOptsBuilder interface { diff --git a/openstack/placement/v1/resourceproviders/results.go b/openstack/placement/v1/resourceproviders/results.go index 4c00bad016..7f67c39819 100644 --- a/openstack/placement/v1/resourceproviders/results.go +++ b/openstack/placement/v1/resourceproviders/results.go @@ -158,6 +158,19 @@ func (r GetInventoriesResult) Extract() (*ResourceProviderInventories, error) { return &s, err } +// GetInventoryResult is the response of a Get inventory operation. Call its Extract method +// to interpret it as a ResourceProviderInventory. +type GetInventoryResult struct { + gophercloud.Result +} + +// Extract interprets a GetInventoryResult as a ResourceProviderInventory. +func (r GetInventoryResult) Extract() (*ResourceProviderInventory, error) { + var s ResourceProviderInventory + err := r.ExtractInto(&s) + return &s, err +} + // UpdateInventoryResult is the response of an Update inventory operation. Call its Extract method // to interpret it as a ResourceProviderInventory. type UpdateInventoryResult struct { diff --git a/openstack/placement/v1/resourceproviders/testing/fixtures_test.go b/openstack/placement/v1/resourceproviders/testing/fixtures_test.go index f50a7f4547..d904e1e98c 100644 --- a/openstack/placement/v1/resourceproviders/testing/fixtures_test.go +++ b/openstack/placement/v1/resourceproviders/testing/fixtures_test.go @@ -13,6 +13,7 @@ import ( const ResourceProviderTestID = "99c09379-6e52-4ef8-9a95-b9ce6f68452e" const PresentInventoryResourceClass = "VCPU" +const MissingInventoryResourceClass = "NO_SUCH_CLASS" const NonExistentRPID = "00000000-0000-0000-0000-000000000000" const ResourceProvidersBody = ` @@ -428,6 +429,32 @@ func HandleResourceProviderGetInventories(t *testing.T, fakeServer th.FakeServer }) } +func HandleResourceProviderGetInventory(t *testing.T, fakeServer th.FakeServer) { + inventoryTestURL := fmt.Sprintf("/resource_providers/%s/inventories/%s", ResourceProviderTestID, PresentInventoryResourceClass) + + fakeServer.Mux.HandleFunc(inventoryTestURL, + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + + fmt.Fprint(w, InventoryBody) + }) +} + +func HandleResourceProviderGetInventoryNotFound(t *testing.T, fakeServer th.FakeServer) { + inventoryNotFoundURL := fmt.Sprintf("/resource_providers/%s/inventories/%s", ResourceProviderTestID, MissingInventoryResourceClass) + + fakeServer.Mux.HandleFunc(inventoryNotFoundURL, + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + w.WriteHeader(http.StatusNotFound) + }) +} + func HandleResourceProviderPutInventories(t *testing.T, fakeServer th.FakeServer) { inventoriesTestURL := fmt.Sprintf("/resource_providers/%s/inventories", ResourceProviderTestID) diff --git a/openstack/placement/v1/resourceproviders/testing/requests_test.go b/openstack/placement/v1/resourceproviders/testing/requests_test.go index 67546d1930..5b12d37c89 100644 --- a/openstack/placement/v1/resourceproviders/testing/requests_test.go +++ b/openstack/placement/v1/resourceproviders/testing/requests_test.go @@ -126,6 +126,27 @@ func TestGetResourceProvidersInventories(t *testing.T) { th.AssertDeepEquals(t, ExpectedInventories, *actual) } +func TestGetResourceProviderInventory(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleResourceProviderGetInventory(t, fakeServer) + + actual, err := resourceproviders.GetInventory(context.TODO(), client.ServiceClient(fakeServer), ResourceProviderTestID, PresentInventoryResourceClass).Extract() + th.AssertNoErr(t, err) + th.AssertDeepEquals(t, ExpectedInventory, *actual) +} + +func TestGetResourceProviderInventoryNotFound(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleResourceProviderGetInventoryNotFound(t, fakeServer) + + _, err := resourceproviders.GetInventory(context.TODO(), client.ServiceClient(fakeServer), ResourceProviderTestID, MissingInventoryResourceClass).Extract() + th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusNotFound)) +} + func TestUpdateResourceProvidersInventories(t *testing.T) { fakeServer := th.SetupHTTP() defer fakeServer.Teardown() diff --git a/openstack/placement/v1/resourceproviders/urls.go b/openstack/placement/v1/resourceproviders/urls.go index 5fe326e4bc..61d6e1e811 100644 --- a/openstack/placement/v1/resourceproviders/urls.go +++ b/openstack/placement/v1/resourceproviders/urls.go @@ -30,6 +30,10 @@ func getResourceProviderInventoriesURL(client *gophercloud.ServiceClient, resour return client.ServiceURL(apiName, resourceProviderID, "inventories") } +func getResourceProviderInventoryURL(client *gophercloud.ServiceClient, resourceProviderID, resourceClass string) string { + return client.ServiceURL(apiName, resourceProviderID, "inventories", resourceClass) +} + func updateResourceProviderInventoryURL(client *gophercloud.ServiceClient, resourceProviderID, resourceClass string) string { return client.ServiceURL(apiName, resourceProviderID, "inventories", resourceClass) } From 18cbf43dd65e49f10e8ea2bfd29170339b74f979 Mon Sep 17 00:00:00 2001 From: Dominik Danelski Date: Thu, 2 Apr 2026 11:31:47 +0200 Subject: [PATCH 289/353] Implement resource providers inventory DELETE API reference: https://docs.openstack.org/api-ref/placement/#delete-resource-provider-inventories https://docs.openstack.org/api-ref/placement/#delete-resource-provider-inventory Code reference: https://opendev.org/openstack/placement/src/branch/stable/2026.1/placement/handlers/inventory.py#L377-L410 https://opendev.org/openstack/placement/src/branch/stable/2026.1/placement/handlers/inventory.py#L222-L254 Signed-off-by: Dominik Danelski --- .../placement/v1/resourceproviders_test.go | 102 ++++++++++++++++++ .../placement/v1/resourceproviders/doc.go | 16 +++ .../v1/resourceproviders/requests.go | 14 +++ .../testing/fixtures_test.go | 52 +++++++++ .../testing/requests_test.go | 40 +++++++ .../placement/v1/resourceproviders/urls.go | 8 ++ 6 files changed, 232 insertions(+) diff --git a/internal/acceptance/openstack/placement/v1/resourceproviders_test.go b/internal/acceptance/openstack/placement/v1/resourceproviders_test.go index c1aa52ea94..ecad86b4d9 100644 --- a/internal/acceptance/openstack/placement/v1/resourceproviders_test.go +++ b/internal/acceptance/openstack/placement/v1/resourceproviders_test.go @@ -251,6 +251,108 @@ func TestResourceProviderUpdateInventoryNotFound(t *testing.T) { th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusNotFound)) } +func TestResourceProviderDeleteInventorySuccess(t *testing.T) { + clients.RequireAdmin(t) + + client, err := clients.NewPlacementV1Client() + th.AssertNoErr(t, err) + + resourceProvider, err := CreateResourceProvider(t, client) + th.AssertNoErr(t, err) + defer DeleteResourceProvider(t, client, resourceProvider.UUID) + + // Arrange: Get the current inventory to retrieve the generation + inventories, err := resourceproviders.GetInventories(context.TODO(), client, resourceProvider.UUID).Extract() + th.AssertNoErr(t, err) + + _, err = resourceproviders.UpdateInventories(context.TODO(), client, resourceProvider.UUID, resourceproviders.UpdateInventoriesOpts{ + ResourceProviderGeneration: inventories.ResourceProviderGeneration, + Inventories: map[string]resourceproviders.Inventory{ + InventoryResourceClass: { + AllocationRatio: 1.0, + MaxUnit: 4, + MinUnit: 1, + Reserved: 0, + StepSize: 1, + Total: 4, + }, + }, + }).Extract() + th.AssertNoErr(t, err) + + err = resourceproviders.DeleteInventory(context.TODO(), client, resourceProvider.UUID, InventoryResourceClass).ExtractErr() + th.AssertNoErr(t, err) + + // Assert: The inventory should no longer be found + updatedInventories, err := resourceproviders.GetInventories(context.TODO(), client, resourceProvider.UUID).Extract() + th.AssertNoErr(t, err) + + _, found := updatedInventories.Inventories[InventoryResourceClass] + th.AssertEquals(t, false, found) +} + +func TestResourceProviderDeleteInventoryNotFound(t *testing.T) { + clients.RequireAdmin(t) + + client, err := clients.NewPlacementV1Client() + th.AssertNoErr(t, err) + + resourceProvider, err := CreateResourceProvider(t, client) + th.AssertNoErr(t, err) + defer DeleteResourceProvider(t, client, resourceProvider.UUID) + + err = resourceproviders.DeleteInventory(context.TODO(), client, resourceProvider.UUID, MissingInventoryResourceClass).ExtractErr() + th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusNotFound)) +} + +func TestResourceProviderDeleteInventoriesSuccess(t *testing.T) { + clients.RequireAdmin(t) + + client, err := clients.NewPlacementV1Client() + th.AssertNoErr(t, err) + + resourceProvider, err := CreateResourceProvider(t, client) + th.AssertNoErr(t, err) + defer DeleteResourceProvider(t, client, resourceProvider.UUID) + + inventories, err := resourceproviders.GetInventories(context.TODO(), client, resourceProvider.UUID).Extract() + th.AssertNoErr(t, err) + + _, err = resourceproviders.UpdateInventories(context.TODO(), client, resourceProvider.UUID, resourceproviders.UpdateInventoriesOpts{ + ResourceProviderGeneration: inventories.ResourceProviderGeneration, + Inventories: map[string]resourceproviders.Inventory{ + InventoryResourceClass: { + AllocationRatio: 1.0, + MaxUnit: 4, + MinUnit: 1, + Reserved: 0, + StepSize: 1, + Total: 4, + }, + "MEMORY_MB": { + AllocationRatio: 1.0, + MaxUnit: 1024, + MinUnit: 1, + Reserved: 0, + StepSize: 1, + Total: 1024, + }, + }, + }).Extract() + th.AssertNoErr(t, err) + + seededInventories, err := resourceproviders.GetInventories(context.TODO(), client, resourceProvider.UUID).Extract() + th.AssertNoErr(t, err) + th.AssertEquals(t, 2, len(seededInventories.Inventories)) + + err = resourceproviders.DeleteInventories(context.TODO(), client, resourceProvider.UUID).ExtractErr() + th.AssertNoErr(t, err) + + updatedInventories, err := resourceproviders.GetInventories(context.TODO(), client, resourceProvider.UUID).Extract() + th.AssertNoErr(t, err) + th.AssertEquals(t, 0, len(updatedInventories.Inventories)) +} + func TestResourceProviderUpdateInventories(t *testing.T) { clients.RequireAdmin(t) diff --git a/openstack/placement/v1/resourceproviders/doc.go b/openstack/placement/v1/resourceproviders/doc.go index 4a1270794a..d47be9310c 100644 --- a/openstack/placement/v1/resourceproviders/doc.go +++ b/openstack/placement/v1/resourceproviders/doc.go @@ -133,6 +133,22 @@ Example to update one existing resource provider inventory panic(err) } +Example to delete one existing resource provider inventory +Since this request does not accept the resource provider generation, it is not safe to use when multiple threads are managing inventories for a single provider. In such situations use UpdateInventories with the empty inventory. + + err = resourceproviders.DeleteInventory(context.TODO(), placementClient, resourceProviderID, "VCPU").ExtractErr() + if err != nil { + panic(err) + } + +Example to delete all resource provider inventories +Since this request does not accept the resource provider generation, it is not safe to use when multiple threads are managing inventories for a single provider. In such situations use UpdateInventories with an empty inventory map. + + err = resourceproviders.DeleteInventories(context.TODO(), placementClient, resourceProviderID).ExtractErr() + if err != nil { + panic(err) + } + Example to get resource providers traits rp, err := resourceproviders.GetTraits(context.TODO(), placementClient, resourceProviderID).Extract() diff --git a/openstack/placement/v1/resourceproviders/requests.go b/openstack/placement/v1/resourceproviders/requests.go index 2985d63794..a1eedeb28d 100644 --- a/openstack/placement/v1/resourceproviders/requests.go +++ b/openstack/placement/v1/resourceproviders/requests.go @@ -199,6 +199,13 @@ func UpdateInventories(ctx context.Context, client *gophercloud.ServiceClient, r return } +// DeleteInventories deletes all inventories from a resource provider. +func DeleteInventories(ctx context.Context, client *gophercloud.ServiceClient, resourceProviderID string) (r DeleteResult) { + resp, err := client.Delete(ctx, deleteResourceProviderInventoriesURL(client, resourceProviderID), &gophercloud.RequestOpts{OkCodes: []int{204}}) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} + // UpdateInventoryOptsBuilder allows extensions to add additional parameters to the // UpdateInventory request. type UpdateInventoryOptsBuilder interface { @@ -228,6 +235,13 @@ func UpdateInventory(ctx context.Context, client *gophercloud.ServiceClient, res return } +// DeleteInventory deletes one inventory from a resource provider. +func DeleteInventory(ctx context.Context, client *gophercloud.ServiceClient, resourceProviderID, resourceClass string) (r DeleteResult) { + resp, err := client.Delete(ctx, deleteResourceProviderInventoryURL(client, resourceProviderID, resourceClass), &gophercloud.RequestOpts{OkCodes: []int{204}}) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} + func GetAllocations(ctx context.Context, client *gophercloud.ServiceClient, resourceProviderID string) (r GetAllocationsResult) { resp, err := client.Get(ctx, getResourceProviderAllocationsURL(client, resourceProviderID), &r.Body, nil) _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) diff --git a/openstack/placement/v1/resourceproviders/testing/fixtures_test.go b/openstack/placement/v1/resourceproviders/testing/fixtures_test.go index d904e1e98c..7a0b176114 100644 --- a/openstack/placement/v1/resourceproviders/testing/fixtures_test.go +++ b/openstack/placement/v1/resourceproviders/testing/fixtures_test.go @@ -517,6 +517,58 @@ func HandleResourceProviderPutInventoryNotFound(t *testing.T, fakeServer th.Fake }) } +func HandleResourceProviderDeleteInventorySuccess(t *testing.T, fakeServer th.FakeServer) { + inventoryDeleteURL := fmt.Sprintf("/resource_providers/%s/inventories/%s", ResourceProviderTestID, PresentInventoryResourceClass) + + fakeServer.Mux.HandleFunc(inventoryDeleteURL, + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "DELETE") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.AssertEquals(t, "", r.URL.RawQuery) + w.WriteHeader(http.StatusNoContent) + }) +} + +func HandleResourceProviderDeleteInventoryInUse(t *testing.T, fakeServer th.FakeServer) { + inventoryDeleteURL := fmt.Sprintf("/resource_providers/%s/inventories/%s", ResourceProviderTestID, PresentInventoryResourceClass) + + fakeServer.Mux.HandleFunc(inventoryDeleteURL, + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "DELETE") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.AssertEquals(t, "", r.URL.RawQuery) + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusConflict) + fmt.Fprint(w, `{"errors":[{"status":409,"title":"Conflict","detail":"Inventory is in use.","code":"placement.inventory.inuse"}]}`) + }) +} + +func HandleResourceProviderDeleteInventoriesSuccess(t *testing.T, fakeServer th.FakeServer) { + inventoriesDeleteURL := fmt.Sprintf("/resource_providers/%s/inventories", ResourceProviderTestID) + + fakeServer.Mux.HandleFunc(inventoriesDeleteURL, + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "DELETE") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.AssertEquals(t, "", r.URL.RawQuery) + w.WriteHeader(http.StatusNoContent) + }) +} + +func HandleResourceProviderDeleteInventoriesConflict(t *testing.T, fakeServer th.FakeServer) { + inventoriesDeleteURL := fmt.Sprintf("/resource_providers/%s/inventories", ResourceProviderTestID) + + fakeServer.Mux.HandleFunc(inventoriesDeleteURL, + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "DELETE") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.AssertEquals(t, "", r.URL.RawQuery) + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusConflict) + fmt.Fprint(w, `{"errors":[{"status":409,"title":"Conflict","detail":"Inventory is in use.","code":"placement.inventory.inuse"}]}`) + }) +} + func HandleResourceProviderGetAllocations(t *testing.T, fakeServer th.FakeServer) { allocationsTestUrl := fmt.Sprintf("/resource_providers/%s/allocations", ResourceProviderTestID) diff --git a/openstack/placement/v1/resourceproviders/testing/requests_test.go b/openstack/placement/v1/resourceproviders/testing/requests_test.go index 5b12d37c89..693b0d80ff 100644 --- a/openstack/placement/v1/resourceproviders/testing/requests_test.go +++ b/openstack/placement/v1/resourceproviders/testing/requests_test.go @@ -193,6 +193,46 @@ func TestUpdateResourceProviderInventoryNotFound(t *testing.T) { th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusNotFound)) } +func TestDeleteResourceProviderInventorySuccess(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleResourceProviderDeleteInventorySuccess(t, fakeServer) + + err := resourceproviders.DeleteInventory(context.TODO(), client.ServiceClient(fakeServer), ResourceProviderTestID, PresentInventoryResourceClass).ExtractErr() + th.AssertNoErr(t, err) +} + +func TestDeleteResourceProviderInventoryInUse(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleResourceProviderDeleteInventoryInUse(t, fakeServer) + + err := resourceproviders.DeleteInventory(context.TODO(), client.ServiceClient(fakeServer), ResourceProviderTestID, PresentInventoryResourceClass).ExtractErr() + th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusConflict)) +} + +func TestDeleteResourceProviderInventoriesSuccess(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleResourceProviderDeleteInventoriesSuccess(t, fakeServer) + + err := resourceproviders.DeleteInventories(context.TODO(), client.ServiceClient(fakeServer), ResourceProviderTestID).ExtractErr() + th.AssertNoErr(t, err) +} + +func TestDeleteResourceProviderInventoriesConflict(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleResourceProviderDeleteInventoriesConflict(t, fakeServer) + + err := resourceproviders.DeleteInventories(context.TODO(), client.ServiceClient(fakeServer), ResourceProviderTestID).ExtractErr() + th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusConflict)) +} + func TestGetResourceProvidersAllocations(t *testing.T) { fakeServer := th.SetupHTTP() defer fakeServer.Teardown() diff --git a/openstack/placement/v1/resourceproviders/urls.go b/openstack/placement/v1/resourceproviders/urls.go index 61d6e1e811..fbc0ff2955 100644 --- a/openstack/placement/v1/resourceproviders/urls.go +++ b/openstack/placement/v1/resourceproviders/urls.go @@ -30,6 +30,10 @@ func getResourceProviderInventoriesURL(client *gophercloud.ServiceClient, resour return client.ServiceURL(apiName, resourceProviderID, "inventories") } +func deleteResourceProviderInventoriesURL(client *gophercloud.ServiceClient, resourceProviderID string) string { + return client.ServiceURL(apiName, resourceProviderID, "inventories") +} + func getResourceProviderInventoryURL(client *gophercloud.ServiceClient, resourceProviderID, resourceClass string) string { return client.ServiceURL(apiName, resourceProviderID, "inventories", resourceClass) } @@ -38,6 +42,10 @@ func updateResourceProviderInventoryURL(client *gophercloud.ServiceClient, resou return client.ServiceURL(apiName, resourceProviderID, "inventories", resourceClass) } +func deleteResourceProviderInventoryURL(client *gophercloud.ServiceClient, resourceProviderID, resourceClass string) string { + return client.ServiceURL(apiName, resourceProviderID, "inventories", resourceClass) +} + func getResourceProviderAllocationsURL(client *gophercloud.ServiceClient, resourceProviderID string) string { return client.ServiceURL(apiName, resourceProviderID, "allocations") } From 3b3c41a736d4f25c0b3490ff014c9b6ca2fb1b9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Andr=C3=A9?= Date: Tue, 7 Apr 2026 17:20:42 +0200 Subject: [PATCH 290/353] Drop context from NewMetricV1() signature The context was added in 2595acd79aae2345990bba941291afd763f0de81 that didn't make it to the `v2` branch. --- internal/acceptance/clients/clients.go | 2 +- openstack/client.go | 4 ++-- openstack/metric/v1/metrics/doc.go | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/internal/acceptance/clients/clients.go b/internal/acceptance/clients/clients.go index 9e258dfe51..fc60e795d6 100644 --- a/internal/acceptance/clients/clients.go +++ b/internal/acceptance/clients/clients.go @@ -601,7 +601,7 @@ func NewMetricV1Client() (*gophercloud.ServiceClient, error) { client = configureDebug(client) - return openstack.NewMetricV1(context.TODO(), client, gophercloud.EndpointOpts{ + return openstack.NewMetricV1(client, gophercloud.EndpointOpts{ Region: os.Getenv("OS_REGION_NAME"), }) } diff --git a/openstack/client.go b/openstack/client.go index d1026b16b2..cd95e599e5 100644 --- a/openstack/client.go +++ b/openstack/client.go @@ -466,8 +466,8 @@ func NewLoadBalancerV2(client *gophercloud.ProviderClient, eo gophercloud.Endpoi // NewMetricV1 creates a ServiceClient that may be used with the v1 metric-storage // service (Aetos). -func NewMetricV1(ctx context.Context, client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { - sc, err := initClientOpts(ctx, client, eo, "metric-storage", 1) +func NewMetricV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { + sc, err := initClientOpts(client, eo, "metric-storage", 1) sc.ResourceBase = sc.Endpoint + "api/v1/" return sc, err } diff --git a/openstack/metric/v1/metrics/doc.go b/openstack/metric/v1/metrics/doc.go index 410dc07735..b7d76377a4 100644 --- a/openstack/metric/v1/metrics/doc.go +++ b/openstack/metric/v1/metrics/doc.go @@ -8,7 +8,7 @@ under /api/v1/ with OpenStack authentication. Example to Create a Metric Service Client - metricClient, err := openstack.NewMetricV1(ctx, providerClient, gophercloud.EndpointOpts{ + metricClient, err := openstack.NewMetricV1(providerClient, gophercloud.EndpointOpts{ Region: "RegionOne", }) if err != nil { From e82c6ccf76a065211aefa0254dac38d88af449fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Andr=C3=A9?= Date: Thu, 26 Mar 2026 08:05:21 +0100 Subject: [PATCH 291/353] Fix TestCreateTempURL flaky test by removing hardcoded port dependency SetupPersistentPortHTTP used t.Errorf on bind failure, which didn't stop execution and caused a nil pointer panic on server.Start(). Changed to t.Fatalf to fail cleanly. Replaced SetupPersistentPortHTTP with SetupHTTP in objectstorage temp URL tests since the HMAC signature only covers the path, not the host:port. This eliminates the flaky port-already-in-use failures in CI. Fixes #3661. --- .../objectstorage/v1/objects/testing/requests_test.go | 8 +++----- testhelper/http_responses.go | 2 +- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/openstack/objectstorage/v1/objects/testing/requests_test.go b/openstack/objectstorage/v1/objects/testing/requests_test.go index d131f1bdcd..b49cf63a7f 100644 --- a/openstack/objectstorage/v1/objects/testing/requests_test.go +++ b/openstack/objectstorage/v1/objects/testing/requests_test.go @@ -93,8 +93,7 @@ func TestContainerNames(t *testing.T) { th.CheckErr(t, res.Err, &tc.expectedError) }) t.Run("createTempURL", func(t *testing.T) { - port := 33200 - fakeServer := th.SetupPersistentPortHTTP(t, port) + fakeServer := th.SetupHTTP() defer fakeServer.Teardown() // Handle fetching of secret key inside of CreateTempURL @@ -503,8 +502,7 @@ func TestObjectCreateParamsWithSeek(t *testing.T) { } func TestCreateTempURL(t *testing.T) { - port := 33200 - fakeServer := th.SetupPersistentPortHTTP(t, port) + fakeServer := th.SetupHTTP() defer fakeServer.Teardown() // Handle fetching of secret key inside of CreateTempURL @@ -522,7 +520,7 @@ func TestCreateTempURL(t *testing.T) { sig := "89be454a9c7e2e9f3f50a8441815e0b5801cba5b" expiry := "1593565980" - expectedURL := fmt.Sprintf("http://127.0.0.1:%v/v1/testContainer/testObject%%2FtestFile.txt?temp_url_sig=%v&temp_url_expires=%v", port, sig, expiry) + expectedURL := fmt.Sprintf("%sv1/testContainer/testObject%%2FtestFile.txt?temp_url_sig=%v&temp_url_expires=%v", fakeServer.Endpoint(), sig, expiry) th.AssertNoErr(t, err) th.AssertEquals(t, expectedURL, tempURL) diff --git a/testhelper/http_responses.go b/testhelper/http_responses.go index f57645e441..d0034a5a7b 100644 --- a/testhelper/http_responses.go +++ b/testhelper/http_responses.go @@ -50,7 +50,7 @@ func SetupPersistentPortHTTP(t *testing.T, port int) FakeServer { server := httptest.NewUnstartedServer(mux) l, err := net.Listen("tcp", fmt.Sprintf("127.0.0.1:%d", port)) if err != nil { - t.Errorf("Failed to listen to 127.0.0.1:%d: %s", port, err) + t.Fatalf("Failed to listen to 127.0.0.1:%d: %s", port, err) } server.Listener = l server.Start() From c08ede0d4d95cac827ad9049c152b88a8a6edec7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Andr=C3=A9?= Date: Thu, 26 Mar 2026 08:29:43 +0100 Subject: [PATCH 292/353] Replace t.Errorf with th.AssertNoErr to prevent nil pointer panics in tests Several tests used t.Errorf after fallible operations, which logs the error but doesn't stop execution. This caused nil pointer dereferences when subsequent code accessed the result. Replace with th.AssertNoErr which calls t.Fatal internally, stopping the test immediately on error. --- .../sharedfilesystems/v2/replicas_test.go | 8 ++------ .../v2/securityservices_test.go | 13 ++++-------- .../v2/sharenetworks_test.go | 12 +++-------- .../sharedfilesystems/v2/shares_test.go | 20 +++++-------------- .../sharedfilesystems/v2/snapshots_test.go | 12 +++-------- .../v3/tokens/testing/requests_test.go | 12 +++-------- 6 files changed, 20 insertions(+), 57 deletions(-) diff --git a/internal/acceptance/openstack/sharedfilesystems/v2/replicas_test.go b/internal/acceptance/openstack/sharedfilesystems/v2/replicas_test.go index 8432afeb77..e662781360 100644 --- a/internal/acceptance/openstack/sharedfilesystems/v2/replicas_test.go +++ b/internal/acceptance/openstack/sharedfilesystems/v2/replicas_test.go @@ -181,15 +181,11 @@ func TestReplicaExportLocations(t *testing.T) { } exportLocations, err = replicas.ListExportLocations(context.TODO(), client, activeReplicaID).Extract() - if err != nil { - t.Errorf("Unable to list replica export locations: %v", err) - } + th.AssertNoErr(t, err) tools.PrintResource(t, exportLocations) exportLocation, err := replicas.GetExportLocation(context.TODO(), client, activeReplicaID, exportLocations[0].ID).Extract() - if err != nil { - t.Errorf("Unable to get replica export location: %v", err) - } + th.AssertNoErr(t, err) tools.PrintResource(t, exportLocation) // unset CreatedAt and UpdatedAt exportLocation.CreatedAt = time.Time{} diff --git a/internal/acceptance/openstack/sharedfilesystems/v2/securityservices_test.go b/internal/acceptance/openstack/sharedfilesystems/v2/securityservices_test.go index a149a83324..abbb0b557c 100644 --- a/internal/acceptance/openstack/sharedfilesystems/v2/securityservices_test.go +++ b/internal/acceptance/openstack/sharedfilesystems/v2/securityservices_test.go @@ -9,6 +9,7 @@ import ( "github.com/gophercloud/gophercloud/v2/internal/acceptance/clients" "github.com/gophercloud/gophercloud/v2/internal/acceptance/tools" "github.com/gophercloud/gophercloud/v2/openstack/sharedfilesystems/v2/securityservices" + th "github.com/gophercloud/gophercloud/v2/testhelper" ) func TestSecurityServiceCreateDelete(t *testing.T) { @@ -23,9 +24,7 @@ func TestSecurityServiceCreateDelete(t *testing.T) { } newSecurityService, err := securityservices.Get(context.TODO(), client, securityService.ID).Extract() - if err != nil { - t.Errorf("Unable to retrieve the security service: %v", err) - } + th.AssertNoErr(t, err) if newSecurityService.Name != securityService.Name { t.Fatalf("Security service name was expeted to be: %s", securityService.Name) @@ -125,14 +124,10 @@ func TestSecurityServiceUpdate(t *testing.T) { } _, err = securityservices.Update(context.TODO(), client, securityService.ID, options).Extract() - if err != nil { - t.Errorf("Unable to update the security service: %v", err) - } + th.AssertNoErr(t, err) newSecurityService, err := securityservices.Get(context.TODO(), client, securityService.ID).Extract() - if err != nil { - t.Errorf("Unable to retrieve the security service: %v", err) - } + th.AssertNoErr(t, err) if newSecurityService.Name != name { t.Fatalf("Security service name was expeted to be: %s", name) diff --git a/internal/acceptance/openstack/sharedfilesystems/v2/sharenetworks_test.go b/internal/acceptance/openstack/sharedfilesystems/v2/sharenetworks_test.go index c6a9bf1530..c75c07a26b 100644 --- a/internal/acceptance/openstack/sharedfilesystems/v2/sharenetworks_test.go +++ b/internal/acceptance/openstack/sharedfilesystems/v2/sharenetworks_test.go @@ -25,9 +25,7 @@ func TestShareNetworkCreateDestroy(t *testing.T) { } newShareNetwork, err := sharenetworks.Get(context.TODO(), client, shareNetwork.ID).Extract() - if err != nil { - t.Errorf("Unable to retrieve shareNetwork: %v", err) - } + th.AssertNoErr(t, err) if newShareNetwork.Name != shareNetwork.Name { t.Fatalf("Share network name was expeted to be: %s", shareNetwork.Name) @@ -56,9 +54,7 @@ func TestShareNetworkUpdate(t *testing.T) { } expectedShareNetwork, err := sharenetworks.Get(context.TODO(), client, shareNetwork.ID).Extract() - if err != nil { - t.Errorf("Unable to retrieve shareNetwork: %v", err) - } + th.AssertNoErr(t, err) name := "NewName" description := "" @@ -76,9 +72,7 @@ func TestShareNetworkUpdate(t *testing.T) { } updatedShareNetwork, err := sharenetworks.Get(context.TODO(), client, shareNetwork.ID).Extract() - if err != nil { - t.Errorf("Unable to retrieve shareNetwork: %v", err) - } + th.AssertNoErr(t, err) // Update time has to be set in order to get the assert equal to pass expectedShareNetwork.UpdatedAt = updatedShareNetwork.UpdatedAt diff --git a/internal/acceptance/openstack/sharedfilesystems/v2/shares_test.go b/internal/acceptance/openstack/sharedfilesystems/v2/shares_test.go index 3d8bb0d32e..7247aa8984 100644 --- a/internal/acceptance/openstack/sharedfilesystems/v2/shares_test.go +++ b/internal/acceptance/openstack/sharedfilesystems/v2/shares_test.go @@ -53,15 +53,11 @@ func TestShareExportLocations(t *testing.T) { client.Microversion = "2.9" exportLocations, err := shares.ListExportLocations(context.TODO(), client, share.ID).Extract() - if err != nil { - t.Errorf("Unable to list share export locations: %v", err) - } + th.AssertNoErr(t, err) tools.PrintResource(t, exportLocations) exportLocation, err := shares.GetExportLocation(context.TODO(), client, share.ID, exportLocations[0].ID).Extract() - if err != nil { - t.Errorf("Unable to get share export location: %v", err) - } + th.AssertNoErr(t, err) tools.PrintResource(t, exportLocation) th.AssertEquals(t, exportLocations[0], *exportLocation) } @@ -80,9 +76,7 @@ func TestShareUpdate(t *testing.T) { defer DeleteShare(t, client, share) expectedShare, err := shares.Get(context.TODO(), client, share.ID).Extract() - if err != nil { - t.Errorf("Unable to retrieve share: %v", err) - } + th.AssertNoErr(t, err) name := "NewName" description := "" @@ -98,14 +92,10 @@ func TestShareUpdate(t *testing.T) { expectedShare.IsPublic = iFalse _, err = shares.Update(context.TODO(), client, share.ID, options).Extract() - if err != nil { - t.Errorf("Unable to update share: %v", err) - } + th.AssertNoErr(t, err) updatedShare, err := shares.Get(context.TODO(), client, share.ID).Extract() - if err != nil { - t.Errorf("Unable to retrieve share: %v", err) - } + th.AssertNoErr(t, err) // Update time has to be set in order to get the assert equal to pass expectedShare.UpdatedAt = updatedShare.UpdatedAt diff --git a/internal/acceptance/openstack/sharedfilesystems/v2/snapshots_test.go b/internal/acceptance/openstack/sharedfilesystems/v2/snapshots_test.go index 46b7c6d488..3c997d3c49 100644 --- a/internal/acceptance/openstack/sharedfilesystems/v2/snapshots_test.go +++ b/internal/acceptance/openstack/sharedfilesystems/v2/snapshots_test.go @@ -65,9 +65,7 @@ func TestSnapshotUpdate(t *testing.T) { defer DeleteSnapshot(t, client, snapshot) expectedSnapshot, err := snapshots.Get(context.TODO(), client, snapshot.ID).Extract() - if err != nil { - t.Errorf("Unable to retrieve snapshot: %v", err) - } + th.AssertNoErr(t, err) name := "NewName" description := "" @@ -80,14 +78,10 @@ func TestSnapshotUpdate(t *testing.T) { expectedSnapshot.Description = description _, err = snapshots.Update(context.TODO(), client, snapshot.ID, options).Extract() - if err != nil { - t.Errorf("Unable to update snapshot: %v", err) - } + th.AssertNoErr(t, err) updatedSnapshot, err := snapshots.Get(context.TODO(), client, snapshot.ID).Extract() - if err != nil { - t.Errorf("Unable to retrieve snapshot: %v", err) - } + th.AssertNoErr(t, err) tools.PrintResource(t, snapshot) diff --git a/openstack/identity/v3/tokens/testing/requests_test.go b/openstack/identity/v3/tokens/testing/requests_test.go index 8157de3ca7..5599379dc9 100644 --- a/openstack/identity/v3/tokens/testing/requests_test.go +++ b/openstack/identity/v3/tokens/testing/requests_test.go @@ -383,18 +383,14 @@ func TestCreateUserIDPasswordTrustID(t *testing.T) { rsp := tokens.Create(context.TODO(), client.ServiceClient(fakeServer), &ao) token, err := rsp.Extract() - if err != nil { - t.Errorf("Create returned an error: %v", err) - } + th.AssertNoErr(t, err) expectedToken := &tokens.Token{ ExpiresAt: time.Date(2024, 02, 28, 12, 10, 39, 0, time.UTC), } th.AssertDeepEquals(t, expectedToken, token) trust, err := rsp.ExtractTrust() - if err != nil { - t.Errorf("ExtractTrust returned an error: %v", err) - } + th.AssertNoErr(t, err) expectedTrust := &tokens.Trust{ ID: "95946f9eef864fdc993079d8fe3e5747", Impersonation: false, @@ -676,9 +672,7 @@ func TestGetRequest(t *testing.T) { }) token, err := tokens.Get(context.TODO(), &client, "abcdef12345").Extract() - if err != nil { - t.Errorf("Info returned an error: %v", err) - } + th.AssertNoErr(t, err) expected, _ := time.Parse(time.UnixDate, "Fri Aug 29 13:10:01 UTC 2014") if token.ExpiresAt != expected { From 5825da828d51b7e61040a3221dcf52ed46b58655 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Andr=C3=A9?= Date: Wed, 8 Apr 2026 08:42:53 +0200 Subject: [PATCH 293/353] Adapt metric job to v2 We're not using merge queue in v2. --- .github/workflows/functional-metric.yaml | 50 ++++++------------------ 1 file changed, 12 insertions(+), 38 deletions(-) diff --git a/.github/workflows/functional-metric.yaml b/.github/workflows/functional-metric.yaml index 8f60039792..5377d07739 100644 --- a/.github/workflows/functional-metric.yaml +++ b/.github/workflows/functional-metric.yaml @@ -1,7 +1,16 @@ name: functional-metric on: - merge_group: pull_request: + paths: + - 'openstack/auth_env.go' + - 'openstack/client.go' + - 'openstack/endpoint.go' + - 'openstack/endpoint_location.go' + - 'openstack/config/provider_client.go' + - 'openstack/utils/choose_version.go' + - 'openstack/utils/discovery.go' + - '**metric**' + - '.github/workflows/functional-metric.yaml' schedule: - cron: '0 0 */3 * *' jobs: @@ -29,29 +38,7 @@ jobs: with: persist-credentials: false - - name: Check changed files - uses: ./.github/actions/file-filter - id: changed-files - with: - patterns: | - openstack/auth_env.go - openstack/client.go - openstack/endpoint.go - openstack/endpoint_location.go - openstack/config/provider_client.go - openstack/utils/choose_version.go - openstack/utils/discovery.go - **metric** - .github/workflows/functional-metric.yaml - - - name: Skip tests for unrelated changed-files - if: ${{ ! fromJSON(steps.changed-files.outputs.matches) }} - run: | - echo "No relevant files changed - skipping tests for ${{ matrix.name }}" - echo "TESTS_SKIPPED=true" >> $GITHUB_ENV - - name: Deploy devstack - if: ${{ fromJSON(steps.changed-files.outputs.matches) }} uses: gophercloud/devstack-action@60ca1042045c0c9e3e001c64575d381654ffcba1 # v0.19 with: branch: ${{ matrix.openstack_version }} @@ -67,39 +54,26 @@ jobs: enabled_services: "prometheus,node_exporter,openstack_exporter,ceilometer-acompute,ceilometer-acentral,ceilometer-anotification,sg-core,aetos,openstack-cli-server" - name: Checkout go - if: ${{ fromJSON(steps.changed-files.outputs.matches) }} uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 with: go-version-file: 'go.mod' cache: true - name: Run Gophercloud acceptance tests - if: ${{ fromJSON(steps.changed-files.outputs.matches) }} run: | source ${{ github.workspace }}/script/stackenv make acceptance-metric - echo "TESTS_RUN=true" >> $GITHUB_ENV env: DEVSTACK_PATH: ${{ github.workspace }}/devstack OS_BRANCH: ${{ matrix.openstack_version }} - name: Generate logs on failure run: ./script/collectlogs - if: ${{ failure() && fromJSON(steps.changed-files.outputs.matches) }} + if: failure() - name: Upload logs artifacts on failure - if: ${{ failure() && fromJSON(steps.changed-files.outputs.matches) }} + if: failure() uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: functional-metric-${{ matrix.name }}-${{ github.run_id }} path: /tmp/devstack-logs/* - - - name: Set job status - run: | - if [[ "$TESTS_SKIPPED" == "true" || "$TESTS_RUN" == "true" ]]; then - echo "Job completed successfully (either ran tests or skipped appropriately)" - exit 0 - else - echo "Job failed - neither tests ran nor were properly skipped" - exit 1 - fi From b06761abbc377af87b62eb3257a58fcfaf5a8ebf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Andr=C3=A9?= Date: Wed, 8 Apr 2026 11:32:37 +0200 Subject: [PATCH 294/353] Remove redundant backport_v1 workflow from v2 branch Backports to v1 are already handled by the backport.yaml workflow on the main branch, making this workflow unnecessary on v2. --- .github/workflows/backport_v1.yaml | 73 ------------------------------ 1 file changed, 73 deletions(-) delete mode 100644 .github/workflows/backport_v1.yaml diff --git a/.github/workflows/backport_v1.yaml b/.github/workflows/backport_v1.yaml deleted file mode 100644 index eb8875545f..0000000000 --- a/.github/workflows/backport_v1.yaml +++ /dev/null @@ -1,73 +0,0 @@ -name: Pull Request backporting - -on: - # Safe: only runs on merged PRs, does not checkout PR code, and - # needs secrets to generate the backport bot token. - pull_request_target: # zizmor: ignore[dangerous-triggers] - types: - - closed - - labeled - -jobs: - backporting: - name: "Backporting" - permissions: - contents: read - issues: write - pull-requests: write - # Only react to merged PRs for security reasons. - # See https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target. - if: > - github.event.pull_request.merged - && ( - github.event.action == 'closed' - && contains(github.event.pull_request.labels.*.name, 'backport-v1') - || ( - github.event.action == 'labeled' - && contains(github.event.label.name, 'backport-v1') - ) - ) - runs-on: ubuntu-latest - steps: - - name: Generate a token from the gophercloud-backport-bot github-app - id: generate_token - uses: getsentry/action-github-app-token@a0061014b82a6a5d6aeeb3b824aced47e3c3a7ef - with: - app_id: ${{ secrets.BACKPORT_APP_ID }} # zizmor: ignore[secrets-outside-env] - private_key: ${{ secrets.BACKPORT_APP_PRIVATE_KEY }} # zizmor: ignore[secrets-outside-env] - - - name: Backporting - if: > - contains(github.event.pull_request.labels.*.name, 'semver:patch') - || contains(github.event.pull_request.labels.*.name, 'semver:minor') - || contains(github.event.label.name, 'semver:patch') - || contains(github.event.label.name, 'semver:minor') - uses: kiegroup/git-backporting@08da0b07ef2330d189f6074ec8db736b3aa9f465 # v4.9.1 - with: - target-branch: v1 - pull-request: ${{ github.event.pull_request.url }} - auth: ${{ steps.generate_token.outputs.token }} - no-squash: true - strategy-option: find-renames - - - name: Report failure - if: failure() - run: gh issue comment "$NUMBER" --body "$BODY" - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - GH_REPO: ${{ github.repository }} - NUMBER: ${{ github.event.pull_request.number }} - BODY: > - Failed to backport PR to `v1` branch. See [logs](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) for details. - - - name: Report an error if backport unsupported labels - if: > - contains(github.event.pull_request.labels.*.name, 'semver:major') - || contains(github.event.pull_request.labels.*.name, 'semver:unknown') - || contains(github.event.label.name, 'semver:major') - || contains(github.event.label.name, 'semver:unknown') - uses: thollander/actions-comment-pull-request@fabd468d3a1a0b97feee5f6b9e499eab0dd903f6 - with: - message: | - Labels `semver-major` or `semver-unknown` can not trigger backports. - The PR has to be labeled `semver-patch` or `semver-minor`. From 3e35142bcd90212d74b79f5f392abdab3f1a61f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Andr=C3=A9?= Date: Wed, 8 Apr 2026 11:38:53 +0200 Subject: [PATCH 295/353] Remove redundant ensure-labels workflow and labels.yaml from v2 branch The ensure-labels workflow was targeting the non-existent 'master' branch and label syncing is already handled from the main branch. --- .github/labels.yaml | 116 --------------------------- .github/workflows/ensure-labels.yaml | 23 ------ 2 files changed, 139 deletions(-) delete mode 100644 .github/labels.yaml delete mode 100644 .github/workflows/ensure-labels.yaml diff --git a/.github/labels.yaml b/.github/labels.yaml deleted file mode 100644 index ad21863831..0000000000 --- a/.github/labels.yaml +++ /dev/null @@ -1,116 +0,0 @@ -- color: '30ABB9' - description: This PR will be backported to v1 - name: backport-v1 -- color: 'E99695' - description: This PR will be backported to v2 - name: backport-v2 -- color: 'BCF611' - description: A good issue for first-time contributors - name: good first issue -- color: '9E1957' - description: Breaking change - name: semver:major -- color: 'FBCA04' - description: Backwards-compatible change - name: semver:minor -- color: '6E7624' - description: No API change - name: semver:patch -- color: 'D73A4A' - description: Do not merge - name: hold -- color: 'F9D0C4' - description: Additional information requested - name: needinfo -- color: 'FEF2C0' - description: This PR lacks tests before it can be merged - name: just-needs-tests - -- color: '30ABB9' - description: This PR targets v1 - name: v1 -- color: 'E99695' - description: This PR targets v2 - name: v2 - -- color: '000000' - description: This PR updates dependencies - name: edit:dependencies -- color: '000000' - description: This PR updates GitHub Actions code - name: edit:actions -- color: '000000' - description: This PR updates common Gophercloud code - name: edit:gophercloud -- color: '000000' - description: This PR updates common OpenStack code - name: edit:openstack -- color: '000000' - description: This PR updates baremetal code - name: edit:baremetal -- color: '000000' - description: This PR updates baremetalintrospection code - name: edit:baremetalintrospection -- color: '000000' - description: This PR updates blockstorage code - name: edit:blockstorage -- color: '000000' - description: This PR updates common code - name: edit:common -- color: '000000' - description: This PR updates compute code - name: edit:compute -- color: '000000' - description: This PR updates config code - name: edit:config -- color: '000000' - description: This PR updates container code - name: edit:container -- color: '000000' - description: This PR updates containerinfra code - name: edit:containerinfra -- color: '000000' - description: This PR updates db code - name: edit:db -- color: '000000' - description: This PR updates dns code - name: edit:dns -- color: '000000' - description: This PR updates identity code - name: edit:identity -- color: '000000' - description: This PR updates image code - name: edit:image -- color: '000000' - description: This PR updates keymanager code - name: edit:keymanager -- color: '000000' - description: This PR updates loadbalancer code - name: edit:loadbalancer -- color: '000000' - description: This PR updates messaging code - name: edit:messaging -- color: '000000' - description: This PR updates networking code - name: edit:networking -- color: '000000' - description: This PR updates objectstorage code - name: edit:objectstorage -- color: '000000' - description: This PR updates orchestration code - name: edit:orchestration -- color: '000000' - description: This PR updates placement code - name: edit:placement -- color: '000000' - description: This PR updates sharedfilesystems code - name: edit:sharedfilesystems -- color: '000000' - description: This PR updates testing code - name: edit:testing -- color: '000000' - description: This PR updates utils code - name: edit:utils -- color: '000000' - description: This PR updates workflow code - name: edit:workflow diff --git a/.github/workflows/ensure-labels.yaml b/.github/workflows/ensure-labels.yaml deleted file mode 100644 index 9ccc6df3d6..0000000000 --- a/.github/workflows/ensure-labels.yaml +++ /dev/null @@ -1,23 +0,0 @@ -name: Apply labels in .github/labels.yaml -on: - push: - branches: - - master - paths: - - .github/labels.yaml - - .github/workflows/ensure-labels.yaml -jobs: - ensure: - permissions: - contents: read - issues: write - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - with: - persist-credentials: false - - uses: micnncim/action-label-syncer@3abd5ab72fda571e69fffd97bd4e0033dd5f495c # v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - manifest: .github/labels.yaml From a01a21a72cefb1bf81eab08ec3117a9bd9f88d57 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 Apr 2026 14:21:31 +0000 Subject: [PATCH 296/353] build(deps): bump golang.org/x/crypto from 0.33.0 to 0.49.0 Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.33.0 to 0.49.0. - [Commits](https://github.com/golang/crypto/compare/v0.33.0...v0.49.0) --- updated-dependencies: - dependency-name: golang.org/x/crypto dependency-version: 0.49.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 4 ++-- go.sum | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/go.mod b/go.mod index 94309249a1..7460f9edd8 100644 --- a/go.mod +++ b/go.mod @@ -3,8 +3,8 @@ module github.com/gophercloud/gophercloud/v2 go 1.25.0 require ( - golang.org/x/crypto v0.33.0 + golang.org/x/crypto v0.49.0 gopkg.in/yaml.v2 v2.4.0 ) -require golang.org/x/sys v0.30.0 // indirect +require golang.org/x/sys v0.42.0 // indirect diff --git a/go.sum b/go.sum index 0bfa14296f..ce4a08f52d 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,9 @@ -golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus= -golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M= -golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= -golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU= -golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s= +golang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4= +golang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA= +golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= +golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/term v0.41.0 h1:QCgPso/Q3RTJx2Th4bDLqML4W6iJiaXFq2/ftQF13YU= +golang.org/x/term v0.41.0/go.mod h1:3pfBgksrReYfZ5lvYM0kSO0LIkAl4Yl2bXOkKP7Ec2A= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= From 75e877afd16b312dc096f17fd1318082f28ee0e6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 Apr 2026 14:22:05 +0000 Subject: [PATCH 297/353] build(deps): bump actions/setup-go from 6.3.0 to 6.4.0 Bumps [actions/setup-go](https://github.com/actions/setup-go) from 6.3.0 to 6.4.0. - [Release notes](https://github.com/actions/setup-go/releases) - [Commits](https://github.com/actions/setup-go/compare/v6.3.0...4a3601121dd01d1626a1e23e37211e3254c1c06c) --- updated-dependencies: - dependency-name: actions/setup-go dependency-version: 6.4.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/functional-metric.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/functional-metric.yaml b/.github/workflows/functional-metric.yaml index 5377d07739..4be409d41e 100644 --- a/.github/workflows/functional-metric.yaml +++ b/.github/workflows/functional-metric.yaml @@ -54,7 +54,7 @@ jobs: enabled_services: "prometheus,node_exporter,openstack_exporter,ceilometer-acompute,ceilometer-acentral,ceilometer-anotification,sg-core,aetos,openstack-cli-server" - name: Checkout go - uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 + uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c with: go-version-file: 'go.mod' cache: true From b895c870ef4be305cfc6f04699098530fc1b260f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 Apr 2026 14:23:46 +0000 Subject: [PATCH 298/353] build(deps): bump github/codeql-action from 4.34.1 to 4.35.1 Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.34.1 to 4.35.1. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/38697555549f1db7851b81482ff19f1fa5c4fedc...c10b8064de6f491fea524254123dbe5e09572f13) --- updated-dependencies: - dependency-name: github/codeql-action dependency-version: 4.35.1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/codeql-analysis.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql-analysis.yaml b/.github/workflows/codeql-analysis.yaml index 12d4008b74..3d11b8f50a 100644 --- a/.github/workflows/codeql-analysis.yaml +++ b/.github/workflows/codeql-analysis.yaml @@ -29,12 +29,12 @@ jobs: cache: true - name: Initialize CodeQL - uses: github/codeql-action/init@38697555549f1db7851b81482ff19f1fa5c4fedc # v4 + uses: github/codeql-action/init@c10b8064de6f491fea524254123dbe5e09572f13 # v4 with: languages: ${{ matrix.language }} - name: Autobuild - uses: github/codeql-action/autobuild@38697555549f1db7851b81482ff19f1fa5c4fedc # v4 + uses: github/codeql-action/autobuild@c10b8064de6f491fea524254123dbe5e09572f13 # v4 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@38697555549f1db7851b81482ff19f1fa5c4fedc # v4 + uses: github/codeql-action/analyze@c10b8064de6f491fea524254123dbe5e09572f13 # v4 From 22bbccd4d9ec2d67de3fb0cbc99d3afce000b566 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Andr=C3=A9?= Date: Wed, 8 Apr 2026 13:53:23 +0200 Subject: [PATCH 299/353] CI: prefer github mirrors whenever possible Our CI runs in github infra, let's use code that's already in github if we can. --- .github/workflows/functional-fwaas_v2.yaml | 2 +- .github/workflows/functional-metric.yaml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/functional-fwaas_v2.yaml b/.github/workflows/functional-fwaas_v2.yaml index b074a859f0..048fc0a04d 100644 --- a/.github/workflows/functional-fwaas_v2.yaml +++ b/.github/workflows/functional-fwaas_v2.yaml @@ -54,7 +54,7 @@ jobs: with: branch: ${{ matrix.openstack_version }} conf_overrides: | - enable_plugin neutron-fwaas https://opendev.org/openstack/neutron-fwaas ${{ matrix.openstack_version }} + enable_plugin neutron-fwaas https://github.com/openstack/neutron-fwaas ${{ matrix.openstack_version }} Q_AGENT=openvswitch Q_ML2_PLUGIN_MECHANISM_DRIVERS=openvswitch,l2population Q_ML2_PLUGIN_TYPE_DRIVERS=flat,gre,vlan,vxlan diff --git a/.github/workflows/functional-metric.yaml b/.github/workflows/functional-metric.yaml index 4be409d41e..8690e2be8c 100644 --- a/.github/workflows/functional-metric.yaml +++ b/.github/workflows/functional-metric.yaml @@ -43,12 +43,12 @@ jobs: with: branch: ${{ matrix.openstack_version }} conf_overrides: | - enable_plugin devstack-plugin-prometheus https://opendev.org/openstack/devstack-plugin-prometheus ${{ matrix.openstack_version }} - enable_plugin ceilometer https://opendev.org/openstack/ceilometer ${{ matrix.openstack_version }} + enable_plugin devstack-plugin-prometheus https://github.com/openstack/devstack-plugin-prometheus ${{ matrix.openstack_version }} + enable_plugin ceilometer https://github.com/openstack/ceilometer ${{ matrix.openstack_version }} CEILOMETER_BACKEND=sg-core PROMETHEUS_CUSTOM_SCRAPE_TARGETS="localhost:3000" enable_plugin sg-core https://github.com/openstack-k8s-operators/sg-core main - enable_plugin aetos https://opendev.org/openstack/aetos ${{ matrix.openstack_version }} + enable_plugin aetos https://github.com/openstack/aetos ${{ matrix.openstack_version }} ${{ matrix.devstack_conf_overrides }} enabled_services: "prometheus,node_exporter,openstack_exporter,ceilometer-acompute,ceilometer-acentral,ceilometer-anotification,sg-core,aetos,openstack-cli-server" From 03e84fcb8b84cc084d5b425c352c5fcb2393da49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Andr=C3=A9?= Date: Wed, 8 Apr 2026 16:58:14 +0200 Subject: [PATCH 300/353] CI: drop pyghmi dependency It has been deprecated for a very long time [1]. [1] https://opendev.org/openstack/ironic/src/branch/master/releasenotes/notes/remove-ipminative-driver-3367d25bbcc41fdc.yaml --- .github/workflows/functional-baremetal.yaml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/functional-baremetal.yaml b/.github/workflows/functional-baremetal.yaml index ec5645a098..782cc1d7af 100644 --- a/.github/workflows/functional-baremetal.yaml +++ b/.github/workflows/functional-baremetal.yaml @@ -44,10 +44,8 @@ jobs: with: branch: ${{ matrix.openstack_version }} conf_overrides: | - # pyghmi is not mirrored on github - PYGHMI_REPO=https://opendev.org/x/pyghmi enable_plugin ironic https://github.com/openstack/ironic ${{ matrix.openstack_version }} - LIBS_FROM_GIT=pyghmi,virtualbmc + LIBS_FROM_GIT=virtualbmc FORCE_CONFIG_DRIVE=True Q_AGENT=openvswitch Q_ML2_TENANT_NETWORK_TYPE=vxlan From ef2d558a6920b90f0541ba72b6df5f597d345c3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Andr=C3=A9?= Date: Wed, 8 Apr 2026 17:09:34 +0200 Subject: [PATCH 301/353] CI: Get virtualbmc from pypi --- .github/workflows/functional-baremetal.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/functional-baremetal.yaml b/.github/workflows/functional-baremetal.yaml index 782cc1d7af..477f9181e0 100644 --- a/.github/workflows/functional-baremetal.yaml +++ b/.github/workflows/functional-baremetal.yaml @@ -45,7 +45,6 @@ jobs: branch: ${{ matrix.openstack_version }} conf_overrides: | enable_plugin ironic https://github.com/openstack/ironic ${{ matrix.openstack_version }} - LIBS_FROM_GIT=virtualbmc FORCE_CONFIG_DRIVE=True Q_AGENT=openvswitch Q_ML2_TENANT_NETWORK_TYPE=vxlan From 9b6268086a3573c482b79de60b9b0520f2e15e7c Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Wed, 8 Apr 2026 12:23:41 +0100 Subject: [PATCH 302/353] ci: Drop Dalmatian testing, add Gazpacho Dalmatian goes EOL later this month [1] and Gazpacho is the latest SLURP release. Epoxy is retained as our new oldest supported release. Signed-off-by: Stephen Finucane --- .github/workflows/functional-baremetal.yaml | 6 +++--- .github/workflows/functional-basic.yaml | 6 +++--- .github/workflows/functional-blockstorage.yaml | 6 +++--- .github/workflows/functional-compute.yaml | 6 +++--- .github/workflows/functional-containerinfra.yaml | 16 ++++++++-------- .github/workflows/functional-dns.yaml | 6 +++--- .github/workflows/functional-fwaas_v2.yaml | 6 +++--- .github/workflows/functional-identity.yaml | 6 +++--- .github/workflows/functional-image.yaml | 6 +++--- .github/workflows/functional-keymanager.yaml | 10 +++++----- .github/workflows/functional-loadbalancer.yaml | 9 ++++++--- .github/workflows/functional-messaging.yaml | 6 +++--- .github/workflows/functional-networking.yaml | 6 +++--- .github/workflows/functional-objectstorage.yaml | 6 +++--- .github/workflows/functional-orchestration.yaml | 6 +++--- .github/workflows/functional-placement.yaml | 6 +++--- .../workflows/functional-sharedfilesystems.yaml | 6 +++--- .github/workflows/functional-workflow.yaml | 8 ++++---- 18 files changed, 65 insertions(+), 62 deletions(-) diff --git a/.github/workflows/functional-baremetal.yaml b/.github/workflows/functional-baremetal.yaml index 477f9181e0..c83ff45d33 100644 --- a/.github/workflows/functional-baremetal.yaml +++ b/.github/workflows/functional-baremetal.yaml @@ -24,12 +24,12 @@ jobs: - name: "master" openstack_version: "master" ubuntu_version: "24.04" + - name: "gazpacho" + openstack_version: "stable/2026.1" + ubuntu_version: "24.04" - name: "epoxy" openstack_version: "stable/2025.1" ubuntu_version: "24.04" - - name: "dalmatian" - openstack_version: "stable/2024.2" - ubuntu_version: "22.04" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Ironic on OpenStack ${{ matrix.name }} steps: diff --git a/.github/workflows/functional-basic.yaml b/.github/workflows/functional-basic.yaml index fb92290488..cd1b0f23d3 100644 --- a/.github/workflows/functional-basic.yaml +++ b/.github/workflows/functional-basic.yaml @@ -19,12 +19,12 @@ jobs: - name: "master" openstack_version: "master" ubuntu_version: "24.04" + - name: "gazpacho" + openstack_version: "stable/2026.1" + ubuntu_version: "24.04" - name: "epoxy" openstack_version: "stable/2025.1" ubuntu_version: "24.04" - - name: "dalmatian" - openstack_version: "stable/2024.2" - ubuntu_version: "22.04" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: basic tests on OpenStack ${{ matrix.name }} steps: diff --git a/.github/workflows/functional-blockstorage.yaml b/.github/workflows/functional-blockstorage.yaml index e01de55edd..94c226289e 100644 --- a/.github/workflows/functional-blockstorage.yaml +++ b/.github/workflows/functional-blockstorage.yaml @@ -24,12 +24,12 @@ jobs: - name: "master" openstack_version: "master" ubuntu_version: "24.04" + - name: "gazpacho" + openstack_version: "stable/2026.1" + ubuntu_version: "24.04" - name: "epoxy" openstack_version: "stable/2025.1" ubuntu_version: "24.04" - - name: "dalmatian" - openstack_version: "stable/2024.2" - ubuntu_version: "22.04" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Cinder on OpenStack ${{ matrix.name }} steps: diff --git a/.github/workflows/functional-compute.yaml b/.github/workflows/functional-compute.yaml index 7c64092b28..2bc27e64f4 100644 --- a/.github/workflows/functional-compute.yaml +++ b/.github/workflows/functional-compute.yaml @@ -24,12 +24,12 @@ jobs: - name: "master" openstack_version: "master" ubuntu_version: "24.04" + - name: "gazpacho" + openstack_version: "stable/2026.1" + ubuntu_version: "24.04" - name: "epoxy" openstack_version: "stable/2025.1" ubuntu_version: "24.04" - - name: "dalmatian" - openstack_version: "stable/2024.2" - ubuntu_version: "22.04" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Nova on OpenStack ${{ matrix.name }} steps: diff --git a/.github/workflows/functional-containerinfra.yaml b/.github/workflows/functional-containerinfra.yaml index c12d4a2caf..61e1c26d6c 100644 --- a/.github/workflows/functional-containerinfra.yaml +++ b/.github/workflows/functional-containerinfra.yaml @@ -33,8 +33,8 @@ jobs: enable_plugin magnum https://github.com/openstack/magnum master MAGNUMCLIENT_BRANCH=master - - name: "epoxy" - openstack_version: "stable/2025.1" + - name: "gazpacho" + openstack_version: "stable/2026.1" ubuntu_version: "24.04" devstack_conf_overrides: | # ensure we're using a working version of setuptools @@ -43,14 +43,14 @@ jobs: sed -i 's/pip_install "-U" "pbr"/pip_install "-U" "pbr" "setuptools[core]==79.0.1"/g' \$TOP_DIR/lib/infra fi + enable_plugin magnum https://github.com/openstack/magnum stable/2026.1 + MAGNUMCLIENT_BRANCH=stable/2026.1 + - name: "epoxy" + openstack_version: "stable/2025.1" + ubuntu_version: "24.04" + devstack_conf_overrides: | enable_plugin magnum https://github.com/openstack/magnum stable/2025.1 MAGNUMCLIENT_BRANCH=stable/2025.1 - - name: "dalmatian" - openstack_version: "stable/2024.2" - ubuntu_version: "22.04" - devstack_conf_overrides: | - enable_plugin magnum https://github.com/openstack/magnum stable/2024.2 - MAGNUMCLIENT_BRANCH=stable/2024.2 runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Magnum on OpenStack ${{ matrix.name }} steps: diff --git a/.github/workflows/functional-dns.yaml b/.github/workflows/functional-dns.yaml index 59826c9693..61da3bd7e2 100644 --- a/.github/workflows/functional-dns.yaml +++ b/.github/workflows/functional-dns.yaml @@ -30,12 +30,12 @@ jobs: sed -i 's/setuptools\[core\]$/setuptools[core]==79.0.1/g' \$TOP_DIR/lib/infra \$TOP_DIR/inc/python sed -i 's/pip_install "-U" "pbr"/pip_install "-U" "pbr" "setuptools[core]==79.0.1"/g' \$TOP_DIR/lib/infra fi + - name: "gazpacho" + openstack_version: "stable/2026.1" + ubuntu_version: "24.04" - name: "epoxy" openstack_version: "stable/2025.1" ubuntu_version: "24.04" - - name: "dalmatian" - openstack_version: "stable/2024.2" - ubuntu_version: "22.04" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Designate on OpenStack ${{ matrix.name }} steps: diff --git a/.github/workflows/functional-fwaas_v2.yaml b/.github/workflows/functional-fwaas_v2.yaml index 048fc0a04d..c09c0e7e9a 100644 --- a/.github/workflows/functional-fwaas_v2.yaml +++ b/.github/workflows/functional-fwaas_v2.yaml @@ -28,12 +28,12 @@ jobs: - name: "master" openstack_version: "master" ubuntu_version: "24.04" + - name: "gazpacho" + openstack_version: "stable/2026.1" + ubuntu_version: "24.04" - name: "epoxy" openstack_version: "stable/2025.1" ubuntu_version: "24.04" - - name: "dalmatian" - openstack_version: "stable/2024.2" - ubuntu_version: "22.04" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: FWaaS_v2 on OpenStack ${{ matrix.name }} steps: diff --git a/.github/workflows/functional-identity.yaml b/.github/workflows/functional-identity.yaml index cf7e577932..4c9b1de272 100644 --- a/.github/workflows/functional-identity.yaml +++ b/.github/workflows/functional-identity.yaml @@ -24,12 +24,12 @@ jobs: - name: "master" openstack_version: "master" ubuntu_version: "24.04" + - name: "gazpacho" + openstack_version: "stable/2026.1" + ubuntu_version: "24.04" - name: "epoxy" openstack_version: "stable/2025.1" ubuntu_version: "24.04" - - name: "dalmatian" - openstack_version: "stable/2024.2" - ubuntu_version: "22.04" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Keystone on OpenStack ${{ matrix.name }} steps: diff --git a/.github/workflows/functional-image.yaml b/.github/workflows/functional-image.yaml index 33b93ee4cb..7c33bad9b4 100644 --- a/.github/workflows/functional-image.yaml +++ b/.github/workflows/functional-image.yaml @@ -24,12 +24,12 @@ jobs: - name: "master" openstack_version: "master" ubuntu_version: "24.04" + - name: "gazpacho" + openstack_version: "stable/2026.1" + ubuntu_version: "24.04" - name: "epoxy" openstack_version: "stable/2025.1" ubuntu_version: "24.04" - - name: "dalmatian" - openstack_version: "stable/2024.2" - ubuntu_version: "22.04" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Glance on OpenStack ${{ matrix.name }} steps: diff --git a/.github/workflows/functional-keymanager.yaml b/.github/workflows/functional-keymanager.yaml index 4858e6eaee..e2c2c534a8 100644 --- a/.github/workflows/functional-keymanager.yaml +++ b/.github/workflows/functional-keymanager.yaml @@ -30,8 +30,8 @@ jobs: sed -i 's/setuptools\[core\]$/setuptools[core]==79.0.1/g' \$TOP_DIR/lib/infra \$TOP_DIR/inc/python sed -i 's/pip_install "-U" "pbr"/pip_install "-U" "pbr" "setuptools[core]==79.0.1"/g' \$TOP_DIR/lib/infra fi - - name: "epoxy" - openstack_version: "stable/2025.1" + - name: "gazpacho" + openstack_version: "stable/2026.1" ubuntu_version: "24.04" devstack_conf_overrides: | # ensure we're using a working version of setuptools @@ -39,9 +39,9 @@ jobs: sed -i 's/setuptools\[core\]$/setuptools[core]==79.0.1/g' \$TOP_DIR/lib/infra \$TOP_DIR/inc/python sed -i 's/pip_install "-U" "pbr"/pip_install "-U" "pbr" "setuptools[core]==79.0.1"/g' \$TOP_DIR/lib/infra fi - - name: "dalmatian" - openstack_version: "stable/2024.2" - ubuntu_version: "22.04" + - name: "epoxy" + openstack_version: "stable/2025.1" + ubuntu_version: "24.04" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Barbican on OpenStack ${{ matrix.name }} steps: diff --git a/.github/workflows/functional-loadbalancer.yaml b/.github/workflows/functional-loadbalancer.yaml index 53a947f907..61f4a18d5d 100644 --- a/.github/workflows/functional-loadbalancer.yaml +++ b/.github/workflows/functional-loadbalancer.yaml @@ -32,15 +32,18 @@ jobs: sed -i 's/setuptools\[core\]$/setuptools[core]==79.0.1/g' \$TOP_DIR/lib/infra \$TOP_DIR/inc/python sed -i 's/pip_install "-U" "pbr"/pip_install "-U" "pbr" "setuptools[core]==79.0.1"/g' \$TOP_DIR/lib/infra fi + - name: "gazpacho" + openstack_version: "stable/2026.1" + ubuntu_version: "24.04" + devstack_conf_overrides: | + LIBVIRT_CPU_MODE=host-passthrough + OCTAVIA_AMP_DISTRIBUTION_RELEASE_ID=jammy - name: "epoxy" openstack_version: "stable/2025.1" ubuntu_version: "24.04" devstack_conf_overrides: | LIBVIRT_CPU_MODE=host-passthrough OCTAVIA_AMP_DISTRIBUTION_RELEASE_ID=jammy - - name: "dalmatian" - openstack_version: "stable/2024.2" - ubuntu_version: "22.04" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Octavia on OpenStack ${{ matrix.name }} steps: diff --git a/.github/workflows/functional-messaging.yaml b/.github/workflows/functional-messaging.yaml index 3e8fb62649..e2973dde67 100644 --- a/.github/workflows/functional-messaging.yaml +++ b/.github/workflows/functional-messaging.yaml @@ -24,12 +24,12 @@ jobs: - name: "master" openstack_version: "master" ubuntu_version: "24.04" + - name: "gazpacho" + openstack_version: "stable/2026.1" + ubuntu_version: "24.04" - name: "epoxy" openstack_version: "stable/2025.1" ubuntu_version: "24.04" - - name: "dalmatian" - openstack_version: "stable/2024.2" - ubuntu_version: "22.04" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Zaqar on OpenStack ${{ matrix.name }} steps: diff --git a/.github/workflows/functional-networking.yaml b/.github/workflows/functional-networking.yaml index 9201f2f117..b04ea9b684 100644 --- a/.github/workflows/functional-networking.yaml +++ b/.github/workflows/functional-networking.yaml @@ -24,12 +24,12 @@ jobs: - name: "master" openstack_version: "master" ubuntu_version: "24.04" + - name: "gazpacho" + openstack_version: "stable/2026.1" + ubuntu_version: "24.04" - name: "epoxy" openstack_version: "stable/2025.1" ubuntu_version: "24.04" - - name: "dalmatian" - openstack_version: "stable/2024.2" - ubuntu_version: "22.04" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Neutron on OpenStack ${{ matrix.name }} steps: diff --git a/.github/workflows/functional-objectstorage.yaml b/.github/workflows/functional-objectstorage.yaml index 7449a71477..6512a237a1 100644 --- a/.github/workflows/functional-objectstorage.yaml +++ b/.github/workflows/functional-objectstorage.yaml @@ -24,12 +24,12 @@ jobs: - name: "master" openstack_version: "master" ubuntu_version: "24.04" + - name: "gazpacho" + openstack_version: "stable/2026.1" + ubuntu_version: "24.04" - name: "epoxy" openstack_version: "stable/2025.1" ubuntu_version: "24.04" - - name: "dalmatian" - openstack_version: "stable/2024.2" - ubuntu_version: "22.04" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Swift on OpenStack ${{ matrix.name }} steps: diff --git a/.github/workflows/functional-orchestration.yaml b/.github/workflows/functional-orchestration.yaml index e5970db41a..5e7fa73c10 100644 --- a/.github/workflows/functional-orchestration.yaml +++ b/.github/workflows/functional-orchestration.yaml @@ -24,12 +24,12 @@ jobs: - name: "master" openstack_version: "master" ubuntu_version: "24.04" + - name: "gazpacho" + openstack_version: "stable/2026.1" + ubuntu_version: "24.04" - name: "epoxy" openstack_version: "stable/2025.1" ubuntu_version: "24.04" - - name: "dalmatian" - openstack_version: "stable/2024.2" - ubuntu_version: "22.04" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Heat on OpenStack ${{ matrix.name }} steps: diff --git a/.github/workflows/functional-placement.yaml b/.github/workflows/functional-placement.yaml index ce5a76f9e0..3e7f5f5772 100644 --- a/.github/workflows/functional-placement.yaml +++ b/.github/workflows/functional-placement.yaml @@ -24,12 +24,12 @@ jobs: - name: "master" openstack_version: "master" ubuntu_version: "24.04" + - name: "gazpacho" + openstack_version: "stable/2026.1" + ubuntu_version: "24.04" - name: "epoxy" openstack_version: "stable/2025.1" ubuntu_version: "24.04" - - name: "dalmatian" - openstack_version: "stable/2024.2" - ubuntu_version: "22.04" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Placement on OpenStack ${{ matrix.name }} steps: diff --git a/.github/workflows/functional-sharedfilesystems.yaml b/.github/workflows/functional-sharedfilesystems.yaml index 7185c5cd76..dd06faac8d 100644 --- a/.github/workflows/functional-sharedfilesystems.yaml +++ b/.github/workflows/functional-sharedfilesystems.yaml @@ -30,12 +30,12 @@ jobs: sed -i 's/setuptools\[core\]$/setuptools[core]==79.0.1/g' \$TOP_DIR/lib/infra \$TOP_DIR/inc/python sed -i 's/pip_install "-U" "pbr"/pip_install "-U" "pbr" "setuptools[core]==79.0.1"/g' \$TOP_DIR/lib/infra fi + - name: "gazpacho" + openstack_version: "stable/2026.1" + ubuntu_version: "24.04" - name: "epoxy" openstack_version: "stable/2025.1" ubuntu_version: "24.04" - - name: "dalmatian" - openstack_version: "stable/2024.2" - ubuntu_version: "22.04" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Manila on OpenStack ${{ matrix.name }} steps: diff --git a/.github/workflows/functional-workflow.yaml b/.github/workflows/functional-workflow.yaml index 2ae9b8682c..50f2d4144f 100644 --- a/.github/workflows/functional-workflow.yaml +++ b/.github/workflows/functional-workflow.yaml @@ -25,14 +25,14 @@ jobs: openstack_version: "master" ubuntu_version: "24.04" mistral_plugin_version: "master" + - name: "gazpacho" + openstack_version: "stable/2026.1" + ubuntu_version: "24.04" + mistral_plugin_version: "stable/2026.1" - name: "epoxy" openstack_version: "stable/2025.1" ubuntu_version: "24.04" mistral_plugin_version: "stable/2025.1" - - name: "dalmatian" - openstack_version: "stable/2024.2" - ubuntu_version: "22.04" - mistral_plugin_version: "stable/2024.2" runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Mistral on Deploy OpenStack ${{ matrix.name }} steps: From eaaccc58d5726c2d7aa62935f83dfe5964f335b8 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Wed, 8 Apr 2026 12:25:32 +0100 Subject: [PATCH 303/353] ci: Remove setuptools overrides Most of these issues have been fixed upstream by now. Signed-off-by: Stephen Finucane --- .github/workflows/functional-containerinfra.yaml | 12 ------------ .github/workflows/functional-dns.yaml | 6 ------ .github/workflows/functional-keymanager.yaml | 12 ------------ .github/workflows/functional-loadbalancer.yaml | 5 ----- .github/workflows/functional-metric.yaml | 6 ------ .github/workflows/functional-sharedfilesystems.yaml | 6 ------ 6 files changed, 47 deletions(-) diff --git a/.github/workflows/functional-containerinfra.yaml b/.github/workflows/functional-containerinfra.yaml index 61e1c26d6c..2dd0cd6674 100644 --- a/.github/workflows/functional-containerinfra.yaml +++ b/.github/workflows/functional-containerinfra.yaml @@ -25,24 +25,12 @@ jobs: openstack_version: "master" ubuntu_version: "24.04" devstack_conf_overrides: | - # ensure we're using a working version of setuptools - if [ -n "\$TOP_DIR" ]; then - sed -i 's/setuptools\[core\]$/setuptools[core]==79.0.1/g' \$TOP_DIR/lib/infra \$TOP_DIR/inc/python - sed -i 's/pip_install "-U" "pbr"/pip_install "-U" "pbr" "setuptools[core]==79.0.1"/g' \$TOP_DIR/lib/infra - fi - enable_plugin magnum https://github.com/openstack/magnum master MAGNUMCLIENT_BRANCH=master - name: "gazpacho" openstack_version: "stable/2026.1" ubuntu_version: "24.04" devstack_conf_overrides: | - # ensure we're using a working version of setuptools - if [ -n "\$TOP_DIR" ]; then - sed -i 's/setuptools\[core\]$/setuptools[core]==79.0.1/g' \$TOP_DIR/lib/infra \$TOP_DIR/inc/python - sed -i 's/pip_install "-U" "pbr"/pip_install "-U" "pbr" "setuptools[core]==79.0.1"/g' \$TOP_DIR/lib/infra - fi - enable_plugin magnum https://github.com/openstack/magnum stable/2026.1 MAGNUMCLIENT_BRANCH=stable/2026.1 - name: "epoxy" diff --git a/.github/workflows/functional-dns.yaml b/.github/workflows/functional-dns.yaml index 61da3bd7e2..d3076cd680 100644 --- a/.github/workflows/functional-dns.yaml +++ b/.github/workflows/functional-dns.yaml @@ -24,12 +24,6 @@ jobs: - name: "master" openstack_version: "master" ubuntu_version: "24.04" - devstack_conf_overrides: | - # ensure we're using a working version of setuptools - if [ -n "\$TOP_DIR" ]; then - sed -i 's/setuptools\[core\]$/setuptools[core]==79.0.1/g' \$TOP_DIR/lib/infra \$TOP_DIR/inc/python - sed -i 's/pip_install "-U" "pbr"/pip_install "-U" "pbr" "setuptools[core]==79.0.1"/g' \$TOP_DIR/lib/infra - fi - name: "gazpacho" openstack_version: "stable/2026.1" ubuntu_version: "24.04" diff --git a/.github/workflows/functional-keymanager.yaml b/.github/workflows/functional-keymanager.yaml index e2c2c534a8..71997e296d 100644 --- a/.github/workflows/functional-keymanager.yaml +++ b/.github/workflows/functional-keymanager.yaml @@ -24,21 +24,9 @@ jobs: - name: "master" openstack_version: "master" ubuntu_version: "24.04" - devstack_conf_overrides: | - # ensure we're using a working version of setuptools - if [ -n "\$TOP_DIR" ]; then - sed -i 's/setuptools\[core\]$/setuptools[core]==79.0.1/g' \$TOP_DIR/lib/infra \$TOP_DIR/inc/python - sed -i 's/pip_install "-U" "pbr"/pip_install "-U" "pbr" "setuptools[core]==79.0.1"/g' \$TOP_DIR/lib/infra - fi - name: "gazpacho" openstack_version: "stable/2026.1" ubuntu_version: "24.04" - devstack_conf_overrides: | - # ensure we're using a working version of setuptools - if [ -n "\$TOP_DIR" ]; then - sed -i 's/setuptools\[core\]$/setuptools[core]==79.0.1/g' \$TOP_DIR/lib/infra \$TOP_DIR/inc/python - sed -i 's/pip_install "-U" "pbr"/pip_install "-U" "pbr" "setuptools[core]==79.0.1"/g' \$TOP_DIR/lib/infra - fi - name: "epoxy" openstack_version: "stable/2025.1" ubuntu_version: "24.04" diff --git a/.github/workflows/functional-loadbalancer.yaml b/.github/workflows/functional-loadbalancer.yaml index 61f4a18d5d..ef91756760 100644 --- a/.github/workflows/functional-loadbalancer.yaml +++ b/.github/workflows/functional-loadbalancer.yaml @@ -27,11 +27,6 @@ jobs: devstack_conf_overrides: | LIBVIRT_CPU_MODE=host-passthrough OCTAVIA_AMP_DISTRIBUTION_RELEASE_ID=jammy - # ensure we're using a working version of setuptools - if [ -n "\$TOP_DIR" ]; then - sed -i 's/setuptools\[core\]$/setuptools[core]==79.0.1/g' \$TOP_DIR/lib/infra \$TOP_DIR/inc/python - sed -i 's/pip_install "-U" "pbr"/pip_install "-U" "pbr" "setuptools[core]==79.0.1"/g' \$TOP_DIR/lib/infra - fi - name: "gazpacho" openstack_version: "stable/2026.1" ubuntu_version: "24.04" diff --git a/.github/workflows/functional-metric.yaml b/.github/workflows/functional-metric.yaml index 8690e2be8c..aeba6485e3 100644 --- a/.github/workflows/functional-metric.yaml +++ b/.github/workflows/functional-metric.yaml @@ -24,12 +24,6 @@ jobs: - name: "master" openstack_version: "master" ubuntu_version: "24.04" - devstack_conf_overrides: | - # ensure we're using a working version of setuptools - if [ -n "\$TOP_DIR" ]; then - sed -i 's/setuptools\[core\]$/setuptools[core]==79.0.1/g' \$TOP_DIR/lib/infra \$TOP_DIR/inc/python - sed -i 's/pip_install "-U" "pbr"/pip_install "-U" "pbr" "setuptools[core]==79.0.1"/g' \$TOP_DIR/lib/infra - fi runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Aetos on OpenStack ${{ matrix.name }} steps: diff --git a/.github/workflows/functional-sharedfilesystems.yaml b/.github/workflows/functional-sharedfilesystems.yaml index dd06faac8d..cdfe562953 100644 --- a/.github/workflows/functional-sharedfilesystems.yaml +++ b/.github/workflows/functional-sharedfilesystems.yaml @@ -24,12 +24,6 @@ jobs: - name: "master" openstack_version: "master" ubuntu_version: "24.04" - devstack_conf_overrides: | - # ensure we're using a working version of setuptools - if [ -n "\$TOP_DIR" ]; then - sed -i 's/setuptools\[core\]$/setuptools[core]==79.0.1/g' \$TOP_DIR/lib/infra \$TOP_DIR/inc/python - sed -i 's/pip_install "-U" "pbr"/pip_install "-U" "pbr" "setuptools[core]==79.0.1"/g' \$TOP_DIR/lib/infra - fi - name: "gazpacho" openstack_version: "stable/2026.1" ubuntu_version: "24.04" From 920cb43888bcca84ce10d97477cf38f96bd5a835 Mon Sep 17 00:00:00 2001 From: Dominik Danelski Date: Wed, 8 Apr 2026 15:48:12 +0200 Subject: [PATCH 304/353] Implement Placement allocationcandidates Related #526 API reference: https://docs.openstack.org/api-ref/placement/#list-allocation-candidates Code reference: https://opendev.org/openstack/placement/src/branch/stable/2026.1/placement/handlers/allocation_candidate.py#L256-L304 Signed-off-by: Dominik Danelski --- .../placement/v1/allocationcandidates_test.go | 208 +++++++ .../placement/v1/allocationcandidates/doc.go | 58 ++ .../v1/allocationcandidates/microversions.go | 52 ++ .../v1/allocationcandidates/requests.go | 140 +++++ .../v1/allocationcandidates/results.go | 85 +++ .../v1/allocationcandidates/testing/doc.go | 1 + .../testing/fixtures_test.go | 578 ++++++++++++++++++ .../testing/requests_test.go | 140 +++++ .../placement/v1/allocationcandidates/urls.go | 9 + 9 files changed, 1271 insertions(+) create mode 100644 internal/acceptance/openstack/placement/v1/allocationcandidates_test.go create mode 100644 openstack/placement/v1/allocationcandidates/doc.go create mode 100644 openstack/placement/v1/allocationcandidates/microversions.go create mode 100644 openstack/placement/v1/allocationcandidates/requests.go create mode 100644 openstack/placement/v1/allocationcandidates/results.go create mode 100644 openstack/placement/v1/allocationcandidates/testing/doc.go create mode 100644 openstack/placement/v1/allocationcandidates/testing/fixtures_test.go create mode 100644 openstack/placement/v1/allocationcandidates/testing/requests_test.go create mode 100644 openstack/placement/v1/allocationcandidates/urls.go diff --git a/internal/acceptance/openstack/placement/v1/allocationcandidates_test.go b/internal/acceptance/openstack/placement/v1/allocationcandidates_test.go new file mode 100644 index 0000000000..2cfc4074ac --- /dev/null +++ b/internal/acceptance/openstack/placement/v1/allocationcandidates_test.go @@ -0,0 +1,208 @@ +//go:build acceptance || placement || allocationcandidates + +package v1 + +import ( + "context" + "slices" + "testing" + + "github.com/gophercloud/gophercloud/v2/internal/acceptance/clients" + "github.com/gophercloud/gophercloud/v2/internal/acceptance/tools" + "github.com/gophercloud/gophercloud/v2/openstack/placement/v1/allocationcandidates" + "github.com/gophercloud/gophercloud/v2/openstack/placement/v1/resourceproviders" + th "github.com/gophercloud/gophercloud/v2/testhelper" +) + +// createRPWithVCPUInventory creates a resource provider and seeds it with +// VCPU inventory, returning the provider UUID. The caller is responsible for +// deferring deletion of the provider. +func createRPWithVCPUInventory(t *testing.T, microversion string) (string, func()) { + t.Helper() + + client, err := clients.NewPlacementV1Client() + th.AssertNoErr(t, err) + client.Microversion = microversion + + rp, err := CreateResourceProvider(t, client) + th.AssertNoErr(t, err) + + inventories, err := resourceproviders.GetInventories(context.TODO(), client, rp.UUID).Extract() + th.AssertNoErr(t, err) + + inventories, err = resourceproviders.UpdateInventories(context.TODO(), client, rp.UUID, resourceproviders.UpdateInventoriesOpts{ + ResourceProviderGeneration: inventories.ResourceProviderGeneration, + Inventories: map[string]resourceproviders.Inventory{ + "VCPU": { + AllocationRatio: 1.0, + MaxUnit: 8, + MinUnit: 1, + Reserved: 0, + StepSize: 1, + Total: 8, + }, + }, + }).Extract() + th.AssertNoErr(t, err) + + _, err = resourceproviders.UpdateTraits(context.TODO(), client, rp.UUID, resourceproviders.UpdateTraitsOpts{ + ResourceProviderGeneration: inventories.ResourceProviderGeneration, + Traits: []string{"COMPUTE_NODE"}, + }).Extract() + th.AssertNoErr(t, err) + + cleanup := func() { DeleteResourceProvider(t, client, rp.UUID) } + return rp.UUID, cleanup +} + +func TestAllocationCandidatesList(t *testing.T) { + clients.SkipReleasesBelow(t, "stable/train") + clients.RequireAdmin(t) + + microversion := "1.34" + rpUUID, cleanup := createRPWithVCPUInventory(t, microversion) + defer cleanup() + + client, err := clients.NewPlacementV1Client() + th.AssertNoErr(t, err) + client.Microversion = microversion + + page, err := allocationcandidates.List(client, allocationcandidates.ListOpts{ + Resources: "VCPU:1", + }).AllPages(context.TODO()) + th.AssertNoErr(t, err) + + result, err := allocationcandidates.ExtractAllocationCandidates(page) + th.AssertNoErr(t, err) + + th.AssertEquals(t, true, len(result.AllocationRequests) > 0) + + // Assert: The provider's summary contains the exact inventory we seeded: + // VCPU total=8, reserved=0 → capacity=8, used=0. + summary, present := result.ProviderSummaries[rpUUID] + th.AssertEquals(t, true, present) + vcpuSummary, present := summary.Resources["VCPU"] + th.AssertEquals(t, true, present) + th.AssertEquals(t, 8, vcpuSummary.Capacity) + th.AssertEquals(t, 0, vcpuSummary.Used) + th.AssertEquals(t, true, slices.Contains(*summary.Traits, "COMPUTE_NODE")) + // It is a root provider: root UUID equals its own UUID, parent is absent. + th.AssertEquals(t, rpUUID, *summary.RootProviderUUID) + th.AssertEquals(t, (*string)(nil), summary.ParentProviderUUID) + + // Assert: The allocation request contains the exact resource amount + // and the unsuffixed group maps to the newly created RP. + var req allocationcandidates.AllocationRequest + for _, r := range result.AllocationRequests { + if _, present := r.Allocations[rpUUID]; present { + req = r + break + } + } + th.AssertEquals(t, 1, req.Allocations[rpUUID].Resources["VCPU"]) + th.AssertDeepEquals(t, []string{rpUUID}, (*req.Mappings)[""]) + + tools.PrintResource(t, result) +} + +func TestAllocationCandidatesListPre129(t *testing.T) { + clients.SkipReleasesBelow(t, "stable/queens") + clients.RequireAdmin(t) + + microversion := "1.17" + rpUUID, cleanup := createRPWithVCPUInventory(t, microversion) + defer cleanup() + + client, err := clients.NewPlacementV1Client() + th.AssertNoErr(t, err) + client.Microversion = microversion + + page, err := allocationcandidates.List(client, allocationcandidates.ListOpts{ + Resources: "VCPU:1", + }).AllPages(context.TODO()) + th.AssertNoErr(t, err) + + result, err := allocationcandidates.ExtractAllocationCandidates(page) + th.AssertNoErr(t, err) + + th.AssertEquals(t, true, len(result.AllocationRequests) > 0) + + summary, present := result.ProviderSummaries[rpUUID] + th.AssertEquals(t, true, present) + vcpuSummary, present := summary.Resources["VCPU"] + th.AssertEquals(t, true, present) + th.AssertEquals(t, 8, vcpuSummary.Capacity) + th.AssertEquals(t, 0, vcpuSummary.Used) + th.AssertEquals(t, true, slices.Contains(*summary.Traits, "COMPUTE_NODE")) + // Root/parent UUIDs are absent below 1.29. + th.AssertEquals(t, (*string)(nil), summary.RootProviderUUID) + th.AssertEquals(t, (*string)(nil), summary.ParentProviderUUID) + // Mappings are absent below 1.34. + th.AssertEquals(t, (*map[string][]string)(nil), result.AllocationRequests[0].Mappings) +} + +func TestAllocationCandidatesList110(t *testing.T) { + clients.SkipReleasesBelow(t, "stable/pike") + clients.RequireAdmin(t) + + microversion := "1.10" + rpUUID, cleanup := createRPWithVCPUInventory(t, microversion) + defer cleanup() + + client, err := clients.NewPlacementV1Client() + th.AssertNoErr(t, err) + client.Microversion = microversion + + page, err := allocationcandidates.List(client, allocationcandidates.ListOpts{ + Resources: "VCPU:1", + }).AllPages(context.TODO()) + th.AssertNoErr(t, err) + + // Pre 1.12 uses an incompatible response format; use the separate function + // from microversions.go. + result, err := allocationcandidates.ExtractAllocationCandidates110(page) + th.AssertNoErr(t, err) + + th.AssertEquals(t, true, len(result.AllocationRequests) > 0) + th.AssertEquals(t, true, len(result.ProviderSummaries) > 0) + + // Assert: UUID of the created RP present and resource amount correct. + var foundAlloc allocationcandidates.AllocationRequest110Resource + for _, req := range result.AllocationRequests { + for _, alloc := range req.Allocations { + if alloc.ResourceProvider.UUID == rpUUID { + foundAlloc = alloc + } + } + } + th.AssertEquals(t, rpUUID, foundAlloc.ResourceProvider.UUID) + th.AssertEquals(t, 1, foundAlloc.Resources["VCPU"]) + + // Assert: The provider summary contains the expected inventory. + rpSummary, present := result.ProviderSummaries[rpUUID] + th.AssertEquals(t, true, present) + vcpuSummary, present := rpSummary.Resources["VCPU"] + th.AssertEquals(t, true, present) + th.AssertEquals(t, 8, vcpuSummary.Capacity) + th.AssertEquals(t, 0, vcpuSummary.Used) +} + +func TestAllocationCandidatesListEmpty(t *testing.T) { + clients.SkipReleasesBelow(t, "stable/pike") + clients.RequireAdmin(t) + + microversion := "1.10" + client, err := clients.NewPlacementV1Client() + th.AssertNoErr(t, err) + client.Microversion = microversion + + page, err := allocationcandidates.List(client, allocationcandidates.ListOpts{ + Resources: "MEMORY_MB:999999", + }).AllPages(context.TODO()) + th.AssertNoErr(t, err) + + result, err := allocationcandidates.ExtractAllocationCandidates(page) + th.AssertNoErr(t, err) + th.AssertEquals(t, 0, len(result.AllocationRequests)) + th.AssertEquals(t, 0, len(result.ProviderSummaries)) +} diff --git a/openstack/placement/v1/allocationcandidates/doc.go b/openstack/placement/v1/allocationcandidates/doc.go new file mode 100644 index 0000000000..ae9ceb284c --- /dev/null +++ b/openstack/placement/v1/allocationcandidates/doc.go @@ -0,0 +1,58 @@ +/* +Package allocationcandidates queries allocation candidates from the +OpenStack Placement service. + +Allocation candidates API requests are available starting from version 1.10. + +The response format changed in version 1.12: the allocations field in +allocation_requests changed from an array to a dictionary keyed by +resource provider UUID. Use the microversions.go types for 1.10-1.11. + +Example to list allocation candidates + + listOpts := allocationcandidates.ListOpts{ + Resources: "VCPU:1,MEMORY_MB:1024", + Required: []string{"HW_CPU_X86_SSE"}, + } + + page, err := allocationcandidates.List(placementClient, listOpts).AllPages(context.TODO()) + if err != nil { + panic(err) + } + allocationCandidates, err := allocationcandidates.ExtractAllocationCandidates(page) + if err != nil { + panic(err) + } + + fmt.Printf("%+v\n", allocationCandidates) + +Example to list allocation candidates with granular resource groups (microversion >= 1.33) + + listOpts := allocationcandidates.ListOpts{ + Resources: "VCPU:1,MEMORY_MB:1024", + GroupPolicy: "isolate", + ResourceGroups: map[string]allocationcandidates.ResourceGroup{ + "1": { + Resources: "SRIOV_NET_VF:1", + Required: []string{"CUSTOM_PHYSNET1"}, + }, + "_NET": { + Resources: "NET_BW_EGR_KILOBIT_PER_SEC:10", + MemberOf: "in:42896e0d-205d-4fe3-bd1e-100924931787,5e08ea53-c4c6-448e-9334-ac4953de3cfa", + }, + }, + } + + placementClient.Microversion = "1.33" + page, err := allocationcandidates.List(placementClient, listOpts).AllPages(context.TODO()) + if err != nil { + panic(err) + } + allocationCandidates, err := allocationcandidates.ExtractAllocationCandidates(page) + if err != nil { + panic(err) + } + + fmt.Printf("%+v\n", allocationCandidates) +*/ +package allocationcandidates diff --git a/openstack/placement/v1/allocationcandidates/microversions.go b/openstack/placement/v1/allocationcandidates/microversions.go new file mode 100644 index 0000000000..56b3c3c41b --- /dev/null +++ b/openstack/placement/v1/allocationcandidates/microversions.go @@ -0,0 +1,52 @@ +package allocationcandidates + +import "github.com/gophercloud/gophercloud/v2/pagination" + +// AllocationCandidates110 represents the response from a List allocation +// candidates request for microversions 1.10-1.11. +// In these versions the allocations field is an array rather than a dictionary. +type AllocationCandidates110 struct { + // AllocationRequests is a list of objects that contain information + // for creating a later allocation claim request. + AllocationRequests []AllocationRequest110 `json:"allocation_requests"` + + // ProviderSummaries is a dictionary keyed by resource provider UUID of + // inventory/capacity information for providers in the allocation_requests. + ProviderSummaries map[string]ProviderSummary110 `json:"provider_summaries"` +} + +// AllocationRequest110 represents a single allocation request for +// microversions 1.10-1.11 where allocations is an array. +type AllocationRequest110 struct { + // Allocations is a list of allocation resources per provider. + Allocations []AllocationRequest110Resource `json:"allocations"` +} + +// AllocationRequest110Resource represents a single provider allocation +// within a 1.10-1.11 allocation request. +type AllocationRequest110Resource struct { + // ResourceProvider contains the UUID of the resource provider. + ResourceProvider AllocationRequest110ResourceProvider `json:"resource_provider"` + + // Resources is a dictionary of resource class names to the amount requested. + Resources map[string]int `json:"resources"` +} + +// AllocationRequest110ResourceProvider contains the UUID of a resource provider. +type AllocationRequest110ResourceProvider struct { + UUID string `json:"uuid"` +} + +// ProviderSummary110 represents a provider summary for microversions 1.10-1.11 +// which only includes resources (no traits or parent/root UUIDs). +type ProviderSummary110 struct { + // Resources is a dictionary of resource class names to capacity/usage info. + Resources map[string]ProviderSummaryResource `json:"resources"` +} + +// ExtractAllocationCandidates110 interprets an AllocationCandidatesPage as AllocationCandidates110 (microversions 1.10-1.11). +func ExtractAllocationCandidates110(r pagination.Page) (*AllocationCandidates110, error) { + var s AllocationCandidates110 + err := (r.(AllocationCandidatesPage)).ExtractInto(&s) + return &s, err +} diff --git a/openstack/placement/v1/allocationcandidates/requests.go b/openstack/placement/v1/allocationcandidates/requests.go new file mode 100644 index 0000000000..02530a7cf2 --- /dev/null +++ b/openstack/placement/v1/allocationcandidates/requests.go @@ -0,0 +1,140 @@ +package allocationcandidates + +import ( + "github.com/gophercloud/gophercloud/v2" + "github.com/gophercloud/gophercloud/v2/pagination" +) + +// ListOptsBuilder allows extensions to add additional parameters to the +// List request. +type ListOptsBuilder interface { + ToAllocationCandidatesListQuery() (string, error) +} + +// ResourceGroup represents a granular resource request group. +// It is not a standalone request type, but becomes part of ListOpts, +// keyed by a user-defined suffix string. +// Available in version >= 1.25. +type ResourceGroup struct { + // Resources is a comma-separated list of resource amounts, e.g. "VCPU:1,MEMORY_MB:1024". + // Becomes the resourcesN query parameter. + Resources string + + // Required is a list of trait expressions for this group. + // Each entry becomes one requiredN query parameter. + // Available in version >= 1.39: can be repeated; supports in: syntax. + Required []string + + // MemberOf is an aggregate UUID or the prefix in: followed by a + // comma-separated list of aggregate UUIDs for this group. + // Becomes the member_ofN query parameter. + // Available in version >= 1.32: forbidden aggregates can be expressed + // with a ! prefix or the !in: prefix. + MemberOf string + + // InTree filters results to include only providers in the same tree as + // the specified provider UUID for this group. + // Becomes the in_treeN query parameter. + // Available in version >= 1.31. + InTree string +} + +// ListOpts allows filtering of allocation candidates. +type ListOpts struct { + // Resources is a comma-separated list of resource amounts that providers + // must collectively have capacity to serve, e.g. "VCPU:4,DISK_GB:64,MEMORY_MB:2048". + Resources string `q:"resources"` + + // Required is a comma-separated list of traits that a provider must have. + // Available in version >= 1.17. + // Available in version >= 1.22: prefix with ! for forbidden traits. + // Available in version >= 1.39: can be repeated and supports in: syntax. + Required []string `q:"required"` + + // MemberOf is a string representing an aggregate UUID, or the prefix in: + // followed by a comma-separated list of aggregate UUIDs. + // Available in version >= 1.21. + // Available in version >= 1.24: can be specified multiple times. + MemberOf []string `q:"member_of"` + + // InTree is a resource provider UUID. When supplied, filters candidates to + // only those providers that are in the same tree. + // Available in version >= 1.31. + InTree string `q:"in_tree"` + + // GroupPolicy indicates how the groups should interact when more than one + // resourcesN parameter is supplied. Valid values are "none" and "isolate". + // Available in version >= 1.25. + GroupPolicy string `q:"group_policy"` + + // Limit is a positive integer used to limit the maximum number of + // allocation candidates returned. + // Available in version >= 1.16. + Limit int `q:"limit"` + + // RootRequired is a comma-separated list of trait requirements that the + // root provider of the (non-sharing) tree must satisfy. + // Available in version >= 1.35. + RootRequired string `q:"root_required"` + + // SameSubtree is a comma-separated list of request group suffix strings. + // At least one of the resource providers satisfying a specified request group + // must be an ancestor of the rest. + // Available in version >= 1.36. + SameSubtree []string `q:"same_subtree"` + + // ResourceGroups allows specifying suffixed granular resource request groups. + // The map key is the non-empty group suffix (e.g. "1", "_NET1", "_STORAGE"). + // Use the top-level Resources/Required/MemberOf/InTree fields for the + // unsuffixed (default) group; do not use an empty string key here. + // In microversions 1.25-1.32 the suffix must be a numeric string. + // Starting from microversion 1.33 it can be 1-64 characters [a-zA-Z0-9_-]. + // Available in version >= 1.25. + ResourceGroups map[string]ResourceGroup `q:"-"` +} + +// ToAllocationCandidatesListQuery formats a ListOpts into a query string. +func (opts ListOpts) ToAllocationCandidatesListQuery() (string, error) { + q, err := gophercloud.BuildQueryString(opts) + if err != nil { + return "", err + } + + params := q.Query() + for suffix, group := range opts.ResourceGroups { + if group.Resources != "" { + params.Add("resources"+suffix, group.Resources) + } + for _, required := range group.Required { + if required != "" { + params.Add("required"+suffix, required) + } + } + if group.MemberOf != "" { + params.Add("member_of"+suffix, group.MemberOf) + } + if group.InTree != "" { + params.Add("in_tree"+suffix, group.InTree) + } + } + q.RawQuery = params.Encode() + + return q.String(), nil +} + +// List makes a request against the API to list allocation candidates. +func List(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { + url := listURL(client) + + if opts != nil { + query, err := opts.ToAllocationCandidatesListQuery() + if err != nil { + return pagination.Pager{Err: err} + } + url += query + } + + return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { + return AllocationCandidatesPage{pagination.SinglePageBase(r)} + }) +} diff --git a/openstack/placement/v1/allocationcandidates/results.go b/openstack/placement/v1/allocationcandidates/results.go new file mode 100644 index 0000000000..44212872de --- /dev/null +++ b/openstack/placement/v1/allocationcandidates/results.go @@ -0,0 +1,85 @@ +package allocationcandidates + +import "github.com/gophercloud/gophercloud/v2/pagination" + +// AllocationCandidates represents the response from a List allocation +// candidates request for microversions 1.12 and above. +type AllocationCandidates struct { + // AllocationRequests is a list of objects that contain information + // for creating a later allocation claim request. + AllocationRequests []AllocationRequest `json:"allocation_requests"` + + // ProviderSummaries is a dictionary keyed by resource provider UUID of + // inventory/capacity information for providers in the allocation_requests. + ProviderSummaries map[string]ProviderSummary `json:"provider_summaries"` +} + +// AllocationRequest represents a single allocation request within the +// allocation candidates response. +type AllocationRequest struct { + // Allocations is a dictionary of resource allocations keyed by + // resource provider UUID. + Allocations map[string]AllocationRequestResource `json:"allocations"` + + // Mappings is a dictionary associating request group suffixes with a + // list of UUIDs identifying the resource providers that satisfied each group. + // Available in version >= 1.34. + Mappings *map[string][]string `json:"mappings"` +} + +// AllocationRequestResource represents the resources requested from a +// single resource provider within an allocation request. +type AllocationRequestResource struct { + // Resources is a dictionary of resource class names to the amount requested. + Resources map[string]int `json:"resources"` +} + +// ProviderSummary represents the summary of a resource provider's inventory +// and traits. +type ProviderSummary struct { + // Resources is a dictionary of resource class names to capacity/usage info. + Resources map[string]ProviderSummaryResource `json:"resources"` + + // Traits is a list of traits the resource provider has associated with it. + // Available in version >= 1.17. + Traits *[]string `json:"traits"` + + // ParentProviderUUID is the UUID of the immediate parent of the resource provider. + // Available in version >= 1.29. + ParentProviderUUID *string `json:"parent_provider_uuid"` + + // RootProviderUUID is the UUID of the top-most provider in this provider tree. + // Available in version >= 1.29. + RootProviderUUID *string `json:"root_provider_uuid"` +} + +// ProviderSummaryResource represents the capacity and usage of a single +// resource class for a provider. +type ProviderSummaryResource struct { + // Capacity is the amount of the resource that the provider can accommodate. + Capacity int `json:"capacity"` + + // Used is the amount of the resource that has been already allocated. + Used int `json:"used"` +} + +// AllocationCandidatesPage is the page returned from a List call. +type AllocationCandidatesPage struct { + pagination.SinglePageBase +} + +// IsEmpty determines if an AllocationCandidatesPage contains any results. +func (page AllocationCandidatesPage) IsEmpty() (bool, error) { + candidates, err := ExtractAllocationCandidates(page) + if err != nil { + return false, err + } + return len(candidates.AllocationRequests) == 0, nil +} + +// ExtractAllocationCandidates interprets an AllocationCandidatesPage as AllocationCandidates (microversion 1.12+). +func ExtractAllocationCandidates(r pagination.Page) (*AllocationCandidates, error) { + var s AllocationCandidates + err := (r.(AllocationCandidatesPage)).ExtractInto(&s) + return &s, err +} diff --git a/openstack/placement/v1/allocationcandidates/testing/doc.go b/openstack/placement/v1/allocationcandidates/testing/doc.go new file mode 100644 index 0000000000..7603f836a0 --- /dev/null +++ b/openstack/placement/v1/allocationcandidates/testing/doc.go @@ -0,0 +1 @@ +package testing diff --git a/openstack/placement/v1/allocationcandidates/testing/fixtures_test.go b/openstack/placement/v1/allocationcandidates/testing/fixtures_test.go new file mode 100644 index 0000000000..f69a1ffb62 --- /dev/null +++ b/openstack/placement/v1/allocationcandidates/testing/fixtures_test.go @@ -0,0 +1,578 @@ +package testing + +import ( + "fmt" + "net/http" + "testing" + + "github.com/gophercloud/gophercloud/v2/internal/ptr" + "github.com/gophercloud/gophercloud/v2/openstack/placement/v1/allocationcandidates" + th "github.com/gophercloud/gophercloud/v2/testhelper" + "github.com/gophercloud/gophercloud/v2/testhelper/client" +) + +const AllocationCandidatesBody = ` +{ + "allocation_requests": [ + { + "allocations": { + "rp-uuid-1": { + "resources": { + "VCPU": 1, + "MEMORY_MB": 1024 + } + }, + "rp-uuid-2": { + "resources": { + "DISK_GB": 100 + } + } + }, + "mappings": { + "": ["rp-uuid-1"], + "_DISK": ["rp-uuid-2"] + } + } + ], + "provider_summaries": { + "rp-uuid-1": { + "resources": { + "VCPU": { + "capacity": 16, + "used": 0 + }, + "MEMORY_MB": { + "capacity": 32768, + "used": 0 + } + }, + "traits": ["HW_CPU_X86_AVX2", "HW_CPU_X86_SSE"], + "parent_provider_uuid": null, + "root_provider_uuid": "rp-uuid-1" + }, + "rp-uuid-2": { + "resources": { + "DISK_GB": { + "capacity": 1900, + "used": 0 + } + }, + "traits": ["MISC_SHARES_VIA_AGGREGATE"], + "parent_provider_uuid": null, + "root_provider_uuid": "rp-uuid-2" + } + } +} +` + +const AllocationCandidatesBodyPre134 = ` +{ + "allocation_requests": [ + { + "allocations": { + "rp-uuid-1": { + "resources": { + "VCPU": 1, + "MEMORY_MB": 1024 + } + }, + "rp-uuid-2": { + "resources": { + "DISK_GB": 100 + } + } + } + } + ], + "provider_summaries": { + "rp-uuid-1": { + "resources": { + "VCPU": { + "capacity": 16, + "used": 0 + }, + "MEMORY_MB": { + "capacity": 32768, + "used": 0 + } + }, + "traits": ["HW_CPU_X86_AVX2", "HW_CPU_X86_SSE"], + "parent_provider_uuid": null, + "root_provider_uuid": "rp-uuid-1" + }, + "rp-uuid-2": { + "resources": { + "DISK_GB": { + "capacity": 1900, + "used": 0 + } + }, + "traits": ["MISC_SHARES_VIA_AGGREGATE"], + "parent_provider_uuid": null, + "root_provider_uuid": "rp-uuid-2" + } + } +} +` + +const AllocationCandidatesBodyPre129 = ` +{ + "allocation_requests": [ + { + "allocations": { + "rp-uuid-1": { + "resources": { + "VCPU": 1, + "MEMORY_MB": 1024 + } + }, + "rp-uuid-2": { + "resources": { + "DISK_GB": 100 + } + } + } + } + ], + "provider_summaries": { + "rp-uuid-1": { + "resources": { + "VCPU": { + "capacity": 16, + "used": 0 + }, + "MEMORY_MB": { + "capacity": 32768, + "used": 0 + } + }, + "traits": ["HW_CPU_X86_AVX2", "HW_CPU_X86_SSE"] + }, + "rp-uuid-2": { + "resources": { + "DISK_GB": { + "capacity": 1900, + "used": 0 + } + }, + "traits": ["MISC_SHARES_VIA_AGGREGATE"] + } + } +} +` + +const AllocationCandidatesBodyPre117 = ` +{ + "allocation_requests": [ + { + "allocations": { + "rp-uuid-1": { + "resources": { + "VCPU": 1, + "MEMORY_MB": 1024 + } + }, + "rp-uuid-2": { + "resources": { + "DISK_GB": 100 + } + } + } + } + ], + "provider_summaries": { + "rp-uuid-1": { + "resources": { + "VCPU": { + "capacity": 16, + "used": 0 + }, + "MEMORY_MB": { + "capacity": 32768, + "used": 0 + } + } + }, + "rp-uuid-2": { + "resources": { + "DISK_GB": { + "capacity": 1900, + "used": 0 + } + } + } + } +} +` + +const AllocationCandidatesBody110 = ` +{ + "allocation_requests": [ + { + "allocations": [ + { + "resource_provider": { + "uuid": "rp-uuid-1" + }, + "resources": { + "VCPU": 1, + "MEMORY_MB": 1024 + } + } + ] + } + ], + "provider_summaries": { + "rp-uuid-1": { + "resources": { + "VCPU": { + "capacity": 16, + "used": 0 + }, + "MEMORY_MB": { + "capacity": 32768, + "used": 0 + } + } + } + } +} +` + +const AllocationCandidatesEmptyBody = ` +{ + "allocation_requests": [], + "provider_summaries": {} +} +` + +var ExpectedAllocationCandidates = allocationcandidates.AllocationCandidates{ + AllocationRequests: []allocationcandidates.AllocationRequest{ + { + Allocations: map[string]allocationcandidates.AllocationRequestResource{ + "rp-uuid-1": { + Resources: map[string]int{ + "VCPU": 1, + "MEMORY_MB": 1024, + }, + }, + "rp-uuid-2": { + Resources: map[string]int{ + "DISK_GB": 100, + }, + }, + }, + Mappings: &map[string][]string{ + "": {"rp-uuid-1"}, + "_DISK": {"rp-uuid-2"}, + }, + }, + }, + ProviderSummaries: map[string]allocationcandidates.ProviderSummary{ + "rp-uuid-1": { + Resources: map[string]allocationcandidates.ProviderSummaryResource{ + "VCPU": { + Capacity: 16, + Used: 0, + }, + "MEMORY_MB": { + Capacity: 32768, + Used: 0, + }, + }, + Traits: ptr.To([]string{"HW_CPU_X86_AVX2", "HW_CPU_X86_SSE"}), + ParentProviderUUID: nil, + RootProviderUUID: ptr.To("rp-uuid-1"), + }, + "rp-uuid-2": { + Resources: map[string]allocationcandidates.ProviderSummaryResource{ + "DISK_GB": { + Capacity: 1900, + Used: 0, + }, + }, + Traits: ptr.To([]string{"MISC_SHARES_VIA_AGGREGATE"}), + ParentProviderUUID: nil, + RootProviderUUID: ptr.To("rp-uuid-2"), + }, + }, +} + +var ExpectedAllocationCandidatesPre134 = allocationcandidates.AllocationCandidates{ + AllocationRequests: []allocationcandidates.AllocationRequest{ + { + Allocations: map[string]allocationcandidates.AllocationRequestResource{ + "rp-uuid-1": { + Resources: map[string]int{ + "VCPU": 1, + "MEMORY_MB": 1024, + }, + }, + "rp-uuid-2": { + Resources: map[string]int{ + "DISK_GB": 100, + }, + }, + }, + }, + }, + ProviderSummaries: map[string]allocationcandidates.ProviderSummary{ + "rp-uuid-1": { + Resources: map[string]allocationcandidates.ProviderSummaryResource{ + "VCPU": { + Capacity: 16, + Used: 0, + }, + "MEMORY_MB": { + Capacity: 32768, + Used: 0, + }, + }, + Traits: ptr.To([]string{"HW_CPU_X86_AVX2", "HW_CPU_X86_SSE"}), + ParentProviderUUID: nil, + RootProviderUUID: ptr.To("rp-uuid-1"), + }, + "rp-uuid-2": { + Resources: map[string]allocationcandidates.ProviderSummaryResource{ + "DISK_GB": { + Capacity: 1900, + Used: 0, + }, + }, + Traits: ptr.To([]string{"MISC_SHARES_VIA_AGGREGATE"}), + ParentProviderUUID: nil, + RootProviderUUID: ptr.To("rp-uuid-2"), + }, + }, +} + +var ExpectedAllocationCandidatesPre129 = allocationcandidates.AllocationCandidates{ + AllocationRequests: []allocationcandidates.AllocationRequest{ + { + Allocations: map[string]allocationcandidates.AllocationRequestResource{ + "rp-uuid-1": { + Resources: map[string]int{ + "VCPU": 1, + "MEMORY_MB": 1024, + }, + }, + "rp-uuid-2": { + Resources: map[string]int{ + "DISK_GB": 100, + }, + }, + }, + }, + }, + ProviderSummaries: map[string]allocationcandidates.ProviderSummary{ + "rp-uuid-1": { + Resources: map[string]allocationcandidates.ProviderSummaryResource{ + "VCPU": { + Capacity: 16, + Used: 0, + }, + "MEMORY_MB": { + Capacity: 32768, + Used: 0, + }, + }, + Traits: ptr.To([]string{"HW_CPU_X86_AVX2", "HW_CPU_X86_SSE"}), + }, + "rp-uuid-2": { + Resources: map[string]allocationcandidates.ProviderSummaryResource{ + "DISK_GB": { + Capacity: 1900, + Used: 0, + }, + }, + Traits: ptr.To([]string{"MISC_SHARES_VIA_AGGREGATE"}), + }, + }, +} + +var ExpectedAllocationCandidatesPre117 = allocationcandidates.AllocationCandidates{ + AllocationRequests: []allocationcandidates.AllocationRequest{ + { + Allocations: map[string]allocationcandidates.AllocationRequestResource{ + "rp-uuid-1": { + Resources: map[string]int{ + "VCPU": 1, + "MEMORY_MB": 1024, + }, + }, + "rp-uuid-2": { + Resources: map[string]int{ + "DISK_GB": 100, + }, + }, + }, + }, + }, + ProviderSummaries: map[string]allocationcandidates.ProviderSummary{ + "rp-uuid-1": { + Resources: map[string]allocationcandidates.ProviderSummaryResource{ + "VCPU": { + Capacity: 16, + Used: 0, + }, + "MEMORY_MB": { + Capacity: 32768, + Used: 0, + }, + }, + }, + "rp-uuid-2": { + Resources: map[string]allocationcandidates.ProviderSummaryResource{ + "DISK_GB": { + Capacity: 1900, + Used: 0, + }, + }, + }, + }, +} + +var ExpectedAllocationCandidates110 = allocationcandidates.AllocationCandidates110{ + AllocationRequests: []allocationcandidates.AllocationRequest110{ + { + Allocations: []allocationcandidates.AllocationRequest110Resource{ + { + ResourceProvider: allocationcandidates.AllocationRequest110ResourceProvider{ + UUID: "rp-uuid-1", + }, + Resources: map[string]int{ + "VCPU": 1, + "MEMORY_MB": 1024, + }, + }, + }, + }, + }, + ProviderSummaries: map[string]allocationcandidates.ProviderSummary110{ + "rp-uuid-1": { + Resources: map[string]allocationcandidates.ProviderSummaryResource{ + "VCPU": { + Capacity: 16, + Used: 0, + }, + "MEMORY_MB": { + Capacity: 32768, + Used: 0, + }, + }, + }, + }, +} + +func HandleListAllocationCandidatesSuccess(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/allocation_candidates", + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + + fmt.Fprint(w, AllocationCandidatesBody) + }) +} + +func HandleListAllocationCandidatesPre134Success(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/allocation_candidates", + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + + fmt.Fprint(w, AllocationCandidatesBodyPre134) + }) +} + +func HandleListAllocationCandidatesPre129Success(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/allocation_candidates", + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + + fmt.Fprint(w, AllocationCandidatesBodyPre129) + }) +} + +func HandleListAllocationCandidatesPre117Success(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/allocation_candidates", + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + + fmt.Fprint(w, AllocationCandidatesBodyPre117) + }) +} + +func HandleListAllocationCandidates110Success(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/allocation_candidates", + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + + fmt.Fprint(w, AllocationCandidatesBody110) + }) +} + +func HandleListAllocationCandidatesEmptySuccess(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/allocation_candidates", + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + + fmt.Fprint(w, AllocationCandidatesEmptyBody) + }) +} + +func HandleListAllocationCandidatesBadRequest(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/allocation_candidates", + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusBadRequest) + + fmt.Fprint(w, `{"errors": [{"status": 400, "detail": "Invalid resources parameter."}]}`) + }) +} + +func HandleListAllocationCandidatesWithFullQuerySuccess(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/allocation_candidates", + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + q := r.URL.Query() + th.AssertEquals(t, "VCPU:1,MEMORY_MB:1024", q.Get("resources")) + th.AssertEquals(t, "5", q.Get("limit")) + th.AssertEquals(t, "isolate", q.Get("group_policy")) + th.AssertEquals(t, "SRIOV_NET_VF:1", q.Get("resources1")) + th.AssertEquals(t, "CUSTOM_PHYSNET1", q.Get("required1")) + // required is repeated; order matches the ListOpts.Required slice order. + th.AssertDeepEquals(t, []string{"HW_CPU_X86_SSE", "!HW_CPU_X86_AVX2"}, q["required"]) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + + fmt.Fprint(w, AllocationCandidatesBody) + }) +} diff --git a/openstack/placement/v1/allocationcandidates/testing/requests_test.go b/openstack/placement/v1/allocationcandidates/testing/requests_test.go new file mode 100644 index 0000000000..14b0530512 --- /dev/null +++ b/openstack/placement/v1/allocationcandidates/testing/requests_test.go @@ -0,0 +1,140 @@ +package testing + +import ( + "context" + "net/http" + "testing" + + "github.com/gophercloud/gophercloud/v2" + "github.com/gophercloud/gophercloud/v2/openstack/placement/v1/allocationcandidates" + th "github.com/gophercloud/gophercloud/v2/testhelper" + "github.com/gophercloud/gophercloud/v2/testhelper/client" +) + +func TestListAllocationCandidatesSuccess(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleListAllocationCandidatesSuccess(t, fakeServer) + + page, err := allocationcandidates.List(client.ServiceClient(fakeServer), allocationcandidates.ListOpts{ + Resources: "VCPU:1,MEMORY_MB:1024", + }).AllPages(context.TODO()) + th.AssertNoErr(t, err) + actual, err := allocationcandidates.ExtractAllocationCandidates(page) + th.AssertNoErr(t, err) + th.AssertDeepEquals(t, ExpectedAllocationCandidates, *actual) +} + +func TestListAllocationCandidatesPre134Success(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleListAllocationCandidatesPre134Success(t, fakeServer) + + page, err := allocationcandidates.List(client.ServiceClient(fakeServer), allocationcandidates.ListOpts{ + Resources: "VCPU:1,MEMORY_MB:1024", + }).AllPages(context.TODO()) + th.AssertNoErr(t, err) + actual, err := allocationcandidates.ExtractAllocationCandidates(page) + th.AssertNoErr(t, err) + th.AssertDeepEquals(t, ExpectedAllocationCandidatesPre134, *actual) +} + +func TestListAllocationCandidatesPre129Success(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleListAllocationCandidatesPre129Success(t, fakeServer) + + page, err := allocationcandidates.List(client.ServiceClient(fakeServer), allocationcandidates.ListOpts{ + Resources: "VCPU:1,MEMORY_MB:1024", + }).AllPages(context.TODO()) + th.AssertNoErr(t, err) + actual, err := allocationcandidates.ExtractAllocationCandidates(page) + th.AssertNoErr(t, err) + th.AssertDeepEquals(t, ExpectedAllocationCandidatesPre129, *actual) +} + +func TestListAllocationCandidatesPre117Success(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleListAllocationCandidatesPre117Success(t, fakeServer) + + page, err := allocationcandidates.List(client.ServiceClient(fakeServer), allocationcandidates.ListOpts{ + Resources: "VCPU:1,MEMORY_MB:1024", + }).AllPages(context.TODO()) + th.AssertNoErr(t, err) + actual, err := allocationcandidates.ExtractAllocationCandidates(page) + th.AssertNoErr(t, err) + th.AssertDeepEquals(t, ExpectedAllocationCandidatesPre117, *actual) +} + +func TestListAllocationCandidates110Success(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleListAllocationCandidates110Success(t, fakeServer) + + page, err := allocationcandidates.List(client.ServiceClient(fakeServer), allocationcandidates.ListOpts{ + Resources: "VCPU:1,MEMORY_MB:1024", + }).AllPages(context.TODO()) + th.AssertNoErr(t, err) + actual, err := allocationcandidates.ExtractAllocationCandidates110(page) + th.AssertNoErr(t, err) + th.AssertDeepEquals(t, ExpectedAllocationCandidates110, *actual) +} + +func TestListAllocationCandidatesEmptySuccess(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleListAllocationCandidatesEmptySuccess(t, fakeServer) + + page, err := allocationcandidates.List(client.ServiceClient(fakeServer), allocationcandidates.ListOpts{ + Resources: "VCPU:1,MEMORY_MB:1024", + }).AllPages(context.TODO()) + th.AssertNoErr(t, err) + actual, err := allocationcandidates.ExtractAllocationCandidates(page) + th.AssertNoErr(t, err) + th.AssertEquals(t, 0, len(actual.AllocationRequests)) + th.AssertEquals(t, 0, len(actual.ProviderSummaries)) +} + +func TestListAllocationCandidatesBadRequest(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleListAllocationCandidatesBadRequest(t, fakeServer) + + _, err := allocationcandidates.List(client.ServiceClient(fakeServer), allocationcandidates.ListOpts{ + Resources: "INVALID", + }).AllPages(context.TODO()) + th.AssertErr(t, err) + th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusBadRequest)) +} + +func TestListAllocationCandidatesWithFullQuerySuccess(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleListAllocationCandidatesWithFullQuerySuccess(t, fakeServer) + + page, err := allocationcandidates.List(client.ServiceClient(fakeServer), allocationcandidates.ListOpts{ + Resources: "VCPU:1,MEMORY_MB:1024", + Required: []string{"HW_CPU_X86_SSE", "!HW_CPU_X86_AVX2"}, + Limit: 5, + GroupPolicy: "isolate", + ResourceGroups: map[string]allocationcandidates.ResourceGroup{ + "1": { + Resources: "SRIOV_NET_VF:1", + Required: []string{"CUSTOM_PHYSNET1"}, + }, + }, + }).AllPages(context.TODO()) + th.AssertNoErr(t, err) + actual, err := allocationcandidates.ExtractAllocationCandidates(page) + th.AssertNoErr(t, err) + th.AssertDeepEquals(t, ExpectedAllocationCandidates, *actual) +} diff --git a/openstack/placement/v1/allocationcandidates/urls.go b/openstack/placement/v1/allocationcandidates/urls.go new file mode 100644 index 0000000000..fd3f4a6743 --- /dev/null +++ b/openstack/placement/v1/allocationcandidates/urls.go @@ -0,0 +1,9 @@ +package allocationcandidates + +import "github.com/gophercloud/gophercloud/v2" + +const apiName = "allocation_candidates" + +func listURL(client *gophercloud.ServiceClient) string { + return client.ServiceURL(apiName) +} From 6e3db72334f19d358b06d95e3873c4deb850f29b Mon Sep 17 00:00:00 2001 From: Dominik Danelski Date: Fri, 10 Apr 2026 00:54:39 +0200 Subject: [PATCH 305/353] Fix IsEmpty for allocation_candidates in 1.10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Full deserialisation could crash on older structure defined for 1.10. Co-authored-by: Martin André Signed-off-by: Dominik Danelski --- .../placement/v1/allocationcandidates_test.go | 26 +++++++++++++++++++ .../v1/allocationcandidates/results.go | 14 +++++++--- .../testing/requests_test.go | 20 ++++++++++++++ 3 files changed, 57 insertions(+), 3 deletions(-) diff --git a/internal/acceptance/openstack/placement/v1/allocationcandidates_test.go b/internal/acceptance/openstack/placement/v1/allocationcandidates_test.go index 2cfc4074ac..38cc6dcc06 100644 --- a/internal/acceptance/openstack/placement/v1/allocationcandidates_test.go +++ b/internal/acceptance/openstack/placement/v1/allocationcandidates_test.go @@ -187,6 +187,28 @@ func TestAllocationCandidatesList110(t *testing.T) { th.AssertEquals(t, 0, vcpuSummary.Used) } +func TestAllocationCandidatesIsEmpty110(t *testing.T) { + clients.SkipReleasesBelow(t, "stable/pike") + clients.RequireAdmin(t) + + microversion := "1.10" + _, cleanup := createRPWithVCPUInventory(t, microversion) + defer cleanup() + + client, err := clients.NewPlacementV1Client() + th.AssertNoErr(t, err) + client.Microversion = microversion + + page, err := allocationcandidates.List(client, allocationcandidates.ListOpts{ + Resources: "VCPU:1", + }).AllPages(context.TODO()) + th.AssertNoErr(t, err) + + isEmpty, err := page.IsEmpty() + th.AssertNoErr(t, err) + th.AssertEquals(t, false, isEmpty) +} + func TestAllocationCandidatesListEmpty(t *testing.T) { clients.SkipReleasesBelow(t, "stable/pike") clients.RequireAdmin(t) @@ -205,4 +227,8 @@ func TestAllocationCandidatesListEmpty(t *testing.T) { th.AssertNoErr(t, err) th.AssertEquals(t, 0, len(result.AllocationRequests)) th.AssertEquals(t, 0, len(result.ProviderSummaries)) + + isEmpty, err := page.IsEmpty() + th.AssertNoErr(t, err) + th.AssertEquals(t, true, isEmpty) } diff --git a/openstack/placement/v1/allocationcandidates/results.go b/openstack/placement/v1/allocationcandidates/results.go index 44212872de..8b94a0a7f5 100644 --- a/openstack/placement/v1/allocationcandidates/results.go +++ b/openstack/placement/v1/allocationcandidates/results.go @@ -1,6 +1,10 @@ package allocationcandidates -import "github.com/gophercloud/gophercloud/v2/pagination" +import ( + "encoding/json" + + "github.com/gophercloud/gophercloud/v2/pagination" +) // AllocationCandidates represents the response from a List allocation // candidates request for microversions 1.12 and above. @@ -69,12 +73,16 @@ type AllocationCandidatesPage struct { } // IsEmpty determines if an AllocationCandidatesPage contains any results. +// It avoids full deserialization so that it works across all microversions, func (page AllocationCandidatesPage) IsEmpty() (bool, error) { - candidates, err := ExtractAllocationCandidates(page) + var s struct { + AllocationRequests []json.RawMessage `json:"allocation_requests"` + } + err := page.ExtractInto(&s) if err != nil { return false, err } - return len(candidates.AllocationRequests) == 0, nil + return len(s.AllocationRequests) == 0, nil } // ExtractAllocationCandidates interprets an AllocationCandidatesPage as AllocationCandidates (microversion 1.12+). diff --git a/openstack/placement/v1/allocationcandidates/testing/requests_test.go b/openstack/placement/v1/allocationcandidates/testing/requests_test.go index 14b0530512..98bb29b9c9 100644 --- a/openstack/placement/v1/allocationcandidates/testing/requests_test.go +++ b/openstack/placement/v1/allocationcandidates/testing/requests_test.go @@ -100,6 +100,26 @@ func TestListAllocationCandidatesEmptySuccess(t *testing.T) { th.AssertNoErr(t, err) th.AssertEquals(t, 0, len(actual.AllocationRequests)) th.AssertEquals(t, 0, len(actual.ProviderSummaries)) + + isEmpty, err := page.IsEmpty() + th.AssertNoErr(t, err) + th.AssertEquals(t, true, isEmpty) +} + +func TestIsEmpty110Success(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleListAllocationCandidates110Success(t, fakeServer) + + page, err := allocationcandidates.List(client.ServiceClient(fakeServer), allocationcandidates.ListOpts{ + Resources: "VCPU:1,MEMORY_MB:1024", + }).AllPages(context.TODO()) + th.AssertNoErr(t, err) + + isEmpty, err := page.IsEmpty() + th.AssertNoErr(t, err) + th.AssertEquals(t, false, isEmpty) } func TestListAllocationCandidatesBadRequest(t *testing.T) { From c617434fb4e9db6a6d50613562ac9b9af595dbd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Andr=C3=A9?= Date: Fri, 10 Apr 2026 10:22:52 +0200 Subject: [PATCH 306/353] Add internal/ptr package with generic To helper The allocationcandidates test fixtures import internal/ptr but the package was missing from this branch, causing a linter typecheck failure. Partial backport from #3190. --- internal/ptr/ptr.go | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 internal/ptr/ptr.go diff --git a/internal/ptr/ptr.go b/internal/ptr/ptr.go new file mode 100644 index 0000000000..6c3ee9bd51 --- /dev/null +++ b/internal/ptr/ptr.go @@ -0,0 +1,5 @@ +package ptr + +func To[T any](v T) *T { + return &v +} From f88846a3530ff7e9a2af03222ed1396ea5aa3752 Mon Sep 17 00:00:00 2001 From: Dominik Danelski Date: Thu, 2 Apr 2026 15:11:50 +0200 Subject: [PATCH 307/353] Implement GET operation on Placement resource provider aggregates Related: #526 API reference: https://docs.openstack.org/api-ref/placement/#list-resource-provider-aggregates Code reference: https://opendev.org/openstack/placement/src/branch/stable/2026.1/placement/handlers/aggregate.py#L81-L99 Signed-off-by: Dominik Danelski --- .../placement/v1/resourceproviders_test.go | 67 +++++++++++++++++++ .../placement/v1/resourceproviders/doc.go | 9 +++ .../v1/resourceproviders/requests.go | 6 ++ .../placement/v1/resourceproviders/results.go | 19 ++++++ .../testing/fixtures_test.go | 47 +++++++++++++ .../testing/requests_test.go | 21 ++++++ .../placement/v1/resourceproviders/urls.go | 4 ++ 7 files changed, 173 insertions(+) diff --git a/internal/acceptance/openstack/placement/v1/resourceproviders_test.go b/internal/acceptance/openstack/placement/v1/resourceproviders_test.go index ecad86b4d9..61daf45f77 100644 --- a/internal/acceptance/openstack/placement/v1/resourceproviders_test.go +++ b/internal/acceptance/openstack/placement/v1/resourceproviders_test.go @@ -451,3 +451,70 @@ func TestResourceProviderAllocations(t *testing.T) { tools.PrintResource(t, usage) } + +func TestResourceProviderAggregatesGetSuccess(t *testing.T) { + // Resource_provider_generation in the aggregates response was introduced in microversion 1.19. + clients.SkipReleasesBelow(t, "stable/ocata") + clients.RequireAdmin(t) + + client, err := clients.NewPlacementV1Client() + th.AssertNoErr(t, err) + + resourceProvider, err := CreateResourceProvider(t, client) + th.AssertNoErr(t, err) + defer DeleteResourceProvider(t, client, resourceProvider.UUID) + + client.Microversion = "1.19" + + aggregates, err := resourceproviders.GetAggregates(context.TODO(), client, resourceProvider.UUID).Extract() + th.AssertNoErr(t, err) + th.AssertEquals(t, true, aggregates.ResourceProviderGeneration != nil) +} + +func TestResourceProviderAggregatesGetPreGenerationSuccess(t *testing.T) { + // Resource provider aggregates operations were introduced in microversion 1.1. + clients.SkipReleasesBelow(t, "stable/ocata") + clients.RequireAdmin(t) + + client, err := clients.NewPlacementV1Client() + th.AssertNoErr(t, err) + + resourceProvider, err := CreateResourceProvider(t, client) + th.AssertNoErr(t, err) + defer DeleteResourceProvider(t, client, resourceProvider.UUID) + + client.Microversion = "1.1" + + aggregates, err := resourceproviders.GetAggregates(context.TODO(), client, resourceProvider.UUID).Extract() + th.AssertNoErr(t, err) + th.AssertEquals(t, 0, len(aggregates.Aggregates)) + th.AssertDeepEquals(t, (*int)(nil), aggregates.ResourceProviderGeneration) +} + +func TestResourceProviderAggregatesGetNegative(t *testing.T) { + // Resource_provider_generation in the aggregates response was introduced in microversion 1.19. + clients.SkipReleasesBelow(t, "stable/ocata") + clients.RequireAdmin(t) + + client, err := clients.NewPlacementV1Client() + th.AssertNoErr(t, err) + + client.Microversion = "1.19" + + _, err = resourceproviders.GetAggregates(context.TODO(), client, "00000000-0000-0000-0000-000000000000").Extract() + th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusNotFound)) +} + +func TestResourceProviderAggregatesGetPreGenerationNegative(t *testing.T) { + // Resource provider aggregates operations were introduced in microversion 1.1. + clients.SkipReleasesBelow(t, "stable/ocata") + clients.RequireAdmin(t) + + client, err := clients.NewPlacementV1Client() + th.AssertNoErr(t, err) + + client.Microversion = "1.1" + + _, err = resourceproviders.GetAggregates(context.TODO(), client, "00000000-0000-0000-0000-000000000000").Extract() + th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusNotFound)) +} diff --git a/openstack/placement/v1/resourceproviders/doc.go b/openstack/placement/v1/resourceproviders/doc.go index d47be9310c..d85c2b85cc 100644 --- a/openstack/placement/v1/resourceproviders/doc.go +++ b/openstack/placement/v1/resourceproviders/doc.go @@ -162,5 +162,14 @@ Example to get resource providers allocations if err != nil { panic(err) } + +Example to get resource providers aggregates + + placementClient.Microversion = "1.1" + + rp, err := resourceproviders.GetAggregates(context.TODO(), placementClient, resourceProviderID).Extract() + if err != nil { + panic(err) + } */ package resourceproviders diff --git a/openstack/placement/v1/resourceproviders/requests.go b/openstack/placement/v1/resourceproviders/requests.go index a1eedeb28d..94e8e7cf69 100644 --- a/openstack/placement/v1/resourceproviders/requests.go +++ b/openstack/placement/v1/resourceproviders/requests.go @@ -254,6 +254,12 @@ func GetTraits(ctx context.Context, client *gophercloud.ServiceClient, resourceP return } +func GetAggregates(ctx context.Context, client *gophercloud.ServiceClient, resourceProviderID string) (r GetAggregatesResult) { + resp, err := client.Get(ctx, getResourceProviderAggregatesURL(client, resourceProviderID), &r.Body, nil) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} + // UpdateTraitsOptsBuilder allows extensions to add additional parameters to the // UpdateTraits request. type UpdateTraitsOptsBuilder interface { diff --git a/openstack/placement/v1/resourceproviders/results.go b/openstack/placement/v1/resourceproviders/results.go index 7f67c39819..db24e3cc6f 100644 --- a/openstack/placement/v1/resourceproviders/results.go +++ b/openstack/placement/v1/resourceproviders/results.go @@ -71,6 +71,12 @@ type ResourceProviderTraits struct { Traits []string `json:"traits"` } +type ResourceProviderAggregates struct { + // ResourceProviderGeneration is available from microversion 1.19 and later. + ResourceProviderGeneration *int `json:"resource_provider_generation"` + Aggregates []string `json:"aggregates"` +} + // resourceProviderResult is the response of a base ResourceProvider result. type resourceProviderResult struct { gophercloud.Result @@ -209,3 +215,16 @@ func (r GetTraitsResult) Extract() (*ResourceProviderTraits, error) { err := r.ExtractInto(&s) return &s, err } + +// GetAggregatesResult is the response of a Get aggregates operations. Call its Extract method +// to interpret it as a ResourceProviderAggregates. +type GetAggregatesResult struct { + gophercloud.Result +} + +// Extract interprets a GetAggregatesResult as a ResourceProviderAggregates. +func (r GetAggregatesResult) Extract() (*ResourceProviderAggregates, error) { + var s ResourceProviderAggregates + err := r.ExtractInto(&s) + return &s, err +} diff --git a/openstack/placement/v1/resourceproviders/testing/fixtures_test.go b/openstack/placement/v1/resourceproviders/testing/fixtures_test.go index 7a0b176114..e774bcf507 100644 --- a/openstack/placement/v1/resourceproviders/testing/fixtures_test.go +++ b/openstack/placement/v1/resourceproviders/testing/fixtures_test.go @@ -223,6 +223,18 @@ const TraitsBody = ` } ` +const AggregatesBody = ` +{ + "resource_provider_generation": 1, + "aggregates": [ + "6d84f6f6-7736-40ff-84d2-7db47f18ea25", + "f11f14bc-6f17-4f0a-b7c2-44b3e685ccf4" + ] +} +` + +const AbsentResourceProviderID = "non-existent-rp" + var ExpectedResourceProvider1 = resourceproviders.ResourceProvider{ Generation: 1, UUID: "99c09379-6e52-4ef8-9a95-b9ce6f68452e", @@ -339,6 +351,14 @@ var ExpectedTraits = resourceproviders.ResourceProviderTraits{ }, } +var ExpectedAggregates = resourceproviders.ResourceProviderAggregates{ + ResourceProviderGeneration: 1, + Aggregates: []string{ + "6d84f6f6-7736-40ff-84d2-7db47f18ea25", + "f11f14bc-6f17-4f0a-b7c2-44b3e685ccf4", + }, +} + func HandleResourceProviderList(t *testing.T, fakeServer th.FakeServer) { fakeServer.Mux.HandleFunc("/resource_providers", func(w http.ResponseWriter, r *http.Request) { @@ -624,3 +644,30 @@ func HandleResourceProviderDeleteTraits(t *testing.T, fakeServer th.FakeServer) w.WriteHeader(http.StatusNoContent) }) } + +func HandleResourceProviderGetAggregatesSuccess(t *testing.T, fakeServer th.FakeServer) { + aggregatesTestURL := fmt.Sprintf("/resource_providers/%s/aggregates", ResourceProviderTestID) + + fakeServer.Mux.HandleFunc(aggregatesTestURL, + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + + fmt.Fprint(w, AggregatesBody) + }) +} + +func HandleResourceProviderGetAggregatesNotFound(t *testing.T, fakeServer th.FakeServer) { + aggregatesTestURL := fmt.Sprintf("/resource_providers/%s/aggregates", AbsentResourceProviderID) + + fakeServer.Mux.HandleFunc(aggregatesTestURL, + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.WriteHeader(http.StatusNotFound) + }) +} diff --git a/openstack/placement/v1/resourceproviders/testing/requests_test.go b/openstack/placement/v1/resourceproviders/testing/requests_test.go index 693b0d80ff..e854b3bac5 100644 --- a/openstack/placement/v1/resourceproviders/testing/requests_test.go +++ b/openstack/placement/v1/resourceproviders/testing/requests_test.go @@ -276,3 +276,24 @@ func TestDeleteResourceProvidersTraits(t *testing.T) { err := resourceproviders.DeleteTraits(context.TODO(), client.ServiceClient(fakeServer), ResourceProviderTestID).ExtractErr() th.AssertNoErr(t, err) } + +func TestGetResourceProviderAggregatesSuccess(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleResourceProviderGetAggregatesSuccess(t, fakeServer) + + actual, err := resourceproviders.GetAggregates(context.TODO(), client.ServiceClient(fakeServer), ResourceProviderTestID).Extract() + th.AssertNoErr(t, err) + th.AssertDeepEquals(t, ExpectedAggregates, *actual) +} + +func TestGetResourceProviderAggregatesNotFound(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleResourceProviderGetAggregatesNotFound(t, fakeServer) + + _, err := resourceproviders.GetAggregates(context.TODO(), client.ServiceClient(fakeServer), AbsentResourceProviderID).Extract() + th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusNotFound)) +} diff --git a/openstack/placement/v1/resourceproviders/urls.go b/openstack/placement/v1/resourceproviders/urls.go index fbc0ff2955..15bc09e7d0 100644 --- a/openstack/placement/v1/resourceproviders/urls.go +++ b/openstack/placement/v1/resourceproviders/urls.go @@ -53,3 +53,7 @@ func getResourceProviderAllocationsURL(client *gophercloud.ServiceClient, resour func getResourceProviderTraitsURL(client *gophercloud.ServiceClient, resourceProviderID string) string { return client.ServiceURL(apiName, resourceProviderID, "traits") } + +func getResourceProviderAggregatesURL(client *gophercloud.ServiceClient, resourceProviderID string) string { + return client.ServiceURL(apiName, resourceProviderID, "aggregates") +} From 5ed0d131372a0f09ebf9ceeb360622ff61fbff77 Mon Sep 17 00:00:00 2001 From: Dominik Danelski Date: Thu, 2 Apr 2026 15:16:25 +0200 Subject: [PATCH 308/353] Implement PUT operation on Placement resource provider aggregates Related: #526 API reference: https://docs.openstack.org/api-ref/placement/#update-resource-provider-aggregates Code reference: https://opendev.org/openstack/placement/src/branch/stable/2026.1/placement/handlers/aggregate.py#L102-L132 Signed-off-by: Dominik Danelski --- .../placement/v1/resourceproviders_test.go | 69 ++++++++ .../placement/v1/resourceproviders/doc.go | 17 ++ .../v1/resourceproviders/requests.go | 32 ++++ .../testing/fixtures_test.go | 150 +++++++++++++++++- .../testing/requests_test.go | 54 +++++++ .../placement/v1/resourceproviders/urls.go | 4 + 6 files changed, 324 insertions(+), 2 deletions(-) diff --git a/internal/acceptance/openstack/placement/v1/resourceproviders_test.go b/internal/acceptance/openstack/placement/v1/resourceproviders_test.go index 61daf45f77..c60f0b93a4 100644 --- a/internal/acceptance/openstack/placement/v1/resourceproviders_test.go +++ b/internal/acceptance/openstack/placement/v1/resourceproviders_test.go @@ -5,6 +5,7 @@ package v1 import ( "context" "net/http" + "slices" "testing" "github.com/gophercloud/gophercloud/v2" @@ -518,3 +519,71 @@ func TestResourceProviderAggregatesGetPreGenerationNegative(t *testing.T) { _, err = resourceproviders.GetAggregates(context.TODO(), client, "00000000-0000-0000-0000-000000000000").Extract() th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusNotFound)) } + +func TestResourceProviderAggregatesUpdateSuccess(t *testing.T) { + // resource_provider_generation is required in the PUT request body from microversion 1.19. + clients.SkipReleasesBelow(t, "stable/ocata") + clients.RequireAdmin(t) + + client, err := clients.NewPlacementV1Client() + th.AssertNoErr(t, err) + + resourceProvider, err := CreateResourceProvider(t, client) + th.AssertNoErr(t, err) + defer DeleteResourceProvider(t, client, resourceProvider.UUID) + + client.Microversion = "1.19" + + before, err := resourceproviders.GetAggregates(context.TODO(), client, resourceProvider.UUID).Extract() + th.AssertNoErr(t, err) + th.AssertEquals(t, true, before.ResourceProviderGeneration != nil) + + updateOpts := resourceproviders.UpdateAggregatesOpts{ + ResourceProviderGeneration: before.ResourceProviderGeneration, + Aggregates: []string{ + "6d84f6f6-7736-40ff-84d2-7db47f18ea25", + "f11f14bc-6f17-4f0a-b7c2-44b3e685ccf4", + }, + } + + _, err = resourceproviders.UpdateAggregates(context.TODO(), client, resourceProvider.UUID, updateOpts).Extract() + th.AssertNoErr(t, err) + + after, err := resourceproviders.GetAggregates(context.TODO(), client, resourceProvider.UUID).Extract() + th.AssertNoErr(t, err) + th.AssertEquals(t, len(updateOpts.Aggregates), len(after.Aggregates)) + + for _, aggregate := range updateOpts.Aggregates { + th.AssertEquals(t, true, slices.Contains(after.Aggregates, aggregate)) + } +} + +func TestResourceProviderAggregatesUpdateNegative(t *testing.T) { + // resource_provider_generation is required in the PUT request body from microversion 1.19. + clients.SkipReleasesBelow(t, "stable/ocata") + clients.RequireAdmin(t) + + client, err := clients.NewPlacementV1Client() + th.AssertNoErr(t, err) + + resourceProvider, err := CreateResourceProvider(t, client) + th.AssertNoErr(t, err) + defer DeleteResourceProvider(t, client, resourceProvider.UUID) + + client.Microversion = "1.19" + + current, err := resourceproviders.GetAggregates(context.TODO(), client, resourceProvider.UUID).Extract() + th.AssertNoErr(t, err) + th.AssertEquals(t, true, current.ResourceProviderGeneration != nil) + wrongGeneration := *current.ResourceProviderGeneration + 100 + + updateOpts := resourceproviders.UpdateAggregatesOpts{ + ResourceProviderGeneration: &wrongGeneration, + Aggregates: []string{ + "6d84f6f6-7736-40ff-84d2-7db47f18ea25", + }, + } + + _, err = resourceproviders.UpdateAggregates(context.TODO(), client, resourceProvider.UUID, updateOpts).Extract() + th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusConflict)) +} diff --git a/openstack/placement/v1/resourceproviders/doc.go b/openstack/placement/v1/resourceproviders/doc.go index d85c2b85cc..10e65ea7f5 100644 --- a/openstack/placement/v1/resourceproviders/doc.go +++ b/openstack/placement/v1/resourceproviders/doc.go @@ -171,5 +171,22 @@ Example to get resource providers aggregates if err != nil { panic(err) } + +Example to update resource providers aggregates + + placementClient.Microversion = "1.1" + + updateOpts := resourceproviders.UpdateAggregatesOpts{ + ResourceProviderGeneration: rp.ResourceProviderGeneration, + Aggregates: []string{ + "6d84f6f6-7736-40ff-84d2-7db47f18ea25", + "f11f14bc-6f17-4f0a-b7c2-44b3e685ccf4", + }, + } + + rp, err = resourceproviders.UpdateAggregates(context.TODO(), placementClient, resourceProviderID, updateOpts).Extract() + if err != nil { + panic(err) + } */ package resourceproviders diff --git a/openstack/placement/v1/resourceproviders/requests.go b/openstack/placement/v1/resourceproviders/requests.go index 94e8e7cf69..1f7eed4af6 100644 --- a/openstack/placement/v1/resourceproviders/requests.go +++ b/openstack/placement/v1/resourceproviders/requests.go @@ -260,6 +260,38 @@ func GetAggregates(ctx context.Context, client *gophercloud.ServiceClient, resou return } +// UpdateAggregatesOptsBuilder allows extensions to add additional parameters to the +// UpdateAggregates request. +type UpdateAggregatesOptsBuilder interface { + ToResourceProviderUpdateAggregatesMap() (map[string]any, error) +} + +// UpdateAggregatesOpts represents options used to update aggregates of a resource provider. +type UpdateAggregatesOpts struct { + // ResourceProviderGeneration is required from microversion 1.19 and later. + ResourceProviderGeneration *int `json:"resource_provider_generation,omitempty"` + Aggregates []string `json:"aggregates"` +} + +// ToResourceProviderUpdateAggregatesMap constructs a request body from UpdateAggregatesOpts. +func (opts UpdateAggregatesOpts) ToResourceProviderUpdateAggregatesMap() (map[string]any, error) { + return gophercloud.BuildRequestBody(opts, "") +} + +func UpdateAggregates(ctx context.Context, client *gophercloud.ServiceClient, resourceProviderID string, opts UpdateAggregatesOptsBuilder) (r GetAggregatesResult) { + b, err := opts.ToResourceProviderUpdateAggregatesMap() + if err != nil { + r.Err = err + return + } + + resp, err := client.Put(ctx, updateResourceProviderAggregatesURL(client, resourceProviderID), b, &r.Body, &gophercloud.RequestOpts{ + OkCodes: []int{200}, + }) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} + // UpdateTraitsOptsBuilder allows extensions to add additional parameters to the // UpdateTraits request. type UpdateTraitsOptsBuilder interface { diff --git a/openstack/placement/v1/resourceproviders/testing/fixtures_test.go b/openstack/placement/v1/resourceproviders/testing/fixtures_test.go index e774bcf507..8b25cd8102 100644 --- a/openstack/placement/v1/resourceproviders/testing/fixtures_test.go +++ b/openstack/placement/v1/resourceproviders/testing/fixtures_test.go @@ -233,7 +233,35 @@ const AggregatesBody = ` } ` -const AbsentResourceProviderID = "non-existent-rp" +const AggregatesBodyPreGeneration = ` +{ + "aggregates": [ + "6d84f6f6-7736-40ff-84d2-7db47f18ea25", + "f11f14bc-6f17-4f0a-b7c2-44b3e685ccf4" + ] +} +` + +const AggregatesUpdateBody = ` +{ + "resource_provider_generation": 1, + "aggregates": [ + "89f68995-4fd8-4f8b-a03e-7d5980762ff2", + "16d0e5f2-7f66-4f32-9040-b09de2f40afd" + ] +} +` + +const AggregatesUpdateBodyPreGeneration = ` +{ + "aggregates": [ + "89f68995-4fd8-4f8b-a03e-7d5980762ff2", + "16d0e5f2-7f66-4f32-9040-b09de2f40afd" + ] +} +` + +const AbsentResourceProviderID = "00000000-0000-0000-0000-000000000000" var ExpectedResourceProvider1 = resourceproviders.ResourceProvider{ Generation: 1, @@ -351,14 +379,41 @@ var ExpectedTraits = resourceproviders.ResourceProviderTraits{ }, } +var expectedAggregatesGeneration = 1 + var ExpectedAggregates = resourceproviders.ResourceProviderAggregates{ - ResourceProviderGeneration: 1, + ResourceProviderGeneration: &expectedAggregatesGeneration, + Aggregates: []string{ + "6d84f6f6-7736-40ff-84d2-7db47f18ea25", + "f11f14bc-6f17-4f0a-b7c2-44b3e685ccf4", + }, +} + +var ExpectedAggregatesPreGeneration = resourceproviders.ResourceProviderAggregates{ + ResourceProviderGeneration: nil, Aggregates: []string{ "6d84f6f6-7736-40ff-84d2-7db47f18ea25", "f11f14bc-6f17-4f0a-b7c2-44b3e685ccf4", }, } +var expectedUpdatedAggregatesGeneration = 1 + +var ExpectedUpdatedAggregates = resourceproviders.ResourceProviderAggregates{ + ResourceProviderGeneration: &expectedUpdatedAggregatesGeneration, + Aggregates: []string{ + "89f68995-4fd8-4f8b-a03e-7d5980762ff2", + "16d0e5f2-7f66-4f32-9040-b09de2f40afd", + }, +} + +var ExpectedUpdatedAggregatesPreGeneration = resourceproviders.ResourceProviderAggregates{ + Aggregates: []string{ + "89f68995-4fd8-4f8b-a03e-7d5980762ff2", + "16d0e5f2-7f66-4f32-9040-b09de2f40afd", + }, +} + func HandleResourceProviderList(t *testing.T, fakeServer th.FakeServer) { fakeServer.Mux.HandleFunc("/resource_providers", func(w http.ResponseWriter, r *http.Request) { @@ -660,6 +715,21 @@ func HandleResourceProviderGetAggregatesSuccess(t *testing.T, fakeServer th.Fake }) } +func HandleResourceProviderGetAggregatesPreGenerationSuccess(t *testing.T, fakeServer th.FakeServer) { + aggregatesTestURL := fmt.Sprintf("/resource_providers/%s/aggregates", ResourceProviderTestID) + + fakeServer.Mux.HandleFunc(aggregatesTestURL, + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + + fmt.Fprint(w, AggregatesBodyPreGeneration) + }) +} + func HandleResourceProviderGetAggregatesNotFound(t *testing.T, fakeServer th.FakeServer) { aggregatesTestURL := fmt.Sprintf("/resource_providers/%s/aggregates", AbsentResourceProviderID) @@ -671,3 +741,79 @@ func HandleResourceProviderGetAggregatesNotFound(t *testing.T, fakeServer th.Fak w.WriteHeader(http.StatusNotFound) }) } + +func HandleResourceProviderUpdateAndGetAggregatesSuccess(t *testing.T, fakeServer th.FakeServer) { + aggregatesTestURL := fmt.Sprintf("/resource_providers/%s/aggregates", ResourceProviderTestID) + + // This handler must cover PUT and GET because the test updates and then fetches on the same path. + body := AggregatesBody + + fakeServer.Mux.HandleFunc(aggregatesTestURL, + func(w http.ResponseWriter, r *http.Request) { + switch r.Method { + case http.MethodGet: + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + fmt.Fprint(w, body) + case http.MethodPut: + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.TestHeader(t, r, "Content-Type", "application/json") + th.TestHeader(t, r, "Accept", "application/json") + th.TestJSONRequest(t, r, AggregatesUpdateBody) + + body = AggregatesUpdateBody + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + fmt.Fprint(w, body) + default: + w.WriteHeader(http.StatusMethodNotAllowed) + } + }) +} + +func HandleResourceProviderUpdateAndGetAggregatesPreGenerationSuccess(t *testing.T, fakeServer th.FakeServer) { + aggregatesTestURL := fmt.Sprintf("/resource_providers/%s/aggregates", ResourceProviderTestID) + + // Pre-generation variant of the same update-then-fetch flow on a shared endpoint. + body := AggregatesBodyPreGeneration + + fakeServer.Mux.HandleFunc(aggregatesTestURL, + func(w http.ResponseWriter, r *http.Request) { + switch r.Method { + case http.MethodGet: + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + fmt.Fprint(w, body) + case http.MethodPut: + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.TestHeader(t, r, "Content-Type", "application/json") + th.TestHeader(t, r, "Accept", "application/json") + th.TestJSONRequest(t, r, AggregatesUpdateBodyPreGeneration) + + body = AggregatesUpdateBodyPreGeneration + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + fmt.Fprint(w, body) + default: + w.WriteHeader(http.StatusMethodNotAllowed) + } + }) +} + +func HandleResourceProviderUpdateAggregatesConflict(t *testing.T, fakeServer th.FakeServer) { + aggregatesTestURL := fmt.Sprintf("/resource_providers/%s/aggregates", ResourceProviderTestID) + + fakeServer.Mux.HandleFunc(aggregatesTestURL, + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "PUT") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.WriteHeader(http.StatusConflict) + }) +} diff --git a/openstack/placement/v1/resourceproviders/testing/requests_test.go b/openstack/placement/v1/resourceproviders/testing/requests_test.go index e854b3bac5..ccdef63c6a 100644 --- a/openstack/placement/v1/resourceproviders/testing/requests_test.go +++ b/openstack/placement/v1/resourceproviders/testing/requests_test.go @@ -288,6 +288,17 @@ func TestGetResourceProviderAggregatesSuccess(t *testing.T) { th.AssertDeepEquals(t, ExpectedAggregates, *actual) } +func TestGetResourceProviderAggregatesPreGenerationSuccess(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleResourceProviderGetAggregatesPreGenerationSuccess(t, fakeServer) + + actual, err := resourceproviders.GetAggregates(context.TODO(), client.ServiceClient(fakeServer), ResourceProviderTestID).Extract() + th.AssertNoErr(t, err) + th.AssertDeepEquals(t, ExpectedAggregatesPreGeneration, *actual) +} + func TestGetResourceProviderAggregatesNotFound(t *testing.T) { fakeServer := th.SetupHTTP() defer fakeServer.Teardown() @@ -297,3 +308,46 @@ func TestGetResourceProviderAggregatesNotFound(t *testing.T) { _, err := resourceproviders.GetAggregates(context.TODO(), client.ServiceClient(fakeServer), AbsentResourceProviderID).Extract() th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusNotFound)) } + +func TestUpdateResourceProviderAggregatesSuccess(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleResourceProviderUpdateAndGetAggregatesSuccess(t, fakeServer) + + updateOpts := resourceproviders.UpdateAggregatesOpts(ExpectedUpdatedAggregates) + _, err := resourceproviders.UpdateAggregates(context.TODO(), client.ServiceClient(fakeServer), ResourceProviderTestID, updateOpts).Extract() + th.AssertNoErr(t, err) + + actual, err := resourceproviders.GetAggregates(context.TODO(), client.ServiceClient(fakeServer), ResourceProviderTestID).Extract() + th.AssertNoErr(t, err) + th.AssertDeepEquals(t, ExpectedUpdatedAggregates, *actual) +} + +func TestUpdateResourceProviderAggregatesPreGenerationSuccess(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleResourceProviderUpdateAndGetAggregatesPreGenerationSuccess(t, fakeServer) + + updateOpts := resourceproviders.UpdateAggregatesOpts{ + Aggregates: ExpectedUpdatedAggregatesPreGeneration.Aggregates, + } + _, err := resourceproviders.UpdateAggregates(context.TODO(), client.ServiceClient(fakeServer), ResourceProviderTestID, updateOpts).Extract() + th.AssertNoErr(t, err) + + actual, err := resourceproviders.GetAggregates(context.TODO(), client.ServiceClient(fakeServer), ResourceProviderTestID).Extract() + th.AssertNoErr(t, err) + th.AssertDeepEquals(t, ExpectedUpdatedAggregatesPreGeneration, *actual) +} + +func TestUpdateResourceProviderAggregatesConflict(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleResourceProviderUpdateAggregatesConflict(t, fakeServer) + + updateOpts := resourceproviders.UpdateAggregatesOpts(ExpectedUpdatedAggregates) + _, err := resourceproviders.UpdateAggregates(context.TODO(), client.ServiceClient(fakeServer), ResourceProviderTestID, updateOpts).Extract() + th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusConflict)) +} diff --git a/openstack/placement/v1/resourceproviders/urls.go b/openstack/placement/v1/resourceproviders/urls.go index 15bc09e7d0..b55426d4a7 100644 --- a/openstack/placement/v1/resourceproviders/urls.go +++ b/openstack/placement/v1/resourceproviders/urls.go @@ -57,3 +57,7 @@ func getResourceProviderTraitsURL(client *gophercloud.ServiceClient, resourcePro func getResourceProviderAggregatesURL(client *gophercloud.ServiceClient, resourceProviderID string) string { return client.ServiceURL(apiName, resourceProviderID, "aggregates") } + +func updateResourceProviderAggregatesURL(client *gophercloud.ServiceClient, resourceProviderID string) string { + return client.ServiceURL(apiName, resourceProviderID, "aggregates") +} From 436937cd74132a7b6c3636bfce0aeb24be6733f7 Mon Sep 17 00:00:00 2001 From: Dominik Danelski Date: Thu, 9 Apr 2026 22:45:33 +0200 Subject: [PATCH 309/353] Properly handle pre-1.19 in resourceproviders aggregates We don't provide resource provider's generation in request nor do we get it back in response. The original tests got it slightly wrong; fix it. Automatically correct the request if user wrongly provides generation in opts for pre-1.19. Signed-off-by: Dominik Danelski --- .../placement/v1/resourceproviders_test.go | 69 +++++++++++++++++++ .../placement/v1/resourceproviders/doc.go | 7 +- .../v1/resourceproviders/requests.go | 6 +- .../testing/fixtures_test.go | 12 +++- .../testing/requests_test.go | 40 +++++++++-- .../placement/v1/resourceproviders/util.go | 14 ++++ 6 files changed, 138 insertions(+), 10 deletions(-) create mode 100644 openstack/placement/v1/resourceproviders/util.go diff --git a/internal/acceptance/openstack/placement/v1/resourceproviders_test.go b/internal/acceptance/openstack/placement/v1/resourceproviders_test.go index c60f0b93a4..277dd5d38b 100644 --- a/internal/acceptance/openstack/placement/v1/resourceproviders_test.go +++ b/internal/acceptance/openstack/placement/v1/resourceproviders_test.go @@ -587,3 +587,72 @@ func TestResourceProviderAggregatesUpdateNegative(t *testing.T) { _, err = resourceproviders.UpdateAggregates(context.TODO(), client, resourceProvider.UUID, updateOpts).Extract() th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusConflict)) } + +func TestResourceProviderAggregatesUpdatePreGenerationSuccess(t *testing.T) { + // Before microversion 1.19, the PUT request body is just a list of aggregate UUIDs. + clients.SkipReleasesBelow(t, "stable/ocata") + clients.RequireAdmin(t) + + client, err := clients.NewPlacementV1Client() + th.AssertNoErr(t, err) + + resourceProvider, err := CreateResourceProvider(t, client) + th.AssertNoErr(t, err) + defer DeleteResourceProvider(t, client, resourceProvider.UUID) + + client.Microversion = "1.1" + + updateOpts := resourceproviders.UpdateAggregatesOpts{ + Aggregates: []string{ + "6d84f6f6-7736-40ff-84d2-7db47f18ea25", + "f11f14bc-6f17-4f0a-b7c2-44b3e685ccf4", + }, + } + + _, err = resourceproviders.UpdateAggregates(context.TODO(), client, resourceProvider.UUID, updateOpts).Extract() + th.AssertNoErr(t, err) + + after, err := resourceproviders.GetAggregates(context.TODO(), client, resourceProvider.UUID).Extract() + th.AssertNoErr(t, err) + th.AssertEquals(t, len(updateOpts.Aggregates), len(after.Aggregates)) + + for _, aggregate := range updateOpts.Aggregates { + th.AssertEquals(t, true, slices.Contains(after.Aggregates, aggregate)) + } +} + +func TestResourceProviderAggregatesUpdatePreGenerationWithGenerationSuccess(t *testing.T) { + // Before microversion 1.19, ResourceProviderGeneration in opts is silently stripped from + // the request body, so the operation must succeed even when the caller supplies it. + clients.SkipReleasesBelow(t, "stable/ocata") + clients.RequireAdmin(t) + + client, err := clients.NewPlacementV1Client() + th.AssertNoErr(t, err) + + resourceProvider, err := CreateResourceProvider(t, client) + th.AssertNoErr(t, err) + defer DeleteResourceProvider(t, client, resourceProvider.UUID) + + client.Microversion = "1.1" + + gen := 1 + updateOpts := resourceproviders.UpdateAggregatesOpts{ + ResourceProviderGeneration: &gen, + Aggregates: []string{ + "6d84f6f6-7736-40ff-84d2-7db47f18ea25", + "f11f14bc-6f17-4f0a-b7c2-44b3e685ccf4", + }, + } + + _, err = resourceproviders.UpdateAggregates(context.TODO(), client, resourceProvider.UUID, updateOpts).Extract() + th.AssertNoErr(t, err) + + after, err := resourceproviders.GetAggregates(context.TODO(), client, resourceProvider.UUID).Extract() + th.AssertNoErr(t, err) + th.AssertEquals(t, len(updateOpts.Aggregates), len(after.Aggregates)) + + for _, aggregate := range updateOpts.Aggregates { + th.AssertEquals(t, true, slices.Contains(after.Aggregates, aggregate)) + } +} diff --git a/openstack/placement/v1/resourceproviders/doc.go b/openstack/placement/v1/resourceproviders/doc.go index 10e65ea7f5..d0a6caa515 100644 --- a/openstack/placement/v1/resourceproviders/doc.go +++ b/openstack/placement/v1/resourceproviders/doc.go @@ -172,9 +172,12 @@ Example to get resource providers aggregates panic(err) } -Example to update resource providers aggregates +# Example to update resource providers aggregates - placementClient.Microversion = "1.1" +For microversion 1.18 and earlier the ResourceProviderGeneration is optional and would be ignored if provided, +as it was not supported pre-1.19. For greater safety, it is recommended to use the newer microversion. + + placementClient.Microversion = "1.19" updateOpts := resourceproviders.UpdateAggregatesOpts{ ResourceProviderGeneration: rp.ResourceProviderGeneration, diff --git a/openstack/placement/v1/resourceproviders/requests.go b/openstack/placement/v1/resourceproviders/requests.go index 1f7eed4af6..f71bfe8519 100644 --- a/openstack/placement/v1/resourceproviders/requests.go +++ b/openstack/placement/v1/resourceproviders/requests.go @@ -285,7 +285,11 @@ func UpdateAggregates(ctx context.Context, client *gophercloud.ServiceClient, re return } - resp, err := client.Put(ctx, updateResourceProviderAggregatesURL(client, resourceProviderID), b, &r.Body, &gophercloud.RequestOpts{ + var body any = b + if useGenerations := microversionAtLeast(client, 1, 19); !useGenerations { + body = b["aggregates"] + } + resp, err := client.Put(ctx, updateResourceProviderAggregatesURL(client, resourceProviderID), body, &r.Body, &gophercloud.RequestOpts{ OkCodes: []int{200}, }) _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) diff --git a/openstack/placement/v1/resourceproviders/testing/fixtures_test.go b/openstack/placement/v1/resourceproviders/testing/fixtures_test.go index 8b25cd8102..45faff6427 100644 --- a/openstack/placement/v1/resourceproviders/testing/fixtures_test.go +++ b/openstack/placement/v1/resourceproviders/testing/fixtures_test.go @@ -252,7 +252,13 @@ const AggregatesUpdateBody = ` } ` -const AggregatesUpdateBodyPreGeneration = ` +// AggregatesUpdateRequestPreGeneration is the raw JSON array sent as the PUT request body +// for microversions < 1.19, where the payload is just a list of aggregate UUIDs. +const AggregatesUpdateRequestPreGeneration = `["89f68995-4fd8-4f8b-a03e-7d5980762ff2","16d0e5f2-7f66-4f32-9040-b09de2f40afd"]` + +// AggregatesUpdateBodyWithoutGeneration is the pre-1.19 server response body for an aggregates update. +// Unlike the request, the response is not flat. +const AggregatesUpdateBodyWithoutGeneration = ` { "aggregates": [ "89f68995-4fd8-4f8b-a03e-7d5980762ff2", @@ -793,9 +799,9 @@ func HandleResourceProviderUpdateAndGetAggregatesPreGenerationSuccess(t *testing th.TestHeader(t, r, "X-Auth-Token", client.TokenID) th.TestHeader(t, r, "Content-Type", "application/json") th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, AggregatesUpdateBodyPreGeneration) + th.TestJSONRequest(t, r, AggregatesUpdateRequestPreGeneration) - body = AggregatesUpdateBodyPreGeneration + body = AggregatesUpdateBodyWithoutGeneration w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) diff --git a/openstack/placement/v1/resourceproviders/testing/requests_test.go b/openstack/placement/v1/resourceproviders/testing/requests_test.go index ccdef63c6a..36909fb3df 100644 --- a/openstack/placement/v1/resourceproviders/testing/requests_test.go +++ b/openstack/placement/v1/resourceproviders/testing/requests_test.go @@ -315,11 +315,14 @@ func TestUpdateResourceProviderAggregatesSuccess(t *testing.T) { HandleResourceProviderUpdateAndGetAggregatesSuccess(t, fakeServer) + sc := client.ServiceClient(fakeServer) + sc.Microversion = "1.19" + updateOpts := resourceproviders.UpdateAggregatesOpts(ExpectedUpdatedAggregates) - _, err := resourceproviders.UpdateAggregates(context.TODO(), client.ServiceClient(fakeServer), ResourceProviderTestID, updateOpts).Extract() + _, err := resourceproviders.UpdateAggregates(context.TODO(), sc, ResourceProviderTestID, updateOpts).Extract() th.AssertNoErr(t, err) - actual, err := resourceproviders.GetAggregates(context.TODO(), client.ServiceClient(fakeServer), ResourceProviderTestID).Extract() + actual, err := resourceproviders.GetAggregates(context.TODO(), sc, ResourceProviderTestID).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, ExpectedUpdatedAggregates, *actual) } @@ -330,13 +333,42 @@ func TestUpdateResourceProviderAggregatesPreGenerationSuccess(t *testing.T) { HandleResourceProviderUpdateAndGetAggregatesPreGenerationSuccess(t, fakeServer) + sc := client.ServiceClient(fakeServer) + sc.Microversion = "1.10" + updateOpts := resourceproviders.UpdateAggregatesOpts{ Aggregates: ExpectedUpdatedAggregatesPreGeneration.Aggregates, } - _, err := resourceproviders.UpdateAggregates(context.TODO(), client.ServiceClient(fakeServer), ResourceProviderTestID, updateOpts).Extract() + _, err := resourceproviders.UpdateAggregates(context.TODO(), sc, ResourceProviderTestID, updateOpts).Extract() th.AssertNoErr(t, err) - actual, err := resourceproviders.GetAggregates(context.TODO(), client.ServiceClient(fakeServer), ResourceProviderTestID).Extract() + actual, err := resourceproviders.GetAggregates(context.TODO(), sc, ResourceProviderTestID).Extract() + th.AssertNoErr(t, err) + th.AssertDeepEquals(t, ExpectedUpdatedAggregatesPreGeneration, *actual) +} + +// TestUpdateResourceProviderAggregatesPreGenerationWithGenerationInOptsSuccess validates that +// when the microversion is < 1.19 but the caller supplies ResourceProviderGeneration in opts, +// the generation field is stripped from the request body and the operation succeeds. +func TestUpdateResourceProviderAggregatesPreGenerationWithGenerationInOptsSuccess(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + // Reuse the same handler: it validates the request body contains only aggregates (no generation). + HandleResourceProviderUpdateAndGetAggregatesPreGenerationSuccess(t, fakeServer) + + sc := client.ServiceClient(fakeServer) + sc.Microversion = "1.10" + + gen := 1 + updateOpts := resourceproviders.UpdateAggregatesOpts{ + ResourceProviderGeneration: &gen, + Aggregates: ExpectedUpdatedAggregatesPreGeneration.Aggregates, + } + _, err := resourceproviders.UpdateAggregates(context.TODO(), sc, ResourceProviderTestID, updateOpts).Extract() + th.AssertNoErr(t, err) + + actual, err := resourceproviders.GetAggregates(context.TODO(), sc, ResourceProviderTestID).Extract() th.AssertNoErr(t, err) th.AssertDeepEquals(t, ExpectedUpdatedAggregatesPreGeneration, *actual) } diff --git a/openstack/placement/v1/resourceproviders/util.go b/openstack/placement/v1/resourceproviders/util.go new file mode 100644 index 0000000000..ecddaed8ea --- /dev/null +++ b/openstack/placement/v1/resourceproviders/util.go @@ -0,0 +1,14 @@ +package resourceproviders + +import ( + "github.com/gophercloud/gophercloud/v2" + "github.com/gophercloud/gophercloud/v2/openstack/utils" +) + +func microversionAtLeast(client *gophercloud.ServiceClient, major, minor int) bool { + M, m, err := utils.ParseMicroversion(client.Microversion) + if err != nil { + return false + } + return M > major || (M == major && m >= minor) +} From 9faac1a2d683c6a0ec079e224774c51a59690654 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Fri, 10 Apr 2026 13:37:01 +0100 Subject: [PATCH 310/353] Address review comments from resourceprovider aggregates PR Per comments [1], remove an unnecessary helper and tweak some tests. [1] https://github.com/gophercloud/gophercloud/pull/3709 Signed-off-by: Stephen Finucane --- .../placement/v1/resourceproviders_test.go | 48 ++++--------------- .../v1/resourceproviders/requests.go | 13 ++++- .../placement/v1/resourceproviders/util.go | 14 ------ 3 files changed, 21 insertions(+), 54 deletions(-) delete mode 100644 openstack/placement/v1/resourceproviders/util.go diff --git a/internal/acceptance/openstack/placement/v1/resourceproviders_test.go b/internal/acceptance/openstack/placement/v1/resourceproviders_test.go index 277dd5d38b..3babbf9006 100644 --- a/internal/acceptance/openstack/placement/v1/resourceproviders_test.go +++ b/internal/acceptance/openstack/placement/v1/resourceproviders_test.go @@ -453,47 +453,33 @@ func TestResourceProviderAllocations(t *testing.T) { tools.PrintResource(t, usage) } -func TestResourceProviderAggregatesGetSuccess(t *testing.T) { - // Resource_provider_generation in the aggregates response was introduced in microversion 1.19. +func TestResourceProviderAggregates(t *testing.T) { clients.SkipReleasesBelow(t, "stable/ocata") clients.RequireAdmin(t) client, err := clients.NewPlacementV1Client() th.AssertNoErr(t, err) + // first create new resource provider resourceProvider, err := CreateResourceProvider(t, client) th.AssertNoErr(t, err) defer DeleteResourceProvider(t, client, resourceProvider.UUID) + // now get the aggregates for same client.Microversion = "1.19" - aggregates, err := resourceproviders.GetAggregates(context.TODO(), client, resourceProvider.UUID).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, true, aggregates.ResourceProviderGeneration != nil) -} - -func TestResourceProviderAggregatesGetPreGenerationSuccess(t *testing.T) { - // Resource provider aggregates operations were introduced in microversion 1.1. - clients.SkipReleasesBelow(t, "stable/ocata") - clients.RequireAdmin(t) - - client, err := clients.NewPlacementV1Client() - th.AssertNoErr(t, err) - - resourceProvider, err := CreateResourceProvider(t, client) - th.AssertNoErr(t, err) - defer DeleteResourceProvider(t, client, resourceProvider.UUID) + // ensure that we handle older microversions where generation is missing client.Microversion = "1.1" - - aggregates, err := resourceproviders.GetAggregates(context.TODO(), client, resourceProvider.UUID).Extract() + aggregates, err = resourceproviders.GetAggregates(context.TODO(), client, resourceProvider.UUID).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, 0, len(aggregates.Aggregates)) th.AssertDeepEquals(t, (*int)(nil), aggregates.ResourceProviderGeneration) } -func TestResourceProviderAggregatesGetNegative(t *testing.T) { - // Resource_provider_generation in the aggregates response was introduced in microversion 1.19. +func TestResourceProviderAggregatesNotFound(t *testing.T) { clients.SkipReleasesBelow(t, "stable/ocata") clients.RequireAdmin(t) @@ -501,27 +487,15 @@ func TestResourceProviderAggregatesGetNegative(t *testing.T) { th.AssertNoErr(t, err) client.Microversion = "1.19" - _, err = resourceproviders.GetAggregates(context.TODO(), client, "00000000-0000-0000-0000-000000000000").Extract() th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusNotFound)) -} - -func TestResourceProviderAggregatesGetPreGenerationNegative(t *testing.T) { - // Resource provider aggregates operations were introduced in microversion 1.1. - clients.SkipReleasesBelow(t, "stable/ocata") - clients.RequireAdmin(t) - - client, err := clients.NewPlacementV1Client() - th.AssertNoErr(t, err) client.Microversion = "1.1" - _, err = resourceproviders.GetAggregates(context.TODO(), client, "00000000-0000-0000-0000-000000000000").Extract() th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusNotFound)) } -func TestResourceProviderAggregatesUpdateSuccess(t *testing.T) { - // resource_provider_generation is required in the PUT request body from microversion 1.19. +func TestResourceProviderUpdateAggregates(t *testing.T) { clients.SkipReleasesBelow(t, "stable/ocata") clients.RequireAdmin(t) @@ -558,8 +532,7 @@ func TestResourceProviderAggregatesUpdateSuccess(t *testing.T) { } } -func TestResourceProviderAggregatesUpdateNegative(t *testing.T) { - // resource_provider_generation is required in the PUT request body from microversion 1.19. +func TestResourceProviderUpdateAggregateMismatch(t *testing.T) { clients.SkipReleasesBelow(t, "stable/ocata") clients.RequireAdmin(t) @@ -588,8 +561,7 @@ func TestResourceProviderAggregatesUpdateNegative(t *testing.T) { th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusConflict)) } -func TestResourceProviderAggregatesUpdatePreGenerationSuccess(t *testing.T) { - // Before microversion 1.19, the PUT request body is just a list of aggregate UUIDs. +func TestResourceProviderUpdateAggregatesPreGeneration(t *testing.T) { clients.SkipReleasesBelow(t, "stable/ocata") clients.RequireAdmin(t) @@ -621,7 +593,7 @@ func TestResourceProviderAggregatesUpdatePreGenerationSuccess(t *testing.T) { } } -func TestResourceProviderAggregatesUpdatePreGenerationWithGenerationSuccess(t *testing.T) { +func TestResourceProviderUpdateAggregatesPreGenerationWithGenerationSuccess(t *testing.T) { // Before microversion 1.19, ResourceProviderGeneration in opts is silently stripped from // the request body, so the operation must succeed even when the caller supplies it. clients.SkipReleasesBelow(t, "stable/ocata") diff --git a/openstack/placement/v1/resourceproviders/requests.go b/openstack/placement/v1/resourceproviders/requests.go index f71bfe8519..aecc975060 100644 --- a/openstack/placement/v1/resourceproviders/requests.go +++ b/openstack/placement/v1/resourceproviders/requests.go @@ -4,6 +4,7 @@ import ( "context" "github.com/gophercloud/gophercloud/v2" + "github.com/gophercloud/gophercloud/v2/openstack/utils" "github.com/gophercloud/gophercloud/v2/pagination" ) @@ -286,8 +287,16 @@ func UpdateAggregates(ctx context.Context, client *gophercloud.ServiceClient, re } var body any = b - if useGenerations := microversionAtLeast(client, 1, 19); !useGenerations { - body = b["aggregates"] + if client.Microversion != "" { + _, minor, err := utils.ParseMicroversion(client.Microversion) + if err != nil { + r.Err = err + return + } + // In microversions prior to 1.19, the body was not enveloped. + if minor < 19 { + body = b["aggregates"] + } } resp, err := client.Put(ctx, updateResourceProviderAggregatesURL(client, resourceProviderID), body, &r.Body, &gophercloud.RequestOpts{ OkCodes: []int{200}, diff --git a/openstack/placement/v1/resourceproviders/util.go b/openstack/placement/v1/resourceproviders/util.go deleted file mode 100644 index ecddaed8ea..0000000000 --- a/openstack/placement/v1/resourceproviders/util.go +++ /dev/null @@ -1,14 +0,0 @@ -package resourceproviders - -import ( - "github.com/gophercloud/gophercloud/v2" - "github.com/gophercloud/gophercloud/v2/openstack/utils" -) - -func microversionAtLeast(client *gophercloud.ServiceClient, major, minor int) bool { - M, m, err := utils.ParseMicroversion(client.Microversion) - if err != nil { - return false - } - return M > major || (M == major && m >= minor) -} From 44169d76e12fe938490a48f1ad7d3b231a7f2fd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Andr=C3=A9?= Date: Fri, 10 Apr 2026 14:19:41 +0200 Subject: [PATCH 311/353] Prepare v2.12.0 --- CHANGELOG.md | 26 ++++++++++++++++++++++++++ provider_client.go | 2 +- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 388e8c50b9..5d0a140d03 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,29 @@ +## v2.12.0 (2026-04-10) + +* [GH-3653](https://github.com/gophercloud/gophercloud/pull/3653) [v2] Fix clouds.yaml search path to use XDG convention on all platforms +* [GH-3660](https://github.com/gophercloud/gophercloud/pull/3660) [v2] Use jammy amphora in octavia epoxy job +* [GH-3670](https://github.com/gophercloud/gophercloud/pull/3670) [v2] Implement READ operations on Placement traits +* [GH-3673](https://github.com/gophercloud/gophercloud/pull/3673) [v2] Github action fixes +* [GH-3674](https://github.com/gophercloud/gophercloud/pull/3674) [v2] Update acceptance README to remove mentions of Packstack +* [GH-3678](https://github.com/gophercloud/gophercloud/pull/3678) [v2] Implement CREATE/UPDATE operation on Placement traits +* [GH-3679](https://github.com/gophercloud/gophercloud/pull/3679) [v2] Implement DELETE operations on Placement traits +* [GH-3682](https://github.com/gophercloud/gophercloud/pull/3682) [v2] Implement resource_classes GET operations +* [GH-3683](https://github.com/gophercloud/gophercloud/pull/3683) [v2] Implement resource classes CREATE operations +* [GH-3684](https://github.com/gophercloud/gophercloud/pull/3684) [v2] Implement resource classes DELETE operation +* [GH-3690](https://github.com/gophercloud/gophercloud/pull/3690) [v2] Add metric-storage (Aetos) v1 service support +* [GH-3691](https://github.com/gophercloud/gophercloud/pull/3691) [v2] Implement GET/UPDATE/DELETE operations on Placement resource providers inventories +* [GH-3692](https://github.com/gophercloud/gophercloud/pull/3692) [v2] Fix TestCreateTempURL flaky test by removing hardcoded port dependency +* [GH-3695](https://github.com/gophercloud/gophercloud/pull/3695) [v2] Remove legacy workflows +* [GH-3698](https://github.com/gophercloud/gophercloud/pull/3698) build(deps): bump golang.org/x/crypto from 0.33.0 to 0.49.0 +* [GH-3699](https://github.com/gophercloud/gophercloud/pull/3699) build(deps): bump actions/setup-go from 6.3.0 to 6.4.0 +* [GH-3700](https://github.com/gophercloud/gophercloud/pull/3700) build(deps): bump github/codeql-action from 4.34.1 to 4.35.1 +* [GH-3703](https://github.com/gophercloud/gophercloud/pull/3703) [v2] CI: prefer github mirrors whenever possible +* [GH-3708](https://github.com/gophercloud/gophercloud/pull/3708) [v2] Implement Placement allocationcandidates + +## v2.11.1 (2026-03-10) + +* [GH-3648](https://github.com/gophercloud/gophercloud/pull/3648) [v2] Do not specify go patch version + ## v2.11.0 (2026-03-04) * [GH-3602](https://github.com/gophercloud/gophercloud/pull/3602) [v2] Add PCIAddress field to baremetal InterfaceType diff --git a/provider_client.go b/provider_client.go index 26e2d8874c..fda42d92e3 100644 --- a/provider_client.go +++ b/provider_client.go @@ -14,7 +14,7 @@ import ( // DefaultUserAgent is the default User-Agent string set in the request header. const ( - DefaultUserAgent = "gophercloud/v2.11.0" + DefaultUserAgent = "gophercloud/v2.12.0" DefaultMaxBackoffRetries = 60 ) From 106640ba8f4aabeaf176f186afe10962a3098d4a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 17 Apr 2026 09:17:50 +0000 Subject: [PATCH 312/353] build(deps): bump golang.org/x/crypto from 0.49.0 to 0.50.0 Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.49.0 to 0.50.0. - [Commits](https://github.com/golang/crypto/compare/v0.49.0...v0.50.0) --- updated-dependencies: - dependency-name: golang.org/x/crypto dependency-version: 0.50.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 4 ++-- go.sum | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/go.mod b/go.mod index 7460f9edd8..006d43c5ee 100644 --- a/go.mod +++ b/go.mod @@ -3,8 +3,8 @@ module github.com/gophercloud/gophercloud/v2 go 1.25.0 require ( - golang.org/x/crypto v0.49.0 + golang.org/x/crypto v0.50.0 gopkg.in/yaml.v2 v2.4.0 ) -require golang.org/x/sys v0.42.0 // indirect +require golang.org/x/sys v0.43.0 // indirect diff --git a/go.sum b/go.sum index ce4a08f52d..9bf6d4b97d 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,9 @@ -golang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4= -golang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA= -golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= -golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= -golang.org/x/term v0.41.0 h1:QCgPso/Q3RTJx2Th4bDLqML4W6iJiaXFq2/ftQF13YU= -golang.org/x/term v0.41.0/go.mod h1:3pfBgksrReYfZ5lvYM0kSO0LIkAl4Yl2bXOkKP7Ec2A= +golang.org/x/crypto v0.50.0 h1:zO47/JPrL6vsNkINmLoo/PH1gcxpls50DNogFvB5ZGI= +golang.org/x/crypto v0.50.0/go.mod h1:3muZ7vA7PBCE6xgPX7nkzzjiUq87kRItoJQM1Yo8S+Q= +golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI= +golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/term v0.42.0 h1:UiKe+zDFmJobeJ5ggPwOshJIVt6/Ft0rcfrXZDLWAWY= +golang.org/x/term v0.42.0/go.mod h1:Dq/D+snpsbazcBG5+F9Q1n2rXV8Ma+71xEjTRufARgY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= From 361aef226100b4feeef7e7df61fec4e13a1f1747 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 17 Apr 2026 09:19:23 +0000 Subject: [PATCH 313/353] build(deps): bump actions/upload-artifact from 7.0.0 to 7.0.1 Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 7.0.0 to 7.0.1. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/bbbca2ddaa5d8feaa63e36b76fdaad77386f024f...043fb46d1a93c77aae656e7c1c64a875d1fc6a0a) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-version: 7.0.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/functional-baremetal.yaml | 2 +- .github/workflows/functional-basic.yaml | 2 +- .github/workflows/functional-blockstorage.yaml | 2 +- .github/workflows/functional-compute.yaml | 2 +- .github/workflows/functional-containerinfra.yaml | 2 +- .github/workflows/functional-dns.yaml | 2 +- .github/workflows/functional-fwaas_v2.yaml | 2 +- .github/workflows/functional-identity.yaml | 2 +- .github/workflows/functional-image.yaml | 2 +- .github/workflows/functional-keymanager.yaml | 2 +- .github/workflows/functional-loadbalancer.yaml | 2 +- .github/workflows/functional-messaging.yaml | 2 +- .github/workflows/functional-metric.yaml | 2 +- .github/workflows/functional-networking.yaml | 2 +- .github/workflows/functional-objectstorage.yaml | 2 +- .github/workflows/functional-orchestration.yaml | 2 +- .github/workflows/functional-placement.yaml | 2 +- .github/workflows/functional-sharedfilesystems.yaml | 2 +- .github/workflows/functional-workflow.yaml | 2 +- .github/workflows/semver.yaml | 2 +- 20 files changed, 20 insertions(+), 20 deletions(-) diff --git a/.github/workflows/functional-baremetal.yaml b/.github/workflows/functional-baremetal.yaml index c83ff45d33..75e126f4a1 100644 --- a/.github/workflows/functional-baremetal.yaml +++ b/.github/workflows/functional-baremetal.yaml @@ -93,7 +93,7 @@ jobs: if: failure() - name: Upload logs artifacts on failure if: failure() - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: functional-baremetal-${{ matrix.name }}-${{ github.run_id }} path: /tmp/devstack-logs/* diff --git a/.github/workflows/functional-basic.yaml b/.github/workflows/functional-basic.yaml index cd1b0f23d3..3943c3a9f0 100644 --- a/.github/workflows/functional-basic.yaml +++ b/.github/workflows/functional-basic.yaml @@ -54,7 +54,7 @@ jobs: if: failure() - name: Upload logs artifacts on failure if: failure() - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: functional-basic-${{ matrix.name }}-${{ github.run_id }} path: /tmp/devstack-logs/* diff --git a/.github/workflows/functional-blockstorage.yaml b/.github/workflows/functional-blockstorage.yaml index 94c226289e..f99da523fb 100644 --- a/.github/workflows/functional-blockstorage.yaml +++ b/.github/workflows/functional-blockstorage.yaml @@ -61,7 +61,7 @@ jobs: if: failure() - name: Upload logs artifacts on failure if: failure() - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: functional-blockstorage-${{ matrix.name }}-${{ github.run_id }} path: /tmp/devstack-logs/* diff --git a/.github/workflows/functional-compute.yaml b/.github/workflows/functional-compute.yaml index 2bc27e64f4..4459b48aa0 100644 --- a/.github/workflows/functional-compute.yaml +++ b/.github/workflows/functional-compute.yaml @@ -61,7 +61,7 @@ jobs: if: failure() - name: Upload logs artifacts on failure if: failure() - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: functional-compute-${{ matrix.name }}-${{ github.run_id }} path: /tmp/devstack-logs/* diff --git a/.github/workflows/functional-containerinfra.yaml b/.github/workflows/functional-containerinfra.yaml index 2dd0cd6674..6565ec5ca4 100644 --- a/.github/workflows/functional-containerinfra.yaml +++ b/.github/workflows/functional-containerinfra.yaml @@ -76,7 +76,7 @@ jobs: if: failure() - name: Upload logs artifacts on failure if: failure() - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: functional-containerinfra-${{ matrix.name }}-${{ github.run_id }} path: /tmp/devstack-logs/* diff --git a/.github/workflows/functional-dns.yaml b/.github/workflows/functional-dns.yaml index d3076cd680..045824bff1 100644 --- a/.github/workflows/functional-dns.yaml +++ b/.github/workflows/functional-dns.yaml @@ -63,7 +63,7 @@ jobs: if: failure() - name: Upload logs artifacts on failure if: failure() - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: functional-dns-${{ matrix.name }}-${{ github.run_id }} path: /tmp/devstack-logs/* diff --git a/.github/workflows/functional-fwaas_v2.yaml b/.github/workflows/functional-fwaas_v2.yaml index c09c0e7e9a..acbb63c9d0 100644 --- a/.github/workflows/functional-fwaas_v2.yaml +++ b/.github/workflows/functional-fwaas_v2.yaml @@ -82,7 +82,7 @@ jobs: if: failure() - name: Upload logs artifacts on failure if: failure() - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: functional-fwaas_v2-${{ matrix.name }}-${{ github.run_id }} path: /tmp/devstack-logs/* diff --git a/.github/workflows/functional-identity.yaml b/.github/workflows/functional-identity.yaml index 4c9b1de272..86627541cb 100644 --- a/.github/workflows/functional-identity.yaml +++ b/.github/workflows/functional-identity.yaml @@ -59,7 +59,7 @@ jobs: if: failure() - name: Upload logs artifacts on failure if: failure() - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: functional-identity-${{ matrix.name }}-${{ github.run_id }} path: /tmp/devstack-logs/* diff --git a/.github/workflows/functional-image.yaml b/.github/workflows/functional-image.yaml index 7c33bad9b4..6ef80cc4be 100644 --- a/.github/workflows/functional-image.yaml +++ b/.github/workflows/functional-image.yaml @@ -59,7 +59,7 @@ jobs: if: failure() - name: Upload logs artifacts on failure if: failure() - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: functional-image-${{ matrix.name }}-${{ github.run_id }} path: /tmp/devstack-logs/* diff --git a/.github/workflows/functional-keymanager.yaml b/.github/workflows/functional-keymanager.yaml index 71997e296d..9b05982c47 100644 --- a/.github/workflows/functional-keymanager.yaml +++ b/.github/workflows/functional-keymanager.yaml @@ -63,7 +63,7 @@ jobs: if: failure() - name: Upload logs artifacts on failure if: failure() - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: functional-keymanager-${{ matrix.name }}-${{ github.run_id }} path: /tmp/devstack-logs/* diff --git a/.github/workflows/functional-loadbalancer.yaml b/.github/workflows/functional-loadbalancer.yaml index ef91756760..dcb3af41d1 100644 --- a/.github/workflows/functional-loadbalancer.yaml +++ b/.github/workflows/functional-loadbalancer.yaml @@ -73,7 +73,7 @@ jobs: if: failure() - name: Upload logs artifacts on failure if: failure() - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: functional-loadbalancer-${{ matrix.name }}-${{ github.run_id }} path: /tmp/devstack-logs/* diff --git a/.github/workflows/functional-messaging.yaml b/.github/workflows/functional-messaging.yaml index e2973dde67..d4c0889dea 100644 --- a/.github/workflows/functional-messaging.yaml +++ b/.github/workflows/functional-messaging.yaml @@ -62,7 +62,7 @@ jobs: if: failure() - name: Upload logs artifacts on failure if: failure() - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: functional-messaging-${{ matrix.name }}-${{ github.run_id }} path: /tmp/devstack-logs/* diff --git a/.github/workflows/functional-metric.yaml b/.github/workflows/functional-metric.yaml index aeba6485e3..a11fe939f7 100644 --- a/.github/workflows/functional-metric.yaml +++ b/.github/workflows/functional-metric.yaml @@ -67,7 +67,7 @@ jobs: - name: Upload logs artifacts on failure if: failure() - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: functional-metric-${{ matrix.name }}-${{ github.run_id }} path: /tmp/devstack-logs/* diff --git a/.github/workflows/functional-networking.yaml b/.github/workflows/functional-networking.yaml index b04ea9b684..d4fb90ee4e 100644 --- a/.github/workflows/functional-networking.yaml +++ b/.github/workflows/functional-networking.yaml @@ -77,7 +77,7 @@ jobs: if: failure() - name: Upload logs artifacts on failure if: failure() - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: functional-networking-${{ matrix.name }}-${{ github.run_id }} path: /tmp/devstack-logs/* diff --git a/.github/workflows/functional-objectstorage.yaml b/.github/workflows/functional-objectstorage.yaml index 6512a237a1..a03ac7fb6a 100644 --- a/.github/workflows/functional-objectstorage.yaml +++ b/.github/workflows/functional-objectstorage.yaml @@ -65,7 +65,7 @@ jobs: if: failure() - name: Upload logs artifacts on failure if: failure() - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: functional-objectstorage-${{ matrix.name }}-${{ github.run_id }} path: /tmp/devstack-logs/* diff --git a/.github/workflows/functional-orchestration.yaml b/.github/workflows/functional-orchestration.yaml index 5e7fa73c10..3f850944a4 100644 --- a/.github/workflows/functional-orchestration.yaml +++ b/.github/workflows/functional-orchestration.yaml @@ -61,7 +61,7 @@ jobs: if: failure() - name: Upload logs artifacts on failure if: failure() - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: functional-orchestration-${{ matrix.name }}-${{ github.run_id }} path: /tmp/devstack-logs/* diff --git a/.github/workflows/functional-placement.yaml b/.github/workflows/functional-placement.yaml index 3e7f5f5772..1d061ca2d9 100644 --- a/.github/workflows/functional-placement.yaml +++ b/.github/workflows/functional-placement.yaml @@ -59,7 +59,7 @@ jobs: if: failure() - name: Upload logs artifacts on failure if: failure() - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: functional-placement-${{ matrix.name }}-${{ github.run_id }} path: /tmp/devstack-logs/* diff --git a/.github/workflows/functional-sharedfilesystems.yaml b/.github/workflows/functional-sharedfilesystems.yaml index cdfe562953..9ca40cb9d9 100644 --- a/.github/workflows/functional-sharedfilesystems.yaml +++ b/.github/workflows/functional-sharedfilesystems.yaml @@ -77,7 +77,7 @@ jobs: if: failure() - name: Upload logs artifacts on failure if: failure() - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: functional-sharedfilesystems-${{ matrix.name }}-${{ github.run_id }} path: /tmp/devstack-logs/* diff --git a/.github/workflows/functional-workflow.yaml b/.github/workflows/functional-workflow.yaml index 50f2d4144f..f68a3a4a91 100644 --- a/.github/workflows/functional-workflow.yaml +++ b/.github/workflows/functional-workflow.yaml @@ -64,7 +64,7 @@ jobs: if: failure() - name: Upload logs artifacts on failure if: failure() - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: functional-workflow-${{ matrix.name }}-${{ github.run_id }} path: /tmp/devstack-logs/* diff --git a/.github/workflows/semver.yaml b/.github/workflows/semver.yaml index af9ff9643d..3e1c7e2c8b 100644 --- a/.github/workflows/semver.yaml +++ b/.github/workflows/semver.yaml @@ -60,7 +60,7 @@ jobs: - name: Upload semver results if: always() - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: semver-results path: semver-results/ From 1b48b426eb355588f592b4d8937b3530738ba69d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 22 Apr 2026 09:20:43 +0000 Subject: [PATCH 314/353] build(deps): bump github/codeql-action from 4.35.1 to 4.35.2 Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.35.1 to 4.35.2. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/c10b8064de6f491fea524254123dbe5e09572f13...95e58e9a2cdfd71adc6e0353d5c52f41a045d225) --- updated-dependencies: - dependency-name: github/codeql-action dependency-version: 4.35.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/codeql-analysis.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql-analysis.yaml b/.github/workflows/codeql-analysis.yaml index 3d11b8f50a..fdc009036f 100644 --- a/.github/workflows/codeql-analysis.yaml +++ b/.github/workflows/codeql-analysis.yaml @@ -29,12 +29,12 @@ jobs: cache: true - name: Initialize CodeQL - uses: github/codeql-action/init@c10b8064de6f491fea524254123dbe5e09572f13 # v4 + uses: github/codeql-action/init@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4 with: languages: ${{ matrix.language }} - name: Autobuild - uses: github/codeql-action/autobuild@c10b8064de6f491fea524254123dbe5e09572f13 # v4 + uses: github/codeql-action/autobuild@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@c10b8064de6f491fea524254123dbe5e09572f13 # v4 + uses: github/codeql-action/analyze@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4 From 8e42a9cf05f3714125d26994766ed9c1110319c7 Mon Sep 17 00:00:00 2001 From: Dominik Danelski Date: Fri, 10 Apr 2026 15:01:39 +0200 Subject: [PATCH 315/353] Implement Placement allocations GET Related #526 API reference: https://docs.openstack.org/api-ref/placement/?expanded=#list-allocations Code reference: https://opendev.org/openstack/placement/src/branch/stable/2026.1/placement/handlers/allocation.py#L260-L286 --- .../placement/v1/allocations_test.go | 29 +++++ openstack/placement/v1/allocations/doc.go | 15 +++ .../placement/v1/allocations/requests.go | 14 +++ openstack/placement/v1/allocations/results.go | 46 ++++++++ .../placement/v1/allocations/testing/doc.go | 2 + .../v1/allocations/testing/fixtures_test.go | 110 ++++++++++++++++++ .../v1/allocations/testing/requests_test.go | 32 +++++ openstack/placement/v1/allocations/urls.go | 7 ++ 8 files changed, 255 insertions(+) create mode 100644 internal/acceptance/openstack/placement/v1/allocations_test.go create mode 100644 openstack/placement/v1/allocations/doc.go create mode 100644 openstack/placement/v1/allocations/requests.go create mode 100644 openstack/placement/v1/allocations/results.go create mode 100644 openstack/placement/v1/allocations/testing/doc.go create mode 100644 openstack/placement/v1/allocations/testing/fixtures_test.go create mode 100644 openstack/placement/v1/allocations/testing/requests_test.go create mode 100644 openstack/placement/v1/allocations/urls.go diff --git a/internal/acceptance/openstack/placement/v1/allocations_test.go b/internal/acceptance/openstack/placement/v1/allocations_test.go new file mode 100644 index 0000000000..71452221f2 --- /dev/null +++ b/internal/acceptance/openstack/placement/v1/allocations_test.go @@ -0,0 +1,29 @@ +//go:build acceptance || placement || allocations + +package v1 + +import ( + "context" + "fmt" + "math/rand" + "testing" + + "github.com/gophercloud/gophercloud/v2/internal/acceptance/clients" + "github.com/gophercloud/gophercloud/v2/openstack/placement/v1/allocations" + th "github.com/gophercloud/gophercloud/v2/testhelper" +) + +func TestGetAllocationsSuccess(t *testing.T) { + clients.RequireAdmin(t) + + client, err := clients.NewPlacementV1Client() + th.AssertNoErr(t, err) + + consumerUUID := fmt.Sprintf("%08x-0000-0000-0000-000000000000", rand.Int31()) + + // Assert: We don't have any allocations for this random UUID. + // We get an empty allocations map, not 404. + allocs, err := allocations.Get(context.TODO(), client, consumerUUID).Extract() + th.AssertNoErr(t, err) + th.AssertEquals(t, 0, len(allocs.Allocations)) +} diff --git a/openstack/placement/v1/allocations/doc.go b/openstack/placement/v1/allocations/doc.go new file mode 100644 index 0000000000..9851f50e01 --- /dev/null +++ b/openstack/placement/v1/allocations/doc.go @@ -0,0 +1,15 @@ +/* +Package allocations manages consumer allocations from the OpenStack Placement service. + +Allocation API requests are available starting from microversion 1.0. + +# Example to get allocations for a consumer + + allocs, err := allocations.Get(context.TODO(), placementClient, consumerUUID).Extract() + if err != nil { + panic(err) + } + + fmt.Printf("%+v\n", allocs) +*/ +package allocations diff --git a/openstack/placement/v1/allocations/requests.go b/openstack/placement/v1/allocations/requests.go new file mode 100644 index 0000000000..8e4dd8dfb9 --- /dev/null +++ b/openstack/placement/v1/allocations/requests.go @@ -0,0 +1,14 @@ +package allocations + +import ( + "context" + + "github.com/gophercloud/gophercloud/v2" +) + +// Get retrieves the allocations for a specific consumer by its UUID. +func Get(ctx context.Context, client *gophercloud.ServiceClient, consumerUUID string) (r GetResult) { + resp, err := client.Get(ctx, getURL(client, consumerUUID), &r.Body, nil) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} diff --git a/openstack/placement/v1/allocations/results.go b/openstack/placement/v1/allocations/results.go new file mode 100644 index 0000000000..01d91713b3 --- /dev/null +++ b/openstack/placement/v1/allocations/results.go @@ -0,0 +1,46 @@ +package allocations + +import "github.com/gophercloud/gophercloud/v2" + +// ProviderAllocations represents the per-provider portion of an allocations response. +type ProviderAllocations struct { + Generation int `json:"generation"` + + // Resources maps resource class names to the integer amount consumed from the provider. + Resources map[string]int `json:"resources"` +} + +// Allocations represents the allocations for a single consumer. +// The Allocations field maps resource provider UUIDs to ProviderAllocations, +// describing how much of each resource class is consumed from each provider. +type Allocations struct { + // Allocations maps resource provider UUIDs to the resources consumed from each. + Allocations map[string]ProviderAllocations `json:"allocations"` + + // Available from microversion 1.12. + // Will be absent when listing allocations for a consumer UUID that has no allocations. + ProjectID *string `json:"project_id"` + + // Available from microversion 1.12. + // Will be absent when listing allocations for a consumer UUID that has no allocations. + UserID *string `json:"user_id"` + + // Available from microversion 1.28. + ConsumerGeneration *int `json:"consumer_generation"` + + // Available from microversion 1.38. + ConsumerType *string `json:"consumer_type"` +} + +// GetResult is the result of a Get operation. Call its Extract method +// to interpret it as an Allocations. +type GetResult struct { + gophercloud.Result +} + +// Extract interprets a GetResult as Allocations. +func (r GetResult) Extract() (*Allocations, error) { + var s Allocations + err := r.ExtractInto(&s) + return &s, err +} diff --git a/openstack/placement/v1/allocations/testing/doc.go b/openstack/placement/v1/allocations/testing/doc.go new file mode 100644 index 0000000000..a06432adf8 --- /dev/null +++ b/openstack/placement/v1/allocations/testing/doc.go @@ -0,0 +1,2 @@ +// Package testing contains allocations unit tests. +package testing diff --git a/openstack/placement/v1/allocations/testing/fixtures_test.go b/openstack/placement/v1/allocations/testing/fixtures_test.go new file mode 100644 index 0000000000..0cc47e1816 --- /dev/null +++ b/openstack/placement/v1/allocations/testing/fixtures_test.go @@ -0,0 +1,110 @@ +package testing + +import ( + "fmt" + "net/http" + "testing" + + "github.com/gophercloud/gophercloud/v2/openstack/placement/v1/allocations" + th "github.com/gophercloud/gophercloud/v2/testhelper" + "github.com/gophercloud/gophercloud/v2/testhelper/client" +) + +const ConsumerUUID = "ba8f2c8e-0bf7-4a32-aacf-7c11f7f9a321" +const EmptyConsumerUUID = "00000000-0000-0000-0000-000000000000" +const ProviderUUID1 = "7d4f1abe-2f91-4f7a-8872-b70d9fb5c3dd" +const ProviderUUID2 = "f3f97e00-13e1-4c88-a7cd-db3bb4f99357" +const ProjectID = "42a2b0fa980d4f7f873e8f0d8b4e1b0e" +const UserID = "b29d880b2c114d5d9a55748b26b2e41e" + +var GetAllocationsBody = fmt.Sprintf(` +{ + "allocations": { + "%s": { + "generation": 3, + "resources": { + "VCPU": 2, + "MEMORY_MB": 2048 + } + }, + "%s": { + "generation": 7, + "resources": { + "DISK_GB": 50 + } + } + }, + "project_id": "%s", + "user_id": "%s", + "consumer_generation": 2, + "consumer_type": "INSTANCE" +} +`, ProviderUUID1, ProviderUUID2, ProjectID, UserID) + +// GetEmptyAllocationsBody is the response for a consumer UUID that has no +// allocations. Per the Placement API, only the "allocations" key is present; +// project_id, user_id, consumer_generation, and consumer_type are absent. +const GetEmptyAllocationsBody = ` +{ + "allocations": {} +} +` + +var consumerGeneration = 2 +var consumerType = "INSTANCE" +var projectID = ProjectID +var userID = UserID + +var ExpectedAllocations = allocations.Allocations{ + Allocations: map[string]allocations.ProviderAllocations{ + ProviderUUID1: { + Generation: 3, + Resources: map[string]int{ + "VCPU": 2, + "MEMORY_MB": 2048, + }, + }, + ProviderUUID2: { + Generation: 7, + Resources: map[string]int{ + "DISK_GB": 50, + }, + }, + }, + ProjectID: &projectID, + UserID: &userID, + ConsumerGeneration: &consumerGeneration, + ConsumerType: &consumerType, +} + +var ExpectedEmptyAllocations = allocations.Allocations{ + Allocations: map[string]allocations.ProviderAllocations{}, +} + +func HandleGetAllocationsSuccess(t *testing.T, fakeServer th.FakeServer) { + url := fmt.Sprintf("/allocations/%s", ConsumerUUID) + + fakeServer.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + + fmt.Fprint(w, GetAllocationsBody) + }) +} + +func HandleGetEmptyAllocationsSuccess(t *testing.T, fakeServer th.FakeServer) { + url := fmt.Sprintf("/allocations/%s", EmptyConsumerUUID) + + fakeServer.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + + fmt.Fprint(w, GetEmptyAllocationsBody) + }) +} diff --git a/openstack/placement/v1/allocations/testing/requests_test.go b/openstack/placement/v1/allocations/testing/requests_test.go new file mode 100644 index 0000000000..9ee5a736c9 --- /dev/null +++ b/openstack/placement/v1/allocations/testing/requests_test.go @@ -0,0 +1,32 @@ +package testing + +import ( + "context" + "testing" + + "github.com/gophercloud/gophercloud/v2/openstack/placement/v1/allocations" + th "github.com/gophercloud/gophercloud/v2/testhelper" + "github.com/gophercloud/gophercloud/v2/testhelper/client" +) + +func TestGetSuccess(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleGetAllocationsSuccess(t, fakeServer) + + actual, err := allocations.Get(context.TODO(), client.ServiceClient(fakeServer), ConsumerUUID).Extract() + th.AssertNoErr(t, err) + th.AssertDeepEquals(t, ExpectedAllocations, *actual) +} + +func TestGetEmptySuccess(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleGetEmptyAllocationsSuccess(t, fakeServer) + + actual, err := allocations.Get(context.TODO(), client.ServiceClient(fakeServer), EmptyConsumerUUID).Extract() + th.AssertNoErr(t, err) + th.AssertDeepEquals(t, ExpectedEmptyAllocations, *actual) +} diff --git a/openstack/placement/v1/allocations/urls.go b/openstack/placement/v1/allocations/urls.go new file mode 100644 index 0000000000..f1deebb82e --- /dev/null +++ b/openstack/placement/v1/allocations/urls.go @@ -0,0 +1,7 @@ +package allocations + +import "github.com/gophercloud/gophercloud/v2" + +func getURL(client *gophercloud.ServiceClient, consumerUUID string) string { + return client.ServiceURL("allocations", consumerUUID) +} From c542064e4d21eeeb1f36f711d401e35036901a9d Mon Sep 17 00:00:00 2001 From: Dominik Danelski Date: Fri, 10 Apr 2026 15:15:01 +0200 Subject: [PATCH 316/353] Implement Placement allocations PUT Related #526 API reference: https://docs.openstack.org/api-ref/placement/?expanded=#update-allocations Code reference: https://opendev.org/openstack/placement/src/branch/stable/2026.1/placement/handlers/allocation.py#L391-L413 --- .../placement/v1/allocations_test.go | 163 ++++++++++++++++++ .../openstack/placement/v1/placement.go | 43 +++++ openstack/placement/v1/allocations/doc.go | 49 ++++++ .../placement/v1/allocations/requests.go | 63 +++++++ openstack/placement/v1/allocations/results.go | 6 + .../v1/allocations/testing/fixtures_test.go | 130 ++++++++++++++ .../v1/allocations/testing/requests_test.go | 69 ++++++++ openstack/placement/v1/allocations/urls.go | 4 + 8 files changed, 527 insertions(+) diff --git a/internal/acceptance/openstack/placement/v1/allocations_test.go b/internal/acceptance/openstack/placement/v1/allocations_test.go index 71452221f2..bb2297eb48 100644 --- a/internal/acceptance/openstack/placement/v1/allocations_test.go +++ b/internal/acceptance/openstack/placement/v1/allocations_test.go @@ -6,9 +6,12 @@ import ( "context" "fmt" "math/rand" + "net/http" "testing" + "github.com/gophercloud/gophercloud/v2" "github.com/gophercloud/gophercloud/v2/internal/acceptance/clients" + "github.com/gophercloud/gophercloud/v2/internal/acceptance/tools" "github.com/gophercloud/gophercloud/v2/openstack/placement/v1/allocations" th "github.com/gophercloud/gophercloud/v2/testhelper" ) @@ -27,3 +30,163 @@ func TestGetAllocationsSuccess(t *testing.T) { th.AssertNoErr(t, err) th.AssertEquals(t, 0, len(allocs.Allocations)) } + +func TestUpdateAllocationsNewConsumerSuccess(t *testing.T) { + clients.RequireAdmin(t) + clients.SkipReleasesBelow(t, "stable/rocky") + + client, err := clients.NewPlacementV1Client() + th.AssertNoErr(t, err) + + resourceProvider, _, err := CreateResourceProviderWithVCPUInventory(t, client) + th.AssertNoErr(t, err) + defer DeleteResourceProvider(t, client, resourceProvider.UUID) + + consumerUUID := fmt.Sprintf("%08x-0000-0000-0000-000000000000", rand.Int31()) + + client.Microversion = "1.28" + + // Act: Update with nil ConsumerGeneration to signal a new consumer (serialized as JSON null, not omitted). + err = allocations.Update(context.TODO(), client, consumerUUID, allocations.UpdateOpts{ + Allocations: map[string]allocations.ProviderAllocationsOpts{ + resourceProvider.UUID: { + Resources: map[string]int{"VCPU": 2, "MEMORY_MB": 1024}, + }, + }, + ProjectID: "test-project", + UserID: "test-user", + ConsumerGeneration: nil, + }).ExtractErr() + th.AssertNoErr(t, err) + + allocs, err := allocations.Get(context.TODO(), client, consumerUUID).Extract() + th.AssertNoErr(t, err) + th.AssertEquals(t, 1, len(allocs.Allocations)) + th.AssertEquals(t, 2, allocs.Allocations[resourceProvider.UUID].Resources["VCPU"]) + th.AssertEquals(t, 1024, allocs.Allocations[resourceProvider.UUID].Resources["MEMORY_MB"]) + + // Clean up: remove allocations using PUT with empty allocations and the + // current generation (safe deletion, recommended over DELETE). + err = allocations.Update(context.TODO(), client, consumerUUID, allocations.UpdateOpts{ + Allocations: map[string]allocations.ProviderAllocationsOpts{}, + ProjectID: "test-project", + UserID: "test-user", + ConsumerGeneration: allocs.ConsumerGeneration, + }).ExtractErr() + th.AssertNoErr(t, err) +} + +func TestUpdateAllocationsSuccess(t *testing.T) { + clients.RequireAdmin(t) + clients.SkipReleasesBelow(t, "stable/rocky") + + client, err := clients.NewPlacementV1Client() + th.AssertNoErr(t, err) + + resourceProvider, _, err := CreateResourceProviderWithVCPUInventory(t, client) + th.AssertNoErr(t, err) + defer DeleteResourceProvider(t, client, resourceProvider.UUID) + + consumerUUID := fmt.Sprintf("%08x-0000-0000-0000-000000000001", rand.Int31()) + + client.Microversion = "1.28" + + // Arrange: Create the consumer with nil ConsumerGeneration. + err = allocations.Update(context.TODO(), client, consumerUUID, allocations.UpdateOpts{ + Allocations: map[string]allocations.ProviderAllocationsOpts{ + resourceProvider.UUID: { + Resources: map[string]int{"VCPU": 1}, + }, + }, + ProjectID: "test-project", + UserID: "test-user", + ConsumerGeneration: nil, + }).ExtractErr() + th.AssertNoErr(t, err) + + existing, err := allocations.Get(context.TODO(), client, consumerUUID).Extract() + th.AssertNoErr(t, err) + + // Act: Update allocations using the consumer's current generation. + err = allocations.Update(context.TODO(), client, consumerUUID, allocations.UpdateOpts{ + Allocations: map[string]allocations.ProviderAllocationsOpts{ + resourceProvider.UUID: { + Resources: map[string]int{"VCPU": 2, "MEMORY_MB": 1024}, + }, + }, + ProjectID: *existing.ProjectID, + UserID: *existing.UserID, + ConsumerGeneration: existing.ConsumerGeneration, + }).ExtractErr() + th.AssertNoErr(t, err) + + updated, err := allocations.Get(context.TODO(), client, consumerUUID).Extract() + th.AssertNoErr(t, err) + th.AssertEquals(t, 2, updated.Allocations[resourceProvider.UUID].Resources["VCPU"]) + th.AssertEquals(t, 1024, updated.Allocations[resourceProvider.UUID].Resources["MEMORY_MB"]) + + tools.PrintResource(t, updated) + + // Clean up. + err = allocations.Update(context.TODO(), client, consumerUUID, allocations.UpdateOpts{ + Allocations: map[string]allocations.ProviderAllocationsOpts{}, + ProjectID: updated.ProjectID, + UserID: updated.UserID, + ConsumerGeneration: updated.ConsumerGeneration, + }).ExtractErr() + th.AssertNoErr(t, err) +} + +func TestUpdateAllocationsConflict(t *testing.T) { + clients.RequireAdmin(t) + clients.SkipReleasesBelow(t, "stable/rocky") + + client, err := clients.NewPlacementV1Client() + th.AssertNoErr(t, err) + + resourceProvider, _, err := CreateResourceProviderWithVCPUInventory(t, client) + th.AssertNoErr(t, err) + defer DeleteResourceProvider(t, client, resourceProvider.UUID) + + consumerUUID := fmt.Sprintf("%08x-0000-0000-0000-000000000002", rand.Int31()) + + client.Microversion = "1.28" + + // Arrange: Create the consumer to establish a valid generation. + err = allocations.Update(context.TODO(), client, consumerUUID, allocations.UpdateOpts{ + Allocations: map[string]allocations.ProviderAllocationsOpts{ + resourceProvider.UUID: { + Resources: map[string]int{"VCPU": 1}, + }, + }, + ProjectID: "test-project", + UserID: "test-user", + ConsumerGeneration: nil, + }).ExtractErr() + th.AssertNoErr(t, err) + + // Act: Update with a stale generation to trigger a 409 conflict. + staleGeneration := -1 + err = allocations.Update(context.TODO(), client, consumerUUID, allocations.UpdateOpts{ + Allocations: map[string]allocations.ProviderAllocationsOpts{ + resourceProvider.UUID: { + Resources: map[string]int{"VCPU": 2}, + }, + }, + ProjectID: "test-project", + UserID: "test-user", + ConsumerGeneration: &staleGeneration, + }).ExtractErr() + th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusConflict)) + + // Clean up with correct generation. + existing, err := allocations.Get(context.TODO(), client, consumerUUID).Extract() + th.AssertNoErr(t, err) + err = allocations.Update(context.TODO(), client, consumerUUID, allocations.UpdateOpts{ + Allocations: map[string]allocations.ProviderAllocationsOpts{}, + ProjectID: *existing.ProjectID, + UserID: *existing.UserID, + ConsumerGeneration: existing.ConsumerGeneration, + }).ExtractErr() + th.AssertNoErr(t, err) +} diff --git a/internal/acceptance/openstack/placement/v1/placement.go b/internal/acceptance/openstack/placement/v1/placement.go index 4149d5ff8b..18c3304075 100644 --- a/internal/acceptance/openstack/placement/v1/placement.go +++ b/internal/acceptance/openstack/placement/v1/placement.go @@ -69,3 +69,46 @@ func DeleteResourceProvider(t *testing.T, client *gophercloud.ServiceClient, res t.Logf("Deleted resourceProvider: %s.", resourceProviderID) } + +// CreateResourceProviderWithVCPUInventory creates a resource provider and seeds it +// with a VCPU inventory, returning the provider and the inventory generation. +// This is used by acceptance tests that need a resource provider with available +// capacity before setting allocations against it. +func CreateResourceProviderWithVCPUInventory(t *testing.T, client *gophercloud.ServiceClient) (*resourceproviders.ResourceProvider, int, error) { + resourceProvider, err := CreateResourceProvider(t, client) + if err != nil { + return nil, 0, err + } + + inventories, err := resourceproviders.GetInventories(context.TODO(), client, resourceProvider.UUID).Extract() + if err != nil { + return nil, 0, err + } + + updatedInventories, err := resourceproviders.UpdateInventories(context.TODO(), client, resourceProvider.UUID, resourceproviders.UpdateInventoriesOpts{ + ResourceProviderGeneration: inventories.ResourceProviderGeneration, + Inventories: map[string]resourceproviders.Inventory{ + "VCPU": { + AllocationRatio: 1.0, + MaxUnit: 8, + MinUnit: 1, + Reserved: 0, + StepSize: 1, + Total: 8, + }, + "MEMORY_MB": { + AllocationRatio: 1.0, + MaxUnit: 8192, + MinUnit: 1, + Reserved: 0, + StepSize: 1, + Total: 8192, + }, + }, + }).Extract() + if err != nil { + return nil, 0, err + } + + return resourceProvider, updatedInventories.ResourceProviderGeneration, nil +} diff --git a/openstack/placement/v1/allocations/doc.go b/openstack/placement/v1/allocations/doc.go index 9851f50e01..769c114258 100644 --- a/openstack/placement/v1/allocations/doc.go +++ b/openstack/placement/v1/allocations/doc.go @@ -11,5 +11,54 @@ Allocation API requests are available starting from microversion 1.0. } fmt.Printf("%+v\n", allocs) + +# Example to set allocations for a new consumer (microversion 1.28+) + +When creating allocations for a consumer that does not yet exist, set +ConsumerGeneration to nil. It will be serialized as JSON null, telling the +server that no prior allocation is expected. This is different from omitting +the field: nil is required, not optional. + + placementClient.Microversion = "1.28" + + err := allocations.Update(context.TODO(), placementClient, consumerUUID, allocations.UpdateOpts{ + Allocations: map[string]allocations.ProviderAllocationsOpts{ + providerUUID: { + Resources: map[string]int{"VCPU": 2, "MEMORY_MB": 2048}, + }, + }, + ProjectID: projectID, + UserID: userID, + ConsumerGeneration: nil, + }).ExtractErr() + if err != nil { + panic(err) + } + +# Example to update allocations for an existing consumer (microversion 1.28+) + +When updating allocations for an existing consumer, retrieve the current +generation first and pass it in. + + placementClient.Microversion = "1.28" + + existing, err := allocations.Get(context.TODO(), placementClient, consumerUUID).Extract() + if err != nil { + panic(err) + } + + err = allocations.Update(context.TODO(), placementClient, consumerUUID, allocations.UpdateOpts{ + Allocations: map[string]allocations.ProviderAllocationsOpts{ + providerUUID: { + Resources: map[string]int{"VCPU": 4, "MEMORY_MB": 4096}, + }, + }, + ProjectID: *existing.ProjectID, + UserID: *existing.UserID, + ConsumerGeneration: existing.ConsumerGeneration, + }).ExtractErr() + if err != nil { + panic(err) + } */ package allocations diff --git a/openstack/placement/v1/allocations/requests.go b/openstack/placement/v1/allocations/requests.go index 8e4dd8dfb9..0996df58c1 100644 --- a/openstack/placement/v1/allocations/requests.go +++ b/openstack/placement/v1/allocations/requests.go @@ -12,3 +12,66 @@ func Get(ctx context.Context, client *gophercloud.ServiceClient, consumerUUID st _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) return } + +// ProviderAllocationsOpts specifies the resources to consume from a single resource +// provider in a write request. +type ProviderAllocationsOpts struct { + // Resources maps resource class names to the integer amount to consume. + Resources map[string]int `json:"resources"` +} + +// UpdateOptsBuilder allows extensions to add additional parameters to the +// Update request. +type UpdateOptsBuilder interface { + ToAllocationUpdateMap() (map[string]any, error) +} + +// UpdateOpts specifies the allocation to be set for a consumer. +// +// This requires microversion 1.28 or later. Write operations on allocations +// using earlier microversions are not safe in concurrent environments. +// +// ConsumerGeneration must be set to nil when creating allocations for a new +// consumer (it serializes as JSON null, which signals to the server that no +// prior allocation is expected). For an existing consumer, set it to the +// generation value returned by a prior Get call. A mismatch causes a 409 +// Conflict response, allowing the caller to retry safely. +type UpdateOpts struct { + // Allocations maps resource provider UUIDs to the resources to consume. + Allocations map[string]ProviderAllocationsOpts `json:"allocations"` + + // Required from microversion 1.8. + ProjectID string `json:"project_id"` + + // Required from microversion 1.8. + UserID string `json:"user_id"` + + // ConsumerGeneration must be nil for new consumers (serializes as null) or + // the current generation for existing consumers. + // See the UpdateOpts type documentation for details. + ConsumerGeneration *int `json:"consumer_generation"` + + // Required from microversion 1.38. + ConsumerType string `json:"consumer_type,omitempty"` +} + +// ToAllocationUpdateMap constructs a request body from UpdateOpts. +func (opts UpdateOpts) ToAllocationUpdateMap() (map[string]any, error) { + return gophercloud.BuildRequestBody(opts, "") +} + +// Update replaces all allocations for a consumer. The operation is atomic. +// +// Requires microversion 1.28 or later. +func Update(ctx context.Context, client *gophercloud.ServiceClient, consumerUUID string, opts UpdateOptsBuilder) (r UpdateResult) { + b, err := opts.ToAllocationUpdateMap() + if err != nil { + r.Err = err + return + } + resp, err := client.Put(ctx, updateURL(client, consumerUUID), b, nil, &gophercloud.RequestOpts{ + OkCodes: []int{204}, + }) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} diff --git a/openstack/placement/v1/allocations/results.go b/openstack/placement/v1/allocations/results.go index 01d91713b3..ce5775df81 100644 --- a/openstack/placement/v1/allocations/results.go +++ b/openstack/placement/v1/allocations/results.go @@ -44,3 +44,9 @@ func (r GetResult) Extract() (*Allocations, error) { err := r.ExtractInto(&s) return &s, err } + +// UpdateResult is the result of an Update operation. Call its ExtractErr +// method to determine if the request succeeded or failed. +type UpdateResult struct { + gophercloud.ErrResult +} diff --git a/openstack/placement/v1/allocations/testing/fixtures_test.go b/openstack/placement/v1/allocations/testing/fixtures_test.go index 0cc47e1816..cc329aa2b1 100644 --- a/openstack/placement/v1/allocations/testing/fixtures_test.go +++ b/openstack/placement/v1/allocations/testing/fixtures_test.go @@ -12,6 +12,7 @@ import ( const ConsumerUUID = "ba8f2c8e-0bf7-4a32-aacf-7c11f7f9a321" const EmptyConsumerUUID = "00000000-0000-0000-0000-000000000000" +const ConflictConsumerUUID = "ffffffff-ffff-ffff-ffff-ffffffffffff" const ProviderUUID1 = "7d4f1abe-2f91-4f7a-8872-b70d9fb5c3dd" const ProviderUUID2 = "f3f97e00-13e1-4c88-a7cd-db3bb4f99357" const ProjectID = "42a2b0fa980d4f7f873e8f0d8b4e1b0e" @@ -81,6 +82,72 @@ var ExpectedEmptyAllocations = allocations.Allocations{ Allocations: map[string]allocations.ProviderAllocations{}, } +var UpdateAllocationsRequest = fmt.Sprintf(` +{ + "allocations": { + "%s": { + "resources": { + "VCPU": 2, + "MEMORY_MB": 2048 + } + } + }, + "project_id": "%s", + "user_id": "%s", + "consumer_generation": null +} +`, ProviderUUID1, ProjectID, UserID) + +var UpdateAllocationsExistingRequest = fmt.Sprintf(` +{ + "allocations": { + "%s": { + "resources": { + "VCPU": 2, + "MEMORY_MB": 2048 + } + } + }, + "project_id": "%s", + "user_id": "%s", + "consumer_generation": 1 +} +`, ProviderUUID1, ProjectID, UserID) + +var GetAllocationsAfterUpdateBody = fmt.Sprintf(` +{ + "allocations": { + "%s": { + "generation": 4, + "resources": { + "VCPU": 2, + "MEMORY_MB": 2048 + } + } + }, + "project_id": "%s", + "user_id": "%s", + "consumer_generation": 1 +} +`, ProviderUUID1, ProjectID, UserID) + +var consumerGenerationAfterUpdate = 1 + +var ExpectedAllocationsAfterUpdate = allocations.Allocations{ + Allocations: map[string]allocations.ProviderAllocations{ + ProviderUUID1: { + Generation: 4, + Resources: map[string]int{ + "VCPU": 2, + "MEMORY_MB": 2048, + }, + }, + }, + ProjectID: &projectID, + UserID: &userID, + ConsumerGeneration: &consumerGenerationAfterUpdate, +} + func HandleGetAllocationsSuccess(t *testing.T, fakeServer th.FakeServer) { url := fmt.Sprintf("/allocations/%s", ConsumerUUID) @@ -108,3 +175,66 @@ func HandleGetEmptyAllocationsSuccess(t *testing.T, fakeServer th.FakeServer) { fmt.Fprint(w, GetEmptyAllocationsBody) }) } + +// HandleUpdateAndGetAllocationsSuccess handles PUT followed by GET on the same URL, +// branching by HTTP method. +func HandleUpdateAndGetAllocationsSuccess(t *testing.T, fakeServer th.FakeServer) { + url := fmt.Sprintf("/allocations/%s", ConsumerUUID) + + fakeServer.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + switch r.Method { + case http.MethodPut: + th.TestHeader(t, r, "Content-Type", "application/json") + th.TestHeader(t, r, "Accept", "application/json") + th.TestJSONRequest(t, r, UpdateAllocationsRequest) + w.WriteHeader(http.StatusNoContent) + case http.MethodGet: + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + fmt.Fprint(w, GetAllocationsAfterUpdateBody) + default: + t.Fatalf("unexpected method: %s", r.Method) + } + }) +} + +// HandleUpdateAllocationsNewConsumerSuccess handles PUT with nil consumer_generation +// (new consumer case), verifying that null is sent in the request body. +func HandleUpdateAllocationsNewConsumerSuccess(t *testing.T, fakeServer th.FakeServer) { + url := fmt.Sprintf("/allocations/%s", EmptyConsumerUUID) + + fakeServer.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + switch r.Method { + case http.MethodPut: + th.TestHeader(t, r, "Content-Type", "application/json") + th.TestHeader(t, r, "Accept", "application/json") + th.TestJSONRequest(t, r, UpdateAllocationsRequest) + w.WriteHeader(http.StatusNoContent) + case http.MethodGet: + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + fmt.Fprint(w, GetAllocationsAfterUpdateBody) + default: + t.Fatalf("unexpected method: %s", r.Method) + } + }) +} + +// HandleUpdateAllocationsConflict simulates a 409 when the consumer_generation +// in the request does not match the server's current value. +func HandleUpdateAllocationsConflict(t *testing.T, fakeServer th.FakeServer) { + url := fmt.Sprintf("/allocations/%s", ConflictConsumerUUID) + + fakeServer.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "PUT") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusConflict) + fmt.Fprint(w, `{"errors":[{"status":409,"title":"Conflict","code":"placement.concurrent_update"}]}`) + }) +} diff --git a/openstack/placement/v1/allocations/testing/requests_test.go b/openstack/placement/v1/allocations/testing/requests_test.go index 9ee5a736c9..510fd78195 100644 --- a/openstack/placement/v1/allocations/testing/requests_test.go +++ b/openstack/placement/v1/allocations/testing/requests_test.go @@ -2,8 +2,10 @@ package testing import ( "context" + "net/http" "testing" + "github.com/gophercloud/gophercloud/v2" "github.com/gophercloud/gophercloud/v2/openstack/placement/v1/allocations" th "github.com/gophercloud/gophercloud/v2/testhelper" "github.com/gophercloud/gophercloud/v2/testhelper/client" @@ -30,3 +32,70 @@ func TestGetEmptySuccess(t *testing.T) { th.AssertNoErr(t, err) th.AssertDeepEquals(t, ExpectedEmptyAllocations, *actual) } + +func TestUpdateSuccess(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleUpdateAndGetAllocationsSuccess(t, fakeServer) + + err := allocations.Update(context.TODO(), client.ServiceClient(fakeServer), ConsumerUUID, allocations.UpdateOpts{ + Allocations: map[string]allocations.ProviderAllocationsOpts{ + ProviderUUID1: { + Resources: map[string]int{"VCPU": 2, "MEMORY_MB": 2048}, + }, + }, + ProjectID: ProjectID, + UserID: UserID, + ConsumerGeneration: nil, + }).ExtractErr() + th.AssertNoErr(t, err) + + actual, err := allocations.Get(context.TODO(), client.ServiceClient(fakeServer), ConsumerUUID).Extract() + th.AssertNoErr(t, err) + th.AssertDeepEquals(t, ExpectedAllocationsAfterUpdate, *actual) +} + +func TestUpdateNewConsumerSuccess(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleUpdateAllocationsNewConsumerSuccess(t, fakeServer) + + // Act: Update with nil ConsumerGeneration; it must be serialized as JSON null, not omitted. + err := allocations.Update(context.TODO(), client.ServiceClient(fakeServer), EmptyConsumerUUID, allocations.UpdateOpts{ + Allocations: map[string]allocations.ProviderAllocationsOpts{ + ProviderUUID1: { + Resources: map[string]int{"VCPU": 2, "MEMORY_MB": 2048}, + }, + }, + ProjectID: ProjectID, + UserID: UserID, + ConsumerGeneration: nil, + }).ExtractErr() + th.AssertNoErr(t, err) + + actual, err := allocations.Get(context.TODO(), client.ServiceClient(fakeServer), EmptyConsumerUUID).Extract() + th.AssertNoErr(t, err) + th.AssertDeepEquals(t, ExpectedAllocationsAfterUpdate, *actual) +} + +func TestUpdateConflict(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleUpdateAllocationsConflict(t, fakeServer) + + staleGeneration := 0 + err := allocations.Update(context.TODO(), client.ServiceClient(fakeServer), ConflictConsumerUUID, allocations.UpdateOpts{ + Allocations: map[string]allocations.ProviderAllocationsOpts{ + ProviderUUID1: { + Resources: map[string]int{"VCPU": 1}, + }, + }, + ProjectID: ProjectID, + UserID: UserID, + ConsumerGeneration: &staleGeneration, + }).ExtractErr() + th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusConflict)) +} diff --git a/openstack/placement/v1/allocations/urls.go b/openstack/placement/v1/allocations/urls.go index f1deebb82e..93c43d3c66 100644 --- a/openstack/placement/v1/allocations/urls.go +++ b/openstack/placement/v1/allocations/urls.go @@ -5,3 +5,7 @@ import "github.com/gophercloud/gophercloud/v2" func getURL(client *gophercloud.ServiceClient, consumerUUID string) string { return client.ServiceURL("allocations", consumerUUID) } + +func updateURL(client *gophercloud.ServiceClient, consumerUUID string) string { + return client.ServiceURL("allocations", consumerUUID) +} From 5b996be3bb867d0157e03198806a33dd127acfe7 Mon Sep 17 00:00:00 2001 From: Dominik Danelski Date: Fri, 10 Apr 2026 15:21:55 +0200 Subject: [PATCH 317/353] Implement Placement allocations DELETE Related #526 API reference: https://docs.openstack.org/api-ref/placement/?expanded=#delete-allocations Code reference: https://opendev.org/openstack/placement/src/branch/stable/2026.1/placement/handlers/allocation.py#L376-L388 --- .../placement/v1/allocations_test.go | 76 +++++++++++++------ openstack/placement/v1/allocations/doc.go | 11 +++ .../placement/v1/allocations/requests.go | 12 +++ openstack/placement/v1/allocations/results.go | 6 ++ .../v1/allocations/testing/fixtures_test.go | 36 +++++++++ .../v1/allocations/testing/requests_test.go | 25 ++++++ openstack/placement/v1/allocations/urls.go | 4 + 7 files changed, 145 insertions(+), 25 deletions(-) diff --git a/internal/acceptance/openstack/placement/v1/allocations_test.go b/internal/acceptance/openstack/placement/v1/allocations_test.go index bb2297eb48..63716941e7 100644 --- a/internal/acceptance/openstack/placement/v1/allocations_test.go +++ b/internal/acceptance/openstack/placement/v1/allocations_test.go @@ -43,6 +43,7 @@ func TestUpdateAllocationsNewConsumerSuccess(t *testing.T) { defer DeleteResourceProvider(t, client, resourceProvider.UUID) consumerUUID := fmt.Sprintf("%08x-0000-0000-0000-000000000000", rand.Int31()) + defer allocations.Delete(context.TODO(), client, consumerUUID) client.Microversion = "1.28" @@ -64,16 +65,6 @@ func TestUpdateAllocationsNewConsumerSuccess(t *testing.T) { th.AssertEquals(t, 1, len(allocs.Allocations)) th.AssertEquals(t, 2, allocs.Allocations[resourceProvider.UUID].Resources["VCPU"]) th.AssertEquals(t, 1024, allocs.Allocations[resourceProvider.UUID].Resources["MEMORY_MB"]) - - // Clean up: remove allocations using PUT with empty allocations and the - // current generation (safe deletion, recommended over DELETE). - err = allocations.Update(context.TODO(), client, consumerUUID, allocations.UpdateOpts{ - Allocations: map[string]allocations.ProviderAllocationsOpts{}, - ProjectID: "test-project", - UserID: "test-user", - ConsumerGeneration: allocs.ConsumerGeneration, - }).ExtractErr() - th.AssertNoErr(t, err) } func TestUpdateAllocationsSuccess(t *testing.T) { @@ -88,6 +79,7 @@ func TestUpdateAllocationsSuccess(t *testing.T) { defer DeleteResourceProvider(t, client, resourceProvider.UUID) consumerUUID := fmt.Sprintf("%08x-0000-0000-0000-000000000001", rand.Int31()) + defer allocations.Delete(context.TODO(), client, consumerUUID) client.Microversion = "1.28" @@ -126,15 +118,6 @@ func TestUpdateAllocationsSuccess(t *testing.T) { th.AssertEquals(t, 1024, updated.Allocations[resourceProvider.UUID].Resources["MEMORY_MB"]) tools.PrintResource(t, updated) - - // Clean up. - err = allocations.Update(context.TODO(), client, consumerUUID, allocations.UpdateOpts{ - Allocations: map[string]allocations.ProviderAllocationsOpts{}, - ProjectID: updated.ProjectID, - UserID: updated.UserID, - ConsumerGeneration: updated.ConsumerGeneration, - }).ExtractErr() - th.AssertNoErr(t, err) } func TestUpdateAllocationsConflict(t *testing.T) { @@ -149,6 +132,7 @@ func TestUpdateAllocationsConflict(t *testing.T) { defer DeleteResourceProvider(t, client, resourceProvider.UUID) consumerUUID := fmt.Sprintf("%08x-0000-0000-0000-000000000002", rand.Int31()) + defer allocations.Delete(context.TODO(), client, consumerUUID) client.Microversion = "1.28" @@ -178,15 +162,57 @@ func TestUpdateAllocationsConflict(t *testing.T) { ConsumerGeneration: &staleGeneration, }).ExtractErr() th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusConflict)) +} - // Clean up with correct generation. - existing, err := allocations.Get(context.TODO(), client, consumerUUID).Extract() +func TestDeleteAllocationsSuccess(t *testing.T) { + clients.RequireAdmin(t) + clients.SkipReleasesBelow(t, "stable/rocky") + + client, err := clients.NewPlacementV1Client() th.AssertNoErr(t, err) + + resourceProvider, _, err := CreateResourceProviderWithVCPUInventory(t, client) + th.AssertNoErr(t, err) + defer DeleteResourceProvider(t, client, resourceProvider.UUID) + + consumerUUID := fmt.Sprintf("%08x-0000-0000-0000-000000000003", rand.Int31()) + + client.Microversion = "1.28" + + // Arrange: Create allocations for the consumer. err = allocations.Update(context.TODO(), client, consumerUUID, allocations.UpdateOpts{ - Allocations: map[string]allocations.ProviderAllocationsOpts{}, - ProjectID: *existing.ProjectID, - UserID: *existing.UserID, - ConsumerGeneration: existing.ConsumerGeneration, + Allocations: map[string]allocations.ProviderAllocationsOpts{ + resourceProvider.UUID: { + Resources: map[string]int{"VCPU": 1}, + }, + }, + ProjectID: "test-project", + UserID: "test-user", + ConsumerGeneration: nil, }).ExtractErr() th.AssertNoErr(t, err) + + // Act: Delete all allocations for the consumer. + err = allocations.Delete(context.TODO(), client, consumerUUID).ExtractErr() + th.AssertNoErr(t, err) + + // Assert: Consumer now returns an empty allocations map. + allocs, err := allocations.Get(context.TODO(), client, consumerUUID).Extract() + th.AssertNoErr(t, err) + th.AssertEquals(t, 0, len(allocs.Allocations)) +} + +func TestDeleteAllocationsNotFound(t *testing.T) { + clients.RequireAdmin(t) + + client, err := clients.NewPlacementV1Client() + th.AssertNoErr(t, err) + + resourceProvider, err := CreateResourceProvider(t, client) + th.AssertNoErr(t, err) + defer DeleteResourceProvider(t, client, resourceProvider.UUID) + + // Assert: An RP that was never a consumer returns 404 on DELETE. + err = allocations.Delete(context.TODO(), client, resourceProvider.UUID).ExtractErr() + th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusNotFound)) } diff --git a/openstack/placement/v1/allocations/doc.go b/openstack/placement/v1/allocations/doc.go index 769c114258..83917d40c0 100644 --- a/openstack/placement/v1/allocations/doc.go +++ b/openstack/placement/v1/allocations/doc.go @@ -60,5 +60,16 @@ generation first and pass it in. if err != nil { panic(err) } + +# Example to delete all allocations for a consumer + +Note: using Update with an empty Allocations map is generally safer because +it is protected by the consumer generation check. Use Delete only when you +do not need that protection. + + err = allocations.Delete(context.TODO(), placementClient, consumerUUID).ExtractErr() + if err != nil { + panic(err) + } */ package allocations diff --git a/openstack/placement/v1/allocations/requests.go b/openstack/placement/v1/allocations/requests.go index 0996df58c1..6d65faeeb7 100644 --- a/openstack/placement/v1/allocations/requests.go +++ b/openstack/placement/v1/allocations/requests.go @@ -75,3 +75,15 @@ func Update(ctx context.Context, client *gophercloud.ServiceClient, consumerUUID _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) return } + +// Delete removes all allocations for a consumer. Returns 204 on success or +// 404 if the consumer does not exist. +// +// Note: using Update with an empty Allocations map is generally safer because +// it is protected by the consumer generation check, preventing accidental +// deletion under concurrent updates. +func Delete(ctx context.Context, client *gophercloud.ServiceClient, consumerUUID string) (r DeleteResult) { + resp, err := client.Delete(ctx, deleteURL(client, consumerUUID), nil) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} diff --git a/openstack/placement/v1/allocations/results.go b/openstack/placement/v1/allocations/results.go index ce5775df81..e8c30bff7f 100644 --- a/openstack/placement/v1/allocations/results.go +++ b/openstack/placement/v1/allocations/results.go @@ -50,3 +50,9 @@ func (r GetResult) Extract() (*Allocations, error) { type UpdateResult struct { gophercloud.ErrResult } + +// DeleteResult is the result of a Delete operation. Call its ExtractErr +// method to determine if the request succeeded or failed. +type DeleteResult struct { + gophercloud.ErrResult +} diff --git a/openstack/placement/v1/allocations/testing/fixtures_test.go b/openstack/placement/v1/allocations/testing/fixtures_test.go index cc329aa2b1..3a5c4e19ad 100644 --- a/openstack/placement/v1/allocations/testing/fixtures_test.go +++ b/openstack/placement/v1/allocations/testing/fixtures_test.go @@ -13,6 +13,7 @@ import ( const ConsumerUUID = "ba8f2c8e-0bf7-4a32-aacf-7c11f7f9a321" const EmptyConsumerUUID = "00000000-0000-0000-0000-000000000000" const ConflictConsumerUUID = "ffffffff-ffff-ffff-ffff-ffffffffffff" +const NotFoundConsumerUUID = "11111111-1111-1111-1111-111111111111" const ProviderUUID1 = "7d4f1abe-2f91-4f7a-8872-b70d9fb5c3dd" const ProviderUUID2 = "f3f97e00-13e1-4c88-a7cd-db3bb4f99357" const ProjectID = "42a2b0fa980d4f7f873e8f0d8b4e1b0e" @@ -238,3 +239,38 @@ func HandleUpdateAllocationsConflict(t *testing.T, fakeServer th.FakeServer) { fmt.Fprint(w, `{"errors":[{"status":409,"title":"Conflict","code":"placement.concurrent_update"}]}`) }) } + +// HandleDeleteAndGetAllocationsSuccess handles DELETE followed by GET on the same URL. +// DELETE returns 204; the subsequent GET returns an empty allocations body. +func HandleDeleteAndGetAllocationsSuccess(t *testing.T, fakeServer th.FakeServer) { + url := fmt.Sprintf("/allocations/%s", ConsumerUUID) + + fakeServer.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + switch r.Method { + case http.MethodDelete: + w.WriteHeader(http.StatusNoContent) + case http.MethodGet: + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + fmt.Fprint(w, GetEmptyAllocationsBody) + default: + t.Fatalf("unexpected method: %s", r.Method) + } + }) +} + +// HandleDeleteAllocationsNotFound simulates a 404 when the consumer does not exist. +func HandleDeleteAllocationsNotFound(t *testing.T, fakeServer th.FakeServer) { + url := fmt.Sprintf("/allocations/%s", NotFoundConsumerUUID) + + fakeServer.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "DELETE") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusNotFound) + fmt.Fprint(w, `{"errors":[{"status":404,"title":"Not Found","code":"placement.undefined_code"}]}`) + }) +} diff --git a/openstack/placement/v1/allocations/testing/requests_test.go b/openstack/placement/v1/allocations/testing/requests_test.go index 510fd78195..5ff5a6e4d6 100644 --- a/openstack/placement/v1/allocations/testing/requests_test.go +++ b/openstack/placement/v1/allocations/testing/requests_test.go @@ -99,3 +99,28 @@ func TestUpdateConflict(t *testing.T) { }).ExtractErr() th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusConflict)) } + +func TestDeleteSuccess(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleDeleteAndGetAllocationsSuccess(t, fakeServer) + + err := allocations.Delete(context.TODO(), client.ServiceClient(fakeServer), ConsumerUUID).ExtractErr() + th.AssertNoErr(t, err) + + // Assert: Consumer now has no allocations. + actual, err := allocations.Get(context.TODO(), client.ServiceClient(fakeServer), ConsumerUUID).Extract() + th.AssertNoErr(t, err) + th.AssertDeepEquals(t, ExpectedEmptyAllocations, *actual) +} + +func TestDeleteNotFound(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleDeleteAllocationsNotFound(t, fakeServer) + + err := allocations.Delete(context.TODO(), client.ServiceClient(fakeServer), NotFoundConsumerUUID).ExtractErr() + th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusNotFound)) +} diff --git a/openstack/placement/v1/allocations/urls.go b/openstack/placement/v1/allocations/urls.go index 93c43d3c66..525468caf3 100644 --- a/openstack/placement/v1/allocations/urls.go +++ b/openstack/placement/v1/allocations/urls.go @@ -9,3 +9,7 @@ func getURL(client *gophercloud.ServiceClient, consumerUUID string) string { func updateURL(client *gophercloud.ServiceClient, consumerUUID string) string { return client.ServiceURL("allocations", consumerUUID) } + +func deleteURL(client *gophercloud.ServiceClient, consumerUUID string) string { + return client.ServiceURL("allocations", consumerUUID) +} From 1fd21bf540ee8270d0e61fccb7b26b3bb0cee4ec Mon Sep 17 00:00:00 2001 From: Dominik Danelski Date: Fri, 10 Apr 2026 15:37:24 +0200 Subject: [PATCH 318/353] Implement Placement allocations POST Related #526 API reference: https://docs.openstack.org/api-ref/placement/?expanded=#manage-allocations Code reference: https://opendev.org/openstack/placement/src/branch/stable/2026.1/placement/handlers/allocation.py#L166-L205 --- .../placement/v1/allocations_test.go | 51 +++++++++ openstack/placement/v1/allocations/doc.go | 34 ++++++ .../placement/v1/allocations/requests.go | 48 +++++++++ openstack/placement/v1/allocations/results.go | 6 ++ .../v1/allocations/testing/fixtures_test.go | 101 ++++++++++++++++++ .../v1/allocations/testing/requests_test.go | 59 ++++++++++ openstack/placement/v1/allocations/urls.go | 4 + 7 files changed, 303 insertions(+) diff --git a/internal/acceptance/openstack/placement/v1/allocations_test.go b/internal/acceptance/openstack/placement/v1/allocations_test.go index 63716941e7..2a3607b219 100644 --- a/internal/acceptance/openstack/placement/v1/allocations_test.go +++ b/internal/acceptance/openstack/placement/v1/allocations_test.go @@ -216,3 +216,54 @@ func TestDeleteAllocationsNotFound(t *testing.T) { err = allocations.Delete(context.TODO(), client, resourceProvider.UUID).ExtractErr() th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusNotFound)) } + +func TestManageAllocationsSuccess(t *testing.T) { + clients.RequireAdmin(t) + clients.SkipReleasesBelow(t, "stable/rocky") + + client, err := clients.NewPlacementV1Client() + th.AssertNoErr(t, err) + + resourceProvider, _, err := CreateResourceProviderWithVCPUInventory(t, client) + th.AssertNoErr(t, err) + defer DeleteResourceProvider(t, client, resourceProvider.UUID) + + consumer1UUID := fmt.Sprintf("%08x-0000-0000-0000-000000000004", rand.Int31()) + consumer2UUID := fmt.Sprintf("%08x-0000-0000-0000-000000000005", rand.Int31()) + defer allocations.Delete(context.TODO(), client, consumer1UUID) + defer allocations.Delete(context.TODO(), client, consumer2UUID) + + client.Microversion = "1.28" + + // Act: Atomically set allocations for two consumers. + err = allocations.Manage(context.TODO(), client, allocations.ManageOpts{ + consumer1UUID: { + Allocations: map[string]allocations.ProviderAllocationsOpts{ + resourceProvider.UUID: { + Resources: map[string]int{"VCPU": 1}, + }, + }, + ProjectID: "test-project", + UserID: "test-user", + ConsumerGeneration: nil, + }, + consumer2UUID: { + Allocations: map[string]allocations.ProviderAllocationsOpts{ + resourceProvider.UUID: { + Resources: map[string]int{"VCPU": 1}, + }, + }, + ProjectID: "test-project", + UserID: "test-user", + ConsumerGeneration: nil, + }, + }).ExtractErr() + th.AssertNoErr(t, err) + + for _, consumerUUID := range []string{consumer1UUID, consumer2UUID} { + allocs, err := allocations.Get(context.TODO(), client, consumerUUID).Extract() + th.AssertNoErr(t, err) + th.AssertEquals(t, 1, len(allocs.Allocations)) + th.AssertEquals(t, 1, allocs.Allocations[resourceProvider.UUID].Resources["VCPU"]) + } +} diff --git a/openstack/placement/v1/allocations/doc.go b/openstack/placement/v1/allocations/doc.go index 83917d40c0..8233418bb1 100644 --- a/openstack/placement/v1/allocations/doc.go +++ b/openstack/placement/v1/allocations/doc.go @@ -71,5 +71,39 @@ do not need that protection. if err != nil { panic(err) } + +# Example to atomically set allocations for multiple consumers (microversion 1.13+) + +Manage sets allocations for any number of consumers in a single atomic +request. The map key is the consumer UUID. Use microversion 1.28 or later +for generation-safe writes. + + placementClient.Microversion = "1.28" + + err = allocations.Manage(context.TODO(), placementClient, allocations.ManageOpts{ + consumer1UUID: { + Allocations: map[string]allocations.ProviderAllocationsOpts{ + providerUUID: { + Resources: map[string]int{"VCPU": 2}, + }, + }, + ProjectID: projectID, + UserID: userID, + ConsumerGeneration: nil, + }, + consumer2UUID: { + Allocations: map[string]allocations.ProviderAllocationsOpts{ + providerUUID: { + Resources: map[string]int{"VCPU": 1}, + }, + }, + ProjectID: projectID, + UserID: userID, + ConsumerGeneration: nil, + }, + }).ExtractErr() + if err != nil { + panic(err) + } */ package allocations diff --git a/openstack/placement/v1/allocations/requests.go b/openstack/placement/v1/allocations/requests.go index 6d65faeeb7..6640681f4c 100644 --- a/openstack/placement/v1/allocations/requests.go +++ b/openstack/placement/v1/allocations/requests.go @@ -2,6 +2,7 @@ package allocations import ( "context" + "encoding/json" "github.com/gophercloud/gophercloud/v2" ) @@ -87,3 +88,50 @@ func Delete(ctx context.Context, client *gophercloud.ServiceClient, consumerUUID _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) return } + +// ManageOptsBuilder allows extensions to add additional parameters to the +// Manage request. +type ManageOptsBuilder interface { + ToAllocationManageMap() (map[string]any, error) +} + +// ManageOpts specifies allocations for multiple consumers in a single atomic +// operation. The map key is the consumer UUID; the value describes the +// allocations and consumer metadata for that consumer. +// +// This requires microversion 1.13 or later. For generation-safe writes, use +// microversion 1.28 or later and set ConsumerGeneration on each entry. +// +// Set ConsumerGeneration to nil for new consumers (serializes as JSON null). +// For existing consumers, set it to the generation returned by a prior Get +// call. A mismatch on any entry causes a 409 Conflict for the entire batch. +type ManageOpts map[string]UpdateOpts + +// ToAllocationManageMap constructs a request body from ManageOpts. +func (opts ManageOpts) ToAllocationManageMap() (map[string]any, error) { + b, err := json.Marshal(opts) + if err != nil { + return nil, err + } + var m map[string]any + err = json.Unmarshal(b, &m) + return m, err +} + +// Manage atomically sets allocations for one or more consumers in a single +// request. +// +// Requires microversion 1.13 or later. For generation-safe writes, use +// microversion 1.28 or later. +func Manage(ctx context.Context, client *gophercloud.ServiceClient, opts ManageOptsBuilder) (r ManageResult) { + b, err := opts.ToAllocationManageMap() + if err != nil { + r.Err = err + return + } + resp, err := client.Post(ctx, manageURL(client), b, nil, &gophercloud.RequestOpts{ + OkCodes: []int{204}, + }) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} diff --git a/openstack/placement/v1/allocations/results.go b/openstack/placement/v1/allocations/results.go index e8c30bff7f..5ca69a8894 100644 --- a/openstack/placement/v1/allocations/results.go +++ b/openstack/placement/v1/allocations/results.go @@ -56,3 +56,9 @@ type UpdateResult struct { type DeleteResult struct { gophercloud.ErrResult } + +// ManageResult is the result of a Manage operation. Call its ExtractErr +// method to determine if the request succeeded or failed. +type ManageResult struct { + gophercloud.ErrResult +} diff --git a/openstack/placement/v1/allocations/testing/fixtures_test.go b/openstack/placement/v1/allocations/testing/fixtures_test.go index 3a5c4e19ad..5e75fd4a72 100644 --- a/openstack/placement/v1/allocations/testing/fixtures_test.go +++ b/openstack/placement/v1/allocations/testing/fixtures_test.go @@ -14,6 +14,8 @@ const ConsumerUUID = "ba8f2c8e-0bf7-4a32-aacf-7c11f7f9a321" const EmptyConsumerUUID = "00000000-0000-0000-0000-000000000000" const ConflictConsumerUUID = "ffffffff-ffff-ffff-ffff-ffffffffffff" const NotFoundConsumerUUID = "11111111-1111-1111-1111-111111111111" +const ManageConsumerUUID1 = "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" +const ManageConsumerUUID2 = "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb" const ProviderUUID1 = "7d4f1abe-2f91-4f7a-8872-b70d9fb5c3dd" const ProviderUUID2 = "f3f97e00-13e1-4c88-a7cd-db3bb4f99357" const ProjectID = "42a2b0fa980d4f7f873e8f0d8b4e1b0e" @@ -149,6 +151,65 @@ var ExpectedAllocationsAfterUpdate = allocations.Allocations{ ConsumerGeneration: &consumerGenerationAfterUpdate, } +var ManageAllocationsRequest = fmt.Sprintf(` +{ + "%s": { + "allocations": { + "%s": { + "resources": { + "VCPU": 1 + } + } + }, + "project_id": "%s", + "user_id": "%s", + "consumer_generation": null + }, + "%s": { + "allocations": { + "%s": { + "resources": { + "VCPU": 1 + } + } + }, + "project_id": "%s", + "user_id": "%s", + "consumer_generation": null + } +} +`, ManageConsumerUUID1, ProviderUUID1, ProjectID, UserID, ManageConsumerUUID2, ProviderUUID1, ProjectID, UserID) + +var GetAllocationsAfterManageBody = fmt.Sprintf(` +{ + "allocations": { + "%s": { + "generation": 1, + "resources": { + "VCPU": 1 + } + } + }, + "project_id": "%s", + "user_id": "%s", + "consumer_generation": 1 +} +`, ProviderUUID1, ProjectID, UserID) + +var ExpectedAllocationsAfterManage = allocations.Allocations{ + Allocations: map[string]allocations.ProviderAllocations{ + ProviderUUID1: { + Generation: 1, + Resources: map[string]int{ + "VCPU": 1, + }, + }, + }, + ProjectID: &projectID, + UserID: &userID, + ConsumerGeneration: &consumerGenerationAfterUpdate, +} + func HandleGetAllocationsSuccess(t *testing.T, fakeServer th.FakeServer) { url := fmt.Sprintf("/allocations/%s", ConsumerUUID) @@ -274,3 +335,43 @@ func HandleDeleteAllocationsNotFound(t *testing.T, fakeServer th.FakeServer) { fmt.Fprint(w, `{"errors":[{"status":404,"title":"Not Found","code":"placement.undefined_code"}]}`) }) } + +// HandleManageAllocationsSuccess handles POST to /allocations, verifying the +// request body, then handles GET requests for each managed consumer. +func HandleManageAllocationsSuccess(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/allocations", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "POST") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.TestHeader(t, r, "Content-Type", "application/json") + th.TestHeader(t, r, "Accept", "application/json") + th.TestJSONRequest(t, r, ManageAllocationsRequest) + + w.WriteHeader(http.StatusNoContent) + }) + + for _, uuid := range []string{ManageConsumerUUID1, ManageConsumerUUID2} { + uuid := uuid + url := fmt.Sprintf("/allocations/%s", uuid) + fakeServer.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + fmt.Fprint(w, GetAllocationsAfterManageBody) + }) + } +} + +// HandleManageAllocationsConflict simulates a 409 when a consumer_generation +// in the batch does not match the server's current value. +func HandleManageAllocationsConflict(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/allocations", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "POST") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusConflict) + fmt.Fprint(w, `{"errors":[{"status":409,"title":"Conflict","code":"placement.concurrent_update"}]}`) + }) +} diff --git a/openstack/placement/v1/allocations/testing/requests_test.go b/openstack/placement/v1/allocations/testing/requests_test.go index 5ff5a6e4d6..ac259167f9 100644 --- a/openstack/placement/v1/allocations/testing/requests_test.go +++ b/openstack/placement/v1/allocations/testing/requests_test.go @@ -124,3 +124,62 @@ func TestDeleteNotFound(t *testing.T) { err := allocations.Delete(context.TODO(), client.ServiceClient(fakeServer), NotFoundConsumerUUID).ExtractErr() th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusNotFound)) } + +func TestManageSuccess(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleManageAllocationsSuccess(t, fakeServer) + + err := allocations.Manage(context.TODO(), client.ServiceClient(fakeServer), allocations.ManageOpts{ + ManageConsumerUUID1: { + Allocations: map[string]allocations.ProviderAllocationsOpts{ + ProviderUUID1: { + Resources: map[string]int{"VCPU": 1}, + }, + }, + ProjectID: ProjectID, + UserID: UserID, + ConsumerGeneration: nil, + }, + ManageConsumerUUID2: { + Allocations: map[string]allocations.ProviderAllocationsOpts{ + ProviderUUID1: { + Resources: map[string]int{"VCPU": 1}, + }, + }, + ProjectID: ProjectID, + UserID: UserID, + ConsumerGeneration: nil, + }, + }).ExtractErr() + th.AssertNoErr(t, err) + + for _, uuid := range []string{ManageConsumerUUID1, ManageConsumerUUID2} { + actual, err := allocations.Get(context.TODO(), client.ServiceClient(fakeServer), uuid).Extract() + th.AssertNoErr(t, err) + th.AssertDeepEquals(t, ExpectedAllocationsAfterManage, *actual) + } +} + +func TestManageConflict(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleManageAllocationsConflict(t, fakeServer) + + staleGeneration := 0 + err := allocations.Manage(context.TODO(), client.ServiceClient(fakeServer), allocations.ManageOpts{ + ConflictConsumerUUID: { + Allocations: map[string]allocations.ProviderAllocationsOpts{ + ProviderUUID1: { + Resources: map[string]int{"VCPU": 1}, + }, + }, + ProjectID: ProjectID, + UserID: UserID, + ConsumerGeneration: &staleGeneration, + }, + }).ExtractErr() + th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusConflict)) +} diff --git a/openstack/placement/v1/allocations/urls.go b/openstack/placement/v1/allocations/urls.go index 525468caf3..267adb143b 100644 --- a/openstack/placement/v1/allocations/urls.go +++ b/openstack/placement/v1/allocations/urls.go @@ -13,3 +13,7 @@ func updateURL(client *gophercloud.ServiceClient, consumerUUID string) string { func deleteURL(client *gophercloud.ServiceClient, consumerUUID string) string { return client.ServiceURL("allocations", consumerUUID) } + +func manageURL(client *gophercloud.ServiceClient) string { + return client.ServiceURL("allocations") +} From 269f7a4f38e2a703aa4bbc2758482f47009de897 Mon Sep 17 00:00:00 2001 From: Dominik Danelski Date: Mon, 4 May 2026 11:53:29 +0200 Subject: [PATCH 319/353] Use RandomUUID() for creating consumer IDs in Placement allocations Signed-off-by: Dominik Danelski --- .../openstack/placement/v1/allocations_test.go | 16 +++++++--------- internal/acceptance/tools/tools.go | 5 +++++ 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/internal/acceptance/openstack/placement/v1/allocations_test.go b/internal/acceptance/openstack/placement/v1/allocations_test.go index 2a3607b219..bf95d0bc40 100644 --- a/internal/acceptance/openstack/placement/v1/allocations_test.go +++ b/internal/acceptance/openstack/placement/v1/allocations_test.go @@ -4,8 +4,6 @@ package v1 import ( "context" - "fmt" - "math/rand" "net/http" "testing" @@ -22,7 +20,7 @@ func TestGetAllocationsSuccess(t *testing.T) { client, err := clients.NewPlacementV1Client() th.AssertNoErr(t, err) - consumerUUID := fmt.Sprintf("%08x-0000-0000-0000-000000000000", rand.Int31()) + consumerUUID := tools.RandomUUID() // Assert: We don't have any allocations for this random UUID. // We get an empty allocations map, not 404. @@ -42,7 +40,7 @@ func TestUpdateAllocationsNewConsumerSuccess(t *testing.T) { th.AssertNoErr(t, err) defer DeleteResourceProvider(t, client, resourceProvider.UUID) - consumerUUID := fmt.Sprintf("%08x-0000-0000-0000-000000000000", rand.Int31()) + consumerUUID := tools.RandomUUID() defer allocations.Delete(context.TODO(), client, consumerUUID) client.Microversion = "1.28" @@ -78,7 +76,7 @@ func TestUpdateAllocationsSuccess(t *testing.T) { th.AssertNoErr(t, err) defer DeleteResourceProvider(t, client, resourceProvider.UUID) - consumerUUID := fmt.Sprintf("%08x-0000-0000-0000-000000000001", rand.Int31()) + consumerUUID := tools.RandomUUID() defer allocations.Delete(context.TODO(), client, consumerUUID) client.Microversion = "1.28" @@ -131,7 +129,7 @@ func TestUpdateAllocationsConflict(t *testing.T) { th.AssertNoErr(t, err) defer DeleteResourceProvider(t, client, resourceProvider.UUID) - consumerUUID := fmt.Sprintf("%08x-0000-0000-0000-000000000002", rand.Int31()) + consumerUUID := tools.RandomUUID() defer allocations.Delete(context.TODO(), client, consumerUUID) client.Microversion = "1.28" @@ -175,7 +173,7 @@ func TestDeleteAllocationsSuccess(t *testing.T) { th.AssertNoErr(t, err) defer DeleteResourceProvider(t, client, resourceProvider.UUID) - consumerUUID := fmt.Sprintf("%08x-0000-0000-0000-000000000003", rand.Int31()) + consumerUUID := tools.RandomUUID() client.Microversion = "1.28" @@ -228,8 +226,8 @@ func TestManageAllocationsSuccess(t *testing.T) { th.AssertNoErr(t, err) defer DeleteResourceProvider(t, client, resourceProvider.UUID) - consumer1UUID := fmt.Sprintf("%08x-0000-0000-0000-000000000004", rand.Int31()) - consumer2UUID := fmt.Sprintf("%08x-0000-0000-0000-000000000005", rand.Int31()) + consumer1UUID := tools.RandomUUID() + consumer2UUID := tools.RandomUUID() defer allocations.Delete(context.TODO(), client, consumer1UUID) defer allocations.Delete(context.TODO(), client, consumer2UUID) diff --git a/internal/acceptance/tools/tools.go b/internal/acceptance/tools/tools.go index 75ac004473..2f0238226a 100644 --- a/internal/acceptance/tools/tools.go +++ b/internal/acceptance/tools/tools.go @@ -3,6 +3,7 @@ package tools import ( "context" "encoding/json" + "fmt" "math/rand" "strings" "testing" @@ -69,6 +70,10 @@ func RandomInt(min, max int) int { return rand.Intn(max-min) + min } +func RandomUUID() string { + return fmt.Sprintf("%08x-0000-0000-0000-000000000000", rand.Int31()) +} + // Elide returns the first bit of its input string with a suffix of "..." if it's longer than // a comfortable 40 characters. func Elide(value string) string { From e0433a0a04df192d2dec70251114cbb42883c3ff Mon Sep 17 00:00:00 2001 From: Winicius Silva Date: Thu, 23 Apr 2026 18:11:04 +0100 Subject: [PATCH 320/353] add a check to skip unmarshal for non-struct types --- results.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/results.go b/results.go index d5b947b7f0..101a7d24dc 100644 --- a/results.go +++ b/results.go @@ -117,6 +117,9 @@ func (r Result) extractIntoPtr(to any, label string) error { // a struct that is never used, but it's good enough to // trigger the UnmarshalJSON method. for i := 0; i < newType.NumField(); i++ { + if newType.Field(i).Kind() != reflect.Struct { + continue + } s := newType.Field(i).Addr().Interface() // Unmarshal is used rather than NewDecoder to also work From 64b31057d85f69cfa432813ee81f00f29097c719 Mon Sep 17 00:00:00 2001 From: Dominik Danelski Date: Wed, 15 Apr 2026 15:53:11 +0200 Subject: [PATCH 321/353] Implement Placement usages Related #526 API reference: https://docs.openstack.org/api-ref/placement/?expanded=#list-usages Code reference: https://opendev.org/openstack/placement/src/branch/stable/2026.1/placement/handlers/usage.py#L83-L143 Signed-off-by: Dominik Danelski --- .../openstack/placement/v1/usages_test.go | 195 ++++++++++++++++++ openstack/placement/v1/usages/doc.go | 49 +++++ .../placement/v1/usages/microversions.go | 16 ++ openstack/placement/v1/usages/requests.go | 59 ++++++ openstack/placement/v1/usages/results.go | 33 +++ openstack/placement/v1/usages/testing/doc.go | 2 + .../v1/usages/testing/fixtures_test.go | 172 +++++++++++++++ .../v1/usages/testing/requests_test.go | 90 ++++++++ openstack/placement/v1/usages/urls.go | 7 + 9 files changed, 623 insertions(+) create mode 100644 internal/acceptance/openstack/placement/v1/usages_test.go create mode 100644 openstack/placement/v1/usages/doc.go create mode 100644 openstack/placement/v1/usages/microversions.go create mode 100644 openstack/placement/v1/usages/requests.go create mode 100644 openstack/placement/v1/usages/results.go create mode 100644 openstack/placement/v1/usages/testing/doc.go create mode 100644 openstack/placement/v1/usages/testing/fixtures_test.go create mode 100644 openstack/placement/v1/usages/testing/requests_test.go create mode 100644 openstack/placement/v1/usages/urls.go diff --git a/internal/acceptance/openstack/placement/v1/usages_test.go b/internal/acceptance/openstack/placement/v1/usages_test.go new file mode 100644 index 0000000000..20fa216a71 --- /dev/null +++ b/internal/acceptance/openstack/placement/v1/usages_test.go @@ -0,0 +1,195 @@ +//go:build acceptance || placement || usages + +package v1 + +import ( + "context" + "testing" + + "github.com/gophercloud/gophercloud/v2/internal/acceptance/clients" + "github.com/gophercloud/gophercloud/v2/internal/acceptance/tools" + "github.com/gophercloud/gophercloud/v2/openstack/placement/v1/allocations" + "github.com/gophercloud/gophercloud/v2/openstack/placement/v1/usages" + th "github.com/gophercloud/gophercloud/v2/testhelper" +) + +func TestGetUsagesSuccess(t *testing.T) { + clients.RequireAdmin(t) + clients.SkipReleasesBelow(t, "stable/rocky") + + client, err := clients.NewPlacementV1Client() + th.AssertNoErr(t, err) + + resourceProvider, _, err := CreateResourceProviderWithVCPUInventory(t, client) + th.AssertNoErr(t, err) + defer DeleteResourceProvider(t, client, resourceProvider.UUID) + + consumerUUID := tools.RandomUUID() + defer allocations.Delete(context.TODO(), client, consumerUUID) + + projectID := "test-project" + userID := "test-user" + + client.Microversion = "1.38" + + // Arrange: Create allocations for a consumer under the test project. + err = allocations.Update(context.TODO(), client, consumerUUID, allocations.UpdateOpts{ + Allocations: map[string]allocations.ProviderAllocationsOpts{ + resourceProvider.UUID: { + Resources: map[string]int{"VCPU": 2, "MEMORY_MB": 1024}, + }, + }, + ProjectID: projectID, + UserID: userID, + ConsumerGeneration: nil, + ConsumerType: "INSTANCE", + }).ExtractErr() + th.AssertNoErr(t, err) + + // Act: Retrieve total usages for the project (1.38+, grouped by consumer type). + totalUsages, err := usages.Get(context.TODO(), client, usages.GetOpts{ + ProjectID: projectID, + }).Extract() + th.AssertNoErr(t, err) + + // Assert: Exactly one consumer type "INSTANCE" with our exact resource usage. + th.AssertEquals(t, 1, len(totalUsages.Usages)) + ctUsage := totalUsages.Usages["INSTANCE"] + th.AssertEquals(t, 2, ctUsage["VCPU"]) + th.AssertEquals(t, 1024, ctUsage["MEMORY_MB"]) + th.AssertEquals(t, 1, ctUsage["consumer_count"]) + + tools.PrintResource(t, totalUsages) +} + +func TestGetUsagesWithUserSuccess(t *testing.T) { + clients.RequireAdmin(t) + clients.SkipReleasesBelow(t, "stable/rocky") + + client, err := clients.NewPlacementV1Client() + th.AssertNoErr(t, err) + + resourceProvider, _, err := CreateResourceProviderWithVCPUInventory(t, client) + th.AssertNoErr(t, err) + defer DeleteResourceProvider(t, client, resourceProvider.UUID) + + consumerUUID := tools.RandomUUID() + defer allocations.Delete(context.TODO(), client, consumerUUID) + + projectID := "test-project" + userID := "test-user" + + client.Microversion = "1.38" + + // Arrange: Create allocations. + err = allocations.Update(context.TODO(), client, consumerUUID, allocations.UpdateOpts{ + Allocations: map[string]allocations.ProviderAllocationsOpts{ + resourceProvider.UUID: { + Resources: map[string]int{"VCPU": 1}, + }, + }, + ProjectID: projectID, + UserID: userID, + ConsumerGeneration: nil, + ConsumerType: "INSTANCE", + }).ExtractErr() + th.AssertNoErr(t, err) + + // Act: Retrieve usages filtered by project and user (1.38+). + totalUsages, err := usages.Get(context.TODO(), client, usages.GetOpts{ + ProjectID: projectID, + UserID: userID, + }).Extract() + th.AssertNoErr(t, err) + + // Assert: Exactly one consumer type "INSTANCE" with our exact VCPU usage. + th.AssertEquals(t, 1, len(totalUsages.Usages)) + ctUsage := totalUsages.Usages["INSTANCE"] + th.AssertEquals(t, 1, ctUsage["VCPU"]) + th.AssertEquals(t, 1, ctUsage["consumer_count"]) + + tools.PrintResource(t, totalUsages) +} + +func TestGetUsagesEmptySuccess(t *testing.T) { + clients.RequireAdmin(t) + clients.SkipReleasesBelow(t, "stable/rocky") + + client, err := clients.NewPlacementV1Client() + th.AssertNoErr(t, err) + + client.Microversion = "1.38" + + // Act: Query usages for a project with no allocations. + totalUsages, err := usages.Get(context.TODO(), client, usages.GetOpts{ + ProjectID: "nonexistent-project-with-no-allocations", + }).Extract() + th.AssertNoErr(t, err) + + // Assert: Empty usages map. + th.AssertEquals(t, 0, len(totalUsages.Usages)) +} + +func TestGetUsagesPre138Success(t *testing.T) { + clients.RequireAdmin(t) + clients.SkipReleasesBelow(t, "stable/rocky") + + client, err := clients.NewPlacementV1Client() + th.AssertNoErr(t, err) + + resourceProvider, _, err := CreateResourceProviderWithVCPUInventory(t, client) + th.AssertNoErr(t, err) + defer DeleteResourceProvider(t, client, resourceProvider.UUID) + + consumerUUID := tools.RandomUUID() + defer allocations.Delete(context.TODO(), client, consumerUUID) + + projectID := "test-project" + userID := "test-user" + + client.Microversion = "1.28" + + // Arrange: Create allocations for a consumer. + err = allocations.Update(context.TODO(), client, consumerUUID, allocations.UpdateOpts{ + Allocations: map[string]allocations.ProviderAllocationsOpts{ + resourceProvider.UUID: { + Resources: map[string]int{"VCPU": 2, "MEMORY_MB": 1024}, + }, + }, + ProjectID: projectID, + UserID: userID, + ConsumerGeneration: nil, + }).ExtractErr() + th.AssertNoErr(t, err) + + // Act: Retrieve total usages for the project (pre-1.38, flat map). + totalUsages, err := usages.Get(context.TODO(), client, usages.GetOpts{ + ProjectID: projectID, + }).ExtractPre138() + th.AssertNoErr(t, err) + + // Assert: Usages reflect the allocations we just created. + th.AssertEquals(t, 2, totalUsages.Usages["VCPU"]) + th.AssertEquals(t, 1024, totalUsages.Usages["MEMORY_MB"]) + + tools.PrintResource(t, totalUsages) +} + +func TestGetUsagesPre138EmptySuccess(t *testing.T) { + clients.RequireAdmin(t) + clients.SkipReleasesBelow(t, "stable/rocky") + + client, err := clients.NewPlacementV1Client() + th.AssertNoErr(t, err) + + client.Microversion = "1.9" + + // Act: Query usages for a project with no allocations (pre-1.38). + totalUsages, err := usages.Get(context.TODO(), client, usages.GetOpts{ + ProjectID: "nonexistent-project-with-no-allocations", + }).ExtractPre138() + th.AssertNoErr(t, err) + + // Assert: Empty usages map. + th.AssertEquals(t, 0, len(totalUsages.Usages)) +} diff --git a/openstack/placement/v1/usages/doc.go b/openstack/placement/v1/usages/doc.go new file mode 100644 index 0000000000..ea629113b4 --- /dev/null +++ b/openstack/placement/v1/usages/doc.go @@ -0,0 +1,49 @@ +/* +Package usages retrieves total resource usage from the OpenStack Placement service. + +Usage API requests are available starting from microversion 1.9. + +# Example to get total usages grouped by consumer type (microversion 1.38+) + + placementClient.Microversion = "1.38" + + totalUsages, err := usages.Get(context.TODO(), placementClient, usages.GetOpts{ + ProjectID: projectID, + }).Extract() + if err != nil { + panic(err) + } + + for consumerType, usage := range totalUsages.Usages { + fmt.Printf("%s: VCPU=%d, consumer_count=%d\n", + consumerType, usage["VCPU"], usage["consumer_count"]) + } + +# Example to get total usages without consumer type grouping (microversion 1.9–1.37) + + placementClient.Microversion = "1.9" + + totalUsages, err := usages.Get(context.TODO(), placementClient, usages.GetOpts{ + ProjectID: projectID, + }).ExtractPre138() + if err != nil { + panic(err) + } + + fmt.Printf("VCPU usage: %d\n", totalUsages.Usages["VCPU"]) + +# Example to get total usages for a specific project and user + + placementClient.Microversion = "1.38" + + totalUsages, err := usages.Get(context.TODO(), placementClient, usages.GetOpts{ + ProjectID: projectID, + UserID: userID, + }).Extract() + if err != nil { + panic(err) + } + + fmt.Printf("%+v\n", totalUsages) +*/ +package usages diff --git a/openstack/placement/v1/usages/microversions.go b/openstack/placement/v1/usages/microversions.go new file mode 100644 index 0000000000..0b83cb06a6 --- /dev/null +++ b/openstack/placement/v1/usages/microversions.go @@ -0,0 +1,16 @@ +package usages + +// UsagesPre138 represents the total resource consumption for a project for +// microversions 1.9 through 1.37. In these versions, usages are not grouped +// by consumer type. +type UsagesPre138 struct { + // Usages maps resource class names to the total integer amount consumed. + Usages map[string]int `json:"usages"` +} + +// ExtractPre138 interprets a GetResult as UsagesPre138 (microversions 1.9–1.37). +func (r GetResult) ExtractPre138() (*UsagesPre138, error) { + var s UsagesPre138 + err := r.ExtractInto(&s) + return &s, err +} diff --git a/openstack/placement/v1/usages/requests.go b/openstack/placement/v1/usages/requests.go new file mode 100644 index 0000000000..0deedf8096 --- /dev/null +++ b/openstack/placement/v1/usages/requests.go @@ -0,0 +1,59 @@ +package usages + +import ( + "context" + "net/http" + + "github.com/gophercloud/gophercloud/v2" +) + +// GetOptsBuilder allows extensions to add additional parameters to the +// Get request. +type GetOptsBuilder interface { + ToUsagesGetQuery() (string, error) +} + +// GetOpts specifies the query parameters for retrieving total usages. +// +// This requires microversion 1.9 or later. +type GetOpts struct { + // ProjectID is required: only usages for this project are returned. + ProjectID string `q:"project_id"` + + // UserID is optional: when set, only usages for this user within the + // project are returned. + UserID string `q:"user_id,omitempty"` + + // ConsumerType is optional: when set, results are filtered to this consumer type. + // Available from microversion 1.38. + ConsumerType string `q:"consumer_type,omitempty"` +} + +// ToUsagesGetQuery formats a GetOpts into a query string. +func (opts GetOpts) ToUsagesGetQuery() (string, error) { + q, err := gophercloud.BuildQueryString(opts) + if err != nil { + return "", err + } + return q.String(), nil +} + +// Get retrieves the total resource usages for a project (and optionally a user). +// +// Requires microversion 1.9 or later. +func Get(ctx context.Context, client *gophercloud.ServiceClient, opts GetOptsBuilder) (r GetResult) { + url := getURL(client) + if opts != nil { + query, err := opts.ToUsagesGetQuery() + if err != nil { + r.Err = err + return + } + url += query + } + resp, err := client.Get(ctx, url, &r.Body, &gophercloud.RequestOpts{ + OkCodes: []int{http.StatusOK}, + }) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} diff --git a/openstack/placement/v1/usages/results.go b/openstack/placement/v1/usages/results.go new file mode 100644 index 0000000000..ad19fee31b --- /dev/null +++ b/openstack/placement/v1/usages/results.go @@ -0,0 +1,33 @@ +package usages + +import "github.com/gophercloud/gophercloud/v2" + +// ConsumerTypeUsage maps resource class names to the total integer amount +// consumed by consumers of a given type. The special key "consumer_count" +// holds the number of consumers of this type. +type ConsumerTypeUsage map[string]int + +// Usages represents the total resource consumption for a project, grouped by +// consumer type. This is the response shape for microversion 1.38 and later. +// +// Each key in the Usages map is a consumer type name (e.g. "INSTANCE"). +// The value is a ConsumerTypeUsage containing resource class totals and a +// consumer_count entry. +type Usages struct { + // Usages maps consumer type names to their aggregated resource usage. + Usages map[string]ConsumerTypeUsage `json:"usages"` +} + +// GetResult is the result of a Get operation. Call its Extract method +// to interpret it as Usages (microversion 1.38+), or ExtractPre138 for +// earlier microversions. +type GetResult struct { + gophercloud.Result +} + +// Extract interprets a GetResult as Usages (microversion 1.38+). +func (r GetResult) Extract() (*Usages, error) { + var s Usages + err := r.ExtractInto(&s) + return &s, err +} diff --git a/openstack/placement/v1/usages/testing/doc.go b/openstack/placement/v1/usages/testing/doc.go new file mode 100644 index 0000000000..ed99c1eafa --- /dev/null +++ b/openstack/placement/v1/usages/testing/doc.go @@ -0,0 +1,2 @@ +// usages unit tests. +package testing diff --git a/openstack/placement/v1/usages/testing/fixtures_test.go b/openstack/placement/v1/usages/testing/fixtures_test.go new file mode 100644 index 0000000000..a1f9de05d4 --- /dev/null +++ b/openstack/placement/v1/usages/testing/fixtures_test.go @@ -0,0 +1,172 @@ +package testing + +import ( + "fmt" + "net/http" + "testing" + + "github.com/gophercloud/gophercloud/v2/openstack/placement/v1/usages" + th "github.com/gophercloud/gophercloud/v2/testhelper" + "github.com/gophercloud/gophercloud/v2/testhelper/client" +) + +const ProjectID = "42a2b0fa980d4f7f873e8f0d8b4e1b0e" +const UserID = "b29d880b2c114d5d9a55748b26b2e41e" + +var GetUsagesBody = ` +{ + "usages": { + "INSTANCE": { + "VCPU": 2, + "MEMORY_MB": 2048, + "consumer_count": 1 + } + } +} +` + +var ExpectedUsages = usages.Usages{ + Usages: map[string]usages.ConsumerTypeUsage{ + "INSTANCE": { + "VCPU": 2, + "MEMORY_MB": 2048, + "consumer_count": 1, + }, + }, +} + +var GetUsagesWithUserBody = ` +{ + "usages": { + "INSTANCE": { + "VCPU": 2, + "MEMORY_MB": 2048, + "consumer_count": 1 + } + } +} +` + +var GetEmptyUsagesBody = ` +{ + "usages": {} +} +` + +var ExpectedEmptyUsages = usages.Usages{ + Usages: map[string]usages.ConsumerTypeUsage{}, +} + +var GetUsagesPre138Body = ` +{ + "usages": { + "VCPU": 2, + "MEMORY_MB": 2048 + } +} +` + +var ExpectedUsagesPre138 = usages.UsagesPre138{ + Usages: map[string]int{ + "VCPU": 2, + "MEMORY_MB": 2048, + }, +} + +var GetEmptyUsagesPre138Body = ` +{ + "usages": {} +} +` + +var ExpectedEmptyUsagesPre138 = usages.UsagesPre138{ + Usages: map[string]int{}, +} + +func HandleGetUsagesSuccess(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/usages", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + th.AssertEquals(t, ProjectID, r.URL.Query().Get("project_id")) + th.AssertEquals(t, "", r.URL.Query().Get("user_id")) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + + fmt.Fprint(w, GetUsagesBody) + }) +} + +func HandleGetUsagesWithUserSuccess(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/usages", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + th.AssertEquals(t, ProjectID, r.URL.Query().Get("project_id")) + th.AssertEquals(t, UserID, r.URL.Query().Get("user_id")) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + + fmt.Fprint(w, GetUsagesWithUserBody) + }) +} + +func HandleGetEmptyUsagesSuccess(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/usages", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + th.AssertEquals(t, ProjectID, r.URL.Query().Get("project_id")) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + + fmt.Fprint(w, GetEmptyUsagesBody) + }) +} + +func HandleGetUsagesPre138Success(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/usages", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + th.AssertEquals(t, ProjectID, r.URL.Query().Get("project_id")) + th.AssertEquals(t, "", r.URL.Query().Get("user_id")) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + + fmt.Fprint(w, GetUsagesPre138Body) + }) +} + +func HandleGetUsagesPre138WithUserSuccess(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/usages", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + th.AssertEquals(t, ProjectID, r.URL.Query().Get("project_id")) + th.AssertEquals(t, UserID, r.URL.Query().Get("user_id")) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + + fmt.Fprint(w, GetUsagesPre138Body) + }) +} + +func HandleGetEmptyUsagesPre138Success(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/usages", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + th.AssertEquals(t, ProjectID, r.URL.Query().Get("project_id")) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + + fmt.Fprint(w, GetEmptyUsagesPre138Body) + }) +} diff --git a/openstack/placement/v1/usages/testing/requests_test.go b/openstack/placement/v1/usages/testing/requests_test.go new file mode 100644 index 0000000000..022a1b9999 --- /dev/null +++ b/openstack/placement/v1/usages/testing/requests_test.go @@ -0,0 +1,90 @@ +package testing + +import ( + "context" + "testing" + + "github.com/gophercloud/gophercloud/v2/openstack/placement/v1/usages" + th "github.com/gophercloud/gophercloud/v2/testhelper" + "github.com/gophercloud/gophercloud/v2/testhelper/client" +) + +func TestGetSuccess(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleGetUsagesSuccess(t, fakeServer) + + actual, err := usages.Get(context.TODO(), client.ServiceClient(fakeServer), usages.GetOpts{ + ProjectID: ProjectID, + }).Extract() + th.AssertNoErr(t, err) + th.AssertDeepEquals(t, ExpectedUsages, *actual) +} + +func TestGetWithUserSuccess(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleGetUsagesWithUserSuccess(t, fakeServer) + + actual, err := usages.Get(context.TODO(), client.ServiceClient(fakeServer), usages.GetOpts{ + ProjectID: ProjectID, + UserID: UserID, + }).Extract() + th.AssertNoErr(t, err) + th.AssertDeepEquals(t, ExpectedUsages, *actual) +} + +func TestGetEmptySuccess(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleGetEmptyUsagesSuccess(t, fakeServer) + + actual, err := usages.Get(context.TODO(), client.ServiceClient(fakeServer), usages.GetOpts{ + ProjectID: ProjectID, + }).Extract() + th.AssertNoErr(t, err) + th.AssertDeepEquals(t, ExpectedEmptyUsages, *actual) +} + +func TestGetPre138Success(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleGetUsagesPre138Success(t, fakeServer) + + actual, err := usages.Get(context.TODO(), client.ServiceClient(fakeServer), usages.GetOpts{ + ProjectID: ProjectID, + }).ExtractPre138() + th.AssertNoErr(t, err) + th.AssertDeepEquals(t, ExpectedUsagesPre138, *actual) +} + +func TestGetPre138WithUserSuccess(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleGetUsagesPre138WithUserSuccess(t, fakeServer) + + actual, err := usages.Get(context.TODO(), client.ServiceClient(fakeServer), usages.GetOpts{ + ProjectID: ProjectID, + UserID: UserID, + }).ExtractPre138() + th.AssertNoErr(t, err) + th.AssertDeepEquals(t, ExpectedUsagesPre138, *actual) +} + +func TestGetPre138EmptySuccess(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleGetEmptyUsagesPre138Success(t, fakeServer) + + actual, err := usages.Get(context.TODO(), client.ServiceClient(fakeServer), usages.GetOpts{ + ProjectID: ProjectID, + }).ExtractPre138() + th.AssertNoErr(t, err) + th.AssertDeepEquals(t, ExpectedEmptyUsagesPre138, *actual) +} diff --git a/openstack/placement/v1/usages/urls.go b/openstack/placement/v1/usages/urls.go new file mode 100644 index 0000000000..5de8523797 --- /dev/null +++ b/openstack/placement/v1/usages/urls.go @@ -0,0 +1,7 @@ +package usages + +import "github.com/gophercloud/gophercloud/v2" + +func getURL(client *gophercloud.ServiceClient) string { + return client.ServiceURL("usages") +} From a2fc57ed3efaed8b61039e538f8ac333146047d2 Mon Sep 17 00:00:00 2001 From: Dominik Danelski Date: Mon, 4 May 2026 12:16:34 +0200 Subject: [PATCH 322/353] Leverage RandomUUID() in Placement resourceproviders tests Signed-off-by: Dominik Danelski --- .../placement/v1/resourceproviders_test.go | 23 +++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/internal/acceptance/openstack/placement/v1/resourceproviders_test.go b/internal/acceptance/openstack/placement/v1/resourceproviders_test.go index 3babbf9006..4b2f70d819 100644 --- a/internal/acceptance/openstack/placement/v1/resourceproviders_test.go +++ b/internal/acceptance/openstack/placement/v1/resourceproviders_test.go @@ -17,7 +17,6 @@ import ( const InventoryResourceClass = "VCPU" const MissingInventoryResourceClass = "NO_SUCH_CLASS" -const NonExistentRPUUID = "00000000-0000-0000-0000-000000000000" func TestResourceProviderList(t *testing.T) { clients.RequireAdmin(t) @@ -248,7 +247,7 @@ func TestResourceProviderUpdateInventoryNotFound(t *testing.T) { }, } - _, err = resourceproviders.UpdateInventory(context.TODO(), client, NonExistentRPUUID, InventoryResourceClass, updateOpts).Extract() + _, err = resourceproviders.UpdateInventory(context.TODO(), client, tools.RandomUUID(), InventoryResourceClass, updateOpts).Extract() th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusNotFound)) } @@ -413,7 +412,7 @@ func TestResourceProviderUpdateInventoriesNotFound(t *testing.T) { }, } - _, err = resourceproviders.UpdateInventories(context.TODO(), client, NonExistentRPUUID, updateOpts).Extract() + _, err = resourceproviders.UpdateInventories(context.TODO(), client, tools.RandomUUID(), updateOpts).Extract() th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusNotFound)) } @@ -487,11 +486,11 @@ func TestResourceProviderAggregatesNotFound(t *testing.T) { th.AssertNoErr(t, err) client.Microversion = "1.19" - _, err = resourceproviders.GetAggregates(context.TODO(), client, "00000000-0000-0000-0000-000000000000").Extract() + _, err = resourceproviders.GetAggregates(context.TODO(), client, tools.RandomUUID()).Extract() th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusNotFound)) client.Microversion = "1.1" - _, err = resourceproviders.GetAggregates(context.TODO(), client, "00000000-0000-0000-0000-000000000000").Extract() + _, err = resourceproviders.GetAggregates(context.TODO(), client, tools.RandomUUID()).Extract() th.AssertEquals(t, true, gophercloud.ResponseCodeIs(err, http.StatusNotFound)) } @@ -515,8 +514,8 @@ func TestResourceProviderUpdateAggregates(t *testing.T) { updateOpts := resourceproviders.UpdateAggregatesOpts{ ResourceProviderGeneration: before.ResourceProviderGeneration, Aggregates: []string{ - "6d84f6f6-7736-40ff-84d2-7db47f18ea25", - "f11f14bc-6f17-4f0a-b7c2-44b3e685ccf4", + tools.RandomUUID(), + tools.RandomUUID(), }, } @@ -553,7 +552,7 @@ func TestResourceProviderUpdateAggregateMismatch(t *testing.T) { updateOpts := resourceproviders.UpdateAggregatesOpts{ ResourceProviderGeneration: &wrongGeneration, Aggregates: []string{ - "6d84f6f6-7736-40ff-84d2-7db47f18ea25", + tools.RandomUUID(), }, } @@ -576,8 +575,8 @@ func TestResourceProviderUpdateAggregatesPreGeneration(t *testing.T) { updateOpts := resourceproviders.UpdateAggregatesOpts{ Aggregates: []string{ - "6d84f6f6-7736-40ff-84d2-7db47f18ea25", - "f11f14bc-6f17-4f0a-b7c2-44b3e685ccf4", + tools.RandomUUID(), + tools.RandomUUID(), }, } @@ -612,8 +611,8 @@ func TestResourceProviderUpdateAggregatesPreGenerationWithGenerationSuccess(t *t updateOpts := resourceproviders.UpdateAggregatesOpts{ ResourceProviderGeneration: &gen, Aggregates: []string{ - "6d84f6f6-7736-40ff-84d2-7db47f18ea25", - "f11f14bc-6f17-4f0a-b7c2-44b3e685ccf4", + tools.RandomUUID(), + tools.RandomUUID(), }, } From 7f57fb2f30e837e1c84244f791576ecf6dd0bd9a Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Tue, 5 May 2026 12:41:48 +0100 Subject: [PATCH 323/353] trivial: Replace reflect.Ptr with reflect.Pointer The former is a deprecated alias for the latter. Signed-off-by: Stephen Finucane --- params.go | 34 +++++++++++++++++----------------- results.go | 6 +++--- testhelper/convenience.go | 2 +- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/params.go b/params.go index e282033683..ddb61b3d08 100644 --- a/params.go +++ b/params.go @@ -58,12 +58,12 @@ above. */ func BuildRequestBody(opts any, parent string) (map[string]any, error) { optsValue := reflect.ValueOf(opts) - if optsValue.Kind() == reflect.Ptr { + if optsValue.Kind() == reflect.Pointer { optsValue = optsValue.Elem() } optsType := reflect.TypeOf(opts) - if optsType.Kind() == reflect.Ptr { + if optsType.Kind() == reflect.Pointer { optsType = optsType.Elem() } @@ -104,7 +104,7 @@ func BuildRequestBody(opts any, parent string) (map[string]any, error) { if reflect.ValueOf(xorField.Interface()) == reflect.Zero(xorField.Type()) { xorFieldIsZero = true } else { - if xorField.Kind() == reflect.Ptr { + if xorField.Kind() == reflect.Pointer { xorField = xorField.Elem() } xorFieldIsZero = isZero(xorField) @@ -126,7 +126,7 @@ func BuildRequestBody(opts any, parent string) (map[string]any, error) { if reflect.ValueOf(orField.Interface()) == reflect.Zero(orField.Type()) { orFieldIsZero = true } else { - if orField.Kind() == reflect.Ptr { + if orField.Kind() == reflect.Pointer { orField = orField.Elem() } orFieldIsZero = isZero(orField) @@ -145,15 +145,15 @@ func BuildRequestBody(opts any, parent string) (map[string]any, error) { continue } - if v.Kind() == reflect.Slice || (v.Kind() == reflect.Ptr && v.Elem().Kind() == reflect.Slice) { + if v.Kind() == reflect.Slice || (v.Kind() == reflect.Pointer && v.Elem().Kind() == reflect.Slice) { sliceValue := v - if sliceValue.Kind() == reflect.Ptr { + if sliceValue.Kind() == reflect.Pointer { sliceValue = sliceValue.Elem() } for i := 0; i < sliceValue.Len(); i++ { element := sliceValue.Index(i) - if element.Kind() == reflect.Struct || (element.Kind() == reflect.Ptr && element.Elem().Kind() == reflect.Struct) { + if element.Kind() == reflect.Struct || (element.Kind() == reflect.Pointer && element.Elem().Kind() == reflect.Struct) { _, err := BuildRequestBody(element.Interface(), "") if err != nil { return nil, err @@ -161,7 +161,7 @@ func BuildRequestBody(opts any, parent string) (map[string]any, error) { } } } - if v.Kind() == reflect.Struct || (v.Kind() == reflect.Ptr && v.Elem().Kind() == reflect.Struct) { + if v.Kind() == reflect.Struct || (v.Kind() == reflect.Pointer && v.Elem().Kind() == reflect.Struct) { if zero { //fmt.Printf("value before change: %+v\n", optsValue.Field(i)) if jsonTag != "" { @@ -169,7 +169,7 @@ func BuildRequestBody(opts any, parent string) (map[string]any, error) { if len(jsonTagPieces) > 1 && jsonTagPieces[1] == "omitempty" { if v.CanSet() { if !v.IsNil() { - if v.Kind() == reflect.Ptr { + if v.Kind() == reflect.Pointer { v.Set(reflect.Zero(v.Type())) } } @@ -292,7 +292,7 @@ func MaybeInt(original int) *int { /* func isUnderlyingStructZero(v reflect.Value) bool { switch v.Kind() { - case reflect.Ptr: + case reflect.Pointer: return isUnderlyingStructZero(v.Elem()) default: return isZero(v) @@ -305,7 +305,7 @@ var t time.Time func isZero(v reflect.Value) bool { //fmt.Printf("\n\nchecking isZero for value: %+v\n", v) switch v.Kind() { - case reflect.Ptr: + case reflect.Pointer: if v.IsNil() { return true } @@ -365,12 +365,12 @@ Slice are handled in one of two ways: */ func BuildQueryString(opts any) (*url.URL, error) { optsValue := reflect.ValueOf(opts) - if optsValue.Kind() == reflect.Ptr { + if optsValue.Kind() == reflect.Pointer { optsValue = optsValue.Elem() } optsType := reflect.TypeOf(opts) - if optsType.Kind() == reflect.Ptr { + if optsType.Kind() == reflect.Pointer { optsType = optsType.Elem() } @@ -390,7 +390,7 @@ func BuildQueryString(opts any) (*url.URL, error) { if !isZero(v) { loop: switch v.Kind() { - case reflect.Ptr: + case reflect.Pointer: v = v.Elem() goto loop case reflect.String: @@ -471,12 +471,12 @@ booleans and string values are supported. */ func BuildHeaders(opts any) (map[string]string, error) { optsValue := reflect.ValueOf(opts) - if optsValue.Kind() == reflect.Ptr { + if optsValue.Kind() == reflect.Pointer { optsValue = optsValue.Elem() } optsType := reflect.TypeOf(opts) - if optsType.Kind() == reflect.Ptr { + if optsType.Kind() == reflect.Pointer { optsType = optsType.Elem() } @@ -493,7 +493,7 @@ func BuildHeaders(opts any) (map[string]string, error) { // if the field is set, add it to the slice of query pieces if !isZero(v) { - if v.Kind() == reflect.Ptr { + if v.Kind() == reflect.Pointer { v = v.Elem() } switch v.Kind() { diff --git a/results.go b/results.go index 101a7d24dc..3ca191683e 100644 --- a/results.go +++ b/results.go @@ -84,7 +84,7 @@ func (r Result) extractIntoPtr(to any, label string) error { } toValue := reflect.ValueOf(to) - if toValue.Kind() == reflect.Ptr { + if toValue.Kind() == reflect.Pointer { toValue = toValue.Elem() } @@ -192,7 +192,7 @@ func (r Result) ExtractIntoStructPtr(to any, label string) error { } t := reflect.TypeOf(to) - if k := t.Kind(); k != reflect.Ptr { + if k := t.Kind(); k != reflect.Pointer { return fmt.Errorf("expected pointer, got %v", k) } @@ -227,7 +227,7 @@ func (r Result) ExtractIntoSlicePtr(to any, label string) error { } t := reflect.TypeOf(to) - if k := t.Kind(); k != reflect.Ptr { + if k := t.Kind(); k != reflect.Pointer { return fmt.Errorf("expected pointer, got %v", k) } diff --git a/testhelper/convenience.go b/testhelper/convenience.go index 57fa558fd1..9c61d48cf5 100644 --- a/testhelper/convenience.go +++ b/testhelper/convenience.go @@ -142,7 +142,7 @@ func deepDiffEqual(expected, actual reflect.Value, visited map[visit]bool, path } deepDiffEqual(expected.Elem(), actual.Elem(), visited, path, logDifference) return - case reflect.Ptr: + case reflect.Pointer: deepDiffEqual(expected.Elem(), actual.Elem(), visited, path, logDifference) return case reflect.Struct: From 714a26c49733df3552a850df66b9205a3d17627d Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Tue, 5 May 2026 12:38:20 +0100 Subject: [PATCH 324/353] Bump golangci-lint Signed-off-by: Stephen Finucane --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 6b9d043cf2..9041e0c4fd 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ undefine GOFLAGS -GOLANGCI_LINT_VERSION?=v2.5.0 +GOLANGCI_LINT_VERSION?=v2.12.1 GOTESTSUM_VERSION?=v1.13.0 GO_TEST?=go run gotest.tools/gotestsum@$(GOTESTSUM_VERSION) --format testname -- TIMEOUT := "60m" From 96169a33038999446d820836a0e2a8d161985d7e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 May 2026 14:49:34 +0000 Subject: [PATCH 325/353] build(deps): bump actions/labeler from 6.0.1 to 6.1.0 Bumps [actions/labeler](https://github.com/actions/labeler) from 6.0.1 to 6.1.0. - [Release notes](https://github.com/actions/labeler/releases) - [Commits](https://github.com/actions/labeler/compare/634933edcd8ababfe52f92936142cc22ac488b1b...f27b608878404679385c85cfa523b85ccb86e213) --- updated-dependencies: - dependency-name: actions/labeler dependency-version: 6.1.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/label-pr.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/label-pr.yaml b/.github/workflows/label-pr.yaml index de5d9a52b0..abb676ac04 100644 --- a/.github/workflows/label-pr.yaml +++ b/.github/workflows/label-pr.yaml @@ -109,4 +109,4 @@ jobs: contents: read pull-requests: write steps: - - uses: actions/labeler@634933edcd8ababfe52f92936142cc22ac488b1b # v6 + - uses: actions/labeler@f27b608878404679385c85cfa523b85ccb86e213 # v6 From 78cbe68022b7f3ef9251b90cdc47cd01bb3fb617 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 14 May 2026 09:23:00 +0000 Subject: [PATCH 326/353] build(deps): bump github/codeql-action from 4.35.2 to 4.35.4 Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.35.2 to 4.35.4. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/95e58e9a2cdfd71adc6e0353d5c52f41a045d225...68bde559dea0fdcac2102bfdf6230c5f70eb485e) --- updated-dependencies: - dependency-name: github/codeql-action dependency-version: 4.35.4 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/codeql-analysis.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql-analysis.yaml b/.github/workflows/codeql-analysis.yaml index fdc009036f..6b3a3ceee3 100644 --- a/.github/workflows/codeql-analysis.yaml +++ b/.github/workflows/codeql-analysis.yaml @@ -29,12 +29,12 @@ jobs: cache: true - name: Initialize CodeQL - uses: github/codeql-action/init@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4 + uses: github/codeql-action/init@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4 with: languages: ${{ matrix.language }} - name: Autobuild - uses: github/codeql-action/autobuild@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4 + uses: github/codeql-action/autobuild@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4 + uses: github/codeql-action/analyze@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4 From dd535b95e1a4f207eb8c853ea6bbc1795395a812 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 May 2026 17:08:55 +0000 Subject: [PATCH 327/353] build(deps): bump golang.org/x/crypto from 0.50.0 to 0.51.0 Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.50.0 to 0.51.0. - [Commits](https://github.com/golang/crypto/compare/v0.50.0...v0.51.0) --- updated-dependencies: - dependency-name: golang.org/x/crypto dependency-version: 0.51.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 4 ++-- go.sum | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/go.mod b/go.mod index 006d43c5ee..3dd692fc81 100644 --- a/go.mod +++ b/go.mod @@ -3,8 +3,8 @@ module github.com/gophercloud/gophercloud/v2 go 1.25.0 require ( - golang.org/x/crypto v0.50.0 + golang.org/x/crypto v0.51.0 gopkg.in/yaml.v2 v2.4.0 ) -require golang.org/x/sys v0.43.0 // indirect +require golang.org/x/sys v0.44.0 // indirect diff --git a/go.sum b/go.sum index 9bf6d4b97d..76b00b7aaf 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,9 @@ -golang.org/x/crypto v0.50.0 h1:zO47/JPrL6vsNkINmLoo/PH1gcxpls50DNogFvB5ZGI= -golang.org/x/crypto v0.50.0/go.mod h1:3muZ7vA7PBCE6xgPX7nkzzjiUq87kRItoJQM1Yo8S+Q= -golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI= -golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= -golang.org/x/term v0.42.0 h1:UiKe+zDFmJobeJ5ggPwOshJIVt6/Ft0rcfrXZDLWAWY= -golang.org/x/term v0.42.0/go.mod h1:Dq/D+snpsbazcBG5+F9Q1n2rXV8Ma+71xEjTRufARgY= +golang.org/x/crypto v0.51.0 h1:IBPXwPfKxY7cWQZ38ZCIRPI50YLeevDLlLnyC5wRGTI= +golang.org/x/crypto v0.51.0/go.mod h1:8AdwkbraGNABw2kOX6YFPs3WM22XqI4EXEd8g+x7Oc8= +golang.org/x/sys v0.44.0 h1:ildZl3J4uzeKP07r2F++Op7E9B29JRUy+a27EibtBTQ= +golang.org/x/sys v0.44.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/term v0.43.0 h1:S4RLU2sB31O/NCl+zFN9Aru9A/Cq2aqKpTZJ6B+DwT4= +golang.org/x/term v0.43.0/go.mod h1:lrhlHNdQJHO+1qVYiHfFKVuVioJIheAc3fBSMFYEIsk= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= From 56188a1cabc10a7af13e6194b2e26c176a910748 Mon Sep 17 00:00:00 2001 From: Winicius Silva Date: Thu, 14 May 2026 20:10:11 +0100 Subject: [PATCH 328/353] fix(vpnaas): change encryption and auth method on acceptance tests The SHA1, MD5, DES, and 3DES were deprecated in a recent neutron-vpnaas patch[1], leading functional-network tests to fail, because it was still using the deprecated algorithms when creating IKEPolicies and IPSecPolicies. [1] https://review.opendev.org/c/openstack/neutron-vpnaas/+/982383 --- .../openstack/networking/v2/extensions/vpnaas/vpnaas.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/internal/acceptance/openstack/networking/v2/extensions/vpnaas/vpnaas.go b/internal/acceptance/openstack/networking/v2/extensions/vpnaas/vpnaas.go index 07b9e38839..76652134ea 100644 --- a/internal/acceptance/openstack/networking/v2/extensions/vpnaas/vpnaas.go +++ b/internal/acceptance/openstack/networking/v2/extensions/vpnaas/vpnaas.go @@ -61,7 +61,9 @@ func CreateIPSecPolicy(t *testing.T, client *gophercloud.ServiceClient) (*ipsecp t.Logf("Attempting to create IPSec policy %s", policyName) createOpts := ipsecpolicies.CreateOpts{ - Name: policyName, + Name: policyName, + EncryptionAlgorithm: ipsecpolicies.EncryptionAlgorithmAES128, + AuthAlgorithm: ipsecpolicies.AuthAlgorithmAESCMAC, } policy, err := ipsecpolicies.Create(context.TODO(), client, createOpts).Extract() @@ -85,8 +87,9 @@ func CreateIKEPolicy(t *testing.T, client *gophercloud.ServiceClient) (*ikepolic createOpts := ikepolicies.CreateOpts{ Name: policyName, - EncryptionAlgorithm: ikepolicies.EncryptionAlgorithm3DES, + EncryptionAlgorithm: ikepolicies.EncryptionAlgorithmAES128, PFS: ikepolicies.PFSGroup5, + AuthAlgorithm: ikepolicies.AuthAlgorithmSHA256, } policy, err := ikepolicies.Create(context.TODO(), client, createOpts).Extract() @@ -195,7 +198,6 @@ func DeleteEndpointGroup(t *testing.T, client *gophercloud.ServiceClient, epGrou } t.Logf("Deleted endpoint group: %s", epGroupID) - } // CreateEndpointGroupWithSubnet will create an endpoint group with a random name. From ba183809b547ceb76ec6bf638dd797ce02613cce Mon Sep 17 00:00:00 2001 From: Dominik Danelski Date: Wed, 13 May 2026 19:22:12 +0200 Subject: [PATCH 329/353] Allow clearing Placement resource provider parent_provider_uuid Current implementation describes the possibility to set parent_provider_uuid for a child resource provider to detach it from its parent, but actually doesn't allow it due to the use of omitempty which would clear such nil input. To allow for this operation, I introduce the empty value of "" replaced by nil before being sent. This pattern allows for parent_provider_uuid to remain an optional argument just as in the API. Such pattern was previously introduced in DNS recordsets. Fixes #3746 Signed-off-by: Dominik Danelski --- .../placement/v1/resourceproviders_test.go | 38 +++++++++++++++++++ .../placement/v1/resourceproviders/doc.go | 33 +++++++++++++--- .../v1/resourceproviders/requests.go | 18 ++++++--- .../testing/requests_test.go | 33 ++++++++++++++++ 4 files changed, 111 insertions(+), 11 deletions(-) diff --git a/internal/acceptance/openstack/placement/v1/resourceproviders_test.go b/internal/acceptance/openstack/placement/v1/resourceproviders_test.go index 4b2f70d819..ee4e22ec9c 100644 --- a/internal/acceptance/openstack/placement/v1/resourceproviders_test.go +++ b/internal/acceptance/openstack/placement/v1/resourceproviders_test.go @@ -627,3 +627,41 @@ func TestResourceProviderUpdateAggregatesPreGenerationWithGenerationSuccess(t *t th.AssertEquals(t, true, slices.Contains(after.Aggregates, aggregate)) } } + +func TestResourceProviderParentDetach(t *testing.T) { + clients.RequireAdmin(t) + + client, err := clients.NewPlacementV1Client() + th.AssertNoErr(t, err) + + // Arrange: Create a parent resource provider + parentProvider, err := CreateResourceProvider(t, client) + th.AssertNoErr(t, err) + defer DeleteResourceProvider(t, client, parentProvider.UUID) + + // Arrange: Create a child resource provider with that parent + childProvider, err := CreateResourceProviderWithParent(t, client, parentProvider.UUID) + th.AssertNoErr(t, err) + defer DeleteResourceProvider(t, client, childProvider.UUID) + + // Sanity check: Verify that the child provider has the correct parent before the update + th.AssertEquals(t, parentProvider.UUID, childProvider.ParentProviderUUID) + + // Act: Update the child resource provider to remove the parent (transform to root) + client.Microversion = "1.37" + empty := "" + updateOpts := resourceproviders.UpdateOpts{ + Name: &childProvider.Name, + ParentProviderUUID: &empty, + } + updatedChild, err := resourceproviders.Update(context.TODO(), client, childProvider.UUID, updateOpts).Extract() + th.AssertNoErr(t, err) + + // Assert: Verify that the ParentProviderUUID is now null (empty string in Gophercloud result struct) + th.AssertEquals(t, "", updatedChild.ParentProviderUUID) + + // Assert: Double check with a Get request + childGet, err := resourceproviders.Get(context.TODO(), client, childProvider.UUID).Extract() + th.AssertNoErr(t, err) + th.AssertEquals(t, "", childGet.ParentProviderUUID) +} diff --git a/openstack/placement/v1/resourceproviders/doc.go b/openstack/placement/v1/resourceproviders/doc.go index d0a6caa515..120affca67 100644 --- a/openstack/placement/v1/resourceproviders/doc.go +++ b/openstack/placement/v1/resourceproviders/doc.go @@ -20,9 +20,9 @@ Example to list resource providers Example to create resource providers createOpts := resourceproviders.CreateOpts{ - Name: "new-rp", - UUID: "b99b3ab4-3aa6-4fba-b827-69b88b9c544a", - ParentProvider: "c7f50b40-6f32-4d7a-9f32-9384057be83b" + Name: "new-rp", + UUID: "b99b3ab4-3aa6-4fba-b827-69b88b9c544a", + ParentProviderUUID: "c7f50b40-6f32-4d7a-9f32-9384057be83b", } rp, err := resourceproviders.Create(context.TODO(), placementClient, createOpts).Extract() @@ -49,14 +49,35 @@ Example to Get a resource provider Example to Update a resource provider resourceProviderID := "b99b3ab4-3aa6-4fba-b827-69b88b9c544a" + name := "new-rp" + parent := "c7f50b40-6f32-4d7a-9f32-9384057be83b" updateOpts := resourceproviders.UpdateOpts{ - Name: "new-rp", - ParentProvider: "c7f50b40-6f32-4d7a-9f32-9384057be83b" + Name: &name, + ParentProviderUUID: &parent, } placementClient.Microversion = "1.37" - resourceProvider, err := resourceproviders.Update(context.TODO(), placementClient, resourceProviderID).Extract() + resourceProvider, err := resourceproviders.Update(context.TODO(), placementClient, resourceProviderID, updateOpts).Extract() + if err != nil { + panic(err) + } + +Example to transform a provider to a new root provider (set parent_provider_uuid to null). +Note that Gophercloud uses an empty string as a sentinel value to represent JSON null +for this optional field. + + resourceProviderID := "b99b3ab4-3aa6-4fba-b827-69b88b9c544a" + name := "existing-rp" + parent := "" + + updateOpts := resourceproviders.UpdateOpts{ + Name: &name, + ParentProviderUUID: &parent, + } + + placementClient.Microversion = "1.37" + resourceProvider, err = resourceproviders.Update(context.TODO(), placementClient, resourceProviderID, updateOpts).Extract() if err != nil { panic(err) } diff --git a/openstack/placement/v1/resourceproviders/requests.go b/openstack/placement/v1/resourceproviders/requests.go index aecc975060..603d8eea7f 100644 --- a/openstack/placement/v1/resourceproviders/requests.go +++ b/openstack/placement/v1/resourceproviders/requests.go @@ -126,16 +126,24 @@ type UpdateOptsBuilder interface { type UpdateOpts struct { Name *string `json:"name,omitempty"` // Available in version >= 1.37. It can be set to any existing provider UUID - // except to providers that would cause a loop. Also it can be set to null - // to transform the provider to a new root provider. This operation needs to - // be used carefully. Moving providers can mean that the original rules used - // to create the existing resource allocations may be invalidated by that move. + // except to providers that would cause a loop. Using an empty string + // transforms the provider to a new root provider. ParentProviderUUID *string `json:"parent_provider_uuid,omitempty"` } // ToResourceProviderUpdateMap constructs a request body from UpdateOpts. func (opts UpdateOpts) ToResourceProviderUpdateMap() (map[string]any, error) { - return gophercloud.BuildRequestBody(opts, "") + b, err := gophercloud.BuildRequestBody(opts, "") + if err != nil { + return nil, err + } + + // In order to set this to null, use an empty string as a value. + if opts.ParentProviderUUID != nil && *opts.ParentProviderUUID == "" { + b["parent_provider_uuid"] = nil + } + + return b, nil } // Update makes a request against the API to create a resource provider diff --git a/openstack/placement/v1/resourceproviders/testing/requests_test.go b/openstack/placement/v1/resourceproviders/testing/requests_test.go index 36909fb3df..1e316c46ff 100644 --- a/openstack/placement/v1/resourceproviders/testing/requests_test.go +++ b/openstack/placement/v1/resourceproviders/testing/requests_test.go @@ -104,6 +104,39 @@ func TestUpdate(t *testing.T) { th.AssertEquals(t, rp.ParentProviderUUID, parentProviderUUID) } +func TestUpdateParentProviderUUID(t *testing.T) { + // 1. Test non-empty UUID + uuid := "b99b3ab4-3aa6-4fba-b827-69b88b9c544a" + opts := resourceproviders.UpdateOpts{ + ParentProviderUUID: &uuid, + } + actual, err := opts.ToResourceProviderUpdateMap() + th.AssertNoErr(t, err) + expected := map[string]any{ + "parent_provider_uuid": uuid, + } + th.AssertDeepEquals(t, expected, actual) + + // 2. Test empty string sentinel (should be null) + empty := "" + opts = resourceproviders.UpdateOpts{ + ParentProviderUUID: &empty, + } + actual, err = opts.ToResourceProviderUpdateMap() + th.AssertNoErr(t, err) + expected = map[string]any{ + "parent_provider_uuid": nil, + } + th.AssertDeepEquals(t, expected, actual) + + // 3. Test nil (should be omitted) + opts = resourceproviders.UpdateOpts{} + actual, err = opts.ToResourceProviderUpdateMap() + th.AssertNoErr(t, err) + expected = map[string]any{} + th.AssertDeepEquals(t, expected, actual) +} + func TestGetResourceProvidersUsages(t *testing.T) { fakeServer := th.SetupHTTP() defer fakeServer.Teardown() From 2f0593c68608f111fe60b504f21e1afcd5216725 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 May 2026 09:28:50 +0000 Subject: [PATCH 330/353] build(deps): bump github/codeql-action from 4.35.4 to 4.35.5 Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.35.4 to 4.35.5. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/68bde559dea0fdcac2102bfdf6230c5f70eb485e...9e0d7b8d25671d64c341c19c0152d693099fb5ba) --- updated-dependencies: - dependency-name: github/codeql-action dependency-version: 4.35.5 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/codeql-analysis.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql-analysis.yaml b/.github/workflows/codeql-analysis.yaml index 6b3a3ceee3..abf0e90143 100644 --- a/.github/workflows/codeql-analysis.yaml +++ b/.github/workflows/codeql-analysis.yaml @@ -29,12 +29,12 @@ jobs: cache: true - name: Initialize CodeQL - uses: github/codeql-action/init@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4 + uses: github/codeql-action/init@9e0d7b8d25671d64c341c19c0152d693099fb5ba # v4 with: languages: ${{ matrix.language }} - name: Autobuild - uses: github/codeql-action/autobuild@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4 + uses: github/codeql-action/autobuild@9e0d7b8d25671d64c341c19c0152d693099fb5ba # v4 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4 + uses: github/codeql-action/analyze@9e0d7b8d25671d64c341c19c0152d693099fb5ba # v4 From a69b9d6806f23bf91d8d59b5182f3e3fbc5e1b00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A2=D1=80=D0=B5=D1=84=D0=B8=D0=BB=D0=BE=D0=B2=20=D0=90?= =?UTF-8?q?=D0=BB=D0=B5=D0=BA=D1=81=D0=B0=D0=BD=D0=B4=D1=80=20=D0=90=D0=BD?= =?UTF-8?q?=D0=B4=D1=80=D0=B5=D0=B5=D0=B2=D0=B8=D1=87?= Date: Tue, 5 May 2026 15:03:41 +0500 Subject: [PATCH 331/353] db/instances: remove hardcoded 300GB size cap --- openstack/db/v1/instances/requests.go | 8 +++--- .../db/v1/instances/testing/requests_test.go | 26 +++++++++++++++++++ 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/openstack/db/v1/instances/requests.go b/openstack/db/v1/instances/requests.go index b4e946025f..fd9599f985 100644 --- a/openstack/db/v1/instances/requests.go +++ b/openstack/db/v1/instances/requests.go @@ -56,8 +56,8 @@ type CreateOpts struct { // Either the integer UUID (in string form) of the flavor, or its URI // reference as specified in the response from the List() call. Required. FlavorRef string - // Specifies the volume size in gigabytes (GB). The value must be between 1 - // and 300. Required. + // Specifies the volume size in gigabytes (GB). The value must be > 1. + // Required. Size int // Specifies the volume type. VolumeType string @@ -77,11 +77,11 @@ type CreateOpts struct { // ToInstanceCreateMap will render a JSON map. func (opts CreateOpts) ToInstanceCreateMap() (map[string]any, error) { - if opts.Size > 300 || opts.Size < 1 { + if opts.Size < 1 { err := gophercloud.ErrInvalidInput{} err.Argument = "instances.CreateOpts.Size" err.Value = opts.Size - err.Info = "Size (GB) must be between 1-300" + err.Info = "Size (GB) must be >= 1" return nil, err } diff --git a/openstack/db/v1/instances/testing/requests_test.go b/openstack/db/v1/instances/testing/requests_test.go index b7278bf8d4..8961bc1727 100644 --- a/openstack/db/v1/instances/testing/requests_test.go +++ b/openstack/db/v1/instances/testing/requests_test.go @@ -78,6 +78,32 @@ func TestCreateWithFault(t *testing.T) { th.AssertDeepEquals(t, &expectedInstanceWithFault, instance) } +func TestCreateOptsToInstanceCreateMapAllowsSizeAbove300(t *testing.T) { + opts := instances.CreateOpts{ + FlavorRef: "1", + Size: 301, + } + + body, err := opts.ToInstanceCreateMap() + th.AssertNoErr(t, err) + + instance := body["instance"].(map[string]any) + volume := instance["volume"].(map[string]any) + th.AssertEquals(t, 301, volume["size"]) +} + +func TestCreateOptsToInstanceCreateMapRejectsSizeBelow1(t *testing.T) { + opts := instances.CreateOpts{ + FlavorRef: "1", + Size: 0, + } + + _, err := opts.ToInstanceCreateMap() + if err == nil { + t.Fatalf("expected error for invalid size, got nil") + } +} + func TestInstanceList(t *testing.T) { fakeServer := th.SetupHTTP() defer fakeServer.Teardown() From 5f89a2552160ed1cc4c3fc9efab73d4868c19758 Mon Sep 17 00:00:00 2001 From: DDuckSCH21 <100148228+DDuckSCH21@users.noreply.github.com> Date: Fri, 8 May 2026 10:03:17 +0500 Subject: [PATCH 332/353] Update openstack/db/v1/instances/requests.go MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Martin André --- openstack/db/v1/instances/requests.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openstack/db/v1/instances/requests.go b/openstack/db/v1/instances/requests.go index fd9599f985..7e66cb26c0 100644 --- a/openstack/db/v1/instances/requests.go +++ b/openstack/db/v1/instances/requests.go @@ -56,7 +56,7 @@ type CreateOpts struct { // Either the integer UUID (in string form) of the flavor, or its URI // reference as specified in the response from the List() call. Required. FlavorRef string - // Specifies the volume size in gigabytes (GB). The value must be > 1. + // Specifies the volume size in gigabytes (GB). The value must be >= 1. The upper limit is specific to each OpenStack environment. // Required. Size int // Specifies the volume type. From 535413ef95cb762a0bce355ae231c2e008cf2005 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Wed, 14 May 2025 10:37:48 +0100 Subject: [PATCH 333/353] tests: Prefer extension check over environment variable Signed-off-by: Stephen Finucane --- .../acceptance/openstack/networking/v2/conditions.go | 9 --------- .../v2/extensions/layer3/portforwardings_test.go | 4 ++-- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/internal/acceptance/openstack/networking/v2/conditions.go b/internal/acceptance/openstack/networking/v2/conditions.go index 6ce6b145f3..036cba6044 100644 --- a/internal/acceptance/openstack/networking/v2/conditions.go +++ b/internal/acceptance/openstack/networking/v2/conditions.go @@ -2,7 +2,6 @@ package v2 import ( "context" - "os" "testing" "github.com/gophercloud/gophercloud/v2" @@ -17,11 +16,3 @@ func RequireNeutronExtension(t *testing.T, client *gophercloud.ServiceClient, ex t.Skipf("this test requires %s Neutron extension", extension) } } - -// RequirePortForwarding will restrict a test to only be run in environments -// that support port forwarding -func RequirePortForwarding(t *testing.T) { - if os.Getenv("OS_PORTFORWARDING_ENVIRONMENT") == "" { - t.Skip("this test requires support for port forwarding") - } -} diff --git a/internal/acceptance/openstack/networking/v2/extensions/layer3/portforwardings_test.go b/internal/acceptance/openstack/networking/v2/extensions/layer3/portforwardings_test.go index d6f3e9595e..6811d472f7 100644 --- a/internal/acceptance/openstack/networking/v2/extensions/layer3/portforwardings_test.go +++ b/internal/acceptance/openstack/networking/v2/extensions/layer3/portforwardings_test.go @@ -15,11 +15,11 @@ import ( ) func TestLayer3PortForwardingsCreateDelete(t *testing.T) { - networking.RequirePortForwarding(t) - client, err := clients.NewNetworkV2Client() th.AssertNoErr(t, err) + networking.RequireNeutronExtension(t, client, "floating-ip-port-forwarding") + choices, err := clients.AcceptanceTestChoicesFromEnv() th.AssertNoErr(t, err) From 7fed78ef31e736f398aaecd4a63be237bec31cda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?p=C3=BDrus?= Date: Tue, 26 May 2026 11:25:58 +0200 Subject: [PATCH 334/353] neutron: properly enable port-forwarding extension in devstack --- .github/workflows/functional-networking.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/functional-networking.yaml b/.github/workflows/functional-networking.yaml index d4fb90ee4e..179109b51c 100644 --- a/.github/workflows/functional-networking.yaml +++ b/.github/workflows/functional-networking.yaml @@ -50,16 +50,16 @@ jobs: with: branch: ${{ matrix.openstack_version }} conf_overrides: | + enable_plugin neutron https://opendev.org/openstack/neutron ${{ matrix.openstack_version }} enable_plugin neutron-dynamic-routing https://github.com/openstack/neutron-dynamic-routing ${{ matrix.openstack_version }} enable_plugin neutron-vpnaas https://github.com/openstack/neutron-vpnaas ${{ matrix.openstack_version }} enable_plugin networking-bgpvpn https://github.com/openstack/networking-bgpvpn.git ${{ matrix.openstack_version }} - Q_ML2_PLUGIN_EXT_DRIVERS=qos,port_security,dns_domain_keywords,port_trusted BGP_SCHEDULER_DRIVER=neutron_dynamic_routing.services.bgp.scheduler.bgp_dragent_scheduler.StaticScheduler [[post-config|\$NEUTRON_CONF]] [oslo_policy] policy_dirs = /tmp/neutron-policies - enabled_services: "neutron-dns,neutron-qos,neutron-segments,neutron-trunk,neutron-uplink-status-propagation,neutron-network-segment-range,neutron-port-forwarding,openstack-cli-server" + enabled_services: "neutron-dns,neutron-qos,neutron-segments,neutron-trunk,neutron-port-trusted-vif,neutron-uplink-status-propagation,neutron-network-segment-range,neutron-port-forwarding,openstack-cli-server" - name: Checkout go uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 with: From beba249beb2a74b4a99041348ebcf7946de863fe Mon Sep 17 00:00:00 2001 From: Dominik Danelski Date: Mon, 18 May 2026 11:45:45 +0200 Subject: [PATCH 335/353] Add Placement resourceprovider list post 1.39 Allows for repeating required and member_of arguments. Change of the type of field, microversions.go required. Related #526 Signed-off-by: Dominik Danelski --- .../openstack/placement/v1/placement.go | 11 +++ .../placement/v1/resourceproviders_test.go | 76 +++++++++++++++++++ .../placement/v1/resourceproviders/doc.go | 23 ++++++ .../v1/resourceproviders/microversions.go | 40 ++++++++++ .../testing/fixtures_test.go | 19 +++++ .../testing/requests_test.go | 27 +++++++ 6 files changed, 196 insertions(+) create mode 100644 openstack/placement/v1/resourceproviders/microversions.go diff --git a/internal/acceptance/openstack/placement/v1/placement.go b/internal/acceptance/openstack/placement/v1/placement.go index 18c3304075..977b59459d 100644 --- a/internal/acceptance/openstack/placement/v1/placement.go +++ b/internal/acceptance/openstack/placement/v1/placement.go @@ -10,6 +10,13 @@ import ( th "github.com/gophercloud/gophercloud/v2/testhelper" ) +func restoreClientMicroversion(client *gophercloud.ServiceClient) func() { + originalMicroversion := client.Microversion + return func() { + client.Microversion = originalMicroversion + } +} + func CreateResourceProvider(t *testing.T, client *gophercloud.ServiceClient) (*resourceproviders.ResourceProvider, error) { name := tools.RandomString("TESTACC-", 8) t.Logf("Attempting to create resource provider: %s", name) @@ -18,6 +25,8 @@ func CreateResourceProvider(t *testing.T, client *gophercloud.ServiceClient) (*r Name: name, } + defer restoreClientMicroversion(client)() + client.Microversion = "1.20" resourceProvider, err := resourceproviders.Create(context.TODO(), client, createOpts).Extract() if err != nil { @@ -41,6 +50,8 @@ func CreateResourceProviderWithParent(t *testing.T, client *gophercloud.ServiceC ParentProviderUUID: parentUUID, } + defer restoreClientMicroversion(client)() + client.Microversion = "1.20" resourceProvider, err := resourceproviders.Create(context.TODO(), client, createOpts).Extract() if err != nil { diff --git a/internal/acceptance/openstack/placement/v1/resourceproviders_test.go b/internal/acceptance/openstack/placement/v1/resourceproviders_test.go index ee4e22ec9c..5e89cc5ecc 100644 --- a/internal/acceptance/openstack/placement/v1/resourceproviders_test.go +++ b/internal/acceptance/openstack/placement/v1/resourceproviders_test.go @@ -6,12 +6,14 @@ import ( "context" "net/http" "slices" + "strings" "testing" "github.com/gophercloud/gophercloud/v2" "github.com/gophercloud/gophercloud/v2/internal/acceptance/clients" "github.com/gophercloud/gophercloud/v2/internal/acceptance/tools" "github.com/gophercloud/gophercloud/v2/openstack/placement/v1/resourceproviders" + "github.com/gophercloud/gophercloud/v2/openstack/placement/v1/traits" th "github.com/gophercloud/gophercloud/v2/testhelper" ) @@ -35,6 +37,76 @@ func TestResourceProviderList(t *testing.T) { } } +func TestResourceProviderList139(t *testing.T) { + clients.RequireAdmin(t) + + client, err := clients.NewPlacementV1Client() + th.AssertNoErr(t, err) + + client.Microversion = "1.39" + + // Arrange: Create a resource provider, traits, and aggregates. + // Assign them to the created RP. + resourceProvider, err := CreateResourceProvider(t, client) + th.AssertNoErr(t, err) + defer DeleteResourceProvider(t, client, resourceProvider.UUID) + + trait1 := strings.ToUpper(tools.RandomString("CUSTOM_", 8)) + trait2 := strings.ToUpper(tools.RandomString("CUSTOM_", 8)) + err = traits.Create(context.TODO(), client, trait1).ExtractErr() + th.AssertNoErr(t, err) + defer traits.Delete(context.TODO(), client, trait1) + err = traits.Create(context.TODO(), client, trait2).ExtractErr() + th.AssertNoErr(t, err) + defer traits.Delete(context.TODO(), client, trait2) + + currentTraits, err := resourceproviders.GetTraits(context.TODO(), client, resourceProvider.UUID).Extract() + th.AssertNoErr(t, err) + + _, err = resourceproviders.UpdateTraits(context.TODO(), client, resourceProvider.UUID, resourceproviders.UpdateTraitsOpts{ + ResourceProviderGeneration: currentTraits.ResourceProviderGeneration, + Traits: []string{trait1, trait2}, + }).Extract() + th.AssertNoErr(t, err) + + currentAggregates, err := resourceproviders.GetAggregates(context.TODO(), client, resourceProvider.UUID).Extract() + th.AssertNoErr(t, err) + + aggregate1 := tools.RandomUUID() + aggregate2 := tools.RandomUUID() + aggregate3 := tools.RandomUUID() + _, err = resourceproviders.UpdateAggregates(context.TODO(), client, resourceProvider.UUID, resourceproviders.UpdateAggregatesOpts{ + ResourceProviderGeneration: currentAggregates.ResourceProviderGeneration, + Aggregates: []string{aggregate1, aggregate2}, + }).Extract() + th.AssertNoErr(t, err) + + listOpts := resourceproviders.ListOpts139{ + // Repeating member_of means AND: provider must be in aggregate1 and in any of (aggregate2, aggregate3). + // We'll expect list to return our provider. + MemberOf: []string{aggregate1, "in:" + aggregate2 + "," + aggregate3}, + Required: []string{trait1, trait2}, + } + + // Act: List resource providers with the above traits and aggregates as filters. + allPages, err := resourceproviders.List(client, listOpts).AllPages(context.TODO()) + th.AssertNoErr(t, err) + + // Assert: Our resource provider is in the results and has the traits and aggregates we set. + allResourceProviders, err := resourceproviders.ExtractResourceProviders(allPages) + th.AssertNoErr(t, err) + th.AssertEquals(t, true, len(allResourceProviders) > 0) + + found := false + for _, rp := range allResourceProviders { + if rp.UUID == resourceProvider.UUID { + found = true + break + } + } + th.AssertEquals(t, true, found) +} + func TestResourceProvider(t *testing.T) { clients.SkipRelease(t, "stable/mitaka") clients.SkipRelease(t, "stable/newton") @@ -311,6 +383,8 @@ func TestResourceProviderDeleteInventoriesSuccess(t *testing.T) { client, err := clients.NewPlacementV1Client() th.AssertNoErr(t, err) + client.Microversion = "1.20" + resourceProvider, err := CreateResourceProvider(t, client) th.AssertNoErr(t, err) defer DeleteResourceProvider(t, client, resourceProvider.UUID) @@ -422,6 +496,8 @@ func TestResourceProviderTraits(t *testing.T) { client, err := clients.NewPlacementV1Client() th.AssertNoErr(t, err) + client.Microversion = "1.20" + // first create new resource provider resourceProvider, err := CreateResourceProvider(t, client) th.AssertNoErr(t, err) diff --git a/openstack/placement/v1/resourceproviders/doc.go b/openstack/placement/v1/resourceproviders/doc.go index 120affca67..2a23ad5a9e 100644 --- a/openstack/placement/v1/resourceproviders/doc.go +++ b/openstack/placement/v1/resourceproviders/doc.go @@ -17,6 +17,29 @@ Example to list resource providers fmt.Printf("%+v\n", r) } +Example to list resource providers with repeating member_of and required parameters (microversion >= 1.39) + + placementClient.Microversion = "1.39" + + listOpts := resourceproviders.ListOpts139{ + MemberOf: []string{"42896e0d-205d-4fe3-bd1e-100924931787", "in:7834d585-31d4-486f-be8c-b3c1a58ca710,5e08ea53-c4c6-448e-9334-ac4953de3cfa"}, + Required: []string{"CUSTOM_TRAIT1", "CUSTOM_TRAIT2"}, + } + + allPages, err := resourceproviders.List(placementClient, listOpts).AllPages(context.TODO()) + if err != nil { + panic(err) + } + + allResourceProviders, err := resourceproviders.ExtractResourceProviders(allPages) + if err != nil { + panic(err) + } + + for _, r := range allResourceProviders { + fmt.Printf("%+v\n", r) + } + Example to create resource providers createOpts := resourceproviders.CreateOpts{ diff --git a/openstack/placement/v1/resourceproviders/microversions.go b/openstack/placement/v1/resourceproviders/microversions.go new file mode 100644 index 0000000000..607688212a --- /dev/null +++ b/openstack/placement/v1/resourceproviders/microversions.go @@ -0,0 +1,40 @@ +package resourceproviders + +import "github.com/gophercloud/gophercloud/v2" + +// ListOpts139 allows filtering resource providers. Filtering is achieved by +// passing in struct field values that map to the resource provider +// attributes you want to see returned. +// ListOpts139 is available in version >= 1.39. +type ListOpts139 struct { + // Name is the name of the resource provider to filter the list + Name string `q:"name"` + + // UUID is the uuid of the resource provider to filter the list + UUID string `q:"uuid"` + + // MemberOf is a list representing aggregate uuids that a provider must be + // associated with to be returned. + // Alternative is defined using the in: syntax, e.g. member_of=in:agg1,agg2,agg3. + // Forbidden aggregates are prefixed with !. + // Starting with microversion 1.24, the member_of parameter may be repeated. + MemberOf []string `q:"member_of"` + + // Resources is a comma-separated list of string indicating an amount of resource + // of a specified class that a provider must have the capacity and availability to serve + Resources string `q:"resources"` + + // InTree is a string that represents a resource provider UUID. The returned resource + // providers will be in the same provider tree as the specified provider. + InTree string `q:"in_tree"` + + // Required is a list of trait names. + // Microversion 1.39 added support for repeating the required parameter and for the in: syntax. + Required []string `q:"required"` +} + +// ToResourceProviderListQuery formats a ListOpts139 into a query string. +func (opts ListOpts139) ToResourceProviderListQuery() (string, error) { + q, err := gophercloud.BuildQueryString(opts) + return q.String(), err +} diff --git a/openstack/placement/v1/resourceproviders/testing/fixtures_test.go b/openstack/placement/v1/resourceproviders/testing/fixtures_test.go index 45faff6427..7299162eb0 100644 --- a/openstack/placement/v1/resourceproviders/testing/fixtures_test.go +++ b/openstack/placement/v1/resourceproviders/testing/fixtures_test.go @@ -433,6 +433,25 @@ func HandleResourceProviderList(t *testing.T, fakeServer th.FakeServer) { }) } +func HandleResourceProviderList139(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/resource_providers", + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + q := r.URL.Query() + th.AssertDeepEquals(t, + []string{"a09ba171-9405-40ca-bfe1-a8d1208af2ed", "47abce38-8a58-47b3-81e0-c647e37e03ae"}, + q["member_of"]) + th.AssertDeepEquals(t, []string{"HW:A_TRAIT", "CUSTOM_TRAIT"}, q["required"]) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + + fmt.Fprint(w, ResourceProvidersBody) + }) +} + func HandleResourceProviderCreate(t *testing.T, fakeServer th.FakeServer) { fakeServer.Mux.HandleFunc("/resource_providers", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "POST") diff --git a/openstack/placement/v1/resourceproviders/testing/requests_test.go b/openstack/placement/v1/resourceproviders/testing/requests_test.go index 1e316c46ff..fe0500d95b 100644 --- a/openstack/placement/v1/resourceproviders/testing/requests_test.go +++ b/openstack/placement/v1/resourceproviders/testing/requests_test.go @@ -40,6 +40,33 @@ func TestListResourceProviders(t *testing.T) { } } +func TestListResourceProviders139(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + HandleResourceProviderList139(t, fakeServer) + + count := 0 + opts := resourceproviders.ListOpts139{ + MemberOf: []string{"a09ba171-9405-40ca-bfe1-a8d1208af2ed", "47abce38-8a58-47b3-81e0-c647e37e03ae"}, + Required: []string{"HW:A_TRAIT", "CUSTOM_TRAIT"}, + } + err := resourceproviders.List(client.ServiceClient(fakeServer), opts).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + count++ + + actual, err := resourceproviders.ExtractResourceProviders(page) + if err != nil { + t.Errorf("Failed to extract resource providers: %v", err) + return false, err + } + th.AssertDeepEquals(t, ExpectedResourceProviders, actual) + + return true, nil + }) + + th.AssertNoErr(t, err) +} + func TestCreateResourceProvider(t *testing.T) { fakeServer := th.SetupHTTP() defer fakeServer.Teardown() From 28fe5566fecd622687c544acc47ae5216ff763a1 Mon Sep 17 00:00:00 2001 From: Adam Sharp <46480158+Sharpz7@users.noreply.github.com> Date: Wed, 27 May 2026 17:53:21 +0200 Subject: [PATCH 336/353] Add support for listing recordsets across all zones This change introduces a new ListAll function and helper URL builder to expose the Designate /recordsets endpoint via gophercloud. This allows callers to retrieve recordsets across all zones, in addition to the existing per-zone ListByZone helper. The new ListAll function: - Reuses the existing ListOpts/ListOptsBuilder types for filtering, sorting, and pagination. - Returns a pagination.Pager consistent with other list operations in this package. --- .../openstack/dns/v2/recordsets_test.go | 43 +++++++++++++++ openstack/dns/v2/recordsets/requests.go | 19 ++++++- .../v2/recordsets/testing/fixtures_test.go | 37 ++++++++----- .../v2/recordsets/testing/requests_test.go | 52 +++++++++++++++++++ openstack/dns/v2/recordsets/urls.go | 4 ++ 5 files changed, 140 insertions(+), 15 deletions(-) diff --git a/internal/acceptance/openstack/dns/v2/recordsets_test.go b/internal/acceptance/openstack/dns/v2/recordsets_test.go index fd2e4d41bf..7030791f6d 100644 --- a/internal/acceptance/openstack/dns/v2/recordsets_test.go +++ b/internal/acceptance/openstack/dns/v2/recordsets_test.go @@ -52,6 +52,49 @@ func TestRecordSetsListByZone(t *testing.T) { th.AssertNoErr(t, err) } +func TestRecordSetsListAll(t *testing.T) { + client, err := clients.NewDNSV2Client() + th.AssertNoErr(t, err) + + zone, err := CreateZone(t, client) + th.AssertNoErr(t, err) + defer DeleteZone(t, client, zone) + + rs, err := CreateRecordSet(t, client, zone) + th.AssertNoErr(t, err) + defer DeleteRecordSet(t, client, rs) + + allPages, err := recordsets.ListAll(client, nil).AllPages(context.TODO()) + th.AssertNoErr(t, err) + + allRecordSets, err := recordsets.ExtractRecordSets(allPages) + th.AssertNoErr(t, err) + + var found bool + for _, recordset := range allRecordSets { + tools.PrintResource(t, &recordset) + + if recordset.ID == rs.ID { + found = true + } + } + + th.AssertEquals(t, found, true) + + listOpts := recordsets.ListOpts{ + Limit: 1, + } + + pager := recordsets.ListAll(client, listOpts) + err = pager.EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + rr, err := recordsets.ExtractRecordSets(page) + th.AssertNoErr(t, err) + th.AssertEquals(t, len(rr), 1) + return false, nil + }) + th.AssertNoErr(t, err) +} + func TestRecordSetsCRUD(t *testing.T) { client, err := clients.NewDNSV2Client() th.AssertNoErr(t, err) diff --git a/openstack/dns/v2/recordsets/requests.go b/openstack/dns/v2/recordsets/requests.go index 49e629b393..2bf952446c 100644 --- a/openstack/dns/v2/recordsets/requests.go +++ b/openstack/dns/v2/recordsets/requests.go @@ -42,7 +42,7 @@ func (opts ListOpts) ToRecordSetListQuery() (string, error) { return q.String(), err } -// ListByZone implements the recordset list request. +// ListByZone implements the recordset list request for a specific zone. func ListByZone(client *gophercloud.ServiceClient, zoneID string, opts ListOptsBuilder) pagination.Pager { url := baseURL(client, zoneID) if opts != nil { @@ -57,6 +57,21 @@ func ListByZone(client *gophercloud.ServiceClient, zoneID string, opts ListOptsB }) } +// ListAll implements the recordset list request across all zones. +func ListAll(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { + url := listAllRecordSetsURL(client) + if opts != nil { + query, err := opts.ToRecordSetListQuery() + if err != nil { + return pagination.Pager{Err: err} + } + url += query + } + return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { + return RecordSetPage{pagination.LinkedPageBase{PageResult: r}} + }) +} + // Get implements the recordset Get request. func Get(ctx context.Context, client *gophercloud.ServiceClient, zoneID string, rrsetID string) (r GetResult) { resp, err := client.Get(ctx, rrsetURL(client, zoneID, rrsetID), &r.Body, nil) @@ -155,7 +170,7 @@ func (opts UpdateOpts) ToRecordSetUpdateMap() (map[string]any, error) { return b, nil } -// Update updates a recordset in a given zone +// Update updates a recordset in a given zone. func Update(ctx context.Context, client *gophercloud.ServiceClient, zoneID string, rrsetID string, opts UpdateOptsBuilder) (r UpdateResult) { b, err := opts.ToRecordSetUpdateMap() if err != nil { diff --git a/openstack/dns/v2/recordsets/testing/fixtures_test.go b/openstack/dns/v2/recordsets/testing/fixtures_test.go index 42a6c0d6e5..037f3d374d 100644 --- a/openstack/dns/v2/recordsets/testing/fixtures_test.go +++ b/openstack/dns/v2/recordsets/testing/fixtures_test.go @@ -199,23 +199,34 @@ var ExpectedRecordSetSlice = []recordsets.RecordSet{FirstRecordSet, SecondRecord // from ListByZoneOutput. var ExpectedRecordSetSliceLimited = []recordsets.RecordSet{SecondRecordSet} +func handleListSuccessfully(t *testing.T, w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.Header().Add("Content-Type", "application/json") + if err := r.ParseForm(); err != nil { + t.Errorf("Failed to parse request form %v", err) + } + marker := r.Form.Get("marker") + switch marker { + case "f7b10e9b-0cae-4a91-b162-562bc6096648": + fmt.Fprint(w, ListByZoneOutputLimited) + case "": + fmt.Fprint(w, ListByZoneOutput) + } +} + // HandleListByZoneSuccessfully configures the test server to respond to a ListByZone request. func HandleListByZoneSuccessfully(t *testing.T, fakeServer th.FakeServer) { fakeServer.Mux.HandleFunc("/zones/2150b1bf-dee2-4221-9d85-11f7886fb15f/recordsets", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + handleListSuccessfully(t, w, r) + }) +} - w.Header().Add("Content-Type", "application/json") - if err := r.ParseForm(); err != nil { - t.Errorf("Failed to parse request form %v", err) - } - marker := r.Form.Get("marker") - switch marker { - case "f7b10e9b-0cae-4a91-b162-562bc6096648": - fmt.Fprint(w, ListByZoneOutputLimited) - case "": - fmt.Fprint(w, ListByZoneOutput) - } +// HandleListAllSuccessfully configures the test server to respond to a ListAll request. +func HandleListAllSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/recordsets", func(w http.ResponseWriter, r *http.Request) { + handleListSuccessfully(t, w, r) }) } diff --git a/openstack/dns/v2/recordsets/testing/requests_test.go b/openstack/dns/v2/recordsets/testing/requests_test.go index fb06587f86..f2adcd7012 100644 --- a/openstack/dns/v2/recordsets/testing/requests_test.go +++ b/openstack/dns/v2/recordsets/testing/requests_test.go @@ -63,6 +63,58 @@ func TestListByZoneAllPages(t *testing.T) { th.CheckEquals(t, 2, len(allRecordSets)) } +func TestListAll(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListAllSuccessfully(t, fakeServer) + + count := 0 + err := recordsets.ListAll(client.ServiceClient(fakeServer), nil).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + count++ + actual, err := recordsets.ExtractRecordSets(page) + th.AssertNoErr(t, err) + th.CheckDeepEquals(t, ExpectedRecordSetSlice, actual) + + return true, nil + }) + th.AssertNoErr(t, err) + th.CheckEquals(t, 1, count) +} + +func TestListAllLimited(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListAllSuccessfully(t, fakeServer) + + count := 0 + listOpts := recordsets.ListOpts{ + Limit: 1, + Marker: "f7b10e9b-0cae-4a91-b162-562bc6096648", + } + err := recordsets.ListAll(client.ServiceClient(fakeServer), listOpts).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { + count++ + actual, err := recordsets.ExtractRecordSets(page) + th.AssertNoErr(t, err) + th.CheckDeepEquals(t, ExpectedRecordSetSliceLimited, actual) + + return true, nil + }) + th.AssertNoErr(t, err) + th.CheckEquals(t, 1, count) +} + +func TestListAllPages(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListAllSuccessfully(t, fakeServer) + + allPages, err := recordsets.ListAll(client.ServiceClient(fakeServer), nil).AllPages(context.TODO()) + th.AssertNoErr(t, err) + allRecordSets, err := recordsets.ExtractRecordSets(allPages) + th.AssertNoErr(t, err) + th.CheckEquals(t, 2, len(allRecordSets)) +} + func TestGet(t *testing.T) { fakeServer := th.SetupHTTP() defer fakeServer.Teardown() diff --git a/openstack/dns/v2/recordsets/urls.go b/openstack/dns/v2/recordsets/urls.go index 26d9384aa0..8e539d2311 100644 --- a/openstack/dns/v2/recordsets/urls.go +++ b/openstack/dns/v2/recordsets/urls.go @@ -6,6 +6,10 @@ func baseURL(c *gophercloud.ServiceClient, zoneID string) string { return c.ServiceURL("zones", zoneID, "recordsets") } +func listAllRecordSetsURL(c *gophercloud.ServiceClient) string { + return c.ServiceURL("recordsets") +} + func rrsetURL(c *gophercloud.ServiceClient, zoneID string, rrsetID string) string { return c.ServiceURL("zones", zoneID, "recordsets", rrsetID) } From d992a09d4854c7132497e55795a47d17bd812d9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Andr=C3=A9?= Date: Wed, 27 May 2026 16:21:18 +0200 Subject: [PATCH 337/353] CI: Use pre-built amphora images for Octavia jobs The octavia master job started failing recently while building the amphora image with diskimage-builder. Instead of building images from scratch (which is fragile and slow), download pre-built test images from https://tarballs.opendev.org/openstack/octavia/test-images/. The Octavia devstack plugin skips the DIB build when the image file already exists at the path specified by OCTAVIA_AMP_IMAGE_FILE. --- .github/workflows/functional-loadbalancer.yaml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/.github/workflows/functional-loadbalancer.yaml b/.github/workflows/functional-loadbalancer.yaml index dcb3af41d1..e8913a4623 100644 --- a/.github/workflows/functional-loadbalancer.yaml +++ b/.github/workflows/functional-loadbalancer.yaml @@ -24,21 +24,21 @@ jobs: - name: "master" openstack_version: "master" ubuntu_version: "24.04" + amphora_image_url: "https://tarballs.opendev.org/openstack/octavia/test-images/test-only-amphora-x64-haproxy-ubuntu-noble.qcow2" devstack_conf_overrides: | LIBVIRT_CPU_MODE=host-passthrough - OCTAVIA_AMP_DISTRIBUTION_RELEASE_ID=jammy - name: "gazpacho" openstack_version: "stable/2026.1" ubuntu_version: "24.04" + amphora_image_url: "https://tarballs.opendev.org/openstack/octavia/test-images/test-only-amphora-x64-haproxy-ubuntu-noble.qcow2" devstack_conf_overrides: | LIBVIRT_CPU_MODE=host-passthrough - OCTAVIA_AMP_DISTRIBUTION_RELEASE_ID=jammy - name: "epoxy" openstack_version: "stable/2025.1" ubuntu_version: "24.04" + amphora_image_url: "https://tarballs.opendev.org/openstack/octavia/test-images/test-only-amphora-x64-haproxy-ubuntu-jammy.qcow2" devstack_conf_overrides: | LIBVIRT_CPU_MODE=host-passthrough - OCTAVIA_AMP_DISTRIBUTION_RELEASE_ID=jammy runs-on: ubuntu-${{ matrix.ubuntu_version }} name: Octavia on OpenStack ${{ matrix.name }} steps: @@ -46,6 +46,10 @@ jobs: uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: persist-credentials: false + + - name: Download pre-built amphora image + run: | + wget -q "${{ matrix.amphora_image_url }}" -O /tmp/amphora-x64-haproxy.qcow2 - name: Deploy devstack uses: gophercloud/devstack-action@60ca1042045c0c9e3e001c64575d381654ffcba1 # v0.19 with: @@ -53,6 +57,7 @@ jobs: conf_overrides: | enable_plugin octavia https://github.com/openstack/octavia ${{ matrix.openstack_version }} enable_plugin neutron https://github.com/openstack/neutron ${{ matrix.openstack_version }} + OCTAVIA_AMP_IMAGE_FILE=/tmp/amphora-x64-haproxy.qcow2 ${{ matrix.devstack_conf_overrides }} enabled_services: "octavia,o-api,o-cw,o-hk,o-hm,o-da,neutron-qos,openstack-cli-server" From 89dbdfb23df51c272a3e6c7338840bbce2c236b3 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 15 May 2026 06:52:50 -0700 Subject: [PATCH 338/353] add support for portforwarding ranges --- .../networking/v2/extensions/layer3/layer3.go | 29 +++ .../extensions/layer3/portforwardings_test.go | 37 ++++ .../extensions/layer3/portforwarding/doc.go | 16 ++ .../layer3/portforwarding/requests.go | 12 +- .../layer3/portforwarding/results.go | 7 + .../portforwarding/testing/fixtures_test.go | 12 +- .../portforwarding/testing/requests_test.go | 180 +++++++++++++++++- 7 files changed, 279 insertions(+), 14 deletions(-) diff --git a/internal/acceptance/openstack/networking/v2/extensions/layer3/layer3.go b/internal/acceptance/openstack/networking/v2/extensions/layer3/layer3.go index c45bb08069..52d91c0118 100644 --- a/internal/acceptance/openstack/networking/v2/extensions/layer3/layer3.go +++ b/internal/acceptance/openstack/networking/v2/extensions/layer3/layer3.go @@ -97,6 +97,35 @@ func CreatePortForwarding(t *testing.T, client *gophercloud.ServiceClient, fipID return pf, err } +// CreatePortRangeForwarding creates a port range forwarding for a given floating IP +// and port. An error will be returned if the creation failed. +func CreatePortRangeForwarding(t *testing.T, client *gophercloud.ServiceClient, fipID string, portID string, portFixedIPs []ports.IP) (*portforwarding.PortForwarding, error) { + t.Logf("Attempting to create Port Range forwarding for floating IP with ID: %s", fipID) + + fixedIP := portFixedIPs[0] + internalIP := fixedIP.IPAddress + pfDescription := "Test description range" + createOpts := &portforwarding.CreateOpts{ + Description: pfDescription, + Protocol: "tcp", + InternalPortRange: "1200:1299", + ExternalPortRange: "1200:1299", + InternalIPAddress: internalIP, + InternalPortID: portID, + } + + pf, err := portforwarding.Create(context.TODO(), client, fipID, createOpts).Extract() + if err != nil { + return pf, err + } + + t.Logf("Created Port Range Forwarding.") + + th.AssertEquals(t, pf.Protocol, "tcp") + + return pf, err +} + // DeletePortForwarding deletes a Port Forwarding with a given ID and a given floating IP ID. // A fatal error is returned if the deletion fails. Works best as a deferred function func DeletePortForwarding(t *testing.T, client *gophercloud.ServiceClient, fipID string, pfID string) { diff --git a/internal/acceptance/openstack/networking/v2/extensions/layer3/portforwardings_test.go b/internal/acceptance/openstack/networking/v2/extensions/layer3/portforwardings_test.go index 6811d472f7..e6ba659068 100644 --- a/internal/acceptance/openstack/networking/v2/extensions/layer3/portforwardings_test.go +++ b/internal/acceptance/openstack/networking/v2/extensions/layer3/portforwardings_test.go @@ -60,6 +60,13 @@ func TestLayer3PortForwardingsCreateDelete(t *testing.T) { defer DeletePortForwarding(t, client, fip.ID, pf.ID) tools.PrintResource(t, pf) + pfRange, err := CreatePortRangeForwarding(t, client, fip.ID, port.ID, port.FixedIPs) + th.AssertNoErr(t, err) + th.AssertEquals(t, pfRange.Description, "Test description range") + defer DeletePortForwarding(t, client, fip.ID, pfRange.ID) + tools.PrintResource(t, pfRange) + + // Test updating port newPf, err := portforwarding.Get(context.TODO(), client, fip.ID, pf.ID).Extract() th.AssertNoErr(t, err) @@ -77,6 +84,27 @@ func TestLayer3PortForwardingsCreateDelete(t *testing.T) { th.AssertNoErr(t, err) th.AssertEquals(t, newPf.Description, "") + // Test updating port range + newRangePf, err := portforwarding.Get(context.TODO(), client, fip.ID, pfRange.ID).Extract() + th.AssertNoErr(t, err) + + updateOpts = portforwarding.UpdateOpts{ + Description: new(string), + Protocol: "tcp", + InternalPortRange: "1300:1399", + ExternalPortRange: "1300:1399", + } + + _, err = portforwarding.Update(context.TODO(), client, fip.ID, newRangePf.ID, updateOpts).Extract() + th.AssertNoErr(t, err) + + newRangePf, err = portforwarding.Get(context.TODO(), client, fip.ID, pfRange.ID).Extract() + th.AssertNoErr(t, err) + th.AssertEquals(t, newRangePf.Description, "") + th.AssertEquals(t, newRangePf.Protocol, "tcp") + th.AssertEquals(t, newRangePf.InternalPortRange, "1300:1399") + th.AssertEquals(t, newRangePf.ExternalPortRange, "1300:1399") + allPages, err := portforwarding.List(client, portforwarding.ListOpts{}, fip.ID).AllPages(context.TODO()) th.AssertNoErr(t, err) @@ -92,4 +120,13 @@ func TestLayer3PortForwardingsCreateDelete(t *testing.T) { th.AssertEquals(t, true, found) + found = false + for _, pf := range allPFs { + if pf.ID == newRangePf.ID { + found = true + } + } + + th.AssertEquals(t, true, found) + } diff --git a/openstack/networking/v2/extensions/layer3/portforwarding/doc.go b/openstack/networking/v2/extensions/layer3/portforwarding/doc.go index bf67b92b6b..b010f62177 100644 --- a/openstack/networking/v2/extensions/layer3/portforwarding/doc.go +++ b/openstack/networking/v2/extensions/layer3/portforwarding/doc.go @@ -44,6 +44,22 @@ Example to Create a Port Forwarding for a floating IP panic(err) } +or, for port ranges + + createOpts := &portforwarding.CreateOpts{ + Protocol: "tcp", + InternalPortRange: "100:199", + ExternalPortRange: "1500:1599", + InternalIPAddress: internalIP, + InternalPortID: portID, + } + + pf, err := portforwarding.Create(context.TODO(), networkingClient, floatingIPID, createOpts).Extract() + + if err != nil { + panic(err) + } + Example to Update a Port Forwarding updateOpts := portforwarding.UpdateOpts{ diff --git a/openstack/networking/v2/extensions/layer3/portforwarding/requests.go b/openstack/networking/v2/extensions/layer3/portforwarding/requests.go index 1b07b6b7c9..49b7842389 100644 --- a/openstack/networking/v2/extensions/layer3/portforwarding/requests.go +++ b/openstack/networking/v2/extensions/layer3/portforwarding/requests.go @@ -21,6 +21,7 @@ type ListOpts struct { Description string `q:"description"` InternalPortID string `q:"internal_port_id"` ExternalPort string `q:"external_port"` + ExternalPortRange string `q:"external_port_range"` InternalIPAddress string `q:"internal_ip_address"` Protocol string `q:"protocol"` InternalPort string `q:"internal_port"` @@ -62,13 +63,15 @@ func Get(ctx context.Context, c *gophercloud.ServiceClient, floatingIpId string, } // CreateOpts contains all the values needed to create a new port forwarding -// resource. All attributes are required. +// resource. Internal/External ports and port ranges are mutually exclusive. type CreateOpts struct { Description string `json:"description,omitempty"` InternalPortID string `json:"internal_port_id"` InternalIPAddress string `json:"internal_ip_address"` - InternalPort int `json:"internal_port"` - ExternalPort int `json:"external_port"` + InternalPort int `json:"internal_port,omitempty"` + InternalPortRange string `json:"internal_port_range,omitempty"` + ExternalPort int `json:"external_port,omitempty"` + ExternalPortRange string `json:"external_port_range,omitempty"` Protocol string `json:"protocol"` } @@ -98,12 +101,15 @@ func Create(ctx context.Context, c *gophercloud.ServiceClient, floatingIpId stri } // UpdateOpts contains the values used when updating a port forwarding resource. +// Only Internal/External port values OR range values should be specified, not both or mixed. type UpdateOpts struct { Description *string `json:"description,omitempty"` InternalPortID string `json:"internal_port_id,omitempty"` InternalIPAddress string `json:"internal_ip_address,omitempty"` InternalPort int `json:"internal_port,omitempty"` + InternalPortRange string `json:"internal_port_range,omitempty"` ExternalPort int `json:"external_port,omitempty"` + ExternalPortRange string `json:"external_port_range,omitempty"` Protocol string `json:"protocol,omitempty"` } diff --git a/openstack/networking/v2/extensions/layer3/portforwarding/results.go b/openstack/networking/v2/extensions/layer3/portforwarding/results.go index c2ed860231..62e8b1f3eb 100644 --- a/openstack/networking/v2/extensions/layer3/portforwarding/results.go +++ b/openstack/networking/v2/extensions/layer3/portforwarding/results.go @@ -19,6 +19,9 @@ type PortForwarding struct { // The TCP/UDP/other protocol port number of the port forwarding’s floating IP address. ExternalPort int `json:"external_port"` + // The TCP/UDP/other protocol port range of the port forwarding’s floating IP address. + ExternalPortRange string `json:"external_port_range"` + // The IP protocol used in the floating IP port forwarding. Protocol string `json:"protocol"` @@ -26,6 +29,10 @@ type PortForwarding struct { // IP address associated to the floating ip port forwarding. InternalPort int `json:"internal_port"` + // The TCP/UDP/other protocol port range of the Neutron port fixed + // IP address associated to the floating ip port forwarding. + InternalPortRange string `json:"internal_port_range"` + // The fixed IPv4 address of the Neutron port associated // to the floating IP port forwarding. InternalIPAddress string `json:"internal_ip_address"` diff --git a/openstack/networking/v2/extensions/layer3/portforwarding/testing/fixtures_test.go b/openstack/networking/v2/extensions/layer3/portforwarding/testing/fixtures_test.go index b9362c4859..d479e0577f 100644 --- a/openstack/networking/v2/extensions/layer3/portforwarding/testing/fixtures_test.go +++ b/openstack/networking/v2/extensions/layer3/portforwarding/testing/fixtures_test.go @@ -20,11 +20,21 @@ const PoFw_second = `{ "id": "e0a0274e-4d19-4eab-9e12-9e77a8caf3ea" }` +const PoFw_third = `{ + "protocol": "tcp", + "internal_ip_address": "10.0.0.19", + "internal_port_range": "1200:1299", + "internal_port_id": "dba563d2-aa9e-4a21-8cc2-3e0bdec9015a", + "external_port_range": "1100:1199", + "id": "f3a9f921-6bed-492b-a3fa-32a76fdd0159" + }` + var ListResponse = fmt.Sprintf(` { "port_forwardings": [ %s, +%s, %s ] } -`, PoFw, PoFw_second) +`, PoFw, PoFw_second, PoFw_third) diff --git a/openstack/networking/v2/extensions/layer3/portforwarding/testing/requests_test.go b/openstack/networking/v2/extensions/layer3/portforwarding/testing/requests_test.go index 57f7fce6c8..384354c3f5 100644 --- a/openstack/networking/v2/extensions/layer3/portforwarding/testing/requests_test.go +++ b/openstack/networking/v2/extensions/layer3/portforwarding/testing/requests_test.go @@ -53,6 +53,14 @@ func TestPortForwardingList(t *testing.T) { ExternalPort: 2230, ID: "e0a0274e-4d19-4eab-9e12-9e77a8caf3ea", }, + { + Protocol: "tcp", + InternalIPAddress: "10.0.0.19", + InternalPortRange: "1200:1299", + InternalPortID: "dba563d2-aa9e-4a21-8cc2-3e0bdec9015a", + ExternalPortRange: "1100:1199", + ID: "f3a9f921-6bed-492b-a3fa-32a76fdd0159", + }, } th.CheckDeepEquals(t, expected, actual) @@ -77,7 +85,7 @@ func TestCreate(t *testing.T) { th.TestHeader(t, r, "Accept", "application/json") th.TestJSONRequest(t, r, ` { - "port_forwarding": { + "port_forwarding": { "protocol": "tcp", "internal_ip_address": "10.0.0.11", "internal_port": 25, @@ -85,21 +93,20 @@ func TestCreate(t *testing.T) { "external_port": 2230 } } - - `) +`) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) fmt.Fprint(w, ` { - "port_forwarding": { - "protocol": "tcp", - "internal_ip_address": "10.0.0.11", - "internal_port": 25, - "internal_port_id": "1238be08-a2a8-4b8d-addf-fb5e2250e480", - "external_port": 2230, - "id": "725ade3c-9760-4880-8080-8fc2dbab9acc" + "port_forwarding": { + "protocol": "tcp", + "internal_ip_address": "10.0.0.11", + "internal_port": 25, + "internal_port_id": "1238be08-a2a8-4b8d-addf-fb5e2250e480", + "external_port": 2230, + "id": "725ade3c-9760-4880-8080-8fc2dbab9acc" } }`) }) @@ -123,6 +130,62 @@ func TestCreate(t *testing.T) { th.AssertEquals(t, "tcp", pf.Protocol) } +func TestCreateRange(t *testing.T) { + // Test port range + fakeServerRange := th.SetupHTTP() + defer fakeServerRange.Teardown() + fakeServerRange.Mux.HandleFunc("/v2.0/floatingips/f40600c2-f240-4bb0-aa76-f6f18b2aaab1/port_forwardings", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "POST") + th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "Content-Type", "application/json") + th.TestHeader(t, r, "Accept", "application/json") + th.TestJSONRequest(t, r, ` +{ + "port_forwarding": { + "protocol": "tcp", + "internal_ip_address": "10.0.0.19", + "internal_port_range": "1200:1299", + "internal_port_id": "dba563d2-aa9e-4a21-8cc2-3e0bdec9015a", + "external_port_range": "1100:1199" + } +} +`) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusCreated) + + fmt.Fprint(w, ` +{ + "port_forwarding": { + "protocol": "tcp", + "internal_ip_address": "10.0.0.19", + "internal_port_range": "1200:1299", + "internal_port_id": "dba563d2-aa9e-4a21-8cc2-3e0bdec9015a", + "external_port_range": "1100:1199", + "id": "f3a9f921-6bed-492b-a3fa-32a76fdd0159" + } +}`) + }) + + options := portforwarding.CreateOpts{ + Protocol: "tcp", + InternalIPAddress: "10.0.0.19", + InternalPortRange: "1200:1299", + ExternalPortRange: "1100:1199", + InternalPortID: "dba563d2-aa9e-4a21-8cc2-3e0bdec9015a", + } + + pf, err := portforwarding.Create(context.TODO(), fake.ServiceClient(fakeServerRange), "f40600c2-f240-4bb0-aa76-f6f18b2aaab1", options).Extract() + th.AssertNoErr(t, err) + + th.AssertEquals(t, "f3a9f921-6bed-492b-a3fa-32a76fdd0159", pf.ID) + th.AssertEquals(t, "10.0.0.19", pf.InternalIPAddress) + th.AssertEquals(t, "1200:1299", pf.InternalPortRange) + th.AssertEquals(t, "dba563d2-aa9e-4a21-8cc2-3e0bdec9015a", pf.InternalPortID) + th.AssertEquals(t, "1100:1199", pf.ExternalPortRange) + th.AssertEquals(t, "tcp", pf.Protocol) +} + func TestGet(t *testing.T) { fakeServer := th.SetupHTTP() defer fakeServer.Teardown() @@ -159,6 +222,42 @@ func TestGet(t *testing.T) { th.AssertEquals(t, 2230, pf.ExternalPort) } +func TestGetRange(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + fakeServer.Mux.HandleFunc("/v2.0/floatingips/2f245a7b-796b-4f26-9cf9-9e82d248fda7/port_forwardings/725ade3c-9760-4880-8080-8fc2dbab9acc", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + + fmt.Fprint(w, ` +{ + "port_forwarding": { + "protocol": "tcp", + "internal_ip_address": "10.0.0.11", + "internal_port_range": "1200:1299", + "internal_port_id": "1238be08-a2a8-4b8d-addf-fb5e2250e480", + "external_port_range": "1100:1199", + "id": "725ade3c-9760-4880-8080-8fc2dbab9acc" + } +} + `) + }) + + pf, err := portforwarding.Get(context.TODO(), fake.ServiceClient(fakeServer), "2f245a7b-796b-4f26-9cf9-9e82d248fda7", "725ade3c-9760-4880-8080-8fc2dbab9acc").Extract() + th.AssertNoErr(t, err) + + th.AssertEquals(t, "tcp", pf.Protocol) + th.AssertEquals(t, "725ade3c-9760-4880-8080-8fc2dbab9acc", pf.ID) + th.AssertEquals(t, "10.0.0.11", pf.InternalIPAddress) + th.AssertEquals(t, "1200:1299", pf.InternalPortRange) + th.AssertEquals(t, "1238be08-a2a8-4b8d-addf-fb5e2250e480", pf.InternalPortID) + th.AssertEquals(t, "1100:1199", pf.ExternalPortRange) +} + func TestDelete(t *testing.T) { fakeServer := th.SetupHTTP() defer fakeServer.Teardown() @@ -233,3 +332,64 @@ func TestUpdate(t *testing.T) { } th.AssertDeepEquals(t, expected, *actual) } + +func TestUpdateRange(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + + fakeServer.Mux.HandleFunc("/v2.0/floatingips/2f245a7b-796b-4f26-9cf9-9e82d248fda7/port_forwardings/f3a9f921-6bed-492b-a3fa-32a76fdd0159", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "PUT") + th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "Content-Type", "application/json") + th.TestHeader(t, r, "Accept", "application/json") + th.TestJSONRequest(t, r, ` +{ + "port_forwarding": { + "protocol": "udp", + "internal_port_range": "1500:1599", + "internal_port_id": "99889dc2-19a7-4edb-b9d0-d2ace8d1e144", + "external_port_range": "23000:23099" + } +} +`) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + + fmt.Fprint(w, ` +{ + "port_forwarding": { + "protocol": "udp", + "internal_ip_address": "10.0.0.14", + "internal_port_range": "1500:1599", + "internal_port_id": "99889dc2-19a7-4edb-b9d0-d2ace8d1e144", + "external_port_range": "23000:23099", + "id": "f3a9f921-6bed-492b-a3fa-32a76fdd0159" + } +} +`) + }) + + updatedProtocol := "udp" + updatedInternalPortRange := "1500:1599" + updatedInternalPortID := "99889dc2-19a7-4edb-b9d0-d2ace8d1e144" + updatedExternalPortRange := "23000:23099" + options := portforwarding.UpdateOpts{ + Protocol: updatedProtocol, + InternalPortRange: updatedInternalPortRange, + InternalPortID: updatedInternalPortID, + ExternalPortRange: updatedExternalPortRange, + } + + actual, err := portforwarding.Update(context.TODO(), fake.ServiceClient(fakeServer), "2f245a7b-796b-4f26-9cf9-9e82d248fda7", "f3a9f921-6bed-492b-a3fa-32a76fdd0159", options).Extract() + th.AssertNoErr(t, err) + expected := portforwarding.PortForwarding{ + Protocol: "udp", + InternalIPAddress: "10.0.0.14", + InternalPortRange: "1500:1599", + ID: "f3a9f921-6bed-492b-a3fa-32a76fdd0159", + InternalPortID: "99889dc2-19a7-4edb-b9d0-d2ace8d1e144", + ExternalPortRange: "23000:23099", + } + th.AssertDeepEquals(t, expected, *actual) +} From 467e049ce4c6181366fd015e3c70005d12781e7d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 29 May 2026 09:53:32 +0000 Subject: [PATCH 339/353] build(deps): bump golang.org/x/crypto from 0.51.0 to 0.52.0 Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.51.0 to 0.52.0. - [Commits](https://github.com/golang/crypto/compare/v0.51.0...v0.52.0) --- updated-dependencies: - dependency-name: golang.org/x/crypto dependency-version: 0.52.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 3dd692fc81..c15cc9b26f 100644 --- a/go.mod +++ b/go.mod @@ -3,8 +3,8 @@ module github.com/gophercloud/gophercloud/v2 go 1.25.0 require ( - golang.org/x/crypto v0.51.0 + golang.org/x/crypto v0.52.0 gopkg.in/yaml.v2 v2.4.0 ) -require golang.org/x/sys v0.44.0 // indirect +require golang.org/x/sys v0.45.0 // indirect diff --git a/go.sum b/go.sum index 76b00b7aaf..dfe9be1b81 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,7 @@ -golang.org/x/crypto v0.51.0 h1:IBPXwPfKxY7cWQZ38ZCIRPI50YLeevDLlLnyC5wRGTI= -golang.org/x/crypto v0.51.0/go.mod h1:8AdwkbraGNABw2kOX6YFPs3WM22XqI4EXEd8g+x7Oc8= -golang.org/x/sys v0.44.0 h1:ildZl3J4uzeKP07r2F++Op7E9B29JRUy+a27EibtBTQ= -golang.org/x/sys v0.44.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/crypto v0.52.0 h1:RMs7fP2rXdep0CftQlK8Uf+kibLm7qkCcradZWYz988= +golang.org/x/crypto v0.52.0/go.mod h1:1QgfPxDqh0T2M/elOJtp9RvuR95kVjir0e6/BvEmGbc= +golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= +golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/term v0.43.0 h1:S4RLU2sB31O/NCl+zFN9Aru9A/Cq2aqKpTZJ6B+DwT4= golang.org/x/term v0.43.0/go.mod h1:lrhlHNdQJHO+1qVYiHfFKVuVioJIheAc3fBSMFYEIsk= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= From d772e52f1a91c133c7fcc916f859c3c757982150 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 29 May 2026 09:55:19 +0000 Subject: [PATCH 340/353] build(deps): bump github/codeql-action from 4.35.5 to 4.36.0 Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.35.5 to 4.36.0. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/9e0d7b8d25671d64c341c19c0152d693099fb5ba...7211b7c8077ea37d8641b6271f6a365a22a5fbfa) --- updated-dependencies: - dependency-name: github/codeql-action dependency-version: 4.36.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/codeql-analysis.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql-analysis.yaml b/.github/workflows/codeql-analysis.yaml index abf0e90143..0bfa188281 100644 --- a/.github/workflows/codeql-analysis.yaml +++ b/.github/workflows/codeql-analysis.yaml @@ -29,12 +29,12 @@ jobs: cache: true - name: Initialize CodeQL - uses: github/codeql-action/init@9e0d7b8d25671d64c341c19c0152d693099fb5ba # v4 + uses: github/codeql-action/init@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v4 with: languages: ${{ matrix.language }} - name: Autobuild - uses: github/codeql-action/autobuild@9e0d7b8d25671d64c341c19c0152d693099fb5ba # v4 + uses: github/codeql-action/autobuild@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v4 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@9e0d7b8d25671d64c341c19c0152d693099fb5ba # v4 + uses: github/codeql-action/analyze@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v4 From 081be9c9756d23614d67ad85ea47323545c3f73e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Andr=C3=A9?= Date: Fri, 29 May 2026 08:58:17 +0200 Subject: [PATCH 341/353] docs: relax one-operation-per-PR rule Soften the PR scope guidance across contributor documentation to allow grouping related operations in a single PR. This better reflects current practice now that we have stable branches where non-breaking features are backported. --- docs/STYLEGUIDE.md | 5 ++--- docs/contributor-tutorial/step-02-issues.md | 5 +++-- .../step-05-pull-requests.md | 20 ++++++++----------- 3 files changed, 13 insertions(+), 17 deletions(-) diff --git a/docs/STYLEGUIDE.md b/docs/STYLEGUIDE.md index fb09b72f6a..8d3b426d28 100644 --- a/docs/STYLEGUIDE.md +++ b/docs/STYLEGUIDE.md @@ -28,9 +28,8 @@ [Pending #PRNUM] tag once the PR has been updated with the merged, dependent PR. That will let reviewers know it is ready to review. -- A PR should be small. Even if you intend on implementing an entire - service, a PR should only be one route of that service - (e.g. create server or get server, but not both). +- A PR should be focused. Group related operations together, but avoid + mixing unrelated changes in a single PR. - Unless explicitly asked, do not squash commits in the middle of a review; only append. It makes it difficult for the reviewer to see what's changed from one diff --git a/docs/contributor-tutorial/step-02-issues.md b/docs/contributor-tutorial/step-02-issues.md index 3c1937612b..62d8fc7094 100644 --- a/docs/contributor-tutorial/step-02-issues.md +++ b/docs/contributor-tutorial/step-02-issues.md @@ -87,8 +87,9 @@ supports the OpenStack projects proper. ### Adding a Missing API Suite -Adding support to a missing suite of API calls will require more than one Pull -Request. However, you can use a single issue for all PRs. +Adding support to a missing suite of API calls can be done in a single Pull +Request or broken into multiple PRs. Either way, you can use a single issue +to track the work. Examples of issues which track the addition of a missing API suite are: diff --git a/docs/contributor-tutorial/step-05-pull-requests.md b/docs/contributor-tutorial/step-05-pull-requests.md index 1f5373bc57..042dbe1da5 100644 --- a/docs/contributor-tutorial/step-05-pull-requests.md +++ b/docs/contributor-tutorial/step-05-pull-requests.md @@ -37,9 +37,6 @@ If you're adding a single field, then a single Pull Request is also fine. See [#662](https://github.com/gophercloud/gophercloud/pull/662) as an example of this. -If you plan to add more than one missing field, you will need to open a Pull -Request for _each_ field. - ### Adding a Single API Call Single API calls can also be submitted as a single Pull Request. See @@ -49,14 +46,13 @@ this. ### Adding a Suite of API Calls If you're adding support for a "suite" of API calls (meaning: Create, Update, -Delete, Get), then you will need to create one Pull Request for _each_ call. +Delete, Get), you can group related operations into a single Pull Request. +Different API suites (e.g. servers and flavors) should be submitted as separate +PRs. -The following Pull Requests are good examples of how to do this: +The following Pull Request is a good example of adding an entire API suite: -* https://github.com/gophercloud/gophercloud/pull/584 -* https://github.com/gophercloud/gophercloud/pull/586 -* https://github.com/gophercloud/gophercloud/pull/587 -* https://github.com/gophercloud/gophercloud/pull/594 +* https://github.com/gophercloud/gophercloud/pull/3701 You can also use the provided [template](/docs/contributor-tutorial/.template) as it contains a lot of the repeated boiler plate code seen in each resource. @@ -66,9 +62,9 @@ the work and will require further rounds of review to fix. ### Adding an Entire OpenStack Project -To add an entire OpenStack project, you must break each set of API calls into -individual Pull Requests. Implementing an entire project can be thought of as -implementing multiple API suites. +To add an entire OpenStack project, break it into Pull Requests by API suite. +Implementing an entire project can be thought of as implementing multiple API +suites. An example of this can be seen from the Pull Requests referenced in [#723](https://github.com/gophercloud/gophercloud/issues/723). From 4227bb35379c372bdcd62cdecad3d6377b67aed5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Andr=C3=A9?= Date: Fri, 29 May 2026 09:03:16 +0200 Subject: [PATCH 342/353] Add AGENTS.md Add a reference guide for AI coding agents. Unfortunately, claude still doesn't understand standards and we need to symlink AGENTS.md to CLAUDE.md. --- AGENTS.md | 215 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ CLAUDE.md | 1 + 2 files changed, 216 insertions(+) create mode 100644 AGENTS.md create mode 120000 CLAUDE.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000000..1b5a20580b --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,215 @@ +# AGENTS.md + +Quick reference guide for AI coding agents working in the Gophercloud repository. + +**Project:** Gophercloud - Go SDK for OpenStack services +**Module:** `github.com/gophercloud/gophercloud/v2` +**Language:** Go (see version in [go.mod](go.mod)) +**Stable Branch:** v2 (main development on `main`) + +## Build, Test & Lint Commands + +### Running Tests + +**Unit tests (default):** +```bash +make unit +``` + +**Unit tests with verbose output:** +```bash +go test -v ./... +``` + +**Run single test by name:** +```bash +cd openstack/compute/v2/servers +go test -run TestCreateServer ./... +``` + +**Coverage:** +```bash +make coverage +``` + +**Acceptance tests (requires live OpenStack - may incur charges):** +```bash +make acceptance # All services +make acceptance-compute # Specific service +``` + +**Run single acceptance test:** +```bash +cd internal/acceptance/openstack/compute/v2 +go test -timeout 60m -tags "acceptance" -run TestServersList +``` + +### Linting & Formatting + +```bash +make lint # Run golangci-lint in container (Docker/Podman) +make format # Run gofmt with simplify flag +``` + +**Note:** If lint fails with SELinux errors, run: +```bash +chcon -Rt svirt_sandbox_file_t . +chcon -Rt svirt_sandbox_file_t ~/.cache/golangci-lint +``` + +## Code Style Guidelines + +### Import Organization + +Group imports in this order (separated by blank lines): +1. Standard library (alphabetically) +2. External dependencies (alphabetically) +3. Gophercloud internal packages (alphabetically) + +Example: +```go +import ( + "context" + "encoding/json" + "fmt" + + "github.com/gophercloud/gophercloud/v2" + "github.com/gophercloud/gophercloud/v2/pagination" +) +``` + +### File Structure + +Standard package structure under `openstack////`: +- **`requests.go`** - HTTP request functions and OptsBuilder types +- **`results.go`** - Response structs and extraction methods +- **`urls.go`** - Endpoint URL construction helpers +- **`microversions.go`** - Microversion-specific types (when needed) +- **`testing/`** - Unit tests with HTTP mocking + +### Naming Conventions + +**Result receivers and variables:** +- Result method receiver: `r` +- Unmarshalled variable: `s` +- Request function return value: `r` + +**OptsBuilder pattern:** +- Interface name: `OptsBuilder` (e.g., `CreateOptsBuilder`, `ListOptsBuilder`) +- Method for request body: `ToMap` (e.g., `ToServerCreateMap`) +- Method for query string: `ToQuery` (e.g., `ToServerListQuery`) + +Example: +```go +type CreateOptsBuilder interface { + ToServerCreateMap() (map[string]interface{}, error) +} + +type CreateOpts struct { + Name string `json:"name"` +} + +func (opts CreateOpts) ToServerCreateMap() (map[string]interface{}, error) { + return gophercloud.BuildRequestBody(opts, "server") +} +``` + +### Types & Pointers + +- **New response fields (microversions):** Use pointer types to allow nil-checking +- **Optional request fields:** Always use `omitempty` JSON tag +- **Required fields:** No `omitempty` tag + +### Error Handling + +- Use `gophercloud.Result` and `gophercloud.ErrResult` types +- Extract errors with `.ExtractErr()` method +- Return errors directly, don't wrap unless adding context + +### Documentation + +- **All struct fields** must have GoDoc comments +- **Microversion-dependent fields** must document required version in GoDoc +- **Package documentation** goes in `doc.go` +- Follow existing comment style in similar packages + +Example: +```go +// This requires the client to be set to microversion 2.52 or later. +// Tags is the list of server tags. +Tags []string `json:"tags,omitempty"` +``` + +### Testing Requirements + +**Unit tests (in `testing/` subdirectory):** +- Use `testhelper` package to mock HTTP +- `fakeServer := th.SetupHTTP()` / `defer fakeServer.Teardown()` for setup/teardown +- `fakeServer.Mux.HandleFunc()` to register mock endpoints +- Test ALL options (every field in request/response structs) +- Use assertion helpers from `testhelper/convenience.go` (value assertions) and `testhelper/http_responses.go` (HTTP request assertions) +- `Assert*` variants are fatal (`t.Fatalf`), `Check*` variants are non-fatal (`t.Errorf`) +- Assertion argument order is **expected first, actual second**: `th.AssertEquals(t, "expected_value", actual.Field)` + +**Acceptance tests:** +- Located in `internal/acceptance/openstack//` +- Test against real OpenStack APIs +- Cover all operation variants + +## Microversions + +Set microversion on ServiceClient: +```go +client.Microversion = "2.52" +``` + +**Implementation rules:** +- **New request fields:** Must use `omitempty` + document microversion +- **New response fields:** Add as pointer types +- **Changed response types:** Create new structs in `microversions.go` + +See `docs/MICROVERSIONS.md` for details. + +## Pull Request Requirements + +**Before opening PR:** +1. **GitHub issue must exist** with core contributor approval +2. **PR description must include:** + - `For #` reference + - Link(s) to OpenStack source code (non-master branch) proving validity +3. **Keep PRs focused:** Group related operations together; avoid mixing unrelated changes +4. **Tests required:** Unit tests AND acceptance tests covering all options +5. **Work-in-progress:** Prefix title with `[wip]` until ready +6. **Dependencies:** Prefix with `[Pending #PRNUM]` if depends on another PR + +**During review:** +- Do NOT squash commits (only append) +- Follow existing patterns in codebase +- Address all reviewer feedback + +## Common Patterns + +**Context usage:** +Always pass `context.Context` to API operations: +```go +servers.List(client, opts).EachPage(ctx, func(ctx context.Context, page pagination.Page) (bool, error) { + // ... +}) +``` + +**Pagination:** +```go +pager := servers.List(client, servers.ListOpts{}) +err := pager.EachPage(ctx, func(ctx context.Context, page pagination.Page) (bool, error) { + servers, err := servers.ExtractServers(page) + // process... + return true, nil +}) +``` + +## Key Reminders + +- Module path: `github.com/gophercloud/gophercloud/v2` (note the `/v2`) +- Gophercloud does NOT validate microversion compatibility +- PRs target `main` branch, not `v2` +- Documentation auto-generated from GoDoc comments diff --git a/CLAUDE.md b/CLAUDE.md new file mode 120000 index 0000000000..47dc3e3d86 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1 @@ +AGENTS.md \ No newline at end of file From e11860521d6e28545d2d244a9779ec07585f5ade Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Jun 2026 09:10:57 +0000 Subject: [PATCH 343/353] build(deps): bump github/codeql-action from 4.36.0 to 4.36.1 Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.36.0 to 4.36.1. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/7211b7c8077ea37d8641b6271f6a365a22a5fbfa...87557b9c84dde89fdd9b10e88954ac2f4248e463) --- updated-dependencies: - dependency-name: github/codeql-action dependency-version: 4.36.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/codeql-analysis.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql-analysis.yaml b/.github/workflows/codeql-analysis.yaml index 0bfa188281..3f706c8b12 100644 --- a/.github/workflows/codeql-analysis.yaml +++ b/.github/workflows/codeql-analysis.yaml @@ -29,12 +29,12 @@ jobs: cache: true - name: Initialize CodeQL - uses: github/codeql-action/init@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v4 + uses: github/codeql-action/init@87557b9c84dde89fdd9b10e88954ac2f4248e463 # v4 with: languages: ${{ matrix.language }} - name: Autobuild - uses: github/codeql-action/autobuild@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v4 + uses: github/codeql-action/autobuild@87557b9c84dde89fdd9b10e88954ac2f4248e463 # v4 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v4 + uses: github/codeql-action/analyze@87557b9c84dde89fdd9b10e88954ac2f4248e463 # v4 From 880913eef68b1e401966d2cc2028fd0b153f38e0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 11 Jun 2026 09:09:05 +0000 Subject: [PATCH 344/353] build(deps): bump github/codeql-action from 4.36.1 to 4.36.2 Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.36.1 to 4.36.2. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/87557b9c84dde89fdd9b10e88954ac2f4248e463...8aad20d150bbac5944a9f9d289da16a4b0d87c1e) --- updated-dependencies: - dependency-name: github/codeql-action dependency-version: 4.36.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/codeql-analysis.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql-analysis.yaml b/.github/workflows/codeql-analysis.yaml index 3f706c8b12..a8ad31ad58 100644 --- a/.github/workflows/codeql-analysis.yaml +++ b/.github/workflows/codeql-analysis.yaml @@ -29,12 +29,12 @@ jobs: cache: true - name: Initialize CodeQL - uses: github/codeql-action/init@87557b9c84dde89fdd9b10e88954ac2f4248e463 # v4 + uses: github/codeql-action/init@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4 with: languages: ${{ matrix.language }} - name: Autobuild - uses: github/codeql-action/autobuild@87557b9c84dde89fdd9b10e88954ac2f4248e463 # v4 + uses: github/codeql-action/autobuild@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@87557b9c84dde89fdd9b10e88954ac2f4248e463 # v4 + uses: github/codeql-action/analyze@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4 From 2e16ec521db55d11da3b05820f9b99de5ec329df Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 16 Jun 2026 09:08:23 +0000 Subject: [PATCH 345/353] build(deps): bump golang.org/x/crypto from 0.52.0 to 0.53.0 Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.52.0 to 0.53.0. - [Commits](https://github.com/golang/crypto/compare/v0.52.0...v0.53.0) --- updated-dependencies: - dependency-name: golang.org/x/crypto dependency-version: 0.53.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 4 ++-- go.sum | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/go.mod b/go.mod index c15cc9b26f..6a794e5d89 100644 --- a/go.mod +++ b/go.mod @@ -3,8 +3,8 @@ module github.com/gophercloud/gophercloud/v2 go 1.25.0 require ( - golang.org/x/crypto v0.52.0 + golang.org/x/crypto v0.53.0 gopkg.in/yaml.v2 v2.4.0 ) -require golang.org/x/sys v0.45.0 // indirect +require golang.org/x/sys v0.46.0 // indirect diff --git a/go.sum b/go.sum index dfe9be1b81..fe1199b618 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,9 @@ -golang.org/x/crypto v0.52.0 h1:RMs7fP2rXdep0CftQlK8Uf+kibLm7qkCcradZWYz988= -golang.org/x/crypto v0.52.0/go.mod h1:1QgfPxDqh0T2M/elOJtp9RvuR95kVjir0e6/BvEmGbc= -golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= -golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= -golang.org/x/term v0.43.0 h1:S4RLU2sB31O/NCl+zFN9Aru9A/Cq2aqKpTZJ6B+DwT4= -golang.org/x/term v0.43.0/go.mod h1:lrhlHNdQJHO+1qVYiHfFKVuVioJIheAc3fBSMFYEIsk= +golang.org/x/crypto v0.53.0 h1:QZ4Muo8THX6CizN2vPPd5fBGHyogrdK9fG4wLPFUsto= +golang.org/x/crypto v0.53.0/go.mod h1:DNLU434OwVakk9PzuwV8w62mAJpRJL3vsgcfp4Qnsio= +golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw= +golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/term v0.44.0 h1:0rLvDRCtNj0gZkyIXhCyOb2OAzEhLVqc4B+hrsBhrmc= +golang.org/x/term v0.44.0/go.mod h1:7ze4MdzUzLXpSAoFP1H0bOI9aXDqveSvatT5vKcFh2Y= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= From bab93777714a92e1024f333eb55a2af99a590847 Mon Sep 17 00:00:00 2001 From: abhijith-darshan Date: Thu, 18 Jun 2026 11:13:16 +0200 Subject: [PATCH 346/353] dns: add AllProjects and SudoTenantID header support to zones.List Add ListOptsHeadersBuilder optional interface and AllProjects/SudoTenantID fields to ListOpts, allowing admin users to enumerate zones across all projects via X-Auth-All-Projects header, and to impersonate a tenant via X-Auth-Sudo-Tenant-ID header. List() uses a type assertion to remain backward compatible with existing ListOptsBuilder implementations. Functional tests require admin credentials via clients.RequireAdmin. Signed-off-by: abhijith-darshan --- .../acceptance/openstack/dns/v2/zones_test.go | 27 ++++++++++++++++ openstack/dns/v2/zones/doc.go | 20 ++++++++++++ openstack/dns/v2/zones/requests.go | 31 ++++++++++++++++++- .../dns/v2/zones/testing/fixtures_test.go | 13 ++++++++ .../dns/v2/zones/testing/requests_test.go | 13 ++++++++ 5 files changed, 103 insertions(+), 1 deletion(-) diff --git a/internal/acceptance/openstack/dns/v2/zones_test.go b/internal/acceptance/openstack/dns/v2/zones_test.go index 2281094377..28fbdeadff 100644 --- a/internal/acceptance/openstack/dns/v2/zones_test.go +++ b/internal/acceptance/openstack/dns/v2/zones_test.go @@ -52,3 +52,30 @@ func TestZonesCRUD(t *testing.T) { th.AssertEquals(t, newZone.Description, description) } + +func TestZonesListWithAllProjects(t *testing.T) { + clients.RequireAdmin(t) + + client, err := clients.NewDNSV2Client() + th.AssertNoErr(t, err) + + zone, err := CreateZone(t, client) + th.AssertNoErr(t, err) + defer DeleteZone(t, client, zone) + + listOpts := zones.ListOpts{AllProjects: true} + allPages, err := zones.List(client, listOpts).AllPages(context.TODO()) + th.AssertNoErr(t, err) + + allZones, err := zones.ExtractZones(allPages) + th.AssertNoErr(t, err) + + var found bool + for _, z := range allZones { + if zone.Name == z.Name { + found = true + } + } + + th.AssertEquals(t, found, true) +} diff --git a/openstack/dns/v2/zones/doc.go b/openstack/dns/v2/zones/doc.go index 6bd7d98cb5..4537eda5d4 100644 --- a/openstack/dns/v2/zones/doc.go +++ b/openstack/dns/v2/zones/doc.go @@ -22,6 +22,26 @@ Example to List Zones fmt.Printf("%+v\n", zone) } +Example to List Zones Across All Projects + + listOpts := zones.ListOpts{ + AllProjects: true, + } + + allPages, err := zones.List(dnsClient, listOpts).AllPages(context.TODO()) + if err != nil { + panic(err) + } + + allZones, err := zones.ExtractZones(allPages) + if err != nil { + panic(err) + } + + for _, zone := range allZones { + fmt.Printf("%+v\n", zone) + } + Example to Create a Zone createOpts := zones.CreateOpts{ diff --git a/openstack/dns/v2/zones/requests.go b/openstack/dns/v2/zones/requests.go index b0049a9148..6be0f27772 100644 --- a/openstack/dns/v2/zones/requests.go +++ b/openstack/dns/v2/zones/requests.go @@ -12,6 +12,11 @@ type ListOptsBuilder interface { ToZoneListQuery() (string, error) } +// ListOptsHeadersBuilder allows extensions to add additional headers to the List request. +type ListOptsHeadersBuilder interface { + ToZoneListHeaders() (map[string]string, error) +} + // ListOpts allows the filtering and sorting of paginated collections through // the API. Filtering is achieved by passing in struct field values that map to // the server attributes you want to see returned. Marker and Limit are used @@ -32,6 +37,12 @@ type ListOpts struct { Status string `q:"status"` TTL int `q:"ttl"` Type string `q:"type"` + + // All projects header + AllProjects bool `h:"X-Auth-All-Projects"` + + // Sudo tenant ID + SudoTenantID bool `h:"X-Auth-Sudo-Tenant-ID"` } // ToZoneListQuery formats a ListOpts into a query string. @@ -40,19 +51,37 @@ func (opts ListOpts) ToZoneListQuery() (string, error) { return q.String(), err } +// ToZoneListHeaders formats a ListOpts into header parameters. +func (opts ListOpts) ToZoneListHeaders() (map[string]string, error) { + return gophercloud.BuildHeaders(opts) +} + // List implements a zone List request. func List(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { url := baseURL(client) + var h map[string]string + if opts != nil { query, err := opts.ToZoneListQuery() if err != nil { return pagination.Pager{Err: err} } url += query + + // Check if opts implements the optional headers interface + if optsWithHeaders, ok := opts.(ListOptsHeadersBuilder); ok { + h, err = optsWithHeaders.ToZoneListHeaders() + if err != nil { + return pagination.Pager{Err: err} + } + } } - return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { + + pager := pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { return ZonePage{pagination.LinkedPageBase{PageResult: r}} }) + pager.Headers = h + return pager } // Get returns information about a zone, given its ID. diff --git a/openstack/dns/v2/zones/testing/fixtures_test.go b/openstack/dns/v2/zones/testing/fixtures_test.go index 8a7b12a09f..120a6818ad 100644 --- a/openstack/dns/v2/zones/testing/fixtures_test.go +++ b/openstack/dns/v2/zones/testing/fixtures_test.go @@ -153,6 +153,19 @@ func HandleListSuccessfully(t *testing.T, fakeServer th.FakeServer) { }) } +// HandleListAllProjectsSuccessfully configures the test server to respond to a List request +// with the X-Auth-All-Projects header set. +func HandleListAllProjectsSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/zones", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.TestHeader(t, r, "X-Auth-All-Projects", "true") + + w.Header().Add("Content-Type", "application/json") + fmt.Fprint(w, ListOutput) + }) +} + // HandleGetSuccessfully configures the test server to respond to a List request. func HandleGetSuccessfully(t *testing.T, fakeServer th.FakeServer) { fakeServer.Mux.HandleFunc("/zones/a86dba58-0043-4cc6-a1bb-69d5e86f3ca3", func(w http.ResponseWriter, r *http.Request) { diff --git a/openstack/dns/v2/zones/testing/requests_test.go b/openstack/dns/v2/zones/testing/requests_test.go index fcc1838ce3..e73884a6ff 100644 --- a/openstack/dns/v2/zones/testing/requests_test.go +++ b/openstack/dns/v2/zones/testing/requests_test.go @@ -44,6 +44,19 @@ func TestListAllPages(t *testing.T) { th.CheckEquals(t, 2, len(allZones)) } +func TestListWithAllProjects(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListAllProjectsSuccessfully(t, fakeServer) + + opts := zones.ListOpts{AllProjects: true} + allPages, err := zones.List(client.ServiceClient(fakeServer), opts).AllPages(context.TODO()) + th.AssertNoErr(t, err) + allZones, err := zones.ExtractZones(allPages) + th.AssertNoErr(t, err) + th.CheckEquals(t, 2, len(allZones)) +} + func TestGet(t *testing.T) { fakeServer := th.SetupHTTP() defer fakeServer.Teardown() From 22e36bc5ae57bbcf84f00ed79f9c3b0eade360bf Mon Sep 17 00:00:00 2001 From: abhijith-darshan Date: Fri, 19 Jun 2026 15:53:23 +0200 Subject: [PATCH 347/353] dns: fix SudoTenantID type in zones ListOpts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change SudoTenantID from bool to string — it carries a tenant UUID, not a boolean flag. --- openstack/dns/v2/zones/requests.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openstack/dns/v2/zones/requests.go b/openstack/dns/v2/zones/requests.go index 6be0f27772..f234766f9f 100644 --- a/openstack/dns/v2/zones/requests.go +++ b/openstack/dns/v2/zones/requests.go @@ -41,8 +41,8 @@ type ListOpts struct { // All projects header AllProjects bool `h:"X-Auth-All-Projects"` - // Sudo tenant ID - SudoTenantID bool `h:"X-Auth-Sudo-Tenant-ID"` + // SudoTenantID impersonates the given project. + SudoTenantID string `h:"X-Auth-Sudo-Tenant-ID"` } // ToZoneListQuery formats a ListOpts into a query string. From 91d86b56dfc1a21c1c17668ad38b3e94a6500b75 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 24 Jun 2026 09:08:23 +0000 Subject: [PATCH 348/353] build(deps): bump actions/checkout from 6.0.2 to 7.0.0 Bumps [actions/checkout](https://github.com/actions/checkout) from 6.0.2 to 7.0.0. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/de0fac2e4500dabe0009e67214ff5f5447ce83dd...9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: 7.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/codeql-analysis.yaml | 2 +- .github/workflows/functional-baremetal.yaml | 2 +- .github/workflows/functional-basic.yaml | 2 +- .github/workflows/functional-blockstorage.yaml | 2 +- .github/workflows/functional-compute.yaml | 2 +- .github/workflows/functional-containerinfra.yaml | 2 +- .github/workflows/functional-dns.yaml | 2 +- .github/workflows/functional-fwaas_v2.yaml | 2 +- .github/workflows/functional-identity.yaml | 2 +- .github/workflows/functional-image.yaml | 2 +- .github/workflows/functional-keymanager.yaml | 2 +- .github/workflows/functional-loadbalancer.yaml | 2 +- .github/workflows/functional-messaging.yaml | 2 +- .github/workflows/functional-metric.yaml | 2 +- .github/workflows/functional-networking.yaml | 2 +- .github/workflows/functional-objectstorage.yaml | 2 +- .github/workflows/functional-orchestration.yaml | 2 +- .github/workflows/functional-placement.yaml | 2 +- .github/workflows/functional-sharedfilesystems.yaml | 2 +- .github/workflows/functional-workflow.yaml | 2 +- .github/workflows/lint.yaml | 2 +- .github/workflows/semver.yaml | 2 +- .github/workflows/unit.yaml | 2 +- 23 files changed, 23 insertions(+), 23 deletions(-) diff --git a/.github/workflows/codeql-analysis.yaml b/.github/workflows/codeql-analysis.yaml index 3f706c8b12..ea5e3f5a50 100644 --- a/.github/workflows/codeql-analysis.yaml +++ b/.github/workflows/codeql-analysis.yaml @@ -18,7 +18,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v6 with: persist-credentials: false diff --git a/.github/workflows/functional-baremetal.yaml b/.github/workflows/functional-baremetal.yaml index 75e126f4a1..06e34727dd 100644 --- a/.github/workflows/functional-baremetal.yaml +++ b/.github/workflows/functional-baremetal.yaml @@ -34,7 +34,7 @@ jobs: name: Ironic on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v6 with: persist-credentials: false - name: Work around broken dnsmasq diff --git a/.github/workflows/functional-basic.yaml b/.github/workflows/functional-basic.yaml index 3943c3a9f0..31b96b1e09 100644 --- a/.github/workflows/functional-basic.yaml +++ b/.github/workflows/functional-basic.yaml @@ -29,7 +29,7 @@ jobs: name: basic tests on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v6 with: persist-credentials: false - name: Deploy devstack diff --git a/.github/workflows/functional-blockstorage.yaml b/.github/workflows/functional-blockstorage.yaml index f99da523fb..15384fc4bd 100644 --- a/.github/workflows/functional-blockstorage.yaml +++ b/.github/workflows/functional-blockstorage.yaml @@ -34,7 +34,7 @@ jobs: name: Cinder on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v6 with: persist-credentials: false - name: Deploy devstack diff --git a/.github/workflows/functional-compute.yaml b/.github/workflows/functional-compute.yaml index 4459b48aa0..3a6f1901b6 100644 --- a/.github/workflows/functional-compute.yaml +++ b/.github/workflows/functional-compute.yaml @@ -34,7 +34,7 @@ jobs: name: Nova on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v6 with: persist-credentials: false - name: Deploy devstack diff --git a/.github/workflows/functional-containerinfra.yaml b/.github/workflows/functional-containerinfra.yaml index 6565ec5ca4..4a650c2a8f 100644 --- a/.github/workflows/functional-containerinfra.yaml +++ b/.github/workflows/functional-containerinfra.yaml @@ -43,7 +43,7 @@ jobs: name: Magnum on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v6 with: persist-credentials: false - name: Deploy devstack diff --git a/.github/workflows/functional-dns.yaml b/.github/workflows/functional-dns.yaml index 045824bff1..458a657e92 100644 --- a/.github/workflows/functional-dns.yaml +++ b/.github/workflows/functional-dns.yaml @@ -34,7 +34,7 @@ jobs: name: Designate on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v6 with: persist-credentials: false - name: Deploy devstack diff --git a/.github/workflows/functional-fwaas_v2.yaml b/.github/workflows/functional-fwaas_v2.yaml index acbb63c9d0..244886a52e 100644 --- a/.github/workflows/functional-fwaas_v2.yaml +++ b/.github/workflows/functional-fwaas_v2.yaml @@ -38,7 +38,7 @@ jobs: name: FWaaS_v2 on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v6 with: persist-credentials: false - name: Create additional neutron policies diff --git a/.github/workflows/functional-identity.yaml b/.github/workflows/functional-identity.yaml index 86627541cb..00a72a7f64 100644 --- a/.github/workflows/functional-identity.yaml +++ b/.github/workflows/functional-identity.yaml @@ -34,7 +34,7 @@ jobs: name: Keystone on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v6 with: persist-credentials: false - name: Deploy devstack diff --git a/.github/workflows/functional-image.yaml b/.github/workflows/functional-image.yaml index 6ef80cc4be..6ee911987c 100644 --- a/.github/workflows/functional-image.yaml +++ b/.github/workflows/functional-image.yaml @@ -34,7 +34,7 @@ jobs: name: Glance on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v6 with: persist-credentials: false - name: Deploy devstack diff --git a/.github/workflows/functional-keymanager.yaml b/.github/workflows/functional-keymanager.yaml index 9b05982c47..48fa05e7fd 100644 --- a/.github/workflows/functional-keymanager.yaml +++ b/.github/workflows/functional-keymanager.yaml @@ -34,7 +34,7 @@ jobs: name: Barbican on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v6 with: persist-credentials: false - name: Deploy devstack diff --git a/.github/workflows/functional-loadbalancer.yaml b/.github/workflows/functional-loadbalancer.yaml index e8913a4623..99007ff505 100644 --- a/.github/workflows/functional-loadbalancer.yaml +++ b/.github/workflows/functional-loadbalancer.yaml @@ -43,7 +43,7 @@ jobs: name: Octavia on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v6 with: persist-credentials: false diff --git a/.github/workflows/functional-messaging.yaml b/.github/workflows/functional-messaging.yaml index d4c0889dea..4d9e6658c1 100644 --- a/.github/workflows/functional-messaging.yaml +++ b/.github/workflows/functional-messaging.yaml @@ -34,7 +34,7 @@ jobs: name: Zaqar on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v6 with: persist-credentials: false - name: Deploy devstack diff --git a/.github/workflows/functional-metric.yaml b/.github/workflows/functional-metric.yaml index a11fe939f7..3451643dc3 100644 --- a/.github/workflows/functional-metric.yaml +++ b/.github/workflows/functional-metric.yaml @@ -28,7 +28,7 @@ jobs: name: Aetos on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v6 with: persist-credentials: false diff --git a/.github/workflows/functional-networking.yaml b/.github/workflows/functional-networking.yaml index 179109b51c..0b59ee166b 100644 --- a/.github/workflows/functional-networking.yaml +++ b/.github/workflows/functional-networking.yaml @@ -34,7 +34,7 @@ jobs: name: Neutron on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v6 with: persist-credentials: false - name: Create additional neutron policies diff --git a/.github/workflows/functional-objectstorage.yaml b/.github/workflows/functional-objectstorage.yaml index a03ac7fb6a..e7d6fee372 100644 --- a/.github/workflows/functional-objectstorage.yaml +++ b/.github/workflows/functional-objectstorage.yaml @@ -34,7 +34,7 @@ jobs: name: Swift on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v6 with: persist-credentials: false - name: Deploy devstack diff --git a/.github/workflows/functional-orchestration.yaml b/.github/workflows/functional-orchestration.yaml index 3f850944a4..ef326c7d81 100644 --- a/.github/workflows/functional-orchestration.yaml +++ b/.github/workflows/functional-orchestration.yaml @@ -34,7 +34,7 @@ jobs: name: Heat on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v6 with: persist-credentials: false - name: Deploy devstack diff --git a/.github/workflows/functional-placement.yaml b/.github/workflows/functional-placement.yaml index 1d061ca2d9..4961b6b262 100644 --- a/.github/workflows/functional-placement.yaml +++ b/.github/workflows/functional-placement.yaml @@ -34,7 +34,7 @@ jobs: name: Placement on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v6 with: persist-credentials: false - name: Deploy devstack diff --git a/.github/workflows/functional-sharedfilesystems.yaml b/.github/workflows/functional-sharedfilesystems.yaml index 9ca40cb9d9..2dba003320 100644 --- a/.github/workflows/functional-sharedfilesystems.yaml +++ b/.github/workflows/functional-sharedfilesystems.yaml @@ -34,7 +34,7 @@ jobs: name: Manila on OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v6 with: persist-credentials: false - name: Deploy devstack diff --git a/.github/workflows/functional-workflow.yaml b/.github/workflows/functional-workflow.yaml index f68a3a4a91..c9092f0dcb 100644 --- a/.github/workflows/functional-workflow.yaml +++ b/.github/workflows/functional-workflow.yaml @@ -37,7 +37,7 @@ jobs: name: Mistral on Deploy OpenStack ${{ matrix.name }} steps: - name: Checkout Gophercloud - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v6 with: persist-credentials: false - name: Deploy devstack diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index a2577fa289..a40bdc6e48 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -9,7 +9,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout Gophercloud - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v6 with: persist-credentials: false - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 diff --git a/.github/workflows/semver.yaml b/.github/workflows/semver.yaml index 3e1c7e2c8b..40e3ef0f99 100644 --- a/.github/workflows/semver.yaml +++ b/.github/workflows/semver.yaml @@ -13,7 +13,7 @@ jobs: analyze: runs-on: ubuntu-latest steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v6 with: fetch-depth: 0 ref: ${{ github.event.pull_request.head.sha }} diff --git a/.github/workflows/unit.yaml b/.github/workflows/unit.yaml index 9c31223208..f7c8916cd9 100644 --- a/.github/workflows/unit.yaml +++ b/.github/workflows/unit.yaml @@ -14,7 +14,7 @@ jobs: fail-fast: false steps: - name: Checkout Gophercloud - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v6 with: persist-credentials: false - name: Setup Go From 8143dd449b4d34c07a93d054d8ff106420973198 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Wed, 13 May 2026 13:46:25 +0100 Subject: [PATCH 349/353] Add deprecation warning for V2EndpointURL, V3EndpointURL These are no longer used as of #3351. Mark them as deprecated so users know to migrate to their replacements. Signed-off-by: Stephen Finucane --- .golangci.yaml | 2 +- openstack/endpoint_location.go | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/.golangci.yaml b/.golangci.yaml index 2de1155c03..1a197efa58 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -17,7 +17,7 @@ linters: rules: - linters: - staticcheck - text: "SA1019: (x509.EncryptPEMBlock|strings.Title)" + text: "SA1019: (x509.EncryptPEMBlock|strings.Title|openstack.V2EndpointURL|openstack.V3EndpointURL)" paths: - third_party$ - builtin$ diff --git a/openstack/endpoint_location.go b/openstack/endpoint_location.go index 573c1f06f4..579139c26d 100644 --- a/openstack/endpoint_location.go +++ b/openstack/endpoint_location.go @@ -19,6 +19,9 @@ to return. It's an error both when multiple endpoints match the provided criteria and when none do. The minimum that can be specified is a Type, but you will also often need to specify a Name and/or a Region depending on what's available on your OpenStack deployment. + +Deprecated: This function does not respect the [gophercloud.EndpointOpts.Version] parameter, +which can result in random endpoints being selected. Use [V2Endpoint] instead. */ func V2EndpointURL(catalog *tokens2.ServiceCatalog, opts gophercloud.EndpointOpts) (string, error) { // Extract Endpoints from the catalog entries that match the requested Type, Name if provided, and Region if provided. @@ -66,6 +69,9 @@ to return. It's an error both when multiple endpoints match the provided criteria and when none do. The minimum that can be specified is a Type, but you will also often need to specify a Name and/or a Region depending on what's available on your OpenStack deployment. + +Deprecated: This function does not respect the [gophercloud.EndpointOpts.Version] parameter, +which can result in random endpoint being selected. Use [V3Endpoint] instead. */ func V3EndpointURL(catalog *tokens3.ServiceCatalog, opts gophercloud.EndpointOpts) (string, error) { if opts.Availability != gophercloud.AvailabilityAdmin && From ee7fcad340d04c74b0c24904d71a3e4ec16ac317 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Andr=C3=A9?= Date: Thu, 25 Jun 2026 18:10:19 +0200 Subject: [PATCH 350/353] Prepare v2.13.0 --- CHANGELOG.md | 32 ++++++++++++++++++++++++++++++++ provider_client.go | 2 +- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5d0a140d03..c759354df7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,35 @@ +## v2.13.0 (2026-06-25) + +* [GH-3717](https://github.com/gophercloud/gophercloud/pull/3717) build(deps): bump golang.org/x/crypto from 0.49.0 to 0.50.0 +* [GH-3720](https://github.com/gophercloud/gophercloud/pull/3720) build(deps): bump actions/upload-artifact from 7.0.0 to 7.0.1 +* [GH-3723](https://github.com/gophercloud/gophercloud/pull/3723) build(deps): bump github/codeql-action from 4.35.1 to 4.35.2 +* [GH-3728](https://github.com/gophercloud/gophercloud/pull/3728) [v2] Implement resource provider allocations +* [GH-3730](https://github.com/gophercloud/gophercloud/pull/3730) [v2] fix: skip non-struct fields in extractIntoPtr slice path to prevent unmarshal panic +* [GH-3731](https://github.com/gophercloud/gophercloud/pull/3731) [v2] Implement usages +* [GH-3732](https://github.com/gophercloud/gophercloud/pull/3732) [v2] Leverage RandomUUID() in Placement resourceproviders tests +* [GH-3737](https://github.com/gophercloud/gophercloud/pull/3737) [v2] Bump golangci-lint +* [GH-3744](https://github.com/gophercloud/gophercloud/pull/3744) build(deps): bump actions/labeler from 6.0.1 to 6.1.0 +* [GH-3752](https://github.com/gophercloud/gophercloud/pull/3752) build(deps): bump github/codeql-action from 4.35.2 to 4.35.4 +* [GH-3758](https://github.com/gophercloud/gophercloud/pull/3758) build(deps): bump golang.org/x/crypto from 0.50.0 to 0.51.0 +* [GH-3760](https://github.com/gophercloud/gophercloud/pull/3760) [v2] fix(vpnaas): change encryption and auth method in acceptance tests +* [GH-3762](https://github.com/gophercloud/gophercloud/pull/3762) [v2] Allow clearing Placement resource provider parent_provider_uuid +* [GH-3764](https://github.com/gophercloud/gophercloud/pull/3764) build(deps): bump github/codeql-action from 4.35.4 to 4.35.5 +* [GH-3769](https://github.com/gophercloud/gophercloud/pull/3769) [v2] db/instances: remove hardcoded 300GB size cap +* [GH-3770](https://github.com/gophercloud/gophercloud/pull/3770) [v2] neutron: properly enable port-forwarding extension in devstack +* [GH-3771](https://github.com/gophercloud/gophercloud/pull/3771) [v2] tests: Prefer extension check over environment variable +* [GH-3772](https://github.com/gophercloud/gophercloud/pull/3772) [v2] Add Placement resourceprovider list post 1.39 +* [GH-3774](https://github.com/gophercloud/gophercloud/pull/3774) [v2] Add support for listing recordsets across all zones +* [GH-3775](https://github.com/gophercloud/gophercloud/pull/3775) [v2] CI: Use pre-built amphora images for Octavia jobs +* [GH-3776](https://github.com/gophercloud/gophercloud/pull/3776) [v2] allow port ranges in floating ip portforwarding +* [GH-3781](https://github.com/gophercloud/gophercloud/pull/3781) build(deps): bump golang.org/x/crypto from 0.51.0 to 0.52.0 +* [GH-3784](https://github.com/gophercloud/gophercloud/pull/3784) build(deps): bump github/codeql-action from 4.35.5 to 4.36.0 +* [GH-3787](https://github.com/gophercloud/gophercloud/pull/3787) [v2] docs: relax one-operation-per-PR rule +* [GH-3790](https://github.com/gophercloud/gophercloud/pull/3790) [v2] Add AGENTS.md +* [GH-3794](https://github.com/gophercloud/gophercloud/pull/3794) build(deps): bump github/codeql-action from 4.36.0 to 4.36.1 +* [GH-3802](https://github.com/gophercloud/gophercloud/pull/3802) [v2] dns: add AllProjects support to zones.List via X-Auth-All-Projects header +* [GH-3808](https://github.com/gophercloud/gophercloud/pull/3808) dns: fix SudoTenantID type in zones ListOpts + + ## v2.12.0 (2026-04-10) * [GH-3653](https://github.com/gophercloud/gophercloud/pull/3653) [v2] Fix clouds.yaml search path to use XDG convention on all platforms diff --git a/provider_client.go b/provider_client.go index fda42d92e3..e618744d97 100644 --- a/provider_client.go +++ b/provider_client.go @@ -14,7 +14,7 @@ import ( // DefaultUserAgent is the default User-Agent string set in the request header. const ( - DefaultUserAgent = "gophercloud/v2.12.0" + DefaultUserAgent = "gophercloud/v2.13.0" DefaultMaxBackoffRetries = 60 ) From 390904e8a3e58c2faed6abdfc4a0e06dfcb03d6e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 Jun 2026 09:08:56 +0000 Subject: [PATCH 351/353] build(deps): bump actions/setup-go from 6.4.0 to 6.5.0 Bumps [actions/setup-go](https://github.com/actions/setup-go) from 6.4.0 to 6.5.0. - [Release notes](https://github.com/actions/setup-go/releases) - [Commits](https://github.com/actions/setup-go/compare/4a3601121dd01d1626a1e23e37211e3254c1c06c...924ae3a1cded613372ab5595356fb5720e22ba16) --- updated-dependencies: - dependency-name: actions/setup-go dependency-version: 6.5.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/codeql-analysis.yaml | 2 +- .github/workflows/functional-baremetal.yaml | 2 +- .github/workflows/functional-basic.yaml | 2 +- .github/workflows/functional-blockstorage.yaml | 2 +- .github/workflows/functional-compute.yaml | 2 +- .github/workflows/functional-containerinfra.yaml | 2 +- .github/workflows/functional-dns.yaml | 2 +- .github/workflows/functional-fwaas_v2.yaml | 2 +- .github/workflows/functional-identity.yaml | 2 +- .github/workflows/functional-image.yaml | 2 +- .github/workflows/functional-keymanager.yaml | 2 +- .github/workflows/functional-loadbalancer.yaml | 2 +- .github/workflows/functional-messaging.yaml | 2 +- .github/workflows/functional-metric.yaml | 2 +- .github/workflows/functional-networking.yaml | 2 +- .github/workflows/functional-objectstorage.yaml | 2 +- .github/workflows/functional-orchestration.yaml | 2 +- .github/workflows/functional-placement.yaml | 2 +- .github/workflows/functional-sharedfilesystems.yaml | 2 +- .github/workflows/functional-workflow.yaml | 2 +- .github/workflows/lint.yaml | 2 +- .github/workflows/semver.yaml | 2 +- .github/workflows/unit.yaml | 2 +- 23 files changed, 23 insertions(+), 23 deletions(-) diff --git a/.github/workflows/codeql-analysis.yaml b/.github/workflows/codeql-analysis.yaml index 76b98bcfba..acc26ca886 100644 --- a/.github/workflows/codeql-analysis.yaml +++ b/.github/workflows/codeql-analysis.yaml @@ -23,7 +23,7 @@ jobs: persist-credentials: false - name: Setup Go - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 + uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6 with: go-version-file: 'go.mod' cache: true diff --git a/.github/workflows/functional-baremetal.yaml b/.github/workflows/functional-baremetal.yaml index 06e34727dd..497a827f3f 100644 --- a/.github/workflows/functional-baremetal.yaml +++ b/.github/workflows/functional-baremetal.yaml @@ -76,7 +76,7 @@ jobs: SWIFT_TEMPURL_KEY=secretkey enabled_services: "ir-api,ir-cond,s-account,s-container,s-object,s-proxy,q-svc,q-agt,q-dhcp,q-l3,q-meta,-cinder,-c-sch,-c-api,-c-vol,-c-bak,-ovn,-ovn-controller,-ovn-northd,-q-ovn-metadata-agent,openstack-cli-server" - name: Checkout go - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 + uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6 with: go-version-file: 'go.mod' cache: true diff --git a/.github/workflows/functional-basic.yaml b/.github/workflows/functional-basic.yaml index 31b96b1e09..13461be921 100644 --- a/.github/workflows/functional-basic.yaml +++ b/.github/workflows/functional-basic.yaml @@ -38,7 +38,7 @@ jobs: branch: ${{ matrix.openstack_version }} enabled_services: 's-account,s-container,s-object,s-proxy,openstack-cli-server' - name: Checkout go - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 + uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6 with: go-version-file: 'go.mod' cache: true diff --git a/.github/workflows/functional-blockstorage.yaml b/.github/workflows/functional-blockstorage.yaml index 15384fc4bd..816dd42710 100644 --- a/.github/workflows/functional-blockstorage.yaml +++ b/.github/workflows/functional-blockstorage.yaml @@ -45,7 +45,7 @@ jobs: CINDER_ISCSI_HELPER=lioadm enabled_services: "s-account,s-container,s-object,s-proxy,c-bak,openstack-cli-server" - name: Checkout go - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 + uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6 with: go-version-file: 'go.mod' cache: true diff --git a/.github/workflows/functional-compute.yaml b/.github/workflows/functional-compute.yaml index 3a6f1901b6..650d39634b 100644 --- a/.github/workflows/functional-compute.yaml +++ b/.github/workflows/functional-compute.yaml @@ -45,7 +45,7 @@ jobs: CINDER_ISCSI_HELPER=lioadm enabled_services: "openstack-cli-server" - name: Checkout go - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 + uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6 with: go-version-file: 'go.mod' cache: true diff --git a/.github/workflows/functional-containerinfra.yaml b/.github/workflows/functional-containerinfra.yaml index 4a650c2a8f..52bca36927 100644 --- a/.github/workflows/functional-containerinfra.yaml +++ b/.github/workflows/functional-containerinfra.yaml @@ -60,7 +60,7 @@ jobs: ${{ matrix.devstack_conf_overrides }} enabled_services: "h-eng,h-api,h-api-cfn,h-api-cw,openstack-cli-server" - name: Checkout go - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 + uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6 with: go-version-file: 'go.mod' cache: true diff --git a/.github/workflows/functional-dns.yaml b/.github/workflows/functional-dns.yaml index 458a657e92..5474823faf 100644 --- a/.github/workflows/functional-dns.yaml +++ b/.github/workflows/functional-dns.yaml @@ -47,7 +47,7 @@ jobs: ${{ matrix.devstack_conf_overrides }} enabled_services: "designate,designate-central,designate-api,designate-worker,designate-producer,designate-mdns,openstack-cli-server" - name: Checkout go - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 + uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6 with: go-version-file: 'go.mod' cache: true diff --git a/.github/workflows/functional-fwaas_v2.yaml b/.github/workflows/functional-fwaas_v2.yaml index 244886a52e..15f787a369 100644 --- a/.github/workflows/functional-fwaas_v2.yaml +++ b/.github/workflows/functional-fwaas_v2.yaml @@ -66,7 +66,7 @@ jobs: policy_dirs = /tmp/neutron-policies enabled_services: 'q-svc,q-agt,q-dhcp,q-l3,q-meta,q-fwaas-v2,-cinder,-horizon,-tempest,-swift,-c-sch,-c-api,-c-vol,-c-bak,-ovn,-ovn-controller,-ovn-northd,-q-ovn-metadata-agent,openstack-cli-server' - name: Checkout go - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 + uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6 with: go-version-file: 'go.mod' cache: true diff --git a/.github/workflows/functional-identity.yaml b/.github/workflows/functional-identity.yaml index 00a72a7f64..c661d0c25c 100644 --- a/.github/workflows/functional-identity.yaml +++ b/.github/workflows/functional-identity.yaml @@ -43,7 +43,7 @@ jobs: branch: ${{ matrix.openstack_version }} enabled_services: "openstack-cli-server" - name: Checkout go - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 + uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6 with: go-version-file: 'go.mod' cache: true diff --git a/.github/workflows/functional-image.yaml b/.github/workflows/functional-image.yaml index 6ee911987c..b837743ae1 100644 --- a/.github/workflows/functional-image.yaml +++ b/.github/workflows/functional-image.yaml @@ -43,7 +43,7 @@ jobs: branch: ${{ matrix.openstack_version }} enabled_services: "openstack-cli-server" - name: Checkout go - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 + uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6 with: go-version-file: 'go.mod' cache: true diff --git a/.github/workflows/functional-keymanager.yaml b/.github/workflows/functional-keymanager.yaml index 48fa05e7fd..84c1208a88 100644 --- a/.github/workflows/functional-keymanager.yaml +++ b/.github/workflows/functional-keymanager.yaml @@ -47,7 +47,7 @@ jobs: ${{ matrix.devstack_conf_overrides }} enabled_services: "barbican-svc,barbican-retry,barbican-keystone-listener,openstack-cli-server" - name: Checkout go - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 + uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6 with: go-version-file: 'go.mod' cache: true diff --git a/.github/workflows/functional-loadbalancer.yaml b/.github/workflows/functional-loadbalancer.yaml index 99007ff505..d86e2a2756 100644 --- a/.github/workflows/functional-loadbalancer.yaml +++ b/.github/workflows/functional-loadbalancer.yaml @@ -62,7 +62,7 @@ jobs: ${{ matrix.devstack_conf_overrides }} enabled_services: "octavia,o-api,o-cw,o-hk,o-hm,o-da,neutron-qos,openstack-cli-server" - name: Checkout go - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 + uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6 with: go-version-file: 'go.mod' cache: true diff --git a/.github/workflows/functional-messaging.yaml b/.github/workflows/functional-messaging.yaml index 4d9e6658c1..6baceee221 100644 --- a/.github/workflows/functional-messaging.yaml +++ b/.github/workflows/functional-messaging.yaml @@ -46,7 +46,7 @@ jobs: ZAQARCLIENT_BRANCH=${{ matrix.openstack_version }} enabled_services: "openstack-cli-server" - name: Checkout go - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 + uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6 with: go-version-file: 'go.mod' cache: true diff --git a/.github/workflows/functional-metric.yaml b/.github/workflows/functional-metric.yaml index 3451643dc3..b2afabebdb 100644 --- a/.github/workflows/functional-metric.yaml +++ b/.github/workflows/functional-metric.yaml @@ -48,7 +48,7 @@ jobs: enabled_services: "prometheus,node_exporter,openstack_exporter,ceilometer-acompute,ceilometer-acentral,ceilometer-anotification,sg-core,aetos,openstack-cli-server" - name: Checkout go - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c + uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 with: go-version-file: 'go.mod' cache: true diff --git a/.github/workflows/functional-networking.yaml b/.github/workflows/functional-networking.yaml index 0b59ee166b..2fe90fe6d9 100644 --- a/.github/workflows/functional-networking.yaml +++ b/.github/workflows/functional-networking.yaml @@ -61,7 +61,7 @@ jobs: policy_dirs = /tmp/neutron-policies enabled_services: "neutron-dns,neutron-qos,neutron-segments,neutron-trunk,neutron-port-trusted-vif,neutron-uplink-status-propagation,neutron-network-segment-range,neutron-port-forwarding,openstack-cli-server" - name: Checkout go - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 + uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6 with: go-version-file: 'go.mod' cache: true diff --git a/.github/workflows/functional-objectstorage.yaml b/.github/workflows/functional-objectstorage.yaml index e7d6fee372..82f4e1647a 100644 --- a/.github/workflows/functional-objectstorage.yaml +++ b/.github/workflows/functional-objectstorage.yaml @@ -49,7 +49,7 @@ jobs: allow_object_versioning = true enabled_services: 's-account,s-container,s-object,s-proxy,openstack-cli-server' - name: Checkout go - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 + uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6 with: go-version-file: 'go.mod' cache: true diff --git a/.github/workflows/functional-orchestration.yaml b/.github/workflows/functional-orchestration.yaml index ef326c7d81..e302a42235 100644 --- a/.github/workflows/functional-orchestration.yaml +++ b/.github/workflows/functional-orchestration.yaml @@ -45,7 +45,7 @@ jobs: enable_plugin heat https://github.com/openstack/heat ${{ matrix.openstack_version }} enabled_services: 'h-eng,h-api,h-api-cfn,h-api-cw,openstack-cli-server' - name: Checkout go - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 + uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6 with: go-version-file: 'go.mod' cache: true diff --git a/.github/workflows/functional-placement.yaml b/.github/workflows/functional-placement.yaml index 4961b6b262..b78437aff3 100644 --- a/.github/workflows/functional-placement.yaml +++ b/.github/workflows/functional-placement.yaml @@ -43,7 +43,7 @@ jobs: branch: ${{ matrix.openstack_version }} enabled_services: "openstack-cli-server" - name: Checkout go - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 + uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6 with: go-version-file: 'go.mod' cache: true diff --git a/.github/workflows/functional-sharedfilesystems.yaml b/.github/workflows/functional-sharedfilesystems.yaml index 2dba003320..f565aab255 100644 --- a/.github/workflows/functional-sharedfilesystems.yaml +++ b/.github/workflows/functional-sharedfilesystems.yaml @@ -61,7 +61,7 @@ jobs: ${{ matrix.devstack_conf_overrides }} enabled_services: "openstack-cli-server" - name: Checkout go - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 + uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6 with: go-version-file: 'go.mod' cache: true diff --git a/.github/workflows/functional-workflow.yaml b/.github/workflows/functional-workflow.yaml index c9092f0dcb..6100c4c157 100644 --- a/.github/workflows/functional-workflow.yaml +++ b/.github/workflows/functional-workflow.yaml @@ -48,7 +48,7 @@ jobs: enable_plugin mistral https://github.com/openstack/mistral ${{ matrix.mistral_plugin_version }} enabled_services: "mistral,mistral-api,mistral-engine,mistral-executor,mistral-event-engine,openstack-cli-server" - name: Checkout go - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 + uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6 with: go-version-file: 'go.mod' cache: true diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index a40bdc6e48..1e02313d72 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -12,7 +12,7 @@ jobs: uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v6 with: persist-credentials: false - - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 + - uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6 with: go-version-file: 'go.mod' cache: true diff --git a/.github/workflows/semver.yaml b/.github/workflows/semver.yaml index 40e3ef0f99..14cf7e12a1 100644 --- a/.github/workflows/semver.yaml +++ b/.github/workflows/semver.yaml @@ -28,7 +28,7 @@ jobs: GIT_SEQUENCE_EDITOR: '/usr/bin/true' BASE_REF: ${{ github.base_ref }} - - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 + - uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6 with: go-version-file: 'go.mod' cache: true diff --git a/.github/workflows/unit.yaml b/.github/workflows/unit.yaml index f7c8916cd9..2d05b4a740 100644 --- a/.github/workflows/unit.yaml +++ b/.github/workflows/unit.yaml @@ -18,7 +18,7 @@ jobs: with: persist-credentials: false - name: Setup Go - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 + uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6 with: go-version-file: 'go.mod' cache: true From 0b02a6b50e52799cba8ea95a7cec6736775d3a80 Mon Sep 17 00:00:00 2001 From: Winicius Allan Date: Thu, 9 Jul 2026 12:26:44 -0300 Subject: [PATCH 352/353] create an external router when testing L3RouterScheduling --- .../networking/v2/extensions/layer3/l3_scheduling_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/acceptance/openstack/networking/v2/extensions/layer3/l3_scheduling_test.go b/internal/acceptance/openstack/networking/v2/extensions/layer3/l3_scheduling_test.go index f186118d44..71a54c1a4a 100644 --- a/internal/acceptance/openstack/networking/v2/extensions/layer3/l3_scheduling_test.go +++ b/internal/acceptance/openstack/networking/v2/extensions/layer3/l3_scheduling_test.go @@ -29,7 +29,7 @@ func TestLayer3RouterScheduling(t *testing.T) { th.AssertNoErr(t, err) defer v2.DeleteSubnet(t, client, subnet.ID) - router, err := CreateRouter(t, client, network.ID) + router, err := CreateExternalRouter(t, client) th.AssertNoErr(t, err) defer DeleteRouter(t, client, router.ID) tools.PrintResource(t, router) From 80f3a9fee6cd6eeda160d0cd3c40ab13d0ccf25a Mon Sep 17 00:00:00 2001 From: abhijith-darshan Date: Fri, 10 Jul 2026 20:27:54 +0200 Subject: [PATCH 353/353] dns: add X-Auth-All-Projects and X-Auth-Sudo-Tenant-ID header support to recordsets Add AllProjects and SudoTenantID fields to ListOpts, CreateOpts, UpdateOpts, and DeleteOpts, allowing admin users to enumerate and manage recordsets across projects via X-Auth-All-Projects header, and to impersonate a tenant via X-Auth-Sudo-Tenant-ID header. Follows the optional type assertion pattern established in the zones package. DeleteWithOpts is introduced as a new function to pass optional headers without breaking the existing Delete signature. Closes #3803 --- internal/acceptance/openstack/dns/v2/dns.go | 9 ++ .../openstack/dns/v2/recordsets_test.go | 62 ++++++++ openstack/dns/v2/recordsets/doc.go | 99 ++++++++++++ openstack/dns/v2/recordsets/requests.go | 150 ++++++++++++++++-- .../v2/recordsets/testing/fixtures_test.go | 71 +++++++++ .../v2/recordsets/testing/requests_test.go | 80 ++++++++++ 6 files changed, 454 insertions(+), 17 deletions(-) diff --git a/internal/acceptance/openstack/dns/v2/dns.go b/internal/acceptance/openstack/dns/v2/dns.go index 596ce75431..0e2d48dbb7 100644 --- a/internal/acceptance/openstack/dns/v2/dns.go +++ b/internal/acceptance/openstack/dns/v2/dns.go @@ -234,6 +234,15 @@ func DeleteRecordSet(t *testing.T, client *gophercloud.ServiceClient, rs *record t.Logf("Deleted record set: %s", rs.ID) } +func DeleteRecordSetAllProjects(t *testing.T, client *gophercloud.ServiceClient, rs *recordsets.RecordSet) { + err := recordsets.DeleteWithOpts(context.TODO(), client, rs.ZoneID, rs.ID, recordsets.DeleteOpts{AllProjects: true}).ExtractErr() + if err != nil { + t.Fatalf("Unable to delete record set %s: %v", rs.ID, err) + } + + t.Logf("Deleted record set: %s", rs.ID) +} + // DeleteZone will delete a specified zone. A fatal error will occur if // the zone failed to be deleted. This works best when used as a deferred // function. diff --git a/internal/acceptance/openstack/dns/v2/recordsets_test.go b/internal/acceptance/openstack/dns/v2/recordsets_test.go index 7030791f6d..ac7345226d 100644 --- a/internal/acceptance/openstack/dns/v2/recordsets_test.go +++ b/internal/acceptance/openstack/dns/v2/recordsets_test.go @@ -149,3 +149,65 @@ func TestRecordSetsCRUD(t *testing.T) { th.AssertDeepEquals(t, newRS.Records, records) th.AssertEquals(t, newRS.TTL, ttl) } + +func TestRecordSetsListByZoneWithAllProjects(t *testing.T) { + clients.RequireAdmin(t) + + client, err := clients.NewDNSV2Client() + th.AssertNoErr(t, err) + + zone, err := CreateZone(t, client) + th.AssertNoErr(t, err) + defer DeleteZone(t, client, zone) + + rs, err := CreateRecordSet(t, client, zone) + th.AssertNoErr(t, err) + defer DeleteRecordSetAllProjects(t, client, rs) + + listOpts := recordsets.ListOpts{AllProjects: true} + allPages, err := recordsets.ListByZone(client, zone.ID, listOpts).AllPages(context.TODO()) + th.AssertNoErr(t, err) + + allRecordSets, err := recordsets.ExtractRecordSets(allPages) + th.AssertNoErr(t, err) + + var found bool + for _, recordset := range allRecordSets { + if recordset.ID == rs.ID { + found = true + } + } + + th.AssertEquals(t, found, true) +} + +func TestRecordSetsListAllWithAllProjects(t *testing.T) { + clients.RequireAdmin(t) + + client, err := clients.NewDNSV2Client() + th.AssertNoErr(t, err) + + zone, err := CreateZone(t, client) + th.AssertNoErr(t, err) + defer DeleteZone(t, client, zone) + + rs, err := CreateRecordSet(t, client, zone) + th.AssertNoErr(t, err) + defer DeleteRecordSetAllProjects(t, client, rs) + + listOpts := recordsets.ListOpts{AllProjects: true} + allPages, err := recordsets.ListAll(client, listOpts).AllPages(context.TODO()) + th.AssertNoErr(t, err) + + allRecordSets, err := recordsets.ExtractRecordSets(allPages) + th.AssertNoErr(t, err) + + var found bool + for _, recordset := range allRecordSets { + if recordset.ID == rs.ID { + found = true + } + } + + th.AssertEquals(t, found, true) +} diff --git a/openstack/dns/v2/recordsets/doc.go b/openstack/dns/v2/recordsets/doc.go index c1f6f93c56..67cf2d1472 100644 --- a/openstack/dns/v2/recordsets/doc.go +++ b/openstack/dns/v2/recordsets/doc.go @@ -24,6 +24,48 @@ Example to List RecordSets by Zone fmt.Printf("%+v\n", rr) } +Example to List RecordSets by Zone across projects (admin) + + listOpts := recordsets.ListOpts{ + AllProjects: true, + } + + zoneID := "fff121f5-c506-410a-a69e-2d73ef9cbdbd" + + allPages, err := recordsets.ListByZone(dnsClient, zoneID, listOpts).AllPages(context.TODO()) + if err != nil { + panic(err) + } + + allRRs, err := recordsets.ExtractRecordSets(allPages) + if err != nil { + panic(err) + } + + for _, rr := range allRRs { + fmt.Printf("%+v\n", rr) + } + +Example to List all RecordSets across zones and all projects (admin) + + listOpts := recordsets.ListOpts{ + AllProjects: true, + } + + allPages, err := recordsets.ListAll(dnsClient, listOpts).AllPages(context.TODO()) + if err != nil { + panic(err) + } + + allRRs, err := recordsets.ExtractRecordSets(allPages) + if err != nil { + panic(err) + } + + for _, rr := range allRRs { + fmt.Printf("%+v\n", rr) + } + Example to Create a RecordSet createOpts := recordsets.CreateOpts{ @@ -41,6 +83,53 @@ Example to Create a RecordSet panic(err) } +Example to Create a RecordSet across projects (admin) + + createOpts := recordsets.CreateOpts{ + Name: "example.com.", + Type: "A", + TTL: 3600, + Description: "This is a recordset.", + Records: []string{"10.1.0.2"}, + AllProjects: true, + } + + zoneID := "fff121f5-c506-410a-a69e-2d73ef9cbdbd" + + rr, err := recordsets.Create(context.TODO(), dnsClient, zoneID, createOpts).Extract() + if err != nil { + panic(err) + } + +Example to Update a RecordSet + + recordsetID := "d96ed01a-b439-4eb8-9b90-7a9f71017f7b" + zoneID := "fff121f5-c506-410a-a69e-2d73ef9cbdbd" + + updateOpts := recordsets.UpdateOpts{ + Records: []string{"10.1.0.3"}, + } + + rr, err := recordsets.Update(context.TODO(), dnsClient, zoneID, recordsetID, updateOpts).Extract() + if err != nil { + panic(err) + } + +Example to Update a RecordSet across projects (admin) + + recordsetID := "d96ed01a-b439-4eb8-9b90-7a9f71017f7b" + zoneID := "fff121f5-c506-410a-a69e-2d73ef9cbdbd" + + updateOpts := recordsets.UpdateOpts{ + Records: []string{"10.1.0.3"}, + AllProjects: true, + } + + rr, err := recordsets.Update(context.TODO(), dnsClient, zoneID, recordsetID, updateOpts).Extract() + if err != nil { + panic(err) + } + Example to Delete a RecordSet zoneID := "fff121f5-c506-410a-a69e-2d73ef9cbdbd" @@ -50,5 +139,15 @@ Example to Delete a RecordSet if err != nil { panic(err) } + +Example to Delete a RecordSet across projects (admin) + + zoneID := "fff121f5-c506-410a-a69e-2d73ef9cbdbd" + recordsetID := "d96ed01a-b439-4eb8-9b90-7a9f71017f7b" + + err := recordsets.DeleteWithOpts(context.TODO(), dnsClient, zoneID, recordsetID, recordsets.DeleteOpts{AllProjects: true}).ExtractErr() + if err != nil { + panic(err) + } */ package recordsets diff --git a/openstack/dns/v2/recordsets/requests.go b/openstack/dns/v2/recordsets/requests.go index 2bf952446c..fafd490261 100644 --- a/openstack/dns/v2/recordsets/requests.go +++ b/openstack/dns/v2/recordsets/requests.go @@ -13,6 +13,37 @@ type ListOptsBuilder interface { ToRecordSetListQuery() (string, error) } +// ListOptsHeadersBuilder allows extensions to add additional headers to the List request. +type ListOptsHeadersBuilder interface { + ToRecordSetListHeaders() (map[string]string, error) +} + +// RequestOptsHeadersBuilder allows extensions to add additional headers to +// Create and Update requests. +type RequestOptsHeadersBuilder interface { + ToRecordSetRequestHeaders() (map[string]string, error) +} + +// DeleteOptsBuilder allows extensions to add additional headers to the +// Delete request. +type DeleteOptsBuilder interface { + ToRecordSetDeleteHeaders() (map[string]string, error) +} + +// DeleteOpts specifies headers that may be set on a DeleteWithOpts request. +type DeleteOpts struct { + // AllProjects header. + AllProjects bool `h:"X-Auth-All-Projects"` + + // SudoTenantID impersonates the given project. + SudoTenantID string `h:"X-Auth-Sudo-Tenant-ID"` +} + +// ToRecordSetDeleteHeaders formats a DeleteOpts into header parameters. +func (opts DeleteOpts) ToRecordSetDeleteHeaders() (map[string]string, error) { + return gophercloud.BuildHeaders(opts) +} + // ListOpts allows the filtering and sorting of paginated collections through // the API. Filtering is achieved by passing in struct field values that map to // the server attributes you want to see returned. Marker and Limit are used @@ -25,15 +56,17 @@ type ListOpts struct { // UUID of the recordset at which you want to set a marker. Marker string `q:"marker"` - Data string `q:"data"` - Description string `q:"description"` - Name string `q:"name"` - SortDir string `q:"sort_dir"` - SortKey string `q:"sort_key"` - Status string `q:"status"` - TTL int `q:"ttl"` - Type string `q:"type"` - ZoneID string `q:"zone_id"` + Data string `q:"data"` + Description string `q:"description"` + Name string `q:"name"` + SortDir string `q:"sort_dir"` + SortKey string `q:"sort_key"` + Status string `q:"status"` + TTL int `q:"ttl"` + Type string `q:"type"` + ZoneID string `q:"zone_id"` + AllProjects bool `h:"X-Auth-All-Projects"` + SudoTenantID string `h:"X-Auth-Sudo-Tenant-ID"` } // ToRecordSetListQuery formats a ListOpts into a query string. @@ -42,34 +75,65 @@ func (opts ListOpts) ToRecordSetListQuery() (string, error) { return q.String(), err } +// ToRecordSetListHeaders formats a ListOpts into header parameters. +func (opts ListOpts) ToRecordSetListHeaders() (map[string]string, error) { + return gophercloud.BuildHeaders(opts) +} + // ListByZone implements the recordset list request for a specific zone. func ListByZone(client *gophercloud.ServiceClient, zoneID string, opts ListOptsBuilder) pagination.Pager { url := baseURL(client, zoneID) + var h map[string]string + if opts != nil { query, err := opts.ToRecordSetListQuery() if err != nil { return pagination.Pager{Err: err} } url += query + + // Check if opts implements the optional headers interface + if optsWithHeaders, ok := opts.(ListOptsHeadersBuilder); ok { + h, err = optsWithHeaders.ToRecordSetListHeaders() + if err != nil { + return pagination.Pager{Err: err} + } + } } - return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { + + pager := pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { return RecordSetPage{pagination.LinkedPageBase{PageResult: r}} }) + pager.Headers = h + return pager } // ListAll implements the recordset list request across all zones. func ListAll(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { url := listAllRecordSetsURL(client) + var h map[string]string + if opts != nil { query, err := opts.ToRecordSetListQuery() if err != nil { return pagination.Pager{Err: err} } url += query + + // Check if opts implements the optional headers interface + if optsWithHeaders, ok := opts.(ListOptsHeadersBuilder); ok { + h, err = optsWithHeaders.ToRecordSetListHeaders() + if err != nil { + return pagination.Pager{Err: err} + } + } } - return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { + + pager := pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { return RecordSetPage{pagination.LinkedPageBase{PageResult: r}} }) + pager.Headers = h + return pager } // Get implements the recordset Get request. @@ -102,6 +166,12 @@ type CreateOpts struct { // Type is the RRTYPE of the RecordSet. Type string `json:"type,omitempty"` + + // AllProjects header. + AllProjects bool `h:"X-Auth-All-Projects" json:"-"` + + // SudoTenantID impersonates the given project. + SudoTenantID string `h:"X-Auth-Sudo-Tenant-ID" json:"-"` } // ToRecordSetCreateMap formats an CreateOpts structure into a request body. @@ -114,6 +184,11 @@ func (opts CreateOpts) ToRecordSetCreateMap() (map[string]any, error) { return b, nil } +// ToRecordSetRequestHeaders formats a CreateOpts into header parameters. +func (opts CreateOpts) ToRecordSetRequestHeaders() (map[string]string, error) { + return gophercloud.BuildHeaders(opts) +} + // Create creates a recordset in a given zone. func Create(ctx context.Context, client *gophercloud.ServiceClient, zoneID string, opts CreateOptsBuilder) (r CreateResult) { b, err := opts.ToRecordSetCreateMap() @@ -121,9 +196,16 @@ func Create(ctx context.Context, client *gophercloud.ServiceClient, zoneID strin r.Err = err return } - resp, err := client.Post(ctx, baseURL(client, zoneID), &b, &r.Body, &gophercloud.RequestOpts{ - OkCodes: []int{201, 202}, - }) + reqOpts := &gophercloud.RequestOpts{OkCodes: []int{201, 202}} + // Check if opts implements the optional headers interface + if optsWithHeaders, ok := opts.(RequestOptsHeadersBuilder); ok { + reqOpts.MoreHeaders, err = optsWithHeaders.ToRecordSetRequestHeaders() + if err != nil { + r.Err = err + return + } + } + resp, err := client.Post(ctx, baseURL(client, zoneID), &b, &r.Body, reqOpts) _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) return } @@ -145,6 +227,17 @@ type UpdateOpts struct { // Records are the DNS records of the RecordSet. Records []string `json:"records,omitempty"` + + // AllProjects header. + AllProjects bool `h:"X-Auth-All-Projects" json:"-"` + + // SudoTenantID impersonates the given project. + SudoTenantID string `h:"X-Auth-Sudo-Tenant-ID" json:"-"` +} + +// ToRecordSetRequestHeaders formats an UpdateOpts into header parameters. +func (opts UpdateOpts) ToRecordSetRequestHeaders() (map[string]string, error) { + return gophercloud.BuildHeaders(opts) } // ToRecordSetUpdateMap formats an UpdateOpts structure into a request body. @@ -177,9 +270,16 @@ func Update(ctx context.Context, client *gophercloud.ServiceClient, zoneID strin r.Err = err return } - resp, err := client.Put(ctx, rrsetURL(client, zoneID, rrsetID), &b, &r.Body, &gophercloud.RequestOpts{ - OkCodes: []int{200, 202}, - }) + reqOpts := &gophercloud.RequestOpts{OkCodes: []int{200, 202}} + // Check if opts implements the optional headers interface + if optsWithHeaders, ok := opts.(RequestOptsHeadersBuilder); ok { + reqOpts.MoreHeaders, err = optsWithHeaders.ToRecordSetRequestHeaders() + if err != nil { + r.Err = err + return + } + } + resp, err := client.Put(ctx, rrsetURL(client, zoneID, rrsetID), &b, &r.Body, reqOpts) _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) return } @@ -192,3 +292,19 @@ func Delete(ctx context.Context, client *gophercloud.ServiceClient, zoneID strin _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) return } + +// DeleteWithOpts removes an existing RecordSet with additional header options. +func DeleteWithOpts(ctx context.Context, client *gophercloud.ServiceClient, zoneID string, rrsetID string, opts DeleteOptsBuilder) (r DeleteResult) { + reqOpts := &gophercloud.RequestOpts{OkCodes: []int{202}} + if opts != nil { + h, err := opts.ToRecordSetDeleteHeaders() + if err != nil { + r.Err = err + return + } + reqOpts.MoreHeaders = h + } + resp, err := client.Delete(ctx, rrsetURL(client, zoneID, rrsetID), reqOpts) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} diff --git a/openstack/dns/v2/recordsets/testing/fixtures_test.go b/openstack/dns/v2/recordsets/testing/fixtures_test.go index 037f3d374d..be102f5e64 100644 --- a/openstack/dns/v2/recordsets/testing/fixtures_test.go +++ b/openstack/dns/v2/recordsets/testing/fixtures_test.go @@ -223,6 +223,19 @@ func HandleListByZoneSuccessfully(t *testing.T, fakeServer th.FakeServer) { }) } +// HandleListByZoneAllProjectsSuccessfully configures the test server to respond to a ListByZone +// request with the X-Auth-All-Projects header set. +func HandleListByZoneAllProjectsSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/zones/2150b1bf-dee2-4221-9d85-11f7886fb15f/recordsets", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.TestHeader(t, r, "X-Auth-All-Projects", "true") + + w.Header().Add("Content-Type", "application/json") + fmt.Fprint(w, ListByZoneOutput) + }) +} + // HandleListAllSuccessfully configures the test server to respond to a ListAll request. func HandleListAllSuccessfully(t *testing.T, fakeServer th.FakeServer) { fakeServer.Mux.HandleFunc("/recordsets", func(w http.ResponseWriter, r *http.Request) { @@ -230,6 +243,19 @@ func HandleListAllSuccessfully(t *testing.T, fakeServer th.FakeServer) { }) } +// HandleListAllAllProjectsSuccessfully configures the test server to respond to a ListAll +// request with the X-Auth-All-Projects header set. +func HandleListAllAllProjectsSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/recordsets", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.TestHeader(t, r, "X-Auth-All-Projects", "true") + + w.Header().Add("Content-Type", "application/json") + fmt.Fprint(w, ListByZoneOutput) + }) +} + // HandleGetSuccessfully configures the test server to respond to a Get request. func HandleGetSuccessfully(t *testing.T, fakeServer th.FakeServer) { fakeServer.Mux.HandleFunc("/zones/2150b1bf-dee2-4221-9d85-11f7886fb15f/recordsets/f7b10e9b-0cae-4a91-b162-562bc6096648", @@ -297,6 +323,22 @@ func HandleCreateSuccessfully(t *testing.T, fakeServer th.FakeServer) { }) } +// HandleCreateAllProjectsSuccessfully configures the test server to respond to a Create request +// with the X-Auth-All-Projects header set. +func HandleCreateAllProjectsSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/zones/2150b1bf-dee2-4221-9d85-11f7886fb15f/recordsets", + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "POST") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.TestHeader(t, r, "X-Auth-All-Projects", "true") + th.TestJSONRequest(t, r, CreateRecordSetRequest) + + w.WriteHeader(http.StatusCreated) + w.Header().Add("Content-Type", "application/json") + fmt.Fprint(w, CreateRecordSetResponse) + }) +} + // UpdateRecordSetRequest is a sample request to update a record set. const UpdateRecordSetRequest = ` { @@ -349,6 +391,22 @@ func HandleUpdateSuccessfully(t *testing.T, fakeServer th.FakeServer) { }) } +// HandleUpdateAllProjectsSuccessfully configures the test server to respond to an Update request +// with the X-Auth-All-Projects header set. +func HandleUpdateAllProjectsSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/zones/2150b1bf-dee2-4221-9d85-11f7886fb15f/recordsets/f7b10e9b-0cae-4a91-b162-562bc6096648", + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "PUT") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.TestHeader(t, r, "X-Auth-All-Projects", "true") + th.TestJSONRequest(t, r, UpdateRecordSetRequest) + + w.WriteHeader(http.StatusOK) + w.Header().Add("Content-Type", "application/json") + fmt.Fprint(w, UpdateRecordSetResponse) + }) +} + // DeleteRecordSetResponse is a sample response to a delete request. const DeleteRecordSetResponse = ` { @@ -387,3 +445,16 @@ func HandleDeleteSuccessfully(t *testing.T, fakeServer th.FakeServer) { //fmt.Fprint(w, DeleteZoneResponse) }) } + +// HandleDeleteAllProjectsSuccessfully configures the test server to respond to a Delete request +// with the X-Auth-All-Projects header set. +func HandleDeleteAllProjectsSuccessfully(t *testing.T, fakeServer th.FakeServer) { + fakeServer.Mux.HandleFunc("/zones/2150b1bf-dee2-4221-9d85-11f7886fb15f/recordsets/f7b10e9b-0cae-4a91-b162-562bc6096648", + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "DELETE") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.TestHeader(t, r, "X-Auth-All-Projects", "true") + + w.WriteHeader(http.StatusAccepted) + }) +} diff --git a/openstack/dns/v2/recordsets/testing/requests_test.go b/openstack/dns/v2/recordsets/testing/requests_test.go index f2adcd7012..564d269e96 100644 --- a/openstack/dns/v2/recordsets/testing/requests_test.go +++ b/openstack/dns/v2/recordsets/testing/requests_test.go @@ -198,3 +198,83 @@ func TestDelete(t *testing.T) { th.AssertNoErr(t, err) //th.CheckDeepEquals(t, &DeletedZone, actual) } + +func TestListByZoneWithAllProjects(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListByZoneAllProjectsSuccessfully(t, fakeServer) + + opts := recordsets.ListOpts{AllProjects: true} + allPages, err := recordsets.ListByZone(client.ServiceClient(fakeServer), "2150b1bf-dee2-4221-9d85-11f7886fb15f", opts).AllPages(context.TODO()) + th.AssertNoErr(t, err) + allRecordSets, err := recordsets.ExtractRecordSets(allPages) + th.AssertNoErr(t, err) + th.CheckEquals(t, 2, len(allRecordSets)) +} + +func TestListAllWithAllProjects(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleListAllAllProjectsSuccessfully(t, fakeServer) + + opts := recordsets.ListOpts{AllProjects: true} + allPages, err := recordsets.ListAll(client.ServiceClient(fakeServer), opts).AllPages(context.TODO()) + th.AssertNoErr(t, err) + allRecordSets, err := recordsets.ExtractRecordSets(allPages) + th.AssertNoErr(t, err) + th.CheckEquals(t, 2, len(allRecordSets)) +} + +func TestCreateWithAllProjects(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleCreateAllProjectsSuccessfully(t, fakeServer) + + createOpts := recordsets.CreateOpts{ + Name: "example.org.", + Type: "A", + TTL: 3600, + Description: "This is an example record set.", + Records: []string{"10.1.0.2"}, + AllProjects: true, + } + + actual, err := recordsets.Create(context.TODO(), client.ServiceClient(fakeServer), "2150b1bf-dee2-4221-9d85-11f7886fb15f", createOpts).Extract() + th.AssertNoErr(t, err) + th.CheckDeepEquals(t, &CreatedRecordSet, actual) +} + +func TestUpdateWithAllProjects(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleUpdateAllProjectsSuccessfully(t, fakeServer) + + var description = "Updated description" + ttl := 0 + updateOpts := recordsets.UpdateOpts{ + TTL: &ttl, + Description: &description, + Records: []string{"10.1.0.2", "10.1.0.3"}, + AllProjects: true, + } + + UpdatedRecordSet := CreatedRecordSet + UpdatedRecordSet.Status = "PENDING" + UpdatedRecordSet.Action = "UPDATE" + UpdatedRecordSet.Description = "Updated description" + UpdatedRecordSet.Records = []string{"10.1.0.2", "10.1.0.3"} + UpdatedRecordSet.Version = 2 + + actual, err := recordsets.Update(context.TODO(), client.ServiceClient(fakeServer), UpdatedRecordSet.ZoneID, UpdatedRecordSet.ID, updateOpts).Extract() + th.AssertNoErr(t, err) + th.CheckDeepEquals(t, &UpdatedRecordSet, actual) +} + +func TestDeleteWithAllProjects(t *testing.T) { + fakeServer := th.SetupHTTP() + defer fakeServer.Teardown() + HandleDeleteAllProjectsSuccessfully(t, fakeServer) + + err := recordsets.DeleteWithOpts(context.TODO(), client.ServiceClient(fakeServer), "2150b1bf-dee2-4221-9d85-11f7886fb15f", "f7b10e9b-0cae-4a91-b162-562bc6096648", recordsets.DeleteOpts{AllProjects: true}).ExtractErr() + th.AssertNoErr(t, err) +}