mirror of
https://github.com/luxfi/vm.git
synced 2026-10-30 15:13:40 +00:00
359 lines
8.6 KiB
Go
359 lines
8.6 KiB
Go
// Copyright (C) 2019-2025, Lux Industries, Inc. All rights reserved.
|
|
// See the file LICENSE for licensing terms.
|
|
|
|
package admin
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/luxfi/ids"
|
|
"github.com/luxfi/log/level"
|
|
"github.com/luxfi/rpc"
|
|
"github.com/luxfi/vm/api"
|
|
)
|
|
|
|
var (
|
|
errTest = errors.New("non-nil error")
|
|
|
|
SuccessResponseTests = []struct {
|
|
name string
|
|
expectedErr error
|
|
}{
|
|
{
|
|
name: "no error",
|
|
expectedErr: nil,
|
|
},
|
|
{
|
|
name: "error",
|
|
expectedErr: errTest,
|
|
},
|
|
}
|
|
)
|
|
|
|
type mockClient struct {
|
|
response interface{}
|
|
err error
|
|
}
|
|
|
|
// NewMockClient returns a mock client for testing
|
|
func NewMockClient(response interface{}, err error) rpc.EndpointRequester {
|
|
return &mockClient{
|
|
response: response,
|
|
err: err,
|
|
}
|
|
}
|
|
|
|
func (mc *mockClient) SendRequest(_ context.Context, _ string, _ interface{}, reply interface{}, _ ...rpc.Option) error {
|
|
if mc.err != nil {
|
|
return mc.err
|
|
}
|
|
|
|
switch p := reply.(type) {
|
|
case *api.EmptyReply:
|
|
response := mc.response.(*api.EmptyReply)
|
|
*p = *response
|
|
case *GetChainAliasesReply:
|
|
response := mc.response.(*GetChainAliasesReply)
|
|
*p = *response
|
|
case *LoadVMsReply:
|
|
response := mc.response.(*LoadVMsReply)
|
|
*p = *response
|
|
case *LoggerLevelReply:
|
|
response := mc.response.(*LoggerLevelReply)
|
|
*p = *response
|
|
case *interface{}:
|
|
response := mc.response.(*interface{})
|
|
*p = *response
|
|
default:
|
|
panic("illegal type")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func TestStartCPUProfiler(t *testing.T) {
|
|
for _, test := range SuccessResponseTests {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
mockClient := Client{Requester: NewMockClient(&api.EmptyReply{}, test.expectedErr)}
|
|
err := mockClient.StartCPUProfiler(context.Background())
|
|
require.ErrorIs(t, err, test.expectedErr)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestStopCPUProfiler(t *testing.T) {
|
|
for _, test := range SuccessResponseTests {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
mockClient := Client{Requester: NewMockClient(&api.EmptyReply{}, test.expectedErr)}
|
|
err := mockClient.StopCPUProfiler(context.Background())
|
|
require.ErrorIs(t, err, test.expectedErr)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestMemoryProfile(t *testing.T) {
|
|
for _, test := range SuccessResponseTests {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
mockClient := Client{Requester: NewMockClient(&api.EmptyReply{}, test.expectedErr)}
|
|
err := mockClient.MemoryProfile(context.Background())
|
|
require.ErrorIs(t, err, test.expectedErr)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestLockProfile(t *testing.T) {
|
|
for _, test := range SuccessResponseTests {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
mockClient := Client{Requester: NewMockClient(&api.EmptyReply{}, test.expectedErr)}
|
|
err := mockClient.LockProfile(context.Background())
|
|
require.ErrorIs(t, err, test.expectedErr)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestAlias(t *testing.T) {
|
|
for _, test := range SuccessResponseTests {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
mockClient := Client{Requester: NewMockClient(&api.EmptyReply{}, test.expectedErr)}
|
|
err := mockClient.Alias(context.Background(), "alias", "alias2")
|
|
require.ErrorIs(t, err, test.expectedErr)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestAliasChain(t *testing.T) {
|
|
for _, test := range SuccessResponseTests {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
mockClient := Client{Requester: NewMockClient(&api.EmptyReply{}, test.expectedErr)}
|
|
err := mockClient.AliasChain(context.Background(), "chain", "chain-alias")
|
|
require.ErrorIs(t, err, test.expectedErr)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGetChainAliases(t *testing.T) {
|
|
t.Run("successful", func(t *testing.T) {
|
|
require := require.New(t)
|
|
|
|
expectedReply := []string{"alias1", "alias2"}
|
|
mockClient := Client{Requester: NewMockClient(&GetChainAliasesReply{
|
|
Aliases: expectedReply,
|
|
}, nil)}
|
|
|
|
reply, err := mockClient.GetChainAliases(context.Background(), "chain")
|
|
require.NoError(err)
|
|
require.Equal(expectedReply, reply)
|
|
})
|
|
|
|
t.Run("failure", func(t *testing.T) {
|
|
mockClient := Client{Requester: NewMockClient(&GetChainAliasesReply{}, errTest)}
|
|
_, err := mockClient.GetChainAliases(context.Background(), "chain")
|
|
require.ErrorIs(t, err, errTest)
|
|
})
|
|
}
|
|
|
|
func TestStacktrace(t *testing.T) {
|
|
for _, test := range SuccessResponseTests {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
mockClient := Client{Requester: NewMockClient(&api.EmptyReply{}, test.expectedErr)}
|
|
err := mockClient.Stacktrace(context.Background())
|
|
require.ErrorIs(t, err, test.expectedErr)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestReloadInstalledVMs(t *testing.T) {
|
|
t.Run("successful", func(t *testing.T) {
|
|
require := require.New(t)
|
|
|
|
expectedNewVMs := map[ids.ID][]string{
|
|
ids.GenerateTestID(): {"foo"},
|
|
ids.GenerateTestID(): {"bar"},
|
|
}
|
|
expectedFailedVMs := map[ids.ID]string{
|
|
ids.GenerateTestID(): "oops",
|
|
ids.GenerateTestID(): "uh-oh",
|
|
}
|
|
mockClient := Client{Requester: NewMockClient(&LoadVMsReply{
|
|
NewVMs: expectedNewVMs,
|
|
FailedVMs: expectedFailedVMs,
|
|
}, nil)}
|
|
|
|
loadedVMs, failedVMs, err := mockClient.LoadVMs(context.Background())
|
|
require.NoError(err)
|
|
require.Equal(expectedNewVMs, loadedVMs)
|
|
require.Equal(expectedFailedVMs, failedVMs)
|
|
})
|
|
|
|
t.Run("failure", func(t *testing.T) {
|
|
mockClient := Client{Requester: NewMockClient(&LoadVMsReply{}, errTest)}
|
|
_, _, err := mockClient.LoadVMs(context.Background())
|
|
require.ErrorIs(t, err, errTest)
|
|
})
|
|
}
|
|
|
|
func TestSetLoggerLevel(t *testing.T) {
|
|
type test struct {
|
|
name string
|
|
logLevel string
|
|
displayLevel string
|
|
serviceResponse map[string]LogAndDisplayLevels
|
|
serviceErr error
|
|
clientErr error
|
|
}
|
|
tests := []test{
|
|
{
|
|
name: "Happy path",
|
|
logLevel: "INFO",
|
|
displayLevel: "INFO",
|
|
serviceResponse: map[string]LogAndDisplayLevels{
|
|
"Happy path": {LogLevel: level.Info, DisplayLevel: level.Info},
|
|
},
|
|
serviceErr: nil,
|
|
clientErr: nil,
|
|
},
|
|
{
|
|
name: "Service errors",
|
|
logLevel: "INFO",
|
|
displayLevel: "INFO",
|
|
serviceResponse: nil,
|
|
serviceErr: errTest,
|
|
clientErr: errTest,
|
|
},
|
|
{
|
|
name: "Invalid log level",
|
|
logLevel: "invalid",
|
|
displayLevel: "INFO",
|
|
serviceResponse: nil,
|
|
serviceErr: nil,
|
|
clientErr: level.ErrUnknownLevel,
|
|
},
|
|
{
|
|
name: "Invalid display level",
|
|
logLevel: "INFO",
|
|
displayLevel: "invalid",
|
|
serviceResponse: nil,
|
|
serviceErr: nil,
|
|
clientErr: level.ErrUnknownLevel,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
require := require.New(t)
|
|
|
|
c := Client{
|
|
Requester: NewMockClient(
|
|
&LoggerLevelReply{
|
|
LoggerLevels: tt.serviceResponse,
|
|
},
|
|
tt.serviceErr,
|
|
),
|
|
}
|
|
res, err := c.SetLoggerLevel(
|
|
context.Background(),
|
|
"",
|
|
tt.logLevel,
|
|
tt.displayLevel,
|
|
)
|
|
require.ErrorIs(err, tt.clientErr)
|
|
if tt.clientErr != nil {
|
|
return
|
|
}
|
|
require.Equal(tt.serviceResponse, res)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGetLoggerLevel(t *testing.T) {
|
|
type test struct {
|
|
name string
|
|
loggerName string
|
|
serviceResponse map[string]LogAndDisplayLevels
|
|
serviceErr error
|
|
clientErr error
|
|
}
|
|
tests := []test{
|
|
{
|
|
name: "Happy Path",
|
|
loggerName: "foo",
|
|
serviceResponse: map[string]LogAndDisplayLevels{
|
|
"foo": {LogLevel: level.Info, DisplayLevel: level.Info},
|
|
},
|
|
serviceErr: nil,
|
|
clientErr: nil,
|
|
},
|
|
{
|
|
name: "service errors",
|
|
loggerName: "foo",
|
|
serviceResponse: nil,
|
|
serviceErr: errTest,
|
|
clientErr: errTest,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
require := require.New(t)
|
|
|
|
c := Client{
|
|
Requester: NewMockClient(
|
|
&LoggerLevelReply{
|
|
LoggerLevels: tt.serviceResponse,
|
|
},
|
|
tt.serviceErr,
|
|
),
|
|
}
|
|
res, err := c.GetLoggerLevel(
|
|
context.Background(),
|
|
tt.loggerName,
|
|
)
|
|
require.ErrorIs(err, tt.clientErr)
|
|
if tt.clientErr != nil {
|
|
return
|
|
}
|
|
require.Equal(tt.serviceResponse, res)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGetConfig(t *testing.T) {
|
|
type test struct {
|
|
name string
|
|
serviceErr error
|
|
clientErr error
|
|
expectedResponse interface{}
|
|
}
|
|
var resp interface{} = "response"
|
|
tests := []test{
|
|
{
|
|
name: "Happy path",
|
|
serviceErr: nil,
|
|
clientErr: nil,
|
|
expectedResponse: &resp,
|
|
},
|
|
{
|
|
name: "service errors",
|
|
serviceErr: errTest,
|
|
clientErr: errTest,
|
|
expectedResponse: nil,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
require := require.New(t)
|
|
|
|
c := Client{
|
|
Requester: NewMockClient(tt.expectedResponse, tt.serviceErr),
|
|
}
|
|
res, err := c.GetConfig(context.Background())
|
|
require.ErrorIs(err, tt.clientErr)
|
|
if tt.clientErr != nil {
|
|
return
|
|
}
|
|
require.Equal(resp, res)
|
|
})
|
|
}
|
|
}
|