gitserver: Make gitserver code internal (#57122)

* gitserver: Make gitserver code internal

This puts the code of gitserver into a package called internal, to prevent imports from it from other binaries. This is in line with what our other services do, and prevents us from accidentally importing from gitserver, which could have undesirable side-effects like metrics registered that are not used and so forth.

* Fixup bad imports in test packages

The integration_tests package and a few of the client tests needed to be moved into the gitserver package - this doesn't feel wrong to me as when they do test the server code, they really are an integration test and not just an isolated client test anymore.
This commit is contained in:
Erik Seliger 2023-10-04 14:14:47 +02:00 committed by GitHub
parent 96ffbeaacb
commit 600916f4ec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
91 changed files with 798 additions and 741 deletions

View File

@ -1,8 +1,8 @@
load("//dev:go_defs.bzl", "go_test")
load("@io_bazel_rules_go//go:def.bzl", "go_library")
load("//dev:go_defs.bzl", "go_test")
go_library(
name = "server",
name = "internal",
srcs = [
"cleanup.go",
"clone.go",
@ -33,16 +33,16 @@ go_library(
"vcs_syncer_rust_packages.go",
],
embedsrcs = ["sg_maintenance.sh"],
importpath = "github.com/sourcegraph/sourcegraph/cmd/gitserver/server",
visibility = ["//visibility:public"],
importpath = "github.com/sourcegraph/sourcegraph/cmd/gitserver/internal",
visibility = ["//cmd/gitserver:__subpackages__"],
deps = [
"//cmd/frontend/envvar",
"//cmd/gitserver/server/accesslog",
"//cmd/gitserver/server/common",
"//cmd/gitserver/server/internal/cacert",
"//cmd/gitserver/server/perforce",
"//cmd/gitserver/server/sshagent",
"//cmd/gitserver/server/urlredactor",
"//cmd/gitserver/internal/accesslog",
"//cmd/gitserver/internal/cacert",
"//cmd/gitserver/internal/common",
"//cmd/gitserver/internal/perforce",
"//cmd/gitserver/internal/sshagent",
"//cmd/gitserver/internal/urlredactor",
"//internal/actor",
"//internal/api",
"//internal/codeintel/dependencies",
@ -109,7 +109,7 @@ go_library(
)
go_test(
name = "server_test",
name = "internal_test",
timeout = "moderate",
srcs = [
"cleanup_test.go",
@ -127,7 +127,7 @@ go_test(
"vcs_syncer_python_packages_test.go",
],
data = glob(["testdata/**"]),
embed = [":server"],
embed = [":internal"],
# This test loads coursier as a side effect, so we ensure the
# path is sandboxed properly.
env = {"COURSIER_CACHE_DIR": "/tmp"},
@ -136,8 +136,8 @@ go_test(
"requires-network",
],
deps = [
"//cmd/gitserver/server/common",
"//cmd/gitserver/server/perforce",
"//cmd/gitserver/internal/common",
"//cmd/gitserver/internal/perforce",
"//internal/actor",
"//internal/api",
"//internal/codeintel/dependencies",

View File

@ -1,10 +1,10 @@
load("//dev:go_defs.bzl", "go_test")
load("@io_bazel_rules_go//go:def.bzl", "go_library")
load("//dev:go_defs.bzl", "go_test")
go_library(
name = "accesslog",
srcs = ["accesslog.go"],
importpath = "github.com/sourcegraph/sourcegraph/cmd/gitserver/server/accesslog",
importpath = "github.com/sourcegraph/sourcegraph/cmd/gitserver/internal/accesslog",
visibility = ["//cmd/gitserver:__subpackages__"],
deps = [
"//internal/audit",

View File

@ -1,5 +1,5 @@
load("//dev:go_defs.bzl", "go_test")
load("@io_bazel_rules_go//go:def.bzl", "go_library")
load("//dev:go_defs.bzl", "go_test")
go_library(
name = "cacert",
@ -9,8 +9,8 @@ go_library(
"root_other.go",
"root_unix.go",
],
importpath = "github.com/sourcegraph/sourcegraph/cmd/gitserver/server/internal/cacert",
visibility = ["//cmd/gitserver/server:__subpackages__"],
importpath = "github.com/sourcegraph/sourcegraph/cmd/gitserver/internal/cacert",
visibility = ["//cmd/gitserver:__subpackages__"],
deps = ["//internal/syncx"],
)

View File

@ -5,7 +5,7 @@ import (
"runtime"
"testing"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/server/internal/cacert"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/internal/cacert"
)
func TestSystem(t *testing.T) {

View File

@ -1,4 +1,4 @@
package server
package internal
import (
"bytes"
@ -22,7 +22,7 @@ import (
"github.com/sourcegraph/log"
"github.com/sourcegraph/sourcegraph/cmd/frontend/envvar"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/server/common"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/internal/common"
"github.com/sourcegraph/sourcegraph/internal/actor"
"github.com/sourcegraph/sourcegraph/internal/api"
"github.com/sourcegraph/sourcegraph/internal/conf"

View File

@ -1,4 +1,4 @@
package server
package internal
import (
"context"
@ -20,7 +20,7 @@ import (
"github.com/sourcegraph/log/logtest"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/server/common"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/internal/common"
"github.com/sourcegraph/sourcegraph/internal/actor"
"github.com/sourcegraph/sourcegraph/internal/api"
"github.com/sourcegraph/sourcegraph/internal/database"

View File

@ -1,4 +1,4 @@
package server
package internal
import (
"context"

View File

@ -1,4 +1,4 @@
package server
package internal
import (
"encoding/json"
@ -6,7 +6,7 @@ import (
"github.com/sourcegraph/log"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/server/accesslog"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/internal/accesslog"
"github.com/sourcegraph/sourcegraph/internal/gitserver/gitdomain"
"github.com/sourcegraph/sourcegraph/internal/gitserver/protocol"
)

View File

@ -1,5 +1,5 @@
load("//dev:go_defs.bzl", "go_test")
load("@io_bazel_rules_go//go:def.bzl", "go_library")
load("//dev:go_defs.bzl", "go_test")
go_library(
name = "common",
@ -7,8 +7,8 @@ go_library(
"common.go",
"queue.go",
],
importpath = "github.com/sourcegraph/sourcegraph/cmd/gitserver/server/common",
visibility = ["//visibility:public"],
importpath = "github.com/sourcegraph/sourcegraph/cmd/gitserver/internal/common",
visibility = ["//cmd/gitserver:__subpackages__"],
deps = [
"//internal/observation",
"@com_github_prometheus_client_golang//prometheus",

View File

@ -1,4 +1,4 @@
package server
package internal
import (
"context"
@ -7,6 +7,7 @@ import (
"strings"
"github.com/sourcegraph/log"
"github.com/sourcegraph/sourcegraph/internal/conf"
"github.com/sourcegraph/sourcegraph/internal/env"
"github.com/sourcegraph/sourcegraph/internal/vcs"

View File

@ -1,4 +1,4 @@
package server
package internal
import (
"context"

View File

@ -1,4 +1,4 @@
package server
package internal
import (
"net/http"

View File

@ -1,4 +1,4 @@
package server
package internal
import (
"context"
@ -14,7 +14,7 @@ import (
"github.com/sourcegraph/log"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/server/accesslog"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/internal/accesslog"
"github.com/sourcegraph/sourcegraph/internal/api"
"github.com/sourcegraph/sourcegraph/internal/env"
"github.com/sourcegraph/sourcegraph/lib/gitservice"

View File

@ -1,16 +1,13 @@
load("//dev:go_defs.bzl", "go_test")
load("@io_bazel_rules_go//go:def.bzl", "go_library")
load("//dev:go_defs.bzl", "go_test")
go_library(
name = "integration_tests",
srcs = [
"doc.go",
"test_utils.go",
],
importpath = "github.com/sourcegraph/sourcegraph/internal/gitserver/integration_tests",
visibility = ["//:__subpackages__"],
srcs = ["test_utils.go"],
importpath = "github.com/sourcegraph/sourcegraph/cmd/gitserver/internal/integration_tests",
visibility = ["//cmd/gitserver:__subpackages__"],
deps = [
"//cmd/gitserver/server",
"//cmd/gitserver/internal",
"//internal/api",
"//internal/database/dbmocks",
"//internal/extsvc",
@ -33,9 +30,11 @@ go_test(
name = "integration_tests_test",
timeout = "short",
srcs = [
"archivereader_test.go",
"commits_test.go",
"main_test.go",
"object_test.go",
"resolverevisions_test.go",
"tree_test.go",
],
embed = [":integration_tests"],
@ -43,18 +42,34 @@ go_test(
# path is sandboxed properly.
env = {"COURSIER_CACHE_DIR": "/tmp"},
deps = [
"//cmd/gitserver/internal",
"//cmd/gitserver/internal/perforce",
"//internal/actor",
"//internal/api",
"//internal/authz",
"//internal/authz/subrepoperms",
"//internal/conf",
"//internal/database",
"//internal/database/dbmocks",
"//internal/extsvc",
"//internal/gitserver",
"//internal/gitserver/gitdomain",
"//internal/gitserver/protocol",
"//internal/gitserver/v1:gitserver",
"//internal/grpc",
"//internal/grpc/defaults",
"//internal/observation",
"//internal/ratelimit",
"//internal/types",
"//internal/wrexec",
"//lib/errors",
"//schema",
"@com_github_google_go_cmp//cmp",
"@com_github_sourcegraph_log//:log",
"@com_github_sourcegraph_log//logtest",
"@com_github_stretchr_testify//require",
"@com_github_tj_assert//:assert",
"@org_golang_google_grpc//:go_default_library",
"@org_golang_x_time//rate",
],
)

View File

@ -0,0 +1,373 @@
package inttests
import (
"archive/zip"
"bytes"
"context"
"encoding/base64"
"fmt"
"io"
"net/http"
"net/http/httptest"
"net/url"
"os"
"os/exec"
"path/filepath"
"testing"
"github.com/google/go-cmp/cmp"
"github.com/sourcegraph/log/logtest"
"golang.org/x/time/rate"
"google.golang.org/grpc"
server "github.com/sourcegraph/sourcegraph/cmd/gitserver/internal"
"github.com/sourcegraph/sourcegraph/internal/api"
"github.com/sourcegraph/sourcegraph/internal/conf"
"github.com/sourcegraph/sourcegraph/internal/gitserver"
"github.com/sourcegraph/sourcegraph/internal/gitserver/gitdomain"
proto "github.com/sourcegraph/sourcegraph/internal/gitserver/v1"
internalgrpc "github.com/sourcegraph/sourcegraph/internal/grpc"
"github.com/sourcegraph/sourcegraph/internal/grpc/defaults"
"github.com/sourcegraph/sourcegraph/internal/ratelimit"
"github.com/sourcegraph/sourcegraph/internal/wrexec"
"github.com/sourcegraph/sourcegraph/lib/errors"
"github.com/sourcegraph/sourcegraph/schema"
)
func TestClient_ArchiveReader(t *testing.T) {
root := gitserver.CreateRepoDir(t)
type test struct {
name string
remote string
revision string
want map[string]string
clientErr error
readerError error
skipReader bool
}
tests := []test{
{
name: "simple",
remote: createSimpleGitRepo(t, root),
revision: "HEAD",
want: map[string]string{
"dir1/": "",
"dir1/file1": "infile1",
"file 2": "infile2",
},
skipReader: false,
},
{
name: "repo-with-dotgit-dir",
remote: createRepoWithDotGitDir(t, root),
revision: "HEAD",
want: map[string]string{
"file1": "hello\n",
".git/mydir/file2": "milton\n",
".git/mydir/": "",
".git/": "",
},
skipReader: false,
},
{
name: "not-found",
revision: "HEAD",
clientErr: errors.New("repository does not exist: not-found"),
skipReader: false,
},
{
name: "revision-not-found",
remote: createRepoWithDotGitDir(t, root),
revision: "revision-not-found",
clientErr: nil,
readerError: &gitdomain.RevisionNotFoundError{Repo: "revision-not-found", Spec: "revision-not-found"},
skipReader: true,
},
}
runArchiveReaderTestfunc := func(t *testing.T, mkClient func(t *testing.T, addrs []string) gitserver.Client, name api.RepoName, test test) {
t.Run(string(name), func(t *testing.T) {
// Setup: Prepare the test Gitserver server + register the gRPC server
s := &server.Server{
Logger: logtest.Scoped(t),
ReposDir: filepath.Join(root, "repos"),
DB: newMockDB(),
GetRemoteURLFunc: func(_ context.Context, name api.RepoName) (string, error) {
if test.remote != "" {
return test.remote, nil
}
return "", errors.Errorf("no remote for %s", test.name)
},
GetVCSSyncer: func(ctx context.Context, name api.RepoName) (server.VCSSyncer, error) {
return server.NewGitRepoSyncer(wrexec.NewNoOpRecordingCommandFactory()), nil
},
RecordingCommandFactory: wrexec.NewNoOpRecordingCommandFactory(),
Locker: server.NewRepositoryLocker(),
RPSLimiter: ratelimit.NewInstrumentedLimiter("GitserverTest", rate.NewLimiter(100, 10)),
}
grpcServer := defaults.NewServer(logtest.Scoped(t))
proto.RegisterGitserverServiceServer(grpcServer, &server.GRPCServer{Server: s})
handler := internalgrpc.MultiplexHandlers(grpcServer, s.Handler())
srv := httptest.NewServer(handler)
defer srv.Close()
u, _ := url.Parse(srv.URL)
addrs := []string{u.Host}
cli := mkClient(t, addrs)
ctx := context.Background()
if test.remote != "" {
if _, err := cli.RequestRepoUpdate(ctx, name, 0); err != nil {
t.Fatal(err)
}
}
rc, err := cli.ArchiveReader(ctx, nil, name, gitserver.ArchiveOptions{Treeish: test.revision, Format: gitserver.ArchiveFormatZip})
if have, want := fmt.Sprint(err), fmt.Sprint(test.clientErr); have != want {
t.Errorf("archive: have err %v, want %v", have, want)
}
if rc == nil {
return
}
t.Cleanup(func() {
if err := rc.Close(); err != nil {
t.Fatal(err)
}
})
data, readErr := io.ReadAll(rc)
if readErr != nil {
if readErr.Error() != test.readerError.Error() {
t.Errorf("archive: have reader err %v, want %v", readErr.Error(), test.readerError.Error())
}
if test.skipReader {
return
}
t.Fatal(readErr)
}
zr, err := zip.NewReader(bytes.NewReader(data), int64(len(data)))
if err != nil {
t.Fatal(err)
}
got := map[string]string{}
for _, f := range zr.File {
r, err := f.Open()
if err != nil {
t.Errorf("failed to open %q because %s", f.Name, err)
continue
}
contents, err := io.ReadAll(r)
_ = r.Close()
if err != nil {
t.Errorf("Read(%q): %s", f.Name, err)
continue
}
got[f.Name] = string(contents)
}
if !cmp.Equal(test.want, got) {
t.Errorf("mismatch (-want +got):\n%s", cmp.Diff(test.want, got))
}
})
}
t.Run("grpc", func(t *testing.T) {
conf.Mock(&conf.Unified{
SiteConfiguration: schema.SiteConfiguration{
ExperimentalFeatures: &schema.ExperimentalFeatures{
EnableGRPC: boolPointer(true),
},
},
})
t.Cleanup(func() {
conf.Mock(nil)
})
for _, test := range tests {
repoName := api.RepoName(test.name)
called := false
mkClient := func(t *testing.T, addrs []string) gitserver.Client {
t.Helper()
source := gitserver.NewTestClientSource(t, addrs, func(o *gitserver.TestClientSourceOptions) {
o.ClientFunc = func(cc *grpc.ClientConn) proto.GitserverServiceClient {
base := proto.NewGitserverServiceClient(cc)
mockArchive := func(ctx context.Context, in *proto.ArchiveRequest, opts ...grpc.CallOption) (proto.GitserverService_ArchiveClient, error) {
called = true
return base.Archive(ctx, in, opts...)
}
mockRepoUpdate := func(ctx context.Context, in *proto.RepoUpdateRequest, opts ...grpc.CallOption) (*proto.RepoUpdateResponse, error) {
base := proto.NewGitserverServiceClient(cc)
return base.RepoUpdate(ctx, in, opts...)
}
return &gitserver.MockGRPCClient{
MockArchive: mockArchive,
MockRepoUpdate: mockRepoUpdate,
}
}
})
return gitserver.NewTestClient(&http.Client{}, source)
}
runArchiveReaderTestfunc(t, mkClient, repoName, test)
if !called {
t.Error("archiveReader: GitserverServiceClient should have been called")
}
}
})
t.Run("http", func(t *testing.T) {
conf.Mock(&conf.Unified{
SiteConfiguration: schema.SiteConfiguration{
ExperimentalFeatures: &schema.ExperimentalFeatures{
EnableGRPC: boolPointer(false),
},
},
})
t.Cleanup(func() {
conf.Mock(nil)
})
for _, test := range tests {
repoName := api.RepoName(test.name)
called := false
mkClient := func(t *testing.T, addrs []string) gitserver.Client {
t.Helper()
source := gitserver.NewTestClientSource(t, addrs, func(o *gitserver.TestClientSourceOptions) {
o.ClientFunc = func(cc *grpc.ClientConn) proto.GitserverServiceClient {
mockArchive := func(ctx context.Context, in *proto.ArchiveRequest, opts ...grpc.CallOption) (proto.GitserverService_ArchiveClient, error) {
called = true
base := proto.NewGitserverServiceClient(cc)
return base.Archive(ctx, in, opts...)
}
return &gitserver.MockGRPCClient{MockArchive: mockArchive}
}
})
return gitserver.NewTestClient(&http.Client{}, source)
}
runArchiveReaderTestfunc(t, mkClient, repoName, test)
if called {
t.Error("archiveReader: GitserverServiceClient should have been called")
}
}
})
}
func createSimpleGitRepo(t *testing.T, root string) string {
t.Helper()
dir := filepath.Join(root, "remotes", "simple")
if err := os.MkdirAll(dir, 0700); err != nil {
t.Fatal(err)
}
for _, cmd := range []string{
"git init",
"mkdir dir1",
"echo -n infile1 > dir1/file1",
"touch --date=2006-01-02T15:04:05Z dir1 dir1/file1 || touch -t 200601021704.05 dir1 dir1/file1",
"git add dir1/file1",
"GIT_COMMITTER_NAME=a GIT_COMMITTER_EMAIL=a@a.com GIT_AUTHOR_DATE=2006-01-02T15:04:05Z GIT_COMMITTER_DATE=2006-01-02T15:04:05Z git commit -m commit1 --author='a <a@a.com>' --date 2006-01-02T15:04:05Z",
"echo -n infile2 > 'file 2'",
"touch --date=2014-05-06T19:20:21Z 'file 2' || touch -t 201405062120.21 'file 2'",
"git add 'file 2'",
"GIT_COMMITTER_NAME=a GIT_COMMITTER_EMAIL=a@a.com GIT_AUTHOR_DATE=2006-01-02T15:04:05Z GIT_COMMITTER_DATE=2014-05-06T19:20:21Z git commit -m commit2 --author='a <a@a.com>' --date 2014-05-06T19:20:21Z",
"git branch test-ref HEAD~1",
"git branch test-nested-ref test-ref",
} {
c := exec.Command("bash", "-c", `GIT_CONFIG_GLOBAL="" GIT_CONFIG_SYSTEM="" `+cmd)
c.Dir = dir
out, err := c.CombinedOutput()
if err != nil {
t.Fatalf("Command %q failed. Output was:\n\n%s", cmd, out)
}
}
return dir
}
func createRepoWithDotGitDir(t *testing.T, root string) string {
t.Helper()
b64 := func(s string) string {
t.Helper()
b, err := base64.StdEncoding.DecodeString(s)
if err != nil {
t.Fatal(err)
}
return string(b)
}
dir := filepath.Join(root, "remotes", "repo-with-dot-git-dir")
// This repo was synthesized by hand to contain a file whose path is `.git/mydir/file2` (the Git
// CLI will not let you create a file with a `.git` path component).
//
// The synthesized bad commit is:
//
// commit aa600fc517ea6546f31ae8198beb1932f13b0e4c (HEAD -> master)
// Author: Quinn Slack <qslack@qslack.com>
// Date: Tue Jun 5 16:17:20 2018 -0700
//
// wip
//
// diff --git a/.git/mydir/file2 b/.git/mydir/file2
// new file mode 100644
// index 0000000..82b919c
// --- /dev/null
// +++ b/.git/mydir/file2
// @@ -0,0 +1 @@
// +milton
files := map[string]string{
"config": `
[core]
repositoryformatversion=0
filemode=true
`,
"HEAD": `ref: refs/heads/master`,
"refs/heads/master": `aa600fc517ea6546f31ae8198beb1932f13b0e4c`,
"objects/e7/9c5e8f964493290a409888d5413a737e8e5dd5": b64("eAFLyslPUrBgyMzLLMlMzOECACgtBOw="),
"objects/ce/013625030ba8dba906f756967f9e9ca394464a": b64("eAFLyslPUjBjyEjNycnnAgAdxQQU"),
"objects/82/b919c9c565d162c564286d9d6a2497931be47e": b64("eAFLyslPUjBnyM3MKcnP4wIAIw8ElA=="),
"objects/e5/231c1d547df839dce09809e43608fe6c537682": b64("eAErKUpNVTAzYTAxAAIFvfTMEgbb8lmsKdJ+zz7ukeMOulcqZqOllmloYGBmYqKQlpmTashwjtFMlZl7xe2VbN/DptXPm7N4ipsXACOoGDo="),
"objects/da/5ecc846359eaf23e8abe907b3125fdd7abdbc0": b64("eAErKUpNVTA2ZjA0MDAzMVFIy8xJNWJo2il58mjqxaSjKRq5c7NUpk+WflIHABZRD2I="),
"objects/d0/01d287018593691c36042e1c8089fde7415296": b64("eAErKUpNVTA2ZjA0MDAzMVFIy8xJNWQ4x2imysy94vZKtu9h0+rnzVk8xc0LAP2TDiQ="),
"objects/b4/009ecbf1eba01c5279f25840e2afc0d15f5005": b64("eAGdjdsJAjEQRf1OFdOAMpPN5gEitiBWEJIRBzcJu2b7N2IHfh24nMtJrRTpQA4PfWOGjEhZe4fk5zDZQGmyaDRT8ujDI7MzNOtgVdz7s21w26VWuC8xveC8vr+8/nBKrVxgyF4bJBfgiA5RjXUEO/9xVVKlS1zUB/JxNbA="),
"objects/3d/779a05641b4ee6f1bc1e0b52de75163c2a2669": b64("eAErKUpNVTA2YjAxAAKF3MqUzCKGW3FnWpIjX32y69o3odpQ9e/11bcPAAAipRGQ"),
"objects/aa/600fc517ea6546f31ae8198beb1932f13b0e4c": b64("eAGdjlkKAjEQBf3OKfoCSmfpLCDiFcQTZDodHHQWxwxe3xFv4FfBKx4UT8PQNzDa7doiAkLGataFXCg12lRYMEVM4qzHWMUz2eCjUXNeZGzQOdwkd1VLl1EzmZCqoehQTK6MRVMlRFJ5bbdpgcvajyNcH5nvcHy+vjz/cOBpOIEmE41D7xD2GBDVtm6BTf64qnc/qw9c4UKS"),
"objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391": b64("eAFLyslPUjBgAAAJsAHw"),
}
for name, data := range files {
name = filepath.Join(dir, name)
if err := os.MkdirAll(filepath.Dir(name), 0700); err != nil {
t.Fatal(err)
}
if err := os.WriteFile(name, []byte(data), 0600); err != nil {
t.Fatal(err)
}
}
return dir
}

View File

@ -0,0 +1,137 @@
package inttests
import (
"container/list"
"context"
"net/http"
"net/http/httptest"
"net/url"
"path/filepath"
"testing"
"github.com/sourcegraph/log/logtest"
"github.com/stretchr/testify/require"
"golang.org/x/time/rate"
server "github.com/sourcegraph/sourcegraph/cmd/gitserver/internal"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/internal/perforce"
"github.com/sourcegraph/sourcegraph/internal/api"
"github.com/sourcegraph/sourcegraph/internal/database"
"github.com/sourcegraph/sourcegraph/internal/database/dbmocks"
"github.com/sourcegraph/sourcegraph/internal/extsvc"
"github.com/sourcegraph/sourcegraph/internal/gitserver"
"github.com/sourcegraph/sourcegraph/internal/gitserver/gitdomain"
"github.com/sourcegraph/sourcegraph/internal/gitserver/protocol"
proto "github.com/sourcegraph/sourcegraph/internal/gitserver/v1"
internalgrpc "github.com/sourcegraph/sourcegraph/internal/grpc"
"github.com/sourcegraph/sourcegraph/internal/grpc/defaults"
"github.com/sourcegraph/sourcegraph/internal/observation"
"github.com/sourcegraph/sourcegraph/internal/ratelimit"
"github.com/sourcegraph/sourcegraph/internal/types"
"github.com/sourcegraph/sourcegraph/internal/wrexec"
)
func TestClient_ResolveRevisions(t *testing.T) {
root := t.TempDir()
remote := createSimpleGitRepo(t, root)
// These hashes should be stable since we set the timestamps
// when creating the commits.
hash1 := "b6602ca96bdc0ab647278577a3c6edcb8fe18fb0"
hash2 := "c5151eceb40d5e625716589b745248e1a6c6228d"
tests := []struct {
input []protocol.RevisionSpecifier
want []string
err error
}{{
input: []protocol.RevisionSpecifier{{}},
want: []string{hash2},
}, {
input: []protocol.RevisionSpecifier{{RevSpec: "HEAD"}},
want: []string{hash2},
}, {
input: []protocol.RevisionSpecifier{{RevSpec: "HEAD~1"}},
want: []string{hash1},
}, {
input: []protocol.RevisionSpecifier{{RevSpec: "test-ref"}},
want: []string{hash1},
}, {
input: []protocol.RevisionSpecifier{{RevSpec: "test-nested-ref"}},
want: []string{hash1},
}, {
input: []protocol.RevisionSpecifier{{RefGlob: "refs/heads/test-*"}},
want: []string{hash1, hash1}, // two hashes because to refs point to that hash
}, {
input: []protocol.RevisionSpecifier{{RevSpec: "test-fake-ref"}},
err: &gitdomain.RevisionNotFoundError{Repo: api.RepoName(remote), Spec: "test-fake-ref"},
}}
logger := logtest.Scoped(t)
db := newMockDB()
ctx := context.Background()
s := server.Server{
Logger: logger,
ReposDir: filepath.Join(root, "repos"),
GetRemoteURLFunc: func(_ context.Context, name api.RepoName) (string, error) {
return remote, nil
},
GetVCSSyncer: func(ctx context.Context, name api.RepoName) (server.VCSSyncer, error) {
return server.NewGitRepoSyncer(wrexec.NewNoOpRecordingCommandFactory()), nil
},
DB: db,
Perforce: perforce.NewService(ctx, observation.TestContextTB(t), logger, db, list.New()),
RecordingCommandFactory: wrexec.NewNoOpRecordingCommandFactory(),
Locker: server.NewRepositoryLocker(),
RPSLimiter: ratelimit.NewInstrumentedLimiter("GitserverTest", rate.NewLimiter(100, 10)),
}
grpcServer := defaults.NewServer(logtest.Scoped(t))
proto.RegisterGitserverServiceServer(grpcServer, &server.GRPCServer{Server: &s})
handler := internalgrpc.MultiplexHandlers(grpcServer, s.Handler())
srv := httptest.NewServer(handler)
defer srv.Close()
u, _ := url.Parse(srv.URL)
addrs := []string{u.Host}
source := gitserver.NewTestClientSource(t, addrs)
cli := gitserver.NewTestClient(&http.Client{}, source)
for _, test := range tests {
t.Run("", func(t *testing.T) {
_, err := cli.RequestRepoUpdate(ctx, api.RepoName(remote), 0)
require.NoError(t, err)
got, err := cli.ResolveRevisions(ctx, api.RepoName(remote), test.input)
if test.err != nil {
require.Equal(t, test.err, err)
return
}
require.NoError(t, err)
require.Equal(t, test.want, got)
})
}
}
func newMockDB() database.DB {
db := dbmocks.NewMockDB()
db.GitserverReposFunc.SetDefaultReturn(dbmocks.NewMockGitserverRepoStore())
db.FeatureFlagsFunc.SetDefaultReturn(dbmocks.NewMockFeatureFlagStore())
r := dbmocks.NewMockRepoStore()
r.GetByNameFunc.SetDefaultHook(func(ctx context.Context, repoName api.RepoName) (*types.Repo, error) {
return &types.Repo{
Name: repoName,
ExternalRepo: api.ExternalRepoSpec{
ServiceType: extsvc.TypeGitHub,
},
}, nil
})
db.ReposFunc.SetDefaultReturn(r)
return db
}

View File

@ -16,7 +16,7 @@ import (
sglog "github.com/sourcegraph/log"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/server"
server "github.com/sourcegraph/sourcegraph/cmd/gitserver/internal"
"github.com/sourcegraph/sourcegraph/internal/api"
"github.com/sourcegraph/sourcegraph/internal/database/dbmocks"
"github.com/sourcegraph/sourcegraph/internal/extsvc"

View File

@ -1,4 +1,4 @@
package server
package internal
import (
"context"

View File

@ -1,4 +1,4 @@
package server
package internal
import (
"context"

View File

@ -1,9 +1,9 @@
package server
package internal
import (
"sync"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/server/common"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/internal/common"
)
// RepositoryLock is returned by RepositoryLocker.TryAcquire. It allows

View File

@ -1,4 +1,4 @@
package server
package internal
import (
"fmt"

View File

@ -1,4 +1,4 @@
package server
package internal
import (
"bufio"
@ -20,8 +20,8 @@ import (
"github.com/sourcegraph/sourcegraph/internal/api"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/server/sshagent"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/server/urlredactor"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/internal/sshagent"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/internal/urlredactor"
"github.com/sourcegraph/sourcegraph/internal/gitserver/gitdomain"
"github.com/sourcegraph/sourcegraph/internal/gitserver/protocol"
"github.com/sourcegraph/sourcegraph/internal/lazyregexp"

View File

@ -1,12 +1,32 @@
load("//dev:go_defs.bzl", "go_test")
load("@io_bazel_rules_go//go:def.bzl", "go_library")
load("//dev:go_defs.bzl", "go_test")
go_library(
name = "perforce",
srcs = ["perforce.go"],
importpath = "github.com/sourcegraph/sourcegraph/cmd/gitserver/internal/perforce",
visibility = ["//cmd/gitserver:__subpackages__"],
deps = [
"//cmd/gitserver/internal/common",
"//internal/api",
"//internal/conf",
"//internal/database",
"//internal/extsvc",
"//internal/goroutine",
"//internal/observation",
"//internal/perforce",
"//internal/types",
"//lib/errors",
"@com_github_sourcegraph_log//:log",
],
)
go_test(
name = "perforce_test",
srcs = ["perforce_test.go"],
embed = [":perforce"],
deps = [
"//cmd/gitserver/server/common",
"//cmd/gitserver/internal/common",
"//internal/api",
"//internal/conf",
"//internal/database/dbmocks",
@ -21,23 +41,3 @@ go_test(
"@com_github_stretchr_testify//require",
],
)
go_library(
name = "perforce",
srcs = ["perforce.go"],
importpath = "github.com/sourcegraph/sourcegraph/cmd/gitserver/server/perforce",
visibility = ["//visibility:public"],
deps = [
"//cmd/gitserver/server/common",
"//internal/api",
"//internal/conf",
"//internal/database",
"//internal/extsvc",
"//internal/goroutine",
"//internal/observation",
"//internal/perforce",
"//internal/types",
"//lib/errors",
"@com_github_sourcegraph_log//:log",
],
)

View File

@ -14,7 +14,7 @@ import (
"github.com/sourcegraph/log"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/server/common"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/internal/common"
"github.com/sourcegraph/sourcegraph/internal/api"
"github.com/sourcegraph/sourcegraph/internal/conf"
"github.com/sourcegraph/sourcegraph/internal/database"

View File

@ -11,7 +11,9 @@ import (
"github.com/google/go-cmp/cmp"
"github.com/sourcegraph/log/logtest"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/server/common"
"github.com/stretchr/testify/require"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/internal/common"
"github.com/sourcegraph/sourcegraph/internal/api"
"github.com/sourcegraph/sourcegraph/internal/conf"
"github.com/sourcegraph/sourcegraph/internal/database/dbmocks"
@ -21,7 +23,6 @@ import (
"github.com/sourcegraph/sourcegraph/internal/observation"
"github.com/sourcegraph/sourcegraph/internal/types"
"github.com/sourcegraph/sourcegraph/schema"
"github.com/stretchr/testify/require"
)
// setupTestRepo will setup a git repo with 5 commits using p4-fusion as the format in the commit

View File

@ -1,4 +1,4 @@
package server
package internal
import (
"context"

View File

@ -1,4 +1,4 @@
package server
package internal
import (
"context"

View File

@ -1,4 +1,4 @@
package server
package internal
import (
"bytes"
@ -14,7 +14,7 @@ import (
"github.com/sourcegraph/log"
"go.opentelemetry.io/otel/attribute"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/server/internal/cacert"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/internal/cacert"
"github.com/sourcegraph/sourcegraph/internal/conf"
"github.com/sourcegraph/sourcegraph/internal/trace" //nolint:staticcheck // OT is deprecated
"github.com/sourcegraph/sourcegraph/internal/wrexec"

View File

@ -1,4 +1,4 @@
package server
package internal
import (
"os"
@ -7,9 +7,10 @@ import (
"testing"
"github.com/google/go-cmp/cmp"
"github.com/stretchr/testify/assert"
"github.com/sourcegraph/sourcegraph/internal/conf"
"github.com/sourcegraph/sourcegraph/schema"
"github.com/stretchr/testify/assert"
)
// head will return the first n lines of data.

View File

@ -1,5 +1,5 @@
// Package server implements the gitserver service.
package server
// Package internal implements the gitserver service.
package internal
import (
"bufio"
@ -35,10 +35,10 @@ import (
"github.com/sourcegraph/conc"
"github.com/sourcegraph/log"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/server/accesslog"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/server/common"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/server/perforce"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/server/urlredactor"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/internal/accesslog"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/internal/common"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/internal/perforce"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/internal/urlredactor"
"github.com/sourcegraph/sourcegraph/internal/actor"
"github.com/sourcegraph/sourcegraph/internal/api"
"github.com/sourcegraph/sourcegraph/internal/conf"

View File

@ -1,4 +1,4 @@
package server
package internal
import (
"context"
@ -11,7 +11,7 @@ import (
"github.com/sourcegraph/log"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/server/accesslog"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/internal/accesslog"
"github.com/sourcegraph/sourcegraph/internal/api"
"github.com/sourcegraph/sourcegraph/internal/gitserver"
"github.com/sourcegraph/sourcegraph/internal/gitserver/adapters"

View File

@ -1,4 +1,4 @@
package server
package internal
import (
"bytes"
@ -31,8 +31,8 @@ import (
"github.com/sourcegraph/log"
"github.com/sourcegraph/log/logtest"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/server/common"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/server/perforce"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/internal/common"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/internal/perforce"
"github.com/sourcegraph/sourcegraph/internal/api"
"github.com/sourcegraph/sourcegraph/internal/database"
"github.com/sourcegraph/sourcegraph/internal/database/dbmocks"

View File

@ -1,4 +1,4 @@
package server
package internal
import (
"os/exec"

View File

@ -1,4 +1,4 @@
package server
package internal
import (
"fmt"
@ -14,7 +14,7 @@ import (
"github.com/sourcegraph/log"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/server/common"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/internal/common"
"github.com/sourcegraph/sourcegraph/internal/api"
"github.com/sourcegraph/sourcegraph/internal/gitserver/protocol"
"github.com/sourcegraph/sourcegraph/internal/types"

View File

@ -1,4 +1,4 @@
package server
package internal
import (
"net/http/httptest"

View File

@ -4,8 +4,8 @@ load("//dev:go_defs.bzl", "go_test")
go_library(
name = "sshagent",
srcs = ["ssh_agent.go"],
importpath = "github.com/sourcegraph/sourcegraph/cmd/gitserver/server/sshagent",
visibility = ["//visibility:public"],
importpath = "github.com/sourcegraph/sourcegraph/cmd/gitserver/internal/sshagent",
visibility = ["//cmd/gitserver:__subpackages__"],
deps = [
"//lib/errors",
"@com_github_sourcegraph_log//:log",

View File

@ -4,8 +4,8 @@ load("//dev:go_defs.bzl", "go_test")
go_library(
name = "urlredactor",
srcs = ["urlredactor.go"],
importpath = "github.com/sourcegraph/sourcegraph/cmd/gitserver/server/urlredactor",
visibility = ["//visibility:public"],
importpath = "github.com/sourcegraph/sourcegraph/cmd/gitserver/internal/urlredactor",
visibility = ["//cmd/gitserver:__subpackages__"],
deps = ["//internal/vcs"],
)

View File

@ -1,4 +1,4 @@
package server
package internal
import (
"context"
@ -11,7 +11,7 @@ import (
"github.com/sourcegraph/log"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/server/common"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/internal/common"
"github.com/sourcegraph/sourcegraph/internal/api"
"github.com/sourcegraph/sourcegraph/internal/errcode"

View File

@ -1,4 +1,4 @@
package server
package internal
import (
"bufio"
@ -16,7 +16,7 @@ import (
"github.com/stretchr/testify/require"
"golang.org/x/exp/slices"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/server/common"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/internal/common"
"github.com/sourcegraph/sourcegraph/internal/api"
"github.com/sourcegraph/sourcegraph/internal/codeintel/dependencies"
"github.com/sourcegraph/sourcegraph/internal/conf/reposource"

View File

@ -1,10 +1,10 @@
package server
package internal
import (
"context"
"os/exec"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/server/common"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/internal/common"
"github.com/sourcegraph/sourcegraph/internal/api"
"github.com/sourcegraph/sourcegraph/internal/vcs"
)

View File

@ -1,4 +1,4 @@
package server
package internal
import (
"context"
@ -9,8 +9,8 @@ import (
"github.com/sourcegraph/sourcegraph/internal/api"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/server/common"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/server/urlredactor"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/internal/common"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/internal/urlredactor"
"github.com/sourcegraph/sourcegraph/internal/vcs"
"github.com/sourcegraph/sourcegraph/internal/wrexec"
"github.com/sourcegraph/sourcegraph/lib/errors"

View File

@ -1,4 +1,4 @@
package server
package internal
import (
"bytes"

View File

@ -1,4 +1,4 @@
package server
package internal
import (
"archive/zip"

View File

@ -1,4 +1,4 @@
package server
package internal
import (
"archive/zip"

View File

@ -1,4 +1,4 @@
package server
package internal
import (
"archive/zip"

View File

@ -4,21 +4,21 @@
// this repository. To add additional mocks to this or another package, add a new entry
// to the mockgen.yaml file in the root of this repository.
package server
package internal
import (
"context"
"os/exec"
"sync"
common "github.com/sourcegraph/sourcegraph/cmd/gitserver/server/common"
common "github.com/sourcegraph/sourcegraph/cmd/gitserver/internal/common"
api "github.com/sourcegraph/sourcegraph/internal/api"
vcs "github.com/sourcegraph/sourcegraph/internal/vcs"
)
// MockVCSSyncer is a mock implementation of the VCSSyncer interface (from
// the package github.com/sourcegraph/sourcegraph/cmd/gitserver/server) used
// for unit testing.
// the package github.com/sourcegraph/sourcegraph/cmd/gitserver/internal)
// used for unit testing.
type MockVCSSyncer struct {
// CloneCommandFunc is an instance of a mock function object controlling
// the behavior of the method CloneCommand.

View File

@ -1,4 +1,4 @@
package server
package internal
import (
"context"

View File

@ -1,4 +1,4 @@
package server
package internal
import (
"archive/tar"

View File

@ -1,4 +1,4 @@
package server
package internal
import (
"bufio"
@ -17,8 +17,8 @@ import (
"github.com/sourcegraph/sourcegraph/internal/api"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/server/common"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/server/urlredactor"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/internal/common"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/internal/urlredactor"
"github.com/sourcegraph/sourcegraph/internal/vcs"
"github.com/sourcegraph/sourcegraph/internal/wrexec"
"github.com/sourcegraph/sourcegraph/lib/errors"

View File

@ -1,4 +1,4 @@
package server
package internal
import (
"os/exec"

View File

@ -1,4 +1,4 @@
package server
package internal
import (
"context"

View File

@ -1,4 +1,4 @@
package server
package internal
import (
"archive/zip"

View File

@ -1,4 +1,4 @@
package server
package internal
import (
"bytes"

View File

@ -1,4 +1,4 @@
package server
package internal
import (
"context"

View File

@ -12,10 +12,10 @@ go_library(
importpath = "github.com/sourcegraph/sourcegraph/cmd/gitserver/shared",
visibility = ["//visibility:public"],
deps = [
"//cmd/gitserver/server",
"//cmd/gitserver/server/accesslog",
"//cmd/gitserver/internal",
"//cmd/gitserver/internal/accesslog",
"//cmd/gitserver/internal/perforce",
"//cmd/gitserver/server/cloneurl",
"//cmd/gitserver/server/perforce",
"//internal/actor",
"//internal/api",
"//internal/authz",
@ -72,7 +72,6 @@ go_test(
# path is sandboxed properly.
env = {"COURSIER_CACHE_DIR": "/tmp"},
deps = [
"//cmd/gitserver/server",
"//internal/api",
"//internal/codeintel/dependencies",
"//internal/database/dbmocks",
@ -81,6 +80,7 @@ go_test(
"@com_github_google_go_cmp//cmp",
"@com_github_sourcegraph_log//:log",
"@com_github_sourcegraph_log//logtest",
"@com_github_stretchr_testify//require",
"@org_golang_google_grpc//:go_default_library",
],
)

View File

@ -18,10 +18,10 @@ import (
"golang.org/x/sync/semaphore"
"google.golang.org/grpc"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/server"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/server/accesslog"
server "github.com/sourcegraph/sourcegraph/cmd/gitserver/internal"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/internal/accesslog"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/internal/perforce"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/server/cloneurl"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/server/perforce"
"github.com/sourcegraph/sourcegraph/internal/actor"
"github.com/sourcegraph/sourcegraph/internal/api"
"github.com/sourcegraph/sourcegraph/internal/authz"

View File

@ -15,9 +15,9 @@ import (
"github.com/google/go-cmp/cmp"
"github.com/sourcegraph/log"
"github.com/sourcegraph/log/logtest"
"github.com/stretchr/testify/require"
"google.golang.org/grpc"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/server"
"github.com/sourcegraph/sourcegraph/internal/api"
"github.com/sourcegraph/sourcegraph/internal/codeintel/dependencies"
"github.com/sourcegraph/sourcegraph/internal/database/dbmocks"
@ -84,10 +84,7 @@ func TestGetVCSSyncer(t *testing.T) {
t.Fatal(err)
}
_, ok := s.(*server.PerforceDepotSyncer)
if !ok {
t.Fatalf("Want *server.PerforceDepotSyncer, got %T", s)
}
require.Equal(t, "perforce", s.Type())
}
func TestMethodSpecificStreamInterceptor(t *testing.T) {

View File

@ -52,7 +52,7 @@ Here's a word-by-word breakout to demonstrate how the captured entry aligns with
### What is audited?
- [Security events](https://sourcegraph.com/github.com/sourcegraph/sourcegraph/-/blob/internal/database/security_event_logs.go?L120-131)
- [Gitserver access](https://sourcegraph.com/github.com/sourcegraph/sourcegraph/-/blob/cmd/gitserver/server/internal/accesslog/accesslog.go?L100-104)
- [Gitserver access](https://sourcegraph.com/github.com/sourcegraph/sourcegraph/-/blob/cmd/gitserver/internal/accesslog/accesslog.go?L100-104)
- [GraphQL requests](https://sourcegraph.com/github.com/sourcegraph/sourcegraph/-/blob/cmd/frontend/internal/httpapi/graphql.go?L226-244)
This list is expected to grow in the future.

View File

@ -33,7 +33,7 @@ Owner is assigned successfully.
### Directory level ownership
Go to any directory view (in our example it is `cmd/gitserver/server`) and click "Show more" on Own panel.
Go to any directory view (in our example it is `cmd/gitserver/internal`) and click "Show more" on Own panel.
<picture title="Repository page with Ownership button selected"><img class="theme-dark-only" src="https://storage.googleapis.com/sourcegraph-assets/docs/own/assigned-owners-dir-1-dark.png"><img class="theme-light-only" src="https://storage.googleapis.com/sourcegraph-assets/docs/own/assigned-owners-dir-1-light.png"></picture>
@ -50,7 +50,7 @@ Owner is assigned successfully.
### File level ownership
Go to the blob view of any file (in our example it is `cmd/gitserver/server/cleanup.go`).
Go to the blob view of any file (in our example it is `cmd/gitserver/internal/cleanup.go`).
1. Click on the Own bar in the top-right corner.
2. Click "Add owner" button in the bottom-right corner of an opened Ownership tab.

View File

@ -487,16 +487,16 @@ func cleanupStaleLockFiles(gitDir string, logger *log.Logger) error {
"gc.pid.lock", // created when git starts a garbage collection run
"index.lock", // created when running "git add" / "git commit"
// from cmd/gitserver/server/cleanup.go, see
// https://github.com/sourcegraph/sourcegraph/blob/55d83e8111d4dfea480ad94813e07d58068fec9c/cmd/gitserver/server/cleanup.go#L325-L359
// from cmd/gitserver/internal/cleanup.go, see
// https://github.com/sourcegraph/sourcegraph/blob/55d83e8111d4dfea480ad94813e07d58068fec9c/cmd/gitserver/internal/cleanup.go#L325-L359
"config.lock",
"packed-refs.lock",
} {
lockFiles = append(lockFiles, filepath.Join(gitDir, f))
}
// from cmd/gitserver/server/cleanup.go, see
// https://github.com/sourcegraph/sourcegraph/blob/55d83e8111d4dfea480ad94813e07d58068fec9c/cmd/gitserver/server/cleanup.go#L325-L359
// from cmd/gitserver/internal/cleanup.go, see
// https://github.com/sourcegraph/sourcegraph/blob/55d83e8111d4dfea480ad94813e07d58068fec9c/cmd/gitserver/internal/cleanup.go#L325-L359
lockFiles = append(lockFiles, filepath.Join(gitDir, "objects", "info", "commit-graph.lock"))
refsDir := filepath.Join(gitDir, "refs")

View File

@ -9,6 +9,7 @@ go_library(
"commands.go",
"git_command.go",
"gitolite.go",
"mock.go",
"mocks_temp.go",
"observability.go",
"proxy.go",
@ -74,38 +75,28 @@ go_test(
# path is sandboxed properly.
env = {"COURSIER_CACHE_DIR": "/tmp"},
deps = [
"//cmd/gitserver/server",
"//cmd/gitserver/server/perforce",
"//internal/actor",
"//internal/api",
"//internal/authz",
"//internal/conf",
"//internal/conf/conftypes",
"//internal/database",
"//internal/database/dbmocks",
"//internal/errcode",
"//internal/extsvc",
"//internal/extsvc/gitolite",
"//internal/gitserver/gitdomain",
"//internal/gitserver/protocol",
"//internal/gitserver/v1:gitserver",
"//internal/grpc",
"//internal/grpc/defaults",
"//internal/httpcli",
"//internal/observation",
"//internal/ratelimit",
"//internal/types",
"//internal/wrexec",
"//lib/errors",
"//schema",
"@com_github_google_go_cmp//cmp",
"@com_github_sourcegraph_go_diff//diff",
"@com_github_sourcegraph_log//logtest",
"@com_github_stretchr_testify//assert",
"@com_github_stretchr_testify//require",
"@org_golang_google_grpc//:go_default_library",
"@org_golang_google_grpc//codes",
"@org_golang_google_grpc//status",
"@org_golang_x_time//rate",
],
)

View File

@ -1,11 +1,8 @@
package gitserver_test
import (
"archive/zip"
"bytes"
"container/list"
"context"
"encoding/base64"
"encoding/json"
"fmt"
"io"
@ -13,7 +10,6 @@ import (
"net/http"
"net/http/httptest"
"net/url"
"os"
"os/exec"
"path/filepath"
"reflect"
@ -25,55 +21,21 @@ import (
"github.com/google/go-cmp/cmp"
"github.com/stretchr/testify/require"
"golang.org/x/time/rate"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"github.com/sourcegraph/log/logtest"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/server"
"github.com/sourcegraph/sourcegraph/cmd/gitserver/server/perforce"
"github.com/sourcegraph/sourcegraph/internal/api"
"github.com/sourcegraph/sourcegraph/internal/conf"
"github.com/sourcegraph/sourcegraph/internal/database"
"github.com/sourcegraph/sourcegraph/internal/database/dbmocks"
"github.com/sourcegraph/sourcegraph/internal/extsvc"
"github.com/sourcegraph/sourcegraph/internal/extsvc/gitolite"
"github.com/sourcegraph/sourcegraph/internal/gitserver"
"github.com/sourcegraph/sourcegraph/internal/gitserver/gitdomain"
"github.com/sourcegraph/sourcegraph/internal/gitserver/protocol"
proto "github.com/sourcegraph/sourcegraph/internal/gitserver/v1"
internalgrpc "github.com/sourcegraph/sourcegraph/internal/grpc"
"github.com/sourcegraph/sourcegraph/internal/grpc/defaults"
"github.com/sourcegraph/sourcegraph/internal/httpcli"
"github.com/sourcegraph/sourcegraph/internal/observation"
"github.com/sourcegraph/sourcegraph/internal/ratelimit"
"github.com/sourcegraph/sourcegraph/internal/types"
"github.com/sourcegraph/sourcegraph/internal/wrexec"
"github.com/sourcegraph/sourcegraph/lib/errors"
"github.com/sourcegraph/sourcegraph/schema"
)
func newMockDB() database.DB {
db := dbmocks.NewMockDB()
db.GitserverReposFunc.SetDefaultReturn(dbmocks.NewMockGitserverRepoStore())
db.FeatureFlagsFunc.SetDefaultReturn(dbmocks.NewMockFeatureFlagStore())
r := dbmocks.NewMockRepoStore()
r.GetByNameFunc.SetDefaultHook(func(ctx context.Context, repoName api.RepoName) (*types.Repo, error) {
return &types.Repo{
Name: repoName,
ExternalRepo: api.ExternalRepoSpec{
ServiceType: extsvc.TypeGitHub,
},
}, nil
})
db.ReposFunc.SetDefaultReturn(r)
return db
}
func TestClient_Archive_ProtoRoundTrip(t *testing.T) {
var diff string
@ -362,8 +324,8 @@ func TestClient_Remove(t *testing.T) {
*called = true
return nil, nil
}
return &mockClient{
mockRepoDelete: mockRepoDelete,
return &gitserver.MockGRPCClient{
MockRepoDelete: mockRepoDelete,
}
}
})
@ -429,344 +391,6 @@ func TestClient_Remove(t *testing.T) {
}
func TestClient_ArchiveReader(t *testing.T) {
root := gitserver.CreateRepoDir(t)
type test struct {
name string
remote string
revision string
want map[string]string
clientErr error
readerError error
skipReader bool
}
tests := []test{
{
name: "simple",
remote: createSimpleGitRepo(t, root),
revision: "HEAD",
want: map[string]string{
"dir1/": "",
"dir1/file1": "infile1",
"file 2": "infile2",
},
skipReader: false,
},
{
name: "repo-with-dotgit-dir",
remote: createRepoWithDotGitDir(t, root),
revision: "HEAD",
want: map[string]string{
"file1": "hello\n",
".git/mydir/file2": "milton\n",
".git/mydir/": "",
".git/": "",
},
skipReader: false,
},
{
name: "not-found",
revision: "HEAD",
clientErr: errors.New("repository does not exist: not-found"),
skipReader: false,
},
{
name: "revision-not-found",
remote: createRepoWithDotGitDir(t, root),
revision: "revision-not-found",
clientErr: nil,
readerError: &gitdomain.RevisionNotFoundError{Repo: "revision-not-found", Spec: "revision-not-found"},
skipReader: true,
},
}
runArchiveReaderTestfunc := func(t *testing.T, mkClient func(t *testing.T, addrs []string) gitserver.Client, name api.RepoName, test test) {
t.Run(string(name), func(t *testing.T) {
// Setup: Prepare the test Gitserver server + register the gRPC server
s := &server.Server{
Logger: logtest.Scoped(t),
ReposDir: filepath.Join(root, "repos"),
DB: newMockDB(),
GetRemoteURLFunc: func(_ context.Context, name api.RepoName) (string, error) {
if test.remote != "" {
return test.remote, nil
}
return "", errors.Errorf("no remote for %s", test.name)
},
GetVCSSyncer: func(ctx context.Context, name api.RepoName) (server.VCSSyncer, error) {
return server.NewGitRepoSyncer(wrexec.NewNoOpRecordingCommandFactory()), nil
},
RecordingCommandFactory: wrexec.NewNoOpRecordingCommandFactory(),
Locker: server.NewRepositoryLocker(),
RPSLimiter: ratelimit.NewInstrumentedLimiter("GitserverTest", rate.NewLimiter(100, 10)),
}
grpcServer := defaults.NewServer(logtest.Scoped(t))
proto.RegisterGitserverServiceServer(grpcServer, &server.GRPCServer{Server: s})
handler := internalgrpc.MultiplexHandlers(grpcServer, s.Handler())
srv := httptest.NewServer(handler)
defer srv.Close()
u, _ := url.Parse(srv.URL)
addrs := []string{u.Host}
cli := mkClient(t, addrs)
ctx := context.Background()
if test.remote != "" {
if _, err := cli.RequestRepoUpdate(ctx, name, 0); err != nil {
t.Fatal(err)
}
}
rc, err := cli.ArchiveReader(ctx, nil, name, gitserver.ArchiveOptions{Treeish: test.revision, Format: gitserver.ArchiveFormatZip})
if have, want := fmt.Sprint(err), fmt.Sprint(test.clientErr); have != want {
t.Errorf("archive: have err %v, want %v", have, want)
}
if rc == nil {
return
}
t.Cleanup(func() {
if err := rc.Close(); err != nil {
t.Fatal(err)
}
})
data, readErr := io.ReadAll(rc)
if readErr != nil {
if readErr.Error() != test.readerError.Error() {
t.Errorf("archive: have reader err %v, want %v", readErr.Error(), test.readerError.Error())
}
if test.skipReader {
return
}
t.Fatal(readErr)
}
zr, err := zip.NewReader(bytes.NewReader(data), int64(len(data)))
if err != nil {
t.Fatal(err)
}
got := map[string]string{}
for _, f := range zr.File {
r, err := f.Open()
if err != nil {
t.Errorf("failed to open %q because %s", f.Name, err)
continue
}
contents, err := io.ReadAll(r)
_ = r.Close()
if err != nil {
t.Errorf("Read(%q): %s", f.Name, err)
continue
}
got[f.Name] = string(contents)
}
if !cmp.Equal(test.want, got) {
t.Errorf("mismatch (-want +got):\n%s", cmp.Diff(test.want, got))
}
})
}
t.Run("grpc", func(t *testing.T) {
conf.Mock(&conf.Unified{
SiteConfiguration: schema.SiteConfiguration{
ExperimentalFeatures: &schema.ExperimentalFeatures{
EnableGRPC: boolPointer(true),
},
},
})
t.Cleanup(func() {
conf.Mock(nil)
})
for _, test := range tests {
repoName := api.RepoName(test.name)
called := false
mkClient := func(t *testing.T, addrs []string) gitserver.Client {
t.Helper()
source := gitserver.NewTestClientSource(t, addrs, func(o *gitserver.TestClientSourceOptions) {
o.ClientFunc = func(cc *grpc.ClientConn) proto.GitserverServiceClient {
base := proto.NewGitserverServiceClient(cc)
mockArchive := func(ctx context.Context, in *proto.ArchiveRequest, opts ...grpc.CallOption) (proto.GitserverService_ArchiveClient, error) {
called = true
return base.Archive(ctx, in, opts...)
}
mockRepoUpdate := func(ctx context.Context, in *proto.RepoUpdateRequest, opts ...grpc.CallOption) (*proto.RepoUpdateResponse, error) {
base := proto.NewGitserverServiceClient(cc)
return base.RepoUpdate(ctx, in, opts...)
}
return &mockClient{
mockArchive: mockArchive,
mockRepoUpdate: mockRepoUpdate,
}
}
})
return gitserver.NewTestClient(&http.Client{}, source)
}
runArchiveReaderTestfunc(t, mkClient, repoName, test)
if !called {
t.Error("archiveReader: GitserverServiceClient should have been called")
}
}
})
t.Run("http", func(t *testing.T) {
conf.Mock(&conf.Unified{
SiteConfiguration: schema.SiteConfiguration{
ExperimentalFeatures: &schema.ExperimentalFeatures{
EnableGRPC: boolPointer(false),
},
},
})
t.Cleanup(func() {
conf.Mock(nil)
})
for _, test := range tests {
repoName := api.RepoName(test.name)
called := false
mkClient := func(t *testing.T, addrs []string) gitserver.Client {
t.Helper()
source := gitserver.NewTestClientSource(t, addrs, func(o *gitserver.TestClientSourceOptions) {
o.ClientFunc = func(cc *grpc.ClientConn) proto.GitserverServiceClient {
mockArchive := func(ctx context.Context, in *proto.ArchiveRequest, opts ...grpc.CallOption) (proto.GitserverService_ArchiveClient, error) {
called = true
base := proto.NewGitserverServiceClient(cc)
return base.Archive(ctx, in, opts...)
}
return &mockClient{mockArchive: mockArchive}
}
})
return gitserver.NewTestClient(&http.Client{}, source)
}
runArchiveReaderTestfunc(t, mkClient, repoName, test)
if called {
t.Error("archiveReader: GitserverServiceClient should have been called")
}
}
})
}
func createRepoWithDotGitDir(t *testing.T, root string) string {
t.Helper()
b64 := func(s string) string {
t.Helper()
b, err := base64.StdEncoding.DecodeString(s)
if err != nil {
t.Fatal(err)
}
return string(b)
}
dir := filepath.Join(root, "remotes", "repo-with-dot-git-dir")
// This repo was synthesized by hand to contain a file whose path is `.git/mydir/file2` (the Git
// CLI will not let you create a file with a `.git` path component).
//
// The synthesized bad commit is:
//
// commit aa600fc517ea6546f31ae8198beb1932f13b0e4c (HEAD -> master)
// Author: Quinn Slack <qslack@qslack.com>
// Date: Tue Jun 5 16:17:20 2018 -0700
//
// wip
//
// diff --git a/.git/mydir/file2 b/.git/mydir/file2
// new file mode 100644
// index 0000000..82b919c
// --- /dev/null
// +++ b/.git/mydir/file2
// @@ -0,0 +1 @@
// +milton
files := map[string]string{
"config": `
[core]
repositoryformatversion=0
filemode=true
`,
"HEAD": `ref: refs/heads/master`,
"refs/heads/master": `aa600fc517ea6546f31ae8198beb1932f13b0e4c`,
"objects/e7/9c5e8f964493290a409888d5413a737e8e5dd5": b64("eAFLyslPUrBgyMzLLMlMzOECACgtBOw="),
"objects/ce/013625030ba8dba906f756967f9e9ca394464a": b64("eAFLyslPUjBjyEjNycnnAgAdxQQU"),
"objects/82/b919c9c565d162c564286d9d6a2497931be47e": b64("eAFLyslPUjBnyM3MKcnP4wIAIw8ElA=="),
"objects/e5/231c1d547df839dce09809e43608fe6c537682": b64("eAErKUpNVTAzYTAxAAIFvfTMEgbb8lmsKdJ+zz7ukeMOulcqZqOllmloYGBmYqKQlpmTashwjtFMlZl7xe2VbN/DptXPm7N4ipsXACOoGDo="),
"objects/da/5ecc846359eaf23e8abe907b3125fdd7abdbc0": b64("eAErKUpNVTA2ZjA0MDAzMVFIy8xJNWJo2il58mjqxaSjKRq5c7NUpk+WflIHABZRD2I="),
"objects/d0/01d287018593691c36042e1c8089fde7415296": b64("eAErKUpNVTA2ZjA0MDAzMVFIy8xJNWQ4x2imysy94vZKtu9h0+rnzVk8xc0LAP2TDiQ="),
"objects/b4/009ecbf1eba01c5279f25840e2afc0d15f5005": b64("eAGdjdsJAjEQRf1OFdOAMpPN5gEitiBWEJIRBzcJu2b7N2IHfh24nMtJrRTpQA4PfWOGjEhZe4fk5zDZQGmyaDRT8ujDI7MzNOtgVdz7s21w26VWuC8xveC8vr+8/nBKrVxgyF4bJBfgiA5RjXUEO/9xVVKlS1zUB/JxNbA="),
"objects/3d/779a05641b4ee6f1bc1e0b52de75163c2a2669": b64("eAErKUpNVTA2YjAxAAKF3MqUzCKGW3FnWpIjX32y69o3odpQ9e/11bcPAAAipRGQ"),
"objects/aa/600fc517ea6546f31ae8198beb1932f13b0e4c": b64("eAGdjlkKAjEQBf3OKfoCSmfpLCDiFcQTZDodHHQWxwxe3xFv4FfBKx4UT8PQNzDa7doiAkLGataFXCg12lRYMEVM4qzHWMUz2eCjUXNeZGzQOdwkd1VLl1EzmZCqoehQTK6MRVMlRFJ5bbdpgcvajyNcH5nvcHy+vjz/cOBpOIEmE41D7xD2GBDVtm6BTf64qnc/qw9c4UKS"),
"objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391": b64("eAFLyslPUjBgAAAJsAHw"),
}
for name, data := range files {
name = filepath.Join(dir, name)
if err := os.MkdirAll(filepath.Dir(name), 0700); err != nil {
t.Fatal(err)
}
if err := os.WriteFile(name, []byte(data), 0600); err != nil {
t.Fatal(err)
}
}
return dir
}
func createSimpleGitRepo(t *testing.T, root string) string {
t.Helper()
dir := filepath.Join(root, "remotes", "simple")
if err := os.MkdirAll(dir, 0700); err != nil {
t.Fatal(err)
}
for _, cmd := range []string{
"git init",
"mkdir dir1",
"echo -n infile1 > dir1/file1",
"touch --date=2006-01-02T15:04:05Z dir1 dir1/file1 || touch -t 200601021704.05 dir1 dir1/file1",
"git add dir1/file1",
"GIT_COMMITTER_NAME=a GIT_COMMITTER_EMAIL=a@a.com GIT_AUTHOR_DATE=2006-01-02T15:04:05Z GIT_COMMITTER_DATE=2006-01-02T15:04:05Z git commit -m commit1 --author='a <a@a.com>' --date 2006-01-02T15:04:05Z",
"echo -n infile2 > 'file 2'",
"touch --date=2014-05-06T19:20:21Z 'file 2' || touch -t 201405062120.21 'file 2'",
"git add 'file 2'",
"GIT_COMMITTER_NAME=a GIT_COMMITTER_EMAIL=a@a.com GIT_AUTHOR_DATE=2006-01-02T15:04:05Z GIT_COMMITTER_DATE=2014-05-06T19:20:21Z git commit -m commit2 --author='a <a@a.com>' --date 2014-05-06T19:20:21Z",
"git branch test-ref HEAD~1",
"git branch test-nested-ref test-ref",
} {
c := exec.Command("bash", "-c", `GIT_CONFIG_GLOBAL="" GIT_CONFIG_SYSTEM="" `+cmd)
c.Dir = dir
out, err := c.CombinedOutput()
if err != nil {
t.Fatalf("Command %q failed. Output was:\n\n%s", cmd, out)
}
}
return dir
}
type mockP4ExecClient struct {
isEndOfStream bool
Err error
@ -887,7 +511,7 @@ func TestClient_P4ExecGRPC(t *testing.T) {
}, nil
}
return &mockClient{mockP4Exec: mockP4Exec}
return &gitserver.MockGRPCClient{MockP4Exec: mockP4Exec}
}
})
@ -1038,92 +662,6 @@ func TestClient_P4Exec(t *testing.T) {
})
}
func TestClient_ResolveRevisions(t *testing.T) {
root := t.TempDir()
remote := createSimpleGitRepo(t, root)
// These hashes should be stable since we set the timestamps
// when creating the commits.
hash1 := "b6602ca96bdc0ab647278577a3c6edcb8fe18fb0"
hash2 := "c5151eceb40d5e625716589b745248e1a6c6228d"
tests := []struct {
input []protocol.RevisionSpecifier
want []string
err error
}{{
input: []protocol.RevisionSpecifier{{}},
want: []string{hash2},
}, {
input: []protocol.RevisionSpecifier{{RevSpec: "HEAD"}},
want: []string{hash2},
}, {
input: []protocol.RevisionSpecifier{{RevSpec: "HEAD~1"}},
want: []string{hash1},
}, {
input: []protocol.RevisionSpecifier{{RevSpec: "test-ref"}},
want: []string{hash1},
}, {
input: []protocol.RevisionSpecifier{{RevSpec: "test-nested-ref"}},
want: []string{hash1},
}, {
input: []protocol.RevisionSpecifier{{RefGlob: "refs/heads/test-*"}},
want: []string{hash1, hash1}, // two hashes because to refs point to that hash
}, {
input: []protocol.RevisionSpecifier{{RevSpec: "test-fake-ref"}},
err: &gitdomain.RevisionNotFoundError{Repo: api.RepoName(remote), Spec: "test-fake-ref"},
}}
logger := logtest.Scoped(t)
db := newMockDB()
ctx := context.Background()
s := server.Server{
Logger: logger,
ReposDir: filepath.Join(root, "repos"),
GetRemoteURLFunc: func(_ context.Context, name api.RepoName) (string, error) {
return remote, nil
},
GetVCSSyncer: func(ctx context.Context, name api.RepoName) (server.VCSSyncer, error) {
return server.NewGitRepoSyncer(wrexec.NewNoOpRecordingCommandFactory()), nil
},
DB: db,
Perforce: perforce.NewService(ctx, observation.TestContextTB(t), logger, db, list.New()),
RecordingCommandFactory: wrexec.NewNoOpRecordingCommandFactory(),
Locker: server.NewRepositoryLocker(),
RPSLimiter: ratelimit.NewInstrumentedLimiter("GitserverTest", rate.NewLimiter(100, 10)),
}
grpcServer := defaults.NewServer(logtest.Scoped(t))
proto.RegisterGitserverServiceServer(grpcServer, &server.GRPCServer{Server: &s})
handler := internalgrpc.MultiplexHandlers(grpcServer, s.Handler())
srv := httptest.NewServer(handler)
defer srv.Close()
u, _ := url.Parse(srv.URL)
addrs := []string{u.Host}
source := gitserver.NewTestClientSource(t, addrs)
cli := gitserver.NewTestClient(&http.Client{}, source)
for _, test := range tests {
t.Run("", func(t *testing.T) {
_, err := cli.RequestRepoUpdate(ctx, api.RepoName(remote), 0)
require.NoError(t, err)
got, err := cli.ResolveRevisions(ctx, api.RepoName(remote), test.input)
if test.err != nil {
require.Equal(t, test.err, err)
return
}
require.NoError(t, err)
require.Equal(t, test.want, got)
})
}
}
func TestClient_BatchLogGRPC(t *testing.T) {
conf.Mock(&conf.Unified{
SiteConfiguration: schema.SiteConfiguration{
@ -1163,7 +701,7 @@ func TestClient_BatchLogGRPC(t *testing.T) {
return resp.ToProto(), nil
}
return &mockClient{mockBatchLog: mockBatchLog}
return &gitserver.MockGRPCClient{MockBatchLog: mockBatchLog}
}
})
@ -1244,8 +782,8 @@ func TestClient_BatchLog(t *testing.T) {
}, nil
}
return &mockClient{
mockBatchLog: mockBatchLog,
return &gitserver.MockGRPCClient{
MockBatchLog: mockBatchLog,
}
}
})
@ -1444,7 +982,7 @@ func TestClient_IsRepoCloneableGRPC(t *testing.T) {
}
return tc.mockResponse.ToProto(), nil
}
return &mockClient{mockIsRepoCloneable: mockIsRepoCloneable}
return &gitserver.MockGRPCClient{MockIsRepoCloneable: mockIsRepoCloneable}
}
})
@ -1481,7 +1019,7 @@ func TestClient_IsRepoCloneableGRPC(t *testing.T) {
}
return tc.mockResponse.ToProto(), nil
}
return &mockClient{mockIsRepoCloneable: mockIsRepoCloneable}
return &gitserver.MockGRPCClient{MockIsRepoCloneable: mockIsRepoCloneable}
}
})
@ -1546,7 +1084,7 @@ func TestClient_SystemsInfo(t *testing.T) {
called = true
return mockResponse, nil
}
return &mockClient{mockDiskInfo: mockDiskInfo}
return &gitserver.MockGRPCClient{MockDiskInfo: mockDiskInfo}
}
})
@ -1578,7 +1116,7 @@ func TestClient_SystemsInfo(t *testing.T) {
called = true
return mockResponse, nil
}
return &mockClient{mockDiskInfo: mockDiskInfo}
return &gitserver.MockGRPCClient{MockDiskInfo: mockDiskInfo}
}
})
@ -1641,7 +1179,7 @@ func TestClient_SystemInfo(t *testing.T) {
called = true
return mockResponse, nil
}
return &mockClient{mockDiskInfo: mockDiskInfo}
return &gitserver.MockGRPCClient{MockDiskInfo: mockDiskInfo}
}
})
@ -1673,7 +1211,7 @@ func TestClient_SystemInfo(t *testing.T) {
called = true
return mockResponse, nil
}
return &mockClient{mockDiskInfo: mockDiskInfo}
return &gitserver.MockGRPCClient{MockDiskInfo: mockDiskInfo}
}
})
@ -1701,103 +1239,6 @@ func TestClient_SystemInfo(t *testing.T) {
})
}
type mockClient struct {
mockBatchLog func(ctx context.Context, in *proto.BatchLogRequest, opts ...grpc.CallOption) (*proto.BatchLogResponse, error)
mockCreateCommitFromPatchBinary func(ctx context.Context, opts ...grpc.CallOption) (proto.GitserverService_CreateCommitFromPatchBinaryClient, error)
mockDiskInfo func(ctx context.Context, in *proto.DiskInfoRequest, opts ...grpc.CallOption) (*proto.DiskInfoResponse, error)
mockExec func(ctx context.Context, in *proto.ExecRequest, opts ...grpc.CallOption) (proto.GitserverService_ExecClient, error)
mockGetObject func(ctx context.Context, in *proto.GetObjectRequest, opts ...grpc.CallOption) (*proto.GetObjectResponse, error)
mockIsRepoCloneable func(ctx context.Context, in *proto.IsRepoCloneableRequest, opts ...grpc.CallOption) (*proto.IsRepoCloneableResponse, error)
mockListGitolite func(ctx context.Context, in *proto.ListGitoliteRequest, opts ...grpc.CallOption) (*proto.ListGitoliteResponse, error)
mockRepoClone func(ctx context.Context, in *proto.RepoCloneRequest, opts ...grpc.CallOption) (*proto.RepoCloneResponse, error)
mockRepoCloneProgress func(ctx context.Context, in *proto.RepoCloneProgressRequest, opts ...grpc.CallOption) (*proto.RepoCloneProgressResponse, error)
mockRepoDelete func(ctx context.Context, in *proto.RepoDeleteRequest, opts ...grpc.CallOption) (*proto.RepoDeleteResponse, error)
mockRepoUpdate func(ctx context.Context, in *proto.RepoUpdateRequest, opts ...grpc.CallOption) (*proto.RepoUpdateResponse, error)
mockArchive func(ctx context.Context, in *proto.ArchiveRequest, opts ...grpc.CallOption) (proto.GitserverService_ArchiveClient, error)
mockSearch func(ctx context.Context, in *proto.SearchRequest, opts ...grpc.CallOption) (proto.GitserverService_SearchClient, error)
mockP4Exec func(ctx context.Context, in *proto.P4ExecRequest, opts ...grpc.CallOption) (proto.GitserverService_P4ExecClient, error)
mockIsPerforcePathCloneable func(ctx context.Context, in *proto.IsPerforcePathCloneableRequest, opts ...grpc.CallOption) (*proto.IsPerforcePathCloneableResponse, error)
mockCheckPerforceCredentials func(ctx context.Context, in *proto.CheckPerforceCredentialsRequest, opts ...grpc.CallOption) (*proto.CheckPerforceCredentialsResponse, error)
}
// BatchLog implements v1.GitserverServiceClient.
func (mc *mockClient) BatchLog(ctx context.Context, in *proto.BatchLogRequest, opts ...grpc.CallOption) (*proto.BatchLogResponse, error) {
return mc.mockBatchLog(ctx, in, opts...)
}
// DiskInfo implements v1.GitserverServiceClient.
func (mc *mockClient) DiskInfo(ctx context.Context, in *proto.DiskInfoRequest, opts ...grpc.CallOption) (*proto.DiskInfoResponse, error) {
return mc.mockDiskInfo(ctx, in, opts...)
}
// GetObject implements v1.GitserverServiceClient.
func (mc *mockClient) GetObject(ctx context.Context, in *proto.GetObjectRequest, opts ...grpc.CallOption) (*proto.GetObjectResponse, error) {
return mc.mockGetObject(ctx, in, opts...)
}
// ListGitolite implements v1.GitserverServiceClient.
func (mc *mockClient) ListGitolite(ctx context.Context, in *proto.ListGitoliteRequest, opts ...grpc.CallOption) (*proto.ListGitoliteResponse, error) {
return mc.mockListGitolite(ctx, in, opts...)
}
// P4Exec implements v1.GitserverServiceClient.
func (mc *mockClient) P4Exec(ctx context.Context, in *proto.P4ExecRequest, opts ...grpc.CallOption) (proto.GitserverService_P4ExecClient, error) {
return mc.mockP4Exec(ctx, in, opts...)
}
// CreateCommitFromPatchBinary implements v1.GitserverServiceClient.
func (mc *mockClient) CreateCommitFromPatchBinary(ctx context.Context, opts ...grpc.CallOption) (proto.GitserverService_CreateCommitFromPatchBinaryClient, error) {
return mc.mockCreateCommitFromPatchBinary(ctx, opts...)
}
// RepoUpdate implements v1.GitserverServiceClient
func (mc *mockClient) RepoUpdate(ctx context.Context, in *proto.RepoUpdateRequest, opts ...grpc.CallOption) (*proto.RepoUpdateResponse, error) {
return mc.mockRepoUpdate(ctx, in, opts...)
}
// RepoDelete implements v1.GitserverServiceClient
func (mc *mockClient) RepoDelete(ctx context.Context, in *proto.RepoDeleteRequest, opts ...grpc.CallOption) (*proto.RepoDeleteResponse, error) {
return mc.mockRepoDelete(ctx, in, opts...)
}
// RepoCloneProgress implements v1.GitserverServiceClient
func (mc *mockClient) RepoCloneProgress(ctx context.Context, in *proto.RepoCloneProgressRequest, opts ...grpc.CallOption) (*proto.RepoCloneProgressResponse, error) {
return mc.mockRepoCloneProgress(ctx, in, opts...)
}
// Exec implements v1.GitserverServiceClient
func (mc *mockClient) Exec(ctx context.Context, in *proto.ExecRequest, opts ...grpc.CallOption) (proto.GitserverService_ExecClient, error) {
return mc.mockExec(ctx, in, opts...)
}
// RepoClone implements v1.GitserverServiceClient
func (mc *mockClient) RepoClone(ctx context.Context, in *proto.RepoCloneRequest, opts ...grpc.CallOption) (*proto.RepoCloneResponse, error) {
return mc.mockRepoClone(ctx, in, opts...)
}
func (ms *mockClient) IsRepoCloneable(ctx context.Context, in *proto.IsRepoCloneableRequest, opts ...grpc.CallOption) (*proto.IsRepoCloneableResponse, error) {
return ms.mockIsRepoCloneable(ctx, in, opts...)
}
// Search implements v1.GitserverServiceClient
func (ms *mockClient) Search(ctx context.Context, in *proto.SearchRequest, opts ...grpc.CallOption) (proto.GitserverService_SearchClient, error) {
return ms.mockSearch(ctx, in, opts...)
}
func (mc *mockClient) Archive(ctx context.Context, in *proto.ArchiveRequest, opts ...grpc.CallOption) (proto.GitserverService_ArchiveClient, error) {
return mc.mockArchive(ctx, in, opts...)
}
func (mc *mockClient) IsPerforcePathCloneable(ctx context.Context, in *proto.IsPerforcePathCloneableRequest, opts ...grpc.CallOption) (*proto.IsPerforcePathCloneableResponse, error) {
return mc.mockIsPerforcePathCloneable(ctx, in, opts...)
}
func (mc *mockClient) CheckPerforceCredentials(ctx context.Context, in *proto.CheckPerforceCredentialsRequest, opts ...grpc.CallOption) (*proto.CheckPerforceCredentialsResponse, error) {
return mc.mockCheckPerforceCredentials(ctx, in, opts...)
}
var _ proto.GitserverServiceClient = &mockClient{}
var _ proto.GitserverService_P4ExecClient = &mockP4ExecClient{}
type fuzzTime time.Time

View File

@ -1,4 +0,0 @@
// Package inttests contains integration tests that requires a running gitserver
// instance and are in their own package to avoid cyclic dependencies between
// cmd/gitserver and internal/gitserver
package inttests

106
internal/gitserver/mock.go Normal file
View File

@ -0,0 +1,106 @@
package gitserver
import (
"context"
"google.golang.org/grpc"
proto "github.com/sourcegraph/sourcegraph/internal/gitserver/v1"
)
type MockGRPCClient struct {
MockBatchLog func(ctx context.Context, in *proto.BatchLogRequest, opts ...grpc.CallOption) (*proto.BatchLogResponse, error)
MockCreateCommitFromPatchBinary func(ctx context.Context, opts ...grpc.CallOption) (proto.GitserverService_CreateCommitFromPatchBinaryClient, error)
MockDiskInfo func(ctx context.Context, in *proto.DiskInfoRequest, opts ...grpc.CallOption) (*proto.DiskInfoResponse, error)
MockExec func(ctx context.Context, in *proto.ExecRequest, opts ...grpc.CallOption) (proto.GitserverService_ExecClient, error)
MockGetObject func(ctx context.Context, in *proto.GetObjectRequest, opts ...grpc.CallOption) (*proto.GetObjectResponse, error)
MockIsRepoCloneable func(ctx context.Context, in *proto.IsRepoCloneableRequest, opts ...grpc.CallOption) (*proto.IsRepoCloneableResponse, error)
MockListGitolite func(ctx context.Context, in *proto.ListGitoliteRequest, opts ...grpc.CallOption) (*proto.ListGitoliteResponse, error)
MockRepoClone func(ctx context.Context, in *proto.RepoCloneRequest, opts ...grpc.CallOption) (*proto.RepoCloneResponse, error)
MockRepoCloneProgress func(ctx context.Context, in *proto.RepoCloneProgressRequest, opts ...grpc.CallOption) (*proto.RepoCloneProgressResponse, error)
MockRepoDelete func(ctx context.Context, in *proto.RepoDeleteRequest, opts ...grpc.CallOption) (*proto.RepoDeleteResponse, error)
MockRepoUpdate func(ctx context.Context, in *proto.RepoUpdateRequest, opts ...grpc.CallOption) (*proto.RepoUpdateResponse, error)
MockArchive func(ctx context.Context, in *proto.ArchiveRequest, opts ...grpc.CallOption) (proto.GitserverService_ArchiveClient, error)
MockSearch func(ctx context.Context, in *proto.SearchRequest, opts ...grpc.CallOption) (proto.GitserverService_SearchClient, error)
MockP4Exec func(ctx context.Context, in *proto.P4ExecRequest, opts ...grpc.CallOption) (proto.GitserverService_P4ExecClient, error)
MockIsPerforcePathCloneable func(ctx context.Context, in *proto.IsPerforcePathCloneableRequest, opts ...grpc.CallOption) (*proto.IsPerforcePathCloneableResponse, error)
MockCheckPerforceCredentials func(ctx context.Context, in *proto.CheckPerforceCredentialsRequest, opts ...grpc.CallOption) (*proto.CheckPerforceCredentialsResponse, error)
}
// BatchLog implements v1.GitserverServiceClient.
func (mc *MockGRPCClient) BatchLog(ctx context.Context, in *proto.BatchLogRequest, opts ...grpc.CallOption) (*proto.BatchLogResponse, error) {
return mc.MockBatchLog(ctx, in, opts...)
}
// DiskInfo implements v1.GitserverServiceClient.
func (mc *MockGRPCClient) DiskInfo(ctx context.Context, in *proto.DiskInfoRequest, opts ...grpc.CallOption) (*proto.DiskInfoResponse, error) {
return mc.MockDiskInfo(ctx, in, opts...)
}
// GetObject implements v1.GitserverServiceClient.
func (mc *MockGRPCClient) GetObject(ctx context.Context, in *proto.GetObjectRequest, opts ...grpc.CallOption) (*proto.GetObjectResponse, error) {
return mc.MockGetObject(ctx, in, opts...)
}
// ListGitolite implements v1.GitserverServiceClient.
func (mc *MockGRPCClient) ListGitolite(ctx context.Context, in *proto.ListGitoliteRequest, opts ...grpc.CallOption) (*proto.ListGitoliteResponse, error) {
return mc.MockListGitolite(ctx, in, opts...)
}
// P4Exec implements v1.GitserverServiceClient.
func (mc *MockGRPCClient) P4Exec(ctx context.Context, in *proto.P4ExecRequest, opts ...grpc.CallOption) (proto.GitserverService_P4ExecClient, error) {
return mc.MockP4Exec(ctx, in, opts...)
}
// CreateCommitFromPatchBinary implements v1.GitserverServiceClient.
func (mc *MockGRPCClient) CreateCommitFromPatchBinary(ctx context.Context, opts ...grpc.CallOption) (proto.GitserverService_CreateCommitFromPatchBinaryClient, error) {
return mc.MockCreateCommitFromPatchBinary(ctx, opts...)
}
// RepoUpdate implements v1.GitserverServiceClient
func (mc *MockGRPCClient) RepoUpdate(ctx context.Context, in *proto.RepoUpdateRequest, opts ...grpc.CallOption) (*proto.RepoUpdateResponse, error) {
return mc.MockRepoUpdate(ctx, in, opts...)
}
// RepoDelete implements v1.GitserverServiceClient
func (mc *MockGRPCClient) RepoDelete(ctx context.Context, in *proto.RepoDeleteRequest, opts ...grpc.CallOption) (*proto.RepoDeleteResponse, error) {
return mc.MockRepoDelete(ctx, in, opts...)
}
// RepoCloneProgress implements v1.GitserverServiceClient
func (mc *MockGRPCClient) RepoCloneProgress(ctx context.Context, in *proto.RepoCloneProgressRequest, opts ...grpc.CallOption) (*proto.RepoCloneProgressResponse, error) {
return mc.MockRepoCloneProgress(ctx, in, opts...)
}
// Exec implements v1.GitserverServiceClient
func (mc *MockGRPCClient) Exec(ctx context.Context, in *proto.ExecRequest, opts ...grpc.CallOption) (proto.GitserverService_ExecClient, error) {
return mc.MockExec(ctx, in, opts...)
}
// RepoClone implements v1.GitserverServiceClient
func (mc *MockGRPCClient) RepoClone(ctx context.Context, in *proto.RepoCloneRequest, opts ...grpc.CallOption) (*proto.RepoCloneResponse, error) {
return mc.MockRepoClone(ctx, in, opts...)
}
func (ms *MockGRPCClient) IsRepoCloneable(ctx context.Context, in *proto.IsRepoCloneableRequest, opts ...grpc.CallOption) (*proto.IsRepoCloneableResponse, error) {
return ms.MockIsRepoCloneable(ctx, in, opts...)
}
// Search implements v1.GitserverServiceClient
func (ms *MockGRPCClient) Search(ctx context.Context, in *proto.SearchRequest, opts ...grpc.CallOption) (proto.GitserverService_SearchClient, error) {
return ms.MockSearch(ctx, in, opts...)
}
func (mc *MockGRPCClient) Archive(ctx context.Context, in *proto.ArchiveRequest, opts ...grpc.CallOption) (proto.GitserverService_ArchiveClient, error) {
return mc.MockArchive(ctx, in, opts...)
}
func (mc *MockGRPCClient) IsPerforcePathCloneable(ctx context.Context, in *proto.IsPerforcePathCloneableRequest, opts ...grpc.CallOption) (*proto.IsPerforcePathCloneableResponse, error) {
return mc.MockIsPerforcePathCloneable(ctx, in, opts...)
}
func (mc *MockGRPCClient) CheckPerforceCredentials(ctx context.Context, in *proto.CheckPerforceCredentialsRequest, opts ...grpc.CallOption) (*proto.CheckPerforceCredentialsResponse, error) {
return mc.MockCheckPerforceCredentials(ctx, in, opts...)
}
var _ proto.GitserverServiceClient = &MockGRPCClient{}

View File

@ -33,13 +33,11 @@ go_library(
embed = [":v1_go_proto"],
importpath = "github.com/sourcegraph/sourcegraph/internal/gitserver/v1",
visibility = [
"//cmd/gitserver/server:__pkg__",
"//cmd/gitserver/shared:__pkg__",
"//cmd/gitserver:__subpackages__",
"//internal/api:__pkg__",
"//internal/extsvc/gitolite:__pkg__",
"//internal/gitserver:__pkg__",
"//internal/gitserver/gitdomain:__pkg__",
"//internal/gitserver/integration_tests:__pkg__",
"//internal/gitserver/protocol:__pkg__",
],
deps = [

View File

@ -8,10 +8,10 @@ import (
"testing"
"github.com/sourcegraph/log/logtest"
"github.com/sourcegraph/sourcegraph/internal/authz"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/sourcegraph/sourcegraph/internal/authz"
"github.com/sourcegraph/sourcegraph/internal/database"
"github.com/sourcegraph/sourcegraph/internal/database/dbtest"
"github.com/sourcegraph/sourcegraph/internal/types"
@ -74,8 +74,8 @@ func TestRecentViewsIndexer(t *testing.T) {
require.NoError(t, err)
defer rs.Close()
// `insertEvents` inserts two relevant events for paths:
// - cmd/gitserver/server/main.go
// - cmd/gitserver/server/patch.go
// - cmd/gitserver/internal/main.go
// - cmd/gitserver/internal/patch.go
// Since these are in the same directory:
// - every summary record that indicates a file, will have a count
// corresponding to the number of handlerRuns

View File

@ -35,8 +35,8 @@
path: github.com/sourcegraph/sourcegraph/cmd/frontend/internal/httpapi/releasecache
interfaces:
- ReleaseCache
- filename: cmd/gitserver/server/vcs_syncer_mock_test.go
path: github.com/sourcegraph/sourcegraph/cmd/gitserver/server
- filename: cmd/gitserver/internal/vcs_syncer_mock_test.go
path: github.com/sourcegraph/sourcegraph/cmd/gitserver/internal
interfaces:
- VCSSyncer
- filename: cmd/symbols/fetcher/mocks_test.go