github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/pkg/state/tests/struct_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 package tests 16 17 import ( 18 "math/rand" 19 "testing" 20 ) 21 22 func TestEmptyStruct(t *testing.T) { 23 runTestCases(t, false, "plain", []interface{}{ 24 unregisteredEmptyStruct{}, 25 typeOnlyEmptyStruct{}, 26 savableEmptyStruct{}, 27 }) 28 runTestCases(t, false, "pointers", pointersTo([]interface{}{ 29 unregisteredEmptyStruct{}, 30 typeOnlyEmptyStruct{}, 31 savableEmptyStruct{}, 32 })) 33 runTestCases(t, false, "interfaces-pass", interfacesTo([]interface{}{ 34 // Only registered types can be dispatched via interfaces. All 35 // other types should fail, even if it is the empty struct. 36 savableEmptyStruct{}, 37 })) 38 runTestCases(t, true, "interfaces-fail", interfacesTo([]interface{}{ 39 unregisteredEmptyStruct{}, 40 typeOnlyEmptyStruct{}, 41 })) 42 runTestCases(t, false, "interfacesToPointers-pass", interfacesTo(pointersTo([]interface{}{ 43 savableEmptyStruct{}, 44 }))) 45 runTestCases(t, true, "interfacesToPointers-fail", interfacesTo(pointersTo([]interface{}{ 46 unregisteredEmptyStruct{}, 47 typeOnlyEmptyStruct{}, 48 }))) 49 50 // Ensuring empty struct aliasing works. 51 es := emptyStructPointer{new(struct{})} 52 runTestCases(t, false, "empty-struct-pointers", []interface{}{ 53 emptyStructPointer{}, 54 es, 55 []emptyStructPointer{es, es}, // Same pointer. 56 }) 57 } 58 59 func TestEmbeddedPointers(t *testing.T) { 60 // Give each int64 a random value to prevent Go from using 61 // runtime.staticuint64s, which confounds tests for struct duplication. 62 magic := func() int64 { 63 for { 64 n := rand.Int63() 65 if n < 0 || n > 255 { 66 return n 67 } 68 } 69 } 70 71 ofs := outerSame{inner{magic()}} 72 of1 := outerFieldFirst{inner{magic()}, magic()} 73 of2 := outerFieldSecond{magic(), inner{magic()}} 74 oa := outerArray{[2]inner{{magic()}, {magic()}}} 75 osl := outerSlice{oa.inner[:]} 76 ofv := outerFieldValue{innerFieldValue{magic()}} 77 78 runTestCases(t, false, "embedded-pointers", []interface{}{ 79 system{&ofs, &ofs.inner}, 80 system{&ofs.inner, &ofs}, 81 system{&of1, &of1.inner}, 82 system{&of1.inner, &of1}, 83 system{&of2, &of2.inner}, 84 system{&of2.inner, &of2}, 85 system{&oa, &oa.inner[0]}, 86 system{&oa, &oa.inner[1]}, 87 system{&oa.inner[0], &oa}, 88 system{&oa.inner[1], &oa}, 89 system3{&oa, &oa.inner[0], &oa.inner[1]}, 90 system3{&oa, &oa.inner[1], &oa.inner[0]}, 91 system3{&oa.inner[0], &oa, &oa.inner[1]}, 92 system3{&oa.inner[1], &oa, &oa.inner[0]}, 93 system3{&oa.inner[0], &oa.inner[1], &oa}, 94 system3{&oa.inner[1], &oa.inner[0], &oa}, 95 system{&oa, &osl}, 96 system{&osl, &oa}, 97 system{&ofv, &ofv.inner}, 98 system{&ofv.inner, &ofv}, 99 }) 100 }