transfer-bench_test.go 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. // Copyright (C) 2014 The Syncthing Authors.
  2. //
  3. // This Source Code Form is subject to the terms of the Mozilla Public
  4. // License, v. 2.0. If a copy of the MPL was not distributed with this file,
  5. // You can obtain one at https://mozilla.org/MPL/2.0/.
  6. //go:build integration && benchmark
  7. // +build integration,benchmark
  8. package integration
  9. import (
  10. "log"
  11. "math/rand"
  12. "os"
  13. "testing"
  14. "time"
  15. "github.com/syncthing/syncthing/lib/rc"
  16. )
  17. func TestBenchmarkTransferManyFiles(t *testing.T) {
  18. setupAndBenchmarkTransfer(t, 10000, 15)
  19. }
  20. func TestBenchmarkTransferLargeFile1G(t *testing.T) {
  21. setupAndBenchmarkTransfer(t, 1, 30)
  22. }
  23. func TestBenchmarkTransferLargeFile2G(t *testing.T) {
  24. setupAndBenchmarkTransfer(t, 1, 31)
  25. }
  26. func TestBenchmarkTransferLargeFile4G(t *testing.T) {
  27. setupAndBenchmarkTransfer(t, 1, 32)
  28. }
  29. func TestBenchmarkTransferLargeFile8G(t *testing.T) {
  30. setupAndBenchmarkTransfer(t, 1, 33)
  31. }
  32. func TestBenchmarkTransferLargeFile16G(t *testing.T) {
  33. setupAndBenchmarkTransfer(t, 1, 34)
  34. }
  35. func TestBenchmarkTransferLargeFile32G(t *testing.T) {
  36. setupAndBenchmarkTransfer(t, 1, 35)
  37. }
  38. func setupAndBenchmarkTransfer(t *testing.T, files, sizeExp int) {
  39. cleanBenchmarkTransfer(t)
  40. log.Println("Generating files...")
  41. var err error
  42. if files == 1 {
  43. // Special case. Generate one file with the specified size exactly.
  44. var fd *os.File
  45. fd, err = os.Open("../LICENSE")
  46. if err != nil {
  47. t.Fatal(err)
  48. }
  49. err = os.MkdirAll("s1", 0755)
  50. if err != nil {
  51. t.Fatal(err)
  52. }
  53. err = generateOneFile(fd, "s1/onefile", 1<<uint(sizeExp), time.Now())
  54. } else {
  55. err = generateFiles("s1", files, sizeExp, "../LICENSE")
  56. }
  57. if err != nil {
  58. t.Fatal(err)
  59. }
  60. benchmarkTransfer(t)
  61. }
  62. // TestBenchmarkTransferSameFiles doesn't actually transfer anything, but tests
  63. // how fast two devicees get in sync if they have the same data locally.
  64. func TestBenchmarkTransferSameFiles(t *testing.T) {
  65. cleanBenchmarkTransfer(t)
  66. t0 := time.Now()
  67. rand.Seed(0)
  68. log.Println("Generating files in s1...")
  69. if err := generateFilesWithTime("s1", 10000, 10, "../LICENSE", t0); err != nil {
  70. t.Fatal(err)
  71. }
  72. rand.Seed(0)
  73. log.Println("Generating same files in s2...")
  74. if err := generateFilesWithTime("s2", 10000, 10, "../LICENSE", t0); err != nil {
  75. t.Fatal(err)
  76. }
  77. benchmarkTransfer(t)
  78. }
  79. func benchmarkTransfer(t *testing.T) {
  80. expected, err := directoryContents("s1")
  81. if err != nil {
  82. t.Fatal(err)
  83. }
  84. var total int64
  85. var nfiles int
  86. for _, f := range expected {
  87. total += f.size
  88. if f.mode.IsRegular() {
  89. nfiles++
  90. }
  91. }
  92. log.Printf("Total %.01f MiB in %d files", float64(total)/1024/1024, nfiles)
  93. sender := startInstance(t, 1)
  94. defer checkedStop(t, sender)
  95. receiver := startInstance(t, 2)
  96. defer checkedStop(t, receiver)
  97. sender.ResumeAll()
  98. receiver.ResumeAll()
  99. t0 := time.Now()
  100. var t1 time.Time
  101. lastEvent := 0
  102. loop:
  103. for {
  104. evs, err := receiver.Events(lastEvent)
  105. if err != nil {
  106. if isTimeout(err) {
  107. continue
  108. }
  109. t.Fatal(err)
  110. }
  111. for _, ev := range evs {
  112. lastEvent = ev.ID
  113. switch ev.Type {
  114. case "ItemFinished":
  115. break loop
  116. }
  117. }
  118. time.Sleep(250 * time.Millisecond)
  119. }
  120. processes := []*rc.Process{sender, receiver}
  121. for {
  122. if rc.InSync("default", processes...) {
  123. t1 = time.Now()
  124. break
  125. }
  126. time.Sleep(250 * time.Millisecond)
  127. }
  128. sendProc, err := sender.Stop()
  129. if err != nil {
  130. t.Fatal(err)
  131. }
  132. recvProc, err := receiver.Stop()
  133. if err != nil {
  134. t.Fatal(err)
  135. }
  136. log.Println("Verifying...")
  137. actual, err := directoryContents("s2")
  138. if err != nil {
  139. t.Fatal(err)
  140. }
  141. err = compareDirectoryContents(actual, expected)
  142. if err != nil {
  143. t.Fatal(err)
  144. }
  145. log.Printf("Result: Wall time: %v / MiB", t1.Sub(t0)/time.Duration(total/1024/1024))
  146. log.Printf("Result: %.3g KiB/s synced", float64(total)/1024/t1.Sub(t0).Seconds())
  147. printUsage("Receiver", recvProc, total)
  148. printUsage("Sender", sendProc, total)
  149. cleanBenchmarkTransfer(t)
  150. }
  151. func cleanBenchmarkTransfer(t *testing.T) {
  152. log.Println("Cleaning...")
  153. err := removeAll("s1", "s2", "h1/index*", "h2/index*")
  154. if err != nil {
  155. t.Fatal(err)
  156. }
  157. }