+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: Apache-2.0
+
package blockdigest
import (
"fmt"
+ "runtime"
"strings"
"testing"
)
+func getStackTrace() string {
+ buf := make([]byte, 1000)
+ bytes_written := runtime.Stack(buf, false)
+ return "Stack Trace:\n" + string(buf[:bytes_written])
+}
+
+func expectEqual(t *testing.T, actual interface{}, expected interface{}) {
+ if actual != expected {
+ t.Fatalf("Expected %v but received %v instead. %s",
+ expected,
+ actual,
+ getStackTrace())
+ }
+}
+
+func expectStringSlicesEqual(t *testing.T, actual []string, expected []string) {
+ if len(actual) != len(expected) {
+ t.Fatalf("Expected %v (length %d), but received %v (length %d) instead. %s", expected, len(expected), actual, len(actual), getStackTrace())
+ }
+ for i := range actual {
+ if actual[i] != expected[i] {
+ t.Fatalf("Expected %v but received %v instead (first disagreement at position %d). %s", expected, actual, i, getStackTrace())
+ }
+ }
+}
+
func expectValidDigestString(t *testing.T, s string) {
bd, err := FromString(s)
if err != nil {
}
expected := strings.ToLower(s)
-
+
if expected != bd.String() {
t.Fatalf("Expected %s to be returned by FromString(%s).String() but instead we received %s", expected, s, bd.String())
}
}
}
+func expectBlockLocator(t *testing.T, actual BlockLocator, expected BlockLocator) {
+ expectEqual(t, actual.Digest, expected.Digest)
+ expectEqual(t, actual.Size, expected.Size)
+ expectStringSlicesEqual(t, actual.Hints, expected.Hints)
+}
+
+func expectLocatorPatternMatch(t *testing.T, s string) {
+ if !LocatorPattern.MatchString(s) {
+ t.Fatalf("Expected \"%s\" to match locator pattern but it did not.",
+ s)
+ }
+}
+
+func expectLocatorPatternFail(t *testing.T, s string) {
+ if LocatorPattern.MatchString(s) {
+ t.Fatalf("Expected \"%s\" to fail locator pattern but it passed.",
+ s)
+ }
+}
+
func TestValidDigestStrings(t *testing.T) {
expectValidDigestString(t, "01234567890123456789abcdefabcdef")
expectValidDigestString(t, "01234567890123456789ABCDEFABCDEF")
func TestBlockDigestWorksAsMapKey(t *testing.T) {
m := make(map[BlockDigest]int)
- bd := AssertFromString("01234567890123456789abcdefabcdef")
+ bd, err := FromString("01234567890123456789abcdefabcdef")
+ if err != nil {
+ t.Fatalf("Unexpected error during FromString for block: %v", err)
+ }
m[bd] = 5
}
func TestBlockDigestGetsPrettyPrintedByPrintf(t *testing.T) {
input := "01234567890123456789abcdefabcdef"
- prettyPrinted := fmt.Sprintf("%v", AssertFromString(input))
+ fromString, err := FromString(input)
+ if err != nil {
+ t.Fatalf("Unexpected error during FromString: %v", err)
+ }
+ prettyPrinted := fmt.Sprintf("%v", fromString)
if prettyPrinted != input {
- t.Fatalf("Expected blockDigest produced from \"%s\" to be printed as " +
+ t.Fatalf("Expected blockDigest produced from \"%s\" to be printed as "+
"\"%s\", but instead it was printed as %s",
input, input, prettyPrinted)
}
}
func TestBlockDigestGetsPrettyPrintedByPrintfInNestedStructs(t *testing.T) {
- input := "01234567890123456789abcdefabcdef"
+ input, err := FromString("01234567890123456789abcdefabcdef")
+ if err != nil {
+ t.Fatalf("Unexpected error during FromString for block: %v", err)
+ }
value := 42
- nested := struct{
+ nested := struct {
// Fun trivia fact: If this field was called "digest" instead of
// "Digest", then it would not be exported and String() would
// never get called on it and our output would look very
// different.
Digest BlockDigest
- value int
+ value int
}{
- AssertFromString(input),
+ input,
value,
}
prettyPrinted := fmt.Sprintf("%+v", nested)
expected := fmt.Sprintf("{Digest:%s value:%d}", input, value)
if prettyPrinted != expected {
- t.Fatalf("Expected blockDigest produced from \"%s\" to be printed as " +
+ t.Fatalf("Expected blockDigest produced from \"%s\" to be printed as "+
"\"%s\", but instead it was printed as %s",
input, expected, prettyPrinted)
}
}
+
+func TestLocatorPatternBasic(t *testing.T) {
+ expectLocatorPatternMatch(t, "12345678901234567890123456789012+12345")
+ expectLocatorPatternMatch(t, "A2345678901234abcdefababdeffdfdf+12345")
+ expectLocatorPatternMatch(t, "12345678901234567890123456789012+12345+A1")
+ expectLocatorPatternMatch(t,
+ "12345678901234567890123456789012+12345+A1+B123wxyz@_-")
+ expectLocatorPatternMatch(t,
+ "12345678901234567890123456789012+12345+A1+B123wxyz@_-+C@")
+ expectLocatorPatternMatch(t, "12345678901234567890123456789012+12345+A")
+ expectLocatorPatternMatch(t, "12345678901234567890123456789012+12345+A1+B")
+ expectLocatorPatternMatch(t, "12345678901234567890123456789012+12345+A+B2")
+
+ expectLocatorPatternFail(t, "12345678901234567890123456789012")
+ expectLocatorPatternFail(t, "12345678901234567890123456789012+")
+ expectLocatorPatternFail(t, "12345678901234567890123456789012+12345+")
+ expectLocatorPatternFail(t, "1234567890123456789012345678901+12345")
+ expectLocatorPatternFail(t, "123456789012345678901234567890123+12345")
+ expectLocatorPatternFail(t, "g2345678901234abcdefababdeffdfdf+12345")
+ expectLocatorPatternFail(t, "12345678901234567890123456789012+12345 ")
+ expectLocatorPatternFail(t, "12345678901234567890123456789012+12345+1")
+ expectLocatorPatternFail(t, "12345678901234567890123456789012+12345+1A")
+ expectLocatorPatternFail(t, "12345678901234567890123456789012+12345+a1")
+ expectLocatorPatternFail(t, "12345678901234567890123456789012+12345+A1+")
+
+}
+
+func TestParseBlockLocatorSimple(t *testing.T) {
+ b, err := ParseBlockLocator("365f83f5f808896ec834c8b595288735+2310+K@qr1hi+Af0c9a66381f3b028677411926f0be1c6282fe67c@542b5ddf")
+ if err != nil {
+ t.Fatalf("Unexpected error parsing block locator: %v", err)
+ }
+ d, err := FromString("365f83f5f808896ec834c8b595288735")
+ if err != nil {
+ t.Fatalf("Unexpected error during FromString for block: %v", err)
+ }
+ expectBlockLocator(t, b, BlockLocator{Digest: d,
+ Size: 2310,
+ Hints: []string{"K@qr1hi",
+ "Af0c9a66381f3b028677411926f0be1c6282fe67c@542b5ddf"}})
+}