decred.org/dcrdex@v1.0.5/client/cmd/simnet-trade-tests/main.go (about)

     1  //go:build harness && !nolgpl
     2  
     3  package main
     4  
     5  import (
     6  	"errors"
     7  	"flag"
     8  	"fmt"
     9  	"os"
    10  
    11  	"decred.org/dcrdex/client/core"
    12  	"decred.org/dcrdex/dex"
    13  	dexeth "decred.org/dcrdex/dex/networks/eth"
    14  	dexpolygon "decred.org/dcrdex/dex/networks/polygon"
    15  	"github.com/fatih/color"
    16  )
    17  
    18  func parseWalletType(t string) (core.SimWalletType, error) {
    19  	switch t {
    20  	case "core":
    21  		return core.WTCoreClone, nil
    22  	case "spv":
    23  		return core.WTSPVNative, nil
    24  	case "electrum":
    25  		return core.WTElectrum, nil
    26  	default:
    27  		return 0, errors.New("invalid wallet type")
    28  	}
    29  }
    30  
    31  func main() {
    32  	if err := run(); err != nil {
    33  		fmt.Fprintf(os.Stderr, "ERROR: %v\n", err)
    34  		os.Exit(1)
    35  	}
    36  	fmt.Println("SUCCESS!")
    37  	os.Exit(0)
    38  }
    39  
    40  func run() error {
    41  	var baseSymbol, quoteSymbol, base1Node, quote1Node, base2Node, quote2Node, regAsset, logColor string
    42  	var base1SPV, quote1SPV, base2SPV, quote2SPV, debug, trace, list, all, runOnce bool
    43  	var base1Type, quote1Type, base2Type, quote2Type string
    44  	var tests, except flagArray
    45  	flag.Var(&tests, "t", "the test(s) to run. multiple --t flags OK")
    46  	flag.StringVar(&baseSymbol, "base", "dcr", "the bot program to run")
    47  	flag.StringVar(&quoteSymbol, "quote", "btc", "the bot program to run")
    48  	flag.StringVar(&base1Node, "base1node", "beta", "the harness node to connect to for the first client's base asset. only RPC wallets")
    49  	flag.StringVar(&quote1Node, "quote1node", "beta", "the harness node to connect to for the first client's quote asset. only RPC wallets")
    50  	flag.StringVar(&base2Node, "base2node", "gamma", "the harness node to connect to for the second client's base asset. only RPC wallets")
    51  	flag.StringVar(&quote2Node, "quote2node", "gamma", "the harness node to connect to for the second client's quote asset. only RPC wallets")
    52  	flag.StringVar(&regAsset, "regasset", "", "the asset to use for registration. default is base asset")
    53  	flag.StringVar(&base1Type, "base1type", "core", "the wallet type for the first client's base asset (core, spv, electrum). ignored for eth")
    54  	flag.StringVar(&quote1Type, "quote1type", "core", "the wallet type for the first client's quote asset (core, spv, electrum). ignored for eth")
    55  	flag.StringVar(&base2Type, "base2type", "core", "the wallet type for the second client's base asset (core, spv, electrum). ignored for eth")
    56  	flag.StringVar(&quote2Type, "quote2type", "core", "the wallet type for the second client's quote asset (core, spv, electrum). ignored for eth")
    57  	flag.StringVar(&logColor, "color", "green", "the color to show test progress logs with. white, black, blue, yellow, magenta, green, or red")
    58  	flag.BoolVar(&base1SPV, "base1spv", false, "use native SPV wallet for the first client's base asset (removed: use base1type)")
    59  	flag.BoolVar(&quote1SPV, "quote1spv", false, "use native SPV wallet for the first client's quote asset (removed: use quote1type)")
    60  	flag.BoolVar(&base2SPV, "base2spv", false, "use native SPV wallet for the second client's base asset (removed: use base2type)")
    61  	flag.BoolVar(&quote2SPV, "quote2spv", false, "use native SPV wallet for the second client's quote asset (removed: use quote2type)")
    62  	flag.BoolVar(&list, "list", false, "list available tests")
    63  	flag.BoolVar(&debug, "debug", false, "log at logging level debug")
    64  	flag.BoolVar(&trace, "trace", false, "log at logging level trace")
    65  	flag.BoolVar(&all, "all", false, "run all tests for the asset")
    66  	flag.Var(&except, "except", "can only be used with the \"all\" flag and removes unwanted tests. multiple --except flags OK")
    67  	flag.BoolVar(&runOnce, "runonce", false, "some tests will run twice to swap maker/taker. Set to only run once. default is false")
    68  	flag.Parse()
    69  
    70  	if list {
    71  		for _, s := range core.SimTests() {
    72  			fmt.Println(s)
    73  		}
    74  		return nil
    75  	}
    76  
    77  	if base1SPV {
    78  		return errors.New("base1spv is removed - use base1type=spv instead")
    79  	}
    80  	if quote1SPV {
    81  		return errors.New("quote1spv is removed - use quote1type=spv instead")
    82  	}
    83  	if base2SPV {
    84  		return errors.New("base2spv is removed - use base2type=spv instead")
    85  	}
    86  	if quote2SPV {
    87  		return errors.New("quote2spv is removed - use quote2type=spv instead")
    88  	}
    89  
    90  	logLevel := dex.LevelInfo
    91  	switch {
    92  	case trace:
    93  		logLevel = dex.LevelTrace
    94  	case debug:
    95  		logLevel = dex.LevelDebug
    96  	}
    97  
    98  	// Assume any trailing arguments are test names.
    99  	tests = append(tests, flag.Args()...)
   100  
   101  	// Check that all test names are valid.
   102  	allTests := core.SimTests()
   103  	var containsAll bool
   104  	if len(tests) == 0 {
   105  		tests = []string{"success"}
   106  	} else {
   107  		for _, t := range tests {
   108  			if t == "all" {
   109  				containsAll = true
   110  				break
   111  			}
   112  			var found bool
   113  			for _, at := range allTests {
   114  				if at == t {
   115  					found = true
   116  					break
   117  				}
   118  			}
   119  			if !found {
   120  				return fmt.Errorf("test %s is unknown. Possible tests are %s", t, allTests)
   121  			}
   122  		}
   123  	}
   124  
   125  	if regAsset == "" {
   126  		regAsset = baseSymbol
   127  	}
   128  
   129  	b1wt, err := parseWalletType(base1Type)
   130  	if err != nil {
   131  		return fmt.Errorf("invalid base1 wallet type %q", base1Type)
   132  	}
   133  	q1wt, err := parseWalletType(quote1Type)
   134  	if err != nil {
   135  		return fmt.Errorf("invalid quote1 wallet type %q", quote1Type)
   136  	}
   137  	b2wt, err := parseWalletType(base2Type)
   138  	if err != nil {
   139  		return fmt.Errorf("invalid base2 wallet type %q", base2Type)
   140  	}
   141  	q2wt, err := parseWalletType(quote2Type)
   142  	if err != nil {
   143  		return fmt.Errorf("invalid quote2 wallet type %q", quote2Type)
   144  	}
   145  
   146  	if all || containsAll {
   147  		tests = allTests
   148  		if len(except) > 0 {
   149  			for i := len(tests) - 1; i >= 0; i-- {
   150  				for _, ex := range except {
   151  					if tests[i] == ex {
   152  						tests = append(tests[:i], tests[i+1:]...)
   153  						break
   154  					}
   155  				}
   156  			}
   157  		}
   158  	}
   159  
   160  	var fgColor color.Attribute
   161  	switch logColor {
   162  	case "magenta":
   163  		fgColor = color.FgMagenta
   164  	case "white":
   165  		fgColor = color.FgWhite
   166  	case "black":
   167  		fgColor = color.FgBlack
   168  	case "blue":
   169  		fgColor = color.FgBlue
   170  	case "yellow":
   171  		fgColor = color.FgYellow
   172  	case "green":
   173  		fgColor = color.FgGreen
   174  	case "red":
   175  		fgColor = color.FgRed
   176  	default:
   177  		return fmt.Errorf("unknown color %s", logColor)
   178  	}
   179  
   180  	pl := prettyLogger{c: color.New(fgColor)}
   181  
   182  	return core.RunSimulationTest(&core.SimulationConfig{
   183  		BaseSymbol:        baseSymbol,
   184  		QuoteSymbol:       quoteSymbol,
   185  		RegistrationAsset: regAsset,
   186  		Client1: &core.SimClient{
   187  			BaseWalletType:  b1wt,
   188  			QuoteWalletType: q1wt,
   189  			BaseNode:        base1Node,
   190  			QuoteNode:       quote1Node,
   191  		},
   192  		Client2: &core.SimClient{
   193  			BaseWalletType:  b2wt,
   194  			QuoteWalletType: q2wt,
   195  			BaseNode:        base2Node,
   196  			QuoteNode:       quote2Node,
   197  		},
   198  		Tests:   tests,
   199  		Logger:  dex.NewLogger("T", logLevel, pl),
   200  		RunOnce: runOnce,
   201  	})
   202  }
   203  
   204  type prettyLogger struct {
   205  	c *color.Color
   206  }
   207  
   208  func (cl prettyLogger) Write(p []byte) (n int, err error) {
   209  	return cl.c.Fprint(os.Stdout, string(p))
   210  }
   211  
   212  type flagArray []string
   213  
   214  func (f *flagArray) String() string {
   215  	return "my string representation"
   216  }
   217  
   218  func (f *flagArray) Set(value string) error {
   219  	*f = append(*f, value)
   220  	return nil
   221  }
   222  
   223  func init() {
   224  	dexeth.MaybeReadSimnetAddrs()
   225  	dexpolygon.MaybeReadSimnetAddrs()
   226  }