setmatrix_test.go 3.7 KB

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