Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitaly.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'internal/gitaly/service/repository/config_test.go')
-rw-r--r--internal/gitaly/service/repository/config_test.go161
1 files changed, 156 insertions, 5 deletions
diff --git a/internal/gitaly/service/repository/config_test.go b/internal/gitaly/service/repository/config_test.go
index c8f108075..00a365b7f 100644
--- a/internal/gitaly/service/repository/config_test.go
+++ b/internal/gitaly/service/repository/config_test.go
@@ -3,6 +3,10 @@ package repository
import (
"bufio"
"bytes"
+ "context"
+ "io/ioutil"
+ "os"
+ "path/filepath"
"strings"
"testing"
@@ -10,12 +14,70 @@ import (
"gitlab.com/gitlab-org/gitaly/internal/git/gittest"
"gitlab.com/gitlab-org/gitaly/internal/gitaly/config"
"gitlab.com/gitlab-org/gitaly/internal/gitaly/rubyserver"
+ "gitlab.com/gitlab-org/gitaly/internal/gitaly/transaction"
+ "gitlab.com/gitlab-org/gitaly/internal/helper"
+ "gitlab.com/gitlab-org/gitaly/internal/metadata/featureflag"
"gitlab.com/gitlab-org/gitaly/internal/testhelper"
+ "gitlab.com/gitlab-org/gitaly/internal/testhelper/testserver"
+ "gitlab.com/gitlab-org/gitaly/internal/transaction/txinfo"
+ "gitlab.com/gitlab-org/gitaly/internal/transaction/voting"
"gitlab.com/gitlab-org/gitaly/proto/go/gitalypb"
+ "gitlab.com/gitlab-org/gitaly/streamio"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)
+func TestGetConfig(t *testing.T) {
+ cfg, client := setupRepositoryServiceWithoutRepo(t)
+
+ getConfig := func(
+ t *testing.T,
+ client gitalypb.RepositoryServiceClient,
+ repo *gitalypb.Repository,
+ ) (string, error) {
+ ctx, cleanup := testhelper.Context()
+ defer cleanup()
+
+ stream, err := client.GetConfig(ctx, &gitalypb.GetConfigRequest{
+ Repository: repo,
+ })
+ require.NoError(t, err)
+
+ reader := streamio.NewReader(func() ([]byte, error) {
+ response, err := stream.Recv()
+ var bytes []byte
+ if response != nil {
+ bytes = response.Data
+ }
+ return bytes, err
+ })
+
+ contents, err := ioutil.ReadAll(reader)
+ return string(contents), err
+ }
+
+ t.Run("normal repo", func(t *testing.T) {
+ repo, _, cleanup := gittest.InitBareRepoAt(t, cfg, cfg.Storages[0])
+ defer cleanup()
+
+ config, err := getConfig(t, client, repo)
+ require.NoError(t, err)
+ require.Equal(t, "[core]\n\trepositoryformatversion = 0\n\tfilemode = true\n\tbare = true\n", config)
+ })
+
+ t.Run("missing config", func(t *testing.T) {
+ repo, repoPath, cleanup := gittest.InitBareRepoAt(t, cfg, cfg.Storages[0])
+ defer cleanup()
+
+ configPath := filepath.Join(repoPath, "config")
+ require.NoError(t, os.Remove(configPath))
+
+ config, err := getConfig(t, client, repo)
+ require.Equal(t, status.Errorf(codes.NotFound, "opening gitconfig: open %s: no such file or directory", configPath), err)
+ require.Equal(t, "", config)
+ })
+}
+
func TestDeleteConfig(t *testing.T) {
cfg, client := setupRepositoryServiceWithoutRepo(t)
@@ -44,11 +106,11 @@ func TestDeleteConfig(t *testing.T) {
ctx, cancel := testhelper.Context()
defer cancel()
- repo, repoPath, cleanupFn := gittest.CloneRepoAtStorage(t, cfg.Storages[0], t.Name())
+ repo, repoPath, cleanupFn := gittest.CloneRepoAtStorage(t, cfg, cfg.Storages[0], t.Name())
t.Cleanup(cleanupFn)
for _, k := range tc.addKeys {
- testhelper.MustRunCommand(t, nil, "git", "-C", repoPath, "config", k, "blabla")
+ gittest.Exec(t, cfg, "-C", repoPath, "config", k, "blabla")
}
_, err := client.DeleteConfig(ctx, &gitalypb.DeleteConfigRequest{Repository: repo, Keys: tc.reqKeys})
@@ -59,7 +121,7 @@ func TestDeleteConfig(t *testing.T) {
return
}
- actualConfig := testhelper.MustRunCommand(t, nil, "git", "-C", repoPath, "config", "-l")
+ actualConfig := gittest.Exec(t, cfg, "-C", repoPath, "config", "-l")
scanner := bufio.NewScanner(bytes.NewReader(actualConfig))
for scanner.Scan() {
for _, k := range tc.reqKeys {
@@ -72,6 +134,47 @@ func TestDeleteConfig(t *testing.T) {
}
}
+func TestDeleteConfigTransactional(t *testing.T) {
+ testhelper.NewFeatureSets([]featureflag.FeatureFlag{
+ featureflag.TxConfig,
+ }).Run(t, func(t *testing.T, ctx context.Context) {
+ var votes []voting.Vote
+ txManager := transaction.MockManager{
+ VoteFn: func(_ context.Context, _ txinfo.Transaction, _ txinfo.PraefectServer, vote voting.Vote) error {
+ votes = append(votes, vote)
+ return nil
+ },
+ }
+
+ cfg, repo, repoPath, client := setupRepositoryService(t, testserver.WithTransactionManager(&txManager))
+
+ ctx, err := (&txinfo.PraefectServer{SocketPath: "i-dont-care"}).Inject(ctx)
+ require.NoError(t, err)
+ ctx, err = txinfo.InjectTransaction(ctx, 1, "node", true)
+ require.NoError(t, err)
+ ctx = helper.IncomingToOutgoing(ctx)
+
+ unmodifiedContents := testhelper.MustReadFile(t, filepath.Join(repoPath, "config"))
+ gittest.Exec(t, cfg, "-C", repoPath, "config", "delete.me", "now")
+ modifiedContents := testhelper.MustReadFile(t, filepath.Join(repoPath, "config"))
+
+ _, err = client.DeleteConfig(ctx, &gitalypb.DeleteConfigRequest{
+ Repository: repo,
+ Keys: []string{"delete.me"},
+ })
+ require.NoError(t, err)
+
+ if featureflag.IsEnabled(ctx, featureflag.TxConfig) {
+ require.Equal(t, []voting.Vote{
+ voting.VoteFromData(modifiedContents),
+ voting.VoteFromData(unmodifiedContents),
+ }, votes)
+ } else {
+ require.Len(t, votes, 0)
+ }
+ })
+}
+
func testSetConfig(t *testing.T, cfg config.Cfg, rubySrv *rubyserver.Server) {
cfg, _, _, client := setupRepositoryServiceWithRuby(t, cfg, rubySrv)
@@ -104,7 +207,7 @@ func testSetConfig(t *testing.T, cfg config.Cfg, rubySrv *rubyserver.Server) {
ctx, cancel := testhelper.Context()
defer cancel()
- testRepo, testRepoPath, cleanupFn := gittest.CloneRepoAtStorage(t, cfg.Storages[0], t.Name())
+ testRepo, testRepoPath, cleanupFn := gittest.CloneRepoAtStorage(t, cfg, cfg.Storages[0], t.Name())
defer cleanupFn()
_, err := client.SetConfig(ctx, &gitalypb.SetConfigRequest{Repository: testRepo, Entries: tc.entries})
@@ -115,7 +218,7 @@ func testSetConfig(t *testing.T, cfg config.Cfg, rubySrv *rubyserver.Server) {
return
}
- actualConfigBytes := testhelper.MustRunCommand(t, nil, "git", "-C", testRepoPath, "config", "--local", "-l")
+ actualConfigBytes := gittest.Exec(t, cfg, "-C", testRepoPath, "config", "--local", "-l")
scanner := bufio.NewScanner(bytes.NewReader(actualConfigBytes))
var actualConfig []string
@@ -130,3 +233,51 @@ func testSetConfig(t *testing.T, cfg config.Cfg, rubySrv *rubyserver.Server) {
})
}
}
+
+func testSetConfigTransactional(t *testing.T, cfg config.Cfg, rubySrv *rubyserver.Server) {
+ testhelper.NewFeatureSets([]featureflag.FeatureFlag{
+ featureflag.TxConfig,
+ }).Run(t, func(t *testing.T, ctx context.Context) {
+ var votes []voting.Vote
+
+ txManager := transaction.MockManager{
+ VoteFn: func(_ context.Context, _ txinfo.Transaction, _ txinfo.PraefectServer, vote voting.Vote) error {
+ votes = append(votes, vote)
+ return nil
+ },
+ }
+
+ _, repo, repoPath, client := setupRepositoryServiceWithRuby(t, cfg, rubySrv, testserver.WithTransactionManager(&txManager))
+
+ ctx, err := (&txinfo.PraefectServer{SocketPath: "i-dont-care"}).Inject(ctx)
+ require.NoError(t, err)
+ ctx, err = txinfo.InjectTransaction(ctx, 1, "node", true)
+ require.NoError(t, err)
+ ctx = helper.IncomingToOutgoing(ctx)
+
+ unmodifiedContents := testhelper.MustReadFile(t, filepath.Join(repoPath, "config"))
+
+ _, err = client.SetConfig(ctx, &gitalypb.SetConfigRequest{
+ Repository: repo,
+ Entries: []*gitalypb.SetConfigRequest_Entry{
+ &gitalypb.SetConfigRequest_Entry{
+ Key: "set.me",
+ Value: &gitalypb.SetConfigRequest_Entry_ValueStr{
+ "something",
+ },
+ },
+ },
+ })
+ require.NoError(t, err)
+
+ if featureflag.IsEnabled(ctx, featureflag.TxConfig) {
+ modifiedContents := string(unmodifiedContents) + "[set]\n\tme = something\n"
+ require.Equal(t, []voting.Vote{
+ voting.VoteFromData(unmodifiedContents),
+ voting.VoteFromData([]byte(modifiedContents)),
+ }, votes)
+ } else {
+ require.Len(t, votes, 0)
+ }
+ })
+}