mirror of
https://github.com/sourcegraph/sourcegraph.git
synced 2026-02-06 19:21:50 +00:00
codeintel: Support filtering precise indexes by indexer (#47733)
This commit is contained in:
parent
d4ca94a591
commit
0eb66f0ee4
@ -274,6 +274,16 @@ extend type Query {
|
||||
after: String
|
||||
): CodeIntelligenceConfigurationPolicyConnection!
|
||||
|
||||
"""
|
||||
A list of unique indexer keys queryable via the `preciseIndexes.indexerKey` filter.
|
||||
"""
|
||||
indexerKeys(
|
||||
"""
|
||||
If supplied, only indexers associated with the given repository will be returned.
|
||||
"""
|
||||
repo: ID
|
||||
): [String!]!
|
||||
|
||||
"""
|
||||
Query precise code intelligence indexes.
|
||||
"""
|
||||
@ -294,6 +304,11 @@ extend type Query {
|
||||
"""
|
||||
states: [PreciseIndexState!]
|
||||
|
||||
"""
|
||||
If supplied, only precise indexes created by an indexer with the given key are returned.
|
||||
"""
|
||||
indexerKey: String
|
||||
|
||||
"""
|
||||
If supplied, only precise indexes that are a dependency of the specified index are returned.
|
||||
"""
|
||||
|
||||
@ -47,6 +47,10 @@ func (r *Resolver) NodeResolvers() map[string]gql.NodeByIDFunc {
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Resolver) IndexerKeys(ctx context.Context, opts *resolverstubs.IndexerKeyQueryArgs) (_ []string, err error) {
|
||||
return r.autoIndexingRootResolver.IndexerKeys(ctx, opts)
|
||||
}
|
||||
|
||||
func (r *Resolver) LSIFUploadByID(ctx context.Context, id graphql.ID) (_ resolverstubs.LSIFUploadResolver, err error) {
|
||||
return r.uploadsRootResolver.LSIFUploadByID(ctx, id)
|
||||
}
|
||||
|
||||
@ -127,6 +127,15 @@ func (s *store) GetIndexes(ctx context.Context, opts shared.GetIndexesOptions) (
|
||||
conds = append(conds, sqlf.Sprintf("NOT EXISTS (SELECT 1 FROM lsif_uploads u2 WHERE u2.associated_index_id = u.id)"))
|
||||
}
|
||||
|
||||
if len(opts.IndexerNames) != 0 {
|
||||
var indexerConds []*sqlf.Query
|
||||
for _, indexerName := range opts.IndexerNames {
|
||||
indexerConds = append(indexerConds, sqlf.Sprintf("u.indexer ILIKE %s", "%"+indexerName+"%"))
|
||||
}
|
||||
|
||||
conds = append(conds, sqlf.Sprintf("(%s)", sqlf.Join(indexerConds, " OR ")))
|
||||
}
|
||||
|
||||
authzConds, err := database.AuthzQueryConds(ctx, database.NewDBWith(s.logger, tx.db))
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
|
||||
@ -180,8 +180,8 @@ func TestGetIndexes(t *testing.T) {
|
||||
types.Index{ID: 4, QueuedAt: t4, State: "queued", RepositoryID: 51, RepositoryName: "foo bar x"},
|
||||
types.Index{ID: 5, Commit: makeCommit(3333), QueuedAt: t5, State: "processing", AssociatedUploadID: &uploadID1},
|
||||
types.Index{ID: 6, QueuedAt: t6, State: "processing", RepositoryID: 52, RepositoryName: "foo bar y"},
|
||||
types.Index{ID: 7, QueuedAt: t7},
|
||||
types.Index{ID: 8, QueuedAt: t8},
|
||||
types.Index{ID: 7, QueuedAt: t7, Indexer: "lsif-typescript"},
|
||||
types.Index{ID: 8, QueuedAt: t8, Indexer: "scip-ocaml"},
|
||||
types.Index{ID: 9, QueuedAt: t9, State: "queued"},
|
||||
types.Index{ID: 10, QueuedAt: t10},
|
||||
)
|
||||
@ -197,6 +197,7 @@ func TestGetIndexes(t *testing.T) {
|
||||
state string
|
||||
states []string
|
||||
term string
|
||||
indexerNames []string
|
||||
withoutUpload bool
|
||||
expectedIDs []int
|
||||
}{
|
||||
@ -210,6 +211,7 @@ func TestGetIndexes(t *testing.T) {
|
||||
{state: "failed", expectedIDs: []int{2}}, // treats errored/failed states equivalently
|
||||
{states: []string{"completed", "failed"}, expectedIDs: []int{2, 7, 8, 10}}, // searches multiple states
|
||||
{withoutUpload: true, expectedIDs: []int{2, 4, 6, 7, 8, 9, 10}}, // anti-join with upload records
|
||||
{indexerNames: []string{"typescript", "ocaml"}, expectedIDs: []int{7, 8}}, // searches indexer name (only)
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
@ -220,12 +222,13 @@ func TestGetIndexes(t *testing.T) {
|
||||
}
|
||||
|
||||
name := fmt.Sprintf(
|
||||
"repositoryID=%d state=%s states=%s term=%s without_upload=%v offset=%d",
|
||||
"repositoryID=%d state=%s states=%s term=%s without_upload=%v indexer_names=%v offset=%d",
|
||||
testCase.repositoryID,
|
||||
testCase.state,
|
||||
strings.Join(testCase.states, ","),
|
||||
testCase.term,
|
||||
testCase.withoutUpload,
|
||||
testCase.indexerNames,
|
||||
lo,
|
||||
)
|
||||
|
||||
@ -235,6 +238,7 @@ func TestGetIndexes(t *testing.T) {
|
||||
State: testCase.state,
|
||||
States: testCase.states,
|
||||
Term: testCase.term,
|
||||
IndexerNames: testCase.indexerNames,
|
||||
WithoutUpload: testCase.withoutUpload,
|
||||
Limit: 3,
|
||||
Offset: lo,
|
||||
|
||||
@ -9,6 +9,7 @@ type GetIndexesOptions struct {
|
||||
State string
|
||||
States []string
|
||||
Term string
|
||||
IndexerNames []string
|
||||
WithoutUpload bool
|
||||
Limit int
|
||||
Offset int
|
||||
|
||||
@ -2,7 +2,6 @@ package graphql
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"github.com/sourcegraph/sourcegraph/enterprise/internal/codeintel/autoindexing/internal/inference"
|
||||
codeinteltypes "github.com/sourcegraph/sourcegraph/enterprise/internal/codeintel/shared/types"
|
||||
@ -84,7 +83,7 @@ func (r *codeIntelTreeInfoResolver) PreciseSupport(ctx context.Context) (resolve
|
||||
resolvers = append(resolvers, &codeIntelTreePreciseCoverageResolver{
|
||||
confidence: indexJobInfered,
|
||||
// drop the tag if it exists
|
||||
indexer: codeinteltypes.NewCodeIntelIndexerResolverFrom(codeinteltypes.ImageToIndexer[strings.Split(job.Indexer, ":")[0]]),
|
||||
indexer: codeinteltypes.NewCodeIntelIndexerResolver(job.Indexer),
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -104,7 +103,7 @@ func (r *codeIntelTreeInfoResolver) PreciseSupport(ctx context.Context) (resolve
|
||||
resolvers = append(resolvers, &codeIntelTreePreciseCoverageResolver{
|
||||
confidence: confidence,
|
||||
// expected that job hints don't include a tag in the indexer name
|
||||
indexer: codeinteltypes.NewCodeIntelIndexerResolverFrom(codeinteltypes.ImageToIndexer[hint.Indexer]),
|
||||
indexer: codeinteltypes.NewCodeIntelIndexerResolver(hint.Indexer),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -53,6 +53,7 @@ type UploadsService interface {
|
||||
GetLastUploadRetentionScanForRepository(ctx context.Context, repositoryID int) (_ *time.Time, err error)
|
||||
GetRecentUploadsSummary(ctx context.Context, repositoryID int) (upload []uploadshared.UploadsWithRepositoryNamespace, err error)
|
||||
GetUploads(ctx context.Context, opts uploadshared.GetUploadsOptions) (uploads []types.Upload, totalCount int, err error)
|
||||
GetIndexers(ctx context.Context, opts uploadshared.GetIndexersOptions) ([]string, error)
|
||||
GetAuditLogsForUpload(ctx context.Context, uploadID int) (_ []types.UploadLog, err error)
|
||||
GetListTags(ctx context.Context, repo api.RepoName, commitObjs ...string) (_ []*gitdomain.Tag, err error)
|
||||
GetUploadDocumentsForPath(ctx context.Context, bundleID int, pathPattern string) ([]string, int, error)
|
||||
|
||||
@ -3631,6 +3631,9 @@ type MockUploadsService struct {
|
||||
// GetAuditLogsForUploadFunc is an instance of a mock function object
|
||||
// controlling the behavior of the method GetAuditLogsForUpload.
|
||||
GetAuditLogsForUploadFunc *UploadsServiceGetAuditLogsForUploadFunc
|
||||
// GetIndexersFunc is an instance of a mock function object controlling
|
||||
// the behavior of the method GetIndexers.
|
||||
GetIndexersFunc *UploadsServiceGetIndexersFunc
|
||||
// GetLastUploadRetentionScanForRepositoryFunc is an instance of a mock
|
||||
// function object controlling the behavior of the method
|
||||
// GetLastUploadRetentionScanForRepository.
|
||||
@ -3681,6 +3684,11 @@ func NewMockUploadsService() *MockUploadsService {
|
||||
return
|
||||
},
|
||||
},
|
||||
GetIndexersFunc: &UploadsServiceGetIndexersFunc{
|
||||
defaultHook: func(context.Context, shared1.GetIndexersOptions) (r0 []string, r1 error) {
|
||||
return
|
||||
},
|
||||
},
|
||||
GetLastUploadRetentionScanForRepositoryFunc: &UploadsServiceGetLastUploadRetentionScanForRepositoryFunc{
|
||||
defaultHook: func(context.Context, int) (r0 *time.Time, r1 error) {
|
||||
return
|
||||
@ -3748,6 +3756,11 @@ func NewStrictMockUploadsService() *MockUploadsService {
|
||||
panic("unexpected invocation of MockUploadsService.GetAuditLogsForUpload")
|
||||
},
|
||||
},
|
||||
GetIndexersFunc: &UploadsServiceGetIndexersFunc{
|
||||
defaultHook: func(context.Context, shared1.GetIndexersOptions) ([]string, error) {
|
||||
panic("unexpected invocation of MockUploadsService.GetIndexers")
|
||||
},
|
||||
},
|
||||
GetLastUploadRetentionScanForRepositoryFunc: &UploadsServiceGetLastUploadRetentionScanForRepositoryFunc{
|
||||
defaultHook: func(context.Context, int) (*time.Time, error) {
|
||||
panic("unexpected invocation of MockUploadsService.GetLastUploadRetentionScanForRepository")
|
||||
@ -3810,6 +3823,9 @@ func NewMockUploadsServiceFrom(i UploadsService) *MockUploadsService {
|
||||
GetAuditLogsForUploadFunc: &UploadsServiceGetAuditLogsForUploadFunc{
|
||||
defaultHook: i.GetAuditLogsForUpload,
|
||||
},
|
||||
GetIndexersFunc: &UploadsServiceGetIndexersFunc{
|
||||
defaultHook: i.GetIndexers,
|
||||
},
|
||||
GetLastUploadRetentionScanForRepositoryFunc: &UploadsServiceGetLastUploadRetentionScanForRepositoryFunc{
|
||||
defaultHook: i.GetLastUploadRetentionScanForRepository,
|
||||
},
|
||||
@ -4167,6 +4183,114 @@ func (c UploadsServiceGetAuditLogsForUploadFuncCall) Results() []interface{} {
|
||||
return []interface{}{c.Result0, c.Result1}
|
||||
}
|
||||
|
||||
// UploadsServiceGetIndexersFunc describes the behavior when the GetIndexers
|
||||
// method of the parent MockUploadsService instance is invoked.
|
||||
type UploadsServiceGetIndexersFunc struct {
|
||||
defaultHook func(context.Context, shared1.GetIndexersOptions) ([]string, error)
|
||||
hooks []func(context.Context, shared1.GetIndexersOptions) ([]string, error)
|
||||
history []UploadsServiceGetIndexersFuncCall
|
||||
mutex sync.Mutex
|
||||
}
|
||||
|
||||
// GetIndexers delegates to the next hook function in the queue and stores
|
||||
// the parameter and result values of this invocation.
|
||||
func (m *MockUploadsService) GetIndexers(v0 context.Context, v1 shared1.GetIndexersOptions) ([]string, error) {
|
||||
r0, r1 := m.GetIndexersFunc.nextHook()(v0, v1)
|
||||
m.GetIndexersFunc.appendCall(UploadsServiceGetIndexersFuncCall{v0, v1, r0, r1})
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// SetDefaultHook sets function that is called when the GetIndexers method
|
||||
// of the parent MockUploadsService instance is invoked and the hook queue
|
||||
// is empty.
|
||||
func (f *UploadsServiceGetIndexersFunc) SetDefaultHook(hook func(context.Context, shared1.GetIndexersOptions) ([]string, error)) {
|
||||
f.defaultHook = hook
|
||||
}
|
||||
|
||||
// PushHook adds a function to the end of hook queue. Each invocation of the
|
||||
// GetIndexers method of the parent MockUploadsService 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 *UploadsServiceGetIndexersFunc) PushHook(hook func(context.Context, shared1.GetIndexersOptions) ([]string, 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 *UploadsServiceGetIndexersFunc) SetDefaultReturn(r0 []string, r1 error) {
|
||||
f.SetDefaultHook(func(context.Context, shared1.GetIndexersOptions) ([]string, error) {
|
||||
return r0, r1
|
||||
})
|
||||
}
|
||||
|
||||
// PushReturn calls PushHook with a function that returns the given values.
|
||||
func (f *UploadsServiceGetIndexersFunc) PushReturn(r0 []string, r1 error) {
|
||||
f.PushHook(func(context.Context, shared1.GetIndexersOptions) ([]string, error) {
|
||||
return r0, r1
|
||||
})
|
||||
}
|
||||
|
||||
func (f *UploadsServiceGetIndexersFunc) nextHook() func(context.Context, shared1.GetIndexersOptions) ([]string, 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 *UploadsServiceGetIndexersFunc) appendCall(r0 UploadsServiceGetIndexersFuncCall) {
|
||||
f.mutex.Lock()
|
||||
f.history = append(f.history, r0)
|
||||
f.mutex.Unlock()
|
||||
}
|
||||
|
||||
// History returns a sequence of UploadsServiceGetIndexersFuncCall objects
|
||||
// describing the invocations of this function.
|
||||
func (f *UploadsServiceGetIndexersFunc) History() []UploadsServiceGetIndexersFuncCall {
|
||||
f.mutex.Lock()
|
||||
history := make([]UploadsServiceGetIndexersFuncCall, len(f.history))
|
||||
copy(history, f.history)
|
||||
f.mutex.Unlock()
|
||||
|
||||
return history
|
||||
}
|
||||
|
||||
// UploadsServiceGetIndexersFuncCall is an object that describes an
|
||||
// invocation of method GetIndexers on an instance of MockUploadsService.
|
||||
type UploadsServiceGetIndexersFuncCall 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 shared1.GetIndexersOptions
|
||||
// Result0 is the value of the 1st result returned from this method
|
||||
// invocation.
|
||||
Result0 []string
|
||||
// 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 UploadsServiceGetIndexersFuncCall) Args() []interface{} {
|
||||
return []interface{}{c.Arg0, c.Arg1}
|
||||
}
|
||||
|
||||
// Results returns an interface slice containing the results of this
|
||||
// invocation.
|
||||
func (c UploadsServiceGetIndexersFuncCall) Results() []interface{} {
|
||||
return []interface{}{c.Result0, c.Result1}
|
||||
}
|
||||
|
||||
// UploadsServiceGetLastUploadRetentionScanForRepositoryFunc describes the
|
||||
// behavior when the GetLastUploadRetentionScanForRepository method of the
|
||||
// parent MockUploadsService instance is invoked.
|
||||
|
||||
@ -2,6 +2,7 @@ package graphql
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
@ -22,6 +23,38 @@ import (
|
||||
|
||||
const DefaultPageSize = 50
|
||||
|
||||
func (r *rootResolver) IndexerKeys(ctx context.Context, args *resolverstubs.IndexerKeyQueryArgs) ([]string, error) {
|
||||
var repositoryID int
|
||||
if args.Repo != nil {
|
||||
v, err := UnmarshalRepositoryID(*args.Repo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
repositoryID = int(v)
|
||||
}
|
||||
|
||||
indexers, err := r.uploadSvc.GetIndexers(ctx, uploadsshared.GetIndexersOptions{
|
||||
RepositoryID: repositoryID,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
keyMap := map[string]struct{}{}
|
||||
for _, indexer := range indexers {
|
||||
keyMap[types.NewCodeIntelIndexerResolver(indexer).Key()] = struct{}{}
|
||||
}
|
||||
|
||||
var keys []string
|
||||
for key := range keyMap {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
|
||||
return keys, nil
|
||||
}
|
||||
|
||||
func (r *rootResolver) PreciseIndexes(ctx context.Context, args *resolverstubs.PreciseIndexesQueryArgs) (_ resolverstubs.PreciseIndexConnectionResolver, err error) {
|
||||
ctx, errTracer, endObservation := r.operations.preciseIndexes.WithErrors(ctx, &err, observation.Args{LogFields: []log.Field{
|
||||
// log.String("uploadID", string(id)),
|
||||
@ -110,6 +143,11 @@ func (r *rootResolver) PreciseIndexes(ctx context.Context, args *resolverstubs.P
|
||||
term = *args.Query
|
||||
}
|
||||
|
||||
var indexerNames []string
|
||||
if args.IndexerKey != nil {
|
||||
indexerNames = types.NamesForKey(*args.IndexerKey)
|
||||
}
|
||||
|
||||
var uploads []types.Upload
|
||||
totalUploadCount := 0
|
||||
if !skipUploads {
|
||||
@ -119,6 +157,7 @@ func (r *rootResolver) PreciseIndexes(ctx context.Context, args *resolverstubs.P
|
||||
Term: term,
|
||||
DependencyOf: dependencyOf,
|
||||
DependentOf: dependentOf,
|
||||
IndexerNames: indexerNames,
|
||||
Limit: pageSize,
|
||||
Offset: uploadOffset,
|
||||
}); err != nil {
|
||||
@ -133,6 +172,7 @@ func (r *rootResolver) PreciseIndexes(ctx context.Context, args *resolverstubs.P
|
||||
RepositoryID: repositoryID,
|
||||
States: indexStates,
|
||||
Term: term,
|
||||
IndexerNames: indexerNames,
|
||||
WithoutUpload: true,
|
||||
Limit: pageSize,
|
||||
Offset: indexOffset,
|
||||
|
||||
@ -283,7 +283,7 @@ func (r *rootResolver) InferAutoIndexJobsForRepo(ctx context.Context, args *reso
|
||||
|
||||
resolvers = append(resolvers, &autoIndexJobDescriptionResolver{
|
||||
root: indexJob.Root,
|
||||
indexer: types.NewIndexerResolver(indexJob.Indexer),
|
||||
indexer: types.NewCodeIntelIndexerResolver(indexJob.Indexer),
|
||||
steps: sharedresolvers.NewIndexStepsResolver(r.autoindexSvc, types.Index{
|
||||
DockerSteps: steps,
|
||||
LocalSteps: indexJob.LocalSteps,
|
||||
|
||||
@ -124,10 +124,5 @@ func (r *indexResolver) ProjectRoot(ctx context.Context) (_ resolverstubs.GitTre
|
||||
}
|
||||
|
||||
func (r *indexResolver) Indexer() resolverstubs.CodeIntelIndexerResolver {
|
||||
// drop the tag if it exists
|
||||
if idx, ok := types.ImageToIndexer[strings.Split(strings.Split(r.index.Indexer, "@sha256:")[0], ":")[0]]; ok {
|
||||
return types.NewCodeIntelIndexerResolverFrom(idx)
|
||||
}
|
||||
|
||||
return types.NewCodeIntelIndexerResolver(r.index.Indexer)
|
||||
}
|
||||
|
||||
@ -1,8 +1,6 @@
|
||||
package sharedresolvers
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
autoindexingShared "github.com/sourcegraph/sourcegraph/enterprise/internal/codeintel/autoindexing/shared"
|
||||
"github.com/sourcegraph/sourcegraph/enterprise/internal/codeintel/shared/types"
|
||||
resolverstubs "github.com/sourcegraph/sourcegraph/internal/codeintel/resolvers"
|
||||
@ -25,11 +23,6 @@ func (r *lsifIndexesWithRepositoryNamespaceResolver) Root() string {
|
||||
}
|
||||
|
||||
func (r *lsifIndexesWithRepositoryNamespaceResolver) Indexer() resolverstubs.CodeIntelIndexerResolver {
|
||||
// drop the tag if it exists
|
||||
if idx, ok := types.ImageToIndexer[strings.Split(r.indexesSummary.Indexer, ":")[0]]; ok {
|
||||
return types.NewCodeIntelIndexerResolverFrom(idx)
|
||||
}
|
||||
|
||||
return types.NewCodeIntelIndexerResolver(r.indexesSummary.Indexer)
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
package types
|
||||
|
||||
import "strings"
|
||||
|
||||
type CodeIntelIndexerResolver interface {
|
||||
Key() string
|
||||
Name() string
|
||||
@ -10,24 +12,26 @@ type codeIntelIndexerResolver struct {
|
||||
indexer CodeIntelIndexer
|
||||
}
|
||||
|
||||
func NewIndexerResolver(indexerName string) CodeIntelIndexerResolver {
|
||||
for _, indexer := range AllIndexers {
|
||||
if indexer.Name == indexerName {
|
||||
return NewCodeIntelIndexerResolverFrom(indexer)
|
||||
}
|
||||
}
|
||||
|
||||
return NewCodeIntelIndexerResolver(indexerName)
|
||||
func NewCodeIntelIndexerResolver(name string) CodeIntelIndexerResolver {
|
||||
return NewCodeIntelIndexerResolverFrom(indexerFromName(name))
|
||||
}
|
||||
|
||||
func NewCodeIntelIndexerResolver(name string) CodeIntelIndexerResolver {
|
||||
for _, indexer := range AllIndexers {
|
||||
func indexerFromName(name string) CodeIntelIndexer {
|
||||
// drop the Docker image tag if one exists
|
||||
name = strings.Split(name, "@sha256:")[0]
|
||||
name = strings.Split(name, ":")[0]
|
||||
|
||||
if indexer, ok := imageToIndexer[name]; ok {
|
||||
return indexer
|
||||
}
|
||||
|
||||
for _, indexer := range allIndexers {
|
||||
if indexer.Name == name {
|
||||
return NewCodeIntelIndexerResolverFrom(indexer)
|
||||
return indexer
|
||||
}
|
||||
}
|
||||
|
||||
return NewCodeIntelIndexerResolverFrom(CodeIntelIndexer{Name: name})
|
||||
return CodeIntelIndexer{Name: name}
|
||||
}
|
||||
|
||||
func NewCodeIntelIndexerResolverFrom(indexer CodeIntelIndexer) CodeIntelIndexerResolver {
|
||||
|
||||
@ -9,9 +9,9 @@ type CodeIntelIndexer struct {
|
||||
DockerImages []string
|
||||
}
|
||||
|
||||
// AllIndexers is a list of all detectable/suggested indexers known to Sourcegraph.
|
||||
// allIndexers is a list of all detectable/suggested indexers known to Sourcegraph.
|
||||
// Two indexers with the same language key will be preferred according to the given order.
|
||||
var AllIndexers = []CodeIntelIndexer{
|
||||
var allIndexers = []CodeIntelIndexer{
|
||||
// C++
|
||||
makeInternalIndexer("C++", "lsif-clang"),
|
||||
makeInternalIndexer("C++", "lsif-cpp"),
|
||||
@ -62,6 +62,17 @@ var AllIndexers = []CodeIntelIndexer{
|
||||
makeInternalIndexer("TypeScript", "lsif-node"),
|
||||
}
|
||||
|
||||
func NamesForKey(key string) []string {
|
||||
var names []string
|
||||
for _, indexer := range allIndexers {
|
||||
if indexer.LanguageKey == key {
|
||||
names = append(names, indexer.Name)
|
||||
}
|
||||
}
|
||||
|
||||
return names
|
||||
}
|
||||
|
||||
var extensions = map[string][]string{
|
||||
"C++": {".c", ".cp", ".cpp", ".cxx", ".h", ".hpp"},
|
||||
"Dart": {".dart"},
|
||||
@ -79,9 +90,9 @@ var extensions = map[string][]string{
|
||||
"TypeScript": {".js", ".jsx", ".ts", ".tsx"},
|
||||
}
|
||||
|
||||
var ImageToIndexer = func() map[string]CodeIntelIndexer {
|
||||
var imageToIndexer = func() map[string]CodeIntelIndexer {
|
||||
m := map[string]CodeIntelIndexer{}
|
||||
for _, indexer := range AllIndexers {
|
||||
for _, indexer := range allIndexers {
|
||||
for _, dockerImage := range indexer.DockerImages {
|
||||
m[dockerImage] = indexer
|
||||
}
|
||||
@ -94,7 +105,7 @@ var PreferredIndexers = func() map[string]CodeIntelIndexer {
|
||||
preferred := map[string]CodeIntelIndexer{}
|
||||
|
||||
m := map[string]CodeIntelIndexer{}
|
||||
for _, indexer := range AllIndexers {
|
||||
for _, indexer := range allIndexers {
|
||||
if p, ok := preferred[indexer.LanguageKey]; ok {
|
||||
m[indexer.Name] = p
|
||||
} else {
|
||||
@ -109,7 +120,7 @@ var PreferredIndexers = func() map[string]CodeIntelIndexer {
|
||||
// A map of file extension to a list of indexers in order of recommendation from most to least.
|
||||
var LanguageToIndexer = func() map[string][]CodeIntelIndexer {
|
||||
m := map[string][]CodeIntelIndexer{}
|
||||
for _, indexer := range AllIndexers {
|
||||
for _, indexer := range allIndexers {
|
||||
for _, extension := range extensions[indexer.LanguageKey] {
|
||||
m[extension] = append(m[extension], indexer)
|
||||
}
|
||||
|
||||
@ -2425,6 +2425,9 @@ type MockStore struct {
|
||||
// function object controlling the behavior of the method
|
||||
// GetDumpsWithDefinitionsForMonikers.
|
||||
GetDumpsWithDefinitionsForMonikersFunc *StoreGetDumpsWithDefinitionsForMonikersFunc
|
||||
// GetIndexersFunc is an instance of a mock function object controlling
|
||||
// the behavior of the method GetIndexers.
|
||||
GetIndexersFunc *StoreGetIndexersFunc
|
||||
// GetLastUploadRetentionScanForRepositoryFunc is an instance of a mock
|
||||
// function object controlling the behavior of the method
|
||||
// GetLastUploadRetentionScanForRepository.
|
||||
@ -2652,6 +2655,11 @@ func NewMockStore() *MockStore {
|
||||
return
|
||||
},
|
||||
},
|
||||
GetIndexersFunc: &StoreGetIndexersFunc{
|
||||
defaultHook: func(context.Context, shared1.GetIndexersOptions) (r0 []string, r1 error) {
|
||||
return
|
||||
},
|
||||
},
|
||||
GetLastUploadRetentionScanForRepositoryFunc: &StoreGetLastUploadRetentionScanForRepositoryFunc{
|
||||
defaultHook: func(context.Context, int) (r0 *time.Time, r1 error) {
|
||||
return
|
||||
@ -2949,6 +2957,11 @@ func NewStrictMockStore() *MockStore {
|
||||
panic("unexpected invocation of MockStore.GetDumpsWithDefinitionsForMonikers")
|
||||
},
|
||||
},
|
||||
GetIndexersFunc: &StoreGetIndexersFunc{
|
||||
defaultHook: func(context.Context, shared1.GetIndexersOptions) ([]string, error) {
|
||||
panic("unexpected invocation of MockStore.GetIndexers")
|
||||
},
|
||||
},
|
||||
GetLastUploadRetentionScanForRepositoryFunc: &StoreGetLastUploadRetentionScanForRepositoryFunc{
|
||||
defaultHook: func(context.Context, int) (*time.Time, error) {
|
||||
panic("unexpected invocation of MockStore.GetLastUploadRetentionScanForRepository")
|
||||
@ -3212,6 +3225,9 @@ func NewMockStoreFrom(i store.Store) *MockStore {
|
||||
GetDumpsWithDefinitionsForMonikersFunc: &StoreGetDumpsWithDefinitionsForMonikersFunc{
|
||||
defaultHook: i.GetDumpsWithDefinitionsForMonikers,
|
||||
},
|
||||
GetIndexersFunc: &StoreGetIndexersFunc{
|
||||
defaultHook: i.GetIndexers,
|
||||
},
|
||||
GetLastUploadRetentionScanForRepositoryFunc: &StoreGetLastUploadRetentionScanForRepositoryFunc{
|
||||
defaultHook: i.GetLastUploadRetentionScanForRepository,
|
||||
},
|
||||
@ -5236,6 +5252,113 @@ func (c StoreGetDumpsWithDefinitionsForMonikersFuncCall) Results() []interface{}
|
||||
return []interface{}{c.Result0, c.Result1}
|
||||
}
|
||||
|
||||
// StoreGetIndexersFunc describes the behavior when the GetIndexers method
|
||||
// of the parent MockStore instance is invoked.
|
||||
type StoreGetIndexersFunc struct {
|
||||
defaultHook func(context.Context, shared1.GetIndexersOptions) ([]string, error)
|
||||
hooks []func(context.Context, shared1.GetIndexersOptions) ([]string, error)
|
||||
history []StoreGetIndexersFuncCall
|
||||
mutex sync.Mutex
|
||||
}
|
||||
|
||||
// GetIndexers delegates to the next hook function in the queue and stores
|
||||
// the parameter and result values of this invocation.
|
||||
func (m *MockStore) GetIndexers(v0 context.Context, v1 shared1.GetIndexersOptions) ([]string, error) {
|
||||
r0, r1 := m.GetIndexersFunc.nextHook()(v0, v1)
|
||||
m.GetIndexersFunc.appendCall(StoreGetIndexersFuncCall{v0, v1, r0, r1})
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// SetDefaultHook sets function that is called when the GetIndexers method
|
||||
// of the parent MockStore instance is invoked and the hook queue is empty.
|
||||
func (f *StoreGetIndexersFunc) SetDefaultHook(hook func(context.Context, shared1.GetIndexersOptions) ([]string, error)) {
|
||||
f.defaultHook = hook
|
||||
}
|
||||
|
||||
// PushHook adds a function to the end of hook queue. Each invocation of the
|
||||
// GetIndexers method of the parent MockStore 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 *StoreGetIndexersFunc) PushHook(hook func(context.Context, shared1.GetIndexersOptions) ([]string, 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 *StoreGetIndexersFunc) SetDefaultReturn(r0 []string, r1 error) {
|
||||
f.SetDefaultHook(func(context.Context, shared1.GetIndexersOptions) ([]string, error) {
|
||||
return r0, r1
|
||||
})
|
||||
}
|
||||
|
||||
// PushReturn calls PushHook with a function that returns the given values.
|
||||
func (f *StoreGetIndexersFunc) PushReturn(r0 []string, r1 error) {
|
||||
f.PushHook(func(context.Context, shared1.GetIndexersOptions) ([]string, error) {
|
||||
return r0, r1
|
||||
})
|
||||
}
|
||||
|
||||
func (f *StoreGetIndexersFunc) nextHook() func(context.Context, shared1.GetIndexersOptions) ([]string, 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 *StoreGetIndexersFunc) appendCall(r0 StoreGetIndexersFuncCall) {
|
||||
f.mutex.Lock()
|
||||
f.history = append(f.history, r0)
|
||||
f.mutex.Unlock()
|
||||
}
|
||||
|
||||
// History returns a sequence of StoreGetIndexersFuncCall objects describing
|
||||
// the invocations of this function.
|
||||
func (f *StoreGetIndexersFunc) History() []StoreGetIndexersFuncCall {
|
||||
f.mutex.Lock()
|
||||
history := make([]StoreGetIndexersFuncCall, len(f.history))
|
||||
copy(history, f.history)
|
||||
f.mutex.Unlock()
|
||||
|
||||
return history
|
||||
}
|
||||
|
||||
// StoreGetIndexersFuncCall is an object that describes an invocation of
|
||||
// method GetIndexers on an instance of MockStore.
|
||||
type StoreGetIndexersFuncCall 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 shared1.GetIndexersOptions
|
||||
// Result0 is the value of the 1st result returned from this method
|
||||
// invocation.
|
||||
Result0 []string
|
||||
// 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 StoreGetIndexersFuncCall) Args() []interface{} {
|
||||
return []interface{}{c.Arg0, c.Arg1}
|
||||
}
|
||||
|
||||
// Results returns an interface slice containing the results of this
|
||||
// invocation.
|
||||
func (c StoreGetIndexersFuncCall) Results() []interface{} {
|
||||
return []interface{}{c.Result0, c.Result1}
|
||||
}
|
||||
|
||||
// StoreGetLastUploadRetentionScanForRepositoryFunc describes the behavior
|
||||
// when the GetLastUploadRetentionScanForRepository method of the parent
|
||||
// MockStore instance is invoked.
|
||||
|
||||
@ -33,6 +33,7 @@ type operations struct {
|
||||
hasRepository *observation.Operation
|
||||
|
||||
// Uploads
|
||||
getIndexers *observation.Operation
|
||||
getUploads *observation.Operation
|
||||
getUploadByID *observation.Operation
|
||||
getUploadsByIDs *observation.Operation
|
||||
@ -127,6 +128,7 @@ func newOperations(observationCtx *observation.Context) *operations {
|
||||
hasRepository: op("HasRepository"),
|
||||
|
||||
// Uploads
|
||||
getIndexers: op("GetIndexers"),
|
||||
getUploads: op("GetUploads"),
|
||||
getUploadByID: op("GetUploadByID"),
|
||||
getUploadsByIDs: op("GetUploadsByIDs"),
|
||||
|
||||
@ -43,6 +43,7 @@ type Store interface {
|
||||
HasRepository(ctx context.Context, repositoryID int) (_ bool, err error)
|
||||
|
||||
// Uploads
|
||||
GetIndexers(ctx context.Context, opts shared.GetIndexersOptions) ([]string, error)
|
||||
GetUploads(ctx context.Context, opts shared.GetUploadsOptions) (_ []types.Upload, _ int, err error)
|
||||
GetUploadByID(ctx context.Context, id int) (_ types.Upload, _ bool, err error)
|
||||
GetUploadsByIDs(ctx context.Context, ids ...int) (_ []types.Upload, err error)
|
||||
|
||||
@ -27,6 +27,42 @@ import (
|
||||
"github.com/sourcegraph/sourcegraph/lib/errors"
|
||||
)
|
||||
|
||||
func (s *store) GetIndexers(ctx context.Context, opts shared.GetIndexersOptions) (_ []string, err error) {
|
||||
ctx, _, endObservation := s.operations.getIndexers.With(ctx, &err, observation.Args{LogFields: []log.Field{
|
||||
log.Int("repositoryID", opts.RepositoryID),
|
||||
}})
|
||||
defer endObservation(1, observation.Args{})
|
||||
|
||||
var conds []*sqlf.Query
|
||||
if opts.RepositoryID != 0 {
|
||||
conds = append(conds, sqlf.Sprintf("u.repository_id = %s", opts.RepositoryID))
|
||||
}
|
||||
|
||||
authzConds, err := database.AuthzQueryConds(ctx, database.NewDBWith(s.logger, s.db))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
conds = append(conds, authzConds)
|
||||
|
||||
return basestore.ScanStrings(s.db.Query(ctx, sqlf.Sprintf(getIndexersQuery, sqlf.Join(conds, "AND"))))
|
||||
}
|
||||
|
||||
const getIndexersQuery = `
|
||||
WITH
|
||||
combined_indexers AS (
|
||||
SELECT u.indexer, u.repository_id FROM lsif_uploads u
|
||||
UNION
|
||||
SELECT u.indexer, u.repository_id FROM lsif_indexes u
|
||||
)
|
||||
SELECT DISTINCT u.indexer
|
||||
FROM combined_indexers u
|
||||
JOIN repo r ON r.id = u.repository_id
|
||||
WHERE
|
||||
%s AND
|
||||
r.deleted_at IS NULL AND
|
||||
r.blocked IS NULL
|
||||
`
|
||||
|
||||
// GetUploads returns a list of uploads and the total count of records matching the given conditions.
|
||||
func (s *store) GetUploads(ctx context.Context, opts shared.GetUploadsOptions) (uploads []types.Upload, totalCount int, err error) {
|
||||
ctx, trace, endObservation := s.operations.getUploads.With(ctx, &err, observation.Args{LogFields: buildGetUploadsLogFields(opts)})
|
||||
@ -2051,6 +2087,15 @@ func buildGetConditionsAndCte(opts shared.GetUploadsOptions) (*sqlf.Query, []*sq
|
||||
)`, opts.DependentOf))
|
||||
}
|
||||
|
||||
if len(opts.IndexerNames) != 0 {
|
||||
var indexerConds []*sqlf.Query
|
||||
for _, indexerName := range opts.IndexerNames {
|
||||
indexerConds = append(indexerConds, sqlf.Sprintf("u.indexer ILIKE %s", "%"+indexerName+"%"))
|
||||
}
|
||||
|
||||
conds = append(conds, sqlf.Sprintf("(%s)", sqlf.Join(indexerConds, " OR ")))
|
||||
}
|
||||
|
||||
sourceTableExpr := sqlf.Sprintf("lsif_uploads u")
|
||||
if allowDeletedUploads {
|
||||
cteDefinitions = append(cteDefinitions, cteDefinition{
|
||||
|
||||
@ -17,7 +17,6 @@ import (
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/keegancsmith/sqlf"
|
||||
|
||||
"github.com/sourcegraph/log/logtest"
|
||||
|
||||
"github.com/sourcegraph/sourcegraph/cmd/frontend/globals"
|
||||
@ -33,6 +32,51 @@ import (
|
||||
"github.com/sourcegraph/sourcegraph/schema"
|
||||
)
|
||||
|
||||
func TestGetIndexers(t *testing.T) {
|
||||
logger := logtest.Scoped(t)
|
||||
db := database.NewDB(logger, dbtest.NewDB(logger, t))
|
||||
store := New(&observation.TestContext, db)
|
||||
ctx := context.Background()
|
||||
|
||||
insertUploads(t, db,
|
||||
types.Upload{ID: 1, Indexer: "scip-typescript"},
|
||||
types.Upload{ID: 2, Indexer: "scip-typescript"},
|
||||
types.Upload{ID: 3, Indexer: "scip-typescript"},
|
||||
types.Upload{ID: 4, Indexer: "scip-typescript"},
|
||||
types.Upload{ID: 5, Indexer: "scip-typescript"},
|
||||
types.Upload{ID: 6, Indexer: "lsif-ocaml", RepositoryID: 51},
|
||||
types.Upload{ID: 7, Indexer: "lsif-ocaml", RepositoryID: 51},
|
||||
types.Upload{ID: 8, Indexer: "third-party/scip-python@sha256:deadbeefdeadbeefdeadbeef", RepositoryID: 51},
|
||||
)
|
||||
|
||||
// Global
|
||||
indexers, err := store.GetIndexers(ctx, shared.GetIndexersOptions{})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error getting indexers: %s", err)
|
||||
}
|
||||
expectedIndexers := []string{
|
||||
"lsif-ocaml",
|
||||
"scip-typescript",
|
||||
"third-party/scip-python@sha256:deadbeefdeadbeefdeadbeef",
|
||||
}
|
||||
if diff := cmp.Diff(expectedIndexers, indexers); diff != "" {
|
||||
t.Errorf("unexpected indexers (-want +got):\n%s", diff)
|
||||
}
|
||||
|
||||
// Repo-specific
|
||||
indexers, err = store.GetIndexers(ctx, shared.GetIndexersOptions{RepositoryID: 51})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error getting indexers: %s", err)
|
||||
}
|
||||
expectedIndexers = []string{
|
||||
"lsif-ocaml",
|
||||
"third-party/scip-python@sha256:deadbeefdeadbeefdeadbeef",
|
||||
}
|
||||
if diff := cmp.Diff(expectedIndexers, indexers); diff != "" {
|
||||
t.Errorf("unexpected indexers (-want +got):\n%s", diff)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetUploads(t *testing.T) {
|
||||
logger := logtest.Scoped(t)
|
||||
db := database.NewDB(logger, dbtest.NewDB(logger, t))
|
||||
@ -60,9 +104,9 @@ func TestGetUploads(t *testing.T) {
|
||||
types.Upload{ID: 5, Commit: makeCommit(3333), UploadedAt: t5, Root: "sub1/", State: "processing", Indexer: "scip-typescript"},
|
||||
types.Upload{ID: 6, UploadedAt: t6, Root: "sub2/", State: "processing", RepositoryID: 52, RepositoryName: "foo bar y"},
|
||||
types.Upload{ID: 7, UploadedAt: t7, FinishedAt: &t4, Root: "sub1/", Indexer: "scip-typescript"},
|
||||
types.Upload{ID: 8, UploadedAt: t8, FinishedAt: &t4, Indexer: "scip-typescript"},
|
||||
types.Upload{ID: 8, UploadedAt: t8, FinishedAt: &t4, Indexer: "lsif-typescript"},
|
||||
types.Upload{ID: 9, UploadedAt: t9, State: "queued"},
|
||||
types.Upload{ID: 10, UploadedAt: t10, FinishedAt: &t6, Root: "sub1/", Indexer: "scip-typescript"},
|
||||
types.Upload{ID: 10, UploadedAt: t10, FinishedAt: &t6, Root: "sub1/", Indexer: "lsif-ocaml"},
|
||||
types.Upload{ID: 11, UploadedAt: t11, FinishedAt: &t6, Root: "sub1/", Indexer: "scip-typescript"},
|
||||
|
||||
// Deleted duplicates
|
||||
@ -116,6 +160,7 @@ func TestGetUploads(t *testing.T) {
|
||||
visibleAtTip bool
|
||||
dependencyOf int
|
||||
dependentOf int
|
||||
indexerNames []string
|
||||
uploadedBefore *time.Time
|
||||
uploadedAfter *time.Time
|
||||
inCommitGraph bool
|
||||
@ -129,13 +174,13 @@ func TestGetUploads(t *testing.T) {
|
||||
{oldestFirst: true, expectedIDs: []int{11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1}},
|
||||
{repositoryID: 50, expectedIDs: []int{1, 2, 3, 5, 7, 8, 9, 10, 11}},
|
||||
{state: "completed", expectedIDs: []int{7, 8, 10, 11}},
|
||||
{term: "sub", expectedIDs: []int{1, 3, 5, 6, 7, 10, 11}}, // searches root
|
||||
{term: "003", expectedIDs: []int{1, 3, 5}}, // searches commits
|
||||
{term: "333", expectedIDs: []int{1, 2, 3, 5}}, // searches commits and failure message
|
||||
{term: "typescript", expectedIDs: []int{2, 5, 7, 8, 10, 11}}, // searches indexer
|
||||
{term: "QuEuEd", expectedIDs: []int{1, 3, 4, 9}}, // searches text status
|
||||
{term: "bAr", expectedIDs: []int{4, 6}}, // search repo names
|
||||
{state: "failed", expectedIDs: []int{2}}, // treats errored/failed states equivalently
|
||||
{term: "sub", expectedIDs: []int{1, 3, 5, 6, 7, 10, 11}}, // searches root
|
||||
{term: "003", expectedIDs: []int{1, 3, 5}}, // searches commits
|
||||
{term: "333", expectedIDs: []int{1, 2, 3, 5}}, // searches commits and failure message
|
||||
{term: "typescript", expectedIDs: []int{2, 5, 7, 8, 11}}, // searches indexer
|
||||
{term: "QuEuEd", expectedIDs: []int{1, 3, 4, 9}}, // searches text status
|
||||
{term: "bAr", expectedIDs: []int{4, 6}}, // search repo names
|
||||
{state: "failed", expectedIDs: []int{2}}, // treats errored/failed states equivalently
|
||||
{visibleAtTip: true, expectedIDs: []int{2, 5, 7, 8}},
|
||||
{uploadedBefore: &t5, expectedIDs: []int{6, 7, 8, 9, 10, 11}},
|
||||
{uploadedAfter: &t4, expectedIDs: []int{1, 2, 3}},
|
||||
@ -148,6 +193,7 @@ func TestGetUploads(t *testing.T) {
|
||||
{dependentOf: 10, expectedIDs: []int{}},
|
||||
{dependencyOf: 11, expectedIDs: []int{8}},
|
||||
{dependentOf: 11, expectedIDs: []int{}},
|
||||
{indexerNames: []string{"typescript", "ocaml"}, expectedIDs: []int{2, 5, 7, 8, 10, 11}}, // search indexer names (only)
|
||||
{allowDeletedRepo: true, state: "deleted", expectedIDs: []int{12, 13, 14, 15}},
|
||||
{allowDeletedRepo: true, state: "deleted", alllowDeletedUpload: true, expectedIDs: []int{12, 13, 14, 15, 16, 17}},
|
||||
{states: []string{"completed", "failed"}, expectedIDs: []int{2, 7, 8, 10, 11}},
|
||||
@ -155,7 +201,7 @@ func TestGetUploads(t *testing.T) {
|
||||
|
||||
runTest := func(testCase testCase, lo, hi int) (errors int) {
|
||||
name := fmt.Sprintf(
|
||||
"repositoryID=%d|state='%s'|states='%s',term='%s'|visibleAtTip=%v|dependencyOf=%d|dependentOf=%d|offset=%d",
|
||||
"repositoryID=%d|state='%s'|states='%s',term='%s'|visibleAtTip=%v|dependencyOf=%d|dependentOf=%d|indexersNames=%v|offset=%d",
|
||||
testCase.repositoryID,
|
||||
testCase.state,
|
||||
strings.Join(testCase.states, ","),
|
||||
@ -163,6 +209,7 @@ func TestGetUploads(t *testing.T) {
|
||||
testCase.visibleAtTip,
|
||||
testCase.dependencyOf,
|
||||
testCase.dependentOf,
|
||||
testCase.indexerNames,
|
||||
lo,
|
||||
)
|
||||
|
||||
@ -175,6 +222,7 @@ func TestGetUploads(t *testing.T) {
|
||||
VisibleAtTip: testCase.visibleAtTip,
|
||||
DependencyOf: testCase.dependencyOf,
|
||||
DependentOf: testCase.dependentOf,
|
||||
IndexerNames: testCase.indexerNames,
|
||||
UploadedBefore: testCase.uploadedBefore,
|
||||
UploadedAfter: testCase.uploadedAfter,
|
||||
InCommitGraph: testCase.inCommitGraph,
|
||||
|
||||
123
enterprise/internal/codeintel/uploads/mocks_test.go
generated
123
enterprise/internal/codeintel/uploads/mocks_test.go
generated
@ -96,6 +96,9 @@ type MockStore struct {
|
||||
// function object controlling the behavior of the method
|
||||
// GetDumpsWithDefinitionsForMonikers.
|
||||
GetDumpsWithDefinitionsForMonikersFunc *StoreGetDumpsWithDefinitionsForMonikersFunc
|
||||
// GetIndexersFunc is an instance of a mock function object controlling
|
||||
// the behavior of the method GetIndexers.
|
||||
GetIndexersFunc *StoreGetIndexersFunc
|
||||
// GetLastUploadRetentionScanForRepositoryFunc is an instance of a mock
|
||||
// function object controlling the behavior of the method
|
||||
// GetLastUploadRetentionScanForRepository.
|
||||
@ -323,6 +326,11 @@ func NewMockStore() *MockStore {
|
||||
return
|
||||
},
|
||||
},
|
||||
GetIndexersFunc: &StoreGetIndexersFunc{
|
||||
defaultHook: func(context.Context, shared.GetIndexersOptions) (r0 []string, r1 error) {
|
||||
return
|
||||
},
|
||||
},
|
||||
GetLastUploadRetentionScanForRepositoryFunc: &StoreGetLastUploadRetentionScanForRepositoryFunc{
|
||||
defaultHook: func(context.Context, int) (r0 *time.Time, r1 error) {
|
||||
return
|
||||
@ -620,6 +628,11 @@ func NewStrictMockStore() *MockStore {
|
||||
panic("unexpected invocation of MockStore.GetDumpsWithDefinitionsForMonikers")
|
||||
},
|
||||
},
|
||||
GetIndexersFunc: &StoreGetIndexersFunc{
|
||||
defaultHook: func(context.Context, shared.GetIndexersOptions) ([]string, error) {
|
||||
panic("unexpected invocation of MockStore.GetIndexers")
|
||||
},
|
||||
},
|
||||
GetLastUploadRetentionScanForRepositoryFunc: &StoreGetLastUploadRetentionScanForRepositoryFunc{
|
||||
defaultHook: func(context.Context, int) (*time.Time, error) {
|
||||
panic("unexpected invocation of MockStore.GetLastUploadRetentionScanForRepository")
|
||||
@ -883,6 +896,9 @@ func NewMockStoreFrom(i store.Store) *MockStore {
|
||||
GetDumpsWithDefinitionsForMonikersFunc: &StoreGetDumpsWithDefinitionsForMonikersFunc{
|
||||
defaultHook: i.GetDumpsWithDefinitionsForMonikers,
|
||||
},
|
||||
GetIndexersFunc: &StoreGetIndexersFunc{
|
||||
defaultHook: i.GetIndexers,
|
||||
},
|
||||
GetLastUploadRetentionScanForRepositoryFunc: &StoreGetLastUploadRetentionScanForRepositoryFunc{
|
||||
defaultHook: i.GetLastUploadRetentionScanForRepository,
|
||||
},
|
||||
@ -2907,6 +2923,113 @@ func (c StoreGetDumpsWithDefinitionsForMonikersFuncCall) Results() []interface{}
|
||||
return []interface{}{c.Result0, c.Result1}
|
||||
}
|
||||
|
||||
// StoreGetIndexersFunc describes the behavior when the GetIndexers method
|
||||
// of the parent MockStore instance is invoked.
|
||||
type StoreGetIndexersFunc struct {
|
||||
defaultHook func(context.Context, shared.GetIndexersOptions) ([]string, error)
|
||||
hooks []func(context.Context, shared.GetIndexersOptions) ([]string, error)
|
||||
history []StoreGetIndexersFuncCall
|
||||
mutex sync.Mutex
|
||||
}
|
||||
|
||||
// GetIndexers delegates to the next hook function in the queue and stores
|
||||
// the parameter and result values of this invocation.
|
||||
func (m *MockStore) GetIndexers(v0 context.Context, v1 shared.GetIndexersOptions) ([]string, error) {
|
||||
r0, r1 := m.GetIndexersFunc.nextHook()(v0, v1)
|
||||
m.GetIndexersFunc.appendCall(StoreGetIndexersFuncCall{v0, v1, r0, r1})
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// SetDefaultHook sets function that is called when the GetIndexers method
|
||||
// of the parent MockStore instance is invoked and the hook queue is empty.
|
||||
func (f *StoreGetIndexersFunc) SetDefaultHook(hook func(context.Context, shared.GetIndexersOptions) ([]string, error)) {
|
||||
f.defaultHook = hook
|
||||
}
|
||||
|
||||
// PushHook adds a function to the end of hook queue. Each invocation of the
|
||||
// GetIndexers method of the parent MockStore 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 *StoreGetIndexersFunc) PushHook(hook func(context.Context, shared.GetIndexersOptions) ([]string, 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 *StoreGetIndexersFunc) SetDefaultReturn(r0 []string, r1 error) {
|
||||
f.SetDefaultHook(func(context.Context, shared.GetIndexersOptions) ([]string, error) {
|
||||
return r0, r1
|
||||
})
|
||||
}
|
||||
|
||||
// PushReturn calls PushHook with a function that returns the given values.
|
||||
func (f *StoreGetIndexersFunc) PushReturn(r0 []string, r1 error) {
|
||||
f.PushHook(func(context.Context, shared.GetIndexersOptions) ([]string, error) {
|
||||
return r0, r1
|
||||
})
|
||||
}
|
||||
|
||||
func (f *StoreGetIndexersFunc) nextHook() func(context.Context, shared.GetIndexersOptions) ([]string, 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 *StoreGetIndexersFunc) appendCall(r0 StoreGetIndexersFuncCall) {
|
||||
f.mutex.Lock()
|
||||
f.history = append(f.history, r0)
|
||||
f.mutex.Unlock()
|
||||
}
|
||||
|
||||
// History returns a sequence of StoreGetIndexersFuncCall objects describing
|
||||
// the invocations of this function.
|
||||
func (f *StoreGetIndexersFunc) History() []StoreGetIndexersFuncCall {
|
||||
f.mutex.Lock()
|
||||
history := make([]StoreGetIndexersFuncCall, len(f.history))
|
||||
copy(history, f.history)
|
||||
f.mutex.Unlock()
|
||||
|
||||
return history
|
||||
}
|
||||
|
||||
// StoreGetIndexersFuncCall is an object that describes an invocation of
|
||||
// method GetIndexers on an instance of MockStore.
|
||||
type StoreGetIndexersFuncCall 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 shared.GetIndexersOptions
|
||||
// Result0 is the value of the 1st result returned from this method
|
||||
// invocation.
|
||||
Result0 []string
|
||||
// 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 StoreGetIndexersFuncCall) Args() []interface{} {
|
||||
return []interface{}{c.Arg0, c.Arg1}
|
||||
}
|
||||
|
||||
// Results returns an interface slice containing the results of this
|
||||
// invocation.
|
||||
func (c StoreGetIndexersFuncCall) Results() []interface{} {
|
||||
return []interface{}{c.Result0, c.Result1}
|
||||
}
|
||||
|
||||
// StoreGetLastUploadRetentionScanForRepositoryFunc describes the behavior
|
||||
// when the GetLastUploadRetentionScanForRepository method of the parent
|
||||
// MockStore instance is invoked.
|
||||
|
||||
@ -32,6 +32,7 @@ type operations struct {
|
||||
getRepositoriesMaxStaleAge *observation.Operation
|
||||
|
||||
// Uploads
|
||||
getIndexers *observation.Operation
|
||||
getUploads *observation.Operation
|
||||
getUploadByID *observation.Operation
|
||||
getUploadsByIDs *observation.Operation
|
||||
@ -145,6 +146,7 @@ func newOperations(observationCtx *observation.Context) *operations {
|
||||
getRepositoriesMaxStaleAge: op("GetRepositoriesMaxStaleAge"),
|
||||
|
||||
// Uploads
|
||||
getIndexers: op("GetIndexers"),
|
||||
getUploads: op("GetUploads"),
|
||||
getUploadByID: op("GetUploadByID"),
|
||||
getUploadsByIDs: op("GetUploadsByIDs"),
|
||||
|
||||
@ -115,6 +115,15 @@ func (s *Service) GetDirtyRepositories(ctx context.Context) (_ map[int]int, err
|
||||
return s.store.GetDirtyRepositories(ctx)
|
||||
}
|
||||
|
||||
func (s *Service) GetIndexers(ctx context.Context, opts shared.GetIndexersOptions) (_ []string, err error) {
|
||||
ctx, _, endObservation := s.operations.getIndexers.With(ctx, &err, observation.Args{
|
||||
LogFields: []log.Field{log.Int("repositoryID", opts.RepositoryID)},
|
||||
})
|
||||
defer endObservation(1, observation.Args{})
|
||||
|
||||
return s.store.GetIndexers(ctx, opts)
|
||||
}
|
||||
|
||||
func (s *Service) GetUploads(ctx context.Context, opts shared.GetUploadsOptions) (uploads []types.Upload, totalCount int, err error) {
|
||||
ctx, _, endObservation := s.operations.getUploads.With(ctx, &err, observation.Args{
|
||||
LogFields: []log.Field{log.Int("repositoryID", opts.RepositoryID), log.String("state", opts.State), log.String("term", opts.Term)},
|
||||
|
||||
@ -14,6 +14,10 @@ type SourcedCommits struct {
|
||||
Commits []string
|
||||
}
|
||||
|
||||
type GetIndexersOptions struct {
|
||||
RepositoryID int
|
||||
}
|
||||
|
||||
type GetUploadsOptions struct {
|
||||
RepositoryID int
|
||||
State string
|
||||
@ -22,6 +26,7 @@ type GetUploadsOptions struct {
|
||||
VisibleAtTip bool
|
||||
DependencyOf int
|
||||
DependentOf int
|
||||
IndexerNames []string
|
||||
UploadedBefore *time.Time
|
||||
UploadedAfter *time.Time
|
||||
LastRetentionScanBefore *time.Time
|
||||
|
||||
@ -47,6 +47,7 @@ type AutoindexingServiceResolver interface {
|
||||
UpdateCodeIntelligenceInferenceScript(ctx context.Context, args *UpdateCodeIntelligenceInferenceScriptArgs) (*EmptyResponse, error)
|
||||
|
||||
PreciseIndexByID(ctx context.Context, id graphql.ID) (PreciseIndexResolver, error)
|
||||
IndexerKeys(ctx context.Context, args *IndexerKeyQueryArgs) ([]string, error)
|
||||
PreciseIndexes(ctx context.Context, args *PreciseIndexesQueryArgs) (PreciseIndexConnectionResolver, error)
|
||||
DeletePreciseIndex(ctx context.Context, args *struct{ ID graphql.ID }) (*EmptyResponse, error)
|
||||
DeletePreciseIndexes(ctx context.Context, args *DeletePreciseIndexesArgs) (*EmptyResponse, error)
|
||||
@ -126,12 +127,17 @@ type CodeIntelRepositorySummaryResolver interface {
|
||||
LimitError() *string
|
||||
}
|
||||
|
||||
type IndexerKeyQueryArgs struct {
|
||||
Repo *graphql.ID
|
||||
}
|
||||
|
||||
type PreciseIndexesQueryArgs struct {
|
||||
graphqlutil.ConnectionArgs
|
||||
After *string
|
||||
Repo *graphql.ID
|
||||
Query *string
|
||||
States *[]string
|
||||
IndexerKey *string
|
||||
DependencyOf *string
|
||||
DependentOf *string
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user