...

Source file src/edge-infra.dev/pkg/edge/api/services/vm_service_test.go

Documentation: edge-infra.dev/pkg/edge/api/services

     1  package services
     2  
     3  import (
     4  	"context"
     5  	"database/sql/driver"
     6  	"testing"
     7  
     8  	"github.com/DATA-DOG/go-sqlmock"
     9  	"github.com/stretchr/testify/assert"
    10  
    11  	"edge-infra.dev/pkg/edge/api/graph/model"
    12  	sqlquery "edge-infra.dev/pkg/edge/api/sql"
    13  )
    14  
    15  var (
    16  	virtualMachineIDs                    = []string{"v001", "v002"}
    17  	virtualMachineClusterEdgeIDs         = []string{"cluster-0001", "cluster-0002"}
    18  	virtualMachineClusterNames           = []string{"cluster-name-1", "cluster-name-2"}
    19  	virtualMachineNamespaceName          = "test-namespace"
    20  	virtualMachineNamespaceEdgeID        = "31d51d8c-b580-4e1a-94f6-a970bae8c132"
    21  	virtualMachineClusterNamespaceEdgeID = "61f25e90-81e7-4e44-b9f7-512cfecc2966"
    22  	uniqueHostname                       = "ien-12345e0053ap"
    23  	virtualMachineHostnames              = []string{"ien-00005e0053af", "ien-1a74bbfed056"}
    24  	virtualMachineTargetPowerStates      = []bool{true, false}
    25  	virtualMachineCpus                   = []int{1, 8}
    26  	virtualMachineMemorys                = []string{"1024Mi", "4096Mi"}
    27  	virtualMachineMachineTypes           = []model.MachineType{model.MachineTypeQ35, model.MachineTypeI440fx}
    28  	containerImageURLs                   = []string{"docker://us-east1-docker.pkg.dev/ret-edge-pltf-infra/workloads/ien-image:v1.6.0", "docker://us-east1-docker.pkg.dev/ret-edge-pltf-infra/workloads/edge-ui@sha256:7b50f24825c3ecf48fd078fb3b64c6838e8a7226a56df19a93b3deef742c9c8e"}
    29  	virtualMachines                      = []model.VirtualMachine{
    30  		{
    31  			VirtualMachineID: virtualMachineIDs[0],
    32  			Namespace:        virtualMachineNamespaceName,
    33  			ClusterEdgeID:    virtualMachineClusterEdgeIDs[0],
    34  			ClusterName:      virtualMachineClusterNames[0],
    35  			Hostname:         virtualMachineHostnames[0],
    36  			TargetPowerState: virtualMachineTargetPowerStates[0],
    37  			Cpus:             virtualMachineCpus[0],
    38  			Memory:           virtualMachineMemorys[0],
    39  			MachineType:      virtualMachineMachineTypes[0],
    40  			Disks: []*model.VirtualMachineDisk{
    41  				{
    42  					DiskID:            "29988157-f173-4bda-85c3-ad6f9848da1f",
    43  					VirtualMachineID:  virtualMachineIDs[0],
    44  					Type:              model.DiskTypeCdrom,
    45  					Bus:               model.BusTypeVirtio,
    46  					BootOrder:         0,
    47  					Size:              "2Gi",
    48  					ContainerImageURL: containerImageURLs[0],
    49  				},
    50  				{
    51  					DiskID:            "d5c209bc-0375-44e3-9343-82cc0ef656af",
    52  					VirtualMachineID:  virtualMachineIDs[0],
    53  					Type:              model.DiskTypeCdrom,
    54  					Bus:               model.BusTypeVirtio,
    55  					BootOrder:         1,
    56  					Size:              "2Gi",
    57  					ContainerImageURL: containerImageURLs[1],
    58  				},
    59  			},
    60  		},
    61  		{
    62  			VirtualMachineID: virtualMachineIDs[1],
    63  			Namespace:        virtualMachineNamespaceName,
    64  			ClusterEdgeID:    virtualMachineClusterEdgeIDs[1],
    65  			ClusterName:      virtualMachineClusterNames[1],
    66  			Hostname:         virtualMachineHostnames[1],
    67  			TargetPowerState: virtualMachineTargetPowerStates[1],
    68  			Cpus:             virtualMachineCpus[1],
    69  			Memory:           virtualMachineMemorys[1],
    70  			MachineType:      virtualMachineMachineTypes[1],
    71  			Disks: []*model.VirtualMachineDisk{
    72  				{
    73  					DiskID:           "f6db2f37-8c73-4dae-8cf9-1e4e5c6f2c9b",
    74  					VirtualMachineID: virtualMachineIDs[1],
    75  					Type:             model.DiskTypeDisk,
    76  					Bus:              model.BusTypeSata,
    77  					BootOrder:        2,
    78  					Size:             "1024Mi",
    79  				},
    80  			},
    81  		},
    82  	}
    83  	virtualMachineColumns     = []string{"vm_id", "namespace", "cluster_edge_id", "cluster_name", "hostname", "target_state", "cpus", "memory", "machine_type"}
    84  	virtualMachineDiskColumns = []string{"disk_id", "vm_id", "type", "bus", "boot_order", "size", "container_image_url"}
    85  )
    86  
    87  func TestCreateVirtualMachine(t *testing.T) {
    88  	mockVM := virtualMachines[0]
    89  
    90  	createErr, mockErr := genericTestCreateVirtualMachine(t, mockVM, uniqueHostname)
    91  
    92  	assert.NoError(t, createErr)
    93  	assert.NoError(t, mockErr)
    94  }
    95  
    96  func TestCreateVirtualMachineWithDisk(t *testing.T) {
    97  	db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
    98  	if err != nil {
    99  		t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
   100  	}
   101  	defer db.Close()
   102  
   103  	mockVM := virtualMachines[1]
   104  	virtualMachineHostname := uniqueHostname
   105  	createVM := getVirtualMachineCreateInput(mockVM)
   106  
   107  	mock.ExpectBegin()
   108  	mock.ExpectQuery(sqlquery.GetClusterNameByClusterEdgeIDQuery).
   109  		WithArgs(mockVM.ClusterEdgeID).
   110  		WillReturnRows(sqlmock.NewRows([]string{"cluster_name"}).
   111  			AddRow(mockVM.ClusterName))
   112  	mock.ExpectQuery(sqlquery.GetNamespaceNameByNamespaceEdgeIDQuery).
   113  		WithArgs(virtualMachineNamespaceEdgeID).
   114  		WillReturnRows(sqlmock.NewRows([]string{"name"}).
   115  			AddRow(mockVM.Namespace))
   116  	namespaceEdgeID := virtualMachineNamespaceEdgeID
   117  	clusterNamespaceEdgeID := virtualMachineClusterNamespaceEdgeID
   118  	mockDBClusterNamespaceCreate(mock, namespaceEdgeID, mockVM.ClusterEdgeID, sqlmock.NewResult(1, 1))
   119  	mockDBGetClusterNamespaceEdgeID(mock, namespaceEdgeID, mockVM.ClusterEdgeID, clusterNamespaceEdgeID)
   120  	mockDBGetAllVirtualMachineHostnamesForAClusterNamespace(mock, virtualMachineClusterNamespaceEdgeID, []string{virtualMachineHostname}) // checking unique hostname
   121  	mockDBVirtualMachineCreate(mock, mockVM, virtualMachineClusterNamespaceEdgeID, sqlmock.NewResult(1, 1))
   122  	mockDBVirtualMachineDisksCreate(mock, createVM.Disks, sqlmock.NewResult(1, 1))
   123  	mock.ExpectCommit()
   124  
   125  	service := NewVirtualMachineService(db)
   126  
   127  	createdVM, _, createErr := service.CreateVirtualMachineEntry(context.Background(), createVM)
   128  	mockErr := mock.ExpectationsWereMet()
   129  	assert.NoError(t, createErr)
   130  	assert.NoError(t, mockErr)
   131  	assert.NotNil(t, createdVM.Disks)
   132  	assert.Equal(t, mockVM.Disks[0].BootOrder, createdVM.Disks[0].BootOrder)
   133  }
   134  
   135  func TestCreateVirtualMachineHostnameExists(t *testing.T) {
   136  	mockVM := virtualMachines[0]
   137  	virtualMachineHostname := mockVM.Hostname
   138  
   139  	db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
   140  	if err != nil {
   141  		t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
   142  	}
   143  	defer db.Close()
   144  
   145  	createVM := getVirtualMachineCreateInput(mockVM)
   146  
   147  	mock.ExpectBegin()
   148  	mock.ExpectQuery(sqlquery.GetClusterNameByClusterEdgeIDQuery).
   149  		WithArgs(mockVM.ClusterEdgeID).
   150  		WillReturnRows(sqlmock.NewRows([]string{"cluster_name"}).
   151  			AddRow(mockVM.ClusterName))
   152  	mock.ExpectQuery(sqlquery.GetNamespaceNameByNamespaceEdgeIDQuery).
   153  		WithArgs(virtualMachineNamespaceEdgeID).
   154  		WillReturnRows(sqlmock.NewRows([]string{"name"}).
   155  			AddRow(mockVM.Namespace))
   156  	namespaceEdgeID := virtualMachineNamespaceEdgeID
   157  	clusterNamespaceEdgeID := virtualMachineClusterNamespaceEdgeID
   158  	mockDBClusterNamespaceCreate(mock, namespaceEdgeID, mockVM.ClusterEdgeID, sqlmock.NewResult(1, 1))
   159  	mockDBGetClusterNamespaceEdgeID(mock, namespaceEdgeID, mockVM.ClusterEdgeID, clusterNamespaceEdgeID)
   160  	mockDBGetAllVirtualMachineHostnamesForAClusterNamespace(mock, virtualMachineClusterNamespaceEdgeID, []string{virtualMachineHostname}) // checking unique hostname
   161  	mock.ExpectRollback()
   162  
   163  	service := NewVirtualMachineService(db)
   164  
   165  	_, _, createErr := service.CreateVirtualMachineEntry(context.Background(), createVM)
   166  	mockErr := mock.ExpectationsWereMet()
   167  
   168  	assert.Error(t, createErr)
   169  	assert.NoError(t, mockErr)
   170  }
   171  
   172  func TestDeleteVirtualMachine(t *testing.T) {
   173  	db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
   174  	if err != nil {
   175  		t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
   176  	}
   177  	defer db.Close()
   178  
   179  	virtualMachineID := virtualMachines[0].VirtualMachineID
   180  
   181  	mockDBVirtualMachineDelete(mock, virtualMachineID, sqlmock.NewResult(1, 1))
   182  	service := NewVirtualMachineService(db)
   183  
   184  	if err := service.DeleteVirtualMachineEntry(context.Background(), virtualMachineID); err != nil {
   185  		t.Errorf("error was not expected while deleting vm: %s", err)
   186  	}
   187  
   188  	if err := mock.ExpectationsWereMet(); err != nil {
   189  		t.Errorf("there were unfulfilled expectations: %s", err)
   190  	}
   191  }
   192  
   193  func TestGetVirtualMachineByID(t *testing.T) {
   194  	db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
   195  	if err != nil {
   196  		t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
   197  	}
   198  	defer db.Close()
   199  
   200  	mockVM := virtualMachines[0]
   201  
   202  	mockDBGetVirtualMachineByID(mock, mockVM.VirtualMachineID, &mockVM)
   203  
   204  	service := NewVirtualMachineService(db)
   205  
   206  	returnVM, err := service.GetVirtualMachine(context.Background(), mockVM.VirtualMachineID)
   207  
   208  	assert.NoError(t, err)
   209  	checkVirtualMachinesEqual(t, mockVM, returnVM)
   210  	assert.NoError(t, mock.ExpectationsWereMet())
   211  }
   212  
   213  func TestGetVirtualMachinesByClusterEdgeID(t *testing.T) {
   214  	db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
   215  	if err != nil {
   216  		t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
   217  	}
   218  	defer db.Close()
   219  
   220  	mockVMs := virtualMachines[0:2]
   221  	testVirtualMachineClusterEdgeID := mockVMs[0].ClusterEdgeID
   222  	mockVMs[1].ClusterEdgeID = testVirtualMachineClusterEdgeID
   223  
   224  	mockDBGetVirtualMachinesByClusterEdgeID(mock, testVirtualMachineClusterEdgeID, mockVMs)
   225  
   226  	service := NewVirtualMachineService(db)
   227  
   228  	returnVMs, err := service.GetVirtualMachines(context.Background(), &testVirtualMachineClusterEdgeID, nil)
   229  	assert.NoError(t, err)
   230  	assert.Equal(t, len(mockVMs), len(returnVMs))
   231  	checkVirtualMachinesEqual(t, mockVMs[0], returnVMs[0])
   232  	checkVirtualMachinesEqual(t, mockVMs[1], returnVMs[1])
   233  	assert.NoError(t, mock.ExpectationsWereMet())
   234  }
   235  
   236  func TestGetVirtualMachinesWithHostname(t *testing.T) {
   237  	db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
   238  	if err != nil {
   239  		t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
   240  	}
   241  	defer db.Close()
   242  
   243  	mockVMs := virtualMachines[0:2]
   244  	testVirtualMachineHostname := mockVMs[0].Hostname
   245  	mockVMs[1].Hostname = testVirtualMachineHostname
   246  
   247  	mockDBGetVirtualMachinesByHostname(mock, testVirtualMachineHostname, mockVMs)
   248  
   249  	service := NewVirtualMachineService(db)
   250  
   251  	returnVMs, err := service.GetVirtualMachines(context.Background(), nil, &testVirtualMachineHostname)
   252  	assert.NoError(t, err)
   253  	assert.Equal(t, len(mockVMs), len(returnVMs))
   254  	checkVirtualMachinesEqual(t, mockVMs[0], returnVMs[0])
   255  	checkVirtualMachinesEqual(t, mockVMs[1], returnVMs[1])
   256  	assert.NoError(t, mock.ExpectationsWereMet())
   257  }
   258  
   259  func TestGetVirtualMachinesWithClusterEdgeIDAndHostname(t *testing.T) {
   260  	db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
   261  	if err != nil {
   262  		t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
   263  	}
   264  	defer db.Close()
   265  
   266  	mockVMs := virtualMachines[0:2]
   267  	testVirtualMachineHostname := mockVMs[0].Hostname
   268  	testVirtualMachineClusterEdgeID := mockVMs[0].ClusterEdgeID
   269  	mockVMs[1].Hostname = testVirtualMachineHostname
   270  	mockVMs[1].ClusterEdgeID = testVirtualMachineClusterEdgeID
   271  
   272  	mockDBGetVirtualMachinesByClusterEdgeIDAndHostname(mock, testVirtualMachineClusterEdgeID, testVirtualMachineHostname, mockVMs)
   273  
   274  	service := NewVirtualMachineService(db)
   275  
   276  	returnVMs, err := service.GetVirtualMachines(context.Background(), &testVirtualMachineClusterEdgeID, &testVirtualMachineHostname)
   277  	assert.NoError(t, err)
   278  	assert.Equal(t, len(mockVMs), len(returnVMs))
   279  	checkVirtualMachinesEqual(t, mockVMs[0], returnVMs[0])
   280  	checkVirtualMachinesEqual(t, mockVMs[1], returnVMs[1])
   281  	assert.NoError(t, mock.ExpectationsWereMet())
   282  }
   283  
   284  func TestGetVirtualMachinesWithoutClusterEdgeIDAndHostname(t *testing.T) {
   285  	db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
   286  	if err != nil {
   287  		t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
   288  	}
   289  	defer db.Close()
   290  
   291  	mockVMs := virtualMachines[0:2]
   292  	testVirtualMachineHostname := mockVMs[0].Hostname
   293  	testVirtualMachineClusterEdgeID := mockVMs[0].ClusterEdgeID
   294  	mockVMs[1].Hostname = testVirtualMachineHostname
   295  	mockVMs[1].ClusterEdgeID = testVirtualMachineClusterEdgeID
   296  
   297  	mockDBGetAllVirtualMachines(mock, mockVMs)
   298  
   299  	service := NewVirtualMachineService(db)
   300  
   301  	returnVMs, err := service.GetVirtualMachines(context.Background(), nil, nil)
   302  	assert.NoError(t, err)
   303  	assert.Equal(t, len(mockVMs), len(returnVMs))
   304  	checkVirtualMachinesEqual(t, mockVMs[0], returnVMs[0])
   305  	checkVirtualMachinesEqual(t, mockVMs[1], returnVMs[1])
   306  	assert.NoError(t, mock.ExpectationsWereMet())
   307  }
   308  
   309  func TestUpdateVirtualMachine(t *testing.T) {
   310  	db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
   311  	if err != nil {
   312  		t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
   313  	}
   314  	defer db.Close()
   315  
   316  	mockVM := virtualMachines[0]
   317  	mock.ExpectBegin()
   318  	mockDBGetVirtualMachineByID(mock, mockVM.VirtualMachineID, &mockVM) // get mock VirtualMachine to update
   319  	newTargetPowerState := !mockVM.TargetPowerState
   320  	mockDBVirtualMachineUpdate(mock, mockVM.VirtualMachineID, model.VirtualMachineUpdateInput{TargetPowerState: &newTargetPowerState, Cpus: &mockVM.Cpus, Memory: &mockVM.Memory, MachineType: &mockVM.MachineType}, sqlmock.NewResult(1, 1))
   321  	mockDBGetVirtualMachineDisks(mock, mockVM.Disks)
   322  	mock.ExpectCommit()
   323  
   324  	service := NewVirtualMachineService(db)
   325  
   326  	updateVMValues := model.VirtualMachineUpdateInput{
   327  		TargetPowerState: &newTargetPowerState,
   328  		Cpus:             &mockVM.Cpus,
   329  		Memory:           &mockVM.Memory,
   330  		MachineType:      &mockVM.MachineType,
   331  	}
   332  	updateVM := model.VirtualMachineIDInput{
   333  		VirtualMachineID:     mockVM.VirtualMachineID,
   334  		VirtualMachineValues: &updateVMValues,
   335  	}
   336  
   337  	updatedVM, err := service.UpdateVirtualMachineEntry(context.Background(), &updateVM)
   338  	assert.NoError(t, err)
   339  	mockVM.TargetPowerState = newTargetPowerState
   340  	checkVirtualMachinesEqual(t, mockVM, updatedVM)
   341  
   342  	if err := mock.ExpectationsWereMet(); err != nil {
   343  		t.Errorf("there were unfulfilled expectations: %s", err)
   344  	}
   345  }
   346  
   347  func TestUpdateVirtualMachineWithDisk(t *testing.T) {
   348  	db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
   349  	if err != nil {
   350  		t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
   351  	}
   352  	defer db.Close()
   353  
   354  	mockVM := virtualMachines[0]
   355  	currentDisk := mockVM.Disks[0]
   356  	mock.ExpectBegin()
   357  	mockDBGetVirtualMachineByID(mock, mockVM.VirtualMachineID, &mockVM) // get mock VirtualMachine to update
   358  	mockDBVirtualMachineUpdate(mock, mockVM.VirtualMachineID, model.VirtualMachineUpdateInput{TargetPowerState: &mockVM.TargetPowerState, Cpus: &mockVM.Cpus, Memory: &mockVM.Memory, MachineType: &mockVM.MachineType}, sqlmock.NewResult(1, 1))
   359  	newDiskType := model.DiskTypeDisk
   360  	updateDisk := model.VirtualMachineDiskUpdateInput{
   361  		Type:              &newDiskType,
   362  		Bus:               &currentDisk.Bus,
   363  		BootOrder:         &currentDisk.BootOrder,
   364  		Size:              &currentDisk.Size,
   365  		ContainerImageURL: &currentDisk.ContainerImageURL,
   366  	}
   367  	mockDBGetVirtualMachineDiskByID(mock, currentDisk.DiskID, currentDisk)
   368  	mockDBUpdateVirtualMachineDisk(mock, currentDisk.DiskID, updateDisk, sqlmock.NewResult(1, 1))
   369  	mockDBGetVirtualMachineDisks(mock, []*model.VirtualMachineDisk{
   370  		{
   371  			DiskID:            currentDisk.DiskID,
   372  			VirtualMachineID:  currentDisk.DiskID,
   373  			Type:              newDiskType,
   374  			Bus:               currentDisk.Bus,
   375  			BootOrder:         currentDisk.BootOrder,
   376  			Size:              currentDisk.Size,
   377  			ContainerImageURL: currentDisk.ContainerImageURL,
   378  		},
   379  		mockVM.Disks[1],
   380  	})
   381  	mock.ExpectCommit()
   382  
   383  	service := NewVirtualMachineService(db)
   384  
   385  	updateVMValues := model.VirtualMachineUpdateInput{
   386  		TargetPowerState: &mockVM.TargetPowerState,
   387  		Cpus:             &mockVM.Cpus,
   388  		Memory:           &mockVM.Memory,
   389  		MachineType:      &mockVM.MachineType,
   390  		Disks: []*model.VirtualMachineDiskIDInput{
   391  			{
   392  				DiskID:                   currentDisk.DiskID,
   393  				VirtualMachineDiskValues: &updateDisk,
   394  			},
   395  		},
   396  	}
   397  	updateVM := model.VirtualMachineIDInput{
   398  		VirtualMachineID:     mockVM.VirtualMachineID,
   399  		VirtualMachineValues: &updateVMValues,
   400  	}
   401  
   402  	updatedVM, err := service.UpdateVirtualMachineEntry(context.Background(), &updateVM)
   403  	assert.NoError(t, err)
   404  	assert.NotNil(t, updatedVM.Disks[0])
   405  	assert.Equal(t, currentDisk.DiskID, updatedVM.Disks[0].DiskID)
   406  	assert.Equal(t, newDiskType, updatedVM.Disks[0].Type)
   407  
   408  	if err := mock.ExpectationsWereMet(); err != nil {
   409  		t.Errorf("there were unfulfilled expectations: %s", err)
   410  	}
   411  }
   412  
   413  func mockDBGetAllVirtualMachineHostnamesForAClusterNamespace(mock sqlmock.Sqlmock, clusterNamespaceEdgeID string, hostnames []string) {
   414  	rows := mock.NewRows([]string{"hostname"})
   415  
   416  	if len(hostnames) != 0 {
   417  		for _, hostname := range hostnames {
   418  			rows.AddRow(hostname)
   419  		}
   420  	}
   421  
   422  	mock.ExpectQuery(sqlquery.GetVirtualMachineHostnamesForAClusterNamespaceQuery).
   423  		WithArgs(clusterNamespaceEdgeID).
   424  		WillReturnRows(rows)
   425  }
   426  
   427  func mockDBClusterNamespaceCreate(mock sqlmock.Sqlmock, namespaceEdgeID string, clusterEdgeID string, result driver.Result) {
   428  	input := []driver.Value{
   429  		namespaceEdgeID,
   430  		clusterEdgeID,
   431  	}
   432  
   433  	mock.ExpectExec(sqlquery.ClusterNamespaceCreateQuery).
   434  		WithArgs(input...).
   435  		WillReturnResult(result)
   436  }
   437  
   438  func mockDBGetClusterNamespaceEdgeID(mock sqlmock.Sqlmock, namespaceEdgeID string, clusterEdgeID string, clusterNamespaceEdgeID string) {
   439  	rows := mock.NewRows([]string{"cluster_namespace_edge_id"})
   440  	rows.AddRow(clusterNamespaceEdgeID)
   441  
   442  	input := []driver.Value{
   443  		namespaceEdgeID,
   444  		clusterEdgeID,
   445  	}
   446  	mock.ExpectQuery(sqlquery.GetClusterNamespaceEdgeIDQuery).
   447  		WithArgs(input...).
   448  		WillReturnRows(rows)
   449  }
   450  
   451  func mockDBVirtualMachineCreate(mock sqlmock.Sqlmock, mockVM model.VirtualMachine, clusterNamespaceEdgeID string, result driver.Result) {
   452  	input := []driver.Value{
   453  		sqlmock.AnyArg(),
   454  		clusterNamespaceEdgeID,
   455  		mockVM.Hostname,
   456  		mockVM.TargetPowerState,
   457  		mockVM.Cpus,
   458  		mockVM.Memory,
   459  		mockVM.MachineType,
   460  	}
   461  
   462  	mock.ExpectExec(sqlquery.VirtualMachineCreateQuery).
   463  		WithArgs(input...).
   464  		WillReturnResult(result)
   465  }
   466  
   467  func mockDBVirtualMachineDelete(mock sqlmock.Sqlmock, virtualMachineID string, result driver.Result) {
   468  	mock.ExpectExec(sqlquery.VirtualMachineDeleteQuery).
   469  		WithArgs(virtualMachineID).
   470  		WillReturnResult(result)
   471  }
   472  
   473  func mockDBGetVirtualMachineByID(mock sqlmock.Sqlmock, virtualMachineID string, returnVM *model.VirtualMachine) {
   474  	rows := mock.NewRows(virtualMachineColumns)
   475  
   476  	if returnVM != nil {
   477  		rows.AddRow(returnVM.VirtualMachineID, returnVM.Namespace, returnVM.ClusterEdgeID, returnVM.ClusterName, returnVM.Hostname, returnVM.TargetPowerState, returnVM.Cpus, returnVM.Memory, returnVM.MachineType)
   478  	}
   479  
   480  	mock.ExpectQuery(sqlquery.GetVirtualMachineByIDQuery).
   481  		WithArgs(virtualMachineID).
   482  		WillReturnRows(rows)
   483  }
   484  
   485  func mockDBGetVirtualMachinesByClusterEdgeID(mock sqlmock.Sqlmock, clusterEdgeID string, returnVMs []model.VirtualMachine) {
   486  	rows := mock.NewRows(virtualMachineColumns)
   487  
   488  	if len(returnVMs) != 0 {
   489  		for _, returnVM := range returnVMs {
   490  			rows.AddRow(returnVM.VirtualMachineID, returnVM.Namespace, returnVM.ClusterEdgeID, returnVM.ClusterName, returnVM.Hostname, returnVM.TargetPowerState, returnVM.Cpus, returnVM.Memory, returnVM.MachineType)
   491  		}
   492  	}
   493  
   494  	mock.ExpectQuery(sqlquery.GetVirtualMachinesByClusterEdgeIDQuery).
   495  		WithArgs(clusterEdgeID).
   496  		WillReturnRows(rows)
   497  }
   498  
   499  func mockDBGetVirtualMachinesByHostname(mock sqlmock.Sqlmock, hostname string, returnVMs []model.VirtualMachine) {
   500  	rows := mock.NewRows(virtualMachineColumns)
   501  
   502  	if len(returnVMs) != 0 {
   503  		for _, returnVM := range returnVMs {
   504  			rows.AddRow(returnVM.VirtualMachineID, returnVM.Namespace, returnVM.ClusterEdgeID, returnVM.ClusterName, returnVM.Hostname, returnVM.TargetPowerState, returnVM.Cpus, returnVM.Memory, returnVM.MachineType)
   505  		}
   506  	}
   507  
   508  	mock.ExpectQuery(sqlquery.GetVirtualMachinesByHostnameQuery).
   509  		WithArgs(hostname).
   510  		WillReturnRows(rows)
   511  }
   512  
   513  func mockDBGetVirtualMachinesByClusterEdgeIDAndHostname(mock sqlmock.Sqlmock, clusterEdgeID string, hostname string, returnVMs []model.VirtualMachine) {
   514  	rows := mock.NewRows(virtualMachineColumns)
   515  
   516  	if len(returnVMs) != 0 {
   517  		for _, returnVM := range returnVMs {
   518  			rows.AddRow(returnVM.VirtualMachineID, returnVM.Namespace, returnVM.ClusterEdgeID, returnVM.ClusterName, returnVM.Hostname, returnVM.TargetPowerState, returnVM.Cpus, returnVM.Memory, returnVM.MachineType)
   519  		}
   520  	}
   521  
   522  	mock.ExpectQuery(sqlquery.GetVirtualMachinesByClusterEdgeIDAndHostnameQuery).
   523  		WithArgs(clusterEdgeID, hostname).
   524  		WillReturnRows(rows)
   525  }
   526  
   527  func mockDBGetAllVirtualMachines(mock sqlmock.Sqlmock, returnVMs []model.VirtualMachine) {
   528  	rows := mock.NewRows(virtualMachineColumns)
   529  
   530  	if len(returnVMs) != 0 {
   531  		for _, returnVM := range returnVMs {
   532  			rows.AddRow(returnVM.VirtualMachineID, returnVM.Namespace, returnVM.ClusterEdgeID, returnVM.ClusterName, returnVM.Hostname, returnVM.TargetPowerState, returnVM.Cpus, returnVM.Memory, returnVM.MachineType)
   533  		}
   534  	}
   535  
   536  	mock.ExpectQuery(sqlquery.GetAllVirtualMachinesQuery).
   537  		WillReturnRows(rows)
   538  }
   539  
   540  func mockDBVirtualMachineUpdate(mock sqlmock.Sqlmock, virtualMachineID string, updateVM model.VirtualMachineUpdateInput, result driver.Result) {
   541  	update := []driver.Value{
   542  		updateVM.TargetPowerState,
   543  		updateVM.Cpus,
   544  		updateVM.Memory,
   545  		updateVM.MachineType,
   546  		virtualMachineID,
   547  	}
   548  	mock.ExpectExec(sqlquery.VirtualMachineUpdateQuery).
   549  		WithArgs(update...).
   550  		WillReturnResult(result)
   551  }
   552  
   553  // helper for successfully creating a mock vm
   554  func genericTestCreateVirtualMachine(t *testing.T, mockVM model.VirtualMachine, virtualMachineHostname string) (error, error) {
   555  	db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
   556  	if err != nil {
   557  		t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
   558  	}
   559  	defer db.Close()
   560  
   561  	createVM := getVirtualMachineCreateInput(mockVM)
   562  
   563  	mock.ExpectBegin()
   564  	mock.ExpectQuery(sqlquery.GetClusterNameByClusterEdgeIDQuery).
   565  		WithArgs(mockVM.ClusterEdgeID).
   566  		WillReturnRows(sqlmock.NewRows([]string{"cluster_name"}).
   567  			AddRow(mockVM.ClusterName))
   568  	mock.ExpectQuery(sqlquery.GetNamespaceNameByNamespaceEdgeIDQuery).
   569  		WithArgs(virtualMachineNamespaceEdgeID).
   570  		WillReturnRows(sqlmock.NewRows([]string{"name"}).
   571  			AddRow(mockVM.Namespace))
   572  	namespaceEdgeID := virtualMachineNamespaceEdgeID
   573  	clusterNamespaceEdgeID := virtualMachineClusterNamespaceEdgeID
   574  	mockDBClusterNamespaceCreate(mock, namespaceEdgeID, mockVM.ClusterEdgeID, sqlmock.NewResult(1, 1))
   575  	mockDBGetClusterNamespaceEdgeID(mock, namespaceEdgeID, mockVM.ClusterEdgeID, clusterNamespaceEdgeID)
   576  	mockDBGetAllVirtualMachineHostnamesForAClusterNamespace(mock, virtualMachineClusterNamespaceEdgeID, []string{virtualMachineHostname}) // checking unique hostname
   577  	mockDBVirtualMachineCreate(mock, mockVM, virtualMachineClusterNamespaceEdgeID, sqlmock.NewResult(1, 1))
   578  	mockDBVirtualMachineDisksCreate(mock, createVM.Disks, sqlmock.NewResult(1, 1))
   579  	mock.ExpectCommit()
   580  
   581  	service := NewVirtualMachineService(db)
   582  
   583  	_, _, createErr := service.CreateVirtualMachineEntry(context.Background(), createVM)
   584  	mockErr := mock.ExpectationsWereMet()
   585  
   586  	return createErr, mockErr
   587  }
   588  
   589  func getVirtualMachineCreateInput(createVM model.VirtualMachine) *model.VirtualMachineCreateInput {
   590  	createDisks := []*model.VirtualMachineDiskCreateInput{}
   591  	for _, disk := range createVM.Disks {
   592  		createDisks = append(createDisks, getVirtualMachineDiskCreateInput(*disk))
   593  	}
   594  	namespaceEdgeID := virtualMachineNamespaceEdgeID
   595  	return &model.VirtualMachineCreateInput{
   596  		NamespaceEdgeID:  namespaceEdgeID,
   597  		ClusterEdgeID:    createVM.ClusterEdgeID,
   598  		Hostname:         createVM.Hostname,
   599  		TargetPowerState: &createVM.TargetPowerState,
   600  		Cpus:             &createVM.Cpus,
   601  		Memory:           &createVM.Memory,
   602  		MachineType:      &createVM.MachineType,
   603  		Disks:            createDisks,
   604  	}
   605  }
   606  
   607  func checkVirtualMachinesEqual(t *testing.T, mockVM model.VirtualMachine, returnVM *model.VirtualMachine) {
   608  	assert.Equal(t, mockVM.VirtualMachineID, returnVM.VirtualMachineID)
   609  	assert.Equal(t, mockVM.Namespace, returnVM.Namespace)
   610  	assert.Equal(t, mockVM.ClusterEdgeID, returnVM.ClusterEdgeID)
   611  	assert.Equal(t, mockVM.ClusterName, returnVM.ClusterName)
   612  	assert.Equal(t, mockVM.Hostname, returnVM.Hostname)
   613  	assert.Equal(t, mockVM.TargetPowerState, returnVM.TargetPowerState)
   614  	assert.Equal(t, mockVM.Cpus, returnVM.Cpus)
   615  	assert.Equal(t, mockVM.Memory, returnVM.Memory)
   616  	assert.Equal(t, mockVM.MachineType, returnVM.MachineType)
   617  }
   618  

View as plain text