Merge branch 'master' into 4232-slow-pipes-n-jobs
[arvados.git] / sdk / go / manifest / manifest_test.go
1 package manifest
2
3 import (
4         "git.curoverse.com/arvados.git/sdk/go/blockdigest"
5         "io/ioutil"
6         "runtime"
7         "testing"
8 )
9
10 func getStackTrace() (string) {
11         buf := make([]byte, 1000)
12         bytes_written := runtime.Stack(buf, false)
13         return "Stack Trace:\n" + string(buf[:bytes_written])
14 }
15
16 func expectFromChannel(t *testing.T, c <-chan string, expected string) {
17         actual, ok := <- c
18         if !ok {
19                 t.Fatalf("Expected to receive %s but channel was closed. %s",
20                         expected,
21                         getStackTrace())
22         }
23         if actual != expected {
24                 t.Fatalf("Expected %s but got %s instead. %s",
25                         expected,
26                         actual,
27                         getStackTrace())
28         }
29 }
30
31 func expectChannelClosed(t *testing.T, c <-chan interface{}) {
32         received, ok := <- c
33         if ok {
34                 t.Fatalf("Expected channel to be closed, but received %v instead. %s",
35                         received,
36                         getStackTrace())
37         }
38 }
39
40 func expectEqual(t *testing.T, actual interface{}, expected interface{}) {
41         if actual != expected {
42                 t.Fatalf("Expected %v but received %v instead. %s",
43                         expected,
44                         actual,
45                         getStackTrace())
46         }
47 }
48
49 func expectStringSlicesEqual(t *testing.T, actual []string, expected []string) {
50         if len(actual) != len(expected) {
51                 t.Fatalf("Expected %v (length %d), but received %v (length %d) instead. %s", expected, len(expected), actual, len(actual), getStackTrace())
52         }
53         for i := range actual {
54                 if actual[i] != expected[i] {
55                         t.Fatalf("Expected %v but received %v instead (first disagreement at position %d). %s", expected, actual, i, getStackTrace())
56                 }
57         }
58 }
59
60 func expectManifestStream(t *testing.T, actual ManifestStream, expected ManifestStream) {
61         expectEqual(t, actual.StreamName, expected.StreamName)
62         expectStringSlicesEqual(t, actual.Blocks, expected.Blocks)
63         expectStringSlicesEqual(t, actual.Files, expected.Files)
64 }
65
66 func expectBlockLocator(t *testing.T, actual BlockLocator, expected BlockLocator) {
67         expectEqual(t, actual.Digest, expected.Digest)
68         expectEqual(t, actual.Size, expected.Size)
69         expectStringSlicesEqual(t, actual.Hints, expected.Hints)
70 }
71
72 func expectLocatorPatternMatch(t *testing.T, s string) {
73         if !LocatorPattern.MatchString(s) {
74                 t.Fatalf("Expected \"%s\" to match locator pattern but it did not.",
75                         s)
76         }
77 }
78
79 func expectLocatorPatternFail(t *testing.T, s string) {
80         if LocatorPattern.MatchString(s) {
81                 t.Fatalf("Expected \"%s\" to fail locator pattern but it passed.",
82                         s)
83         }
84 }
85
86 func TestLocatorPatternBasic(t *testing.T) {
87         expectLocatorPatternMatch(t, "12345678901234567890123456789012+12345")
88         expectLocatorPatternMatch(t, "A2345678901234abcdefababdeffdfdf+12345")
89         expectLocatorPatternMatch(t, "12345678901234567890123456789012+12345+A1")
90         expectLocatorPatternMatch(t,
91                 "12345678901234567890123456789012+12345+A1+B123wxyz@_-")
92         expectLocatorPatternMatch(t,
93                 "12345678901234567890123456789012+12345+A1+B123wxyz@_-+C@")
94
95         expectLocatorPatternFail(t,  "12345678901234567890123456789012")
96         expectLocatorPatternFail(t,  "12345678901234567890123456789012+")
97         expectLocatorPatternFail(t,  "12345678901234567890123456789012+12345+")
98         expectLocatorPatternFail(t,  "1234567890123456789012345678901+12345")
99         expectLocatorPatternFail(t,  "123456789012345678901234567890123+12345")
100         expectLocatorPatternFail(t,  "g2345678901234abcdefababdeffdfdf+12345")
101         expectLocatorPatternFail(t,  "12345678901234567890123456789012+12345 ")
102         expectLocatorPatternFail(t,  "12345678901234567890123456789012+12345+1")
103         expectLocatorPatternFail(t,  "12345678901234567890123456789012+12345+1A")
104         expectLocatorPatternFail(t,  "12345678901234567890123456789012+12345+A")
105         expectLocatorPatternFail(t,  "12345678901234567890123456789012+12345+a1")
106         expectLocatorPatternFail(t,  "12345678901234567890123456789012+12345+A1+")
107         expectLocatorPatternFail(t,  "12345678901234567890123456789012+12345+A1+B")
108         expectLocatorPatternFail(t,  "12345678901234567890123456789012+12345+A+B2")
109 }
110
111 func TestParseManifestStreamSimple(t *testing.T) {
112         m := parseManifestStream(". 365f83f5f808896ec834c8b595288735+2310+K@qr1hi+Af0c9a66381f3b028677411926f0be1c6282fe67c@542b5ddf 0:2310:qr1hi-8i9sb-ienvmpve1a0vpoi.log.txt")
113         expectManifestStream(t, m, ManifestStream{StreamName: ".",
114                 Blocks: []string{"365f83f5f808896ec834c8b595288735+2310+K@qr1hi+Af0c9a66381f3b028677411926f0be1c6282fe67c@542b5ddf"},
115                 Files: []string{"0:2310:qr1hi-8i9sb-ienvmpve1a0vpoi.log.txt"}})
116 }
117
118 func TestParseBlockLocatorSimple(t *testing.T) {
119         b, err := ParseBlockLocator("365f83f5f808896ec834c8b595288735+2310+K@qr1hi+Af0c9a66381f3b028677411926f0be1c6282fe67c@542b5ddf")
120         if err != nil {
121                 t.Fatalf("Unexpected error parsing block locator: %v", err)
122         }
123         expectBlockLocator(t, b, BlockLocator{Digest: blockdigest.AssertFromString("365f83f5f808896ec834c8b595288735"),
124                 Size: 2310,
125                 Hints: []string{"K@qr1hi",
126                         "Af0c9a66381f3b028677411926f0be1c6282fe67c@542b5ddf"}})
127 }
128
129 func TestStreamIterShortManifestWithBlankStreams(t *testing.T) {
130         content, err := ioutil.ReadFile("testdata/short_manifest")
131         if err != nil {
132                 t.Fatalf("Unexpected error reading manifest from file: %v", err)
133         }
134         manifest := Manifest{string(content)}
135         streamIter := manifest.StreamIter()
136
137         firstStream := <-streamIter
138         expectManifestStream(t,
139                 firstStream,
140                 ManifestStream{StreamName: ".",
141                         Blocks: []string{"b746e3d2104645f2f64cd3cc69dd895d+15693477+E2866e643690156651c03d876e638e674dcd79475@5441920c"},
142                         Files: []string{"0:15893477:chr10_band0_s0_e3000000.fj"}})
143
144         received, ok := <- streamIter
145         if ok {
146                 t.Fatalf("Expected streamIter to be closed, but received %v instead.",
147                         received)
148         }
149 }
150
151 func TestBlockIterLongManifest(t *testing.T) {
152         content, err := ioutil.ReadFile("testdata/long_manifest")
153         if err != nil {
154                 t.Fatalf("Unexpected error reading manifest from file: %v", err)
155         }
156         manifest := Manifest{string(content)}
157         blockChannel := manifest.BlockIterWithDuplicates()
158
159         firstBlock := <-blockChannel
160         expectBlockLocator(t,
161                 firstBlock,
162                 BlockLocator{Digest: blockdigest.AssertFromString("b746e3d2104645f2f64cd3cc69dd895d"),
163                         Size: 15693477,
164                         Hints: []string{"E2866e643690156651c03d876e638e674dcd79475@5441920c"}})
165         blocksRead := 1
166         var lastBlock BlockLocator
167         for lastBlock = range blockChannel {
168                 //log.Printf("Blocks Read: %d", blocksRead)
169                 blocksRead++
170         }
171         expectEqual(t, blocksRead, 853)
172
173         expectBlockLocator(t,
174                 lastBlock,
175                 BlockLocator{Digest: blockdigest.AssertFromString("f9ce82f59e5908d2d70e18df9679b469"),
176                         Size: 31367794,
177                         Hints: []string{"E53f903684239bcc114f7bf8ff9bd6089f33058db@5441920c"}})
178 }