package common import ( "os" "os/exec" "path" "strings" "testing" ) func TestGitMsgParsing(t *testing.T) { t.Run("tree message with size 56", func(t *testing.T) { const hdr = "f40888ea4515fe2e8eea617a16f5f50a45f652d894de3ad181d58de3aafb8f98 tree 56\x00" data := make(chan byte, 500) for _, b := range []byte(hdr) { data <- b } gitHdr, err := parseGitMsg(data) if err != nil { t.Error(err) } if gitHdr.hash != "f40888ea4515fe2e8eea617a16f5f50a45f652d894de3ad181d58de3aafb8f98" { t.Errorf("Invalid hash %s", gitHdr.hash) } if gitHdr.size != 56 { t.Errorf("Invalid msg size: %d", gitHdr.size) } if gitHdr.itemType != "tree" { t.Errorf("Invalid msg type: %s", gitHdr.itemType) } }) t.Run("commit message with size 256", func(t *testing.T) { const hdr = "f40888ea4515fe2e8eea617a16f5f50a45f652d894de3ad181d58de3aafb8f99 commit 256\x00" data := make(chan byte, 500) for _, b := range []byte(hdr) { data <- b } gitHdr, err := parseGitMsg(data) if err != nil { t.Error(err) } if gitHdr.hash != "f40888ea4515fe2e8eea617a16f5f50a45f652d894de3ad181d58de3aafb8f99" { t.Errorf("Invalid hash %s", gitHdr.hash) } if gitHdr.size != 256 { t.Errorf("Invalid msg size: %d", gitHdr.size) } if gitHdr.itemType != "commit" { t.Errorf("Invalid msg type: %s", gitHdr.itemType) } }) t.Run("invalid tree message with size 56", func(t *testing.T) { const hdr = "f408r8ea4515fe2e8eea617a16f5f50a45f652d894de3ad181d58de3aafb8f98 tree 56\x00" data := make(chan byte, 500) for _, b := range []byte(hdr) { data <- b } gitHdr, err := parseGitMsg(data) if err.Error() != "Invalid character during object hash parse 'r' at 4" { t.Error(err) } if gitHdr.hash != "" { t.Errorf("Invalid hash %s", gitHdr.hash) } if gitHdr.size != 0 { t.Errorf("Invalid msg size: %d", gitHdr.size) } if gitHdr.itemType != "" { t.Errorf("Invalid msg type: %s", gitHdr.itemType) } }) } func TestGitCommitParsing(t *testing.T) { t.Run("parse valid commit message", func(t *testing.T) { const commitData = "f40888ea4515fe2e8eea617a16f5f50a45f652d894de3ad181d58de3aafb8f99 commit 253\000" + `tree e20033df9f18780756ba4a96dbc7eb1a626253961039cb674156f266ba7a4e53 parent 429cc2fe02170ca5668f0461928c7e7430c7a17cd64ac298286d7162572a7703 author Adam Majer 1720709149 +0200 committer Adam Majer 1720709149 +0200 .` + "\000" ch := make(chan byte, 5000) for _, b := range []byte(commitData) { ch <- b } commit, err := parseGitCommit(ch) if err != nil { t.Error(err) } if commit.Tree != "e20033df9f18780756ba4a96dbc7eb1a626253961039cb674156f266ba7a4e53" { t.Errorf("Invalid commit object: %#v", commit) } if commit.Msg != "." { t.Errorf("Invalid commit msg: '%s'", commit.Msg) } }) t.Run("parse multiline headers", func(t *testing.T) { const commitData = "cae5831ab48470ff060a5aaa12eb6e5a7acaf91e commit 1491\x00" + `tree 1f9c8fe8099615d6d3921528402ac53f09213b02 parent e08a654fae0ecc91678819e0b62a2e014bad3339 author Yagiz Nizipli 1720967314 -0400 committer GitHub 1720967314 +0200 gpgsig -----BEGIN PGP SIGNATURE----- wsFcBAABCAAQBQJmk+CSCRC1aQ7uu5UhlAAAQIYQAEQXCl3bUUuegiz5/oitIIF7 6xhndcjQIuqY4dONIeOARrGwbKh8OtMHpfJhMRUmvWvXrsTA6P1PWl0YcyyIMzHZ a4sBsWyxA0uSztVywpvksvk6EdMoEXeXrHS3cBxePsH8bI+Pwnsv27PsevEwpyIT reB4zZsoGySFVqf2lnXxG5hSRMYw++BDXSDMZk2BP9BvueRXasJ0lT1c7HlbHepF TWzwyHZ91OhXjrdPY7qLQEEV/frwuM+UrxOPb2e83ZTg81vXFuugURfhHNx4Iu+F LCMvOeaF2vO5yJtMe8+tY1l0Wb8S1aWcGCECN2XCXmmnWxt+yYh2gjqxq3y0DMcz zvg6arQIepDFLkQPZMDlUCIjIJQn4FbAaQAvoyMF8Pi5YmxhRqgo3iOB5SBE8eES 63ifZ311izuSdD+o3ObFpzLoTgq62kglwfegZN/X8CzTSIqrT1norYJEbSwkWID1 WeRHUHfC7f6N3XK8zeb83zmhBU58ghW9sp5/LcefGMRJmVhBWhjBCpeMUaFHdKhl /dfgPl5gJrrJ+wM3O6iaay0R1Iv4Upe/yXrbQnIgGj/qqgMLEPBY8lzNYimVTLxd 2ObrcXnERo3wwxeUgWaAARbEGQjC51DK/2SXxVGUh+IokicsBNRKU7lVWwwFFely ntjtge6Gs9pA5rSIilPH =V1bK -----END PGP SIGNATURE----- meta: change email address of anonrig PR-URL: https://github.com/nodejs/node/pull/53829 Reviewed-By: Antoine du Hamel Reviewed-By: James M Snell Reviewed-By: Luigi Pinca Reviewed-By: Matteo Collina Reviewed-By: Ulises Gascón Reviewed-By: Richard Lau Reviewed-By: Marco Ippolito ` + "\x00" ch := make(chan byte, 5000) for _, b := range []byte(commitData) { ch <- b } commit, err := parseGitCommit(ch) if err != nil { t.Error(err) } if commit.Tree != "1f9c8fe8099615d6d3921528402ac53f09213b02" { t.Errorf("Invalid commit object: %#v", commit) } if commit.Msg[len(commit.Msg)-55:] != "Reviewed-By: Marco Ippolito " { t.Errorf("Invalid commit msg: '%s'", commit.Msg[len(commit.Msg)-55:]) } }) t.Run("parse tree object", func(t *testing.T) { const treeData = "\x31\x61\x30\x35\x64\x62\x37\x33\x36\x39\x33\x37\x34\x33\x30\x65\x31\x38\x64\x66\x34\x33\x61\x32\x37\x61\x39\x38\x30\x30\x31\x30\x31\x32\x65\x31\x65\x64\x32\x30\x34\x38\x32\x39\x38\x36\x37\x31\x32\x38\x66\x32\x63\x65\x38\x34\x30\x36\x62\x35\x63\x66\x63\x39\x20\x74\x72\x65\x65\x20\x32\x30\x35\x00\x34\x30\x30\x30\x30\x20\x62\x6f\x74\x73\x2d\x63\x6f\x6d\x6d\x6f\x6e\x00\x93\x17\xaa\x47\xf6\xea\x37\xe8\xbc\xe2\x80\x77\x57\x90\xf4\xa8\x01\xd7\xe3\x70\x2f\x84\xfb\xe1\xb0\x0e\x4a\x2c\x1c\x75\x2c\x2b\x34\x30\x30\x30\x30\x20\x6f\x62\x73\x2d\x73\x74\x61\x67\x69\x6e\x67\x2d\x62\x6f\x74\x00\x79\x77\x8b\x28\x7d\x37\x10\x59\xb9\x71\x28\x36\xed\x20\x31\x5f\xfb\xe1\xed\xb5\xba\x4f\x5e\xbb\x65\x65\x68\x23\x77\x32\x58\xfe\x34\x30\x30\x30\x30\x20\x70\x72\x2d\x72\x65\x76\x69\x65\x77\x00\x36\x0d\x45\xcb\x76\xb8\x93\xb3\x21\xba\xfa\xd5\x00\x9d\xfc\x59\xab\x88\xc1\x3c\x81\xcb\x48\x5a\xe0\x29\x29\x0f\xe3\x6b\x3c\x5e\x34\x30\x30\x30\x30\x20\x70\x72\x6a\x67\x69\x74\x2d\x75\x70\x64\x61\x74\x65\x72\x00\xb4\x0b\x1c\xf5\xfb\xec\x9a\xb2\x9f\x48\x3e\x21\x18\x0d\x51\xb7\x98\x6e\x21\x99\x74\x84\x67\x71\x41\x24\x42\xfc\xc9\x04\x12\x99\x00" ch := make(chan byte, 1000) for _, b := range []byte(treeData) { ch <- b } tree, err := parseGitTree(ch) if err != nil { t.Error(err) } found := false t.Log(tree.items) for _, item := range tree.items { if item.name == "bots-common" && item.hash == "9317aa47f6ea37e8bce280775790f4a801d7e3702f84fbe1b00e4a2c1c752c2b" && item.isTree() { found = true t.Log("found") break } } if !found { t.Error("expected sub-tree not found") } }) t.Run("parse tree object with submodules", func(t *testing.T) { const treeData = "\x34\x38\x34\x66\x31\x62\x65\x65\x63\x39\x35\x63\x61\x36\x62\x38\x36\x30\x64\x30\x64\x37\x63\x35\x65\x34\x38\x37\x31\x36\x36\x62\x30\x38\x65\x31\x61\x34\x35\x36\x37\x36\x62\x31\x37\x64\x39\x65\x65\x66\x32\x39\x39\x39\x65\x39\x64\x37\x34\x63\x62\x63\x64\x36\x20\x74\x72\x65\x65\x20\x33\x34\x39\x00\x31\x30\x30\x36\x34\x34\x20\x2e\x67\x69\x74\x6d\x6f\x64\x75\x6c\x65\x73\x00\xc8\x1e\x14\x29\xc5\xd4\x07\xfc\x32\xf1\xd7\xe2\x64\xee\x88\xfc\xce\xfc\x44\xf7\xae\x2e\xc4\x6e\x2c\x15\x27\x26\x65\xd4\xb8\x78\x31\x30\x30\x36\x34\x34\x20\x52\x45\x41\x44\x4d\x45\x2e\x6d\x64\x00\x90\x22\x84\x13\xbf\xd3\x5c\xfb\x1e\x27\x6b\xd6\x17\x3e\x89\xed\x0f\xc6\x31\x85\x24\x58\x6d\x9d\xf0\x6a\x1e\x17\x57\x19\x8d\xc2\x31\x36\x30\x30\x30\x30\x20\x6d\x69\x6e\x67\x77\x33\x32\x2d\x67\x63\x63\x00\xdc\x55\xb8\x28\x32\x8c\x8e\x49\x4f\x67\x87\x4a\x7d\x8c\x03\xdd\x1c\x6b\x4e\x02\xd1\x6b\x86\xe0\x8e\x47\xd7\x0e\xcd\x79\x96\x80\x31\x36\x30\x30\x30\x30\x20\x6e\x6f\x64\x65\x6a\x73\x2d\x63\x6f\x6d\x6d\x6f\x6e\x00\xd6\xa7\x4c\x08\x40\x6c\xe4\x0c\xc8\xf7\xbf\xf2\xd5\xcf\x30\x90\x87\xa8\x72\x83\x61\xcc\x75\x35\x4b\x08\x62\xba\x50\x81\x93\xb8\x31\x36\x30\x30\x30\x30\x20\x6e\x6f\x64\x65\x6a\x73\x32\x31\x00\x24\xee\x6b\xee\x74\x59\xa3\x86\xda\xda\xbf\x8a\x9f\x6a\xe4\xfa\x15\xc3\xf8\x10\xbf\xa0\x1c\xee\x52\x38\x13\x8a\xa2\x14\xd1\x80\x31\x36\x30\x30\x30\x30\x20\x6e\x6f\x64\x65\x6a\x73\x32\x32\x00\x87\x3a\x32\x3b\x26\x2e\xbb\x3b\xd7\x7b\x25\x92\xb2\xe1\x1b\xdd\x08\xdb\xc7\x21\xcb\xf4\xac\x9f\x97\x63\x7e\x58\xe1\xff\xfc\xe7\x31\x36\x30\x30\x30\x30\x20\x70\x79\x74\x68\x6f\x6e\x33\x31\x31\x00\x35\xc7\x02\xe8\x50\x1e\xed\xeb\x5c\xe4\x3d\x6f\x34\x60\xd1\x1c\x79\x1c\xfe\xfa\xa7\x72\x48\xf0\x8c\xad\x55\xd0\x0c\x37\xe7\x3a\x00" ch := make(chan byte, 1000) for _, b := range []byte(treeData) { ch <- b } tree, err := parseGitTree(ch) if err != nil { t.Error(err) } found := false for _, item := range tree.items { t.Log(item) if item.name == "nodejs22" && item.hash == "873a323b262ebb3bd77b2592b2e11bdd08dbc721cbf4ac9f97637e58e1fffce7" && item.isSubmodule() { found = true break } } if !found { t.Error("expected submodule not found") } }) } func TestCommitTreeParsingOfHead(t *testing.T) { gitDir := t.TempDir() testDir, _ := os.Getwd() var commitId string cmd := exec.Command("/usr/bin/bash", path.Join(testDir, "tsetup.sh")) cmd.Dir = gitDir cmd.Stdout = writeFunc(func(data []byte) (int, error) { commitId = commitId + strings.TrimSpace(string(data)) return len(data), nil }) if err := cmd.Run(); err != nil { t.Fatal(err.Error()) } t.Run("reads HEAD and parses the tree", func(t *testing.T) { const nodejs21 = "c678c57007d496a98bec668ae38f2c26a695f94af78012f15d044ccf066ccb41" h := RequestHandler{ GitPath: gitDir, Logger: CreateTestLogger(t), } id, ok := h.GitSubmoduleCommitId("", "nodejs21", commitId) if !ok { t.Error("failed parse") } if id != nodejs21 { t.Errorf("hash doesn't match: %s vs. expected %s", id, nodejs21) } }) t.Run("reads README.md", func (t *testing.T) { h := RequestHandler{ GitPath: gitDir, Logger: CreateTestLogger(t), } data := h.GitCatFile("", commitId, "README.md") if h.HasError() { t.Errorf("failed parse: %v", h.Error) } if string(data) != "foo\n" || len(data) != 4 { t.Errorf("Wrong data of len: %d", len(data)) } }) t.Run("try to parse unknown item", func(t *testing.T) { }) }