1// Copyright 2013-2020 Aerospike, Inc. 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 15package aerospike_test 16 17import ( 18 "math/rand" 19 "strings" 20 "time" 21 22 as "github.com/aerospike/aerospike-client-go" 23 24 . "github.com/onsi/ginkgo" 25 . "github.com/onsi/gomega" 26) 27 28const RANDOM_OPS_RUNS = 1000 29 30// ALL tests are isolated by SetName and Key, which are 50 random characters 31var _ = Describe("Aerospike", func() { 32 33 Describe("Random Data Operations", func() { 34 // connection data 35 var err error 36 var ns = *namespace 37 var set = randString(50) 38 var key *as.Key 39 var wpolicy = as.NewWritePolicy(0, 0) 40 var rpolicy = as.NewPolicy() 41 var rec *as.Record 42 43 if *useReplicas { 44 rpolicy.ReplicaPolicy = as.MASTER_PROLES 45 } 46 47 Context("Put/Get operations", func() { 48 49 It("must create, update and read keys consistently", func() { 50 key, err = as.NewKey(ns, set, randString(50)) 51 Expect(err).ToNot(HaveOccurred()) 52 53 bin1 := as.NewBin("Aerospike1", 0) 54 bin2 := as.NewBin("Aerospike2", "a") // to avoid deletion of key 55 56 i := 0 57 for i < RANDOM_OPS_RUNS { 58 iters := rand.Intn(10) + 1 59 for wr := 0; wr < iters; wr++ { 60 i++ 61 62 //reset 63 err = client.PutBins(wpolicy, key, bin1, bin2) 64 Expect(err).ToNot(HaveOccurred()) 65 66 // update 67 err = client.PutBins(wpolicy, key, as.NewBin("Aerospike1", i), as.NewBin("Aerospike2", strings.Repeat("a", i))) 68 Expect(err).ToNot(HaveOccurred()) 69 } 70 71 rec, err = client.Get(rpolicy, key) 72 Expect(err).ToNot(HaveOccurred()) 73 Expect(rec.Bins[bin1.Name]).To(Equal(i)) 74 Expect(rec.Bins[bin2.Name]).To(Equal(strings.Repeat("a", i))) 75 } 76 }) 77 78 }) // context put/get operations 79 80 Context("Parallel Put/Get/Delete operations", func() { 81 82 It("must save, read, delete keys consistently", func() { 83 84 errChan := make(chan error, 100) 85 86 func_delete := func(keys ...*as.Key) { 87 defer GinkgoRecover() 88 for _, key := range keys { 89 existed, err := client.Delete(wpolicy, key) 90 Expect(existed).To(BeTrue()) 91 errChan <- err 92 } 93 } 94 95 i := 0 96 for i < RANDOM_OPS_RUNS { 97 iters := rand.Intn(1000) + 1 98 for wr := 0; wr < iters; wr++ { 99 i++ 100 101 key, err = as.NewKey(ns, set, randString(50)) 102 Expect(err).ToNot(HaveOccurred()) 103 104 err = client.PutBins(wpolicy, key, as.NewBin("Aerospike1", i), as.NewBin("Aerospike2", strings.Repeat("a", i))) 105 Expect(err).ToNot(HaveOccurred()) 106 107 go func_delete(key) 108 } 109 110 // Timeout 111 timeout := time.After(time.Second * 3) 112 113 // Gather errors 114 for i := 0; i < iters; i++ { 115 select { 116 case err := <-errChan: 117 Expect(err).ToNot(HaveOccurred()) 118 119 case <-timeout: 120 Expect(timeout).To(BeNil()) 121 } 122 } // for i < iters 123 124 } // for i < iters 125 }) 126 127 }) // context parallel put/get/delete operations 128 129 }) // describe 130 131}) // describe 132