mirror of
https://github.com/sourcegraph/sourcegraph.git
synced 2026-02-06 18:51:59 +00:00
symbols: replace usage of gitserver client's DiffSymbols method with new ChangedFiles method (#62355)
Part of https://github.com/sourcegraph/sourcegraph/issues/60654 This PR builds on the new ChangedFiles method introduced in https://github.com/sourcegraph/sourcegraph/pull/62354, and changes the symbols service to use it instead of the old custom diff symbols method. ## Test plan Existing CI pipeline
This commit is contained in:
parent
3a3ce68138
commit
fc03ac90e9
@ -32,6 +32,7 @@ go_test(
|
||||
deps = [
|
||||
"//cmd/symbols/gitserver",
|
||||
"//internal/api",
|
||||
"//internal/gitserver",
|
||||
"//internal/gitserver/gitdomain",
|
||||
"//internal/observation",
|
||||
"//internal/search",
|
||||
|
||||
264
cmd/symbols/fetcher/mocks_test.go
generated
264
cmd/symbols/fetcher/mocks_test.go
generated
@ -11,8 +11,9 @@ import (
|
||||
"io"
|
||||
"sync"
|
||||
|
||||
gitserver "github.com/sourcegraph/sourcegraph/cmd/symbols/gitserver"
|
||||
gitserver1 "github.com/sourcegraph/sourcegraph/cmd/symbols/gitserver"
|
||||
api "github.com/sourcegraph/sourcegraph/internal/api"
|
||||
gitserver "github.com/sourcegraph/sourcegraph/internal/gitserver"
|
||||
gitdomain "github.com/sourcegraph/sourcegraph/internal/gitserver/gitdomain"
|
||||
types "github.com/sourcegraph/sourcegraph/internal/types"
|
||||
)
|
||||
@ -22,12 +23,12 @@ import (
|
||||
// github.com/sourcegraph/sourcegraph/cmd/symbols/gitserver) used for unit
|
||||
// testing.
|
||||
type MockGitserverClient struct {
|
||||
// ChangedFilesFunc is an instance of a mock function object controlling
|
||||
// the behavior of the method ChangedFiles.
|
||||
ChangedFilesFunc *GitserverClientChangedFilesFunc
|
||||
// FetchTarFunc is an instance of a mock function object controlling the
|
||||
// behavior of the method FetchTar.
|
||||
FetchTarFunc *GitserverClientFetchTarFunc
|
||||
// GitDiffFunc is an instance of a mock function object controlling the
|
||||
// behavior of the method GitDiff.
|
||||
GitDiffFunc *GitserverClientGitDiffFunc
|
||||
// LogReverseEachFunc is an instance of a mock function object
|
||||
// controlling the behavior of the method LogReverseEach.
|
||||
LogReverseEachFunc *GitserverClientLogReverseEachFunc
|
||||
@ -44,13 +45,13 @@ type MockGitserverClient struct {
|
||||
// overwritten.
|
||||
func NewMockGitserverClient() *MockGitserverClient {
|
||||
return &MockGitserverClient{
|
||||
FetchTarFunc: &GitserverClientFetchTarFunc{
|
||||
defaultHook: func(context.Context, api.RepoName, api.CommitID, []string) (r0 io.ReadCloser, r1 error) {
|
||||
ChangedFilesFunc: &GitserverClientChangedFilesFunc{
|
||||
defaultHook: func(context.Context, api.RepoName, api.CommitID, api.CommitID) (r0 gitserver.ChangedFilesIterator, r1 error) {
|
||||
return
|
||||
},
|
||||
},
|
||||
GitDiffFunc: &GitserverClientGitDiffFunc{
|
||||
defaultHook: func(context.Context, api.RepoName, api.CommitID, api.CommitID) (r0 gitserver.Changes, r1 error) {
|
||||
FetchTarFunc: &GitserverClientFetchTarFunc{
|
||||
defaultHook: func(context.Context, api.RepoName, api.CommitID, []string) (r0 io.ReadCloser, r1 error) {
|
||||
return
|
||||
},
|
||||
},
|
||||
@ -76,16 +77,16 @@ func NewMockGitserverClient() *MockGitserverClient {
|
||||
// interface. All methods panic on invocation, unless overwritten.
|
||||
func NewStrictMockGitserverClient() *MockGitserverClient {
|
||||
return &MockGitserverClient{
|
||||
ChangedFilesFunc: &GitserverClientChangedFilesFunc{
|
||||
defaultHook: func(context.Context, api.RepoName, api.CommitID, api.CommitID) (gitserver.ChangedFilesIterator, error) {
|
||||
panic("unexpected invocation of MockGitserverClient.ChangedFiles")
|
||||
},
|
||||
},
|
||||
FetchTarFunc: &GitserverClientFetchTarFunc{
|
||||
defaultHook: func(context.Context, api.RepoName, api.CommitID, []string) (io.ReadCloser, error) {
|
||||
panic("unexpected invocation of MockGitserverClient.FetchTar")
|
||||
},
|
||||
},
|
||||
GitDiffFunc: &GitserverClientGitDiffFunc{
|
||||
defaultHook: func(context.Context, api.RepoName, api.CommitID, api.CommitID) (gitserver.Changes, error) {
|
||||
panic("unexpected invocation of MockGitserverClient.GitDiff")
|
||||
},
|
||||
},
|
||||
LogReverseEachFunc: &GitserverClientLogReverseEachFunc{
|
||||
defaultHook: func(context.Context, string, string, int, func(entry gitdomain.LogEntry) error) error {
|
||||
panic("unexpected invocation of MockGitserverClient.LogReverseEach")
|
||||
@ -107,14 +108,14 @@ func NewStrictMockGitserverClient() *MockGitserverClient {
|
||||
// NewMockGitserverClientFrom creates a new mock of the MockGitserverClient
|
||||
// interface. All methods delegate to the given implementation, unless
|
||||
// overwritten.
|
||||
func NewMockGitserverClientFrom(i gitserver.GitserverClient) *MockGitserverClient {
|
||||
func NewMockGitserverClientFrom(i gitserver1.GitserverClient) *MockGitserverClient {
|
||||
return &MockGitserverClient{
|
||||
ChangedFilesFunc: &GitserverClientChangedFilesFunc{
|
||||
defaultHook: i.ChangedFiles,
|
||||
},
|
||||
FetchTarFunc: &GitserverClientFetchTarFunc{
|
||||
defaultHook: i.FetchTar,
|
||||
},
|
||||
GitDiffFunc: &GitserverClientGitDiffFunc{
|
||||
defaultHook: i.GitDiff,
|
||||
},
|
||||
LogReverseEachFunc: &GitserverClientLogReverseEachFunc{
|
||||
defaultHook: i.LogReverseEach,
|
||||
},
|
||||
@ -127,6 +128,121 @@ func NewMockGitserverClientFrom(i gitserver.GitserverClient) *MockGitserverClien
|
||||
}
|
||||
}
|
||||
|
||||
// GitserverClientChangedFilesFunc describes the behavior when the
|
||||
// ChangedFiles method of the parent MockGitserverClient instance is
|
||||
// invoked.
|
||||
type GitserverClientChangedFilesFunc struct {
|
||||
defaultHook func(context.Context, api.RepoName, api.CommitID, api.CommitID) (gitserver.ChangedFilesIterator, error)
|
||||
hooks []func(context.Context, api.RepoName, api.CommitID, api.CommitID) (gitserver.ChangedFilesIterator, error)
|
||||
history []GitserverClientChangedFilesFuncCall
|
||||
mutex sync.Mutex
|
||||
}
|
||||
|
||||
// ChangedFiles delegates to the next hook function in the queue and stores
|
||||
// the parameter and result values of this invocation.
|
||||
func (m *MockGitserverClient) ChangedFiles(v0 context.Context, v1 api.RepoName, v2 api.CommitID, v3 api.CommitID) (gitserver.ChangedFilesIterator, error) {
|
||||
r0, r1 := m.ChangedFilesFunc.nextHook()(v0, v1, v2, v3)
|
||||
m.ChangedFilesFunc.appendCall(GitserverClientChangedFilesFuncCall{v0, v1, v2, v3, r0, r1})
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// SetDefaultHook sets function that is called when the ChangedFiles method
|
||||
// of the parent MockGitserverClient instance is invoked and the hook queue
|
||||
// is empty.
|
||||
func (f *GitserverClientChangedFilesFunc) SetDefaultHook(hook func(context.Context, api.RepoName, api.CommitID, api.CommitID) (gitserver.ChangedFilesIterator, error)) {
|
||||
f.defaultHook = hook
|
||||
}
|
||||
|
||||
// PushHook adds a function to the end of hook queue. Each invocation of the
|
||||
// ChangedFiles method of the parent MockGitserverClient instance invokes
|
||||
// the hook at the front of the queue and discards it. After the queue is
|
||||
// empty, the default hook function is invoked for any future action.
|
||||
func (f *GitserverClientChangedFilesFunc) PushHook(hook func(context.Context, api.RepoName, api.CommitID, api.CommitID) (gitserver.ChangedFilesIterator, error)) {
|
||||
f.mutex.Lock()
|
||||
f.hooks = append(f.hooks, hook)
|
||||
f.mutex.Unlock()
|
||||
}
|
||||
|
||||
// SetDefaultReturn calls SetDefaultHook with a function that returns the
|
||||
// given values.
|
||||
func (f *GitserverClientChangedFilesFunc) SetDefaultReturn(r0 gitserver.ChangedFilesIterator, r1 error) {
|
||||
f.SetDefaultHook(func(context.Context, api.RepoName, api.CommitID, api.CommitID) (gitserver.ChangedFilesIterator, error) {
|
||||
return r0, r1
|
||||
})
|
||||
}
|
||||
|
||||
// PushReturn calls PushHook with a function that returns the given values.
|
||||
func (f *GitserverClientChangedFilesFunc) PushReturn(r0 gitserver.ChangedFilesIterator, r1 error) {
|
||||
f.PushHook(func(context.Context, api.RepoName, api.CommitID, api.CommitID) (gitserver.ChangedFilesIterator, error) {
|
||||
return r0, r1
|
||||
})
|
||||
}
|
||||
|
||||
func (f *GitserverClientChangedFilesFunc) nextHook() func(context.Context, api.RepoName, api.CommitID, api.CommitID) (gitserver.ChangedFilesIterator, error) {
|
||||
f.mutex.Lock()
|
||||
defer f.mutex.Unlock()
|
||||
|
||||
if len(f.hooks) == 0 {
|
||||
return f.defaultHook
|
||||
}
|
||||
|
||||
hook := f.hooks[0]
|
||||
f.hooks = f.hooks[1:]
|
||||
return hook
|
||||
}
|
||||
|
||||
func (f *GitserverClientChangedFilesFunc) appendCall(r0 GitserverClientChangedFilesFuncCall) {
|
||||
f.mutex.Lock()
|
||||
f.history = append(f.history, r0)
|
||||
f.mutex.Unlock()
|
||||
}
|
||||
|
||||
// History returns a sequence of GitserverClientChangedFilesFuncCall objects
|
||||
// describing the invocations of this function.
|
||||
func (f *GitserverClientChangedFilesFunc) History() []GitserverClientChangedFilesFuncCall {
|
||||
f.mutex.Lock()
|
||||
history := make([]GitserverClientChangedFilesFuncCall, len(f.history))
|
||||
copy(history, f.history)
|
||||
f.mutex.Unlock()
|
||||
|
||||
return history
|
||||
}
|
||||
|
||||
// GitserverClientChangedFilesFuncCall is an object that describes an
|
||||
// invocation of method ChangedFiles on an instance of MockGitserverClient.
|
||||
type GitserverClientChangedFilesFuncCall struct {
|
||||
// Arg0 is the value of the 1st argument passed to this method
|
||||
// invocation.
|
||||
Arg0 context.Context
|
||||
// Arg1 is the value of the 2nd argument passed to this method
|
||||
// invocation.
|
||||
Arg1 api.RepoName
|
||||
// Arg2 is the value of the 3rd argument passed to this method
|
||||
// invocation.
|
||||
Arg2 api.CommitID
|
||||
// Arg3 is the value of the 4th argument passed to this method
|
||||
// invocation.
|
||||
Arg3 api.CommitID
|
||||
// Result0 is the value of the 1st result returned from this method
|
||||
// invocation.
|
||||
Result0 gitserver.ChangedFilesIterator
|
||||
// Result1 is the value of the 2nd result returned from this method
|
||||
// invocation.
|
||||
Result1 error
|
||||
}
|
||||
|
||||
// Args returns an interface slice containing the arguments of this
|
||||
// invocation.
|
||||
func (c GitserverClientChangedFilesFuncCall) Args() []interface{} {
|
||||
return []interface{}{c.Arg0, c.Arg1, c.Arg2, c.Arg3}
|
||||
}
|
||||
|
||||
// Results returns an interface slice containing the results of this
|
||||
// invocation.
|
||||
func (c GitserverClientChangedFilesFuncCall) Results() []interface{} {
|
||||
return []interface{}{c.Result0, c.Result1}
|
||||
}
|
||||
|
||||
// GitserverClientFetchTarFunc describes the behavior when the FetchTar
|
||||
// method of the parent MockGitserverClient instance is invoked.
|
||||
type GitserverClientFetchTarFunc struct {
|
||||
@ -241,120 +357,6 @@ func (c GitserverClientFetchTarFuncCall) Results() []interface{} {
|
||||
return []interface{}{c.Result0, c.Result1}
|
||||
}
|
||||
|
||||
// GitserverClientGitDiffFunc describes the behavior when the GitDiff method
|
||||
// of the parent MockGitserverClient instance is invoked.
|
||||
type GitserverClientGitDiffFunc struct {
|
||||
defaultHook func(context.Context, api.RepoName, api.CommitID, api.CommitID) (gitserver.Changes, error)
|
||||
hooks []func(context.Context, api.RepoName, api.CommitID, api.CommitID) (gitserver.Changes, error)
|
||||
history []GitserverClientGitDiffFuncCall
|
||||
mutex sync.Mutex
|
||||
}
|
||||
|
||||
// GitDiff delegates to the next hook function in the queue and stores the
|
||||
// parameter and result values of this invocation.
|
||||
func (m *MockGitserverClient) GitDiff(v0 context.Context, v1 api.RepoName, v2 api.CommitID, v3 api.CommitID) (gitserver.Changes, error) {
|
||||
r0, r1 := m.GitDiffFunc.nextHook()(v0, v1, v2, v3)
|
||||
m.GitDiffFunc.appendCall(GitserverClientGitDiffFuncCall{v0, v1, v2, v3, r0, r1})
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// SetDefaultHook sets function that is called when the GitDiff method of
|
||||
// the parent MockGitserverClient instance is invoked and the hook queue is
|
||||
// empty.
|
||||
func (f *GitserverClientGitDiffFunc) SetDefaultHook(hook func(context.Context, api.RepoName, api.CommitID, api.CommitID) (gitserver.Changes, error)) {
|
||||
f.defaultHook = hook
|
||||
}
|
||||
|
||||
// PushHook adds a function to the end of hook queue. Each invocation of the
|
||||
// GitDiff method of the parent MockGitserverClient instance invokes the
|
||||
// hook at the front of the queue and discards it. After the queue is empty,
|
||||
// the default hook function is invoked for any future action.
|
||||
func (f *GitserverClientGitDiffFunc) PushHook(hook func(context.Context, api.RepoName, api.CommitID, api.CommitID) (gitserver.Changes, error)) {
|
||||
f.mutex.Lock()
|
||||
f.hooks = append(f.hooks, hook)
|
||||
f.mutex.Unlock()
|
||||
}
|
||||
|
||||
// SetDefaultReturn calls SetDefaultHook with a function that returns the
|
||||
// given values.
|
||||
func (f *GitserverClientGitDiffFunc) SetDefaultReturn(r0 gitserver.Changes, r1 error) {
|
||||
f.SetDefaultHook(func(context.Context, api.RepoName, api.CommitID, api.CommitID) (gitserver.Changes, error) {
|
||||
return r0, r1
|
||||
})
|
||||
}
|
||||
|
||||
// PushReturn calls PushHook with a function that returns the given values.
|
||||
func (f *GitserverClientGitDiffFunc) PushReturn(r0 gitserver.Changes, r1 error) {
|
||||
f.PushHook(func(context.Context, api.RepoName, api.CommitID, api.CommitID) (gitserver.Changes, error) {
|
||||
return r0, r1
|
||||
})
|
||||
}
|
||||
|
||||
func (f *GitserverClientGitDiffFunc) nextHook() func(context.Context, api.RepoName, api.CommitID, api.CommitID) (gitserver.Changes, error) {
|
||||
f.mutex.Lock()
|
||||
defer f.mutex.Unlock()
|
||||
|
||||
if len(f.hooks) == 0 {
|
||||
return f.defaultHook
|
||||
}
|
||||
|
||||
hook := f.hooks[0]
|
||||
f.hooks = f.hooks[1:]
|
||||
return hook
|
||||
}
|
||||
|
||||
func (f *GitserverClientGitDiffFunc) appendCall(r0 GitserverClientGitDiffFuncCall) {
|
||||
f.mutex.Lock()
|
||||
f.history = append(f.history, r0)
|
||||
f.mutex.Unlock()
|
||||
}
|
||||
|
||||
// History returns a sequence of GitserverClientGitDiffFuncCall objects
|
||||
// describing the invocations of this function.
|
||||
func (f *GitserverClientGitDiffFunc) History() []GitserverClientGitDiffFuncCall {
|
||||
f.mutex.Lock()
|
||||
history := make([]GitserverClientGitDiffFuncCall, len(f.history))
|
||||
copy(history, f.history)
|
||||
f.mutex.Unlock()
|
||||
|
||||
return history
|
||||
}
|
||||
|
||||
// GitserverClientGitDiffFuncCall is an object that describes an invocation
|
||||
// of method GitDiff on an instance of MockGitserverClient.
|
||||
type GitserverClientGitDiffFuncCall struct {
|
||||
// Arg0 is the value of the 1st argument passed to this method
|
||||
// invocation.
|
||||
Arg0 context.Context
|
||||
// Arg1 is the value of the 2nd argument passed to this method
|
||||
// invocation.
|
||||
Arg1 api.RepoName
|
||||
// Arg2 is the value of the 3rd argument passed to this method
|
||||
// invocation.
|
||||
Arg2 api.CommitID
|
||||
// Arg3 is the value of the 4th argument passed to this method
|
||||
// invocation.
|
||||
Arg3 api.CommitID
|
||||
// Result0 is the value of the 1st result returned from this method
|
||||
// invocation.
|
||||
Result0 gitserver.Changes
|
||||
// Result1 is the value of the 2nd result returned from this method
|
||||
// invocation.
|
||||
Result1 error
|
||||
}
|
||||
|
||||
// Args returns an interface slice containing the arguments of this
|
||||
// invocation.
|
||||
func (c GitserverClientGitDiffFuncCall) Args() []interface{} {
|
||||
return []interface{}{c.Arg0, c.Arg1, c.Arg2, c.Arg3}
|
||||
}
|
||||
|
||||
// Results returns an interface slice containing the results of this
|
||||
// invocation.
|
||||
func (c GitserverClientGitDiffFuncCall) Results() []interface{} {
|
||||
return []interface{}{c.Result0, c.Result1}
|
||||
}
|
||||
|
||||
// GitserverClientLogReverseEachFunc describes the behavior when the
|
||||
// LogReverseEach method of the parent MockGitserverClient instance is
|
||||
// invoked.
|
||||
|
||||
@ -33,7 +33,6 @@ go_test(
|
||||
"//internal/gitserver",
|
||||
"//internal/gitserver/gitdomain",
|
||||
"//internal/observation",
|
||||
"@com_github_google_go_cmp//cmp",
|
||||
"@com_github_stretchr_testify//require",
|
||||
],
|
||||
)
|
||||
|
||||
@ -22,8 +22,8 @@ type GitserverClient interface {
|
||||
// determine if the error is a bad request (eg invalid repo).
|
||||
FetchTar(context.Context, api.RepoName, api.CommitID, []string) (io.ReadCloser, error)
|
||||
|
||||
// GitDiff returns the paths that have changed between two commits.
|
||||
GitDiff(context.Context, api.RepoName, api.CommitID, api.CommitID) (Changes, error)
|
||||
// ChangedFiles returns an iterator that yields the paths that have changed between two commits.
|
||||
ChangedFiles(context.Context, api.RepoName, api.CommitID, api.CommitID) (gitserver.ChangedFilesIterator, error)
|
||||
|
||||
// NewFileReader returns an io.ReadCloser reading from the named file at commit.
|
||||
// The caller should always close the reader after use.
|
||||
@ -75,7 +75,7 @@ func (c *gitserverClient) FetchTar(ctx context.Context, repo api.RepoName, commi
|
||||
return c.innerClient.ArchiveReader(ctx, repo, opts)
|
||||
}
|
||||
|
||||
func (c *gitserverClient) GitDiff(ctx context.Context, repo api.RepoName, commitA, commitB api.CommitID) (_ Changes, err error) {
|
||||
func (c *gitserverClient) ChangedFiles(ctx context.Context, repo api.RepoName, commitA, commitB api.CommitID) (iterator gitserver.ChangedFilesIterator, err error) {
|
||||
ctx, _, endObservation := c.operations.gitDiff.With(ctx, &err, observation.Args{Attrs: []attribute.KeyValue{
|
||||
repo.Attr(),
|
||||
attribute.String("commitA", string(commitA)),
|
||||
@ -83,14 +83,7 @@ func (c *gitserverClient) GitDiff(ctx context.Context, repo api.RepoName, commit
|
||||
}})
|
||||
defer endObservation(1, observation.Args{})
|
||||
|
||||
output, err := c.innerClient.DiffSymbols(ctx, repo, commitA, commitB)
|
||||
|
||||
changes, err := parseGitDiffOutput(output)
|
||||
if err != nil {
|
||||
return Changes{}, errors.Wrap(err, "failed to parse git diff output")
|
||||
}
|
||||
|
||||
return changes, nil
|
||||
return c.innerClient.ChangedFiles(ctx, repo, string(commitA), string(commitB))
|
||||
}
|
||||
|
||||
func (c *gitserverClient) NewFileReader(ctx context.Context, repoCommitPath types.RepoCommitPath) (io.ReadCloser, error) {
|
||||
|
||||
@ -4,7 +4,6 @@ import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/sourcegraph/sourcegraph/internal/api"
|
||||
@ -13,67 +12,6 @@ import (
|
||||
"github.com/sourcegraph/sourcegraph/internal/observation"
|
||||
)
|
||||
|
||||
func TestParseGitDiffOutput(t *testing.T) {
|
||||
testCases := []struct {
|
||||
output []byte
|
||||
expectedChanges Changes
|
||||
shouldError bool
|
||||
}{
|
||||
{
|
||||
output: combineBytes(
|
||||
[]byte("A"), NUL, []byte("added1.json"), NUL,
|
||||
[]byte("M"), NUL, []byte("modified1.json"), NUL,
|
||||
[]byte("D"), NUL, []byte("deleted1.json"), NUL,
|
||||
[]byte("A"), NUL, []byte("added2.json"), NUL,
|
||||
[]byte("M"), NUL, []byte("modified2.json"), NUL,
|
||||
[]byte("D"), NUL, []byte("deleted2.json"), NUL,
|
||||
[]byte("A"), NUL, []byte("added3.json"), NUL,
|
||||
[]byte("M"), NUL, []byte("modified3.json"), NUL,
|
||||
[]byte("D"), NUL, []byte("deleted3.json"), NUL,
|
||||
),
|
||||
expectedChanges: Changes{
|
||||
Added: []string{"added1.json", "added2.json", "added3.json"},
|
||||
Modified: []string{"modified1.json", "modified2.json", "modified3.json"},
|
||||
Deleted: []string{"deleted1.json", "deleted2.json", "deleted3.json"},
|
||||
},
|
||||
},
|
||||
{
|
||||
output: combineBytes(
|
||||
[]byte("A"), NUL, []byte("added1.json"), NUL,
|
||||
[]byte("M"), NUL, []byte("modified1.json"), NUL,
|
||||
[]byte("D"), NUL,
|
||||
),
|
||||
shouldError: true,
|
||||
},
|
||||
{
|
||||
output: []byte{},
|
||||
},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
changes, err := parseGitDiffOutput(testCase.output)
|
||||
if err != nil {
|
||||
if !testCase.shouldError {
|
||||
t.Fatalf("unexpected error parsing git diff output: %s", err)
|
||||
}
|
||||
} else if testCase.shouldError {
|
||||
t.Fatalf("expected error, got none")
|
||||
}
|
||||
|
||||
if diff := cmp.Diff(testCase.expectedChanges, changes); diff != "" {
|
||||
t.Errorf("unexpected changes (-want +got):\n%s", diff)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func combineBytes(bss ...[]byte) (combined []byte) {
|
||||
for _, bs := range bss {
|
||||
combined = append(combined, bs...)
|
||||
}
|
||||
|
||||
return combined
|
||||
}
|
||||
|
||||
func TestGitserverClient_PaginatedRevList(t *testing.T) {
|
||||
allCommits := []*gitdomain.Commit{
|
||||
{ID: "4ac04f2761285633cd35188c696a6e08de03c00c"},
|
||||
|
||||
@ -30,6 +30,6 @@ func newOperations(observationCtx *observation.Context) *operations {
|
||||
|
||||
return &operations{
|
||||
fetchTar: op("FetchTar"),
|
||||
gitDiff: op("GitDiff"),
|
||||
gitDiff: op("ChangedFiles"),
|
||||
}
|
||||
}
|
||||
|
||||
@ -58,6 +58,7 @@ go_test(
|
||||
"//internal/database/dbmocks",
|
||||
"//internal/diskcache",
|
||||
"//internal/endpoint",
|
||||
"//internal/gitserver",
|
||||
"//internal/gitserver/gitdomain",
|
||||
"//internal/grpc/defaults",
|
||||
"//internal/observation",
|
||||
|
||||
264
cmd/symbols/internal/api/mocks_test.go
generated
264
cmd/symbols/internal/api/mocks_test.go
generated
@ -11,8 +11,9 @@ import (
|
||||
"io"
|
||||
"sync"
|
||||
|
||||
gitserver "github.com/sourcegraph/sourcegraph/cmd/symbols/gitserver"
|
||||
gitserver1 "github.com/sourcegraph/sourcegraph/cmd/symbols/gitserver"
|
||||
api "github.com/sourcegraph/sourcegraph/internal/api"
|
||||
gitserver "github.com/sourcegraph/sourcegraph/internal/gitserver"
|
||||
gitdomain "github.com/sourcegraph/sourcegraph/internal/gitserver/gitdomain"
|
||||
types "github.com/sourcegraph/sourcegraph/internal/types"
|
||||
)
|
||||
@ -22,12 +23,12 @@ import (
|
||||
// github.com/sourcegraph/sourcegraph/cmd/symbols/gitserver) used for unit
|
||||
// testing.
|
||||
type MockGitserverClient struct {
|
||||
// ChangedFilesFunc is an instance of a mock function object controlling
|
||||
// the behavior of the method ChangedFiles.
|
||||
ChangedFilesFunc *GitserverClientChangedFilesFunc
|
||||
// FetchTarFunc is an instance of a mock function object controlling the
|
||||
// behavior of the method FetchTar.
|
||||
FetchTarFunc *GitserverClientFetchTarFunc
|
||||
// GitDiffFunc is an instance of a mock function object controlling the
|
||||
// behavior of the method GitDiff.
|
||||
GitDiffFunc *GitserverClientGitDiffFunc
|
||||
// LogReverseEachFunc is an instance of a mock function object
|
||||
// controlling the behavior of the method LogReverseEach.
|
||||
LogReverseEachFunc *GitserverClientLogReverseEachFunc
|
||||
@ -44,13 +45,13 @@ type MockGitserverClient struct {
|
||||
// overwritten.
|
||||
func NewMockGitserverClient() *MockGitserverClient {
|
||||
return &MockGitserverClient{
|
||||
FetchTarFunc: &GitserverClientFetchTarFunc{
|
||||
defaultHook: func(context.Context, api.RepoName, api.CommitID, []string) (r0 io.ReadCloser, r1 error) {
|
||||
ChangedFilesFunc: &GitserverClientChangedFilesFunc{
|
||||
defaultHook: func(context.Context, api.RepoName, api.CommitID, api.CommitID) (r0 gitserver.ChangedFilesIterator, r1 error) {
|
||||
return
|
||||
},
|
||||
},
|
||||
GitDiffFunc: &GitserverClientGitDiffFunc{
|
||||
defaultHook: func(context.Context, api.RepoName, api.CommitID, api.CommitID) (r0 gitserver.Changes, r1 error) {
|
||||
FetchTarFunc: &GitserverClientFetchTarFunc{
|
||||
defaultHook: func(context.Context, api.RepoName, api.CommitID, []string) (r0 io.ReadCloser, r1 error) {
|
||||
return
|
||||
},
|
||||
},
|
||||
@ -76,16 +77,16 @@ func NewMockGitserverClient() *MockGitserverClient {
|
||||
// interface. All methods panic on invocation, unless overwritten.
|
||||
func NewStrictMockGitserverClient() *MockGitserverClient {
|
||||
return &MockGitserverClient{
|
||||
ChangedFilesFunc: &GitserverClientChangedFilesFunc{
|
||||
defaultHook: func(context.Context, api.RepoName, api.CommitID, api.CommitID) (gitserver.ChangedFilesIterator, error) {
|
||||
panic("unexpected invocation of MockGitserverClient.ChangedFiles")
|
||||
},
|
||||
},
|
||||
FetchTarFunc: &GitserverClientFetchTarFunc{
|
||||
defaultHook: func(context.Context, api.RepoName, api.CommitID, []string) (io.ReadCloser, error) {
|
||||
panic("unexpected invocation of MockGitserverClient.FetchTar")
|
||||
},
|
||||
},
|
||||
GitDiffFunc: &GitserverClientGitDiffFunc{
|
||||
defaultHook: func(context.Context, api.RepoName, api.CommitID, api.CommitID) (gitserver.Changes, error) {
|
||||
panic("unexpected invocation of MockGitserverClient.GitDiff")
|
||||
},
|
||||
},
|
||||
LogReverseEachFunc: &GitserverClientLogReverseEachFunc{
|
||||
defaultHook: func(context.Context, string, string, int, func(entry gitdomain.LogEntry) error) error {
|
||||
panic("unexpected invocation of MockGitserverClient.LogReverseEach")
|
||||
@ -107,14 +108,14 @@ func NewStrictMockGitserverClient() *MockGitserverClient {
|
||||
// NewMockGitserverClientFrom creates a new mock of the MockGitserverClient
|
||||
// interface. All methods delegate to the given implementation, unless
|
||||
// overwritten.
|
||||
func NewMockGitserverClientFrom(i gitserver.GitserverClient) *MockGitserverClient {
|
||||
func NewMockGitserverClientFrom(i gitserver1.GitserverClient) *MockGitserverClient {
|
||||
return &MockGitserverClient{
|
||||
ChangedFilesFunc: &GitserverClientChangedFilesFunc{
|
||||
defaultHook: i.ChangedFiles,
|
||||
},
|
||||
FetchTarFunc: &GitserverClientFetchTarFunc{
|
||||
defaultHook: i.FetchTar,
|
||||
},
|
||||
GitDiffFunc: &GitserverClientGitDiffFunc{
|
||||
defaultHook: i.GitDiff,
|
||||
},
|
||||
LogReverseEachFunc: &GitserverClientLogReverseEachFunc{
|
||||
defaultHook: i.LogReverseEach,
|
||||
},
|
||||
@ -127,6 +128,121 @@ func NewMockGitserverClientFrom(i gitserver.GitserverClient) *MockGitserverClien
|
||||
}
|
||||
}
|
||||
|
||||
// GitserverClientChangedFilesFunc describes the behavior when the
|
||||
// ChangedFiles method of the parent MockGitserverClient instance is
|
||||
// invoked.
|
||||
type GitserverClientChangedFilesFunc struct {
|
||||
defaultHook func(context.Context, api.RepoName, api.CommitID, api.CommitID) (gitserver.ChangedFilesIterator, error)
|
||||
hooks []func(context.Context, api.RepoName, api.CommitID, api.CommitID) (gitserver.ChangedFilesIterator, error)
|
||||
history []GitserverClientChangedFilesFuncCall
|
||||
mutex sync.Mutex
|
||||
}
|
||||
|
||||
// ChangedFiles delegates to the next hook function in the queue and stores
|
||||
// the parameter and result values of this invocation.
|
||||
func (m *MockGitserverClient) ChangedFiles(v0 context.Context, v1 api.RepoName, v2 api.CommitID, v3 api.CommitID) (gitserver.ChangedFilesIterator, error) {
|
||||
r0, r1 := m.ChangedFilesFunc.nextHook()(v0, v1, v2, v3)
|
||||
m.ChangedFilesFunc.appendCall(GitserverClientChangedFilesFuncCall{v0, v1, v2, v3, r0, r1})
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// SetDefaultHook sets function that is called when the ChangedFiles method
|
||||
// of the parent MockGitserverClient instance is invoked and the hook queue
|
||||
// is empty.
|
||||
func (f *GitserverClientChangedFilesFunc) SetDefaultHook(hook func(context.Context, api.RepoName, api.CommitID, api.CommitID) (gitserver.ChangedFilesIterator, error)) {
|
||||
f.defaultHook = hook
|
||||
}
|
||||
|
||||
// PushHook adds a function to the end of hook queue. Each invocation of the
|
||||
// ChangedFiles method of the parent MockGitserverClient instance invokes
|
||||
// the hook at the front of the queue and discards it. After the queue is
|
||||
// empty, the default hook function is invoked for any future action.
|
||||
func (f *GitserverClientChangedFilesFunc) PushHook(hook func(context.Context, api.RepoName, api.CommitID, api.CommitID) (gitserver.ChangedFilesIterator, error)) {
|
||||
f.mutex.Lock()
|
||||
f.hooks = append(f.hooks, hook)
|
||||
f.mutex.Unlock()
|
||||
}
|
||||
|
||||
// SetDefaultReturn calls SetDefaultHook with a function that returns the
|
||||
// given values.
|
||||
func (f *GitserverClientChangedFilesFunc) SetDefaultReturn(r0 gitserver.ChangedFilesIterator, r1 error) {
|
||||
f.SetDefaultHook(func(context.Context, api.RepoName, api.CommitID, api.CommitID) (gitserver.ChangedFilesIterator, error) {
|
||||
return r0, r1
|
||||
})
|
||||
}
|
||||
|
||||
// PushReturn calls PushHook with a function that returns the given values.
|
||||
func (f *GitserverClientChangedFilesFunc) PushReturn(r0 gitserver.ChangedFilesIterator, r1 error) {
|
||||
f.PushHook(func(context.Context, api.RepoName, api.CommitID, api.CommitID) (gitserver.ChangedFilesIterator, error) {
|
||||
return r0, r1
|
||||
})
|
||||
}
|
||||
|
||||
func (f *GitserverClientChangedFilesFunc) nextHook() func(context.Context, api.RepoName, api.CommitID, api.CommitID) (gitserver.ChangedFilesIterator, error) {
|
||||
f.mutex.Lock()
|
||||
defer f.mutex.Unlock()
|
||||
|
||||
if len(f.hooks) == 0 {
|
||||
return f.defaultHook
|
||||
}
|
||||
|
||||
hook := f.hooks[0]
|
||||
f.hooks = f.hooks[1:]
|
||||
return hook
|
||||
}
|
||||
|
||||
func (f *GitserverClientChangedFilesFunc) appendCall(r0 GitserverClientChangedFilesFuncCall) {
|
||||
f.mutex.Lock()
|
||||
f.history = append(f.history, r0)
|
||||
f.mutex.Unlock()
|
||||
}
|
||||
|
||||
// History returns a sequence of GitserverClientChangedFilesFuncCall objects
|
||||
// describing the invocations of this function.
|
||||
func (f *GitserverClientChangedFilesFunc) History() []GitserverClientChangedFilesFuncCall {
|
||||
f.mutex.Lock()
|
||||
history := make([]GitserverClientChangedFilesFuncCall, len(f.history))
|
||||
copy(history, f.history)
|
||||
f.mutex.Unlock()
|
||||
|
||||
return history
|
||||
}
|
||||
|
||||
// GitserverClientChangedFilesFuncCall is an object that describes an
|
||||
// invocation of method ChangedFiles on an instance of MockGitserverClient.
|
||||
type GitserverClientChangedFilesFuncCall struct {
|
||||
// Arg0 is the value of the 1st argument passed to this method
|
||||
// invocation.
|
||||
Arg0 context.Context
|
||||
// Arg1 is the value of the 2nd argument passed to this method
|
||||
// invocation.
|
||||
Arg1 api.RepoName
|
||||
// Arg2 is the value of the 3rd argument passed to this method
|
||||
// invocation.
|
||||
Arg2 api.CommitID
|
||||
// Arg3 is the value of the 4th argument passed to this method
|
||||
// invocation.
|
||||
Arg3 api.CommitID
|
||||
// Result0 is the value of the 1st result returned from this method
|
||||
// invocation.
|
||||
Result0 gitserver.ChangedFilesIterator
|
||||
// Result1 is the value of the 2nd result returned from this method
|
||||
// invocation.
|
||||
Result1 error
|
||||
}
|
||||
|
||||
// Args returns an interface slice containing the arguments of this
|
||||
// invocation.
|
||||
func (c GitserverClientChangedFilesFuncCall) Args() []interface{} {
|
||||
return []interface{}{c.Arg0, c.Arg1, c.Arg2, c.Arg3}
|
||||
}
|
||||
|
||||
// Results returns an interface slice containing the results of this
|
||||
// invocation.
|
||||
func (c GitserverClientChangedFilesFuncCall) Results() []interface{} {
|
||||
return []interface{}{c.Result0, c.Result1}
|
||||
}
|
||||
|
||||
// GitserverClientFetchTarFunc describes the behavior when the FetchTar
|
||||
// method of the parent MockGitserverClient instance is invoked.
|
||||
type GitserverClientFetchTarFunc struct {
|
||||
@ -241,120 +357,6 @@ func (c GitserverClientFetchTarFuncCall) Results() []interface{} {
|
||||
return []interface{}{c.Result0, c.Result1}
|
||||
}
|
||||
|
||||
// GitserverClientGitDiffFunc describes the behavior when the GitDiff method
|
||||
// of the parent MockGitserverClient instance is invoked.
|
||||
type GitserverClientGitDiffFunc struct {
|
||||
defaultHook func(context.Context, api.RepoName, api.CommitID, api.CommitID) (gitserver.Changes, error)
|
||||
hooks []func(context.Context, api.RepoName, api.CommitID, api.CommitID) (gitserver.Changes, error)
|
||||
history []GitserverClientGitDiffFuncCall
|
||||
mutex sync.Mutex
|
||||
}
|
||||
|
||||
// GitDiff delegates to the next hook function in the queue and stores the
|
||||
// parameter and result values of this invocation.
|
||||
func (m *MockGitserverClient) GitDiff(v0 context.Context, v1 api.RepoName, v2 api.CommitID, v3 api.CommitID) (gitserver.Changes, error) {
|
||||
r0, r1 := m.GitDiffFunc.nextHook()(v0, v1, v2, v3)
|
||||
m.GitDiffFunc.appendCall(GitserverClientGitDiffFuncCall{v0, v1, v2, v3, r0, r1})
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// SetDefaultHook sets function that is called when the GitDiff method of
|
||||
// the parent MockGitserverClient instance is invoked and the hook queue is
|
||||
// empty.
|
||||
func (f *GitserverClientGitDiffFunc) SetDefaultHook(hook func(context.Context, api.RepoName, api.CommitID, api.CommitID) (gitserver.Changes, error)) {
|
||||
f.defaultHook = hook
|
||||
}
|
||||
|
||||
// PushHook adds a function to the end of hook queue. Each invocation of the
|
||||
// GitDiff method of the parent MockGitserverClient instance invokes the
|
||||
// hook at the front of the queue and discards it. After the queue is empty,
|
||||
// the default hook function is invoked for any future action.
|
||||
func (f *GitserverClientGitDiffFunc) PushHook(hook func(context.Context, api.RepoName, api.CommitID, api.CommitID) (gitserver.Changes, error)) {
|
||||
f.mutex.Lock()
|
||||
f.hooks = append(f.hooks, hook)
|
||||
f.mutex.Unlock()
|
||||
}
|
||||
|
||||
// SetDefaultReturn calls SetDefaultHook with a function that returns the
|
||||
// given values.
|
||||
func (f *GitserverClientGitDiffFunc) SetDefaultReturn(r0 gitserver.Changes, r1 error) {
|
||||
f.SetDefaultHook(func(context.Context, api.RepoName, api.CommitID, api.CommitID) (gitserver.Changes, error) {
|
||||
return r0, r1
|
||||
})
|
||||
}
|
||||
|
||||
// PushReturn calls PushHook with a function that returns the given values.
|
||||
func (f *GitserverClientGitDiffFunc) PushReturn(r0 gitserver.Changes, r1 error) {
|
||||
f.PushHook(func(context.Context, api.RepoName, api.CommitID, api.CommitID) (gitserver.Changes, error) {
|
||||
return r0, r1
|
||||
})
|
||||
}
|
||||
|
||||
func (f *GitserverClientGitDiffFunc) nextHook() func(context.Context, api.RepoName, api.CommitID, api.CommitID) (gitserver.Changes, error) {
|
||||
f.mutex.Lock()
|
||||
defer f.mutex.Unlock()
|
||||
|
||||
if len(f.hooks) == 0 {
|
||||
return f.defaultHook
|
||||
}
|
||||
|
||||
hook := f.hooks[0]
|
||||
f.hooks = f.hooks[1:]
|
||||
return hook
|
||||
}
|
||||
|
||||
func (f *GitserverClientGitDiffFunc) appendCall(r0 GitserverClientGitDiffFuncCall) {
|
||||
f.mutex.Lock()
|
||||
f.history = append(f.history, r0)
|
||||
f.mutex.Unlock()
|
||||
}
|
||||
|
||||
// History returns a sequence of GitserverClientGitDiffFuncCall objects
|
||||
// describing the invocations of this function.
|
||||
func (f *GitserverClientGitDiffFunc) History() []GitserverClientGitDiffFuncCall {
|
||||
f.mutex.Lock()
|
||||
history := make([]GitserverClientGitDiffFuncCall, len(f.history))
|
||||
copy(history, f.history)
|
||||
f.mutex.Unlock()
|
||||
|
||||
return history
|
||||
}
|
||||
|
||||
// GitserverClientGitDiffFuncCall is an object that describes an invocation
|
||||
// of method GitDiff on an instance of MockGitserverClient.
|
||||
type GitserverClientGitDiffFuncCall struct {
|
||||
// Arg0 is the value of the 1st argument passed to this method
|
||||
// invocation.
|
||||
Arg0 context.Context
|
||||
// Arg1 is the value of the 2nd argument passed to this method
|
||||
// invocation.
|
||||
Arg1 api.RepoName
|
||||
// Arg2 is the value of the 3rd argument passed to this method
|
||||
// invocation.
|
||||
Arg2 api.CommitID
|
||||
// Arg3 is the value of the 4th argument passed to this method
|
||||
// invocation.
|
||||
Arg3 api.CommitID
|
||||
// Result0 is the value of the 1st result returned from this method
|
||||
// invocation.
|
||||
Result0 gitserver.Changes
|
||||
// Result1 is the value of the 2nd result returned from this method
|
||||
// invocation.
|
||||
Result1 error
|
||||
}
|
||||
|
||||
// Args returns an interface slice containing the arguments of this
|
||||
// invocation.
|
||||
func (c GitserverClientGitDiffFuncCall) Args() []interface{} {
|
||||
return []interface{}{c.Arg0, c.Arg1, c.Arg2, c.Arg3}
|
||||
}
|
||||
|
||||
// Results returns an interface slice containing the results of this
|
||||
// invocation.
|
||||
func (c GitserverClientGitDiffFuncCall) Results() []interface{} {
|
||||
return []interface{}{c.Result0, c.Result1}
|
||||
}
|
||||
|
||||
// GitserverClientLogReverseEachFunc describes the behavior when the
|
||||
// LogReverseEach method of the parent MockGitserverClient instance is
|
||||
// invoked.
|
||||
|
||||
@ -16,6 +16,7 @@ go_library(
|
||||
"//cmd/symbols/parser",
|
||||
"//internal/api",
|
||||
"//internal/diskcache",
|
||||
"//internal/gitserver/gitdomain",
|
||||
"//internal/observation",
|
||||
"//internal/search",
|
||||
"//lib/errors",
|
||||
|
||||
@ -2,6 +2,7 @@ package writer
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"path/filepath"
|
||||
|
||||
"golang.org/x/sync/semaphore"
|
||||
@ -12,6 +13,7 @@ import (
|
||||
"github.com/sourcegraph/sourcegraph/cmd/symbols/parser"
|
||||
"github.com/sourcegraph/sourcegraph/internal/api"
|
||||
"github.com/sourcegraph/sourcegraph/internal/diskcache"
|
||||
"github.com/sourcegraph/sourcegraph/internal/gitserver/gitdomain"
|
||||
"github.com/sourcegraph/sourcegraph/internal/observation"
|
||||
"github.com/sourcegraph/sourcegraph/internal/search"
|
||||
"github.com/sourcegraph/sourcegraph/lib/errors"
|
||||
@ -111,16 +113,36 @@ func (w *databaseWriter) writeDBFile(ctx context.Context, args search.SymbolsPar
|
||||
func (w *databaseWriter) writeFileIncrementally(ctx context.Context, args search.SymbolsParameters, dbFile, newestDBFile, oldCommit string) (bool, error) {
|
||||
observability.SetParseAmount(ctx, observability.PartialParse)
|
||||
|
||||
changes, err := w.gitserverClient.GitDiff(ctx, args.Repo, api.CommitID(oldCommit), args.CommitID)
|
||||
changedFilesIterator, err := w.gitserverClient.ChangedFiles(ctx, args.Repo, api.CommitID(oldCommit), args.CommitID)
|
||||
if err != nil {
|
||||
return false, errors.Wrap(err, "gitserverClient.GitDiff")
|
||||
return false, errors.Wrap(err, "gitserverClient.ChangedFiles")
|
||||
}
|
||||
defer changedFilesIterator.Close()
|
||||
|
||||
// Paths to re-parse
|
||||
addedOrModifiedPaths := append(changes.Added, changes.Modified...)
|
||||
var addedOrModifiedPaths []string
|
||||
|
||||
// Paths to modify in the database
|
||||
addedModifiedOrDeletedPaths := append(addedOrModifiedPaths, changes.Deleted...)
|
||||
var addedModifiedOrDeletedPaths []string
|
||||
|
||||
for {
|
||||
c, err := changedFilesIterator.Next()
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return false, errors.Wrap(err, "iterating over changed files in git diff")
|
||||
}
|
||||
|
||||
switch c.Status {
|
||||
case gitdomain.AddedAMD, gitdomain.ModifiedAMD:
|
||||
addedOrModifiedPaths = append(addedOrModifiedPaths, c.Path)
|
||||
addedModifiedOrDeletedPaths = append(addedModifiedOrDeletedPaths, c.Path)
|
||||
case gitdomain.DeletedAMD:
|
||||
addedModifiedOrDeletedPaths = append(addedModifiedOrDeletedPaths, c.Path)
|
||||
}
|
||||
}
|
||||
|
||||
if err := copyFile(newestDBFile, dbFile); err != nil {
|
||||
return false, err
|
||||
|
||||
@ -377,6 +377,7 @@ type changedFilesIterator struct {
|
||||
closeChan chan struct{}
|
||||
|
||||
buffer []gitdomain.PathStatus
|
||||
index int
|
||||
}
|
||||
|
||||
func (i *changedFilesIterator) Next() (gitdomain.PathStatus, error) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user