| package testutils |
| |
| /* |
| Utilities for mocking requests to Gitiles. |
| */ |
| |
| import ( |
| "context" |
| "encoding/base64" |
| "encoding/json" |
| "fmt" |
| "io" |
| |
| "github.com/stretchr/testify/require" |
| "go.skia.org/infra/go/git" |
| "go.skia.org/infra/go/gitiles" |
| "go.skia.org/infra/go/mockhttpclient" |
| "go.skia.org/infra/go/sktest" |
| "go.skia.org/infra/go/vfs" |
| ) |
| |
| type MockRepo struct { |
| URLMock *mockhttpclient.URLMock |
| repo git.GitDir |
| t sktest.TestingT |
| url string |
| } |
| |
| func NewMockRepo(t sktest.TestingT, url string, repo git.GitDir, c *mockhttpclient.URLMock) *MockRepo { |
| return &MockRepo{ |
| URLMock: c, |
| repo: repo, |
| t: t, |
| url: url, |
| } |
| } |
| |
| func (mr *MockRepo) Empty() bool { |
| return mr.URLMock.Empty() |
| } |
| |
| func (mr *MockRepo) MockReadFile(ctx context.Context, srcPath, ref string) { |
| fs, err := mr.repo.VFS(ctx, ref) |
| require.NoError(mr.t, err) |
| defer func() { |
| require.NoError(mr.t, fs.Close(ctx)) |
| }() |
| f, err := fs.Open(ctx, srcPath) |
| require.NoError(mr.t, err) |
| contents, err := io.ReadAll(vfs.WithContext(ctx, f)) |
| require.NoError(mr.t, err) |
| st, err := f.Stat(ctx) |
| require.NoError(mr.t, err) |
| body := make([]byte, base64.StdEncoding.EncodedLen(len(contents))) |
| base64.StdEncoding.Encode(body, contents) |
| url := fmt.Sprintf(gitiles.DownloadURL, mr.url, ref, srcPath) |
| md := mockhttpclient.MockGetDialogue(body) |
| typ := git.ObjectTypeBlob |
| if st.IsDir() { |
| typ = git.ObjectTypeTree |
| } |
| md.ResponseHeader(gitiles.ModeHeader, fmt.Sprintf("%o", st.Mode())) |
| md.ResponseHeader(gitiles.TypeHeader, string(typ)) |
| mr.URLMock.MockOnce(url, md) |
| } |
| |
| func (mr *MockRepo) getCommit(ctx context.Context, ref string) *gitiles.Commit { |
| details, err := mr.repo.Details(ctx, ref) |
| require.NoError(mr.t, err) |
| rv, err := gitiles.LongCommitToCommit(details) |
| require.NoError(mr.t, err) |
| return rv |
| } |
| |
| func (mr *MockRepo) MockGetCommit(ctx context.Context, ref string) { |
| c := mr.getCommit(ctx, ref) |
| b, err := json.Marshal(c) |
| require.NoError(mr.t, err) |
| b = append([]byte(")]}'\n"), b...) |
| url := fmt.Sprintf(gitiles.CommitURLJSON, mr.url, ref) |
| mr.URLMock.MockOnce(url, mockhttpclient.MockGetDialogue(b)) |
| } |
| |
| func (mr *MockRepo) MockBranches(ctx context.Context) { |
| branches, err := mr.repo.Branches(ctx) |
| require.NoError(mr.t, err) |
| res := make(gitiles.RefsMap, len(branches)) |
| for _, branch := range branches { |
| res[branch.Name] = gitiles.Ref{ |
| Value: branch.Head, |
| } |
| } |
| b, err := json.Marshal(res) |
| require.NoError(mr.t, err) |
| b = append([]byte(")]}'\n"), b...) |
| url := fmt.Sprintf(gitiles.RefsURL, mr.url) |
| mr.URLMock.MockOnce(url, mockhttpclient.MockGetDialogue(b)) |
| } |
| |
| func (mr *MockRepo) MockLog(ctx context.Context, logExpr string, opts ...gitiles.LogOption) { |
| path, query, _, err := gitiles.LogOptionsToQuery(opts) |
| require.NoError(mr.t, err) |
| args := []string{logExpr} |
| if path != "" { |
| args = append(args, "--", path) |
| } |
| revlist, err := mr.repo.RevList(ctx, args...) |
| require.NoError(mr.t, err) |
| log := &gitiles.Log{ |
| Log: make([]*gitiles.Commit, len(revlist)), |
| } |
| for idx, hash := range revlist { |
| log.Log[idx] = mr.getCommit(ctx, hash) |
| } |
| b, err := json.Marshal(log) |
| require.NoError(mr.t, err) |
| b = append([]byte(")]}'\n"), b...) |
| if path != "" { |
| logExpr += "/" + path |
| } |
| url := fmt.Sprintf(gitiles.LogURL, mr.url, logExpr) |
| if query != "" { |
| url += "&" + query |
| } |
| mr.URLMock.MockOnce(url, mockhttpclient.MockGetDialogue(b)) |
| } |