mirror of
				https://github.com/tailscale/tailscale.git
				synced 2025-10-31 16:22:03 +01:00 
			
		
		
		
	Updates #11058 Change-Id: I35e7ef9b90e83cac04ca93fd964ad00ed5b48430 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
		
			
				
	
	
		
			151 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			151 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // Copyright (c) Tailscale Inc & AUTHORS
 | |
| // SPDX-License-Identifier: BSD-3-Clause
 | |
| 
 | |
| package cstruct
 | |
| 
 | |
| import (
 | |
| 	"errors"
 | |
| 	"fmt"
 | |
| 	"io"
 | |
| 	"testing"
 | |
| )
 | |
| 
 | |
| func TestPadBytes(t *testing.T) {
 | |
| 	testCases := []struct {
 | |
| 		offset int
 | |
| 		size   int
 | |
| 		want   int
 | |
| 	}{
 | |
| 		// No padding at beginning of structure
 | |
| 		{0, 1, 0},
 | |
| 		{0, 2, 0},
 | |
| 		{0, 4, 0},
 | |
| 		{0, 8, 0},
 | |
| 
 | |
| 		// No padding for single bytes
 | |
| 		{1, 1, 0},
 | |
| 
 | |
| 		// Single byte padding
 | |
| 		{1, 2, 1},
 | |
| 		{3, 4, 1},
 | |
| 
 | |
| 		// Multi-byte padding
 | |
| 		{1, 4, 3},
 | |
| 		{2, 8, 6},
 | |
| 	}
 | |
| 	for _, tc := range testCases {
 | |
| 		t.Run(fmt.Sprintf("%d_%d_%d", tc.offset, tc.size, tc.want), func(t *testing.T) {
 | |
| 			got := padBytes(tc.offset, tc.size)
 | |
| 			if got != tc.want {
 | |
| 				t.Errorf("got=%d; want=%d", got, tc.want)
 | |
| 			}
 | |
| 		})
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func TestDecoder(t *testing.T) {
 | |
| 	t.Run("UnsignedTypes", func(t *testing.T) {
 | |
| 		dec := func(n int) *Decoder {
 | |
| 			buf := make([]byte, n)
 | |
| 			buf[0] = 1
 | |
| 
 | |
| 			d := NewDecoder(buf)
 | |
| 
 | |
| 			// Use t.Cleanup to perform an assertion on this
 | |
| 			// decoder after the test code is finished with it.
 | |
| 			t.Cleanup(func() {
 | |
| 				if err := d.Err(); err != nil {
 | |
| 					t.Fatal(err)
 | |
| 				}
 | |
| 			})
 | |
| 			return d
 | |
| 		}
 | |
| 		if got := dec(2).Uint16(); got != 1 {
 | |
| 			t.Errorf("uint16: got=%d; want=1", got)
 | |
| 		}
 | |
| 		if got := dec(4).Uint32(); got != 1 {
 | |
| 			t.Errorf("uint32: got=%d; want=1", got)
 | |
| 		}
 | |
| 		if got := dec(8).Uint64(); got != 1 {
 | |
| 			t.Errorf("uint64: got=%d; want=1", got)
 | |
| 		}
 | |
| 		if got := dec(pointerSize / 8).Uintptr(); got != 1 {
 | |
| 			t.Errorf("uintptr: got=%d; want=1", got)
 | |
| 		}
 | |
| 	})
 | |
| 
 | |
| 	t.Run("SignedTypes", func(t *testing.T) {
 | |
| 		dec := func(n int) *Decoder {
 | |
| 			// Make a buffer of the exact size that consists of 0xff bytes
 | |
| 			buf := make([]byte, n)
 | |
| 			for i := range n {
 | |
| 				buf[i] = 0xff
 | |
| 			}
 | |
| 
 | |
| 			d := NewDecoder(buf)
 | |
| 
 | |
| 			// Use t.Cleanup to perform an assertion on this
 | |
| 			// decoder after the test code is finished with it.
 | |
| 			t.Cleanup(func() {
 | |
| 				if err := d.Err(); err != nil {
 | |
| 					t.Fatal(err)
 | |
| 				}
 | |
| 			})
 | |
| 			return d
 | |
| 		}
 | |
| 		if got := dec(2).Int16(); got != -1 {
 | |
| 			t.Errorf("int16: got=%d; want=-1", got)
 | |
| 		}
 | |
| 		if got := dec(4).Int32(); got != -1 {
 | |
| 			t.Errorf("int32: got=%d; want=-1", got)
 | |
| 		}
 | |
| 		if got := dec(8).Int64(); got != -1 {
 | |
| 			t.Errorf("int64: got=%d; want=-1", got)
 | |
| 		}
 | |
| 	})
 | |
| 
 | |
| 	t.Run("InsufficientData", func(t *testing.T) {
 | |
| 		dec := func(n int) *Decoder {
 | |
| 			// Make a buffer that's too small and contains arbitrary bytes
 | |
| 			buf := make([]byte, n-1)
 | |
| 			for i := range n - 1 {
 | |
| 				buf[i] = 0xAD
 | |
| 			}
 | |
| 
 | |
| 			// Use t.Cleanup to perform an assertion on this
 | |
| 			// decoder after the test code is finished with it.
 | |
| 			d := NewDecoder(buf)
 | |
| 			t.Cleanup(func() {
 | |
| 				if err := d.Err(); err == nil || !errors.Is(err, io.EOF) {
 | |
| 					t.Errorf("(n=%d) expected io.EOF; got=%v", n, err)
 | |
| 				}
 | |
| 			})
 | |
| 			return d
 | |
| 		}
 | |
| 
 | |
| 		dec(2).Uint16()
 | |
| 		dec(4).Uint32()
 | |
| 		dec(8).Uint64()
 | |
| 		dec(pointerSize / 8).Uintptr()
 | |
| 
 | |
| 		dec(2).Int16()
 | |
| 		dec(4).Int32()
 | |
| 		dec(8).Int64()
 | |
| 	})
 | |
| 
 | |
| 	t.Run("Bytes", func(t *testing.T) {
 | |
| 		d := NewDecoder([]byte("hello worldasdf"))
 | |
| 		t.Cleanup(func() {
 | |
| 			if err := d.Err(); err != nil {
 | |
| 				t.Fatal(err)
 | |
| 			}
 | |
| 		})
 | |
| 
 | |
| 		buf := make([]byte, 11)
 | |
| 		d.Bytes(buf)
 | |
| 		if got := string(buf); got != "hello world" {
 | |
| 			t.Errorf("bytes: got=%q; want=%q", got, "hello world")
 | |
| 		}
 | |
| 	})
 | |
| }
 |