Skip to content

Commit

Permalink
Merge branch 'main' into issue-251-gt
Browse files Browse the repository at this point in the history
  • Loading branch information
AlekSi committed Mar 18, 2022
2 parents 27450fa + d7de884 commit d84508e
Show file tree
Hide file tree
Showing 58 changed files with 1,388 additions and 357 deletions.
4 changes: 2 additions & 2 deletions .github/RELEASE_CHECKLIST.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@
9. Refresh
* `env GOPROXY=https://proxy.golang.org go get -v github.com/FerretDB/FerretDB@<tag>`
* https://pkg.go.dev/github.com/FerretDB/FerretDB
10. `make docker-local`
11. `make docker-push` with four tags (`X.Y.Z` and `latest` for both ghcr.io and Docker Hub).
10. `bin/task docker-local`
11. `bin/task docker-push` with four tags (`X.Y.Z` and `latest` for both ghcr.io and Docker Hub).
13 changes: 8 additions & 5 deletions .github/workflows/docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,14 @@ jobs:
with:
cache-key: build

- name: Install Task
run: cd tools; go generate -x

- name: Run init
run: make init
run: bin/task init

- name: Initialize Docker Buildx builder
run: make docker-init
run: bin/task docker-init

- name: Extract Docker image name and tag
id: extract
Expand All @@ -99,7 +102,7 @@ jobs:
password: ${{ secrets.GITHUB_TOKEN }}

- name: Build Docker image ${{ steps.extract.outputs.ghcr }}
run: make docker-push
run: bin/task docker-push
env:
DOCKER_IMAGE: ${{ steps.extract.outputs.ghcr }}

Expand All @@ -116,11 +119,11 @@ jobs:
if: github.event_name != 'pull_request_target' || contains(github.event.pull_request.labels.*.name, 'trust')

steps:
- name: Detect matching PR
- name: Detect matching PR or branch
id: detect
uses: FerretDB/github-actions/detect-matching-pr@main

- name: Restart dance PR actions
- name: Restart dance PR or branch actions
uses: FerretDB/github-actions/restart-pr-actions@main
with:
owner: ${{ steps.detect.outputs.owner }}
Expand Down
52 changes: 36 additions & 16 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,24 +30,27 @@ jobs:
fetch-depth: 0

- name: Start pulling environment in the background
run: make env-pull &
run: bin/task env-pull &

- name: Setup Go
uses: FerretDB/github-actions/setup-go@main
with:
cache-key: test

- name: Install Task
run: cd tools; go generate -x

- name: Start environment
run: make env-up-detach
run: bin/task env-up-detach

- name: Run init
run: make init
run: bin/task init

- name: Wait for and setup environment
run: make env-setup
run: bin/task env-setup

- name: Run tests
run: make test
run: bin/task test

- name: Upload coverage information
uses: codecov/codecov-action@v2
Expand Down Expand Up @@ -78,6 +81,19 @@ jobs:
path: source
fetch-depth: 0

- name: Setup Go
uses: FerretDB/github-actions/setup-go@main
with:
cache-key: fuzz

- name: Install Task
run: cd tools; go generate -x
working-directory: source

- name: Start pulling environment in the background
run: bin/task env-pull &
working-directory: source

# Use deploy key instead of Personal Access Token (PAT) to limit access to one repository.
# If secrets are not available (for example, for a pull request from a fork), GITHUB_TOKEN PAT is used automatically.
- name: Checkout collected fuzz corpus
Expand All @@ -88,37 +104,41 @@ jobs:
path: fuzz-corpus
fetch-depth: 0

- name: Setup Go
uses: FerretDB/github-actions/setup-go@main
with:
cache-key: fuzz
- name: Start environment
run: bin/task env-up-detach
working-directory: source

- name: Run init
run: make init
run: bin/task init
working-directory: source

- name: Setup corpus
run: make fuzz-corpus
run: bin/task fuzz-corpus
working-directory: source

- name: Wait for and setup environment
run: bin/task env-setup
working-directory: source

# precompile tests with unset GOMAXPROCS
- name: Init fuzzers
run: make fuzz-init
run: bin/task fuzz-init
working-directory: source

# TODO https://github.com/FerretDB/FerretDB/issues/238
- name: Run fuzzers
run: make fuzz
# TODO https://github.com/FerretDB/FerretDB/issues/344
- name: Run collected fuzzing corpus
run: bin/task fuzz
working-directory: source
env:
GOMAXPROCS: 1 # otherwise, oom-killer kills fuzzer too often
FUZZTIME: 10s
FUZZTIME: 5s
FUZZCORPUS: ../fuzz-corpus

- name: Collect corpus
if: always()
run: |
make fuzz-corpus
bin/task fuzz-corpus
go run ./cmd/fuzztool/fuzztool.go -src=seed -dst=../fuzz-corpus
working-directory: source

Expand Down
6 changes: 6 additions & 0 deletions .golangci-required.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ run:
linters-settings:
exhaustive:
default-signifies-exhaustive: false
gci:
sections:
- standard
- default
- prefix(github.com/FerretDB/FerretDB)
godox:
keywords:
- BUG
Expand Down Expand Up @@ -38,6 +43,7 @@ linters:
disable-all: true
enable:
- exhaustive
- gci
- godox
- goheader
- goimports
Expand Down
5 changes: 5 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ linters-settings:
- github.com/FerretDB/FerretDB/internal/bson
exhaustive:
default-signifies-exhaustive: false
gci:
sections:
- standard
- default
- prefix(github.com/FerretDB/FerretDB)
goconst:
min-occurrences: 5
ignore-tests: true
Expand Down
43 changes: 17 additions & 26 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,51 +2,42 @@

FerretDB is currently developed in either Linux or macOS, everything else is running inside Docker Compose.

You will need Go 1.18 (for [fuzzing](https://go.dev/blog/fuzz-beta) and [generics](https://go.dev/blog/generics-proposal)) that is not yet released.
[Compile it yourself](https://golang.org/doc/install/source) or use [`gotip download`](https://pkg.go.dev/golang.org/dl/gotip).

To verify your Go version:
```
$ go version
go version devel go1.18-[...]
```
**Note:** If using gotip and `go version` does not return version 1.18, you may need to symbolic link `gotip` to `go`.
```sh
$ ln -s `which gotip` /usr/local/bin/go
```
Use `which gotip` to get the path to gotip.
You will need Go 1.18 as FerretDB extensively uses ([fuzzing](https://go.dev/doc/tutorial/fuzz)) and [generics](https://go.dev/doc/tutorial/generics)).
If your package manager does not provide it yet, please install it from [go.dev](https://go.dev/dl/).

## Cloning the Repository

After forking FerretDB you can clone the repository - for the best practices use the following instructions:
After forking FerretDB on GitHub, you can clone the repository:

```sh
$ git clone git@github.com:FerretDB/FerretDB.git
$ cd FerretDB
$ git remote rename origin upstream
$ git remote set-url --push upstream NO_PUSH
$ git remote add origin git@github.com:<YOUR_GITHUB_USERNAME>/FerretDB.git
git clone git@github.com:<YOUR_GITHUB_USERNAME>/FerretDB.git
cd FerretDB
git remote add upstream https://github.com/FerretDB/FerretDB.git
```

## Helpful Commands

1. Install tools with `make init`.
2. Start the development environment with `make env-up`.
In order to run development commands you should get [task](https://taskfile.dev/).
You can do this with `cd tools; go generate -x`.
After this `task` will be available with `bin/task` on Linux and `bin\task.exe` on Windows.

1. Install development tools with `bin/task init`.
2. Start the development environment with `bin/task env-up`.
This will start PostgreSQL and MongoDB; filling them with identical sets of test data.
3. You may then run tests in another window with `make test`.
4. You can start FerretDB with `make run`.
3. You may then run tests in another window with `bin/task test`.
4. You can start FerretDB with `bin/task run`.
This will start it in a development mode where all requests are handled by FerretDB, but also routed to MongoDB.
The differences in response are then logged and the FerretDB response is sent back to the client.
5. Run `mongosh` with `make mongosh`.
5. Run `mongosh` with `bin/task mongosh`.
This allows you to run commands against FerretDB.

You can see all available "make" commands with `make help`.
You can see all available "task" commands with `bin/task -l`.

## Code Overview

Package `cmd` provides commands implementation. `ferretdb` is the main FerretDB binary; others are tools for development.

Package `tools` uses "tools.go" approach to fix tools versions. They are installed into `bin/` by `make init`.
Package `tools` uses "tools.go" approach to fix tools versions. They are installed into `bin/` by `cd tools; go generate -x`.

`internal` subpackages contain most of the FerretDB code:
* `types` package provides Go types matching BSON types that don't have built-in Go equivalents: we use `int32` for BSON's int32, but `types.ObjectID` for BSON's ObjectId.
Expand Down
135 changes: 9 additions & 126 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,128 +1,11 @@
FUZZTIME ?= 20s
FUZZCORPUS ?= ../fuzz-corpus
# That's a shim for https://github.com/FerretDB/github-actions/blob/main/linters/action.yml
# TODO Remove this file when https://github.com/FerretDB/dance/issues/75 is done
# and github-actions are updated to use bin/task.

all: fmt test
init:
cd tools; go generate -x
bin/task init

help: ## Display this help message
@echo "Please use \`make <target>\` where <target> is one of:"
@grep '^[a-zA-Z]' $(MAKEFILE_LIST) | \
awk -F ':.*?## ' 'NF==2 {printf " %-26s%s\n", $$1, $$2}'

env-up: env-up-detach env-setup ## Start development environment
docker-compose logs --follow

env-up-detach:
docker-compose up --always-recreate-deps --force-recreate --remove-orphans --renew-anon-volumes --detach

env-setup: gen-version
go run ./cmd/envtool/main.go

env-pull:
docker-compose pull --include-deps --quiet

env-down: ## Stop development environment
docker-compose down --remove-orphans --volumes

init: gen-version ## Install development tools
rm -fr bin
go mod tidy
cd tools && go mod tidy
go mod verify
cd tools && go generate -tags=tools -x

gen: bin/gofumpt ## Generate code
go generate -x ./...
$(MAKE) fmt

gen-version:
go generate -x ./internal/util/version

fmt: bin/gofumpt ## Format code
bin/gofumpt -w .

test: ## Run tests
go test -race -shuffle=on -coverprofile=cover.txt -coverpkg=./... ./...
go test -race -shuffle=on -bench=. -benchtime=1x ./...

# That's not quite correct: https://github.com/golang/go/issues/15513
# But good enough for us.
fuzz-init: gen-version
go test -count=0 ./...

fuzz: ## Fuzz for about 2 minutes (with default FUZZTIME)
go test -list='Fuzz.*' ./...
# Running seven functions for $(FUZZTIME) each..."
go test -fuzz=FuzzArray -fuzztime=$(FUZZTIME) ./internal/bson/
go test -fuzz=FuzzDocument -fuzztime=$(FUZZTIME) ./internal/bson/
go test -fuzz=FuzzArray -fuzztime=$(FUZZTIME) ./internal/fjson/
go test -fuzz=FuzzDocument -fuzztime=$(FUZZTIME) ./internal/fjson/
go test -fuzz=FuzzMsg -fuzztime=$(FUZZTIME) ./internal/wire/
go test -fuzz=FuzzQuery -fuzztime=$(FUZZTIME) ./internal/wire/
go test -fuzz=FuzzReply -fuzztime=$(FUZZTIME) ./internal/wire/

fuzz-corpus: ## Sync generated fuzz corpus with FUZZCORPUS
go run ./cmd/fuzztool/fuzztool.go -src=$(FUZZCORPUS) -dst=generated
go run ./cmd/fuzztool/fuzztool.go -dst=$(FUZZCORPUS) -src=generated

bench-short: ## Benchmark for about 20 seconds
go test -list='Benchmark.*' ./...
rm -f new.txt
go test -bench=BenchmarkArray -benchtime=5s ./internal/bson/ | tee -a new.txt
go test -bench=BenchmarkDocument -benchtime=5s ./internal/bson/ | tee -a new.txt
go test -bench=BenchmarkArray -benchtime=5s ./internal/fjson/ | tee -a new.txt
go test -bench=BenchmarkDocument -benchtime=5s ./internal/fjson/ | tee -a new.txt
bin/benchstat old.txt new.txt

build-testcover: gen-version ## Build bin/ferretdb-testcover
go test -c -o=bin/ferretdb-testcover -trimpath -tags=testcover -race -coverpkg=./... ./cmd/ferretdb

run: build-testcover ## Run FerretDB
bin/ferretdb-testcover -test.coverprofile=cover.txt -mode=diff-normal -listen-addr=:27017

lint: bin/go-sumtype bin/golangci-lint ## Run linters
bin/go-sumtype ./...
bin/golangci-lint run --config=.golangci-required.yml
bin/golangci-lint run --config=.golangci.yml
bin/go-consistent -pedantic ./...

psql: ## Run psql
docker-compose exec postgres psql -U postgres -d ferretdb

mongosh: ## Run mongosh
docker-compose exec mongodb mongosh mongodb://host.docker.internal:27017/monila?heartbeatFrequencyMS=300000 \
--verbose --eval 'disableTelemetry()' --shell

mongo: ## Run (legacy) mongo shell
docker-compose exec mongodb mongo mongodb://host.docker.internal:27017/monila?heartbeatFrequencyMS=300000 \
--verbose

docker-init:
docker buildx create --driver=docker-container --name=ferretdb

docker-build: build-testcover
env CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go test -c -o=bin/ferretdb-arm64 -trimpath -tags=testcover -coverpkg=./... ./cmd/ferretdb
env CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go test -c -o=bin/ferretdb-amd64 -trimpath -tags=testcover -coverpkg=./... ./cmd/ferretdb

docker-local: docker-build
docker buildx build --builder=ferretdb \
--build-arg VERSION=$(shell cat internal/util/version/version.txt) \
--build-arg COMMIT=$(shell cat internal/util/version/commit.txt) \
--tag=ferretdb-local \
--load .

docker-push: docker-build
test $(DOCKER_IMAGE)
docker buildx build --builder=ferretdb --platform=linux/arm64,linux/amd64 \
--build-arg VERSION=$(shell cat internal/util/version/version.txt) \
--build-arg COMMIT=$(shell cat internal/util/version/commit.txt) \
--tag=$(DOCKER_IMAGE) \
--push .

bin/golangci-lint:
$(MAKE) init

bin/go-sumtype:
$(MAKE) init

bin/gofumports:
$(MAKE) init
%:
# Use `bin/task $@` instead.
bin/task $@
Loading

0 comments on commit d84508e

Please sign in to comment.