123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720 |
- /*
- 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 openstack
- import (
- "context"
- "fmt"
- "os"
- "reflect"
- "regexp"
- "sort"
- "strings"
- "testing"
- "time"
- "github.com/gophercloud/gophercloud"
- "github.com/gophercloud/gophercloud/openstack/compute/v2/servers"
- "k8s.io/api/core/v1"
- "k8s.io/apimachinery/pkg/api/resource"
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- "k8s.io/apimachinery/pkg/util/rand"
- "k8s.io/apimachinery/pkg/util/wait"
- )
- const (
- testClusterName = "testCluster"
- volumeStatusTimeoutSeconds = 30
- // volumeStatus* is configuration of exponential backoff for
- // waiting for specified volume status. Starting with 1
- // seconds, multiplying by 1.2 with each step and taking 13 steps at maximum
- // it will time out after 32s, which roughly corresponds to 30s
- volumeStatusInitDelay = 1 * time.Second
- volumeStatusFactor = 1.2
- volumeStatusSteps = 13
- )
- func WaitForVolumeStatus(t *testing.T, os *OpenStack, volumeName string, status string) {
- backoff := wait.Backoff{
- Duration: volumeStatusInitDelay,
- Factor: volumeStatusFactor,
- Steps: volumeStatusSteps,
- }
- err := wait.ExponentialBackoff(backoff, func() (bool, error) {
- getVol, err := os.getVolume(volumeName)
- if err != nil {
- return false, err
- }
- if getVol.Status == status {
- t.Logf("Volume (%s) status changed to %s after %v seconds\n",
- volumeName,
- status,
- volumeStatusTimeoutSeconds)
- return true, nil
- }
- return false, nil
- })
- if err == wait.ErrWaitTimeout {
- t.Logf("Volume (%s) status did not change to %s after %v seconds\n",
- volumeName,
- status,
- volumeStatusTimeoutSeconds)
- return
- }
- if err != nil {
- t.Fatalf("Cannot get existing Cinder volume (%s): %v", volumeName, err)
- }
- }
- func TestReadConfig(t *testing.T) {
- _, err := readConfig(nil)
- if err == nil {
- t.Errorf("Should fail when no config is provided: %s", err)
- }
- // Since we are setting env vars, we need to reset old
- // values for other tests to succeed.
- env := clearEnviron(t)
- defer resetEnviron(t, env)
- os.Setenv("OS_PASSWORD", "mypass")
- defer os.Unsetenv("OS_PASSWORD")
- os.Setenv("OS_TENANT_NAME", "admin")
- defer os.Unsetenv("OS_TENANT_NAME")
- cfg, err := readConfig(strings.NewReader(`
- [Global]
- auth-url = http://auth.url
- user-id = user
- tenant-name = demo
- region = RegionOne
- [LoadBalancer]
- create-monitor = yes
- monitor-delay = 1m
- monitor-timeout = 30s
- monitor-max-retries = 3
- [BlockStorage]
- bs-version = auto
- trust-device-path = yes
- ignore-volume-az = yes
- [Metadata]
- search-order = configDrive, metadataService
- `))
- if err != nil {
- t.Fatalf("Should succeed when a valid config is provided: %s", err)
- }
- if cfg.Global.AuthURL != "http://auth.url" {
- t.Errorf("incorrect authurl: %s", cfg.Global.AuthURL)
- }
- if cfg.Global.UserID != "user" {
- t.Errorf("incorrect userid: %s", cfg.Global.UserID)
- }
- if cfg.Global.Password != "mypass" {
- t.Errorf("incorrect password: %s", cfg.Global.Password)
- }
- // config file wins over environment variable
- if cfg.Global.TenantName != "demo" {
- t.Errorf("incorrect tenant name: %s", cfg.Global.TenantName)
- }
- if cfg.Global.Region != "RegionOne" {
- t.Errorf("incorrect region: %s", cfg.Global.Region)
- }
- if !cfg.LoadBalancer.CreateMonitor {
- t.Errorf("incorrect lb.createmonitor: %t", cfg.LoadBalancer.CreateMonitor)
- }
- if cfg.LoadBalancer.MonitorDelay.Duration != 1*time.Minute {
- t.Errorf("incorrect lb.monitordelay: %s", cfg.LoadBalancer.MonitorDelay)
- }
- if cfg.LoadBalancer.MonitorTimeout.Duration != 30*time.Second {
- t.Errorf("incorrect lb.monitortimeout: %s", cfg.LoadBalancer.MonitorTimeout)
- }
- if cfg.LoadBalancer.MonitorMaxRetries != 3 {
- t.Errorf("incorrect lb.monitormaxretries: %d", cfg.LoadBalancer.MonitorMaxRetries)
- }
- if cfg.BlockStorage.TrustDevicePath != true {
- t.Errorf("incorrect bs.trustdevicepath: %v", cfg.BlockStorage.TrustDevicePath)
- }
- if cfg.BlockStorage.BSVersion != "auto" {
- t.Errorf("incorrect bs.bs-version: %v", cfg.BlockStorage.BSVersion)
- }
- if cfg.BlockStorage.IgnoreVolumeAZ != true {
- t.Errorf("incorrect bs.IgnoreVolumeAZ: %v", cfg.BlockStorage.IgnoreVolumeAZ)
- }
- if cfg.Metadata.SearchOrder != "configDrive, metadataService" {
- t.Errorf("incorrect md.search-order: %v", cfg.Metadata.SearchOrder)
- }
- }
- func TestToAuthOptions(t *testing.T) {
- cfg := Config{}
- cfg.Global.Username = "user"
- cfg.Global.Password = "pass"
- cfg.Global.DomainID = "2a73b8f597c04551a0fdc8e95544be8a"
- cfg.Global.DomainName = "local"
- cfg.Global.AuthURL = "http://auth.url"
- cfg.Global.UserID = "user"
- ao := cfg.toAuthOptions()
- if !ao.AllowReauth {
- t.Errorf("Will need to be able to reauthenticate")
- }
- if ao.Username != cfg.Global.Username {
- t.Errorf("Username %s != %s", ao.Username, cfg.Global.Username)
- }
- if ao.Password != cfg.Global.Password {
- t.Errorf("Password %s != %s", ao.Password, cfg.Global.Password)
- }
- if ao.DomainID != cfg.Global.DomainID {
- t.Errorf("DomainID %s != %s", ao.DomainID, cfg.Global.DomainID)
- }
- if ao.IdentityEndpoint != cfg.Global.AuthURL {
- t.Errorf("IdentityEndpoint %s != %s", ao.IdentityEndpoint, cfg.Global.AuthURL)
- }
- if ao.UserID != cfg.Global.UserID {
- t.Errorf("UserID %s != %s", ao.UserID, cfg.Global.UserID)
- }
- if ao.DomainName != cfg.Global.DomainName {
- t.Errorf("DomainName %s != %s", ao.DomainName, cfg.Global.DomainName)
- }
- if ao.TenantID != cfg.Global.TenantID {
- t.Errorf("TenantID %s != %s", ao.TenantID, cfg.Global.TenantID)
- }
- }
- func TestCheckOpenStackOpts(t *testing.T) {
- delay := MyDuration{60 * time.Second}
- timeout := MyDuration{30 * time.Second}
- tests := []struct {
- name string
- openstackOpts *OpenStack
- expectedError error
- }{
- {
- name: "test1",
- openstackOpts: &OpenStack{
- provider: nil,
- lbOpts: LoadBalancerOpts{
- LBVersion: "v2",
- SubnetID: "6261548e-ffde-4bc7-bd22-59c83578c5ef",
- FloatingNetworkID: "38b8b5f9-64dc-4424-bf86-679595714786",
- LBMethod: "ROUND_ROBIN",
- LBProvider: "haproxy",
- CreateMonitor: true,
- MonitorDelay: delay,
- MonitorTimeout: timeout,
- MonitorMaxRetries: uint(3),
- ManageSecurityGroups: true,
- },
- metadataOpts: MetadataOpts{
- SearchOrder: configDriveID,
- },
- },
- expectedError: nil,
- },
- {
- name: "test2",
- openstackOpts: &OpenStack{
- provider: nil,
- lbOpts: LoadBalancerOpts{
- LBVersion: "v2",
- FloatingNetworkID: "38b8b5f9-64dc-4424-bf86-679595714786",
- LBMethod: "ROUND_ROBIN",
- CreateMonitor: true,
- MonitorDelay: delay,
- MonitorTimeout: timeout,
- MonitorMaxRetries: uint(3),
- ManageSecurityGroups: true,
- },
- metadataOpts: MetadataOpts{
- SearchOrder: configDriveID,
- },
- },
- expectedError: nil,
- },
- {
- name: "test3",
- openstackOpts: &OpenStack{
- provider: nil,
- lbOpts: LoadBalancerOpts{
- LBVersion: "v2",
- SubnetID: "6261548e-ffde-4bc7-bd22-59c83578c5ef",
- FloatingNetworkID: "38b8b5f9-64dc-4424-bf86-679595714786",
- LBMethod: "ROUND_ROBIN",
- CreateMonitor: true,
- MonitorTimeout: timeout,
- MonitorMaxRetries: uint(3),
- ManageSecurityGroups: true,
- },
- metadataOpts: MetadataOpts{
- SearchOrder: configDriveID,
- },
- },
- expectedError: fmt.Errorf("monitor-delay not set in cloud provider config"),
- },
- {
- name: "test4",
- openstackOpts: &OpenStack{
- provider: nil,
- metadataOpts: MetadataOpts{
- SearchOrder: "",
- },
- },
- expectedError: fmt.Errorf("invalid value in section [Metadata] with key `search-order`. Value cannot be empty"),
- },
- {
- name: "test5",
- openstackOpts: &OpenStack{
- provider: nil,
- metadataOpts: MetadataOpts{
- SearchOrder: "value1,value2,value3",
- },
- },
- expectedError: fmt.Errorf("invalid value in section [Metadata] with key `search-order`. Value cannot contain more than 2 elements"),
- },
- {
- name: "test6",
- openstackOpts: &OpenStack{
- provider: nil,
- metadataOpts: MetadataOpts{
- SearchOrder: "value1",
- },
- },
- expectedError: fmt.Errorf("invalid element %q found in section [Metadata] with key `search-order`."+
- "Supported elements include %q and %q", "value1", configDriveID, metadataID),
- },
- {
- name: "test7",
- openstackOpts: &OpenStack{
- provider: nil,
- lbOpts: LoadBalancerOpts{
- LBVersion: "v2",
- SubnetID: "6261548e-ffde-4bc7-bd22-59c83578c5ef",
- FloatingNetworkID: "38b8b5f9-64dc-4424-bf86-679595714786",
- LBMethod: "ROUND_ROBIN",
- CreateMonitor: true,
- MonitorDelay: delay,
- MonitorTimeout: timeout,
- ManageSecurityGroups: true,
- },
- metadataOpts: MetadataOpts{
- SearchOrder: configDriveID,
- },
- },
- expectedError: fmt.Errorf("monitor-max-retries not set in cloud provider config"),
- },
- {
- name: "test8",
- openstackOpts: &OpenStack{
- provider: nil,
- lbOpts: LoadBalancerOpts{
- LBVersion: "v2",
- SubnetID: "6261548e-ffde-4bc7-bd22-59c83578c5ef",
- FloatingNetworkID: "38b8b5f9-64dc-4424-bf86-679595714786",
- LBMethod: "ROUND_ROBIN",
- CreateMonitor: true,
- MonitorDelay: delay,
- MonitorMaxRetries: uint(3),
- ManageSecurityGroups: true,
- },
- metadataOpts: MetadataOpts{
- SearchOrder: configDriveID,
- },
- },
- expectedError: fmt.Errorf("monitor-timeout not set in cloud provider config"),
- },
- }
- for _, testcase := range tests {
- err := checkOpenStackOpts(testcase.openstackOpts)
- if err == nil && testcase.expectedError == nil {
- continue
- }
- if (err != nil && testcase.expectedError == nil) || (err == nil && testcase.expectedError != nil) || err.Error() != testcase.expectedError.Error() {
- t.Errorf("%s failed: expected err=%q, got %q",
- testcase.name, testcase.expectedError, err)
- }
- }
- }
- func TestCaller(t *testing.T) {
- called := false
- myFunc := func() { called = true }
- c := newCaller()
- c.call(myFunc)
- if !called {
- t.Errorf("caller failed to call function in default case")
- }
- c.disarm()
- called = false
- c.call(myFunc)
- if called {
- t.Error("caller still called function when disarmed")
- }
- // Confirm the "usual" deferred caller pattern works as expected
- called = false
- successCase := func() {
- c := newCaller()
- defer c.call(func() { called = true })
- c.disarm()
- }
- if successCase(); called {
- t.Error("Deferred success case still invoked unwind")
- }
- called = false
- failureCase := func() {
- c := newCaller()
- defer c.call(func() { called = true })
- }
- if failureCase(); !called {
- t.Error("Deferred failure case failed to invoke unwind")
- }
- }
- // An arbitrary sort.Interface, just for easier comparison
- type AddressSlice []v1.NodeAddress
- func (a AddressSlice) Len() int { return len(a) }
- func (a AddressSlice) Less(i, j int) bool { return a[i].Address < a[j].Address }
- func (a AddressSlice) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
- func TestNodeAddresses(t *testing.T) {
- srv := servers.Server{
- Status: "ACTIVE",
- HostID: "29d3c8c896a45aa4c34e52247875d7fefc3d94bbcc9f622b5d204362",
- AccessIPv4: "50.56.176.99",
- AccessIPv6: "2001:4800:790e:510:be76:4eff:fe04:82a8",
- Addresses: map[string]interface{}{
- "private": []interface{}{
- map[string]interface{}{
- "OS-EXT-IPS-MAC:mac_addr": "fa:16:3e:7c:1b:2b",
- "version": float64(4),
- "addr": "10.0.0.32",
- "OS-EXT-IPS:type": "fixed",
- },
- map[string]interface{}{
- "version": float64(4),
- "addr": "50.56.176.36",
- "OS-EXT-IPS:type": "floating",
- },
- map[string]interface{}{
- "version": float64(4),
- "addr": "10.0.0.31",
- // No OS-EXT-IPS:type
- },
- },
- "public": []interface{}{
- map[string]interface{}{
- "version": float64(4),
- "addr": "50.56.176.35",
- },
- map[string]interface{}{
- "version": float64(6),
- "addr": "2001:4800:780e:510:be76:4eff:fe04:84a8",
- },
- },
- },
- Metadata: map[string]string{
- "name": "a1-yinvcez57-0-bvynoyawrhcg-kube-minion-fg5i4jwcc2yy",
- TypeHostName: "a1-yinvcez57-0-bvynoyawrhcg-kube-minion-fg5i4jwcc2yy.novalocal",
- },
- }
- addrs, err := nodeAddresses(&srv)
- if err != nil {
- t.Fatalf("nodeAddresses returned error: %v", err)
- }
- sort.Sort(AddressSlice(addrs))
- t.Logf("addresses is %v", addrs)
- want := []v1.NodeAddress{
- {Type: v1.NodeInternalIP, Address: "10.0.0.31"},
- {Type: v1.NodeInternalIP, Address: "10.0.0.32"},
- {Type: v1.NodeExternalIP, Address: "2001:4800:780e:510:be76:4eff:fe04:84a8"},
- {Type: v1.NodeExternalIP, Address: "2001:4800:790e:510:be76:4eff:fe04:82a8"},
- {Type: v1.NodeExternalIP, Address: "50.56.176.35"},
- {Type: v1.NodeExternalIP, Address: "50.56.176.36"},
- {Type: v1.NodeExternalIP, Address: "50.56.176.99"},
- {Type: v1.NodeHostName, Address: "a1-yinvcez57-0-bvynoyawrhcg-kube-minion-fg5i4jwcc2yy.novalocal"},
- }
- if !reflect.DeepEqual(want, addrs) {
- t.Errorf("nodeAddresses returned incorrect value %v", addrs)
- }
- }
- func TestNewOpenStack(t *testing.T) {
- cfg, ok := configFromEnv()
- if !ok {
- t.Skip("No config found in environment")
- }
- _, err := newOpenStack(cfg)
- if err != nil {
- t.Fatalf("Failed to construct/authenticate OpenStack: %s", err)
- }
- }
- func TestLoadBalancer(t *testing.T) {
- cfg, ok := configFromEnv()
- if !ok {
- t.Skip("No config found in environment")
- }
- versions := []string{"v2", ""}
- for _, v := range versions {
- t.Logf("Trying LBVersion = '%s'\n", v)
- cfg.LoadBalancer.LBVersion = v
- os, err := newOpenStack(cfg)
- if err != nil {
- t.Fatalf("Failed to construct/authenticate OpenStack: %s", err)
- }
- lb, ok := os.LoadBalancer()
- if !ok {
- t.Fatalf("LoadBalancer() returned false - perhaps your stack doesn't support Neutron?")
- }
- _, exists, err := lb.GetLoadBalancer(context.TODO(), testClusterName, &v1.Service{ObjectMeta: metav1.ObjectMeta{Name: "noexist"}})
- if err != nil {
- t.Fatalf("GetLoadBalancer(\"noexist\") returned error: %s", err)
- }
- if exists {
- t.Fatalf("GetLoadBalancer(\"noexist\") returned exists")
- }
- }
- }
- func TestZones(t *testing.T) {
- SetMetadataFixture(&FakeMetadata)
- defer ClearMetadata()
- os := OpenStack{
- provider: &gophercloud.ProviderClient{
- IdentityBase: "http://auth.url/",
- },
- region: "myRegion",
- }
- z, ok := os.Zones()
- if !ok {
- t.Fatalf("Zones() returned false")
- }
- zone, err := z.GetZone(context.TODO())
- if err != nil {
- t.Fatalf("GetZone() returned error: %s", err)
- }
- if zone.Region != "myRegion" {
- t.Fatalf("GetZone() returned wrong region (%s)", zone.Region)
- }
- if zone.FailureDomain != "nova" {
- t.Fatalf("GetZone() returned wrong failure domain (%s)", zone.FailureDomain)
- }
- }
- var diskPathRegexp = regexp.MustCompile("/dev/disk/(?:by-id|by-path)/")
- func TestVolumes(t *testing.T) {
- cfg, ok := configFromEnv()
- if !ok {
- t.Skip("No config found in environment")
- }
- os, err := newOpenStack(cfg)
- if err != nil {
- t.Fatalf("Failed to construct/authenticate OpenStack: %s", err)
- }
- tags := map[string]string{
- "test": "value",
- }
- vol, _, _, _, err := os.CreateVolume("kubernetes-test-volume-"+rand.String(10), 1, "", "", &tags)
- if err != nil {
- t.Fatalf("Cannot create a new Cinder volume: %v", err)
- }
- t.Logf("Volume (%s) created\n", vol)
- WaitForVolumeStatus(t, os, vol, volumeAvailableStatus)
- id, err := os.InstanceID()
- if err != nil {
- t.Logf("Cannot find instance id: %v - perhaps you are running this test outside a VM launched by OpenStack", err)
- } else {
- diskID, err := os.AttachDisk(id, vol)
- if err != nil {
- t.Fatalf("Cannot AttachDisk Cinder volume %s: %v", vol, err)
- }
- t.Logf("Volume (%s) attached, disk ID: %s\n", vol, diskID)
- WaitForVolumeStatus(t, os, vol, volumeInUseStatus)
- devicePath := os.GetDevicePath(diskID)
- if diskPathRegexp.FindString(devicePath) == "" {
- t.Fatalf("GetDevicePath returned and unexpected path for Cinder volume %s, returned %s", vol, devicePath)
- }
- t.Logf("Volume (%s) found at path: %s\n", vol, devicePath)
- err = os.DetachDisk(id, vol)
- if err != nil {
- t.Fatalf("Cannot DetachDisk Cinder volume %s: %v", vol, err)
- }
- t.Logf("Volume (%s) detached\n", vol)
- WaitForVolumeStatus(t, os, vol, volumeAvailableStatus)
- }
- expectedVolSize := resource.MustParse("2Gi")
- newVolSize, err := os.ExpandVolume(vol, resource.MustParse("1Gi"), expectedVolSize)
- if err != nil {
- t.Fatalf("Cannot expand a Cinder volume: %v", err)
- }
- if newVolSize != expectedVolSize {
- t.Logf("Expected: %v but got: %v ", expectedVolSize, newVolSize)
- }
- t.Logf("Volume expanded to (%v) \n", newVolSize)
- WaitForVolumeStatus(t, os, vol, volumeAvailableStatus)
- err = os.DeleteVolume(vol)
- if err != nil {
- t.Fatalf("Cannot delete Cinder volume %s: %v", vol, err)
- }
- t.Logf("Volume (%s) deleted\n", vol)
- }
- func TestInstanceIDFromProviderID(t *testing.T) {
- testCases := []struct {
- providerID string
- instanceID string
- fail bool
- }{
- {
- providerID: ProviderName + "://" + "/" + "7b9cf879-7146-417c-abfd-cb4272f0c935",
- instanceID: "7b9cf879-7146-417c-abfd-cb4272f0c935",
- fail: false,
- },
- {
- providerID: "openstack://7b9cf879-7146-417c-abfd-cb4272f0c935",
- instanceID: "",
- fail: true,
- },
- {
- providerID: "7b9cf879-7146-417c-abfd-cb4272f0c935",
- instanceID: "",
- fail: true,
- },
- {
- providerID: "other-provider:///7b9cf879-7146-417c-abfd-cb4272f0c935",
- instanceID: "",
- fail: true,
- },
- }
- for _, test := range testCases {
- instanceID, err := instanceIDFromProviderID(test.providerID)
- if (err != nil) != test.fail {
- t.Errorf("%s yielded `err != nil` as %t. expected %t", test.providerID, (err != nil), test.fail)
- }
- if test.fail {
- continue
- }
- if instanceID != test.instanceID {
- t.Errorf("%s yielded %s. expected %s", test.providerID, instanceID, test.instanceID)
- }
- }
- }
- func TestToAuth3Options(t *testing.T) {
- cfg := Config{}
- cfg.Global.Username = "user"
- cfg.Global.Password = "pass"
- cfg.Global.DomainID = "2a73b8f597c04551a0fdc8e95544be8a"
- cfg.Global.DomainName = "local"
- cfg.Global.AuthURL = "http://auth.url"
- cfg.Global.UserID = "user"
- ao := cfg.toAuth3Options()
- if !ao.AllowReauth {
- t.Errorf("Will need to be able to reauthenticate")
- }
- if ao.Username != cfg.Global.Username {
- t.Errorf("Username %s != %s", ao.Username, cfg.Global.Username)
- }
- if ao.Password != cfg.Global.Password {
- t.Errorf("Password %s != %s", ao.Password, cfg.Global.Password)
- }
- if ao.DomainID != cfg.Global.DomainID {
- t.Errorf("DomainID %s != %s", ao.DomainID, cfg.Global.DomainID)
- }
- if ao.IdentityEndpoint != cfg.Global.AuthURL {
- t.Errorf("IdentityEndpoint %s != %s", ao.IdentityEndpoint, cfg.Global.AuthURL)
- }
- if ao.UserID != cfg.Global.UserID {
- t.Errorf("UserID %s != %s", ao.UserID, cfg.Global.UserID)
- }
- if ao.DomainName != cfg.Global.DomainName {
- t.Errorf("DomainName %s != %s", ao.DomainName, cfg.Global.DomainName)
- }
- }
- func clearEnviron(t *testing.T) []string {
- env := os.Environ()
- for _, pair := range env {
- if strings.HasPrefix(pair, "OS_") {
- i := strings.Index(pair, "=") + 1
- os.Unsetenv(pair[:i-1])
- }
- }
- return env
- }
- func resetEnviron(t *testing.T, items []string) {
- for _, pair := range items {
- if strings.HasPrefix(pair, "OS_") {
- i := strings.Index(pair, "=") + 1
- if err := os.Setenv(pair[:i-1], pair[i:]); err != nil {
- t.Errorf("Setenv(%q, %q) failed during reset: %v", pair[:i-1], pair[i:], err)
- }
- }
- }
- }
|