Something went wrong. Try again.
Monorepo for Tangled tangled.org
Something went wrong. Try again.
Go
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274package knotfeed
import ( "fmt" "reflect" "strings" "testing"
"tangled.org/core/tapc")
const ( legacyNewSha = "bcfa6359b037bc411e9626260cc3dd9a28408d2c" legacyOldSha = "9eab6c4f29bc9e609ec52888cd6a4ef716b567c9" zeroSha1 = "0000000000000000000000000000000000000000")
const legacyRefFrame = `{ "rkey": "3mug", "nsid": "sh.tangled.git.refUpdate", "created": 1788245839553422000, "event": { "$type": "sh.tangled.git.refUpdate", "ref": "refs/heads/iso16283-low-frequency-corner", "oldSha": "9eab6c4f29bc9e609ec52888cd6a4ef716b567c9", "newSha": "bcfa6359b037bc411e9626260cc3dd9a28408d2c", "committerDid": "did:plc:jder4wkjnwh6mzhrx4n5ebti", "ownerDid": "did:plc:jder4wkjnwh6mzhrx4n5ebti", "repo": "did:plc:5i6o2hrw2viwpxgicwad7f2h", "pushOptions": ["skip-ci"], "changedFiles": ["tests/building/measurement/test_low_frequency.py"], "meta": {"isDefaultRef": false, "commitCount": {"byEmail": [{"email": "mail@jmrp.io", "count": 1}]}} }}`
func refFrame(ref, repo, oldSha, newSha string) string { return fmt.Sprintf( `{"nsid":"sh.tangled.git.refUpdate","created":11,`+ `"event":{"ref":%q,"repo":%q,"oldSha":%q,"newSha":%q}}`, ref, repo, oldSha, newSha)}
func sha(t *testing.T, hex string) ObjectID { t.Helper() id, ok := ParseObjectID(hex) if !ok { t.Fatalf("ParseObjectID(%q)", hex) } return id}
func refOp(t *testing.T, refname, oldSha string, rec RefRecord) RecordOp { t.Helper() rkey, ok := EscapeRefname(refname) if !ok { t.Fatalf("EscapeRefname(%q)", refname) } op := RecordOp{ Action: tapc.RecordDeleteAction, Collection: GitRefCollection, Rkey: rkey, Prior: ParsePriorSha(oldSha), } if rec.Sha.IsZero() { return op } record, err := encodeRefRecord(rec) if err != nil { t.Fatalf("encodeRefRecord: %v", err) } op.Action, op.Bytes = tapc.RecordCreateAction, record return op}
func TestLegacyFrameReadsAsCommit(t *testing.T) { for _, tt := range []struct { name string frame string want Commit }{ { name: "push", frame: legacyRefFrame, want: Commit{ Repo: "did:plc:5i6o2hrw2viwpxgicwad7f2h", Seq: 1788245839553422000, Records: []RecordOp{refOp(t, "refs/heads/iso16283-low-frequency-corner", legacyOldSha, RefRecord{ Sha: sha(t, legacyNewSha), Editor: "did:plc:jder4wkjnwh6mzhrx4n5ebti", PushOptions: []string{"skip-ci"}, })}, }, }, { name: "deleted branch", frame: refFrame("refs/heads/gone", "did:plc:scallop", legacyOldSha, zeroSha1), want: Commit{ Repo: "did:plc:scallop", Seq: 11, Records: []RecordOp{refOp(t, "refs/heads/gone", legacyOldSha, RefRecord{})}, }, }, { name: "deleted branch in a sha256 repo", frame: refFrame("refs/heads/gone", "did:plc:scallop", strings.Repeat("ab", 32), strings.Repeat("0", 64)), want: Commit{ Repo: "did:plc:scallop", Seq: 11, Records: []RecordOp{refOp(t, "refs/heads/gone", strings.Repeat("ab", 32), RefRecord{})}, }, }, { name: "brand new branch", frame: refFrame("refs/heads/new", "did:plc:scallop", zeroSha1, legacyNewSha), want: Commit{ Repo: "did:plc:scallop", Seq: 11, Records: []RecordOp{refOp(t, "refs/heads/new", zeroSha1, RefRecord{Sha: sha(t, legacyNewSha), Editor: "did:plc:scallop"})}, }, }, { name: "push that left oldSha empty", frame: refFrame("refs/heads/new", "did:plc:scallop", "", legacyNewSha), want: Commit{ Repo: "did:plc:scallop", Seq: 11, Records: []RecordOp{refOp(t, "refs/heads/new", "", RefRecord{Sha: sha(t, legacyNewSha), Editor: "did:plc:scallop"})}, }, }, { name: "push from a pre-1.14 knot, which names the repo repoDid", frame: `{"nsid":"sh.tangled.git.refUpdate","created":11,"event":{` + `"ref":"refs/heads/main","ownerDid":"did:plc:clam","repoDid":"did:plc:scallop",` + `"repoName":"shell","committerDid":"did:plc:clam",` + `"oldSha":"` + legacyOldSha + `","newSha":"` + legacyNewSha + `"}}`, want: Commit{ Repo: "did:plc:scallop", Seq: 11, Records: []RecordOp{refOp(t, "refs/heads/main", legacyOldSha, RefRecord{Sha: sha(t, legacyNewSha), Editor: "did:plc:clam"})}, }, }, { name: "push with an empty committerDid", frame: `{"nsid":"sh.tangled.git.refUpdate","created":11,` + `"event":{"ref":"refs/heads/main","repo":"did:plc:scallop","committerDid":"",` + `"oldSha":"` + legacyOldSha + `","newSha":"` + legacyNewSha + `"}}`, want: Commit{ Repo: "did:plc:scallop", Seq: 11, Records: []RecordOp{refOp(t, "refs/heads/main", legacyOldSha, RefRecord{Sha: sha(t, legacyNewSha), Editor: "did:plc:scallop"})}, }, }, { name: "collaborator removal", frame: `{"nsid":"sh.tangled.repo.collaboratorUpdate","created":9, "event":{"op":"remove","subject":"did:plc:olaren","repo":"did:plc:scallop"}}`, want: Commit{ Repo: "did:plc:scallop", Seq: 9, Records: []RecordOp{{ Action: tapc.RecordDeleteAction, Collection: collaboratorInviteCollection, Rkey: "did:plc:olaren", }}, }, }, { name: "knot member update", frame: `{"nsid":"sh.tangled.knot.memberUpdate","created":11, "event":{"op":"add","subject":"did:plc:limpet"}}`, want: Commit{Seq: 11}, }, { name: "ref update with an empty sha", frame: refFrame("refs/heads/main", "did:plc:scallop", legacyOldSha, ""), want: Commit{Seq: 11}, }, { name: "ref update with an empty refname", frame: refFrame("", "did:plc:scallop", legacyOldSha, legacyNewSha), want: Commit{Seq: 11}, }, { name: "new sha with shell junk in it", frame: refFrame("refs/heads/main", "did:plc:scallop", legacyOldSha, "HEAD~1; rm -rf /"), want: Commit{Seq: 11}, }, } { t.Run(tt.name, func(t *testing.T) { msg, err := decodeLegacy([]byte(tt.frame), nil) if err != nil { t.Fatalf("decodeLegacy: %v", err) } if msg.Type != TypeCommit || msg.Commit == nil { t.Fatalf("message type = %q, want a commit", msg.Type) } if !reflect.DeepEqual(*msg.Commit, tt.want) { t.Errorf("commit = %+v, want %+v", *msg.Commit, tt.want) } }) }}
func TestLegacyFrameWithoutCursorErrorsOut(t *testing.T) { if _, err := decodeLegacy([]byte(`{"nsid":"sh.tangled.git.refUpdate"}`), nil); err == nil { t.Error("frame without a created stamp decoded anyway") }}
func TestOnlyObjectIdReadsAsPriorSha(t *testing.T) { for _, reported := range []string{"", "def456", "HEAD", strings.Repeat("zz", 20), zeroSha1 + "0"} { if id, known := ParsePriorSha(reported).Sha(); known { t.Errorf("ParsePriorSha(%q) = %q, want an unknown prior", reported, id) } } if _, known := (RecordOp{}).Prior.Sha(); known { t.Error("zero-value RecordOp came back with a known prior sha") }
hex := strings.Repeat("ab", 32) if got, known := ParsePriorSha(hex).Sha(); !known || got.String() != hex { t.Errorf("ParsePriorSha(%q) = (%q, %v), want the sha back", hex, got, known) } if got, known := ParsePriorSha(zeroSha1).Sha(); !known || !got.IsZero() { t.Errorf("ParsePriorSha(%q) = (%q, %v), want a known absence", zeroSha1, got, known) }}
func TestParseObjectIDTakesOnlyRealObjectIds(t *testing.T) { for _, hex := range []string{ "", "def456", strings.Repeat("ab", 21), strings.Repeat("zz", 20), "HEAD~1; rm -rf /", } { if id, ok := ParseObjectID(hex); ok { t.Errorf("ParseObjectID(%q) = %q, want a refusal", hex, id) } } for _, hex := range []string{zeroSha1, strings.Repeat("0", 64)} { id, ok := ParseObjectID(hex) if !ok || !id.IsZero() { t.Errorf("ParseObjectID(%q) = (%q, %v), want the null object id", hex, id, ok) } } for _, hex := range []string{legacyNewSha, strings.Repeat("AB", 20), strings.Repeat("cD", 32)} { id, ok := ParseObjectID(hex) if !ok || id.String() != hex { t.Errorf("ParseObjectID(%q) = (%q, %v), want the sha back", hex, id, ok) } }}
func TestLegacyFrameWithUnusableFieldsIsRefused(t *testing.T) { for _, tt := range []struct { name string frame string }{ {"nsid that isn't an nsid", `{"nsid":"not an nsid","created":11}`}, {"repo that isn't a did", refFrame("refs/heads/main", "scallop", legacyOldSha, legacyNewSha)}, {"collaborator subject that isn't a did", `{"nsid":"sh.tangled.repo.collaboratorUpdate","created":9, "event":{"op":"remove","subject":"olaren","repo":"did:plc:scallop"}}`}, } { t.Run(tt.name, func(t *testing.T) { if _, err := decodeLegacy([]byte(tt.frame), nil); err == nil { t.Error("frame decoded anyway") } }) }}