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  }