sync_test.go 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  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. package sync
  7. import (
  8. "strings"
  9. "sync"
  10. "testing"
  11. "time"
  12. "github.com/syncthing/syncthing/lib/logger"
  13. )
  14. const (
  15. logThreshold = 100 * time.Millisecond
  16. shortWait = 5 * time.Millisecond
  17. longWait = 125 * time.Millisecond
  18. )
  19. var skipTimingTests = false
  20. func init() {
  21. // Check a few times that a short sleep does not in fact overrun the log
  22. // threshold. If it does, the timer accuracy is crap or the host is
  23. // overloaded and we can't reliably run the tests in here. In the normal
  24. // case this takes just 25*5 = 125 ms.
  25. for i := 0; i < 25; i++ {
  26. t0 := time.Now()
  27. time.Sleep(shortWait)
  28. if time.Since(t0) > logThreshold {
  29. skipTimingTests = true
  30. return
  31. }
  32. }
  33. }
  34. func TestTypes(t *testing.T) {
  35. debug = false
  36. l.SetDebug("sync", false)
  37. if _, ok := NewMutex().(*sync.Mutex); !ok {
  38. t.Error("Wrong type")
  39. }
  40. if _, ok := NewRWMutex().(*sync.RWMutex); !ok {
  41. t.Error("Wrong type")
  42. }
  43. if _, ok := NewWaitGroup().(*sync.WaitGroup); !ok {
  44. t.Error("Wrong type")
  45. }
  46. debug = true
  47. l.SetDebug("sync", true)
  48. if _, ok := NewMutex().(*loggedMutex); !ok {
  49. t.Error("Wrong type")
  50. }
  51. if _, ok := NewRWMutex().(*loggedRWMutex); !ok {
  52. t.Error("Wrong type")
  53. }
  54. if _, ok := NewWaitGroup().(*loggedWaitGroup); !ok {
  55. t.Error("Wrong type")
  56. }
  57. debug = false
  58. l.SetDebug("sync", false)
  59. }
  60. func TestMutex(t *testing.T) {
  61. if skipTimingTests {
  62. t.Skip("insufficient timer accuracy")
  63. return
  64. }
  65. debug = true
  66. l.SetDebug("sync", true)
  67. threshold = logThreshold
  68. msgmut := sync.Mutex{}
  69. var messages []string
  70. l.AddHandler(logger.LevelDebug, func(_ logger.LogLevel, message string) {
  71. msgmut.Lock()
  72. messages = append(messages, message)
  73. msgmut.Unlock()
  74. })
  75. mut := NewMutex()
  76. mut.Lock()
  77. time.Sleep(shortWait)
  78. mut.Unlock()
  79. if len(messages) > 0 {
  80. t.Errorf("Unexpected message count")
  81. }
  82. mut.Lock()
  83. time.Sleep(longWait)
  84. mut.Unlock()
  85. if len(messages) != 1 {
  86. t.Errorf("Unexpected message count")
  87. }
  88. debug = false
  89. l.SetDebug("sync", false)
  90. }
  91. func TestRWMutex(t *testing.T) {
  92. if skipTimingTests {
  93. t.Skip("insufficient timer accuracy")
  94. return
  95. }
  96. debug = true
  97. l.SetDebug("sync", true)
  98. threshold = logThreshold
  99. msgmut := sync.Mutex{}
  100. var messages []string
  101. l.AddHandler(logger.LevelDebug, func(_ logger.LogLevel, message string) {
  102. msgmut.Lock()
  103. messages = append(messages, message)
  104. msgmut.Unlock()
  105. })
  106. mut := NewRWMutex()
  107. mut.Lock()
  108. time.Sleep(shortWait)
  109. mut.Unlock()
  110. if len(messages) > 0 {
  111. t.Errorf("Unexpected message count")
  112. }
  113. mut.Lock()
  114. time.Sleep(longWait)
  115. mut.Unlock()
  116. if len(messages) != 1 {
  117. t.Errorf("Unexpected message count")
  118. }
  119. // Testing rlocker logging
  120. mut.RLock()
  121. go func() {
  122. time.Sleep(longWait)
  123. mut.RUnlock()
  124. }()
  125. mut.Lock()
  126. mut.Unlock()
  127. if len(messages) != 2 {
  128. t.Errorf("Unexpected message count")
  129. }
  130. if !strings.Contains(messages[1], "RUnlockers while locking: sync") || !strings.Contains(messages[1], "sync_test.go:") {
  131. t.Error("Unexpected message")
  132. }
  133. // Testing multiple rlockers
  134. mut.RLock()
  135. mut.RLock()
  136. mut.RLock()
  137. mut.RUnlock()
  138. mut.RUnlock()
  139. mut.RUnlock()
  140. debug = false
  141. l.SetDebug("sync", false)
  142. }
  143. func TestWaitGroup(t *testing.T) {
  144. if skipTimingTests {
  145. t.Skip("insufficient timer accuracy")
  146. return
  147. }
  148. debug = true
  149. l.SetDebug("sync", true)
  150. threshold = logThreshold
  151. msgmut := sync.Mutex{}
  152. var messages []string
  153. l.AddHandler(logger.LevelDebug, func(_ logger.LogLevel, message string) {
  154. msgmut.Lock()
  155. messages = append(messages, message)
  156. msgmut.Unlock()
  157. })
  158. wg := NewWaitGroup()
  159. wg.Add(1)
  160. go func() {
  161. time.Sleep(shortWait)
  162. wg.Done()
  163. }()
  164. wg.Wait()
  165. if len(messages) > 0 {
  166. t.Errorf("Unexpected message count")
  167. }
  168. wg = NewWaitGroup()
  169. wg.Add(1)
  170. go func() {
  171. time.Sleep(longWait)
  172. wg.Done()
  173. }()
  174. wg.Wait()
  175. if len(messages) != 1 {
  176. t.Errorf("Unexpected message count")
  177. }
  178. debug = false
  179. l.SetDebug("sync", false)
  180. }