diff options
author | Santiago M. Mola <santi@mola.io> | 2016-11-25 15:48:20 +0100 |
---|---|---|
committer | Máximo Cuadros <mcuadros@gmail.com> | 2016-11-25 15:48:20 +0100 |
commit | f9adb3565b36ba1573102f954d0ee916009efac2 (patch) | |
tree | abc5b98e61b5851a985a215f7265ce2e9eb131f7 /plumbing/format/pktline/scanner_test.go | |
parent | c1e0932c6cbcc55a78f338d437b9f13d89f33552 (diff) | |
download | go-git-f9adb3565b36ba1573102f954d0ee916009efac2.tar.gz |
move: format/packp -> protocol/packp (#141)
* move: format/packp -> protocol/packp
* format/packp -> protocol/packp
* format/packp/pktline -> format/pktline.
* move: protocol/packp/ulreq/* -> protocol/packp/*
* protocol/packp: rename UlReq types to make them unique.
* * protocol/packp: namespace UlReq encoder.
* protocol/packp: namespace UlReq decoder.
* protocol/packp: fix example names
* move: protocol/packp/advrefs/* -> protocol/packp/*
* further ulreq namespacing
* protocol/packp: namespace AdvRefs types.
Diffstat (limited to 'plumbing/format/pktline/scanner_test.go')
-rw-r--r-- | plumbing/format/pktline/scanner_test.go | 225 |
1 files changed, 225 insertions, 0 deletions
diff --git a/plumbing/format/pktline/scanner_test.go b/plumbing/format/pktline/scanner_test.go new file mode 100644 index 0000000..9f440a4 --- /dev/null +++ b/plumbing/format/pktline/scanner_test.go @@ -0,0 +1,225 @@ +package pktline_test + +import ( + "bytes" + "fmt" + "io" + "strings" + + "gopkg.in/src-d/go-git.v4/plumbing/format/pktline" + + . "gopkg.in/check.v1" +) + +type SuiteScanner struct{} + +var _ = Suite(&SuiteScanner{}) + +func (s *SuiteScanner) TestInvalid(c *C) { + for _, test := range [...]string{ + "0001", "0002", "0003", "0004", + "0001asdfsadf", "0004foo", + "fff1", "fff2", + "gorka", + "0", "003", + " 5a", "5 a", "5 \n", + "-001", "-000", + } { + r := strings.NewReader(test) + sc := pktline.NewScanner(r) + _ = sc.Scan() + c.Assert(sc.Err(), ErrorMatches, pktline.ErrInvalidPktLen.Error(), + Commentf("data = %q", test)) + } +} + +func (s *SuiteScanner) TestEmptyReader(c *C) { + r := strings.NewReader("") + sc := pktline.NewScanner(r) + hasPayload := sc.Scan() + c.Assert(hasPayload, Equals, false) + c.Assert(sc.Err(), Equals, nil) +} + +func (s *SuiteScanner) TestFlush(c *C) { + var buf bytes.Buffer + e := pktline.NewEncoder(&buf) + err := e.Flush() + c.Assert(err, IsNil) + + sc := pktline.NewScanner(&buf) + c.Assert(sc.Scan(), Equals, true) + + payload := sc.Bytes() + c.Assert(len(payload), Equals, 0) +} + +func (s *SuiteScanner) TestPktLineTooShort(c *C) { + r := strings.NewReader("010cfoobar") + + sc := pktline.NewScanner(r) + + c.Assert(sc.Scan(), Equals, false) + c.Assert(sc.Err(), ErrorMatches, "unexpected EOF") +} + +func (s *SuiteScanner) TestScanAndPayload(c *C) { + for _, test := range [...]string{ + "a", + "a\n", + strings.Repeat("a", 100), + strings.Repeat("a", 100) + "\n", + strings.Repeat("\x00", 100), + strings.Repeat("\x00", 100) + "\n", + strings.Repeat("a", pktline.MaxPayloadSize), + strings.Repeat("a", pktline.MaxPayloadSize-1) + "\n", + } { + var buf bytes.Buffer + e := pktline.NewEncoder(&buf) + err := e.EncodeString(test) + c.Assert(err, IsNil, + Commentf("input len=%x, contents=%.10q\n", len(test), test)) + + sc := pktline.NewScanner(&buf) + c.Assert(sc.Scan(), Equals, true, + Commentf("test = %.20q...", test)) + + obtained := sc.Bytes() + c.Assert(obtained, DeepEquals, []byte(test), + Commentf("in = %.20q out = %.20q", test, string(obtained))) + } +} + +func (s *SuiteScanner) TestSkip(c *C) { + for _, test := range [...]struct { + input []string + n int + expected []byte + }{ + { + input: []string{ + "first", + "second", + "third"}, + n: 1, + expected: []byte("second"), + }, + { + input: []string{ + "first", + "second", + "third"}, + n: 2, + expected: []byte("third"), + }, + } { + var buf bytes.Buffer + e := pktline.NewEncoder(&buf) + err := e.EncodeString(test.input...) + c.Assert(err, IsNil) + + sc := pktline.NewScanner(&buf) + for i := 0; i < test.n; i++ { + c.Assert(sc.Scan(), Equals, true, + Commentf("scan error = %s", sc.Err())) + } + c.Assert(sc.Scan(), Equals, true, + Commentf("scan error = %s", sc.Err())) + + obtained := sc.Bytes() + c.Assert(obtained, DeepEquals, test.expected, + Commentf("\nin = %.20q\nout = %.20q\nexp = %.20q", + test.input, obtained, test.expected)) + } +} + +func (s *SuiteScanner) TestEOF(c *C) { + var buf bytes.Buffer + e := pktline.NewEncoder(&buf) + err := e.EncodeString("first", "second") + c.Assert(err, IsNil) + + sc := pktline.NewScanner(&buf) + for sc.Scan() { + } + c.Assert(sc.Err(), IsNil) +} + +// A section are several non flush-pkt lines followed by a flush-pkt, which +// how the git protocol sends long messages. +func (s *SuiteScanner) TestReadSomeSections(c *C) { + nSections := 2 + nLines := 4 + data := sectionsExample(c, nSections, nLines) + sc := pktline.NewScanner(data) + + sectionCounter := 0 + lineCounter := 0 + for sc.Scan() { + if len(sc.Bytes()) == 0 { + sectionCounter++ + } + lineCounter++ + } + c.Assert(sc.Err(), IsNil) + c.Assert(sectionCounter, Equals, nSections) + c.Assert(lineCounter, Equals, (1+nLines)*nSections) +} + +// returns nSection sections, each of them with nLines pkt-lines (not +// counting the flush-pkt: +// +// 0009 0.0\n +// 0009 0.1\n +// ... +// 0000 +// and so on +func sectionsExample(c *C, nSections, nLines int) io.Reader { + var buf bytes.Buffer + e := pktline.NewEncoder(&buf) + + for section := 0; section < nSections; section++ { + ss := []string{} + for line := 0; line < nLines; line++ { + line := fmt.Sprintf(" %d.%d\n", section, line) + ss = append(ss, line) + } + err := e.EncodeString(ss...) + c.Assert(err, IsNil) + err = e.Flush() + c.Assert(err, IsNil) + } + + return &buf +} + +func ExampleScanner() { + // A reader is needed as input. + input := strings.NewReader("000ahello\n" + + "000bworld!\n" + + "0000", + ) + + // Create the scanner... + s := pktline.NewScanner(input) + + // and scan every pkt-line found in the input. + for s.Scan() { + payload := s.Bytes() + if len(payload) == 0 { // zero sized payloads correspond to flush-pkts. + fmt.Println("FLUSH-PKT DETECTED\n") + } else { // otherwise, you will be able to access the full payload. + fmt.Printf("PAYLOAD = %q\n", string(payload)) + } + } + + // this will catch any error when reading from the input, if any. + if s.Err() != nil { + fmt.Println(s.Err()) + } + + // Output: + // PAYLOAD = "hello\n" + // PAYLOAD = "world!\n" + // FLUSH-PKT DETECTED +} |