setmatrix_test.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. package setmatrix
  2. import (
  3. "context"
  4. "strconv"
  5. "strings"
  6. "testing"
  7. "time"
  8. _ "github.com/docker/libnetwork/testutils"
  9. )
  10. func TestSetSerialInsertDelete(t *testing.T) {
  11. s := NewSetMatrix()
  12. b, i := s.Insert("a", "1")
  13. if !b || i != 1 {
  14. t.Fatalf("error in insert %t %d", b, i)
  15. }
  16. b, i = s.Insert("a", "1")
  17. if b || i != 1 {
  18. t.Fatalf("error in insert %t %d", b, i)
  19. }
  20. b, i = s.Insert("a", "2")
  21. if !b || i != 2 {
  22. t.Fatalf("error in insert %t %d", b, i)
  23. }
  24. b, i = s.Insert("a", "1")
  25. if b || i != 2 {
  26. t.Fatalf("error in insert %t %d", b, i)
  27. }
  28. b, i = s.Insert("a", "3")
  29. if !b || i != 3 {
  30. t.Fatalf("error in insert %t %d", b, i)
  31. }
  32. b, i = s.Insert("a", "2")
  33. if b || i != 3 {
  34. t.Fatalf("error in insert %t %d", b, i)
  35. }
  36. b, i = s.Insert("a", "3")
  37. if b || i != 3 {
  38. t.Fatalf("error in insert %t %d", b, i)
  39. }
  40. b, i = s.Insert("a", "4")
  41. if !b || i != 4 {
  42. t.Fatalf("error in insert %t %d", b, i)
  43. }
  44. b, p := s.Contains("a", "1")
  45. if !b || !p {
  46. t.Fatalf("error in contains %t %t", b, p)
  47. }
  48. b, p = s.Contains("a", "2")
  49. if !b || !p {
  50. t.Fatalf("error in contains %t %t", b, p)
  51. }
  52. b, p = s.Contains("a", "3")
  53. if !b || !p {
  54. t.Fatalf("error in contains %t %t", b, p)
  55. }
  56. b, p = s.Contains("a", "4")
  57. if !b || !p {
  58. t.Fatalf("error in contains %t %t", b, p)
  59. }
  60. i, b = s.Cardinality("a")
  61. if !b || i != 4 {
  62. t.Fatalf("error in cardinality count %t %d", b, i)
  63. }
  64. keys := s.Keys()
  65. if len(keys) != 1 {
  66. t.Fatalf("error in keys %v", keys)
  67. }
  68. str, b := s.String("a")
  69. if !b ||
  70. !strings.Contains(str, "1") ||
  71. !strings.Contains(str, "2") ||
  72. !strings.Contains(str, "3") ||
  73. !strings.Contains(str, "4") {
  74. t.Fatalf("error in string %t %s", b, str)
  75. }
  76. _, b = s.Get("a")
  77. if !b {
  78. t.Fatalf("error in get %t", b)
  79. }
  80. b, i = s.Remove("a", "1")
  81. if !b || i != 3 {
  82. t.Fatalf("error in remove %t %d", b, i)
  83. }
  84. b, i = s.Remove("a", "3")
  85. if !b || i != 2 {
  86. t.Fatalf("error in remove %t %d", b, i)
  87. }
  88. b, i = s.Remove("a", "1")
  89. if b || i != 2 {
  90. t.Fatalf("error in remove %t %d", b, i)
  91. }
  92. b, i = s.Remove("a", "4")
  93. if !b || i != 1 {
  94. t.Fatalf("error in remove %t %d", b, i)
  95. }
  96. b, i = s.Remove("a", "2")
  97. if !b || i != 0 {
  98. t.Fatalf("error in remove %t %d", b, i)
  99. }
  100. b, i = s.Remove("a", "2")
  101. if b || i != 0 {
  102. t.Fatalf("error in remove %t %d", b, i)
  103. }
  104. i, b = s.Cardinality("a")
  105. if b || i != 0 {
  106. t.Fatalf("error in cardinality count %t %d", b, i)
  107. }
  108. str, b = s.String("a")
  109. if b || str != "" {
  110. t.Fatalf("error in string %t %s", b, str)
  111. }
  112. keys = s.Keys()
  113. if len(keys) > 0 {
  114. t.Fatalf("error in keys %v", keys)
  115. }
  116. // Negative tests
  117. _, b = s.Get("not exists")
  118. if b {
  119. t.Fatalf("error should not happen %t", b)
  120. }
  121. b1, b := s.Contains("not exists", "a")
  122. if b1 || b {
  123. t.Fatalf("error should not happen %t %t", b1, b)
  124. }
  125. }
  126. func insertDeleteRotuine(ctx context.Context, endCh chan int, s SetMatrix, key, value string) {
  127. for {
  128. select {
  129. case <-ctx.Done():
  130. endCh <- 0
  131. return
  132. default:
  133. b, _ := s.Insert(key, value)
  134. if !b {
  135. endCh <- 1
  136. return
  137. }
  138. b, _ = s.Remove(key, value)
  139. if !b {
  140. endCh <- 2
  141. return
  142. }
  143. }
  144. }
  145. }
  146. func TestSetParallelInsertDelete(t *testing.T) {
  147. s := NewSetMatrix()
  148. parallelRoutines := 6
  149. endCh := make(chan int)
  150. // Let the routines running and competing for 10s
  151. ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
  152. defer cancel()
  153. for i := 0; i < parallelRoutines; i++ {
  154. go insertDeleteRotuine(ctx, endCh, s, "key-"+strconv.Itoa(i%3), strconv.Itoa(i))
  155. }
  156. for parallelRoutines > 0 {
  157. v := <-endCh
  158. if v == 1 {
  159. t.Fatalf("error one goroutine failed on the insert")
  160. }
  161. if v == 2 {
  162. t.Fatalf("error one goroutine failed on the remove")
  163. }
  164. parallelRoutines--
  165. }
  166. if i, b := s.Cardinality("key"); b || i > 0 {
  167. t.Fatalf("error the set should be empty %t %d", b, i)
  168. }
  169. }