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

Unified Diff: client/logdog/butlerproto/proto_test.go

Issue 1321273002: LogDog: Add butler protocol reader/write library. (Closed) Base URL: https://github.com/luci/luci-go@logdog-review-frame
Patch Set: Updates. Created 5 years, 1 month 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 side-by-side diff with in-line comments
Download patch
« client/logdog/butlerproto/proto.go ('K') | « client/logdog/butlerproto/proto.go ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: client/logdog/butlerproto/proto_test.go
diff --git a/client/logdog/butlerproto/proto_test.go b/client/logdog/butlerproto/proto_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..b70edd444899eb9392d0a1e2cf43968f5e00aa18
--- /dev/null
+++ b/client/logdog/butlerproto/proto_test.go
@@ -0,0 +1,210 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package butlerproto
+
+import (
+ "bytes"
+ "io"
+ "strings"
+ "testing"
+
+ "github.com/golang/protobuf/proto"
+ "github.com/luci/luci-go/common/logdog/protocol"
+ "github.com/luci/luci-go/common/recordio"
+ . "github.com/smartystreets/goconvey/convey"
+)
+
+func read(ir io.Reader) (*Reader, error) {
+ r := Reader{}
+ if err := r.Read(ir); err != nil {
+ return nil, err
+ }
+ return &r, nil
+}
+
+func TestReader(t *testing.T) {
+ Convey(`A Reader instance`, t, func() {
+ r := Reader{}
+ buf := bytes.Buffer{}
+ fw := recordio.NewWriter(&buf)
+
+ writeFrame := func(data []byte) error {
+ if _, err := fw.Write(data); err != nil {
+ return err
+ }
+ if err := fw.Flush(); err != nil {
+ return err
+ }
+ return nil
+ }
+
+ push := func(m proto.Message) error {
+ data, err := proto.Marshal(m)
+ if err != nil {
+ return err
+ }
+ return writeFrame(data)
+ }
+
+ Convey(`Can read a ButlerLogBundle entry.`, func() {
+ md := protocol.ButlerMetadata{
+ Type: protocol.ButlerMetadata_ButlerLogBundle,
+ }
+ bundle := protocol.ButlerLogBundle{
+ Source: "test source",
+ }
+
+ So(push(&md), ShouldBeNil)
+ So(push(&bundle), ShouldBeNil)
+
+ So(r.Read(&buf), ShouldBeNil)
+ So(r.Bundle, ShouldNotBeNil)
+ So(r.Bundle.Source, ShouldEqual, "test source")
+ })
+
+ Convey(`Will fail to Read an unknown type.`, func() {
+ // Assert that we are testing an unknown type.
+ unknownType := protocol.ButlerMetadata_ContentType(-1)
+ So(protocol.ButlerMetadata_ContentType_name[int32(unknownType)], ShouldEqual, "")
+
+ md := protocol.ButlerMetadata{
+ Type: unknownType,
+ }
+ So(push(&md), ShouldBeNil)
+
+ err := r.Read(&buf)
+ So(err, ShouldNotBeNil)
+ So(err.Error(), ShouldContainSubstring, "unknown data type")
+ })
+
+ Convey(`Will fail to read junk metadata.`, func() {
+ So(writeFrame([]byte{0xd0, 0x6f, 0x00, 0xd5}), ShouldBeNil)
+
+ err := r.Read(&buf)
+ So(err, ShouldNotBeNil)
+ So(err.Error(), ShouldContainSubstring, "failed to unmarshal Metadata frame")
+ })
+
+ Convey(`With a proper Metadata frame`, func() {
+ md := protocol.ButlerMetadata{
+ Type: protocol.ButlerMetadata_ButlerLogBundle,
+ }
+ So(push(&md), ShouldBeNil)
+
+ Convey(`Will fail if the bundle data is junk.`, func() {
+ So(writeFrame([]byte{0xd0, 0x6f, 0x00, 0xd5}), ShouldBeNil)
+
+ err := r.Read(&buf)
+ So(err, ShouldNotBeNil)
+ So(err.Error(), ShouldContainSubstring, "failed to unmarshal Bundle frame")
+ })
+ })
+
+ Convey(`With a proper compressed Metadata frame`, func() {
+ md := protocol.ButlerMetadata{
+ Type: protocol.ButlerMetadata_ButlerLogBundle,
+ Compression: protocol.ButlerMetadata_ZLIB,
+ }
+ So(push(&md), ShouldBeNil)
+
+ Convey(`Will fail if the data frame is missing.`, func() {
+ err := r.Read(&buf)
+ So(err, ShouldNotBeNil)
+ So(err.Error(), ShouldContainSubstring, "failed to read Bundle data")
+ })
+
+ Convey(`Will fail if there is junk compressed data.`, func() {
+ So(writeFrame(bytes.Repeat([]byte{0x55, 0xAA}, 16)), ShouldBeNil)
+
+ err := r.Read(&buf)
+ So(err, ShouldNotBeNil)
+ So(err.Error(), ShouldContainSubstring, "failed to initialize zlib reader")
+ })
+ })
+
+ Convey(`Will refuse to read a frame larger than our maximum size.`, func() {
+ r.maxSize = 16
+ So(writeFrame(bytes.Repeat([]byte{0x55}, 17)), ShouldBeNil)
+
+ err := r.Read(&buf)
+ So(err, ShouldEqual, recordio.ErrFrameTooLarge)
+ })
+
+ Convey(`Will refuse to read a compressed protobuf larger than our maximum size.`, func() {
+ // We are crafting this data such that its compressed (frame) size is
+ // below our threshold (16), but its compressed size exceeds it. Repeated
+ // bytes compress very well :)
+ //
+ // Because the frame it smaller than our threshold, our FrameReader will
+ // not outright reject the frame. However, the data is still larger than
+ // we're allowed, and we must reject it.
+ r.maxSize = 16
+ w := Writer{
+ Compress: true,
+ CompressThreshold: 0,
+ }
+ So(w.writeData(recordio.NewWriter(&buf), protocol.ButlerMetadata_ButlerLogBundle,
+ bytes.Repeat([]byte{0x55}, 64)), ShouldBeNil)
+
+ err := r.Read(&buf)
+ So(err, ShouldNotBeNil)
+ So(err.Error(), ShouldContainSubstring, "limit exceeded")
+ })
+ })
+}
+
+func TestWriter(t *testing.T) {
+ Convey(`A Writer instance outputting to a Buffer`, t, func() {
+ buf := bytes.Buffer{}
+ w := Writer{}
+ bundle := protocol.ButlerLogBundle{
+ Source: "test source",
+ Entries: []*protocol.ButlerLogBundle_Entry{
+ {},
+ },
+ }
+
+ Convey(`When configured to compress with a threshold of 64`, func() {
+ w.Compress = true
+ w.CompressThreshold = 64
+
+ Convey(`Will not compress if below the compression threshold.`, func() {
+ So(w.Write(&buf, &bundle), ShouldBeNil)
+
+ r, err := read(&buf)
+ So(err, ShouldBeNil)
+ So(r.Metadata.Compression, ShouldEqual, protocol.ButlerMetadata_NONE)
+ })
+
+ Convey(`Will not write data larger than the maximum bundle size.`, func() {
+ w.maxSize = 16
+ bundle.Source = strings.Repeat("A", 17)
+ err := w.Write(&buf, &bundle)
+ So(err, ShouldNotBeNil)
+ So(err.Error(), ShouldContainSubstring, "exceeds soft cap")
+ })
+
+ Convey(`Will compress data >= the threshold.`, func() {
+ bundle.Source = strings.Repeat("A", 64)
+ So(w.Write(&buf, &bundle), ShouldBeNil)
+
+ r, err := read(&buf)
+ So(err, ShouldBeNil)
+ So(r.Metadata.Compression, ShouldEqual, protocol.ButlerMetadata_ZLIB)
+ So(r.Bundle.Source, ShouldResemble, bundle.Source)
+
+ Convey(`And can be reused.`, func() {
+ bundle.Source = strings.Repeat("A", 64)
+ So(w.Write(&buf, &bundle), ShouldBeNil)
+
+ r, err := read(&buf)
+ So(err, ShouldBeNil)
+ So(r.Metadata.Compression, ShouldEqual, protocol.ButlerMetadata_ZLIB)
+ So(r.Bundle.Source, ShouldEqual, bundle.Source)
+ })
+ })
+ })
+ })
+}
« client/logdog/butlerproto/proto.go ('K') | « client/logdog/butlerproto/proto.go ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698