aboutsummaryrefslogtreecommitdiffstats
path: root/formats/packp/pktline/scanner_test.go
diff options
context:
space:
mode:
authorAlberto Cortés <alcortesm@gmail.com>2016-10-18 15:23:01 +0200
committerMáximo Cuadros <mcuadros@gmail.com>2016-10-18 15:23:01 +0200
commit5f7d34066cc5583ee30a315e0661b5326dc548db (patch)
treec10fdbf1f42d5b51de25c6828ba6573dd28f4536 /formats/packp/pktline/scanner_test.go
parent6c6a37b9128189ba4cdde8128428a36ef75d1a44 (diff)
downloadgo-git-5f7d34066cc5583ee30a315e0661b5326dc548db.tar.gz
Substitute old pktline encoder/decoder with new pktline scanner (#84)
* replace old pktline package with new pktline scanner * remove error checks on pktline.NewFromString * fix deppend bug * reduce memory garbage when pktline.NewFromStrings * improve int to hex conversion to help gc * make intToHex func private * clean function names
Diffstat (limited to 'formats/packp/pktline/scanner_test.go')
-rw-r--r--formats/packp/pktline/scanner_test.go208
1 files changed, 208 insertions, 0 deletions
diff --git a/formats/packp/pktline/scanner_test.go b/formats/packp/pktline/scanner_test.go
new file mode 100644
index 0000000..08ca51f
--- /dev/null
+++ b/formats/packp/pktline/scanner_test.go
@@ -0,0 +1,208 @@
+package pktline_test
+
+import (
+ "fmt"
+ "io"
+ "strings"
+
+ "gopkg.in/src-d/go-git.v4/formats/packp/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) {
+ r, err := pktline.NewFromStrings("")
+ c.Assert(err, IsNil)
+ sc := pktline.NewScanner(r)
+ 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",
+ } {
+ r, err := pktline.NewFromStrings(test)
+ c.Assert(err, IsNil, Commentf("input len=%x, contents=%.10q\n", len(test), test))
+ sc := pktline.NewScanner(r)
+
+ 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"),
+ },
+ } {
+ r, err := pktline.NewFromStrings(test.input...)
+ c.Assert(err, IsNil)
+ sc := pktline.NewScanner(r)
+ 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) {
+ r, err := pktline.NewFromStrings("first", "second")
+ c.Assert(err, IsNil)
+ sc := pktline.NewScanner(r)
+ 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 {
+ ss := []string{}
+ for section := 0; section < nSections; section++ {
+ for line := 0; line < nLines; line++ {
+ line := fmt.Sprintf(" %d.%d\n", section, line)
+ ss = append(ss, line)
+ }
+ ss = append(ss, "")
+ }
+
+ ret, err := pktline.NewFromStrings(ss...)
+ c.Assert(err, IsNil)
+
+ return ret
+}
+
+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
+}