package buildstep import ( "bytes" "crypto/sha256" "encoding/hex" "os" "path/filepath" "testing" "time" ) // fixture writes three files in two directories (modes 0644 and 0755). func fixture(t *testing.T) string { t.Helper() root := t.TempDir() for _, f := range []struct { p string mode os.FileMode body string }{{"a/x.txt", 0o644, "x\n"}, {"a/run.sh", 0o755, "#!/bin/sh\necho hi\n"}, {"b/c/y.txt", 0o644, "why\n"}} { path := filepath.Join(root, f.p) if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil { t.Fatal(err) } if err := os.WriteFile(path, []byte(f.body), f.mode); err != nil { t.Fatal(err) } if err := os.Chmod(path, f.mode); err != nil { t.Fatal(err) } } return root } // 1479/AC1: the archive equals the bytes mesh-controller's pack makes for this tree. testdata/pack-golden.tar.gz // was made once by running mesh-controller internal/builder/builder.go pack (origin/main 073ccc29, :1351-1425) // on this fixture (fixture above, modes set by chmod). func TestPackEqualsTheBuildAgentsArchive(t *testing.T) { golden, err := os.ReadFile("testdata/pack-golden.tar.gz") if err != nil { t.Fatal(err) } archive, digest, err := Pack(fixture(t)) if err != nil { t.Fatal(err) } if !bytes.Equal(archive, golden) { t.Errorf("the archive is %d bytes, the build agent's %d, and they differ", len(archive), len(golden)) } sum := sha256.Sum256(golden) if digest != "sha256:"+hex.EncodeToString(sum[:]) { t.Errorf("digest = %s", digest) } } // 1479/AC2: touching every file's time changes nothing. func TestPackDigestIgnoresFileTimes(t *testing.T) { root := fixture(t) _, first, err := Pack(root) if err != nil { t.Fatal(err) } later := time.Now().Add(48 * time.Hour) filepath.Walk(root, func(p string, _ os.FileInfo, _ error) error { return os.Chtimes(p, later, later) }) if _, second, err := Pack(root); err != nil || second != first { t.Errorf("digests %s and %s (%v)", first, second, err) } }