github.com/grailbio/base@v0.0.11/fatbin/fatbin_test.go (about)

     1  // Copyright 2019 GRAIL, Inc. All rights reserved.
     2  // Use of this source code is governed by the Apache 2.0
     3  // license that can be found in the LICENSE file.
     4  
     5  package fatbin
     6  
     7  import (
     8  	"bytes"
     9  	"io"
    10  	"io/ioutil"
    11  	"os"
    12  	"runtime"
    13  	"testing"
    14  )
    15  
    16  func TestFatbin(t *testing.T) {
    17  	filename, err := os.Executable()
    18  	if err != nil {
    19  		t.Fatal(err)
    20  	}
    21  	body, err := ioutil.ReadFile(filename)
    22  	if err != nil {
    23  		t.Fatal(err)
    24  	}
    25  
    26  	self, err := Self()
    27  	if err != nil {
    28  		t.Fatal(err)
    29  	}
    30  	r, err := self.Open(runtime.GOOS, runtime.GOARCH)
    31  	if err != nil {
    32  		t.Fatal(err)
    33  	}
    34  	defer r.Close()
    35  	embedded, err := ioutil.ReadAll(r)
    36  	if err != nil {
    37  		t.Fatal(err)
    38  	}
    39  	if !bytes.Equal(body, embedded) {
    40  		t.Error("content mismatch")
    41  	}
    42  
    43  	info, ok := self.Stat(runtime.GOOS, runtime.GOARCH)
    44  	if !ok {
    45  		t.Fatal(runtime.GOOS, "/", runtime.GOARCH, ": not found")
    46  	}
    47  	if got, want := info.Size, int64(len(embedded)); got != want {
    48  		t.Errorf("got %v, want %v", got, want)
    49  	}
    50  }
    51  
    52  func TestFatbinNonExist(t *testing.T) {
    53  	self, err := Self()
    54  	if err != nil {
    55  		t.Fatal(err)
    56  	}
    57  	_, err = self.Open("nonexistent", "nope")
    58  	if got, want := err, ErrNoSuchImage; got != want {
    59  		t.Errorf("got %v, want %v", got, want)
    60  	}
    61  }
    62  
    63  func TestSniff(t *testing.T) {
    64  	filename, err := os.Executable()
    65  	if err != nil {
    66  		t.Fatal(err)
    67  	}
    68  	f, err := os.Open(filename)
    69  	if err != nil {
    70  		t.Fatal(err)
    71  	}
    72  	defer f.Close()
    73  	info, err := f.Stat()
    74  	if err != nil {
    75  		t.Fatal(err)
    76  	}
    77  
    78  	goos, goarch, size, err := Sniff(f, info.Size())
    79  	if err != nil {
    80  		t.Fatal(err)
    81  	}
    82  	if got, want := goarch, runtime.GOARCH; got != want {
    83  		t.Errorf("got %v, want %v", got, want)
    84  	}
    85  	if got, want := goos, runtime.GOOS; got != want {
    86  		t.Errorf("got %v, want %v", got, want)
    87  	}
    88  	if got, want := size, info.Size(); got != want {
    89  		t.Errorf("got %v, want %v", got, want)
    90  	}
    91  }
    92  
    93  func TestLinuxElf(t *testing.T) {
    94  	r := bytes.NewReader(svelteLinuxElfBinary)
    95  	goos, goarch, size, err := Sniff(r, int64(r.Len()))
    96  	if err != nil {
    97  		t.Fatal(err)
    98  	}
    99  	if got, want := goos, "linux"; got != want {
   100  		t.Errorf("got %v, want %v", got, want)
   101  	}
   102  	if got, want := goarch, "386"; got != want {
   103  		t.Errorf("got %v, want %v", got, want)
   104  	}
   105  	if got, want := size, len(svelteLinuxElfBinary); got != int64(want) {
   106  		t.Errorf("got %v, want %v", got, want)
   107  	}
   108  }
   109  
   110  func TestCreate(t *testing.T) {
   111  	f, err := ioutil.TempFile("", "")
   112  	must(t, err)
   113  	_, err = f.Write(svelteLinuxElfBinary)
   114  	must(t, err)
   115  	w, err := NewFileWriter(f)
   116  	must(t, err)
   117  	dw, err := w.Create("darwin", "amd64")
   118  	must(t, err)
   119  	_, err = dw.Write([]byte("darwin/amd64"))
   120  	must(t, err)
   121  	dw, err = w.Create("darwin", "386")
   122  	must(t, err)
   123  	_, err = dw.Write([]byte("darwin/386"))
   124  	must(t, err)
   125  	must(t, w.Close())
   126  	info, err := f.Stat()
   127  	must(t, err)
   128  	r, err := OpenFile(f, info.Size())
   129  	must(t, err)
   130  
   131  	cases := []struct {
   132  		goos, goarch string
   133  		body         []byte
   134  	}{
   135  		{"linux", "386", svelteLinuxElfBinary},
   136  		{"darwin", "amd64", []byte("darwin/amd64")},
   137  		{"darwin", "386", []byte("darwin/386")},
   138  	}
   139  	for _, c := range cases {
   140  		rc, err := r.Open(c.goos, c.goarch)
   141  		if err != nil {
   142  			t.Fatal(err)
   143  		}
   144  		mustBytes(t, rc, c.body)
   145  		must(t, rc.Close())
   146  		info, ok := r.Stat(c.goos, c.goarch)
   147  		if !ok {
   148  			t.Error(c.goos, "/", c.goarch, ": not found")
   149  			continue
   150  		}
   151  		if got, want := info.Size, int64(len(c.body)); got != want {
   152  			t.Errorf("%s/%s: got %v, want %v", c.goos, c.goarch, got, want)
   153  		}
   154  	}
   155  
   156  	_, err = r.Open("test", "nope")
   157  	if got, want := err, ErrNoSuchImage; got != want {
   158  		t.Errorf("got %v, want %v", got, want)
   159  	}
   160  }
   161  
   162  func must(t *testing.T, err error) {
   163  	t.Helper()
   164  	if err != nil {
   165  		t.Fatal(err)
   166  	}
   167  }
   168  
   169  func mustBytes(t *testing.T, r io.Reader, want []byte) {
   170  	t.Helper()
   171  	got, err := ioutil.ReadAll(r)
   172  	if err != nil {
   173  		t.Fatal(err)
   174  	}
   175  	if !bytes.Equal(got, want) {
   176  		t.Errorf("got %s, want %s", got, want)
   177  	}
   178  }