aboutsummaryrefslogtreecommitdiffstats
path: root/plumbing/format/packfile/encoder_test.go
diff options
context:
space:
mode:
authorAntonio Navarro Perez <antnavper@gmail.com>2016-12-14 10:20:00 +0100
committerMáximo Cuadros <mcuadros@gmail.com>2016-12-14 10:20:00 +0100
commit500b1e1e183c73e3087710fca2f96acfd2e2d5cb (patch)
treeb2777dedd22f7279f2df7da8eb3b433d560c5701 /plumbing/format/packfile/encoder_test.go
parent40875ee0df345468f36cb00d54820d622b37cbc5 (diff)
downloadgo-git-500b1e1e183c73e3087710fca2f96acfd2e2d5cb.tar.gz
format/packfile: implement delta encoding (#172)
* format/packfile: implement delta encoding - Added all the logic to the encoder to be able to encode ref-delta and offset-delta objects - Created plumbing.ObjectToPack to handle deltas and standard objects when we are writting them into a packfile - Added specific encoder delta tests, one standard object and one delta, and one standard object and two deltas * Requested changes. * Requested changes
Diffstat (limited to 'plumbing/format/packfile/encoder_test.go')
-rw-r--r--plumbing/format/packfile/encoder_test.go128
1 files changed, 124 insertions, 4 deletions
diff --git a/plumbing/format/packfile/encoder_test.go b/plumbing/format/packfile/encoder_test.go
index 729843d..b07e2f4 100644
--- a/plumbing/format/packfile/encoder_test.go
+++ b/plumbing/format/packfile/encoder_test.go
@@ -79,6 +79,13 @@ func (s *EncoderSuite) TestMaxObjectSize(c *C) {
c.Assert(hash.IsZero(), Not(Equals), true)
}
+func (s *EncoderSuite) TestHashNotFound(c *C) {
+ h, err := s.enc.Encode([]plumbing.Hash{plumbing.NewHash("BAD")})
+ c.Assert(h, Equals, plumbing.ZeroHash)
+ c.Assert(err, NotNil)
+ c.Assert(err, Equals, plumbing.ErrObjectNotFound)
+}
+
func (s *EncoderSuite) TestDecodeEncodeDecode(c *C) {
fixtures.Basic().ByTag("packfile").Test(c, func(f *fixtures.Fixture) {
scanner := NewScanner(f.Packfile())
@@ -91,14 +98,16 @@ func (s *EncoderSuite) TestDecodeEncodeDecode(c *C) {
c.Assert(err, IsNil)
c.Assert(ch, Equals, f.PackfileHash)
- commitIter, err := d.o.IterObjects(plumbing.AnyObject)
+ objIter, err := d.o.IterObjects(plumbing.AnyObject)
c.Assert(err, IsNil)
objects := []plumbing.Object{}
hashes := []plumbing.Hash{}
- err = commitIter.ForEach(func(o plumbing.Object) error {
+ err = objIter.ForEach(func(o plumbing.Object) error {
objects = append(objects, o)
hash, err := s.store.SetObject(o)
+ c.Assert(err, IsNil)
+
hashes = append(hashes, hash)
return err
@@ -115,10 +124,10 @@ func (s *EncoderSuite) TestDecodeEncodeDecode(c *C) {
_, err = d.Decode()
c.Assert(err, IsNil)
- commitIter, err = d.o.IterObjects(plumbing.AnyObject)
+ objIter, err = d.o.IterObjects(plumbing.AnyObject)
c.Assert(err, IsNil)
obtainedObjects := []plumbing.Object{}
- err = commitIter.ForEach(func(o plumbing.Object) error {
+ err = objIter.ForEach(func(o plumbing.Object) error {
obtainedObjects = append(obtainedObjects, o)
return nil
@@ -138,3 +147,114 @@ func (s *EncoderSuite) TestDecodeEncodeDecode(c *C) {
c.Assert(len(obtainedObjects), Equals, equals)
})
}
+
+func (s *EncoderSuite) TestDecodeEncodeWithDeltaDecodeREF(c *C) {
+ s.simpleDeltaTest(c, plumbing.REFDeltaObject)
+}
+
+func (s *EncoderSuite) TestDecodeEncodeWithDeltaDecodeOFS(c *C) {
+ s.simpleDeltaTest(c, plumbing.OFSDeltaObject)
+}
+
+func (s *EncoderSuite) TestDecodeEncodeWithDeltasDecodeREF(c *C) {
+ s.deltaOverDeltaTest(c, plumbing.REFDeltaObject)
+}
+
+func (s *EncoderSuite) TestDecodeEncodeWithDeltasDecodeOFS(c *C) {
+ s.deltaOverDeltaTest(c, plumbing.OFSDeltaObject)
+}
+
+func (s *EncoderSuite) simpleDeltaTest(c *C, t plumbing.ObjectType) {
+ srcObject := newObject(plumbing.BlobObject, []byte("0"))
+ targetObject := newObject(plumbing.BlobObject, []byte("01"))
+
+ deltaObject, err := delta(srcObject, targetObject, t)
+ c.Assert(err, IsNil)
+
+ srcToPack := newObjectToPack(srcObject)
+ _, err = s.enc.encode([]*ObjectToPack{
+ srcToPack,
+ newDeltaObjectToPack(srcToPack, targetObject, deltaObject),
+ })
+ c.Assert(err, IsNil)
+
+ scanner := NewScanner(s.buf)
+
+ storage := memory.NewStorage()
+ d, err := NewDecoder(scanner, storage)
+ c.Assert(err, IsNil)
+
+ _, err = d.Decode()
+ c.Assert(err, IsNil)
+
+ decSrc, err := storage.Object(srcObject.Type(), srcObject.Hash())
+ c.Assert(err, IsNil)
+ c.Assert(decSrc, DeepEquals, srcObject)
+
+ decTarget, err := storage.Object(targetObject.Type(), targetObject.Hash())
+ c.Assert(err, IsNil)
+ c.Assert(decTarget, DeepEquals, targetObject)
+}
+
+func (s *EncoderSuite) deltaOverDeltaTest(c *C, t plumbing.ObjectType) {
+ srcObject := newObject(plumbing.BlobObject, []byte("0"))
+ targetObject := newObject(plumbing.BlobObject, []byte("01"))
+ otherTargetObject := newObject(plumbing.BlobObject, []byte("011111"))
+
+ deltaObject, err := delta(srcObject, targetObject, t)
+ c.Assert(err, IsNil)
+ c.Assert(deltaObject.Hash(), Not(Equals), plumbing.ZeroHash)
+
+ otherDeltaObject, err := delta(targetObject, otherTargetObject, t)
+ c.Assert(err, IsNil)
+ c.Assert(otherDeltaObject.Hash(), Not(Equals), plumbing.ZeroHash)
+
+ srcToPack := newObjectToPack(srcObject)
+ targetToPack := newObjectToPack(targetObject)
+ _, err = s.enc.encode([]*ObjectToPack{
+ srcToPack,
+ newDeltaObjectToPack(srcToPack, targetObject, deltaObject),
+ newDeltaObjectToPack(targetToPack, otherTargetObject, otherDeltaObject),
+ })
+ c.Assert(err, IsNil)
+
+ scanner := NewScanner(s.buf)
+ storage := memory.NewStorage()
+ d, err := NewDecoder(scanner, storage)
+ c.Assert(err, IsNil)
+
+ _, err = d.Decode()
+ c.Assert(err, IsNil)
+
+ decSrc, err := storage.Object(srcObject.Type(), srcObject.Hash())
+ c.Assert(err, IsNil)
+ c.Assert(decSrc, DeepEquals, srcObject)
+
+ decTarget, err := storage.Object(targetObject.Type(), targetObject.Hash())
+ c.Assert(err, IsNil)
+ c.Assert(decTarget, DeepEquals, targetObject)
+
+ decOtherTarget, err := storage.Object(otherTargetObject.Type(), otherTargetObject.Hash())
+ c.Assert(err, IsNil)
+ c.Assert(decOtherTarget, DeepEquals, otherTargetObject)
+}
+
+func delta(base, target plumbing.Object, t plumbing.ObjectType) (plumbing.Object, error) {
+ switch t {
+ case plumbing.OFSDeltaObject:
+ return GetOFSDelta(base, target)
+ case plumbing.REFDeltaObject:
+ return GetRefDelta(base, target)
+ default:
+ panic("delta type not found")
+ }
+}
+
+func newObject(t plumbing.ObjectType, cont []byte) plumbing.Object {
+ o := plumbing.MemoryObject{}
+ o.SetType(t)
+ o.SetSize(int64(len(cont)))
+ o.Write(cont)
+
+ return &o
+}