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