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  }