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:
authorKim "BKC" Carlbäcker <kim.carlbacker@gmail.com>2017-10-22 21:39:53 +0300
committerKim "BKC" Carlbäcker <kim.carlbacker@gmail.com>2017-10-31 16:11:25 +0300
commit86d4e13cb2a642df3d3cd31b78977b16d756a19a (patch)
treeb788856243f494a98d2c4f0f0f98bcefb8ccc150
parent9ef5784e9a5f95cebb5cfda6a6a7bac7842c2a28 (diff)
WikiService::WikiUpdatePage
-rw-r--r--CHANGELOG.md2
-rw-r--r--internal/service/wiki/testhelper_test.go17
-rw-r--r--internal/service/wiki/update_page.go73
-rw-r--r--internal/service/wiki/update_page_test.go205
-rw-r--r--internal/service/wiki/write_page_test.go17
-rw-r--r--ruby/lib/gitaly_server/wiki_service.rb25
6 files changed, 320 insertions, 19 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 81d229216..bdeb1ee32 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,8 @@ v0.51.0
- Implement OperationService.UserFFMerge
https://gitlab.com/gitlab-org/gitaly/merge_requests/426
+- Implement WikiUpdatePage RPC
+ https://gitlab.com/gitlab-org/gitaly/merge_requests/422
- Implement WikiFindFile RPC
https://gitlab.com/gitlab-org/gitaly/merge_requests/425
- Implement WikiDeletePage RPC
diff --git a/internal/service/wiki/testhelper_test.go b/internal/service/wiki/testhelper_test.go
index 0de56997e..d41e97607 100644
--- a/internal/service/wiki/testhelper_test.go
+++ b/internal/service/wiki/testhelper_test.go
@@ -113,3 +113,20 @@ func writeWikiPage(t *testing.T, client pb.WikiServiceClient, name string, conte
_, err = stream.CloseAndRecv()
require.NoError(t, err)
}
+
+func sendBytes(data []byte, chunkSize int, sender func([]byte) error) (int, error) {
+ i := 0
+ for ; len(data) > 0; i++ {
+ n := chunkSize
+ if n > len(data) {
+ n = len(data)
+ }
+
+ if err := sender(data[:n]); err != nil {
+ return i, err
+ }
+ data = data[n:]
+ }
+
+ return i, nil
+}
diff --git a/internal/service/wiki/update_page.go b/internal/service/wiki/update_page.go
index 880591544..450971bd6 100644
--- a/internal/service/wiki/update_page.go
+++ b/internal/service/wiki/update_page.go
@@ -1,10 +1,79 @@
package wiki
import (
+ "fmt"
+
+ "gitlab.com/gitlab-org/gitaly/internal/rubyserver"
+
pb "gitlab.com/gitlab-org/gitaly-proto/go"
- "gitlab.com/gitlab-org/gitaly/internal/helper"
+
+ "google.golang.org/grpc"
+ "google.golang.org/grpc/codes"
)
func (s *server) WikiUpdatePage(stream pb.WikiService_WikiUpdatePageServer) error {
- return helper.Unimplemented
+ firstRequest, err := stream.Recv()
+ if err != nil {
+ return err
+ }
+
+ if err := validateWikiUpdatePageRequest(firstRequest); err != nil {
+ return grpc.Errorf(codes.InvalidArgument, "WikiUpdatePage: %v", err)
+ }
+
+ ctx := stream.Context()
+
+ client, err := s.WikiServiceClient(ctx)
+ if err != nil {
+ return err
+ }
+
+ clientCtx, err := rubyserver.SetHeaders(ctx, firstRequest.GetRepository())
+ if err != nil {
+ return err
+ }
+
+ rubyStream, err := client.WikiUpdatePage(clientCtx)
+ if err != nil {
+ return err
+ }
+
+ if err := rubyStream.Send(firstRequest); err != nil {
+ return err
+ }
+
+ err = rubyserver.Proxy(func() error {
+ request, err := stream.Recv()
+ if err != nil {
+ return err
+ }
+ return rubyStream.Send(request)
+ })
+
+ if err != nil {
+ return err
+ }
+
+ response, err := rubyStream.CloseAndRecv()
+ if err != nil {
+ return err
+ }
+
+ return stream.SendAndClose(response)
+}
+
+func validateWikiUpdatePageRequest(request *pb.WikiUpdatePageRequest) error {
+ if len(request.GetPagePath()) == 0 {
+ return fmt.Errorf("empty Page Path")
+ }
+
+ if len(request.GetTitle()) == 0 {
+ return fmt.Errorf("empty Title")
+ }
+
+ if len(request.GetFormat()) == 0 {
+ return fmt.Errorf("empty Format")
+ }
+
+ return validateRequestCommitDetails(request)
}
diff --git a/internal/service/wiki/update_page_test.go b/internal/service/wiki/update_page_test.go
new file mode 100644
index 000000000..1a9ba0eb5
--- /dev/null
+++ b/internal/service/wiki/update_page_test.go
@@ -0,0 +1,205 @@
+package wiki
+
+import (
+ "bytes"
+ "testing"
+
+ gitlog "gitlab.com/gitlab-org/gitaly/internal/git/log"
+ "gitlab.com/gitlab-org/gitaly/internal/testhelper"
+
+ pb "gitlab.com/gitlab-org/gitaly-proto/go"
+
+ "github.com/stretchr/testify/require"
+ "google.golang.org/grpc/codes"
+)
+
+func TestSuccessfulWikiUpdatePageRequest(t *testing.T) {
+ ctx, cancel := testhelper.Context()
+ defer cancel()
+
+ server, serverSocketPath := runWikiServiceServer(t)
+ defer server.Stop()
+
+ client, conn := newWikiClient(t, serverSocketPath)
+ defer conn.Close()
+
+ writeWikiPage(t, client, "Installing Gitaly", []byte("foobar"))
+
+ content := bytes.Repeat([]byte("Mock wiki page content"), 10000)
+
+ authorName := []byte("Ahmad Sherif")
+ authorEmail := []byte("ahmad@gitlab.com")
+ message := []byte("Add installation instructions")
+
+ request := &pb.WikiUpdatePageRequest{
+ Repository: wikiRepo,
+ PagePath: []byte("//Installing Gitaly"),
+ Title: []byte("Installing Gitaly"),
+ Format: "markdown",
+ CommitDetails: &pb.WikiCommitDetails{
+ Name: authorName,
+ Email: authorEmail,
+ Message: message,
+ },
+ }
+
+ stream, err := client.WikiUpdatePage(ctx)
+ require.NoError(t, err)
+
+ nSends, err := sendBytes(content, 1000, func(p []byte) error {
+ request.Content = p
+
+ if err := stream.Send(request); err != nil {
+ return err
+ }
+
+ // Use a new response so we don't send other fields (Repository, ...) over and over
+ request = &pb.WikiUpdatePageRequest{}
+
+ return nil
+ })
+
+ require.NoError(t, err)
+ require.True(t, nSends > 1, "should have sent more than one message")
+
+ _, err = stream.CloseAndRecv()
+ require.NoError(t, err)
+
+ headID := testhelper.MustRunCommand(t, nil, "git", "-C", wikiRepoPath, "show", "--format=format:%H", "--no-patch", "HEAD")
+ commit, err := gitlog.GetCommit(ctx, wikiRepo, string(headID), "")
+ require.NoError(t, err, "look up git commit before merge is applied")
+
+ require.Equal(t, authorName, commit.Author.Name, "author name mismatched")
+ require.Equal(t, authorEmail, commit.Author.Email, "author email mismatched")
+ require.Equal(t, message, commit.Subject, "message mismatched")
+
+ pageContent := testhelper.MustRunCommand(t, nil, "git", "-C", wikiRepoPath, "cat-file", "blob", "HEAD:Installing-Gitaly.md")
+ require.Equal(t, content, pageContent, "mismatched content")
+}
+
+func TestFailedWikiUpdatePageDueToValidations(t *testing.T) {
+ server, serverSocketPath := runWikiServiceServer(t)
+ defer server.Stop()
+
+ client, conn := newWikiClient(t, serverSocketPath)
+ defer conn.Close()
+
+ writeWikiPage(t, client, "Installing Gitaly", []byte("foobar"))
+
+ commitDetails := &pb.WikiCommitDetails{
+ Name: []byte("Ahmad Sherif"),
+ Email: []byte("ahmad@gitlab.com"),
+ Message: []byte("Add installation instructions"),
+ }
+
+ testCases := []struct {
+ desc string
+ request *pb.WikiUpdatePageRequest
+ code codes.Code
+ }{
+ {
+ desc: "empty page_path",
+ request: &pb.WikiUpdatePageRequest{
+ Repository: wikiRepo,
+ Title: []byte("Installing Gitaly"),
+ Format: "markdown",
+ CommitDetails: commitDetails,
+ Content: []byte(""),
+ },
+ code: codes.InvalidArgument,
+ },
+ {
+ desc: "empty title",
+ request: &pb.WikiUpdatePageRequest{
+ Repository: wikiRepo,
+ PagePath: []byte("//Installing Gitaly"),
+ Format: "markdown",
+ CommitDetails: commitDetails,
+ Content: []byte(""),
+ },
+ code: codes.InvalidArgument,
+ },
+ {
+ desc: "empty format",
+ request: &pb.WikiUpdatePageRequest{
+ Repository: wikiRepo,
+ PagePath: []byte("//Installing Gitaly.md"),
+ Title: []byte("Installing Gitaly"),
+ CommitDetails: commitDetails,
+ Content: []byte(""),
+ },
+ code: codes.InvalidArgument,
+ },
+ {
+ desc: "empty commit details",
+ request: &pb.WikiUpdatePageRequest{
+ Repository: wikiRepo,
+ PagePath: []byte("//Installing Gitaly.md"),
+ Title: []byte("Installing Gitaly"),
+ Format: "markdown",
+ Content: []byte(""),
+ },
+ code: codes.InvalidArgument,
+ },
+ {
+ desc: "empty commit details' name",
+ request: &pb.WikiUpdatePageRequest{
+ Repository: wikiRepo,
+ PagePath: []byte("//Installing Gitaly.md"),
+ Title: []byte("Installing Gitaly"),
+ Format: "markdown",
+ CommitDetails: &pb.WikiCommitDetails{
+ Email: []byte("a@b.com"),
+ Message: []byte("A message"),
+ },
+ Content: []byte(""),
+ },
+ code: codes.InvalidArgument,
+ },
+ {
+ desc: "empty commit details' email",
+ request: &pb.WikiUpdatePageRequest{
+ Repository: wikiRepo,
+ PagePath: []byte("//Installing Gitaly.md"),
+ Title: []byte("Installing Gitaly"),
+ Format: "markdown",
+ CommitDetails: &pb.WikiCommitDetails{
+ Name: []byte("A name"),
+ Message: []byte("A message"),
+ },
+ Content: []byte(""),
+ },
+ code: codes.InvalidArgument,
+ },
+ {
+ desc: "empty commit details' message",
+ request: &pb.WikiUpdatePageRequest{
+ Repository: wikiRepo,
+ PagePath: []byte("//Installing Gitaly.md"),
+ Title: []byte("Installing Gitaly"),
+ Format: "markdown",
+ CommitDetails: &pb.WikiCommitDetails{
+ Name: []byte("A name"),
+ Email: []byte("a@b.com"),
+ },
+ Content: []byte(""),
+ },
+ code: codes.InvalidArgument,
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.desc, func(t *testing.T) {
+ ctx, cancel := testhelper.Context()
+ defer cancel()
+
+ stream, err := client.WikiUpdatePage(ctx)
+ require.NoError(t, err)
+
+ require.NoError(t, stream.Send(testCase.request))
+
+ _, err = stream.CloseAndRecv()
+ testhelper.AssertGrpcError(t, err, testCase.code, "")
+ })
+ }
+}
diff --git a/internal/service/wiki/write_page_test.go b/internal/service/wiki/write_page_test.go
index b61724321..99b515c20 100644
--- a/internal/service/wiki/write_page_test.go
+++ b/internal/service/wiki/write_page_test.go
@@ -221,20 +221,3 @@ func TestFailedWikiWritePageDueToValidations(t *testing.T) {
})
}
}
-
-func sendBytes(data []byte, chunkSize int, sender func([]byte) error) (int, error) {
- i := 0
- for ; len(data) > 0; i++ {
- n := chunkSize
- if n > len(data) {
- n = len(data)
- }
-
- if err := sender(data[:n]); err != nil {
- return i, err
- }
- data = data[n:]
- }
-
- return i, nil
-}
diff --git a/ruby/lib/gitaly_server/wiki_service.rb b/ruby/lib/gitaly_server/wiki_service.rb
index 5cb6721c3..a22553705 100644
--- a/ruby/lib/gitaly_server/wiki_service.rb
+++ b/ruby/lib/gitaly_server/wiki_service.rb
@@ -119,5 +119,30 @@ module GitalyServer
end
end
end
+
+ def wiki_update_page(call)
+ bridge_exceptions do
+ repo = Gitlab::Git::Repository.from_call(call)
+ title = format = page_path = commit_details = nil
+ content = ""
+
+ wiki = Gitlab::Git::Wiki.new(repo)
+ call.each_remote_read.with_index do |request, index|
+ if index.zero?
+ title = request.title
+ page_path = request.page_path
+ format = request.format
+
+ commit_details = commit_details_from_gitaly(request.commit_details)
+ end
+
+ content << request.content
+ end
+
+ wiki.update_page(page_path, title, format.to_sym, content, commit_details)
+
+ Gitaly::WikiUpdatePageResponse.new
+ end
+ end
end
end