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