Merge branch '8784-dir-listings'
[arvados.git] / sdk / go / blockdigest / blockdigest_test.go
index 068a1385aef5e4f714e5282235da621fb4e970b4..a9994f7047c79b19c98dd5f09d8184ef048686ed 100644 (file)
@@ -1,11 +1,42 @@
+// 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 {
@@ -13,7 +44,7 @@ func expectValidDigestString(t *testing.T, s string) {
        }
 
        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())
        }
@@ -26,6 +57,26 @@ func expectInvalidDigestString(t *testing.T, s 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")
@@ -41,39 +92,90 @@ func TestInvalidDigestStrings(t *testing.T) {
 
 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"}})
+}