github.com/vmware/govmomi@v0.37.2/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  }