2018-09-12 05:53:46 +08:00
package vsphere
import (
"context"
"crypto/tls"
"fmt"
2023-03-13 19:19:49 +08:00
"net/url"
2020-08-27 00:58:28 +08:00
"os"
"strings"
2018-09-12 05:53:46 +08:00
"testing"
"time"
"github.com/stretchr/testify/require"
2018-11-07 06:22:43 +08:00
"github.com/vmware/govmomi/object"
2018-09-12 05:53:46 +08:00
"github.com/vmware/govmomi/simulator"
2019-02-13 06:05:14 +08:00
"github.com/vmware/govmomi/vim25/mo"
2018-11-07 06:22:43 +08:00
"github.com/vmware/govmomi/vim25/types"
2021-11-18 22:22:43 +08:00
"github.com/influxdata/telegraf/config"
itls "github.com/influxdata/telegraf/plugins/common/tls"
"github.com/influxdata/telegraf/testutil"
2018-09-12 05:53:46 +08:00
)
func defaultVSphere ( ) * VSphere {
return & VSphere {
2019-09-24 06:39:50 +08:00
Log : testutil . Logger { } ,
2018-09-12 05:53:46 +08:00
ClusterMetricInclude : [ ] string {
"cpu.usage.*" ,
"cpu.usagemhz.*" ,
"mem.usage.*" ,
"mem.active.*" } ,
ClusterMetricExclude : nil ,
2019-02-13 06:05:14 +08:00
ClusterInclude : [ ] string { "/**" } ,
2018-09-12 05:53:46 +08:00
HostMetricInclude : [ ] string {
2019-02-13 06:05:14 +08:00
"cpu.coreUtilization.average" ,
"cpu.costop.summation" ,
"cpu.demand.average" ,
"cpu.idle.summation" ,
"cpu.latency.average" ,
"cpu.readiness.average" ,
"cpu.ready.summation" ,
"cpu.swapwait.summation" ,
"cpu.usage.average" ,
"cpu.usagemhz.average" ,
"cpu.used.summation" ,
"cpu.utilization.average" ,
"cpu.wait.summation" ,
"disk.deviceReadLatency.average" ,
"disk.deviceWriteLatency.average" ,
"disk.kernelReadLatency.average" ,
"disk.kernelWriteLatency.average" ,
"disk.numberReadAveraged.average" ,
"disk.numberWriteAveraged.average" ,
"disk.read.average" ,
"disk.totalReadLatency.average" ,
"disk.totalWriteLatency.average" ,
"disk.write.average" ,
"mem.active.average" ,
"mem.latency.average" ,
"mem.state.latest" ,
"mem.swapin.average" ,
"mem.swapinRate.average" ,
"mem.swapout.average" ,
"mem.swapoutRate.average" ,
"mem.totalCapacity.average" ,
"mem.usage.average" ,
"mem.vmmemctl.average" ,
"net.bytesRx.average" ,
"net.bytesTx.average" ,
"net.droppedRx.summation" ,
"net.droppedTx.summation" ,
"net.errorsRx.summation" ,
"net.errorsTx.summation" ,
"net.usage.average" ,
"power.power.average" ,
"storageAdapter.numberReadAveraged.average" ,
"storageAdapter.numberWriteAveraged.average" ,
"storageAdapter.read.average" ,
"storageAdapter.write.average" ,
"sys.uptime.latest" } ,
2018-09-12 05:53:46 +08:00
HostMetricExclude : nil ,
2019-02-13 06:05:14 +08:00
HostInclude : [ ] string { "/**" } ,
2018-09-12 05:53:46 +08:00
VMMetricInclude : [ ] string {
2019-02-13 06:05:14 +08:00
"cpu.demand.average" ,
"cpu.idle.summation" ,
"cpu.latency.average" ,
"cpu.readiness.average" ,
"cpu.ready.summation" ,
"cpu.run.summation" ,
"cpu.usagemhz.average" ,
"cpu.used.summation" ,
"cpu.wait.summation" ,
"mem.active.average" ,
"mem.granted.average" ,
"mem.latency.average" ,
"mem.swapin.average" ,
"mem.swapinRate.average" ,
"mem.swapout.average" ,
"mem.swapoutRate.average" ,
"mem.usage.average" ,
"mem.vmmemctl.average" ,
"net.bytesRx.average" ,
"net.bytesTx.average" ,
"net.droppedRx.summation" ,
"net.droppedTx.summation" ,
"net.usage.average" ,
"power.power.average" ,
"virtualDisk.numberReadAveraged.average" ,
"virtualDisk.numberWriteAveraged.average" ,
"virtualDisk.read.average" ,
"virtualDisk.readOIO.latest" ,
"virtualDisk.throughput.usage.average" ,
"virtualDisk.totalReadLatency.average" ,
"virtualDisk.totalWriteLatency.average" ,
"virtualDisk.write.average" ,
"virtualDisk.writeOIO.latest" ,
"sys.uptime.latest" } ,
2018-09-12 05:53:46 +08:00
VMMetricExclude : nil ,
2019-02-13 06:05:14 +08:00
VMInclude : [ ] string { "/**" } ,
2018-09-12 05:53:46 +08:00
DatastoreMetricInclude : [ ] string {
"disk.used.*" ,
2020-05-16 06:43:32 +08:00
"disk.provisioned.*" } ,
2022-05-13 04:36:56 +08:00
DatastoreMetricExclude : nil ,
DatastoreInclude : [ ] string { "/**" } ,
ResourcePoolMetricInclude : [ ] string {
"cpu.capacity.*" ,
"mem.capacity.*" } ,
ResourcePoolMetricExclude : nil ,
ResourcePoolInclude : [ ] string { "/**" } ,
DatacenterMetricInclude : nil ,
DatacenterMetricExclude : nil ,
DatacenterInclude : [ ] string { "/**" } ,
ClientConfig : itls . ClientConfig { InsecureSkipVerify : true } ,
2018-09-12 05:53:46 +08:00
2023-03-13 19:19:49 +08:00
MaxQueryObjects : 256 ,
MaxQueryMetrics : 256 ,
ObjectDiscoveryInterval : config . Duration ( time . Second * 300 ) ,
Timeout : config . Duration ( time . Second * 20 ) ,
ForceDiscoverOnInit : true ,
DiscoverConcurrency : 1 ,
CollectConcurrency : 1 ,
Separator : "." ,
HistoricalInterval : config . Duration ( time . Second * 300 ) ,
DisconnectedServersBehavior : "error" ,
2018-09-12 05:53:46 +08:00
}
}
2019-08-20 09:17:27 +08:00
func createSim ( folders int ) ( * simulator . Model , * simulator . Server , error ) {
2018-09-12 05:53:46 +08:00
model := simulator . VPX ( )
2019-08-20 09:17:27 +08:00
model . Folder = folders
model . Datacenter = 2
//model.App = 1
2018-09-12 05:53:46 +08:00
err := model . Create ( )
if err != nil {
return nil , nil , err
}
model . Service . TLS = new ( tls . Config )
s := model . Service . NewServer ( )
return model , s , nil
}
2019-02-13 06:05:14 +08:00
func testAlignUniform ( t * testing . T , n int ) {
now := time . Now ( ) . Truncate ( 60 * time . Second )
2022-12-12 22:05:33 +08:00
info := make ( [ ] types . PerfSampleInfo , 0 , n )
values := make ( [ ] int64 , 0 , n )
2019-02-13 06:05:14 +08:00
for i := 0 ; i < n ; i ++ {
2022-12-12 22:05:33 +08:00
info = append ( info , types . PerfSampleInfo {
2019-02-13 06:05:14 +08:00
Timestamp : now . Add ( time . Duration ( 20 * i ) * time . Second ) ,
Interval : 20 ,
2022-12-12 22:05:33 +08:00
} )
values = append ( values , 1 )
2019-02-13 06:05:14 +08:00
}
2020-04-22 02:30:29 +08:00
e := Endpoint { log : testutil . Logger { } }
newInfo , newValues := e . alignSamples ( info , values , 60 * time . Second )
2019-02-13 06:05:14 +08:00
require . Equal ( t , n / 3 , len ( newInfo ) , "Aligned infos have wrong size" )
require . Equal ( t , n / 3 , len ( newValues ) , "Aligned values have wrong size" )
for _ , v := range newValues {
require . Equal ( t , 1.0 , v , "Aligned value should be 1" )
}
}
func TestAlignMetrics ( t * testing . T ) {
testAlignUniform ( t , 3 )
testAlignUniform ( t , 30 )
testAlignUniform ( t , 333 )
// 20s to 60s of 1,2,3,1,2,3... (should average to 2)
n := 30
now := time . Now ( ) . Truncate ( 60 * time . Second )
2022-12-12 22:05:33 +08:00
info := make ( [ ] types . PerfSampleInfo , 0 , n )
values := make ( [ ] int64 , 0 , n )
2019-02-13 06:05:14 +08:00
for i := 0 ; i < n ; i ++ {
2022-12-12 22:05:33 +08:00
info = append ( info , types . PerfSampleInfo {
2019-02-13 06:05:14 +08:00
Timestamp : now . Add ( time . Duration ( 20 * i ) * time . Second ) ,
Interval : 20 ,
2022-12-12 22:05:33 +08:00
} )
values = append ( values , int64 ( i % 3 + 1 ) )
2019-02-13 06:05:14 +08:00
}
2020-04-22 02:30:29 +08:00
e := Endpoint { log : testutil . Logger { } }
newInfo , newValues := e . alignSamples ( info , values , 60 * time . Second )
2019-02-13 06:05:14 +08:00
require . Equal ( t , n / 3 , len ( newInfo ) , "Aligned infos have wrong size" )
require . Equal ( t , n / 3 , len ( newValues ) , "Aligned values have wrong size" )
for _ , v := range newValues {
require . Equal ( t , 2.0 , v , "Aligned value should be 2" )
}
}
2021-05-21 04:50:40 +08:00
func TestConfigDurationParsing ( t * testing . T ) {
v := defaultVSphere ( )
require . Equal ( t , int32 ( 300 ) , int32 ( time . Duration ( v . HistoricalInterval ) . Seconds ( ) ) , "HistoricalInterval.Seconds() with default duration should resolve 300" )
2018-09-12 05:53:46 +08:00
}
2018-11-07 06:22:43 +08:00
func TestMaxQuery ( t * testing . T ) {
2022-03-25 01:55:36 +08:00
if testing . Short ( ) {
t . Skip ( "Skipping long test in short mode" )
}
2019-08-20 09:17:27 +08:00
m , s , err := createSim ( 0 )
2023-01-10 00:17:23 +08:00
require . NoError ( t , err )
2018-11-07 06:22:43 +08:00
defer m . Remove ( )
defer s . Close ( )
v := defaultVSphere ( )
v . MaxQueryMetrics = 256
ctx := context . Background ( )
c , err := NewClient ( ctx , s . URL , v )
2023-01-10 00:17:23 +08:00
require . NoError ( t , err )
2018-11-07 06:22:43 +08:00
require . Equal ( t , 256 , v . MaxQueryMetrics )
om := object . NewOptionManager ( c . Client . Client , * c . Client . Client . ServiceContent . Setting )
err = om . Update ( ctx , [ ] types . BaseOptionValue { & types . OptionValue {
Key : "config.vpxd.stats.maxQueryMetrics" ,
Value : "42" ,
} } )
2023-01-10 00:17:23 +08:00
require . NoError ( t , err )
2018-11-07 06:22:43 +08:00
v . MaxQueryMetrics = 256
ctx = context . Background ( )
c2 , err := NewClient ( ctx , s . URL , v )
2023-01-10 00:17:23 +08:00
require . NoError ( t , err )
2018-11-07 06:22:43 +08:00
require . Equal ( t , 42 , v . MaxQueryMetrics )
c . close ( )
c2 . close ( )
}
2019-08-20 09:17:27 +08:00
func testLookupVM ( ctx context . Context , t * testing . T , f * Finder , path string , expected int , expectedName string ) {
poweredOn := types . VirtualMachinePowerState ( "poweredOn" )
var vm [ ] mo . VirtualMachine
err := f . Find ( ctx , "VirtualMachine" , path , & vm )
require . NoError ( t , err )
require . Equal ( t , expected , len ( vm ) )
if expectedName != "" {
require . Equal ( t , expectedName , vm [ 0 ] . Name )
}
for _ , v := range vm {
require . Equal ( t , poweredOn , v . Runtime . PowerState )
}
}
2019-02-13 06:05:14 +08:00
func TestFinder ( t * testing . T ) {
2022-03-25 01:55:36 +08:00
if testing . Short ( ) {
t . Skip ( "Skipping long test in short mode" )
}
2019-08-20 09:17:27 +08:00
m , s , err := createSim ( 0 )
2023-01-10 00:17:23 +08:00
require . NoError ( t , err )
2019-02-13 06:05:14 +08:00
defer m . Remove ( )
defer s . Close ( )
v := defaultVSphere ( )
ctx := context . Background ( )
c , err := NewClient ( ctx , s . URL , v )
2021-11-18 22:22:43 +08:00
require . NoError ( t , err )
2019-02-13 06:05:14 +08:00
f := Finder { c }
2019-08-20 09:17:27 +08:00
var dc [ ] mo . Datacenter
2019-02-13 06:05:14 +08:00
err = f . Find ( ctx , "Datacenter" , "/DC0" , & dc )
require . NoError ( t , err )
require . Equal ( t , 1 , len ( dc ) )
require . Equal ( t , "DC0" , dc [ 0 ] . Name )
2019-08-20 09:17:27 +08:00
var host [ ] mo . HostSystem
2019-02-13 06:05:14 +08:00
err = f . Find ( ctx , "HostSystem" , "/DC0/host/DC0_H0/DC0_H0" , & host )
require . NoError ( t , err )
require . Equal ( t , 1 , len ( host ) )
require . Equal ( t , "DC0_H0" , host [ 0 ] . Name )
host = [ ] mo . HostSystem { }
err = f . Find ( ctx , "HostSystem" , "/DC0/host/DC0_C0/DC0_C0_H0" , & host )
require . NoError ( t , err )
require . Equal ( t , 1 , len ( host ) )
require . Equal ( t , "DC0_C0_H0" , host [ 0 ] . Name )
2022-05-13 04:36:56 +08:00
var resourcepool = [ ] mo . ResourcePool { }
err = f . Find ( ctx , "ResourcePool" , "/DC0/host/DC0_C0/Resources/DC0_C0_RP0" , & resourcepool )
require . NoError ( t , err )
require . Equal ( t , 1 , len ( host ) )
require . Equal ( t , "DC0_C0_H0" , host [ 0 ] . Name )
2019-02-13 06:05:14 +08:00
host = [ ] mo . HostSystem { }
err = f . Find ( ctx , "HostSystem" , "/DC0/host/DC0_C0/*" , & host )
require . NoError ( t , err )
require . Equal ( t , 3 , len ( host ) )
2019-08-20 09:17:27 +08:00
var vm [ ] mo . VirtualMachine
testLookupVM ( ctx , t , & f , "/DC0/vm/DC0_H0_VM0" , 1 , "" )
testLookupVM ( ctx , t , & f , "/DC0/vm/DC0_C0*" , 2 , "" )
testLookupVM ( ctx , t , & f , "/DC0/*/DC0_H0_VM0" , 1 , "DC0_H0_VM0" )
testLookupVM ( ctx , t , & f , "/DC0/*/DC0_H0_*" , 2 , "" )
testLookupVM ( ctx , t , & f , "/DC0/**/DC0_H0_VM*" , 2 , "" )
testLookupVM ( ctx , t , & f , "/DC0/**" , 4 , "" )
testLookupVM ( ctx , t , & f , "/DC1/**" , 4 , "" )
testLookupVM ( ctx , t , & f , "/**" , 8 , "" )
testLookupVM ( ctx , t , & f , "/**/vm/**" , 8 , "" )
testLookupVM ( ctx , t , & f , "/*/host/**/*DC*" , 8 , "" )
testLookupVM ( ctx , t , & f , "/*/host/**/*DC*VM*" , 8 , "" )
testLookupVM ( ctx , t , & f , "/*/host/**/*DC*/*/*DC*" , 4 , "" )
2019-02-13 06:05:14 +08:00
vm = [ ] mo . VirtualMachine { }
2020-01-17 04:14:00 +08:00
err = f . FindAll ( ctx , "VirtualMachine" , [ ] string { "/DC0/vm/DC0_H0*" , "/DC0/vm/DC0_C0*" } , [ ] string { } , & vm )
2019-02-13 06:05:14 +08:00
require . NoError ( t , err )
2019-08-20 09:17:27 +08:00
require . Equal ( t , 4 , len ( vm ) )
2019-02-13 06:05:14 +08:00
2020-01-17 04:14:00 +08:00
rf := ResourceFilter {
finder : & f ,
paths : [ ] string { "/DC0/vm/DC0_H0*" , "/DC0/vm/DC0_C0*" } ,
excludePaths : [ ] string { "/DC0/vm/DC0_H0_VM0" } ,
resType : "VirtualMachine" ,
}
vm = [ ] mo . VirtualMachine { }
require . NoError ( t , rf . FindAll ( ctx , & vm ) )
require . Equal ( t , 3 , len ( vm ) )
rf = ResourceFilter {
finder : & f ,
paths : [ ] string { "/DC0/vm/DC0_H0*" , "/DC0/vm/DC0_C0*" } ,
excludePaths : [ ] string { "/**" } ,
resType : "VirtualMachine" ,
}
vm = [ ] mo . VirtualMachine { }
require . NoError ( t , rf . FindAll ( ctx , & vm ) )
require . Equal ( t , 0 , len ( vm ) )
rf = ResourceFilter {
finder : & f ,
paths : [ ] string { "/**" } ,
excludePaths : [ ] string { "/**" } ,
resType : "VirtualMachine" ,
}
vm = [ ] mo . VirtualMachine { }
require . NoError ( t , rf . FindAll ( ctx , & vm ) )
require . Equal ( t , 0 , len ( vm ) )
rf = ResourceFilter {
finder : & f ,
paths : [ ] string { "/**" } ,
excludePaths : [ ] string { "/this won't match anything" } ,
resType : "VirtualMachine" ,
}
vm = [ ] mo . VirtualMachine { }
require . NoError ( t , rf . FindAll ( ctx , & vm ) )
require . Equal ( t , 8 , len ( vm ) )
rf = ResourceFilter {
finder : & f ,
paths : [ ] string { "/**" } ,
excludePaths : [ ] string { "/**/*VM0" } ,
resType : "VirtualMachine" ,
}
vm = [ ] mo . VirtualMachine { }
require . NoError ( t , rf . FindAll ( ctx , & vm ) )
require . Equal ( t , 4 , len ( vm ) )
2019-08-20 09:17:27 +08:00
}
2019-02-13 06:05:14 +08:00
2019-08-20 09:17:27 +08:00
func TestFolders ( t * testing . T ) {
2022-03-25 01:55:36 +08:00
if testing . Short ( ) {
t . Skip ( "Skipping long test in short mode" )
}
2019-08-20 09:17:27 +08:00
m , s , err := createSim ( 1 )
2023-01-10 00:17:23 +08:00
require . NoError ( t , err )
2019-08-20 09:17:27 +08:00
defer m . Remove ( )
defer s . Close ( )
2019-02-13 06:05:14 +08:00
2019-08-20 09:17:27 +08:00
ctx := context . Background ( )
2019-02-13 06:05:14 +08:00
2020-08-27 00:58:28 +08:00
v := defaultVSphere ( )
2019-08-20 09:17:27 +08:00
c , err := NewClient ( ctx , s . URL , v )
2021-11-18 22:22:43 +08:00
require . NoError ( t , err )
2019-02-13 06:05:14 +08:00
2019-08-20 09:17:27 +08:00
f := Finder { c }
2019-08-15 08:03:33 +08:00
2019-08-20 09:17:27 +08:00
var folder [ ] mo . Folder
err = f . Find ( ctx , "Folder" , "/F0" , & folder )
2019-02-13 06:05:14 +08:00
require . NoError ( t , err )
2019-08-20 09:17:27 +08:00
require . Equal ( t , 1 , len ( folder ) )
require . Equal ( t , "F0" , folder [ 0 ] . Name )
2019-02-13 06:05:14 +08:00
2019-08-20 09:17:27 +08:00
var dc [ ] mo . Datacenter
err = f . Find ( ctx , "Datacenter" , "/F0/DC1" , & dc )
2019-02-13 06:05:14 +08:00
require . NoError ( t , err )
2019-08-20 09:17:27 +08:00
require . Equal ( t , 1 , len ( dc ) )
require . Equal ( t , "DC1" , dc [ 0 ] . Name )
2019-02-13 06:05:14 +08:00
2019-08-20 09:17:27 +08:00
testLookupVM ( ctx , t , & f , "/F0/DC0/vm/**/F*" , 0 , "" )
testLookupVM ( ctx , t , & f , "/F0/DC1/vm/**/F*/*VM*" , 4 , "" )
testLookupVM ( ctx , t , & f , "/F0/DC1/vm/**/F*/**" , 4 , "" )
2019-02-13 06:05:14 +08:00
}
2021-11-18 22:22:43 +08:00
func TestCollectionWithClusterMetrics ( t * testing . T ) {
2022-03-25 01:55:36 +08:00
if testing . Short ( ) {
t . Skip ( "Skipping long test in short mode" )
}
2020-08-27 00:58:28 +08:00
testCollection ( t , false )
}
func TestCollectionNoClusterMetrics ( t * testing . T ) {
2022-03-25 01:55:36 +08:00
if testing . Short ( ) {
t . Skip ( "Skipping long test in short mode" )
}
2020-08-27 00:58:28 +08:00
testCollection ( t , true )
}
2023-03-13 19:19:49 +08:00
func TestDisconnectedServerBehavior ( t * testing . T ) {
u , err := url . Parse ( "https://definitely.not.a.valid.host" )
require . NoError ( t , err )
v := defaultVSphere ( )
v . DisconnectedServersBehavior = "error"
_ , err = NewEndpoint ( context . Background ( ) , v , u , v . Log )
require . Error ( t , err )
v . DisconnectedServersBehavior = "ignore"
_ , err = NewEndpoint ( context . Background ( ) , v , u , v . Log )
require . NoError ( t , err )
v . DisconnectedServersBehavior = "something else"
_ , err = NewEndpoint ( context . Background ( ) , v , u , v . Log )
require . Error ( t , err )
require . Equal ( t , err . Error ( ) , ` "something else" is not a valid value for disconnected_servers_behavior ` )
}
2020-08-27 00:58:28 +08:00
func testCollection ( t * testing . T , excludeClusters bool ) {
mustHaveMetrics := map [ string ] struct { } {
"vsphere.vm.cpu" : { } ,
"vsphere.vm.mem" : { } ,
"vsphere.vm.net" : { } ,
"vsphere.host.cpu" : { } ,
"vsphere.host.mem" : { } ,
"vsphere.host.net" : { } ,
"vsphere.datastore.disk" : { } ,
2018-12-29 05:24:43 +08:00
}
2020-08-27 00:58:28 +08:00
vCenter := os . Getenv ( "VCENTER_URL" )
username := os . Getenv ( "VCENTER_USER" )
password := os . Getenv ( "VCENTER_PASSWORD" )
v := defaultVSphere ( )
if vCenter != "" {
v . Vcenters = [ ] string { vCenter }
2023-01-10 00:17:23 +08:00
v . Username = config . NewSecret ( [ ] byte ( username ) )
v . Password = config . NewSecret ( [ ] byte ( password ) )
2020-08-27 00:58:28 +08:00
} else {
m , s , err := createSim ( 0 )
2023-01-10 00:17:23 +08:00
require . NoError ( t , err )
2020-08-27 00:58:28 +08:00
defer m . Remove ( )
defer s . Close ( )
v . Vcenters = [ ] string { s . URL . String ( ) }
}
if excludeClusters {
v . ClusterMetricExclude = [ ] string { "*" }
2018-09-12 05:53:46 +08:00
}
var acc testutil . Accumulator
2020-08-27 00:58:28 +08:00
require . NoError ( t , v . Start ( & acc ) )
2018-09-12 05:53:46 +08:00
defer v . Stop ( )
require . NoError ( t , v . Gather ( & acc ) )
2018-12-29 05:24:43 +08:00
require . Equal ( t , 0 , len ( acc . Errors ) , fmt . Sprintf ( "Errors found: %s" , acc . Errors ) )
2019-02-13 06:05:14 +08:00
require . True ( t , len ( acc . Metrics ) > 0 , "No metrics were collected" )
2020-08-27 00:58:28 +08:00
cache := make ( map [ string ] string )
client , err := v . endpoints [ 0 ] . clientFactory . GetClient ( context . Background ( ) )
require . NoError ( t , err )
hostCache := make ( map [ string ] string )
for _ , m := range acc . Metrics {
delete ( mustHaveMetrics , m . Measurement )
if strings . HasPrefix ( m . Measurement , "vsphere.vm." ) {
mustContainAll ( t , m . Tags , [ ] string { "esxhostname" , "moid" , "vmname" , "guest" , "dcname" , "uuid" , "vmname" } )
hostName := m . Tags [ "esxhostname" ]
hostMoid , ok := hostCache [ hostName ]
if ! ok {
// We have to follow the host parent path to locate a cluster. Look up the host!
finder := Finder { client }
var hosts [ ] mo . HostSystem
2021-04-09 00:43:39 +08:00
err := finder . Find ( context . Background ( ) , "HostSystem" , "/**/" + hostName , & hosts )
require . NoError ( t , err )
2020-08-27 00:58:28 +08:00
require . NotEmpty ( t , hosts )
hostMoid = hosts [ 0 ] . Reference ( ) . Value
hostCache [ hostName ] = hostMoid
}
2021-03-23 01:21:36 +08:00
if isInCluster ( v , client , cache , "HostSystem" , hostMoid ) { // If the VM lives in a cluster
2020-08-27 00:58:28 +08:00
mustContainAll ( t , m . Tags , [ ] string { "clustername" } )
}
} else if strings . HasPrefix ( m . Measurement , "vsphere.host." ) {
2021-03-23 01:21:36 +08:00
if isInCluster ( v , client , cache , "HostSystem" , m . Tags [ "moid" ] ) { // If the host lives in a cluster
2020-08-27 00:58:28 +08:00
mustContainAll ( t , m . Tags , [ ] string { "esxhostname" , "clustername" , "moid" , "dcname" } )
} else {
mustContainAll ( t , m . Tags , [ ] string { "esxhostname" , "moid" , "dcname" } )
}
} else if strings . HasPrefix ( m . Measurement , "vsphere.cluster." ) {
mustContainAll ( t , m . Tags , [ ] string { "clustername" , "moid" , "dcname" } )
} else {
mustContainAll ( t , m . Tags , [ ] string { "moid" , "dcname" } )
}
}
require . Empty ( t , mustHaveMetrics , "Some metrics were not found" )
}
2021-03-23 01:21:36 +08:00
func isInCluster ( v * VSphere , client * Client , cache map [ string ] string , resourceKind , moid string ) bool {
2020-08-27 00:58:28 +08:00
ctx := context . Background ( )
ref := types . ManagedObjectReference {
Type : resourceKind ,
Value : moid ,
}
_ , ok := v . endpoints [ 0 ] . getAncestorName ( ctx , client , "ClusterComputeResource" , cache , ref )
return ok
}
func mustContainAll ( t * testing . T , tagMap map [ string ] string , mustHave [ ] string ) {
for _ , tag := range mustHave {
require . Contains ( t , tagMap , tag )
}
2018-09-12 05:53:46 +08:00
}