Home | History | Annotate | Download | only in buildid
      1 // Copyright 2017 The Go 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 buildid
      6 
      7 import (
      8 	"bytes"
      9 	"crypto/sha256"
     10 	"io/ioutil"
     11 	"os"
     12 	"reflect"
     13 	"testing"
     14 )
     15 
     16 const (
     17 	expectedID = "abcdefghijklmnopqrstuvwxyz.1234567890123456789012345678901234567890123456789012345678901234"
     18 	newID      = "bcdefghijklmnopqrstuvwxyza.2345678901234567890123456789012345678901234567890123456789012341"
     19 )
     20 
     21 func TestReadFile(t *testing.T) {
     22 	var files = []string{
     23 		"p.a",
     24 		"a.elf",
     25 		"a.macho",
     26 		"a.pe",
     27 	}
     28 
     29 	f, err := ioutil.TempFile("", "buildid-test-")
     30 	if err != nil {
     31 		t.Fatal(err)
     32 	}
     33 	tmp := f.Name()
     34 	defer os.Remove(tmp)
     35 	f.Close()
     36 
     37 	for _, f := range files {
     38 		id, err := ReadFile("testdata/" + f)
     39 		if id != expectedID || err != nil {
     40 			t.Errorf("ReadFile(testdata/%s) = %q, %v, want %q, nil", f, id, err, expectedID)
     41 		}
     42 		old := readSize
     43 		readSize = 2048
     44 		id, err = ReadFile("testdata/" + f)
     45 		readSize = old
     46 		if id != expectedID || err != nil {
     47 			t.Errorf("ReadFile(testdata/%s) [readSize=2k] = %q, %v, want %q, nil", f, id, err, expectedID)
     48 		}
     49 
     50 		data, err := ioutil.ReadFile("testdata/" + f)
     51 		if err != nil {
     52 			t.Fatal(err)
     53 		}
     54 		m, _, err := FindAndHash(bytes.NewReader(data), expectedID, 1024)
     55 		if err != nil {
     56 			t.Errorf("FindAndHash(testdata/%s): %v", f, err)
     57 			continue
     58 		}
     59 		if err := ioutil.WriteFile(tmp, data, 0666); err != nil {
     60 			t.Error(err)
     61 			continue
     62 		}
     63 		tf, err := os.OpenFile(tmp, os.O_WRONLY, 0)
     64 		if err != nil {
     65 			t.Error(err)
     66 			continue
     67 		}
     68 		err = Rewrite(tf, m, newID)
     69 		err2 := tf.Close()
     70 		if err != nil {
     71 			t.Errorf("Rewrite(testdata/%s): %v", f, err)
     72 			continue
     73 		}
     74 		if err2 != nil {
     75 			t.Fatal(err2)
     76 		}
     77 
     78 		id, err = ReadFile(tmp)
     79 		if id != newID || err != nil {
     80 			t.Errorf("ReadFile(testdata/%s after Rewrite) = %q, %v, want %q, nil", f, id, err, newID)
     81 		}
     82 	}
     83 }
     84 
     85 func TestFindAndHash(t *testing.T) {
     86 	buf := make([]byte, 64)
     87 	buf2 := make([]byte, 64)
     88 	id := make([]byte, 8)
     89 	zero := make([]byte, 8)
     90 	for i := range id {
     91 		id[i] = byte(i)
     92 	}
     93 	numError := 0
     94 	errorf := func(msg string, args ...interface{}) {
     95 		t.Errorf(msg, args...)
     96 		if numError++; numError > 20 {
     97 			t.Logf("stopping after too many errors")
     98 			t.FailNow()
     99 		}
    100 	}
    101 	for bufSize := len(id); bufSize <= len(buf); bufSize++ {
    102 		for j := range buf {
    103 			for k := 0; k < 2*len(id) && j+k < len(buf); k++ {
    104 				for i := range buf {
    105 					buf[i] = 1
    106 				}
    107 				copy(buf[j:], id)
    108 				copy(buf[j+k:], id)
    109 				var m []int64
    110 				if j+len(id) <= j+k {
    111 					m = append(m, int64(j))
    112 				}
    113 				if j+k+len(id) <= len(buf) {
    114 					m = append(m, int64(j+k))
    115 				}
    116 				copy(buf2, buf)
    117 				for _, p := range m {
    118 					copy(buf2[p:], zero)
    119 				}
    120 				h := sha256.Sum256(buf2)
    121 
    122 				matches, hash, err := FindAndHash(bytes.NewReader(buf), string(id), bufSize)
    123 				if err != nil {
    124 					errorf("bufSize=%d j=%d k=%d: findAndHash: %v", bufSize, j, k, err)
    125 					continue
    126 				}
    127 				if !reflect.DeepEqual(matches, m) {
    128 					errorf("bufSize=%d j=%d k=%d: findAndHash: matches=%v, want %v", bufSize, j, k, matches, m)
    129 					continue
    130 				}
    131 				if hash != h {
    132 					errorf("bufSize=%d j=%d k=%d: findAndHash: matches correct, but hash=%x, want %x", bufSize, j, k, hash, h)
    133 				}
    134 			}
    135 		}
    136 	}
    137 }
    138