lab.nexedi.com/kirr/go123@v0.0.0-20240207185015-8299741fa871/xbytes/alloc_test.go (about)

     1  // Copyright (C) 2017  Nexedi SA and Contributors.
     2  //                     Kirill Smelkov <kirr@nexedi.com>
     3  //
     4  // This program is free software: you can Use, Study, Modify and Redistribute
     5  // it under the terms of the GNU General Public License version 3, or (at your
     6  // option) any later version, as published by the Free Software Foundation.
     7  //
     8  // You can also Link and Combine this program with other software covered by
     9  // the terms of any of the Free Software licenses or any of the Open Source
    10  // Initiative approved licenses and Convey the resulting work. Corresponding
    11  // source of such a combination shall include the source code for all other
    12  // software used.
    13  //
    14  // This program is distributed WITHOUT ANY WARRANTY; without even the implied
    15  // warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    16  //
    17  // See COPYING file for full licensing terms.
    18  // See https://www.nexedi.com/licensing for rationale and options.
    19  
    20  package xbytes
    21  
    22  import (
    23  	"bytes"
    24  	"reflect"
    25  	"testing"
    26  	"unsafe"
    27  )
    28  
    29  // aliases returns whether two slice memory is aliased
    30  func aliases(b1, b2 []byte) bool {
    31  	s1 := (*reflect.SliceHeader)(unsafe.Pointer(&b1))
    32  	s2 := (*reflect.SliceHeader)(unsafe.Pointer(&b2))
    33  	return s1.Data == s2.Data
    34  }
    35  
    36  func TestSlice(t *testing.T) {
    37  	s := make([]byte, 0, 10)
    38  
    39  	testv := []struct {op func([]byte, int) []byte; n, Len, Cap int; aliased bool; content []byte} {
    40  		// op,    n, Len, Cap, aliased, content
    41  		{Grow,     5,  5, 10, true,  []byte{0,0,0,0,0}},
    42  
    43  		// here "Hello" is assigned
    44  		{Grow,     6, 11, 16, false, []byte("Hello\x00\x00\x00\x00\x00\x00")},
    45  		{MakeRoom, 4, 11, 16, true,  []byte("Hello\x00\x00\x00\x00\x00\x00")},
    46  		{MakeRoom, 6, 11, 32, false, []byte("Hello\x00\x00\x00\x00\x00\x00")},
    47  		{Resize,   8,  8, 32, true,  []byte("Hello\x00\x00\x00")},
    48  		{Resize,  33, 33, 64, false, append([]byte("Hello"), bytes.Repeat([]byte{0}, 33-5)...)},
    49  		{Realloc, 16, 16, 64, true,  []byte("Hello\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")},
    50  		{Realloc, 65, 65, 128, false, make([]byte, 65)},
    51  	}
    52  
    53  	for i, tt := range testv {
    54  		sprev := s
    55  		s = tt.op(s, tt.n)
    56  
    57  		if !(len(s) == tt.Len && cap(s) == tt.Cap && bytes.Equal(s, tt.content)) {
    58  			t.Fatalf("step %d: %v: unexpected slice state: %v (cap: %v)", i, tt, s, cap(s))
    59  		}
    60  
    61  		if !(aliases(s, sprev) == tt.aliased) {
    62  			t.Fatalf("step %d: %v: unexpected slice aliasing: %v", i, tt, aliases(s, sprev))
    63  		}
    64  
    65  
    66  		// assign data after first iteration
    67  		if i == 0 {
    68  			copy(s, "Hello")
    69  		}
    70  	}
    71  }