blob: e364a137e549fb89ba741ec57c30a94c04201fb3 [file] [log] [blame]
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))
}