lnd_test.go 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. package itest
  2. import (
  3. "flag"
  4. "fmt"
  5. "io"
  6. "math"
  7. "os"
  8. "path/filepath"
  9. "runtime"
  10. "strings"
  11. "testing"
  12. "time"
  13. "github.com/btcsuite/btcd/chaincfg"
  14. "github.com/btcsuite/btcd/integration/rpctest"
  15. "github.com/lightningnetwork/lnd/lnrpc"
  16. "github.com/lightningnetwork/lnd/lntest"
  17. "github.com/lightningnetwork/lnd/lntest/node"
  18. "github.com/lightningnetwork/lnd/lntest/port"
  19. "github.com/lightningnetwork/lnd/lntest/wait"
  20. "github.com/stretchr/testify/require"
  21. "google.golang.org/grpc/grpclog"
  22. )
  23. const (
  24. // defaultSplitTranches is the default number of tranches we split the
  25. // test cases into.
  26. defaultSplitTranches uint = 1
  27. // defaultRunTranche is the default index of the test cases tranche that
  28. // we run.
  29. defaultRunTranche uint = 0
  30. defaultTimeout = wait.DefaultTimeout
  31. itestLndBinary = "../lnd-itest"
  32. // TODO(yy): remove the following defined constants and put them in the
  33. // specific tests where they are used?
  34. testFeeBase = 1e+6
  35. anchorSize = 330
  36. defaultCSV = node.DefaultCSV
  37. noFeeLimitMsat = math.MaxInt64
  38. AddrTypeWitnessPubkeyHash = lnrpc.AddressType_WITNESS_PUBKEY_HASH
  39. AddrTypeNestedPubkeyHash = lnrpc.AddressType_NESTED_PUBKEY_HASH
  40. AddrTypeTaprootPubkey = lnrpc.AddressType_TAPROOT_PUBKEY
  41. )
  42. var (
  43. harnessNetParams = &chaincfg.RegressionNetParams
  44. // testCasesSplitParts is the number of tranches the test cases should
  45. // be split into. By default this is set to 1, so no splitting happens.
  46. // If this value is increased, then the -runtranche flag must be
  47. // specified as well to indicate which part should be run in the current
  48. // invocation.
  49. testCasesSplitTranches = flag.Uint(
  50. "splittranches", defaultSplitTranches, "split the test cases "+
  51. "in this many tranches and run the tranche at "+
  52. "0-based index specified by the -runtranche flag",
  53. )
  54. // testCasesRunTranche is the 0-based index of the split test cases
  55. // tranche to run in the current invocation.
  56. testCasesRunTranche = flag.Uint(
  57. "runtranche", defaultRunTranche, "run the tranche of the "+
  58. "split test cases with the given (0-based) index",
  59. )
  60. // dbBackendFlag specifies the backend to use.
  61. dbBackendFlag = flag.String("dbbackend", "bbolt", "Database backend "+
  62. "(bbolt, etcd, postgres)")
  63. nativeSQLFlag = flag.Bool("nativesql", false, "Database backend to "+
  64. "use native SQL when applicable (only for sqlite and postgres")
  65. // lndExecutable is the full path to the lnd binary.
  66. lndExecutable = flag.String(
  67. "lndexec", itestLndBinary, "full path to lnd binary",
  68. )
  69. )
  70. // TestLightningNetworkDaemon performs a series of integration tests amongst a
  71. // programmatically driven network of lnd nodes.
  72. func TestLightningNetworkDaemon(t *testing.T) {
  73. // If no tests are registered, then we can exit early.
  74. if len(allTestCases) == 0 {
  75. t.Skip("integration tests not selected with flag 'integration'")
  76. }
  77. // Get the test cases to be run in this tranche.
  78. testCases, trancheIndex, trancheOffset := getTestCaseSplitTranche()
  79. // Create a simple fee service.
  80. feeService := lntest.NewFeeService(t)
  81. // Get the binary path and setup the harness test.
  82. binary := getLndBinary(t)
  83. harnessTest := lntest.SetupHarness(
  84. t, binary, *dbBackendFlag, *nativeSQLFlag, feeService,
  85. )
  86. defer harnessTest.Stop()
  87. // Setup standby nodes, Alice and Bob, which will be alive and shared
  88. // among all the test cases.
  89. harnessTest.SetupStandbyNodes()
  90. // Run the subset of the test cases selected in this tranche.
  91. for idx, testCase := range testCases {
  92. testCase := testCase
  93. name := fmt.Sprintf("tranche%02d/%02d-of-%d/%s/%s",
  94. trancheIndex, trancheOffset+uint(idx)+1,
  95. len(allTestCases), harnessTest.ChainBackendName(),
  96. testCase.Name)
  97. success := t.Run(name, func(t1 *testing.T) {
  98. // Create a separate harness test for the testcase to
  99. // avoid overwriting the external harness test that is
  100. // tied to the parent test.
  101. ht := harnessTest.Subtest(t1)
  102. // TODO(yy): split log files.
  103. cleanTestCaseName := strings.ReplaceAll(
  104. testCase.Name, " ", "_",
  105. )
  106. ht.SetTestName(cleanTestCaseName)
  107. logLine := fmt.Sprintf(
  108. "STARTING ============ %v ============\n",
  109. testCase.Name,
  110. )
  111. ht.Alice.AddToLogf(logLine)
  112. ht.Bob.AddToLogf(logLine)
  113. ht.EnsureConnected(ht.Alice, ht.Bob)
  114. ht.RunTestCase(testCase)
  115. })
  116. // Stop at the first failure. Mimic behavior of original test
  117. // framework.
  118. if !success {
  119. // Log failure time to help relate the lnd logs to the
  120. // failure.
  121. t.Logf("Failure time: %v", time.Now().Format(
  122. "2006-01-02 15:04:05.000",
  123. ))
  124. break
  125. }
  126. }
  127. _, height := harnessTest.Miner.GetBestBlock()
  128. t.Logf("=========> tests finished for tranche: %v, tested %d "+
  129. "cases, end height: %d\n", trancheIndex, len(testCases), height)
  130. }
  131. // getTestCaseSplitTranche returns the sub slice of the test cases that should
  132. // be run as the current split tranche as well as the index and slice offset of
  133. // the tranche.
  134. func getTestCaseSplitTranche() ([]*lntest.TestCase, uint, uint) {
  135. numTranches := defaultSplitTranches
  136. if testCasesSplitTranches != nil {
  137. numTranches = *testCasesSplitTranches
  138. }
  139. runTranche := defaultRunTranche
  140. if testCasesRunTranche != nil {
  141. runTranche = *testCasesRunTranche
  142. }
  143. // There's a special flake-hunt mode where we run the same test multiple
  144. // times in parallel. In that case the tranche index is equal to the
  145. // thread ID, but we need to actually run all tests for the regex
  146. // selection to work.
  147. threadID := runTranche
  148. if numTranches == 1 {
  149. runTranche = 0
  150. }
  151. numCases := uint(len(allTestCases))
  152. testsPerTranche := numCases / numTranches
  153. trancheOffset := runTranche * testsPerTranche
  154. trancheEnd := trancheOffset + testsPerTranche
  155. if trancheEnd > numCases || runTranche == numTranches-1 {
  156. trancheEnd = numCases
  157. }
  158. return allTestCases[trancheOffset:trancheEnd], threadID,
  159. trancheOffset
  160. }
  161. func getLndBinary(t *testing.T) string {
  162. binary := itestLndBinary
  163. lndExec := ""
  164. if lndExecutable != nil && *lndExecutable != "" {
  165. lndExec = *lndExecutable
  166. }
  167. if lndExec == "" && runtime.GOOS == "windows" {
  168. // Windows (even in a bash like environment like git bash as on
  169. // Travis) doesn't seem to like relative paths to exe files...
  170. currentDir, err := os.Getwd()
  171. require.NoError(t, err, "unable to get working directory")
  172. targetPath := filepath.Join(currentDir, "../../lnd-itest.exe")
  173. binary, err = filepath.Abs(targetPath)
  174. require.NoError(t, err, "unable to get absolute path")
  175. } else if lndExec != "" {
  176. binary = lndExec
  177. }
  178. return binary
  179. }
  180. func init() {
  181. // Before we start any node, we need to make sure that any btcd node
  182. // that is started through the RPC harness uses a unique port as well
  183. // to avoid any port collisions.
  184. rpctest.ListenAddressGenerator =
  185. port.GenerateSystemUniqueListenerAddresses
  186. // Swap out grpc's default logger with our fake logger which drops the
  187. // statements on the floor.
  188. fakeLogger := grpclog.NewLoggerV2(io.Discard, io.Discard, io.Discard)
  189. grpclog.SetLoggerV2(fakeLogger)
  190. }