diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index 8d280089..e18c0d46 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -36,7 +36,7 @@ jobs: go test -mod=vendor -timeout=60s -covermode=count -coverprofile=$GITHUB_WORKSPACE/profile.cov_tmp ./... cat $GITHUB_WORKSPACE/profile.cov_tmp | grep -v "_mock.go" > $GITHUB_WORKSPACE/profile.cov cd ../_example/memory_store - go test ./... + go test -race ./... - name: install golangci-lint and goveralls run: | @@ -50,6 +50,11 @@ jobs: --enable=megacheck --enable=structcheck --enable=gas --enable=gocyclo --enable=dupl --enable=misspell \ --enable=unparam --enable=varcheck --enable=deadcode --enable=typecheck \ --enable=ineffassign --enable=varcheck ./... ; + cd _example/memory_store + $GITHUB_WORKSPACE/golangci-lint run --out-format=tab --disable-all --tests=false --enable=unconvert \ + --enable=megacheck --enable=structcheck --enable=gas --enable=gocyclo --enable=dupl --enable=misspell \ + --enable=unparam --enable=varcheck --enable=deadcode --enable=typecheck \ + --enable=ineffassign --enable=varcheck ./... ; - name: submit coverage run: | diff --git a/Makefile b/Makefile index fa3b1872..45ffdb8e 100644 --- a/Makefile +++ b/Makefile @@ -23,4 +23,7 @@ deploy: docker cp remark42.bin:/artifacts/remark42.windows-amd64.zip bin/remark42.windows-amd64.zip docker rm -f remark42.bin +race_test: + cd backend/app && go test -race -mod=vendor -timeout=60s -count 1 ./... + .PHONY: bin \ No newline at end of file diff --git a/README.md b/README.md index 3fd2d55e..62ff67c5 100644 --- a/README.md +++ b/README.md @@ -776,17 +776,17 @@ _returned id should be appended to load image url on caller side_ Until time.Time `json:"time"` } ``` -* `GET /api/v1/admin/export?site=side-id&mode=[stream|file]` - export all comments to json stream or gz file. -* `POST /api/v1/admin/import?site=side-id` - import comments from the backup, uses post body. -* `POST /api/v1/admin/import/form?site=side-id` - import comments from the backup, user post form. -* `POST /api/v1/admin/remap?site=side-id` - remap comments to different URLs. Expect list of "from-url new-url" pairs separated by \n. +* `GET /api/v1/admin/export?site=site-id&mode=[stream|file]` - export all comments to json stream or gz file. +* `POST /api/v1/admin/import?site=site-id` - import comments from the backup, uses post body. +* `POST /api/v1/admin/import/form?site=site-id` - import comments from the backup, user post form. +* `POST /api/v1/admin/remap?site=site-id` - remap comments to different URLs. Expect list of "from-url new-url" pairs separated by \n. From-url and new-url parts separated by space. If urls end with asterisk (*) it means matching by prefix. Remap procedure based on export/import chain so make backup first. ``` http://oldsite.com* https://newsite.com* http://oldsite.com/from-old-page/1 https://newsite.com/to-new-page/1 ``` -* `GET /api/v1/admin/wait?site=side-id` - wait for completion for any async migration ops (import or remap). +* `GET /api/v1/admin/wait?site=site-id` - wait for completion for any async migration ops (import or remap). * `PUT /api/v1/admin/pin/{id}?site=site-id&url=post-url&pin=1` - pin or unpin comment. * `GET /api/v1/admin/user/{userid}?site=site-id` - get user's info. * `DELETE /api/v1/admin/user/{userid}?site=site-id` - delete all user's comments. diff --git a/backend/_example/memory_store/accessor/data.go b/backend/_example/memory_store/accessor/data.go index 024520d0..7c045c1e 100644 --- a/backend/_example/memory_store/accessor/data.go +++ b/backend/_example/memory_store/accessor/data.go @@ -406,8 +406,7 @@ func (m *MemData) setFlag(req engine.FlagRequest) (res bool, err error) { until = time.Now().Add(req.TTL) } } - meta := m.metaUsers[req.UserID] - meta = metaUser{ + meta := metaUser{ UserID: req.UserID, SiteID: req.Locator.SiteID, Blocked: status, @@ -416,8 +415,7 @@ func (m *MemData) setFlag(req engine.FlagRequest) (res bool, err error) { m.metaUsers[req.UserID] = meta case engine.Verified: - meta := m.metaUsers[req.UserID] - meta = metaUser{ + meta := metaUser{ UserID: req.UserID, SiteID: req.Locator.SiteID, Verified: status, diff --git a/backend/app/main_test.go b/backend/app/main_test.go index aaa7cce0..259e2b3e 100644 --- a/backend/app/main_test.go +++ b/backend/app/main_test.go @@ -38,7 +38,7 @@ func Test_Main(t *testing.T) { go func() { st := time.Now() main() - assert.True(t, time.Since(st).Seconds() >= 4, "should take about 5s", time.Since(st)) + assert.True(t, time.Since(st).Seconds() >= 4, "should take about 5s, took %s", time.Since(st)) wg.Done() }() diff --git a/backend/app/notify/telegram.go b/backend/app/notify/telegram.go index 4d253711..0151012b 100644 --- a/backend/app/notify/telegram.go +++ b/backend/app/notify/telegram.go @@ -40,7 +40,7 @@ func NewTelegram(token string, channelID string, timeout time.Duration, api stri if res.timeout == 0 { res.timeout = telegramTimeOut } - log.Printf("[DEBUG] create new telegram notifier for cham %s, timeout=%s, api=%s", channelID, res.timeout, res.timeout) + log.Printf("[DEBUG] create new telegram notifier for chan %s, timeout=%s, api=%s", channelID, res.timeout, res.timeout) ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() diff --git a/backend/app/rest/api/rest_test.go b/backend/app/rest/api/rest_test.go index 812402f3..99d531e8 100644 --- a/backend/app/rest/api/rest_test.go +++ b/backend/app/rest/api/rest_test.go @@ -73,15 +73,20 @@ func TestRest_GetStarted(t *testing.T) { func TestRest_Shutdown(t *testing.T) { srv := Rest{Authenticator: &auth.Service{}, ImageProxy: &proxy.Image{}} + finished := make(chan bool) + // without waiting for channel close at the end goroutine will stay alive after test finish + // which would create data race with next test go func() { time.Sleep(200 * time.Millisecond) srv.Shutdown() + close(finished) }() st := time.Now() srv.Run(0) assert.True(t, time.Since(st).Seconds() < 1, "should take about 100ms") + <-finished } func TestRest_filterComments(t *testing.T) { @@ -362,7 +367,7 @@ func startupT(t *testing.T) (ts *httptest.Server, srv *Rest, teardown func()) { return ts, srv, teardown } -// fake auth middleware make user authed and uses query's fake_id for ID and fake_name for Name +// fake auth middleware make user authenticated and uses query's fake_id for ID and fake_name for Name func fakeAuth(next http.Handler) http.Handler { fn := func(w http.ResponseWriter, r *http.Request) { if r.URL.Query().Get("fake_id") != "" {