github.com/FlowerWrong/netstack@v0.0.0-20191009141956-e5848263af28/tcpip/buffer/view_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 buffer_test contains tests for the VectorisedView type.
    16  package buffer
    17  
    18  import (
    19  	"reflect"
    20  	"testing"
    21  )
    22  
    23  // copy returns a deep-copy of the vectorised view.
    24  func (vv VectorisedView) copy() VectorisedView {
    25  	uu := VectorisedView{
    26  		views: make([]View, 0, len(vv.views)),
    27  		size:  vv.size,
    28  	}
    29  	for _, v := range vv.views {
    30  		uu.views = append(uu.views, append(View(nil), v...))
    31  	}
    32  	return uu
    33  }
    34  
    35  // vv is an helper to build VectorisedView from different strings.
    36  func vv(size int, pieces ...string) VectorisedView {
    37  	views := make([]View, len(pieces))
    38  	for i, p := range pieces {
    39  		views[i] = []byte(p)
    40  	}
    41  
    42  	return NewVectorisedView(size, views)
    43  }
    44  
    45  var capLengthTestCases = []struct {
    46  	comment string
    47  	in      VectorisedView
    48  	length  int
    49  	want    VectorisedView
    50  }{
    51  	{
    52  		comment: "Simple case",
    53  		in:      vv(2, "12"),
    54  		length:  1,
    55  		want:    vv(1, "1"),
    56  	},
    57  	{
    58  		comment: "Case spanning across two Views",
    59  		in:      vv(4, "123", "4"),
    60  		length:  2,
    61  		want:    vv(2, "12"),
    62  	},
    63  	{
    64  		comment: "Corner case with negative length",
    65  		in:      vv(1, "1"),
    66  		length:  -1,
    67  		want:    vv(0),
    68  	},
    69  	{
    70  		comment: "Corner case with length = 0",
    71  		in:      vv(3, "12", "3"),
    72  		length:  0,
    73  		want:    vv(0),
    74  	},
    75  	{
    76  		comment: "Corner case with length = size",
    77  		in:      vv(1, "1"),
    78  		length:  1,
    79  		want:    vv(1, "1"),
    80  	},
    81  	{
    82  		comment: "Corner case with length > size",
    83  		in:      vv(1, "1"),
    84  		length:  2,
    85  		want:    vv(1, "1"),
    86  	},
    87  }
    88  
    89  func TestCapLength(t *testing.T) {
    90  	for _, c := range capLengthTestCases {
    91  		orig := c.in.copy()
    92  		c.in.CapLength(c.length)
    93  		if !reflect.DeepEqual(c.in, c.want) {
    94  			t.Errorf("Test \"%s\" failed when calling CapLength(%d) on %v. Got %v. Want %v",
    95  				c.comment, c.length, orig, c.in, c.want)
    96  		}
    97  	}
    98  }
    99  
   100  var trimFrontTestCases = []struct {
   101  	comment string
   102  	in      VectorisedView
   103  	count   int
   104  	want    VectorisedView
   105  }{
   106  	{
   107  		comment: "Simple case",
   108  		in:      vv(2, "12"),
   109  		count:   1,
   110  		want:    vv(1, "2"),
   111  	},
   112  	{
   113  		comment: "Case where we trim an entire View",
   114  		in:      vv(2, "1", "2"),
   115  		count:   1,
   116  		want:    vv(1, "2"),
   117  	},
   118  	{
   119  		comment: "Case spanning across two Views",
   120  		in:      vv(3, "1", "23"),
   121  		count:   2,
   122  		want:    vv(1, "3"),
   123  	},
   124  	{
   125  		comment: "Corner case with negative count",
   126  		in:      vv(1, "1"),
   127  		count:   -1,
   128  		want:    vv(1, "1"),
   129  	},
   130  	{
   131  		comment: " Corner case with count = 0",
   132  		in:      vv(1, "1"),
   133  		count:   0,
   134  		want:    vv(1, "1"),
   135  	},
   136  	{
   137  		comment: "Corner case with count = size",
   138  		in:      vv(1, "1"),
   139  		count:   1,
   140  		want:    vv(0),
   141  	},
   142  	{
   143  		comment: "Corner case with count > size",
   144  		in:      vv(1, "1"),
   145  		count:   2,
   146  		want:    vv(0),
   147  	},
   148  }
   149  
   150  func TestTrimFront(t *testing.T) {
   151  	for _, c := range trimFrontTestCases {
   152  		orig := c.in.copy()
   153  		c.in.TrimFront(c.count)
   154  		if !reflect.DeepEqual(c.in, c.want) {
   155  			t.Errorf("Test \"%s\" failed when calling TrimFront(%d) on %v. Got %v. Want %v",
   156  				c.comment, c.count, orig, c.in, c.want)
   157  		}
   158  	}
   159  }
   160  
   161  var toViewCases = []struct {
   162  	comment string
   163  	in      VectorisedView
   164  	want    View
   165  }{
   166  	{
   167  		comment: "Simple case",
   168  		in:      vv(2, "12"),
   169  		want:    []byte("12"),
   170  	},
   171  	{
   172  		comment: "Case with multiple views",
   173  		in:      vv(2, "1", "2"),
   174  		want:    []byte("12"),
   175  	},
   176  	{
   177  		comment: "Empty case",
   178  		in:      vv(0),
   179  		want:    []byte(""),
   180  	},
   181  }
   182  
   183  func TestToView(t *testing.T) {
   184  	for _, c := range toViewCases {
   185  		got := c.in.ToView()
   186  		if !reflect.DeepEqual(got, c.want) {
   187  			t.Errorf("Test \"%s\" failed when calling ToView() on %v. Got %v. Want %v",
   188  				c.comment, c.in, got, c.want)
   189  		}
   190  	}
   191  }
   192  
   193  var toCloneCases = []struct {
   194  	comment  string
   195  	inView   VectorisedView
   196  	inBuffer []View
   197  }{
   198  	{
   199  		comment:  "Simple case",
   200  		inView:   vv(1, "1"),
   201  		inBuffer: make([]View, 1),
   202  	},
   203  	{
   204  		comment:  "Case with multiple views",
   205  		inView:   vv(2, "1", "2"),
   206  		inBuffer: make([]View, 2),
   207  	},
   208  	{
   209  		comment:  "Case with buffer too small",
   210  		inView:   vv(2, "1", "2"),
   211  		inBuffer: make([]View, 1),
   212  	},
   213  	{
   214  		comment:  "Case with buffer larger than needed",
   215  		inView:   vv(1, "1"),
   216  		inBuffer: make([]View, 2),
   217  	},
   218  	{
   219  		comment:  "Case with nil buffer",
   220  		inView:   vv(1, "1"),
   221  		inBuffer: nil,
   222  	},
   223  }
   224  
   225  func TestToClone(t *testing.T) {
   226  	for _, c := range toCloneCases {
   227  		t.Run(c.comment, func(t *testing.T) {
   228  			got := c.inView.Clone(c.inBuffer)
   229  			if !reflect.DeepEqual(got, c.inView) {
   230  				t.Fatalf("got (%+v).Clone(%+v) = %+v, want = %+v",
   231  					c.inView, c.inBuffer, got, c.inView)
   232  			}
   233  		})
   234  	}
   235  }