Skip to content
quarry Artifact [045ca1f3ae]
Login

Artifact [045ca1f3ae]

Artifact 045ca1f3ae7f006c269c6cf303fb1e0b733131ee250ec0621018fb1442cd7986:


package artifact

import "testing"

// A check-in in a sub-manifest store lists S cards where a flat one
// lists F, as every check-in of netbsd-src does. It is a manifest: read
// as one, the fold skips it without a parse, as it skips flat ones.
func TestAnSCardCheckinIsAManifest(t *testing.T) {
	raw := []byte("C initial\\simport\n" +
		"D 1993-03-21T09:45:37\n" +
		"P 97a86ea938482eb15026533cdc560ca53c2e9039424db7747f2eb136f8f4d05e\n" +
		"S Makefile 149872c845b50c8f542cd729ab2bae46cbd5f487f7c09fcf8a61e7cf6c324fe7\n" +
		"U dmestas\n" +
		"Z 00000000000000000000000000000000\n")
	isM, decided := QuickIsManifest(raw)
	if !decided || !isM {
		t.Errorf("FAIL: an S-card check-in read as manifest=%v decided=%v", isM, decided)
	}
}

// A tree check-in parses as the manifest it is: header, parents and the
// S run it lists in place of F cards. Refused, it fell to content and
// the live fold never saw the check-in (quarry ticket 431).
func TestAnSCardCheckinParses(t *testing.T) {
	a := parseOK(t, "C tree\\scheck-in\n"+
		"D 2026-11-12T10:00:00\n"+
		"P "+h64+"\n"+
		"S alpha/a.c "+h40+"\n"+
		"S beta/b.c "+h64+"\n"+
		"T *branch * trunk\n"+
		"U ana\n")
	if a.Type != Manifest {
		t.Fatalf("FAIL: type %v, want a manifest", a.Type)
	}
	if a.Comment != "tree check-in" || a.Date != "2026-11-12T10:00:00" || a.User != "ana" ||
		len(a.Parents) != 1 || a.Parents[0] != h64 || len(a.Tags) != 1 {
		t.Errorf("FAIL: header read as %+v", a)
	}
	want := []File{{Name: "alpha/a.c", Hash: h40}, {Name: "beta/b.c", Hash: h64}}
	if len(a.SubManifests) != 2 || a.SubManifests[0] != want[0] || a.SubManifests[1] != want[1] {
		t.Errorf("FAIL: S run read as %+v, want %+v", a.SubManifests, want)
	}
	if len(a.Files) != 0 {
		t.Errorf("FAIL: S cards read as F cards: %+v", a.Files)
	}
	if !t.Failed() {
		t.Log("ok")
	}
}

// A D-less node of the tree is a sub-manifest, interior (S) or leaf (F),
// never a check-in.
func TestATreeNodeIsASubManifest(t *testing.T) {
	interior := parseOK(t, "S alpha/a.c "+h40+"\nS beta/b.c "+h64+"\n")
	if interior.Type != SubManifest || len(interior.SubManifests) != 2 {
		t.Errorf("FAIL: interior node read as %v with %d S cards", interior.Type, len(interior.SubManifests))
	}
	leaf := parseOK(t, "F alpha/a.c "+h40+"\nF alpha/b.c "+h64+" x\n")
	if leaf.Type != SubManifest || len(leaf.Files) != 2 || leaf.Files[1].Perm != "x" {
		t.Errorf("FAIL: leaf node read as %v with files %+v", leaf.Type, leaf.Files)
	}
	if !t.Failed() {
		t.Log("ok")
	}
}

func TestSubManifestRulesAreEnforced(t *testing.T) {
	wantReject(t, "D 2026-11-12T10:00:00\nF a.c "+h40+"\nS b.c "+h40+"\n", "F and S in one check-in")
	wantReject(t, "B "+h40+"\nD 2026-11-12T10:00:00\nS b.c "+h40+"\n", "B and S in one check-in")
	wantReject(t, "F a.c "+h40+"\nS b.c "+h40+"\n", "F and S in one node")
	wantReject(t, "F a.c\n", "hash-less F in a node")
	wantReject(t, "S b.c "+h40+"\nS a.c "+h40+"\n", "S run descending")
	wantReject(t, "S a.c "+h40+"\nS a.c "+h64+"\n", "S run repeating a name")
	wantReject(t, "S a.c "+h40+" x\n", "S card with a third token")
	wantReject(t, "S a.c nothex\n", "S card with a bad hash")
	wantReject(t, "S ../a.c "+h40+"\n", "S card with a bad name")
	wantReject(t, "C x\nS a.c "+h40+"\n", "C card in a node")
	t.Log("ok")
}