go.mercari.io/datastore@v1.8.2/clouddatastore/testsuite_test.go (about) 1 package clouddatastore 2 3 import ( 4 "context" 5 "fmt" 6 "math/rand" 7 "net" 8 "os" 9 "testing" 10 "time" 11 12 "go.mercari.io/datastore/testsuite" 13 _ "go.mercari.io/datastore/testsuite/dsmiddleware/dslog" 14 _ "go.mercari.io/datastore/testsuite/dsmiddleware/fishbone" 15 _ "go.mercari.io/datastore/testsuite/dsmiddleware/localcache" 16 _ "go.mercari.io/datastore/testsuite/dsmiddleware/rpcretry" 17 _ "go.mercari.io/datastore/testsuite/favcliptools" 18 _ "go.mercari.io/datastore/testsuite/realworld/recursivebatch" 19 _ "go.mercari.io/datastore/testsuite/realworld/tbf" 20 21 "github.com/bradfitz/gomemcache/memcache" 22 "github.com/gomodule/redigo/redis" 23 "go.mercari.io/datastore/dsmiddleware/chaosrpc" 24 "go.mercari.io/datastore/dsmiddleware/dsmemcache" 25 "go.mercari.io/datastore/dsmiddleware/localcache" 26 "go.mercari.io/datastore/dsmiddleware/rediscache" 27 "go.mercari.io/datastore/dsmiddleware/rpcretry" 28 "go.mercari.io/datastore/dsmiddleware/splitop" 29 "google.golang.org/api/iterator" 30 ) 31 32 func cleanUp() error { 33 ctx := context.Background() 34 client, err := FromContext(ctx) 35 if err != nil { 36 return err 37 } 38 defer client.Close() 39 40 q := client.NewQuery("__kind__").KeysOnly() 41 iter := client.Run(ctx, q) 42 var kinds []string 43 for { 44 key, err := iter.Next(nil) 45 if err == iterator.Done { 46 break 47 } 48 if err != nil { 49 return err 50 } 51 kinds = append(kinds, key.Name()) 52 } 53 54 for _, kind := range kinds { 55 q := client.NewQuery(kind).KeysOnly() 56 keys, err := client.GetAll(ctx, q, nil) 57 if err != nil { 58 return err 59 } 60 err = client.DeleteMulti(ctx, keys) 61 if err != nil { 62 return err 63 } 64 } 65 66 return nil 67 } 68 69 func TestCloudDatastoreTestSuite(t *testing.T) { 70 ctx := context.Background() 71 for name, test := range testsuite.TestSuite { 72 t.Run(name, func(t *testing.T) { 73 defer cleanUp() 74 75 datastore, err := FromContext(ctx) 76 if err != nil { 77 t.Fatal(err) 78 } 79 ctx = testsuite.WrapCloudFlag(ctx) 80 test(ctx, t, datastore) 81 }) 82 } 83 } 84 85 func TestCloudDatastoreWithLocalCacheTestSuite(t *testing.T) { 86 ctx := context.Background() 87 for name, test := range testsuite.TestSuite { 88 t.Run(name, func(t *testing.T) { 89 switch name { 90 // Skip the failure that happens when you firstly appended another middleware layer. 91 case 92 "LocalCache_Basic", 93 "LocalCache_WithIncludeKinds", 94 "LocalCache_WithExcludeKinds", 95 "LocalCache_WithKeyFilter", 96 "FishBone_QueryWithoutTx": 97 t.SkipNow() 98 // It's annoying to avoid failure test. I think there is no problem in practical use. I believe... 99 case "PutAndGet_TimeTime": 100 t.SkipNow() 101 } 102 103 defer cleanUp() 104 105 datastore, err := FromContext(ctx) 106 if err != nil { 107 t.Fatal(err) 108 } 109 110 ch := localcache.New() 111 datastore.AppendMiddleware(ch) 112 113 ctx = testsuite.WrapCloudFlag(ctx) 114 test(ctx, t, datastore) 115 }) 116 } 117 } 118 119 func TestCloudDatastoreWithRedisCacheTestSuite(t *testing.T) { 120 ctx := context.Background() 121 for name, test := range testsuite.TestSuite { 122 t.Run(name, func(t *testing.T) { 123 switch name { 124 // Skip the failure that happens when you firstly appended another middleware layer. 125 case 126 "LocalCache_Basic", 127 "LocalCache_WithIncludeKinds", 128 "LocalCache_WithExcludeKinds", 129 "LocalCache_WithKeyFilter", 130 "FishBone_QueryWithoutTx": 131 t.SkipNow() 132 // It's annoying to avoid failure test. I think there is no problem in practical use. I believe... 133 case "PutAndGet_TimeTime": 134 t.SkipNow() 135 } 136 137 defer cleanUp() 138 139 datastore, err := FromContext(ctx) 140 if err != nil { 141 t.Fatal(err) 142 } 143 144 dial, err := net.Dial("tcp", os.Getenv("REDIS_HOST")+":"+os.Getenv("REDIS_PORT")) 145 if err != nil { 146 t.Fatal(err) 147 } 148 defer dial.Close() 149 conn := redis.NewConn(dial, 100*time.Millisecond, 100*time.Millisecond) 150 defer conn.Close() 151 152 rc := rediscache.New(conn) 153 datastore.AppendMiddleware(rc) 154 155 ctx = testsuite.WrapCloudFlag(ctx) 156 test(ctx, t, datastore) 157 }) 158 } 159 } 160 161 func TestCloudDatastoreWithMemcacheTestSuite(t *testing.T) { 162 ctx := context.Background() 163 for name, test := range testsuite.TestSuite { 164 t.Run(name, func(t *testing.T) { 165 switch name { 166 // Skip the failure that happens when you firstly appended another middleware layer. 167 case 168 "LocalCache_Basic", 169 "LocalCache_WithIncludeKinds", 170 "LocalCache_WithExcludeKinds", 171 "LocalCache_WithKeyFilter", 172 "FishBone_QueryWithoutTx": 173 t.SkipNow() 174 // It's annoying to avoid failure test. I think there is no problem in practical use. I believe... 175 case "PutAndGet_TimeTime": 176 t.SkipNow() 177 } 178 179 defer cleanUp() 180 181 datastore, err := FromContext(ctx) 182 if err != nil { 183 t.Fatal(err) 184 } 185 186 memcacheClient := memcache.New(os.Getenv("MEMCACHE_ADDR")) 187 ch := dsmemcache.New( 188 memcacheClient, 189 ) 190 datastore.AppendMiddleware(ch) 191 192 ctx = testsuite.WrapCloudFlag(ctx) 193 test(ctx, t, datastore) 194 }) 195 } 196 } 197 198 func TestCloudDatastoreWithSplitCallTestSuite(t *testing.T) { 199 ctx := context.Background() 200 201 thresholds := []int{0, 1, 2, 1000} 202 for _, threshold := range thresholds { 203 threshold := threshold 204 t.Run(fmt.Sprintf("threshold %d", threshold), func(t *testing.T) { 205 for name, test := range testsuite.TestSuite { 206 t.Run(name, func(t *testing.T) { 207 // Skip the failure that happens when you firstly appended another middleware layer. 208 switch name { 209 case 210 //"LocalCache_Basic", 211 "LocalCache_WithIncludeKinds", 212 "LocalCache_WithExcludeKinds", 213 "LocalCache_WithKeyFilter", 214 "FishBone_QueryWithoutTx": 215 t.SkipNow() 216 } 217 218 defer cleanUp() 219 220 datastore, err := FromContext(ctx) 221 if err != nil { 222 t.Fatal(err) 223 } 224 225 sc := splitop.New( 226 splitop.WithGetSplitThreshold(threshold), 227 splitop.WithLogger(func(ctx context.Context, format string, args ...interface{}) { 228 t.Logf(format, args...) 229 }), 230 ) 231 datastore.AppendMiddleware(sc) 232 233 ctx = testsuite.WrapCloudFlag(ctx) 234 test(ctx, t, datastore) 235 }) 236 } 237 }) 238 } 239 } 240 241 func TestCloudDatastoreWithRPCRetryAndChaosRPCTestSuite(t *testing.T) { 242 ctx := context.Background() 243 for name, test := range testsuite.TestSuite { 244 t.Run(name, func(t *testing.T) { 245 // Skip the flaky tests. 246 switch name { 247 case 248 "Filter_PropertyTranslaterMustError": 249 t.SkipNow() 250 } 251 252 defer cleanUp() 253 254 datastore, err := FromContext(ctx) 255 if err != nil { 256 t.Fatal(err) 257 } 258 259 rr := rpcretry.New( 260 rpcretry.WithRetryLimit(10), 261 rpcretry.WithMinBackoffDuration(1), 262 rpcretry.WithMaxBackoffDuration(1), 263 rpcretry.WithLogger(func(ctx context.Context, format string, args ...interface{}) { 264 t.Logf(format, args...) 265 }), 266 ) 267 datastore.AppendMiddleware(rr) 268 269 seed := time.Now().UnixNano() 270 t.Logf("chaos seed: %d", seed) 271 cr := chaosrpc.New(rand.NewSource(seed)) 272 datastore.AppendMiddleware(cr) 273 274 ctx = testsuite.WrapCloudFlag(ctx) 275 test(ctx, t, datastore) 276 }) 277 } 278 }