move master to main #1

Merged
erius merged 18 commits from master into main 2024-06-05 17:39:20 +00:00
269 changed files with 5275 additions and 1624 deletions

View file

@ -1,190 +0,0 @@
- group: Bonus
start: 11-02-2023 18:00
deadline: 29-05-2023 23:59
tasks:
- task: consistenthash
score: 200
- task: gossip
score: 300
- task: smartsched
score: 200
watch:
- distbuild/pkg/scheduler
- task: wasm
score: 300
- group: Analysis
start: 29-04-2023 18:00
deadline: 10-05-2023 23:59
tasks:
- task: testifycheck
score: 200
- task: gzep
score: 100
- group: "[HW] Dist Build"
start: 26-04-2023 12:00
deadline: 29-05-2023 23:59
tasks:
- task: distbuild
score: 0
- group: Low level
start: 22-04-2023 16:00
deadline: 03-05-2023 23:59
tasks:
- task: illegal
score: 100
- task: blowfish
score: 100
- group: Reflect
start: 15-04-2023 16:00
deadline: 25-04-2023 23:59
tasks:
- task: reversemap
score: 100
- task: jsonlist
score: 100
- task: jsonrpc
score: 100
- task: structtags
score: 100
- group: SQL
start: 08-04-2023 16:00
deadline: 18-04-2023 23:59
tasks:
- task: dao
score: 100
- task: ledger
score: 200
- task: shopfront
score: 100
- task: wscat
score: 200
- group: Generics
start: 01-04-2023 16:00
deadline: 11-04-2023 23:59
tasks:
- task: genericsum
score: 100
- task: treeiter
score: 100
- task: coverme
score: 300
- group: HTTP
start: 25-03-2023 16:00
deadline: 06-04-2023 23:59
tasks:
- task: urlshortener
score: 100
- task: digitalclock
score: 100
- task: middleware
score: 200
- task: olympics
score: 200
- task: firewall
score: 200
- group: Concurrency with shared memory
start: 18-03-2023 15:59
deadline: 29-03-2023 23:59
tasks:
- task: dupcall
score: 200
- task: keylock
score: 200
- task: batcher
score: 200
- task: pubsub
score: 300
- group: Testing
start: 11-03-2023 13:00
deadline: 21-03-2023 23:59
tasks:
- task: testequal
score: 100
- task: fileleak
score: 100
- task: tabletest
score: 100
- task: tparallel
score: 200
- task: iprange
score: 100
- group: "[HW] Gitfame"
start: 04-03-2023 16:30
deadline: 19-03-2023 23:59
tasks:
- task: gitfame
score: 0
- group: Goroutines
start: 04-03-2023 16:30
deadline: 14-03-2023 23:59
tasks:
- task: tour1
score: 100
- task: once
score: 100
- task: rwmutex
score: 100
- task: waitgroup
score: 100
- task: cond
score: 100
- task: ratelimit
score: 100
- group: Interfaces
start: 25-02-2023 16:30
deadline: 07-03-2023 23:59
tasks:
- task: otp
score: 100
- task: lrucache
score: 100
- task: externalsort
score: 100
- task: retryupdate
score: 100
- task: ciletters
score: 100
- group: Basics
start: 18-02-2023 16:00
deadline: 28-02-2023 23:59
tasks:
- task: hotelbusiness
score: 100
- task: hogwarts
score: 100
- task: utf8
score: 100
- task: varfmt
score: 100
- task: speller
score: 100
- task: forth
score: 100
- group: Hello World
start: 11-02-2023 18:00
deadline: 21-02-2023 23:59
tasks:
- task: sum
score: 100
- task: tour0
score: 100
- task: wordcount
score: 100
- task: urlfetch
score: 100
- task: fetchall
score: 100

4
.gitignore vendored
View file

@ -3,3 +3,7 @@
.vscode/ .vscode/
/example/ /example/
# Go profiling files
*.out
*.test

View file

@ -1,11 +1,7 @@
grade: grade:
image: cr.yandex/crp9onavos88ug32d5r2/grader/go tags:
variables: - experimental
DOCKER_HOST: tcp://docker:2375/ image: gitlab.manytask.org:5050/go/public-2024-spring
DOCKER_TLS_CERTDIR: ""
APP_HOST: docker
# services:
#- docker:dind
script: script:
- testtool grade - testtool grade
timeout: 10 minutes timeout: 10 minutes

263
.manytask.yml Normal file
View file

@ -0,0 +1,263 @@
version: 1
settings: # required
course_name: go
gitlab_base_url: https://gitlab.manytask.org
public_repo: go/public-2024-spring
students_group: go/students-2024-spring
ui:
task_url_template: https://github.com/slon/shad-go/tree/main/$TASK_NAME
# optional, any number of links
links:
"TG Channel": https://t.me/+eb5z6ZS-sI8xZDNi
"TG Chat": https://t.me/+Tk8VTMAk5Tlp7Txm
"LMS": https://lk.yandexdataschool.ru/
"Contribute Manytask": https://github.com/manytask
deadlines:
timezone: Europe/Moscow
deadlines: hard # hard/interpolate
# max_submissions: 10 # optional
# submission_penalty: 0.1 # optional
schedule:
- group: Hello World
start: 2024-01-01 18:00
steps:
0.3: 2024-02-27 23:59
end: 2024-07-10 23:59
tasks:
- task: sum
score: 100
- task: tour0
score: 100
- task: wordcount
score: 100
- task: urlfetch
score: 100
- task: fetchall
score: 100
- group: Basics
start: 2024-02-24 13:00
steps:
0.3: 2024-03-06 06:00
end: 2024-07-10 23:59
tasks:
- task: hotelbusiness
score: 100
- task: hogwarts
score: 100
- task: utf8
score: 100
- task: varfmt
score: 100
- task: speller
score: 100
- task: forth
score: 100
- group: Interfaces
start: 2024-03-02 13:00
steps:
0.3: 2024-03-12 23:59
end: 2024-07-10 23:59
tasks:
- task: otp
score: 100
- task: retryupdate
score: 100
- task: lrucache
score: 100
- task: externalsort
score: 100
- task: ciletters
score: 100
- group: Goroutines
start: 2024-03-03 13:00
steps:
0.3: 2024-03-19 23:59
end: 2024-07-10 23:59
tasks:
- task: tour1
score: 100
- task: once
score: 100
- task: rwmutex
score: 100
- task: waitgroup
score: 100
- task: cond
score: 100
- task: ratelimit
score: 100
- group: "[HW] Gitfame"
start: 2024-03-09 13:00
end: 2024-03-24 23:59
tasks:
- task: gitfame
score: 0
- group: Testing
start: 2024-03-16 13:00
steps:
0.3: 2024-03-27 23:59
end: 2024-07-10 23:59
tasks:
- task: testequal
score: 100
- task: fileleak
score: 100
- task: tabletest
score: 100
- task: tparallel
score: 200
- task: iprange
score: 100
- group: Concurrency with shared memory
start: 2024-03-30 13:00
steps:
0.3: 2024-04-10 23:59
end: 2024-07-10 23:59
tasks:
- task: dupcall
score: 200
- task: keylock
score: 200
- task: batcher
score: 200
- task: pubsub
score: 300
- group: HTTP
start: 2024-04-06 13:00
steps:
0.3: 2024-04-16 23:59
end: 2024-07-10 23:59
tasks:
- task: urlshortener
score: 100
- task: digitalclock
score: 100
- task: middleware
score: 200
- task: firewall
score: 200
- task: olympics
score: 200
- group: SQL
start: 2024-04-13 13:00
steps:
0.3: 2024-04-23 23:59
end: 2024-07-10 23:59
tasks:
- task: dao
score: 100
- task: ledger
score: 200
- task: shopfront
score: 100
- task: wscat
score: 200
- group: "[HW] Dist Build"
start: 2024-04-13 13:00
end: 2024-05-13 23:59
tasks:
- task: distbuild
score: 1
- group: Generics
start: 2024-04-20 13:00
steps:
0.3: 2024-05-02 23:59
end: 2024-07-10 23:59
tasks:
- task: genericsum
score: 100
- task: treeiter
score: 100
- task: coverme
score: 300
- group: Reflect
start: 2024-04-27 13:00
steps:
0.3: 2024-05-07 23:59
end: 2024-07-10 23:59
tasks:
- task: reversemap
score: 100
- task: jsonlist
score: 100
- task: jsonrpc
score: 100
- task: structtags
score: 100
- group: Low level
start: 2024-05-04 13:00
steps:
0.3: 2024-05-14 23:59
end: 2024-07-10 23:59
tasks:
- task: illegal
score: 100
- task: blowfish
score: 100
- task: gzep
score: 100
- group: Analysis
start: 2024-05-11 13:00
steps:
0.3: 2024-05-21 23:59
end: 2024-07-10 23:59
tasks:
- task: testifycheck
score: 200
- group: Bonus
start: 2024-03-03 13:00
end: 2024-07-10 23:59
tasks:
- task: yamlembed
is_bonus: true
score: 100
- task: consistenthash
is_bonus: true
score: 200
- task: gossip
is_bonus: true
score: 300
- task: smartsched
is_bonus: true
score: 200
watch:
- distbuild/pkg/scheduler
- task: wasm
is_bonus: true
score: 300
- task: firegod
is_bonus: true
score: 200
- task: excelwriter
is_bonus: true
score: 200
- task: rsem
is_bonus: true
score: 200
- task: psycher
is_bonus: true
score: 200

View file

@ -1 +1,2 @@
wasm/flappygopher/main_solution.go wasm/flappygopher/main_solution.go
rsem/try_lock.lua

View file

@ -1,11 +1,5 @@
check: check:
image: cr.yandex/crp9onavos88ug32d5r2/grader/go-build image: gitlab.manytask.org:5050/go/public-2024-spring/build
variables:
DOCKER_HOST: tcp://docker:2375/
DOCKER_TLS_CERTDIR: ""
APP_HOST: docker
# services:
#- docker:dind
script: script:
- golangci-lint run --build-tags private,solution ./... - golangci-lint run --build-tags private,solution ./...
#- go test -v -tags private,solution ./... #- go test -v -tags private,solution ./...
@ -19,8 +13,8 @@ rebuild-base-image:
- docker - docker
when: manual when: manual
script: script:
- docker build -f build.docker -t cr.yandex/crp9onavos88ug32d5r2/grader/go-build . - docker build -f build.docker -t gitlab.manytask.org:5050/go/public-2024-spring/build .
- docker push cr.yandex/crp9onavos88ug32d5r2/grader/go-build:latest - docker push gitlab.manytask.org:5050/go/public-2024-spring/build:latest
deploy: deploy:
only: only:
@ -28,9 +22,9 @@ deploy:
tags: tags:
- docker - docker
script: script:
- docker pull cr.yandex/crp9onavos88ug32d5r2/grader/go-build:latest - docker pull gitlab.manytask.org:5050/go/public-2024-spring/build:latest
- docker build -f testenv.docker -t cr.yandex/crp9onavos88ug32d5r2/grader/go . - docker build -f testenv.docker -t gitlab.manytask.org:5050/go/public-2024-spring .
- docker push cr.yandex/crp9onavos88ug32d5r2/grader/go:latest - docker push gitlab.manytask.org:5050/go/public-2024-spring:latest
build-slides: build-slides:
only: only:
@ -38,28 +32,32 @@ build-slides:
tags: tags:
- docker - docker
script: script:
- docker build lectures -t cr.yandex/crp9onavos88ug32d5r2/go-lectures - docker build lectures -t gitlab.manytask.org:5050/go/public-2024-spring/lectures
- docker push cr.yandex/crp9onavos88ug32d5r2/go-lectures - docker push gitlab.manytask.org:5050/go/public-2024-spring/lectures
push-to-public: update-config:
stage: .post
image: cr.yandex/crp9onavos88ug32d5r2/grader/go
only: only:
- master - master
script: script:
- git remote rm public || true - >
- git remote add -f public https://svparamoshkin:${CI_PUSH_TOKEN}@gitlab.manytask.org/go/public-itmo-2023-fall curl -v --fail --silent -X POST \
- git config --global user.email 'svparamoshkin@yandex-team.ru' -H "Authorization: Bearer $TESTER_TOKEN" \
- git config --global user.name 'svparamoshkin' -H "Content-type: application/x-yaml" \
- git fetch public --data-binary "@.manytask.yml" \
- git branch -D public || true https://go.manytask.org/api/update_config
- git branch public public/master - >
- testtool export --push --move-to-master=false curl -v --fail --silent -X POST \
- curl -F token=$TESTER_TOKEN http://itmo-go.manytask.org/api/sync_task_columns -H "Authorization: Bearer $TESTER_TOKEN" \
https://go.manytask.org/api/update_cache
push-to-github: push-to-public:
stage: .post stage: .post
image: cr.yandex/crp9onavos88ug32d5r2/grader/go image: gitlab.manytask.org:5050/go/public-2024-spring
parallel:
matrix:
- REMOTE:
- git@github.com:slon/shad-go.git
- git@gitlab.manytask.org:go/public-2024-spring.git
only: only:
- master - master
script: script:
@ -69,7 +67,7 @@ push-to-github:
- git branch -D main || true - git branch -D main || true
- git checkout -b main - git checkout -b main
- git remote rm github || true - git remote rm github || true
- env GIT_SSH_COMMAND="ssh -i ${PWD}/private.key -o StrictHostKeyChecking=no" git remote add -f github git@github.com:slon/shad-go.git - env GIT_SSH_COMMAND="ssh -i ${PWD}/private.key -o StrictHostKeyChecking=no" git remote add -f github $REMOTE
- env GIT_SSH_COMMAND="ssh -i ${PWD}/private.key -o StrictHostKeyChecking=no" git push github main - env GIT_SSH_COMMAND="ssh -i ${PWD}/private.key -o StrictHostKeyChecking=no" git push github main
deploy-slides: deploy-slides:
@ -79,5 +77,5 @@ deploy-slides:
tags: tags:
- web - web
script: script:
- docker pull cr.yandex/crp9onavos88ug32d5r2/go-lectures - docker pull gitlab.manytask.org:5050/go/public-2024-spring/lectures
- cd /srv/manytask/go && docker compose up -d - cd /srv/manytask/go && docker compose up -d

View file

@ -1,26 +1,28 @@
# Как послать патч # Как послать патч
Если вы нашли недоработку в тестах или неточность/опечатку в условии, то вы можете послать MR Если вы нашли недоработку в тестах или неточность/опечатку в условии, то вы можете послать PR
с исправлением в репозиторий курса. с исправлением в репозиторий курса.
За все исправления начисляются дополнительные баллы в колонке bugs в таблице. За все исправления начисляются дополнительные баллы в колонке bonus в таблице.
Размер дополнительных баллов зависит от серьёзности исправления и определяется преподавателями. Размер дополнительных баллов зависит от серьёзности исправления и определяется преподавателями.
## Небольшие исправления ## Небольшие исправления
Небольшие исправления на <10 строк проще всего послать через веб интерфейс гитлаба. Небольшие исправления на <10 строк проще всего послать через веб интерфейс гитхаба.
1. Откройте нужный файл в веб интерфейсе репозитория https://gitlab.com/manytask/itmo-go/private 1. Откройте нужный файл в веб интерфейсе репозитория https://github.com/slon/shad-go
2. Нажмите на кнопку "Edit". Во всплывающей подсказке нажмите кнопку "Fork". 2. Нажмите на кнопку "Edit in place".
![](docs/edit-and-fork.png) ![](docs/edit-in-place.png)
3. Внесите изменения в файл. Нажмите "Commit Changes" внизу страницы. 3. На следующем экране нажмите "Fork this repository".
4. Добавьте описание вашего изменения. Нажмите "Submit Merge Request". 3. Внесите изменения в файл. Нажмите "Commit Changes" сверху страницы.
4. Добавьте описание вашего изменения. Нажмите "Propose changed".
5. Нажмите "Create pull request".
## Продвинутые исправления ## Продвинутые исправления
Для многофайловых исправлений можно сначала сделать исправление локально: Для многофайловых исправлений можно сначала сделать исправление локально:
1. Создайте форк https://gitlab.com/manytask/itmo-go/private аналогично тому, что выше. 1. Создайте форк https://github.com/slon/shad-go аналогично тому, что выше.
2. Закоммитьте все локальные изменения, которые вы не хотите добавлять в репозиторий курса. 2. Закоммитьте все локальные изменения, которые вы не хотите добавлять в репозиторий курса.
@ -30,16 +32,13 @@
git checkout origin/master -b newbranchforupdate git checkout origin/master -b newbranchforupdate
``` ```
4. Внесите локальные изменения и запушьте их в свой форк на [gitlab.com](https://gitlab.com/) (не в `student`), например 4. Внесите локальные изменения и запушьте их в свой форк на [github.com](https://github.com/) (не в `student`), например
``` ```
git add . git add .
git commit -m "Update tests" git commit -m "Update tests"
git push https://gitlab.com/%USERNAME%/shad-go/ git push https://github.com/%USERNAME%/shad-go/
``` ```
5. В своём форке выберите созданную ветку и создайте Merge Request в репозиторий курса. Обычно GitLab подсказывает недавно запушенную ветку и предлагает создать для неё MR. 5. В своём форке выберите созданную ветку и создайте Pull Request в репозиторий курса. Обычно Github подсказывает недавно запушенную ветку и предлагает создать для неё PR.
![](docs/create-mr.png) На странице c формой нового Pull Request убедитесь, что ветвь назначения — `slon/shad-go:master`. Нажмите кнопку "Create Pull Request".
На странице c формой нового Merge Request убедитесь, что ветвь назначения — `slon/shad-go:master`. Нажмите кнопку "Create Merge Request".
![](docs/create-mr-form.png)

View file

@ -1,13 +1,5 @@
# Курс по Го в ШАД # Курс по Го в ШАД
Для работы с кодом нужен go 1.18 или выше.
```sh
git clone https://gitlab.com/manytask/itmo-go/private.git
cd shad-go
go test ./sum/...
```
Проект можно открыть в любой go IDE с поддержкой модулей. Проект можно открыть в любой go IDE с поддержкой модулей.
## Информация ## Информация

View file

@ -15,7 +15,7 @@
``` ```
goos: linux goos: linux
goarch: amd64 goarch: amd64
pkg: gitlab.com/manytask/itmo-go/private/allocs pkg: gitlab.com/slon/shad-go/allocs
Benchmark/count-4 73200 16294 ns/op 880 B/op 5 allocs/op Benchmark/count-4 73200 16294 ns/op 880 B/op 5 allocs/op
Benchmark/main-4 40485 30113 ns/op 1034 B/op 9 allocs/op Benchmark/main-4 40485 30113 ns/op 1034 B/op 9 allocs/op
``` ```
@ -23,7 +23,7 @@ Benchmark/main-4 40485 30113 ns/op 1034
Значения бенчмарков для авторского решения: Значения бенчмарков для авторского решения:
```goos: linux ```goos: linux
goarch: amd64 goarch: amd64
pkg: gitlab.com/manytask/itmo-go/private/allocs pkg: gitlab.com/slon/shad-go/allocs
Benchmark/count-4 212850 5471 ns/op 4144 B/op 2 allocs/op Benchmark/count-4 212850 5471 ns/op 4144 B/op 2 allocs/op
Benchmark/main-4 143937 8247 ns/op 4176 B/op 3 allocs/op Benchmark/main-4 143937 8247 ns/op 4176 B/op 3 allocs/op
``` ```

View file

@ -5,7 +5,6 @@ package allocs
import ( import (
"fmt" "fmt"
"io" "io"
"io/ioutil"
"sort" "sort"
"strings" "strings"
) )
@ -24,7 +23,7 @@ func NewBaselineCounter() Counter {
} }
func (c BaselineCounter) Count(r io.Reader) error { func (c BaselineCounter) Count(r io.Reader) error {
data, err := ioutil.ReadAll(r) data, err := io.ReadAll(r)
if err != nil { if err != nil {
return err return err
} }

View file

@ -2,9 +2,10 @@
package batcher package batcher
import "gitlab.com/manytask/itmo-go/private/batcher/slow" import "gitlab.com/slon/shad-go/batcher/slow"
type Batcher struct{} type Batcher struct {
}
func NewBatcher(v *slow.Value) *Batcher { func NewBatcher(v *slow.Value) *Batcher {
return nil return nil

View file

@ -9,7 +9,7 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"go.uber.org/goleak" "go.uber.org/goleak"
"gitlab.com/manytask/itmo-go/private/batcher/slow" "gitlab.com/slon/shad-go/batcher/slow"
) )
func TestSimple(t *testing.T) { func TestSimple(t *testing.T) {

View file

@ -8,7 +8,7 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"gitlab.com/manytask/itmo-go/private/blowfish" "gitlab.com/slon/shad-go/blowfish"
) )
var _ cipher.Block = (*blowfish.Blowfish)(nil) var _ cipher.Block = (*blowfish.Blowfish)(nil)

View file

@ -1,4 +1,4 @@
FROM golang:1.20 FROM golang:1.22
# enable backports for git-filter-repo # enable backports for git-filter-repo
RUN echo "deb http://deb.debian.org/debian bullseye-backports main" >> /etc/apt/sources.list.d/backports.list RUN echo "deb http://deb.debian.org/debian bullseye-backports main" >> /etc/apt/sources.list.d/backports.list
@ -7,4 +7,4 @@ RUN apt-get update && apt-get install -y \
rsync libssl-dev postgresql sudo redis-server git-filter-repo/bullseye-backports \ rsync libssl-dev postgresql sudo redis-server git-filter-repo/bullseye-backports \
&& rm -rf /var/lib/apt/lists/* && rm -rf /var/lib/apt/lists/*
RUN curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.51.1 RUN curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.56.2

View file

@ -35,7 +35,7 @@ Your pipeline #194613 has failed! // 194613 -- это ID pipeline'а
// Далее идут последние 10 строк лога gitlab runner'а // Далее идут последние 10 строк лога gitlab runner'а
testtool: copying go.mod, go.sum and .golangci.yml testtool: copying go.mod, go.sum and .golangci.yml
testtool: running tests testtool: running tests
testtool: > go test -mod readonly -tags private -c -o /tmp/bincache730817117/5d83984f885e61c1 gitlab.com/manytask/itmo-go/private/sum testtool: > go test -mod readonly -tags private -c -o /tmp/bincache730817117/5d83984f885e61c1 gitlab.com/slon/shad-go/sum
--- FAIL: TestSum (0.00s) --- FAIL: TestSum (0.00s)
sum_test.go:19: 2 + 2 == 0 != 4 sum_test.go:19: 2 + 2 == 0 != 4
sum_test.go:19: 9223372036854775807 + 1 == 0 != -9223372036854775808 sum_test.go:19: 9223372036854775807 + 1 == 0 != -9223372036854775808

View file

@ -8,7 +8,7 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"gitlab.com/manytask/itmo-go/private/tools/testtool" "gitlab.com/slon/shad-go/tools/testtool"
) )
type testCase struct { type testCase struct {
@ -93,7 +93,7 @@ testtool: copying !change files
testtool: copying testdata directory testtool: copying testdata directory
testtool: copying go.mod, go.sum and .golangci.yml testtool: copying go.mod, go.sum and .golangci.yml
testtool: running tests testtool: running tests
testtool: > go test -mod readonly -tags private -c -o /tmp/bincache730817117/5d83984f885e61c1 gitlab.com/manytask/itmo-go/private/sum testtool: > go test -mod readonly -tags private -c -o /tmp/bincache730817117/5d83984f885e61c1 gitlab.com/slon/shad-go/sum
--- FAIL: TestSum (0.00s) --- FAIL: TestSum (0.00s)
sum_test.go:19: 2 + 2 == 0 != 4 sum_test.go:19: 2 + 2 == 0 != 4
sum_test.go:19: 9223372036854775807 + 1 == 0 != -9223372036854775808 sum_test.go:19: 9223372036854775807 + 1 == 0 != -9223372036854775808
@ -113,7 +113,7 @@ ERROR: Job failed: exit code 1`,
Stage: test, Job grade Stage: test, Job grade
testtool: copying go.mod, go.sum and .golangci.yml testtool: copying go.mod, go.sum and .golangci.yml
testtool: running tests testtool: running tests
testtool: > go test -mod readonly -tags private -c -o /tmp/bincache730817117/5d83984f885e61c1 gitlab.com/manytask/itmo-go/private/sum testtool: > go test -mod readonly -tags private -c -o /tmp/bincache730817117/5d83984f885e61c1 gitlab.com/slon/shad-go/sum
--- FAIL: TestSum (0.00s) --- FAIL: TestSum (0.00s)
sum_test.go:19: 2 + 2 == 0 != 4 sum_test.go:19: 2 + 2 == 0 != 4
sum_test.go:19: 9223372036854775807 + 1 == 0 != -9223372036854775808 sum_test.go:19: 9223372036854775807 + 1 == 0 != -9223372036854775808
@ -156,7 +156,7 @@ testtool: copying !change files
testtool: copying testdata directory testtool: copying testdata directory
testtool: copying go.mod, go.sum and .golangci.yml testtool: copying go.mod, go.sum and .golangci.yml
testtool: running tests testtool: running tests
testtool: > go test -mod readonly -tags private -c -o /tmp/bincache730817117/5d83984f885e61c1 gitlab.com/manytask/itmo-go/private/sum testtool: > go test -mod readonly -tags private -c -o /tmp/bincache730817117/5d83984f885e61c1 gitlab.com/slon/shad-go/sum
--- FAIL: TestSum (0.00s) --- FAIL: TestSum (0.00s)
sum_test.go:19: 2 + 2 == 0 != 4 sum_test.go:19: 2 + 2 == 0 != 4
sum_test.go:19: 9223372036854775807 + 1 == 0 != -9223372036854775808 sum_test.go:19: 9223372036854775807 + 1 == 0 != -9223372036854775808
@ -188,7 +188,7 @@ ERROR: Job failed: exit code 1`,
Stage: %v, Job %v Stage: %v, Job %v
testtool: copying go.mod, go.sum and .golangci.yml testtool: copying go.mod, go.sum and .golangci.yml
testtool: running tests testtool: running tests
testtool: > go test -mod readonly -tags private -c -o /tmp/bincache730817117/5d83984f885e61c1 gitlab.com/manytask/itmo-go/private/sum testtool: > go test -mod readonly -tags private -c -o /tmp/bincache730817117/5d83984f885e61c1 gitlab.com/slon/shad-go/sum
--- FAIL: TestSum (0.00s) --- FAIL: TestSum (0.00s)
sum_test.go:19: 2 + 2 == 0 != 4 sum_test.go:19: 2 + 2 == 0 != 4
sum_test.go:19: 9223372036854775807 + 1 == 0 != -9223372036854775808 sum_test.go:19: 9223372036854775807 + 1 == 0 != -9223372036854775808

View file

@ -1,6 +1,7 @@
package cond package cond
import ( import (
"gitlab.com/slon/shad-go/tools/testtool"
"sync" "sync"
"testing" "testing"
"time" "time"
@ -44,6 +45,38 @@ func TestCondSignal(t *testing.T) {
c.Signal() c.Signal()
} }
func TestCondSignalOveruse(t *testing.T) {
var m sync.Mutex
c := New(&m)
running := make(chan bool, 1)
awake := make(chan bool, 1)
for i := 0; i < 5; i++ {
c.Signal() // Checks if empty signals are not deadlocking
}
go func() {
m.Lock()
running <- true
c.Wait() // Checks if it will wait after empty signals
awake <- true
m.Unlock()
}()
<-running
select {
case <-awake:
t.Fatal("goroutine not asleep")
default:
}
m.Lock()
c.Signal()
m.Unlock()
<-awake // Will deadlock if no goroutine wakes up
}
func TestCondSignalGenerations(t *testing.T) { func TestCondSignalGenerations(t *testing.T) {
var m sync.Mutex var m sync.Mutex
c := New(&m) c := New(&m)
@ -182,3 +215,7 @@ func TestCondSignalStealing(t *testing.T) {
cond.Broadcast() cond.Broadcast()
} }
} }
func TestNoSyncPackageImported(t *testing.T) {
testtool.CheckForbiddenImport(t, "sync")
}

View file

@ -57,7 +57,7 @@ func TestHash_EvenDistribution(t *testing.T) {
h.AddNode(&n) h.AddNode(&n)
} }
counts := map[*node]int{} counts := map[*node]float64{}
const N = 1 << 16 const N = 1 << 16
for i := 0; i < N; i++ { for i := 0; i < N; i++ {
counts[h.GetNode(fmt.Sprintf("key%d", i))] += 1 counts[h.GetNode(fmt.Sprintf("key%d", i))] += 1
@ -65,14 +65,23 @@ func TestHash_EvenDistribution(t *testing.T) {
const P = 1 / float64(K) const P = 1 / float64(K)
const variance = N * (P) * (1 - P) const variance = N * (P) * (1 - P)
stddev := math.Sqrt(variance) idealStddev := math.Sqrt(variance)
t.Logf("P = %v, var = %v, stddev = %v", P, variance, stddev)
t.Logf("P = %v, var = %v, stddev = %v", P, variance, idealStddev)
t.Logf("counts = %v", maps.Values(counts)) t.Logf("counts = %v", maps.Values(counts))
total := float64(N)
mean := total / K
var dispersion float64
for _, count := range counts { for _, count := range counts {
require.Greater(t, count, int(N/K-stddev*10)) dispersion += (count - mean) * (count - mean)
require.Less(t, count, int(N/K+stddev*10))
} }
realStddev := math.Sqrt(dispersion / K)
t.Logf("read stddev = %v", realStddev)
require.Less(t, math.Abs(realStddev-idealStddev)/idealStddev, float64(4))
} }
func TestHash_ConsistentDistribution(t *testing.T) { func TestHash_ConsistentDistribution(t *testing.T) {

View file

@ -12,8 +12,8 @@ import (
"github.com/gorilla/handlers" "github.com/gorilla/handlers"
"github.com/gorilla/mux" "github.com/gorilla/mux"
"gitlab.com/manytask/itmo-go/private/coverme/models" "gitlab.com/slon/shad-go/coverme/models"
"gitlab.com/manytask/itmo-go/private/coverme/utils" "gitlab.com/slon/shad-go/coverme/utils"
) )
type App struct { type App struct {

View file

@ -8,7 +8,7 @@ import (
"fmt" "fmt"
"net/http" "net/http"
"gitlab.com/manytask/itmo-go/private/coverme/models" "gitlab.com/slon/shad-go/coverme/models"
) )
type Client struct { type Client struct {

View file

@ -5,8 +5,8 @@ package main
import ( import (
"flag" "flag"
"gitlab.com/manytask/itmo-go/private/coverme/app" "gitlab.com/slon/shad-go/coverme/app"
"gitlab.com/manytask/itmo-go/private/coverme/models" "gitlab.com/slon/shad-go/coverme/models"
) )
func main() { func main() {

View file

@ -31,18 +31,14 @@ sudo apt install postgresql
Альтернативный способ — запустить бд в докере. Альтернативный способ — запустить бд в докере.
Для этого нужно установить docker и docker-compose по инструкции из [dockertest](../dockertest/README.md). Для этого нужно установить docker и docker-compose по инструкции из [dockertest](../dockertest/README.md).
Добиться успешного запуска
```
go test -v ./dockertest/...
```
Запускать тесты можно будет так: Запускать тесты можно будет так:
``` ```
(cd dao && docker-compose up -d && sleep 1 && env PGCONN="host=127.0.0.1 port=5432 database=shad-go user=gopher password=pass" go test -v ./... -count=1 || true && docker-compose down) (cd dao && docker compose up -d --wait && env PGCONN="host=127.0.0.1 port=5432 database=shad-go user=gopher password=pass" go test -v ./... -count=1 || true && docker compose down)
``` ```
Эта команда стартует docker с postgresql, запускает тесты, передав им DSN через переменную окружения, удаляет контейнеры в конце. Эта команда стартует docker с postgresql, запускает тесты, передав им DSN через переменную окружения, удаляет контейнеры в конце.
Как подчистить контейнеры, если что-то пошло не так: Как подчистить контейнеры, если что-то пошло не так:
``` ```
(cd dao && docker-compose down) (cd dao && docker compose down)
``` ```

View file

@ -9,7 +9,7 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"go.uber.org/goleak" "go.uber.org/goleak"
"gitlab.com/manytask/itmo-go/private/pgfixture" "gitlab.com/slon/shad-go/pgfixture"
) )
func TestDao(t *testing.T) { func TestDao(t *testing.T) {
@ -36,7 +36,7 @@ func TestDao(t *testing.T) {
alice, err := dao.Lookup(ctx, aliceID) alice, err := dao.Lookup(ctx, aliceID)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, alice, User{ID: aliceID, Name: "Alice"}) require.Equal(t, User{ID: aliceID, Name: "Alice"}, alice)
require.NoError(t, dao.Delete(ctx, bobID)) require.NoError(t, dao.Delete(ctx, bobID))
@ -44,6 +44,7 @@ func TestDao(t *testing.T) {
require.ErrorIs(t, err, sql.ErrNoRows) require.ErrorIs(t, err, sql.ErrNoRows)
require.NoError(t, dao.Update(ctx, &User{ID: charlieID, Name: "Chaplin"})) require.NoError(t, dao.Update(ctx, &User{ID: charlieID, Name: "Chaplin"}))
require.Error(t, dao.Update(ctx, &User{ID: 999, Name: "FooBar"}))
users, err := dao.List(ctx) users, err := dao.List(ctx)
require.NoError(t, err) require.NoError(t, err)

View file

@ -8,3 +8,8 @@ services:
POSTGRES_PASSWORD: pass POSTGRES_PASSWORD: pass
ports: ports:
- 5432:5432 - 5432:5432
healthcheck:
test: [ "CMD-SHELL", "pg_isready -U $${POSTGRES_USER}" ]
interval: 1s
timeout: 3s
retries: 5

View file

@ -5,7 +5,6 @@ import (
"fmt" "fmt"
"image" "image"
"image/png" "image/png"
"io/ioutil"
"net/http" "net/http"
"net/url" "net/url"
"os" "os"
@ -18,10 +17,10 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"gitlab.com/manytask/itmo-go/private/tools/testtool" "gitlab.com/slon/shad-go/tools/testtool"
) )
const importPath = "gitlab.com/manytask/itmo-go/private/digitalclock" const importPath = "gitlab.com/slon/shad-go/digitalclock"
var binCache testtool.BinCache var binCache testtool.BinCache
@ -125,7 +124,7 @@ func TestDigitalClock_valid(t *testing.T) {
port, stop := startServer(t) port, stop := startServer(t)
defer stop() defer stop()
files, err := ioutil.ReadDir("./testdata") files, err := os.ReadDir("./testdata")
require.NoError(t, err) require.NoError(t, err)
c := &http.Client{Timeout: time.Second * 10} c := &http.Client{Timeout: time.Second * 10}

View file

@ -4,7 +4,6 @@ import (
"context" "context"
"errors" "errors"
"fmt" "fmt"
"io/ioutil"
"net" "net"
"net/http" "net/http"
"net/url" "net/url"
@ -17,13 +16,13 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"go.uber.org/goleak" "go.uber.org/goleak"
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/api" "gitlab.com/slon/shad-go/distbuild/pkg/api"
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/artifact" "gitlab.com/slon/shad-go/distbuild/pkg/artifact"
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/client" "gitlab.com/slon/shad-go/distbuild/pkg/client"
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/dist" "gitlab.com/slon/shad-go/distbuild/pkg/dist"
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/filecache" "gitlab.com/slon/shad-go/distbuild/pkg/filecache"
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/worker" "gitlab.com/slon/shad-go/distbuild/pkg/worker"
"gitlab.com/manytask/itmo-go/private/tools/testtool" "gitlab.com/slon/shad-go/tools/testtool"
"go.uber.org/zap" "go.uber.org/zap"
) )
@ -50,7 +49,11 @@ type Config struct {
WorkerCount int WorkerCount int
} }
func newEnv(t *testing.T, config *Config) (e *env, cancel func()) { func newEnv(t *testing.T, config *Config) (e *env) {
t.Cleanup(func() {
goleak.VerifyNone(t)
})
cwd, err := os.Getwd() cwd, err := os.Getwd()
require.NoError(t, err) require.NoError(t, err)
@ -60,9 +63,9 @@ func newEnv(t *testing.T, config *Config) (e *env, cancel func()) {
rootDir := filepath.Join(absCWD, "workdir", t.Name()) rootDir := filepath.Join(absCWD, "workdir", t.Name())
require.NoError(t, os.RemoveAll(rootDir)) require.NoError(t, os.RemoveAll(rootDir))
if err = os.MkdirAll(rootDir, 0o777); err != nil { if err = os.MkdirAll(rootDir, 0777); err != nil {
if errors.Is(err, os.ErrPermission) { if errors.Is(err, os.ErrPermission) {
rootDir, err = ioutil.TempDir("", "") rootDir, err = os.MkdirTemp("", "")
require.NoError(t, err) require.NoError(t, err)
} else { } else {
require.NoError(t, err) require.NoError(t, err)
@ -90,6 +93,10 @@ func newEnv(t *testing.T, config *Config) (e *env, cancel func()) {
env.Logger, err = cfg.Build() env.Logger, err = cfg.Build()
require.NoError(t, err) require.NoError(t, err)
t.Cleanup(func() {
_ = env.Logger.Sync()
})
t.Helper() t.Helper()
t.Logf("test is running inside %s; see test.log file for more info", filepath.Join("workdir", t.Name())) t.Logf("test is running inside %s; see test.log file for more info", filepath.Join("workdir", t.Name()))
@ -100,6 +107,7 @@ func newEnv(t *testing.T, config *Config) (e *env, cancel func()) {
var cancelRootContext func() var cancelRootContext func()
env.Ctx, cancelRootContext = context.WithCancel(context.Background()) env.Ctx, cancelRootContext = context.WithCancel(context.Background())
t.Cleanup(cancelRootContext)
env.Client = client.NewClient( env.Client = client.NewClient(
env.Logger.Named("client"), env.Logger.Named("client"),
@ -113,6 +121,7 @@ func newEnv(t *testing.T, config *Config) (e *env, cancel func()) {
env.Logger.Named("coordinator"), env.Logger.Named("coordinator"),
coordinatorCache, coordinatorCache,
) )
t.Cleanup(env.Coordinator.Stop)
router := http.NewServeMux() router := http.NewServeMux()
router.Handle("/coordinator/", http.StripPrefix("/coordinator", env.Coordinator)) router.Handle("/coordinator/", http.StripPrefix("/coordinator", env.Coordinator))
@ -161,6 +170,11 @@ func newEnv(t *testing.T, config *Config) (e *env, cancel func()) {
} }
}() }()
t.Cleanup(func() {
cancelRootContext()
_ = env.HTTP.Shutdown(context.Background())
})
for _, w := range env.Workers { for _, w := range env.Workers {
go func(w *worker.Worker) { go func(w *worker.Worker) {
err := w.Run(env.Ctx) err := w.Run(env.Ctx)
@ -181,20 +195,14 @@ func newEnv(t *testing.T, config *Config) (e *env, cancel func()) {
} }
}() }()
return env, func() { return env
cancelRootContext()
_ = env.HTTP.Shutdown(context.Background())
_ = env.Logger.Sync()
goleak.VerifyNone(t)
}
} }
func newWinFileSink(u *url.URL) (zap.Sink, error) { func newWinFileSink(u *url.URL) (zap.Sink, error) {
if len(u.Opaque) > 0 { if len(u.Opaque) > 0 {
// Remove leading slash left by url.Parse() // Remove leading slash left by url.Parse()
return os.OpenFile(u.Opaque[1:], os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0o644) return os.OpenFile(u.Opaque[1:], os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644)
} }
// if url.URL is empty, don't panic slice index error // if url.URL is empty, don't panic slice index error
return os.OpenFile(u.Opaque, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0o644) return os.OpenFile(u.Opaque, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644)
} }

View file

@ -1,7 +1,7 @@
package disttest package disttest
import ( import (
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/build" "gitlab.com/slon/shad-go/distbuild/pkg/build"
) )
type JobResult struct { type JobResult struct {

View file

@ -2,13 +2,14 @@ package disttest
import ( import (
"fmt" "fmt"
"io/ioutil" "io"
"os"
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/build" "gitlab.com/slon/shad-go/distbuild/pkg/build"
) )
var singleWorkerConfig = &Config{WorkerCount: 1} var singleWorkerConfig = &Config{WorkerCount: 1}
@ -26,8 +27,7 @@ var echoGraph = build.Graph{
} }
func TestSingleCommand(t *testing.T) { func TestSingleCommand(t *testing.T) {
env, cancel := newEnv(t, singleWorkerConfig) env := newEnv(t, singleWorkerConfig)
defer cancel()
recorder := NewRecorder() recorder := NewRecorder()
require.NoError(t, env.Client.Build(env.Ctx, echoGraph, recorder)) require.NoError(t, env.Client.Build(env.Ctx, echoGraph, recorder))
@ -37,10 +37,9 @@ func TestSingleCommand(t *testing.T) {
} }
func TestJobCaching(t *testing.T) { func TestJobCaching(t *testing.T) {
env, cancel := newEnv(t, singleWorkerConfig) env := newEnv(t, singleWorkerConfig)
defer cancel()
tmpFile, err := ioutil.TempFile("", "") tmpFile, err := os.CreateTemp("", "")
require.NoError(t, err) require.NoError(t, err)
graph := build.Graph{ graph := build.Graph{
@ -62,12 +61,12 @@ func TestJobCaching(t *testing.T) {
assert.Len(t, recorder.Jobs, 1) assert.Len(t, recorder.Jobs, 1)
assert.Equal(t, &JobResult{Stdout: "OK\n", Code: new(int)}, recorder.Jobs[build.ID{'a'}]) assert.Equal(t, &JobResult{Stdout: "OK\n", Code: new(int)}, recorder.Jobs[build.ID{'a'}])
require.NoError(t, ioutil.WriteFile(tmpFile.Name(), []byte("NOTOK\n"), 0o666)) require.NoError(t, os.WriteFile(tmpFile.Name(), []byte("NOTOK\n"), 0666))
// Second build must get results from cache. // Second build must get results from cache.
require.NoError(t, env.Client.Build(env.Ctx, graph, NewRecorder())) require.NoError(t, env.Client.Build(env.Ctx, graph, NewRecorder()))
output, err := ioutil.ReadAll(tmpFile) output, err := io.ReadAll(tmpFile)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, []byte("NOTOK\n"), output) require.Equal(t, []byte("NOTOK\n"), output)
} }
@ -94,8 +93,7 @@ var sourceFilesGraph = build.Graph{
} }
func TestSourceFiles(t *testing.T) { func TestSourceFiles(t *testing.T) {
env, cancel := newEnv(t, singleWorkerConfig) env := newEnv(t, singleWorkerConfig)
defer cancel()
recorder := NewRecorder() recorder := NewRecorder()
require.NoError(t, env.Client.Build(env.Ctx, sourceFilesGraph, recorder)) require.NoError(t, env.Client.Build(env.Ctx, sourceFilesGraph, recorder))
@ -125,8 +123,7 @@ var artifactTransferGraph = build.Graph{
} }
func TestArtifactTransferBetweenJobs(t *testing.T) { func TestArtifactTransferBetweenJobs(t *testing.T) {
env, cancel := newEnv(t, singleWorkerConfig) env := newEnv(t, singleWorkerConfig)
defer cancel()
recorder := NewRecorder() recorder := NewRecorder()
require.NoError(t, env.Client.Build(env.Ctx, artifactTransferGraph, recorder)) require.NoError(t, env.Client.Build(env.Ctx, artifactTransferGraph, recorder))

View file

@ -9,14 +9,13 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/build" "gitlab.com/slon/shad-go/distbuild/pkg/build"
) )
var threeWorkerConfig = &Config{WorkerCount: 3} var threeWorkerConfig = &Config{WorkerCount: 3}
func TestArtifactTransferBetweenWorkers(t *testing.T) { func TestArtifactTransferBetweenWorkers(t *testing.T) {
env, cancel := newEnv(t, threeWorkerConfig) env := newEnv(t, threeWorkerConfig)
defer cancel()
baseJob := build.Job{ baseJob := build.Job{
ID: build.ID{'a'}, ID: build.ID{'a'},

View file

@ -3,7 +3,7 @@ package api
import ( import (
"context" "context"
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/build" "gitlab.com/slon/shad-go/distbuild/pkg/build"
) )
type BuildRequest struct { type BuildRequest struct {
@ -25,7 +25,8 @@ type BuildFailed struct {
Error string Error string
} }
type BuildFinished struct{} type BuildFinished struct {
}
type UploadDone struct{} type UploadDone struct{}
@ -33,7 +34,8 @@ type SignalRequest struct {
UploadDone *UploadDone UploadDone *UploadDone
} }
type SignalResponse struct{} type SignalResponse struct {
}
type StatusWriter interface { type StatusWriter interface {
Started(rsp *BuildStarted) error Started(rsp *BuildStarted) error

View file

@ -7,10 +7,11 @@ import (
"go.uber.org/zap" "go.uber.org/zap"
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/build" "gitlab.com/slon/shad-go/distbuild/pkg/build"
) )
type BuildClient struct{} type BuildClient struct {
}
func NewBuildClient(l *zap.Logger, endpoint string) *BuildClient { func NewBuildClient(l *zap.Logger, endpoint string) *BuildClient {
panic("implement me") panic("implement me")

View file

@ -12,9 +12,9 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"go.uber.org/zap/zaptest" "go.uber.org/zap/zaptest"
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/api" "gitlab.com/slon/shad-go/distbuild/pkg/api"
mock "gitlab.com/manytask/itmo-go/private/distbuild/pkg/api/mock" mock "gitlab.com/slon/shad-go/distbuild/pkg/api/mock"
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/build" "gitlab.com/slon/shad-go/distbuild/pkg/build"
) )
//go:generate mockgen -package mock -destination mock/mock.go . Service //go:generate mockgen -package mock -destination mock/mock.go . Service
@ -28,7 +28,6 @@ type env struct {
func (e *env) stop() { func (e *env) stop() {
e.server.Close() e.server.Close()
e.ctrl.Finish()
} }
func newEnv(t *testing.T) (*env, func()) { func newEnv(t *testing.T) (*env, func()) {
@ -56,8 +55,8 @@ func TestBuildSignal(t *testing.T) {
ctx := context.Background() ctx := context.Background()
buildIDa := build.ID{0o1} buildIDa := build.ID{01}
buildIDb := build.ID{0o2} buildIDb := build.ID{02}
req := &api.SignalRequest{} req := &api.SignalRequest{}
rsp := &api.SignalResponse{} rsp := &api.SignalResponse{}
@ -91,10 +90,10 @@ func TestBuildRunning(t *testing.T) {
ctx := context.Background() ctx := context.Background()
buildID := build.ID{0o2} buildID := build.ID{02}
req := &api.BuildRequest{ req := &api.BuildRequest{
Graph: build.Graph{SourceFiles: map[build.ID]string{{0o1}: "a.txt"}}, Graph: build.Graph{SourceFiles: map[build.ID]string{{01}: "a.txt"}},
} }
started := &api.BuildStarted{ID: buildID} started := &api.BuildStarted{ID: buildID}
@ -141,7 +140,7 @@ func TestBuildResultsStreaming(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
defer cancel() defer cancel()
buildID := build.ID{0o2} buildID := build.ID{02}
req := &api.BuildRequest{} req := &api.BuildRequest{}
started := &api.BuildStarted{ID: buildID} started := &api.BuildStarted{ID: buildID}

View file

@ -3,7 +3,7 @@ package api
import ( import (
"context" "context"
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/build" "gitlab.com/slon/shad-go/distbuild/pkg/build"
) )
// JobResult описывает результат работы джоба. // JobResult описывает результат работы джоба.

View file

@ -11,16 +11,15 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"go.uber.org/zap/zaptest" "go.uber.org/zap/zaptest"
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/api" "gitlab.com/slon/shad-go/distbuild/pkg/api"
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/api/mock" "gitlab.com/slon/shad-go/distbuild/pkg/api/mock"
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/build" "gitlab.com/slon/shad-go/distbuild/pkg/build"
) )
//go:generate mockgen -package mock -destination mock/heartbeat.go . HeartbeatService //go:generate mockgen -package mock -destination mock/heartbeat.go . HeartbeatService
func TestHeartbeat(t *testing.T) { func TestHeartbeat(t *testing.T) {
ctrl := gomock.NewController(t) ctrl := gomock.NewController(t)
defer ctrl.Finish()
l := zaptest.NewLogger(t) l := zaptest.NewLogger(t)
m := mock.NewMockHeartbeatService(ctrl) m := mock.NewMockHeartbeatService(ctrl)

View file

@ -1,5 +1,5 @@
// Code generated by MockGen. DO NOT EDIT. // Code generated by MockGen. DO NOT EDIT.
// Source: gitlab.com/manytask/itmo-go/private/distbuild/pkg/api (interfaces: HeartbeatService) // Source: gitlab.com/slon/shad-go/distbuild/pkg/api (interfaces: HeartbeatService)
// Package mock is a generated GoMock package. // Package mock is a generated GoMock package.
package mock package mock
@ -7,7 +7,7 @@ package mock
import ( import (
context "context" context "context"
gomock "github.com/golang/mock/gomock" gomock "github.com/golang/mock/gomock"
api "gitlab.com/manytask/itmo-go/private/distbuild/pkg/api" api "gitlab.com/slon/shad-go/distbuild/pkg/api"
reflect "reflect" reflect "reflect"
) )

View file

@ -1,5 +1,5 @@
// Code generated by MockGen. DO NOT EDIT. // Code generated by MockGen. DO NOT EDIT.
// Source: gitlab.com/manytask/itmo-go/private/distbuild/pkg/api (interfaces: Service) // Source: gitlab.com/slon/shad-go/distbuild/pkg/api (interfaces: Service)
// Package mock is a generated GoMock package. // Package mock is a generated GoMock package.
package mock package mock
@ -7,8 +7,8 @@ package mock
import ( import (
context "context" context "context"
gomock "github.com/golang/mock/gomock" gomock "github.com/golang/mock/gomock"
api "gitlab.com/manytask/itmo-go/private/distbuild/pkg/api" api "gitlab.com/slon/shad-go/distbuild/pkg/api"
build "gitlab.com/manytask/itmo-go/private/distbuild/pkg/build" build "gitlab.com/slon/shad-go/distbuild/pkg/build"
reflect "reflect" reflect "reflect"
) )

View file

@ -4,12 +4,11 @@ import (
"encoding/hex" "encoding/hex"
"errors" "errors"
"fmt" "fmt"
"io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
"sync" "sync"
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/build" "gitlab.com/slon/shad-go/distbuild/pkg/build"
) )
var ( var (
@ -34,18 +33,18 @@ func NewCache(root string) (*Cache, error) {
if err := os.RemoveAll(tmpDir); err != nil { if err := os.RemoveAll(tmpDir); err != nil {
return nil, err return nil, err
} }
if err := os.MkdirAll(tmpDir, 0o777); err != nil { if err := os.MkdirAll(tmpDir, 0777); err != nil {
return nil, err return nil, err
} }
cacheDir := filepath.Join(root, "c") cacheDir := filepath.Join(root, "c")
if err := os.MkdirAll(cacheDir, 0o777); err != nil { if err := os.MkdirAll(cacheDir, 0777); err != nil {
return nil, err return nil, err
} }
for i := 0; i < 256; i++ { for i := 0; i < 256; i++ {
d := hex.EncodeToString([]byte{uint8(i)}) d := hex.EncodeToString([]byte{uint8(i)})
if err := os.MkdirAll(filepath.Join(cacheDir, d), 0o777); err != nil { if err := os.MkdirAll(filepath.Join(cacheDir, d), 0777); err != nil {
return nil, err return nil, err
} }
} }
@ -110,13 +109,13 @@ func (c *Cache) writeUnlock(id build.ID) {
} }
func (c *Cache) Range(artifactFn func(artifact build.ID) error) error { func (c *Cache) Range(artifactFn func(artifact build.ID) error) error {
shards, err := ioutil.ReadDir(c.cacheDir) shards, err := os.ReadDir(c.cacheDir)
if err != nil { if err != nil {
return err return err
} }
for _, shard := range shards { for _, shard := range shards {
dirs, err := ioutil.ReadDir(filepath.Join(c.cacheDir, shard.Name())) dirs, err := os.ReadDir(filepath.Join(c.cacheDir, shard.Name()))
if err != nil { if err != nil {
return err return err
} }
@ -151,7 +150,7 @@ func (c *Cache) Create(artifact build.ID) (path string, commit, abort func() err
} }
path = filepath.Join(c.tmpDir, artifact.String()) path = filepath.Join(c.tmpDir, artifact.String())
if err = os.MkdirAll(path, 0o777); err != nil { if err = os.MkdirAll(path, 0777); err != nil {
c.writeUnlock(artifact) c.writeUnlock(artifact)
return return
} }

View file

@ -2,15 +2,14 @@ package artifact_test
import ( import (
"errors" "errors"
"io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
"testing" "testing"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/artifact" "gitlab.com/slon/shad-go/distbuild/pkg/artifact"
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/build" "gitlab.com/slon/shad-go/distbuild/pkg/build"
) )
type testCache struct { type testCache struct {
@ -23,7 +22,7 @@ func (c *testCache) cleanup() {
} }
func newTestCache(t *testing.T) *testCache { func newTestCache(t *testing.T) *testCache {
tmpDir, err := ioutil.TempDir("", "") tmpDir, err := os.MkdirTemp("", "")
require.NoError(t, err) require.NoError(t, err)
cache, err := artifact.NewCache(tmpDir) cache, err := artifact.NewCache(tmpDir)

View file

@ -5,7 +5,7 @@ package artifact
import ( import (
"context" "context"
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/build" "gitlab.com/slon/shad-go/distbuild/pkg/build"
) )
// Download artifact from remote cache into local cache. // Download artifact from remote cache into local cache.

View file

@ -2,17 +2,17 @@ package artifact_test
import ( import (
"context" "context"
"io/ioutil"
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
"os"
"path/filepath" "path/filepath"
"testing" "testing"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"go.uber.org/zap/zaptest" "go.uber.org/zap/zaptest"
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/artifact" "gitlab.com/slon/shad-go/distbuild/pkg/artifact"
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/build" "gitlab.com/slon/shad-go/distbuild/pkg/build"
) )
func TestArtifactTransfer(t *testing.T) { func TestArtifactTransfer(t *testing.T) {
@ -23,7 +23,7 @@ func TestArtifactTransfer(t *testing.T) {
dir, commit, _, err := remoteCache.Create(id) dir, commit, _, err := remoteCache.Create(id)
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, ioutil.WriteFile(filepath.Join(dir, "a.txt"), []byte("foobar"), 0o777)) require.NoError(t, os.WriteFile(filepath.Join(dir, "a.txt"), []byte("foobar"), 0777))
require.NoError(t, commit()) require.NoError(t, commit())
l := zaptest.NewLogger(t) l := zaptest.NewLogger(t)
@ -42,7 +42,7 @@ func TestArtifactTransfer(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
defer unlock() defer unlock()
content, err := ioutil.ReadFile(filepath.Join(dir, "a.txt")) content, err := os.ReadFile(filepath.Join(dir, "a.txt"))
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, []byte("foobar"), content) require.Equal(t, []byte("foobar"), content)

View file

@ -39,7 +39,7 @@ type Job struct {
// exec - выполняет произвольную команду // exec - выполняет произвольную команду
// cat - записывает строку в файл // cat - записывает строку в файл
// //
// Все строки в описании команды могут содержать в себе на переменные. Перед выполнением // Все строки в описании команды могут содержать в себе ссылки на контекстные переменные. Перед выполнением
// реальной команды, переменные заменяются на их реальные значения. // реальной команды, переменные заменяются на их реальные значения.
// //
// {{.OutputDir}} - абсолютный путь до выходной директории джоба. // {{.OutputDir}} - абсолютный путь до выходной директории джоба.

View file

@ -7,10 +7,11 @@ import (
"go.uber.org/zap" "go.uber.org/zap"
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/build" "gitlab.com/slon/shad-go/distbuild/pkg/build"
) )
type Client struct{} type Client struct {
}
func NewClient( func NewClient(
l *zap.Logger, l *zap.Logger,

View file

@ -8,11 +8,12 @@ import (
"go.uber.org/zap" "go.uber.org/zap"
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/filecache" "gitlab.com/slon/shad-go/distbuild/pkg/filecache"
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/scheduler" "gitlab.com/slon/shad-go/distbuild/pkg/scheduler"
) )
type Coordinator struct{} type Coordinator struct {
}
var defaultConfig = scheduler.Config{ var defaultConfig = scheduler.Config{
CacheTimeout: time.Millisecond * 10, CacheTimeout: time.Millisecond * 10,
@ -26,6 +27,8 @@ func NewCoordinator(
panic("implement me") panic("implement me")
} }
func (c *Coordinator) Stop() {}
func (c *Coordinator) ServeHTTP(w http.ResponseWriter, r *http.Request) { func (c *Coordinator) ServeHTTP(w http.ResponseWriter, r *http.Request) {
panic("implement me") panic("implement me")
} }

View file

@ -7,10 +7,11 @@ import (
"go.uber.org/zap" "go.uber.org/zap"
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/build" "gitlab.com/slon/shad-go/distbuild/pkg/build"
) )
type Client struct{} type Client struct {
}
func NewClient(l *zap.Logger, endpoint string) *Client { func NewClient(l *zap.Logger, endpoint string) *Client {
panic("implement me") panic("implement me")

View file

@ -3,9 +3,9 @@ package filecache_test
import ( import (
"bytes" "bytes"
"context" "context"
"io/ioutil"
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
"os"
"path/filepath" "path/filepath"
"sync" "sync"
"testing" "testing"
@ -14,8 +14,8 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"go.uber.org/zap/zaptest" "go.uber.org/zap/zaptest"
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/build" "gitlab.com/slon/shad-go/distbuild/pkg/build"
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/filecache" "gitlab.com/slon/shad-go/distbuild/pkg/filecache"
) )
type env struct { type env struct {
@ -52,7 +52,7 @@ func TestFileUpload(t *testing.T) {
content := bytes.Repeat([]byte("foobar"), 1024*1024) content := bytes.Repeat([]byte("foobar"), 1024*1024)
tmpFilePath := filepath.Join(env.cache.tmpDir, "foo.txt") tmpFilePath := filepath.Join(env.cache.tmpDir, "foo.txt")
require.NoError(t, ioutil.WriteFile(tmpFilePath, content, 0o666)) require.NoError(t, os.WriteFile(tmpFilePath, content, 0666))
ctx := context.Background() ctx := context.Background()
@ -65,7 +65,7 @@ func TestFileUpload(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
defer unlock() defer unlock()
actualContent, err := ioutil.ReadFile(path) actualContent, err := os.ReadFile(path)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, content, actualContent) require.Equal(t, content, actualContent)
}) })
@ -123,7 +123,7 @@ func TestFileDownload(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
defer unlock() defer unlock()
content, err := ioutil.ReadFile(path) content, err := os.ReadFile(path)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, []byte("foobar"), content) require.Equal(t, []byte("foobar"), content)
} }

View file

@ -6,8 +6,8 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/artifact" "gitlab.com/slon/shad-go/distbuild/pkg/artifact"
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/build" "gitlab.com/slon/shad-go/distbuild/pkg/build"
) )
var ( var (

View file

@ -2,14 +2,13 @@ package filecache_test
import ( import (
"errors" "errors"
"io/ioutil"
"os" "os"
"testing" "testing"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/build" "gitlab.com/slon/shad-go/distbuild/pkg/build"
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/filecache" "gitlab.com/slon/shad-go/distbuild/pkg/filecache"
) )
type testCache struct { type testCache struct {
@ -18,7 +17,7 @@ type testCache struct {
} }
func newCache(t *testing.T) *testCache { func newCache(t *testing.T) *testCache {
tmpDir, err := ioutil.TempDir("", "filecache") tmpDir, err := os.MkdirTemp("", "filecache")
require.NoError(t, err) require.NoError(t, err)
c, err := filecache.New(tmpDir) c, err := filecache.New(tmpDir)
@ -36,25 +35,25 @@ func (c *testCache) cleanup() {
func TestFileCache(t *testing.T) { func TestFileCache(t *testing.T) {
cache := newCache(t) cache := newCache(t)
_, abort, err := cache.Write(build.ID{0o1}) _, abort, err := cache.Write(build.ID{01})
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, abort()) require.NoError(t, abort())
_, _, err = cache.Get(build.ID{0o1}) _, _, err = cache.Get(build.ID{01})
require.Truef(t, errors.Is(err, filecache.ErrNotFound), "%v", err) require.Truef(t, errors.Is(err, filecache.ErrNotFound), "%v", err)
f, _, err := cache.Write(build.ID{0o2}) f, _, err := cache.Write(build.ID{02})
require.NoError(t, err) require.NoError(t, err)
_, err = f.Write([]byte("foo bar")) _, err = f.Write([]byte("foo bar"))
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, f.Close()) require.NoError(t, f.Close())
path, unlock, err := cache.Get(build.ID{0o2}) path, unlock, err := cache.Get(build.ID{02})
require.NoError(t, err) require.NoError(t, err)
defer unlock() defer unlock()
content, err := ioutil.ReadFile(path) content, err := os.ReadFile(path)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, []byte("foo bar"), content) require.Equal(t, []byte("foo bar"), content)
} }

View file

@ -8,8 +8,8 @@ import (
"go.uber.org/zap" "go.uber.org/zap"
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/api" "gitlab.com/slon/shad-go/distbuild/pkg/api"
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/build" "gitlab.com/slon/shad-go/distbuild/pkg/build"
) )
var TimeAfter = time.After var TimeAfter = time.After
@ -25,7 +25,8 @@ type Config struct {
DepsTimeout time.Duration DepsTimeout time.Duration
} }
type Scheduler struct{} type Scheduler struct {
}
func NewScheduler(l *zap.Logger, config Config) *Scheduler { func NewScheduler(l *zap.Logger, config Config) *Scheduler {
panic("implement me") panic("implement me")
@ -46,3 +47,7 @@ func (c *Scheduler) ScheduleJob(job *api.JobSpec) *PendingJob {
func (c *Scheduler) PickJob(ctx context.Context, workerID api.WorkerID) *PendingJob { func (c *Scheduler) PickJob(ctx context.Context, workerID api.WorkerID) *PendingJob {
panic("implement me") panic("implement me")
} }
func (c *Scheduler) Stop() {
panic("implement me")
}

View file

@ -2,7 +2,6 @@ package tarstream_test
import ( import (
"bytes" "bytes"
"io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
"testing" "testing"
@ -10,11 +9,11 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"golang.org/x/sys/unix" "golang.org/x/sys/unix"
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/tarstream" "gitlab.com/slon/shad-go/distbuild/pkg/tarstream"
) )
func TestTarStream(t *testing.T) { func TestTarStream(t *testing.T) {
tmpDir, err := ioutil.TempDir("", "tarstream") tmpDir, err := os.MkdirTemp("", "tarstream")
require.NoError(t, err) require.NoError(t, err)
t.Logf("running inside %s", tmpDir) t.Logf("running inside %s", tmpDir)
@ -22,15 +21,15 @@ func TestTarStream(t *testing.T) {
from := filepath.Join(tmpDir, "from") from := filepath.Join(tmpDir, "from")
to := filepath.Join(tmpDir, "to") to := filepath.Join(tmpDir, "to")
require.NoError(t, os.Mkdir(from, 0o777)) require.NoError(t, os.Mkdir(from, 0777))
require.NoError(t, os.Mkdir(to, 0o777)) require.NoError(t, os.Mkdir(to, 0777))
var buf bytes.Buffer var buf bytes.Buffer
require.NoError(t, os.Mkdir(filepath.Join(from, "a"), 0o777)) require.NoError(t, os.Mkdir(filepath.Join(from, "a"), 0777))
require.NoError(t, os.MkdirAll(filepath.Join(from, "b", "c", "d"), 0o777)) require.NoError(t, os.MkdirAll(filepath.Join(from, "b", "c", "d"), 0777))
require.NoError(t, ioutil.WriteFile(filepath.Join(from, "a", "x.bin"), []byte("xxx"), 0o777)) require.NoError(t, os.WriteFile(filepath.Join(from, "a", "x.bin"), []byte("xxx"), 0777))
require.NoError(t, ioutil.WriteFile(filepath.Join(from, "b", "c", "y.txt"), []byte("yyy"), 0o666)) require.NoError(t, os.WriteFile(filepath.Join(from, "b", "c", "y.txt"), []byte("yyy"), 0666))
require.NoError(t, tarstream.Send(from, &buf)) require.NoError(t, tarstream.Send(from, &buf))
@ -53,15 +52,15 @@ func TestTarStream(t *testing.T) {
require.Equal(t, mode.String(), st.Mode().String()) require.Equal(t, mode.String(), st.Mode().String())
b, err := ioutil.ReadFile(path) b, err := os.ReadFile(path)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, content, b) require.Equal(t, content, b)
} }
checkFile(filepath.Join(to, "a", "x.bin"), []byte("xxx"), 0o755) checkFile(filepath.Join(to, "a", "x.bin"), []byte("xxx"), 0755)
checkFile(filepath.Join(to, "b", "c", "y.txt"), []byte("yyy"), 0o644) checkFile(filepath.Join(to, "b", "c", "y.txt"), []byte("yyy"), 0644)
} }
func init() { func init() {
unix.Umask(0o022) unix.Umask(0022)
} }

View file

@ -8,12 +8,13 @@ import (
"go.uber.org/zap" "go.uber.org/zap"
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/api" "gitlab.com/slon/shad-go/distbuild/pkg/api"
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/artifact" "gitlab.com/slon/shad-go/distbuild/pkg/artifact"
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/filecache" "gitlab.com/slon/shad-go/distbuild/pkg/filecache"
) )
type Worker struct{} type Worker struct {
}
func New( func New(
workerID api.WorkerID, workerID api.WorkerID,

View file

@ -7,7 +7,7 @@
✗ go test -v -run=^$ -bench=BenchmarkSprintf -memprofile=mem.out ./varfmt/... ✗ go test -v -run=^$ -bench=BenchmarkSprintf -memprofile=mem.out ./varfmt/...
goos: linux goos: linux
goarch: amd64 goarch: amd64
pkg: gitlab.com/manytask/itmo-go/private/varfmt pkg: gitlab.com/slon/shad-go/varfmt
cpu: Intel(R) Core(TM) i7-8650U CPU @ 1.90GHz cpu: Intel(R) Core(TM) i7-8650U CPU @ 1.90GHz
BenchmarkSprintf BenchmarkSprintf
BenchmarkSprintf/small BenchmarkSprintf/small
@ -17,7 +17,7 @@ BenchmarkSprintf/small_string-8 13282659 84.48 ns/op 16 B/op
BenchmarkSprintf/big BenchmarkSprintf/big
BenchmarkSprintf/big-8 20089 62372 ns/op 16388 B/op 1 allocs/op BenchmarkSprintf/big-8 20089 62372 ns/op 16388 B/op 1 allocs/op
PASS PASS
ok gitlab.com/manytask/itmo-go/private/varfmt 4.363s ok gitlab.com/slon/shad-go/varfmt 4.363s
``` ```
Сэмплы профайлера будут записаны в бинарный файл `mem.out`. Сэмплы профайлера будут записаны в бинарный файл `mem.out`.
@ -53,7 +53,7 @@ Showing nodes accounting for 715.73MB, 99.37% of 720.23MB total
Dropped 24 nodes (cum <= 3.60MB) Dropped 24 nodes (cum <= 3.60MB)
flat flat% sum% cum cum% flat flat% sum% cum cum%
715.73MB 99.37% 99.37% 716.73MB 99.51% fmt.Sprintf 715.73MB 99.37% 99.37% 716.73MB 99.51% fmt.Sprintf
0 0% 99.37% 716.73MB 99.51% gitlab.com/manytask/itmo-go/private/varfmt.BenchmarkSprintf.func1 0 0% 99.37% 716.73MB 99.51% gitlab.com/slon/shad-go/varfmt.BenchmarkSprintf.func1
0 0% 99.37% 716.73MB 99.51% testing.(*B).launch 0 0% 99.37% 716.73MB 99.51% testing.(*B).launch
0 0% 99.37% 716.73MB 99.51% testing.(*B).runN 0 0% 99.37% 716.73MB 99.51% testing.(*B).runN
(pprof) (pprof)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

BIN
docs/edit-in-place.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 173 KiB

View file

@ -63,8 +63,8 @@ import (
"flag" "flag"
"log" "log"
"gitlab.com/manytask/itmo-go/private/gitfame/configs" "gitlab.com/slon/shad-go/gitfame/configs"
"gitlab.com/manytask/itmo-go/private/gitfame/internal" "gitlab.com/slon/shad-go/gitfame/internal"
"github.com/spf13/pflag" "github.com/spf13/pflag"
@ -81,8 +81,8 @@ import (
"github.com/spf13/pflag" "github.com/spf13/pflag"
"gitlab.com/manytask/itmo-go/private/gitfame/configs" "gitlab.com/slon/shad-go/gitfame/configs"
"gitlab.com/manytask/itmo-go/private/gitfame/internal" "gitlab.com/slon/shad-go/gitfame/internal"
) )
``` ```

View file

@ -48,7 +48,7 @@
Low-level programming. unsafe. Package binary. bytes.Buffer. cgo, syscall. Low-level programming. unsafe. Package binary. bytes.Buffer. cgo, syscall.
11. Архитектура GC. Write barrier. Stack growth. GC pause. GOGC. sync.Pool. Шедулер 11. Архитектура GC. Write barrier. Stack growth. GC pause. GOGC. sync.Pool. Шедулер
горутин. GOMACPROCS. Утечка тредов. горутин. GOMAXPROCS. Утечка тредов.
12. Go tooling. pprof. CPU and Memory profiling. Кросс-компиляция. GOOS, GOARCH. CGO_ENABLED=0. 12. Go tooling. pprof. CPU and Memory profiling. Кросс-компиляция. GOOS, GOARCH. CGO_ENABLED=0.
Build tags. go modules. godoc. Code generation. Build tags. go modules. godoc. Code generation.

View file

@ -8,6 +8,7 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"gitlab.com/slon/shad-go/tools/testtool"
"go.uber.org/goleak" "go.uber.org/goleak"
) )
@ -38,6 +39,23 @@ func TestCall_Simple(t *testing.T) {
require.Equal(t, 2, called) require.Equal(t, 2, called)
} }
func TestCall_NoBusyWait(t *testing.T) {
done := make(chan struct{})
defer close(done)
var call Call
for i := 0; i < 10; i++ {
go func() {
_, _ = call.Do(context.Background(), func(ctx context.Context) (interface{}, error) {
<-done
return nil, nil
})
}()
}
testtool.VerifyNoBusyGoroutines(t)
}
func TestCall_Dedup(t *testing.T) { func TestCall_Dedup(t *testing.T) {
defer goleak.VerifyNone(t) defer goleak.VerifyNone(t)

67
excelwriter/README.md Normal file
View file

@ -0,0 +1,67 @@
# excelwriter [reflect]
В этой задаче нужно обернуть библиотеку для работы с exel'ем в reflect, реализовав интерфейс для построчной записи go объектов в excel
```go
type Writer interface {
WriteRow(r any) error
}
```
r — это либо структура, либо map[smth]any, либо указатель на что-то из этого.
smth — это либо строка, либо тип реализующий [TextMarshaler](https://pkg.go.dev/encoding#TextMarshaler)
Как должны сериализовываться поля структур подробно написано в интерфейсе.
Всё, что не специфицировано в доке и не проверяется тестами можно делать как сочтёте разумным.
Также нужно реализовать конструктор
```go
func New(f *excelize.File) Writer {
panic("implement me")
}
```
принимающий на вход инициализированный excel клиент.
Можно считать, что excel файл изначально пустой у которого создана 1 страница. Все записи нужно делать в ней.
Пример использования
```go
type Movie struct {
Title string
Year int `xlsx:"release_year"`
}
func StoreMovies() {
f := excelize.NewFile()
_, _ = f.NewSheet("Sheet1")
w := excelwriter.New(f)
_ = w.WriteRow(&Movie{Title: "Blade Runner", Year: 1982})
_ = w.WriteRow(&Movie{Title: "Blade Runner 2049", Year: 2017})
_ = w.WriteRow(map[string]any{"title": "Into the wild", "release_year": 2007})
out, _ := os.Create("/tmp/movie.xlsx")
_, _ = f.WriteTo(out)
}
```
В результате будет создан excel документ со следующим содержимым
```
title release_year
Blade Runner 1982
Blade Runner 2049 2017
Into the wild 2007
```
В первой строке хранятся имена колонок, которые вычисляются из имён полей, тэгов и ключей map'ов.
Разные структуры могут превращаться в разные наборы колонок.
Для каждого уникального имени должна быть ровно одна колонка, их нужно "создавать" по мере возникновения.
Новые ключи каждого конкретного мапа добавляются в колонки в отсортированном порядке, чтобы при перезапусках на одних и тех же данных получались одинаковые excel'ки.
Помимо имён полей в xlsx тэгах для числовых полей нужно поддержать стили форматирования.
Например, в excel нет отдельного типа для дат. Дата — это 15-и значный double (excel тип Number) со стилем форматирования `d-mmm-yy`. Библиотека для работы с excel'ем определяет [наборы популярных стилей](https://pkg.go.dev/github.com/xuri/excelize/v2#File.NewStyle) в виде enum'а `15 d-mmm-yy`. Это число 15 и нужно поддержать в тэге `xslx:"date,numfmt:15"`.
## Вопросы со звёздочкой
1. Как бы вы поддержали в тэгах стили форматирования ячеек (excelize.Fill, excelize.Border ...)?
2. Как бы вы поддержали в тэгах кастомные стили форматирования числовых значений, те, что не входят в стандартный набор, например `0,"K"`?
3. Как мог бы выглядеть Reader, совместимый с Writer'ом, читающий строчки из excel в Go структуры и map'ы?

48
excelwriter/writer.go Normal file
View file

@ -0,0 +1,48 @@
//go:build !solution
package excelwriter
import (
"github.com/xuri/excelize/v2"
)
type Writer interface {
// WriteRow appends struct fields or map values to excel sheet.
//
// Integers and floats are encoded as excel type Number.
// Strings are encoded as excel type Text.
// Booleans are encoded as excel type Logical.
//
// Pointer values are encoded as the value pointed to. A nil pointer is skipped.
//
// Values implementing encoding.TextMarshaler interface are encoded as excel Text.
//
// Interface values are encoded as the value contained in the interface. A nil interface is skipped.
//
// Channels and functions are skipped.
//
// Structs, maps, slices and arrays are marshaled into json and encoded as excel Text.
//
// Encoding of each struct field can be customized by format string
// stored under the "xlsx" key in the field's tag.
//
// // Field appears in excel under column "my_field".
// Field int `xlsx:"my_field"`
//
// // Field appears in excel under column "my_field" formatted with predeclared style 15 ("d-mmm-yy").
// // Only applicable for integers and floats.
// Field int `xlsx:"my_field,numfmt:15"`
//
// // Field is ignored by this package
// Field int `xlsx:"-"`
//
// The first row is reserved for column names.
// For structs column name must be either lowercase field name or the name from "xlsx" tag if present.
// For maps column name is a map key.
// If map key implements encoding.TextMarshaler then column name is string(key.MarshalText()).
WriteRow(r any) error
}
func New(f *excelize.File) Writer {
panic("implement me")
}

268
excelwriter/writer_test.go Normal file
View file

@ -0,0 +1,268 @@
package excelwriter_test
import (
"fmt"
"os"
"testing"
"github.com/stretchr/testify/require"
"github.com/xuri/excelize/v2"
"gitlab.com/slon/shad-go/excelwriter"
)
const Sheet = "Sheet1"
type MyInt int
type Basic struct {
I int `xlsx:"i"`
UI uint `xlsx:"ui"`
I16 int16 `xlsx:"i_16"`
UI16 uint16 `xlsx:"ui_16"`
I32 int32 `xlsx:"i_32"`
UI32 uint32 `xlsx:"ui_32"`
I64 int64 `xlsx:"i_64"`
UI64 uint64 `xlsx:"ui_64"`
Float float32 `xlsx:"float"`
Double float64 `xlsx:"double"`
Bool bool `xlsx:"bool"`
String string `xlsx:"string"`
MyInt int `xlsx:"my_int"`
}
type Inner struct {
Name string `xlsx:"name"`
}
type TextInt int
func (i TextInt) MarshalText() ([]byte, error) {
return []byte("__" + fmt.Sprint(i) + "__"), nil
}
type TextStruct struct {
V string
}
func (s TextStruct) MarshalText() (text []byte, err error) {
return []byte("__" + s.V + "__"), nil
}
func TestWriter_basic(t *testing.T) {
f := excelize.NewFile()
_, err := f.NewSheet(Sheet)
require.NoError(t, err)
w := excelwriter.New(f)
b := &Basic{
I: -1,
UI: 1,
I16: -16,
UI16: 16,
I32: -32,
UI32: 32,
I64: -64,
UI64: 64,
Float: -2.5,
Double: 5.5,
Bool: true,
String: "hello",
MyInt: 23,
}
require.NoError(t, w.WriteRow(b))
storeFile(t, f, "basic")
rows := readAll(t, f, true)
require.Equal(t, []string{"i", "ui", "i_16", "ui_16", "i_32", "ui_32", "i_64", "ui_64", "float", "double", "bool", "string", "my_int"}, rows[0])
require.Equal(t, []string{"-1", "1", "-16", "16", "-32", "32", "-64", "64", "-2.5", "5.5", "1", "hello", "23"}, rows[1])
}
func TestWriter_map(t *testing.T) {
f := excelize.NewFile()
_, err := f.NewSheet(Sheet)
require.NoError(t, err)
w := excelwriter.New(f)
require.NoError(t, w.WriteRow(map[string]any{
"id": 29,
"name": "hello",
"title": "yo",
}))
require.NoError(t, w.WriteRow(map[string]any{}))
require.NoError(t, w.WriteRow(map[TextStruct]any{
{"id"}: 18,
{"name"}: "tm",
}))
storeFile(t, f, "map")
rows := readAll(t, f, true)
require.Equal(t, []string{"id", "name", "title", "__id__", "__name__"}, rows[0])
require.Equal(t, []string{"29", "hello", "yo"}, rows[1])
require.Equal(t, []string{"", "", "", "18", "tm"}, rows[2])
}
type E struct {
ID string `xlsx:"id"`
NoTag string
Skipped int `xlsx:"-"`
private float32 `xlsx:"private"`
TextInt TextInt `xlsx:"text-int"`
TextStruct TextStruct `xlsx:"text-struct"`
Struct Inner `xlsx:"inner"`
StructPtr *Inner `xlsx:"inner-ptr"`
Slice []int `xlsx:"slice"`
Array [2]int `xlsx:"arr"`
Map map[string]string `xlsx:"map"`
TMMap map[TextStruct]string `xlsx:"tm-map"`
F func() `xlsx:"func"`
Ch chan int `xlsx:"chan"`
}
func TestWriter_elaborate(t *testing.T) {
f := excelize.NewFile()
_, err := f.NewSheet("Sheet1")
require.NoError(t, err)
w := excelwriter.New(f)
e := &E{
ID: "42",
NoTag: "no-tag",
Skipped: 29,
private: 2,
TextInt: 77,
TextStruct: TextStruct{V: "text-struct"},
Struct: Inner{Name: "inner"},
StructPtr: &Inner{Name: "inner-ptr"},
Slice: []int{1, 2, 3},
Array: [2]int{4, 5},
Map: map[string]string{"foo": "bar"},
TMMap: map[TextStruct]string{{"foo"}: "bar"},
F: func() { fmt.Println("hello") },
Ch: make(chan int, 10),
}
require.NoError(t, w.WriteRow(e))
storeFile(t, f, "elaborate")
rows := readAll(t, f, true)
require.Equal(t, []string{"id", "notag", "private", "text-int", "text-struct", "inner", "inner-ptr", "slice", "arr", "map", "tm-map"}, rows[0])
require.Equal(t, []string{"42", "no-tag", "2", "__77__", "__text-struct__", `{"Name":"inner"}`, `{"Name":"inner-ptr"}`, "[1,2,3]", "[4,5]", `{"foo":"bar"}`, `{"__foo__":"bar"}`}, rows[1])
}
func TestWriter_ptr(t *testing.T) {
f := excelize.NewFile()
_, err := f.NewSheet(Sheet)
require.NoError(t, err)
w := excelwriter.New(f)
require.NoError(t, w.WriteRow(struct{ Name string }{"foo"}))
require.NoError(t, w.WriteRow(&struct{ Name string }{"bar"}))
require.NoError(t, w.WriteRow(map[string]string{"name": "baz"}))
require.NoError(t, w.WriteRow(&map[string]string{"name": "qux"}))
storeFile(t, f, "ptr")
rows := readAll(t, f, true)
require.Equal(t, []string{"name"}, rows[0])
require.Equal(t, []string{"foo"}, rows[1])
require.Equal(t, []string{"bar"}, rows[2])
require.Equal(t, []string{"baz"}, rows[3])
require.Equal(t, []string{"qux"}, rows[4])
}
func TestWriter_unsupported(t *testing.T) {
f := excelize.NewFile()
_, err := f.NewSheet("Sheet1")
require.NoError(t, err)
w := excelwriter.New(f)
require.Error(t, w.WriteRow(2))
require.Error(t, w.WriteRow(nil))
var b *Basic
require.Error(t, w.WriteRow(b))
}
type S struct {
P float64 `xlsx:"percent,numfmt:9"`
D int `xlsx:"date,numfmt:15"`
D2 int `xlsx:",numfmt:15"`
T float64 `xlsx:"time,numfmt:22"`
Y int `xlsx:"jpy,numfmt:194"`
}
func TestWriter_style(t *testing.T) {
f := excelize.NewFile()
_, err := f.NewSheet("Sheet1")
require.NoError(t, err)
w := excelwriter.New(f)
s := &S{
P: 0.5,
D: 100,
D2: 100,
T: 100.5,
Y: 200,
}
require.NoError(t, w.WriteRow(s))
storeFile(t, f, "style")
rows := readAll(t, f, false)
require.Equal(t, []string{"percent", "date", "d2", "time", "jpy"}, rows[0])
require.Equal(t, []string{"50%", "9-Apr-00", "9-Apr-00", "4/9/00 12:00", "¥200.00"}, rows[1])
}
func readAll(t *testing.T, f *excelize.File, raw bool) [][]string {
t.Helper()
var out [][]string
rows, err := f.Rows(Sheet)
require.NoError(t, err)
var opts []excelize.Options
if raw {
opts = append(opts, excelize.Options{RawCellValue: true})
}
for i := 1; rows.Next(); i++ {
row, err := rows.Columns(opts...)
require.NoError(t, err)
out = append(out, row)
}
return out
}
func storeFile(t *testing.T, f *excelize.File, prefix string) {
t.Helper()
out, err := os.CreateTemp("/tmp", prefix+"-*.xlsx")
require.NoError(t, err)
_, err = f.WriteTo(out)
require.NoError(t, err)
t.Logf("stored file in %s", out.Name())
}

View file

@ -4,7 +4,6 @@ import (
"bufio" "bufio"
"bytes" "bytes"
"fmt" "fmt"
"io/ioutil"
"os" "os"
"path" "path"
"strings" "strings"
@ -12,7 +11,7 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"gitlab.com/manytask/itmo-go/private/tools/testtool" "gitlab.com/slon/shad-go/tools/testtool"
) )
func TestMerge(t *testing.T) { func TestMerge(t *testing.T) {
@ -33,6 +32,32 @@ func TestMerge(t *testing.T) {
1 1
1 1
2 2
`,
},
{
name: "with empty lines",
in: []string{`
0`, `
1
1
1`, `
0
2`},
out: `
0
0
1
1
1
2
`, `,
}, },
} { } {
@ -65,7 +90,7 @@ func TestSort(t *testing.T) {
testDir := path.Join("./testdata", "sort") testDir := path.Join("./testdata", "sort")
readTestCase := func(dir string) (in []string, out string) { readTestCase := func(dir string) (in []string, out string) {
files, err := ioutil.ReadDir(dir) files, err := os.ReadDir(dir)
require.NoError(t, err) require.NoError(t, err)
for _, f := range files { for _, f := range files {
@ -84,7 +109,7 @@ func TestSort(t *testing.T) {
testCaseDir := path.Join(testDir, d) testCaseDir := path.Join(testDir, d)
t.Run(d, func(t *testing.T) { t.Run(d, func(t *testing.T) {
tmpDir, err := ioutil.TempDir("", fmt.Sprintf("sort%s-", d)) tmpDir, err := os.MkdirTemp("", fmt.Sprintf("sort%s-", d))
require.NoError(t, err) require.NoError(t, err)
defer func() { _ = os.RemoveAll(tmpDir) }() defer func() { _ = os.RemoveAll(tmpDir) }()
@ -95,7 +120,7 @@ func TestSort(t *testing.T) {
w := bufio.NewWriter(&buf) w := bufio.NewWriter(&buf)
require.NoError(t, Sort(w, in...)) require.NoError(t, Sort(w, in...))
expected, err := ioutil.ReadFile(out) expected, err := os.ReadFile(out)
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, w.Flush()) require.NoError(t, w.Flush())
@ -107,7 +132,7 @@ func TestSort(t *testing.T) {
func listDirs(t *testing.T, dir string) []string { func listDirs(t *testing.T, dir string) []string {
t.Helper() t.Helper()
files, err := ioutil.ReadDir(dir) files, err := os.ReadDir(dir)
require.NoError(t, err) require.NoError(t, err)
var dirs []string var dirs []string
@ -134,11 +159,11 @@ func copyFiles(t *testing.T, in []string, dir string) []string {
func copyFile(t *testing.T, f, dir string) string { func copyFile(t *testing.T, f, dir string) string {
t.Helper() t.Helper()
data, err := ioutil.ReadFile(f) data, err := os.ReadFile(f)
require.NoError(t, err) require.NoError(t, err)
dst := path.Join(dir, path.Base(f)) dst := path.Join(dir, path.Base(f))
err = ioutil.WriteFile(dst, data, 0o644) err = os.WriteFile(dst, data, 0644)
require.NoError(t, err) require.NoError(t, err)
return dst return dst

BIN
externalsort/testdata/.gitattributes vendored Normal file

Binary file not shown.

View file

@ -2,6 +2,61 @@
package main package main
func main() { import (
"fmt"
"io"
"net/http"
"os"
"time"
)
type HTTPGetResult struct {
Success bool
Body string
Elapsed time.Duration
Size int
URL string
Error error
}
func (result HTTPGetResult) String() string {
if result.Success {
return fmt.Sprintf("%v\t%v\t%v", result.Elapsed, result.Size, result.URL)
} else {
return result.Error.Error()
}
}
func GetHTTPBody(url string, ch chan HTTPGetResult) {
startTime := time.Now()
resp, err := http.Get(url)
if err != nil {
ch <- HTTPGetResult{Success: false, Error: err}
return
}
defer resp.Body.Close()
data, err := io.ReadAll(resp.Body)
if err != nil {
ch <- HTTPGetResult{Success: false, Error: err}
return
}
ch <- HTTPGetResult{
Success: true,
Body: string(data),
Elapsed: time.Since(startTime),
Size: len(data),
URL: url,
}
}
func main() {
startTime := time.Now()
urls, ch := os.Args[1:], make(chan HTTPGetResult)
for _, url := range urls {
go GetHTTPBody(url, ch)
}
for i := 0; i < len(urls); i++ {
fmt.Println(<-ch)
}
fmt.Println(time.Since(startTime), "elapsed")
} }

View file

@ -17,10 +17,10 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"gitlab.com/manytask/itmo-go/private/tools/testtool" "gitlab.com/slon/shad-go/tools/testtool"
) )
const fetchallImportPath = "gitlab.com/manytask/itmo-go/private/fetchall" const fetchallImportPath = "gitlab.com/slon/shad-go/fetchall"
var binCache testtool.BinCache var binCache testtool.BinCache

View file

@ -3,7 +3,6 @@ package fileleak_test
import ( import (
"bytes" "bytes"
"fmt" "fmt"
"io/ioutil"
"net" "net"
"os" "os"
"syscall" "syscall"
@ -11,8 +10,8 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"gitlab.com/manytask/itmo-go/private/fileleak" "gitlab.com/slon/shad-go/fileleak"
"gitlab.com/manytask/itmo-go/private/tools/testtool" "gitlab.com/slon/shad-go/tools/testtool"
) )
type fakeT struct { type fakeT struct {
@ -75,7 +74,7 @@ func TestFileLeak_ReopenFile(t *testing.T) {
checkLeak(t, true, func() { checkLeak(t, true, func() {
_ = f.Close() _ = f.Close()
ff, err := ioutil.TempFile("", "") ff, err := os.CreateTemp("", "")
require.NoError(t, err) require.NoError(t, err)
f = ff f = ff
}) })
@ -129,6 +128,7 @@ func TestFileLeak_DupLeak(t *testing.T) {
var err error var err error
fd, err = syscall.Dup(1) fd, err = syscall.Dup(1)
require.NoError(t, err) require.NoError(t, err)
}) })
} }

11
firegod/Dockerfile Normal file
View file

@ -0,0 +1,11 @@
FROM golang:1.22
RUN ["mkdir", "-p", "/build"]
WORKDIR /build
COPY . .
RUN ["go", "build", "-tags", "solution", "-o", "/firegod", "./firegod"]
ENTRYPOINT [ "/firegod", "-http=0.0.0.0:8080" ]

55
firegod/README.md Normal file
View file

@ -0,0 +1,55 @@
# firegod
В этой задаче вам нужно научиться пользоваться связкой prometheus+grafana для отладки собственного кода.
Вам дан код сервиса. Нужно добавить в него метрики, и потом используя графану с помощью графиков ответить на ряд вопросов.
В этой задаче нет автоматической проверки. Чтобы получить оценку, нужно закоммитить свои ответы вместе со скриншотами в репозиторий, и поменять значение константы в `Solved` в файле `main.go` на `true`.
## Окружение
В файле `docker-compose.yaml` описан тестовый стенд.
- `prometheus` - контейнер с прометеем, который собирает метрики и выполняет запросы над ними.
- `grafana` - контейнер с графаной, дающий удобный `Web UI` для работы с прометеем.
- `my_service` - 5 реплик вашего сервиса.
Чтобы запустит тестовый стенд, выполните команду `docker compose up --build`. Чтобы перезапустить стенд, остановите `docker compose` нажав `Ctrl+C` и перезапустите команду.
После запуска стенда, проверьте что:
- [targets](http://localhost:9090/targets) показывает правильный список процессов. Один прометей в состоянии `up` и 5 копий вашего сервиса в состоянии `down` с ошибкой `server returned HTTP status 404 Not Found`.
- [grafana](http://localhost:3000/explore) пускает вас в интерфейс с логином `admin` и паролем `grafana`, а на странице Explore видно какие-то метрики (например `up`).
## Сервис
В пакете `dontlook` находится код сервиса. В него смотреть *нельзя*.
Вам нужно дописать код сбора и экспорта метрик в файл `main.go`.
1. Сделайте так, чтобы метрики экспортировались по запросу `GET /metrics`.
2. Включите экспорт метрик go рантайма и процесса (если они уже не экспортируются по дефолту).
3. Добавьте middleware записывающий метрики из http хендлеров.
## Вопросы
1. Сколько процессов каких сервисов подключено к прометею? (пример)
**Ответ**: 1 прометей и 5 моих сервисов.
![](screenshots/up.png)
2. Какой процесс постоянно перезапускается?
3. В каком процесс есть утечка файловых дескрипторов?
4. В каком процессе есть утечка памяти?
5. В каком процессе утекают горутины?
6. Какой хендлер пятисотит больше всех?
7. Сколько всего запросов в секунду приходит в сервис?
8. Какой хендлер медленнее всех отвечает, если сравнивать по 90-ой перцентиле времени ответа?
9. Какой хендлер генерирует больше всего трафика?

View file

@ -0,0 +1,62 @@
services:
prometheus:
image: prom/prometheus
container_name: prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
ports:
- 9090:9090
restart: unless-stopped
volumes:
- ./prometheus:/etc/prometheus
grafana:
image: grafana/grafana
container_name: grafana
ports:
- 3000:3000
restart: unless-stopped
environment:
- GF_SECURITY_ADMIN_USER=admin
- GF_SECURITY_ADMIN_PASSWORD=grafana
volumes:
- ./grafana:/etc/grafana/provisioning/datasources
my-service-0: &service
build:
context: ..
dockerfile: firegod/Dockerfile
restart: always
deploy:
resources:
limits:
cpus: '0.5'
memory: 100M
container_name: my-service-0
environment:
- REPLICA=0
my-service-1:
<<: *service
container_name: my-service-1
environment:
- REPLICA=1
my-service-2:
<<: *service
container_name: my-service-2
environment:
- REPLICA=2
my-service-3:
<<: *service
container_name: my-service-3
environment:
- REPLICA=3
my-service-4:
<<: *service
container_name: my-service-4
environment:
- REPLICA=4

View file

@ -0,0 +1,111 @@
package dontlook
import (
"bytes"
"fmt"
"io"
"net"
"net/http"
"os"
"strings"
"sync/atomic"
"time"
"github.com/go-chi/chi/v5"
)
func NewService(r chi.Router) {
replica := os.Getenv("REPLICA")
switch replica {
case "0":
go func() {
for {
go func() { select {} }()
time.Sleep(time.Millisecond * 100)
}
}()
case "2":
go func() {
var buf []string
for i := 0; true; i++ {
buf = append(buf, strings.Repeat("f", 1<<20))
_ = buf
time.Sleep(time.Millisecond * 100 * time.Duration(i))
}
}()
case "3":
go func() {
for {
_, _ = net.Dial("tcp", "localhost:8080")
time.Sleep(time.Millisecond * 10)
}
}()
case "4":
go func() {
time.Sleep(time.Second * 15)
os.Exit(1)
}()
}
runClient := func(getUrl func() string) {
for {
go func() {
rsp, err := http.Get(fmt.Sprintf("http://localhost:8080%s", getUrl()))
if err != nil {
fmt.Fprintf(os.Stderr, "%v\n", err)
return
}
_, _ = io.ReadAll(rsp.Body)
_ = rsp.Body.Close()
}()
time.Sleep(time.Microsecond * 100)
}
}
r.Get("/apple", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(200)
time.Sleep(time.Millisecond * 100)
_, _ = w.Write([]byte("OK"))
})
go runClient(func() string { return "/apple" })
r.Get("/banana", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(200)
_, _ = w.Write(bytes.Repeat([]byte("f"), 1<<10))
if replica == "0" {
time.Sleep(time.Second)
}
})
go runClient(func() string { return "/banana" })
var k atomic.Int32
r.Get("/orange", func(w http.ResponseWriter, r *http.Request) {
if k.Add(1)%100 == 0 {
w.WriteHeader(500)
} else {
w.WriteHeader(200)
}
})
go runClient(func() string { return "/orange" })
r.Get("/kiwi/{id}", func(w http.ResponseWriter, r *http.Request) {
if replica == "3" {
w.WriteHeader(200)
} else {
w.WriteHeader(500)
}
})
var i atomic.Int32
go runClient(func() string { return fmt.Sprintf("/kiwi/%d", i.Add(1)) })
}

View file

@ -0,0 +1,9 @@
apiVersion: 1
datasources:
- name: Prometheus
type: prometheus
url: http://prometheus:9090
isDefault: true
access: proxy
editable: true

24
firegod/main.go Normal file
View file

@ -0,0 +1,24 @@
package main
import (
"flag"
"log"
"net/http"
"github.com/go-chi/chi/v5"
"gitlab.com/slon/shad-go/firegod/dontlook"
)
var Solved = false
var flagPort = flag.String("http", "", "")
var router = chi.NewRouter()
func main() {
flag.Parse()
dontlook.NewService(router)
log.Fatal(http.ListenAndServe(*flagPort, router))
}

11
firegod/main_test.go Normal file
View file

@ -0,0 +1,11 @@
package main
import (
"testing"
"github.com/stretchr/testify/require"
)
func TestFiregod(t *testing.T) {
require.True(t, Solved)
}

View file

@ -0,0 +1,36 @@
global:
scrape_interval: 5s
evaluation_interval: 5s
scrape_timeout: 1s
alerting:
alertmanagers:
- static_configs:
- targets: []
scheme: http
timeout: 1s
api_version: v1
scrape_configs:
- job_name: prometheus
honor_timestamps: true
scrape_interval: 5s
scrape_timeout: 1s
metrics_path: /metrics
scheme: http
static_configs:
- targets:
- localhost:9090
- job_name: my-service
honor_timestamps: true
scrape_interval: 5s
scrape_timeout: 1s
metrics_path: /metrics
scheme: http
static_configs:
- targets:
- my-service-0:8080
- my-service-1:8080
- my-service-2:8080
- my-service-3:8080
- my-service-4:8080

BIN
firegod/screenshots/up.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 KiB

View file

@ -51,6 +51,6 @@ Forbidden
## Resources ## Resources
* project layout: https://github.com/golang-standards/project-layout * project layout: https://github.com/golang-standards/project-layout
* reverse proxy: https://en.wikipedia.org/wiki/Reverse_proxy * reverse proxy: https://pkg.go.dev/net/http/httputil#ReverseProxy
* yaml: https://gopkg.in/yaml.v2 * yaml: https://gopkg.in/yaml.v2
* regexp: https://golang.org/pkg/regexp/ * regexp: https://golang.org/pkg/regexp/

View file

@ -3,7 +3,6 @@ package main
import ( import (
"fmt" "fmt"
"io" "io"
"io/ioutil"
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
"os" "os"
@ -15,10 +14,10 @@ import (
"github.com/go-resty/resty/v2" "github.com/go-resty/resty/v2"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"gitlab.com/manytask/itmo-go/private/tools/testtool" "gitlab.com/slon/shad-go/tools/testtool"
) )
const importPath = "gitlab.com/manytask/itmo-go/private/firewall/cmd/firewall" const importPath = "gitlab.com/slon/shad-go/firewall/cmd/firewall"
var binCache testtool.BinCache var binCache testtool.BinCache
@ -36,7 +35,7 @@ func storeConfig(t *testing.T, conf string) (filename string, cleanup func()) {
t.Helper() t.Helper()
filename = path.Join(os.TempDir(), testtool.RandomName()+".yaml") filename = path.Join(os.TempDir(), testtool.RandomName()+".yaml")
err := ioutil.WriteFile(filename, []byte(conf), 0o777) err := os.WriteFile(filename, []byte(conf), 0777)
require.NoError(t, err) require.NoError(t, err)
cleanup = func() { _ = os.Remove(filename) } cleanup = func() { _ = os.Remove(filename) }

View file

@ -79,6 +79,18 @@ Stack:
а `definition` состоит из известных слов и чисел, разделённых пробелами. а `definition` состоит из известных слов и чисел, разделённых пробелами.
Слова можно переопределять. Слова можно переопределять.
При реализации механизма определений обратите внимание на юнит-тест
```go
{
description: "no redefinition",
input: []string{": foo 5 ;", ": bar foo ;", ": foo 6 ;", "bar foo"},
expected: []int{5, 6},
},
```
То есть семантика слова вычисляется непосредственно при определении и не меняется при переопределении "зависимостей".
### Проверка решения ### Проверка решения
Для запуска тестов нужно выполнить следующую команду: Для запуска тестов нужно выполнить следующую команду:

View file

@ -2,17 +2,173 @@
package main package main
import (
"errors"
"strconv"
"strings"
)
type Evaluator struct { type Evaluator struct {
stack []int
words map[string](func() error)
}
func (e *Evaluator) push(n int) {
e.stack = append(e.stack, n)
}
func (e *Evaluator) pop() (int, error) {
size := len(e.stack)
if size == 0 {
return 0, errors.New("nothing to pop")
}
n := e.stack[size-1]
e.stack = e.stack[:size-1]
return n, nil
}
func (e *Evaluator) popTwo() (int, int, error) {
if len(e.stack) < 2 {
return 0, 0, errors.New("not enough elements on stack")
}
second, _ := e.pop()
first, _ := e.pop()
return first, second, nil
}
// Used to initialzie arithemtic operations in words map
func (e *Evaluator) arithmeticOp(op func(int, int) int) func() error {
return func() error {
a, b, err := e.popTwo()
if err != nil {
return errors.New("not enough elements on stack")
}
e.push(op(a, b))
return nil
}
}
func (e *Evaluator) initBasicWords() {
e.words["+"] = e.arithmeticOp(func(a, b int) int { return a + b })
e.words["-"] = e.arithmeticOp(func(a, b int) int { return a - b })
e.words["*"] = e.arithmeticOp(func(a, b int) int { return a * b })
e.words["/"] = func() error {
a, b, err := e.popTwo()
if err != nil {
return errors.New("not enough elements on stack")
}
if b == 0 {
return errors.New("division by zero")
}
e.push(a / b)
return nil
}
e.words["dup"] = func() error {
size := len(e.stack)
if size == 0 {
return errors.New("not enough elements on stack")
}
e.stack = append(e.stack, e.stack[size-1])
return nil
}
e.words["over"] = func() error {
size := len(e.stack)
if size < 2 {
return errors.New("not enough elements on stack")
}
e.stack = append(e.stack, e.stack[size-2])
return nil
}
e.words["drop"] = func() error {
_, err := e.pop()
return err
}
e.words["swap"] = func() error {
size := len(e.stack)
if size < 2 {
return errors.New("not enough elements on stack")
}
e.stack[size-1], e.stack[size-2] = e.stack[size-2], e.stack[size-1]
return nil
}
}
func (e *Evaluator) getFunc(word string) (func() error, error) {
call, found := e.words[word]
if found {
return call, nil
}
num, err := strconv.Atoi(word)
if err != nil {
return nil, errors.New("word is not numerical or is not defined")
}
call = func() error {
e.push(num)
return nil
}
return call, nil
}
func (e *Evaluator) defineWord(word string, def string) error {
_, err := strconv.Atoi(word)
if err == nil {
return errors.New("word definition must not be numeric")
}
definitionWords := strings.Fields(def)
callChain := make([](func() error), len(definitionWords))
for i, w := range definitionWords {
call, err := e.getFunc(w)
if err != nil {
return err
}
callChain[i] = call
}
e.words[word] = func() error {
for _, call := range callChain {
err := call()
if err != nil {
return err
}
}
return nil
}
return nil
} }
// NewEvaluator creates evaluator. // NewEvaluator creates evaluator.
func NewEvaluator() *Evaluator { func NewEvaluator() *Evaluator {
return &Evaluator{} eval := &Evaluator{make([]int, 0), make(map[string](func() error))}
eval.initBasicWords()
return eval
} }
// Process evaluates sequence of words or definition. // Process evaluates sequence of words or definition.
// //
// Returns resulting stack state and an error. // Returns resulting stack state and an error.
func (e *Evaluator) Process(row string) ([]int, error) { func (e *Evaluator) Process(row string) ([]int, error) {
return nil, nil row = strings.ToLower(row)
if strings.HasPrefix(row, ":") && strings.HasSuffix(row, ";") {
row = strings.Trim(row, " :;")
wordAndDef := strings.SplitN(row, " ", 2)
if len(wordAndDef) < 2 {
return e.stack, errors.New("couldn't define a new word - incorrect syntax")
}
word, def := wordAndDef[0], wordAndDef[1]
err := e.defineWord(word, def)
if err != nil {
return e.stack, err
}
return e.stack, nil
}
for _, word := range strings.Fields(row) {
call, err := e.getFunc(word)
if err != nil {
return e.stack, err
}
err = call()
if err != nil {
return e.stack, err
}
}
return e.stack, nil
} }

View file

@ -99,6 +99,11 @@ var testCases = []testCase{
input: []string{"2 4 * 3 /"}, input: []string{"2 4 * 3 /"},
expected: []int{2}, expected: []int{2},
}, },
{
description: "add non-empty stack",
input: []string{"1 2 3 +"},
expected: []int{1, 5},
},
{ {
description: "dup", description: "dup",
input: []string{"1 dup"}, input: []string{"1 dup"},

View file

@ -9,7 +9,7 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"go.uber.org/goleak" "go.uber.org/goleak"
"gitlab.com/manytask/itmo-go/private/genericsum" "gitlab.com/slon/shad-go/genericsum"
) )
func TestMin(t *testing.T) { func TestMin(t *testing.T) {
@ -184,11 +184,42 @@ func TestIsHermitianMatrix(t *testing.T) {
{7, 2, 12}, {7, 2, 12},
{9, 12, 19}, {9, 12, 19},
})) }))
assert.True(t, genericsum.IsHermitianMatrix([][]int8{
{-1, 7, 9},
{7, -2, 12},
{9, 12, -19},
}))
assert.True(t, genericsum.IsHermitianMatrix([][]uint16{
{1, 7, 9},
{7, 2, 12},
{9, 12, 19},
}))
assert.False(t, genericsum.IsHermitianMatrix([][]int{ assert.False(t, genericsum.IsHermitianMatrix([][]int{
{1, 12, 8}, {1, 12, 8},
{3, 4, 7}, {3, 4, 7},
{8, 7, 11}, {8, 7, 11},
})) }))
assert.False(t, genericsum.IsHermitianMatrix([][]int32{
{1, 112, 8},
{-3, 4, -7},
{8, 7, 11},
}))
assert.False(t, genericsum.IsHermitianMatrix([][]uint64{
{1, 12, 8},
{3, 4, 7},
{8, 7, 11},
}))
assert.True(t, genericsum.IsHermitianMatrix([][]float32{
{1.0, 7.0, 9.0},
{7.0, 2.0, 12.0},
{9.0, 12.0, 19.0},
}))
assert.False(t, genericsum.IsHermitianMatrix([][]float32{
{1.0, 12.0, 8.0},
{3.0, 4.0, 7.0},
{8.0, 7.0, 11.0},
}))
assert.True(t, genericsum.IsHermitianMatrix([][]complex64{ assert.True(t, genericsum.IsHermitianMatrix([][]complex64{
{1, 3 + 2i}, {1, 3 + 2i},
{3 - 2i, 4}, {3 - 2i, 4},

View file

@ -175,6 +175,11 @@ export PATH=$GOPATH/bin:$PATH
После этого `gitfame` будет доступен всюду. После этого `gitfame` будет доступен всюду.
В реализации вы можете использовать сторонние библиотеки, которые уже доступны в нашем [`go.mod`](../go.mod). Менять `go.mod` нельзя.
Весь репозиторий курса - это один go модуль с одним go.mod файлом в корне. Корню репозитория соответствует импорт путь `gitlab.com/slon/shad-go`. Если вы создадите пакет в директории `gitfame/internal/git`, то импортировать его нужно будет по пути `gitlab.com/slon/shad-go/gitfame/internal/git`.
### Code review comments ### Code review comments
Прочитайте и исправьте [распространённые ошибки](../docs/gitfame_review_comments.md). Прочитайте и исправьте [распространённые ошибки](../docs/gitfame_review_comments.md).

View file

@ -2,7 +2,6 @@ package integration
import ( import (
"bytes" "bytes"
"io/ioutil"
"os" "os"
"os/exec" "os/exec"
"path" "path"
@ -14,10 +13,10 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"gopkg.in/yaml.v2" "gopkg.in/yaml.v2"
"gitlab.com/manytask/itmo-go/private/tools/testtool" "gitlab.com/slon/shad-go/tools/testtool"
) )
const importPath = "gitlab.com/manytask/itmo-go/private/gitfame/cmd/gitfame" const importPath = "gitlab.com/slon/shad-go/gitfame/cmd/gitfame"
var binCache testtool.BinCache var binCache testtool.BinCache
@ -43,7 +42,7 @@ func TestGitFame(t *testing.T) {
tc := ReadTestCase(t, filepath.Join(testsDir, dir)) tc := ReadTestCase(t, filepath.Join(testsDir, dir))
t.Run(dir+"/"+tc.Name, func(t *testing.T) { t.Run(dir+"/"+tc.Name, func(t *testing.T) {
dir, err := ioutil.TempDir("", "gitfame-") dir, err := os.MkdirTemp("", "gitfame-")
require.NoError(t, err) require.NoError(t, err)
defer func() { _ = os.RemoveAll(dir) }() defer func() { _ = os.RemoveAll(dir) }()
@ -75,7 +74,7 @@ func TestGitFame(t *testing.T) {
func ListTestDirs(t *testing.T, path string) []string { func ListTestDirs(t *testing.T, path string) []string {
t.Helper() t.Helper()
files, err := ioutil.ReadDir(path) files, err := os.ReadDir(path)
require.NoError(t, err) require.NoError(t, err)
var names []string var names []string
@ -109,7 +108,7 @@ func ReadTestCase(t *testing.T, path string) *TestCase {
desc := ReadTestDescription(t, path) desc := ReadTestDescription(t, path)
expected, err := ioutil.ReadFile(filepath.Join(path, "expected.out")) expected, err := os.ReadFile(filepath.Join(path, "expected.out"))
require.NoError(t, err) require.NoError(t, err)
return &TestCase{TestDescription: desc, Expected: expected} return &TestCase{TestDescription: desc, Expected: expected}
@ -126,7 +125,7 @@ type TestDescription struct {
func ReadTestDescription(t *testing.T, path string) *TestDescription { func ReadTestDescription(t *testing.T, path string) *TestDescription {
t.Helper() t.Helper()
data, err := ioutil.ReadFile(filepath.Join(path, "description.yaml")) data, err := os.ReadFile(filepath.Join(path, "description.yaml"))
require.NoError(t, err) require.NoError(t, err)
var desc TestDescription var desc TestDescription

84
go.mod
View file

@ -1,66 +1,80 @@
module gitlab.com/manytask/itmo-go/private module gitlab.com/slon/shad-go
go 1.18 go 1.22.0
require ( require (
github.com/felixge/httpsnoop v1.0.3 github.com/felixge/httpsnoop v1.0.3
github.com/go-chi/chi/v5 v5.0.8 github.com/go-chi/chi/v5 v5.0.8
github.com/go-git/go-git/v5 v5.11.0
github.com/go-redis/redis/v8 v8.11.5 github.com/go-redis/redis/v8 v8.11.5
github.com/go-resty/resty/v2 v2.1.0 github.com/go-resty/resty/v2 v2.1.0
github.com/gofrs/uuid v3.3.0+incompatible github.com/gofrs/uuid v3.3.0+incompatible
github.com/golang/mock v1.4.1 github.com/golang/mock v1.6.0
github.com/google/go-cmp v0.5.9 github.com/google/btree v1.1.2
github.com/google/go-cmp v0.6.0
github.com/gorilla/handlers v1.4.2 github.com/gorilla/handlers v1.4.2
github.com/gorilla/mux v1.7.4 github.com/gorilla/mux v1.7.4
github.com/gorilla/websocket v1.4.2 github.com/gorilla/websocket v1.4.2
github.com/jackc/pgx/v4 v4.6.0 github.com/jackc/pgx/v5 v5.5.3
github.com/jonboulle/clockwork v0.1.0 github.com/jonboulle/clockwork v0.4.0
github.com/spf13/cobra v1.1.3 github.com/spf13/cobra v1.1.3
github.com/spf13/pflag v1.0.5 github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.8.2 github.com/stretchr/testify v1.8.4
go.uber.org/goleak v1.0.0 go.uber.org/goleak v1.3.0
go.uber.org/zap v1.14.0 go.uber.org/zap v1.26.0
golang.org/x/exp v0.0.0-20230321023759-10a507213a29 golang.org/x/exp v0.0.0-20230321023759-10a507213a29
golang.org/x/perf v0.0.0-20191209155426-36b577b0eb03 golang.org/x/perf v0.0.0-20191209155426-36b577b0eb03
golang.org/x/sync v0.1.0 golang.org/x/sync v0.6.0
golang.org/x/sys v0.7.0 golang.org/x/sys v0.17.0
golang.org/x/tools v0.7.0 golang.org/x/tools v0.18.0
google.golang.org/grpc v1.54.0 google.golang.org/grpc v1.54.0
google.golang.org/protobuf v1.30.0 google.golang.org/protobuf v1.33.0
gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v2 v2.4.0
) )
require ( require (
github.com/BurntSushi/toml v0.3.1 // indirect dario.cat/mergo v1.0.0 // indirect
github.com/Microsoft/go-winio v0.6.1 // indirect
github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/cloudflare/circl v1.3.3 // indirect
github.com/cyphar/filepath-securejoin v0.2.4 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/emirpasic/gods v1.18.1 // indirect
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
github.com/go-git/go-billy/v5 v5.5.0 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.3 // indirect github.com/golang/protobuf v1.5.3 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/jackc/chunkreader/v2 v2.0.1 // indirect
github.com/jackc/pgconn v1.5.0 // indirect
github.com/jackc/pgio v1.0.0 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgproto3/v2 v2.0.1 // indirect github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
github.com/jackc/pgservicefile v0.0.0-20200307190119-3430c5407db8 // indirect github.com/jackc/puddle/v2 v2.2.1 // indirect
github.com/jackc/pgtype v1.3.0 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
github.com/kr/pretty v0.3.0 // indirect github.com/kevinburke/ssh_config v1.2.0 // indirect
github.com/lib/pq v1.10.0 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
github.com/pkg/errors v0.9.1 // indirect github.com/pjbgf/sha1cd v0.3.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rogpeppe/go-internal v1.8.0 // indirect github.com/prometheus/client_golang v1.19.1 // indirect
github.com/prometheus/client_model v0.5.0 // indirect
github.com/prometheus/common v0.48.0 // indirect
github.com/prometheus/procfs v0.12.0 // indirect
github.com/richardlehane/mscfb v1.0.4 // indirect
github.com/richardlehane/msoleps v1.0.3 // indirect
github.com/sergi/go-diff v1.1.0 // indirect
github.com/skeema/knownhosts v1.2.1 // indirect
github.com/stretchr/objx v0.5.0 // indirect github.com/stretchr/objx v0.5.0 // indirect
go.uber.org/atomic v1.5.0 // indirect github.com/xanzy/ssh-agent v0.3.3 // indirect
go.uber.org/multierr v1.3.0 // indirect github.com/xuri/efp v0.0.0-20231025114914-d1ff6096ae53 // indirect
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee // indirect github.com/xuri/excelize/v2 v2.8.1 // indirect
golang.org/x/crypto v0.5.0 // indirect github.com/xuri/nfp v0.0.0-20230919160717-d98342af3f05 // indirect
golang.org/x/lint v0.0.0-20190930215403-16217165b5de // indirect go.uber.org/multierr v1.10.0 // indirect
golang.org/x/mod v0.9.0 // indirect golang.org/x/crypto v0.19.0 // indirect
golang.org/x/net v0.9.0 // indirect golang.org/x/mod v0.15.0 // indirect
golang.org/x/text v0.9.0 // indirect golang.org/x/net v0.21.0 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect golang.org/x/text v0.14.0 // indirect
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/warnings.v0 v0.1.2 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect
honnef.co/go/tools v0.0.1-2019.2.3 // indirect
) )

301
go.sum
View file

@ -11,38 +11,50 @@ cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7
cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/GoogleCloudPlatform/cloudsql-proxy v0.0.0-20190129172621-c8b1d7a94ddf/go.mod h1:aJ4qN3TfrelA6NZ6AXsXRfmEVaYin3EDbSPJrKS8OXo= github.com/GoogleCloudPlatform/cloudsql-proxy v0.0.0-20190129172621-c8b1d7a94ddf/go.mod h1:aJ4qN3TfrelA6NZ6AXsXRfmEVaYin3EDbSPJrKS8OXo=
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 h1:kkhsdkhsCvIsutKu5zLMgWtgh9YxGCNAw8Ad8hjwfYg=
github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0=
github.com/aclements/go-gg v0.0.0-20170118225347-6dbb4e4fefb0/go.mod h1:55qNq4vcpkIuHowELi5C8e+1yUHtoLoOUR9QU5j7Tes= github.com/aclements/go-gg v0.0.0-20170118225347-6dbb4e4fefb0/go.mod h1:55qNq4vcpkIuHowELi5C8e+1yUHtoLoOUR9QU5j7Tes=
github.com/aclements/go-moremath v0.0.0-20161014184102-0ff62e0875ff/go.mod h1:idZL3yvz4kzx1dsBOAC+oYv6L92P1oFEhUXUB1A/lwQ= github.com/aclements/go-moremath v0.0.0-20161014184102-0ff62e0875ff/go.mod h1:idZL3yvz4kzx1dsBOAC+oYv6L92P1oFEhUXUB1A/lwQ=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs=
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@ -50,14 +62,29 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a h1:mATvB/9r/3gvcejNsXKSkQ6lcIaNec2nyfOdlTBR2lU=
github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM=
github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk=
github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/gliderlabs/ssh v0.3.5 h1:OcaySEmAQJgyYcArR+gGGTHCyE7nvhEMTlYY+Dp8CpY=
github.com/gliderlabs/ssh v0.3.5/go.mod h1:8XB4KraRrX39qHhT6yxPsHedjA08I/uBVwj4xC+/+z4=
github.com/go-chi/chi/v5 v5.0.8 h1:lD+NLqFcAi1ovnVZpsnObHGW4xb4J8lNmoYVfECH1Y0= github.com/go-chi/chi/v5 v5.0.8 h1:lD+NLqFcAi1ovnVZpsnObHGW4xb4J8lNmoYVfECH1Y0=
github.com/go-chi/chi/v5 v5.0.8/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= github.com/go-chi/chi/v5 v5.0.8/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI=
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic=
github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU=
github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow=
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4=
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII=
github.com/go-git/go-git/v5 v5.11.0 h1:XIZc1p+8YzypNr34itUfSvYJcv+eYdTnTvOZ2vD3cA4=
github.com/go-git/go-git/v5 v5.11.0/go.mod h1:6GFcX2P3NM7FPBfpePbpLd21XxsgdAt+lKqXmCUiUCY=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
@ -68,18 +95,19 @@ github.com/go-resty/resty/v2 v2.1.0 h1:Z6IefCpUMfnvItVJaJXWv/pMiiD11So35QgwEELsl
github.com/go-resty/resty/v2 v2.1.0/go.mod h1:dZGr0i9PLlaaTD4H/hoZIDjQ+r6xq8mgbRzHZf7f2J8= github.com/go-resty/resty/v2 v2.1.0/go.mod h1:dZGr0i9PLlaaTD4H/hoZIDjQ+r6xq8mgbRzHZf7f2J8=
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/gofrs/uuid v3.3.0+incompatible h1:8K4tyRfvU1CYPgJsveYFQMhpFd/wXNM7iK6rR7UHz84= github.com/gofrs/uuid v3.3.0+incompatible h1:8K4tyRfvU1CYPgJsveYFQMhpFd/wXNM7iK6rR7UHz84=
github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
github.com/golang/mock v1.4.1 h1:ocYkMQY5RrXTYgXl7ICpV0IXwlEQGwKIsery4gyXa1U= github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
@ -93,11 +121,13 @@ github.com/gonum/lapack v0.0.0-20181123203213-e4cdc5a0bff9/go.mod h1:XA3DeT6rxh2
github.com/gonum/matrix v0.0.0-20181209220409-c518dec07be9/go.mod h1:0EXg4mc1CNP0HCqCz+K4ts155PXIlUywf0wqN+GfPZw= github.com/gonum/matrix v0.0.0-20181209220409-c518dec07be9/go.mod h1:0EXg4mc1CNP0HCqCz+K4ts155PXIlUywf0wqN+GfPZw=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU=
github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
@ -137,78 +167,39 @@ github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2p
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo=
github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8=
github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
github.com/jackc/pgconn v0.0.0-20190420214824-7e0022ef6ba3/go.mod h1:jkELnwuX+w9qN5YIfX0fl88Ehu4XC3keFuOJJk9pcnA=
github.com/jackc/pgconn v0.0.0-20190824142844-760dd75542eb/go.mod h1:lLjNuW/+OfW9/pnVKPazfWOgNfH2aPem8YQ7ilXGvJE=
github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsUgOEh9hBm+xYTstcNHg7UPMVJqRfQxq4s=
github.com/jackc/pgconn v1.5.0 h1:oFSOilzIZkyg787M1fEmyMfOUUvwj0daqYMfaWwNL4o=
github.com/jackc/pgconn v1.5.0/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr0fAI=
github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE=
github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8=
github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2 h1:JVX6jT/XfzNqIjye4717ITLaNwV9mWbJx0dLCpcRzdA=
github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE=
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78= github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk=
github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA= github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg= github.com/jackc/pgx/v5 v5.5.3 h1:Ces6/M3wbDXYpM8JyyPD57ivTtJACFZJd885pdIaV2s=
github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= github.com/jackc/pgx/v5 v5.5.3/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A=
github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk=
github.com/jackc/pgproto3/v2 v2.0.1 h1:Rdjp4NFjwHnEslx2b66FfCI2S0LhO4itac3hXz6WX9M= github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
github.com/jackc/pgproto3/v2 v2.0.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
github.com/jackc/pgservicefile v0.0.0-20200307190119-3430c5407db8 h1:Q3tB+ExeflWUW7AFcAhXqk40s9mnNYLk1nOkKNZ5GnU= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
github.com/jackc/pgservicefile v0.0.0-20200307190119-3430c5407db8/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E=
github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg=
github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc=
github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw=
github.com/jackc/pgtype v1.3.0 h1:l8JvKrby3RI7Kg3bYEeU9TA4vqC38QDpFCfcrC7KuN0=
github.com/jackc/pgtype v1.3.0/go.mod h1:b0JqxHvPmljG+HQ5IsvQ0yqeSi4nGcDTVjFoiLDb0Ik=
github.com/jackc/pgx v3.6.2+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I=
github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y=
github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM=
github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc=
github.com/jackc/pgx/v4 v4.6.0 h1:Fh0O9GdlG4gYpjpwOqjdEodJUQM9jzN3Hdv7PN0xmm0=
github.com/jackc/pgx/v4 v4.6.0/go.mod h1:vPh43ZzxijXUVJ+t/EmXBtFmbFVO72cuneCT9oAlxAg=
github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
github.com/jackc/puddle v1.1.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/jonboulle/clockwork v0.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4=
github.com/jonboulle/clockwork v0.4.0/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK7fnezOII0kc=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4=
github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.10.0 h1:Zx5DJFEYQXio93kgXnQ09fXNiUKsqv4OUEu2UtGcB1E=
github.com/lib/pq v1.10.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
github.com/mattn/go-sqlite3 v0.0.0-20161215041557-2d44decb4941/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-sqlite3 v0.0.0-20161215041557-2d44decb4941/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
@ -222,14 +213,20 @@ github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:F
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI=
github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4=
github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
@ -239,31 +236,40 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE=
github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw=
github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI=
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.48.0 h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSzKKE=
github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo=
github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/richardlehane/mscfb v1.0.4 h1:WULscsljNPConisD5hR0+OyZjwK46Pfyr6mPu5ZawpM=
github.com/richardlehane/mscfb v1.0.4/go.mod h1:YzVpcZg9czvAuhk9T+a3avCpcFPMUWm7gK3DypaEsUk=
github.com/richardlehane/msoleps v1.0.1/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg=
github.com/richardlehane/msoleps v1.0.3 h1:aznSZzrwYRl3rLKRT3gUk9am7T/mLNSnJINvN0AQoVM=
github.com/richardlehane/msoleps v1.0.3/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=
github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24 h1:pntxY8Ary0t43dCZ5dqY4YTJCObLY1kIXl0uzMv+7DE= github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/skeema/knownhosts v1.2.1 h1:SHWdIUa82uGZz+F+47k8SY4QhhI291cXCpopT1lK2AQ=
github.com/skeema/knownhosts v1.2.1/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
@ -279,50 +285,54 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= github.com/xuri/efp v0.0.0-20231025114914-d1ff6096ae53 h1:Chd9DkqERQQuHpXjR/HSV1jLZA6uaoiwwH3vSuF3IW0=
github.com/xuri/efp v0.0.0-20231025114914-d1ff6096ae53/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI=
github.com/xuri/excelize/v2 v2.8.1 h1:pZLMEwK8ep+CLIUWpWmvW8IWE/yxqG0I1xcN6cVMGuQ=
github.com/xuri/excelize/v2 v2.8.1/go.mod h1:oli1E4C3Pa5RXg1TBXn4ENCXDV5JUMlBluUhG7c+CEE=
github.com/xuri/nfp v0.0.0-20230919160717-d98342af3f05 h1:qhbILQo1K3mphbwKh1vNm4oGezE1eF9fQWmNiIpSfI4=
github.com/xuri/nfp v0.0.0-20230919160717-d98342af3f05/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.5.0 h1:OI5t8sDa1Or+q8AeE+yKeB/SDYioSHAgcVljj9JIETY= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
go.uber.org/goleak v1.0.0 h1:qsup4IcBdlmsnGfqyLl4Ntn3C2XCCuKAE7DwHpScyUo=
go.uber.org/goleak v1.0.0/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/multierr v1.3.0 h1:sFPn2GLc3poCkfrpIXGhBD2X0CMIo4Q/zSULXrj/+uc= go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ=
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4=
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.14.0 h1:/pduUoebOeeJzTDFuoMgC6nRkiasr1sBCIEorly7m4o= go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo=
go.uber.org/zap v1.14.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo=
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@ -338,14 +348,16 @@ golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTk
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8=
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -361,9 +373,15 @@ golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/oauth2 v0.0.0-20170207211851-4464e7848382/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20170207211851-4464e7848382/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@ -375,8 +393,11 @@ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -384,25 +405,46 @@ golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U=
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@ -414,26 +456,23 @@ golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ=
golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/api v0.0.0-20170206182103-3d017632ea10/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.0.0-20170206182103-3d017632ea10/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
@ -466,16 +505,21 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s=
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
@ -488,8 +532,5 @@ gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=

View file

@ -5,7 +5,7 @@ package gossip
import ( import (
"time" "time"
"gitlab.com/manytask/itmo-go/private/gossip/meshpb" "gitlab.com/slon/shad-go/gossip/meshpb"
"google.golang.org/grpc" "google.golang.org/grpc"
) )

View file

@ -8,8 +8,8 @@ import (
"time" "time"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"gitlab.com/manytask/itmo-go/private/gossip" "gitlab.com/slon/shad-go/gossip"
"gitlab.com/manytask/itmo-go/private/gossip/meshpb" "gitlab.com/slon/shad-go/gossip/meshpb"
"go.uber.org/goleak" "go.uber.org/goleak"
"google.golang.org/grpc" "google.golang.org/grpc"
) )

View file

@ -2,7 +2,7 @@
syntax = "proto3"; syntax = "proto3";
option go_package = "gitlab.com/manytask/itmo-go/private/gossip/meshpb"; option go_package = "gitlab.com/slon/shad-go/gossip/meshpb";
// PeerMeta is arbitrary message that is propagated with peer gossip. // PeerMeta is arbitrary message that is propagated with peer gossip.
message PeerMeta { message PeerMeta {

View file

@ -6,14 +6,14 @@
``` ```
goos: linux goos: linux
goarch: amd64 goarch: amd64
pkg: gitlab.com/manytask/itmo-go/private/gzep pkg: gitlab.com/slon/shad-go/gzep
cpu: Intel(R) Core(TM) i7-8650U CPU @ 1.90GHz cpu: Intel(R) Core(TM) i7-8650U CPU @ 1.90GHz
BenchmarkEncodeSimple BenchmarkEncodeSimple
BenchmarkEncodeSimple-8 7047 176628 ns/op 813872 B/op 17 allocs/op BenchmarkEncodeSimple-8 7047 176628 ns/op 813872 B/op 17 allocs/op
BenchmarkEncode BenchmarkEncode
BenchmarkEncode-8 41706 32616 ns/op 19 B/op 0 allocs/op BenchmarkEncode-8 41706 32616 ns/op 19 B/op 0 allocs/op
PASS PASS
ok gitlab.com/manytask/itmo-go/private/gzep 3.625s ok gitlab.com/slon/shad-go/gzep 3.625s
``` ```
### С чего начать? ### С чего начать?

View file

@ -9,8 +9,8 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"gitlab.com/manytask/itmo-go/private/gzep" "gitlab.com/slon/shad-go/gzep"
"gitlab.com/manytask/itmo-go/private/tools/testtool" "gitlab.com/slon/shad-go/tools/testtool"
) )
func BenchmarkEncode(b *testing.B) { func BenchmarkEncode(b *testing.B) {
@ -47,6 +47,7 @@ func TestEncode_RoundTrip(t *testing.T) {
require.NoError(t, err, tc.in) require.NoError(t, err, tc.in)
require.Equal(t, tc.in, string(out)) require.Equal(t, tc.in, string(out))
}) })
} }
} }

View file

@ -2,6 +2,39 @@
package hogwarts package hogwarts
func GetCourseList(prereqs map[string][]string) []string { import (
return []string{} "log"
"slices"
)
func singleCourseList(
course string, prereqs map[string][]string, list []string, traversed []string,
) []string {
if slices.Contains(traversed, course) {
log.Panic("Recursive prereqs, aborting...")
}
traversed = append(traversed, course)
for _, prereqCourse := range prereqs[course] {
if !slices.Contains(list, prereqCourse) {
i := slices.Index(list, course)
if i == -1 {
list = append(list, prereqCourse)
} else {
list = slices.Insert(list, i, prereqCourse)
}
}
list = singleCourseList(prereqCourse, prereqs, list, traversed)
}
return list
}
func GetCourseList(prereqs map[string][]string) []string {
list := make([]string, 0)
for course := range prereqs {
if !slices.Contains(list, course) {
list = append(list, course)
}
list = singleCourseList(course, prereqs, list, []string{})
}
return list
} }

View file

@ -2,6 +2,8 @@
package hotelbusiness package hotelbusiness
import "math"
type Guest struct { type Guest struct {
CheckInDate int CheckInDate int
CheckOutDate int CheckOutDate int
@ -13,5 +15,30 @@ type Load struct {
} }
func ComputeLoad(guests []Guest) []Load { func ComputeLoad(guests []Guest) []Load {
return []Load{} if len(guests) == 0 {
return []Load{}
}
minDate, maxDate := math.MaxInt, math.MinInt
loadsNoEmptyDays := make(map[int]int)
for _, guest := range guests {
if guest.CheckInDate < minDate {
minDate = guest.CheckInDate
}
if guest.CheckOutDate > maxDate {
maxDate = guest.CheckOutDate
}
for i := guest.CheckInDate; i < guest.CheckOutDate; i++ {
loadsNoEmptyDays[i]++
}
}
loads, prevGuestCount := make([]Load, 0), 0
for i := minDate; i <= maxDate; i++ {
guestCount := loadsNoEmptyDays[i]
if prevGuestCount == guestCount {
continue
}
loads = append(loads, Load{i, guestCount})
prevGuestCount = guestCount
}
return loads
} }

View file

@ -5,8 +5,8 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"gitlab.com/manytask/itmo-go/private/illegal" "gitlab.com/slon/shad-go/illegal"
"gitlab.com/manytask/itmo-go/private/illegal/internal" "gitlab.com/slon/shad-go/illegal/internal"
) )
func TestIllegalField(t *testing.T) { func TestIllegalField(t *testing.T) {

View file

@ -6,7 +6,7 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"gitlab.com/manytask/itmo-go/private/illegal" "gitlab.com/slon/shad-go/illegal"
) )
func TestStringFromBytes(t *testing.T) { func TestStringFromBytes(t *testing.T) {

View file

@ -4,7 +4,7 @@ import (
"fmt" "fmt"
"log" "log"
"gitlab.com/manytask/itmo-go/private/iprange" "gitlab.com/slon/shad-go/iprange"
) )
func ExampleParseList() { func ExampleParseList() {

View file

@ -4,7 +4,7 @@
В обычном `sync.Mutex` лок всего один. В один момент времени этот лок может находиться В обычном `sync.Mutex` лок всего один. В один момент времени этот лок может находиться
у одной горутины. В нашем примитиве локов может быть сколько угодно. Каждый лок мы идентифицируем у одной горутины. В нашем примитиве локов может быть сколько угодно. Каждый лок мы идентифицируем
ключём - строкой. Каждая горутина приходит к нам со списком ключей и хочет захватить сразу ключом - строкой. Каждая горутина приходит к нам со списком ключей и хочет захватить сразу
все локи из этого списка. (Наша аналогия с `sync.Mutex` вовсе не значит, что нужно использовать все локи из этого списка. (Наша аналогия с `sync.Mutex` вовсе не значит, что нужно использовать
`sync.Mutex` в реализации. Лучше использовать каналы, чтобы проще было реализовать отмену.) `sync.Mutex` в реализации. Лучше использовать каналы, чтобы проще было реализовать отмену.)

View file

@ -1,14 +1,19 @@
package keylock_test package keylock_test
import ( import (
"fmt"
"math/rand"
"slices"
"sync" "sync"
"testing" "testing"
"time" "time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"go.uber.org/goleak" "go.uber.org/goleak"
"gitlab.com/manytask/itmo-go/private/keylock" "gitlab.com/slon/shad-go/keylock"
"gitlab.com/slon/shad-go/tools/testtool"
) )
func timeout(d time.Duration) <-chan struct{} { func timeout(d time.Duration) <-chan struct{} {
@ -57,6 +62,21 @@ func TestKeyLock_Progress(t *testing.T) {
unlock1() unlock1()
} }
func TestKeyLock_NoBusyWait(t *testing.T) {
defer goleak.VerifyNone(t)
l := keylock.New()
_, unlock0 := l.LockKeys([]string{"a", "b"}, nil)
defer unlock0()
go func() {
_, unlock := l.LockKeys([]string{"b", "c"}, nil)
unlock()
}()
testtool.VerifyNoBusyGoroutines(t)
}
func TestKeyLock_DeadlockFree(t *testing.T) { func TestKeyLock_DeadlockFree(t *testing.T) {
const N = 10000 const N = 10000
@ -116,7 +136,7 @@ func TestKeyLock_SingleKeyStress(t *testing.T) {
go func() { go func() {
defer wg.Done() defer wg.Done()
for i := 0; i < N; i++ { for j := 0; j < N; j++ {
cancelled, unlock := l.LockKeys([]string{"a"}, timeout(time.Millisecond)) cancelled, unlock := l.LockKeys([]string{"a"}, timeout(time.Millisecond))
if !cancelled { if !cancelled {
unlock() unlock()
@ -127,3 +147,58 @@ func TestKeyLock_SingleKeyStress(t *testing.T) {
wg.Wait() wg.Wait()
} }
func TestKeyLock_MutualExclusionStress(t *testing.T) {
const (
N = 1000
G = 100
M = 15
K = 3
)
defer goleak.VerifyNone(t)
locked := map[string]bool{}
var mu sync.Mutex
l := keylock.New()
var wg sync.WaitGroup
wg.Add(G)
for i := 0; i < G; i++ {
go func() {
defer wg.Done()
for j := 0; j < N; j++ {
keys := []string{}
for k := 0; k < K; k++ {
keys = append(keys, fmt.Sprint(rand.Intn(N)))
}
slices.Sort(keys)
keys = slices.Compact(keys)
_, unlock := l.LockKeys(keys, nil)
mu.Lock()
for _, key := range keys {
assert.False(t, locked[key])
locked[key] = true
}
mu.Unlock()
time.Sleep(time.Millisecond)
mu.Lock()
for _, key := range keys {
locked[key] = false
}
mu.Unlock()
unlock()
}
}()
}
wg.Wait()
}

View file

@ -3,23 +3,9 @@ package keylock
import ( import (
"math/rand" "math/rand"
"strconv" "strconv"
"sync"
"testing" "testing"
) )
func BenchmarkMutex_Baseline(b *testing.B) {
var mu sync.Mutex
b.ReportAllocs()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
mu.Lock()
_ = 0
mu.Unlock()
}
})
}
func BenchmarkKeyLock_SingleKey(b *testing.B) { func BenchmarkKeyLock_SingleKey(b *testing.B) {
l := New() l := New()

View file

@ -3,7 +3,6 @@ package main
import ( import (
"fmt" "fmt"
"io" "io"
"io/ioutil"
"net/http" "net/http"
"os" "os"
"time" "time"
@ -30,7 +29,7 @@ func fetch(url string, ch chan<- string) {
} }
defer resp.Body.Close() // don't leak resources defer resp.Body.Close() // don't leak resources
nbytes, err := io.Copy(ioutil.Discard, resp.Body) nbytes, err := io.Copy(io.Discard, resp.Body)
if err != nil { if err != nil {
ch <- fmt.Sprintf("while reading %s: %v", url, err) ch <- fmt.Sprintf("while reading %s: %v", url, err)
return return

View file

@ -11,8 +11,7 @@
* Ссылки * Ссылки
.link https://wiki.yandex.ru/shad/groups/2018/Semester4/GoLang/ Вики страница .link https://github.com/slon/shad-go Репозиторий
.link https://gitlab.com/manytask/itmo-go/private Репозиторий
.link https://t.me/joinchat/BjrYSxdPJGtJdd1pae08Zg Чат курса в телеграме .link https://t.me/joinchat/BjrYSxdPJGtJdd1pae08Zg Чат курса в телеграме
[[https://p.go.manytask.org]] - эти слайды. [[https://p.go.manytask.org]] - эти слайды.
@ -21,7 +20,7 @@
- 12+ занятий - 12+ занятий
- Семинарские задания после каждой лекции. *Дедлайн*10*дней.* - Семинарские задания после каждой лекции. *Дедлайн*10*дней.*
- 4 _больших_ домашних задания. *Дедлайн*3*недели.* - 4 _больших_ домашних задания. *Дедлайн*3*недели.*
- Критерий оценки: *TODO*. - Критерий оценки: *В*LMS* (>N домашек и >X% за семинары).
* Hello world * Hello world
@ -37,12 +36,25 @@ Systems
Language Language
* История
- 2009 go public announcement
- 2012 go 1.0
- 2008 github launch
- 2011 C++11
- 2011 pip initial release
- 2010 npm first release
- 2009 nodejs first release
- 2008 python3
- 2006 rust project started
- 2015 rust 1.0
* Современный мир * Современный мир
- Море библиотек. Большие деревья зависимостей. - Море библиотек. Большие деревья зависимостей.
: Нам нужен язык, который будет помогать контролировать сложность at large. : Нам нужен язык, который будет помогать контролировать сложность at large.
- Архитектура построена вокруг сервисов, которые общаются по сети. - Архитектура построена вокруг сервисов, которые общаются по сети.
: Скорее вам придётся писать stateless сервис. Statefull сервисы общаются с базой данных по сети. : Скорее вам придётся писать stateless сервис. Stateful сервисы общаются с базой данных по сети.
- Многоядерные процессоры даже в телефонах. - Многоядерные процессоры даже в телефонах.
* Скорость разработки * Скорость разработки
@ -149,6 +161,8 @@ Language
var s = "" var s = ""
var s string = "" var s string = ""
.link https://go.dev/blog/declaration-syntax Почему тип пишется после названия переменной
* uniq * uniq
.play -edit uniq/uniq.go .play -edit uniq/uniq.go
@ -230,7 +244,7 @@ Pointers
var s string var s string
p := &s p := &s
s2 = *p s2 := *p
var p Point var p Point
p.X = 1 p.X = 1

Some files were not shown because too many files have changed in this diff Show more