Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(216)

Side by Side Diff: appengine/logdog/coordinator/logStream_test.go

Issue 1863973002: LogDog: Update to archival V2. (Closed) Base URL: https://github.com/luci/luci-go@grpcutil-errors
Patch Set: Minor fixes, works in dev now. Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package coordinator 5 package coordinator
6 6
7 import ( 7 import (
8 "bytes" 8 "bytes"
9 "fmt" 9 "fmt"
10 "testing" 10 "testing"
11 "time" 11 "time"
12 12
13 "github.com/luci/gae/impl/memory" 13 "github.com/luci/gae/impl/memory"
14 ds "github.com/luci/gae/service/datastore" 14 ds "github.com/luci/gae/service/datastore"
15 "github.com/luci/luci-go/common/clock"
16 "github.com/luci/luci-go/common/clock/testclock" 15 "github.com/luci/luci-go/common/clock/testclock"
17 "github.com/luci/luci-go/common/logdog/types" 16 "github.com/luci/luci-go/common/logdog/types"
18 "github.com/luci/luci-go/common/proto/google" 17 "github.com/luci/luci-go/common/proto/google"
19 "github.com/luci/luci-go/common/proto/logdog/logpb" 18 "github.com/luci/luci-go/common/proto/logdog/logpb"
20 "golang.org/x/net/context" 19 "golang.org/x/net/context"
21 20
22 . "github.com/luci/luci-go/common/testing/assertions" 21 . "github.com/luci/luci-go/common/testing/assertions"
23 . "github.com/smartystreets/goconvey/convey" 22 . "github.com/smartystreets/goconvey/convey"
24 ) 23 )
25 24
(...skipping 28 matching lines...) Expand all
54 ps := make(ds.PropertySlice, len(values)) 53 ps := make(ds.PropertySlice, len(values))
55 for i, v := range values { 54 for i, v := range values {
56 ps[i] = ds.MkProperty(v) 55 ps[i] = ds.MkProperty(v)
57 } 56 }
58 return ps 57 return ps
59 } 58 }
60 59
61 func TestLogStream(t *testing.T) { 60 func TestLogStream(t *testing.T) {
62 t.Parallel() 61 t.Parallel()
63 62
64 » Convey(`A LogStream with invalid tags will fail to encode.`, t, func() { 63 » Convey(`When creating a LogStream`, t, func() {
65 » » ls := &LogStream{ 64 » » Convey(`Can create keyed on hash.`, func() {
66 » » » Prefix: "foo", 65 » » » ls, err := NewLogStream("0123456789abcdef0123456789ABCDE F0123456789abcdef0123456789ABCDEF")
67 » » » Name: "bar", 66 » » » So(err, ShouldBeNil)
68 » » » Tags: TagMap{ 67 » » » So(ls, ShouldNotBeNil)
69 » » » » "!!!invalid key!!!": "value", 68 » » })
70 » » » }, 69
71 » » } 70 » » Convey(`Will fail to create keyed on an invalid hash-length stri ng.`, func() {
72 » » _, err := ls.Save(true) 71 » » » _, err := NewLogStream("0123456789abcdef!@#$%^&*()ABCDEF 0123456789abcdef0123456789ABCDEF")
73 » » So(err, ShouldErrLike, "failed to encode tags") 72 » » » So(err, ShouldErrLike, "invalid path")
73 » » })
74
75 » » Convey(`Can create keyed on path.`, func() {
76 » » » ls, err := NewLogStream("a/b/+/c/d")
77 » » » So(err, ShouldBeNil)
78 » » » So(ls, ShouldNotBeNil)
79 » » })
80
81 » » Convey(`Will fail to create keyed on neither a path nor hash.`, func() {
82 » » » _, err := NewLogStream("")
83 » » » So(err, ShouldNotBeNil)
84 » » })
74 }) 85 })
75 86
76 » Convey(`A LogStream will skip invalid tags when loading.`, t, func() { 87 » Convey(`A testing log stream`, t, func() {
77 » » ls := &LogStream{
78 » » » Prefix: "foo",
79 » » » Name: "bar",
80 » » }
81 » » pmap := ds.PropertyMap{
82 » » » "_Tags": sps(encodeKey("!!!invalid key!!!")),
83 » » }
84 » » So(ls.Load(pmap), ShouldBeNil)
85 » » So(ls.Tags, ShouldResemble, TagMap(nil))
86 » })
87
88 » Convey(`With a testing configuration`, t, func() {
89 c, tc := testclock.UseTime(context.Background(), testclock.TestT imeLocal) 88 c, tc := testclock.UseTime(context.Background(), testclock.TestT imeLocal)
90 c = memory.Use(c) 89 c = memory.Use(c)
91 di := ds.Get(c) 90 di := ds.Get(c)
92 di.Testable().AutoIndex(true) 91 di.Testable().AutoIndex(true)
93 di.Testable().Consistent(true) 92 di.Testable().Consistent(true)
94 93
94 now := ds.RoundTime(tc.Now().UTC())
95
96 ls := LogStream{
97 Prefix: "foo",
98 Name: "bar",
99 State: LSStreaming,
100 TerminalIndex: -1,
101 Secret: bytes.Repeat([]byte{0x6F}, types.StreamSe cretLength),
102 Created: now.UTC(),
103 ContentType: string(types.ContentTypeText),
104 }
105
95 desc := logpb.LogStreamDescriptor{ 106 desc := logpb.LogStreamDescriptor{
96 Prefix: "testing", 107 Prefix: "testing",
97 Name: "log/stream", 108 Name: "log/stream",
98 StreamType: logpb.StreamType_TEXT, 109 StreamType: logpb.StreamType_TEXT,
99 ContentType: "application/text", 110 ContentType: "application/text",
100 » » » Timestamp: google.NewTimestamp(clock.Now(c)), 111 » » » Timestamp: google.NewTimestamp(now),
101 Tags: map[string]string{ 112 Tags: map[string]string{
102 "foo": "bar", 113 "foo": "bar",
103 "baz": "qux", 114 "baz": "qux",
104 "quux": "", 115 "quux": "",
105 }, 116 },
106 } 117 }
107 118
108 » » Convey(`Can create a LogStream keyed on hash.`, func() { 119 » » Convey(`Will skip invalid tags when loading.`, func() {
109 » » » ls, err := NewLogStream("0123456789abcdef0123456789ABCDE F0123456789abcdef0123456789ABCDEF") 120 » » » pmap, err := ls.Save(false)
110 So(err, ShouldBeNil) 121 So(err, ShouldBeNil)
111 » » » So(ls, ShouldNotBeNil) 122 » » » pmap["_Tags"] = sps(encodeKey("!!!invalid key!!!"))
123
124 » » » So(ls.Load(pmap), ShouldBeNil)
125 » » » So(ls.Tags, ShouldResemble, TagMap(nil))
112 }) 126 })
113 127
114 » » Convey(`Will fail to create a LogStream keyed on an invalid hash -length string.`, func() { 128 » » Convey(`With invalid tags will fail to encode.`, func() {
115 » » » _, err := NewLogStream("0123456789abcdef!@#$%^&*()ABCDEF 0123456789abcdef0123456789ABCDEF") 129 » » » ls.Tags = TagMap{
116 » » » So(err, ShouldErrLike, "invalid path") 130 » » » » "!!!invalid key!!!": "value",
131 » » » }
132
133 » » » ls.SetDSValidate(false)
134 » » » _, err := ls.Save(true)
135 » » » So(err, ShouldErrLike, "failed to encode tags")
117 }) 136 })
118 137
119 » » Convey(`Can create a LogStream keyed on path.`, func() { 138 » » Convey(`Can populate the LogStream with descriptor state.`, func () {
120 » » » ls, err := NewLogStream("a/b/+/c/d") 139 » » » So(ls.LoadDescriptor(&desc), ShouldBeNil)
121 » » » So(err, ShouldBeNil) 140 » » » So(ls.Validate(), ShouldBeNil)
122 » » » So(ls, ShouldNotBeNil)
123 » » })
124 141
125 » » Convey(`Will fail to create a LogStream keyed on neither a path nor hash.`, func() { 142 » » » Convey(`Will not validate`, func() {
126 » » » _, err := NewLogStream("") 143 » » » » Convey(`Without a valid Prefix`, func() {
127 » » » So(err, ShouldNotBeNil) 144 » » » » » ls.Prefix = ""
128 » » }) 145 » » » » » So(ls.Validate(), ShouldErrLike, "invali d prefix")
146 » » » » })
147 » » » » Convey(`Without a valid prefix`, func() {
148 » » » » » ls.Name = ""
149 » » » » » So(ls.Validate(), ShouldErrLike, "invali d name")
150 » » » » })
151 » » » » Convey(`Without a valid stream secret`, func() {
152 » » » » » ls.Secret = nil
153 » » » » » So(ls.Validate(), ShouldErrLike, "invali d secret length")
154 » » » » })
155 » » » » Convey(`Without a valid content type`, func() {
156 » » » » » ls.ContentType = ""
157 » » » » » So(ls.Validate(), ShouldErrLike, "empty content type")
158 » » » » })
159 » » » » Convey(`Without a valid created time`, func() {
160 » » » » » ls.Created = time.Time{}
161 » » » » » So(ls.Validate(), ShouldErrLike, "create d time is not set")
162 » » » » })
163 » » » » Convey(`With a terminal index, will not validate without a TerminatedTime.`, func() {
164 » » » » » ls.State = LSArchiveTasked
165 » » » » » ls.TerminalIndex = 1337
166 » » » » » So(ls.Validate(), ShouldErrLike, "missin g terminated time")
129 167
130 » » Convey(`Can create a new LogStream`, func() { 168 » » » » » ls.TerminatedTime = now
131 » » » ls, err := NewLogStream(string(desc.Path())) 169 » » » » » So(ls.Validate(), ShouldBeNil)
132 » » » So(err, ShouldBeNil) 170 » » » » })
171 » » » » Convey(`When archived, will not validate without an ArchivedTime.`, func() {
172 » » » » » ls.State = LSArchived
173 » » » » » So(ls.Validate(), ShouldErrLike, "missin g terminated time")
133 174
134 » » » Convey(`Can populate the LogStream with descriptor state .`, func() { 175 » » » » » ls.TerminatedTime = now
135 » » » » ls.Created = ds.RoundTime(clock.Now(c).UTC()) 176 » » » » » So(ls.Validate(), ShouldErrLike, "missin g archived time")
136 » » » » ls.Updated = ds.RoundTime(clock.Now(c).UTC())
137 » » » » ls.Secret = bytes.Repeat([]byte{0x6F}, types.Str eamSecretLength)
138 » » » » So(ls.LoadDescriptor(&desc), ShouldBeNil)
139 » » » » So(ls.Validate(), ShouldBeNil)
140 177
141 » » » » Convey(`Will not validate`, func() { 178 » » » » » ls.ArchivedTime = now
142 » » » » » Convey(`Without a valid Prefix`, func() { 179 » » » » » So(ls.Validate(), ShouldBeNil)
143 » » » » » » ls.Prefix = ""
144 » » » » » » So(ls.Validate(), ShouldErrLike, "invalid prefix")
145 » » » » » })
146 » » » » » Convey(`Without a valid prefix`, func() {
147 » » » » » » ls.Name = ""
148 » » » » » » So(ls.Validate(), ShouldErrLike, "invalid name")
149 » » » » » })
150 » » » » » Convey(`Without a valid stream secret`, func() {
151 » » » » » » ls.Secret = nil
152 » » » » » » So(ls.Validate(), ShouldErrLike, "invalid secret length")
153 » » » » » })
154 » » » » » Convey(`Without a valid content type`, f unc() {
155 » » » » » » ls.ContentType = ""
156 » » » » » » So(ls.Validate(), ShouldErrLike, "empty content type")
157 » » » » » })
158 » » » » » Convey(`Without a valid created time`, f unc() {
159 » » » » » » ls.Created = time.Time{}
160 » » » » » » So(ls.Validate(), ShouldErrLike, "created time is not set")
161 » » » » » })
162 » » » » » Convey(`Without a valid updated time`, f unc() {
163 » » » » » » ls.Updated = time.Time{}
164 » » » » » » So(ls.Validate(), ShouldErrLike, "updated time is not set")
165 » » » » » })
166 » » » » » Convey(`With an updated time before the created time`, func() {
167 » » » » » » ls.Updated = ls.Created.Add(-tim e.Second)
168 » » » » » » So(ls.Validate(), ShouldErrLike, "updated time must be >= created time")
169 » » » » » })
170 » » » » » Convey(`Without a valid stream type`, fu nc() {
171 » » » » » » ls.StreamType = -1
172 » » » » » » So(ls.Validate(), ShouldErrLike, "unsupported stream type")
173 » » » » » })
174 » » » » » Convey(`Without an invalid tag: empty ke y`, func() {
175 » » » » » » ls.Tags[""] = "empty"
176 » » » » » » So(ls.Validate(), ShouldErrLike, "invalid tag")
177 » » » » » })
178 » » » » » Convey(`Without an invalid tag: bad key` , func() {
179 » » » » » » ls.Tags["!"] = "bad-value"
180 » » » » » » So(ls.Validate(), ShouldErrLike, "invalid tag")
181 » » » » » })
182 » » » » » Convey(`With an invalid descriptor proto buf`, func() {
183 » » » » » » ls.Descriptor = []byte{0x00} // Invalid tag, "0".
184 » » » » » » So(ls.Validate(), ShouldErrLike, "could not unmarshal descriptor")
185 » » » » » })
186 }) 180 })
187 181 » » » » Convey(`Without a valid stream type`, func() {
188 » » » » Convey(`Can write the LogStream to the Datastore .`, func() { 182 » » » » » ls.StreamType = -1
189 » » » » » So(di.Put(ls), ShouldBeNil) 183 » » » » » So(ls.Validate(), ShouldErrLike, "unsupp orted stream type")
190 184 » » » » })
191 » » » » » Convey(`Can read the LogStream back from the Datastore.`, func() { 185 » » » » Convey(`Without an invalid tag: empty key`, func () {
192 » » » » » » ls2 := LogStreamFromID(ls.HashID ()) 186 » » » » » ls.Tags[""] = "empty"
193 » » » » » » So(di.Get(ls2), ShouldBeNil) 187 » » » » » So(ls.Validate(), ShouldErrLike, "invali d tag")
194 » » » » » » So(ls2, ShouldResemble, ls) 188 » » » » })
195 » » » » » }) 189 » » » » Convey(`Without an invalid tag: bad key`, func() {
190 » » » » » ls.Tags["!"] = "bad-value"
191 » » » » » So(ls.Validate(), ShouldErrLike, "invali d tag")
192 » » » » })
193 » » » » Convey(`With an invalid descriptor protobuf`, fu nc() {
194 » » » » » ls.Descriptor = []byte{0x00} // Invalid tag, "0".
195 » » » » » So(ls.Validate(), ShouldErrLike, "could not unmarshal descriptor")
196 }) 196 })
197 }) 197 })
198 198
199 » » » Convey(`Will refuse to populate from an invalid descript or.`, func() { 199 » » » Convey(`Can write the LogStream to the Datastore.`, func () {
200 » » » » desc.Name = "" 200 » » » » So(di.Put(&ls), ShouldBeNil)
201 » » » » So(ls.LoadDescriptor(&desc), ShouldErrLike, "inv alid descriptor") 201
202 » » » » Convey(`Can read the LogStream back from the Dat astore.`, func() {
203 » » » » » ls2 := LogStreamFromID(ls.HashID())
204 » » » » » So(di.Get(ls2), ShouldBeNil)
205 » » » » » So(ls2, ShouldResemble, &ls)
206 » » » » })
202 }) 207 })
203 }) 208 })
204 209
210 Convey(`Will refuse to populate from an invalid descriptor.`, fu nc() {
211 desc.Name = ""
212 So(ls.LoadDescriptor(&desc), ShouldErrLike, "invalid des criptor")
213 })
214
205 Convey(`Writing multiple LogStream entries`, func() { 215 Convey(`Writing multiple LogStream entries`, func() {
206 times := map[string]time.Time{} 216 times := map[string]time.Time{}
207 streamNames := []string{ 217 streamNames := []string{
208 "foo/bar", 218 "foo/bar",
209 "foo/bar/baz", 219 "foo/bar/baz",
210 "baz/qux", 220 "baz/qux",
211 "cat/dog", 221 "cat/dog",
212 "cat/bird/dog", 222 "cat/bird/dog",
213 "bird/plane", 223 "bird/plane",
214 } 224 }
215 » » » for _, name := range streamNames { 225 » » » for i, name := range streamNames {
216 » » » » desc := desc 226 » » » » lsCopy := ls
217 » » » » desc.Name = name 227 » » » » lsCopy.Name = name
228 » » » » lsCopy.Created = ds.RoundTime(now.Add(time.Durat ion(i) * time.Second))
218 229
219 » » » » ls, err := NewLogStream(string(desc.Path())) 230 » » » » descCopy := desc
220 » » » » So(err, ShouldBeNil) 231 » » » » descCopy.Name = name
221 232
222 » » » » ls.Secret = bytes.Repeat([]byte{0x55}, types.Str eamSecretLength) 233 » » » » if err := lsCopy.LoadDescriptor(&descCopy); err != nil {
223 » » » » So(ls.LoadDescriptor(&desc), ShouldBeNil) 234 » » » » » panic(err)
224 » » » » ls.Created = clock.Now(c).UTC() 235 » » » » }
225 » » » » ls.Updated = ls.Created 236 » » » » So(di.Put(&lsCopy), ShouldBeNil)
226 » » » » So(di.Put(ls), ShouldBeNil)
227 237
228 » » » » times[name] = clock.Now(c) 238 » » » » times[name] = lsCopy.Created
229 » » » » tc.Add(time.Second)
230 } 239 }
231 240
232 Convey(`When querying LogStream by -Created`, func() { 241 Convey(`When querying LogStream by -Created`, func() {
233 q := ds.NewQuery("LogStream").Order("-Created") 242 q := ds.NewQuery("LogStream").Order("-Created")
234 243
235 Convey(`LogStream path queries`, func() { 244 Convey(`LogStream path queries`, func() {
236 Convey(`A query for "foo/bar" should ret urn "foo/bar".`, func() { 245 Convey(`A query for "foo/bar" should ret urn "foo/bar".`, func() {
237 q, err := AddLogStreamPathFilter (q, "**/+/foo/bar") 246 q, err := AddLogStreamPathFilter (q, "**/+/foo/bar")
238 So(err, ShouldBeNil) 247 So(err, ShouldBeNil)
239 248
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
413 "_C": sps("PF:1:foo", "PR:1:baz", "PR:3:bar"), 422 "_C": sps("PF:1:foo", "PR:1:baz", "PR:3:bar"),
414 }) 423 })
415 }) 424 })
416 425
417 Convey(`Will error if more than one greedy glob is present.`, fu nc() { 426 Convey(`Will error if more than one greedy glob is present.`, fu nc() {
418 _, err := AddLogStreamPathFilter(q, "*/foo/**/bar/**") 427 _, err := AddLogStreamPathFilter(q, "*/foo/**/bar/**")
419 So(err, ShouldErrLike, "cannot have more than one greedy glob") 428 So(err, ShouldErrLike, "cannot have more than one greedy glob")
420 }) 429 })
421 }) 430 })
422 } 431 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698