chore: enable contextcheck, fatcontext and noctx linters

Signed-off-by: Matthieu MOREL <matthieu.morel35@gmail.com>
pull/31862/head
Matthieu MOREL 4 months ago
parent be45213874
commit 34cfdfdbe5

@ -20,10 +20,12 @@ linters:
# Keep sorted alphabetically
enable:
- bidichk
- contextcheck
- depguard
- dupl
- errorlint
- exhaustive
- fatcontext
- gocritic
- gomodguard
- govet
@ -31,6 +33,7 @@ linters:
- misspell
- modernize
- nakedret
- noctx
- nolintlint
- perfsprint
- revive

@ -46,7 +46,7 @@ func TestCliPluginExitCode(t *testing.T) {
// So that the second run is able to run main() and this first run can verify the exit status returned by that.
//
// This technique originates from https://talks.golang.org/2014/testing.slide#23.
cmd := exec.Command(os.Args[0], "-test.run=TestCliPluginExitCode")
cmd := exec.CommandContext(t.Context(), os.Args[0], "-test.run=TestCliPluginExitCode")
cmd.Env = append(
os.Environ(),
"RUN_MAIN_FOR_TESTING=1",

@ -19,6 +19,7 @@ package rules
import (
"bufio"
"bytes"
"context"
"errors"
"fmt"
"io"
@ -104,7 +105,7 @@ func TemplatesWithSkipSchemaValidation(linter *support.Linter, values map[string
}
var e engine.Engine
e.LintMode = true
renderedContentMap, err := e.Render(chart, valuesToRender)
renderedContentMap, err := e.RenderWithContext(context.Background(), chart, valuesToRender)
renderOk := linter.RunLinterRule(support.ErrorSev, fpath, err)

@ -17,6 +17,7 @@ limitations under the License.
package monocular
import (
"context"
"encoding/json"
"fmt"
"net/http"
@ -98,7 +99,14 @@ type ChartVersion struct {
}
// Search performs a search against the monocular search API
//
// Deprecated: Use SearchWithContext instead.
func (c *Client) Search(term string) ([]SearchResult, error) {
return c.SearchWithContext(context.Background(), term)
}
// SearchWithContext performs a search against the monocular search API
func (c *Client) SearchWithContext(ctx context.Context, term string) ([]SearchResult, error) {
// Create the URL to the search endpoint
// Note, this is currently an internal API for the Hub. This should be
// formatted without showing how monocular operates.
@ -113,7 +121,7 @@ func (c *Client) Search(term string) ([]SearchResult, error) {
p.RawQuery = "q=" + url.QueryEscape(term)
// Create request
req, err := http.NewRequest(http.MethodGet, p.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, p.String(), http.NoBody)
if err != nil {
return nil, err
}

@ -37,7 +37,7 @@ func TestSearch(t *testing.T) {
t.Errorf("unable to create monocular client: %s", err)
}
results, err := c.Search("phpmyadmin")
results, err := c.SearchWithContext(t.Context(), "phpmyadmin")
if err != nil {
t.Errorf("unable to search monocular: %s", err)
}

@ -16,6 +16,7 @@ limitations under the License.
package installer
import (
"context"
"errors"
"fmt"
"log/slog"
@ -189,12 +190,17 @@ func isRemoteHTTPArchive(source string) bool {
}
// If no suffix match, try HEAD request to check content type
res, err := http.Head(source)
req, err := http.NewRequestWithContext(context.Background(), http.MethodHead, source, http.NoBody)
if err != nil {
// If we get an error at the network layer, we can't install it. So
// we return false.
return false
}
res, err := http.DefaultClient.Do(req)
if err != nil {
return false
}
defer res.Body.Close()
// Next, we look for the content type or content disposition headers to see
// if they have matching extractors.

@ -46,7 +46,7 @@ func buildLoadExtismPlugin(t *testing.T, dir string) pluginRaw {
require.NoError(t, err)
require.Equal(t, "extism/v1", m.Runtime, "expected plugin runtime to be extism/v1")
cmd := exec.Command("make", "-C", dir)
cmd := exec.CommandContext(t.Context(), "make", "-C", dir)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
require.NoError(t, cmd.Run(), "failed to build plugin in %q", dir)

@ -96,14 +96,14 @@ func (r *SubprocessPluginRuntime) Metadata() Metadata {
return r.metadata
}
func (r *SubprocessPluginRuntime) Invoke(_ context.Context, input *Input) (*Output, error) {
func (r *SubprocessPluginRuntime) Invoke(ctx context.Context, input *Input) (*Output, error) {
switch input.Message.(type) {
case schema.InputMessageCLIV1:
return r.runCLI(input)
return r.runCLI(ctx, input)
case schema.InputMessageGetterV1:
return r.runGetter(input)
return r.runGetter(ctx, input)
case schema.InputMessagePostRendererV1:
return r.runPostrenderer(input)
return r.runPostrenderer(ctx, input)
default:
return nil, fmt.Errorf("unsupported subprocess plugin type %q", r.metadata.Type)
}
@ -113,7 +113,7 @@ func (r *SubprocessPluginRuntime) Invoke(_ context.Context, input *Input) (*Outp
// This method allows execution with different command/args than the plugin's default
func (r *SubprocessPluginRuntime) InvokeWithEnv(main string, argv []string, env []string, stdin io.Reader, stdout, stderr io.Writer) error {
mainCmdExp := os.ExpandEnv(main)
cmd := exec.Command(mainCmdExp, argv...)
cmd := exec.CommandContext(context.Background(), mainCmdExp, argv...)
cmd.Env = slices.Clone(os.Environ())
cmd.Env = append(
cmd.Env,
@ -149,7 +149,7 @@ func (r *SubprocessPluginRuntime) InvokeHook(event string) error {
return err
}
cmd := exec.Command(main, argv...)
cmd := exec.CommandContext(context.Background(), main, argv...)
cmd.Env = FormatEnv(env)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
@ -189,7 +189,7 @@ func executeCmd(prog *exec.Cmd, pluginName string) error {
return nil
}
func (r *SubprocessPluginRuntime) runCLI(input *Input) (*Output, error) {
func (r *SubprocessPluginRuntime) runCLI(ctx context.Context, input *Input) (*Output, error) {
if _, ok := input.Message.(schema.InputMessageCLIV1); !ok {
return nil, fmt.Errorf("plugin %q input message does not implement InputMessageCLIV1", r.metadata.Name)
}
@ -209,7 +209,7 @@ func (r *SubprocessPluginRuntime) runCLI(input *Input) (*Output, error) {
return nil, fmt.Errorf("failed to prepare plugin command: %w", err)
}
cmd := exec.Command(command, args...)
cmd := exec.CommandContext(ctx, command, args...)
cmd.Env = FormatEnv(env)
cmd.Stdin = input.Stdin
@ -226,7 +226,7 @@ func (r *SubprocessPluginRuntime) runCLI(input *Input) (*Output, error) {
}, nil
}
func (r *SubprocessPluginRuntime) runPostrenderer(input *Input) (*Output, error) {
func (r *SubprocessPluginRuntime) runPostrenderer(ctx context.Context, input *Input) (*Output, error) {
if _, ok := input.Message.(schema.InputMessagePostRendererV1); !ok {
return nil, fmt.Errorf("plugin %q input message does not implement InputMessagePostRendererV1", r.metadata.Name)
}
@ -244,7 +244,8 @@ func (r *SubprocessPluginRuntime) runPostrenderer(input *Input) (*Output, error)
return nil, fmt.Errorf("failed to prepare plugin command: %w", err)
}
cmd := exec.Command(
cmd := exec.CommandContext(
ctx,
command,
args...)

@ -17,6 +17,7 @@ package plugin
import (
"bytes"
"context"
"fmt"
"log/slog"
"maps"
@ -40,7 +41,7 @@ func getProtocolCommand(commands []SubprocessProtocolCommand, protocol string) *
}
// TODO can we replace a lot of this func with RuntimeSubprocess.invokeWithEnv?
func (r *SubprocessPluginRuntime) runGetter(input *Input) (*Output, error) {
func (r *SubprocessPluginRuntime) runGetter(ctx context.Context, input *Input) (*Output, error) {
msg, ok := (input.Message).(schema.InputMessageGetterV1)
if !ok {
return nil, fmt.Errorf("expected input type schema.InputMessageGetterV1, got %T", input)
@ -81,7 +82,8 @@ func (r *SubprocessPluginRuntime) runGetter(input *Input) (*Output, error) {
buf := bytes.Buffer{} // subprocess getters are expected to write content to stdout
pluginCommand := filepath.Join(r.pluginDir, command)
cmd := exec.Command(
cmd := exec.CommandContext(
ctx,
pluginCommand,
args...)
cmd.Env = FormatEnv(env)

@ -18,6 +18,7 @@ package action
import (
"bytes"
"context"
"errors"
"fmt"
"io"
@ -275,7 +276,7 @@ func splitAndDeannotate(postrendered, fallbackPrefix string) (map[string]string,
// TODO: As part of the refactor the duplicate code in cmd/helm/template.go should be removed
//
// This code has to do with writing files to disk.
func (cfg *Configuration) renderResources(ch *chart.Chart, values common.Values, releaseName, outputDir string, subNotes, useReleaseName, includeCrds bool, pr postrenderer.PostRenderer, interactWithRemote, enableDNS, hideSecret bool, postRenderStrategy PostRenderStrategy) ([]*release.Hook, *bytes.Buffer, string, error) {
func (cfg *Configuration) renderResources(ctx context.Context, ch *chart.Chart, values common.Values, releaseName, outputDir string, subNotes, useReleaseName, includeCrds bool, pr postrenderer.PostRenderer, interactWithRemote, enableDNS, hideSecret bool, postRenderStrategy PostRenderStrategy) ([]*release.Hook, *bytes.Buffer, string, error) {
var hs []*release.Hook
b := bytes.NewBuffer(nil)
@ -305,13 +306,13 @@ func (cfg *Configuration) renderResources(ch *chart.Chart, values common.Values,
e.EnableDNS = enableDNS
e.CustomTemplateFuncs = cfg.CustomTemplateFuncs
files, err2 = e.Render(ch, values)
files, err2 = e.RenderWithContext(ctx, ch, values)
} else {
var e engine.Engine
e.EnableDNS = enableDNS
e.CustomTemplateFuncs = cfg.CustomTemplateFuncs
files, err2 = e.Render(ch, values)
files, err2 = e.RenderWithContext(ctx, ch, values)
}
if err2 != nil {

@ -1823,7 +1823,7 @@ func TestRenderResources_PostRenderer_Success(t *testing.T) {
values := map[string]any{}
hooks, buf, notes, err := cfg.renderResources(
ch, values, "test-release", "", false, false, false,
t.Context(), ch, values, "test-release", "", false, false, false,
mockPR, false, false, false, PostRenderStrategyCombined,
)
@ -1870,7 +1870,7 @@ func TestRenderResources_PostRenderer_Error(t *testing.T) {
values := map[string]any{}
_, _, _, err := cfg.renderResources(
ch, values, "test-release", "", false, false, false,
t.Context(), ch, values, "test-release", "", false, false, false,
mockPR, false, false, false, PostRenderStrategyCombined,
)
@ -1898,7 +1898,7 @@ func TestRenderResources_PostRenderer_MergeError(t *testing.T) {
values := map[string]any{}
_, _, _, err := cfg.renderResources(
ch, values, "test-release", "", false, false, false,
t.Context(), ch, values, "test-release", "", false, false, false,
mockPR, false, false, false, PostRenderStrategyCombined,
)
@ -1920,7 +1920,7 @@ func TestRenderResources_PostRenderer_SplitError(t *testing.T) {
values := map[string]any{}
_, _, _, err := cfg.renderResources(
ch, values, "test-release", "", false, false, false,
t.Context(), ch, values, "test-release", "", false, false, false,
mockPR, false, false, false, PostRenderStrategyCombined,
)
@ -1941,7 +1941,7 @@ func TestRenderResources_PostRenderer_Integration(t *testing.T) {
values := map[string]any{}
hooks, buf, notes, err := cfg.renderResources(
ch, values, "test-release", "", false, false, false,
t.Context(), ch, values, "test-release", "", false, false, false,
mockPR, false, false, false, PostRenderStrategyCombined,
)
@ -1980,7 +1980,7 @@ func TestRenderResources_NoPostRenderer(t *testing.T) {
values := map[string]any{}
hooks, buf, notes, err := cfg.renderResources(
ch, values, "test-release", "", false, false, false,
t.Context(), ch, values, "test-release", "", false, false, false,
nil, false, false, false, PostRenderStrategyCombined,
)
@ -2041,7 +2041,7 @@ spec:
}
hooks, buf, _, err := cfg.renderResources(
ch, nil, "test-release", "", false, false, false,
t.Context(), ch, nil, "test-release", "", false, false, false,
mockPR, false, false, false, PostRenderStrategySeparate,
)
@ -2083,7 +2083,7 @@ metadata:
}
_, _, _, err := cfg.renderResources(
ch, nil, "test-release", "", false, false, false,
t.Context(), ch, nil, "test-release", "", false, false, false,
mockPR, false, false, false, PostRenderStrategyCombined,
)
@ -2119,7 +2119,7 @@ metadata:
}
_, _, _, err := cfg.renderResources(
ch, nil, "test-release", "", false, false, false,
t.Context(), ch, nil, "test-release", "", false, false, false,
mockPR, false, false, false, PostRenderStrategy(""),
)
@ -2153,7 +2153,7 @@ metadata:
}
_, _, _, err := cfg.renderResources(
ch, nil, "test-release", "", false, false, false,
t.Context(), ch, nil, "test-release", "", false, false, false,
mockPR, false, false, false, PostRenderStrategySeparate,
)
@ -2187,7 +2187,7 @@ metadata:
}
_, _, _, err := cfg.renderResources(
ch, nil, "test-release", "", false, false, false,
t.Context(), ch, nil, "test-release", "", false, false, false,
mockPR, false, false, false, PostRenderStrategySeparate,
)
@ -2221,7 +2221,7 @@ metadata:
}
hooks, manifestDoc, _, err := cfg.renderResources(
ch, nil, "test-release", "", false, false, false,
t.Context(), ch, nil, "test-release", "", false, false, false,
mockPR, false, false, false, PostRenderStrategyNoHooks,
)
@ -2258,7 +2258,7 @@ metadata:
}
_, _, _, err := cfg.renderResources(
ch, nil, "test-release", "", false, false, false,
t.Context(), ch, nil, "test-release", "", false, false, false,
mockPR, false, false, false, PostRenderStrategyNoHooks,
)
@ -2280,7 +2280,7 @@ metadata:
mockPR := &mockPostRenderer{}
_, _, _, err := cfg.renderResources(
ch, nil, "test-release", "", false, false, false,
t.Context(), ch, nil, "test-release", "", false, false, false,
mockPR, false, false, false, PostRenderStrategy("bogus"),
)

@ -375,7 +375,7 @@ func (i *Install) RunWithContext(ctx context.Context, ch ci.Charter, vals map[st
rel := i.createRelease(chrt, vals, i.Labels)
var manifestDoc *bytes.Buffer
rel.Hooks, manifestDoc, rel.Info.Notes, err = i.cfg.renderResources(chrt, valuesToRender, i.ReleaseName, i.OutputDir, i.SubNotes, i.UseReleaseName, i.IncludeCRDs, i.PostRenderer, interactWithServer(i.DryRunStrategy), i.EnableDNS, i.HideSecret, i.PostRenderStrategy)
rel.Hooks, manifestDoc, rel.Info.Notes, err = i.cfg.renderResources(ctx, chrt, valuesToRender, i.ReleaseName, i.OutputDir, i.SubNotes, i.UseReleaseName, i.IncludeCRDs, i.PostRenderer, interactWithServer(i.DryRunStrategy), i.EnableDNS, i.HideSecret, i.PostRenderStrategy)
// Even for errors, attach this if available
if manifestDoc != nil {
rel.Manifest = manifestDoc.String()

@ -193,7 +193,7 @@ func (u *Upgrade) RunWithContext(ctx context.Context, name string, ch chart.Char
}
u.cfg.Logger().Debug("preparing upgrade", "name", name)
currentRelease, upgradedRelease, serverSideApply, err := u.prepareUpgrade(name, chrt, vals)
currentRelease, upgradedRelease, serverSideApply, err := u.prepareUpgrade(ctx, name, chrt, vals)
if err != nil {
return nil, err
}
@ -218,7 +218,7 @@ func (u *Upgrade) RunWithContext(ctx context.Context, name string, ch chart.Char
}
// prepareUpgrade builds an upgraded release for an upgrade operation.
func (u *Upgrade) prepareUpgrade(name string, chart *chartv2.Chart, vals map[string]any) (*release.Release, *release.Release, bool, error) {
func (u *Upgrade) prepareUpgrade(ctx context.Context, name string, chart *chartv2.Chart, vals map[string]any) (*release.Release, *release.Release, bool, error) {
if chart == nil {
return nil, nil, false, errMissingChart
}
@ -300,7 +300,7 @@ func (u *Upgrade) prepareUpgrade(name string, chart *chartv2.Chart, vals map[str
return nil, nil, false, err
}
hooks, manifestDoc, notesTxt, err := u.cfg.renderResources(chart, valuesToRender, "", "", u.SubNotes, false, false, u.PostRenderer, interactWithServer(u.DryRunStrategy), u.EnableDNS, u.HideSecret, u.PostRenderStrategy)
hooks, manifestDoc, notesTxt, err := u.cfg.renderResources(ctx, chart, valuesToRender, "", "", u.SubNotes, false, false, u.PostRenderer, interactWithServer(u.DryRunStrategy), u.EnableDNS, u.HideSecret, u.PostRenderStrategy)
if err != nil {
return nil, nil, false, err
}

@ -18,6 +18,7 @@ package util
import (
"bytes"
"context"
"crypto/tls"
"errors"
"fmt"
@ -41,7 +42,7 @@ type HTTPURLLoader http.Client
func (l *HTTPURLLoader) Load(urlStr string) (any, error) {
client := (*http.Client)(l)
req, err := http.NewRequest(http.MethodGet, urlStr, nil)
req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, urlStr, http.NoBody)
if err != nil {
return nil, fmt.Errorf("failed to create HTTP request for %s: %w", urlStr, err)
}

@ -19,6 +19,7 @@ package rules
import (
"bufio"
"bytes"
"context"
"errors"
"fmt"
"io"
@ -134,7 +135,7 @@ func (t *templateLinter) Lint() {
}
var e engine.Engine
e.LintMode = true
renderedContentMap, err := e.Render(chart, valuesToRender)
renderedContentMap, err := e.RenderWithContext(context.Background(), chart, valuesToRender)
renderOk := t.linter.RunLinterRule(support.ErrorSev, templatesDir, err)

@ -17,6 +17,7 @@ limitations under the License.
package cmd
import (
"context"
"errors"
"fmt"
"io"
@ -65,8 +66,8 @@ func newSearchHubCmd(out io.Writer) *cobra.Command {
Use: "hub [KEYWORD]",
Short: "search for charts in the Artifact Hub or your own hub instance",
Long: searchHubDesc,
RunE: func(_ *cobra.Command, args []string) error {
return o.run(out, args)
RunE: func(c *cobra.Command, args []string) error {
return o.run(c.Context(), out, args)
},
}
@ -81,14 +82,14 @@ func newSearchHubCmd(out io.Writer) *cobra.Command {
return cmd
}
func (o *searchHubOptions) run(out io.Writer, args []string) error {
func (o *searchHubOptions) run(ctx context.Context, out io.Writer, args []string) error {
c, err := monocular.New(o.searchEndpoint)
if err != nil {
return fmt.Errorf("unable to create connection to %q: %w", o.searchEndpoint, err)
}
q := strings.Join(args, " ")
results, err := c.Search(q)
results, err := c.SearchWithContext(ctx, q)
if err != nil {
slog.Debug("search failed", slog.Any("error", err))
return fmt.Errorf("unable to perform search against %q", o.searchEndpoint)

@ -17,6 +17,7 @@ limitations under the License.
package engine
import (
"context"
"errors"
"fmt"
"log/slog"
@ -76,9 +77,34 @@ func New(config *rest.Config) Engine {
// that section of the values will be passed into the "foo" chart. And if that
// section contains a value named "bar", that value will be passed on to the
// bar chart during render time.
//
// Deprecated: Use RenderWithContext instead.
func (e Engine) Render(chrt ci.Charter, values common.Values) (map[string]string, error) {
return e.RenderWithContext(context.Background(), chrt, values)
}
// RenderWithContext takes a chart, optional values, and value overrides, and attempts to render the Go templates.
//
// RenderWithContext can be called repeatedly on the same engine.
//
// This will look in the chart's 'templates' data (e.g. the 'templates/' directory)
// and attempt to render the templates there using the values passed in.
//
// Values are scoped to their templates. A dependency template will not have
// access to the values set for its parent. If chart "foo" includes chart "bar",
// "bar" will not have access to the values for "foo".
//
// Values should be prepared with something like `chartutils.ReadValues`.
//
// Values are passed through the templates according to scope. If the top layer
// chart includes the chart foo, which includes the chart bar, the values map
// will be examined for a table called "foo". If "foo" is found in vals,
// that section of the values will be passed into the "foo" chart. And if that
// section contains a value named "bar", that value will be passed on to the
// bar chart during render time.
func (e Engine) RenderWithContext(ctx context.Context, chrt ci.Charter, values common.Values) (map[string]string, error) {
tmap := allTemplates(chrt, values)
return e.render(tmap)
return e.render(ctx, tmap)
}
// Render takes a chart, optional values, and value overrides, and attempts to
@ -195,7 +221,7 @@ func tplFun(parent *template.Template, includedNames map[string]int, strict bool
}
// initFunMap creates the Engine's FuncMap and adds context-specific functions.
func (e Engine) initFunMap(t *template.Template) {
func (e Engine) initFunMap(ctx context.Context, t *template.Template) {
funcMap := funcMap()
includedNames := make(map[string]int)
@ -238,7 +264,7 @@ func (e Engine) initFunMap(t *template.Template) {
// If we are not linting and have a cluster connection, provide a Kubernetes-backed
// implementation.
if !e.LintMode && e.clientProvider != nil {
funcMap["lookup"] = newLookupFunction(*e.clientProvider)
funcMap["lookup"] = newLookupFunction(ctx, *e.clientProvider)
}
// When DNS lookups are not enabled override the sprig function and return
@ -256,7 +282,7 @@ func (e Engine) initFunMap(t *template.Template) {
}
// render takes a map of templates/values and renders them.
func (e Engine) render(tpls map[string]renderable) (rendered map[string]string, err error) {
func (e Engine) render(ctx context.Context, tpls map[string]renderable) (rendered map[string]string, err error) {
// Basically, what we do here is start with an empty parent template and then
// build up a list of templates -- one for each file. Once all of the templates
// have been parsed, we loop through again and execute every template.
@ -278,7 +304,7 @@ func (e Engine) render(tpls map[string]renderable) (rendered map[string]string,
t.Option("missingkey=zero")
}
e.initFunMap(t)
e.initFunMap(ctx, t)
// We want to parse the templates in a predictable order. The order favors
// higher-level (in file system) templates over deeply nested templates.

@ -197,7 +197,7 @@ func TestRenderInternals(t *testing.T) {
"three": {tpl: `{{template "two" dict "Value" "three"}}`, vals: vals},
}
out, err := new(Engine).render(tpls)
out, err := new(Engine).render(t.Context(), tpls)
if err != nil {
t.Fatalf("Failed template rendering: %s", err)
}
@ -443,7 +443,7 @@ func TestParallelRenderInternals(t *testing.T) {
vals: map[string]any{"val": tt},
},
}
out, err := e.render(tpls)
out, err := e.render(t.Context(), tpls)
if err != nil {
t.Errorf("Failed to render %s: %s", tt, err)
}
@ -462,7 +462,7 @@ func TestParseErrors(t *testing.T) {
tplsUndefinedFunction := map[string]renderable{
"undefined_function": {tpl: `{{foo}}`, vals: vals},
}
_, err := new(Engine).render(tplsUndefinedFunction)
_, err := new(Engine).render(t.Context(), tplsUndefinedFunction)
if err == nil {
t.Fatalf("Expected failures while rendering: %s", err)
}
@ -525,7 +525,7 @@ linebreak`,
for _, tt := range cases {
t.Run(tt.name, func(t *testing.T) {
_, err := new(Engine).render(tt.tpls)
_, err := new(Engine).render(t.Context(), tt.tpls)
if err == nil {
t.Fatalf("Expected failures while rendering: %s", err)
}
@ -543,7 +543,7 @@ func TestFailErrors(t *testing.T) {
tplsFailed := map[string]renderable{
"failtpl": {tpl: failtpl, vals: vals},
}
_, err := new(Engine).render(tplsFailed)
_, err := new(Engine).render(t.Context(), tplsFailed)
if err == nil {
t.Fatalf("Expected failures while rendering: %s", err)
}
@ -554,7 +554,7 @@ func TestFailErrors(t *testing.T) {
var e Engine
e.LintMode = true
out, err := e.render(tplsFailed)
out, err := e.render(t.Context(), tplsFailed)
if err != nil {
t.Fatal(err)
}

@ -36,7 +36,7 @@ type lookupFunc = func(apiversion string, resource string, namespace string, nam
//
// If the resource does not exist, no error is raised.
func NewLookupFunction(config *rest.Config) lookupFunc { //nolint:revive
return newLookupFunction(clientProviderFromConfig{config: config})
return newLookupFunction(context.Background(), clientProviderFromConfig{config: config})
}
type ClientProvider interface {
@ -54,7 +54,7 @@ func (c clientProviderFromConfig) GetClientFor(apiVersion, kind string) (dynamic
return getDynamicClientOnKind(apiVersion, kind, c.config)
}
func newLookupFunction(clientProvider ClientProvider) lookupFunc {
func newLookupFunction(ctx context.Context, clientProvider ClientProvider) lookupFunc {
return func(apiversion string, kind string, namespace string, name string) (map[string]any, error) {
var client dynamic.ResourceInterface
c, namespaced, err := clientProvider.GetClientFor(apiversion, kind)
@ -68,7 +68,7 @@ func newLookupFunction(clientProvider ClientProvider) lookupFunc {
}
if name != "" {
// this will return a single object
obj, err := client.Get(context.Background(), name, metav1.GetOptions{})
obj, err := client.Get(ctx, name, metav1.GetOptions{})
if err != nil {
if apierrors.IsNotFound(err) {
// Just return an empty interface when the object was not found.
@ -86,7 +86,7 @@ func newLookupFunction(clientProvider ClientProvider) lookupFunc {
return obj.UnstructuredContent(), nil
}
// this will return a list
obj, err := client.List(context.Background(), metav1.ListOptions{})
obj, err := client.List(ctx, metav1.ListOptions{})
if err != nil {
if apierrors.IsNotFound(err) {
// Just return an empty interface when the object was not found.

@ -17,6 +17,7 @@ package getter
import (
"bytes"
"context"
"crypto/tls"
"fmt"
"io"
@ -49,7 +50,7 @@ func (g *HTTPGetter) Get(href string, options ...Option) (*bytes.Buffer, error)
func (g *HTTPGetter) get(href string, opts getterOptions) (*bytes.Buffer, error) {
// Set a helm specific user agent so that a repo server and metrics can
// separate helm calls from other tools interacting with repos.
req, err := http.NewRequest(http.MethodGet, href, nil)
req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, href, http.NoBody)
if err != nil {
return nil, err
}

@ -108,7 +108,7 @@ func (c *ReadyChecker) IsReady(ctx context.Context, v *resource.Info) (bool, err
return c.pausedAsReady, nil
}
// Find RS associated with deployment
newReplicaSet, err := deploymentutil.GetNewReplicaSet(currentDeployment, c.client.AppsV1())
newReplicaSet, err := deploymentutil.GetNewReplicaSet(currentDeployment, c.client.AppsV1()) //nolint:contextcheck
if err != nil || newReplicaSet == nil {
return false, err
}

@ -25,6 +25,7 @@ import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
type fakeRoundTripper struct {
@ -134,15 +135,15 @@ func TestRetryingRoundTripper_RoundTrip(t *testing.T) {
rt := RetryingRoundTripper{
Wrapped: fakeRT,
}
req, _ := http.NewRequest(http.MethodGet, "http://example.com", nil)
req, err := http.NewRequestWithContext(t.Context(), http.MethodGet, "http://example.com", http.NoBody)
require.NoError(t, err)
resp, err := rt.RoundTrip(req)
if tt.expectedErr != "" {
assert.Error(t, err)
assert.Contains(t, err.Error(), tt.expectedErr)
require.ErrorContains(t, err, tt.expectedErr)
return
}
assert.NoError(t, err)
require.NoError(t, err)
assert.Equal(t, tt.expectedCode, resp.StatusCode)
assert.Equal(t, tt.expectedCalls, fakeRT.calls)

@ -18,7 +18,6 @@ package registry
import (
"bytes"
"context"
"crypto/tls"
"fmt"
"io"
@ -125,7 +124,8 @@ func setup(suite *TestRegistry, tlsEnabled, insecure bool) {
// Registry config
config := &configuration.Configuration{}
ln, err := net.Listen("tcp", "127.0.0.1:0")
lnCfg := net.ListenConfig{}
ln, err := lnCfg.Listen(suite.T().Context(), "tcp", "127.0.0.1:0")
suite.Require().NoError(err, "no error finding free port for test registry")
defer func() { _ = ln.Close() }()
@ -158,7 +158,7 @@ func setup(suite *TestRegistry, tlsEnabled, insecure bool) {
config.HTTP.TLS.ClientCAs = []string{tlsCA}
}
}
suite.dockerRegistry, err = registry.NewRegistry(context.Background(), config)
suite.dockerRegistry, err = registry.NewRegistry(suite.T().Context(), config)
suite.Require().NoError(err, "no error creating test registry")
suite.FakeRegistryHost = initFakeRegistryTestServer()
@ -170,7 +170,7 @@ func setup(suite *TestRegistry, tlsEnabled, insecure bool) {
func teardown(suite *TestRegistry) {
if suite.dockerRegistry != nil {
_ = suite.dockerRegistry.Shutdown(context.Background())
_ = suite.dockerRegistry.Shutdown(suite.T().Context())
}
}

@ -180,7 +180,8 @@ func NewOCIServer(t *testing.T, dir string) (*OCIServer, error) {
// Registry config
config := &configuration.Configuration{}
ln, err := net.Listen("tcp", "127.0.0.1:0")
lnCfg := net.ListenConfig{}
ln, err := lnCfg.Listen(t.Context(), "tcp", "127.0.0.1:0")
if err != nil {
t.Fatalf("error finding free port for test registry: %v", err)
}

@ -22,6 +22,7 @@ import (
"strings"
"testing"
"github.com/stretchr/testify/require"
"sigs.k8s.io/yaml"
"helm.sh/helm/v4/internal/test/ensure"
@ -52,26 +53,24 @@ func TestServer(t *testing.T) {
t.Errorf("Unexpected chart: %s", c[0])
}
res, err := http.Get(srv.URL() + "/examplechart-0.1.0.tgz")
req, err := http.NewRequestWithContext(t.Context(), http.MethodGet, srv.URL()+"/examplechart-0.1.0.tgz", http.NoBody)
require.NoError(t, err)
client := http.DefaultClient
res, err := client.Do(req)
require.NoError(t, err)
res.Body.Close()
if err != nil {
t.Fatal(err)
}
if res.ContentLength < 500 {
t.Errorf("Expected at least 500 bytes of data, got %d", res.ContentLength)
}
res, err = http.Get(srv.URL() + "/index.yaml")
if err != nil {
t.Fatal(err)
}
req, err = http.NewRequestWithContext(t.Context(), http.MethodGet, srv.URL()+"/index.yaml", http.NoBody)
require.NoError(t, err)
res, err = client.Do(req)
require.NoError(t, err)
data, err := io.ReadAll(res.Body)
res.Body.Close()
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
m := repo.NewIndexFile()
if err := yaml.Unmarshal(data, m); err != nil {
@ -87,11 +86,11 @@ func TestServer(t *testing.T) {
t.Errorf("missing %q", expect)
}
res, err = http.Get(srv.URL() + "/index.yaml-nosuchthing")
req, err = http.NewRequestWithContext(t.Context(), http.MethodGet, srv.URL()+"/index.yaml-nosuchthing", http.NoBody)
require.NoError(t, err)
res, err = client.Do(req)
require.NoError(t, err)
res.Body.Close()
if err != nil {
t.Fatal(err)
}
if res.StatusCode != http.StatusNotFound {
t.Fatalf("Expected 404, got %d", res.StatusCode)
}
@ -133,70 +132,56 @@ func TestNewTempServer(t *testing.T) {
client := srv.Client()
{
res, err := client.Head(srv.URL() + "/repositories.yaml")
if err != nil {
t.Error(err)
}
req, err := http.NewRequestWithContext(t.Context(), http.MethodHead, srv.URL()+"/repositories.yaml", http.NoBody)
require.NoError(t, err)
res, err := client.Do(req)
require.NoError(t, err)
res.Body.Close()
if res.StatusCode != http.StatusOK {
t.Errorf("Expected 200, got %d", res.StatusCode)
}
}
{
res, err := client.Head(srv.URL() + "/examplechart-0.1.0.tgz")
if err != nil {
t.Error(err)
}
req, err := http.NewRequestWithContext(t.Context(), http.MethodHead, srv.URL()+"/examplechart-0.1.0.tgz", http.NoBody)
require.NoError(t, err)
res, err := client.Do(req)
require.NoError(t, err)
res.Body.Close()
if res.StatusCode != http.StatusOK {
t.Errorf("Expected 200, got %d", res.StatusCode)
}
}
res, err := client.Get(srv.URL() + "/examplechart-0.1.0.tgz")
req, err := http.NewRequestWithContext(t.Context(), http.MethodGet, srv.URL()+"/examplechart-0.1.0.tgz", http.NoBody)
require.NoError(t, err)
res, err := client.Do(req)
require.NoError(t, err)
res.Body.Close()
if err != nil {
t.Fatal(err)
}
if res.ContentLength < 500 {
t.Errorf("Expected at least 500 bytes of data, got %d", res.ContentLength)
}
res, err = client.Get(srv.URL() + "/index.yaml")
if err != nil {
t.Fatal(err)
}
req, err = http.NewRequestWithContext(t.Context(), http.MethodGet, srv.URL()+"/index.yaml", http.NoBody)
require.NoError(t, err)
res, err = client.Do(req)
require.NoError(t, err)
data, err := io.ReadAll(res.Body)
res.Body.Close()
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
m := repo.NewIndexFile()
if err := yaml.Unmarshal(data, m); err != nil {
t.Fatal(err)
}
if l := len(m.Entries); l != 1 {
t.Fatalf("Expected 1 entry, got %d", l)
}
expect := "examplechart"
if !m.Has(expect, "0.1.0") {
t.Errorf("missing %q", expect)
}
res, err = client.Get(srv.URL() + "/index.yaml-nosuchthing")
req, err = http.NewRequestWithContext(t.Context(), http.MethodGet, srv.URL()+"/index.yaml-nosuchthing", http.NoBody)
require.NoError(t, err)
res, err = client.Do(req)
require.NoError(t, err)
res.Body.Close()
if err != nil {
t.Fatal(err)
}
if res.StatusCode != http.StatusNotFound {
t.Fatalf("Expected 404, got %d", res.StatusCode)
}

Loading…
Cancel
Save