func TestAufsPlacerCompliance(t *testing.T) { Convey("Aufs placers make data appear into place", t, testutil.Requires( testutil.RequiresMounts, testutil.WithTmpdir(func() { CheckAssemblerGetsDataIntoPlace(defaultAssembler{Placer: NewAufsPlacer("./aufs-layers")}.Assemble) }), ), ) Convey("Aufs placers support readonly placement", t, testutil.Requires( testutil.RequiresMounts, testutil.WithTmpdir(func() { CheckAssemblerRespectsReadonly(defaultAssembler{Placer: NewAufsPlacer("./aufs-layers")}.Assemble) }), ), ) Convey("Aufs placers support source isolation", t, testutil.Requires( testutil.RequiresMounts, testutil.WithTmpdir(func() { CheckAssemblerIsolatesSource(defaultAssembler{Placer: NewAufsPlacer("./aufs-layers")}.Assemble) }), ), ) }
func Test(t *testing.T) { // uncomment for an example output // Convey("Describe fixture Beta", t, func() { // Println() // goconvey seems to do alignment rong in cli out of box :I // Println(Beta.Describe(CompareAll)) // }) Convey("All fixtures should be able to apply their content to an empty dir", t, testutil.Requires( testutil.RequiresRoot, testutil.WithTmpdir(func() { for _, fixture := range All { Convey(fmt.Sprintf("- Fixture %q", fixture.Name), func() { fixture.Create(".") So(true, ShouldBeTrue) // reaching here is success }) } }), ), ) Convey("Applying a fixture and rescanning it should produce identical descriptions", t, testutil.Requires( testutil.RequiresRoot, testutil.WithTmpdir(func() { for _, fixture := range All { Convey(fmt.Sprintf("- Fixture %q", fixture.Name), func() { fixture.Create(".") reheat := Scan(".") So(reheat.Describe(CompareDefaults), ShouldEqual, fixture.Describe(CompareDefaults)) }) } }), ), ) Convey("Symlink breakouts should be refuted", t, FailureContinues, testutil.Requires( testutil.RequiresRoot, testutil.WithTmpdir(func() { // this is a sketchy, unsandboxed test. // I hope you don't have anything in /tmp/dangerzone, and/or that you're running the entire suite in a vm. os.RemoveAll("/tmp/dangerzone") Convey("With a relative basepath", func() { So(func() { Breakout.Create(".") }, testutil.ShouldPanicWith, fs.BreakoutError) _, err := os.Stat("/tmp/dangerzone/laaaaanaaa") So(err, ShouldNotBeNil) // if nil err, oh my god, it exists }) Convey("With an absolute basepath", func() { pwd, err := os.Getwd() So(err, ShouldBeNil) So(func() { Breakout.Create(pwd) }, testutil.ShouldPanicWith, fs.BreakoutError) _, err = os.Stat("/tmp/dangerzone/laaaaanaaa") So(err, ShouldNotBeNil) // if nil err, oh my god, it exists }) }), ), ) }
func TestBindPlacerCompliance(t *testing.T) { Convey("Bind placers make data appear into place", t, testutil.Requires( testutil.RequiresMounts, func() { CheckAssemblerGetsDataIntoPlace(defaultAssembler{Placer: BindPlacer}.Assemble) }, ), ) Convey("Bind placers support readonly placement", t, testutil.Requires( testutil.RequiresMounts, func() { CheckAssemblerRespectsReadonly(defaultAssembler{Placer: BindPlacer}.Assemble) }, ), ) // Not Supported: CheckAssemblerIsolatesSource // (use AufsPlacer for that) }
func Test(t *testing.T) { Convey("Spec Compliance: Chroot Executor", t, testutil.Requires( testutil.RequiresRoot, testutil.WithTmpdir(func() { execEng := &Executor{} execEng.Configure("chroot_workspace") So(os.Mkdir(execEng.workspacePath, 0755), ShouldBeNil) tests.CheckBasicExecution(execEng) tests.CheckFilesystemContainment(execEng) tests.CheckPwdBehavior(execEng) tests.CheckEnvBehavior(execEng) }), ), ) }
func TestTarOutputCompat(t *testing.T) { Convey("Output should produce a tar recognizable to gnu tar", t, testutil.Requires( testutil.RequiresRoot, testutil.WithTmpdir(func() { for _, fixture := range filefixture.All { Convey(fmt.Sprintf("- Fixture %q", fixture.Name), func() { // create fixture fixture.Create("./data") // scan it transmat := New("./workdir") transmat.Scan( Kind, "./data", []integrity.SiloURI{ integrity.SiloURI("file://output.tar"), }, ) // sanity check that there's a file. So("./output.tar", testutil.ShouldBeFile, os.FileMode(0)) // now exec tar, and check that it doesn't barf outright. // this is not well isolated from the host; consider improving that a todo. os.Mkdir("./untar", 0755) tarProc := gosh.Gosh( "tar", "-xf", "./output.tar", "-C", "./untar", gosh.NullIO, ).RunAndReport() So(tarProc.GetExitCode(), ShouldEqual, 0) // should look roughly the same again even bounced through // some third-party tar implementation, one would hope. rescan := filefixture.Scan("./untar") comparisonLevel := filefixture.CompareDefaults &^ filefixture.CompareSubsecond So(rescan.Describe(comparisonLevel), ShouldEqual, fixture.Describe(comparisonLevel)) }) } }), ), ) }
func Test(t *testing.T) { Convey("Spec Compliance: nsinit Executor", t, testutil.Requires( testutil.RequiresRoot, testutil.RequiresNamespaces, testutil.WithTmpdir(func() { execEng := &Executor{} execEng.Configure("nsinit_workspace") So(os.Mkdir(execEng.workspacePath, 0755), ShouldBeNil) //tests.CheckBasicExecution(execEng) // correct error reporting sections fail spec compliance tests.CheckFilesystemContainment(execEng) //tests.CheckPwdBehavior(execEng) // correct error reporting sections fail spec compliance tests.CheckEnvBehavior(execEng) }), ), ) }
func CheckAssemblerIsolatesSource(assemblerFn integrity.Assembler) { Convey("Writing to a placement should not alter the source", testutil.Requires( testutil.RequiresRoot, testutil.WithTmpdir(func() { filefixture.Alpha.Create("./material/alpha") assembly := assemblerFn("./assembled", []integrity.AssemblyPart{ {TargetPath: "/", SourcePath: "./material/alpha", Writable: true}, }) defer assembly.Teardown() f, err := os.OpenFile("./assembled/newfile", os.O_CREATE, 0644) defer f.Close() So(err, ShouldBeNil) scan := filefixture.Scan("./material/alpha") So(scan.Describe(filefixture.CompareDefaults), ShouldEqual, filefixture.Alpha.Describe(filefixture.CompareDefaults)) }), ), ) }
func CheckAssemblerRespectsReadonly(assemblerFn integrity.Assembler) { Convey("Writing to a readonly placement should return EROFS", testutil.Requires( testutil.RequiresRoot, testutil.WithTmpdir(func() { filefixture.Alpha.Create("./material/alpha") assembly := assemblerFn("./assembled", []integrity.AssemblyPart{ {TargetPath: "/", SourcePath: "./material/alpha", Writable: false}, }) defer assembly.Teardown() f, err := os.OpenFile("./assembled/newfile", os.O_CREATE, 0644) defer f.Close() So(err, ShouldNotBeNil) So(err, ShouldHaveSameTypeAs, &os.PathError{}) So(err.(*os.PathError).Err, ShouldEqual, syscall.EROFS) }), ), ) }
func CheckScanWithoutMutation(kind integrity.TransmatKind, transmatFabFn integrity.TransmatFactory) { Convey("SPEC: Scanning a filesystem shouldn't change it", testutil.Requires( testutil.RequiresRoot, func() { for _, fixture := range filefixture.All { transmat := transmatFabFn("./workdir") Convey(fmt.Sprintf("- Fixture %q", fixture.Name), func() { // set up fixture fixture.Create("./data") // scan it with the transmat transmat.Scan(kind, "./data", nil) // rescan it with the test system rescan := filefixture.Scan("./data") // should be unchanged So(rescan.Describe(filefixture.CompareDefaults), ShouldEqual, fixture.Describe(filefixture.CompareDefaults)) }) } }, )) }
func Test(t *testing.T) { // Run from the top-level directory to avoid "../" irritants. // Optional TODO: upgrade repeatr to understand how to be relative to a directory. err := os.Chdir("..") if err != nil { panic(err) } Convey("It should not crash without args", t, func() { Main(baseArgs, ioutil.Discard, ioutil.Discard) }) Convey("It should run a basic example", t, testutil.Requires( testutil.RequiresRoot, testutil.RequiresNamespaces, func(c C) { w := testutil.Writer{c} Main(append(baseArgs, "run", "-i", "lib/integration/unittest.json"), w, w) }, ), ) }
// you probs want to create that assembler with a variety of placers func CheckAssemblerGetsDataIntoPlace(assemblerFn integrity.Assembler) { Convey("Assembly with just a root fs works", testutil.Requires( testutil.RequiresRoot, testutil.WithTmpdir(func() { filefixture.Alpha.Create("./material/alpha") assembleAndScan( assemblerFn, []integrity.AssemblyPart{ {TargetPath: "/", SourcePath: "./material/alpha"}, }, filefixture.Alpha, ) }), ), ) Convey("Assembly with one placement into an existing dir works", testutil.Requires( testutil.RequiresRoot, testutil.WithTmpdir(func() { filefixture.Alpha.Create("./material/alpha") filefixture.Beta.Create("./material/beta") assembleAndScan( assemblerFn, []integrity.AssemblyPart{ {TargetPath: "/", SourcePath: "./material/alpha", Writable: true}, {TargetPath: "/a", SourcePath: "./material/beta", Writable: true}, }, filefixture.ConjoinFixtures([]filefixture.FixtureAssemblyPart{ {TargetPath: "/", Fixture: filefixture.Alpha}, {TargetPath: "/a", Fixture: filefixture.Beta}, }), ) }), ), ) Convey("Assembly with one placement into an implicitly-created dir works", testutil.Requires( testutil.RequiresRoot, testutil.WithTmpdir(func() { filefixture.Alpha.Create("./material/alpha") filefixture.Beta.Create("./material/beta") assembleAndScan( assemblerFn, []integrity.AssemblyPart{ {TargetPath: "/", SourcePath: "./material/alpha", Writable: true}, {TargetPath: "/q", SourcePath: "./material/beta", Writable: true}, }, filefixture.ConjoinFixtures([]filefixture.FixtureAssemblyPart{ {TargetPath: "/", Fixture: filefixture.Alpha}, {TargetPath: "/q", Fixture: filefixture.Beta}, }), ) }), ), ) Convey("Assembly with overlapping placements shows only top layer", testutil.Requires( testutil.RequiresRoot, testutil.WithTmpdir(func() { filefixture.Alpha.Create("./material/alpha") filefixture.Beta.Create("./material/beta") assembleAndScan( assemblerFn, []integrity.AssemblyPart{ {TargetPath: "/", SourcePath: "./material/alpha", Writable: true}, // this one's interesting because ./b/c is already a file {TargetPath: "/b", SourcePath: "./material/beta", Writable: true}, }, filefixture.ConjoinFixtures([]filefixture.FixtureAssemblyPart{ {TargetPath: "/", Fixture: filefixture.Alpha}, {TargetPath: "/b", Fixture: filefixture.Beta}, }), ) }), ), ) Convey("Assembly using the same base twice works", testutil.Requires( testutil.RequiresRoot, testutil.WithTmpdir(func() { filefixture.Alpha.Create("./material/alpha") filefixture.Beta.Create("./material/beta") assembleAndScan( assemblerFn, []integrity.AssemblyPart{ {TargetPath: "/", SourcePath: "./material/alpha", Writable: true}, {TargetPath: "/q", SourcePath: "./material/beta", Writable: true}, {TargetPath: "/w", SourcePath: "./material/beta", Writable: true}, }, filefixture.ConjoinFixtures([]filefixture.FixtureAssemblyPart{ {TargetPath: "/", Fixture: filefixture.Alpha}, {TargetPath: "/q", Fixture: filefixture.Beta}, {TargetPath: "/w", Fixture: filefixture.Beta}, }), ) }), ), ) Convey("Assembly with implicitly created deep dirs works", testutil.Requires( testutil.RequiresRoot, testutil.WithTmpdir(func() { filefixture.Alpha.Create("./material/alpha") filefixture.Beta.Create("./material/beta") assembleAndScan( assemblerFn, []integrity.AssemblyPart{ {TargetPath: "/", SourcePath: "./material/alpha", Writable: true}, {TargetPath: "/a", SourcePath: "./material/beta", Writable: true}, {TargetPath: "/d/d/d", SourcePath: "./material/beta", Writable: true}, }, filefixture.Fixture{Files: []filefixture.FixtureFile{ {fs.Metadata{Name: ".", Mode: 0755, ModTime: time.Unix(1000, 2000)}, nil}, // even though the basedir was made by the assembler, this should have the rootfs's properties overlayed onto it {fs.Metadata{Name: "./a"}, nil}, // this one's mode and times should be overlayed by the second mount {fs.Metadata{Name: "./a/1"}, []byte{}}, {fs.Metadata{Name: "./a/2"}, []byte{}}, {fs.Metadata{Name: "./a/3"}, []byte{}}, {fs.Metadata{Name: "./b", Mode: 0750, ModTime: time.Unix(5000, 2000)}, nil}, {fs.Metadata{Name: "./b/c", Mode: 0664, ModTime: time.Unix(7000, 2000)}, []byte("zyx")}, {fs.Metadata{Name: "./d", Uid: -1, Gid: -1}, nil}, // these should have been manifested by the assembler {fs.Metadata{Name: "./d/d", Uid: -1, Gid: -1}, nil}, {fs.Metadata{Name: "./d/d/d"}, nil}, {fs.Metadata{Name: "./d/d/d/1"}, []byte{}}, {fs.Metadata{Name: "./d/d/d/2"}, []byte{}}, {fs.Metadata{Name: "./d/d/d/3"}, []byte{}}, }}.Defaults(), ) }), ), ) // additional coverage todos: // - failure path: placement that overlaps a file somewhere // - everything about changes and ensuring they're isolated... deserves a whole battery }
/* Checks round-trip hash consistency for the input and output halves of a transmat system. - Creates a fixture filesystem - Scans it with the output system - Places it in a new filesystem with the input system and the scanned hash - Checks the new filesystem matches the original */ func CheckRoundTrip(kind integrity.TransmatKind, transmatFabFn integrity.TransmatFactory, bounceURI string, addtnlDesc ...string) { Convey("SPEC: Round-trip scanning and remaking a filesystem should agree on hash and content"+testutil.AdditionalDescription(addtnlDesc...), testutil.Requires( testutil.RequiresRoot, func() { transmat := transmatFabFn("./workdir") for _, fixture := range filefixture.All { Convey(fmt.Sprintf("- Fixture %q", fixture.Name), FailureContinues, func() { uris := []integrity.SiloURI{integrity.SiloURI(bounceURI)} // setup fixture fixture.Create("./fixture") // scan it with the transmat dataHash := transmat.Scan(kind, "./fixture", uris) // materialize what we just scanned (along the way, requires hash match) arena := transmat.Materialize(kind, dataHash, uris, integrity.AcceptHashMismatch) // assert hash match // (normally survival would attest this, but we used the `AcceptHashMismatch` to supress panics in the name of letting the test see more after failures.) So(arena.Hash(), ShouldEqual, dataHash) // check filesystem to match original fixture // (do this check even if the input raised a hash mismatch, because it can help show why) rescan := filefixture.Scan(arena.Path()) comparisonLevel := filefixture.CompareDefaults &^ filefixture.CompareSubsecond So(rescan.Describe(comparisonLevel), ShouldEqual, fixture.Describe(comparisonLevel)) }) } }, )) }
func TestGitLocalFileInputCompat(t *testing.T) { // note that this test eschews use of regular file fixtures for a few reasons: // - because it's capable of working without root if it doesn't try to chown // - because we're doing custom content anyway so we have multiple commits // both of these could be addressed with upgrades to filefixtures in the future. Convey("Given a local git repo", t, testutil.Requires( testutil.WithTmpdir(func() { git := git.Bake(gosh.Opts{Env: map[string]string{ "GIT_AUTHOR_NAME": "repeatr", "GIT_AUTHOR_EMAIL": "repeatr", "GIT_COMMITTER_NAME": "repeatr", "GIT_COMMITTER_EMAIL": "repeatr", }}) var dataHash_1 integrity.CommitID var dataHash_2 integrity.CommitID var dataHash_3 integrity.CommitID git.Bake("init", "--", "repo-a").RunAndReport() testutil.UsingDir("repo-a", func() { git.Bake("commit", "--allow-empty", "-m", "testrepo-a initial commit").RunAndReport() dataHash_1 = integrity.CommitID(strings.Trim(git.Bake("rev-parse", "HEAD").Output(), "\n")) ioutil.WriteFile("file-a", []byte("abcd"), 0644) git.Bake("add", ".").RunAndReport() git.Bake("commit", "-m", "testrepo-a commit 1").RunAndReport() dataHash_2 = integrity.CommitID(strings.Trim(git.Bake("rev-parse", "HEAD").Output(), "\n")) ioutil.WriteFile("file-e", []byte("efghi"), 0644) git.Bake("add", ".").RunAndReport() git.Bake("commit", "-m", "testrepo-a commit 2").RunAndReport() dataHash_3 = integrity.CommitID(strings.Trim(git.Bake("rev-parse", "HEAD").Output(), "\n")) }) transmat := New("./workdir") Convey("Materialization should be able to produce the latest commit", FailureContinues, func() { uris := []integrity.SiloURI{integrity.SiloURI("./repo-a")} // materialize from the ID returned by foreign git arena := transmat.Materialize(Kind, dataHash_3, uris, integrity.AcceptHashMismatch) // assert hash match // (normally survival would attest this, but we used the `AcceptHashMismatch` to supress panics in the name of letting the test see more after failures.) So(arena.Hash(), ShouldEqual, dataHash_3) // check filesystem to loosely match the original fixture So(filepath.Join(arena.Path(), "file-a"), testutil.ShouldBeFile) So(filepath.Join(arena.Path(), "file-e"), testutil.ShouldBeFile) So(filepath.Join(arena.Path(), ".git"), testutil.ShouldBeNotFile) }) Convey("Materialization should be able to produce older commits", FailureContinues, func() { uris := []integrity.SiloURI{integrity.SiloURI("./repo-a")} // materialize from the ID returned by foreign git arena := transmat.Materialize(Kind, dataHash_2, uris, integrity.AcceptHashMismatch) // assert hash match // (normally survival would attest this, but we used the `AcceptHashMismatch` to supress panics in the name of letting the test see more after failures.) So(arena.Hash(), ShouldEqual, dataHash_2) // check filesystem to loosely match the original fixture So(filepath.Join(arena.Path(), "file-a"), testutil.ShouldBeFile) So(filepath.Join(arena.Path(), "file-e"), testutil.ShouldBeNotFile) So(filepath.Join(arena.Path(), ".git"), testutil.ShouldBeNotFile) }) })), ) // TODO you really should do this with a fixture loop // but that does also leave questions about multi-commits, branches, etc. // so do both i guess. //filefixture.Beta.Create("repo-a") }
func TestTarInputCompat(t *testing.T) { projPath, _ := os.Getwd() projPath = filepath.Dir(filepath.Dir(filepath.Dir(projPath))) Convey("Unpacking tars should match exec untar", t, testutil.Requires(testutil.RequiresRoot, testutil.WithTmpdir(func() { checkEquivalence := func(hash, filename string, paveBase bool) { transmat := New("./workdir/tar") // apply it; hope it doesn't blow up arena := transmat.Materialize( integrity.TransmatKind("tar"), integrity.CommitID(hash), []integrity.SiloURI{ integrity.SiloURI("file://" + filename), }, ) defer arena.Teardown() // do a native untar; since we don't have an upfront fixture // for this thing, we'll compare the two as filesystems. // this is not well isolated from the host; consider improving that a todo. os.Mkdir("./untar", 0755) tarProc := gosh.Gosh( "tar", "-xf", filename, "-C", "./untar", gosh.NullIO, ).RunAndReport() So(tarProc.GetExitCode(), ShouldEqual, 0) // native untar may or may not have an opinion about the base dir, depending on how it was formed. // but our scans do, so, if the `paveBase` flag was set to warn us that the tar was missing an "./" entry, flatten that here. if paveBase { So(fspatch.LUtimesNano("./untar", def.Epochwhen, def.Epochwhen), ShouldBeNil) } // scan and compare scan1 := filefixture.Scan(arena.Path()) scan2 := filefixture.Scan("./untar") // boy, that's entertaining though: gnu tar does all the same stuff, // except it doesn't honor our nanosecond timings. // also exclude bodies because they're *big*. comparisonLevel := filefixture.CompareDefaults &^ filefixture.CompareSubsecond &^ filefixture.CompareBody So(scan1.Describe(comparisonLevel), ShouldEqual, scan2.Describe(comparisonLevel)) } Convey("Given a fixture tarball complete with base dir", func() { checkEquivalence( "BX0jm4jRNCg1KMbZfv4zp7ZaShx9SUXKaDrO-Xy6mWIoWOCFP5VnDHDDR3nU4PrR", filepath.Join(projPath, "data/fixture/tar_withBase.tgz"), false, ) }) Convey("Given a fixture tarball lacking base dir", func() { checkEquivalence( "ZdV3xhCGWeJmsfeHpDF4nF9stwvdskYwcepKMcOf7a2ziax1YGjQvGTJjRWFkvG1", filepath.Join(projPath, "data/fixture/tar_sansBase.tgz"), true, ) }) Convey("Given a fixture tarball containing ubuntu", testutil.Requires(testutil.RequiresLongRun, func() { checkEquivalence( ubuntuTarballHash, filepath.Join(projPath, "assets/ubuntu.tar.gz"), true, ) }), ) })), ) Convey("Bouncing unusual tars should match hash", t, // where really all "unusual" means is "valid tar, but not from our own cannonical output". testutil.Requires( testutil.RequiresRoot, testutil.WithTmpdir(func() { checkBounce := func(hash, filename string) { transmat := New("./workdir/tar") // apply it; hope it doesn't blow up arena := transmat.Materialize( integrity.TransmatKind("tar"), integrity.CommitID(hash), []integrity.SiloURI{ integrity.SiloURI("file://" + filename), }, ) defer arena.Teardown() // scan and compare commitID := transmat.Scan(integrity.TransmatKind("tar"), arena.Path(), nil) // debug: gosh.Sh("tar", "--utc", "-xOvf", filename) So(commitID, ShouldEqual, integrity.CommitID(hash)) } Convey("Given a fixture tarball complete with base dir", func() { checkBounce( "BX0jm4jRNCg1KMbZfv4zp7ZaShx9SUXKaDrO-Xy6mWIoWOCFP5VnDHDDR3nU4PrR", filepath.Join(projPath, "data/fixture/tar_withBase.tgz"), ) }) Convey("Given a fixture tarball lacking base dir", func() { checkBounce( "ZdV3xhCGWeJmsfeHpDF4nF9stwvdskYwcepKMcOf7a2ziax1YGjQvGTJjRWFkvG1", filepath.Join(projPath, "data/fixture/tar_sansBase.tgz"), ) }) // this won't fly until we support hardlinks; the original asset uses them. // Convey("Given a fixture tarball containing ubuntu", // testutil.Requires(testutil.RequiresLongRun, func() { // checkBounce( // ubuntuTarballHash, // filepath.Join(projPath, "assets/ubuntu.tar.gz"), // ) // }), // ) }), ), ) }
func CheckScanWithFilters(kind integrity.TransmatKind, transmatFabFn integrity.TransmatFactory) { Convey("SPEC: Filesystems only differing by mtime should have same hash after mtime filter", testutil.Requires( testutil.RequiresRoot, func() { transmat := transmatFabFn("./workdir") // set up fixtures filefixture.Alpha.Create("./alpha1") filefixture.Alpha.Create("./alpha2") // overwrite the time on one of them -- can be nonconstant value, even; that's sorta the point. So(os.Chtimes("./alpha2/a", time.Now(), time.Now()), ShouldBeNil) // set up a filter. can set their times to anything, as long as its the same filt := filter.MtimeFilter{time.Unix(1000000, 9000)} // scan both filesystems with the transmat commitID1 := transmat.Scan(kind, "./alpha1", nil, integrity.UseFilter(filt)) commitID2 := transmat.Scan(kind, "./alpha2", nil, integrity.UseFilter(filt)) // should be same So(commitID2, ShouldEqual, commitID1) }), ) Convey("SPEC: Filesystems only differing by uid/gid should have same hash after filter", testutil.Requires( testutil.RequiresRoot, func() { transmat := transmatFabFn("./workdir") // set up fixtures filefixture.Alpha.Create("./alpha1") filefixture.Alpha.Create("./alpha2") // overwrite the time on one of them -- can be nonconstant value, even; that's sorta the point. So(os.Chown("./alpha2/a", 908234, 20954), ShouldBeNil) // set up a filter. can set their times to anything, as long as its the same ufilt := filter.UidFilter{10401} gfilt := filter.GidFilter{10401} // scan both filesystems with the transmat commitID1 := transmat.Scan(kind, "./alpha1", nil, integrity.UseFilter(ufilt), integrity.UseFilter(gfilt)) commitID2 := transmat.Scan(kind, "./alpha2", nil, integrity.UseFilter(ufilt), integrity.UseFilter(gfilt)) // should be same So(commitID2, ShouldEqual, commitID1) }), ) }
func CheckScanProducesDistinctHashes(kind integrity.TransmatKind, transmatFabFn integrity.TransmatFactory) { Convey("SPEC: Applying the output to two different filesystems should produce different hashes", testutil.Requires( testutil.RequiresRoot, func() { transmat := transmatFabFn("./workdir") // set up fixtures filefixture.Alpha.Create("./alpha") filefixture.Beta.Create("./beta") // scan both filesystems with the transmat commitID1 := transmat.Scan(kind, "./alpha", nil) commitID2 := transmat.Scan(kind, "./beta", nil) // should be distinct So(commitID2, ShouldNotEqual, commitID1) }), ) }
func CheckScanProducesConsistentHash(kind integrity.TransmatKind, transmatFabFn integrity.TransmatFactory) { Convey("SPEC: Applying the output to a filesystem twice should produce the same hash", testutil.Requires( testutil.RequiresRoot, func() { for _, fixture := range filefixture.All { transmat := transmatFabFn("./workdir") Convey(fmt.Sprintf("- Fixture %q", fixture.Name), func() { // set up fixture fixture.Create("./data") // scan it with the transmat commitID1 := transmat.Scan(kind, "./data", nil) // scan it with again commitID2 := transmat.Scan(kind, "./data", nil) // should be same output So(commitID2, ShouldEqual, commitID1) }) } }, )) }