diff --git a/.golangci.yml b/.golangci.yml index a1409daa1b1..078221bf40e 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -29,6 +29,7 @@ linters: - gofmt - goimports - exportloopref + - bodyclose # revive is a replacement for golint, but we do not run it in CI for now. # This is only enabled as a post-commit hook diff --git a/go/test/endtoend/clustertest/main_test.go b/go/test/endtoend/clustertest/main_test.go index 0be66d56af8..35da40a3edb 100644 --- a/go/test/endtoend/clustertest/main_test.go +++ b/go/test/endtoend/clustertest/main_test.go @@ -107,9 +107,10 @@ func testURL(t *testing.T, url string, testCaseName string) { // getStatusForUrl returns the status code for the URL func getStatusForURL(url string) int { - resp, _ := http.Get(url) - if resp != nil { - return resp.StatusCode + resp, err := http.Get(url) + if err != nil { + return 0 } - return 0 + defer resp.Body.Close() + return resp.StatusCode } diff --git a/go/test/endtoend/clustertest/vtctld_test.go b/go/test/endtoend/clustertest/vtctld_test.go index 36fcb51d97d..7533ce4a24e 100644 --- a/go/test/endtoend/clustertest/vtctld_test.go +++ b/go/test/endtoend/clustertest/vtctld_test.go @@ -62,13 +62,15 @@ func TestVtctldProcess(t *testing.T) { func testTopoDataAPI(t *testing.T, url string) { resp, err := http.Get(url) - require.Nil(t, err) + require.NoError(t, err) + defer resp.Body.Close() assert.Equal(t, resp.StatusCode, 200) resultMap := make(map[string]any) - respByte, _ := io.ReadAll(resp.Body) + respByte, err := io.ReadAll(resp.Body) + require.NoError(t, err) err = json.Unmarshal(respByte, &resultMap) - require.Nil(t, err) + require.NoError(t, err) errorValue := reflect.ValueOf(resultMap["Error"]) assert.Empty(t, errorValue.String()) @@ -83,7 +85,7 @@ func testTopoDataAPI(t *testing.T, url string) { func testListAllTablets(t *testing.T) { // first w/o any filters, aside from cell result, err := clusterInstance.VtctlclientProcess.ExecuteCommandWithOutput("ListAllTablets", clusterInstance.Cell) - require.Nil(t, err) + require.NoError(t, err) tablets := getAllTablets() @@ -104,7 +106,7 @@ func testListAllTablets(t *testing.T) { "ListAllTablets", "--", "--keyspace", clusterInstance.Keyspaces[0].Name, "--tablet_type", "primary", clusterInstance.Cell) - require.Nil(t, err) + require.NoError(t, err) // We should only return a single primary tablet per shard in the first keyspace tabletsFromCMD = strings.Split(result, "\n") @@ -115,9 +117,10 @@ func testListAllTablets(t *testing.T) { func testTabletStatus(t *testing.T) { resp, err := http.Get(fmt.Sprintf("http://%s:%d", clusterInstance.Hostname, clusterInstance.Keyspaces[0].Shards[0].Vttablets[0].HTTPPort)) - require.Nil(t, err) + require.NoError(t, err) + defer resp.Body.Close() respByte, err := io.ReadAll(resp.Body) - require.Nil(t, err) + require.NoError(t, err) result := string(respByte) log.Infof("Tablet status response: %v", result) assert.True(t, strings.Contains(result, `Alias: 400) } else { @@ -234,11 +235,11 @@ func checkHealth(t *testing.T, port int, shouldError bool) { func checkTabletType(t *testing.T, tabletAlias string, typeWant string) { result, err := clusterInstance.VtctlclientProcess.ExecuteCommandWithOutput("GetTablet", tabletAlias) - require.Nil(t, err) + require.NoError(t, err) var tablet topodatapb.Tablet err = json2.Unmarshal([]byte(result), &tablet) - require.Nil(t, err) + require.NoError(t, err) actualType := tablet.GetType() got := fmt.Sprintf("%d", actualType) diff --git a/go/test/endtoend/tabletmanager/tablet_health_test.go b/go/test/endtoend/tabletmanager/tablet_health_test.go index d3d23e0075f..19359406607 100644 --- a/go/test/endtoend/tabletmanager/tablet_health_test.go +++ b/go/test/endtoend/tabletmanager/tablet_health_test.go @@ -202,6 +202,7 @@ func checkHealth(t *testing.T, port int, shouldError bool) { url := fmt.Sprintf("http://localhost:%d/healthz", port) resp, err := http.Get(url) require.NoError(t, err) + defer resp.Body.Close() if shouldError { assert.True(t, resp.StatusCode > 400) } else { diff --git a/go/test/endtoend/tabletmanager/throttler/throttler_test.go b/go/test/endtoend/tabletmanager/throttler/throttler_test.go index 1eb9ff22fcd..ed9f04081b4 100644 --- a/go/test/endtoend/tabletmanager/throttler/throttler_test.go +++ b/go/test/endtoend/tabletmanager/throttler/throttler_test.go @@ -149,8 +149,7 @@ func throttledApps(tablet *cluster.Vttablet) (resp *http.Response, respBody stri } func throttleCheck(tablet *cluster.Vttablet, skipRequestHeartbeats bool) (*http.Response, error) { - resp, err := httpClient.Get(fmt.Sprintf("http://localhost:%d/%s?s=%t", tablet.HTTPPort, checkAPIPath, skipRequestHeartbeats)) - return resp, err + return httpClient.Get(fmt.Sprintf("http://localhost:%d/%s?s=%t", tablet.HTTPPort, checkAPIPath, skipRequestHeartbeats)) } func throttleCheckSelf(tablet *cluster.Vttablet) (*http.Response, error) { @@ -161,8 +160,9 @@ func warmUpHeartbeat(t *testing.T) (respStatus int) { // because we run with -heartbeat_on_demand_duration=5s, the heartbeat is "cold" right now. // Let's warm it up. resp, err := throttleCheck(primaryTablet, false) + require.NoError(t, err) + defer resp.Body.Close() time.Sleep(time.Second) - assert.NoError(t, err) return resp.StatusCode } @@ -175,21 +175,23 @@ func waitForThrottleCheckStatus(t *testing.T, tablet *cluster.Vttablet, wantCode for { resp, err := throttleCheck(tablet, true) require.NoError(t, err) - require.NotNil(t, resp) if wantCode == resp.StatusCode { // Wait for any cached check values to be cleared and the new // status value to be in effect everywhere before returning. + resp.Body.Close() return } select { case <-ctx.Done(): b, err := io.ReadAll(resp.Body) require.NoError(t, err) + resp.Body.Close() assert.Equal(t, wantCode, resp.StatusCode, "body: %v", string(b)) return default: + resp.Body.Close() time.Sleep(time.Second) } } @@ -213,29 +215,34 @@ func TestThrottlerAfterMetricsCollected(t *testing.T) { t.Run("expect OK once heartbeats lease renewed", func(t *testing.T) { time.Sleep(1 * time.Second) resp, err := throttleCheck(primaryTablet, false) - assert.NoError(t, err) + require.NoError(t, err) + defer resp.Body.Close() assert.Equal(t, http.StatusOK, resp.StatusCode) }) t.Run("expect OK once heartbeats lease renewed, still", func(t *testing.T) { time.Sleep(1 * time.Second) resp, err := throttleCheck(primaryTablet, false) - assert.NoError(t, err) + require.NoError(t, err) + defer resp.Body.Close() assert.Equal(t, http.StatusOK, resp.StatusCode) }) t.Run("validate throttled-apps", func(t *testing.T) { resp, body, err := throttledApps(primaryTablet) - assert.NoError(t, err) + require.NoError(t, err) + defer resp.Body.Close() assert.Equal(t, http.StatusOK, resp.StatusCode) assert.Contains(t, body, "always-throttled-app") }) t.Run("validate check-self", func(t *testing.T) { resp, err := throttleCheckSelf(primaryTablet) - assert.NoError(t, err) + require.NoError(t, err) + defer resp.Body.Close() assert.Equal(t, http.StatusOK, resp.StatusCode) }) t.Run("validate check-self, again", func(t *testing.T) { resp, err := throttleCheckSelf(replicaTablet) - assert.NoError(t, err) + require.NoError(t, err) + defer resp.Body.Close() assert.Equal(t, http.StatusOK, resp.StatusCode) }) } @@ -251,18 +258,21 @@ func TestLag(t *testing.T) { time.Sleep(2 * throttlerThreshold) resp, err := throttleCheck(primaryTablet, false) - assert.NoError(t, err) + require.NoError(t, err) + defer resp.Body.Close() assert.Equal(t, http.StatusTooManyRequests, resp.StatusCode) }) t.Run("primary self-check should still be fine", func(t *testing.T) { resp, err := throttleCheckSelf(primaryTablet) - assert.NoError(t, err) + require.NoError(t, err) + defer resp.Body.Close() // self (on primary) is unaffected by replication lag assert.Equal(t, http.StatusOK, resp.StatusCode) }) t.Run("replica self-check should show error", func(t *testing.T) { resp, err := throttleCheckSelf(replicaTablet) - assert.NoError(t, err) + require.NoError(t, err) + defer resp.Body.Close() assert.Equal(t, http.StatusTooManyRequests, resp.StatusCode) }) t.Run("starting replication", func(t *testing.T) { @@ -274,13 +284,15 @@ func TestLag(t *testing.T) { }) t.Run("primary self-check should be fine", func(t *testing.T) { resp, err := throttleCheckSelf(primaryTablet) - assert.NoError(t, err) + require.NoError(t, err) + defer resp.Body.Close() // self (on primary) is unaffected by replication lag assert.Equal(t, http.StatusOK, resp.StatusCode) }) t.Run("replica self-check should be fine", func(t *testing.T) { resp, err := throttleCheckSelf(replicaTablet) - assert.NoError(t, err) + require.NoError(t, err) + defer resp.Body.Close() assert.Equal(t, http.StatusOK, resp.StatusCode) }) } diff --git a/go/test/endtoend/tabletmanager/throttler_custom_config/throttler_test.go b/go/test/endtoend/tabletmanager/throttler_custom_config/throttler_test.go index a2d030b85cb..741603ec9f3 100644 --- a/go/test/endtoend/tabletmanager/throttler_custom_config/throttler_test.go +++ b/go/test/endtoend/tabletmanager/throttler_custom_config/throttler_test.go @@ -162,13 +162,15 @@ func TestThrottlerThresholdOK(t *testing.T) { t.Run("immediately", func(t *testing.T) { resp, err := throttleCheck(primaryTablet) - assert.NoError(t, err) + require.NoError(t, err) + defer resp.Body.Close() assert.Equal(t, http.StatusOK, resp.StatusCode) }) t.Run("after long wait", func(t *testing.T) { time.Sleep(applyConfigWait) resp, err := throttleCheck(primaryTablet) - assert.NoError(t, err) + require.NoError(t, err) + defer resp.Body.Close() assert.Equal(t, http.StatusOK, resp.StatusCode) }) } @@ -192,12 +194,14 @@ func TestThreadsRunning(t *testing.T) { // {"StatusCode":429,"Value":2,"Threshold":2,"Message":"Threshold exceeded"} { resp, err := throttleCheck(primaryTablet) - assert.NoError(t, err) + require.NoError(t, err) + defer resp.Body.Close() assert.Equal(t, http.StatusTooManyRequests, resp.StatusCode) } { resp, err := throttleCheckSelf(primaryTablet) - assert.NoError(t, err) + require.NoError(t, err) + defer resp.Body.Close() assert.Equal(t, http.StatusTooManyRequests, resp.StatusCode) } }) @@ -207,12 +211,14 @@ func TestThreadsRunning(t *testing.T) { t.Run("restored below threshold", func(t *testing.T) { { resp, err := throttleCheck(primaryTablet) - assert.NoError(t, err) + require.NoError(t, err) + defer resp.Body.Close() assert.Equal(t, http.StatusOK, resp.StatusCode) } { resp, err := throttleCheckSelf(primaryTablet) - assert.NoError(t, err) + require.NoError(t, err) + defer resp.Body.Close() assert.Equal(t, http.StatusOK, resp.StatusCode) } }) @@ -223,7 +229,7 @@ func vtgateExec(t *testing.T, query string, expectError string) *sqltypes.Result ctx := context.Background() conn, err := mysql.Connect(ctx, &vtParams) - require.Nil(t, err) + require.NoError(t, err) defer conn.Close() qr, err := conn.ExecuteFetch(query, 1000, true) diff --git a/go/test/endtoend/tabletmanager/throttler_topo/throttler_test.go b/go/test/endtoend/tabletmanager/throttler_topo/throttler_test.go index 01c8696f71c..9c3b8843627 100644 --- a/go/test/endtoend/tabletmanager/throttler_topo/throttler_test.go +++ b/go/test/endtoend/tabletmanager/throttler_topo/throttler_test.go @@ -211,8 +211,10 @@ func warmUpHeartbeat(t *testing.T) (respStatus int) { // because we run with -heartbeat_on_demand_duration=5s, the heartbeat is "cold" right now. // Let's warm it up. resp, err := throttleCheck(primaryTablet, false) + require.NoError(t, err) + defer resp.Body.Close() + time.Sleep(time.Second) - assert.NoError(t, err) return resp.StatusCode } @@ -225,21 +227,23 @@ func waitForThrottleCheckStatus(t *testing.T, tablet *cluster.Vttablet, wantCode for { resp, err := throttleCheck(tablet, true) require.NoError(t, err) - require.NotNil(t, resp) if wantCode == resp.StatusCode { // Wait for any cached check values to be cleared and the new // status value to be in effect everywhere before returning. + resp.Body.Close() return } select { case <-ctx.Done(): b, err := io.ReadAll(resp.Body) require.NoError(t, err) + resp.Body.Close() assert.Equal(t, wantCode, resp.StatusCode, "body: %v", string(b)) return default: + resp.Body.Close() time.Sleep(time.Second) } } @@ -268,7 +272,8 @@ func TestInitialThrottler(t *testing.T) { t.Run("validating OK response from disabled throttler", func(t *testing.T) { resp, err := throttleCheck(primaryTablet, false) - assert.NoError(t, err) + require.NoError(t, err) + defer resp.Body.Close() assert.Equal(t, http.StatusOK, resp.StatusCode) }) t.Run("enabling throttler with low threshold", func(t *testing.T) { @@ -284,7 +289,8 @@ func TestInitialThrottler(t *testing.T) { }) t.Run("validating OK response from disabled throttler, again", func(t *testing.T) { resp, err := throttleCheck(primaryTablet, false) - assert.NoError(t, err) + require.NoError(t, err) + defer resp.Body.Close() assert.Equal(t, http.StatusOK, resp.StatusCode) }) t.Run("enabling throttler, again", func(t *testing.T) { @@ -315,13 +321,15 @@ func TestInitialThrottler(t *testing.T) { t.Run("validating OK response from throttler with low threshold, heartbeats running", func(t *testing.T) { time.Sleep(1 * time.Second) resp, err := throttleCheck(primaryTablet, false) - assert.NoError(t, err) + require.NoError(t, err) + defer resp.Body.Close() assert.Equal(t, http.StatusOK, resp.StatusCode) }) t.Run("validating OK response from throttler with low threshold, heartbeats running still", func(t *testing.T) { time.Sleep(1 * time.Second) resp, err := throttleCheck(primaryTablet, false) - assert.NoError(t, err) + require.NoError(t, err) + defer resp.Body.Close() assert.Equal(t, http.StatusOK, resp.StatusCode) }) t.Run("validating pushback response from throttler on low threshold once heartbeats go stale", func(t *testing.T) { @@ -340,18 +348,21 @@ func TestThrottlerAfterMetricsCollected(t *testing.T) { }) t.Run("validating throttled apps", func(t *testing.T) { resp, body, err := throttledApps(primaryTablet) - assert.NoError(t, err) + require.NoError(t, err) + defer resp.Body.Close() assert.Equal(t, http.StatusOK, resp.StatusCode) assert.Contains(t, body, "always-throttled-app") }) t.Run("validating primary check self", func(t *testing.T) { resp, err := throttleCheckSelf(primaryTablet) - assert.NoError(t, err) + require.NoError(t, err) + defer resp.Body.Close() assert.Equal(t, http.StatusOK, resp.StatusCode) }) t.Run("validating replica check self", func(t *testing.T) { resp, err := throttleCheckSelf(replicaTablet) - assert.NoError(t, err) + require.NoError(t, err) + defer resp.Body.Close() assert.Equal(t, http.StatusOK, resp.StatusCode) }) } @@ -367,18 +378,21 @@ func TestLag(t *testing.T) { time.Sleep(2 * throttlerThreshold) resp, err := throttleCheck(primaryTablet, false) - assert.NoError(t, err) + require.NoError(t, err) + defer resp.Body.Close() assert.Equal(t, http.StatusTooManyRequests, resp.StatusCode) }) t.Run("primary self-check should still be fine", func(t *testing.T) { resp, err := throttleCheckSelf(primaryTablet) - assert.NoError(t, err) + require.NoError(t, err) + defer resp.Body.Close() // self (on primary) is unaffected by replication lag assert.Equal(t, http.StatusOK, resp.StatusCode) }) t.Run("replica self-check should show error", func(t *testing.T) { resp, err := throttleCheckSelf(replicaTablet) - assert.NoError(t, err) + require.NoError(t, err) + defer resp.Body.Close() assert.Equal(t, http.StatusTooManyRequests, resp.StatusCode) }) t.Run("starting replication", func(t *testing.T) { @@ -390,13 +404,15 @@ func TestLag(t *testing.T) { }) t.Run("primary self-check should be fine", func(t *testing.T) { resp, err := throttleCheckSelf(primaryTablet) - assert.NoError(t, err) + require.NoError(t, err) + defer resp.Body.Close() // self (on primary) is unaffected by replication lag assert.Equal(t, http.StatusOK, resp.StatusCode) }) t.Run("replica self-check should be fine", func(t *testing.T) { resp, err := throttleCheckSelf(replicaTablet) - assert.NoError(t, err) + require.NoError(t, err) + defer resp.Body.Close() assert.Equal(t, http.StatusOK, resp.StatusCode) }) } @@ -430,7 +446,8 @@ func TestCustomQuery(t *testing.T) { }) t.Run("validating OK response from throttler with custom query", func(t *testing.T) { resp, err := throttleCheck(primaryTablet, false) - assert.NoError(t, err) + require.NoError(t, err) + defer resp.Body.Close() b, err := io.ReadAll(resp.Body) assert.NoError(t, err) @@ -453,7 +470,8 @@ func TestCustomQuery(t *testing.T) { // {"StatusCode":429,"Value":2,"Threshold":2,"Message":"Threshold exceeded"} { resp, err := throttleCheck(primaryTablet, false) - assert.NoError(t, err) + require.NoError(t, err) + defer resp.Body.Close() b, err := io.ReadAll(resp.Body) assert.NoError(t, err) @@ -461,7 +479,8 @@ func TestCustomQuery(t *testing.T) { } { resp, err := throttleCheckSelf(primaryTablet) - assert.NoError(t, err) + require.NoError(t, err) + defer resp.Body.Close() b, err := io.ReadAll(resp.Body) assert.NoError(t, err) @@ -475,12 +494,14 @@ func TestCustomQuery(t *testing.T) { t.Run("restored below threshold", func(t *testing.T) { { resp, err := throttleCheck(primaryTablet, false) - assert.NoError(t, err) + require.NoError(t, err) + defer resp.Body.Close() assert.Equal(t, http.StatusOK, resp.StatusCode) } { resp, err := throttleCheckSelf(primaryTablet) - assert.NoError(t, err) + require.NoError(t, err) + defer resp.Body.Close() assert.Equal(t, http.StatusOK, resp.StatusCode) } }) @@ -501,13 +522,15 @@ func TestRestoreDefaultQuery(t *testing.T) { t.Run("validating OK response from throttler with low threshold, heartbeats running", func(t *testing.T) { time.Sleep(1 * time.Second) resp, err := throttleCheck(primaryTablet, false) - assert.NoError(t, err) + require.NoError(t, err) + defer resp.Body.Close() assert.Equal(t, http.StatusOK, resp.StatusCode) }) t.Run("validating pushback response from throttler on low threshold once heartbeats go stale", func(t *testing.T) { time.Sleep(2 * onDemandHeartbeatDuration) // just... really wait long enough, make sure on-demand stops resp, err := throttleCheck(primaryTablet, false) - assert.NoError(t, err) + require.NoError(t, err) + defer resp.Body.Close() assert.Equal(t, http.StatusTooManyRequests, resp.StatusCode) }) } diff --git a/go/test/endtoend/topoconncache/main_test.go b/go/test/endtoend/topoconncache/main_test.go index 038204108a7..99b2e43de7e 100644 --- a/go/test/endtoend/topoconncache/main_test.go +++ b/go/test/endtoend/topoconncache/main_test.go @@ -240,9 +240,10 @@ func testURL(t *testing.T, url string, testCaseName string) { // getStatusForUrl returns the status code for the URL func getStatusForURL(url string) int { - resp, _ := http.Get(url) - if resp != nil { - return resp.StatusCode + resp, err := http.Get(url) + if err != nil { + return 0 } - return 0 + defer resp.Body.Close() + return resp.StatusCode } diff --git a/go/test/endtoend/vreplication/helper_test.go b/go/test/endtoend/vreplication/helper_test.go index 981d3d6de97..73f752b6bfe 100644 --- a/go/test/endtoend/vreplication/helper_test.go +++ b/go/test/endtoend/vreplication/helper_test.go @@ -98,10 +98,8 @@ func execVtgateQuery(t *testing.T, conn *mysql.Conn, database string, query stri func checkHealth(t *testing.T, url string) bool { resp, err := http.Get(url) require.NoError(t, err) - if err != nil || resp.StatusCode != 200 { - return false - } - return true + defer resp.Body.Close() + return resp.StatusCode == 200 } func waitForQueryResult(t *testing.T, conn *mysql.Conn, database string, query string, want string) { @@ -130,9 +128,9 @@ func waitForTabletThrottlingStatus(t *testing.T, tablet *cluster.VttabletProcess timer := time.NewTimer(defaultTimeout) defer timer.Stop() for { - _, output, err := throttlerCheckSelf(tablet, appName) + output, err := throttlerCheckSelf(tablet, appName) require.NoError(t, err) - require.NotNil(t, output) + gotCode, err = jsonparser.GetInt([]byte(output), "StatusCode") require.NoError(t, err) if wantCode == gotCode { diff --git a/go/test/endtoend/vreplication/vreplication_test.go b/go/test/endtoend/vreplication/vreplication_test.go index 8d700bd8995..396292108f5 100644 --- a/go/test/endtoend/vreplication/vreplication_test.go +++ b/go/test/endtoend/vreplication/vreplication_test.go @@ -82,34 +82,36 @@ func init() { defaultReplicas = 1 } -func throttleResponse(tablet *cluster.VttabletProcess, path string) (resp *http.Response, respBody string, err error) { +func throttleResponse(tablet *cluster.VttabletProcess, path string) (respBody string, err error) { apiURL := fmt.Sprintf("http://%s:%d/%s", tablet.TabletHostname, tablet.Port, path) - resp, err = httpClient.Get(apiURL) + resp, err := httpClient.Get(apiURL) if err != nil { - return resp, respBody, err + return "", err } + defer resp.Body.Close() b, err := io.ReadAll(resp.Body) respBody = string(b) - return resp, respBody, err + return respBody, err } -func throttleApp(tablet *cluster.VttabletProcess, app string) (*http.Response, string, error) { +func throttleApp(tablet *cluster.VttabletProcess, app string) (string, error) { return throttleResponse(tablet, fmt.Sprintf("throttler/throttle-app?app=%s&duration=1h", app)) } -func unthrottleApp(tablet *cluster.VttabletProcess, app string) (*http.Response, string, error) { +func unthrottleApp(tablet *cluster.VttabletProcess, app string) (string, error) { return throttleResponse(tablet, fmt.Sprintf("throttler/unthrottle-app?app=%s", app)) } -func throttlerCheckSelf(tablet *cluster.VttabletProcess, app string) (resp *http.Response, respBody string, err error) { +func throttlerCheckSelf(tablet *cluster.VttabletProcess, app string) (respBody string, err error) { apiURL := fmt.Sprintf("http://%s:%d/throttler/check-self?app=%s", tablet.TabletHostname, tablet.Port, app) - resp, err = httpClient.Get(apiURL) + resp, err := httpClient.Get(apiURL) if err != nil { - return resp, respBody, err + return "", err } + defer resp.Body.Close() b, err := io.ReadAll(resp.Body) respBody = string(b) - return resp, respBody, err + return respBody, err } // TestVReplicationDDLHandling tests the DDL handling in @@ -1090,7 +1092,7 @@ func materializeProduct(t *testing.T) { t.Run("throttle-app-product", func(t *testing.T) { // Now, throttle the streamer on source tablets, insert some rows for _, tab := range productTablets { - _, body, err := throttleApp(tab, sourceThrottlerAppName) + body, err := throttleApp(tab, sourceThrottlerAppName) assert.NoError(t, err) assert.Contains(t, body, sourceThrottlerAppName) @@ -1108,7 +1110,7 @@ func materializeProduct(t *testing.T) { t.Run("unthrottle-app-product", func(t *testing.T) { // unthrottle on source tablets, and expect the rows to show up for _, tab := range productTablets { - _, body, err := unthrottleApp(tab, sourceThrottlerAppName) + body, err := unthrottleApp(tab, sourceThrottlerAppName) assert.NoError(t, err) assert.Contains(t, body, sourceThrottlerAppName) // give time for unthrottling to take effect and for target to fetch data @@ -1123,7 +1125,7 @@ func materializeProduct(t *testing.T) { // Now, throttle vreplication (vcopier/vapplier) on target tablets, and // insert some more rows. for _, tab := range customerTablets { - _, body, err := throttleApp(tab, targetThrottlerAppName) + body, err := throttleApp(tab, targetThrottlerAppName) assert.NoError(t, err) assert.Contains(t, body, targetThrottlerAppName) // Wait for throttling to take effect (caching will expire by this time): @@ -1141,7 +1143,7 @@ func materializeProduct(t *testing.T) { t.Run("unthrottle-app-customer", func(t *testing.T) { // unthrottle on target tablets, and expect the rows to show up for _, tab := range customerTablets { - _, body, err := unthrottleApp(tab, targetThrottlerAppName) + body, err := unthrottleApp(tab, targetThrottlerAppName) assert.NoError(t, err) assert.Contains(t, body, targetThrottlerAppName) } diff --git a/go/test/endtoend/vtcombo/vttest_sample_test.go b/go/test/endtoend/vtcombo/vttest_sample_test.go index df9e11a98f2..91db0f8a2c0 100644 --- a/go/test/endtoend/vtcombo/vttest_sample_test.go +++ b/go/test/endtoend/vtcombo/vttest_sample_test.go @@ -30,7 +30,7 @@ import ( "strings" "testing" - mysql "github.com/go-sql-driver/mysql" + "github.com/go-sql-driver/mysql" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -123,12 +123,13 @@ func TestMain(m *testing.M) { func TestStandalone(t *testing.T) { // validate debug vars resp, err := http.Get(fmt.Sprintf("http://%s/debug/vars", vtctldAddr)) - require.Nil(t, err) + require.NoError(t, err) + defer resp.Body.Close() require.Equal(t, 200, resp.StatusCode) resultMap := make(map[string]any) respByte, _ := io.ReadAll(resp.Body) err = json.Unmarshal(respByte, &resultMap) - require.Nil(t, err) + require.NoError(t, err) cmd := resultMap["cmdline"] require.NotNil(t, cmd, "cmdline is not available in debug vars") tmp, _ := cmd.([]any) @@ -136,7 +137,7 @@ func TestStandalone(t *testing.T) { ctx := context.Background() conn, err := vtgateconn.Dial(ctx, grpcAddress) - require.Nil(t, err) + require.NoError(t, err) defer conn.Close() cfg := mysql.NewConfig() @@ -155,9 +156,9 @@ func TestStandalone(t *testing.T) { assertTabletsPresent(t) err = localCluster.TearDown() - require.Nil(t, err) + require.NoError(t, err) err = localCluster.Setup() - require.Nil(t, err) + require.NoError(t, err) assertInsertedRowsExist(ctx, t, conn, idStart, rowCount) assertTabletsPresent(t) @@ -170,7 +171,7 @@ func assertInsertedRowsExist(ctx context.Context, t *testing.T, conn *vtgateconn "id_start": {Type: querypb.Type_UINT64, Value: []byte(strconv.FormatInt(int64(idStart), 10))}, } res, err := cur.Execute(ctx, "select * from test_table where id >= :id_start", bindVariables) - require.Nil(t, err) + require.NoError(t, err) assert.Equal(t, rowCount, len(res.Rows)) @@ -179,7 +180,7 @@ func assertInsertedRowsExist(ctx context.Context, t *testing.T, conn *vtgateconn "id_start": {Type: querypb.Type_UINT64, Value: []byte(strconv.FormatInt(int64(idStart), 10))}, } res, err = cur.Execute(ctx, "select * from test_table where id = :id_start", bindVariables) - require.Nil(t, err) + require.NoError(t, err) require.Equal(t, 1, len(res.Rows)) assert.Equal(t, "VARCHAR(\"test1000\")", res.Rows[0][1].String()) } @@ -200,7 +201,7 @@ func assertRouting(ctx context.Context, t *testing.T, db *sql.DB) { func assertCanInsertRow(ctx context.Context, t *testing.T, conn *vtgateconn.VTGateConn) { cur := conn.Session(ks1+":80-@primary", nil) _, err := cur.Execute(ctx, "begin", nil) - require.Nil(t, err) + require.NoError(t, err) i := 0x810000000000000 bindVariables := map[string]*querypb.BindVariable{ @@ -210,10 +211,10 @@ func assertCanInsertRow(ctx context.Context, t *testing.T, conn *vtgateconn.VTGa } query := "insert into test_table (id, msg, keyspace_id) values (:id, :msg, :keyspace_id)" _, err = cur.Execute(ctx, query, bindVariables) - require.Nil(t, err) + require.NoError(t, err) _, err = cur.Execute(ctx, "commit", nil) - require.Nil(t, err) + require.NoError(t, err) } func insertManyRows(ctx context.Context, t *testing.T, conn *vtgateconn.VTGateConn, idStart, rowCount int) { @@ -221,7 +222,7 @@ func insertManyRows(ctx context.Context, t *testing.T, conn *vtgateconn.VTGateCo query := "insert into test_table (id, msg, keyspace_id) values (:id, :msg, :keyspace_id)" _, err := cur.Execute(ctx, "begin", nil) - require.Nil(t, err) + require.NoError(t, err) for i := idStart; i < idStart+rowCount; i++ { bindVariables := map[string]*querypb.BindVariable{ @@ -230,11 +231,11 @@ func insertManyRows(ctx context.Context, t *testing.T, conn *vtgateconn.VTGateCo "keyspace_id": {Type: querypb.Type_UINT64, Value: []byte(strconv.FormatInt(int64(i), 10))}, } _, err = cur.Execute(ctx, query, bindVariables) - require.Nil(t, err) + require.NoError(t, err) } _, err = cur.Execute(ctx, "commit", nil) - require.Nil(t, err) + require.NoError(t, err) } func assertTabletsPresent(t *testing.T) { @@ -243,7 +244,7 @@ func assertTabletsPresent(t *testing.T) { log.Infof("Running vtctlclient with command: %v", tmpCmd.Args) output, err := tmpCmd.CombinedOutput() - require.Nil(t, err) + require.NoError(t, err) numPrimary, numReplica, numRdonly, numDash80, num80Dash, numRouted := 0, 0, 0, 0, 0, 0 lines := strings.Split(string(output), "\n") @@ -302,17 +303,17 @@ func assertTransactionalityAndRollbackObeyed(ctx context.Context, t *testing.T, } query := "insert into test_table (id, msg, keyspace_id) values (:id, :msg, :keyspace_id)" _, err := cur.Execute(ctx, query, bindVariables) - require.Nil(t, err) + require.NoError(t, err) bindVariables = map[string]*querypb.BindVariable{ "msg": {Type: querypb.Type_VARCHAR, Value: []byte(msg)}, } res, err := cur.Execute(ctx, "select * from test_table where msg = :msg", bindVariables) - require.Nil(t, err) + require.NoError(t, err) require.Equal(t, 1, len(res.Rows)) _, err = cur.Execute(ctx, "begin", nil) - require.Nil(t, err) + require.NoError(t, err) msg2 := msg + "2" bindVariables = map[string]*querypb.BindVariable{ @@ -321,15 +322,15 @@ func assertTransactionalityAndRollbackObeyed(ctx context.Context, t *testing.T, } query = "update test_table set msg = :msg where id = :id" _, err = cur.Execute(ctx, query, bindVariables) - require.Nil(t, err) + require.NoError(t, err) _, err = cur.Execute(ctx, "rollback", nil) - require.Nil(t, err) + require.NoError(t, err) bindVariables = map[string]*querypb.BindVariable{ "msg": {Type: querypb.Type_VARCHAR, Value: []byte(msg2)}, } res, err = cur.Execute(ctx, "select * from test_table where msg = :msg", bindVariables) - require.Nil(t, err) + require.NoError(t, err) require.Equal(t, 0, len(res.Rows)) } diff --git a/go/test/endtoend/vtgate/schematracker/restarttablet/schema_restart_test.go b/go/test/endtoend/vtgate/schematracker/restarttablet/schema_restart_test.go index 9d3de02f846..6990aa01f88 100644 --- a/go/test/endtoend/vtgate/schematracker/restarttablet/schema_restart_test.go +++ b/go/test/endtoend/vtgate/schematracker/restarttablet/schema_restart_test.go @@ -158,7 +158,8 @@ func TestVSchemaTrackerKeyspaceReInit(t *testing.T) { func readVSchema(t *testing.T, vtgate *cluster.VtgateProcess, results *any) { httpClient := &http.Client{Timeout: 5 * time.Second} resp, err := httpClient.Get(vtgate.VSchemaURL) - require.Nil(t, err) + require.NoError(t, err) + defer resp.Body.Close() assert.Equal(t, 200, resp.StatusCode) json.NewDecoder(resp.Body).Decode(results) } diff --git a/go/vt/vtctld/api_test.go b/go/vt/vtctld/api_test.go index 38eb2785d0d..9607e16d8bf 100644 --- a/go/vt/vtctld/api_test.go +++ b/go/vt/vtctld/api_test.go @@ -26,6 +26,8 @@ import ( "strings" "testing" + "github.com/stretchr/testify/require" + "vitess.io/vitess/go/vt/discovery" "vitess.io/vitess/go/vt/topo/memorytopo" "vitess.io/vitess/go/vt/wrangler" @@ -462,29 +464,19 @@ func TestAPI(t *testing.T) { switch in.method { case "GET": resp, err = http.Get(server.URL + apiPrefix + in.path) + require.NoError(t, err) + defer resp.Body.Close() case "POST": resp, err = http.Post(server.URL+apiPrefix+in.path, "application/json", strings.NewReader(in.body)) + require.NoError(t, err) + defer resp.Body.Close() default: t.Fatalf("[%v] unknown method: %v", in.path, in.method) - return - } - - if err != nil { - t.Fatalf("[%v] http error: %v", in.path, err) - return } body, err := io.ReadAll(resp.Body) - resp.Body.Close() - - if err != nil { - t.Fatalf("[%v] io.ReadAll(resp.Body) error: %v", in.path, err) - return - } - - if resp.StatusCode != in.statusCode { - t.Fatalf("[%v] got unexpected status code %d, want %d", in.path, resp.StatusCode, in.statusCode) - } + require.NoError(t, err) + require.Equal(t, in.statusCode, resp.StatusCode) got := compactJSON(body) want := compactJSON([]byte(in.want)) diff --git a/go/vt/vttablet/tabletserver/throttle/throttler.go b/go/vt/vttablet/tabletserver/throttle/throttler.go index 9b7bb22d7f1..f473ebe06fb 100644 --- a/go/vt/vttablet/tabletserver/throttle/throttler.go +++ b/go/vt/vttablet/tabletserver/throttle/throttler.go @@ -666,6 +666,7 @@ func (throttler *Throttler) generateTabletHTTPProbeFunction(ctx context.Context, mySQLThrottleMetric.Err = err return mySQLThrottleMetric } + defer resp.Body.Close() b, err := io.ReadAll(resp.Body) if err != nil { mySQLThrottleMetric.Err = err diff --git a/go/vt/workflow/long_polling_test.go b/go/vt/workflow/long_polling_test.go index 85dbabd3f28..a1705dd2346 100644 --- a/go/vt/workflow/long_polling_test.go +++ b/go/vt/workflow/long_polling_test.go @@ -94,9 +94,11 @@ func TestLongPolling(t *testing.T) { u.Path = "/workflow/action/1" message := `{"path":"/uuid1","name":"button1"}` buf := bytes.NewReader([]byte(message)) - if _, err := http.Post(u.String(), "application/json; charset=utf-8", buf); err != nil { + pResp, err := http.Post(u.String(), "application/json; charset=utf-8", buf) + if err != nil { t.Fatalf("/action/1 post failed: %v", err) } + pResp.Body.Close() for timeout := 0; ; timeout++ { // This is an asynchronous action, need to take the lock. tw.mu.Lock() diff --git a/go/vt/workflow/websocket_test.go b/go/vt/workflow/websocket_test.go index e47b730e9ad..4a08422f532 100644 --- a/go/vt/workflow/websocket_test.go +++ b/go/vt/workflow/websocket_test.go @@ -46,10 +46,11 @@ func TestWebSocket(t *testing.T) { // Start a client websocket. u := url.URL{Scheme: "ws", Host: listener.Addr().String(), Path: "/workflow"} - c, _, err := websocket.DefaultDialer.Dial(u.String(), nil) + c, resp, err := websocket.DefaultDialer.Dial(u.String(), nil) if err != nil { t.Fatalf("WebSocket dial failed: %v", err) } + defer resp.Body.Close() // Read the original full dump. _, tree, err := c.ReadMessage() diff --git a/test.go b/test.go index 34afbd43041..7f614ad83ab 100755 --- a/test.go +++ b/test.go @@ -659,9 +659,11 @@ type TestStats struct { func sendStats(values url.Values) { if *remoteStats != "" { log.Printf("Sending remote stats to %v", *remoteStats) - if _, err := http.PostForm(*remoteStats, values); err != nil { + resp, err := http.PostForm(*remoteStats, values) + if err != nil { log.Printf("Can't send remote stats: %v", err) } + defer resp.Body.Close() } }