github.com/vmware/govmomi@v0.51.0/simulator/event_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 "reflect" 10 "testing" 11 12 "github.com/vmware/govmomi" 13 "github.com/vmware/govmomi/event" 14 "github.com/vmware/govmomi/vim25/types" 15 ) 16 17 func TestEventManagerVPX(t *testing.T) { 18 logEvents = testing.Verbose() 19 ctx := context.Background() 20 21 m := VPX() 22 m.Datacenter = 2 23 24 defer m.Remove() 25 26 err := m.Create() 27 if err != nil { 28 t.Fatal(err) 29 } 30 31 s := m.Service.NewServer() 32 defer s.Close() 33 34 c, err := govmomi.NewClient(ctx, s.URL, true) 35 if err != nil { 36 t.Fatal(err) 37 } 38 39 e := event.NewManager(c.Client) 40 count := m.Count() 41 42 root := c.ServiceContent.RootFolder 43 vm := m.Map().Any("VirtualMachine").(*VirtualMachine) 44 host := m.Map().Get(vm.Runtime.Host.Reference()).(*HostSystem) 45 46 vmEvents := 6 // BeingCreated + InstanceUuid + Uuid + Created + Starting + PoweredOn 47 tests := []struct { 48 obj types.ManagedObjectReference 49 expect int 50 ids []string 51 }{ 52 {root, -1 * count.Machine, nil}, 53 {root, 1, []string{"SessionEvent"}}, // UserLoginSessionEvent 54 {vm.Reference(), 0, []string{"SessionEvent"}}, 55 {root, count.Machine, []string{"VmCreatedEvent"}}, // concrete type 56 {root, count.Machine * vmEvents, []string{"VmEvent"}}, // base type 57 {vm.Reference(), 1, []string{"VmCreatedEvent"}}, 58 {vm.Reference(), vmEvents, nil}, 59 {host.Reference(), len(host.Vm), []string{"VmCreatedEvent"}}, 60 {host.Reference(), len(host.Vm) * vmEvents, nil}, 61 } 62 63 for i, test := range tests { 64 n := 0 65 filter := types.EventFilterSpec{ 66 Entity: &types.EventFilterSpecByEntity{ 67 Entity: test.obj, 68 Recursion: types.EventFilterSpecRecursionOptionAll, 69 }, 70 EventTypeId: test.ids, 71 MaxCount: 100, 72 } 73 74 f := func(obj types.ManagedObjectReference, events []types.BaseEvent) error { 75 n += len(events) 76 77 qevents, qerr := e.QueryEvents(ctx, filter) 78 if qerr != nil { 79 t.Fatal(qerr) 80 } 81 82 if n != len(qevents) { 83 t.Errorf("%d vs %d", n, len(qevents)) 84 } 85 86 return nil 87 } 88 89 err = e.Events(ctx, []types.ManagedObjectReference{test.obj}, filter.MaxCount, false, false, f, test.ids...) 90 if err != nil { 91 t.Fatalf("%d: %s", i, err) 92 } 93 94 if test.expect < 0 { 95 expect := test.expect * -1 96 if n < expect { 97 t.Errorf("%d: expected at least %d events, got: %d", i, expect, n) 98 } 99 continue 100 } 101 102 if test.expect != n { 103 t.Errorf("%d: expected %d events, got: %d", i, test.expect, n) 104 } 105 } 106 107 // Test that we don't panic if event ID is not defined in esx.EventInfo 108 type TestHostRemovedEvent struct { 109 types.HostEvent 110 } 111 var hre TestHostRemovedEvent 112 kind := reflect.TypeOf(hre) 113 types.Add(kind.Name(), kind) 114 115 err = e.PostEvent(ctx, &hre) 116 if err != nil { 117 t.Fatal(err) 118 } 119 } 120 121 func TestEventManagerRead(t *testing.T) { 122 logEvents = testing.Verbose() 123 ctx := context.Background() 124 m := VPX() 125 126 defer m.Remove() 127 128 err := m.Create() 129 if err != nil { 130 t.Fatal(err) 131 } 132 133 s := m.Service.NewServer() 134 defer s.Close() 135 136 vc, err := govmomi.NewClient(ctx, s.URL, true) 137 if err != nil { 138 t.Fatal(err) 139 } 140 141 defer func() { 142 if err := vc.Logout(ctx); err != nil { 143 t.Fatal(err) 144 } 145 }() 146 147 spec := types.EventFilterSpec{ 148 Entity: &types.EventFilterSpecByEntity{ 149 Entity: vc.Client.ServiceContent.RootFolder, 150 Recursion: types.EventFilterSpecRecursionOptionChildren, 151 }, 152 } 153 em := event.NewManager(vc.Client) 154 c, err := em.CreateCollectorForEvents(ctx, spec) 155 if err != nil { 156 t.Fatal(err) 157 } 158 159 page, err := c.LatestPage(ctx) 160 if err != nil { 161 t.Fatal(err) 162 } 163 nevents := len(page) 164 if nevents == 0 { 165 t.Fatal("no recent events") 166 } 167 tests := []struct { 168 max int 169 rewind bool 170 order bool 171 read func(context.Context, int32) ([]types.BaseEvent, error) 172 }{ 173 {nevents, true, true, c.ReadNextEvents}, 174 {nevents / 3, true, true, c.ReadNextEvents}, 175 {nevents * 3, false, true, c.ReadNextEvents}, 176 {3, false, false, c.ReadPreviousEvents}, 177 {nevents * 3, false, true, c.ReadNextEvents}, 178 } 179 180 for _, test := range tests { 181 var all []types.BaseEvent 182 count := 0 183 for { 184 events, err := test.read(ctx, int32(test.max)) 185 if err != nil { 186 t.Fatal(err) 187 } 188 if len(events) == 0 { 189 // expecting 0 below as we've read all events in the page 190 zevents, nerr := test.read(ctx, int32(test.max)) 191 if nerr != nil { 192 t.Fatal(nerr) 193 } 194 if len(zevents) != 0 { 195 t.Errorf("zevents=%d", len(zevents)) 196 } 197 break 198 } 199 count += len(events) 200 all = append(all, events...) 201 } 202 if count < len(page) { 203 t.Errorf("expected at least %d events, got: %d", len(page), count) 204 } 205 206 for i := 1; i < len(all); i++ { 207 prev := all[i-1].GetEvent().Key 208 key := all[i].GetEvent().Key 209 if test.order { 210 if prev > key { 211 t.Errorf("key %d > %d", prev, key) 212 } 213 } else { 214 if prev < key { 215 t.Errorf("key %d < %d", prev, key) 216 } 217 } 218 } 219 220 if test.rewind { 221 if err = c.Rewind(ctx); err != nil { 222 t.Error(err) 223 } 224 } 225 } 226 227 // after Reset() we should only get events via ReadPreviousEvents 228 if err = c.Reset(ctx); err != nil { 229 t.Fatal(err) 230 } 231 232 events, err := c.ReadNextEvents(ctx, int32(nevents)) 233 if err != nil { 234 t.Fatal(err) 235 } 236 if len(events) != 0 { 237 t.Errorf("expected 0 events, got %d", len(events)) 238 } 239 240 event := &types.GeneralEvent{Message: "vcsim"} 241 event.Datacenter = &types.DatacenterEventArgument{ 242 Datacenter: m.Map().Any("Datacenter").Reference(), 243 } 244 err = em.PostEvent(ctx, event) 245 if err != nil { 246 t.Fatal(err) 247 } 248 249 events, err = c.ReadNextEvents(ctx, int32(nevents)) 250 if err != nil { 251 t.Fatal(err) 252 } 253 if len(events) != 1 { 254 t.Errorf("expected 1 events, got %d", len(events)) 255 } 256 257 count := 0 258 for { 259 events, err = c.ReadPreviousEvents(ctx, 3) 260 if err != nil { 261 t.Fatal(err) 262 } 263 if len(events) == 0 { 264 break 265 } 266 count += len(events) 267 } 268 if count < nevents { 269 t.Errorf("expected %d events, got %d", nevents, count) 270 } 271 }