123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227 |
- package itest
- import (
- "flag"
- "fmt"
- "io"
- "math"
- "os"
- "path/filepath"
- "runtime"
- "strings"
- "testing"
- "time"
- "github.com/btcsuite/btcd/chaincfg"
- "github.com/btcsuite/btcd/integration/rpctest"
- "github.com/lightningnetwork/lnd/lnrpc"
- "github.com/lightningnetwork/lnd/lntest"
- "github.com/lightningnetwork/lnd/lntest/node"
- "github.com/lightningnetwork/lnd/lntest/port"
- "github.com/lightningnetwork/lnd/lntest/wait"
- "github.com/stretchr/testify/require"
- "google.golang.org/grpc/grpclog"
- )
- const (
- // defaultSplitTranches is the default number of tranches we split the
- // test cases into.
- defaultSplitTranches uint = 1
- // defaultRunTranche is the default index of the test cases tranche that
- // we run.
- defaultRunTranche uint = 0
- defaultTimeout = wait.DefaultTimeout
- itestLndBinary = "../lnd-itest"
- // TODO(yy): remove the following defined constants and put them in the
- // specific tests where they are used?
- testFeeBase = 1e+6
- anchorSize = 330
- defaultCSV = node.DefaultCSV
- noFeeLimitMsat = math.MaxInt64
- AddrTypeWitnessPubkeyHash = lnrpc.AddressType_WITNESS_PUBKEY_HASH
- AddrTypeNestedPubkeyHash = lnrpc.AddressType_NESTED_PUBKEY_HASH
- AddrTypeTaprootPubkey = lnrpc.AddressType_TAPROOT_PUBKEY
- )
- var (
- harnessNetParams = &chaincfg.RegressionNetParams
- // testCasesSplitParts is the number of tranches the test cases should
- // be split into. By default this is set to 1, so no splitting happens.
- // If this value is increased, then the -runtranche flag must be
- // specified as well to indicate which part should be run in the current
- // invocation.
- testCasesSplitTranches = flag.Uint(
- "splittranches", defaultSplitTranches, "split the test cases "+
- "in this many tranches and run the tranche at "+
- "0-based index specified by the -runtranche flag",
- )
- // testCasesRunTranche is the 0-based index of the split test cases
- // tranche to run in the current invocation.
- testCasesRunTranche = flag.Uint(
- "runtranche", defaultRunTranche, "run the tranche of the "+
- "split test cases with the given (0-based) index",
- )
- // dbBackendFlag specifies the backend to use.
- dbBackendFlag = flag.String("dbbackend", "bbolt", "Database backend "+
- "(bbolt, etcd, postgres)")
- nativeSQLFlag = flag.Bool("nativesql", false, "Database backend to "+
- "use native SQL when applicable (only for sqlite and postgres")
- // lndExecutable is the full path to the lnd binary.
- lndExecutable = flag.String(
- "lndexec", itestLndBinary, "full path to lnd binary",
- )
- )
- // TestLightningNetworkDaemon performs a series of integration tests amongst a
- // programmatically driven network of lnd nodes.
- func TestLightningNetworkDaemon(t *testing.T) {
- // If no tests are registered, then we can exit early.
- if len(allTestCases) == 0 {
- t.Skip("integration tests not selected with flag 'integration'")
- }
- // Get the test cases to be run in this tranche.
- testCases, trancheIndex, trancheOffset := getTestCaseSplitTranche()
- // Create a simple fee service.
- feeService := lntest.NewFeeService(t)
- // Get the binary path and setup the harness test.
- binary := getLndBinary(t)
- harnessTest := lntest.SetupHarness(
- t, binary, *dbBackendFlag, *nativeSQLFlag, feeService,
- )
- defer harnessTest.Stop()
- // Setup standby nodes, Alice and Bob, which will be alive and shared
- // among all the test cases.
- harnessTest.SetupStandbyNodes()
- // Run the subset of the test cases selected in this tranche.
- for idx, testCase := range testCases {
- testCase := testCase
- name := fmt.Sprintf("tranche%02d/%02d-of-%d/%s/%s",
- trancheIndex, trancheOffset+uint(idx)+1,
- len(allTestCases), harnessTest.ChainBackendName(),
- testCase.Name)
- success := t.Run(name, func(t1 *testing.T) {
- // Create a separate harness test for the testcase to
- // avoid overwriting the external harness test that is
- // tied to the parent test.
- ht := harnessTest.Subtest(t1)
- // TODO(yy): split log files.
- cleanTestCaseName := strings.ReplaceAll(
- testCase.Name, " ", "_",
- )
- ht.SetTestName(cleanTestCaseName)
- logLine := fmt.Sprintf(
- "STARTING ============ %v ============\n",
- testCase.Name,
- )
- ht.Alice.AddToLogf(logLine)
- ht.Bob.AddToLogf(logLine)
- ht.EnsureConnected(ht.Alice, ht.Bob)
- ht.RunTestCase(testCase)
- })
- // Stop at the first failure. Mimic behavior of original test
- // framework.
- if !success {
- // Log failure time to help relate the lnd logs to the
- // failure.
- t.Logf("Failure time: %v", time.Now().Format(
- "2006-01-02 15:04:05.000",
- ))
- break
- }
- }
- _, height := harnessTest.Miner.GetBestBlock()
- t.Logf("=========> tests finished for tranche: %v, tested %d "+
- "cases, end height: %d\n", trancheIndex, len(testCases), height)
- }
- // getTestCaseSplitTranche returns the sub slice of the test cases that should
- // be run as the current split tranche as well as the index and slice offset of
- // the tranche.
- func getTestCaseSplitTranche() ([]*lntest.TestCase, uint, uint) {
- numTranches := defaultSplitTranches
- if testCasesSplitTranches != nil {
- numTranches = *testCasesSplitTranches
- }
- runTranche := defaultRunTranche
- if testCasesRunTranche != nil {
- runTranche = *testCasesRunTranche
- }
- // There's a special flake-hunt mode where we run the same test multiple
- // times in parallel. In that case the tranche index is equal to the
- // thread ID, but we need to actually run all tests for the regex
- // selection to work.
- threadID := runTranche
- if numTranches == 1 {
- runTranche = 0
- }
- numCases := uint(len(allTestCases))
- testsPerTranche := numCases / numTranches
- trancheOffset := runTranche * testsPerTranche
- trancheEnd := trancheOffset + testsPerTranche
- if trancheEnd > numCases || runTranche == numTranches-1 {
- trancheEnd = numCases
- }
- return allTestCases[trancheOffset:trancheEnd], threadID,
- trancheOffset
- }
- func getLndBinary(t *testing.T) string {
- binary := itestLndBinary
- lndExec := ""
- if lndExecutable != nil && *lndExecutable != "" {
- lndExec = *lndExecutable
- }
- if lndExec == "" && runtime.GOOS == "windows" {
- // Windows (even in a bash like environment like git bash as on
- // Travis) doesn't seem to like relative paths to exe files...
- currentDir, err := os.Getwd()
- require.NoError(t, err, "unable to get working directory")
- targetPath := filepath.Join(currentDir, "../../lnd-itest.exe")
- binary, err = filepath.Abs(targetPath)
- require.NoError(t, err, "unable to get absolute path")
- } else if lndExec != "" {
- binary = lndExec
- }
- return binary
- }
- func init() {
- // Before we start any node, we need to make sure that any btcd node
- // that is started through the RPC harness uses a unique port as well
- // to avoid any port collisions.
- rpctest.ListenAddressGenerator =
- port.GenerateSystemUniqueListenerAddresses
- // Swap out grpc's default logger with our fake logger which drops the
- // statements on the floor.
- fakeLogger := grpclog.NewLoggerV2(io.Discard, io.Discard, io.Discard)
- grpclog.SetLoggerV2(fakeLogger)
- }
|