override_test.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. // Copyright (C) 2015 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 http://mozilla.org/MPL/2.0/.
  6. // +build integration
  7. package integration
  8. import (
  9. "io/ioutil"
  10. "log"
  11. "os"
  12. "strings"
  13. "testing"
  14. "time"
  15. "github.com/syncthing/protocol"
  16. "github.com/syncthing/syncthing/internal/config"
  17. )
  18. func TestOverride(t *testing.T) {
  19. // Enable "Master" on s1/default
  20. id, _ := protocol.DeviceIDFromString(id1)
  21. cfg, _ := config.Load("h1/config.xml", id)
  22. fld := cfg.Folders()["default"]
  23. fld.ReadOnly = true
  24. cfg.SetFolder(fld)
  25. os.Rename("h1/config.xml", "h1/config.xml.orig")
  26. defer os.Rename("h1/config.xml.orig", "h1/config.xml")
  27. cfg.Save()
  28. log.Println("Cleaning...")
  29. err := removeAll("s1", "s2", "h1/index*", "h2/index*")
  30. if err != nil {
  31. t.Fatal(err)
  32. }
  33. log.Println("Generating files...")
  34. err = generateFiles("s1", 100, 20, "../LICENSE")
  35. if err != nil {
  36. t.Fatal(err)
  37. }
  38. fd, err := os.Create("s1/testfile.txt")
  39. if err != nil {
  40. t.Fatal(err)
  41. }
  42. _, err = fd.WriteString("hello\n")
  43. if err != nil {
  44. t.Fatal(err)
  45. }
  46. err = fd.Close()
  47. if err != nil {
  48. t.Fatal(err)
  49. }
  50. expected, err := directoryContents("s1")
  51. if err != nil {
  52. t.Fatal(err)
  53. }
  54. log.Println("Starting master...")
  55. master := syncthingProcess{ // id1
  56. instance: "1",
  57. argv: []string{"-home", "h1"},
  58. port: 8081,
  59. apiKey: apiKey,
  60. }
  61. err = master.start()
  62. if err != nil {
  63. t.Fatal(err)
  64. }
  65. defer master.stop()
  66. // Wait for one scan to succeed, or up to 20 seconds... This is to let
  67. // startup, UPnP etc complete and make sure the master has the full index
  68. // before they connect.
  69. for i := 0; i < 20; i++ {
  70. err := master.rescan("default")
  71. if err != nil {
  72. time.Sleep(time.Second)
  73. continue
  74. }
  75. break
  76. }
  77. log.Println("Starting slave...")
  78. slave := syncthingProcess{ // id2
  79. instance: "2",
  80. argv: []string{"-home", "h2"},
  81. port: 8082,
  82. apiKey: apiKey,
  83. }
  84. err = slave.start()
  85. if err != nil {
  86. master.stop()
  87. t.Fatal(err)
  88. }
  89. defer slave.stop()
  90. log.Println("Syncing...")
  91. if err = ovCompletion(100, master, slave); err != nil {
  92. t.Fatal(err)
  93. }
  94. log.Println("Verifying...")
  95. actual, err := directoryContents("s2")
  96. if err != nil {
  97. t.Fatal(err)
  98. }
  99. err = compareDirectoryContents(actual, expected)
  100. if err != nil {
  101. t.Fatal(err)
  102. }
  103. log.Println("Changing file on slave side...")
  104. fd, err = os.OpenFile("s2/testfile.txt", os.O_WRONLY|os.O_APPEND, 0644)
  105. if err != nil {
  106. t.Fatal(err)
  107. }
  108. _, err = fd.WriteString("text added to s2\n")
  109. if err != nil {
  110. t.Fatal(err)
  111. }
  112. err = fd.Close()
  113. if err != nil {
  114. t.Fatal(err)
  115. }
  116. err = slave.rescan("default")
  117. if err != nil {
  118. t.Fatal(err)
  119. }
  120. log.Println("Syncing...")
  121. time.Sleep(5 * time.Second)
  122. // Expect ~99% completion since the change will be rejected by the master side
  123. if err = ovCompletion(99, master, slave); err != nil {
  124. t.Fatal(err)
  125. }
  126. log.Println("Hitting Override on master...")
  127. resp, err := master.post("/rest/model/override?folder=default", nil)
  128. if err != nil {
  129. t.Fatal(err)
  130. }
  131. if resp.StatusCode != 200 {
  132. t.Fatal(resp.Status)
  133. }
  134. log.Println("Syncing...")
  135. if err = ovCompletion(100, master, slave); err != nil {
  136. t.Fatal(err)
  137. }
  138. // Verify that the override worked
  139. fd, err = os.Open("s1/testfile.txt")
  140. if err != nil {
  141. t.Fatal(err)
  142. }
  143. bs, err := ioutil.ReadAll(fd)
  144. if err != nil {
  145. t.Fatal(err)
  146. }
  147. fd.Close()
  148. if strings.Contains(string(bs), "added to s2") {
  149. t.Error("Change should not have been synced to master")
  150. }
  151. fd, err = os.Open("s2/testfile.txt")
  152. if err != nil {
  153. t.Fatal(err)
  154. }
  155. bs, err = ioutil.ReadAll(fd)
  156. if err != nil {
  157. t.Fatal(err)
  158. }
  159. fd.Close()
  160. if strings.Contains(string(bs), "added to s2") {
  161. t.Error("Change should have been overridden on slave")
  162. }
  163. }
  164. func ovCompletion(expected int, p ...syncthingProcess) error {
  165. mainLoop:
  166. for {
  167. time.Sleep(2500 * time.Millisecond)
  168. tot := 0
  169. for i := range p {
  170. comp, err := p[i].peerCompletion()
  171. if err != nil {
  172. if isTimeout(err) {
  173. continue mainLoop
  174. }
  175. return err
  176. }
  177. for _, pct := range comp {
  178. tot += pct
  179. }
  180. }
  181. if tot >= expected*len(p) {
  182. return nil
  183. }
  184. log.Printf("%d / %d...", tot, expected*len(p))
  185. }
  186. }