github.com/bazelbuild/remote-apis-sdks@v0.0.0-20240425170053-8a36686a6350/go/pkg/digest/digest_test.go (about)

     1  package digest
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"path/filepath"
     7  	"strings"
     8  	"testing"
     9  
    10  	"google.golang.org/protobuf/proto"
    11  )
    12  
    13  var (
    14  	dInvalid        = Digest{Hash: strings.Repeat("a", 25), Size: 321}
    15  	dSHA256         = Digest{Hash: strings.Repeat("a", 64), Size: 321}
    16  	dSHA256Sizeless = Digest{Hash: dSHA256.Hash, Size: -1}
    17  
    18  	sGood     = fmt.Sprintf("%s/%d", dSHA256.Hash, dSHA256.Size)
    19  	sSizeless = fmt.Sprintf("%s/%d", dSHA256Sizeless.Hash, dSHA256Sizeless.Size)
    20  	sInvalid1 = fmt.Sprintf("%d/%s", dSHA256.Size, dSHA256.Hash)
    21  	sInvalid2 = fmt.Sprintf("%s/test", sInvalid1)
    22  	sInvalid3 = fmt.Sprintf("x%s", sGood[1:])
    23  )
    24  
    25  func TestProtoConversion(t *testing.T) {
    26  	dPb := dSHA256.ToProto()
    27  	d, err := NewFromProto(dPb)
    28  	if err != nil {
    29  		t.Errorf("NewFromProto(%v) = %v, want nil", dPb, err)
    30  	}
    31  	if dSHA256 != d {
    32  		t.Errorf("NewFromProto(%v.ToProto()) = (%s, _), want (%s, _)", dSHA256, d, dSHA256)
    33  	}
    34  }
    35  
    36  func TestValidateDigests_Pass(t *testing.T) {
    37  	if err := dSHA256.Validate(); err != nil {
    38  		t.Errorf("Validate(%v) = %v, want nil", dSHA256, err)
    39  	}
    40  }
    41  
    42  func TestValidateDigests_Errors(t *testing.T) {
    43  	t.Parallel()
    44  	testcases := []struct {
    45  		desc   string
    46  		digest Digest
    47  	}{
    48  		{"too short", Digest{Hash: "000a"}},
    49  		{"too long", Digest{Hash: "0000000000000000000000000000000000000000000000000000000000000000a"}},
    50  		{"must be lowercase", Digest{Hash: "000000000000000000000000000000000000000000000000000000000000000A"}},
    51  		{"can't be crazy", Digest{Hash: "000000000000000000000000000000000000000000000000000000000foobar!"}},
    52  		{"can't be negatively-sized", Digest{Hash: dSHA256.Hash, Size: -1}},
    53  	}
    54  	for _, tc := range testcases {
    55  		err := tc.digest.Validate()
    56  		if err == nil {
    57  			t.Errorf("%s: got success, wanted error", tc.desc)
    58  		}
    59  		t.Logf("%s: correctly got an error (%s)", tc.desc, err)
    60  	}
    61  }
    62  
    63  func Test_New_Success(t *testing.T) {
    64  	t.Parallel()
    65  	gotDigest, err := New(dSHA256.Hash, dSHA256.Size)
    66  	if err != nil {
    67  		t.Errorf("New(%s, %d) = (_, %v), want (_, nil)", dSHA256.Hash, dSHA256.Size, err)
    68  	}
    69  	if dSHA256 != gotDigest {
    70  		t.Errorf("New(%s, %d) = (%v, _), want (%v, _)", dSHA256.Hash, dSHA256.Size, gotDigest, dSHA256)
    71  	}
    72  }
    73  
    74  func Test_New_Error(t *testing.T) {
    75  	t.Parallel()
    76  	gotDigest, err := New(dInvalid.Hash, dInvalid.Size)
    77  	if err == nil {
    78  		t.Errorf("New(%s, %d) = (%s, nil), want (_, error)", dInvalid.Hash, dInvalid.Size, gotDigest)
    79  	}
    80  }
    81  
    82  func Test_NewFromProto_Success(t *testing.T) {
    83  	t.Parallel()
    84  	dPb := dSHA256.ToProto()
    85  	gotDigest, err := NewFromProto(dPb)
    86  	if err != nil {
    87  		t.Errorf("NewFromProto(%v) = (_, %v), want (_, nil)", dPb, err)
    88  	}
    89  	if dSHA256 != gotDigest {
    90  		t.Errorf("NewFromProto(%v) = (%v, _), want (%v, _)", dPb, gotDigest, dSHA256)
    91  	}
    92  }
    93  
    94  func Test_NewFromProto_Error(t *testing.T) {
    95  	t.Parallel()
    96  	dPb := dInvalid.ToProto()
    97  	gotDigest, err := NewFromProto(dPb)
    98  	if err == nil {
    99  		t.Errorf("NewFromProto(%v) = (%s, nil), want (_, error)", gotDigest, dPb)
   100  	}
   101  }
   102  
   103  func TestNewFromProtoUnvalidated(t *testing.T) {
   104  	t.Parallel()
   105  	testcases := []struct {
   106  		label  string
   107  		digest Digest
   108  	}{
   109  		{"SHA256", dSHA256},
   110  		{"Invalid", dInvalid},
   111  	}
   112  	for _, tc := range testcases {
   113  		dPb := tc.digest.ToProto()
   114  		gotDigest := NewFromProtoUnvalidated(dPb)
   115  		if tc.digest != gotDigest {
   116  			t.Errorf("%s: NewFromProto(%v) = (%v, _), want (%v, _)", tc.label, dPb, gotDigest, tc.digest)
   117  		}
   118  	}
   119  }
   120  
   121  func TestTestNewPads(t *testing.T) {
   122  	t.Parallel()
   123  	dShort := TestNew("a", 0)
   124  	dFull := TestNew("000000000000000000000000000000000000000000000000000000000000000a", 0)
   125  	want := "000000000000000000000000000000000000000000000000000000000000000a"
   126  	if dShort.Hash != want {
   127  		t.Errorf("dShort.Hash = %s, want %s", dShort.Hash, want)
   128  	}
   129  	if dFull.Hash != want {
   130  		t.Errorf("dFull.Hash = %s, want %s", dFull.Hash, want)
   131  	}
   132  }
   133  
   134  func TestTestNew(t *testing.T) {
   135  	t.Parallel()
   136  	dWant := "000000000000000000000000000000000000000000000000000000000000000a"
   137  	if dGot := TestNew("a", 0); dGot.Hash != dWant {
   138  		t.Errorf("TestNew('a', _) = %v, want %v", dGot.Hash, dWant)
   139  	}
   140  }
   141  
   142  func TestTestNew_Panic(t *testing.T) {
   143  	t.Parallel()
   144  	d := &Digest{Hash: "not good", Size: -1}
   145  	defer func() {
   146  		if err := recover(); err == nil {
   147  			t.Errorf("TestNew(%v) should have panicked", d)
   148  		}
   149  	}()
   150  	TestNew(d.Hash, d.Size)
   151  }
   152  
   153  func TestNewFromBlob(t *testing.T) {
   154  	t.Parallel()
   155  	if dGot := NewFromBlob([]byte{}); dGot != Empty {
   156  		t.Errorf("NewFromBlob([]byte{}) = %v, want %v", dGot, Empty)
   157  	}
   158  	dWant := TestNew("039058c6f2c0cb492c533b0a4d14ef77cc0f78abccced5287d84a1a2011cfb81", 3)
   159  	if dGot := NewFromBlob([]byte{1, 2, 3}); dGot != dWant {
   160  		t.Errorf("NewFromBlob([]byte{}) = %v, want %v", dGot, dWant)
   161  	}
   162  }
   163  
   164  func Test_NewFromMessage(t *testing.T) {
   165  	t.Parallel()
   166  	// Use a repb.Digest as a black-box proto.
   167  	msg := NewFromBlob([]byte{1, 2, 3}).ToProto()
   168  	b, err := proto.Marshal(msg)
   169  	if err != nil {
   170  		t.Fatalf("proto.Marshal(%v) = (_, %v), want (_, nil)", msg, err)
   171  	}
   172  	dWant := NewFromBlob(b)
   173  
   174  	dGot, err := NewFromMessage(msg)
   175  	if err != nil {
   176  		t.Errorf("NewFromMessage(%v) = (_, %v), want (_, nil)", msg, err)
   177  	}
   178  	if dGot != dWant {
   179  		t.Errorf("NewFromMessage(%v) = (%v, _), want (%v, _)", msg, dGot, dWant)
   180  	}
   181  }
   182  
   183  func TestTestNewFromMessage(t *testing.T) {
   184  	t.Parallel()
   185  	// Use a repb.Digest as a black-box proto.
   186  	msg := NewFromBlob([]byte{1, 2, 3}).ToProto()
   187  	b, err := proto.Marshal(msg)
   188  	if err != nil {
   189  		t.Fatalf("proto.Marshal(%v) = (_, %v), want (_, nil)", msg, err)
   190  	}
   191  	dWant := NewFromBlob(b)
   192  
   193  	dGot := TestNewFromMessage(msg)
   194  	if dGot != dWant {
   195  		t.Errorf("TestNewFromMessage(%v) = (%v, _), want (%v, _)", msg, dGot, dWant)
   196  	}
   197  }
   198  
   199  func TestNewFromFile(t *testing.T) {
   200  	t.Parallel()
   201  	testDir := t.TempDir()
   202  	path := filepath.Join(testDir, "input")
   203  	if err := os.WriteFile(path, []byte{1, 2, 3}, os.FileMode(0666)); err != nil {
   204  		t.Fatalf("os.WriteFile(%v, _, _) = %v, want nil", path, err)
   205  	}
   206  	dWant := TestNew("039058c6f2c0cb492c533b0a4d14ef77cc0f78abccced5287d84a1a2011cfb81", 3)
   207  	dGot, err := NewFromFile(path)
   208  	if err != nil {
   209  		t.Errorf("NewFromFile(%v) = (_, %v), want (_, nil)", path, err)
   210  	}
   211  	if dGot != dWant {
   212  		t.Errorf("NewFromFile(%v) = (%v, _), want (%v, _)", path, dGot, dWant)
   213  	}
   214  }
   215  
   216  func TestString(t *testing.T) {
   217  	t.Parallel()
   218  	if sGot := dSHA256.String(); sGot != sGood {
   219  		t.Errorf("%v.String() = '%s', want '%s'", dSHA256, sGot, sGood)
   220  	}
   221  	if sGot := dSHA256Sizeless.String(); sGot != sSizeless {
   222  		t.Errorf("%v.String() = '%s', want '%s'", dSHA256Sizeless, sGot, sSizeless)
   223  	}
   224  }
   225  
   226  func TestNewFromString(t *testing.T) {
   227  	t.Parallel()
   228  	if dGot, err := NewFromString(sGood); err != nil || dGot != dSHA256 {
   229  		t.Errorf("FromString(%s) = (%v, %v), want (%v, nil)", sGood, dGot, err, dSHA256)
   230  	}
   231  	if _, err := NewFromString(sSizeless); err == nil {
   232  		t.Errorf("FromString(%s) = (_, nil), want (_, error)", sSizeless)
   233  	}
   234  	if _, err := NewFromString(sInvalid1); err == nil {
   235  		t.Errorf("FromString(%s) = (_, nil), want (_, error)", sInvalid1)
   236  	}
   237  	if _, err := NewFromString(sInvalid2); err == nil {
   238  		t.Errorf("FromString(%s) = (_, nil), want (_, error)", sInvalid2)
   239  	}
   240  	if _, err := NewFromString(sInvalid3); err == nil {
   241  		t.Errorf("FromString(%s) = (_, nil), want (_, error)", sInvalid3)
   242  	}
   243  }