modernc.org/libc@v1.24.1/all_test.go (about)

     1  // Copyright 2020 The Libc Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package libc // import "modernc.org/libc"
     6  
     7  import (
     8  	"encoding/hex"
     9  	"os"
    10  	"path/filepath"
    11  	"runtime"
    12  	"testing"
    13  	"unsafe"
    14  )
    15  
    16  func TestXfmod(t *testing.T) {
    17  	x := 1.3518643030646695
    18  	y := 6.283185307179586
    19  	if g, e := Xfmod(nil, x, y), 1.3518643030646695; g != e {
    20  		t.Fatal(g, e)
    21  	}
    22  }
    23  
    24  func TestSwap(t *testing.T) {
    25  	if g, e := X__builtin_bswap16(nil, 0x1234), uint16(0x3412); g != e {
    26  		t.Errorf("%#04x %#04x", g, e)
    27  	}
    28  	if g, e := X__builtin_bswap32(nil, 0x12345678), uint32(0x78563412); g != e {
    29  		t.Errorf("%#04x %#04x", g, e)
    30  	}
    31  	if g, e := X__builtin_bswap64(nil, 0x123456789abcdef0), uint64(0xf0debc9a78563412); g != e {
    32  		t.Errorf("%#04x %#04x", g, e)
    33  	}
    34  }
    35  
    36  var (
    37  	valist       [256]byte
    38  	formatString [256]byte
    39  	srcString    [256]byte
    40  	testPrintfS1 = [...]byte{'X', 'Y', 0}
    41  )
    42  
    43  func TestPrintf(t *testing.T) {
    44  	isWindows = true
    45  	i := uint64(0x123456789abcdef)
    46  	j := uint64(0xf123456789abcde)
    47  	k := uint64(0x23456789abcdef1)
    48  	l := uint64(0xef123456789abcd)
    49  	for itest, test := range []struct {
    50  		fmt    string
    51  		args   []interface{}
    52  		result string
    53  	}{
    54  		{
    55  			"%I64x %I32x %I64x %I32x",
    56  			[]interface{}{int64(i), int32(j), int64(k), int32(l)},
    57  			"123456789abcdef 789abcde 23456789abcdef1 6789abcd",
    58  		},
    59  		{
    60  			"%llx %x %llx %x",
    61  			[]interface{}{int64(i), int32(j), int64(k), int32(l)},
    62  			"123456789abcdef 789abcde 23456789abcdef1 6789abcd",
    63  		},
    64  		{
    65  			"%.1s\n",
    66  			[]interface{}{uintptr(unsafe.Pointer(&testPrintfS1[0]))},
    67  			"X\n",
    68  		},
    69  		{
    70  			"%.2s\n",
    71  			[]interface{}{uintptr(unsafe.Pointer(&testPrintfS1[0]))},
    72  			"XY\n",
    73  		},
    74  	} {
    75  		copy(formatString[:], test.fmt+"\x00")
    76  		b := printf(uintptr(unsafe.Pointer(&formatString[0])), VaList(uintptr(unsafe.Pointer(&valist[0])), test.args...))
    77  		if g, e := string(b), test.result; g != e {
    78  			t.Errorf("%v: %q %q", itest, g, e)
    79  		}
    80  	}
    81  }
    82  
    83  func TestStrtod(t *testing.T) {
    84  	if runtime.GOOS == "windows" {
    85  		t.Skip("TODO")
    86  	}
    87  
    88  	tls := NewTLS()
    89  	defer tls.Close()
    90  
    91  	for itest, test := range []struct {
    92  		s      string
    93  		result float64
    94  	}{
    95  		{"+0", 0},
    96  		{"+1", 1},
    97  		{"+2", 2},
    98  		{"-0", 0},
    99  		{"-1", -1},
   100  		{"-2", -2},
   101  		{".5", .5},
   102  		{"0", 0},
   103  		{"1", 1},
   104  		{"1.", 1},
   105  		{"1.024e3", 1024},
   106  		{"16", 16},
   107  		{"2", 2},
   108  		{"32", 32},
   109  	} {
   110  		copy(srcString[:], test.s+"\x00")
   111  		if g, e := Xstrtod(tls, uintptr(unsafe.Pointer(&srcString[0])), 0), test.result; g != e {
   112  			t.Errorf("%v: %q: %v %v", itest, test.s, g, e)
   113  		}
   114  	}
   115  }
   116  
   117  func TestParseZone(t *testing.T) {
   118  	for itest, test := range []struct {
   119  		in, out string
   120  		off     int
   121  	}{
   122  		{"America/Los_Angeles", "America/Los_Angeles", 0},
   123  		{"America/Los_Angeles+12", "America/Los_Angeles", 43200},
   124  		{"America/Los_Angeles-12", "America/Los_Angeles", -43200},
   125  		{"UTC", "UTC", 0},
   126  		{"UTC+1", "UTC", 3600},
   127  		{"UTC+10", "UTC", 36000},
   128  		{"UTC-1", "UTC", -3600},
   129  		{"UTC-10", "UTC", -36000},
   130  	} {
   131  		out, off := parseZone(test.in)
   132  		if g, e := out, test.out; g != e {
   133  			t.Errorf("%d: %+v %v %v", itest, test, g, e)
   134  		}
   135  		if g, e := off, test.off; g != e {
   136  			t.Errorf("%d: %+v %v %v", itest, test, g, e)
   137  		}
   138  	}
   139  }
   140  
   141  func TestRint(t *testing.T) {
   142  	tls := NewTLS()
   143  	for itest, test := range []struct {
   144  		x, y float64
   145  	}{
   146  		{-1.1, -1.0},
   147  		{-1.0, -1.0},
   148  		{-0.9, -1.0},
   149  		{-0.51, -1.0},
   150  		{-0.49, 0},
   151  		{-0.1, 0},
   152  		{-0, 0},
   153  		{0.1, 0},
   154  		{0.49, 0},
   155  		{0.51, 1},
   156  		{0.9, 1},
   157  		{1, 1},
   158  		{1.1, 1},
   159  	} {
   160  		if g, e := Xrint(tls, test.x), test.y; g != e {
   161  			t.Errorf("#%d: x %v, got %v, expected %v", itest, test.x, g, e)
   162  		}
   163  	}
   164  }
   165  
   166  var testMemsetBuf [67]byte
   167  
   168  func TestMemset(t *testing.T) {
   169  	v := 0
   170  	for start := 0; start < len(testMemsetBuf); start++ {
   171  		for n := 0; n < len(testMemsetBuf)-start; n++ {
   172  			for x := range testMemsetBuf {
   173  				testMemsetBuf[x] = byte(v)
   174  				v++
   175  			}
   176  			for x := start; x < start+n; x++ {
   177  				testMemsetBuf[x] = byte(v)
   178  			}
   179  			e := testMemsetBuf
   180  			Xmemset(nil, uintptr(unsafe.Pointer(&testMemsetBuf[start])), int32(v), size_t(n))
   181  			if testMemsetBuf != e {
   182  				t.Fatalf("start %v, v %#x n %v, exp\n%s\ngot\n%s", start, byte(v), n, hex.Dump(e[:]), hex.Dump(testMemsetBuf[:]))
   183  			}
   184  		}
   185  	}
   186  }
   187  
   188  const testGetentropySize = 100
   189  
   190  var testGetentropyBuf [testGetentropySize]byte
   191  
   192  func TestGetentropy(t *testing.T) {
   193  	Xgetentropy(NewTLS(), uintptr(unsafe.Pointer(&testGetentropyBuf[0])), testGetentropySize)
   194  	t.Logf("\n%s", hex.Dump(testGetentropyBuf[:]))
   195  }
   196  
   197  func TestReallocArray(t *testing.T) {
   198  	const size = 16
   199  	tls := NewTLS()
   200  	p := Xmalloc(tls, size)
   201  	if p == 0 {
   202  		t.Fatal()
   203  	}
   204  
   205  	for i := 0; i < size; i++ {
   206  		(*RawMem)(unsafe.Pointer(p))[i] = byte(i ^ 0x55)
   207  	}
   208  
   209  	q := Xreallocarray(tls, p, 2, size)
   210  	if q == 0 {
   211  		t.Fatal()
   212  	}
   213  
   214  	for i := 0; i < size; i++ {
   215  		if g, e := (*RawMem)(unsafe.Pointer(q))[i], byte(i^0x55); g != e {
   216  			t.Fatal(i, g, e)
   217  		}
   218  	}
   219  }
   220  
   221  func mustCString(s string) uintptr {
   222  	r, err := CString(s)
   223  	if err != nil {
   224  		panic("CString failed")
   225  	}
   226  
   227  	return r
   228  }
   229  
   230  var testSnprintfBuf [3]byte
   231  
   232  func TestSnprintf(t *testing.T) {
   233  	testSnprintfBuf = [3]byte{0xff, 0xff, 0xff}
   234  	p := uintptr(unsafe.Pointer(&testSnprintfBuf[0]))
   235  	if g, e := Xsnprintf(nil, p, 0, 0, 0), int32(0); g != e {
   236  		t.Fatal(g, e)
   237  	}
   238  
   239  	if g, e := testSnprintfBuf, [3]byte{0xff, 0xff, 0xff}; g != e {
   240  		t.Fatal(g, e)
   241  	}
   242  
   243  	if g, e := Xsnprintf(nil, p, 0, mustCString(""), 0), int32(0); g != e {
   244  		t.Fatal(g, e)
   245  	}
   246  
   247  	if g, e := testSnprintfBuf, [3]byte{0xff, 0xff, 0xff}; g != e {
   248  		t.Fatal(g, e)
   249  	}
   250  
   251  	s := mustCString("12")
   252  	if g, e := Xsnprintf(nil, p, 0, s, 0), int32(2); g != e {
   253  		t.Fatal(g, e)
   254  	}
   255  
   256  	if g, e := testSnprintfBuf, [3]byte{0xff, 0xff, 0xff}; g != e {
   257  		t.Fatal(g, e)
   258  	}
   259  
   260  	if g, e := Xsnprintf(nil, p, 1, s, 0), int32(2); g != e {
   261  		t.Fatal(g, e)
   262  	}
   263  
   264  	if g, e := testSnprintfBuf, [3]byte{0x00, 0xff, 0xff}; g != e {
   265  		t.Fatal(g, e)
   266  	}
   267  
   268  	testSnprintfBuf = [3]byte{0xff, 0xff, 0xff}
   269  	if g, e := Xsnprintf(nil, p, 2, s, 0), int32(2); g != e {
   270  		t.Fatal(g, e)
   271  	}
   272  
   273  	if g, e := testSnprintfBuf, [3]byte{'1', 0x00, 0xff}; g != e {
   274  		t.Fatal(g, e)
   275  	}
   276  
   277  	testSnprintfBuf = [3]byte{0xff, 0xff, 0xff}
   278  	if g, e := Xsnprintf(nil, p, 3, s, 0), int32(2); g != e {
   279  		t.Fatal(g, e)
   280  	}
   281  
   282  	if g, e := testSnprintfBuf, [3]byte{'1', '2', 0x00}; g != e {
   283  		t.Fatal(g, e)
   284  	}
   285  }
   286  
   287  var testFdopenBuf [100]byte
   288  
   289  func TestFdopen(t *testing.T) {
   290  	if runtime.GOOS == "windows" {
   291  		t.Skip("not implemented on Windows")
   292  	}
   293  
   294  	const s = "foobarbaz\n"
   295  	tempdir := t.TempDir()
   296  	f, err := os.Create(filepath.Join(tempdir, "test_fdopen"))
   297  	if err != nil {
   298  		t.Fatal(err)
   299  	}
   300  
   301  	if _, err := f.Write([]byte(s)); err != nil {
   302  		t.Fatal(err)
   303  	}
   304  
   305  	if _, err := f.Seek(0, os.SEEK_SET); err != nil {
   306  		t.Fatal(err)
   307  	}
   308  
   309  	tls := NewTLS()
   310  
   311  	defer tls.Close()
   312  
   313  	p := Xfdopen(tls, int32(f.Fd()), mustCString("r"))
   314  
   315  	bp := uintptr(unsafe.Pointer(&testFdopenBuf))
   316  	if g, e := Xfread(tls, bp, 1, size_t(len(testFdopenBuf)), p), size_t(len(s)); g != e {
   317  		t.Fatal(g, e)
   318  	}
   319  
   320  	if g, e := string(GoBytes(bp, len(s))), s; g != e {
   321  		t.Fatalf("%q %q", g, e)
   322  	}
   323  }
   324  
   325  func TestSync(t *testing.T) {
   326  	tls := NewTLS()
   327  	X__sync_synchronize(tls)
   328  	tls.Close()
   329  }
   330  
   331  func TestProbes(t *testing.T) {
   332  	p := NewPerfCounter([]string{"a", "b", "c"})
   333  	p.Inc(1)
   334  	t.Logf("====\n%s\n----", p)
   335  	c := NewStackCapture(100)
   336  	for i := 0; i < 20; i++ {
   337  		c.Record()
   338  		if i%3 == 0 {
   339  			c.Record()
   340  		}
   341  	}
   342  	t.Logf("====\n%s\n----", c)
   343  }