master
go 238 lines 5.75 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 package client
4
5 import (
6 "context"
7 "crypto/tls"
8 "errors"
9 "net/url"
10 "testing"
11 "time"
12
13 "github.com/stretchr/testify/assert"
14 "github.com/stretchr/testify/require"
15 "github.com/vmware/govmomi"
16 "github.com/vmware/govmomi/property"
17 "github.com/vmware/govmomi/simulator"
18 _ "github.com/vmware/govmomi/vapi/simulator"
19 "github.com/vmware/govmomi/view"
20 "github.com/vmware/govmomi/vim25/mo"
21 "github.com/vmware/govmomi/vim25/types"
22
23 "github.com/netdata/netdata/go/plugins/pkg/tlscfg"
24 )
25
26 func TestNew(t *testing.T) {
27 client, teardown := prepareClient(t)
28 defer teardown()
29
30 v, err := client.IsSessionActive()
31 assert.NoError(t, err)
32 assert.True(t, v)
33 }
34
35 func TestClient_Version(t *testing.T) {
36 client, teardown := prepareClient(t)
37 defer teardown()
38
39 assert.NotEmpty(t, client.Version())
40 }
41
42 func TestClient_CounterInfoByName(t *testing.T) {
43 client, teardown := prepareClient(t)
44 defer teardown()
45
46 v, err := client.CounterInfoByName()
47 assert.NoError(t, err)
48 assert.IsType(t, map[string]*types.PerfCounterInfo{}, v)
49 assert.NotEmpty(t, v)
50 }
51
52 func TestClient_IsSessionActive(t *testing.T) {
53 client, teardown := prepareClient(t)
54 defer teardown()
55
56 v, err := client.IsSessionActive()
57 assert.NoError(t, err)
58 assert.True(t, v)
59 }
60
61 func TestClient_Login(t *testing.T) {
62 client, teardown := prepareClient(t)
63 defer teardown()
64
65 assert.NoError(t, client.Logout())
66
67 err := client.Login(url.UserPassword("admin", "password"))
68 assert.NoError(t, err)
69
70 ok, err := client.IsSessionActive()
71 assert.NoError(t, err)
72 assert.True(t, ok)
73 }
74
75 func TestClient_Logout(t *testing.T) {
76 client, teardown := prepareClient(t)
77 defer teardown()
78
79 assert.NoError(t, client.Logout())
80
81 v, err := client.IsSessionActive()
82 assert.NoError(t, err)
83 assert.False(t, v)
84 }
85
86 func TestClient_Close(t *testing.T) {
87 model, srv := createSim(t)
88 defer model.Remove()
89 defer srv.Close()
90
91 client := newClient(t, srv.URL)
92 _, err := client.tagManager(context.Background())
93 require.NoError(t, err)
94 require.NotNil(t, client.rest)
95 require.NotNil(t, client.tags)
96
97 assert.NoError(t, client.Close())
98 assert.Nil(t, client.root)
99 assert.Nil(t, client.rest)
100 assert.Nil(t, client.tags)
101 assert.Nil(t, client.vsan)
102 assert.Nil(t, client.userInfo)
103
104 v, err := client.IsSessionActive()
105 assert.NoError(t, err)
106 assert.False(t, v)
107
108 control := newClient(t, srv.URL)
109 defer func() { _ = control.Close() }()
110 require.Len(t, sessionList(t, control), 1)
111 }
112
113 func TestNew_LogsOutOnContainerViewFailure(t *testing.T) {
114 model, srv := createSim(t)
115 defer model.Remove()
116 defer srv.Close()
117
118 origCreateContainerView := createContainerView
119 createContainerView = func(context.Context, *govmomi.Client) (*view.ContainerView, error) {
120 return nil, errors.New("create container view failed")
121 }
122 defer func() { createContainerView = origCreateContainerView }()
123
124 client, err := New(Config{
125 URL: srv.URL.String(),
126 User: "admin",
127 Password: "password",
128 Timeout: time.Second * 3,
129 TLSConfig: tlscfg.TLSConfig{InsecureSkipVerify: true},
130 })
131 require.Nil(t, client)
132 require.ErrorContains(t, err, "create container view failed")
133
134 createContainerView = origCreateContainerView
135 control := newClient(t, srv.URL)
136 defer func() { _ = control.Close() }()
137 require.Len(t, sessionList(t, control), 1)
138 }
139
140 func TestClient_InventoryMethods(t *testing.T) {
141 tests := map[string]struct {
142 collect func(*Client) (any, error)
143 }{
144 "datacenters": {
145 collect: func(c *Client) (any, error) { return c.Datacenters() },
146 },
147 "folders": {
148 collect: func(c *Client) (any, error) { return c.Folders() },
149 },
150 "compute resources": {
151 collect: func(c *Client) (any, error) { return c.ComputeResources() },
152 },
153 "hosts": {
154 collect: func(c *Client) (any, error) { return c.Hosts() },
155 },
156 "virtual machines": {
157 collect: func(c *Client) (any, error) { return c.VirtualMachines() },
158 },
159 }
160
161 for name, tc := range tests {
162 t.Run(name, func(t *testing.T) {
163 client, teardown := prepareClient(t)
164 defer teardown()
165
166 got, err := tc.collect(client)
167 assert.NoError(t, err)
168 assert.NotEmpty(t, got)
169 })
170 }
171 }
172
173 func TestClient_PerformanceMetrics(t *testing.T) {
174 client, teardown := prepareClient(t)
175 defer teardown()
176
177 hosts, err := client.Hosts()
178 require.NoError(t, err)
179 metrics, err := client.PerformanceMetrics(hostsPerfQuerySpecs(hosts))
180 require.NoError(t, err)
181 assert.True(t, len(metrics) > 0)
182 }
183
184 func prepareClient(t *testing.T) (client *Client, teardown func()) {
185 model, srv := createSim(t)
186 teardown = func() { model.Remove(); srv.Close() }
187 return newClient(t, srv.URL), teardown
188 }
189
190 func newClient(t *testing.T, vCenterURL *url.URL) *Client {
191 client, err := New(Config{
192 URL: vCenterURL.String(),
193 User: "admin",
194 Password: "password",
195 Timeout: time.Second * 3,
196 TLSConfig: tlscfg.TLSConfig{InsecureSkipVerify: true},
197 })
198 require.NoError(t, err)
199 return client
200 }
201
202 func sessionList(t *testing.T, client *Client) []types.UserSession {
203 t.Helper()
204
205 var sm mo.SessionManager
206 err := property.DefaultCollector(client.client.Client).RetrieveOne(
207 context.Background(),
208 *client.client.ServiceContent.SessionManager,
209 []string{"sessionList"},
210 &sm,
211 )
212 require.NoError(t, err)
213 return sm.SessionList
214 }
215
216 func createSim(t *testing.T) (*simulator.Model, *simulator.Server) {
217 model := simulator.VPX()
218 err := model.Create()
219 require.NoError(t, err)
220 model.Service.TLS = new(tls.Config)
221 model.Service.RegisterEndpoints = true
222 return model, model.Service.NewServer()
223 }
224
225 func hostsPerfQuerySpecs(hosts []mo.HostSystem) []types.PerfQuerySpec {
226 var pqs []types.PerfQuerySpec
227 for _, host := range hosts {
228 pq := types.PerfQuerySpec{
229 Entity: host.Reference(),
230 MaxSample: 1,
231 MetricId: []types.PerfMetricId{{CounterId: 32, Instance: ""}},
232 IntervalId: 20,
233 Format: "normal",
234 }
235 pqs = append(pqs, pq)
236 }
237 return pqs
238 }