diff --git a/backend/go.mod b/backend/go.mod index 2aeaa9ed..11df5b36 100644 --- a/backend/go.mod +++ b/backend/go.mod @@ -21,6 +21,7 @@ require ( github.com/rotisserie/eris v0.5.4 github.com/stretchr/testify v1.8.4 github.com/vrischmann/envconfig v1.3.0 + go.uber.org/goleak v1.3.0 golang.org/x/crypto v0.11.0 gorm.io/datatypes v1.2.0 gorm.io/driver/mysql v1.5.1 diff --git a/backend/go.sum b/backend/go.sum index e7df71cb..e4180b17 100644 --- a/backend/go.sum +++ b/backend/go.sum @@ -145,6 +145,8 @@ github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5t github.com/zenizh/go-capturer v0.0.0-20211219060012-52ea6c8fed04 h1:qXafrlZL1WsJW5OokjraLLRURHiw0OzKHD/RNdspp4w= gitlab.com/jc21com/sqlite v1.22.2-0.20230527022643-b56cedb3bc85 h1:NPHauobrOymc80Euu+e0tsMyXcdtLCX5bQPKX5zsI38= gitlab.com/jc21com/sqlite v1.22.2-0.20230527022643-b56cedb3bc85/go.mod h1:OrDj17Mggn6MhE+iPbBNf7RGKODDE9NFT0f3EwDzJqk= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= diff --git a/backend/internal/acme/acmesh_test.go b/backend/internal/acme/acmesh_test.go index 57a0ba18..26732705 100644 --- a/backend/internal/acme/acmesh_test.go +++ b/backend/internal/acme/acmesh_test.go @@ -9,12 +9,16 @@ import ( "npm/internal/entity/dnsprovider" "github.com/stretchr/testify/assert" + "go.uber.org/goleak" ) // TODO configurable const acmeLogFile = "/data/logs/acme.sh.log" func TestBuildCertRequestArgs(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + type want struct { args []string err error @@ -195,6 +199,9 @@ func TestBuildCertRequestArgs(t *testing.T) { } func TestGetAcmeShFilePath(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + t.Run("basic test", func(t *testing.T) { path, err := getAcmeShFilePath() if err != nil { @@ -207,6 +214,9 @@ func TestGetAcmeShFilePath(t *testing.T) { } func TestGetCommonEnvVars(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + t.Run("basic test", func(t *testing.T) { t.Setenv("ACMESH_CONFIG_HOME", "/data/.acme.sh/config") t.Setenv("ACMESH_HOME", "/data/.acme.sh") @@ -227,6 +237,9 @@ func TestGetCommonEnvVars(t *testing.T) { } func TestGetAcmeShVersion(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + t.Run("basic test", func(t *testing.T) { resp := GetAcmeShVersion() // Seems like a pointless test, however when this is run in CI diff --git a/backend/internal/api/context/context_test.go b/backend/internal/api/context/context_test.go index 0c5365de..9eee4c66 100644 --- a/backend/internal/api/context/context_test.go +++ b/backend/internal/api/context/context_test.go @@ -4,9 +4,13 @@ import ( "testing" "github.com/stretchr/testify/assert" + "go.uber.org/goleak" ) func TestGetString(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + t.Run("basic test", func(t *testing.T) { assert.Equal(t, "context value: Body", BodyCtxKey.String()) }) diff --git a/backend/internal/api/http/responses_test.go b/backend/internal/api/http/responses_test.go index 1bc56f87..71dde997 100644 --- a/backend/internal/api/http/responses_test.go +++ b/backend/internal/api/http/responses_test.go @@ -10,9 +10,13 @@ import ( "github.com/qri-io/jsonschema" "github.com/stretchr/testify/assert" + "go.uber.org/goleak" ) func TestResultResponseJSON(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + tests := []struct { name string status int @@ -67,6 +71,9 @@ func TestResultResponseJSON(t *testing.T) { } func TestResultSchemaErrorJSON(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + tests := []struct { name string given []jsonschema.KeyError @@ -104,6 +111,9 @@ func TestResultSchemaErrorJSON(t *testing.T) { } func TestResultErrorJSON(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + tests := []struct { name string status int @@ -146,6 +156,9 @@ func TestResultErrorJSON(t *testing.T) { } func TestNotFound(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + t.Run("basic test", func(t *testing.T) { r := httptest.NewRequest(http.MethodGet, "/anything", nil) w := httptest.NewRecorder() @@ -163,6 +176,9 @@ func TestNotFound(t *testing.T) { } func TestResultResponseText(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + t.Run("basic test", func(t *testing.T) { r := httptest.NewRequest(http.MethodGet, "/anything", nil) w := httptest.NewRecorder() diff --git a/backend/internal/api/middleware/access_control_test.go b/backend/internal/api/middleware/access_control_test.go index 001736c0..3a84f8e2 100644 --- a/backend/internal/api/middleware/access_control_test.go +++ b/backend/internal/api/middleware/access_control_test.go @@ -8,9 +8,13 @@ import ( "npm/internal/api/middleware" "github.com/stretchr/testify/assert" + "go.uber.org/goleak" ) func TestAccessControl(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) }) diff --git a/backend/internal/api/middleware/body_context_test.go b/backend/internal/api/middleware/body_context_test.go index 97ae734b..da0ad70e 100644 --- a/backend/internal/api/middleware/body_context_test.go +++ b/backend/internal/api/middleware/body_context_test.go @@ -10,9 +10,13 @@ import ( "npm/internal/api/middleware" "github.com/stretchr/testify/assert" + "go.uber.org/goleak" ) func TestBodyContext(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + // Create a test request with a body body := []byte(`{"name": "John", "age": 30}`) req, err := http.NewRequest("POST", "/test", bytes.NewBuffer(body)) diff --git a/backend/internal/api/middleware/enforce_setup_test.go b/backend/internal/api/middleware/enforce_setup_test.go index ce542bd9..434edc06 100644 --- a/backend/internal/api/middleware/enforce_setup_test.go +++ b/backend/internal/api/middleware/enforce_setup_test.go @@ -6,12 +6,16 @@ import ( "testing" "github.com/stretchr/testify/assert" + "go.uber.org/goleak" "npm/internal/api/middleware" "npm/internal/config" ) func TestEnforceSetup(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + tests := []struct { name string shouldBeSetup bool diff --git a/backend/internal/api/middleware/expansion_test.go b/backend/internal/api/middleware/expansion_test.go index da38d378..4d4b324c 100644 --- a/backend/internal/api/middleware/expansion_test.go +++ b/backend/internal/api/middleware/expansion_test.go @@ -10,9 +10,13 @@ import ( "npm/internal/api/middleware" "github.com/stretchr/testify/assert" + "go.uber.org/goleak" ) func TestExpansion(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + t.Run("with expand query param", func(t *testing.T) { req, err := http.NewRequest("GET", "/path?expand=item1,item2", nil) assert.NoError(t, err) @@ -47,6 +51,9 @@ func TestExpansion(t *testing.T) { } func TestGetExpandFromContext(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + t.Run("with context value", func(t *testing.T) { req, err := http.NewRequest("GET", "/path", nil) assert.NoError(t, err) diff --git a/backend/internal/api/middleware/list_query_test.go b/backend/internal/api/middleware/list_query_test.go index 53973fad..d05c4483 100644 --- a/backend/internal/api/middleware/list_query_test.go +++ b/backend/internal/api/middleware/list_query_test.go @@ -13,9 +13,13 @@ import ( "npm/internal/tags" "github.com/stretchr/testify/assert" + "go.uber.org/goleak" ) func TestListQuery(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + tests := []struct { name string queryParams string @@ -61,6 +65,9 @@ func TestListQuery(t *testing.T) { } func TestGetFiltersFromContext(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + req, err := http.NewRequest("GET", "/test", nil) assert.NoError(t, err) @@ -75,6 +82,9 @@ func TestGetFiltersFromContext(t *testing.T) { } func TestGetSortFromContext(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + req, err := http.NewRequest("GET", "/test", nil) assert.NoError(t, err) diff --git a/backend/internal/api/router_test.go b/backend/internal/api/router_test.go index 0fb1cf94..22ac857f 100644 --- a/backend/internal/api/router_test.go +++ b/backend/internal/api/router_test.go @@ -9,6 +9,7 @@ import ( "npm/internal/config" "github.com/stretchr/testify/assert" + "go.uber.org/goleak" ) var ( @@ -25,6 +26,12 @@ func TestMain(m *testing.M) { } func TestGetHealthz(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, + goleak.IgnoreAnyFunction("github.com/patrickmn/go-cache.(*janitor).Run"), + goleak.IgnoreAnyFunction("github.com/jc21/go-sse.(*Server).dispatch"), + ) + respRec := httptest.NewRecorder() req, _ := http.NewRequest("GET", "/api/", nil) @@ -34,6 +41,12 @@ func TestGetHealthz(t *testing.T) { } func TestNonExistent(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, + goleak.IgnoreAnyFunction("github.com/patrickmn/go-cache.(*janitor).Run"), + goleak.IgnoreAnyFunction("github.com/jc21/go-sse.(*Server).dispatch"), + ) + respRec := httptest.NewRecorder() req, _ := http.NewRequest("GET", "/non-existent-endpoint.jpg", nil) diff --git a/backend/internal/config/config_test.go b/backend/internal/config/config_test.go index abe409fb..542d2281 100644 --- a/backend/internal/config/config_test.go +++ b/backend/internal/config/config_test.go @@ -8,9 +8,13 @@ import ( "npm/internal/logger" "github.com/stretchr/testify/assert" + "go.uber.org/goleak" ) func TestInit(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + t.Setenv("NPM_DATA_FOLDER", "/path/to/some/data/folder") t.Setenv("NPM_LOG_LEVEL", "warn") t.Setenv("NPM_DB_DRIVER", "postgres") @@ -45,6 +49,9 @@ func TestInit(t *testing.T) { } func TestConnectURLs(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + type want struct { gorm string dbmate string @@ -118,6 +125,9 @@ func TestConnectURLs(t *testing.T) { } func TestCreateDataFolders(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + t.Setenv("NPM_DATA_FOLDER", "/tmp/npmtest") version := "777.777.777" diff --git a/backend/internal/config/folders.go b/backend/internal/config/folders.go index 7a89e92e..bafe6832 100644 --- a/backend/internal/config/folders.go +++ b/backend/internal/config/folders.go @@ -2,8 +2,9 @@ package config import ( "fmt" - "npm/internal/logger" "os" + + "npm/internal/logger" ) // CreateDataFolders will recursively create these folders within the diff --git a/backend/internal/config/vars_test.go b/backend/internal/config/vars_test.go index 08b79101..be3ae00d 100644 --- a/backend/internal/config/vars_test.go +++ b/backend/internal/config/vars_test.go @@ -4,9 +4,13 @@ import ( "testing" "github.com/stretchr/testify/assert" + "go.uber.org/goleak" ) func TestAcmeshGetWellknown(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + a := acmesh{ Home: "/data/.acme.sh", } diff --git a/backend/internal/dnsproviders/common_test.go b/backend/internal/dnsproviders/common_test.go index f97182c1..80bde44f 100644 --- a/backend/internal/dnsproviders/common_test.go +++ b/backend/internal/dnsproviders/common_test.go @@ -4,9 +4,13 @@ import ( "testing" "github.com/stretchr/testify/assert" + "go.uber.org/goleak" ) func TestGetAll(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + providers := GetAll() // This number will have to (annoyingly) be updated // when adding new dns providers to the list @@ -23,6 +27,9 @@ func TestGetAll(t *testing.T) { } func TestGet(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + provider, err := Get("dns_duckdns") assert.Nil(t, err) assert.Equal(t, "dns_duckdns", provider.Title) diff --git a/backend/internal/dnsproviders/dns_acmedns_test.go b/backend/internal/dnsproviders/dns_acmedns_test.go index cdd5683d..8e60c05a 100644 --- a/backend/internal/dnsproviders/dns_acmedns_test.go +++ b/backend/internal/dnsproviders/dns_acmedns_test.go @@ -5,9 +5,13 @@ import ( "testing" "github.com/stretchr/testify/assert" + "go.uber.org/goleak" ) func TestAcmeDNSProvider(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + provider := getDNSAcmeDNS() json, err := provider.GetJsonSchema() assert.Nil(t, err) diff --git a/backend/internal/dnsproviders/dns_ad_test.go b/backend/internal/dnsproviders/dns_ad_test.go index cb648360..4034a4ca 100644 --- a/backend/internal/dnsproviders/dns_ad_test.go +++ b/backend/internal/dnsproviders/dns_ad_test.go @@ -5,9 +5,13 @@ import ( "testing" "github.com/stretchr/testify/assert" + "go.uber.org/goleak" ) func TestAdProvider(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + provider := getDNSAd() provider.ConvertToUpdatable() json, err := provider.GetJsonSchema() diff --git a/backend/internal/dnsproviders/dns_ali_test.go b/backend/internal/dnsproviders/dns_ali_test.go index 6a4ebe33..e09a2616 100644 --- a/backend/internal/dnsproviders/dns_ali_test.go +++ b/backend/internal/dnsproviders/dns_ali_test.go @@ -5,9 +5,13 @@ import ( "testing" "github.com/stretchr/testify/assert" + "go.uber.org/goleak" ) func TestAliProvider(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + provider := getDNSAli() json, err := provider.GetJsonSchema() assert.Nil(t, err) diff --git a/backend/internal/entity/auth/entity_test.go b/backend/internal/entity/auth/entity_test.go index 27d1ff47..0a672365 100644 --- a/backend/internal/entity/auth/entity_test.go +++ b/backend/internal/entity/auth/entity_test.go @@ -10,6 +10,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" + "go.uber.org/goleak" ) // +------------+ @@ -62,6 +63,9 @@ func assertModel(t *testing.T, m Model) { // +------------+ func (s *testsuite) TestGetByID() { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(s.T(), goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + s.mock. ExpectQuery(regexp.QuoteMeta(`SELECT * FROM "auth" WHERE "auth"."id" = $1 AND "auth"."is_deleted" = $2 ORDER BY "auth"."id" LIMIT 1`)). WithArgs(10, 0). @@ -74,6 +78,9 @@ func (s *testsuite) TestGetByID() { } func (s *testsuite) TestGetByUserIDType() { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(s.T(), goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + s.mock. ExpectQuery(regexp.QuoteMeta(`SELECT * FROM "auth" WHERE user_id = $1 AND type = $2 AND "auth"."is_deleted" = $3 ORDER BY "auth"."id" LIMIT 1`)). WithArgs(100, TypePassword, 0). @@ -86,6 +93,9 @@ func (s *testsuite) TestGetByUserIDType() { } func (s *testsuite) TestSave() { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(s.T(), goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + s.mock.ExpectBegin() s.mock.ExpectQuery(regexp.QuoteMeta(`INSERT INTO "auth" ("created_at","updated_at","is_deleted","user_id","type","secret") VALUES ($1,$2,$3,$4,$5,$6) RETURNING "id"`)). WithArgs( @@ -111,6 +121,9 @@ func (s *testsuite) TestSave() { } func (s *testsuite) TestSetPassword() { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(s.T(), goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + m := Model{UserID: 100} err := m.SetPassword("abc123") require.NoError(s.T(), err) @@ -120,6 +133,9 @@ func (s *testsuite) TestSetPassword() { } func (s *testsuite) TestValidateSecret() { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(s.T(), goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + m := Model{UserID: 100} m.SetPassword("abc123") diff --git a/backend/internal/entity/certificateauthority/entity_test.go b/backend/internal/entity/certificateauthority/entity_test.go index fe2a7577..83616b86 100644 --- a/backend/internal/entity/certificateauthority/entity_test.go +++ b/backend/internal/entity/certificateauthority/entity_test.go @@ -12,6 +12,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" + "go.uber.org/goleak" ) // +------------+ @@ -102,6 +103,9 @@ func assertModel(t *testing.T, m Model) { // +------------+ func (s *testsuite) TestGetByID() { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(s.T(), goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + s.mock. ExpectQuery(regexp.QuoteMeta(`SELECT * FROM "certificate_authority" WHERE "certificate_authority"."id" = $1 AND "certificate_authority"."is_deleted" = $2 ORDER BY "certificate_authority"."id" LIMIT 1`)). WithArgs(10, 0). @@ -114,6 +118,9 @@ func (s *testsuite) TestGetByID() { } func (s *testsuite) TestList() { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(s.T(), goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + s.mock. ExpectQuery(regexp.QuoteMeta(`SELECT count(*) FROM "certificate_authority" WHERE name LIKE $1 AND "certificate_authority"."is_deleted" = $2`)). WithArgs("%test%", 0). @@ -156,6 +163,9 @@ func (s *testsuite) TestList() { } func (s *testsuite) TestSave() { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(s.T(), goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + s.mock.ExpectBegin() s.mock.ExpectQuery(regexp.QuoteMeta(`INSERT INTO "certificate_authority" ("created_at","updated_at","is_deleted","name","acmesh_server","ca_bundle","max_domains","is_wildcard_supported","is_readonly") VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9) RETURNING "id"`)). WithArgs( @@ -185,6 +195,9 @@ func (s *testsuite) TestSave() { } func (s *testsuite) TestDelete() { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(s.T(), goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + s.mock.ExpectBegin() s.mock. ExpectExec(regexp.QuoteMeta(`UPDATE "certificate_authority" SET "is_deleted"=$1 WHERE "certificate_authority"."id" = $2 AND "certificate_authority"."is_deleted" = $3`)). @@ -207,6 +220,9 @@ func (s *testsuite) TestDelete() { } func (s *testsuite) TestCheck() { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(s.T(), goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + m := Model{} err := m.Check() assert.Nil(s.T(), err) diff --git a/backend/internal/entity/dnsprovider/entity_test.go b/backend/internal/entity/dnsprovider/entity_test.go index ae16b8b7..e9ecbc4c 100644 --- a/backend/internal/entity/dnsprovider/entity_test.go +++ b/backend/internal/entity/dnsprovider/entity_test.go @@ -13,6 +13,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" + "go.uber.org/goleak" ) // +------------+ @@ -108,6 +109,9 @@ func assertModel(t *testing.T, m Model) { // +------------+ func (s *testsuite) TestGetByID() { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(s.T(), goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + s.mock. ExpectQuery(regexp.QuoteMeta(`SELECT * FROM "dns_provider" WHERE "dns_provider"."id" = $1 AND "dns_provider"."is_deleted" = $2 ORDER BY "dns_provider"."id" LIMIT 1`)). WithArgs(10, 0). @@ -120,6 +124,9 @@ func (s *testsuite) TestGetByID() { } func (s *testsuite) TestGetAcmeShEnvVars() { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(s.T(), goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + type want struct { envs []string err error @@ -193,6 +200,9 @@ func (s *testsuite) TestGetAcmeShEnvVars() { } func (s *testsuite) TestList() { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(s.T(), goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + s.mock. ExpectQuery(regexp.QuoteMeta(`SELECT count(*) FROM "dns_provider" WHERE acmesh_name LIKE $1 AND "dns_provider"."is_deleted" = $2`)). WithArgs("dns%", 0). @@ -235,6 +245,9 @@ func (s *testsuite) TestList() { } func (s *testsuite) TestSave() { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(s.T(), goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + s.mock.ExpectBegin() s.mock.ExpectQuery(regexp.QuoteMeta(`INSERT INTO "dns_provider" ("created_at","updated_at","is_deleted","user_id","name","acmesh_name","dns_sleep","meta") VALUES ($1,$2,$3,$4,$5,$6,$7,$8) RETURNING "id"`)). WithArgs( @@ -268,6 +281,9 @@ func (s *testsuite) TestSave() { } func (s *testsuite) TestDelete() { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(s.T(), goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + s.mock.ExpectBegin() s.mock. ExpectExec(regexp.QuoteMeta(`UPDATE "dns_provider" SET "is_deleted"=$1 WHERE "dns_provider"."id" = $2 AND "dns_provider"."is_deleted" = $3`)). diff --git a/backend/internal/entity/host/entity_test.go b/backend/internal/entity/host/entity_test.go index 569c3084..efdcef17 100644 --- a/backend/internal/entity/host/entity_test.go +++ b/backend/internal/entity/host/entity_test.go @@ -14,6 +14,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" + "go.uber.org/goleak" ) // +------------+ @@ -105,6 +106,9 @@ func TestExampleTestSuite(t *testing.T) { // +------------+ func (s *testsuite) TestGetByID() { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(s.T(), goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + s.mock. ExpectQuery(regexp.QuoteMeta(`SELECT * FROM "host" WHERE "host"."id" = $1 AND "host"."is_deleted" = $2 ORDER BY "host"."id" LIMIT 1`)). WithArgs(10, 0). @@ -117,6 +121,9 @@ func (s *testsuite) TestGetByID() { } func (s *testsuite) TestSave() { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(s.T(), goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + s.mock.ExpectBegin() s.mock.ExpectQuery(regexp.QuoteMeta(`INSERT INTO "host" ("created_at","updated_at","is_deleted","user_id","type","nginx_template_id","listen_interface","domain_names","upstream_id","proxy_scheme","proxy_host","proxy_port","certificate_id","access_list_id","ssl_forced","caching_enabled","block_exploits","allow_websocket_upgrade","http2_support","hsts_enabled","hsts_subdomains","paths","advanced_config","status","error_message","is_disabled") VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21,$22,$23,$24,$25,$26) RETURNING "id"`)). WithArgs( @@ -167,6 +174,9 @@ func (s *testsuite) TestSave() { } func (s *testsuite) TestDelete() { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(s.T(), goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + s.mock.ExpectBegin() s.mock. ExpectExec(regexp.QuoteMeta(`UPDATE "host" SET "is_deleted"=$1 WHERE "host"."id" = $2 AND "host"."is_deleted" = $3`)). @@ -189,6 +199,9 @@ func (s *testsuite) TestDelete() { } func (s *testsuite) TestGetTemplate() { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(s.T(), goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + m := Model{ ModelBase: model.ModelBase{ ID: 10, diff --git a/backend/internal/entity/user/entity_test.go b/backend/internal/entity/user/entity_test.go index 82dead77..32c3d9f6 100644 --- a/backend/internal/entity/user/entity_test.go +++ b/backend/internal/entity/user/entity_test.go @@ -13,6 +13,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" + "go.uber.org/goleak" ) // +------------+ @@ -114,6 +115,9 @@ func assertModel(t *testing.T, m Model) { // +------------+ func (s *testsuite) TestGetByID() { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(s.T(), goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + s.mock. ExpectQuery(regexp.QuoteMeta(`SELECT * FROM "user" WHERE "user"."id" = $1 AND "user"."is_deleted" = $2 ORDER BY "user"."id" LIMIT 1`)). WithArgs(10, 0). @@ -126,6 +130,9 @@ func (s *testsuite) TestGetByID() { } func (s *testsuite) TestLoadByEmail() { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(s.T(), goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + s.mock. ExpectQuery(regexp.QuoteMeta(`SELECT * FROM "user" WHERE email = $1 AND is_system = $2 AND "user"."is_deleted" = $3 ORDER BY "user"."id" LIMIT 1`)). WithArgs("jon@example.com", false, 0). @@ -138,6 +145,9 @@ func (s *testsuite) TestLoadByEmail() { } func (s *testsuite) TestIsEnabled() { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(s.T(), goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + s.mock. ExpectQuery(regexp.QuoteMeta(`SELECT * FROM "user" WHERE "user"."id" = $1 AND "user"."is_deleted" = $2 ORDER BY "user"."id" LIMIT 1`)). WithArgs(10, 0). @@ -163,6 +173,9 @@ func (s *testsuite) TestIsEnabled() { } func (s *testsuite) TestSave() { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(s.T(), goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + s.mock. ExpectQuery(regexp.QuoteMeta(`SELECT * FROM "user" WHERE email = $1 AND is_system = $2 AND "user"."is_deleted" = $3 ORDER BY "user"."id" LIMIT 1`)). WithArgs("jon@example.com", false, 0). @@ -206,6 +219,9 @@ func (s *testsuite) TestSave() { } func (s *testsuite) TestDelete() { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(s.T(), goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + s.mock.ExpectBegin() s.mock. ExpectExec(regexp.QuoteMeta(`UPDATE "user" SET "is_deleted"=$1 WHERE "user"."id" = $2 AND "user"."is_deleted" = $3`)). @@ -229,12 +245,18 @@ func (s *testsuite) TestDelete() { } func (s *testsuite) TestGenerateGravatar() { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(s.T(), goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + m := Model{Email: "jon@example.com"} m.generateGravatar() assert.Equal(s.T(), "https://www.gravatar.com/avatar/dc36565cc2376197358fa27ed4c47253?d=mm&r=pg&s=128", m.GravatarURL) } func (s *testsuite) TestDeleteAll() { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(s.T(), goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + s.mock. ExpectExec(regexp.QuoteMeta("DELETE FROM `user` WHERE is_system = $1")). WithArgs(false). @@ -246,6 +268,9 @@ func (s *testsuite) TestDeleteAll() { } func (s *testsuite) TestGetCapabilities() { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(s.T(), goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + s.mock. ExpectQuery(regexp.QuoteMeta(`SELECT * FROM "user_has_capability" WHERE user_id = $1`)). WithArgs(10). @@ -278,6 +303,9 @@ func (s *testsuite) TestGetCapabilities() { } func (s *testsuite) TestList() { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(s.T(), goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + s.mock. ExpectQuery(regexp.QuoteMeta(`SELECT count(*) FROM "user" WHERE name LIKE $1 AND "user"."is_deleted" = $2`)). WithArgs("%jon%", 0). @@ -332,6 +360,9 @@ func (s *testsuite) TestList() { } func (s *testsuite) TestSetPermissions() { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(s.T(), goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + s.mock.ExpectBegin() s.mock. ExpectExec(regexp.QuoteMeta(`DELETE FROM "user_has_capability" WHERE user_id = $1`)). @@ -360,6 +391,9 @@ func (s *testsuite) TestSetPermissions() { } func (s *testsuite) TestSaveCapabilities() { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(s.T(), goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + s.mock. ExpectQuery(regexp.QuoteMeta(`SELECT * FROM "capability"`)). WillReturnRows(sqlmock.NewRows([]string{"name"}). @@ -400,6 +434,9 @@ func (s *testsuite) TestSaveCapabilities() { } func (s *testsuite) TestSaveCapabilitiesInvalid() { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(s.T(), goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + s.mock. ExpectQuery(regexp.QuoteMeta(`SELECT * FROM "capability"`)). WillReturnRows(sqlmock.NewRows([]string{"name"}). diff --git a/backend/internal/jwt/suite_test.go b/backend/internal/jwt/suite_test.go index 7f6eb5a7..27ecdb60 100644 --- a/backend/internal/jwt/suite_test.go +++ b/backend/internal/jwt/suite_test.go @@ -13,6 +13,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" + "go.uber.org/goleak" ) // +------------+ @@ -123,6 +124,9 @@ func TestExampleTestSuite(t *testing.T) { // +------------+ func (s *testsuite) TestLoadKeys() { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(s.T(), goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + // Required for clean test runs currentKeys = KeysModel{} @@ -164,6 +168,9 @@ func (s *testsuite) TestLoadKeys() { } func (s *testsuite) TestGetPrivateKey() { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(s.T(), goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + // Required for clean test runs privateKey = nil currentKeys = KeysModel{} @@ -188,6 +195,9 @@ func (s *testsuite) TestGetPrivateKey() { } func (s *testsuite) TestGetPublicKey() { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(s.T(), goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + // Required for clean test runs publicKey = nil currentKeys = KeysModel{} @@ -212,6 +222,9 @@ func (s *testsuite) TestGetPublicKey() { } func (s *testsuite) TestGenerate() { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(s.T(), goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + currentKeys = KeysModel{ ModelBase: model.ModelBase{ ID: 10, diff --git a/backend/internal/logger/logger_test.go b/backend/internal/logger/logger_test.go index 7e88f87b..9fb76529 100644 --- a/backend/internal/logger/logger_test.go +++ b/backend/internal/logger/logger_test.go @@ -9,13 +9,20 @@ import ( "github.com/rotisserie/eris" "github.com/stretchr/testify/assert" + "go.uber.org/goleak" ) func TestGetLogLevel(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + assert.Equal(t, InfoLevel, GetLogLevel()) } func TestThreshold(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + buf := new(bytes.Buffer) log.SetOutput(buf) defer func() { @@ -37,6 +44,9 @@ func TestThreshold(t *testing.T) { } func TestDebug(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + buf := new(bytes.Buffer) log.SetOutput(buf) defer func() { @@ -55,6 +65,9 @@ func TestDebug(t *testing.T) { } func TestInfo(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + buf := new(bytes.Buffer) log.SetOutput(buf) defer func() { @@ -71,6 +84,9 @@ func TestInfo(t *testing.T) { } func TestWarn(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + buf := new(bytes.Buffer) log.SetOutput(buf) defer func() { @@ -87,6 +103,9 @@ func TestWarn(t *testing.T) { } func TestError(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + buf := new(bytes.Buffer) log.SetOutput(buf) defer func() { @@ -103,6 +122,9 @@ func TestError(t *testing.T) { } func TestConfigure(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + type args struct { c *Config } diff --git a/backend/internal/model/pageinfo_test.go b/backend/internal/model/pageinfo_test.go index 810a103d..5fb756e7 100644 --- a/backend/internal/model/pageinfo_test.go +++ b/backend/internal/model/pageinfo_test.go @@ -4,9 +4,13 @@ import ( "testing" "github.com/stretchr/testify/assert" + "go.uber.org/goleak" ) func TestPageInfoGetSort(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("testing.tRunner.func1")) + t.Parallel() pi := PageInfo{} def := Sort{ diff --git a/backend/internal/nginx/control_test.go b/backend/internal/nginx/control_test.go index 7c482aed..53072985 100644 --- a/backend/internal/nginx/control_test.go +++ b/backend/internal/nginx/control_test.go @@ -7,9 +7,13 @@ import ( "testing" "github.com/stretchr/testify/assert" + "go.uber.org/goleak" ) func TestGetHostFilename(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + test.InitConfig(t) tests := []struct { name string diff --git a/backend/internal/nginx/template_test.go b/backend/internal/nginx/template_test.go index 2abd8493..b85013fa 100644 --- a/backend/internal/nginx/template_test.go +++ b/backend/internal/nginx/template_test.go @@ -10,9 +10,13 @@ import ( "npm/internal/types" "github.com/stretchr/testify/assert" + "go.uber.org/goleak" ) func TestRenderTemplate(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + test.InitConfig(t) template := ` diff --git a/backend/internal/serverevents/sse_test.go b/backend/internal/serverevents/sse_test.go index e01c5375..f1353f88 100644 --- a/backend/internal/serverevents/sse_test.go +++ b/backend/internal/serverevents/sse_test.go @@ -4,15 +4,22 @@ import ( "testing" "github.com/stretchr/testify/assert" + "go.uber.org/goleak" ) func TestGet(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("github.com/jc21/go-sse.(*Server).dispatch")) + s := Get() assert.NotEqual(t, nil, s) } // This is just for code coverage more than anything func TestEverything(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t) + Get() SendMessage("test", "test", map[string]string{"user_id": "10"}) SendChange("hosts") diff --git a/backend/internal/tags/filters_test.go b/backend/internal/tags/filters_test.go index c22cfdcd..88b8c841 100644 --- a/backend/internal/tags/filters_test.go +++ b/backend/internal/tags/filters_test.go @@ -1,14 +1,19 @@ package tags import ( - "npm/internal/util" "testing" "time" + "npm/internal/util" + "github.com/stretchr/testify/assert" + "go.uber.org/goleak" ) func TestGetFilterSchema(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + type testDemo struct { ID uint `json:"id" gorm:"column:user_id" filter:"id,number"` Created time.Time `json:"created" gorm:"column:user_created_date" filter:"created,date"` @@ -28,6 +33,9 @@ func TestGetFilterSchema(t *testing.T) { } func TestGetFilterTagSchema(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + schema := util.PrettyPrintJSON(getFilterTagSchema("id,integer")) expectedSchema := `{ @@ -63,6 +71,9 @@ func TestGetFilterTagSchema(t *testing.T) { } func TestBoolFieldSchema(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + schema := util.PrettyPrintJSON(boolFieldSchema("active")) expectedSchema := `{ diff --git a/backend/internal/tags/reflect_test.go b/backend/internal/tags/reflect_test.go index b31e5790..e29c5985 100644 --- a/backend/internal/tags/reflect_test.go +++ b/backend/internal/tags/reflect_test.go @@ -1,13 +1,18 @@ package tags import ( - "npm/internal/model" "testing" + "npm/internal/model" + "github.com/stretchr/testify/assert" + "go.uber.org/goleak" ) func TestGetName(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + type testDemo struct { UserID uint `json:"user_id" gorm:"column:user_id" filter:"user_id,integer"` Type string `json:"type" gorm:"column:type" filter:"type,string"` @@ -18,6 +23,9 @@ func TestGetName(t *testing.T) { } func TestCache(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + name := "testdemo" // Should return error _, exists := getCache(name) diff --git a/backend/internal/types/db_date_test.go b/backend/internal/types/db_date_test.go index c9ca4940..1aeafec1 100644 --- a/backend/internal/types/db_date_test.go +++ b/backend/internal/types/db_date_test.go @@ -4,9 +4,14 @@ import ( "encoding/json" "testing" "time" + + "go.uber.org/goleak" ) func TestDBDate_Value(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + // Create a DBDate instance with a specific time expectedTime := time.Date(2022, time.January, 1, 0, 0, 0, 0, time.UTC) dbDate := DBDate{Time: expectedTime} @@ -32,6 +37,9 @@ func TestDBDate_Value(t *testing.T) { } func TestDBDate_Scan(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + // Simulate a value from the database (unix timestamp) unixTime := int64(1640995200) @@ -56,6 +64,9 @@ func TestDBDate_Scan(t *testing.T) { } func TestDBDate_UnmarshalJSON(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + // Simulate a JSON input representing a unix timestamp jsonData := []byte("1640995200") @@ -81,6 +92,9 @@ func TestDBDate_UnmarshalJSON(t *testing.T) { } func TestDBDate_MarshalJSON(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + // Create a DBDate instance with a specific time expectedTime := time.Date(2022, time.January, 1, 0, 0, 0, 0, time.UTC) dbDate := DBDate{Time: expectedTime} diff --git a/backend/internal/types/db_nullable_int_test.go b/backend/internal/types/db_nullable_int_test.go index 4791404a..13f8558f 100644 --- a/backend/internal/types/db_nullable_int_test.go +++ b/backend/internal/types/db_nullable_int_test.go @@ -2,9 +2,14 @@ package types import ( "testing" + + "go.uber.org/goleak" ) func TestNullableDBIntValue(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + var d NullableDBInt // Test when Int is 0 (null) @@ -23,6 +28,9 @@ func TestNullableDBIntValue(t *testing.T) { } func TestNullableDBIntScan(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + var d NullableDBInt // Test when src is an int @@ -57,6 +65,9 @@ func TestNullableDBIntScan(t *testing.T) { } func TestNullableDBIntUnmarshalJSON(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + var d NullableDBInt // Test when data is an integer value @@ -73,6 +84,9 @@ func TestNullableDBIntUnmarshalJSON(t *testing.T) { } func TestNullableDBIntMarshalJSON(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + var d NullableDBInt // Test when Int is 0 (null) diff --git a/backend/internal/types/db_nullable_uint_test.go b/backend/internal/types/db_nullable_uint_test.go index 8c87b7c6..755b111b 100644 --- a/backend/internal/types/db_nullable_uint_test.go +++ b/backend/internal/types/db_nullable_uint_test.go @@ -3,9 +3,14 @@ package types import ( "database/sql/driver" "testing" + + "go.uber.org/goleak" ) func TestNullableDBUint_Value(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + tests := []struct { name string input NullableDBUint @@ -40,6 +45,9 @@ func TestNullableDBUint_Value(t *testing.T) { } func TestNullableDBUint_Scan(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + tests := []struct { name string input interface{} @@ -76,6 +84,9 @@ func TestNullableDBUint_Scan(t *testing.T) { } func TestNullableDBUint_UnmarshalJSON(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + tests := []struct { name string input []byte @@ -112,6 +123,9 @@ func TestNullableDBUint_UnmarshalJSON(t *testing.T) { } func TestNullableDBUint_MarshalJSON(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + tests := []struct { name string input NullableDBUint diff --git a/backend/internal/types/nullable_db_date_test.go b/backend/internal/types/nullable_db_date_test.go index 5b853ae2..613f3fa0 100644 --- a/backend/internal/types/nullable_db_date_test.go +++ b/backend/internal/types/nullable_db_date_test.go @@ -3,10 +3,15 @@ package types import ( "testing" "time" + + "go.uber.org/goleak" ) // TestNullableDBDateValue tests the Value method of the NullableDBDate type func TestNullableDBDateValue(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + tme := time.Date(2022, time.January, 1, 0, 0, 0, 0, time.UTC) d := NullableDBDate{ Time: &tme, @@ -26,6 +31,9 @@ func TestNullableDBDateValue(t *testing.T) { // TestNullableDBDateScan tests the Scan method of the NullableDBDate type func TestNullableDBDateScan(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + var d NullableDBDate err := d.Scan(int64(1640995200)) @@ -42,6 +50,9 @@ func TestNullableDBDateScan(t *testing.T) { // TestNullableDBDateUnmarshalJSON tests the UnmarshalJSON method of the NullableDBDate type func TestNullableDBDateUnmarshalJSON(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + data := []byte(`1640995200`) var d NullableDBDate @@ -59,6 +70,9 @@ func TestNullableDBDateUnmarshalJSON(t *testing.T) { // TestNullableDBDateMarshalJSON tests the MarshalJSON method of the NullableDBDate type func TestNullableDBDateMarshalJSON(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + tme := time.Date(2022, time.January, 1, 0, 0, 0, 0, time.UTC) d := NullableDBDate{ Time: &tme, @@ -78,6 +92,9 @@ func TestNullableDBDateMarshalJSON(t *testing.T) { // TestNullableDBDateAsInt64 tests the AsInt64 method of the NullableDBDate type func TestNullableDBDateAsInt64(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + tme := time.Date(2022, time.January, 1, 0, 0, 0, 0, time.UTC) d := NullableDBDate{ Time: &tme, @@ -93,6 +110,9 @@ func TestNullableDBDateAsInt64(t *testing.T) { // TestNullableDBDateAsString tests the AsString method of the NullableDBDate type func TestNullableDBDateAsString(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + tme := time.Date(2022, time.January, 1, 0, 0, 0, 0, time.UTC) d := NullableDBDate{ Time: &tme, diff --git a/backend/internal/util/interfaces_test.go b/backend/internal/util/interfaces_test.go index 99542d3d..135edf4a 100644 --- a/backend/internal/util/interfaces_test.go +++ b/backend/internal/util/interfaces_test.go @@ -4,9 +4,13 @@ import ( "testing" "github.com/stretchr/testify/assert" + "go.uber.org/goleak" ) func TestFindItemInInterface(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + obj := map[string]interface{}{ "key1": "value1", "key2": 10, diff --git a/backend/internal/util/maps_test.go b/backend/internal/util/maps_test.go index fdb5d2ff..e4f6ac7d 100644 --- a/backend/internal/util/maps_test.go +++ b/backend/internal/util/maps_test.go @@ -4,6 +4,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "go.uber.org/goleak" ) type rect struct { @@ -12,6 +13,9 @@ type rect struct { } func TestMapContainsKey(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + var r rect r.width = 5 r.height = 5 diff --git a/backend/internal/util/slices_test.go b/backend/internal/util/slices_test.go index 17acd8a0..0653b29c 100644 --- a/backend/internal/util/slices_test.go +++ b/backend/internal/util/slices_test.go @@ -5,9 +5,13 @@ import ( "testing" "github.com/stretchr/testify/assert" + "go.uber.org/goleak" ) func TestSliceContainsItem(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + type want struct { result bool } diff --git a/backend/internal/util/strings_test.go b/backend/internal/util/strings_test.go index 2f5af42d..cb289f0b 100644 --- a/backend/internal/util/strings_test.go +++ b/backend/internal/util/strings_test.go @@ -4,9 +4,13 @@ import ( "testing" "github.com/stretchr/testify/assert" + "go.uber.org/goleak" ) func TestCleanupWhitespace(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + tests := []struct { name string input string @@ -51,6 +55,9 @@ upstream npm_upstream_5 { } func TestPrettyPrintJSON(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + testCases := []struct { input string expected string diff --git a/backend/internal/util/time_test.go b/backend/internal/util/time_test.go index 260d3fbc..d15c7e49 100644 --- a/backend/internal/util/time_test.go +++ b/backend/internal/util/time_test.go @@ -4,9 +4,13 @@ import ( "testing" "github.com/stretchr/testify/assert" + "go.uber.org/goleak" ) func TestUnixMilliToNiceFormat(t *testing.T) { + // goleak is used to detect goroutine leaks + defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) + tests := []struct { input int64 expected string diff --git a/frontend/src/pages/Certificates/TableWrapper.tsx b/frontend/src/pages/Certificates/TableWrapper.tsx index 095753c8..fd00a8f4 100644 --- a/frontend/src/pages/Certificates/TableWrapper.tsx +++ b/frontend/src/pages/Certificates/TableWrapper.tsx @@ -2,7 +2,6 @@ import { useEffect, useReducer, useState } from "react"; import { Alert, AlertIcon, useToast } from "@chakra-ui/react"; import { useQueryClient } from "@tanstack/react-query"; - import { renewCertificate } from "src/api/npm"; import { EmptyList, SpinnerPage, tableEventReducer } from "src/components"; import { useCertificates } from "src/hooks"; @@ -81,10 +80,6 @@ function TableWrapper() { ); } - if (isFetching || isLoading || !tableData) { - return ; - } - // When there are no items and no filters active, show the nicer empty view if (data?.total === 0 && filters?.length === 0) { return (