github.com/kaisenlinux/docker@v0.0.0-20230510090727-ea55db55fac7/swarmkit/agent/exec/dockerapi/controller_integration_test.go (about) 1 package dockerapi 2 3 import ( 4 "context" 5 "flag" 6 "testing" 7 8 engineapi "github.com/docker/docker/client" 9 "github.com/docker/swarmkit/agent/exec" 10 "github.com/docker/swarmkit/api" 11 "github.com/docker/swarmkit/api/genericresource" 12 "github.com/stretchr/testify/assert" 13 ) 14 15 var ( 16 dockerTestAddr string 17 ) 18 19 func init() { 20 flag.StringVar(&dockerTestAddr, "test.docker.addr", "", "Set the address of the docker instance for testing") 21 } 22 23 // TestControllerFlowIntegration simply runs the Controller flow against a docker 24 // instance to make sure we don't blow up. 25 // 26 // This is great for ad-hoc testing while doing development. We can add more 27 // verification but it solves the problem of not being able to run tasks 28 // without a swarm setup. 29 // 30 // Run with something like this: 31 // 32 // go test -run TestControllerFlowIntegration -test.docker.addr unix:///var/run/docker.sock 33 // 34 func TestControllerFlowIntegration(t *testing.T) { 35 if dockerTestAddr == "" { 36 t.Skip("specify docker address to run integration") 37 } 38 39 ctx := context.Background() 40 client, err := engineapi.NewClient(dockerTestAddr, "", nil, nil) 41 assert.NoError(t, err) 42 assert.NotNil(t, client) 43 44 available := genericresource.NewSet("apple", "blue", "red") 45 available = append(available, genericresource.NewDiscrete("orange", 3)) 46 47 task := &api.Task{ 48 ID: "dockerexec-integration-task-id", 49 ServiceID: "dockerexec-integration-service-id", 50 NodeID: "dockerexec-integration-node-id", 51 ServiceAnnotations: api.Annotations{ 52 Name: "dockerexec-integration", 53 }, 54 Spec: api.TaskSpec{ 55 Runtime: &api.TaskSpec_Container{ 56 Container: &api.ContainerSpec{ 57 Command: []string{"sh", "-c", "sleep 5; echo $apple $orange; echo stderr >&2"}, 58 Image: "alpine", 59 }, 60 }, 61 }, 62 AssignedGenericResources: available, 63 } 64 65 var receivedLogs bool 66 publisher := exec.LogPublisherFunc(func(ctx context.Context, message api.LogMessage) error { 67 receivedLogs = true 68 v1 := genericresource.Value(available[0]) 69 v2 := genericresource.Value(available[1]) 70 genericResourceString := v1 + " " + v2 + "\n" 71 72 switch message.Stream { 73 case api.LogStreamStdout: 74 assert.Equal(t, genericResourceString, string(message.Data)) 75 case api.LogStreamStderr: 76 assert.Equal(t, "stderr\n", string(message.Data)) 77 } 78 79 t.Log(message) 80 return nil 81 }) 82 83 ctlr, err := newController(client, nil, task, nil) 84 assert.NoError(t, err) 85 assert.NotNil(t, ctlr) 86 assert.NoError(t, ctlr.Prepare(ctx)) 87 assert.NoError(t, ctlr.Start(ctx)) 88 assert.NoError(t, ctlr.(exec.ControllerLogs).Logs(ctx, publisher, api.LogSubscriptionOptions{ 89 Follow: true, 90 })) 91 assert.NoError(t, ctlr.Wait(ctx)) 92 assert.True(t, receivedLogs) 93 assert.NoError(t, ctlr.Shutdown(ctx)) 94 assert.NoError(t, ctlr.Remove(ctx)) 95 assert.NoError(t, ctlr.Close()) 96 97 // NOTE(stevvooe): testify has no clue how to correctly do error equality. 98 if err := ctlr.Close(); err != exec.ErrControllerClosed { 99 t.Fatalf("expected controller to be closed: %v", err) 100 } 101 }