github.com/vmware/govmomi@v0.51.0/simulator/session_manager_test.go (about) 1 // © Broadcom. All Rights Reserved. 2 // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 3 // SPDX-License-Identifier: Apache-2.0 4 5 package simulator 6 7 import ( 8 "context" 9 "crypto/tls" 10 "log" 11 "strings" 12 "testing" 13 14 "github.com/vmware/govmomi" 15 "github.com/vmware/govmomi/fault" 16 "github.com/vmware/govmomi/object" 17 "github.com/vmware/govmomi/property" 18 "github.com/vmware/govmomi/session" 19 "github.com/vmware/govmomi/simulator/vpx" 20 "github.com/vmware/govmomi/vim25/methods" 21 "github.com/vmware/govmomi/vim25/mo" 22 "github.com/vmware/govmomi/vim25/types" 23 ) 24 25 func TestSessionManagerAuth(t *testing.T) { 26 ctx := context.Background() 27 28 m := VPX() 29 30 defer m.Remove() 31 32 err := m.Create() 33 if err != nil { 34 t.Fatal(err) 35 } 36 37 s := m.Service.NewServer() 38 defer s.Close() 39 40 u := s.URL.User 41 s.URL.User = nil // skip Login() 42 43 c, err := govmomi.NewClient(ctx, s.URL, true) 44 if err != nil { 45 t.Fatal(err) 46 } 47 48 session, err := c.SessionManager.UserSession(ctx) 49 if err != nil { 50 t.Fatal(err) 51 } 52 53 if session != nil { 54 t.Error("expected nil session") 55 } 56 57 opts := object.NewOptionManager(c.Client, *c.ServiceContent.Setting) 58 var content []types.ObjectContent 59 err = opts.Properties(ctx, opts.Reference(), []string{"setting"}, &content) 60 if err != nil { 61 t.Fatal(err) 62 } 63 64 if len(content) != 1 { 65 t.Error("expected content len=1") 66 } 67 68 if len(content[0].PropSet) != 0 { 69 t.Error("non-empty PropSet") 70 } 71 72 if len(content[0].MissingSet) != 1 { 73 t.Error("expected MissingSet len=1") 74 } 75 76 if _, ok := content[0].MissingSet[0].Fault.Fault.(*types.NotAuthenticated); !ok { 77 t.Error("expected NotAuthenticated") 78 } 79 80 _, err = methods.GetCurrentTime(ctx, c) 81 if !fault.Is(err, &types.NotAuthenticated{}) { 82 t.Error("expected NotAuthenticated") 83 } 84 85 err = c.SessionManager.Login(ctx, u) 86 if err != nil { 87 t.Fatal(err) 88 } 89 90 c.UserAgent = "vcsim/x.x" 91 92 session, err = c.SessionManager.UserSession(ctx) 93 if err != nil { 94 t.Fatal(err) 95 } 96 97 if session == nil { 98 t.Error("expected session") 99 } 100 101 if session.UserAgent != c.UserAgent { 102 t.Errorf("UserAgent=%s", session.UserAgent) 103 } 104 105 active, err := c.SessionManager.SessionIsActive(ctx) 106 if err != nil { 107 t.Fatal(err) 108 } 109 110 if active == false { 111 t.Error("not active") 112 } 113 114 { 115 req := types.SessionIsActive{ 116 This: c.SessionManager.Reference(), 117 SessionID: "enoent", 118 UserName: "", 119 } 120 121 active, err := methods.SessionIsActive(ctx, c, &req) 122 if err != nil { 123 t.Fatal(err) 124 } 125 126 if active.Returnval { 127 t.Error("active") 128 } 129 } 130 131 { 132 req := types.SessionIsActive{ 133 This: c.SessionManager.Reference(), 134 SessionID: session.Key, 135 UserName: "enoent", 136 } 137 138 active, err := methods.SessionIsActive(ctx, c, &req) 139 if err != nil { 140 t.Fatal(err) 141 } 142 143 if active.Returnval { 144 t.Error("active") 145 } 146 } 147 148 content = nil 149 err = opts.Properties(ctx, opts.Reference(), []string{"setting"}, &content) 150 if err != nil { 151 t.Fatal(err) 152 } 153 154 if len(content) != 1 { 155 t.Error("expected content len=1") 156 } 157 158 if len(content[0].PropSet) != 1 { 159 t.Error("PropSet len=1") 160 } 161 162 if len(content[0].MissingSet) != 0 { 163 t.Error("expected MissingSet len=0") 164 } 165 166 last := session.LastActiveTime 167 168 _, err = methods.GetCurrentTime(ctx, c) 169 if err != nil { 170 t.Error(err) 171 } 172 173 pc, err := property.DefaultCollector(c.Client).Create(ctx) 174 if err != nil { 175 t.Fatal(err) 176 } 177 178 session, _ = c.SessionManager.UserSession(ctx) 179 180 if session.LastActiveTime.Equal(last) { 181 t.Error("LastActiveTime was not updated") 182 } 183 184 if !strings.Contains(pc.Reference().Value, session.Key) { 185 t.Errorf("invalid ref=%s", pc.Reference()) 186 } 187 188 ticket, err := c.SessionManager.AcquireCloneTicket(ctx) 189 if err != nil { 190 t.Fatal(err) 191 } 192 193 c, err = govmomi.NewClient(ctx, s.URL, true) 194 if err != nil { 195 t.Fatal(err) 196 } 197 198 err = c.SessionManager.CloneSession(ctx, ticket) 199 if err != nil { 200 t.Fatal(err) 201 } 202 203 err = c.SessionManager.CloneSession(ctx, ticket) 204 if err == nil { 205 t.Error("expected error") 206 } 207 208 _, err = methods.GetCurrentTime(ctx, c) 209 if err != nil { 210 t.Error(err) 211 } 212 } 213 214 func TestSessionManagerLoginExtension(t *testing.T) { 215 ctx := context.Background() 216 217 s := New(NewServiceInstance(NewContext(), vpx.ServiceContent, vpx.RootFolder)) 218 s.TLS = new(tls.Config) 219 ts := s.NewServer() 220 defer ts.Close() 221 222 if terr := ts.StartTunnel(); terr != nil { 223 t.Fatal(terr) 224 } 225 226 u := ts.URL.User 227 ts.URL.User = nil // skip Login() 228 229 c, err := govmomi.NewClient(ctx, ts.URL, true) 230 if err != nil { 231 t.Fatal(err) 232 } 233 234 err = session.NewManager(c.Client).LoginExtensionByCertificate(ctx, u.Username()) 235 if err == nil { 236 t.Error("expected error") // client cert not set 237 } 238 239 c.SetCertificate(ts.TLS.Certificates[0]) // any cert is ok with vcsim 240 err = session.NewManager(c.Client).LoginExtensionByCertificate(ctx, u.Username()) 241 if err != nil { 242 t.Fatal(err) 243 } 244 245 _, err = methods.GetCurrentTime(ctx, c) 246 if err != nil { 247 t.Error(err) 248 } 249 } 250 251 // Test WaitForUpdates against the PropertyCollector singleton. 252 // Includes test for issue 1172, where a 2nd session use of the PropertyCollector singleton followed by Logout() 253 // unregistered the 1st session's update listener as the PC singleton has the same moref regardless of session instance. 254 func TestSessionManagerPropertyCollector(t *testing.T) { 255 ctx := context.Background() 256 257 m := VPX() 258 259 defer m.Remove() 260 261 err := m.Create() 262 if err != nil { 263 t.Fatal(err) 264 } 265 266 s := m.Service.NewServer() 267 defer s.Close() 268 269 c, err := govmomi.NewClient(ctx, s.URL, true) 270 if err != nil { 271 t.Fatal(err) 272 } 273 274 pc := property.DefaultCollector(c.Client) 275 root := object.NewRootFolder(c.Client) 276 277 filter := types.CreateFilter{ 278 This: pc.Reference(), 279 Spec: types.PropertyFilterSpec{ 280 PropSet: []types.PropertySpec{ 281 { 282 Type: "Datacenter", 283 All: types.NewBool(false), 284 PathSet: []string{"name"}, 285 }, 286 }, 287 ObjectSet: []types.ObjectSpec{ 288 { 289 Obj: root.Reference(), 290 Skip: (*bool)(nil), 291 SelectSet: []types.BaseSelectionSpec{ 292 &types.TraversalSpec{ 293 SelectionSpec: types.SelectionSpec{ 294 Name: "folder2childEntity", 295 }, 296 Type: "Folder", 297 Path: "childEntity", 298 Skip: types.NewBool(false), 299 SelectSet: []types.BaseSelectionSpec{ 300 &types.SelectionSpec{ 301 Name: "folder2childEntity", 302 }, 303 }, 304 }, 305 }, 306 }, 307 }, 308 ReportMissingObjectsInResults: (*bool)(nil), 309 }, 310 PartialUpdates: true, 311 } 312 313 if _, err = pc.CreateFilter(ctx, filter); err != nil { 314 t.Fatal(err) 315 } 316 317 updates, _ := pc.WaitForUpdates(ctx, "") // disregard first result 318 // add DC and poll 319 dc, _ := root.CreateDatacenter(ctx, "DC-A") 320 updates, _ = pc.WaitForUpdates(ctx, updates.Version) 321 set := updates.FilterSet[0].ObjectSet[0] 322 if set.Obj.Type != "Datacenter" { 323 t.Errorf("obj=%s", set.Obj) 324 } 325 if set.Kind != types.ObjectUpdateKindEnter { 326 t.Errorf("kind=%s", set.Kind) 327 } 328 329 // create a new session and a call to the PropertyCollector singleton 330 c2, err := govmomi.NewClient(ctx, s.URL, true) 331 if err != nil { 332 log.Fatal(err) 333 } 334 var folder mo.Folder 335 property.DefaultCollector(c2.Client).RetrieveOne(ctx, root.Reference(), []string{"name"}, &folder) 336 _ = c2.Logout(ctx) 337 338 // remove DC and poll 339 _, _ = dc.Destroy(ctx) 340 updates, _ = pc.WaitForUpdates(ctx, updates.Version) 341 set = updates.FilterSet[0].ObjectSet[0] 342 if set.Obj.Type != "Datacenter" { 343 t.Errorf("obj=%s", set.Obj) 344 } 345 if set.Kind != types.ObjectUpdateKindLeave { 346 t.Errorf("kind=%s", set.Kind) 347 } 348 }