From 56151a0386411633cb33b7d76339920f4a37b99a Mon Sep 17 00:00:00 2001 From: Andrei Mihu Date: Sat, 3 Oct 2020 12:05:14 +0100 Subject: [PATCH] Better rank caching strategy. --- CHANGELOG.md | 1 + build/Dockerfile | 2 +- internal/skiplist/README.md | 86 ++++ internal/skiplist/element.go | 57 +++ internal/skiplist/skiplist.go | 222 ++++++++++ internal/skiplist/skiplist_test.go | 316 +++++++++++++++ tests/util.go => server/api_test.go | 29 +- {tests => server}/core_storage_test.go | 415 ++++++++++--------- {tests => server}/core_wallet_test.go | 533 ++++++++++++------------- server/leaderboard_rank_cache.go | 254 ++++++------ server/leaderboard_rank_cache_test.go | 309 ++++++++++++++ server/runtime_go_logger_test.go | 23 +- {tests => server}/runtime_test.go | 13 +- 13 files changed, 1635 insertions(+), 625 deletions(-) create mode 100644 internal/skiplist/README.md create mode 100644 internal/skiplist/element.go create mode 100644 internal/skiplist/skiplist.go create mode 100644 internal/skiplist/skiplist_test.go rename tests/util.go => server/api_test.go (85%) rename {tests => server}/core_storage_test.go (85%) rename {tests => server}/core_wallet_test.go (50%) create mode 100644 server/leaderboard_rank_cache_test.go rename {tests => server}/runtime_test.go (97%) diff --git a/CHANGELOG.md b/CHANGELOG.md index d4c46fe00..3494f348c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ The format is based on [keep a changelog](http://keepachangelog.com) and this pr - Replace shell script with Go generate commands to run protoc toolchain. - Update protocol definitions to remove warnings from stricter Go package import paths. See [here](https://developers.google.com/protocol-buffers/docs/reference/go-generated#package). - Move some Go packages to be internal. +- Improved rank caching strategy. ## [2.13.0] - 2020-08-31 ### Added diff --git a/build/Dockerfile b/build/Dockerfile index b81cecea3..512924746 100644 --- a/build/Dockerfile +++ b/build/Dockerfile @@ -47,7 +47,7 @@ LABEL description="Distributed server for social and realtime games and apps." RUN mkdir -p /nakama/data/modules && \ apt-get update && \ apt-get -y upgrade && \ - apt-get install -y --no-install-recommends ca-certificates tzdata curl iproute2 unzip rsync git tini schroot && \ + apt-get install -y --no-install-recommends ca-certificates=20190110 tzdata curl iproute2 unzip rsync git tini schroot && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* diff --git a/internal/skiplist/README.md b/internal/skiplist/README.md new file mode 100644 index 000000000..f40241549 --- /dev/null +++ b/internal/skiplist/README.md @@ -0,0 +1,86 @@ +skiplist +=============== + +reference from redis [zskiplist](https://github.com/antirez/redis) + + +Usage +=============== + +~~~Go + +package main + +import ( + "fmt" + "github.com/gansidui/skiplist" + "log" +) + +type User struct { + score float64 + id string +} + +func (u *User) Less(other interface{}) bool { + if u.score > other.(*User).score { + return true + } + if u.score == other.(*User).score && len(u.id) > len(other.(*User).id) { + return true + } + return false +} + +func main() { + us := make([]*User, 7) + us[0] = &User{6.6, "hi"} + us[1] = &User{4.4, "hello"} + us[2] = &User{2.2, "world"} + us[3] = &User{3.3, "go"} + us[4] = &User{1.1, "skip"} + us[5] = &User{2.2, "list"} + us[6] = &User{3.3, "lang"} + + // insert + sl := skiplist.New() + for i := 0; i < len(us); i++ { + sl.Insert(us[i]) + } + + // traverse + for e := sl.Front(); e != nil; e = e.Next() { + fmt.Println(e.Value.(*User).id, "-->", e.Value.(*User).score) + } + fmt.Println() + + // rank + rank1 := sl.GetRank(&User{2.2, "list"}) + rank2 := sl.GetRank(&User{6.6, "hi"}) + if rank1 != 6 || rank2 != 1 { + log.Fatal() + } + if e := sl.GetElementByRank(2); e.Value.(*User).score != 4.4 || e.Value.(*User).id != "hello" { + log.Fatal() + } +} + +/* output: + +hi --> 6.6 +hello --> 4.4 +lang --> 3.3 +go --> 3.3 +world --> 2.2 +list --> 2.2 +skip --> 1.1 + +*/ + +~~~ + + +License +=============== + +MIT \ No newline at end of file diff --git a/internal/skiplist/element.go b/internal/skiplist/element.go new file mode 100644 index 000000000..754cdbe23 --- /dev/null +++ b/internal/skiplist/element.go @@ -0,0 +1,57 @@ +package skiplist + +import ( + "math/rand" +) + +const SKIPLIST_MAXLEVEL = 32 +const SKIPLIST_BRANCH = 4 + +type skiplistLevel struct { + forward *Element + span int +} + +type Element struct { + Value Interface + backward *Element + level []*skiplistLevel +} + +// Next returns the next skiplist element or nil. +func (e *Element) Next() *Element { + return e.level[0].forward +} + +// Prev returns the previous skiplist element of nil. +func (e *Element) Prev() *Element { + return e.backward +} + +// newElement returns an initialized element. +func newElement(level int, v Interface) *Element { + slLevels := make([]*skiplistLevel, level) + for i := 0; i < level; i++ { + slLevels[i] = new(skiplistLevel) + } + + return &Element{ + Value: v, + backward: nil, + level: slLevels, + } +} + +// randomLevel returns a random level. +func randomLevel(r *rand.Rand) int { + level := 1 + for (r.Int31()&0xFFFF)%SKIPLIST_BRANCH == 0 { + level += 1 + } + + if level < SKIPLIST_MAXLEVEL { + return level + } else { + return SKIPLIST_MAXLEVEL + } +} diff --git a/internal/skiplist/skiplist.go b/internal/skiplist/skiplist.go new file mode 100644 index 000000000..6b3be6497 --- /dev/null +++ b/internal/skiplist/skiplist.go @@ -0,0 +1,222 @@ +package skiplist + +import "math/rand" + +type Interface interface { + Less(other interface{}) bool +} + +type SkipList struct { + r *rand.Rand + header *Element + tail *Element + update []*Element + rank []int + length int + level int +} + +// New returns an initialized skiplist. +func New() *SkipList { + return &SkipList{ + r: rand.New(rand.NewSource(1)), + header: newElement(SKIPLIST_MAXLEVEL, nil), + tail: nil, + update: make([]*Element, SKIPLIST_MAXLEVEL), + rank: make([]int, SKIPLIST_MAXLEVEL), + length: 0, + level: 1, + } +} + +// Init initializes or clears skiplist sl. +func (sl *SkipList) Init() *SkipList { + sl.header = newElement(SKIPLIST_MAXLEVEL, nil) + sl.tail = nil + sl.update = make([]*Element, SKIPLIST_MAXLEVEL) + sl.rank = make([]int, SKIPLIST_MAXLEVEL) + sl.length = 0 + sl.level = 1 + return sl +} + +// Front returns the first elements of skiplist sl or nil. +func (sl *SkipList) Front() *Element { + return sl.header.level[0].forward +} + +// Back returns the last elements of skiplist sl or nil. +func (sl *SkipList) Back() *Element { + return sl.tail +} + +// Len returns the numbler of elements of skiplist sl. +func (sl *SkipList) Len() int { + return sl.length +} + +// Insert inserts v, increments sl.length, and returns a new element of wrap v. +func (sl *SkipList) Insert(v Interface) *Element { + x := sl.header + for i := sl.level - 1; i >= 0; i-- { + // store rank that is crossed to reach the insert position + if i == sl.level-1 { + sl.rank[i] = 0 + } else { + sl.rank[i] = sl.rank[i+1] + } + for x.level[i].forward != nil && x.level[i].forward.Value.Less(v) { + sl.rank[i] += x.level[i].span + x = x.level[i].forward + } + sl.update[i] = x + } + + // ensure that the v is unique, the re-insertion of v should never happen since the + // caller of sl.Insert() should test in the hash table if the element is already inside or not. + level := randomLevel(sl.r) + if level > sl.level { + for i := sl.level; i < level; i++ { + sl.rank[i] = 0 + sl.update[i] = sl.header + sl.update[i].level[i].span = sl.length + } + sl.level = level + } + + x = newElement(level, v) + for i := 0; i < level; i++ { + x.level[i].forward = sl.update[i].level[i].forward + sl.update[i].level[i].forward = x + + // update span covered by update[i] as x is inserted here + x.level[i].span = sl.update[i].level[i].span - sl.rank[0] + sl.rank[i] + sl.update[i].level[i].span = sl.rank[0] - sl.rank[i] + 1 + } + + // increment span for untouched levels + for i := level; i < sl.level; i++ { + sl.update[i].level[i].span++ + } + + if sl.update[0] == sl.header { + x.backward = nil + } else { + x.backward = sl.update[0] + } + if x.level[0].forward != nil { + x.level[0].forward.backward = x + } else { + sl.tail = x + } + sl.length++ + + return x +} + +// deleteElement deletes e from its skiplist, and decrements sl.length. +func (sl *SkipList) deleteElement(e *Element, update []*Element) { + for i := 0; i < sl.level; i++ { + if update[i].level[i].forward == e { + update[i].level[i].span += e.level[i].span - 1 + update[i].level[i].forward = e.level[i].forward + } else { + update[i].level[i].span -= 1 + } + } + + if e.level[0].forward != nil { + e.level[0].forward.backward = e.backward + } else { + sl.tail = e.backward + } + + for sl.level > 1 && sl.header.level[sl.level-1].forward == nil { + sl.level-- + } + sl.length-- +} + +// Remove removes e from sl if e is an element of skiplist sl. +// It returns the element value e.Value. +func (sl *SkipList) Remove(e *Element) interface{} { + x := sl.find(e.Value) // x.Value >= e.Value + if x == e && !e.Value.Less(x.Value) { // e.Value >= x.Value + sl.deleteElement(x, sl.update) + return x.Value + } + + return nil +} + +// Delete deletes an element e that e.Value == v, and returns e.Value or nil. +func (sl *SkipList) Delete(v Interface) interface{} { + x := sl.find(v) // x.Value >= v + if x != nil && !v.Less(x.Value) { // v >= x.Value + sl.deleteElement(x, sl.update) + return x.Value + } + + return nil +} + +// Find finds an element e that e.Value == v, and returns e or nil. +func (sl *SkipList) Find(v Interface) *Element { + x := sl.find(v) // x.Value >= v + if x != nil && !v.Less(x.Value) { // v >= x.Value + return x + } + + return nil +} + +// find finds the first element e that e.Value >= v, and returns e or nil. +func (sl *SkipList) find(v Interface) *Element { + x := sl.header + for i := sl.level - 1; i >= 0; i-- { + for x.level[i].forward != nil && x.level[i].forward.Value.Less(v) { + x = x.level[i].forward + } + sl.update[i] = x + } + + return x.level[0].forward +} + +// GetRank finds the rank for an element e that e.Value == v, +// Returns 0 when the element cannot be found, rank otherwise. +// Note that the rank is 1-based due to the span of sl.header to the first element. +func (sl *SkipList) GetRank(v Interface) int { + x := sl.header + rank := 0 + for i := sl.level - 1; i >= 0; i-- { + for x.level[i].forward != nil && x.level[i].forward.Value.Less(v) { + rank += x.level[i].span + x = x.level[i].forward + } + if x.level[i].forward != nil && !x.level[i].forward.Value.Less(v) && !v.Less(x.level[i].forward.Value) { + rank += x.level[i].span + return rank + } + } + + return 0 +} + +// GetElementByRank finds an element by ites rank. The rank argument needs bo be 1-based. +// Note that is the first element e that GetRank(e.Value) == rank, and returns e or nil. +func (sl *SkipList) GetElementByRank(rank int) *Element { + x := sl.header + traversed := 0 + for i := sl.level - 1; i >= 0; i-- { + for x.level[i].forward != nil && traversed+x.level[i].span <= rank { + traversed += x.level[i].span + x = x.level[i].forward + } + if traversed == rank { + return x + } + } + + return nil +} diff --git a/internal/skiplist/skiplist_test.go b/internal/skiplist/skiplist_test.go new file mode 100644 index 000000000..ef5b5f73c --- /dev/null +++ b/internal/skiplist/skiplist_test.go @@ -0,0 +1,316 @@ +package skiplist + +import ( + "fmt" + "math/rand" + "sort" + "testing" +) + +type Int int + +func (i Int) Less(other interface{}) bool { + return i < other.(Int) +} + +func TestInt(t *testing.T) { + sl := New() + if sl.Len() != 0 || sl.Front() != nil && sl.Back() != nil { + t.Fatal() + } + + testData := []Int{Int(1), Int(2), Int(3)} + + sl.Insert(testData[0]) + if sl.Len() != 1 || sl.Front().Value.(Int) != testData[0] || sl.Back().Value.(Int) != testData[0] { + t.Fatal() + } + + sl.Insert(testData[2]) + if sl.Len() != 2 || sl.Front().Value.(Int) != testData[0] || sl.Back().Value.(Int) != testData[2] { + t.Fatal() + } + + sl.Insert(testData[1]) + if sl.Len() != 3 || sl.Front().Value.(Int) != testData[0] || sl.Back().Value.(Int) != testData[2] { + t.Fatal() + } + + sl.Insert(Int(-999)) + sl.Insert(Int(-888)) + sl.Insert(Int(888)) + sl.Insert(Int(999)) + sl.Insert(Int(1000)) + + expect := []Int{Int(-999), Int(-888), Int(1), Int(2), Int(3), Int(888), Int(999), Int(1000)} + ret := make([]Int, 0) + + for e := sl.Front(); e != nil; e = e.Next() { + ret = append(ret, e.Value.(Int)) + } + for i := 0; i < len(ret); i++ { + if ret[i] != expect[i] { + t.Fatal() + } + } + + e := sl.Find(Int(2)) + if e == nil || e.Value.(Int) != 2 { + t.Fatal() + } + + ret = make([]Int, 0) + for ; e != nil; e = e.Next() { + ret = append(ret, e.Value.(Int)) + } + for i := 0; i < len(ret); i++ { + if ret[i] != expect[i+3] { + t.Fatal() + } + } + + sl.Remove(sl.Find(Int(2))) + sl.Delete(Int(888)) + sl.Delete(Int(1000)) + + expect = []Int{Int(-999), Int(-888), Int(1), Int(3), Int(999)} + ret = make([]Int, 0) + + for e := sl.Back(); e != nil; e = e.Prev() { + ret = append(ret, e.Value.(Int)) + } + + for i := 0; i < len(ret); i++ { + if ret[i] != expect[len(ret)-i-1] { + t.Fatal() + } + } + + if sl.Front().Value.(Int) != -999 { + t.Fatal() + } + + sl.Remove(sl.Front()) + if sl.Front().Value.(Int) != -888 || sl.Back().Value.(Int) != 999 { + t.Fatal() + } + + sl.Remove(sl.Back()) + if sl.Front().Value.(Int) != -888 || sl.Back().Value.(Int) != 3 { + t.Fatal() + } + + if e = sl.Insert(Int(2)); e.Value.(Int) != 2 { + t.Fatal() + } + sl.Delete(Int(-888)) + + if r := sl.Delete(Int(123)); r != nil { + t.Fatal() + } + + if sl.Len() != 3 { + t.Fatal() + } + + sl.Insert(Int(2)) + sl.Insert(Int(2)) + sl.Insert(Int(1)) + + if e = sl.Find(Int(2)); e == nil { + t.Fatal() + } + + expect = []Int{Int(2), Int(2), Int(2), Int(3)} + ret = make([]Int, 0) + for ; e != nil; e = e.Next() { + ret = append(ret, e.Value.(Int)) + } + for i := 0; i < len(ret); i++ { + if ret[i] != expect[i] { + t.Fatal() + } + } + + sl2 := sl.Init() + if sl.Len() != 0 || sl.Front() != nil || sl.Back() != nil || + sl2.Len() != 0 || sl2.Front() != nil || sl2.Back() != nil { + t.Fatal() + } + + // for i := 0; i < 100; i++ { + // sl.Insert(Int(rand.Intn(200))) + // } + // output(sl) +} + +func TestRank(t *testing.T) { + sl := New() + + for i := 1; i <= 10; i++ { + sl.Insert(Int(i)) + } + + for i := 1; i <= 10; i++ { + if sl.GetRank(Int(i)) != i { + t.Fatal() + } + } + + for i := 1; i <= 10; i++ { + if sl.GetElementByRank(i).Value != Int(i) { + t.Fatal() + } + } + + if sl.GetRank(Int(0)) != 0 || sl.GetRank(Int(11)) != 0 { + t.Fatal() + } + + if sl.GetElementByRank(11) != nil || sl.GetElementByRank(12) != nil { + t.Fatal() + } + + expect := []Int{Int(7), Int(8), Int(9), Int(10)} + for e, i := sl.GetElementByRank(7), 0; e != nil; e, i = e.Next(), i+1 { + if e.Value != expect[i] { + t.Fatal() + } + } + + sl = sl.Init() + mark := make(map[int]bool) + ss := make([]int, 0) + + for i := 1; i <= 100000; i++ { + x := rand.Int() + if !mark[x] { + mark[x] = true + sl.Insert(Int(x)) + ss = append(ss, x) + } + } + sort.Ints(ss) + + for i := 0; i < len(ss); i++ { + if sl.GetElementByRank(i+1).Value != Int(ss[i]) || sl.GetRank(Int(ss[i])) != i+1 { + t.Fatal() + } + } + + // output(sl) +} + +func BenchmarkIntInsertOrder(b *testing.B) { + b.StopTimer() + sl := New() + b.StartTimer() + + for i := 0; i < b.N; i++ { + sl.Insert(Int(i)) + } +} + +func BenchmarkIntInsertRandom(b *testing.B) { + b.StopTimer() + sl := New() + b.StartTimer() + + for i := 0; i < b.N; i++ { + sl.Insert(Int(rand.Int())) + } +} + +func BenchmarkIntDeleteOrder(b *testing.B) { + b.StopTimer() + sl := New() + for i := 0; i < 1000000; i++ { + sl.Insert(Int(i)) + } + b.StartTimer() + + for i := 0; i < b.N; i++ { + sl.Delete(Int(i)) + } +} + +func BenchmarkIntDeleteRandome(b *testing.B) { + b.StopTimer() + sl := New() + for i := 0; i < 1000000; i++ { + sl.Insert(Int(rand.Int())) + } + b.StartTimer() + + for i := 0; i < b.N; i++ { + sl.Delete(Int(rand.Int())) + } +} + +func BenchmarkIntFindOrder(b *testing.B) { + b.StopTimer() + sl := New() + for i := 0; i < 1000000; i++ { + sl.Insert(Int(i)) + } + b.StartTimer() + + for i := 0; i < b.N; i++ { + sl.Find(Int(i)) + } +} + +func BenchmarkIntFindRandom(b *testing.B) { + b.StopTimer() + sl := New() + for i := 0; i < 1000000; i++ { + sl.Insert(Int(rand.Int())) + } + b.StartTimer() + + for i := 0; i < b.N; i++ { + sl.Find(Int(rand.Int())) + } +} + +func BenchmarkIntRankOrder(b *testing.B) { + b.StopTimer() + sl := New() + for i := 0; i < 1000000; i++ { + sl.Insert(Int(i)) + } + b.StartTimer() + + for i := 0; i < b.N; i++ { + sl.GetRank(Int(i)) + } +} + +func BenchmarkIntRankRandom(b *testing.B) { + b.StopTimer() + sl := New() + for i := 0; i < 1000000; i++ { + sl.Insert(Int(rand.Int())) + } + b.StartTimer() + + for i := 0; i < b.N; i++ { + sl.GetRank(Int(rand.Int())) + } +} + +func output(sl *SkipList) { + var x *Element + for i := 0; i < SKIPLIST_MAXLEVEL; i++ { + fmt.Printf("LEVEL[%v]: ", i) + count := 0 + x = sl.header.level[i].forward + for x != nil { + // fmt.Printf("%v -> ", x.Value) + count++ + x = x.level[i].forward + } + // fmt.Println("NIL") + fmt.Println("count==", count) + } +} diff --git a/tests/util.go b/server/api_test.go similarity index 85% rename from tests/util.go rename to server/api_test.go index d87e59062..a3407a338 100644 --- a/tests/util.go +++ b/server/api_test.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package tests +package server import ( "bytes" @@ -25,7 +25,6 @@ import ( "github.com/heroiclabs/nakama-common/api" "github.com/heroiclabs/nakama-common/rtapi" "github.com/heroiclabs/nakama/v2/apigrpc" - "github.com/heroiclabs/nakama/v2/server" _ "github.com/jackc/pgx/stdlib" "go.uber.org/zap" "go.uber.org/zap/zapcore" @@ -38,7 +37,7 @@ import ( var ( logger = NewConsoleLogger(os.Stdout, true) - config = server.NewConfig(logger) + cfg = NewConfig(logger) jsonpbMarshaler = &jsonpb.Marshaler{ EnumsAsInts: true, EmitDefaults: false, @@ -48,20 +47,18 @@ var ( jsonpbUnmarshaler = &jsonpb.Unmarshaler{ AllowUnknownFields: false, } + metrics = NewMetrics(logger, logger, cfg) + _ = CheckConfig(logger, cfg) ) -func init() { - _ = server.CheckConfig(logger, config) -} - type DummyMessageRouter struct{} -func (d *DummyMessageRouter) SendDeferred(*zap.Logger, []*server.DeferredMessage) { +func (d *DummyMessageRouter) SendDeferred(*zap.Logger, []*DeferredMessage) { panic("unused") } -func (d *DummyMessageRouter) SendToPresenceIDs(*zap.Logger, []*server.PresenceID, *rtapi.Envelope, bool) { +func (d *DummyMessageRouter) SendToPresenceIDs(*zap.Logger, []*PresenceID, *rtapi.Envelope, bool) { } -func (d *DummyMessageRouter) SendToStream(*zap.Logger, server.PresenceStream, *rtapi.Envelope, bool) {} +func (d *DummyMessageRouter) SendToStream(*zap.Logger, PresenceStream, *rtapi.Envelope, bool) {} type DummySession struct { messages []*rtapi.Envelope @@ -88,8 +85,8 @@ func (d *DummySession) Expiry() int64 { return int64(0) } func (d *DummySession) Consume() {} -func (d *DummySession) Format() server.SessionFormat { - return server.SessionFormatJson +func (d *DummySession) Format() SessionFormat { + return SessionFormatJson } func (d *DummySession) ClientIP() string { return "" @@ -165,12 +162,12 @@ ON CONFLICT(id) DO NOTHING`, uid, uid.String()); err != nil { } } -func NewAPIServer(t *testing.T, runtime *server.Runtime) (*server.ApiServer, *server.Pipeline) { +func NewAPIServer(t *testing.T, runtime *Runtime) (*ApiServer, *Pipeline) { db := NewDB(t) router := &DummyMessageRouter{} - tracker := &server.LocalTracker{} - pipeline := server.NewPipeline(logger, config, db, jsonpbMarshaler, jsonpbUnmarshaler, nil, nil, nil, tracker, router, runtime) - apiServer := server.StartApiServer(logger, logger, db, jsonpbMarshaler, jsonpbUnmarshaler, config, nil, nil, nil, nil, nil, nil, tracker, router, pipeline, runtime) + tracker := &LocalTracker{} + pipeline := NewPipeline(logger, cfg, db, jsonpbMarshaler, jsonpbUnmarshaler, nil, nil, nil, tracker, router, runtime) + apiServer := StartApiServer(logger, logger, db, jsonpbMarshaler, jsonpbUnmarshaler, cfg, nil, nil, nil, nil, nil, nil, tracker, router, metrics, pipeline, runtime) return apiServer, pipeline } diff --git a/tests/core_storage_test.go b/server/core_storage_test.go similarity index 85% rename from tests/core_storage_test.go rename to server/core_storage_test.go index fe8ee8a78..defe3e2ad 100644 --- a/tests/core_storage_test.go +++ b/server/core_storage_test.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package tests +package server import ( "context" @@ -23,7 +23,6 @@ import ( "github.com/gofrs/uuid" "github.com/golang/protobuf/ptypes/wrappers" "github.com/heroiclabs/nakama-common/api" - "github.com/heroiclabs/nakama/v2/server" "github.com/stretchr/testify/assert" "google.golang.org/grpc/codes" ) @@ -33,7 +32,7 @@ func TestStorageWriteRuntimeGlobalSingle(t *testing.T) { key := GenerateString() - ops := server.StorageOpWrites{&server.StorageOpWrite{ + ops := StorageOpWrites{&StorageOpWrite{ OwnerID: uuid.Nil.String(), Object: &api.WriteStorageObject{ Collection: "testcollection", @@ -43,7 +42,7 @@ func TestStorageWriteRuntimeGlobalSingle(t *testing.T) { PermissionWrite: &wrappers.Int32Value{Value: 1}, }, }} - acks, code, err := server.StorageWriteObjects(context.Background(), logger, db, true, ops) + acks, code, err := StorageWriteObjects(context.Background(), logger, db, true, ops) assert.Nil(t, err, "err was not nil") assert.Equal(t, codes.OK, code, "code was not OK") @@ -58,7 +57,7 @@ func TestStorageWriteRuntimeGlobalSingle(t *testing.T) { Collection: "testcollection", Key: key, }} - readData, err := server.StorageReadObjects(context.Background(), logger, db, uuid.Nil, ids) + readData, err := StorageReadObjects(context.Background(), logger, db, uuid.Nil, ids) assert.Nil(t, err, "err was not nil") assert.NotNil(t, readData.Objects, "readData was nil") @@ -82,8 +81,8 @@ func TestStorageWriteRuntimeUserMultiple(t *testing.T) { u2 := uuid.Must(uuid.NewV4()) InsertUser(t, db, u2) - ops := server.StorageOpWrites{ - &server.StorageOpWrite{ + ops := StorageOpWrites{ + &StorageOpWrite{ OwnerID: u0.String(), Object: &api.WriteStorageObject{ Collection: "testcollection", @@ -93,7 +92,7 @@ func TestStorageWriteRuntimeUserMultiple(t *testing.T) { PermissionWrite: &wrappers.Int32Value{Value: 1}, }, }, - &server.StorageOpWrite{ + &StorageOpWrite{ OwnerID: u1.String(), Object: &api.WriteStorageObject{ Collection: "testcollection", @@ -103,7 +102,7 @@ func TestStorageWriteRuntimeUserMultiple(t *testing.T) { PermissionWrite: &wrappers.Int32Value{Value: 0}, }, }, - &server.StorageOpWrite{ + &StorageOpWrite{ OwnerID: u2.String(), Object: &api.WriteStorageObject{ Collection: "testcollection", @@ -114,7 +113,7 @@ func TestStorageWriteRuntimeUserMultiple(t *testing.T) { }, }, } - acks, code, err := server.StorageWriteObjects(context.Background(), logger, db, false, ops) + acks, code, err := StorageWriteObjects(context.Background(), logger, db, false, ops) assert.Nil(t, err, "err was not nil") assert.Equal(t, codes.OK, code, "code was not OK") @@ -133,8 +132,8 @@ func TestStorageWriteRuntimeGlobalSingleIfMatchNotExists(t *testing.T) { db := NewDB(t) defer db.Close() - ops := server.StorageOpWrites{ - &server.StorageOpWrite{ + ops := StorageOpWrites{ + &StorageOpWrite{ OwnerID: uuid.Nil.String(), Object: &api.WriteStorageObject{ Collection: "testcollection", @@ -147,7 +146,7 @@ func TestStorageWriteRuntimeGlobalSingleIfMatchNotExists(t *testing.T) { }, } - acks, code, err := server.StorageWriteObjects(context.Background(), logger, db, true, ops) + acks, code, err := StorageWriteObjects(context.Background(), logger, db, true, ops) assert.Nil(t, acks, "acks was not nil") assert.Equal(t, codes.InvalidArgument, code, "code did not match") @@ -159,8 +158,8 @@ func TestStorageWriteRuntimeGlobalSingleIfMatchExists(t *testing.T) { db := NewDB(t) defer db.Close() - ops := server.StorageOpWrites{ - &server.StorageOpWrite{ + ops := StorageOpWrites{ + &StorageOpWrite{ OwnerID: uuid.Nil.String(), Object: &api.WriteStorageObject{ Collection: "testcollection", @@ -172,7 +171,7 @@ func TestStorageWriteRuntimeGlobalSingleIfMatchExists(t *testing.T) { }, } - acks, code, err := server.StorageWriteObjects(context.Background(), logger, db, true, ops) + acks, code, err := StorageWriteObjects(context.Background(), logger, db, true, ops) assert.Nil(t, err, "err was not nil") assert.Equal(t, codes.OK, code, "code was not OK") @@ -183,8 +182,8 @@ func TestStorageWriteRuntimeGlobalSingleIfMatchExists(t *testing.T) { assert.Equal(t, "", acks.Acks[0].UserId, "user id was not nil") assert.EqualValues(t, []byte(fmt.Sprintf("%x", md5.Sum([]byte((ops[0].Object.Value))))), acks.Acks[0].Version, "version did not match") - ops = server.StorageOpWrites{ - &server.StorageOpWrite{ + ops = StorageOpWrites{ + &StorageOpWrite{ OwnerID: uuid.Nil.String(), Object: &api.WriteStorageObject{ Collection: "testcollection", @@ -197,7 +196,7 @@ func TestStorageWriteRuntimeGlobalSingleIfMatchExists(t *testing.T) { }, } - acks, code, err = server.StorageWriteObjects(context.Background(), logger, db, true, ops) + acks, code, err = StorageWriteObjects(context.Background(), logger, db, true, ops) assert.Nil(t, err, "err was not nil") assert.Equal(t, codes.OK, code, "code was not 0") @@ -213,8 +212,8 @@ func TestStorageWriteRuntimeGlobalSingleIfMatchExistsFail(t *testing.T) { db := NewDB(t) defer db.Close() - ops := server.StorageOpWrites{ - &server.StorageOpWrite{ + ops := StorageOpWrites{ + &StorageOpWrite{ OwnerID: uuid.Nil.String(), Object: &api.WriteStorageObject{ Collection: "testcollection", @@ -226,7 +225,7 @@ func TestStorageWriteRuntimeGlobalSingleIfMatchExistsFail(t *testing.T) { }, } - acks, code, err := server.StorageWriteObjects(context.Background(), logger, db, true, ops) + acks, code, err := StorageWriteObjects(context.Background(), logger, db, true, ops) assert.Nil(t, err, "err was not nil") assert.Equal(t, codes.OK, code, "code was not OK") @@ -237,8 +236,8 @@ func TestStorageWriteRuntimeGlobalSingleIfMatchExistsFail(t *testing.T) { assert.Equal(t, "", acks.Acks[0].UserId, "user id was not nil") assert.EqualValues(t, []byte(fmt.Sprintf("%x", md5.Sum([]byte((ops[0].Object.Value))))), acks.Acks[0].Version, "version did not match") - ops = server.StorageOpWrites{ - &server.StorageOpWrite{ + ops = StorageOpWrites{ + &StorageOpWrite{ OwnerID: uuid.Nil.String(), Object: &api.WriteStorageObject{ Collection: "testcollection", @@ -251,7 +250,7 @@ func TestStorageWriteRuntimeGlobalSingleIfMatchExistsFail(t *testing.T) { }, } - acks, code, err = server.StorageWriteObjects(context.Background(), logger, db, true, ops) + acks, code, err = StorageWriteObjects(context.Background(), logger, db, true, ops) assert.Nil(t, acks, "acks was not nil") assert.Equal(t, codes.InvalidArgument, code, "code did not match") @@ -263,8 +262,8 @@ func TestStorageWriteRuntimeGlobalSingleIfNoneMatchNotExists(t *testing.T) { db := NewDB(t) defer db.Close() - ops := server.StorageOpWrites{ - &server.StorageOpWrite{ + ops := StorageOpWrites{ + &StorageOpWrite{ OwnerID: uuid.Nil.String(), Object: &api.WriteStorageObject{ Collection: "testcollection", @@ -277,7 +276,7 @@ func TestStorageWriteRuntimeGlobalSingleIfNoneMatchNotExists(t *testing.T) { }, } - acks, _, err := server.StorageWriteObjects(context.Background(), logger, db, true, ops) + acks, _, err := StorageWriteObjects(context.Background(), logger, db, true, ops) assert.Nil(t, err, "err was not nil") assert.NotNil(t, acks, "acks was nil") @@ -292,8 +291,8 @@ func TestStorageWriteRuntimeGlobalSingleIfNoneMatchExists(t *testing.T) { db := NewDB(t) defer db.Close() - ops := server.StorageOpWrites{ - &server.StorageOpWrite{ + ops := StorageOpWrites{ + &StorageOpWrite{ OwnerID: uuid.Nil.String(), Object: &api.WriteStorageObject{ Collection: "testcollection", @@ -305,7 +304,7 @@ func TestStorageWriteRuntimeGlobalSingleIfNoneMatchExists(t *testing.T) { }, } - acks, _, err := server.StorageWriteObjects(context.Background(), logger, db, true, ops) + acks, _, err := StorageWriteObjects(context.Background(), logger, db, true, ops) assert.Nil(t, err, "err was not nil") assert.NotNil(t, acks, "acks was nil") @@ -315,8 +314,8 @@ func TestStorageWriteRuntimeGlobalSingleIfNoneMatchExists(t *testing.T) { assert.Equal(t, "", acks.Acks[0].UserId, "user id was not nil") assert.EqualValues(t, []byte(fmt.Sprintf("%x", md5.Sum([]byte((ops[0].Object.Value))))), acks.Acks[0].Version, "version did not match") - ops = server.StorageOpWrites{ - &server.StorageOpWrite{ + ops = StorageOpWrites{ + &StorageOpWrite{ OwnerID: uuid.Nil.String(), Object: &api.WriteStorageObject{ Collection: "testcollection", @@ -329,7 +328,7 @@ func TestStorageWriteRuntimeGlobalSingleIfNoneMatchExists(t *testing.T) { }, } - acks, code, err := server.StorageWriteObjects(context.Background(), logger, db, true, ops) + acks, code, err := StorageWriteObjects(context.Background(), logger, db, true, ops) assert.Nil(t, acks, "acks was not nil") assert.Equal(t, codes.InvalidArgument, code, "code did not match") @@ -341,8 +340,8 @@ func TestStorageWriteRuntimeGlobalMultipleIfMatchNotExists(t *testing.T) { db := NewDB(t) defer db.Close() - ops := server.StorageOpWrites{ - &server.StorageOpWrite{ + ops := StorageOpWrites{ + &StorageOpWrite{ OwnerID: uuid.Nil.String(), Object: &api.WriteStorageObject{ Collection: "testcollection", @@ -352,7 +351,7 @@ func TestStorageWriteRuntimeGlobalMultipleIfMatchNotExists(t *testing.T) { PermissionWrite: &wrappers.Int32Value{Value: 1}, }, }, - &server.StorageOpWrite{ + &StorageOpWrite{ OwnerID: uuid.Nil.String(), Object: &api.WriteStorageObject{ Collection: "testcollection", @@ -365,7 +364,7 @@ func TestStorageWriteRuntimeGlobalMultipleIfMatchNotExists(t *testing.T) { }, } - acks, code, err := server.StorageWriteObjects(context.Background(), logger, db, true, ops) + acks, code, err := StorageWriteObjects(context.Background(), logger, db, true, ops) assert.Nil(t, acks, "acks was not nil") assert.Equal(t, codes.InvalidArgument, code, "code did not match") @@ -380,8 +379,8 @@ func TestStorageWritePipelineUserSingle(t *testing.T) { uid := uuid.Must(uuid.NewV4()) InsertUser(t, db, uid) - ops := server.StorageOpWrites{ - &server.StorageOpWrite{ + ops := StorageOpWrites{ + &StorageOpWrite{ OwnerID: uid.String(), Object: &api.WriteStorageObject{ Collection: "testcollection", @@ -393,7 +392,7 @@ func TestStorageWritePipelineUserSingle(t *testing.T) { }, } - acks, _, err := server.StorageWriteObjects(context.Background(), logger, db, false, ops) + acks, _, err := StorageWriteObjects(context.Background(), logger, db, false, ops) assert.Nil(t, err, "err was not nil") assert.NotNil(t, acks, "acks was nil") @@ -411,8 +410,8 @@ func TestStorageWritePipelineUserMultiple(t *testing.T) { uid := uuid.Must(uuid.NewV4()) InsertUser(t, db, uid) - ops := server.StorageOpWrites{ - &server.StorageOpWrite{ + ops := StorageOpWrites{ + &StorageOpWrite{ OwnerID: uid.String(), Object: &api.WriteStorageObject{ Collection: "testcollection", @@ -422,7 +421,7 @@ func TestStorageWritePipelineUserMultiple(t *testing.T) { PermissionWrite: &wrappers.Int32Value{Value: 1}, }, }, - &server.StorageOpWrite{ + &StorageOpWrite{ OwnerID: uid.String(), Object: &api.WriteStorageObject{ Collection: "testcollection", @@ -432,7 +431,7 @@ func TestStorageWritePipelineUserMultiple(t *testing.T) { PermissionWrite: &wrappers.Int32Value{Value: 0}, }, }, - &server.StorageOpWrite{ + &StorageOpWrite{ OwnerID: uid.String(), Object: &api.WriteStorageObject{ Collection: "testcollection", @@ -444,7 +443,7 @@ func TestStorageWritePipelineUserMultiple(t *testing.T) { }, } - allAcks, code, err := server.StorageWriteObjects(context.Background(), logger, db, false, ops) + allAcks, code, err := StorageWriteObjects(context.Background(), logger, db, false, ops) if err != nil { t.Fatal(err.Error()) } @@ -474,8 +473,8 @@ func TestStorageWriteRuntimeGlobalMultipleSameKey(t *testing.T) { key := GenerateString() - ops := server.StorageOpWrites{ - &server.StorageOpWrite{ + ops := StorageOpWrites{ + &StorageOpWrite{ OwnerID: uuid.Nil.String(), Object: &api.WriteStorageObject{ Collection: "testcollection", @@ -485,7 +484,7 @@ func TestStorageWriteRuntimeGlobalMultipleSameKey(t *testing.T) { PermissionWrite: &wrappers.Int32Value{Value: 1}, }, }, - &server.StorageOpWrite{ + &StorageOpWrite{ OwnerID: uuid.Nil.String(), Object: &api.WriteStorageObject{ Collection: "testcollection", @@ -495,7 +494,7 @@ func TestStorageWriteRuntimeGlobalMultipleSameKey(t *testing.T) { PermissionWrite: &wrappers.Int32Value{Value: 0}, }, }, - &server.StorageOpWrite{ + &StorageOpWrite{ OwnerID: uuid.Nil.String(), Object: &api.WriteStorageObject{ Collection: "testcollection", @@ -507,7 +506,7 @@ func TestStorageWriteRuntimeGlobalMultipleSameKey(t *testing.T) { }, } - acks, code, err := server.StorageWriteObjects(context.Background(), logger, db, true, ops) + acks, code, err := StorageWriteObjects(context.Background(), logger, db, true, ops) assert.Nil(t, err, "err was not nil") assert.Equal(t, codes.OK, code, "code was not OK") @@ -533,7 +532,7 @@ func TestStorageWriteRuntimeGlobalMultipleSameKey(t *testing.T) { Key: key, }} - readData, err := server.StorageReadObjects(context.Background(), logger, db, uuid.Nil, ids) + readData, err := StorageReadObjects(context.Background(), logger, db, uuid.Nil, ids) assert.Nil(t, err, "err was not nil") assert.NotNil(t, readData, "readData was nil") assert.Len(t, readData.Objects, 1, "readData length was not 1") @@ -553,8 +552,8 @@ func TestStorageWritePipelineUserMultipleSameKey(t *testing.T) { uid := uuid.Must(uuid.NewV4()) InsertUser(t, db, uid) - ops := server.StorageOpWrites{ - &server.StorageOpWrite{ + ops := StorageOpWrites{ + &StorageOpWrite{ OwnerID: uid.String(), Object: &api.WriteStorageObject{ Collection: "testcollection", @@ -564,7 +563,7 @@ func TestStorageWritePipelineUserMultipleSameKey(t *testing.T) { PermissionWrite: &wrappers.Int32Value{Value: 1}, }, }, - &server.StorageOpWrite{ + &StorageOpWrite{ OwnerID: uid.String(), Object: &api.WriteStorageObject{ Collection: "testcollection", @@ -576,7 +575,7 @@ func TestStorageWritePipelineUserMultipleSameKey(t *testing.T) { }, } - acks, code, err := server.StorageWriteObjects(context.Background(), logger, db, false, ops) + acks, code, err := StorageWriteObjects(context.Background(), logger, db, false, ops) assert.Nil(t, err, "err was not nil") assert.Equal(t, codes.OK, code, "code was not 0") @@ -597,7 +596,7 @@ func TestStorageWritePipelineUserMultipleSameKey(t *testing.T) { UserId: uid.String(), }} - readData, err := server.StorageReadObjects(context.Background(), logger, db, uid, ids) + readData, err := StorageReadObjects(context.Background(), logger, db, uid, ids) assert.Nil(t, err, "err was not nil") assert.NotNil(t, readData, "readData was nil") assert.Len(t, readData.Objects, 1, "readData length was not 1") @@ -616,8 +615,8 @@ func TestStorageWritePipelineIfMatchNotExists(t *testing.T) { uid := uuid.Must(uuid.NewV4()) InsertUser(t, db, uid) - ops := server.StorageOpWrites{ - &server.StorageOpWrite{ + ops := StorageOpWrites{ + &StorageOpWrite{ OwnerID: uid.String(), Object: &api.WriteStorageObject{ Collection: "testcollection", @@ -630,7 +629,7 @@ func TestStorageWritePipelineIfMatchNotExists(t *testing.T) { }, } - acks, code, err := server.StorageWriteObjects(context.Background(), logger, db, false, ops) + acks, code, err := StorageWriteObjects(context.Background(), logger, db, false, ops) assert.Nil(t, acks, "acks was not nil") assert.Equal(t, codes.InvalidArgument, code, "code did not match") @@ -645,8 +644,8 @@ func TestStorageWritePipelineIfMatchExistsFail(t *testing.T) { uid := uuid.Must(uuid.NewV4()) InsertUser(t, db, uid) - ops := server.StorageOpWrites{ - &server.StorageOpWrite{ + ops := StorageOpWrites{ + &StorageOpWrite{ OwnerID: uid.String(), Object: &api.WriteStorageObject{ Collection: "testcollection", @@ -658,7 +657,7 @@ func TestStorageWritePipelineIfMatchExistsFail(t *testing.T) { }, } - acks, _, err := server.StorageWriteObjects(context.Background(), logger, db, false, ops) + acks, _, err := StorageWriteObjects(context.Background(), logger, db, false, ops) assert.Nil(t, err, "err was not nil") assert.NotNil(t, acks, "acks was nil") @@ -668,8 +667,8 @@ func TestStorageWritePipelineIfMatchExistsFail(t *testing.T) { assert.EqualValues(t, acks.Acks[0].UserId, uid.String(), "user id did not match") assert.EqualValues(t, []byte(fmt.Sprintf("%x", md5.Sum([]byte((ops[0].Object.Value))))), acks.Acks[0].Version, "version did not match") - ops = server.StorageOpWrites{ - &server.StorageOpWrite{ + ops = StorageOpWrites{ + &StorageOpWrite{ OwnerID: uid.String(), Object: &api.WriteStorageObject{ Collection: "testcollection", @@ -682,7 +681,7 @@ func TestStorageWritePipelineIfMatchExistsFail(t *testing.T) { }, } - acks, code, err := server.StorageWriteObjects(context.Background(), logger, db, false, ops) + acks, code, err := StorageWriteObjects(context.Background(), logger, db, false, ops) assert.Nil(t, acks, "acks was not nil") assert.Equal(t, codes.InvalidArgument, code, "code did not match") @@ -698,8 +697,8 @@ func TestStorageWritePipelineIfMatchExists(t *testing.T) { uid := uuid.Must(uuid.NewV4()) InsertUser(t, db, uid) - ops := server.StorageOpWrites{ - &server.StorageOpWrite{ + ops := StorageOpWrites{ + &StorageOpWrite{ OwnerID: uid.String(), Object: &api.WriteStorageObject{ Collection: "testcollection", @@ -711,7 +710,7 @@ func TestStorageWritePipelineIfMatchExists(t *testing.T) { }, } - acks, _, err := server.StorageWriteObjects(context.Background(), logger, db, false, ops) + acks, _, err := StorageWriteObjects(context.Background(), logger, db, false, ops) assert.Nil(t, err, "err was not nil") assert.NotNil(t, acks, "acks was nil") @@ -721,8 +720,8 @@ func TestStorageWritePipelineIfMatchExists(t *testing.T) { assert.EqualValues(t, acks.Acks[0].UserId, uid.String(), "user id did not match") assert.EqualValues(t, []byte(fmt.Sprintf("%x", md5.Sum([]byte((ops[0].Object.Value))))), acks.Acks[0].Version, "version did not match") - ops = server.StorageOpWrites{ - &server.StorageOpWrite{ + ops = StorageOpWrites{ + &StorageOpWrite{ OwnerID: uid.String(), Object: &api.WriteStorageObject{ Collection: "testcollection", @@ -735,7 +734,7 @@ func TestStorageWritePipelineIfMatchExists(t *testing.T) { }, } - acks, _, err = server.StorageWriteObjects(context.Background(), logger, db, false, ops) + acks, _, err = StorageWriteObjects(context.Background(), logger, db, false, ops) assert.Nil(t, err, "err was not nil") assert.NotNil(t, acks, "acks was nil") @@ -753,8 +752,8 @@ func TestStorageWritePipelineIfNoneMatchNotExists(t *testing.T) { uid := uuid.Must(uuid.NewV4()) InsertUser(t, db, uid) - ops := server.StorageOpWrites{ - &server.StorageOpWrite{ + ops := StorageOpWrites{ + &StorageOpWrite{ OwnerID: uid.String(), Object: &api.WriteStorageObject{ Collection: "testcollection", @@ -767,7 +766,7 @@ func TestStorageWritePipelineIfNoneMatchNotExists(t *testing.T) { }, } - acks, _, err := server.StorageWriteObjects(context.Background(), logger, db, false, ops) + acks, _, err := StorageWriteObjects(context.Background(), logger, db, false, ops) assert.Nil(t, err, "err was not nil") assert.NotNil(t, acks, "acks was nil") @@ -786,8 +785,8 @@ func TestStorageWritePipelineIfNoneMatchExists(t *testing.T) { uid := uuid.Must(uuid.NewV4()) InsertUser(t, db, uid) - ops := server.StorageOpWrites{ - &server.StorageOpWrite{ + ops := StorageOpWrites{ + &StorageOpWrite{ OwnerID: uid.String(), Object: &api.WriteStorageObject{ Collection: "testcollection", @@ -799,7 +798,7 @@ func TestStorageWritePipelineIfNoneMatchExists(t *testing.T) { }, } - acks, _, err := server.StorageWriteObjects(context.Background(), logger, db, false, ops) + acks, _, err := StorageWriteObjects(context.Background(), logger, db, false, ops) assert.Nil(t, err, "err was not nil") assert.NotNil(t, acks, "acks was nil") @@ -809,8 +808,8 @@ func TestStorageWritePipelineIfNoneMatchExists(t *testing.T) { assert.EqualValues(t, acks.Acks[0].UserId, uid.String(), "user id did not match") assert.EqualValues(t, []byte(fmt.Sprintf("%x", md5.Sum([]byte((ops[0].Object.Value))))), acks.Acks[0].Version, "version did not match") - ops = server.StorageOpWrites{ - &server.StorageOpWrite{ + ops = StorageOpWrites{ + &StorageOpWrite{ OwnerID: uid.String(), Object: &api.WriteStorageObject{ Collection: "testcollection", @@ -823,7 +822,7 @@ func TestStorageWritePipelineIfNoneMatchExists(t *testing.T) { }, } - acks, code, err := server.StorageWriteObjects(context.Background(), logger, db, false, ops) + acks, code, err := StorageWriteObjects(context.Background(), logger, db, false, ops) assert.Nil(t, acks, "acks was not nil") assert.Equal(t, codes.InvalidArgument, code, "code did not match") @@ -839,8 +838,8 @@ func TestStorageWritePipelinePermissionFail(t *testing.T) { uid := uuid.Must(uuid.NewV4()) InsertUser(t, db, uid) - ops := server.StorageOpWrites{ - &server.StorageOpWrite{ + ops := StorageOpWrites{ + &StorageOpWrite{ OwnerID: uid.String(), Object: &api.WriteStorageObject{ Collection: "testcollection", @@ -852,7 +851,7 @@ func TestStorageWritePipelinePermissionFail(t *testing.T) { }, } - acks, _, err := server.StorageWriteObjects(context.Background(), logger, db, false, ops) + acks, _, err := StorageWriteObjects(context.Background(), logger, db, false, ops) assert.Nil(t, err, "err was not nil") assert.NotNil(t, acks, "acks was nil") @@ -862,8 +861,8 @@ func TestStorageWritePipelinePermissionFail(t *testing.T) { assert.EqualValues(t, acks.Acks[0].UserId, uid.String(), "user id did not match") assert.EqualValues(t, []byte(fmt.Sprintf("%x", md5.Sum([]byte((ops[0].Object.Value))))), acks.Acks[0].Version, "version did not match") - ops = server.StorageOpWrites{ - &server.StorageOpWrite{ + ops = StorageOpWrites{ + &StorageOpWrite{ OwnerID: uid.String(), Object: &api.WriteStorageObject{ Collection: "testcollection", @@ -875,7 +874,7 @@ func TestStorageWritePipelinePermissionFail(t *testing.T) { }, } - acks, code, err := server.StorageWriteObjects(context.Background(), logger, db, false, ops) + acks, code, err := StorageWriteObjects(context.Background(), logger, db, false, ops) assert.Nil(t, acks, "acks was not nil") assert.Equal(t, codes.InvalidArgument, code, "code did not match") @@ -889,8 +888,8 @@ func TestStorageFetchRuntimeGlobalPrivate(t *testing.T) { key := GenerateString() - ops := server.StorageOpWrites{ - &server.StorageOpWrite{ + ops := StorageOpWrites{ + &StorageOpWrite{ OwnerID: uuid.Nil.String(), Object: &api.WriteStorageObject{ Collection: "testcollection", @@ -902,7 +901,7 @@ func TestStorageFetchRuntimeGlobalPrivate(t *testing.T) { }, } - acks, code, err := server.StorageWriteObjects(context.Background(), logger, db, true, ops) + acks, code, err := StorageWriteObjects(context.Background(), logger, db, true, ops) assert.Nil(t, err, "err was not nil") assert.Equal(t, codes.OK, code, "code was not OK") @@ -918,7 +917,7 @@ func TestStorageFetchRuntimeGlobalPrivate(t *testing.T) { Collection: "testcollection", Key: key, }} - readData, err := server.StorageReadObjects(context.Background(), logger, db, uuid.Nil, ids) + readData, err := StorageReadObjects(context.Background(), logger, db, uuid.Nil, ids) assert.Nil(t, err, "err was not nil") assert.NotNil(t, readData, "readData was nil") @@ -937,8 +936,8 @@ func TestStorageFetchRuntimeMixed(t *testing.T) { key := GenerateString() - ops := server.StorageOpWrites{ - &server.StorageOpWrite{ + ops := StorageOpWrites{ + &StorageOpWrite{ OwnerID: uuid.Nil.String(), Object: &api.WriteStorageObject{ Collection: "testcollection", @@ -950,7 +949,7 @@ func TestStorageFetchRuntimeMixed(t *testing.T) { }, } - acks, code, err := server.StorageWriteObjects(context.Background(), logger, db, true, ops) + acks, code, err := StorageWriteObjects(context.Background(), logger, db, true, ops) assert.Nil(t, err, "err was not nil") assert.Equal(t, codes.OK, code, "code was not OK") @@ -969,7 +968,7 @@ func TestStorageFetchRuntimeMixed(t *testing.T) { Collection: "testcollection", Key: "notfound", }} - readData, err := server.StorageReadObjects(context.Background(), logger, db, uuid.Nil, ids) + readData, err := StorageReadObjects(context.Background(), logger, db, uuid.Nil, ids) assert.Nil(t, err, "err was not nil") assert.Equal(t, codes.OK, code, "code was not OK") @@ -992,8 +991,8 @@ func TestStorageFetchRuntimeUserPrivate(t *testing.T) { uid := uuid.Must(uuid.NewV4()) InsertUser(t, db, uid) - ops := server.StorageOpWrites{ - &server.StorageOpWrite{ + ops := StorageOpWrites{ + &StorageOpWrite{ OwnerID: uid.String(), Object: &api.WriteStorageObject{ Collection: "testcollection", @@ -1005,7 +1004,7 @@ func TestStorageFetchRuntimeUserPrivate(t *testing.T) { }, } - acks, code, err := server.StorageWriteObjects(context.Background(), logger, db, true, ops) + acks, code, err := StorageWriteObjects(context.Background(), logger, db, true, ops) assert.Nil(t, err, "err was not nil") assert.Equal(t, codes.OK, code, "code was not OK") @@ -1022,7 +1021,7 @@ func TestStorageFetchRuntimeUserPrivate(t *testing.T) { Key: key, UserId: uid.String(), }} - readData, err := server.StorageReadObjects(context.Background(), logger, db, uuid.Nil, ids) + readData, err := StorageReadObjects(context.Background(), logger, db, uuid.Nil, ids) assert.Nil(t, err, "err was not nil") assert.Equal(t, codes.OK, code, "code was not OK") @@ -1043,8 +1042,8 @@ func TestStorageFetchPipelineGlobalPrivate(t *testing.T) { key := GenerateString() - ops := server.StorageOpWrites{ - &server.StorageOpWrite{ + ops := StorageOpWrites{ + &StorageOpWrite{ OwnerID: uuid.Nil.String(), Object: &api.WriteStorageObject{ Collection: "testcollection", @@ -1056,7 +1055,7 @@ func TestStorageFetchPipelineGlobalPrivate(t *testing.T) { }, } - acks, code, err := server.StorageWriteObjects(context.Background(), logger, db, true, ops) + acks, code, err := StorageWriteObjects(context.Background(), logger, db, true, ops) assert.Nil(t, err, "err was not nil") assert.Equal(t, codes.OK, code, "code was not OK") @@ -1072,7 +1071,7 @@ func TestStorageFetchPipelineGlobalPrivate(t *testing.T) { Collection: "testcollection", Key: key, }} - readData, err := server.StorageReadObjects(context.Background(), logger, db, uuid.Must(uuid.NewV4()), ids) + readData, err := StorageReadObjects(context.Background(), logger, db, uuid.Must(uuid.NewV4()), ids) assert.Nil(t, err, "err was not nil") assert.Equal(t, codes.OK, code, "code was not OK") @@ -1088,8 +1087,8 @@ func TestStorageFetchPipelineUserPrivate(t *testing.T) { uid := uuid.Must(uuid.NewV4()) InsertUser(t, db, uid) - ops := server.StorageOpWrites{ - &server.StorageOpWrite{ + ops := StorageOpWrites{ + &StorageOpWrite{ OwnerID: uid.String(), Object: &api.WriteStorageObject{ Collection: "testcollection", @@ -1101,7 +1100,7 @@ func TestStorageFetchPipelineUserPrivate(t *testing.T) { }, } - acks, code, err := server.StorageWriteObjects(context.Background(), logger, db, false, ops) + acks, code, err := StorageWriteObjects(context.Background(), logger, db, false, ops) assert.Nil(t, err, "err was not nil") assert.Equal(t, codes.OK, code, "code was not OK") @@ -1118,7 +1117,7 @@ func TestStorageFetchPipelineUserPrivate(t *testing.T) { Key: key, UserId: uid.String(), }} - readData, err := server.StorageReadObjects(context.Background(), logger, db, uid, ids) + readData, err := StorageReadObjects(context.Background(), logger, db, uid, ids) assert.Nil(t, err, "err was not nil") assert.Equal(t, codes.OK, code, "code was not OK") @@ -1134,8 +1133,8 @@ func TestStorageFetchPipelineUserRead(t *testing.T) { uid := uuid.Must(uuid.NewV4()) InsertUser(t, db, uid) - ops := server.StorageOpWrites{ - &server.StorageOpWrite{ + ops := StorageOpWrites{ + &StorageOpWrite{ OwnerID: uid.String(), Object: &api.WriteStorageObject{ Collection: "testcollection", @@ -1147,7 +1146,7 @@ func TestStorageFetchPipelineUserRead(t *testing.T) { }, } - acks, code, err := server.StorageWriteObjects(context.Background(), logger, db, false, ops) + acks, code, err := StorageWriteObjects(context.Background(), logger, db, false, ops) assert.Nil(t, err, "err was not nil") assert.Equal(t, codes.OK, code, "code was not OK") @@ -1164,7 +1163,7 @@ func TestStorageFetchPipelineUserRead(t *testing.T) { Key: key, UserId: uid.String(), }} - readData, err := server.StorageReadObjects(context.Background(), logger, db, uid, ids) + readData, err := StorageReadObjects(context.Background(), logger, db, uid, ids) assert.Nil(t, err, "err was not nil") assert.Equal(t, codes.OK, code, "code was not OK") @@ -1187,8 +1186,8 @@ func TestStorageFetchPipelineUserPublic(t *testing.T) { uid := uuid.Must(uuid.NewV4()) InsertUser(t, db, uid) - ops := server.StorageOpWrites{ - &server.StorageOpWrite{ + ops := StorageOpWrites{ + &StorageOpWrite{ OwnerID: uid.String(), Object: &api.WriteStorageObject{ Collection: "testcollection", @@ -1200,7 +1199,7 @@ func TestStorageFetchPipelineUserPublic(t *testing.T) { }, } - acks, code, err := server.StorageWriteObjects(context.Background(), logger, db, false, ops) + acks, code, err := StorageWriteObjects(context.Background(), logger, db, false, ops) assert.Nil(t, err, "err was not nil") assert.Equal(t, codes.OK, code, "code was not OK") @@ -1216,7 +1215,7 @@ func TestStorageFetchPipelineUserPublic(t *testing.T) { Key: key, UserId: uid.String(), }} - readData, err := server.StorageReadObjects(context.Background(), logger, db, uid, ids) + readData, err := StorageReadObjects(context.Background(), logger, db, uid, ids) assert.Nil(t, err, "err was not nil") assert.Equal(t, codes.OK, code, "code was not OK") @@ -1239,8 +1238,8 @@ func TestStorageFetchPipelineUserOtherRead(t *testing.T) { uid := uuid.Must(uuid.NewV4()) InsertUser(t, db, uid) - ops := server.StorageOpWrites{ - &server.StorageOpWrite{ + ops := StorageOpWrites{ + &StorageOpWrite{ OwnerID: uid.String(), Object: &api.WriteStorageObject{ Collection: "testcollection", @@ -1252,7 +1251,7 @@ func TestStorageFetchPipelineUserOtherRead(t *testing.T) { }, } - acks, code, err := server.StorageWriteObjects(context.Background(), logger, db, false, ops) + acks, code, err := StorageWriteObjects(context.Background(), logger, db, false, ops) assert.Nil(t, err, "err was not nil") assert.Equal(t, codes.OK, code, "code was not OK") @@ -1269,7 +1268,7 @@ func TestStorageFetchPipelineUserOtherRead(t *testing.T) { Key: key, UserId: uid.String(), }} - readData, err := server.StorageReadObjects(context.Background(), logger, db, uuid.Must(uuid.NewV4()), ids) + readData, err := StorageReadObjects(context.Background(), logger, db, uuid.Must(uuid.NewV4()), ids) assert.Nil(t, err, "err was not nil") assert.NotNil(t, readData, "readData was nil") @@ -1284,8 +1283,8 @@ func TestStorageFetchPipelineUserOtherPublic(t *testing.T) { uid := uuid.Must(uuid.NewV4()) InsertUser(t, db, uid) - ops := server.StorageOpWrites{ - &server.StorageOpWrite{ + ops := StorageOpWrites{ + &StorageOpWrite{ OwnerID: uid.String(), Object: &api.WriteStorageObject{ Collection: "testcollection", @@ -1297,7 +1296,7 @@ func TestStorageFetchPipelineUserOtherPublic(t *testing.T) { }, } - acks, code, err := server.StorageWriteObjects(context.Background(), logger, db, false, ops) + acks, code, err := StorageWriteObjects(context.Background(), logger, db, false, ops) assert.Nil(t, err, "err was not nil") assert.Equal(t, codes.OK, code, "code was not OK") @@ -1315,7 +1314,7 @@ func TestStorageFetchPipelineUserOtherPublic(t *testing.T) { Key: key, UserId: uid.String(), }} - readData, err := server.StorageReadObjects(context.Background(), logger, db, uuid.Must(uuid.NewV4()), ids) + readData, err := StorageReadObjects(context.Background(), logger, db, uuid.Must(uuid.NewV4()), ids) assert.Nil(t, err, "err was not nil") assert.NotNil(t, readData, "readData was nil") @@ -1338,8 +1337,8 @@ func TestStorageFetchPipelineUserOtherPublicMixed(t *testing.T) { uid := uuid.Must(uuid.NewV4()) InsertUser(t, db, uid) - ops := server.StorageOpWrites{ - &server.StorageOpWrite{ + ops := StorageOpWrites{ + &StorageOpWrite{ OwnerID: uid.String(), Object: &api.WriteStorageObject{ Collection: "testcollection", @@ -1349,7 +1348,7 @@ func TestStorageFetchPipelineUserOtherPublicMixed(t *testing.T) { PermissionWrite: &wrappers.Int32Value{Value: 0}, }, }, - &server.StorageOpWrite{ + &StorageOpWrite{ OwnerID: uid.String(), Object: &api.WriteStorageObject{ Collection: "testcollection", @@ -1361,7 +1360,7 @@ func TestStorageFetchPipelineUserOtherPublicMixed(t *testing.T) { }, } - acks, code, err := server.StorageWriteObjects(context.Background(), logger, db, false, ops) + acks, code, err := StorageWriteObjects(context.Background(), logger, db, false, ops) assert.Nil(t, err, "err was not nil") assert.Equal(t, codes.OK, code, "code was not OK") @@ -1394,7 +1393,7 @@ func TestStorageFetchPipelineUserOtherPublicMixed(t *testing.T) { UserId: uid.String(), }, } - readData, err := server.StorageReadObjects(context.Background(), logger, db, uuid.Must(uuid.NewV4()), ids) + readData, err := StorageReadObjects(context.Background(), logger, db, uuid.Must(uuid.NewV4()), ids) assert.Nil(t, err, "err was not nil") assert.NotNil(t, readData, "readData was nil") @@ -1414,8 +1413,8 @@ func TestStorageRemoveRuntimeGlobalPublic(t *testing.T) { key := GenerateString() - ops := server.StorageOpWrites{ - &server.StorageOpWrite{ + ops := StorageOpWrites{ + &StorageOpWrite{ OwnerID: uuid.Nil.String(), Object: &api.WriteStorageObject{ Collection: "testcollection", @@ -1427,7 +1426,7 @@ func TestStorageRemoveRuntimeGlobalPublic(t *testing.T) { }, } - acks, code, err := server.StorageWriteObjects(context.Background(), logger, db, true, ops) + acks, code, err := StorageWriteObjects(context.Background(), logger, db, true, ops) assert.Nil(t, err, "err was not nil") assert.Equal(t, codes.OK, code, "code was not OK") @@ -1439,8 +1438,8 @@ func TestStorageRemoveRuntimeGlobalPublic(t *testing.T) { assert.Equal(t, "", acks.Acks[0].UserId, "user id was not nil") assert.EqualValues(t, []byte(fmt.Sprintf("%x", md5.Sum([]byte((ops[0].Object.Value))))), acks.Acks[0].Version, "version did not match") - deleteOps := server.StorageOpDeletes{ - &server.StorageOpDelete{ + deleteOps := StorageOpDeletes{ + &StorageOpDelete{ OwnerID: uuid.Nil.String(), ObjectID: &api.DeleteStorageObjectId{ Collection: "testcollection", @@ -1449,7 +1448,7 @@ func TestStorageRemoveRuntimeGlobalPublic(t *testing.T) { }, } - _, err = server.StorageDeleteObjects(context.Background(), logger, db, true, deleteOps) + _, err = StorageDeleteObjects(context.Background(), logger, db, true, deleteOps) assert.Nil(t, err, "err was not nil") } @@ -1459,8 +1458,8 @@ func TestStorageRemoveRuntimeGlobalPrivate(t *testing.T) { key := GenerateString() - ops := server.StorageOpWrites{ - &server.StorageOpWrite{ + ops := StorageOpWrites{ + &StorageOpWrite{ OwnerID: uuid.Nil.String(), Object: &api.WriteStorageObject{ Collection: "testcollection", @@ -1472,7 +1471,7 @@ func TestStorageRemoveRuntimeGlobalPrivate(t *testing.T) { }, } - acks, code, err := server.StorageWriteObjects(context.Background(), logger, db, true, ops) + acks, code, err := StorageWriteObjects(context.Background(), logger, db, true, ops) assert.Nil(t, err, "err was not nil") assert.Equal(t, codes.OK, code, "code was not OK") @@ -1484,8 +1483,8 @@ func TestStorageRemoveRuntimeGlobalPrivate(t *testing.T) { assert.Equal(t, "", acks.Acks[0].UserId, "user id was not nil") assert.EqualValues(t, []byte(fmt.Sprintf("%x", md5.Sum([]byte((ops[0].Object.Value))))), acks.Acks[0].Version, "version did not match") - deleteOps := server.StorageOpDeletes{ - &server.StorageOpDelete{ + deleteOps := StorageOpDeletes{ + &StorageOpDelete{ OwnerID: uuid.Nil.String(), ObjectID: &api.DeleteStorageObjectId{ Collection: "testcollection", @@ -1494,7 +1493,7 @@ func TestStorageRemoveRuntimeGlobalPrivate(t *testing.T) { }, } - _, err = server.StorageDeleteObjects(context.Background(), logger, db, true, deleteOps) + _, err = StorageDeleteObjects(context.Background(), logger, db, true, deleteOps) assert.Nil(t, err, "err was not nil") } @@ -1506,8 +1505,8 @@ func TestStorageRemoveRuntimeUserPublic(t *testing.T) { uid := uuid.Must(uuid.NewV4()) InsertUser(t, db, uid) - ops := server.StorageOpWrites{ - &server.StorageOpWrite{ + ops := StorageOpWrites{ + &StorageOpWrite{ OwnerID: uid.String(), Object: &api.WriteStorageObject{ Collection: "testcollection", @@ -1519,7 +1518,7 @@ func TestStorageRemoveRuntimeUserPublic(t *testing.T) { }, } - acks, code, err := server.StorageWriteObjects(context.Background(), logger, db, true, ops) + acks, code, err := StorageWriteObjects(context.Background(), logger, db, true, ops) assert.Nil(t, err, "err was not nil") assert.Equal(t, codes.OK, code, "code was not OK") @@ -1531,8 +1530,8 @@ func TestStorageRemoveRuntimeUserPublic(t *testing.T) { assert.EqualValues(t, uid.String(), acks.Acks[0].UserId, "user id did not match") assert.EqualValues(t, []byte(fmt.Sprintf("%x", md5.Sum([]byte((ops[0].Object.Value))))), acks.Acks[0].Version, "version did not match") - deleteOps := server.StorageOpDeletes{ - &server.StorageOpDelete{ + deleteOps := StorageOpDeletes{ + &StorageOpDelete{ OwnerID: uid.String(), ObjectID: &api.DeleteStorageObjectId{ Collection: "testcollection", @@ -1541,7 +1540,7 @@ func TestStorageRemoveRuntimeUserPublic(t *testing.T) { }, } - _, err = server.StorageDeleteObjects(context.Background(), logger, db, true, deleteOps) + _, err = StorageDeleteObjects(context.Background(), logger, db, true, deleteOps) assert.Nil(t, err, "err was not nil") } @@ -1553,8 +1552,8 @@ func TestStorageRemoveRuntimeUserPrivate(t *testing.T) { uid := uuid.Must(uuid.NewV4()) InsertUser(t, db, uid) - ops := server.StorageOpWrites{ - &server.StorageOpWrite{ + ops := StorageOpWrites{ + &StorageOpWrite{ OwnerID: uid.String(), Object: &api.WriteStorageObject{ Collection: "testcollection", @@ -1566,7 +1565,7 @@ func TestStorageRemoveRuntimeUserPrivate(t *testing.T) { }, } - acks, code, err := server.StorageWriteObjects(context.Background(), logger, db, false, ops) + acks, code, err := StorageWriteObjects(context.Background(), logger, db, false, ops) assert.Nil(t, err, "err was not nil") assert.Equal(t, codes.OK, code, "code was not OK") @@ -1578,8 +1577,8 @@ func TestStorageRemoveRuntimeUserPrivate(t *testing.T) { assert.EqualValues(t, uid.String(), acks.Acks[0].UserId, "user id did not match") assert.EqualValues(t, []byte(fmt.Sprintf("%x", md5.Sum([]byte((ops[0].Object.Value))))), acks.Acks[0].Version, "version did not match") - deleteOps := server.StorageOpDeletes{ - &server.StorageOpDelete{ + deleteOps := StorageOpDeletes{ + &StorageOpDelete{ OwnerID: uid.String(), ObjectID: &api.DeleteStorageObjectId{ Collection: "testcollection", @@ -1588,7 +1587,7 @@ func TestStorageRemoveRuntimeUserPrivate(t *testing.T) { }, } - _, err = server.StorageDeleteObjects(context.Background(), logger, db, true, deleteOps) + _, err = StorageDeleteObjects(context.Background(), logger, db, true, deleteOps) assert.Nil(t, err, "err was not nil") ids := []*api.ReadStorageObjectId{{ @@ -1597,7 +1596,7 @@ func TestStorageRemoveRuntimeUserPrivate(t *testing.T) { UserId: uid.String(), }} - readData, err := server.StorageReadObjects(context.Background(), logger, db, uuid.Nil, ids) + readData, err := StorageReadObjects(context.Background(), logger, db, uuid.Nil, ids) assert.Nil(t, err, "err was not nil") assert.Len(t, readData.Objects, 0, "data length was not 0") } @@ -1610,8 +1609,8 @@ func TestStorageRemovePipelineUserWrite(t *testing.T) { uid := uuid.Must(uuid.NewV4()) InsertUser(t, db, uid) - ops := server.StorageOpWrites{ - &server.StorageOpWrite{ + ops := StorageOpWrites{ + &StorageOpWrite{ OwnerID: uid.String(), Object: &api.WriteStorageObject{ Collection: "testcollection", @@ -1623,7 +1622,7 @@ func TestStorageRemovePipelineUserWrite(t *testing.T) { }, } - acks, code, err := server.StorageWriteObjects(context.Background(), logger, db, false, ops) + acks, code, err := StorageWriteObjects(context.Background(), logger, db, false, ops) assert.Nil(t, err, "err was not nil") assert.Equal(t, codes.OK, code, "code was not OK") @@ -1635,8 +1634,8 @@ func TestStorageRemovePipelineUserWrite(t *testing.T) { assert.EqualValues(t, uid.String(), acks.Acks[0].UserId, "user id did not match") assert.EqualValues(t, []byte(fmt.Sprintf("%x", md5.Sum([]byte((ops[0].Object.Value))))), acks.Acks[0].Version, "version did not match") - deleteOps := server.StorageOpDeletes{ - &server.StorageOpDelete{ + deleteOps := StorageOpDeletes{ + &StorageOpDelete{ OwnerID: uid.String(), ObjectID: &api.DeleteStorageObjectId{ Collection: "testcollection", @@ -1645,7 +1644,7 @@ func TestStorageRemovePipelineUserWrite(t *testing.T) { }, } - _, err = server.StorageDeleteObjects(context.Background(), logger, db, true, deleteOps) + _, err = StorageDeleteObjects(context.Background(), logger, db, true, deleteOps) assert.Nil(t, err, "err was not nil") } @@ -1657,8 +1656,8 @@ func TestStorageRemovePipelineUserDenied(t *testing.T) { uid := uuid.Must(uuid.NewV4()) InsertUser(t, db, uid) - ops := server.StorageOpWrites{ - &server.StorageOpWrite{ + ops := StorageOpWrites{ + &StorageOpWrite{ OwnerID: uid.String(), Object: &api.WriteStorageObject{ Collection: "testcollection", @@ -1670,7 +1669,7 @@ func TestStorageRemovePipelineUserDenied(t *testing.T) { }, } - acks, code, err := server.StorageWriteObjects(context.Background(), logger, db, false, ops) + acks, code, err := StorageWriteObjects(context.Background(), logger, db, false, ops) assert.Nil(t, err, "err was not nil") assert.Equal(t, codes.OK, code, "code was not OK") @@ -1682,8 +1681,8 @@ func TestStorageRemovePipelineUserDenied(t *testing.T) { assert.EqualValues(t, uid.String(), acks.Acks[0].UserId, "user id did not match") assert.EqualValues(t, []byte(fmt.Sprintf("%x", md5.Sum([]byte((ops[0].Object.Value))))), acks.Acks[0].Version, "version did not match") - deleteOps := server.StorageOpDeletes{ - &server.StorageOpDelete{ + deleteOps := StorageOpDeletes{ + &StorageOpDelete{ OwnerID: uid.String(), ObjectID: &api.DeleteStorageObjectId{ Collection: "testcollection", @@ -1692,7 +1691,7 @@ func TestStorageRemovePipelineUserDenied(t *testing.T) { }, } - code, err = server.StorageDeleteObjects(context.Background(), logger, db, false, deleteOps) + code, err = StorageDeleteObjects(context.Background(), logger, db, false, deleteOps) assert.NotNil(t, err, "err was nil") assert.Equal(t, code, codes.InvalidArgument, "code did not match InvalidArgument.") } @@ -1701,8 +1700,8 @@ func TestStorageRemoveRuntimeGlobalIfMatchNotExists(t *testing.T) { db := NewDB(t) defer db.Close() - deleteOps := server.StorageOpDeletes{ - &server.StorageOpDelete{ + deleteOps := StorageOpDeletes{ + &StorageOpDelete{ OwnerID: uuid.Nil.String(), ObjectID: &api.DeleteStorageObjectId{ Collection: "testcollection", @@ -1712,7 +1711,7 @@ func TestStorageRemoveRuntimeGlobalIfMatchNotExists(t *testing.T) { }, } - code, err := server.StorageDeleteObjects(context.Background(), logger, db, true, deleteOps) + code, err := StorageDeleteObjects(context.Background(), logger, db, true, deleteOps) assert.NotNil(t, err, "err was nil") assert.Equal(t, code, codes.InvalidArgument, "code did not match InvalidArgument.") } @@ -1723,8 +1722,8 @@ func TestStorageRemoveRuntimeGlobalIfMatchRejected(t *testing.T) { key := GenerateString() - ops := server.StorageOpWrites{ - &server.StorageOpWrite{ + ops := StorageOpWrites{ + &StorageOpWrite{ OwnerID: uuid.Nil.String(), Object: &api.WriteStorageObject{ Collection: "testcollection", @@ -1736,7 +1735,7 @@ func TestStorageRemoveRuntimeGlobalIfMatchRejected(t *testing.T) { }, } - acks, code, err := server.StorageWriteObjects(context.Background(), logger, db, true, ops) + acks, code, err := StorageWriteObjects(context.Background(), logger, db, true, ops) assert.Nil(t, err, "err was not nil") assert.Equal(t, codes.OK, code, "code was not OK") @@ -1748,8 +1747,8 @@ func TestStorageRemoveRuntimeGlobalIfMatchRejected(t *testing.T) { assert.EqualValues(t, "", acks.Acks[0].UserId, "user id did not match") assert.EqualValues(t, []byte(fmt.Sprintf("%x", md5.Sum([]byte((ops[0].Object.Value))))), acks.Acks[0].Version, "version did not match") - deleteOps := server.StorageOpDeletes{ - &server.StorageOpDelete{ + deleteOps := StorageOpDeletes{ + &StorageOpDelete{ OwnerID: uuid.Nil.String(), ObjectID: &api.DeleteStorageObjectId{ Collection: "testcollection", @@ -1759,7 +1758,7 @@ func TestStorageRemoveRuntimeGlobalIfMatchRejected(t *testing.T) { }, } - code, err = server.StorageDeleteObjects(context.Background(), logger, db, true, deleteOps) + code, err = StorageDeleteObjects(context.Background(), logger, db, true, deleteOps) assert.NotNil(t, err, "err was not nil") assert.Equal(t, code, codes.InvalidArgument, "code did not match InvalidArgument.") } @@ -1770,8 +1769,8 @@ func TestStorageRemoveRuntimeGlobalIfMatch(t *testing.T) { key := GenerateString() - ops := server.StorageOpWrites{ - &server.StorageOpWrite{ + ops := StorageOpWrites{ + &StorageOpWrite{ OwnerID: uuid.Nil.String(), Object: &api.WriteStorageObject{ Collection: "testcollection", @@ -1783,7 +1782,7 @@ func TestStorageRemoveRuntimeGlobalIfMatch(t *testing.T) { }, } - acks, code, err := server.StorageWriteObjects(context.Background(), logger, db, true, ops) + acks, code, err := StorageWriteObjects(context.Background(), logger, db, true, ops) assert.Nil(t, err, "err was not nil") assert.Equal(t, codes.OK, code, "code was not OK") @@ -1795,8 +1794,8 @@ func TestStorageRemoveRuntimeGlobalIfMatch(t *testing.T) { assert.EqualValues(t, "", acks.Acks[0].UserId, "user id did not match") assert.EqualValues(t, []byte(fmt.Sprintf("%x", md5.Sum([]byte((ops[0].Object.Value))))), acks.Acks[0].Version, "version did not match") - deleteOps := server.StorageOpDeletes{ - &server.StorageOpDelete{ + deleteOps := StorageOpDeletes{ + &StorageOpDelete{ OwnerID: uuid.Nil.String(), ObjectID: &api.DeleteStorageObjectId{ Collection: "testcollection", @@ -1806,7 +1805,7 @@ func TestStorageRemoveRuntimeGlobalIfMatch(t *testing.T) { }, } - code, err = server.StorageDeleteObjects(context.Background(), logger, db, true, deleteOps) + code, err = StorageDeleteObjects(context.Background(), logger, db, true, deleteOps) assert.Nil(t, err, "err was not nil") assert.Equal(t, code, codes.OK, "code did not match OK.") } @@ -1818,8 +1817,8 @@ func TestStorageListRuntimeUser(t *testing.T) { uid := uuid.Must(uuid.NewV4()) InsertUser(t, db, uid) - ops := server.StorageOpWrites{ - &server.StorageOpWrite{ + ops := StorageOpWrites{ + &StorageOpWrite{ OwnerID: uid.String(), Object: &api.WriteStorageObject{ Collection: "testcollection", @@ -1829,7 +1828,7 @@ func TestStorageListRuntimeUser(t *testing.T) { PermissionWrite: &wrappers.Int32Value{Value: 1}, }, }, - &server.StorageOpWrite{ + &StorageOpWrite{ OwnerID: uid.String(), Object: &api.WriteStorageObject{ Collection: "testcollection", @@ -1839,7 +1838,7 @@ func TestStorageListRuntimeUser(t *testing.T) { PermissionWrite: &wrappers.Int32Value{Value: 0}, }, }, - &server.StorageOpWrite{ + &StorageOpWrite{ OwnerID: uid.String(), Object: &api.WriteStorageObject{ Collection: "testcollection", @@ -1851,14 +1850,14 @@ func TestStorageListRuntimeUser(t *testing.T) { }, } - acks, code, err := server.StorageWriteObjects(context.Background(), logger, db, false, ops) + acks, code, err := StorageWriteObjects(context.Background(), logger, db, false, ops) assert.Nil(t, err, "err was not nil") assert.Equal(t, codes.OK, code, "code was not OK") assert.NotNil(t, acks, "acks was nil") assert.Len(t, acks.Acks, 3, "acks length was not 3") - list, code, err := server.StorageListObjects(context.Background(), logger, db, uuid.Nil, &uid, "testcollection", 10, "") + list, code, err := StorageListObjects(context.Background(), logger, db, uuid.Nil, &uid, "testcollection", 10, "") assert.Nil(t, err, "err was not nil") assert.Equal(t, codes.OK, code, "code was not OK") @@ -1875,8 +1874,8 @@ func TestStorageListPipelineUserSelf(t *testing.T) { InsertUser(t, db, uid) collection := GenerateString() - ops := server.StorageOpWrites{ - &server.StorageOpWrite{ + ops := StorageOpWrites{ + &StorageOpWrite{ OwnerID: uid.String(), Object: &api.WriteStorageObject{ Collection: collection, @@ -1886,7 +1885,7 @@ func TestStorageListPipelineUserSelf(t *testing.T) { PermissionWrite: &wrappers.Int32Value{Value: 1}, }, }, - &server.StorageOpWrite{ + &StorageOpWrite{ OwnerID: uid.String(), Object: &api.WriteStorageObject{ Collection: collection, @@ -1896,7 +1895,7 @@ func TestStorageListPipelineUserSelf(t *testing.T) { PermissionWrite: &wrappers.Int32Value{Value: 0}, }, }, - &server.StorageOpWrite{ + &StorageOpWrite{ OwnerID: uid.String(), Object: &api.WriteStorageObject{ Collection: collection, @@ -1908,14 +1907,14 @@ func TestStorageListPipelineUserSelf(t *testing.T) { }, } - acks, code, err := server.StorageWriteObjects(context.Background(), logger, db, false, ops) + acks, code, err := StorageWriteObjects(context.Background(), logger, db, false, ops) assert.Nil(t, err, "err was not nil") assert.Equal(t, codes.OK, code, "code was not OK") assert.NotNil(t, acks, "acks was nil") assert.Len(t, acks.Acks, 3, "acks length was not 3") - list, code, err := server.StorageListObjects(context.Background(), logger, db, uid, &uid, collection, 10, "") + list, code, err := StorageListObjects(context.Background(), logger, db, uid, &uid, collection, 10, "") assert.Nil(t, err, "err was not nil") assert.Equal(t, codes.OK, code, "code was not OK") @@ -1934,8 +1933,8 @@ func TestStorageListPipelineUserOther(t *testing.T) { InsertUser(t, db, uid) collection := GenerateString() - ops := server.StorageOpWrites{ - &server.StorageOpWrite{ + ops := StorageOpWrites{ + &StorageOpWrite{ OwnerID: uid.String(), Object: &api.WriteStorageObject{ Collection: collection, @@ -1945,7 +1944,7 @@ func TestStorageListPipelineUserOther(t *testing.T) { PermissionWrite: &wrappers.Int32Value{Value: 1}, }, }, - &server.StorageOpWrite{ + &StorageOpWrite{ OwnerID: uid.String(), Object: &api.WriteStorageObject{ Collection: collection, @@ -1955,7 +1954,7 @@ func TestStorageListPipelineUserOther(t *testing.T) { PermissionWrite: &wrappers.Int32Value{Value: 0}, }, }, - &server.StorageOpWrite{ + &StorageOpWrite{ OwnerID: uid.String(), Object: &api.WriteStorageObject{ Collection: collection, @@ -1967,14 +1966,14 @@ func TestStorageListPipelineUserOther(t *testing.T) { }, } - acks, code, err := server.StorageWriteObjects(context.Background(), logger, db, false, ops) + acks, code, err := StorageWriteObjects(context.Background(), logger, db, false, ops) assert.Nil(t, err, "err was not nil") assert.Equal(t, codes.OK, code, "code was not OK") assert.NotNil(t, acks, "acks was nil") assert.Len(t, acks.Acks, 3, "acks length was not 3") - values, code, err := server.StorageListObjects(context.Background(), logger, db, uuid.Must(uuid.NewV4()), &uid, collection, 10, "") + values, code, err := StorageListObjects(context.Background(), logger, db, uuid.Must(uuid.NewV4()), &uid, collection, 10, "") assert.Nil(t, err, "err was not nil") assert.Equal(t, codes.OK, code, "code was not OK") @@ -1991,8 +1990,8 @@ func TestStorageListNoRepeats(t *testing.T) { InsertUser(t, db, uid) collection := GenerateString() - ops := server.StorageOpWrites{ - &server.StorageOpWrite{ + ops := StorageOpWrites{ + &StorageOpWrite{ OwnerID: uid.String(), Object: &api.WriteStorageObject{ Collection: collection, @@ -2002,7 +2001,7 @@ func TestStorageListNoRepeats(t *testing.T) { PermissionWrite: &wrappers.Int32Value{Value: 1}, }, }, - &server.StorageOpWrite{ + &StorageOpWrite{ OwnerID: uid.String(), Object: &api.WriteStorageObject{ Collection: collection, @@ -2012,7 +2011,7 @@ func TestStorageListNoRepeats(t *testing.T) { PermissionWrite: &wrappers.Int32Value{Value: 1}, }, }, - &server.StorageOpWrite{ + &StorageOpWrite{ OwnerID: uid.String(), Object: &api.WriteStorageObject{ Collection: collection, @@ -2022,7 +2021,7 @@ func TestStorageListNoRepeats(t *testing.T) { PermissionWrite: &wrappers.Int32Value{Value: 1}, }, }, - &server.StorageOpWrite{ + &StorageOpWrite{ OwnerID: uid.String(), Object: &api.WriteStorageObject{ Collection: collection, @@ -2032,7 +2031,7 @@ func TestStorageListNoRepeats(t *testing.T) { PermissionWrite: &wrappers.Int32Value{Value: 1}, }, }, - &server.StorageOpWrite{ + &StorageOpWrite{ OwnerID: uid.String(), Object: &api.WriteStorageObject{ Collection: collection, @@ -2042,7 +2041,7 @@ func TestStorageListNoRepeats(t *testing.T) { PermissionWrite: &wrappers.Int32Value{Value: 1}, }, }, - &server.StorageOpWrite{ + &StorageOpWrite{ OwnerID: uid.String(), Object: &api.WriteStorageObject{ Collection: collection, @@ -2052,7 +2051,7 @@ func TestStorageListNoRepeats(t *testing.T) { PermissionWrite: &wrappers.Int32Value{Value: 1}, }, }, - &server.StorageOpWrite{ + &StorageOpWrite{ OwnerID: uid.String(), Object: &api.WriteStorageObject{ Collection: collection, @@ -2064,14 +2063,14 @@ func TestStorageListNoRepeats(t *testing.T) { }, } - acks, code, err := server.StorageWriteObjects(context.Background(), logger, db, false, ops) + acks, code, err := StorageWriteObjects(context.Background(), logger, db, false, ops) assert.Nil(t, err, "err was not nil") assert.Equal(t, codes.OK, code, "code was not OK") assert.NotNil(t, acks, "acks was nil") assert.Len(t, acks.Acks, 7, "acks length was not 7") - values, code, err := server.StorageListObjects(context.Background(), logger, db, uuid.Must(uuid.NewV4()), &uid, collection, 10, "") + values, code, err := StorageListObjects(context.Background(), logger, db, uuid.Must(uuid.NewV4()), &uid, collection, 10, "") assert.Nil(t, err, "err was not nil") assert.Equal(t, codes.OK, code, "code was not OK") diff --git a/tests/core_wallet_test.go b/server/core_wallet_test.go similarity index 50% rename from tests/core_wallet_test.go rename to server/core_wallet_test.go index b8ec380f6..9a4a537ee 100644 --- a/tests/core_wallet_test.go +++ b/server/core_wallet_test.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package tests +package server import ( "context" @@ -21,140 +21,139 @@ import ( "github.com/gofrs/uuid" "github.com/heroiclabs/nakama-common/runtime" - "github.com/heroiclabs/nakama/v2/server" "github.com/stretchr/testify/assert" ) func TestUpdateWalletSingleUser(t *testing.T) { - values := []float64{ - 34.01, - 7.41, - 70.86, - 35.11, - 2.68, - 5.55, - 32.05, - 48.07, - 12.07, - 6.62, - 6.86, - 3.94, - 2.05, - 3.87, - 2.38, - 17.42, - 20.79, - 1.58, - 2.5, - 3.7, - 14.88, - 17.51, - 10.91, - 19.6, - 9.98, - 7.86, - 33.11, - 13.58, - 306.74, - 4.9, - 5.11, - 19.15, - 10.28, - 25.51, - 3.69, - 13.21, - 4.93, - 4.4, - 135.13, - 22.83, - 2.17, + values := []int64{ + 34, + 7, + 70, + 35, + 2, + 5, + 32, + 48, + 12, + 6, + 6, + 3, + 2, + 3, + 2, + 17, + 20, + 1, + 2, + 3, + 14, + 17, + 10, + 19, + 9, + 7, + 33, + 13, + 306, + 4, + 5, + 19, + 10, + 25, + 3, + 13, + 4, + 4, + 135, + 22, + 2, } db := NewDB(t) - nk := server.NewRuntimeGoNakamaModule(logger, db, nil, config, nil, nil, nil, nil, nil, nil, nil, nil, nil) + nk := NewRuntimeGoNakamaModule(logger, db, nil, cfg, nil, nil, nil, nil, nil, nil, nil, nil, nil) - userID, _, _, err := server.AuthenticateCustom(context.Background(), logger, db, uuid.Must(uuid.NewV4()).String(), uuid.Must(uuid.NewV4()).String(), true) + userID, _, _, err := AuthenticateCustom(context.Background(), logger, db, uuid.Must(uuid.NewV4()).String(), uuid.Must(uuid.NewV4()).String(), true) if err != nil { t.Fatalf("error creating user: %v", err.Error()) } for _, val := range values { - err := nk.WalletUpdate(context.Background(), userID, map[string]interface{}{"value": val}, nil, true) + _, _, err := nk.WalletUpdate(context.Background(), userID, map[string]int64{"value": val}, nil, true) if err != nil { t.Fatalf("error updating wallet: %v", err.Error()) } } - account, _, err := server.GetAccount(context.Background(), logger, db, nil, uuid.FromStringOrNil(userID)) + account, err := GetAccount(context.Background(), logger, db, nil, uuid.FromStringOrNil(userID)) if err != nil { t.Fatalf("error getting user: %v", err.Error()) } assert.NotNil(t, account, "account is nil") - var wallet map[string]interface{} + var wallet map[string]int64 err = json.Unmarshal([]byte(account.Wallet), &wallet) if err != nil { t.Fatalf("json unmarshal error: %v", err.Error()) } assert.Contains(t, wallet, "value", "wallet did not contain value") - assert.IsType(t, float64(0), wallet["value"], "wallet value was not float64") - assert.Equal(t, float64(1005), wallet["value"].(float64), "wallet value did not match") + assert.IsType(t, int64(0), wallet["value"], "wallet value was not int64") + assert.Equal(t, int64(984), wallet["value"], "wallet value did not match") } func TestUpdateWalletMultiUser(t *testing.T) { - values := []float64{ - 34.01, - 7.41, - 70.86, - 35.11, - 2.68, - 5.55, - 32.05, - 48.07, - 12.07, - 6.62, - 6.86, - 3.94, - 2.05, - 3.87, - 2.38, - 17.42, - 20.79, - 1.58, - 2.5, - 3.7, - 14.88, - 17.51, - 10.91, - 19.6, - 9.98, - 7.86, - 33.11, - 13.58, - 306.74, - 4.9, - 5.11, - 19.15, - 10.28, - 25.51, - 3.69, - 13.21, - 4.93, - 4.4, - 135.13, - 22.83, - 2.17, + values := []int64{ + 34, + 7, + 70, + 35, + 2, + 5, + 32, + 48, + 12, + 6, + 6, + 3, + 2, + 3, + 2, + 17, + 20, + 1, + 2, + 3, + 14, + 17, + 10, + 19, + 9, + 7, + 33, + 13, + 306, + 4, + 5, + 19, + 10, + 25, + 3, + 13, + 4, + 4, + 135, + 22, + 2, } db := NewDB(t) - nk := server.NewRuntimeGoNakamaModule(logger, db, nil, config, nil, nil, nil, nil, nil, nil, nil, nil, nil) + nk := NewRuntimeGoNakamaModule(logger, db, nil, cfg, nil, nil, nil, nil, nil, nil, nil, nil, nil) count := 5 userIDs := make([]string, 0, count) for i := 0; i < count; i++ { - userID, _, _, err := server.AuthenticateCustom(context.Background(), logger, db, uuid.Must(uuid.NewV4()).String(), uuid.Must(uuid.NewV4()).String(), true) + userID, _, _, err := AuthenticateCustom(context.Background(), logger, db, uuid.Must(uuid.NewV4()).String(), uuid.Must(uuid.NewV4()).String(), true) if err != nil { t.Fatalf("error creating user: %v", err.Error()) } @@ -163,7 +162,7 @@ func TestUpdateWalletMultiUser(t *testing.T) { for _, val := range values { for _, userID := range userIDs { - err := nk.WalletUpdate(context.Background(), userID, map[string]interface{}{"value": val}, nil, true) + _, _, err := nk.WalletUpdate(context.Background(), userID, map[string]int64{"value": val}, nil, true) if err != nil { t.Fatalf("error updating wallet: %v", err.Error()) } @@ -171,77 +170,77 @@ func TestUpdateWalletMultiUser(t *testing.T) { } for _, userID := range userIDs { - account, _, err := server.GetAccount(context.Background(), logger, db, nil, uuid.FromStringOrNil(userID)) + account, err := GetAccount(context.Background(), logger, db, nil, uuid.FromStringOrNil(userID)) if err != nil { t.Fatalf("error getting user: %v", err.Error()) } assert.NotNil(t, account, "account is nil") - var wallet map[string]interface{} + var wallet map[string]int64 err = json.Unmarshal([]byte(account.Wallet), &wallet) if err != nil { t.Fatalf("json unmarshal error: %v", err.Error()) } assert.Contains(t, wallet, "value", "wallet did not contain value") - assert.IsType(t, float64(0), wallet["value"], "wallet value was not float64") - assert.Equal(t, float64(1005), wallet["value"].(float64), "wallet value did not match") + assert.IsType(t, int64(0), wallet["value"], "wallet value was not int64") + assert.Equal(t, int64(984), wallet["value"], "wallet value did not match") } } func TestUpdateWalletsMultiUser(t *testing.T) { - values := []float64{ - 34.01, - 7.41, - 70.86, - 35.11, - 2.68, - 5.55, - 32.05, - 48.07, - 12.07, - 6.62, - 6.86, - 3.94, - 2.05, - 3.87, - 2.38, - 17.42, - 20.79, - 1.58, - 2.5, - 3.7, - 14.88, - 17.51, - 10.91, - 19.6, - 9.98, - 7.86, - 33.11, - 13.58, - 306.74, - 4.9, - 5.11, - 19.15, - 10.28, - 25.51, - 3.69, - 13.21, - 4.93, - 4.4, - 135.13, - 22.83, - 2.17, + values := []int64{ + 34, + 7, + 70, + 35, + 2, + 5, + 32, + 48, + 12, + 6, + 6, + 3, + 2, + 3, + 2, + 17, + 20, + 1, + 2, + 3, + 14, + 17, + 10, + 19, + 9, + 7, + 33, + 13, + 306, + 4, + 5, + 19, + 10, + 25, + 3, + 13, + 4, + 4, + 135, + 22, + 2, } db := NewDB(t) - nk := server.NewRuntimeGoNakamaModule(logger, db, nil, config, nil, nil, nil, nil, nil, nil, nil, nil, nil) + nk := NewRuntimeGoNakamaModule(logger, db, nil, cfg, nil, nil, nil, nil, nil, nil, nil, nil, nil) count := 5 userIDs := make([]string, 0, count) for i := 0; i < count; i++ { - userID, _, _, err := server.AuthenticateCustom(context.Background(), logger, db, uuid.Must(uuid.NewV4()).String(), uuid.Must(uuid.NewV4()).String(), true) + userID, _, _, err := AuthenticateCustom(context.Background(), logger, db, uuid.Must(uuid.NewV4()).String(), uuid.Must(uuid.NewV4()).String(), true) if err != nil { t.Fatalf("error creating user: %v", err.Error()) } @@ -253,87 +252,87 @@ func TestUpdateWalletsMultiUser(t *testing.T) { for _, userID := range userIDs { updates = append(updates, &runtime.WalletUpdate{ UserID: userID, - Changeset: map[string]interface{}{"value": val}, + Changeset: map[string]int64{"value": val}, }) } - err := nk.WalletsUpdate(context.Background(), updates, true) + _, err := nk.WalletsUpdate(context.Background(), updates, true) if err != nil { t.Fatalf("error updating wallets: %v", err.Error()) } } for _, userID := range userIDs { - account, _, err := server.GetAccount(context.Background(), logger, db, nil, uuid.FromStringOrNil(userID)) + account, err := GetAccount(context.Background(), logger, db, nil, uuid.FromStringOrNil(userID)) if err != nil { t.Fatalf("error getting user: %v", err.Error()) } assert.NotNil(t, account, "account is nil") - var wallet map[string]interface{} + var wallet map[string]int64 err = json.Unmarshal([]byte(account.Wallet), &wallet) if err != nil { t.Fatalf("json unmarshal error: %v", err.Error()) } assert.Contains(t, wallet, "value", "wallet did not contain value") - assert.IsType(t, float64(0), wallet["value"], "wallet value was not float64") - assert.Equal(t, float64(1005), wallet["value"].(float64), "wallet value did not match") + assert.IsType(t, int64(0), wallet["value"], "wallet value was not int64") + assert.Equal(t, int64(984), wallet["value"], "wallet value did not match") } } func TestUpdateWalletsMultiUserSharedChangeset(t *testing.T) { - values := []float64{ - 34.01, - 7.41, - 70.86, - 35.11, - 2.68, - 5.55, - 32.05, - 48.07, - 12.07, - 6.62, - 6.86, - 3.94, - 2.05, - 3.87, - 2.38, - 17.42, - 20.79, - 1.58, - 2.5, - 3.7, - 14.88, - 17.51, - 10.91, - 19.6, - 9.98, - 7.86, - 33.11, - 13.58, - 306.74, - 4.9, - 5.11, - 19.15, - 10.28, - 25.51, - 3.69, - 13.21, - 4.93, - 4.4, - 135.13, - 22.83, - 2.17, + values := []int64{ + 34, + 7, + 70, + 35, + 2, + 5, + 32, + 48, + 12, + 6, + 6, + 3, + 2, + 3, + 2, + 17, + 20, + 1, + 2, + 3, + 14, + 17, + 10, + 19, + 9, + 7, + 33, + 13, + 306, + 4, + 5, + 19, + 10, + 25, + 3, + 13, + 4, + 4, + 135, + 22, + 2, } db := NewDB(t) - nk := server.NewRuntimeGoNakamaModule(logger, db, nil, config, nil, nil, nil, nil, nil, nil, nil, nil, nil) + nk := NewRuntimeGoNakamaModule(logger, db, nil, cfg, nil, nil, nil, nil, nil, nil, nil, nil, nil) count := 5 userIDs := make([]string, 0, count) for i := 0; i < count; i++ { - userID, _, _, err := server.AuthenticateCustom(context.Background(), logger, db, uuid.Must(uuid.NewV4()).String(), uuid.Must(uuid.NewV4()).String(), true) + userID, _, _, err := AuthenticateCustom(context.Background(), logger, db, uuid.Must(uuid.NewV4()).String(), uuid.Must(uuid.NewV4()).String(), true) if err != nil { t.Fatalf("error creating user: %v", err.Error()) } @@ -341,7 +340,7 @@ func TestUpdateWalletsMultiUserSharedChangeset(t *testing.T) { } for _, val := range values { - changeset := map[string]interface{}{"value": val} + changeset := map[string]int64{"value": val} updates := make([]*runtime.WalletUpdate, 0, len(userIDs)) for _, userID := range userIDs { updates = append(updates, &runtime.WalletUpdate{ @@ -349,96 +348,96 @@ func TestUpdateWalletsMultiUserSharedChangeset(t *testing.T) { Changeset: changeset, }) } - err := nk.WalletsUpdate(context.Background(), updates, true) + _, err := nk.WalletsUpdate(context.Background(), updates, true) if err != nil { t.Fatalf("error updating wallets: %v", err.Error()) } } for _, userID := range userIDs { - account, _, err := server.GetAccount(context.Background(), logger, db, nil, uuid.FromStringOrNil(userID)) + account, err := GetAccount(context.Background(), logger, db, nil, uuid.FromStringOrNil(userID)) if err != nil { t.Fatalf("error getting user: %v", err.Error()) } assert.NotNil(t, account, "account is nil") - var wallet map[string]interface{} + var wallet map[string]int64 err = json.Unmarshal([]byte(account.Wallet), &wallet) if err != nil { t.Fatalf("json unmarshal error: %v", err.Error()) } assert.Contains(t, wallet, "value", "wallet did not contain value") - assert.IsType(t, float64(0), wallet["value"], "wallet value was not float64") - assert.Equal(t, float64(1005), wallet["value"].(float64), "wallet value did not match") + assert.IsType(t, int64(0), wallet["value"], "wallet value was not int64") + assert.Equal(t, int64(984), wallet["value"], "wallet value did not match") } } func TestUpdateWalletsMultiUserSharedChangesetDeductions(t *testing.T) { - values := []float64{ - 34.01, - -34.01, - 7.41, - -7.41, - 70.86, - -70.86, - 35.11, - -35.11, - 2.68, - 5.55, - 32.05, - -40.28, - 48.07, - -48.07, - 12.07, - -12.07, - 6.62, - 6.86, - -13.48, - 3.94, - 2.05, - 3.87, - 2.38, - 17.42, - -29.66, - 20.79, - -20.79, - 1.58, - 2.5, - 3.7, - 14.88, - 17.51, - -40.17, - 10.91, - 19.6, - -30.51, - 9.98, - 7.86, - 33.11, - -50.95, - 13.58, - -13.58, - 306.74, - -306.74, + values := []int64{ + 34, + -34, + 7, + -7, + 70, + -70, + 35, + -35, + 2, + 5, + 33, + -40, + 48, + -48, + 12, + -12, + 6, + 7, + -13, + 3, + 2, + 3, + 2, + 19, + -29, + 20, + -20, + 1, + 2, + 3, + 15, + 19, + -40, + 11, + 19, + -30, + 9, + 7, + 34, + -50, + 13, + -13, + 306, + -306, } db := NewDB(t) - nk := server.NewRuntimeGoNakamaModule(logger, db, nil, config, nil, nil, nil, nil, nil, nil, nil, nil, nil) + nk := NewRuntimeGoNakamaModule(logger, db, nil, cfg, nil, nil, nil, nil, nil, nil, nil, nil, nil) count := 5 userIDs := make([]string, 0, count) for i := 0; i < count; i++ { - userID, _, _, err := server.AuthenticateCustom(context.Background(), logger, db, uuid.Must(uuid.NewV4()).String(), uuid.Must(uuid.NewV4()).String(), true) + userID, _, _, err := AuthenticateCustom(context.Background(), logger, db, uuid.Must(uuid.NewV4()).String(), uuid.Must(uuid.NewV4()).String(), true) if err != nil { t.Fatalf("error creating user: %v", err.Error()) } userIDs = append(userIDs, userID) } - foo := float64(1) + foo := int64(1) for _, val := range values { - changeset := map[string]interface{}{"value": val, "foo": foo} + changeset := map[string]int64{"value": val, "foo": foo} updates := make([]*runtime.WalletUpdate, 0, len(userIDs)) for _, userID := range userIDs { updates = append(updates, &runtime.WalletUpdate{ @@ -446,7 +445,7 @@ func TestUpdateWalletsMultiUserSharedChangesetDeductions(t *testing.T) { Changeset: changeset, }) } - err := nk.WalletsUpdate(context.Background(), updates, true) + _, err := nk.WalletsUpdate(context.Background(), updates, true) if err != nil { t.Fatalf("error updating wallets: %v", err.Error()) } @@ -458,30 +457,30 @@ func TestUpdateWalletsMultiUserSharedChangesetDeductions(t *testing.T) { } for _, userID := range userIDs { - account, _, err := server.GetAccount(context.Background(), logger, db, nil, uuid.FromStringOrNil(userID)) + account, err := GetAccount(context.Background(), logger, db, nil, uuid.FromStringOrNil(userID)) if err != nil { t.Fatalf("error getting user: %v", err.Error()) } assert.NotNil(t, account, "account is nil") - var wallet map[string]interface{} + var wallet map[string]int64 err = json.Unmarshal([]byte(account.Wallet), &wallet) if err != nil { t.Fatalf("json unmarshal error: %v", err.Error()) } assert.Contains(t, wallet, "value", "wallet did not contain value") - assert.IsType(t, float64(0), wallet["value"], "wallet value was not float64") - assert.Equal(t, float64(0), wallet["value"].(float64), "wallet value did not match") + assert.IsType(t, int64(0), wallet["value"], "wallet value was not int64") + assert.Equal(t, int64(0), wallet["value"], "wallet value did not match") } } func TestUpdateWalletsSingleUser(t *testing.T) { db := NewDB(t) - nk := server.NewRuntimeGoNakamaModule(logger, db, nil, config, nil, nil, nil, nil, nil, nil, nil, nil, nil) + nk := NewRuntimeGoNakamaModule(logger, db, nil, cfg, nil, nil, nil, nil, nil, nil, nil, nil, nil) - userID, _, _, err := server.AuthenticateCustom(context.Background(), logger, db, uuid.Must(uuid.NewV4()).String(), uuid.Must(uuid.NewV4()).String(), true) + userID, _, _, err := AuthenticateCustom(context.Background(), logger, db, uuid.Must(uuid.NewV4()).String(), uuid.Must(uuid.NewV4()).String(), true) if err != nil { t.Fatalf("error creating user: %v", err.Error()) } @@ -489,24 +488,24 @@ func TestUpdateWalletsSingleUser(t *testing.T) { updates := []*runtime.WalletUpdate{ { UserID: userID, - Changeset: map[string]interface{}{"value": float64(1)}, + Changeset: map[string]int64{"value": 1}, }, { UserID: userID, - Changeset: map[string]interface{}{"value": float64(2)}, + Changeset: map[string]int64{"value": 2}, }, { UserID: userID, - Changeset: map[string]interface{}{"value": float64(3)}, + Changeset: map[string]int64{"value": 3}, }, } - err = nk.WalletsUpdate(context.Background(), updates, true) + _, err = nk.WalletsUpdate(context.Background(), updates, true) if err != nil { t.Fatalf("error updating wallets: %v", err.Error()) } - account, _, err := server.GetAccount(context.Background(), logger, db, nil, uuid.FromStringOrNil(userID)) + account, err := GetAccount(context.Background(), logger, db, nil, uuid.FromStringOrNil(userID)) if err != nil { t.Fatalf("error getting user: %v", err.Error()) } @@ -526,27 +525,27 @@ func TestUpdateWalletsSingleUser(t *testing.T) { func TestUpdateWalletRepeatedSingleUser(t *testing.T) { db := NewDB(t) - nk := server.NewRuntimeGoNakamaModule(logger, db, nil, config, nil, nil, nil, nil, nil, nil, nil, nil, nil) + nk := NewRuntimeGoNakamaModule(logger, db, nil, cfg, nil, nil, nil, nil, nil, nil, nil, nil, nil) - userID, _, _, err := server.AuthenticateCustom(context.Background(), logger, db, uuid.Must(uuid.NewV4()).String(), uuid.Must(uuid.NewV4()).String(), true) + userID, _, _, err := AuthenticateCustom(context.Background(), logger, db, uuid.Must(uuid.NewV4()).String(), uuid.Must(uuid.NewV4()).String(), true) if err != nil { t.Fatalf("error creating user: %v", err.Error()) } - err = nk.WalletUpdate(context.Background(), userID, map[string]interface{}{"value": float64(1)}, nil, false) + _, _, err = nk.WalletUpdate(context.Background(), userID, map[string]int64{"value": 1}, nil, false) if err != nil { t.Fatalf("error updating wallet: %v", err.Error()) } - err = nk.WalletUpdate(context.Background(), userID, map[string]interface{}{"value": float64(2)}, nil, false) + _, _, err = nk.WalletUpdate(context.Background(), userID, map[string]int64{"value": 2}, nil, false) if err != nil { t.Fatalf("error updating wallet: %v", err.Error()) } - err = nk.WalletUpdate(context.Background(), userID, map[string]interface{}{"value": float64(3)}, nil, false) + _, _, err = nk.WalletUpdate(context.Background(), userID, map[string]int64{"value": 3}, nil, false) if err != nil { t.Fatalf("error updating wallet: %v", err.Error()) } - account, _, err := server.GetAccount(context.Background(), logger, db, nil, uuid.FromStringOrNil(userID)) + account, err := GetAccount(context.Background(), logger, db, nil, uuid.FromStringOrNil(userID)) if err != nil { t.Fatalf("error getting user: %v", err.Error()) } diff --git a/server/leaderboard_rank_cache.go b/server/leaderboard_rank_cache.go index 70ef9ba84..50d537e3b 100644 --- a/server/leaderboard_rank_cache.go +++ b/server/leaderboard_rank_cache.go @@ -16,7 +16,7 @@ package server import ( "database/sql" - "sort" + "github.com/heroiclabs/nakama/v2/internal/skiplist" "sync" "time" @@ -35,62 +35,77 @@ type LeaderboardRankCache interface { TrimExpired(nowUnix int64) bool } -type RankData struct { +type LeaderboardWithExpiry struct { + LeaderboardId string + Expiry int64 +} + +type RankAsc struct { OwnerId uuid.UUID Score int64 Subscore int64 - Rank int64 } -type RankMap struct { - sync.RWMutex - Ranks []*RankData - Haystack map[uuid.UUID]*RankData - SortOrder int +func (r *RankAsc) Less(other interface{}) bool { + ro := other.(*RankAsc) + if r.Score < ro.Score { + return true + } + if r.Subscore > ro.Subscore { + return false + } + if r.Subscore < ro.Subscore { + return true + } + if r.Subscore > ro.Subscore { + return false + } + return r.OwnerId.String() < ro.OwnerId.String() } -func (r *RankMap) Len() int { - return len(r.Ranks) -} -func (r *RankMap) Swap(i, j int) { - rank1 := r.Ranks[i] - rank2 := r.Ranks[j] - r.Ranks[i], r.Ranks[j] = rank2, rank1 - rank1.Rank, rank2.Rank = rank2.Rank, rank1.Rank +type RankDesc struct { + OwnerId uuid.UUID + Score int64 + Subscore int64 } -func (r *RankMap) Less(i, j int) bool { - rank1 := r.Ranks[i] - rank2 := r.Ranks[j] - if r.SortOrder == LeaderboardSortOrderDescending { - rank1, rank2 = rank2, rank1 - } - if rank1.Score < rank2.Score { +func (r *RankDesc) Less(other interface{}) bool { + ro := other.(*RankDesc) + if ro.Score < r.Score { return true - } else if rank2.Score < rank1.Score { + } + if ro.Subscore > r.Subscore { return false } - - return rank1.Subscore <= rank2.Subscore + if ro.Subscore < r.Subscore { + return true + } + if ro.Subscore > r.Subscore { + return false + } + return ro.OwnerId.String() < r.OwnerId.String() } -type LeaderboardWithExpiry struct { - LeaderboardId string - Expiry int64 +type RankCache struct { + sync.RWMutex + owners map[uuid.UUID]skiplist.Interface + cache *skiplist.SkipList } type LocalLeaderboardRankCache struct { sync.RWMutex - cache map[LeaderboardWithExpiry]*RankMap blacklistAll bool blacklistIds map[string]struct{} + cache map[LeaderboardWithExpiry]*RankCache } +var _ LeaderboardRankCache = &LocalLeaderboardRankCache{} + func NewLocalLeaderboardRankCache(startupLogger *zap.Logger, db *sql.DB, config *LeaderboardConfig, leaderboardCache LeaderboardCache) LeaderboardRankCache { cache := &LocalLeaderboardRankCache{ blacklistIds: make(map[string]struct{}, len(config.BlacklistRankCache)), blacklistAll: len(config.BlacklistRankCache) == 1 && config.BlacklistRankCache[0] == "*", - cache: make(map[LeaderboardWithExpiry]*RankMap, 0), + cache: make(map[LeaderboardWithExpiry]*RankCache, 0), } // If caching is disabled completely do not preload any records. @@ -130,13 +145,12 @@ func NewLocalLeaderboardRankCache(startupLogger *zap.Logger, db *sql.DB, config } // Prepare structure to receive rank data. - rankEntries := &RankMap{ - Ranks: make([]*RankData, 0), - Haystack: make(map[uuid.UUID]*RankData), - SortOrder: leaderboard.SortOrder, + rankCache := &RankCache{ + owners: make(map[uuid.UUID]skiplist.Interface), + cache: skiplist.New(), } key := LeaderboardWithExpiry{LeaderboardId: leaderboard.Id, Expiry: expiryUnix} - cache.cache[key] = rankEntries + cache.cache[key] = rankCache // Look up all active records for this leaderboard. query := ` @@ -151,25 +165,40 @@ WHERE leaderboard_id = $1 AND expiry_time = $2` // Process the records. for rows.Next() { - var ownerID string - rankData := &RankData{Rank: int64(len(rankEntries.Ranks) + 1)} + var ownerIDStr string + var score int64 + var subscore int64 - if err = rows.Scan(&ownerID, &rankData.Score, &rankData.Subscore); err != nil { + if err = rows.Scan(&ownerIDStr, &score, &subscore); err != nil { startupLogger.Fatal("Failed to scan leaderboard rank data", zap.String("leaderboard_id", leaderboard.Id), zap.Error(err)) return nil } + ownerID, err := uuid.FromString(ownerIDStr) + if err != nil { + startupLogger.Fatal("Failed to parse scanned leaderboard rank data", zap.String("leaderboard_id", leaderboard.Id), zap.String("owner_id", ownerIDStr), zap.Error(err)) + return nil + } - rankData.OwnerId = uuid.Must(uuid.FromString(ownerID)) + // Prepare new rank data for this leaderboard entry. + var rankData skiplist.Interface + if leaderboard.SortOrder == LeaderboardSortOrderDescending { + rankData = &RankDesc{ + OwnerId: ownerID, + Score: score, + Subscore: subscore, + } + } else { + rankData = &RankAsc{ + OwnerId: ownerID, + Score: score, + Subscore: subscore, + } + } - rankEntries.Ranks = append(rankEntries.Ranks, rankData) - rankEntries.Haystack[rankData.OwnerId] = rankData + rankCache.owners[ownerID] = rankData + rankCache.cache.Insert(rankData) } - rows.Close() - } - - for k, v := range cache.cache { - startupLogger.Debug("Sorting leaderboard ranks", zap.String("leaderboard_id", k.LeaderboardId), zap.Int("count", len(v.Ranks))) - sort.Sort(v) + _ = rows.Close() } startupLogger.Info("Leaderboard rank cache initialization completed successfully", zap.Strings("cached", cachedLeaderboards), zap.Strings("skipped", skippedLeaderboards)) @@ -189,22 +218,23 @@ func (l *LocalLeaderboardRankCache) Get(leaderboardId string, expiryUnix int64, // Find rank map for this leaderboard/expiry pair. key := LeaderboardWithExpiry{LeaderboardId: leaderboardId, Expiry: expiryUnix} l.RLock() - rankMap, ok := l.cache[key] + rankCache, ok := l.cache[key] l.RUnlock() if !ok { return 0 } // Find rank data for this owner. - rankMap.RLock() - rankData, ok := rankMap.Haystack[ownerID] + rankCache.RLock() + rankData, ok := rankCache.owners[ownerID] if !ok { - rankMap.RUnlock() + rankCache.RUnlock() return 0 } - rank := rankData.Rank - rankMap.RUnlock() - return rank + rank := rankCache.cache.GetRank(rankData) + rankCache.RUnlock() + + return int64(rank) } func (l *LocalLeaderboardRankCache) Fill(leaderboardId string, expiryUnix int64, records []*api.LeaderboardRecord) { @@ -225,21 +255,26 @@ func (l *LocalLeaderboardRankCache) Fill(leaderboardId string, expiryUnix int64, // Find rank map for this leaderboard/expiry pair. key := LeaderboardWithExpiry{LeaderboardId: leaderboardId, Expiry: expiryUnix} l.RLock() - rankMap, ok := l.cache[key] + rankCache, ok := l.cache[key] l.RUnlock() if !ok { return } // Find rank data for each owner. - rankMap.RLock() + rankCache.RLock() for _, record := range records { - rankData, ok := rankMap.Haystack[uuid.Must(uuid.FromString(record.OwnerId))] - if ok { - record.Rank = rankData.Rank + ownerID, err := uuid.FromString(record.OwnerId) + if err != nil { + continue } + rankData, ok := rankCache.owners[ownerID] + if !ok { + continue + } + record.Rank = int64(rankCache.cache.GetRank(rankData)) } - rankMap.RUnlock() + rankCache.RUnlock() } func (l *LocalLeaderboardRankCache) Insert(leaderboardId string, expiryUnix int64, sortOrder int, ownerID uuid.UUID, score, subscore int64) int64 { @@ -252,51 +287,53 @@ func (l *LocalLeaderboardRankCache) Insert(leaderboardId string, expiryUnix int6 return 0 } - // Find the rank map for this leaderboard/expiry pair. + // No existing rank map for this leaderboard/expiry pair, prepare to create a new one. key := LeaderboardWithExpiry{LeaderboardId: leaderboardId, Expiry: expiryUnix} l.RLock() - rankMap, ok := l.cache[key] + rankCache, ok := l.cache[key] l.RUnlock() if !ok { - // No existing rank map for this leaderboard/expiry pair, prepare to create a new one. - newRankMap := &RankMap{ - Ranks: make([]*RankData, 0), - Haystack: make(map[uuid.UUID]*RankData), - SortOrder: sortOrder, + newRankCache := &RankCache{ + owners: make(map[uuid.UUID]skiplist.Interface), + cache: skiplist.New(), } l.Lock() // Last check if rank map was created by another writer just after last read. - rankMap, ok = l.cache[key] + rankCache, ok = l.cache[key] if !ok { - rankMap = newRankMap - l.cache[key] = rankMap + rankCache = newRankCache + l.cache[key] = rankCache } l.Unlock() } - // Insert or update the score. - rankMap.Lock() - rankData, ok := rankMap.Haystack[ownerID] - if !ok { - rankData = &RankData{ + // Prepare new rank data for this leaderboard entry. + var rankData skiplist.Interface + if sortOrder == LeaderboardSortOrderDescending { + rankData = &RankDesc{ OwnerId: ownerID, Score: score, Subscore: subscore, - Rank: int64(len(rankMap.Ranks) + 1), } - rankMap.Haystack[ownerID] = rankData - rankMap.Ranks = append(rankMap.Ranks, rankData) } else { - rankData.Score = score - rankData.Subscore = subscore + rankData = &RankAsc{ + OwnerId: ownerID, + Score: score, + Subscore: subscore, + } } - // Re-sort the rank map then check the rank number assigned. - sort.Sort(rankMap) - rank := rankData.Rank - rankMap.Unlock() + // Check for and remove any previous rank entry, then insert the new rank data and get its rank. + rankCache.Lock() + if oldRankData, ok := rankCache.owners[ownerID]; ok { + rankCache.cache.Delete(oldRankData) + } + rankCache.owners[ownerID] = rankData + rankCache.cache.Insert(rankData) + rank := rankCache.cache.GetRank(rankData) + rankCache.Unlock() - return rank + return int64(rank) } func (l *LocalLeaderboardRankCache) Delete(leaderboardId string, expiryUnix int64, ownerID uuid.UUID) bool { @@ -313,48 +350,23 @@ func (l *LocalLeaderboardRankCache) Delete(leaderboardId string, expiryUnix int6 key := LeaderboardWithExpiry{LeaderboardId: leaderboardId, Expiry: expiryUnix} l.RLock() - rankMap, ok := l.cache[key] + rankCache, ok := l.cache[key] l.RUnlock() if !ok { - // No rank map. + // No rank cache for this leaderboard and expiry combination. return true } - // Delete rank data for this owner. - rankMap.Lock() - rankData, ok := rankMap.Haystack[ownerID] + // Remove any existing rank entry. + rankCache.Lock() + rankData, ok := rankCache.owners[ownerID] if !ok { - // No rank data. - rankMap.Unlock() + rankCache.Unlock() return true } - - delete(rankMap.Haystack, ownerID) - - rank := rankData.Rank - totalRanks := len(rankMap.Ranks) - switch { - case rank == 1: - // Dropping the first rank. - rankMap.Ranks = rankMap.Ranks[1:] - case rank == int64(totalRanks): - // Dropping the last rank. - rankMap.Ranks = rankMap.Ranks[:rank-1] - - // No need to reshuffle ranks. - rankMap.Unlock() - return true - default: - // Dropping a rank somewhere in the middle. - rankMap.Ranks = append(rankMap.Ranks[:rank-1], rankMap.Ranks[rank:]...) - } - - // Shift ranks that were after the deleted record down by one rank number to fill the gap. - for i := int(rank) - 1; i < totalRanks-1; i++ { - rankMap.Ranks[i].Rank-- - } - // No need to sort, ranks are still in order. - rankMap.Unlock() + delete(rankCache.owners, ownerID) + rankCache.cache.Delete(rankData) + rankCache.Unlock() return true } @@ -388,7 +400,7 @@ func (l *LocalLeaderboardRankCache) TrimExpired(nowUnix int64) bool { // Used for the timer. l.Lock() for k := range l.cache { - if k.Expiry <= nowUnix { + if k.Expiry != 0 && k.Expiry <= nowUnix { delete(l.cache, k) } } diff --git a/server/leaderboard_rank_cache_test.go b/server/leaderboard_rank_cache_test.go new file mode 100644 index 000000000..cc9b52453 --- /dev/null +++ b/server/leaderboard_rank_cache_test.go @@ -0,0 +1,309 @@ +// Copyright 2020 The Nakama Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package server + +import ( + "github.com/gofrs/uuid" + "github.com/heroiclabs/nakama-common/api" + "github.com/stretchr/testify/assert" + "testing" +) + +func TestLocalLeaderboardRankCache_Insert_Ascending(t *testing.T) { + cache := &LocalLeaderboardRankCache{ + blacklistIds: make(map[string]struct{}, 0), + blacklistAll: false, + cache: make(map[LeaderboardWithExpiry]*RankCache, 0), + } + + u1 := uuid.Must(uuid.NewV4()) + u2 := uuid.Must(uuid.NewV4()) + u3 := uuid.Must(uuid.NewV4()) + u4 := uuid.Must(uuid.NewV4()) + u5 := uuid.Must(uuid.NewV4()) + + cache.Insert("lid", 0, LeaderboardSortOrderAscending, u3, 33, 34) + cache.Insert("lid", 0, LeaderboardSortOrderAscending, u2, 22, 23) + cache.Insert("lid", 0, LeaderboardSortOrderAscending, u4, 44, 45) + cache.Insert("lid", 0, LeaderboardSortOrderAscending, u1, 11, 12) + cache.Insert("lid", 0, LeaderboardSortOrderAscending, u5, 55, 56) + + assert.EqualValues(t, 1, cache.Get("lid", 0, u1)) + assert.EqualValues(t, 2, cache.Get("lid", 0, u2)) + assert.EqualValues(t, 3, cache.Get("lid", 0, u3)) + assert.EqualValues(t, 4, cache.Get("lid", 0, u4)) + assert.EqualValues(t, 5, cache.Get("lid", 0, u5)) +} + +func TestLocalLeaderboardRankCache_Insert_Descending(t *testing.T) { + cache := &LocalLeaderboardRankCache{ + blacklistIds: make(map[string]struct{}, 0), + blacklistAll: false, + cache: make(map[LeaderboardWithExpiry]*RankCache, 0), + } + + u1 := uuid.Must(uuid.NewV4()) + u2 := uuid.Must(uuid.NewV4()) + u3 := uuid.Must(uuid.NewV4()) + u4 := uuid.Must(uuid.NewV4()) + u5 := uuid.Must(uuid.NewV4()) + + cache.Insert("lid", 0, LeaderboardSortOrderDescending, u3, 33, 34) + cache.Insert("lid", 0, LeaderboardSortOrderDescending, u2, 22, 23) + cache.Insert("lid", 0, LeaderboardSortOrderDescending, u4, 44, 45) + cache.Insert("lid", 0, LeaderboardSortOrderDescending, u1, 11, 12) + cache.Insert("lid", 0, LeaderboardSortOrderDescending, u5, 55, 56) + + assert.EqualValues(t, 1, cache.Get("lid", 0, u5)) + assert.EqualValues(t, 2, cache.Get("lid", 0, u4)) + assert.EqualValues(t, 3, cache.Get("lid", 0, u3)) + assert.EqualValues(t, 4, cache.Get("lid", 0, u2)) + assert.EqualValues(t, 5, cache.Get("lid", 0, u1)) +} + +func TestLocalLeaderboardRankCache_Insert_Existing(t *testing.T) { + cache := &LocalLeaderboardRankCache{ + blacklistIds: make(map[string]struct{}, 0), + blacklistAll: false, + cache: make(map[LeaderboardWithExpiry]*RankCache, 0), + } + + u1 := uuid.Must(uuid.NewV4()) + u2 := uuid.Must(uuid.NewV4()) + u3 := uuid.Must(uuid.NewV4()) + u4 := uuid.Must(uuid.NewV4()) + u5 := uuid.Must(uuid.NewV4()) + + cache.Insert("lid", 0, LeaderboardSortOrderDescending, u3, 33, 34) + cache.Insert("lid", 0, LeaderboardSortOrderDescending, u2, 22, 23) + cache.Insert("lid", 0, LeaderboardSortOrderDescending, u4, 44, 45) + cache.Insert("lid", 0, LeaderboardSortOrderDescending, u1, 11, 12) + cache.Insert("lid", 0, LeaderboardSortOrderDescending, u5, 55, 56) + cache.Insert("lid", 0, LeaderboardSortOrderDescending, u2, 55, 57) + + assert.EqualValues(t, 1, cache.Get("lid", 0, u2)) + assert.EqualValues(t, 2, cache.Get("lid", 0, u5)) + assert.EqualValues(t, 3, cache.Get("lid", 0, u4)) + assert.EqualValues(t, 4, cache.Get("lid", 0, u3)) + assert.EqualValues(t, 5, cache.Get("lid", 0, u1)) +} + +func TestLocalLeaderboardRankCache_TrimExpired(t *testing.T) { + cache := &LocalLeaderboardRankCache{ + blacklistIds: make(map[string]struct{}, 0), + blacklistAll: false, + cache: make(map[LeaderboardWithExpiry]*RankCache, 0), + } + + u1 := uuid.Must(uuid.NewV4()) + u2 := uuid.Must(uuid.NewV4()) + u3 := uuid.Must(uuid.NewV4()) + u4 := uuid.Must(uuid.NewV4()) + u5 := uuid.Must(uuid.NewV4()) + + cache.Insert("lid", 1, LeaderboardSortOrderDescending, u3, 33, 34) + cache.Insert("lid", 1, LeaderboardSortOrderDescending, u2, 22, 23) + cache.Insert("lid", 1, LeaderboardSortOrderDescending, u4, 44, 45) + cache.Insert("lid", 1, LeaderboardSortOrderDescending, u1, 11, 12) + cache.Insert("lid", 1, LeaderboardSortOrderDescending, u5, 55, 56) + + assert.EqualValues(t, 1, cache.Get("lid", 1, u5)) + assert.EqualValues(t, 2, cache.Get("lid", 1, u4)) + assert.EqualValues(t, 3, cache.Get("lid", 1, u3)) + assert.EqualValues(t, 4, cache.Get("lid", 1, u2)) + assert.EqualValues(t, 5, cache.Get("lid", 1, u1)) + + cache.TrimExpired(1) + + assert.EqualValues(t, 0, cache.Get("lid", 1, u5)) + assert.EqualValues(t, 0, cache.Get("lid", 1, u4)) + assert.EqualValues(t, 0, cache.Get("lid", 1, u3)) + assert.EqualValues(t, 0, cache.Get("lid", 1, u2)) + assert.EqualValues(t, 0, cache.Get("lid", 1, u1)) +} + +func TestLocalLeaderboardRankCache_ExpirySeparation(t *testing.T) { + cache := &LocalLeaderboardRankCache{ + blacklistIds: make(map[string]struct{}, 0), + blacklistAll: false, + cache: make(map[LeaderboardWithExpiry]*RankCache, 0), + } + + u1 := uuid.Must(uuid.NewV4()) + u2 := uuid.Must(uuid.NewV4()) + u3 := uuid.Must(uuid.NewV4()) + u4 := uuid.Must(uuid.NewV4()) + u5 := uuid.Must(uuid.NewV4()) + + cache.Insert("lid", 1, LeaderboardSortOrderDescending, u3, 33, 34) + cache.Insert("lid", 1, LeaderboardSortOrderDescending, u2, 22, 23) + cache.Insert("lid", 1, LeaderboardSortOrderDescending, u4, 44, 45) + cache.Insert("lid", 1, LeaderboardSortOrderDescending, u1, 11, 12) + cache.Insert("lid", 1, LeaderboardSortOrderDescending, u5, 55, 56) + + assert.EqualValues(t, 1, cache.Get("lid", 1, u5)) + assert.EqualValues(t, 2, cache.Get("lid", 1, u4)) + assert.EqualValues(t, 3, cache.Get("lid", 1, u3)) + assert.EqualValues(t, 4, cache.Get("lid", 1, u2)) + assert.EqualValues(t, 5, cache.Get("lid", 1, u1)) + + assert.EqualValues(t, 0, cache.Get("lid", 2, u5)) + assert.EqualValues(t, 0, cache.Get("lid", 2, u4)) + assert.EqualValues(t, 0, cache.Get("lid", 2, u3)) + assert.EqualValues(t, 0, cache.Get("lid", 2, u2)) + assert.EqualValues(t, 0, cache.Get("lid", 2, u1)) +} + +func TestLocalLeaderboardRankCache_LeaderboardSeparation(t *testing.T) { + cache := &LocalLeaderboardRankCache{ + blacklistIds: make(map[string]struct{}, 0), + blacklistAll: false, + cache: make(map[LeaderboardWithExpiry]*RankCache, 0), + } + + u1 := uuid.Must(uuid.NewV4()) + u2 := uuid.Must(uuid.NewV4()) + u3 := uuid.Must(uuid.NewV4()) + u4 := uuid.Must(uuid.NewV4()) + u5 := uuid.Must(uuid.NewV4()) + + cache.Insert("lid", 1, LeaderboardSortOrderDescending, u3, 33, 34) + cache.Insert("lid", 1, LeaderboardSortOrderDescending, u2, 22, 23) + cache.Insert("lid", 1, LeaderboardSortOrderDescending, u4, 44, 45) + cache.Insert("lid", 1, LeaderboardSortOrderDescending, u1, 11, 12) + cache.Insert("lid", 1, LeaderboardSortOrderDescending, u5, 55, 56) + + assert.EqualValues(t, 1, cache.Get("lid", 1, u5)) + assert.EqualValues(t, 2, cache.Get("lid", 1, u4)) + assert.EqualValues(t, 3, cache.Get("lid", 1, u3)) + assert.EqualValues(t, 4, cache.Get("lid", 1, u2)) + assert.EqualValues(t, 5, cache.Get("lid", 1, u1)) + + assert.EqualValues(t, 0, cache.Get("foo", 1, u5)) + assert.EqualValues(t, 0, cache.Get("foo", 1, u4)) + assert.EqualValues(t, 0, cache.Get("foo", 1, u3)) + assert.EqualValues(t, 0, cache.Get("foo", 1, u2)) + assert.EqualValues(t, 0, cache.Get("foo", 1, u1)) +} + +func TestLocalLeaderboardRankCache_Delete(t *testing.T) { + cache := &LocalLeaderboardRankCache{ + blacklistIds: make(map[string]struct{}, 0), + blacklistAll: false, + cache: make(map[LeaderboardWithExpiry]*RankCache, 0), + } + + u1 := uuid.Must(uuid.NewV4()) + u2 := uuid.Must(uuid.NewV4()) + u3 := uuid.Must(uuid.NewV4()) + u4 := uuid.Must(uuid.NewV4()) + u5 := uuid.Must(uuid.NewV4()) + + cache.Insert("lid", 0, LeaderboardSortOrderDescending, u3, 33, 34) + cache.Insert("lid", 0, LeaderboardSortOrderDescending, u2, 22, 23) + cache.Insert("lid", 0, LeaderboardSortOrderDescending, u4, 44, 45) + cache.Insert("lid", 0, LeaderboardSortOrderDescending, u1, 11, 12) + cache.Insert("lid", 0, LeaderboardSortOrderDescending, u5, 55, 56) + + assert.EqualValues(t, 1, cache.Get("lid", 0, u5)) + assert.EqualValues(t, 2, cache.Get("lid", 0, u4)) + assert.EqualValues(t, 3, cache.Get("lid", 0, u3)) + assert.EqualValues(t, 4, cache.Get("lid", 0, u2)) + assert.EqualValues(t, 5, cache.Get("lid", 0, u1)) + + cache.Delete("lid", 0, u4) + + assert.EqualValues(t, 1, cache.Get("lid", 0, u5)) + assert.EqualValues(t, 0, cache.Get("lid", 0, u4)) + assert.EqualValues(t, 2, cache.Get("lid", 0, u3)) + assert.EqualValues(t, 3, cache.Get("lid", 0, u2)) + assert.EqualValues(t, 4, cache.Get("lid", 0, u1)) +} + +func TestLocalLeaderboardRankCache_DeleteLeaderboard(t *testing.T) { + cache := &LocalLeaderboardRankCache{ + blacklistIds: make(map[string]struct{}, 0), + blacklistAll: false, + cache: make(map[LeaderboardWithExpiry]*RankCache, 0), + } + + u1 := uuid.Must(uuid.NewV4()) + u2 := uuid.Must(uuid.NewV4()) + u3 := uuid.Must(uuid.NewV4()) + u4 := uuid.Must(uuid.NewV4()) + u5 := uuid.Must(uuid.NewV4()) + + cache.Insert("lid", 0, LeaderboardSortOrderDescending, u3, 33, 34) + cache.Insert("lid", 0, LeaderboardSortOrderDescending, u2, 22, 23) + cache.Insert("lid", 0, LeaderboardSortOrderDescending, u4, 44, 45) + cache.Insert("lid", 0, LeaderboardSortOrderDescending, u1, 11, 12) + cache.Insert("lid", 0, LeaderboardSortOrderDescending, u5, 55, 56) + + assert.EqualValues(t, 1, cache.Get("lid", 0, u5)) + assert.EqualValues(t, 2, cache.Get("lid", 0, u4)) + assert.EqualValues(t, 3, cache.Get("lid", 0, u3)) + assert.EqualValues(t, 4, cache.Get("lid", 0, u2)) + assert.EqualValues(t, 5, cache.Get("lid", 0, u1)) + + cache.DeleteLeaderboard("lid", 0) + + assert.EqualValues(t, 0, cache.Get("lid", 0, u5)) + assert.EqualValues(t, 0, cache.Get("lid", 0, u4)) + assert.EqualValues(t, 0, cache.Get("lid", 0, u3)) + assert.EqualValues(t, 0, cache.Get("lid", 0, u2)) + assert.EqualValues(t, 0, cache.Get("lid", 0, u1)) +} + +func TestLocalLeaderboardRankCache_Fill(t *testing.T) { + cache := &LocalLeaderboardRankCache{ + blacklistIds: make(map[string]struct{}, 0), + blacklistAll: false, + cache: make(map[LeaderboardWithExpiry]*RankCache, 0), + } + + u1 := uuid.Must(uuid.NewV4()) + u2 := uuid.Must(uuid.NewV4()) + u3 := uuid.Must(uuid.NewV4()) + u4 := uuid.Must(uuid.NewV4()) + u5 := uuid.Must(uuid.NewV4()) + + cache.Insert("lid", 0, LeaderboardSortOrderDescending, u3, 33, 34) + cache.Insert("lid", 0, LeaderboardSortOrderDescending, u2, 22, 23) + cache.Insert("lid", 0, LeaderboardSortOrderDescending, u4, 44, 45) + cache.Insert("lid", 0, LeaderboardSortOrderDescending, u1, 11, 12) + cache.Insert("lid", 0, LeaderboardSortOrderDescending, u5, 55, 56) + + assert.EqualValues(t, 1, cache.Get("lid", 0, u5)) + assert.EqualValues(t, 2, cache.Get("lid", 0, u4)) + assert.EqualValues(t, 3, cache.Get("lid", 0, u3)) + assert.EqualValues(t, 4, cache.Get("lid", 0, u2)) + assert.EqualValues(t, 5, cache.Get("lid", 0, u1)) + + records := []*api.LeaderboardRecord{ + {OwnerId: u3.String()}, + {OwnerId: u1.String()}, + {OwnerId: u5.String()}, + {OwnerId: u2.String()}, + {OwnerId: u4.String()}, + } + + cache.Fill("lid", 0, records) + + assert.EqualValues(t, 3, records[0].Rank) + assert.EqualValues(t, 5, records[1].Rank) + assert.EqualValues(t, 1, records[2].Rank) + assert.EqualValues(t, 4, records[3].Rank) + assert.EqualValues(t, 2, records[4].Rank) +} diff --git a/server/runtime_go_logger_test.go b/server/runtime_go_logger_test.go index ee47d6f39..5a6952823 100644 --- a/server/runtime_go_logger_test.go +++ b/server/runtime_go_logger_test.go @@ -1,3 +1,17 @@ +// Copyright 2020 The Nakama Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package server import ( @@ -92,8 +106,8 @@ func TestGoLoggerWithFields(t *testing.T) { obs := zap.New(observer) fields := map[string]interface{}{ - "key1": "value1", - "key2": 2, + "key1": "value1", + "key2": 2, "runtime": "foo", // Overwriting runtime should yield no effect } @@ -113,8 +127,8 @@ func TestGoLoggerFields(t *testing.T) { obs := zap.New(observer) fields := map[string]interface{}{ - "key2": "value2", - "key3": 3, + "key2": "value2", + "key3": 3, "runtime": "foo", // Should not be added to fields } @@ -132,4 +146,3 @@ func TestGoLoggerFields(t *testing.T) { _, contains = logger2.Fields()["runtime"] assert.False(t, contains) } - diff --git a/tests/runtime_test.go b/server/runtime_test.go similarity index 97% rename from tests/runtime_test.go rename to server/runtime_test.go index 79a20c2d4..6bac6653d 100644 --- a/tests/runtime_test.go +++ b/server/runtime_test.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package tests +package server import ( "context" @@ -30,7 +30,6 @@ import ( "github.com/golang/protobuf/ptypes/empty" "github.com/heroiclabs/nakama-common/api" "github.com/heroiclabs/nakama-common/rtapi" - "github.com/heroiclabs/nakama/v2/server" "golang.org/x/crypto/bcrypt" ) @@ -62,7 +61,7 @@ print("Test Module Loaded") return test` ) -func runtimeWithModules(t *testing.T, modules map[string]string) (*server.Runtime, error) { +func runtimeWithModules(t *testing.T, modules map[string]string) (*Runtime, error) { dir, err := ioutil.TempDir("", fmt.Sprintf("nakama_runtime_lua_test_%v", uuid.Must(uuid.NewV4()).String())) if err != nil { t.Fatalf("Failed initializing runtime modules tempdir: %s", err.Error()) @@ -75,10 +74,10 @@ func runtimeWithModules(t *testing.T, modules map[string]string) (*server.Runtim } } - cfg := server.NewConfig(logger) + cfg := NewConfig(logger) cfg.Runtime.Path = dir - return server.NewRuntime(logger, logger, NewDB(t), jsonpbMarshaler, jsonpbUnmarshaler, cfg, nil, nil, nil, nil, nil, nil, nil, nil, &DummyMessageRouter{}) + return NewRuntime(logger, logger, NewDB(t), jsonpbMarshaler, jsonpbUnmarshaler, cfg, nil, nil, nil, nil, nil, nil, nil, metrics, nil, &DummyMessageRouter{}) } func TestRuntimeSampleScript(t *testing.T) { @@ -355,8 +354,8 @@ nakama.register_rpc(test.printWorld, "helloworld")`, } db := NewDB(t) - pipeline := server.NewPipeline(logger, config, db, jsonpbMarshaler, jsonpbUnmarshaler, nil, nil, nil, nil, nil, runtime) - apiServer := server.StartApiServer(logger, logger, db, jsonpbMarshaler, jsonpbUnmarshaler, config, nil, nil, nil, nil, nil, nil, nil, nil, pipeline, runtime) + pipeline := NewPipeline(logger, cfg, db, jsonpbMarshaler, jsonpbUnmarshaler, nil, nil, nil, nil, nil, runtime) + apiServer := StartApiServer(logger, logger, db, jsonpbMarshaler, jsonpbUnmarshaler, cfg, nil, nil, nil, nil, nil, nil, nil, nil, metrics, pipeline, runtime) defer apiServer.Stop() payload := "\"Hello World\"" -- GitLab