github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/pkg/state/tests/register_test.go (about) 1 // Copyright 2018 The gVisor Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // +build race 16 17 package tests 18 19 import ( 20 "testing" 21 22 "github.com/SagerNet/gvisor/pkg/state" 23 ) 24 25 // faker calls itself whatever is in the name field. 26 type faker struct { 27 Name string 28 Fields []string 29 } 30 31 func (f *faker) StateTypeName() string { 32 return f.Name 33 } 34 35 func (f *faker) StateFields() []string { 36 return f.Fields 37 } 38 39 // fakerWithSaverLoader has all it needs. 40 type fakerWithSaverLoader struct { 41 faker 42 } 43 44 func (f *fakerWithSaverLoader) StateSave(m state.Sink) {} 45 46 func (f *fakerWithSaverLoader) StateLoad(m state.Source) {} 47 48 // fakerOther calls itself .. uh, itself? 49 type fakerOther string 50 51 func (f *fakerOther) StateTypeName() string { 52 return string(*f) 53 } 54 55 func (f *fakerOther) StateFields() []string { 56 return nil 57 } 58 59 func newFakerOther(name string) *fakerOther { 60 f := fakerOther(name) 61 return &f 62 } 63 64 // fakerOtherBadFields returns non-nil fields. 65 type fakerOtherBadFields string 66 67 func (f *fakerOtherBadFields) StateTypeName() string { 68 return string(*f) 69 } 70 71 func (f *fakerOtherBadFields) StateFields() []string { 72 return []string{string(*f)} 73 } 74 75 func newFakerOtherBadFields(name string) *fakerOtherBadFields { 76 f := fakerOtherBadFields(name) 77 return &f 78 } 79 80 // fakerOtherSaverLoader implements SaverLoader methods. 81 type fakerOtherSaverLoader string 82 83 func (f *fakerOtherSaverLoader) StateTypeName() string { 84 return string(*f) 85 } 86 87 func (f *fakerOtherSaverLoader) StateFields() []string { 88 return nil 89 } 90 91 func (f *fakerOtherSaverLoader) StateSave(m state.Sink) {} 92 93 func (f *fakerOtherSaverLoader) StateLoad(m state.Source) {} 94 95 func newFakerOtherSaverLoader(name string) *fakerOtherSaverLoader { 96 f := fakerOtherSaverLoader(name) 97 return &f 98 } 99 100 func TestRegisterPrimitives(t *testing.T) { 101 for _, typeName := range []string{ 102 "int", 103 "int8", 104 "int16", 105 "int32", 106 "int64", 107 "uint", 108 "uintptr", 109 "uint8", 110 "uint16", 111 "uint32", 112 "uint64", 113 "float32", 114 "float64", 115 "complex64", 116 "complex128", 117 "string", 118 } { 119 t.Run("struct/"+typeName, func(t *testing.T) { 120 defer func() { 121 if r := recover(); r == nil { 122 t.Errorf("Registering type %q did not panic", typeName) 123 } 124 }() 125 state.Register(&faker{ 126 Name: typeName, 127 }) 128 }) 129 t.Run("other/"+typeName, func(t *testing.T) { 130 defer func() { 131 if r := recover(); r == nil { 132 t.Errorf("Registering type %q did not panic", typeName) 133 } 134 }() 135 state.Register(newFakerOther(typeName)) 136 }) 137 } 138 } 139 140 func TestRegisterBad(t *testing.T) { 141 const ( 142 goodName = "foo" 143 firstField = "a" 144 secondField = "b" 145 ) 146 for name, object := range map[string]state.Type{ 147 "non-struct-with-fields": newFakerOtherBadFields(goodName), 148 "non-struct-with-saverloader": newFakerOtherSaverLoader(goodName), 149 "struct-without-saverloader": &faker{Name: goodName}, 150 "non-struct-duplicate-with-struct": newFakerOther((new(alreadyRegisteredStruct)).StateTypeName()), 151 "non-struct-duplicate-with-non-struct": newFakerOther((new(alreadyRegisteredOther)).StateTypeName()), 152 "struct-duplicate-with-struct": &fakerWithSaverLoader{faker{Name: (new(alreadyRegisteredStruct)).StateTypeName()}}, 153 "struct-duplicate-with-non-struct": &fakerWithSaverLoader{faker{Name: (new(alreadyRegisteredOther)).StateTypeName()}}, 154 "struct-with-empty-field": &fakerWithSaverLoader{faker{Name: goodName, Fields: []string{""}}}, 155 "struct-with-empty-field-and-non-empty": &fakerWithSaverLoader{faker{Name: goodName, Fields: []string{firstField, ""}}}, 156 "struct-with-duplicate-field": &fakerWithSaverLoader{faker{Name: goodName, Fields: []string{firstField, firstField}}}, 157 "struct-with-duplicate-field-and-non-dup": &fakerWithSaverLoader{faker{Name: goodName, Fields: []string{firstField, secondField, firstField}}}, 158 } { 159 t.Run(name, func(t *testing.T) { 160 defer func() { 161 if r := recover(); r == nil { 162 t.Errorf("Registering object %#v did not panic", object) 163 } 164 }() 165 state.Register(object) 166 }) 167 168 } 169 } 170 171 func TestRegisterTypeOnlyStruct(t *testing.T) { 172 defer func() { 173 if r := recover(); r == nil { 174 t.Errorf("Register did not panic") 175 } 176 }() 177 state.Register((*typeOnlyEmptyStruct)(nil)) 178 }