github.com/ava-labs/avalanchego@v1.11.11/vms/registry/vm_getter_test.go (about)

     1  // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved.
     2  // See the file LICENSE for licensing terms.
     3  
     4  package registry
     5  
     6  import (
     7  	"errors"
     8  	"io/fs"
     9  	"testing"
    10  	"time"
    11  
    12  	"github.com/prometheus/client_golang/prometheus"
    13  	"github.com/stretchr/testify/require"
    14  	"go.uber.org/mock/gomock"
    15  
    16  	"github.com/ava-labs/avalanchego/ids"
    17  	"github.com/ava-labs/avalanchego/utils/filesystem"
    18  	"github.com/ava-labs/avalanchego/utils/filesystem/filesystemmock"
    19  	"github.com/ava-labs/avalanchego/utils/logging"
    20  	"github.com/ava-labs/avalanchego/utils/resource"
    21  	"github.com/ava-labs/avalanchego/vms"
    22  	"github.com/ava-labs/avalanchego/vms/vmsmock"
    23  )
    24  
    25  var (
    26  	pluginDir = "plugin getter"
    27  
    28  	// errors
    29  	errTest = errors.New("non-nil error")
    30  
    31  	// vm names
    32  	registeredVMName   = "mgj786NP7uDwBCcq6YwThhaN8FLyybkCa4zBWTQbNgmK6k9A6"
    33  	unregisteredVMName = "tGas3T58KzdjLHhBDMnH2TvrddhqTji5iZAMZ3RXs2NLpSnhH"
    34  
    35  	// files
    36  	directory = filesystem.MockFile{
    37  		MockName:  "directory-1",
    38  		MockIsDir: true,
    39  	}
    40  	registeredVM = filesystem.MockFile{
    41  		MockName: registeredVMName + ".abc",
    42  	}
    43  	unregisteredVM = filesystem.MockFile{
    44  		MockName: unregisteredVMName + ".xyz",
    45  	}
    46  	invalidVM = filesystem.MockFile{
    47  		MockName: "invalid-vm.file",
    48  	}
    49  
    50  	// read dir results
    51  	oneValidVM = []fs.DirEntry{
    52  		directory,
    53  		registeredVM,
    54  	}
    55  	twoValidVMs = []fs.DirEntry{
    56  		directory,
    57  		registeredVM,
    58  		unregisteredVM,
    59  	}
    60  	invalidVMs = []fs.DirEntry{
    61  		directory,
    62  		invalidVM,
    63  	}
    64  )
    65  
    66  // Get should fail if we hit an io issue when reading files on the disk
    67  func TestGet_ReadDirFails(t *testing.T) {
    68  	resources := initVMGetterTest(t)
    69  
    70  	// disk read fails
    71  	resources.mockReader.EXPECT().ReadDir(pluginDir).Times(1).Return(nil, errTest)
    72  
    73  	_, _, err := resources.getter.Get()
    74  	require.ErrorIs(t, err, errTest)
    75  }
    76  
    77  // Get should fail if we see an invalid VM id
    78  func TestGet_InvalidVMName(t *testing.T) {
    79  	resources := initVMGetterTest(t)
    80  
    81  	resources.mockReader.EXPECT().ReadDir(pluginDir).Times(1).Return(invalidVMs, nil)
    82  	// didn't find an alias, so we'll try using this invalid vm name
    83  	resources.mockManager.EXPECT().Lookup("invalid-vm").Times(1).Return(ids.Empty, errTest)
    84  
    85  	_, _, err := resources.getter.Get()
    86  	require.ErrorIs(t, err, errInvalidVMID)
    87  }
    88  
    89  // Get should fail if we can't get the VM factory
    90  func TestGet_GetFactoryFails(t *testing.T) {
    91  	resources := initVMGetterTest(t)
    92  
    93  	vm, _ := ids.FromString("vmId")
    94  
    95  	resources.mockReader.EXPECT().ReadDir(pluginDir).Times(1).Return(oneValidVM, nil)
    96  	resources.mockManager.EXPECT().Lookup(registeredVMName).Times(1).Return(vm, nil)
    97  	// Getting the factory fails
    98  	resources.mockManager.EXPECT().GetFactory(vm).Times(1).Return(nil, errTest)
    99  
   100  	_, _, err := resources.getter.Get()
   101  	require.ErrorIs(t, err, errTest)
   102  }
   103  
   104  // Get should return the correct registered and unregistered VMs.
   105  func TestGet_Success(t *testing.T) {
   106  	require := require.New(t)
   107  
   108  	resources := initVMGetterTest(t)
   109  
   110  	registeredVMId := ids.GenerateTestID()
   111  	unregisteredVMId := ids.GenerateTestID()
   112  
   113  	registeredVMFactory := vmsmock.NewFactory(resources.ctrl)
   114  
   115  	resources.mockReader.EXPECT().ReadDir(pluginDir).Times(1).Return(twoValidVMs, nil)
   116  	resources.mockManager.EXPECT().Lookup(registeredVMName).Times(1).Return(registeredVMId, nil)
   117  	resources.mockManager.EXPECT().GetFactory(registeredVMId).Times(1).Return(registeredVMFactory, nil)
   118  	resources.mockManager.EXPECT().Lookup(unregisteredVMName).Times(1).Return(unregisteredVMId, nil)
   119  	resources.mockManager.EXPECT().GetFactory(unregisteredVMId).Times(1).Return(nil, vms.ErrNotFound)
   120  
   121  	registeredVMs, unregisteredVMs, err := resources.getter.Get()
   122  
   123  	// we should have one registered vm, and one unregistered vm.
   124  	require.Len(registeredVMs, 1)
   125  	require.NotNil(registeredVMs[registeredVMId])
   126  
   127  	require.Len(unregisteredVMs, 1)
   128  	require.NotNil(unregisteredVMs[unregisteredVMId])
   129  
   130  	require.NoError(err)
   131  }
   132  
   133  type vmGetterTestResources struct {
   134  	ctrl        *gomock.Controller
   135  	mockReader  *filesystemmock.Reader
   136  	mockManager *vmsmock.Manager
   137  	getter      VMGetter
   138  }
   139  
   140  func initVMGetterTest(t *testing.T) *vmGetterTestResources {
   141  	ctrl := gomock.NewController(t)
   142  
   143  	mockReader := filesystemmock.NewReader(ctrl)
   144  	mockManager := vmsmock.NewManager(ctrl)
   145  	mockRegistry := prometheus.NewRegistry()
   146  	mockCPUTracker, err := resource.NewManager(
   147  		logging.NoLog{},
   148  		"",
   149  		time.Hour,
   150  		time.Hour,
   151  		time.Hour,
   152  		mockRegistry,
   153  	)
   154  	require.NoError(t, err)
   155  
   156  	getter := NewVMGetter(
   157  		VMGetterConfig{
   158  			FileReader:      mockReader,
   159  			Manager:         mockManager,
   160  			PluginDirectory: pluginDir,
   161  			CPUTracker:      mockCPUTracker,
   162  		},
   163  	)
   164  
   165  	return &vmGetterTestResources{
   166  		ctrl:        ctrl,
   167  		mockReader:  mockReader,
   168  		mockManager: mockManager,
   169  		getter:      getter,
   170  	}
   171  }