summaryrefslogtreecommitdiffhomepage
path: root/third_party/gvsync/seqcount_test.go
diff options
context:
space:
mode:
authorMichael Pratt <mpratt@google.com>2019-01-31 17:47:24 -0800
committerShentubot <shentubot@google.com>2019-01-31 17:49:14 -0800
commitfe1369ac98a4f1d8af5e8be6da71165339e52034 (patch)
tree89c1e4553a375b57e9999278613eb37f104e30a6 /third_party/gvsync/seqcount_test.go
parent4e695adcd0c739101c3d50431ca18b1b911c9238 (diff)
Move package sync to third_party
PiperOrigin-RevId: 231889261 Change-Id: I482f1df055bcedf4edb9fe3fe9b8e9c80085f1a0
Diffstat (limited to 'third_party/gvsync/seqcount_test.go')
-rw-r--r--third_party/gvsync/seqcount_test.go153
1 files changed, 153 insertions, 0 deletions
diff --git a/third_party/gvsync/seqcount_test.go b/third_party/gvsync/seqcount_test.go
new file mode 100644
index 000000000..ee6579ed8
--- /dev/null
+++ b/third_party/gvsync/seqcount_test.go
@@ -0,0 +1,153 @@
+// Copyright 2019 Google LLC
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package gvsync
+
+import (
+ "reflect"
+ "testing"
+ "time"
+)
+
+func TestSeqCountWriteUncontended(t *testing.T) {
+ var seq SeqCount
+ seq.BeginWrite()
+ seq.EndWrite()
+}
+
+func TestSeqCountReadUncontended(t *testing.T) {
+ var seq SeqCount
+ epoch := seq.BeginRead()
+ if !seq.ReadOk(epoch) {
+ t.Errorf("ReadOk: got false, wanted true")
+ }
+}
+
+func TestSeqCountBeginReadAfterWrite(t *testing.T) {
+ var seq SeqCount
+ var data int32
+ const want = 1
+ seq.BeginWrite()
+ data = want
+ seq.EndWrite()
+ epoch := seq.BeginRead()
+ if data != want {
+ t.Errorf("Reader: got %v, wanted %v", data, want)
+ }
+ if !seq.ReadOk(epoch) {
+ t.Errorf("ReadOk: got false, wanted true")
+ }
+}
+
+func TestSeqCountBeginReadDuringWrite(t *testing.T) {
+ var seq SeqCount
+ var data int
+ const want = 1
+ seq.BeginWrite()
+ go func() {
+ time.Sleep(time.Second)
+ data = want
+ seq.EndWrite()
+ }()
+ epoch := seq.BeginRead()
+ if data != want {
+ t.Errorf("Reader: got %v, wanted %v", data, want)
+ }
+ if !seq.ReadOk(epoch) {
+ t.Errorf("ReadOk: got false, wanted true")
+ }
+}
+
+func TestSeqCountReadOkAfterWrite(t *testing.T) {
+ var seq SeqCount
+ epoch := seq.BeginRead()
+ seq.BeginWrite()
+ seq.EndWrite()
+ if seq.ReadOk(epoch) {
+ t.Errorf("ReadOk: got true, wanted false")
+ }
+}
+
+func TestSeqCountReadOkDuringWrite(t *testing.T) {
+ var seq SeqCount
+ epoch := seq.BeginRead()
+ seq.BeginWrite()
+ if seq.ReadOk(epoch) {
+ t.Errorf("ReadOk: got true, wanted false")
+ }
+ seq.EndWrite()
+}
+
+func BenchmarkSeqCountWriteUncontended(b *testing.B) {
+ var seq SeqCount
+ for i := 0; i < b.N; i++ {
+ seq.BeginWrite()
+ seq.EndWrite()
+ }
+}
+
+func BenchmarkSeqCountReadUncontended(b *testing.B) {
+ var seq SeqCount
+ b.RunParallel(func(pb *testing.PB) {
+ for pb.Next() {
+ epoch := seq.BeginRead()
+ if !seq.ReadOk(epoch) {
+ b.Fatalf("ReadOk: got false, wanted true")
+ }
+ }
+ })
+}
+
+func TestPointersInType(t *testing.T) {
+ for _, test := range []struct {
+ name string // used for both test and value name
+ val interface{}
+ ptrs []string
+ }{
+ {
+ name: "EmptyStruct",
+ val: struct{}{},
+ },
+ {
+ name: "Int",
+ val: int(0),
+ },
+ {
+ name: "MixedStruct",
+ val: struct {
+ b bool
+ I int
+ ExportedPtr *struct{}
+ unexportedPtr *struct{}
+ arr [2]int
+ ptrArr [2]*int
+ nestedStruct struct {
+ nestedNonptr int
+ nestedPtr *int
+ }
+ structArr [1]struct {
+ nonptr int
+ ptr *int
+ }
+ }{},
+ ptrs: []string{
+ "MixedStruct.ExportedPtr",
+ "MixedStruct.unexportedPtr",
+ "MixedStruct.ptrArr[]",
+ "MixedStruct.nestedStruct.nestedPtr",
+ "MixedStruct.structArr[].ptr",
+ },
+ },
+ } {
+ t.Run(test.name, func(t *testing.T) {
+ typ := reflect.TypeOf(test.val)
+ ptrs := PointersInType(typ, test.name)
+ t.Logf("Found pointers: %v", ptrs)
+ if (len(ptrs) != 0 || len(test.ptrs) != 0) && !reflect.DeepEqual(ptrs, test.ptrs) {
+ t.Errorf("Got %v, wanted %v", ptrs, test.ptrs)
+ }
+ })
+ }
+}