aboutsummaryrefslogblamecommitdiffstats
path: root/plumbing/protocol/packp/updreq_decode_test.go
blob: bdcbdf50336f888c66f8370cee66a045fccd36fa (plain) (tree)
1
2
3
4
5
6
7
8





               

                                                             















































































































































                                                                                                                                                                
                                               




                                                     
                                                                   





                                                                                                              
                                                     







                                                                             


                                                                                             
         
                                                                   







                                                                                                               
                                                     







                                                                             


                                                                                             

                                            
                                                                   







                                                                                                                      
                                                     







                                                                              


                                                                                             


                                            
                                                                   








                                                                                                                      





                                                                             
                                               





                                                     
                                                                          










                                                                                                              

















                                                                                            




















                                                                                                             
                                 

                                  
                                 



                                      
package packp

import (
	"bytes"
	"io"

	"github.com/go-git/go-git/v5/plumbing"
	"github.com/go-git/go-git/v5/plumbing/format/pktline"

	. "gopkg.in/check.v1"
)

type UpdReqDecodeSuite struct{}

var _ = Suite(&UpdReqDecodeSuite{})

func (s *UpdReqDecodeSuite) TestEmpty(c *C) {
	r := NewReferenceUpdateRequest()
	var buf bytes.Buffer
	c.Assert(r.Decode(&buf), Equals, ErrEmpty)
	c.Assert(r, DeepEquals, NewReferenceUpdateRequest())
}

func (s *UpdReqDecodeSuite) TestInvalidPktlines(c *C) {
	r := NewReferenceUpdateRequest()
	input := bytes.NewReader([]byte("xxxxxxxxxx"))
	c.Assert(r.Decode(input), ErrorMatches, "invalid pkt-len found")
}

func (s *UpdReqDecodeSuite) TestInvalidShadow(c *C) {
	payloads := []string{
		"shallow",
		"1ecf0ef2c2dffb796033e5a02219af86ec6584e5 2ecf0ef2c2dffb796033e5a02219af86ec6584e5 myref\x00",
		pktline.FlushString,
	}
	s.testDecoderErrorMatches(c, toPktLines(c, payloads), "^malformed request: invalid shallow line length: expected 48, got 7$")

	payloads = []string{
		"shallow ",
		"1ecf0ef2c2dffb796033e5a02219af86ec6584e5 2ecf0ef2c2dffb796033e5a02219af86ec6584e5 myref\x00",
		pktline.FlushString,
	}
	s.testDecoderErrorMatches(c, toPktLines(c, payloads), "^malformed request: invalid shallow line length: expected 48, got 8$")

	payloads = []string{
		"shallow 1ecf0ef2c2dffb796033e5a02219af86ec65",
		"1ecf0ef2c2dffb796033e5a02219af86ec6584e5 2ecf0ef2c2dffb796033e5a02219af86ec6584e5 myref\x00",
		pktline.FlushString,
	}
	s.testDecoderErrorMatches(c, toPktLines(c, payloads), "^malformed request: invalid shallow line length: expected 48, got 44$")

	payloads = []string{
		"shallow 1ecf0ef2c2dffb796033e5a02219af86ec6584e54",
		"1ecf0ef2c2dffb796033e5a02219af86ec6584e5 2ecf0ef2c2dffb796033e5a02219af86ec6584e5 myref\x00",
		pktline.FlushString,
	}
	s.testDecoderErrorMatches(c, toPktLines(c, payloads), "^malformed request: invalid shallow line length: expected 48, got 49$")

	payloads = []string{
		"shallow 1ecf0ef2c2dffb796033e5a02219af86ec6584eu",
		"1ecf0ef2c2dffb796033e5a02219af86ec6584e5 2ecf0ef2c2dffb796033e5a02219af86ec6584e5 myref\x00",
		pktline.FlushString,
	}
	s.testDecoderErrorMatches(c, toPktLines(c, payloads), "^malformed request: invalid shallow object id: invalid hash: .*")
}

func (s *UpdReqDecodeSuite) TestMalformedCommand(c *C) {
	payloads := []string{
		"1ecf0ef2c2dffb796033e5a02219af86ec6584e5x2ecf0ef2c2dffb796033e5a02219af86ec6584e5xmyref\x00",
		pktline.FlushString,
	}
	s.testDecoderErrorMatches(c, toPktLines(c, payloads), "^malformed request: malformed command: EOF$")

	payloads = []string{
		"1ecf0ef2c2dffb796033e5a02219af86ec6584e5 2ecf0ef2c2dffb796033e5a02219af86ec6584e5 myref\x00",
		"1ecf0ef2c2dffb796033e5a02219af86ec6584e5x2ecf0ef2c2dffb796033e5a02219af86ec6584e5xmyref",
		pktline.FlushString,
	}
	s.testDecoderErrorMatches(c, toPktLines(c, payloads), "^malformed request: malformed command: EOF$")
}

func (s *UpdReqDecodeSuite) TestInvalidCommandInvalidHash(c *C) {
	payloads := []string{
		"1ecf0ef2c2dffb796033e5a02219af86ec6584e 2ecf0ef2c2dffb796033e5a02219af86ec6584e5 myref\x00",
		pktline.FlushString,
	}
	s.testDecoderErrorMatches(c, toPktLines(c, payloads), "^malformed request: invalid old object id: invalid hash size: expected 40, got 39$")

	payloads = []string{
		"1ecf0ef2c2dffb796033e5a02219af86ec6584e5 2ecf0ef2c2dffb796033e5a02219af86ec6584e myref\x00",
		pktline.FlushString,
	}
	s.testDecoderErrorMatches(c, toPktLines(c, payloads), "^malformed request: invalid new object id: invalid hash size: expected 40, got 39$")

	payloads = []string{
		"1ecf0ef2c2dffb796033e5a02219af86e 2ecf0ef2c2dffb796033e5a02219af86ec6 m\x00",
		pktline.FlushString,
	}
	s.testDecoderErrorMatches(c, toPktLines(c, payloads), "^malformed request: invalid command and capabilities line length: expected at least 84, got 72$")

	payloads = []string{
		"1ecf0ef2c2dffb796033e5a02219af86ec6584eu 2ecf0ef2c2dffb796033e5a02219af86ec6584e5 myref\x00",
		pktline.FlushString,
	}
	s.testDecoderErrorMatches(c, toPktLines(c, payloads), "^malformed request: invalid old object id: invalid hash: .*$")

	payloads = []string{
		"1ecf0ef2c2dffb796033e5a02219af86ec6584e5 2ecf0ef2c2dffb796033e5a02219af86ec6584eu myref\x00",
		pktline.FlushString,
	}
	s.testDecoderErrorMatches(c, toPktLines(c, payloads), "^malformed request: invalid new object id: invalid hash: .*$")
}

func (s *UpdReqDecodeSuite) TestInvalidCommandMissingNullDelimiter(c *C) {
	payloads := []string{
		"1ecf0ef2c2dffb796033e5a02219af86ec6584e5 2ecf0ef2c2dffb796033e5a02219af86ec6584e5 myref",
		pktline.FlushString,
	}
	s.testDecoderErrorMatches(c, toPktLines(c, payloads), "capabilities delimiter not found")
}

func (s *UpdReqDecodeSuite) TestInvalidCommandMissingName(c *C) {
	payloads := []string{
		"1ecf0ef2c2dffb796033e5a02219af86ec6584e5 2ecf0ef2c2dffb796033e5a02219af86ec6584e5\x00",
		pktline.FlushString,
	}
	s.testDecoderErrorMatches(c, toPktLines(c, payloads), "^malformed request: invalid command and capabilities line length: expected at least 84, got 82$")

	payloads = []string{
		"1ecf0ef2c2dffb796033e5a02219af86ec6584e5 2ecf0ef2c2dffb796033e5a02219af86ec6584e5 \x00",
		pktline.FlushString,
	}
	s.testDecoderErrorMatches(c, toPktLines(c, payloads), "^malformed request: invalid command and capabilities line length: expected at least 84, got 83$")

	payloads = []string{
		"1ecf0ef2c2dffb796033e5a02219af86ec6584e5 2ecf0ef2c2dffb796033e5a02219af86ec6584e5 myref\x00",
		"1ecf0ef2c2dffb796033e5a02219af86ec6584e5 2ecf0ef2c2dffb796033e5a02219af86ec6584e5",
		pktline.FlushString,
	}
	s.testDecoderErrorMatches(c, toPktLines(c, payloads), "^malformed request: invalid command line length: expected at least 83, got 81$")

	payloads = []string{
		"1ecf0ef2c2dffb796033e5a02219af86ec6584e5 2ecf0ef2c2dffb796033e5a02219af86ec6584e5 myref\x00",
		"1ecf0ef2c2dffb796033e5a02219af86ec6584e5 2ecf0ef2c2dffb796033e5a02219af86ec6584e5 ",
		pktline.FlushString,
	}
	s.testDecoderErrorMatches(c, toPktLines(c, payloads), "^malformed request: invalid command line length: expected at least 83, got 82$")
}

func (s *UpdReqDecodeSuite) TestOneUpdateCommand(c *C) {
	hash1 := plumbing.NewHash("1ecf0ef2c2dffb796033e5a02219af86ec6584e5")
	hash2 := plumbing.NewHash("2ecf0ef2c2dffb796033e5a02219af86ec6584e5")
	name := plumbing.ReferenceName("myref")

	expected := NewReferenceUpdateRequest()
	expected.Commands = []*Command{
		{Name: name, Old: hash1, New: hash2},
	}
	expected.Packfile = io.NopCloser(bytes.NewReader([]byte{}))

	payloads := []string{
		"1ecf0ef2c2dffb796033e5a02219af86ec6584e5 2ecf0ef2c2dffb796033e5a02219af86ec6584e5 myref\x00",
		pktline.FlushString,
	}

	s.testDecodeOkExpected(c, expected, payloads)
}

func (s *UpdReqDecodeSuite) TestMultipleCommands(c *C) {
	hash1 := plumbing.NewHash("1ecf0ef2c2dffb796033e5a02219af86ec6584e5")
	hash2 := plumbing.NewHash("2ecf0ef2c2dffb796033e5a02219af86ec6584e5")

	expected := NewReferenceUpdateRequest()
	expected.Commands = []*Command{
		{Name: plumbing.ReferenceName("myref1"), Old: hash1, New: hash2},
		{Name: plumbing.ReferenceName("myref2"), Old: plumbing.ZeroHash, New: hash2},
		{Name: plumbing.ReferenceName("myref3"), Old: hash1, New: plumbing.ZeroHash},
	}
	expected.Packfile = io.NopCloser(bytes.NewReader([]byte{}))

	payloads := []string{
		"1ecf0ef2c2dffb796033e5a02219af86ec6584e5 2ecf0ef2c2dffb796033e5a02219af86ec6584e5 myref1\x00",
		"0000000000000000000000000000000000000000 2ecf0ef2c2dffb796033e5a02219af86ec6584e5 myref2",
		"1ecf0ef2c2dffb796033e5a02219af86ec6584e5 0000000000000000000000000000000000000000 myref3",
		pktline.FlushString,
	}

	s.testDecodeOkExpected(c, expected, payloads)
}

func (s *UpdReqDecodeSuite) TestMultipleCommandsAndCapabilities(c *C) {
	hash1 := plumbing.NewHash("1ecf0ef2c2dffb796033e5a02219af86ec6584e5")
	hash2 := plumbing.NewHash("2ecf0ef2c2dffb796033e5a02219af86ec6584e5")

	expected := NewReferenceUpdateRequest()
	expected.Commands = []*Command{
		{Name: plumbing.ReferenceName("myref1"), Old: hash1, New: hash2},
		{Name: plumbing.ReferenceName("myref2"), Old: plumbing.ZeroHash, New: hash2},
		{Name: plumbing.ReferenceName("myref3"), Old: hash1, New: plumbing.ZeroHash},
	}
	expected.Capabilities.Add("shallow")
	expected.Packfile = io.NopCloser(bytes.NewReader([]byte{}))

	payloads := []string{
		"1ecf0ef2c2dffb796033e5a02219af86ec6584e5 2ecf0ef2c2dffb796033e5a02219af86ec6584e5 myref1\x00shallow",
		"0000000000000000000000000000000000000000 2ecf0ef2c2dffb796033e5a02219af86ec6584e5 myref2",
		"1ecf0ef2c2dffb796033e5a02219af86ec6584e5 0000000000000000000000000000000000000000 myref3",
		pktline.FlushString,
	}

	s.testDecodeOkExpected(c, expected, payloads)
}

func (s *UpdReqDecodeSuite) TestMultipleCommandsAndCapabilitiesShallow(c *C) {
	hash1 := plumbing.NewHash("1ecf0ef2c2dffb796033e5a02219af86ec6584e5")
	hash2 := plumbing.NewHash("2ecf0ef2c2dffb796033e5a02219af86ec6584e5")

	expected := NewReferenceUpdateRequest()
	expected.Commands = []*Command{
		{Name: plumbing.ReferenceName("myref1"), Old: hash1, New: hash2},
		{Name: plumbing.ReferenceName("myref2"), Old: plumbing.ZeroHash, New: hash2},
		{Name: plumbing.ReferenceName("myref3"), Old: hash1, New: plumbing.ZeroHash},
	}
	expected.Capabilities.Add("shallow")
	expected.Shallow = &hash1
	expected.Packfile = io.NopCloser(bytes.NewReader([]byte{}))

	payloads := []string{
		"shallow 1ecf0ef2c2dffb796033e5a02219af86ec6584e5",
		"1ecf0ef2c2dffb796033e5a02219af86ec6584e5 2ecf0ef2c2dffb796033e5a02219af86ec6584e5 myref1\x00shallow",
		"0000000000000000000000000000000000000000 2ecf0ef2c2dffb796033e5a02219af86ec6584e5 myref2",
		"1ecf0ef2c2dffb796033e5a02219af86ec6584e5 0000000000000000000000000000000000000000 myref3",
		pktline.FlushString,
	}

	s.testDecodeOkExpected(c, expected, payloads)
}

func (s *UpdReqDecodeSuite) TestWithPackfile(c *C) {
	hash1 := plumbing.NewHash("1ecf0ef2c2dffb796033e5a02219af86ec6584e5")
	hash2 := plumbing.NewHash("2ecf0ef2c2dffb796033e5a02219af86ec6584e5")
	name := plumbing.ReferenceName("myref")

	expected := NewReferenceUpdateRequest()
	expected.Commands = []*Command{
		{Name: name, Old: hash1, New: hash2},
	}
	packfileContent := []byte("PACKabc")
	expected.Packfile = io.NopCloser(bytes.NewReader(packfileContent))

	payloads := []string{
		"1ecf0ef2c2dffb796033e5a02219af86ec6584e5 2ecf0ef2c2dffb796033e5a02219af86ec6584e5 myref\x00",
		pktline.FlushString,
	}
	var buf bytes.Buffer
	e := pktline.NewEncoder(&buf)
	c.Assert(e.EncodeString(payloads...), IsNil)
	buf.Write(packfileContent)

	s.testDecodeOkRaw(c, expected, buf.Bytes())
}

func (s *UpdReqDecodeSuite) testDecoderErrorMatches(c *C, input io.Reader, pattern string) {
	r := NewReferenceUpdateRequest()
	c.Assert(r.Decode(input), ErrorMatches, pattern)
}

func (s *UpdReqDecodeSuite) testDecodeOK(c *C, payloads []string) *ReferenceUpdateRequest {
	var buf bytes.Buffer
	e := pktline.NewEncoder(&buf)
	err := e.EncodeString(payloads...)
	c.Assert(err, IsNil)

	r := NewReferenceUpdateRequest()
	c.Assert(r.Decode(&buf), IsNil)

	return r
}

func (s *UpdReqDecodeSuite) testDecodeOkRaw(c *C, expected *ReferenceUpdateRequest, raw []byte) {
	req := NewReferenceUpdateRequest()
	c.Assert(req.Decode(bytes.NewBuffer(raw)), IsNil)
	c.Assert(req.Packfile, NotNil)
	s.compareReaders(c, req.Packfile, expected.Packfile)
	req.Packfile = nil
	expected.Packfile = nil
	c.Assert(req, DeepEquals, expected)
}

func (s *UpdReqDecodeSuite) testDecodeOkExpected(c *C, expected *ReferenceUpdateRequest, payloads []string) {
	req := s.testDecodeOK(c, payloads)
	c.Assert(req.Packfile, NotNil)
	s.compareReaders(c, req.Packfile, expected.Packfile)
	req.Packfile = nil
	expected.Packfile = nil
	c.Assert(req, DeepEquals, expected)
}

func (s *UpdReqDecodeSuite) compareReaders(c *C, a io.ReadCloser, b io.ReadCloser) {
	pba, err := io.ReadAll(a)
	c.Assert(err, IsNil)
	c.Assert(a.Close(), IsNil)
	pbb, err := io.ReadAll(b)
	c.Assert(err, IsNil)
	c.Assert(b.Close(), IsNil)
	c.Assert(pba, DeepEquals, pbb)
}