aboutsummaryrefslogblamecommitdiffstats
path: root/plumbing/protocol/packp/ulreq_decode_test.go
blob: 7658922dec61a5b309e8ce68ff2f6d36fc51e536 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
             






               

                                                             
                                                   
                                                                        



                             
                              
 
                                  
 
                                            
                                
                            
                                  




                                                      
                                             




                                    
                                                              

 
                                                                                           

                                   




                                            
                                                       




                                                                  
                                                           

 
                                             



                                                                
                                         
 

                                                                             


          
                                                                                 




                                          

                                  






                            
                                                           



                                                                                    
                                         

                                                                              
 

                                                                             

 
                                                              






                                                                
                                         
 




                                                                             






                                                
                           



                                                          

                                   


                                              
                                                       







                                                                
                                                                 

 
                                                           







                                                                
                                                             

 
                                                                






                                                                                    
                                         
 




                                                                             





                                                

                                                                             

 
                                                              




                                                                                    
                                         
 

                                                                             

         

                                                                             


                                                     

                                                                             



                                                           
                                                             







                                                                                    
                                         
 




                                                                             


                                        

                                                                             



                                                     

                                                                             



                                                           
                                                            







                                                                                    
                                         
 

                                                                             

         




                                                                             



                                                     

                                                                             




                                                           
                                                           










                                                                                    
                                         
 




                                                                             


                                        




                                                                             




                                                     

                                                                             




                                                           
                                                       





                                                                                    
                                                                 

 
                                                           





                                                                                    
                                                             

 
                                                                   







                                                                                    
                                                                 

 
                                                          





                                                                                    
                                                                

 
                                                                





                                                                                    
                                                                 

 
                                                               






                                                                                    
                                                                 

 
                                                                       






                                                                                    
                                                                 

 
                                                                      







                                                                                    
                                                                 

 
                                                    




                                                                                    
                                         






                                                       
                                                                    




                                                                                    
                                         






                                                       
                                                                    



                                                                                    
                                         






                                                       
                                                             





                                                                                    
                                                             

 
                                                         





                                                                                    
                                                             

 
                                                  




                                                                                    
                                         









                                                                                 
                                                      




                                                                                    
                                         








                                                          
                                          











                                                                                    
                                         
 




                                                                             



                                                     

                                                                             
 




                                                                             










                                                           
                                                






                                                                                    
                                                                 
 
package packp

import (
	"bytes"
	"io"
	"sort"
	"time"

	"github.com/go-git/go-git/v5/plumbing"
	"github.com/go-git/go-git/v5/plumbing/format/pktline"
	"github.com/go-git/go-git/v5/plumbing/hash"
	"github.com/go-git/go-git/v5/plumbing/protocol/packp/capability"

	. "gopkg.in/check.v1"
)

type UlReqDecodeSuite struct{}

var _ = Suite(&UlReqDecodeSuite{})

func (s *UlReqDecodeSuite) TestEmpty(c *C) {
	ur := NewUploadRequest()
	var buf bytes.Buffer
	d := newUlReqDecoder(&buf)

	err := d.Decode(ur)
	c.Assert(err, ErrorMatches, "pkt-line 1: EOF")
}

func (s *UlReqDecodeSuite) TestNoWant(c *C) {
	payloads := []string{
		"foobar",
		pktline.FlushString,
	}
	r := toPktLines(c, payloads)
	s.testDecoderErrorMatches(c, r, ".*missing 'want '.*")
}

func (s *UlReqDecodeSuite) testDecoderErrorMatches(c *C, input io.Reader, pattern string) {
	ur := NewUploadRequest()
	d := newUlReqDecoder(input)

	err := d.Decode(ur)
	c.Assert(err, ErrorMatches, pattern)
}

func (s *UlReqDecodeSuite) TestInvalidFirstHash(c *C) {
	payloads := []string{
		"want 6ecf0ef2c2dffb796alberto2219af86ec6584e5\n",
		pktline.FlushString,
	}
	r := toPktLines(c, payloads)
	s.testDecoderErrorMatches(c, r, ".*invalid hash.*")
}

func (s *UlReqDecodeSuite) TestWantOK(c *C) {
	payloads := []string{
		"want 1111111111111111111111111111111111111111",
		pktline.FlushString,
	}
	ur := s.testDecodeOK(c, payloads)

	c.Assert(ur.Wants, DeepEquals, []plumbing.Hash{
		plumbing.NewHash("1111111111111111111111111111111111111111"),
	})
}

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

	ur := NewUploadRequest()
	d := newUlReqDecoder(&buf)

	err = d.Decode(ur)
	c.Assert(err, IsNil)

	return ur
}

func (s *UlReqDecodeSuite) TestWantWithCapabilities(c *C) {
	payloads := []string{
		"want 1111111111111111111111111111111111111111 ofs-delta multi_ack",
		pktline.FlushString,
	}
	ur := s.testDecodeOK(c, payloads)
	c.Assert(ur.Wants, DeepEquals, []plumbing.Hash{
		plumbing.NewHash("1111111111111111111111111111111111111111")})

	c.Assert(ur.Capabilities.Supports(capability.OFSDelta), Equals, true)
	c.Assert(ur.Capabilities.Supports(capability.MultiACK), Equals, true)
}

func (s *UlReqDecodeSuite) TestManyWantsNoCapabilities(c *C) {
	payloads := []string{
		"want 3333333333333333333333333333333333333333",
		"want 4444444444444444444444444444444444444444",
		"want 1111111111111111111111111111111111111111",
		"want 2222222222222222222222222222222222222222",
		pktline.FlushString,
	}
	ur := s.testDecodeOK(c, payloads)

	expected := []plumbing.Hash{
		plumbing.NewHash("1111111111111111111111111111111111111111"),
		plumbing.NewHash("2222222222222222222222222222222222222222"),
		plumbing.NewHash("3333333333333333333333333333333333333333"),
		plumbing.NewHash("4444444444444444444444444444444444444444"),
	}

	sort.Sort(byHash(ur.Wants))
	sort.Sort(byHash(expected))
	c.Assert(ur.Wants, DeepEquals, expected)
}

type byHash []plumbing.Hash

func (a byHash) Len() int      { return len(a) }
func (a byHash) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a byHash) Less(i, j int) bool {
	ii := [hash.Size]byte(a[i])
	jj := [hash.Size]byte(a[j])
	return bytes.Compare(ii[:], jj[:]) < 0
}

func (s *UlReqDecodeSuite) TestManyWantsBadWant(c *C) {
	payloads := []string{
		"want 3333333333333333333333333333333333333333",
		"want 4444444444444444444444444444444444444444",
		"foo",
		"want 2222222222222222222222222222222222222222",
		pktline.FlushString,
	}
	r := toPktLines(c, payloads)
	s.testDecoderErrorMatches(c, r, ".*unexpected payload.*")
}

func (s *UlReqDecodeSuite) TestManyWantsInvalidHash(c *C) {
	payloads := []string{
		"want 3333333333333333333333333333333333333333",
		"want 4444444444444444444444444444444444444444",
		"want 1234567890abcdef",
		"want 2222222222222222222222222222222222222222",
		pktline.FlushString,
	}
	r := toPktLines(c, payloads)
	s.testDecoderErrorMatches(c, r, ".*malformed hash.*")
}

func (s *UlReqDecodeSuite) TestManyWantsWithCapabilities(c *C) {
	payloads := []string{
		"want 3333333333333333333333333333333333333333 ofs-delta multi_ack",
		"want 4444444444444444444444444444444444444444",
		"want 1111111111111111111111111111111111111111",
		"want 2222222222222222222222222222222222222222",
		pktline.FlushString,
	}
	ur := s.testDecodeOK(c, payloads)

	expected := []plumbing.Hash{
		plumbing.NewHash("1111111111111111111111111111111111111111"),
		plumbing.NewHash("2222222222222222222222222222222222222222"),
		plumbing.NewHash("3333333333333333333333333333333333333333"),
		plumbing.NewHash("4444444444444444444444444444444444444444"),
	}

	sort.Sort(byHash(ur.Wants))
	sort.Sort(byHash(expected))
	c.Assert(ur.Wants, DeepEquals, expected)

	c.Assert(ur.Capabilities.Supports(capability.OFSDelta), Equals, true)
	c.Assert(ur.Capabilities.Supports(capability.MultiACK), Equals, true)
}

func (s *UlReqDecodeSuite) TestSingleShallowSingleWant(c *C) {
	payloads := []string{
		"want 3333333333333333333333333333333333333333 ofs-delta multi_ack",
		"shallow aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
		pktline.FlushString,
	}
	ur := s.testDecodeOK(c, payloads)

	expectedWants := []plumbing.Hash{
		plumbing.NewHash("3333333333333333333333333333333333333333"),
	}

	expectedShallows := []plumbing.Hash{
		plumbing.NewHash("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"),
	}

	c.Assert(ur.Wants, DeepEquals, expectedWants)
	c.Assert(ur.Capabilities.Supports(capability.OFSDelta), Equals, true)
	c.Assert(ur.Capabilities.Supports(capability.MultiACK), Equals, true)

	c.Assert(ur.Shallows, DeepEquals, expectedShallows)
}

func (s *UlReqDecodeSuite) TestSingleShallowManyWants(c *C) {
	payloads := []string{
		"want 3333333333333333333333333333333333333333 ofs-delta multi_ack",
		"want 4444444444444444444444444444444444444444",
		"want 1111111111111111111111111111111111111111",
		"want 2222222222222222222222222222222222222222",
		"shallow aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
		pktline.FlushString,
	}
	ur := s.testDecodeOK(c, payloads)

	expectedWants := []plumbing.Hash{
		plumbing.NewHash("1111111111111111111111111111111111111111"),
		plumbing.NewHash("2222222222222222222222222222222222222222"),
		plumbing.NewHash("3333333333333333333333333333333333333333"),
		plumbing.NewHash("4444444444444444444444444444444444444444"),
	}
	sort.Sort(byHash(expectedWants))

	expectedShallows := []plumbing.Hash{
		plumbing.NewHash("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"),
	}

	sort.Sort(byHash(ur.Wants))
	c.Assert(ur.Wants, DeepEquals, expectedWants)
	c.Assert(ur.Capabilities.Supports(capability.OFSDelta), Equals, true)
	c.Assert(ur.Capabilities.Supports(capability.MultiACK), Equals, true)

	c.Assert(ur.Shallows, DeepEquals, expectedShallows)
}

func (s *UlReqDecodeSuite) TestManyShallowSingleWant(c *C) {
	payloads := []string{
		"want 3333333333333333333333333333333333333333 ofs-delta multi_ack",
		"shallow aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
		"shallow bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
		"shallow cccccccccccccccccccccccccccccccccccccccc",
		"shallow dddddddddddddddddddddddddddddddddddddddd",
		pktline.FlushString,
	}
	ur := s.testDecodeOK(c, payloads)

	expectedWants := []plumbing.Hash{
		plumbing.NewHash("3333333333333333333333333333333333333333"),
	}

	expectedShallows := []plumbing.Hash{
		plumbing.NewHash("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"),
		plumbing.NewHash("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"),
		plumbing.NewHash("cccccccccccccccccccccccccccccccccccccccc"),
		plumbing.NewHash("dddddddddddddddddddddddddddddddddddddddd"),
	}
	sort.Sort(byHash(expectedShallows))

	c.Assert(ur.Wants, DeepEquals, expectedWants)
	c.Assert(ur.Capabilities.Supports(capability.OFSDelta), Equals, true)
	c.Assert(ur.Capabilities.Supports(capability.MultiACK), Equals, true)

	sort.Sort(byHash(ur.Shallows))
	c.Assert(ur.Shallows, DeepEquals, expectedShallows)
}

func (s *UlReqDecodeSuite) TestManyShallowManyWants(c *C) {
	payloads := []string{
		"want 3333333333333333333333333333333333333333 ofs-delta multi_ack",
		"want 4444444444444444444444444444444444444444",
		"want 1111111111111111111111111111111111111111",
		"want 2222222222222222222222222222222222222222",
		"shallow aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
		"shallow bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
		"shallow cccccccccccccccccccccccccccccccccccccccc",
		"shallow dddddddddddddddddddddddddddddddddddddddd",
		pktline.FlushString,
	}
	ur := s.testDecodeOK(c, payloads)

	expectedWants := []plumbing.Hash{
		plumbing.NewHash("1111111111111111111111111111111111111111"),
		plumbing.NewHash("2222222222222222222222222222222222222222"),
		plumbing.NewHash("3333333333333333333333333333333333333333"),
		plumbing.NewHash("4444444444444444444444444444444444444444"),
	}
	sort.Sort(byHash(expectedWants))

	expectedShallows := []plumbing.Hash{
		plumbing.NewHash("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"),
		plumbing.NewHash("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"),
		plumbing.NewHash("cccccccccccccccccccccccccccccccccccccccc"),
		plumbing.NewHash("dddddddddddddddddddddddddddddddddddddddd"),
	}
	sort.Sort(byHash(expectedShallows))

	sort.Sort(byHash(ur.Wants))
	c.Assert(ur.Wants, DeepEquals, expectedWants)
	c.Assert(ur.Capabilities.Supports(capability.OFSDelta), Equals, true)
	c.Assert(ur.Capabilities.Supports(capability.MultiACK), Equals, true)

	sort.Sort(byHash(ur.Shallows))
	c.Assert(ur.Shallows, DeepEquals, expectedShallows)
}

func (s *UlReqDecodeSuite) TestMalformedShallow(c *C) {
	payloads := []string{
		"want 3333333333333333333333333333333333333333 ofs-delta multi_ack",
		"shalow aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
		pktline.FlushString,
	}
	r := toPktLines(c, payloads)
	s.testDecoderErrorMatches(c, r, ".*unexpected payload.*")
}

func (s *UlReqDecodeSuite) TestMalformedShallowHash(c *C) {
	payloads := []string{
		"want 3333333333333333333333333333333333333333 ofs-delta multi_ack",
		"shallow aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
		pktline.FlushString,
	}
	r := toPktLines(c, payloads)
	s.testDecoderErrorMatches(c, r, ".*malformed hash.*")
}

func (s *UlReqDecodeSuite) TestMalformedShallowManyShallows(c *C) {
	payloads := []string{
		"want 3333333333333333333333333333333333333333 ofs-delta multi_ack",
		"shallow aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
		"shalow bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
		"shallow cccccccccccccccccccccccccccccccccccccccc",
		pktline.FlushString,
	}
	r := toPktLines(c, payloads)
	s.testDecoderErrorMatches(c, r, ".*unexpected payload.*")
}

func (s *UlReqDecodeSuite) TestMalformedDeepenSpec(c *C) {
	payloads := []string{
		"want 3333333333333333333333333333333333333333 ofs-delta multi_ack",
		"deepen-foo 34",
		pktline.FlushString,
	}
	r := toPktLines(c, payloads)
	s.testDecoderErrorMatches(c, r, ".*unexpected deepen.*")
}

func (s *UlReqDecodeSuite) TestMalformedDeepenSingleWant(c *C) {
	payloads := []string{
		"want 3333333333333333333333333333333333333333 ofs-delta multi_ack",
		"depth 32",
		pktline.FlushString,
	}
	r := toPktLines(c, payloads)
	s.testDecoderErrorMatches(c, r, ".*unexpected payload.*")
}

func (s *UlReqDecodeSuite) TestMalformedDeepenMultiWant(c *C) {
	payloads := []string{
		"want 3333333333333333333333333333333333333333 ofs-delta multi_ack",
		"want 2222222222222222222222222222222222222222",
		"depth 32",
		pktline.FlushString,
	}
	r := toPktLines(c, payloads)
	s.testDecoderErrorMatches(c, r, ".*unexpected payload.*")
}

func (s *UlReqDecodeSuite) TestMalformedDeepenWithSingleShallow(c *C) {
	payloads := []string{
		"want 3333333333333333333333333333333333333333 ofs-delta multi_ack",
		"shallow 2222222222222222222222222222222222222222",
		"depth 32",
		pktline.FlushString,
	}
	r := toPktLines(c, payloads)
	s.testDecoderErrorMatches(c, r, ".*unexpected payload.*")
}

func (s *UlReqDecodeSuite) TestMalformedDeepenWithMultiShallow(c *C) {
	payloads := []string{
		"want 3333333333333333333333333333333333333333 ofs-delta multi_ack",
		"shallow 2222222222222222222222222222222222222222",
		"shallow 5555555555555555555555555555555555555555",
		"depth 32",
		pktline.FlushString,
	}
	r := toPktLines(c, payloads)
	s.testDecoderErrorMatches(c, r, ".*unexpected payload.*")
}

func (s *UlReqDecodeSuite) TestDeepenCommits(c *C) {
	payloads := []string{
		"want 3333333333333333333333333333333333333333 ofs-delta multi_ack",
		"deepen 1234",
		pktline.FlushString,
	}
	ur := s.testDecodeOK(c, payloads)

	c.Assert(ur.Depth, FitsTypeOf, DepthCommits(0))
	commits, ok := ur.Depth.(DepthCommits)
	c.Assert(ok, Equals, true)
	c.Assert(int(commits), Equals, 1234)
}

func (s *UlReqDecodeSuite) TestDeepenCommitsInfiniteImplicit(c *C) {
	payloads := []string{
		"want 3333333333333333333333333333333333333333 ofs-delta multi_ack",
		"deepen 0",
		pktline.FlushString,
	}
	ur := s.testDecodeOK(c, payloads)

	c.Assert(ur.Depth, FitsTypeOf, DepthCommits(0))
	commits, ok := ur.Depth.(DepthCommits)
	c.Assert(ok, Equals, true)
	c.Assert(int(commits), Equals, 0)
}

func (s *UlReqDecodeSuite) TestDeepenCommitsInfiniteExplicit(c *C) {
	payloads := []string{
		"want 3333333333333333333333333333333333333333 ofs-delta multi_ack",
		pktline.FlushString,
	}
	ur := s.testDecodeOK(c, payloads)

	c.Assert(ur.Depth, FitsTypeOf, DepthCommits(0))
	commits, ok := ur.Depth.(DepthCommits)
	c.Assert(ok, Equals, true)
	c.Assert(int(commits), Equals, 0)
}

func (s *UlReqDecodeSuite) TestMalformedDeepenCommits(c *C) {
	payloads := []string{
		"want 3333333333333333333333333333333333333333 ofs-delta multi_ack",
		"deepen -32",
		pktline.FlushString,
	}
	r := toPktLines(c, payloads)
	s.testDecoderErrorMatches(c, r, ".*negative depth.*")
}

func (s *UlReqDecodeSuite) TestDeepenCommitsEmpty(c *C) {
	payloads := []string{
		"want 3333333333333333333333333333333333333333 ofs-delta multi_ack",
		"deepen ",
		pktline.FlushString,
	}
	r := toPktLines(c, payloads)
	s.testDecoderErrorMatches(c, r, ".*invalid syntax.*")
}

func (s *UlReqDecodeSuite) TestDeepenSince(c *C) {
	payloads := []string{
		"want 3333333333333333333333333333333333333333 ofs-delta multi_ack",
		"deepen-since 1420167845", // 2015-01-02T03:04:05+00:00
		pktline.FlushString,
	}
	ur := s.testDecodeOK(c, payloads)

	expected := time.Date(2015, time.January, 2, 3, 4, 5, 0, time.UTC)

	c.Assert(ur.Depth, FitsTypeOf, DepthSince(time.Now()))
	since, ok := ur.Depth.(DepthSince)
	c.Assert(ok, Equals, true)
	c.Assert(time.Time(since).Equal(expected), Equals, true,
		Commentf("obtained=%s\nexpected=%s", time.Time(since), expected))
}

func (s *UlReqDecodeSuite) TestDeepenReference(c *C) {
	payloads := []string{
		"want 3333333333333333333333333333333333333333 ofs-delta multi_ack",
		"deepen-not refs/heads/master",
		pktline.FlushString,
	}
	ur := s.testDecodeOK(c, payloads)

	expected := "refs/heads/master"

	c.Assert(ur.Depth, FitsTypeOf, DepthReference(""))
	reference, ok := ur.Depth.(DepthReference)
	c.Assert(ok, Equals, true)
	c.Assert(string(reference), Equals, expected)
}

func (s *UlReqDecodeSuite) TestAll(c *C) {
	payloads := []string{
		"want 3333333333333333333333333333333333333333 ofs-delta multi_ack",
		"want 4444444444444444444444444444444444444444",
		"want 1111111111111111111111111111111111111111",
		"want 2222222222222222222222222222222222222222",
		"shallow aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
		"shallow bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
		"shallow cccccccccccccccccccccccccccccccccccccccc",
		"shallow dddddddddddddddddddddddddddddddddddddddd",
		"deepen 1234",
		pktline.FlushString,
	}
	ur := s.testDecodeOK(c, payloads)

	expectedWants := []plumbing.Hash{
		plumbing.NewHash("1111111111111111111111111111111111111111"),
		plumbing.NewHash("2222222222222222222222222222222222222222"),
		plumbing.NewHash("3333333333333333333333333333333333333333"),
		plumbing.NewHash("4444444444444444444444444444444444444444"),
	}
	sort.Sort(byHash(expectedWants))
	sort.Sort(byHash(ur.Wants))
	c.Assert(ur.Wants, DeepEquals, expectedWants)
	c.Assert(ur.Capabilities.Supports(capability.OFSDelta), Equals, true)
	c.Assert(ur.Capabilities.Supports(capability.MultiACK), Equals, true)

	expectedShallows := []plumbing.Hash{
		plumbing.NewHash("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"),
		plumbing.NewHash("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"),
		plumbing.NewHash("cccccccccccccccccccccccccccccccccccccccc"),
		plumbing.NewHash("dddddddddddddddddddddddddddddddddddddddd"),
	}
	sort.Sort(byHash(expectedShallows))
	sort.Sort(byHash(ur.Shallows))
	c.Assert(ur.Shallows, DeepEquals, expectedShallows)

	c.Assert(ur.Depth, FitsTypeOf, DepthCommits(0))
	commits, ok := ur.Depth.(DepthCommits)
	c.Assert(ok, Equals, true)
	c.Assert(int(commits), Equals, 1234)
}

func (s *UlReqDecodeSuite) TestExtraData(c *C) {
	payloads := []string{
		"want 3333333333333333333333333333333333333333 ofs-delta multi_ack",
		"deepen 32",
		"foo",
		pktline.FlushString,
	}
	r := toPktLines(c, payloads)
	s.testDecoderErrorMatches(c, r, ".*unexpected payload.*")
}