summaryrefslogtreecommitdiffhomepage
path: root/pkg/state/tests
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/state/tests')
-rw-r--r--pkg/state/tests/BUILD43
-rw-r--r--pkg/state/tests/array.go35
-rw-r--r--pkg/state/tests/array_test.go134
-rw-r--r--pkg/state/tests/bench.go24
-rw-r--r--pkg/state/tests/bench_test.go153
-rw-r--r--pkg/state/tests/bool_test.go31
-rw-r--r--pkg/state/tests/float_test.go118
-rw-r--r--pkg/state/tests/integer.go163
-rw-r--r--pkg/state/tests/integer_test.go94
-rw-r--r--pkg/state/tests/load.go61
-rw-r--r--pkg/state/tests/load_test.go78
-rw-r--r--pkg/state/tests/map.go28
-rw-r--r--pkg/state/tests/map_test.go90
-rw-r--r--pkg/state/tests/register.go21
-rw-r--r--pkg/state/tests/register_test.go178
-rw-r--r--pkg/state/tests/string_test.go34
-rw-r--r--pkg/state/tests/struct.go100
-rw-r--r--pkg/state/tests/struct_test.go100
-rw-r--r--pkg/state/tests/tests.go215
19 files changed, 0 insertions, 1700 deletions
diff --git a/pkg/state/tests/BUILD b/pkg/state/tests/BUILD
deleted file mode 100644
index 9297cafbe..000000000
--- a/pkg/state/tests/BUILD
+++ /dev/null
@@ -1,43 +0,0 @@
-load("//tools:defs.bzl", "go_library", "go_test")
-
-package(licenses = ["notice"])
-
-go_library(
- name = "tests",
- srcs = [
- "array.go",
- "bench.go",
- "integer.go",
- "load.go",
- "map.go",
- "register.go",
- "struct.go",
- "tests.go",
- ],
- deps = [
- "//pkg/state",
- "//pkg/state/pretty",
- ],
-)
-
-go_test(
- name = "tests_test",
- size = "small",
- srcs = [
- "array_test.go",
- "bench_test.go",
- "bool_test.go",
- "float_test.go",
- "integer_test.go",
- "load_test.go",
- "map_test.go",
- "register_test.go",
- "string_test.go",
- "struct_test.go",
- ],
- library = ":tests",
- deps = [
- "//pkg/state",
- "//pkg/state/wire",
- ],
-)
diff --git a/pkg/state/tests/array.go b/pkg/state/tests/array.go
deleted file mode 100644
index 0972a80e7..000000000
--- a/pkg/state/tests/array.go
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2018 The gVisor 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 tests
-
-// +stateify savable
-type arrayContainer struct {
- v [1]interface{}
-}
-
-// +stateify savable
-type arrayPtrContainer struct {
- v *[1]interface{}
-}
-
-// +stateify savable
-type sliceContainer struct {
- v []interface{}
-}
-
-// +stateify savable
-type slicePtrContainer struct {
- v *[]interface{}
-}
diff --git a/pkg/state/tests/array_test.go b/pkg/state/tests/array_test.go
deleted file mode 100644
index a347b2947..000000000
--- a/pkg/state/tests/array_test.go
+++ /dev/null
@@ -1,134 +0,0 @@
-// Copyright 2018 The gVisor 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 tests
-
-import (
- "reflect"
- "testing"
-)
-
-var allArrayPrimitives = []interface{}{
- [1]bool{},
- [1]bool{true},
- [2]bool{false, true},
- [1]int{},
- [1]int{1},
- [2]int{0, 1},
- [1]int8{},
- [1]int8{1},
- [2]int8{0, 1},
- [1]int16{},
- [1]int16{1},
- [2]int16{0, 1},
- [1]int32{},
- [1]int32{1},
- [2]int32{0, 1},
- [1]int64{},
- [1]int64{1},
- [2]int64{0, 1},
- [1]uint{},
- [1]uint{1},
- [2]uint{0, 1},
- [1]uintptr{},
- [1]uintptr{1},
- [2]uintptr{0, 1},
- [1]uint8{},
- [1]uint8{1},
- [2]uint8{0, 1},
- [1]uint16{},
- [1]uint16{1},
- [2]uint16{0, 1},
- [1]uint32{},
- [1]uint32{1},
- [2]uint32{0, 1},
- [1]uint64{},
- [1]uint64{1},
- [2]uint64{0, 1},
- [1]string{},
- [1]string{""},
- [1]string{nonEmptyString},
- [2]string{"", nonEmptyString},
-}
-
-func TestArrayPrimitives(t *testing.T) {
- runTestCases(t, false, "plain", flatten(allArrayPrimitives))
- runTestCases(t, false, "pointers", pointersTo(flatten(allArrayPrimitives)))
- runTestCases(t, false, "interfaces", interfacesTo(flatten(allArrayPrimitives)))
- runTestCases(t, false, "interfacesToPointers", interfacesTo(pointersTo(flatten(allArrayPrimitives))))
-}
-
-func TestSlices(t *testing.T) {
- var allSlices = flatten(
- filter(allArrayPrimitives, func(o interface{}) (interface{}, bool) {
- v := reflect.New(reflect.TypeOf(o)).Elem()
- v.Set(reflect.ValueOf(o))
- return v.Slice(0, v.Len()).Interface(), true
- }),
- filter(allArrayPrimitives, func(o interface{}) (interface{}, bool) {
- v := reflect.New(reflect.TypeOf(o)).Elem()
- v.Set(reflect.ValueOf(o))
- if v.Len() == 0 {
- // Return the pure "nil" value for the slice.
- return reflect.New(v.Slice(0, 0).Type()).Elem().Interface(), true
- }
- return v.Slice(1, v.Len()).Interface(), true
- }),
- filter(allArrayPrimitives, func(o interface{}) (interface{}, bool) {
- v := reflect.New(reflect.TypeOf(o)).Elem()
- v.Set(reflect.ValueOf(o))
- if v.Len() == 0 {
- // Return the zero-valued slice.
- return reflect.MakeSlice(v.Slice(0, 0).Type(), 0, 0).Interface(), true
- }
- return v.Slice(0, v.Len()-1).Interface(), true
- }),
- )
- runTestCases(t, false, "plain", allSlices)
- runTestCases(t, false, "pointers", pointersTo(allSlices))
- runTestCases(t, false, "interfaces", interfacesTo(allSlices))
- runTestCases(t, false, "interfacesToPointers", interfacesTo(pointersTo(allSlices)))
-}
-
-func TestArrayContainers(t *testing.T) {
- var (
- emptyArray [1]interface{}
- fullArray [1]interface{}
- )
- fullArray[0] = &emptyArray
- runTestCases(t, false, "", []interface{}{
- arrayContainer{v: emptyArray},
- arrayContainer{v: fullArray},
- arrayPtrContainer{v: nil},
- arrayPtrContainer{v: &emptyArray},
- arrayPtrContainer{v: &fullArray},
- })
-}
-
-func TestSliceContainers(t *testing.T) {
- var (
- nilSlice []interface{}
- emptySlice = make([]interface{}, 0)
- fullSlice = []interface{}{nil}
- )
- runTestCases(t, false, "", []interface{}{
- sliceContainer{v: nilSlice},
- sliceContainer{v: emptySlice},
- sliceContainer{v: fullSlice},
- slicePtrContainer{v: nil},
- slicePtrContainer{v: &nilSlice},
- slicePtrContainer{v: &emptySlice},
- slicePtrContainer{v: &fullSlice},
- })
-}
diff --git a/pkg/state/tests/bench.go b/pkg/state/tests/bench.go
deleted file mode 100644
index 40869cdfb..000000000
--- a/pkg/state/tests/bench.go
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2018 The gVisor 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 tests
-
-// +stateify savable
-type benchStruct struct {
- B *benchStruct // Must be exported for gob.
-}
-
-func (b *benchStruct) afterLoad() {
- // Do nothing, just force scheduling.
-}
diff --git a/pkg/state/tests/bench_test.go b/pkg/state/tests/bench_test.go
deleted file mode 100644
index 7e102c907..000000000
--- a/pkg/state/tests/bench_test.go
+++ /dev/null
@@ -1,153 +0,0 @@
-// Copyright 2018 The gVisor 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 tests
-
-import (
- "bytes"
- "context"
- "encoding/gob"
- "fmt"
- "testing"
-
- "gvisor.dev/gvisor/pkg/state"
- "gvisor.dev/gvisor/pkg/state/wire"
-)
-
-// buildPtrObject builds a benchmark object.
-func buildPtrObject(n int) interface{} {
- b := new(benchStruct)
- for i := 0; i < n; i++ {
- b = &benchStruct{B: b}
- }
- return b
-}
-
-// buildMapObject builds a benchmark object.
-func buildMapObject(n int) interface{} {
- b := new(benchStruct)
- m := make(map[int]*benchStruct)
- for i := 0; i < n; i++ {
- m[i] = b
- }
- return &m
-}
-
-// buildSliceObject builds a benchmark object.
-func buildSliceObject(n int) interface{} {
- b := new(benchStruct)
- s := make([]*benchStruct, 0, n)
- for i := 0; i < n; i++ {
- s = append(s, b)
- }
- return &s
-}
-
-var allObjects = map[string]struct {
- New func(int) interface{}
-}{
- "ptr": {
- New: buildPtrObject,
- },
- "map": {
- New: buildMapObject,
- },
- "slice": {
- New: buildSliceObject,
- },
-}
-
-func buildObjects(n int, fn func(int) interface{}) (iters int, v interface{}) {
- // maxSize is the maximum size of an individual object below. For an N
- // larger than this, we start to return multiple objects.
- const maxSize = 1024
- if n <= maxSize {
- return 1, fn(n)
- }
- iters = (n + maxSize - 1) / maxSize
- return iters, fn(maxSize)
-}
-
-// gobSave is a version of save using gob (no stats available).
-func gobSave(_ context.Context, w wire.Writer, v interface{}) (_ state.Stats, err error) {
- enc := gob.NewEncoder(w)
- err = enc.Encode(v)
- return
-}
-
-// gobLoad is a version of load using gob (no stats available).
-func gobLoad(_ context.Context, r wire.Reader, v interface{}) (_ state.Stats, err error) {
- dec := gob.NewDecoder(r)
- err = dec.Decode(v)
- return
-}
-
-var allAlgos = map[string]struct {
- Save func(context.Context, wire.Writer, interface{}) (state.Stats, error)
- Load func(context.Context, wire.Reader, interface{}) (state.Stats, error)
- MaxPtr int
-}{
- "state": {
- Save: state.Save,
- Load: state.Load,
- },
- "gob": {
- Save: gobSave,
- Load: gobLoad,
- },
-}
-
-func BenchmarkEncoding(b *testing.B) {
- for objName, objInfo := range allObjects {
- for algoName, algoInfo := range allAlgos {
- b.Run(fmt.Sprintf("%s/%s", objName, algoName), func(b *testing.B) {
- b.StopTimer()
- n, v := buildObjects(b.N, objInfo.New)
- b.ReportAllocs()
- b.StartTimer()
- for i := 0; i < n; i++ {
- if _, err := algoInfo.Save(context.Background(), discard{}, v); err != nil {
- b.Errorf("save failed: %v", err)
- }
- }
- b.StopTimer()
- })
- }
- }
-}
-
-func BenchmarkDecoding(b *testing.B) {
- for objName, objInfo := range allObjects {
- for algoName, algoInfo := range allAlgos {
- b.Run(fmt.Sprintf("%s/%s", objName, algoName), func(b *testing.B) {
- b.StopTimer()
- n, v := buildObjects(b.N, objInfo.New)
- buf := new(bytes.Buffer)
- if _, err := algoInfo.Save(context.Background(), buf, v); err != nil {
- b.Errorf("save failed: %v", err)
- }
- b.ReportAllocs()
- b.StartTimer()
- var r bytes.Reader
- for i := 0; i < n; i++ {
- r.Reset(buf.Bytes())
- if _, err := algoInfo.Load(context.Background(), &r, v); err != nil {
- b.Errorf("load failed: %v", err)
- }
- }
- b.StopTimer()
- })
- }
- }
-}
diff --git a/pkg/state/tests/bool_test.go b/pkg/state/tests/bool_test.go
deleted file mode 100644
index e17cfacf9..000000000
--- a/pkg/state/tests/bool_test.go
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2018 The gVisor 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 tests
-
-import (
- "testing"
-)
-
-var allBools = []bool{
- true,
- false,
-}
-
-func TestBool(t *testing.T) {
- runTestCases(t, false, "plain", flatten(allBools))
- runTestCases(t, false, "pointers", pointersTo(flatten(allBools)))
- runTestCases(t, false, "interfaces", interfacesTo(flatten(allBools)))
- runTestCases(t, false, "interfacesToPointers", interfacesTo(pointersTo(flatten(allBools))))
-}
diff --git a/pkg/state/tests/float_test.go b/pkg/state/tests/float_test.go
deleted file mode 100644
index 3e89edd9c..000000000
--- a/pkg/state/tests/float_test.go
+++ /dev/null
@@ -1,118 +0,0 @@
-// Copyright 2018 The gVisor 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 tests
-
-import (
- "math"
- "testing"
-)
-
-var safeFloat32s = []float32{
- float32(0.0),
- float32(1.0),
- float32(-1.0),
- float32(math.Inf(1)),
- float32(math.Inf(-1)),
-}
-
-var allFloat32s = append(safeFloat32s, float32(math.NaN()))
-
-var safeFloat64s = []float64{
- float64(0.0),
- float64(1.0),
- float64(-1.0),
- math.Inf(1),
- math.Inf(-1),
-}
-
-var allFloat64s = append(safeFloat64s, math.NaN())
-
-func TestFloat(t *testing.T) {
- runTestCases(t, false, "plain", flatten(
- allFloat32s,
- allFloat64s,
- ))
- // See checkEqual for why NaNs are missing.
- runTestCases(t, false, "pointers", pointersTo(flatten(
- safeFloat32s,
- safeFloat64s,
- )))
- runTestCases(t, false, "interfaces", interfacesTo(flatten(
- safeFloat32s,
- safeFloat64s,
- )))
- runTestCases(t, false, "interfacesToPointers", interfacesTo(pointersTo(flatten(
- safeFloat32s,
- safeFloat64s,
- ))))
-}
-
-const onlyDouble float64 = 1.0000000000000002
-
-func TestFloatTruncation(t *testing.T) {
- runTestCases(t, true, "pass", []interface{}{
- truncatingFloat32{save: onlyDouble},
- })
- runTestCases(t, false, "fail", []interface{}{
- truncatingFloat32{save: 1.0},
- })
-}
-
-var safeComplex64s = combine(safeFloat32s, safeFloat32s, func(i, j interface{}) interface{} {
- return complex(i.(float32), j.(float32))
-})
-
-var allComplex64s = combine(allFloat32s, allFloat32s, func(i, j interface{}) interface{} {
- return complex(i.(float32), j.(float32))
-})
-
-var safeComplex128s = combine(safeFloat64s, safeFloat64s, func(i, j interface{}) interface{} {
- return complex(i.(float64), j.(float64))
-})
-
-var allComplex128s = combine(allFloat64s, allFloat64s, func(i, j interface{}) interface{} {
- return complex(i.(float64), j.(float64))
-})
-
-func TestComplex(t *testing.T) {
- runTestCases(t, false, "plain", flatten(
- allComplex64s,
- allComplex128s,
- ))
- // See TestFloat; same issue.
- runTestCases(t, false, "pointers", pointersTo(flatten(
- safeComplex64s,
- safeComplex128s,
- )))
- runTestCases(t, false, "interfacse", interfacesTo(flatten(
- safeComplex64s,
- safeComplex128s,
- )))
- runTestCases(t, false, "interfacesTo", interfacesTo(pointersTo(flatten(
- safeComplex64s,
- safeComplex128s,
- ))))
-}
-
-func TestComplexTruncation(t *testing.T) {
- runTestCases(t, true, "pass", []interface{}{
- truncatingComplex64{save: complex(onlyDouble, onlyDouble)},
- truncatingComplex64{save: complex(1.0, onlyDouble)},
- truncatingComplex64{save: complex(onlyDouble, 1.0)},
- })
- runTestCases(t, false, "fail", []interface{}{
- truncatingComplex64{save: complex(1.0, 1.0)},
- })
-}
diff --git a/pkg/state/tests/integer.go b/pkg/state/tests/integer.go
deleted file mode 100644
index ca403eed1..000000000
--- a/pkg/state/tests/integer.go
+++ /dev/null
@@ -1,163 +0,0 @@
-// Copyright 2018 The gVisor 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 tests
-
-import (
- "gvisor.dev/gvisor/pkg/state"
-)
-
-// +stateify type
-type truncatingUint8 struct {
- save uint64
- load uint8 `state:"nosave"`
-}
-
-func (t *truncatingUint8) StateSave(m state.Sink) {
- m.Save(0, &t.save)
-}
-
-func (t *truncatingUint8) StateLoad(m state.Source) {
- m.Load(0, &t.load)
- t.save = uint64(t.load)
- t.load = 0
-}
-
-var _ state.SaverLoader = (*truncatingUint8)(nil)
-
-// +stateify type
-type truncatingUint16 struct {
- save uint64
- load uint16 `state:"nosave"`
-}
-
-func (t *truncatingUint16) StateSave(m state.Sink) {
- m.Save(0, &t.save)
-}
-
-func (t *truncatingUint16) StateLoad(m state.Source) {
- m.Load(0, &t.load)
- t.save = uint64(t.load)
- t.load = 0
-}
-
-var _ state.SaverLoader = (*truncatingUint16)(nil)
-
-// +stateify type
-type truncatingUint32 struct {
- save uint64
- load uint32 `state:"nosave"`
-}
-
-func (t *truncatingUint32) StateSave(m state.Sink) {
- m.Save(0, &t.save)
-}
-
-func (t *truncatingUint32) StateLoad(m state.Source) {
- m.Load(0, &t.load)
- t.save = uint64(t.load)
- t.load = 0
-}
-
-var _ state.SaverLoader = (*truncatingUint32)(nil)
-
-// +stateify type
-type truncatingInt8 struct {
- save int64
- load int8 `state:"nosave"`
-}
-
-func (t *truncatingInt8) StateSave(m state.Sink) {
- m.Save(0, &t.save)
-}
-
-func (t *truncatingInt8) StateLoad(m state.Source) {
- m.Load(0, &t.load)
- t.save = int64(t.load)
- t.load = 0
-}
-
-var _ state.SaverLoader = (*truncatingInt8)(nil)
-
-// +stateify type
-type truncatingInt16 struct {
- save int64
- load int16 `state:"nosave"`
-}
-
-func (t *truncatingInt16) StateSave(m state.Sink) {
- m.Save(0, &t.save)
-}
-
-func (t *truncatingInt16) StateLoad(m state.Source) {
- m.Load(0, &t.load)
- t.save = int64(t.load)
- t.load = 0
-}
-
-var _ state.SaverLoader = (*truncatingInt16)(nil)
-
-// +stateify type
-type truncatingInt32 struct {
- save int64
- load int32 `state:"nosave"`
-}
-
-func (t *truncatingInt32) StateSave(m state.Sink) {
- m.Save(0, &t.save)
-}
-
-func (t *truncatingInt32) StateLoad(m state.Source) {
- m.Load(0, &t.load)
- t.save = int64(t.load)
- t.load = 0
-}
-
-var _ state.SaverLoader = (*truncatingInt32)(nil)
-
-// +stateify type
-type truncatingFloat32 struct {
- save float64
- load float32 `state:"nosave"`
-}
-
-func (t *truncatingFloat32) StateSave(m state.Sink) {
- m.Save(0, &t.save)
-}
-
-func (t *truncatingFloat32) StateLoad(m state.Source) {
- m.Load(0, &t.load)
- t.save = float64(t.load)
- t.load = 0
-}
-
-var _ state.SaverLoader = (*truncatingFloat32)(nil)
-
-// +stateify type
-type truncatingComplex64 struct {
- save complex128
- load complex64 `state:"nosave"`
-}
-
-func (t *truncatingComplex64) StateSave(m state.Sink) {
- m.Save(0, &t.save)
-}
-
-func (t *truncatingComplex64) StateLoad(m state.Source) {
- m.Load(0, &t.load)
- t.save = complex128(t.load)
- t.load = 0
-}
-
-var _ state.SaverLoader = (*truncatingComplex64)(nil)
diff --git a/pkg/state/tests/integer_test.go b/pkg/state/tests/integer_test.go
deleted file mode 100644
index 2b1609af0..000000000
--- a/pkg/state/tests/integer_test.go
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright 2018 The gVisor 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 tests
-
-import (
- "math"
- "testing"
-)
-
-var (
- allBasicInts = []int{-1, 0, 1}
- allInt8s = []int8{math.MinInt8, -1, 0, 1, math.MaxInt8}
- allInt16s = []int16{math.MinInt16, -1, 0, 1, math.MaxInt16}
- allInt32s = []int32{math.MinInt32, -1, 0, 1, math.MaxInt32}
- allInt64s = []int64{math.MinInt64, -1, 0, 1, math.MaxInt64}
- allBasicUints = []uint{0, 1}
- allUintptrs = []uintptr{0, 1, ^uintptr(0)}
- allUint8s = []uint8{0, 1, math.MaxUint8}
- allUint16s = []uint16{0, 1, math.MaxUint16}
- allUint32s = []uint32{0, 1, math.MaxUint32}
- allUint64s = []uint64{0, 1, math.MaxUint64}
-)
-
-var allInts = flatten(
- allBasicInts,
- allInt8s,
- allInt16s,
- allInt32s,
- allInt64s,
-)
-
-var allUints = flatten(
- allBasicUints,
- allUintptrs,
- allUint8s,
- allUint16s,
- allUint32s,
- allUint64s,
-)
-
-func TestInt(t *testing.T) {
- runTestCases(t, false, "plain", allInts)
- runTestCases(t, false, "pointers", pointersTo(allInts))
- runTestCases(t, false, "interfaces", interfacesTo(allInts))
- runTestCases(t, false, "interfacesTo", interfacesTo(pointersTo(allInts)))
-}
-
-func TestIntTruncation(t *testing.T) {
- runTestCases(t, true, "pass", []interface{}{
- truncatingInt8{save: math.MinInt8 - 1},
- truncatingInt16{save: math.MinInt16 - 1},
- truncatingInt32{save: math.MinInt32 - 1},
- truncatingInt8{save: math.MaxInt8 + 1},
- truncatingInt16{save: math.MaxInt16 + 1},
- truncatingInt32{save: math.MaxInt32 + 1},
- })
- runTestCases(t, false, "fail", []interface{}{
- truncatingInt8{save: 1},
- truncatingInt16{save: 1},
- truncatingInt32{save: 1},
- })
-}
-
-func TestUint(t *testing.T) {
- runTestCases(t, false, "plain", allUints)
- runTestCases(t, false, "pointers", pointersTo(allUints))
- runTestCases(t, false, "interfaces", interfacesTo(allUints))
- runTestCases(t, false, "interfacesTo", interfacesTo(pointersTo(allUints)))
-}
-
-func TestUintTruncation(t *testing.T) {
- runTestCases(t, true, "pass", []interface{}{
- truncatingUint8{save: math.MaxUint8 + 1},
- truncatingUint16{save: math.MaxUint16 + 1},
- truncatingUint32{save: math.MaxUint32 + 1},
- })
- runTestCases(t, false, "fail", []interface{}{
- truncatingUint8{save: 1},
- truncatingUint16{save: 1},
- truncatingUint32{save: 1},
- })
-}
diff --git a/pkg/state/tests/load.go b/pkg/state/tests/load.go
deleted file mode 100644
index a8350c0f3..000000000
--- a/pkg/state/tests/load.go
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2018 The gVisor 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 tests
-
-// +stateify savable
-type genericContainer struct {
- v interface{}
-}
-
-// +stateify savable
-type afterLoadStruct struct {
- v int `state:"nosave"`
-}
-
-func (a *afterLoadStruct) afterLoad() {
- a.v++
-}
-
-// +stateify savable
-type valueLoadStruct struct {
- v int `state:".(int64)"`
-}
-
-func (v *valueLoadStruct) saveV() int64 {
- return int64(v.v) // Save as int64.
-}
-
-func (v *valueLoadStruct) loadV(value int64) {
- v.v = int(value) // Load as int.
-}
-
-// +stateify savable
-type cycleStruct struct {
- c *cycleStruct
-}
-
-// +stateify savable
-type badCycleStruct struct {
- b *badCycleStruct `state:"wait"`
-}
-
-func (b *badCycleStruct) afterLoad() {
- if b.b != b {
- // This is not executable, since AfterLoad requires that the
- // object and all dependencies are complete. This should cause
- // a deadlock error during load.
- panic("badCycleStruct.afterLoad called")
- }
-}
diff --git a/pkg/state/tests/load_test.go b/pkg/state/tests/load_test.go
deleted file mode 100644
index 3c73ac391..000000000
--- a/pkg/state/tests/load_test.go
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2018 The gVisor 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 tests
-
-import (
- "testing"
-)
-
-func TestLoadHooks(t *testing.T) {
- runTestCases(t, false, "load-hooks", []interface{}{
- // Root object being a struct.
- afterLoadStruct{v: 1},
- valueLoadStruct{v: 1},
- genericContainer{v: &afterLoadStruct{v: 1}},
- genericContainer{v: &valueLoadStruct{v: 1}},
- sliceContainer{v: []interface{}{&afterLoadStruct{v: 1}}},
- sliceContainer{v: []interface{}{&valueLoadStruct{v: 1}}},
- // Root object being a pointer.
- &afterLoadStruct{v: 1},
- &valueLoadStruct{v: 1},
- &genericContainer{v: &afterLoadStruct{v: 1}},
- &genericContainer{v: &valueLoadStruct{v: 1}},
- &sliceContainer{v: []interface{}{&afterLoadStruct{v: 1}}},
- &sliceContainer{v: []interface{}{&valueLoadStruct{v: 1}}},
- &mapContainer{v: map[int]interface{}{0: &afterLoadStruct{v: 1}}},
- &mapContainer{v: map[int]interface{}{0: &valueLoadStruct{v: 1}}},
- })
-}
-
-func TestCycles(t *testing.T) {
- // cs is a single object cycle.
- cs := cycleStruct{nil}
- cs.c = &cs
-
- // cs1 and cs2 are in a two object cycle.
- cs1 := cycleStruct{nil}
- cs2 := cycleStruct{nil}
- cs1.c = &cs2
- cs2.c = &cs1
-
- runTestCases(t, false, "cycles", []interface{}{
- cs,
- cs1,
- })
-}
-
-func TestDeadlock(t *testing.T) {
- // bs is a single object cycle. This does not cause deadlock because an
- // object cannot wait for itself.
- bs := badCycleStruct{nil}
- bs.b = &bs
-
- runTestCases(t, false, "self", []interface{}{
- &bs,
- })
-
- // bs2 and bs2 are in a deadlocking cycle.
- bs1 := badCycleStruct{nil}
- bs2 := badCycleStruct{nil}
- bs1.b = &bs2
- bs2.b = &bs1
-
- runTestCases(t, true, "deadlock", []interface{}{
- &bs1,
- })
-}
diff --git a/pkg/state/tests/map.go b/pkg/state/tests/map.go
deleted file mode 100644
index db4e548f1..000000000
--- a/pkg/state/tests/map.go
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2018 The gVisor 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 tests
-
-// +stateify savable
-type mapContainer struct {
- v map[int]interface{}
-}
-
-// +stateify savable
-type mapPtrContainer struct {
- v *map[int]interface{}
-}
-
-// +stateify savable
-type registeredMapStruct struct{}
diff --git a/pkg/state/tests/map_test.go b/pkg/state/tests/map_test.go
deleted file mode 100644
index 92bf0fc01..000000000
--- a/pkg/state/tests/map_test.go
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright 2018 The gVisor 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 tests
-
-import (
- "reflect"
- "testing"
-)
-
-var allMapPrimitives = []interface{}{
- bool(true),
- int(1),
- int8(1),
- int16(1),
- int32(1),
- int64(1),
- uint(1),
- uintptr(1),
- uint8(1),
- uint16(1),
- uint32(1),
- uint64(1),
- string(""),
- registeredMapStruct{},
-}
-
-var allMapKeys = flatten(allMapPrimitives, pointersTo(allMapPrimitives))
-
-var allMapValues = flatten(allMapPrimitives, pointersTo(allMapPrimitives), interfacesTo(allMapPrimitives))
-
-var emptyMaps = combine(allMapKeys, allMapValues, func(v1, v2 interface{}) interface{} {
- m := reflect.MakeMap(reflect.MapOf(reflect.TypeOf(v1), reflect.TypeOf(v2)))
- return m.Interface()
-})
-
-var fullMaps = combine(allMapKeys, allMapValues, func(v1, v2 interface{}) interface{} {
- m := reflect.MakeMap(reflect.MapOf(reflect.TypeOf(v1), reflect.TypeOf(v2)))
- m.SetMapIndex(reflect.Zero(reflect.TypeOf(v1)), reflect.Zero(reflect.TypeOf(v2)))
- return m.Interface()
-})
-
-func TestMapAliasing(t *testing.T) {
- v := make(map[int]int)
- ptrToV := &v
- aliases := []map[int]int{v, v}
- runTestCases(t, false, "", []interface{}{ptrToV, aliases})
-}
-
-func TestMapsEmpty(t *testing.T) {
- runTestCases(t, false, "plain", emptyMaps)
- runTestCases(t, false, "pointers", pointersTo(emptyMaps))
- runTestCases(t, false, "interfaces", interfacesTo(emptyMaps))
- runTestCases(t, false, "interfacesToPointers", interfacesTo(pointersTo(emptyMaps)))
-}
-
-func TestMapsFull(t *testing.T) {
- runTestCases(t, false, "plain", fullMaps)
- runTestCases(t, false, "pointers", pointersTo(fullMaps))
- runTestCases(t, false, "interfaces", interfacesTo(fullMaps))
- runTestCases(t, false, "interfacesToPointer", interfacesTo(pointersTo(fullMaps)))
-}
-
-func TestMapContainers(t *testing.T) {
- var (
- nilMap map[int]interface{}
- emptyMap = make(map[int]interface{})
- fullMap = map[int]interface{}{0: nil}
- )
- runTestCases(t, false, "", []interface{}{
- mapContainer{v: nilMap},
- mapContainer{v: emptyMap},
- mapContainer{v: fullMap},
- mapPtrContainer{v: nil},
- mapPtrContainer{v: &nilMap},
- mapPtrContainer{v: &emptyMap},
- mapPtrContainer{v: &fullMap},
- })
-}
diff --git a/pkg/state/tests/register.go b/pkg/state/tests/register.go
deleted file mode 100644
index 074d86315..000000000
--- a/pkg/state/tests/register.go
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2018 The gVisor 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 tests
-
-// +stateify savable
-type alreadyRegisteredStruct struct{}
-
-// +stateify savable
-type alreadyRegisteredOther int
diff --git a/pkg/state/tests/register_test.go b/pkg/state/tests/register_test.go
deleted file mode 100644
index 75bdbfc6e..000000000
--- a/pkg/state/tests/register_test.go
+++ /dev/null
@@ -1,178 +0,0 @@
-// Copyright 2018 The gVisor 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.
-
-// +build race
-
-package tests
-
-import (
- "testing"
-
- "gvisor.dev/gvisor/pkg/state"
-)
-
-// faker calls itself whatever is in the name field.
-type faker struct {
- Name string
- Fields []string
-}
-
-func (f *faker) StateTypeName() string {
- return f.Name
-}
-
-func (f *faker) StateFields() []string {
- return f.Fields
-}
-
-// fakerWithSaverLoader has all it needs.
-type fakerWithSaverLoader struct {
- faker
-}
-
-func (f *fakerWithSaverLoader) StateSave(m state.Sink) {}
-
-func (f *fakerWithSaverLoader) StateLoad(m state.Source) {}
-
-// fakerOther calls itself .. uh, itself?
-type fakerOther string
-
-func (f *fakerOther) StateTypeName() string {
- return string(*f)
-}
-
-func (f *fakerOther) StateFields() []string {
- return nil
-}
-
-func newFakerOther(name string) *fakerOther {
- f := fakerOther(name)
- return &f
-}
-
-// fakerOtherBadFields returns non-nil fields.
-type fakerOtherBadFields string
-
-func (f *fakerOtherBadFields) StateTypeName() string {
- return string(*f)
-}
-
-func (f *fakerOtherBadFields) StateFields() []string {
- return []string{string(*f)}
-}
-
-func newFakerOtherBadFields(name string) *fakerOtherBadFields {
- f := fakerOtherBadFields(name)
- return &f
-}
-
-// fakerOtherSaverLoader implements SaverLoader methods.
-type fakerOtherSaverLoader string
-
-func (f *fakerOtherSaverLoader) StateTypeName() string {
- return string(*f)
-}
-
-func (f *fakerOtherSaverLoader) StateFields() []string {
- return nil
-}
-
-func (f *fakerOtherSaverLoader) StateSave(m state.Sink) {}
-
-func (f *fakerOtherSaverLoader) StateLoad(m state.Source) {}
-
-func newFakerOtherSaverLoader(name string) *fakerOtherSaverLoader {
- f := fakerOtherSaverLoader(name)
- return &f
-}
-
-func TestRegisterPrimitives(t *testing.T) {
- for _, typeName := range []string{
- "int",
- "int8",
- "int16",
- "int32",
- "int64",
- "uint",
- "uintptr",
- "uint8",
- "uint16",
- "uint32",
- "uint64",
- "float32",
- "float64",
- "complex64",
- "complex128",
- "string",
- } {
- t.Run("struct/"+typeName, func(t *testing.T) {
- defer func() {
- if r := recover(); r == nil {
- t.Errorf("Registering type %q did not panic", typeName)
- }
- }()
- state.Register(&faker{
- Name: typeName,
- })
- })
- t.Run("other/"+typeName, func(t *testing.T) {
- defer func() {
- if r := recover(); r == nil {
- t.Errorf("Registering type %q did not panic", typeName)
- }
- }()
- state.Register(newFakerOther(typeName))
- })
- }
-}
-
-func TestRegisterBad(t *testing.T) {
- const (
- goodName = "foo"
- firstField = "a"
- secondField = "b"
- )
- for name, object := range map[string]state.Type{
- "non-struct-with-fields": newFakerOtherBadFields(goodName),
- "non-struct-with-saverloader": newFakerOtherSaverLoader(goodName),
- "struct-without-saverloader": &faker{Name: goodName},
- "non-struct-duplicate-with-struct": newFakerOther((new(alreadyRegisteredStruct)).StateTypeName()),
- "non-struct-duplicate-with-non-struct": newFakerOther((new(alreadyRegisteredOther)).StateTypeName()),
- "struct-duplicate-with-struct": &fakerWithSaverLoader{faker{Name: (new(alreadyRegisteredStruct)).StateTypeName()}},
- "struct-duplicate-with-non-struct": &fakerWithSaverLoader{faker{Name: (new(alreadyRegisteredOther)).StateTypeName()}},
- "struct-with-empty-field": &fakerWithSaverLoader{faker{Name: goodName, Fields: []string{""}}},
- "struct-with-empty-field-and-non-empty": &fakerWithSaverLoader{faker{Name: goodName, Fields: []string{firstField, ""}}},
- "struct-with-duplicate-field": &fakerWithSaverLoader{faker{Name: goodName, Fields: []string{firstField, firstField}}},
- "struct-with-duplicate-field-and-non-dup": &fakerWithSaverLoader{faker{Name: goodName, Fields: []string{firstField, secondField, firstField}}},
- } {
- t.Run(name, func(t *testing.T) {
- defer func() {
- if r := recover(); r == nil {
- t.Errorf("Registering object %#v did not panic", object)
- }
- }()
- state.Register(object)
- })
-
- }
-}
-
-func TestRegisterTypeOnlyStruct(t *testing.T) {
- defer func() {
- if r := recover(); r == nil {
- t.Errorf("Register did not panic")
- }
- }()
- state.Register((*typeOnlyEmptyStruct)(nil))
-}
diff --git a/pkg/state/tests/string_test.go b/pkg/state/tests/string_test.go
deleted file mode 100644
index 44f5a562c..000000000
--- a/pkg/state/tests/string_test.go
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2018 The gVisor 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 tests
-
-import (
- "testing"
-)
-
-const nonEmptyString = "hello world"
-
-var allStrings = []string{
- "",
- nonEmptyString,
- "\\0",
-}
-
-func TestString(t *testing.T) {
- runTestCases(t, false, "plain", flatten(allStrings))
- runTestCases(t, false, "pointers", pointersTo(flatten(allStrings)))
- runTestCases(t, false, "interfaces", interfacesTo(flatten(allStrings)))
- runTestCases(t, false, "interfacesToPointers", interfacesTo(pointersTo(flatten(allStrings))))
-}
diff --git a/pkg/state/tests/struct.go b/pkg/state/tests/struct.go
deleted file mode 100644
index 69143d194..000000000
--- a/pkg/state/tests/struct.go
+++ /dev/null
@@ -1,100 +0,0 @@
-// Copyright 2018 The gVisor 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 tests
-
-type unregisteredEmptyStruct struct{}
-
-// typeOnlyEmptyStruct just implements the state.Type interface.
-type typeOnlyEmptyStruct struct{}
-
-func (*typeOnlyEmptyStruct) StateTypeName() string { return "registeredEmptyStruct" }
-
-func (*typeOnlyEmptyStruct) StateFields() []string { return nil }
-
-// +stateify savable
-type savableEmptyStruct struct{}
-
-// +stateify savable
-type emptyStructPointer struct {
- nothing *struct{}
-}
-
-// +stateify savable
-type outerSame struct {
- inner inner
-}
-
-// +stateify savable
-type outerFieldFirst struct {
- inner inner
- v int64
-}
-
-// +stateify savable
-type outerFieldSecond struct {
- v int64
- inner inner
-}
-
-// +stateify savable
-type outerArray struct {
- inner [2]inner
-}
-
-// +stateify savable
-type outerSlice struct {
- inner []inner
-}
-
-// +stateify savable
-type inner struct {
- v int64
-}
-
-// +stateify savable
-type outerFieldValue struct {
- inner innerFieldValue
-}
-
-// +stateify savable
-type innerFieldValue struct {
- v int64 `state:".(*savedFieldValue)"`
-}
-
-// +stateify savable
-type savedFieldValue struct {
- v int64
-}
-
-func (ifv *innerFieldValue) saveV() *savedFieldValue {
- return &savedFieldValue{ifv.v}
-}
-
-func (ifv *innerFieldValue) loadV(sfv *savedFieldValue) {
- ifv.v = sfv.v
-}
-
-// +stateify savable
-type system struct {
- v1 interface{}
- v2 interface{}
-}
-
-// +stateify savable
-type system3 struct {
- v1 interface{}
- v2 interface{}
- v3 interface{}
-}
diff --git a/pkg/state/tests/struct_test.go b/pkg/state/tests/struct_test.go
deleted file mode 100644
index 9826f1ee9..000000000
--- a/pkg/state/tests/struct_test.go
+++ /dev/null
@@ -1,100 +0,0 @@
-// Copyright 2018 The gVisor 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 tests
-
-import (
- "math/rand"
- "testing"
-)
-
-func TestEmptyStruct(t *testing.T) {
- runTestCases(t, false, "plain", []interface{}{
- unregisteredEmptyStruct{},
- typeOnlyEmptyStruct{},
- savableEmptyStruct{},
- })
- runTestCases(t, false, "pointers", pointersTo([]interface{}{
- unregisteredEmptyStruct{},
- typeOnlyEmptyStruct{},
- savableEmptyStruct{},
- }))
- runTestCases(t, false, "interfaces-pass", interfacesTo([]interface{}{
- // Only registered types can be dispatched via interfaces. All
- // other types should fail, even if it is the empty struct.
- savableEmptyStruct{},
- }))
- runTestCases(t, true, "interfaces-fail", interfacesTo([]interface{}{
- unregisteredEmptyStruct{},
- typeOnlyEmptyStruct{},
- }))
- runTestCases(t, false, "interfacesToPointers-pass", interfacesTo(pointersTo([]interface{}{
- savableEmptyStruct{},
- })))
- runTestCases(t, true, "interfacesToPointers-fail", interfacesTo(pointersTo([]interface{}{
- unregisteredEmptyStruct{},
- typeOnlyEmptyStruct{},
- })))
-
- // Ensuring empty struct aliasing works.
- es := emptyStructPointer{new(struct{})}
- runTestCases(t, false, "empty-struct-pointers", []interface{}{
- emptyStructPointer{},
- es,
- []emptyStructPointer{es, es}, // Same pointer.
- })
-}
-
-func TestEmbeddedPointers(t *testing.T) {
- // Give each int64 a random value to prevent Go from using
- // runtime.staticuint64s, which confounds tests for struct duplication.
- magic := func() int64 {
- for {
- n := rand.Int63()
- if n < 0 || n > 255 {
- return n
- }
- }
- }
-
- ofs := outerSame{inner{magic()}}
- of1 := outerFieldFirst{inner{magic()}, magic()}
- of2 := outerFieldSecond{magic(), inner{magic()}}
- oa := outerArray{[2]inner{{magic()}, {magic()}}}
- osl := outerSlice{oa.inner[:]}
- ofv := outerFieldValue{innerFieldValue{magic()}}
-
- runTestCases(t, false, "embedded-pointers", []interface{}{
- system{&ofs, &ofs.inner},
- system{&ofs.inner, &ofs},
- system{&of1, &of1.inner},
- system{&of1.inner, &of1},
- system{&of2, &of2.inner},
- system{&of2.inner, &of2},
- system{&oa, &oa.inner[0]},
- system{&oa, &oa.inner[1]},
- system{&oa.inner[0], &oa},
- system{&oa.inner[1], &oa},
- system3{&oa, &oa.inner[0], &oa.inner[1]},
- system3{&oa, &oa.inner[1], &oa.inner[0]},
- system3{&oa.inner[0], &oa, &oa.inner[1]},
- system3{&oa.inner[1], &oa, &oa.inner[0]},
- system3{&oa.inner[0], &oa.inner[1], &oa},
- system3{&oa.inner[1], &oa.inner[0], &oa},
- system{&oa, &osl},
- system{&osl, &oa},
- system{&ofv, &ofv.inner},
- system{&ofv.inner, &ofv},
- })
-}
diff --git a/pkg/state/tests/tests.go b/pkg/state/tests/tests.go
deleted file mode 100644
index 435a0e9db..000000000
--- a/pkg/state/tests/tests.go
+++ /dev/null
@@ -1,215 +0,0 @@
-// Copyright 2018 The gVisor 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 tests tests the state packages.
-package tests
-
-import (
- "bytes"
- "context"
- "fmt"
- "math"
- "reflect"
- "testing"
-
- "gvisor.dev/gvisor/pkg/state"
- "gvisor.dev/gvisor/pkg/state/pretty"
-)
-
-// discard is an implementation of wire.Writer.
-type discard struct{}
-
-// Write implements wire.Writer.Write.
-func (discard) Write(p []byte) (int, error) { return len(p), nil }
-
-// WriteByte implements wire.Writer.WriteByte.
-func (discard) WriteByte(byte) error { return nil }
-
-// checkEqual checks if two objects are equal.
-//
-// N.B. This only handles one level of dereferences for NaN. Otherwise we
-// would need to fork the entire implementation of reflect.DeepEqual.
-func checkEqual(root, loadedValue interface{}) bool {
- if reflect.DeepEqual(root, loadedValue) {
- return true
- }
-
- // NaN is not equal to itself. We handle the case of raw floating point
- // primitives here, but don't handle this case nested.
- rf32, ok1 := root.(float32)
- lf32, ok2 := loadedValue.(float32)
- if ok1 && ok2 && math.IsNaN(float64(rf32)) && math.IsNaN(float64(lf32)) {
- return true
- }
- rf64, ok1 := root.(float64)
- lf64, ok2 := loadedValue.(float64)
- if ok1 && ok2 && math.IsNaN(rf64) && math.IsNaN(lf64) {
- return true
- }
-
- // Same real for complex numbers.
- rc64, ok1 := root.(complex64)
- lc64, ok2 := root.(complex64)
- if ok1 && ok2 {
- return checkEqual(real(rc64), real(lc64)) && checkEqual(imag(rc64), imag(lc64))
- }
- rc128, ok1 := root.(complex128)
- lc128, ok2 := root.(complex128)
- if ok1 && ok2 {
- return checkEqual(real(rc128), real(lc128)) && checkEqual(imag(rc128), imag(lc128))
- }
-
- return false
-}
-
-// runTestCases runs a test for each object in objects.
-func runTestCases(t *testing.T, shouldFail bool, prefix string, objects []interface{}) {
- t.Helper()
- for i, root := range objects {
- t.Run(fmt.Sprintf("%s%d", prefix, i), func(t *testing.T) {
- t.Logf("Original object:\n%#v", root)
-
- // Save the passed object.
- saveBuffer := &bytes.Buffer{}
- saveObjectPtr := reflect.New(reflect.TypeOf(root))
- saveObjectPtr.Elem().Set(reflect.ValueOf(root))
- saveStats, err := state.Save(context.Background(), saveBuffer, saveObjectPtr.Interface())
- if err != nil {
- if shouldFail {
- return
- }
- t.Fatalf("Save failed unexpectedly: %v", err)
- }
-
- // Dump the serialized proto to aid with debugging.
- var ppBuf bytes.Buffer
- t.Logf("Raw state:\n%v", saveBuffer.Bytes())
- if err := pretty.PrintText(&ppBuf, bytes.NewReader(saveBuffer.Bytes())); err != nil {
- // We don't count this as a test failure if we
- // have shouldFail set, but we will count as a
- // failure if we were not expecting to fail.
- if !shouldFail {
- t.Errorf("PrettyPrint(html=false) failed unexpected: %v", err)
- }
- }
- if err := pretty.PrintHTML(discard{}, bytes.NewReader(saveBuffer.Bytes())); err != nil {
- // See above.
- if !shouldFail {
- t.Errorf("PrettyPrint(html=true) failed unexpected: %v", err)
- }
- }
- t.Logf("Encoded state:\n%s", ppBuf.String())
- t.Logf("Save stats:\n%s", saveStats.String())
-
- // Load a new copy of the object.
- loadObjectPtr := reflect.New(reflect.TypeOf(root))
- loadStats, err := state.Load(context.Background(), bytes.NewReader(saveBuffer.Bytes()), loadObjectPtr.Interface())
- if err != nil {
- if shouldFail {
- return
- }
- t.Fatalf("Load failed unexpectedly: %v", err)
- }
-
- // Compare the values.
- loadedValue := loadObjectPtr.Elem().Interface()
- if !checkEqual(root, loadedValue) {
- if shouldFail {
- return
- }
- t.Fatalf("Objects differ:\n\toriginal: %#v\n\tloaded: %#v\n", root, loadedValue)
- }
-
- // Everything went okay. Is that good?
- if shouldFail {
- t.Fatalf("This test was expected to fail, but didn't.")
- }
- t.Logf("Load stats:\n%s", loadStats.String())
-
- // Truncate half the bytes in the byte stream,
- // and ensure that we can't restore. Then
- // truncate only the final byte and ensure that
- // we can't restore.
- l := saveBuffer.Len()
- halfReader := bytes.NewReader(saveBuffer.Bytes()[:l/2])
- if _, err := state.Load(context.Background(), halfReader, loadObjectPtr.Interface()); err == nil {
- t.Errorf("Load with half bytes succeeded unexpectedly.")
- }
- missingByteReader := bytes.NewReader(saveBuffer.Bytes()[:l-1])
- if _, err := state.Load(context.Background(), missingByteReader, loadObjectPtr.Interface()); err == nil {
- t.Errorf("Load with missing byte succeeded unexpectedly.")
- }
- })
- }
-}
-
-// convert converts the slice to an []interface{}.
-func convert(v interface{}) (r []interface{}) {
- s := reflect.ValueOf(v) // Must be slice.
- for i := 0; i < s.Len(); i++ {
- r = append(r, s.Index(i).Interface())
- }
- return r
-}
-
-// flatten flattens multiple slices.
-func flatten(vs ...interface{}) (r []interface{}) {
- for _, v := range vs {
- r = append(r, convert(v)...)
- }
- return r
-}
-
-// filter maps from one slice to another.
-func filter(vs interface{}, fn func(interface{}) (interface{}, bool)) (r []interface{}) {
- s := reflect.ValueOf(vs)
- for i := 0; i < s.Len(); i++ {
- v, ok := fn(s.Index(i).Interface())
- if ok {
- r = append(r, v)
- }
- }
- return r
-}
-
-// combine combines objects in two slices as specified.
-func combine(v1, v2 interface{}, fn func(_, _ interface{}) interface{}) (r []interface{}) {
- s1 := reflect.ValueOf(v1)
- s2 := reflect.ValueOf(v2)
- for i := 0; i < s1.Len(); i++ {
- for j := 0; j < s2.Len(); j++ {
- // Combine using the given function.
- r = append(r, fn(s1.Index(i).Interface(), s2.Index(j).Interface()))
- }
- }
- return r
-}
-
-// pointersTo is a filter function that returns pointers.
-func pointersTo(vs interface{}) []interface{} {
- return filter(vs, func(o interface{}) (interface{}, bool) {
- v := reflect.New(reflect.TypeOf(o))
- v.Elem().Set(reflect.ValueOf(o))
- return v.Interface(), true
- })
-}
-
-// interfacesTo is a filter function that returns interface objects.
-func interfacesTo(vs interface{}) []interface{} {
- return filter(vs, func(o interface{}) (interface{}, bool) {
- var v [1]interface{}
- v[0] = o
- return v, true
- })
-}