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  }