feat: use main func ctx for cobra and use ctx in tests

Explicitly create the context and set it on the CLI, instead of depending on
NewDockerCli() to instance a default context.

Co-authored-by: Sebastiaan van Stijn <github@gone.nl>
Co-authored-by: Alano Terblanche <18033717+Benehiko@users.noreply.github.com>

Signed-off-by: Alano Terblanche <18033717+Benehiko@users.noreply.github.com>
This commit is contained in:
Sebastiaan van Stijn 2024-01-11 18:25:23 +01:00 committed by Alano Terblanche
parent 865190615b
commit 86162f7816
No known key found for this signature in database
GPG Key ID: 0E8FACD1BA98DE27
6 changed files with 34 additions and 12 deletions

View File

@ -36,13 +36,7 @@ func RunPlugin(dockerCli *command.DockerCli, plugin *cobra.Command, meta manager
PersistentPreRunE = func(cmd *cobra.Command, _ []string) error {
var err error
persistentPreRunOnce.Do(func() {
cmdContext := cmd.Context()
// TODO: revisit and make sure this check makes sense
// see: https://github.com/docker/cli/pull/4599#discussion_r1422487271
if cmdContext == nil {
cmdContext = context.TODO()
}
ctx, cancel := context.WithCancel(cmdContext)
ctx, cancel := context.WithCancel(cmd.Context())
cmd.SetContext(ctx)
// Set up the context to cancel based on signalling via CLI socket.
socket.ConnectAndWait(cancel)

View File

@ -23,6 +23,9 @@ import (
var pluginFilename = "docker-buildx"
func TestBuildWithBuilder(t *testing.T) {
ctx, cancel := context.WithCancel(context.TODO())
defer cancel()
testcases := []struct {
name string
context string
@ -64,12 +67,16 @@ echo '{"SchemaVersion":"0.1.0","Vendor":"Docker Inc.","Version":"v0.6.3","ShortD
for _, tt := range testcases {
tt := tt
t.Run(tt.name, func(t *testing.T) {
ctx2, cancel2 := context.WithCancel(ctx)
defer cancel2()
if tt.builder != "" {
t.Setenv("BUILDX_BUILDER", tt.builder)
}
var b bytes.Buffer
dockerCli, err := command.NewDockerCli(
command.WithBaseContext(ctx2),
command.WithAPIClient(&fakeClient{}),
command.WithInputStream(discard),
command.WithCombinedStreams(&b),
@ -126,6 +133,9 @@ func (c *fakeClient) Ping(_ context.Context) (types.Ping, error) {
}
func TestBuildkitDisabled(t *testing.T) {
ctx, cancel := context.WithCancel(context.TODO())
defer cancel()
t.Setenv("DOCKER_BUILDKIT", "0")
dir := fs.NewDir(t, t.Name(),
@ -136,6 +146,7 @@ func TestBuildkitDisabled(t *testing.T) {
b := bytes.NewBuffer(nil)
dockerCli, err := command.NewDockerCli(
command.WithBaseContext(ctx),
command.WithAPIClient(&fakeClient{}),
command.WithInputStream(discard),
command.WithCombinedStreams(b),
@ -163,6 +174,9 @@ func TestBuildkitDisabled(t *testing.T) {
}
func TestBuilderBroken(t *testing.T) {
ctx, cancel := context.WithCancel(context.TODO())
defer cancel()
dir := fs.NewDir(t, t.Name(),
fs.WithFile(pluginFilename, `#!/bin/sh exit 1`, fs.WithMode(0o777)),
)
@ -171,6 +185,7 @@ func TestBuilderBroken(t *testing.T) {
b := bytes.NewBuffer(nil)
dockerCli, err := command.NewDockerCli(
command.WithBaseContext(ctx),
command.WithAPIClient(&fakeClient{}),
command.WithInputStream(discard),
command.WithCombinedStreams(b),
@ -199,6 +214,8 @@ func TestBuilderBroken(t *testing.T) {
func TestBuilderBrokenEnforced(t *testing.T) {
t.Setenv("DOCKER_BUILDKIT", "1")
ctx, cancel := context.WithCancel(context.TODO())
defer cancel()
dir := fs.NewDir(t, t.Name(),
fs.WithFile(pluginFilename, `#!/bin/sh exit 1`, fs.WithMode(0o777)),
@ -208,6 +225,7 @@ func TestBuilderBrokenEnforced(t *testing.T) {
b := bytes.NewBuffer(nil)
dockerCli, err := command.NewDockerCli(
command.WithBaseContext(ctx),
command.WithAPIClient(&fakeClient{}),
command.WithInputStream(discard),
command.WithCombinedStreams(b),

View File

@ -29,6 +29,7 @@ import (
func main() {
ctx := context.Background()
dockerCli, err := command.NewDockerCli(command.WithBaseContext(ctx))
if err != nil {
fmt.Fprintln(os.Stderr, err)
@ -352,7 +353,7 @@ func runDocker(ctx context.Context, dockerCli *command.DockerCli) error {
// We've parsed global args already, so reset args to those
// which remain.
cmd.SetArgs(args)
err = cmd.Execute()
err = cmd.ExecuteContext(ctx)
// If the command is being executed in an interactive terminal
// and hook are enabled, run the plugin hooks.

View File

@ -2,6 +2,7 @@ package main
import (
"bytes"
"context"
"io"
"os"
"testing"
@ -15,8 +16,10 @@ import (
func TestClientDebugEnabled(t *testing.T) {
defer debug.Disable()
ctx, cancel := context.WithCancel(context.TODO())
defer cancel()
cli, err := command.NewDockerCli()
cli, err := command.NewDockerCli(command.WithBaseContext(ctx))
assert.NilError(t, err)
tcmd := newDockerCommand(cli)
tcmd.SetFlag("debug", "true")
@ -39,7 +42,13 @@ func runCliCommand(t *testing.T, r io.ReadCloser, w io.Writer, args ...string) e
if w == nil {
w = io.Discard
}
cli, err := command.NewDockerCli(command.WithInputStream(r), command.WithCombinedStreams(w))
ctx, cancel := context.WithCancel(context.TODO())
defer cancel()
cli, err := command.NewDockerCli(
command.WithBaseContext(ctx),
command.WithInputStream(r),
command.WithCombinedStreams(w))
assert.NilError(t, err)
tcmd := newDockerCommand(cli)

View File

@ -37,6 +37,7 @@ func gen(opts *options) error {
Use: "docker [OPTIONS] COMMAND [ARG...]",
Short: "The base command for the Docker CLI.",
}
clientOpts, _ := cli.SetupRootCommand(cmd)
if err := dockerCLI.Initialize(clientOpts); err != nil {
return err

View File

@ -11,7 +11,7 @@ import (
func main() {
plugin.Run(func(dockerCli command.Cli) *cobra.Command {
cmd := &cobra.Command{
return &cobra.Command{
Use: "nopersistentprerun",
Short: "Testing without PersistentPreRun hooks",
// PersistentPreRunE: Not specified, we need to test that it works in the absence of an explicit call
@ -25,7 +25,6 @@ func main() {
return nil
},
}
return cmd
},
manager.Metadata{
SchemaVersion: "0.1.0",