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
path: root/doc
diff options
context:
space:
mode:
authorRobert May <rmay@gitlab.com>2021-12-08 16:23:49 +0300
committerPavlo Strokov <pstrokov@gitlab.com>2021-12-08 16:23:49 +0300
commit334cf0611a5819ac983b971ea47cacc0611163de (patch)
treefc1e393cdc308fd441e32fa398d66c90a41e1ade /doc
parentfe6bcc9ca347b59714c46adf65d100dd93abde52 (diff)
Updates to beginners_guide.md
Diffstat (limited to 'doc')
-rw-r--r--doc/beginners_guide.md144
1 files changed, 65 insertions, 79 deletions
diff --git a/doc/beginners_guide.md b/doc/beginners_guide.md
index d5ef0ef0a..a610aa2db 100644
--- a/doc/beginners_guide.md
+++ b/doc/beginners_guide.md
@@ -4,33 +4,31 @@
#### GitLab
-Before you can develop on Gitaly, it's required to have a
+Before you can develop on Gitaly, it's required to have the
[GitLab Development Kit][gdk] properly installed. After installing GitLab, verify
-it to be working by starting the required servers and visiting GitLab on
+it to be working by starting the required servers and visiting GitLab at
`http://localhost:3000`.
#### Gitaly Proto
-GitLab will want to read and manipulate Git data, to do this it needs to talk
-to Gitaly. For GitLab and Gitaly it's important to have a set protocol. This
-protocol defines what requests can be made and what data the requester has to
-send with the request. For each request the response is defined too.
+Data is shared between GitLab Rails and Gitaly using the [Google Protocol Buffers](https://developers.google.com/protocol-buffers) to provide a shared format for serializing the exchanged data. They are also referred to as _protobuf_.
+
+Protocol buffers define which requests can be made and what data the requester must provide with the request. The response to each request is likewise defined using the Protocol buffers format.
The protocol definitions can be found in `proto/*.proto`.
#### Gitaly
-Gitaly is a component that calls procedure on the Git data when it's requested
-to do so.
+Gitaly provides high-level RPC access to Git repositories. It controls access to the `git` binary and is used by GitLab to read and write Git data. Gitaly is present in every GitLab installation and coordinates Git repository storage and retrieval.
-You can find a clone of the gitaly repository in
+Within the GDK, you can find a clone of the Gitaly repository in
`/path/to/gdk/gitaly`. You can check out your working branch here, but
-be aware that `gdk update` will reset it to the tag specified by
+please be aware that `gdk update` will reset it to the tag specified by
`/path/to/gdk/gitlab/GITALY_SERVER_VERSION`.
-If you do a lot of Gitaly development this can get annoying. If you
-want to stop `gdk update` from messing with your Gitaly checkout, put
-the following in `/path/to/gdk/gdk.yml`:
+This can be ineffective if you do a lot of Gitaly development, so if you
+want to stop `gdk update` from overwriting your Gitaly checkout, add
+the following to `/path/to/gdk/gdk.yml`:
```yaml
gitaly:
@@ -43,20 +41,20 @@ gitaly:
##### Using the Makefile
-Gitaly uses make to manage its build process, where all targets are defined in
+Gitaly uses [Make](https://en.wikipedia.org/wiki/Make_(software)) to manage its build process, and all targets are defined in
our top-level [Makefile](../Makefile). By default, simply running `make` will
-build our "all" target, which installs Gitaly into the top-level directory so
+build our `all` target, which installs Gitaly into the `./_build/bin` directory so
that it's easily picked up by the GDK. The following is a list of the most
frequently used targets:
-- build: Build Gitaly, but do not install it.
+- `build`: Build Gitaly, but do not install it.
-- install: Build and install Gitaly. The destination directory can be modified
+- `install`: Build and install Gitaly. The destination directory can be modified
by modifying a set of variables, most importantly `PREFIX`.
-- test: Execute both Go and Ruby tests.
+- `test`: Execute both Go and Ruby tests.
-- clean: Remove all generated build artifacts.
+- `clean`: Remove all generated build artifacts.
You can modify some parts of the build process by setting up various variables.
For example, by executing `make V=1` you can do a verbose build or by overriding
@@ -66,7 +64,7 @@ will be used for generating code.
If you wish to persist your configuration, you may create a `config.mak` file
next to the Makefile and put all variables you wish to override in there.
-##### Editing code and seeing what happens
+##### Experimenting with editing code
If you're used to Ruby on Rails development you may be used to a "edit
code and reload" cycle where you keep editing and reloading until you
@@ -77,22 +75,27 @@ At some point you will know which Gitaly RPC you need to work on. This
is where you probably want to stop using `localhost:3000` and zoom in on
the RPC instead.
+###### A suggested workflow
+
To experiment with changing an RPC you should use the Gitaly service
tests. The RPC you want to work on will have tests somewhere in
-`internal/gitaly/service/...`. Find the tests for your RPC. Next, before you
-edit any code, make sure the tests pass when you run them:
-`go test ./internal/gitaly/service/foobar -count 1 -run MyRPC`. In this
-command, `MyRPC` is a regex that will match functions like
-`TestMyRPCSuccess` and `TestMyRPCValidationFailure`. Once you have found
-your tests and your test command, you can start tweaking the
-implementation or adding test cases and re-running the tests. The cycle
-is "edit code, run tests".
-
-This is many times faster than "edit gitaly, reinstall Gitaly into GDK,
+`internal/gitaly/service/...`.
+
+Before you edit any code, make sure the tests pass when you run them:
+
+```
+TEST_PACKAGES=./internal/gitaly/service/foobar TEST_OPTIONS="-count=1 -run=MyRPC" make test
+```
+
+In this command, `MyRPC` is a regex that will match functions like
+`TestMyRPCSuccess` and `TestMyRPCValidationFailure`.
+
+Once you have found your tests and your test command, you can start tweaking the implementation or adding test cases and re-running the tests.
+
+This approach is many times faster than "edit gitaly, reinstall Gitaly into GDK,
restart, reload `localhost:3000`".
-Regardless, if you do want to see your locally changed Gitaly in
-action on `localhost:3000`, you can. Run the following commands in
+To see the changes, run the following commands in
your GDK directory:
```shell
@@ -100,9 +103,9 @@ make gitaly-setup
gdk restart gitaly
```
-#### Process
+#### Development Process
-In general there are a couple of stages to go through, in order:
+The general approach is:
1. Add a request/response combination to [Gitaly Proto][gitaly-proto], or edit
an existing one
1. Change [Gitaly][gitaly] accordingly
@@ -111,23 +114,16 @@ In general there are a couple of stages to go through, in order:
##### Configuration changes
-When modifying Gitaly's or Praefect's configuration, the changes should be propagated to other GitLab projects that
-rely on them:
+When modifying the Gitaly or Praefect configuration, the changes should be propagated to other GitLab projects that rely on them:
1. [gitlab/omnibus-gitlab](https://gitlab.com/gitlab-org/omnibus-gitlab) contains template files that are used to generate Gitaly's and Praefect's configuration.
2. [gitlab/CNG](https://gitlab.com/gitlab-org/build/CNG) contains configuration required to run Gitaly in a container.
##### Gitaly Proto
-The [Protocol buffer documentation][proto-docs] combined with the
-`*.proto` files in the `proto/` directory should
-be enough to get you started. A service needs to be picked that can
-receive the procedure call. A general rule of thumb is that the
-service is named either after the Git CLI command, or after the Git
-object type.
+The [Protocol buffer documentation][proto-docs] combined with the `*.proto` files in the `proto/` directory should be enough to get you started. A service needs to be picked that can receive the procedure call. A general rule of thumb is that the service is named either after the Git CLI command, or after the Git object type.
-If either your request or response data can exceed 100KB you need to use the
-`stream` keyword. To generate the server and client code, run `make proto`.
+If either your request or response data can exceed 100KB you need to use the `stream` keyword. To generate the server and client code, run `make proto`.
##### Gitaly
@@ -141,9 +137,7 @@ is in the `ruby` subdirectory of Gitaly. Gitaly-ruby is a gRPC server,
just like its Go parent process. The Go parent proxies certain
requests to gitaly-ruby.
-Currently (GitLab 10.8) it is our experience that gitaly-ruby is
-unsuitable for RPC's that are slow, or that are called at a high rate.
-It should only be used for:
+It is our experience that gitaly-ruby is unsuitable for RPC's that are slow, or that are called with a high frequency. It should only be used for:
- legacy GitLab application code that is too complex or subtle to rewrite in Go
- prototyping (if you the contributor are uncomfortable writing Go)
@@ -170,8 +164,7 @@ The method name should match the name defined by the `gitaly` gem. To be sure
run `bundle open gitaly`. The return value of the method should be an
instance of the response object.
-There is no autoloader in gitaly-ruby. If you add new ruby files, you need to manually
-add a `require` statement in `ruby/lib/gitlab/git.rb` or `ruby/lib/gitaly_server.rb.`
+There is no autoloader in gitaly-ruby. If you add new ruby files, you need to manually add a `require` statement in `ruby/lib/gitlab/git.rb` or `ruby/lib/gitaly_server.rb.`
### Testing
@@ -181,11 +174,12 @@ Generally, you should always write new tests in Go even when testing Ruby code,
since we're planning to gradually rewrite everything in Go and want to avoid
having to rewrite the tests as well.
-Because praefect lives in the same repository we need to provide database connection
+Because Praefect lives in the same repository we need to provide database connection
information in order to run tests for it successfully. To get more info check out
[glsql](../internal/praefect/datastore/glsql/doc.go) package documentation.
-The easiest way to set up a Postgres database instance is to run it as a Docker container.
-You can do it using command:
+
+The easiest way to set up a Postgres database instance is to run it as a Docker container:
+
```bash
docker rm -f $(docker ps -q --all -f name=praefect-pg) > /dev/null 2>1; \
docker run --name praefect-pg -p 5432:5432 -e POSTGRES_HOST_AUTH_METHOD=trust -d postgres:12.6
@@ -199,15 +193,20 @@ You'll need some [test repositories](test_repos.md), you can set these up with `
- each RPC must have end-to-end tests at the service level
- optionally, you can add unit tests for functions that need more coverage
+##### Integration Tests
+
A typical set of Go tests for an RPC consists of two or three test
-functions: a success test, a failure test (usually a table driven test
-using t.Run), and sometimes a validation test. Our Go RPC tests use
-in-process test servers that only implement the service the current
-RPC belongs to. So if you are working on an RPC in the
-'RepositoryService', your tests would go in
-`internal/gitaly/service/repository/your_rpc_test.go`.
+functions:
+
+- a success test
+- a failure test (usually a table driven test using t.Run)
+- sometimes a validation test.
+
+Our Go RPC tests use in-process test servers that only implement the service the current RPC belongs to.
-##### Running one specific Go test
+For example, if you are working on an RPC in the 'RepositoryService', your tests would go in `internal/gitaly/service/repository/your_rpc_test.go`.
+
+##### Running a specific test
When you are trying to fix a specific test failure it is inefficient
to run `make test` all the time. To run just one test you need to know
@@ -218,7 +217,7 @@ To run the test you need a terminal window with working directory
`/path/to/gdk/gitaly`. To run just the one test you're interested in:
```
-go test ./internal/gitaly/service/repository -count 1 -run TestRepositoryExists
+TEST_PACKAGES=./internal/gitaly/service/repository TEST_OPTIONS="-count=1 -run=TestRepositoryExists" make test-go
```
When writing tests, prefer using [testify]'s [require], and [assert] as
@@ -229,27 +228,15 @@ called on `testing.T`.
[require]: https://github.com/stretchr/testify/tree/master/require
[assert]: https://github.com/stretchr/testify/tree/master/assert
-##### Troubleshooting
+##### Useful snippets for creating a test
-There is a [known issue][] running Go tests while using the [asdf version
-manager][asdf].
+###### testhelper package
-In order to avoid polluting local configurations during testing, a test may
-redefine the location of `$HOME`, which interferes with asdf's `$ASDF_DATA_DIR`
-definition of `$HOME/.asdf`. You may see errors like this:
+The `testhelper` package provides functions to create configurations to run gitaly and helpers to run a Gitaly gRPC server:
-```
-unknown command: bundle. Perhaps you have to reshim?
-```
-
-As a workaround, explicitly define the variable prior to executing tests:
-
-```sh
-$ ASDF_DATA_DIR=~/.asdf go test ...
-```
-
-[known issue]: https://gitlab.com/gitlab-org/gitaly/-/issues/2646
-[asdf]: https://asdf-vm.com/
+- [Create test configuration](https://gitlab.com/gitlab-org/gitaly/-/blob/aa098de7b267e3d6cb8a05e7862a1ad34f8f2ab5/internal/gitaly/service/ref/testhelper_test.go#L43)
+- [Run Gitaly](https://gitlab.com/gitlab-org/gitaly/-/blob/aa098de7b267e3d6cb8a05e7862a1ad34f8f2ab5/internal/gitaly/service/ref/testhelper_test.go#L57)
+- [Clone test repository](https://gitlab.com/gitlab-org/gitaly/-/blob/aa098de7b267e3d6cb8a05e7862a1ad34f8f2ab5/internal/gitaly/service/ref/find_all_tags_test.go#L30)
#### RSpec tests
@@ -274,7 +261,6 @@ To use your custom Gitaly when running Rails tests in GDK, go to the
`gitlab` directory in your GDK and follow the instructions at
[Running tests with a locally modified version of Gitaly][custom-gitaly].
-
[custom-gitaly]: https://docs.gitlab.com/ee/development/gitaly.html#running-tests-with-a-locally-modified-version-of-gitaly
[gdk]: https://gitlab.com/gitlab-org/gitlab-development-kit/#getting-started
[git-remote]: https://git-scm.com/book/en/v2/Git-Basics-Working-with-Remotes