Beispiel #1
0
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
				})
			}),
		),
	)
}
Beispiel #3
0
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)
			}),
		),
	)
}
Beispiel #5
0
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)
			}),
		),
	)
}
Beispiel #7
0
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))
			}),
		),
	)
}
Beispiel #8
0
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)
			}),
		),
	)
}
Beispiel #9
0
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))
				})
			}
		},
	))
}
Beispiel #10
0
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)
			},
		),
	)
}
Beispiel #11
0
// 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
}
Beispiel #12
0
/*
	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))
				})
			}
		},
	))
}
Beispiel #13
0
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")
}
Beispiel #14
0
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"),
				//			)
				//		}),
				//	)
			}),
		),
	)
}
Beispiel #15
0
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)
		}),
	)
}
Beispiel #16
0
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)
		}),
	)
}
Beispiel #17
0
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)
				})
			}
		},
	))
}