github.com/vmware/govmomi@v0.37.1/simulator/tenant_manager_test.go (about)

     1  /*
     2  Copyright (c) 2021 VMware, Inc. All Rights Reserved.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package simulator
    18  
    19  import (
    20  	"context"
    21  	"reflect"
    22  	"sort"
    23  	"strings"
    24  	"testing"
    25  
    26  	"github.com/vmware/govmomi"
    27  	"github.com/vmware/govmomi/object"
    28  	"github.com/vmware/govmomi/vim25"
    29  	"github.com/vmware/govmomi/vim25/soap"
    30  	"github.com/vmware/govmomi/vim25/types"
    31  )
    32  
    33  func sortMoRefSlice(a []types.ManagedObjectReference) {
    34  	sort.SliceStable(a, func(i, j int) bool {
    35  		lhs, rhs := a[i], a[j]
    36  		switch strings.Compare(lhs.Type, rhs.Type) {
    37  		case -1:
    38  			return true
    39  		case 1:
    40  			return false
    41  		}
    42  		return lhs.Value < rhs.Value
    43  	})
    44  }
    45  
    46  func TestTenantManagerForOldClients(t *testing.T) {
    47  	// ServiceContent TenantManager field is not present in older (<6.9.1) vmodl
    48  	// (e.g. response to RetrieveServiceConent() API or propery collector on
    49  	// ServiceInstance object), this field should be set only if the client is newer.
    50  	// Currently TenantManager is not set in vpx simulator's ServiceContent, and
    51  	// would be added once simulator supports client vmodl versioning properly.
    52  	t.Skip("needs vmodl versioning")
    53  
    54  	ctx := context.Background()
    55  	m := VPX()
    56  	defer m.Remove()
    57  
    58  	err := m.Create()
    59  	if err != nil {
    60  		t.Fatal(err)
    61  	}
    62  
    63  	s := m.Service.NewServer()
    64  	defer s.Close()
    65  
    66  	// Ensure non-nil moref being returned for ServiceContent.TenantManger for newer vim version clients.
    67  	newSoapClient := soap.NewClient(s.URL, true)
    68  	newSoapClient.Version = "6.9.1"
    69  	newVimClient, err := vim25.NewClient(ctx, newSoapClient)
    70  	if err != nil {
    71  		t.Fatal(err)
    72  	}
    73  	if newVimClient.ServiceContent.TenantManager == nil {
    74  		t.Fatal("Expected retrieved ServiceContent.TenantManager to be non-nil")
    75  	}
    76  
    77  	// Ensure non-nil moref being returned for ServiceContent.TenantManger for default version used in vim25 client.
    78  	defaultSoapClient := soap.NewClient(s.URL, true)
    79  	// No version being set for soap client
    80  	defaultVimClient, err := vim25.NewClient(ctx, defaultSoapClient)
    81  	if err != nil {
    82  		t.Fatal(err)
    83  	}
    84  	if defaultVimClient.ServiceContent.TenantManager == nil {
    85  		t.Fatal("Expected retrieved ServiceContent.TenantManager to be non-nil")
    86  	}
    87  
    88  	// Ensure nil being returned for ServiceContent.TenantManger for older vim version clients.
    89  	oldSoapClient := soap.NewClient(s.URL, true)
    90  	oldSoapClient.Version = "6.5"
    91  	oldVimClient, err := vim25.NewClient(ctx, oldSoapClient)
    92  	if err != nil {
    93  		t.Fatal(err)
    94  	}
    95  	if oldVimClient.ServiceContent.TenantManager != nil {
    96  		t.Fatalf("Expected retrieved ServiceContent.TenantManager to be nil but found %v", oldVimClient.ServiceContent.TenantManager)
    97  	}
    98  
    99  }
   100  
   101  func TestTenantManagerVPX(t *testing.T) {
   102  	// ServiceContent TenantManager field is not present in older (<6.9.1) vmodl
   103  	// (e.g. response to RetrieveServiceConent() API or propery collector on
   104  	// ServiceInstance object), this field should be set only if the client is newer.
   105  	// Currently TenantManager is not set in vpx simulator's ServiceContent, and
   106  	// would be added once simulator supports client vmodl versioning properly.
   107  	t.Skip("needs vmodl versioning")
   108  
   109  	ctx := context.Background()
   110  	m := VPX()
   111  	defer m.Remove()
   112  
   113  	err := m.Create()
   114  	if err != nil {
   115  		t.Fatal(err)
   116  	}
   117  
   118  	s := m.Service.NewServer()
   119  	defer s.Close()
   120  
   121  	c, err := govmomi.NewClient(ctx, s.URL, true)
   122  	if err != nil {
   123  		t.Fatal(err)
   124  	}
   125  
   126  	tenantManager := object.NewTenantManager(c.Client)
   127  	serviceProviderEntities := []types.ManagedObjectReference{
   128  		{Type: "VirtualMachine", Value: "vm-123"},
   129  		{Type: "HostSystem", Value: "host-1"},
   130  	}
   131  	sortMoRefSlice(serviceProviderEntities)
   132  
   133  	// "Read your writes", mark entities and verify they are marked.
   134  	err = tenantManager.MarkServiceProviderEntities(ctx, serviceProviderEntities)
   135  	if err != nil {
   136  		t.Fatal(err)
   137  	}
   138  	markedEntities, err := tenantManager.RetrieveServiceProviderEntities(ctx)
   139  	if err != nil {
   140  		t.Fatal(err)
   141  	}
   142  	sortMoRefSlice(markedEntities)
   143  	if !reflect.DeepEqual(serviceProviderEntities, markedEntities) {
   144  		t.Errorf("Requested-to-be-marked entities mismatch with acutally marked: %+v, %+v", serviceProviderEntities, markedEntities)
   145  	}
   146  
   147  	// Repeatedely mark same entities and verify they are deduped.
   148  	err = tenantManager.MarkServiceProviderEntities(ctx, serviceProviderEntities)
   149  	if err != nil {
   150  		t.Fatal(err)
   151  	}
   152  	markedEntities, err = tenantManager.RetrieveServiceProviderEntities(ctx)
   153  	if err != nil {
   154  		t.Fatal(err)
   155  	}
   156  	sortMoRefSlice(markedEntities)
   157  	if !reflect.DeepEqual(serviceProviderEntities, markedEntities) {
   158  		t.Errorf("Requested-to-be-marked entities mismatch with acutally marked: %+v, %+v", serviceProviderEntities, markedEntities)
   159  	}
   160  
   161  	// Unmark not-previously-marked entity and verify no-op.
   162  	unknownEntities := []types.ManagedObjectReference{{Type: "Folder", Value: "group-3"}}
   163  	err = tenantManager.UnmarkServiceProviderEntities(ctx, unknownEntities)
   164  	if err != nil {
   165  		t.Fatal(err)
   166  	}
   167  	markedEntities, err = tenantManager.RetrieveServiceProviderEntities(ctx)
   168  	if err != nil {
   169  		t.Fatal(err)
   170  	}
   171  	sortMoRefSlice(markedEntities)
   172  	if !reflect.DeepEqual(serviceProviderEntities, markedEntities) {
   173  		t.Errorf("Requested-to-be-marked entities mismatch with acutally marked: %+v, %+v", serviceProviderEntities, markedEntities)
   174  	}
   175  
   176  	// Unmark marked entities and verify no longer marked.
   177  	err = tenantManager.UnmarkServiceProviderEntities(ctx, serviceProviderEntities)
   178  	if err != nil {
   179  		t.Fatal(err)
   180  	}
   181  	markedEntities, err = tenantManager.RetrieveServiceProviderEntities(ctx)
   182  	if err != nil {
   183  		t.Fatal(err)
   184  	}
   185  	if len(markedEntities) > 0 {
   186  		t.Errorf("Expected all entities to be unmarked but still found marked: %+v", markedEntities)
   187  	}
   188  }