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