aboutsummaryrefslogblamecommitdiffstats
path: root/storage/filesystem/internal/dotgit/dotgit_test.go
blob: 954eef179acbaed04aab82490696f552c29ce0f9 (plain) (tree)























                                                 
                                    














                                                                                            
















                                                                                          
          






















                                                                                                








                                                                                     
                                                                              





























                                                                 
                                                

































































                                                                                           







                                               









































                                                                               
                                                      


                                         
                                                      

























                                                                                     




































































                                                                                                  





                                                   








                                                                              
package dotgit

import (
	"os"
	"path/filepath"
	"strings"
	"testing"

	"gopkg.in/src-d/go-git.v4/clients/common"
	"gopkg.in/src-d/go-git.v4/core"
	"gopkg.in/src-d/go-git.v4/utils/fs"

	"github.com/alcortesm/tgz"
	. "gopkg.in/check.v1"
)

func Test(t *testing.T) { TestingT(t) }

var initFixtures = [...]struct {
	name         string
	tgz          string
	capabilities [][2]string
	packfile     string
	idxfile      string
	objectfiles  []fixtureObject
}{
	{
		name: "spinnaker",
		tgz:  "fixtures/spinnaker-gc.tgz",
		capabilities: [][2]string{
			{"symref", "HEAD:refs/heads/master"},
		},
		packfile: "objects/pack/pack-584416f86235cac0d54bfabbdc399fb2b09a5269.pack",
		idxfile:  "objects/pack/pack-584416f86235cac0d54bfabbdc399fb2b09a5269.idx",
	}, {
		name: "no-packfile-no-idx",
		tgz:  "fixtures/no-packfile-no-idx.tgz",
	}, {
		name: "empty",
		tgz:  "fixtures/empty-gitdir.tgz",
	}, {
		name: "unpacked",
		tgz:  "fixtures/unpacked-objects-no-packfile-no-idx.tgz",
		objectfiles: []fixtureObject{
			fixtureObject{
				path: "objects/1e/0304e3cb54d0ad612ad70f1f15a285a65a4b8e",
				hash: "1e0304e3cb54d0ad612ad70f1f15a285a65a4b8e",
			},
			fixtureObject{
				path: "objects/5e/fb9bc29c482e023e40e0a2b3b7e49cec842034",
				hash: "5efb9bc29c482e023e40e0a2b3b7e49cec842034",
			},
			fixtureObject{
				path: "objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391",
				hash: "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
			},
		},
	},
	{
		name: "unpacked-dummy",
		tgz:  "fixtures/unpacked-objects-exist-one-dummy-object-no-packfile-no-idx.tgz",
		objectfiles: []fixtureObject{
			fixtureObject{
				path: "objects/1e/0304e3cb54d0ad612ad70f1f15a285a65a4b8e",
				hash: "1e0304e3cb54d0ad612ad70f1f15a285a65a4b8e",
			},
			fixtureObject{
				path: "objects/5e/fb9bc29c482e023e40e0a2b3b7e49cec842034",
				hash: "5efb9bc29c482e023e40e0a2b3b7e49cec842034",
			},
			fixtureObject{
				path: "objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391",
				hash: "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
			},
		},
	},
}

type fixtureObject struct {
	path string
	hash string
}

type fixture struct {
	installDir   string
	fs           fs.FS
	path         string               // repo names to paths of the extracted tgz
	capabilities *common.Capabilities // expected capabilities
	packfile     string               // path of the packfile
	idxfile      string               // path of the idxfile
	objectfiles  []fixtureObject      // path and hash of the object files
}

type SuiteDotGit struct {
	fixtures map[string]fixture
}

var _ = Suite(&SuiteDotGit{})

func (s *SuiteDotGit) SetUpSuite(c *C) {
	s.fixtures = make(map[string]fixture, len(initFixtures))

	for _, init := range initFixtures {
		com := Commentf("fixture name = %s\n", init.name)

		path, err := tgz.Extract(init.tgz)
		c.Assert(err, IsNil, com)

		f := fixture{}

		f.installDir = path
		f.fs = fs.NewOS()
		f.path = f.fs.Join(path, ".git")

		f.capabilities = common.NewCapabilities()
		for _, pair := range init.capabilities {
			f.capabilities.Add(pair[0], pair[1])
		}

		f.packfile = init.packfile
		f.idxfile = init.idxfile
		f.objectfiles = init.objectfiles

		s.fixtures[init.name] = f
	}
}

func (s *SuiteDotGit) TearDownSuite(c *C) {
	for n, f := range s.fixtures {
		err := os.RemoveAll(f.installDir)
		c.Assert(err, IsNil, Commentf("cannot delete tmp dir for fixture %s: %s\n",
			n, f.installDir))
	}
}

func (s *SuiteDotGit) TestNewErrors(c *C) {
	for i, test := range [...]struct {
		input string
		err   error
	}{
		{
			input: "./tmp/foo",
			err:   ErrNotFound,
		}, {
			input: "./tmp/foo/.git",
			err:   ErrNotFound,
		},
	} {
		com := Commentf("subtest %d", i)

		_, err := New(fs.NewOS(), test.input)
		c.Assert(err, Equals, test.err, com)
	}
}

func (s *SuiteDotGit) TestRefsFromPackedRefs(c *C) {
	_, d := s.newFixtureDir(c, "spinnaker")
	refs, err := d.Refs()
	c.Assert(err, IsNil)

	ref := findReference(refs, "refs/tags/v0.37.0")
	c.Assert(ref, NotNil)
	c.Assert(ref.Hash().String(), Equals, "85ec60477681933961c9b64c18ada93220650ac5")

}
func (s *SuiteDotGit) TestRefsFromReferenceFile(c *C) {
	_, d := s.newFixtureDir(c, "spinnaker")
	refs, err := d.Refs()
	c.Assert(err, IsNil)

	ref := findReference(refs, "refs/remotes/origin/HEAD")
	c.Assert(ref, NotNil)
	c.Assert(ref.Type(), Equals, core.SymbolicReference)
	c.Assert(string(ref.Target()), Equals, "refs/remotes/origin/master")

}

func (s *SuiteDotGit) TestRefsFromHEADFile(c *C) {
	_, d := s.newFixtureDir(c, "spinnaker")
	refs, err := d.Refs()
	c.Assert(err, IsNil)

	ref := findReference(refs, "HEAD")
	c.Assert(ref, NotNil)
	c.Assert(ref.Type(), Equals, core.SymbolicReference)
	c.Assert(string(ref.Target()), Equals, "refs/heads/master")
}

func (s *SuiteDotGit) TestConfig(c *C) {
	_, d := s.newFixtureDir(c, "spinnaker")
	fs, path, err := d.Config()
	c.Assert(err, IsNil)
	c.Assert(fs, NotNil)
	c.Assert(path, Not(Equals), "")
}

func findReference(refs []*core.Reference, name string) *core.Reference {
	n := core.ReferenceName(name)
	for _, ref := range refs {
		if ref.Name() == n {
			return ref
		}
	}

	return nil
}

func (s *SuiteDotGit) newFixtureDir(c *C, fixName string) (*fixture, *DotGit) {
	f, ok := s.fixtures[fixName]
	c.Assert(ok, Equals, true)

	d, err := New(fs.NewOS(), f.path)
	c.Assert(err, IsNil)

	return &f, d
}

func (s *SuiteDotGit) TestPackfile(c *C) {
	packfile := func(d *DotGit) (fs.FS, string, error) {
		return d.Packfile()
	}
	idxfile := func(d *DotGit) (fs.FS, string, error) {
		return d.Idxfile()
	}
	for _, test := range [...]struct {
		fixture string
		fn      getPathFn
		err     string // error regexp
	}{
		{
			fixture: "spinnaker",
			fn:      packfile,
		}, {
			fixture: "spinnaker",
			fn:      idxfile,
		}, {
			fixture: "empty",
			fn:      packfile,
			err:     "packfile not found",
		}, {
			fixture: "empty",
			fn:      idxfile,
			err:     "idx file not found",
		}, {
			fixture: "no-packfile-no-idx",
			fn:      packfile,
			err:     "packfile not found",
		}, {
			fixture: "no-packfile-no-idx",
			fn:      idxfile,
			err:     "idx file not found",
		},
	} {
		com := Commentf("fixture = %s", test.fixture)

		fix, dir := s.newFixtureDir(c, test.fixture)

		_, path, err := test.fn(dir)

		if test.err != "" {
			c.Assert(err, ErrorMatches, test.err, com)
		} else {
			c.Assert(err, IsNil, com)
			c.Assert(strings.HasSuffix(noExt(path), noExt(fix.packfile)),
				Equals, true, com)
		}
	}
}

func (s *SuiteDotGit) TestObjectfiles(c *C) {
	for _, test := range [...]struct {
		fixture string
		err     error
	}{
		{
			fixture: "unpacked",
		},
		{
			fixture: "unpacked-dummy",
		}, {
			fixture: "empty",
			err:     ErrObjfileNotFound,
		}, {
			fixture: "no-packfile-no-idx",
		},
	} {
		com := Commentf("fixture = %s", test.fixture)

		fix, dir := s.newFixtureDir(c, test.fixture)

		_, hashes, err := dir.Objectfiles()

		if test.err != nil {
			c.Assert(err, Equals, test.err, com)
		} else {
			c.Assert(err, IsNil, com)
			c.Assert(len(hashes), Equals, len(fix.objectfiles), com)

			for _, hash := range hashes {
				c.Assert(containsObject(fix.objectfiles, hash), Equals, true, com)
			}
		}
	}
}

func (s *SuiteDotGit) TestObjectfile(c *C) {
	for _, test := range [...]struct {
		fixture string
		err     error
	}{
		{
			fixture: "unpacked",
		}, {
			fixture: "empty",
			err:     ErrObjfileNotFound,
		}, {
			fixture: "no-packfile-no-idx",
			err:     ErrObjfileNotFound,
		},
	} {
		com := Commentf("fixture = %s", test.fixture)

		fix, dir := s.newFixtureDir(c, test.fixture)

		for _, fixObj := range fix.objectfiles {
			_, path, err := dir.Objectfile(core.NewHash(fixObj.hash))

			if test.err != nil {
				c.Assert(err, Equals, test.err, com)
			} else {
				c.Assert(err, IsNil, com)
				c.Assert(strings.HasSuffix(path, fixObj.path),
					Equals, true, com)
			}
		}
	}
}

type getPathFn func(*DotGit) (fs.FS, string, error)

func noExt(path string) string {
	ext := filepath.Ext(path)
	return path[0 : len(path)-len(ext)]
}

func containsObject(objs []fixtureObject, hash core.Hash) bool {
	for _, o := range objs {
		if strings.ToLower(o.hash) == strings.ToLower(hash.String()) {
			return true
		}
	}
	return false
}