mirror of https://github.com/k3s-io/k3s
Merge pull request #58534 from dougm/vclib-tests
Automatic merge from submit-queue (batch tested with PRs 58756, 58758, 58725, 52799, 58534). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>. Add vSphere Cloud Provider vclib tests **What this PR does / why we need it**: Additional vSphere Cloud Provider functional tests against vcsim, providing more test coverage without having to run against a real vCenter instance. Follow up to #55918 **Which issue(s) this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close the issue(s) when PR gets merged)*: **Special notes for your reviewer**: This set of tests focuses on Datastore, Folder and VirtualMachine types. A couple of TODOs depend on changes to vcsim, I will follow up on those. **Release note**: ```release-note NONE ```pull/6/head
commit
b40581c14e
|
@ -59,11 +59,17 @@ filegroup(
|
|||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["datacenter_test.go"],
|
||||
srcs = [
|
||||
"datacenter_test.go",
|
||||
"datastore_test.go",
|
||||
"folder_test.go",
|
||||
"virtualmachine_test.go",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
importpath = "k8s.io/kubernetes/pkg/cloudprovider/providers/vsphere/vclib",
|
||||
deps = [
|
||||
"//vendor/github.com/vmware/govmomi:go_default_library",
|
||||
"//vendor/github.com/vmware/govmomi/object:go_default_library",
|
||||
"//vendor/github.com/vmware/govmomi/simulator:go_default_library",
|
||||
],
|
||||
)
|
||||
|
|
|
@ -50,3 +50,10 @@ const (
|
|||
DummyVMPrefixName = "vsphere-k8s"
|
||||
ActivePowerState = "poweredOn"
|
||||
)
|
||||
|
||||
// Test Constants
|
||||
const (
|
||||
testDefaultDatacenter = "DC0"
|
||||
testDefaultDatastore = "LocalDS_0"
|
||||
testNameNotFound = "enoent"
|
||||
)
|
||||
|
|
|
@ -21,6 +21,7 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/vmware/govmomi"
|
||||
"github.com/vmware/govmomi/object"
|
||||
"github.com/vmware/govmomi/simulator"
|
||||
)
|
||||
|
||||
|
@ -39,7 +40,7 @@ func TestDatacenter(t *testing.T) {
|
|||
s := model.Service.NewServer()
|
||||
defer s.Close()
|
||||
|
||||
avm := simulator.Map.Any("VirtualMachine").(*simulator.VirtualMachine)
|
||||
avm := simulator.Map.Any(VirtualMachineType).(*simulator.VirtualMachine)
|
||||
|
||||
c, err := govmomi.NewClient(ctx, s.URL, true)
|
||||
if err != nil {
|
||||
|
@ -48,17 +49,17 @@ func TestDatacenter(t *testing.T) {
|
|||
|
||||
vc := &VSphereConnection{GoVmomiClient: c}
|
||||
|
||||
_, err = GetDatacenter(ctx, vc, "enoent")
|
||||
_, err = GetDatacenter(ctx, vc, testNameNotFound)
|
||||
if err == nil {
|
||||
t.Error("expected error")
|
||||
}
|
||||
|
||||
dc, err := GetDatacenter(ctx, vc, "DC0")
|
||||
dc, err := GetDatacenter(ctx, vc, testDefaultDatacenter)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
_, err = dc.GetVMByUUID(ctx, "enoent")
|
||||
_, err = dc.GetVMByUUID(ctx, testNameNotFound)
|
||||
if err == nil {
|
||||
t.Error("expected error")
|
||||
}
|
||||
|
@ -68,22 +69,26 @@ func TestDatacenter(t *testing.T) {
|
|||
t.Error(err)
|
||||
}
|
||||
|
||||
_, err = dc.GetVMByPath(ctx, "enoent")
|
||||
_, err = dc.GetVMByPath(ctx, testNameNotFound)
|
||||
if err == nil {
|
||||
t.Error("expected error")
|
||||
}
|
||||
|
||||
vm, err := dc.GetVMByPath(ctx, "/DC0/vm/"+avm.Name)
|
||||
vm, err := dc.GetVMByPath(ctx, testDefaultDatacenter+"/vm/"+avm.Name)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
_, err = dc.GetDatastoreByPath(ctx, "enoent") // invalid format
|
||||
_, err = dc.GetDatastoreByPath(ctx, testNameNotFound) // invalid format
|
||||
if err == nil {
|
||||
t.Error("expected error")
|
||||
}
|
||||
|
||||
_, err = dc.GetDatastoreByPath(ctx, "[enoent] no/no.vmx")
|
||||
invalidPath := object.DatastorePath{
|
||||
Datastore: testNameNotFound,
|
||||
Path: testNameNotFound,
|
||||
}
|
||||
_, err = dc.GetDatastoreByPath(ctx, invalidPath.String())
|
||||
if err == nil {
|
||||
t.Error("expected error")
|
||||
}
|
||||
|
@ -93,22 +98,22 @@ func TestDatacenter(t *testing.T) {
|
|||
t.Error(err)
|
||||
}
|
||||
|
||||
_, err = dc.GetDatastoreByName(ctx, "enoent")
|
||||
_, err = dc.GetDatastoreByName(ctx, testNameNotFound)
|
||||
if err == nil {
|
||||
t.Error("expected error")
|
||||
}
|
||||
|
||||
ds, err := dc.GetDatastoreByName(ctx, "LocalDS_0")
|
||||
ds, err := dc.GetDatastoreByName(ctx, testDefaultDatastore)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
_, err = dc.GetFolderByPath(ctx, "enoent")
|
||||
_, err = dc.GetFolderByPath(ctx, testNameNotFound)
|
||||
if err == nil {
|
||||
t.Error("expected error")
|
||||
}
|
||||
|
||||
_, err = dc.GetFolderByPath(ctx, "/DC0/vm")
|
||||
_, err = dc.GetFolderByPath(ctx, testDefaultDatacenter+"/vm")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
@ -118,7 +123,7 @@ func TestDatacenter(t *testing.T) {
|
|||
t.Error("expected error")
|
||||
}
|
||||
|
||||
_, err = dc.GetVMMoList(ctx, []*VirtualMachine{vm}, []string{"enoent"}) // invalid property
|
||||
_, err = dc.GetVMMoList(ctx, []*VirtualMachine{vm}, []string{testNameNotFound}) // invalid property
|
||||
if err == nil {
|
||||
t.Error("expected error")
|
||||
}
|
||||
|
@ -128,14 +133,14 @@ func TestDatacenter(t *testing.T) {
|
|||
t.Error(err)
|
||||
}
|
||||
|
||||
vmdk := ds.Path(avm.Name + "/disk1.vmdk")
|
||||
diskPath := ds.Path(avm.Name + "/disk1.vmdk")
|
||||
|
||||
_, err = dc.GetVirtualDiskPage83Data(ctx, vmdk+"-enoent")
|
||||
_, err = dc.GetVirtualDiskPage83Data(ctx, diskPath+testNameNotFound)
|
||||
if err == nil {
|
||||
t.Error("expected error")
|
||||
}
|
||||
|
||||
_, err = dc.GetVirtualDiskPage83Data(ctx, vmdk)
|
||||
_, err = dc.GetVirtualDiskPage83Data(ctx, diskPath)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
@ -145,7 +150,7 @@ func TestDatacenter(t *testing.T) {
|
|||
t.Error("expected error")
|
||||
}
|
||||
|
||||
_, err = dc.GetDatastoreMoList(ctx, []*Datastore{ds}, []string{"enoent"}) // invalid property
|
||||
_, err = dc.GetDatastoreMoList(ctx, []*Datastore{ds}, []string{testNameNotFound}) // invalid property
|
||||
if err == nil {
|
||||
t.Error("expected error")
|
||||
}
|
||||
|
@ -156,7 +161,7 @@ func TestDatacenter(t *testing.T) {
|
|||
}
|
||||
|
||||
nodeVolumes := map[string][]string{
|
||||
avm.Name: {"enoent", vmdk},
|
||||
avm.Name: {testNameNotFound, diskPath},
|
||||
}
|
||||
|
||||
attached, err := dc.CheckDisksAttached(ctx, nodeVolumes)
|
||||
|
@ -164,11 +169,11 @@ func TestDatacenter(t *testing.T) {
|
|||
t.Error(err)
|
||||
}
|
||||
|
||||
if attached[avm.Name]["enoent"] {
|
||||
if attached[avm.Name][testNameNotFound] {
|
||||
t.Error("should not be attached")
|
||||
}
|
||||
|
||||
if !attached[avm.Name][vmdk] {
|
||||
t.Errorf("%s should be attached", vmdk)
|
||||
if !attached[avm.Name][diskPath] {
|
||||
t.Errorf("%s should be attached", diskPath)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
Copyright 2016 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 vclib
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/vmware/govmomi"
|
||||
"github.com/vmware/govmomi/object"
|
||||
"github.com/vmware/govmomi/simulator"
|
||||
)
|
||||
|
||||
func TestDatastore(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
// vCenter model + initial set of objects (cluster, hosts, VMs, network, datastore, etc)
|
||||
model := simulator.VPX()
|
||||
|
||||
defer model.Remove()
|
||||
err := model.Create()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
s := model.Service.NewServer()
|
||||
defer s.Close()
|
||||
|
||||
c, err := govmomi.NewClient(ctx, s.URL, true)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
vc := &VSphereConnection{GoVmomiClient: c}
|
||||
|
||||
dc, err := GetDatacenter(ctx, vc, testDefaultDatacenter)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
all, err := dc.GetAllDatastores(ctx)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
for _, info := range all {
|
||||
ds := info.Datastore
|
||||
kind, cerr := ds.GetType(ctx)
|
||||
if cerr != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if kind == "" {
|
||||
t.Error("empty Datastore type")
|
||||
}
|
||||
|
||||
dir := object.DatastorePath{
|
||||
Datastore: info.Info.Name,
|
||||
Path: "kubevols",
|
||||
}
|
||||
|
||||
// TODO: test Datastore.IsCompatibleWithStoragePolicy (vcsim needs PBM support)
|
||||
|
||||
for _, fail := range []bool{false, true} {
|
||||
cerr = ds.CreateDirectory(ctx, dir.String(), false)
|
||||
if fail {
|
||||
if cerr != ErrFileAlreadyExist {
|
||||
t.Errorf("expected %s, got: %s", ErrFileAlreadyExist, cerr)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if cerr != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
Copyright 2016 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 vclib
|
||||
|
||||
import (
|
||||
"context"
|
||||
"path"
|
||||
"testing"
|
||||
|
||||
"github.com/vmware/govmomi"
|
||||
"github.com/vmware/govmomi/simulator"
|
||||
)
|
||||
|
||||
func TestFolder(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
model := simulator.VPX()
|
||||
// Child folder "F0" will be created under the root folder and datacenter folders,
|
||||
// and all resources are created within the "F0" child folders.
|
||||
model.Folder = 1
|
||||
|
||||
defer model.Remove()
|
||||
err := model.Create()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
s := model.Service.NewServer()
|
||||
defer s.Close()
|
||||
|
||||
c, err := govmomi.NewClient(ctx, s.URL, true)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
vc := &VSphereConnection{GoVmomiClient: c}
|
||||
|
||||
dc, err := GetDatacenter(ctx, vc, testDefaultDatacenter)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
const folderName = "F0"
|
||||
vmFolder := path.Join("/", folderName, dc.Name(), "vm")
|
||||
|
||||
tests := []struct {
|
||||
folderPath string
|
||||
expect int
|
||||
}{
|
||||
{vmFolder, 0},
|
||||
{path.Join(vmFolder, folderName), (model.Host + model.Cluster) * model.Machine},
|
||||
}
|
||||
|
||||
for i, test := range tests {
|
||||
folder, cerr := dc.GetFolderByPath(ctx, test.folderPath)
|
||||
if cerr != nil {
|
||||
t.Fatal(cerr)
|
||||
}
|
||||
|
||||
vms, cerr := folder.GetVirtualMachines(ctx)
|
||||
if cerr != nil {
|
||||
t.Fatalf("%d: %s", i, cerr)
|
||||
}
|
||||
|
||||
if len(vms) != test.expect {
|
||||
t.Errorf("%d: expected %d VMs, got: %d", i, test.expect, len(vms))
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,144 @@
|
|||
/*
|
||||
Copyright 2016 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 vclib
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/vmware/govmomi"
|
||||
"github.com/vmware/govmomi/simulator"
|
||||
)
|
||||
|
||||
func TestVirtualMachine(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
model := simulator.VPX()
|
||||
|
||||
defer model.Remove()
|
||||
err := model.Create()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
s := model.Service.NewServer()
|
||||
defer s.Close()
|
||||
|
||||
c, err := govmomi.NewClient(ctx, s.URL, true)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
vc := &VSphereConnection{GoVmomiClient: c}
|
||||
|
||||
dc, err := GetDatacenter(ctx, vc, testDefaultDatacenter)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
folders, err := dc.Folders(ctx)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
folder, err := dc.GetFolderByPath(ctx, folders.VmFolder.InventoryPath)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
vms, err := folder.GetVirtualMachines(ctx)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if len(vms) == 0 {
|
||||
t.Fatal("no VMs")
|
||||
}
|
||||
|
||||
for _, vm := range vms {
|
||||
all, err := vm.GetAllAccessibleDatastores(ctx)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if len(all) == 0 {
|
||||
t.Error("no accessible datastores")
|
||||
}
|
||||
|
||||
_, err = vm.GetResourcePool(ctx)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
diskPath, err := vm.GetVirtualDiskPath(ctx)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
options := &VolumeOptions{SCSIControllerType: PVSCSIControllerType}
|
||||
|
||||
for _, expect := range []bool{true} { // TODO: vcsim needs to honor FileOperation to attach an existing disk
|
||||
attached, err := vm.IsDiskAttached(ctx, diskPath)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
if attached != expect {
|
||||
t.Errorf("attached=%t, expected=%t", attached, expect)
|
||||
}
|
||||
|
||||
uuid, err := vm.AttachDisk(ctx, diskPath, options)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if uuid == "" {
|
||||
t.Error("missing uuid")
|
||||
}
|
||||
|
||||
err = vm.DetachDisk(ctx, diskPath)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
for _, expect := range []bool{true, false} {
|
||||
active, err := vm.IsActive(ctx)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
if active != expect {
|
||||
t.Errorf("active=%t, expected=%t", active, expect)
|
||||
}
|
||||
|
||||
if expect {
|
||||
// Expecting to hit the error path since the VM is still powered on
|
||||
err = vm.DeleteVM(ctx)
|
||||
if err == nil {
|
||||
t.Error("expected error")
|
||||
}
|
||||
_, _ = vm.PowerOff(ctx)
|
||||
continue
|
||||
}
|
||||
|
||||
// Should be able to delete now that VM power is off
|
||||
err = vm.DeleteVM(ctx)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue