Replace godep with dep
This commit is contained in:
parent
1e7489927c
commit
bf5616c65b
14883 changed files with 3937406 additions and 361781 deletions
2
vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/gce/doc.go
generated
vendored
2
vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/gce/doc.go
generated
vendored
|
|
@ -16,4 +16,4 @@ limitations under the License.
|
|||
|
||||
// Package gce is an implementation of Interface, LoadBalancer
|
||||
// and Instances for Google Compute Engine.
|
||||
package gce
|
||||
package gce // import "k8s.io/kubernetes/pkg/cloudprovider/providers/gce"
|
||||
|
|
|
|||
137
vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/gce/gce_address_manager_test.go
generated
vendored
Normal file
137
vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/gce/gce_address_manager_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package gce
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
computebeta "google.golang.org/api/compute/v0.beta"
|
||||
)
|
||||
|
||||
const testSvcName = "my-service"
|
||||
const testRegion = "us-central1"
|
||||
const testSubnet = "/projects/x/testRegions/us-central1/testSubnetworks/customsub"
|
||||
const testLBName = "a111111111111111"
|
||||
|
||||
// TestAddressManagerNoRequestedIP tests the typical case of passing in no requested IP
|
||||
func TestAddressManagerNoRequestedIP(t *testing.T) {
|
||||
svc := NewFakeCloudAddressService()
|
||||
targetIP := ""
|
||||
|
||||
mgr := newAddressManager(svc, testSvcName, testRegion, testSubnet, testLBName, targetIP, schemeInternal)
|
||||
testHoldAddress(t, mgr, svc, testLBName, testRegion, targetIP, string(schemeInternal))
|
||||
testReleaseAddress(t, mgr, svc, testLBName, testRegion)
|
||||
}
|
||||
|
||||
// TestAddressManagerBasic tests the typical case of reserving and unreserving an address.
|
||||
func TestAddressManagerBasic(t *testing.T) {
|
||||
svc := NewFakeCloudAddressService()
|
||||
targetIP := "1.1.1.1"
|
||||
|
||||
mgr := newAddressManager(svc, testSvcName, testRegion, testSubnet, testLBName, targetIP, schemeInternal)
|
||||
testHoldAddress(t, mgr, svc, testLBName, testRegion, targetIP, string(schemeInternal))
|
||||
testReleaseAddress(t, mgr, svc, testLBName, testRegion)
|
||||
}
|
||||
|
||||
// TestAddressManagerOrphaned tests the case where the address exists with the IP being equal
|
||||
// to the requested address (forwarding rule or loadbalancer IP).
|
||||
func TestAddressManagerOrphaned(t *testing.T) {
|
||||
svc := NewFakeCloudAddressService()
|
||||
targetIP := "1.1.1.1"
|
||||
|
||||
addr := &computebeta.Address{Name: testLBName, Address: targetIP, AddressType: string(schemeInternal)}
|
||||
err := svc.ReserveBetaRegionAddress(addr, testRegion)
|
||||
require.NoError(t, err)
|
||||
|
||||
mgr := newAddressManager(svc, testSvcName, testRegion, testSubnet, testLBName, targetIP, schemeInternal)
|
||||
testHoldAddress(t, mgr, svc, testLBName, testRegion, targetIP, string(schemeInternal))
|
||||
testReleaseAddress(t, mgr, svc, testLBName, testRegion)
|
||||
}
|
||||
|
||||
// TestAddressManagerOutdatedOrphan tests the case where an address exists but points to
|
||||
// an IP other than the forwarding rule or loadbalancer IP.
|
||||
func TestAddressManagerOutdatedOrphan(t *testing.T) {
|
||||
svc := NewFakeCloudAddressService()
|
||||
previousAddress := "1.1.0.0"
|
||||
targetIP := "1.1.1.1"
|
||||
|
||||
addr := &computebeta.Address{Name: testLBName, Address: previousAddress, AddressType: string(schemeExternal)}
|
||||
err := svc.ReserveBetaRegionAddress(addr, testRegion)
|
||||
require.NoError(t, err)
|
||||
|
||||
mgr := newAddressManager(svc, testSvcName, testRegion, testSubnet, testLBName, targetIP, schemeInternal)
|
||||
testHoldAddress(t, mgr, svc, testLBName, testRegion, targetIP, string(schemeInternal))
|
||||
testReleaseAddress(t, mgr, svc, testLBName, testRegion)
|
||||
}
|
||||
|
||||
// TestAddressManagerExternallyOwned tests the case where the address exists but isn't
|
||||
// owned by the controller.
|
||||
func TestAddressManagerExternallyOwned(t *testing.T) {
|
||||
svc := NewFakeCloudAddressService()
|
||||
targetIP := "1.1.1.1"
|
||||
|
||||
addr := &computebeta.Address{Name: "my-important-address", Address: targetIP, AddressType: string(schemeInternal)}
|
||||
err := svc.ReserveBetaRegionAddress(addr, testRegion)
|
||||
require.NoError(t, err)
|
||||
|
||||
mgr := newAddressManager(svc, testSvcName, testRegion, testSubnet, testLBName, targetIP, schemeInternal)
|
||||
ipToUse, err := mgr.HoldAddress()
|
||||
require.NoError(t, err)
|
||||
assert.NotEmpty(t, ipToUse)
|
||||
|
||||
_, err = svc.GetRegionAddress(testLBName, testRegion)
|
||||
assert.True(t, isNotFound(err))
|
||||
|
||||
testReleaseAddress(t, mgr, svc, testLBName, testRegion)
|
||||
}
|
||||
|
||||
// TestAddressManagerExternallyOwned tests the case where the address exists but isn't
|
||||
// owned by the controller. However, this address has the wrong type.
|
||||
func TestAddressManagerBadExternallyOwned(t *testing.T) {
|
||||
svc := NewFakeCloudAddressService()
|
||||
targetIP := "1.1.1.1"
|
||||
|
||||
addr := &computebeta.Address{Name: "my-important-address", Address: targetIP, AddressType: string(schemeExternal)}
|
||||
err := svc.ReserveBetaRegionAddress(addr, testRegion)
|
||||
require.NoError(t, err)
|
||||
|
||||
mgr := newAddressManager(svc, testSvcName, testRegion, testSubnet, testLBName, targetIP, schemeInternal)
|
||||
_, err = mgr.HoldAddress()
|
||||
assert.NotNil(t, err)
|
||||
}
|
||||
|
||||
func testHoldAddress(t *testing.T, mgr *addressManager, svc CloudAddressService, name, region, targetIP, scheme string) {
|
||||
ipToUse, err := mgr.HoldAddress()
|
||||
require.NoError(t, err)
|
||||
assert.NotEmpty(t, ipToUse)
|
||||
|
||||
addr, err := svc.GetBetaRegionAddress(name, region)
|
||||
require.NoError(t, err)
|
||||
if targetIP != "" {
|
||||
assert.EqualValues(t, targetIP, addr.Address)
|
||||
}
|
||||
assert.EqualValues(t, scheme, addr.AddressType)
|
||||
}
|
||||
|
||||
func testReleaseAddress(t *testing.T, mgr *addressManager, svc CloudAddressService, name, region string) {
|
||||
err := mgr.ReleaseAddress()
|
||||
require.NoError(t, err)
|
||||
_, err = svc.GetBetaRegionAddress(name, region)
|
||||
assert.True(t, isNotFound(err))
|
||||
}
|
||||
70
vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/gce/gce_annotations_test.go
generated
vendored
Normal file
70
vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/gce/gce_annotations_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package gce
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestServiceNetworkTierAnnotationKey(t *testing.T) {
|
||||
createTestService := func() *v1.Service {
|
||||
return &v1.Service{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
UID: "randome-uid",
|
||||
Name: "test-svc",
|
||||
Namespace: "test-ns",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
for testName, testCase := range map[string]struct {
|
||||
annotations map[string]string
|
||||
expectedTier NetworkTier
|
||||
expectErr bool
|
||||
}{
|
||||
"Use the default when the annotation does not exist": {
|
||||
annotations: nil,
|
||||
expectedTier: NetworkTierDefault,
|
||||
},
|
||||
"Standard tier": {
|
||||
annotations: map[string]string{NetworkTierAnnotationKey: "Standard"},
|
||||
expectedTier: NetworkTierStandard,
|
||||
},
|
||||
"Premium tier": {
|
||||
annotations: map[string]string{NetworkTierAnnotationKey: "Premium"},
|
||||
expectedTier: NetworkTierPremium,
|
||||
},
|
||||
"Report an error on invalid network tier value": {
|
||||
annotations: map[string]string{NetworkTierAnnotationKey: "Unknown-tier"},
|
||||
expectedTier: NetworkTierPremium,
|
||||
expectErr: true,
|
||||
},
|
||||
} {
|
||||
t.Run(testName, func(t *testing.T) {
|
||||
svc := createTestService()
|
||||
svc.Annotations = testCase.annotations
|
||||
actualTier, err := GetServiceNetworkTier(svc)
|
||||
assert.Equal(t, testCase.expectedTier, actualTier)
|
||||
assert.Equal(t, testCase.expectErr, err != nil)
|
||||
})
|
||||
}
|
||||
}
|
||||
927
vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/gce/gce_disks_test.go
generated
vendored
Normal file
927
vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/gce/gce_disks_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,927 @@
|
|||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package gce
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"fmt"
|
||||
|
||||
computealpha "google.golang.org/api/compute/v0.alpha"
|
||||
computebeta "google.golang.org/api/compute/v0.beta"
|
||||
compute "google.golang.org/api/compute/v1"
|
||||
"google.golang.org/api/googleapi"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/kubernetes/pkg/cloudprovider"
|
||||
kubeletapis "k8s.io/kubernetes/pkg/kubelet/apis"
|
||||
)
|
||||
|
||||
// TODO TODO write a test for GetDiskByNameUnknownZone and make sure casting logic works
|
||||
// TODO TODO verify that RegionDisks.Get does not return non-replica disks
|
||||
|
||||
func TestCreateDisk_Basic(t *testing.T) {
|
||||
/* Arrange */
|
||||
gceProjectId := "test-project"
|
||||
gceRegion := "fake-region"
|
||||
fakeManager := newFakeManager(gceProjectId, gceRegion)
|
||||
alphaFeatureGate, featureGateErr := NewAlphaFeatureGate([]string{})
|
||||
if featureGateErr != nil {
|
||||
t.Error(featureGateErr)
|
||||
}
|
||||
gce := GCECloud{
|
||||
manager: fakeManager,
|
||||
managedZones: []string{"zone1"},
|
||||
projectID: gceProjectId,
|
||||
AlphaFeatureGate: alphaFeatureGate,
|
||||
}
|
||||
|
||||
diskName := "disk"
|
||||
diskType := DiskTypeSSD
|
||||
zone := "zone1"
|
||||
const sizeGb int64 = 128
|
||||
tags := make(map[string]string)
|
||||
tags["test-tag"] = "test-value"
|
||||
|
||||
expectedDiskTypeURI := gceComputeAPIEndpoint + "projects/" + fmt.Sprintf(
|
||||
diskTypeURITemplateSingleZone, gceProjectId, zone, diskType)
|
||||
expectedDescription := "{\"test-tag\":\"test-value\"}"
|
||||
|
||||
/* Act */
|
||||
err := gce.CreateDisk(diskName, diskType, zone, sizeGb, tags)
|
||||
|
||||
/* Assert */
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if !fakeManager.createDiskCalled {
|
||||
t.Error("Never called GCE disk create.")
|
||||
}
|
||||
if !fakeManager.doesOpMatch {
|
||||
t.Error("Ops used in WaitForZoneOp does not match what's returned by CreateDisk.")
|
||||
}
|
||||
|
||||
// Partial check of equality between disk description sent to GCE and parameters of method.
|
||||
diskToCreate := fakeManager.diskToCreateStable
|
||||
if diskToCreate.Name != diskName {
|
||||
t.Errorf("Expected disk name: %s; Actual: %s", diskName, diskToCreate.Name)
|
||||
}
|
||||
|
||||
if diskToCreate.Type != expectedDiskTypeURI {
|
||||
t.Errorf("Expected disk type: %s; Actual: %s", expectedDiskTypeURI, diskToCreate.Type)
|
||||
}
|
||||
if diskToCreate.SizeGb != sizeGb {
|
||||
t.Errorf("Expected disk size: %d; Actual: %d", sizeGb, diskToCreate.SizeGb)
|
||||
}
|
||||
if diskToCreate.Description != expectedDescription {
|
||||
t.Errorf("Expected tag string: %s; Actual: %s", expectedDescription, diskToCreate.Description)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateRegionalDisk_Basic(t *testing.T) {
|
||||
/* Arrange */
|
||||
gceProjectId := "test-project"
|
||||
gceRegion := "fake-region"
|
||||
fakeManager := newFakeManager(gceProjectId, gceRegion)
|
||||
alphaFeatureGate, featureGateErr := NewAlphaFeatureGate([]string{GCEDiskAlphaFeatureGate})
|
||||
if featureGateErr != nil {
|
||||
t.Error(featureGateErr)
|
||||
}
|
||||
gce := GCECloud{
|
||||
manager: fakeManager,
|
||||
managedZones: []string{"zone1", "zone3", "zone2"},
|
||||
projectID: gceProjectId,
|
||||
AlphaFeatureGate: alphaFeatureGate,
|
||||
}
|
||||
|
||||
diskName := "disk"
|
||||
diskType := DiskTypeSSD
|
||||
replicaZones := sets.NewString("zone1", "zone2")
|
||||
const sizeGb int64 = 128
|
||||
tags := make(map[string]string)
|
||||
tags["test-tag"] = "test-value"
|
||||
|
||||
expectedDiskTypeURI := gceComputeAPIEndpointAlpha + "projects/" + fmt.Sprintf(
|
||||
diskTypeURITemplateRegional, gceProjectId, gceRegion, diskType)
|
||||
expectedDescription := "{\"test-tag\":\"test-value\"}"
|
||||
|
||||
/* Act */
|
||||
err := gce.CreateRegionalDisk(diskName, diskType, replicaZones, sizeGb, tags)
|
||||
|
||||
/* Assert */
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if !fakeManager.createDiskCalled {
|
||||
t.Error("Never called GCE disk create.")
|
||||
}
|
||||
if !fakeManager.doesOpMatch {
|
||||
t.Error("Ops used in WaitForZoneOp does not match what's returned by CreateDisk.")
|
||||
}
|
||||
|
||||
// Partial check of equality between disk description sent to GCE and parameters of method.
|
||||
diskToCreate := fakeManager.diskToCreateStable
|
||||
if diskToCreate.Name != diskName {
|
||||
t.Errorf("Expected disk name: %s; Actual: %s", diskName, diskToCreate.Name)
|
||||
}
|
||||
|
||||
if diskToCreate.Type != expectedDiskTypeURI {
|
||||
t.Errorf("Expected disk type: %s; Actual: %s", expectedDiskTypeURI, diskToCreate.Type)
|
||||
}
|
||||
if diskToCreate.SizeGb != sizeGb {
|
||||
t.Errorf("Expected disk size: %d; Actual: %d", sizeGb, diskToCreate.SizeGb)
|
||||
}
|
||||
if diskToCreate.Description != expectedDescription {
|
||||
t.Errorf("Expected tag string: %s; Actual: %s", expectedDescription, diskToCreate.Description)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateDisk_DiskAlreadyExists(t *testing.T) {
|
||||
/* Arrange */
|
||||
gceProjectId := "test-project"
|
||||
gceRegion := "fake-region"
|
||||
fakeManager := newFakeManager(gceProjectId, gceRegion)
|
||||
alphaFeatureGate, featureGateErr := NewAlphaFeatureGate([]string{})
|
||||
if featureGateErr != nil {
|
||||
t.Error(featureGateErr)
|
||||
}
|
||||
gce := GCECloud{
|
||||
manager: fakeManager,
|
||||
managedZones: []string{"zone1"},
|
||||
AlphaFeatureGate: alphaFeatureGate,
|
||||
}
|
||||
|
||||
// Inject disk AlreadyExists error.
|
||||
alreadyExistsError := googleapi.ErrorItem{Reason: "alreadyExists"}
|
||||
fakeManager.waitForOpError = &googleapi.Error{
|
||||
Errors: []googleapi.ErrorItem{alreadyExistsError},
|
||||
}
|
||||
|
||||
/* Act */
|
||||
err := gce.CreateDisk("disk", DiskTypeSSD, "zone1", 128, nil)
|
||||
|
||||
/* Assert */
|
||||
if err != nil {
|
||||
t.Error(
|
||||
"Expected success when a disk with the given name already exists, but an error is returned.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateDisk_WrongZone(t *testing.T) {
|
||||
/* Arrange */
|
||||
gceProjectId := "test-project"
|
||||
gceRegion := "fake-region"
|
||||
fakeManager := newFakeManager(gceProjectId, gceRegion)
|
||||
gce := GCECloud{manager: fakeManager, managedZones: []string{"zone1"}}
|
||||
|
||||
diskName := "disk"
|
||||
diskType := DiskTypeSSD
|
||||
const sizeGb int64 = 128
|
||||
|
||||
/* Act */
|
||||
err := gce.CreateDisk(diskName, diskType, "zone2", sizeGb, nil)
|
||||
|
||||
/* Assert */
|
||||
if err == nil {
|
||||
t.Error("Expected error when zone is not managed, but none returned.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateDisk_NoManagedZone(t *testing.T) {
|
||||
/* Arrange */
|
||||
gceProjectId := "test-project"
|
||||
gceRegion := "fake-region"
|
||||
fakeManager := newFakeManager(gceProjectId, gceRegion)
|
||||
gce := GCECloud{manager: fakeManager, managedZones: []string{}}
|
||||
|
||||
diskName := "disk"
|
||||
diskType := DiskTypeSSD
|
||||
const sizeGb int64 = 128
|
||||
|
||||
/* Act */
|
||||
err := gce.CreateDisk(diskName, diskType, "zone1", sizeGb, nil)
|
||||
|
||||
/* Assert */
|
||||
if err == nil {
|
||||
t.Error("Expected error when managedZones is empty, but none returned.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateDisk_BadDiskType(t *testing.T) {
|
||||
/* Arrange */
|
||||
gceProjectId := "test-project"
|
||||
gceRegion := "fake-region"
|
||||
fakeManager := newFakeManager(gceProjectId, gceRegion)
|
||||
gce := GCECloud{manager: fakeManager, managedZones: []string{"zone1"}}
|
||||
|
||||
diskName := "disk"
|
||||
diskType := "arbitrary-disk"
|
||||
zone := "zone1"
|
||||
const sizeGb int64 = 128
|
||||
|
||||
/* Act */
|
||||
err := gce.CreateDisk(diskName, diskType, zone, sizeGb, nil)
|
||||
|
||||
/* Assert */
|
||||
if err == nil {
|
||||
t.Error("Expected error when disk type is not supported, but none returned.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateDisk_MultiZone(t *testing.T) {
|
||||
/* Arrange */
|
||||
gceProjectId := "test-project"
|
||||
gceRegion := "fake-region"
|
||||
fakeManager := newFakeManager(gceProjectId, gceRegion)
|
||||
alphaFeatureGate, featureGateErr := NewAlphaFeatureGate([]string{})
|
||||
if featureGateErr != nil {
|
||||
t.Error(featureGateErr)
|
||||
}
|
||||
gce := GCECloud{
|
||||
manager: fakeManager,
|
||||
managedZones: []string{"zone1", "zone2", "zone3"},
|
||||
AlphaFeatureGate: alphaFeatureGate,
|
||||
}
|
||||
|
||||
diskName := "disk"
|
||||
diskType := DiskTypeStandard
|
||||
const sizeGb int64 = 128
|
||||
|
||||
/* Act & Assert */
|
||||
for _, zone := range gce.managedZones {
|
||||
diskName = zone + "disk"
|
||||
err := gce.CreateDisk(diskName, diskType, zone, sizeGb, nil)
|
||||
if err != nil {
|
||||
t.Errorf("Error creating disk in zone '%v'; error: \"%v\"", zone, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeleteDisk_Basic(t *testing.T) {
|
||||
/* Arrange */
|
||||
gceProjectId := "test-project"
|
||||
gceRegion := "fake-region"
|
||||
fakeManager := newFakeManager(gceProjectId, gceRegion)
|
||||
alphaFeatureGate, featureGateErr := NewAlphaFeatureGate([]string{})
|
||||
if featureGateErr != nil {
|
||||
t.Error(featureGateErr)
|
||||
}
|
||||
gce := GCECloud{
|
||||
manager: fakeManager,
|
||||
managedZones: []string{"zone1"},
|
||||
AlphaFeatureGate: alphaFeatureGate,
|
||||
}
|
||||
diskName := "disk"
|
||||
diskType := DiskTypeSSD
|
||||
zone := "zone1"
|
||||
const sizeGb int64 = 128
|
||||
|
||||
gce.CreateDisk(diskName, diskType, zone, sizeGb, nil)
|
||||
|
||||
/* Act */
|
||||
err := gce.DeleteDisk(diskName)
|
||||
|
||||
/* Assert */
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if !fakeManager.deleteDiskCalled {
|
||||
t.Error("Never called GCE disk delete.")
|
||||
}
|
||||
if !fakeManager.doesOpMatch {
|
||||
t.Error("Ops used in WaitForZoneOp does not match what's returned by DeleteDisk.")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestDeleteDisk_NotFound(t *testing.T) {
|
||||
/* Arrange */
|
||||
gceProjectId := "test-project"
|
||||
gceRegion := "fake-region"
|
||||
fakeManager := newFakeManager(gceProjectId, gceRegion)
|
||||
alphaFeatureGate, featureGateErr := NewAlphaFeatureGate([]string{})
|
||||
if featureGateErr != nil {
|
||||
t.Error(featureGateErr)
|
||||
}
|
||||
gce := GCECloud{
|
||||
manager: fakeManager,
|
||||
managedZones: []string{"zone1"},
|
||||
AlphaFeatureGate: alphaFeatureGate,
|
||||
}
|
||||
diskName := "disk"
|
||||
|
||||
/* Act */
|
||||
err := gce.DeleteDisk(diskName)
|
||||
|
||||
/* Assert */
|
||||
if err != nil {
|
||||
t.Error("Expected successful operation when disk is not found, but an error is returned.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeleteDisk_ResourceBeingUsed(t *testing.T) {
|
||||
/* Arrange */
|
||||
gceProjectId := "test-project"
|
||||
gceRegion := "fake-region"
|
||||
fakeManager := newFakeManager(gceProjectId, gceRegion)
|
||||
alphaFeatureGate, featureGateErr := NewAlphaFeatureGate([]string{})
|
||||
if featureGateErr != nil {
|
||||
t.Error(featureGateErr)
|
||||
}
|
||||
gce := GCECloud{
|
||||
manager: fakeManager,
|
||||
managedZones: []string{"zone1"},
|
||||
AlphaFeatureGate: alphaFeatureGate,
|
||||
}
|
||||
diskName := "disk"
|
||||
diskType := DiskTypeSSD
|
||||
zone := "zone1"
|
||||
const sizeGb int64 = 128
|
||||
|
||||
gce.CreateDisk(diskName, diskType, zone, sizeGb, nil)
|
||||
fakeManager.resourceInUse = true
|
||||
|
||||
/* Act */
|
||||
err := gce.DeleteDisk(diskName)
|
||||
|
||||
/* Assert */
|
||||
if err == nil {
|
||||
t.Error("Expected error when disk is in use, but none returned.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeleteDisk_SameDiskMultiZone(t *testing.T) {
|
||||
/* Assert */
|
||||
gceProjectId := "test-project"
|
||||
gceRegion := "fake-region"
|
||||
fakeManager := newFakeManager(gceProjectId, gceRegion)
|
||||
alphaFeatureGate, featureGateErr := NewAlphaFeatureGate([]string{})
|
||||
if featureGateErr != nil {
|
||||
t.Error(featureGateErr)
|
||||
}
|
||||
gce := GCECloud{
|
||||
manager: fakeManager,
|
||||
managedZones: []string{"zone1", "zone2", "zone3"},
|
||||
AlphaFeatureGate: alphaFeatureGate,
|
||||
}
|
||||
diskName := "disk"
|
||||
diskType := DiskTypeSSD
|
||||
const sizeGb int64 = 128
|
||||
|
||||
for _, zone := range gce.managedZones {
|
||||
gce.CreateDisk(diskName, diskType, zone, sizeGb, nil)
|
||||
}
|
||||
|
||||
/* Act */
|
||||
// DeleteDisk will call FakeServiceManager.GetDisk() with all zones,
|
||||
// and FakeServiceManager.GetDisk() always returns a disk,
|
||||
// so DeleteDisk thinks a disk with diskName exists in all zones.
|
||||
err := gce.DeleteDisk(diskName)
|
||||
|
||||
/* Assert */
|
||||
if err == nil {
|
||||
t.Error("Expected error when disk is found in multiple zones, but none returned.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeleteDisk_DiffDiskMultiZone(t *testing.T) {
|
||||
/* Arrange */
|
||||
gceProjectId := "test-project"
|
||||
gceRegion := "fake-region"
|
||||
fakeManager := newFakeManager(gceProjectId, gceRegion)
|
||||
alphaFeatureGate, featureGateErr := NewAlphaFeatureGate([]string{})
|
||||
if featureGateErr != nil {
|
||||
t.Error(featureGateErr)
|
||||
}
|
||||
gce := GCECloud{
|
||||
manager: fakeManager,
|
||||
managedZones: []string{"zone1"},
|
||||
AlphaFeatureGate: alphaFeatureGate,
|
||||
}
|
||||
diskName := "disk"
|
||||
diskType := DiskTypeSSD
|
||||
const sizeGb int64 = 128
|
||||
|
||||
for _, zone := range gce.managedZones {
|
||||
diskName = zone + "disk"
|
||||
gce.CreateDisk(diskName, diskType, zone, sizeGb, nil)
|
||||
}
|
||||
|
||||
/* Act & Assert */
|
||||
var err error
|
||||
for _, zone := range gce.managedZones {
|
||||
diskName = zone + "disk"
|
||||
err = gce.DeleteDisk(diskName)
|
||||
if err != nil {
|
||||
t.Errorf("Error deleting disk in zone '%v'; error: \"%v\"", zone, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetAutoLabelsForPD_Basic(t *testing.T) {
|
||||
/* Arrange */
|
||||
gceProjectId := "test-project"
|
||||
gceRegion := "us-central1"
|
||||
fakeManager := newFakeManager(gceProjectId, gceRegion)
|
||||
diskName := "disk"
|
||||
diskType := DiskTypeSSD
|
||||
zone := "us-central1-c"
|
||||
const sizeGb int64 = 128
|
||||
alphaFeatureGate, featureGateErr := NewAlphaFeatureGate([]string{})
|
||||
if featureGateErr != nil {
|
||||
t.Error(featureGateErr)
|
||||
}
|
||||
gce := GCECloud{
|
||||
manager: fakeManager,
|
||||
managedZones: []string{zone},
|
||||
AlphaFeatureGate: alphaFeatureGate,
|
||||
}
|
||||
|
||||
gce.CreateDisk(diskName, diskType, zone, sizeGb, nil)
|
||||
|
||||
/* Act */
|
||||
labels, err := gce.GetAutoLabelsForPD(diskName, zone)
|
||||
|
||||
/* Assert */
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if labels[kubeletapis.LabelZoneFailureDomain] != zone {
|
||||
t.Errorf("Failure domain is '%v', but zone is '%v'",
|
||||
labels[kubeletapis.LabelZoneFailureDomain], zone)
|
||||
}
|
||||
if labels[kubeletapis.LabelZoneRegion] != gceRegion {
|
||||
t.Errorf("Region is '%v', but region is 'us-central1'", labels[kubeletapis.LabelZoneRegion])
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetAutoLabelsForPD_NoZone(t *testing.T) {
|
||||
/* Arrange */
|
||||
gceProjectId := "test-project"
|
||||
gceRegion := "europe-west1"
|
||||
fakeManager := newFakeManager(gceProjectId, gceRegion)
|
||||
diskName := "disk"
|
||||
diskType := DiskTypeStandard
|
||||
zone := "europe-west1-d"
|
||||
const sizeGb int64 = 128
|
||||
alphaFeatureGate, featureGateErr := NewAlphaFeatureGate([]string{})
|
||||
if featureGateErr != nil {
|
||||
t.Error(featureGateErr)
|
||||
}
|
||||
gce := GCECloud{
|
||||
manager: fakeManager,
|
||||
managedZones: []string{zone},
|
||||
AlphaFeatureGate: alphaFeatureGate,
|
||||
}
|
||||
gce.CreateDisk(diskName, diskType, zone, sizeGb, nil)
|
||||
|
||||
/* Act */
|
||||
labels, err := gce.GetAutoLabelsForPD(diskName, "")
|
||||
|
||||
/* Assert */
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if labels[kubeletapis.LabelZoneFailureDomain] != zone {
|
||||
t.Errorf("Failure domain is '%v', but zone is '%v'",
|
||||
labels[kubeletapis.LabelZoneFailureDomain], zone)
|
||||
}
|
||||
if labels[kubeletapis.LabelZoneRegion] != gceRegion {
|
||||
t.Errorf("Region is '%v', but region is 'europe-west1'", labels[kubeletapis.LabelZoneRegion])
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetAutoLabelsForPD_DiskNotFound(t *testing.T) {
|
||||
/* Arrange */
|
||||
gceProjectId := "test-project"
|
||||
gceRegion := "fake-region"
|
||||
fakeManager := newFakeManager(gceProjectId, gceRegion)
|
||||
diskName := "disk"
|
||||
zone := "asia-northeast1-a"
|
||||
gce := GCECloud{manager: fakeManager, managedZones: []string{zone}}
|
||||
|
||||
/* Act */
|
||||
_, err := gce.GetAutoLabelsForPD(diskName, zone)
|
||||
|
||||
/* Assert */
|
||||
if err == nil {
|
||||
t.Error("Expected error when the specified disk does not exist, but none returned.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetAutoLabelsForPD_DiskNotFoundAndNoZone(t *testing.T) {
|
||||
/* Arrange */
|
||||
gceProjectId := "test-project"
|
||||
gceRegion := "fake-region"
|
||||
fakeManager := newFakeManager(gceProjectId, gceRegion)
|
||||
diskName := "disk"
|
||||
alphaFeatureGate, featureGateErr := NewAlphaFeatureGate([]string{})
|
||||
if featureGateErr != nil {
|
||||
t.Error(featureGateErr)
|
||||
}
|
||||
gce := GCECloud{
|
||||
manager: fakeManager,
|
||||
managedZones: []string{},
|
||||
AlphaFeatureGate: alphaFeatureGate,
|
||||
}
|
||||
|
||||
/* Act */
|
||||
_, err := gce.GetAutoLabelsForPD(diskName, "")
|
||||
|
||||
/* Assert */
|
||||
if err == nil {
|
||||
t.Error("Expected error when the specified disk does not exist, but none returned.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetAutoLabelsForPD_DupDisk(t *testing.T) {
|
||||
/* Arrange */
|
||||
gceProjectId := "test-project"
|
||||
gceRegion := "us-west1"
|
||||
fakeManager := newFakeManager(gceProjectId, gceRegion)
|
||||
diskName := "disk"
|
||||
diskType := DiskTypeStandard
|
||||
zone := "us-west1-b"
|
||||
const sizeGb int64 = 128
|
||||
|
||||
alphaFeatureGate, featureGateErr := NewAlphaFeatureGate([]string{})
|
||||
if featureGateErr != nil {
|
||||
t.Error(featureGateErr)
|
||||
}
|
||||
gce := GCECloud{
|
||||
manager: fakeManager,
|
||||
managedZones: []string{"us-west1-b", "asia-southeast1-a"},
|
||||
AlphaFeatureGate: alphaFeatureGate,
|
||||
}
|
||||
for _, zone := range gce.managedZones {
|
||||
gce.CreateDisk(diskName, diskType, zone, sizeGb, nil)
|
||||
}
|
||||
|
||||
/* Act */
|
||||
labels, err := gce.GetAutoLabelsForPD(diskName, zone)
|
||||
|
||||
/* Assert */
|
||||
if err != nil {
|
||||
t.Error("Disk name and zone uniquely identifies a disk, yet an error is returned.")
|
||||
}
|
||||
if labels[kubeletapis.LabelZoneFailureDomain] != zone {
|
||||
t.Errorf("Failure domain is '%v', but zone is '%v'",
|
||||
labels[kubeletapis.LabelZoneFailureDomain], zone)
|
||||
}
|
||||
if labels[kubeletapis.LabelZoneRegion] != gceRegion {
|
||||
t.Errorf("Region is '%v', but region is 'us-west1'", labels[kubeletapis.LabelZoneRegion])
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetAutoLabelsForPD_DupDiskNoZone(t *testing.T) {
|
||||
/* Arrange */
|
||||
gceProjectId := "test-project"
|
||||
gceRegion := "fake-region"
|
||||
fakeManager := newFakeManager(gceProjectId, gceRegion)
|
||||
diskName := "disk"
|
||||
diskType := DiskTypeStandard
|
||||
const sizeGb int64 = 128
|
||||
|
||||
alphaFeatureGate, featureGateErr := NewAlphaFeatureGate([]string{})
|
||||
if featureGateErr != nil {
|
||||
t.Error(featureGateErr)
|
||||
}
|
||||
gce := GCECloud{
|
||||
manager: fakeManager,
|
||||
managedZones: []string{"us-west1-b", "asia-southeast1-a"},
|
||||
AlphaFeatureGate: alphaFeatureGate,
|
||||
}
|
||||
for _, zone := range gce.managedZones {
|
||||
gce.CreateDisk(diskName, diskType, zone, sizeGb, nil)
|
||||
}
|
||||
|
||||
/* Act */
|
||||
_, err := gce.GetAutoLabelsForPD(diskName, "")
|
||||
|
||||
/* Assert */
|
||||
if err == nil {
|
||||
t.Error("Expected error when the disk is duplicated and zone is not specified, but none returned.")
|
||||
}
|
||||
}
|
||||
|
||||
type targetClientAPI int
|
||||
|
||||
const (
|
||||
targetStable targetClientAPI = iota
|
||||
targetBeta
|
||||
targetAlpha
|
||||
)
|
||||
|
||||
type FakeServiceManager struct {
|
||||
// Common fields shared among tests
|
||||
targetAPI targetClientAPI
|
||||
gceProjectID string
|
||||
gceRegion string
|
||||
opAlpha *computealpha.Operation // Mocks an operation returned by GCE API calls
|
||||
opBeta *computebeta.Operation // Mocks an operation returned by GCE API calls
|
||||
opStable *compute.Operation // Mocks an operation returned by GCE API calls
|
||||
doesOpMatch bool
|
||||
zonalDisks map[string]string // zone: diskName
|
||||
regionalDisks map[string]sets.String // diskName: zones
|
||||
waitForOpError error // Error to be returned by WaitForZoneOp or WaitForRegionalOp
|
||||
|
||||
// Fields for TestCreateDisk
|
||||
createDiskCalled bool
|
||||
diskToCreateAlpha *computealpha.Disk
|
||||
diskToCreateBeta *computebeta.Disk
|
||||
diskToCreateStable *compute.Disk
|
||||
|
||||
// Fields for TestDeleteDisk
|
||||
deleteDiskCalled bool
|
||||
resourceInUse bool // Marks the disk as in-use
|
||||
}
|
||||
|
||||
func newFakeManager(gceProjectID string, gceRegion string) *FakeServiceManager {
|
||||
return &FakeServiceManager{
|
||||
zonalDisks: make(map[string]string),
|
||||
regionalDisks: make(map[string]sets.String),
|
||||
gceProjectID: gceProjectID,
|
||||
gceRegion: gceRegion,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Upon disk creation, disk info is stored in FakeServiceManager
|
||||
* to be used by other tested methods.
|
||||
*/
|
||||
func (manager *FakeServiceManager) CreateDisk(
|
||||
name string,
|
||||
sizeGb int64,
|
||||
tagsStr string,
|
||||
diskType string,
|
||||
zone string) (gceObject, error) {
|
||||
manager.createDiskCalled = true
|
||||
|
||||
switch t := manager.targetAPI; t {
|
||||
case targetStable:
|
||||
manager.opStable = &compute.Operation{}
|
||||
diskTypeURI := gceComputeAPIEndpoint + "projects/" + fmt.Sprintf(diskTypeURITemplateSingleZone, manager.gceProjectID, zone, diskType)
|
||||
diskToCreateV1 := &compute.Disk{
|
||||
Name: name,
|
||||
SizeGb: sizeGb,
|
||||
Description: tagsStr,
|
||||
Type: diskTypeURI,
|
||||
}
|
||||
manager.diskToCreateStable = diskToCreateV1
|
||||
manager.zonalDisks[zone] = diskToCreateV1.Name
|
||||
return manager.opStable, nil
|
||||
case targetBeta:
|
||||
manager.opBeta = &computebeta.Operation{}
|
||||
diskTypeURI := gceComputeAPIEndpoint + "projects/" + fmt.Sprintf(diskTypeURITemplateSingleZone, manager.gceProjectID, zone, diskType)
|
||||
diskToCreateBeta := &computebeta.Disk{
|
||||
Name: name,
|
||||
SizeGb: sizeGb,
|
||||
Description: tagsStr,
|
||||
Type: diskTypeURI,
|
||||
}
|
||||
manager.diskToCreateBeta = diskToCreateBeta
|
||||
manager.zonalDisks[zone] = diskToCreateBeta.Name
|
||||
return manager.opBeta, nil
|
||||
case targetAlpha:
|
||||
manager.opAlpha = &computealpha.Operation{}
|
||||
diskTypeURI := gceComputeAPIEndpointAlpha + "projects/" + fmt.Sprintf(diskTypeURITemplateSingleZone, manager.gceProjectID, zone, diskType)
|
||||
diskToCreateAlpha := &computealpha.Disk{
|
||||
Name: name,
|
||||
SizeGb: sizeGb,
|
||||
Description: tagsStr,
|
||||
Type: diskTypeURI,
|
||||
}
|
||||
manager.diskToCreateAlpha = diskToCreateAlpha
|
||||
manager.zonalDisks[zone] = diskToCreateAlpha.Name
|
||||
return manager.opAlpha, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unexpected type: %T", t)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Upon disk creation, disk info is stored in FakeServiceManager
|
||||
* to be used by other tested methods.
|
||||
*/
|
||||
func (manager *FakeServiceManager) CreateRegionalDisk(
|
||||
name string,
|
||||
sizeGb int64,
|
||||
tagsStr string,
|
||||
diskType string,
|
||||
zones sets.String) (gceObject, error) {
|
||||
manager.createDiskCalled = true
|
||||
diskTypeURI := gceComputeAPIEndpointAlpha + "projects/" + fmt.Sprintf(diskTypeURITemplateRegional, manager.gceProjectID, manager.gceRegion, diskType)
|
||||
|
||||
switch t := manager.targetAPI; t {
|
||||
case targetStable:
|
||||
manager.opStable = &compute.Operation{}
|
||||
diskToCreateV1 := &compute.Disk{
|
||||
Name: name,
|
||||
SizeGb: sizeGb,
|
||||
Description: tagsStr,
|
||||
Type: diskTypeURI,
|
||||
}
|
||||
manager.diskToCreateStable = diskToCreateV1
|
||||
manager.regionalDisks[diskToCreateV1.Name] = zones
|
||||
return manager.opStable, nil
|
||||
case targetBeta:
|
||||
return nil, fmt.Errorf("RegionalDisk CreateDisk op not supported in beta.")
|
||||
case targetAlpha:
|
||||
return nil, fmt.Errorf("RegionalDisk CreateDisk op not supported in alpha.")
|
||||
default:
|
||||
return nil, fmt.Errorf("unexpected type: %T", t)
|
||||
}
|
||||
}
|
||||
|
||||
func (manager *FakeServiceManager) AttachDisk(
|
||||
disk *GCEDisk,
|
||||
readWrite string,
|
||||
instanceZone string,
|
||||
instanceName string) (gceObject, error) {
|
||||
|
||||
switch t := manager.targetAPI; t {
|
||||
case targetStable:
|
||||
manager.opStable = &compute.Operation{}
|
||||
return manager.opStable, nil
|
||||
case targetBeta:
|
||||
manager.opBeta = &computebeta.Operation{}
|
||||
return manager.opBeta, nil
|
||||
case targetAlpha:
|
||||
manager.opAlpha = &computealpha.Operation{}
|
||||
return manager.opAlpha, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unexpected type: %T", t)
|
||||
}
|
||||
}
|
||||
|
||||
func (manager *FakeServiceManager) DetachDisk(
|
||||
instanceZone string,
|
||||
instanceName string,
|
||||
devicePath string) (gceObject, error) {
|
||||
switch t := manager.targetAPI; t {
|
||||
case targetStable:
|
||||
manager.opStable = &compute.Operation{}
|
||||
return manager.opStable, nil
|
||||
case targetBeta:
|
||||
manager.opBeta = &computebeta.Operation{}
|
||||
return manager.opBeta, nil
|
||||
case targetAlpha:
|
||||
manager.opAlpha = &computealpha.Operation{}
|
||||
return manager.opAlpha, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unexpected type: %T", t)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets disk info stored in the FakeServiceManager.
|
||||
*/
|
||||
func (manager *FakeServiceManager) GetDisk(
|
||||
zone string, diskName string) (*GCEDisk, error) {
|
||||
|
||||
if manager.zonalDisks[zone] == "" {
|
||||
return nil, cloudprovider.DiskNotFound
|
||||
}
|
||||
|
||||
if manager.resourceInUse {
|
||||
errorItem := googleapi.ErrorItem{Reason: "resourceInUseByAnotherResource"}
|
||||
err := &googleapi.Error{Errors: []googleapi.ErrorItem{errorItem}}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &GCEDisk{
|
||||
Region: manager.gceRegion,
|
||||
ZoneInfo: singleZone{lastComponent(zone)},
|
||||
Name: diskName,
|
||||
Kind: "compute#disk",
|
||||
Type: "type",
|
||||
}, nil
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets disk info stored in the FakeServiceManager.
|
||||
*/
|
||||
func (manager *FakeServiceManager) GetRegionalDisk(
|
||||
diskName string) (*GCEDisk, error) {
|
||||
|
||||
if _, ok := manager.regionalDisks[diskName]; !ok {
|
||||
return nil, cloudprovider.DiskNotFound
|
||||
}
|
||||
|
||||
if manager.resourceInUse {
|
||||
errorItem := googleapi.ErrorItem{Reason: "resourceInUseByAnotherResource"}
|
||||
err := &googleapi.Error{Errors: []googleapi.ErrorItem{errorItem}}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &GCEDisk{
|
||||
Region: manager.gceRegion,
|
||||
ZoneInfo: multiZone{manager.regionalDisks[diskName]},
|
||||
Name: diskName,
|
||||
Kind: "compute#disk",
|
||||
Type: "type",
|
||||
}, nil
|
||||
}
|
||||
|
||||
/**
|
||||
* Disk info is removed from the FakeServiceManager.
|
||||
*/
|
||||
func (manager *FakeServiceManager) DeleteDisk(
|
||||
zone string,
|
||||
disk string) (gceObject, error) {
|
||||
|
||||
manager.deleteDiskCalled = true
|
||||
delete(manager.zonalDisks, zone)
|
||||
|
||||
switch t := manager.targetAPI; t {
|
||||
case targetStable:
|
||||
manager.opStable = &compute.Operation{}
|
||||
return manager.opStable, nil
|
||||
case targetBeta:
|
||||
manager.opBeta = &computebeta.Operation{}
|
||||
return manager.opBeta, nil
|
||||
case targetAlpha:
|
||||
manager.opAlpha = &computealpha.Operation{}
|
||||
return manager.opAlpha, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unexpected type: %T", t)
|
||||
}
|
||||
}
|
||||
|
||||
func (manager *FakeServiceManager) DeleteRegionalDisk(
|
||||
disk string) (gceObject, error) {
|
||||
|
||||
manager.deleteDiskCalled = true
|
||||
delete(manager.regionalDisks, disk)
|
||||
|
||||
switch t := manager.targetAPI; t {
|
||||
case targetStable:
|
||||
manager.opStable = &compute.Operation{}
|
||||
return manager.opStable, nil
|
||||
case targetBeta:
|
||||
manager.opBeta = &computebeta.Operation{}
|
||||
return manager.opBeta, nil
|
||||
case targetAlpha:
|
||||
manager.opAlpha = &computealpha.Operation{}
|
||||
return manager.opAlpha, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unexpected type: %T", t)
|
||||
}
|
||||
}
|
||||
|
||||
func (manager *FakeServiceManager) WaitForZoneOp(
|
||||
op gceObject,
|
||||
zone string,
|
||||
mc *metricContext) error {
|
||||
switch v := op.(type) {
|
||||
case *computealpha.Operation:
|
||||
if op.(*computealpha.Operation) == manager.opAlpha {
|
||||
manager.doesOpMatch = true
|
||||
}
|
||||
case *computebeta.Operation:
|
||||
if op.(*computebeta.Operation) == manager.opBeta {
|
||||
manager.doesOpMatch = true
|
||||
}
|
||||
case *compute.Operation:
|
||||
if op.(*compute.Operation) == manager.opStable {
|
||||
manager.doesOpMatch = true
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("unexpected type: %T", v)
|
||||
}
|
||||
return manager.waitForOpError
|
||||
}
|
||||
|
||||
func (manager *FakeServiceManager) WaitForRegionalOp(
|
||||
op gceObject, mc *metricContext) error {
|
||||
switch v := op.(type) {
|
||||
case *computealpha.Operation:
|
||||
if op.(*computealpha.Operation) == manager.opAlpha {
|
||||
manager.doesOpMatch = true
|
||||
}
|
||||
case *computebeta.Operation:
|
||||
if op.(*computebeta.Operation) == manager.opBeta {
|
||||
manager.doesOpMatch = true
|
||||
}
|
||||
case *compute.Operation:
|
||||
if op.(*compute.Operation) == manager.opStable {
|
||||
manager.doesOpMatch = true
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("unexpected type: %T", v)
|
||||
}
|
||||
return manager.waitForOpError
|
||||
}
|
||||
124
vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/gce/gce_healthchecks_test.go
generated
vendored
Normal file
124
vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/gce/gce_healthchecks_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package gce
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
)
|
||||
|
||||
func TestIsAtLeastMinNodesHealthCheckVersion(t *testing.T) {
|
||||
testCases := []struct {
|
||||
version string
|
||||
expect bool
|
||||
}{
|
||||
{"v1.7.3", true},
|
||||
{"v1.7.2", true},
|
||||
{"v1.7.2-alpha.2.597+276d289b90d322", true},
|
||||
{"v1.6.0-beta.3.472+831q821c907t31a", false},
|
||||
{"v1.5.2", false},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
if res := isAtLeastMinNodesHealthCheckVersion(tc.version); res != tc.expect {
|
||||
t.Errorf("%v: want %v, got %v", tc.version, tc.expect, res)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSupportsNodesHealthCheck(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
nodes []*v1.Node
|
||||
expect bool
|
||||
}{
|
||||
{
|
||||
"All nodes support nodes health check",
|
||||
[]*v1.Node{
|
||||
{
|
||||
Status: v1.NodeStatus{
|
||||
NodeInfo: v1.NodeSystemInfo{
|
||||
KubeProxyVersion: "v1.7.2",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Status: v1.NodeStatus{
|
||||
NodeInfo: v1.NodeSystemInfo{
|
||||
KubeProxyVersion: "v1.7.2-alpha.2.597+276d289b90d322",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"All nodes don't support nodes health check",
|
||||
[]*v1.Node{
|
||||
{
|
||||
Status: v1.NodeStatus{
|
||||
NodeInfo: v1.NodeSystemInfo{
|
||||
KubeProxyVersion: "v1.6.0-beta.3.472+831q821c907t31a",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Status: v1.NodeStatus{
|
||||
NodeInfo: v1.NodeSystemInfo{
|
||||
KubeProxyVersion: "v1.5.2",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"One node doesn't support nodes health check",
|
||||
[]*v1.Node{
|
||||
{
|
||||
Status: v1.NodeStatus{
|
||||
NodeInfo: v1.NodeSystemInfo{
|
||||
KubeProxyVersion: "v1.7.3",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Status: v1.NodeStatus{
|
||||
NodeInfo: v1.NodeSystemInfo{
|
||||
KubeProxyVersion: "v1.7.2-alpha.2.597+276d289b90d322",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Status: v1.NodeStatus{
|
||||
NodeInfo: v1.NodeSystemInfo{
|
||||
KubeProxyVersion: "v1.5.2",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
if res := supportsNodesHealthCheck(tc.nodes); res != tc.expect {
|
||||
t.Errorf("%v: want %v, got %v", tc.desc, tc.expect, res)
|
||||
}
|
||||
}
|
||||
}
|
||||
239
vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/gce/gce_loadbalancer_external_test.go
generated
vendored
Normal file
239
vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/gce/gce_loadbalancer_external_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,239 @@
|
|||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package gce
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
computealpha "google.golang.org/api/compute/v0.alpha"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
)
|
||||
|
||||
func TestEnsureStaticIP(t *testing.T) {
|
||||
fcas := NewFakeCloudAddressService()
|
||||
ipName := "some-static-ip"
|
||||
serviceName := ""
|
||||
region := "us-central1"
|
||||
|
||||
// First ensure call
|
||||
ip, existed, err := ensureStaticIP(fcas, ipName, serviceName, region, "", NetworkTierDefault)
|
||||
if err != nil || existed || ip == "" {
|
||||
t.Fatalf(`ensureStaticIP(%v, %v, %v, %v, "") = %v, %v, %v; want valid ip, false, nil`, fcas, ipName, serviceName, region, ip, existed, err)
|
||||
}
|
||||
|
||||
// Second ensure call
|
||||
var ipPrime string
|
||||
ipPrime, existed, err = ensureStaticIP(fcas, ipName, serviceName, region, ip, NetworkTierDefault)
|
||||
if err != nil || !existed || ip != ipPrime {
|
||||
t.Fatalf(`ensureStaticIP(%v, %v, %v, %v, %v) = %v, %v, %v; want %v, true, nil`, fcas, ipName, serviceName, region, ip, ipPrime, existed, err, ip)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEnsureStaticIPWithTier(t *testing.T) {
|
||||
s := NewFakeCloudAddressService()
|
||||
serviceName := ""
|
||||
region := "us-east1"
|
||||
|
||||
for desc, tc := range map[string]struct {
|
||||
name string
|
||||
netTier NetworkTier
|
||||
expected string
|
||||
}{
|
||||
"Premium (default)": {
|
||||
name: "foo-1",
|
||||
netTier: NetworkTierPremium,
|
||||
expected: "PREMIUM",
|
||||
},
|
||||
"Standard": {
|
||||
name: "foo-2",
|
||||
netTier: NetworkTierStandard,
|
||||
expected: "STANDARD",
|
||||
},
|
||||
} {
|
||||
t.Run(desc, func(t *testing.T) {
|
||||
ip, existed, err := ensureStaticIP(s, tc.name, serviceName, region, "", tc.netTier)
|
||||
assert.NoError(t, err)
|
||||
assert.False(t, existed)
|
||||
assert.NotEqual(t, "", ip)
|
||||
// Get the Address from the fake address service and verify that the tier
|
||||
// is set correctly.
|
||||
alphaAddr, err := s.GetAlphaRegionAddress(tc.name, region)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, tc.expected, alphaAddr.NetworkTier)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestVerifyRequestedIP(t *testing.T) {
|
||||
region := "test-region"
|
||||
lbRef := "test-lb"
|
||||
s := NewFakeCloudAddressService()
|
||||
|
||||
for desc, tc := range map[string]struct {
|
||||
requestedIP string
|
||||
fwdRuleIP string
|
||||
netTier NetworkTier
|
||||
addrList []*computealpha.Address
|
||||
expectErr bool
|
||||
expectUserOwned bool
|
||||
}{
|
||||
"requested IP exists": {
|
||||
requestedIP: "1.1.1.1",
|
||||
netTier: NetworkTierPremium,
|
||||
addrList: []*computealpha.Address{{Name: "foo", Address: "1.1.1.1", NetworkTier: "PREMIUM"}},
|
||||
expectErr: false,
|
||||
expectUserOwned: true,
|
||||
},
|
||||
"requested IP is not static, but is in use by the fwd rule": {
|
||||
requestedIP: "1.1.1.1",
|
||||
fwdRuleIP: "1.1.1.1",
|
||||
netTier: NetworkTierPremium,
|
||||
expectErr: false,
|
||||
},
|
||||
"requested IP is not static and is not used by the fwd rule": {
|
||||
requestedIP: "1.1.1.1",
|
||||
fwdRuleIP: "2.2.2.2",
|
||||
netTier: NetworkTierPremium,
|
||||
expectErr: true,
|
||||
},
|
||||
"no requested IP": {
|
||||
netTier: NetworkTierPremium,
|
||||
expectErr: false,
|
||||
},
|
||||
"requested IP exists, but network tier does not match": {
|
||||
requestedIP: "1.1.1.1",
|
||||
netTier: NetworkTierStandard,
|
||||
addrList: []*computealpha.Address{{Name: "foo", Address: "1.1.1.1", NetworkTier: "PREMIUM"}},
|
||||
expectErr: true,
|
||||
},
|
||||
} {
|
||||
t.Run(desc, func(t *testing.T) {
|
||||
s.SetRegionalAddresses(region, tc.addrList)
|
||||
isUserOwnedIP, err := verifyUserRequestedIP(s, region, tc.requestedIP, tc.fwdRuleIP, lbRef, tc.netTier)
|
||||
assert.Equal(t, tc.expectErr, err != nil, fmt.Sprintf("err: %v", err))
|
||||
assert.Equal(t, tc.expectUserOwned, isUserOwnedIP)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateForwardingRuleWithTier(t *testing.T) {
|
||||
s := NewFakeCloudForwardingRuleService()
|
||||
// Common variables among the tests.
|
||||
ports := []v1.ServicePort{{Name: "foo", Protocol: v1.ProtocolTCP, Port: int32(123)}}
|
||||
region := "test-region"
|
||||
target := "test-target-pool"
|
||||
svcName := "foo-svc"
|
||||
|
||||
for desc, tc := range map[string]struct {
|
||||
netTier NetworkTier
|
||||
expectedRule *computealpha.ForwardingRule
|
||||
}{
|
||||
"Premium tier": {
|
||||
netTier: NetworkTierPremium,
|
||||
expectedRule: &computealpha.ForwardingRule{
|
||||
Name: "lb-1",
|
||||
Description: `{"kubernetes.io/service-name":"foo-svc"}`,
|
||||
IPAddress: "1.1.1.1",
|
||||
IPProtocol: "TCP",
|
||||
PortRange: "123-123",
|
||||
Target: target,
|
||||
NetworkTier: "PREMIUM",
|
||||
},
|
||||
},
|
||||
"Standard tier": {
|
||||
netTier: NetworkTierStandard,
|
||||
expectedRule: &computealpha.ForwardingRule{
|
||||
Name: "lb-2",
|
||||
Description: `{"kubernetes.io/service-name":"foo-svc"}`,
|
||||
IPAddress: "2.2.2.2",
|
||||
IPProtocol: "TCP",
|
||||
PortRange: "123-123",
|
||||
Target: target,
|
||||
NetworkTier: "STANDARD",
|
||||
},
|
||||
},
|
||||
} {
|
||||
t.Run(desc, func(t *testing.T) {
|
||||
lbName := tc.expectedRule.Name
|
||||
ipAddr := tc.expectedRule.IPAddress
|
||||
|
||||
err := createForwardingRule(s, lbName, svcName, region, ipAddr, target, ports, tc.netTier)
|
||||
assert.NoError(t, err)
|
||||
|
||||
alphaRule, err := s.GetAlphaRegionForwardingRule(lbName, region)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, tc.expectedRule, alphaRule)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeleteAddressWithWrongTier(t *testing.T) {
|
||||
region := "test-region"
|
||||
lbRef := "test-lb"
|
||||
s := NewFakeCloudAddressService()
|
||||
|
||||
for desc, tc := range map[string]struct {
|
||||
addrName string
|
||||
netTier NetworkTier
|
||||
addrList []*computealpha.Address
|
||||
expectDelete bool
|
||||
}{
|
||||
"Network tiers (premium) match; do nothing": {
|
||||
addrName: "foo1",
|
||||
netTier: NetworkTierPremium,
|
||||
addrList: []*computealpha.Address{{Name: "foo1", Address: "1.1.1.1", NetworkTier: "PREMIUM"}},
|
||||
},
|
||||
"Network tiers (standard) match; do nothing": {
|
||||
addrName: "foo2",
|
||||
netTier: NetworkTierStandard,
|
||||
addrList: []*computealpha.Address{{Name: "foo2", Address: "1.1.1.2", NetworkTier: "STANDARD"}},
|
||||
},
|
||||
"Wrong network tier (standard); delete address": {
|
||||
addrName: "foo3",
|
||||
netTier: NetworkTierPremium,
|
||||
addrList: []*computealpha.Address{{Name: "foo3", Address: "1.1.1.3", NetworkTier: "STANDARD"}},
|
||||
expectDelete: true,
|
||||
},
|
||||
"Wrong network tier (preimium); delete address": {
|
||||
addrName: "foo4",
|
||||
netTier: NetworkTierStandard,
|
||||
addrList: []*computealpha.Address{{Name: "foo4", Address: "1.1.1.4", NetworkTier: "PREMIUM"}},
|
||||
expectDelete: true,
|
||||
},
|
||||
} {
|
||||
t.Run(desc, func(t *testing.T) {
|
||||
s.SetRegionalAddresses(region, tc.addrList)
|
||||
// Sanity check to ensure we inject the right address.
|
||||
_, err := s.GetRegionAddress(tc.addrName, region)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = deleteAddressWithWrongTier(s, region, tc.addrName, lbRef, tc.netTier)
|
||||
assert.NoError(t, err)
|
||||
// Check whether the address still exists.
|
||||
_, err = s.GetRegionAddress(tc.addrName, region)
|
||||
if tc.expectDelete {
|
||||
assert.True(t, isNotFound(err))
|
||||
} else {
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
628
vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/gce/gce_test.go
generated
vendored
Normal file
628
vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/gce/gce_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,628 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package gce
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/oauth2/google"
|
||||
|
||||
computealpha "google.golang.org/api/compute/v0.alpha"
|
||||
computebeta "google.golang.org/api/compute/v0.beta"
|
||||
computev1 "google.golang.org/api/compute/v1"
|
||||
"k8s.io/kubernetes/pkg/cloudprovider"
|
||||
)
|
||||
|
||||
func TestReadConfigFile(t *testing.T) {
|
||||
const s = `[Global]
|
||||
token-url = my-token-url
|
||||
token-body = my-token-body
|
||||
project-id = my-project
|
||||
network-project-id = my-network-project
|
||||
network-name = my-network
|
||||
subnetwork-name = my-subnetwork
|
||||
secondary-range-name = my-secondary-range
|
||||
node-tags = my-node-tag1
|
||||
node-instance-prefix = my-prefix
|
||||
multizone = true
|
||||
`
|
||||
reader := strings.NewReader(s)
|
||||
config, err := readConfig(reader)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected config parsing error %v", err)
|
||||
}
|
||||
|
||||
expected := &ConfigFile{Global: ConfigGlobal{
|
||||
TokenURL: "my-token-url",
|
||||
TokenBody: "my-token-body",
|
||||
ProjectID: "my-project",
|
||||
NetworkProjectID: "my-network-project",
|
||||
NetworkName: "my-network",
|
||||
SubnetworkName: "my-subnetwork",
|
||||
SecondaryRangeName: "my-secondary-range",
|
||||
NodeTags: []string{"my-node-tag1"},
|
||||
NodeInstancePrefix: "my-prefix",
|
||||
Multizone: true,
|
||||
}}
|
||||
|
||||
if !reflect.DeepEqual(expected, config) {
|
||||
t.Fatalf("Expected config file values to be read into ConfigFile struct. \nExpected:\n%+v\nActual:\n%+v", expected, config)
|
||||
}
|
||||
}
|
||||
|
||||
func TestExtraKeyInConfig(t *testing.T) {
|
||||
const s = `[Global]
|
||||
project-id = my-project
|
||||
unknown-key = abc
|
||||
network-name = my-network
|
||||
`
|
||||
reader := strings.NewReader(s)
|
||||
config, err := readConfig(reader)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected config parsing error %v", err)
|
||||
}
|
||||
if config.Global.ProjectID != "my-project" || config.Global.NetworkName != "my-network" {
|
||||
t.Fatalf("Expected config values to continue to be read despite extra key-value pair.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetRegion(t *testing.T) {
|
||||
zoneName := "us-central1-b"
|
||||
regionName, err := GetGCERegion(zoneName)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error from GetGCERegion: %v", err)
|
||||
}
|
||||
if regionName != "us-central1" {
|
||||
t.Errorf("Unexpected region from GetGCERegion: %s", regionName)
|
||||
}
|
||||
gce := &GCECloud{
|
||||
localZone: zoneName,
|
||||
region: regionName,
|
||||
}
|
||||
zones, ok := gce.Zones()
|
||||
if !ok {
|
||||
t.Fatalf("Unexpected missing zones impl")
|
||||
}
|
||||
zone, err := zones.GetZone()
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error %v", err)
|
||||
}
|
||||
if zone.Region != "us-central1" {
|
||||
t.Errorf("Unexpected region: %s", zone.Region)
|
||||
}
|
||||
}
|
||||
|
||||
func TestComparingHostURLs(t *testing.T) {
|
||||
tests := []struct {
|
||||
host1 string
|
||||
zone string
|
||||
name string
|
||||
expectEqual bool
|
||||
}{
|
||||
{
|
||||
host1: "https://www.googleapis.com/compute/v1/projects/1234567/zones/us-central1-f/instances/kubernetes-node-fhx1",
|
||||
zone: "us-central1-f",
|
||||
name: "kubernetes-node-fhx1",
|
||||
expectEqual: true,
|
||||
},
|
||||
{
|
||||
host1: "https://www.googleapis.com/compute/v1/projects/cool-project/zones/us-central1-f/instances/kubernetes-node-fhx1",
|
||||
zone: "us-central1-f",
|
||||
name: "kubernetes-node-fhx1",
|
||||
expectEqual: true,
|
||||
},
|
||||
{
|
||||
host1: "https://www.googleapis.com/compute/v23/projects/1234567/zones/us-central1-f/instances/kubernetes-node-fhx1",
|
||||
zone: "us-central1-f",
|
||||
name: "kubernetes-node-fhx1",
|
||||
expectEqual: true,
|
||||
},
|
||||
{
|
||||
host1: "https://www.googleapis.com/compute/v24/projects/1234567/regions/us-central1/zones/us-central1-f/instances/kubernetes-node-fhx1",
|
||||
zone: "us-central1-f",
|
||||
name: "kubernetes-node-fhx1",
|
||||
expectEqual: true,
|
||||
},
|
||||
{
|
||||
host1: "https://www.googleapis.com/compute/v1/projects/1234567/zones/us-central1-f/instances/kubernetes-node-fhx1",
|
||||
zone: "us-central1-c",
|
||||
name: "kubernetes-node-fhx1",
|
||||
expectEqual: false,
|
||||
},
|
||||
{
|
||||
host1: "https://www.googleapis.com/compute/v1/projects/1234567/zones/us-central1-f/instances/kubernetes-node-fhx",
|
||||
zone: "us-central1-f",
|
||||
name: "kubernetes-node-fhx1",
|
||||
expectEqual: false,
|
||||
},
|
||||
{
|
||||
host1: "https://www.googleapis.com/compute/v1/projects/1234567/zones/us-central1-f/instances/kubernetes-node-fhx1",
|
||||
zone: "us-central1-f",
|
||||
name: "kubernetes-node-fhx",
|
||||
expectEqual: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
link1 := hostURLToComparablePath(test.host1)
|
||||
testInstance := &gceInstance{
|
||||
Name: canonicalizeInstanceName(test.name),
|
||||
Zone: test.zone,
|
||||
}
|
||||
link2 := testInstance.makeComparableHostPath()
|
||||
if test.expectEqual && link1 != link2 {
|
||||
t.Errorf("expected link1 and link2 to be equal, got %s and %s", link1, link2)
|
||||
} else if !test.expectEqual && link1 == link2 {
|
||||
t.Errorf("expected link1 and link2 not to be equal, got %s and %s", link1, link2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestScrubDNS(t *testing.T) {
|
||||
tcs := []struct {
|
||||
nameserversIn []string
|
||||
searchesIn []string
|
||||
nameserversOut []string
|
||||
searchesOut []string
|
||||
}{
|
||||
{
|
||||
nameserversIn: []string{"1.2.3.4", "5.6.7.8"},
|
||||
nameserversOut: []string{"1.2.3.4", "5.6.7.8"},
|
||||
},
|
||||
{
|
||||
searchesIn: []string{"c.prj.internal.", "12345678910.google.internal.", "google.internal."},
|
||||
searchesOut: []string{"c.prj.internal.", "google.internal."},
|
||||
},
|
||||
{
|
||||
searchesIn: []string{"c.prj.internal.", "12345678910.google.internal.", "zone.c.prj.internal.", "google.internal."},
|
||||
searchesOut: []string{"c.prj.internal.", "zone.c.prj.internal.", "google.internal."},
|
||||
},
|
||||
{
|
||||
searchesIn: []string{"c.prj.internal.", "12345678910.google.internal.", "zone.c.prj.internal.", "google.internal.", "unexpected"},
|
||||
searchesOut: []string{"c.prj.internal.", "zone.c.prj.internal.", "google.internal.", "unexpected"},
|
||||
},
|
||||
}
|
||||
gce := &GCECloud{}
|
||||
for i := range tcs {
|
||||
n, s := gce.ScrubDNS(tcs[i].nameserversIn, tcs[i].searchesIn)
|
||||
if !reflect.DeepEqual(n, tcs[i].nameserversOut) {
|
||||
t.Errorf("Expected %v, got %v", tcs[i].nameserversOut, n)
|
||||
}
|
||||
if !reflect.DeepEqual(s, tcs[i].searchesOut) {
|
||||
t.Errorf("Expected %v, got %v", tcs[i].searchesOut, s)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSplitProviderID(t *testing.T) {
|
||||
providers := []struct {
|
||||
providerID string
|
||||
|
||||
project string
|
||||
zone string
|
||||
instance string
|
||||
|
||||
fail bool
|
||||
}{
|
||||
{
|
||||
providerID: ProviderName + "://project-example-164317/us-central1-f/kubernetes-node-fhx1",
|
||||
project: "project-example-164317",
|
||||
zone: "us-central1-f",
|
||||
instance: "kubernetes-node-fhx1",
|
||||
fail: false,
|
||||
},
|
||||
{
|
||||
providerID: ProviderName + "://project-example.164317/us-central1-f/kubernetes-node-fhx1",
|
||||
project: "project-example.164317",
|
||||
zone: "us-central1-f",
|
||||
instance: "kubernetes-node-fhx1",
|
||||
fail: false,
|
||||
},
|
||||
{
|
||||
providerID: ProviderName + "://project-example-164317/us-central1-fkubernetes-node-fhx1",
|
||||
project: "",
|
||||
zone: "",
|
||||
instance: "",
|
||||
fail: true,
|
||||
},
|
||||
{
|
||||
providerID: ProviderName + ":/project-example-164317/us-central1-f/kubernetes-node-fhx1",
|
||||
project: "",
|
||||
zone: "",
|
||||
instance: "",
|
||||
fail: true,
|
||||
},
|
||||
{
|
||||
providerID: "aws://project-example-164317/us-central1-f/kubernetes-node-fhx1",
|
||||
project: "",
|
||||
zone: "",
|
||||
instance: "",
|
||||
fail: true,
|
||||
},
|
||||
{
|
||||
providerID: ProviderName + "://project-example-164317/us-central1-f/kubernetes-node-fhx1/",
|
||||
project: "",
|
||||
zone: "",
|
||||
instance: "",
|
||||
fail: true,
|
||||
},
|
||||
{
|
||||
providerID: ProviderName + "://project-example.164317//kubernetes-node-fhx1",
|
||||
project: "",
|
||||
zone: "",
|
||||
instance: "",
|
||||
fail: true,
|
||||
},
|
||||
{
|
||||
providerID: ProviderName + "://project-example.164317/kubernetes-node-fhx1",
|
||||
project: "",
|
||||
zone: "",
|
||||
instance: "",
|
||||
fail: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range providers {
|
||||
project, zone, instance, err := splitProviderID(test.providerID)
|
||||
if (err != nil) != test.fail {
|
||||
t.Errorf("Expected to fail=%t, with pattern %v", test.fail, test)
|
||||
}
|
||||
|
||||
if test.fail {
|
||||
continue
|
||||
}
|
||||
|
||||
if project != test.project {
|
||||
t.Errorf("Expected %v, but got %v", test.project, project)
|
||||
}
|
||||
if zone != test.zone {
|
||||
t.Errorf("Expected %v, but got %v", test.zone, zone)
|
||||
}
|
||||
if instance != test.instance {
|
||||
t.Errorf("Expected %v, but got %v", test.instance, instance)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetZoneByProviderID(t *testing.T) {
|
||||
tests := []struct {
|
||||
providerID string
|
||||
|
||||
expectedZone cloudprovider.Zone
|
||||
|
||||
fail bool
|
||||
description string
|
||||
}{
|
||||
{
|
||||
providerID: ProviderName + "://project-example-164317/us-central1-f/kubernetes-node-fhx1",
|
||||
expectedZone: cloudprovider.Zone{FailureDomain: "us-central1-f", Region: "us-central1"},
|
||||
fail: false,
|
||||
description: "standard gce providerID",
|
||||
},
|
||||
{
|
||||
providerID: ProviderName + "://project-example-164317/us-central1-f/kubernetes-node-fhx1/",
|
||||
expectedZone: cloudprovider.Zone{},
|
||||
fail: true,
|
||||
description: "too many slashes('/') trailing",
|
||||
},
|
||||
{
|
||||
providerID: ProviderName + "://project-example.164317//kubernetes-node-fhx1",
|
||||
expectedZone: cloudprovider.Zone{},
|
||||
fail: true,
|
||||
description: "too many slashes('/') embedded",
|
||||
},
|
||||
{
|
||||
providerID: ProviderName + "://project-example-164317/uscentral1f/kubernetes-node-fhx1",
|
||||
expectedZone: cloudprovider.Zone{},
|
||||
fail: true,
|
||||
description: "invalid name of the GCE zone",
|
||||
},
|
||||
}
|
||||
|
||||
gce := &GCECloud{
|
||||
localZone: "us-central1-f",
|
||||
region: "us-central1",
|
||||
}
|
||||
for _, test := range tests {
|
||||
zone, err := gce.GetZoneByProviderID(test.providerID)
|
||||
if (err != nil) != test.fail {
|
||||
t.Errorf("Expected to fail=%t, provider ID %v, tests %s", test.fail, test, test.description)
|
||||
}
|
||||
|
||||
if test.fail {
|
||||
continue
|
||||
}
|
||||
|
||||
if zone != test.expectedZone {
|
||||
t.Errorf("Expected %v, but got %v", test.expectedZone, zone)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateCloudConfigs(t *testing.T) {
|
||||
configBoilerplate := ConfigGlobal{
|
||||
TokenURL: "",
|
||||
TokenBody: "",
|
||||
ProjectID: "project-id",
|
||||
NetworkName: "network-name",
|
||||
SubnetworkName: "",
|
||||
SecondaryRangeName: "",
|
||||
NodeTags: []string{"node-tag"},
|
||||
NodeInstancePrefix: "node-prefix",
|
||||
Multizone: false,
|
||||
ApiEndpoint: "",
|
||||
LocalZone: "us-central1-a",
|
||||
AlphaFeatures: []string{},
|
||||
}
|
||||
|
||||
cloudBoilerplate := CloudConfig{
|
||||
ApiEndpoint: "",
|
||||
ProjectID: "project-id",
|
||||
NetworkProjectID: "",
|
||||
Region: "us-central1",
|
||||
Zone: "us-central1-a",
|
||||
ManagedZones: []string{"us-central1-a"},
|
||||
NetworkName: "network-name",
|
||||
SubnetworkName: "",
|
||||
NetworkURL: "",
|
||||
SubnetworkURL: "",
|
||||
SecondaryRangeName: "",
|
||||
NodeTags: []string{"node-tag"},
|
||||
TokenSource: google.ComputeTokenSource(""),
|
||||
NodeInstancePrefix: "node-prefix",
|
||||
UseMetadataServer: true,
|
||||
AlphaFeatureGate: &AlphaFeatureGate{map[string]bool{}},
|
||||
}
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
config func() ConfigGlobal
|
||||
cloud func() CloudConfig
|
||||
}{
|
||||
{
|
||||
name: "Empty Config",
|
||||
config: func() ConfigGlobal { return configBoilerplate },
|
||||
cloud: func() CloudConfig { return cloudBoilerplate },
|
||||
},
|
||||
{
|
||||
name: "Nil token URL",
|
||||
config: func() ConfigGlobal {
|
||||
v := configBoilerplate
|
||||
v.TokenURL = "nil"
|
||||
return v
|
||||
},
|
||||
cloud: func() CloudConfig {
|
||||
v := cloudBoilerplate
|
||||
v.TokenSource = nil
|
||||
return v
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Network Project ID",
|
||||
config: func() ConfigGlobal {
|
||||
v := configBoilerplate
|
||||
v.NetworkProjectID = "my-awesome-project"
|
||||
return v
|
||||
},
|
||||
cloud: func() CloudConfig {
|
||||
v := cloudBoilerplate
|
||||
v.NetworkProjectID = "my-awesome-project"
|
||||
return v
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Specified API Endpint",
|
||||
config: func() ConfigGlobal {
|
||||
v := configBoilerplate
|
||||
v.ApiEndpoint = "https://www.googleapis.com/compute/staging_v1/"
|
||||
return v
|
||||
},
|
||||
cloud: func() CloudConfig {
|
||||
v := cloudBoilerplate
|
||||
v.ApiEndpoint = "https://www.googleapis.com/compute/staging_v1/"
|
||||
return v
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Network & Subnetwork names",
|
||||
config: func() ConfigGlobal {
|
||||
v := configBoilerplate
|
||||
v.NetworkName = "my-network"
|
||||
v.SubnetworkName = "my-subnetwork"
|
||||
return v
|
||||
},
|
||||
cloud: func() CloudConfig {
|
||||
v := cloudBoilerplate
|
||||
v.NetworkName = "my-network"
|
||||
v.SubnetworkName = "my-subnetwork"
|
||||
return v
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Network & Subnetwork URLs",
|
||||
config: func() ConfigGlobal {
|
||||
v := configBoilerplate
|
||||
v.NetworkName = "https://www.googleapis.com/compute/v1/projects/project-id/global/networks/my-network"
|
||||
v.SubnetworkName = "https://www.googleapis.com/compute/v1/projects/project-id/regions/us-central1/subnetworks/my-subnetwork"
|
||||
return v
|
||||
},
|
||||
cloud: func() CloudConfig {
|
||||
v := cloudBoilerplate
|
||||
v.NetworkName = ""
|
||||
v.SubnetworkName = ""
|
||||
v.NetworkURL = "https://www.googleapis.com/compute/v1/projects/project-id/global/networks/my-network"
|
||||
v.SubnetworkURL = "https://www.googleapis.com/compute/v1/projects/project-id/regions/us-central1/subnetworks/my-subnetwork"
|
||||
return v
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Multizone",
|
||||
config: func() ConfigGlobal {
|
||||
v := configBoilerplate
|
||||
v.Multizone = true
|
||||
return v
|
||||
},
|
||||
cloud: func() CloudConfig {
|
||||
v := cloudBoilerplate
|
||||
v.ManagedZones = nil
|
||||
return v
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Secondary Range Name",
|
||||
config: func() ConfigGlobal {
|
||||
v := configBoilerplate
|
||||
v.SecondaryRangeName = "my-secondary"
|
||||
return v
|
||||
},
|
||||
cloud: func() CloudConfig {
|
||||
v := cloudBoilerplate
|
||||
v.SecondaryRangeName = "my-secondary"
|
||||
return v
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
resultCloud, err := generateCloudConfig(&ConfigFile{Global: tc.config()})
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpect error: %v", err)
|
||||
}
|
||||
|
||||
v := tc.cloud()
|
||||
if !reflect.DeepEqual(*resultCloud, v) {
|
||||
t.Errorf("Got: \n%v\nWant\n%v\n", v, *resultCloud)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestConvertToV1Operation(t *testing.T) {
|
||||
v1Op := getTestOperation()
|
||||
enc, _ := v1Op.MarshalJSON()
|
||||
var op interface{}
|
||||
var alphaOp computealpha.Operation
|
||||
var betaOp computebeta.Operation
|
||||
|
||||
if err := json.Unmarshal(enc, &alphaOp); err != nil {
|
||||
t.Errorf("Failed to unmarshal operation: %v", err)
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(enc, &betaOp); err != nil {
|
||||
t.Errorf("Failed to unmarshal operation: %v", err)
|
||||
}
|
||||
|
||||
op = convertToV1Operation(&alphaOp)
|
||||
if _, ok := op.(*computev1.Operation); ok {
|
||||
if !reflect.DeepEqual(op, v1Op) {
|
||||
t.Errorf("Failed to maintain consistency across conversion")
|
||||
}
|
||||
} else {
|
||||
t.Errorf("Expect output to be type v1 operation, but got %v", op)
|
||||
}
|
||||
|
||||
op = convertToV1Operation(&betaOp)
|
||||
if _, ok := op.(*computev1.Operation); ok {
|
||||
if !reflect.DeepEqual(op, v1Op) {
|
||||
t.Errorf("Failed to maintain consistency across conversion")
|
||||
}
|
||||
} else {
|
||||
t.Errorf("Expect output to be type v1 operation, but got %v", op)
|
||||
}
|
||||
}
|
||||
|
||||
func getTestOperation() *computev1.Operation {
|
||||
return &computev1.Operation{
|
||||
Name: "test",
|
||||
Description: "test",
|
||||
Id: uint64(12345),
|
||||
Error: &computev1.OperationError{
|
||||
Errors: []*computev1.OperationErrorErrors{
|
||||
{
|
||||
Code: "555",
|
||||
Message: "error",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewAlphaFeatureGate(t *testing.T) {
|
||||
knownAlphaFeatures["foo"] = true
|
||||
knownAlphaFeatures["bar"] = true
|
||||
|
||||
testCases := []struct {
|
||||
alphaFeatures []string
|
||||
expectEnabled []string
|
||||
expectDisabled []string
|
||||
expectError bool
|
||||
}{
|
||||
// enable foo bar
|
||||
{
|
||||
alphaFeatures: []string{"foo", "bar"},
|
||||
expectEnabled: []string{"foo", "bar"},
|
||||
expectDisabled: []string{"aaa"},
|
||||
expectError: false,
|
||||
},
|
||||
// no alpha feature
|
||||
{
|
||||
alphaFeatures: []string{},
|
||||
expectEnabled: []string{},
|
||||
expectDisabled: []string{"foo", "bar"},
|
||||
expectError: false,
|
||||
},
|
||||
// unsupported alpha feature
|
||||
{
|
||||
alphaFeatures: []string{"aaa", "foo"},
|
||||
expectError: true,
|
||||
expectEnabled: []string{"foo"},
|
||||
expectDisabled: []string{"aaa"},
|
||||
},
|
||||
// enable foo
|
||||
{
|
||||
alphaFeatures: []string{"foo"},
|
||||
expectEnabled: []string{"foo"},
|
||||
expectDisabled: []string{"bar"},
|
||||
expectError: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
featureGate, err := NewAlphaFeatureGate(tc.alphaFeatures)
|
||||
|
||||
if (tc.expectError && err == nil) || (!tc.expectError && err != nil) {
|
||||
t.Errorf("Expect error to be %v, but got error %v", tc.expectError, err)
|
||||
}
|
||||
|
||||
for _, key := range tc.expectEnabled {
|
||||
if !featureGate.Enabled(key) {
|
||||
t.Errorf("Expect %q to be enabled.", key)
|
||||
}
|
||||
}
|
||||
for _, key := range tc.expectDisabled {
|
||||
if featureGate.Enabled(key) {
|
||||
t.Errorf("Expect %q to be disabled.", key)
|
||||
}
|
||||
}
|
||||
}
|
||||
delete(knownAlphaFeatures, "foo")
|
||||
delete(knownAlphaFeatures, "bar")
|
||||
}
|
||||
28
vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/gce/metrics_test.go
generated
vendored
Normal file
28
vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/gce/metrics_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package gce
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestVerifyMetricLabelCardinality(t *testing.T) {
|
||||
mc := newGenericMetricContext("foo", "get", "us-central1", "<n/a>", "alpha")
|
||||
assert.Len(t, mc.attributes, len(metricLabels), "cardinalities of labels and values must match")
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue