Files
gocryptotrader/gctscript/vm/vm_test.go
Ryan O'Hara-Reid 8020e1ec6a linter: Enable error checking linter (#766)
* golangci: Enable err checking linter to expose unchecked errors.

* gct: handle errors across the board

* gct: handle errors NOTE: Found bug in FTX (WIP)

* linter: fix issues

* ftx/exchanges: fix bug where error was being returned when setting pair management variables to an already enabled state

* bitmex: fix bug where a dangly supported asset in config danglied up the place.

* linter: fix more linter issues

* linter: fix my terrible spelling.

* currency: fix test

* exchanges: fix tests

* logger: fix test

* exchanges: fix tests

* glorious: nits

* vm: revert rm variable and instigate test
2021-08-30 14:06:40 +10:00

593 lines
12 KiB
Go

package vm
import (
"errors"
"os"
"path/filepath"
"reflect"
"testing"
"time"
"github.com/gofrs/uuid"
"github.com/thrasher-corp/gocryptotrader/common/convert"
"github.com/thrasher-corp/gocryptotrader/log"
)
const (
maxTestVirtualMachines uint8 = 30
testVirtualMachineTimeout = time.Minute
scriptName = "1D01TH0RS3.gct"
)
var (
testScript = filepath.Join("..", "..", "testdata", "gctscript", "once.gct")
testInvalidScript = filepath.Join("..", "..", "testdata", "gctscript", "invalid.gct")
testBrokenScript = filepath.Join("..", "..", "testdata", "gctscript", "broken.gct")
testScriptRunner = filepath.Join("..", "..", "testdata", "gctscript", "timer.gct")
testScriptRunner1s = filepath.Join("..", "..", "testdata", "gctscript", "1s_timer.gct")
testScriptRunnerNegative = filepath.Join("..", "..", "testdata", "gctscript", "negative_timer.gct")
testScriptRunnerInvalid = filepath.Join("..", "..", "testdata", "gctscript", "invalid_timer.gct")
)
func TestMain(m *testing.M) {
c := log.GenDefaultSettings()
c.Enabled = convert.BoolPtr(false)
log.RWM.Lock()
log.GlobalLogConfig = &c
log.RWM.Unlock()
os.Exit(m.Run())
}
func TestNewVM(t *testing.T) {
manager := GctScriptManager{
config: configHelper(true, true, maxTestVirtualMachines),
}
x := manager.New()
if x != nil {
t.Error("Should not create a VM when manager not started")
}
manager.started = 1
x = manager.New()
xType := reflect.TypeOf(x).String()
if xType != "*vm.VM" {
t.Fatalf("vm.New should return pointer to VM instead received: %v", x)
}
}
func TestVMLoad(t *testing.T) {
manager := GctScriptManager{
config: configHelper(true, true, maxTestVirtualMachines),
started: 1,
}
testVM := manager.New()
err := testVM.Load(testScript)
if err != nil {
t.Fatal(err)
}
testScript = testScript[0 : len(testScript)-4]
testVM = manager.New()
err = testVM.Load(testScript)
if err != nil {
t.Fatal(err)
}
manager.config = configHelper(false, false, maxTestVirtualMachines)
err = testVM.Load(testScript)
if err != nil {
if !errors.Is(err, ErrScriptingDisabled) {
t.Fatal(err)
}
}
}
func TestVMLoad1s(t *testing.T) {
manager := GctScriptManager{
config: configHelper(true, true, maxTestVirtualMachines),
started: 1,
}
testVM := manager.New()
err := testVM.Load(testScriptRunner1s)
if err != nil {
t.Fatal(err)
}
testVM.CompileAndRun()
err = testVM.Shutdown()
if err != nil {
if !errors.Is(err, ErrNoVMLoaded) {
t.Fatal(err)
}
}
}
func TestVMLoadNegativeTimer(t *testing.T) {
manager := GctScriptManager{
config: configHelper(true, true, maxTestVirtualMachines),
started: 1,
}
testVM := manager.New()
err := testVM.Load(testScriptRunnerNegative)
if err != nil {
if !errors.Is(err, ErrNoVMLoaded) {
t.Fatal(err)
}
}
testVM.CompileAndRun()
err = testVM.Shutdown()
if err == nil {
t.Fatal("expect error on shutdown due to invalid VM")
}
}
func TestVMLoadNilVM(t *testing.T) {
manager := GctScriptManager{
config: configHelper(true, true, maxTestVirtualMachines),
started: 1,
}
testVM := manager.New()
err := testVM.Load(testScript)
if err != nil {
if !errors.Is(err, ErrNoVMLoaded) {
t.Fatal(err)
}
}
testVM = nil
err = testVM.Load(testScript)
if err != nil {
if !errors.Is(err, ErrNoVMLoaded) {
t.Fatal(err)
}
}
}
func TestCompileAndRunNilVM(t *testing.T) {
manager := GctScriptManager{
config: configHelper(true, true, maxTestVirtualMachines),
started: 1,
}
vmcount := VMSCount.Len()
testVM := manager.New()
err := testVM.Load(testScript)
if err != nil {
if !errors.Is(err, ErrNoVMLoaded) {
t.Fatal(err)
}
}
err = testVM.Load(testScript)
if err != nil {
if !errors.Is(err, ErrNoVMLoaded) {
t.Fatal(err)
}
}
testVM = nil
testVM.CompileAndRun()
err = testVM.Shutdown()
if err == nil {
t.Fatal("VM should not be running with invalid timer")
}
if VMSCount.Len() == vmcount-1 {
t.Fatal("expected VM count to decrease")
}
}
func TestVMLoadNoFile(t *testing.T) {
manager := GctScriptManager{
config: configHelper(true, true, maxTestVirtualMachines),
started: 1,
}
testVM := manager.New()
err := testVM.Load("missing file")
if err != nil {
if !errors.Is(err, os.ErrNotExist) {
t.Fatal(err)
}
}
}
func TestVMCompile(t *testing.T) {
manager := GctScriptManager{
config: configHelper(true, true, maxTestVirtualMachines),
started: 1,
}
testVM := manager.New()
err := testVM.Load(testScript)
if err != nil {
t.Fatal(err)
}
err = testVM.Compile()
if err != nil {
t.Fatal(err)
}
}
func TestVMRun(t *testing.T) {
manager := GctScriptManager{
config: configHelper(true, true, maxTestVirtualMachines),
started: 1,
}
testVM := manager.NewVM()
err := testVM.Load(testScript)
if err != nil {
t.Fatal(err)
}
err = testVM.Compile()
if err != nil {
t.Fatal(err)
}
err = testVM.Run()
if err != nil {
t.Fatal(err)
}
}
func TestVMRunTX(t *testing.T) {
manager := GctScriptManager{
config: configHelper(true, true, maxTestVirtualMachines),
started: 1,
}
testVM := manager.NewVM()
err := testVM.Load(testScript)
if err != nil {
t.Fatal(err)
}
err = testVM.Compile()
if err != nil {
t.Fatal(err)
}
err = testVM.RunCtx()
if err != nil {
t.Fatal(err)
}
}
func TestVMWithRunner(t *testing.T) {
manager := GctScriptManager{
config: configHelper(true, true, maxTestVirtualMachines),
started: 1,
}
vmCount := VMSCount.Len()
VM := manager.New()
if VM == nil {
t.Fatal("Failed to allocate new VM exiting")
}
err := VM.Load(testScriptRunner)
if err != nil {
t.Fatal(err)
}
if VMSCount.Len() == vmCount {
t.Fatal("expected VM count to increase")
}
VM.CompileAndRun()
err = VM.Shutdown()
if err != nil {
t.Fatal(err)
}
if VMSCount.Len() == vmCount-1 {
t.Fatal("expected VM count to decrease")
}
}
func TestVMWithRunnerOnce(t *testing.T) {
manager := GctScriptManager{
config: configHelper(true, true, maxTestVirtualMachines),
started: 1,
}
vmCount := VMSCount.Len()
VM := manager.New()
if VM == nil {
t.Fatal("Failed to allocate new VM exiting")
}
err := VM.Load(testScript)
if err != nil {
t.Fatal(err)
}
if VMSCount.Len() == vmCount {
t.Fatal("expected VM count to increase")
}
VM.CompileAndRun()
err = VM.Shutdown()
if err == nil {
t.Fatal("VM should not be running with invalid timer")
}
}
func TestVMWithRunnerNegativeTimer(t *testing.T) {
manager := GctScriptManager{
config: configHelper(true, true, maxTestVirtualMachines),
started: 1,
}
vmCount := VMSCount.Len()
VM := manager.New()
if VM == nil {
t.Fatal("Failed to allocate new VM exiting")
}
err := VM.Load(testScriptRunnerNegative)
if err != nil {
t.Fatal(err)
}
if VMSCount.Len() == vmCount {
t.Fatal("expected VM count to increase")
}
VM.CompileAndRun()
err = VM.Shutdown()
if err == nil {
t.Fatal("VM should not be running with invalid timer")
}
if VMSCount.Len() == vmCount-1 {
t.Fatal("expected VM count to decrease")
}
}
func TestVMWithRunnerInvalidTimer(t *testing.T) {
manager := GctScriptManager{
config: configHelper(true, true, maxTestVirtualMachines),
started: 1,
}
vmCount := VMSCount.Len()
VM := manager.New()
if VM == nil {
t.Fatal("Failed to allocate new VM exiting")
}
err := VM.Load(testScriptRunnerInvalid)
if err != nil {
t.Fatal(err)
}
if VMSCount.Len() == vmCount {
t.Fatal("expected VM count to increase")
}
VM.CompileAndRun()
err = VM.Shutdown()
if err == nil {
t.Fatal("VM should not be running with invalid timer")
}
if VMSCount.Len() == vmCount-1 {
t.Fatal("expected VM count to decrease")
}
}
func TestShutdownAll(t *testing.T) {
manager := GctScriptManager{
config: configHelper(true, true, maxTestVirtualMachines),
started: 1,
}
vmCount := VMSCount.Len()
VM := manager.New()
err := VM.Load(testScriptRunner)
if err != nil {
t.Fatal(err)
}
VM.CompileAndRun()
if VMSCount.Len() == vmCount {
t.Fatal("expected VM count to increase")
}
err = manager.ShutdownAll()
if err != nil {
t.Fatal(err)
}
if VMSCount.Len() == vmCount-1 {
t.Fatal("expected VM count to decrease")
}
}
func TestRead(t *testing.T) {
manager := GctScriptManager{
config: configHelper(true, true, maxTestVirtualMachines),
started: 1,
}
VM := manager.NewVM()
err := VM.Load(testScriptRunner)
if err != nil {
t.Fatal(err)
}
ScriptPath = filepath.Join("..", "..", "testdata", "gctscript")
data, err := VM.Read()
if err != nil {
t.Fatal(err)
}
if len(data) < 1 {
t.Fatal("expected data to be returned")
}
_ = VM.Shutdown()
}
func TestRemoveVM(t *testing.T) {
manager := GctScriptManager{
config: configHelper(true, true, maxTestVirtualMachines),
started: 1,
}
id, _ := uuid.FromString("6f20c907-64a0-48f2-848a-7837dee61672")
err := manager.RemoveVM(id)
if err != nil {
if err.Error() != "VM 6f20c907-64a0-48f2-848a-7837dee61672 not found" {
t.Fatal(err)
}
}
}
func TestError_Error(t *testing.T) {
x := Error{
Script: "noscript.gct",
Action: "test",
Cause: errors.New("HELLO ERROR"),
}
if x.Error() != "GCT Script: (ACTION) test (SCRIPT) noscript.gct HELLO ERROR" {
t.Fatal(x.Error())
}
}
func TestVM_CompileInvalid(t *testing.T) {
manager := GctScriptManager{
config: configHelper(true, true, maxTestVirtualMachines),
started: 1,
}
testVM := manager.New()
err := testVM.Load(testInvalidScript)
if err != nil {
t.Fatal(err)
}
err = testVM.Compile()
if err != nil {
t.Fatal(err)
}
err = testVM.Run()
if err == nil {
t.Fatal("unexpected result broken script compiled successfully ")
}
testVM = manager.New()
err = testVM.Load(testInvalidScript)
if err != nil {
t.Fatal(err)
}
err = testVM.Compile()
if err != nil {
t.Fatal(err)
}
err = testVM.RunCtx()
if err == nil {
t.Fatal("unexpected result broken script compiled successfully ")
}
testVM = manager.New()
err = testVM.Load(testInvalidScript)
if err != nil {
t.Fatal(err)
}
testVM.CompileAndRun()
err = testVM.Shutdown()
if err == nil {
t.Fatal("Shutdown() passed successfully but expected to fail with invalid script")
}
}
func TestVM_CompileBroken(t *testing.T) {
manager := GctScriptManager{
config: configHelper(true, true, maxTestVirtualMachines),
started: 1,
}
testVM := manager.New()
err := testVM.Load(testBrokenScript)
if err != nil {
t.Fatal(err)
}
err = testVM.Compile()
if err == nil {
t.Fatal("unexpected result broken script compiled successfully ")
}
}
func TestVM_CompileAndRunBroken(t *testing.T) {
manager := GctScriptManager{
config: configHelper(true, true, maxTestVirtualMachines),
started: 1,
}
testVM := manager.New()
err := testVM.Load(testBrokenScript)
if err != nil {
t.Fatal(err)
}
testVM.CompileAndRun()
err = testVM.Shutdown()
if err == nil {
t.Fatal("expect error on shutdown due to invalid VM")
}
}
func TestValidate(t *testing.T) {
manager := GctScriptManager{
config: configHelper(true, true, maxTestVirtualMachines),
started: 1,
}
err := manager.Validate(testBrokenScript)
if err == nil {
t.Fatal(err)
}
err = manager.Validate(testScript)
if err != nil {
t.Fatal(err)
}
}
func TestVMLimit(t *testing.T) {
manager := GctScriptManager{
config: configHelper(true, false, 0),
started: 1,
}
testVM := manager.New()
if testVM != nil {
t.Fatal("expected nil but received pointer to VM")
}
}
func TestAutoload(t *testing.T) {
manager := GctScriptManager{
config: &Config{
Enabled: true,
AutoLoad: []string{
scriptName,
},
Verbose: true,
},
}
ScriptPath = filepath.Join("..", "..", "testdata", "gctscript")
err := manager.Autoload(scriptName, true)
if err != nil {
t.Fatal(err)
}
err = manager.Autoload(scriptName, true)
if err == nil {
t.Fatal("expected err to be script not found received nil")
}
err = manager.Autoload("once", false)
if err != nil {
t.Fatal(err)
}
err = manager.Autoload(scriptName, false)
if err == nil {
t.Fatal("expected err to be script not found received nil")
}
}
func TestVMCount(t *testing.T) {
var c vmscount
c.add()
if c.Len() != 1 {
t.Fatalf("expect c len to be 1 instead received %v", c.Len())
}
c.remove()
if c.Len() != 0 {
t.Fatalf("expect c len to be 0 instead received %v", c.Len())
}
}
func configHelper(enabled, imports bool, max uint8) *Config {
return &Config{
Enabled: enabled,
AllowImports: imports,
ScriptTimeout: testVirtualMachineTimeout,
MaxVirtualMachines: max,
Verbose: true,
}
}