You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

225 lines
6.3 KiB

  1. // Copyright 2016 Google LLC
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package main
  15. import (
  16. "testing"
  17. "time"
  18. "cloud.google.com/go/bigtable"
  19. "cloud.google.com/go/internal/testutil"
  20. "github.com/google/go-cmp/cmp"
  21. )
  22. func TestParseDuration(t *testing.T) {
  23. tests := []struct {
  24. in string
  25. // out or fail are mutually exclusive
  26. out time.Duration
  27. fail bool
  28. }{
  29. {in: "10ms", out: 10 * time.Millisecond},
  30. {in: "3s", out: 3 * time.Second},
  31. {in: "60m", out: 60 * time.Minute},
  32. {in: "12h", out: 12 * time.Hour},
  33. {in: "7d", out: 168 * time.Hour},
  34. {in: "", fail: true},
  35. {in: "0", fail: true},
  36. {in: "7ns", fail: true},
  37. {in: "14mo", fail: true},
  38. {in: "3.5h", fail: true},
  39. {in: "106752d", fail: true}, // overflow
  40. }
  41. for _, tc := range tests {
  42. got, err := parseDuration(tc.in)
  43. if !tc.fail && err != nil {
  44. t.Errorf("parseDuration(%q) unexpectedly failed: %v", tc.in, err)
  45. continue
  46. }
  47. if tc.fail && err == nil {
  48. t.Errorf("parseDuration(%q) did not fail", tc.in)
  49. continue
  50. }
  51. if tc.fail {
  52. continue
  53. }
  54. if got != tc.out {
  55. t.Errorf("parseDuration(%q) = %v, want %v", tc.in, got, tc.out)
  56. }
  57. }
  58. }
  59. func TestParseGCPolicy(t *testing.T) {
  60. tests := []struct {
  61. in string
  62. out bigtable.GCPolicy
  63. fail bool
  64. }{
  65. {in: "maxage=1h", out: bigtable.MaxAgePolicy(time.Hour * 1)},
  66. {in: "maxversions=2", out: bigtable.MaxVersionsPolicy(int(2))},
  67. {in: "maxversions=2 and maxage=1h", out: bigtable.IntersectionPolicy([]bigtable.GCPolicy{bigtable.MaxVersionsPolicy(int(2)), bigtable.MaxAgePolicy(time.Hour * 1)}...)},
  68. {in: "maxversions=2 or maxage=1h", out: bigtable.UnionPolicy([]bigtable.GCPolicy{bigtable.MaxVersionsPolicy(int(2)), bigtable.MaxAgePolicy(time.Hour * 1)}...)},
  69. {in: "maxage=1", fail: true},
  70. {in: "maxage = 1h", fail: true},
  71. {in: "maxage =1h", fail: true},
  72. {in: "maxage= 1h", fail: true},
  73. {in: "foomaxage=1h", fail: true},
  74. {in: "maxversions=1h", fail: true},
  75. {in: "maxversions= 1", fail: true},
  76. {in: "maxversions = 1", fail: true},
  77. {in: "maxversions =1", fail: true},
  78. {in: "barmaxversions=1", fail: true},
  79. {in: "maxage = 1h or maxversions=1h", fail: true},
  80. {in: "foomaxversions=2 or maxage=1h", fail: true},
  81. {in: "maxversions=2 or barmaxage=1h", fail: true},
  82. {in: "foomaxversions=2 or barmaxage=1h", fail: true},
  83. {in: "maxage = 1h and maxversions=1h", fail: true},
  84. {in: "foomaxage=1h and maxversions=1", fail: true},
  85. {in: "maxage=1h and barmaxversions=1", fail: true},
  86. {in: "foomaxage=1h and barmaxversions=1", fail: true},
  87. }
  88. for _, tc := range tests {
  89. got, err := parseGCPolicy(tc.in)
  90. if !tc.fail && err != nil {
  91. t.Errorf("parseGCPolicy(%q) unexpectedly failed: %v", tc.in, err)
  92. continue
  93. }
  94. if tc.fail && err == nil {
  95. t.Errorf("parseGCPolicy(%q) did not fail", tc.in)
  96. continue
  97. }
  98. if tc.fail {
  99. continue
  100. }
  101. var cmpOpts cmp.Options
  102. cmpOpts = append(cmpOpts, cmp.AllowUnexported(bigtable.IntersectionPolicy([]bigtable.GCPolicy{}...)), cmp.AllowUnexported(bigtable.UnionPolicy([]bigtable.GCPolicy{}...)))
  103. if !cmp.Equal(got, tc.out, cmpOpts) {
  104. t.Errorf("parseGCPolicy(%q) =%v, want %v", tc.in, got, tc.out)
  105. }
  106. }
  107. }
  108. func TestParseArgs(t *testing.T) {
  109. got, err := parseArgs([]string{"a=1", "b=2"}, []string{"a", "b"})
  110. if err != nil {
  111. t.Fatal(err)
  112. }
  113. want := map[string]string{"a": "1", "b": "2"}
  114. if !testutil.Equal(got, want) {
  115. t.Fatalf("got %v, want %v", got, want)
  116. }
  117. if _, err := parseArgs([]string{"a1"}, []string{"a1"}); err == nil {
  118. t.Error("malformed: got nil, want error")
  119. }
  120. if _, err := parseArgs([]string{"a=1"}, []string{"b"}); err == nil {
  121. t.Error("invalid: got nil, want error")
  122. }
  123. }
  124. func TestParseColumnsFilter(t *testing.T) {
  125. tests := []struct {
  126. in string
  127. out bigtable.Filter
  128. fail bool
  129. }{
  130. {
  131. in: "columnA",
  132. out: bigtable.ColumnFilter("columnA"),
  133. },
  134. {
  135. in: "familyA:columnA",
  136. out: bigtable.ChainFilters(bigtable.FamilyFilter("familyA"), bigtable.ColumnFilter("columnA")),
  137. },
  138. {
  139. in: "columnA,columnB",
  140. out: bigtable.InterleaveFilters(bigtable.ColumnFilter("columnA"), bigtable.ColumnFilter("columnB")),
  141. },
  142. {
  143. in: "familyA:columnA,columnB",
  144. out: bigtable.InterleaveFilters(
  145. bigtable.ChainFilters(bigtable.FamilyFilter("familyA"), bigtable.ColumnFilter("columnA")),
  146. bigtable.ColumnFilter("columnB"),
  147. ),
  148. },
  149. {
  150. in: "columnA,familyB:columnB",
  151. out: bigtable.InterleaveFilters(
  152. bigtable.ColumnFilter("columnA"),
  153. bigtable.ChainFilters(bigtable.FamilyFilter("familyB"), bigtable.ColumnFilter("columnB")),
  154. ),
  155. },
  156. {
  157. in: "familyA:columnA,familyB:columnB",
  158. out: bigtable.InterleaveFilters(
  159. bigtable.ChainFilters(bigtable.FamilyFilter("familyA"), bigtable.ColumnFilter("columnA")),
  160. bigtable.ChainFilters(bigtable.FamilyFilter("familyB"), bigtable.ColumnFilter("columnB")),
  161. ),
  162. },
  163. {
  164. in: "familyA:",
  165. out: bigtable.FamilyFilter("familyA"),
  166. },
  167. {
  168. in: ":columnA",
  169. out: bigtable.ColumnFilter("columnA"),
  170. },
  171. {
  172. in: ",:columnA,,familyB:columnB,",
  173. out: bigtable.InterleaveFilters(
  174. bigtable.ColumnFilter("columnA"),
  175. bigtable.ChainFilters(bigtable.FamilyFilter("familyB"), bigtable.ColumnFilter("columnB")),
  176. ),
  177. },
  178. {
  179. in: "familyA:columnA:cellA",
  180. fail: true,
  181. },
  182. {
  183. in: "familyA::columnA",
  184. fail: true,
  185. },
  186. }
  187. for _, tc := range tests {
  188. got, err := parseColumnsFilter(tc.in)
  189. if !tc.fail && err != nil {
  190. t.Errorf("parseColumnsFilter(%q) unexpectedly failed: %v", tc.in, err)
  191. continue
  192. }
  193. if tc.fail && err == nil {
  194. t.Errorf("parseColumnsFilter(%q) did not fail", tc.in)
  195. continue
  196. }
  197. if tc.fail {
  198. continue
  199. }
  200. var cmpOpts cmp.Options
  201. cmpOpts =
  202. append(
  203. cmpOpts,
  204. cmp.AllowUnexported(bigtable.ChainFilters([]bigtable.Filter{}...)),
  205. cmp.AllowUnexported(bigtable.InterleaveFilters([]bigtable.Filter{}...)))
  206. if !cmp.Equal(got, tc.out, cmpOpts) {
  207. t.Errorf("parseColumnsFilter(%q) = %v, want %v", tc.in, got, tc.out)
  208. }
  209. }
  210. }