github.com/docker/docker@v299999999.0.0-20200612211812-aaf470eca7b5+incompatible/integration/system/event_test.go (about)

     1  package system // import "github.com/docker/docker/integration/system"
     2  
     3  import (
     4  	"context"
     5  	"encoding/json"
     6  	"io"
     7  	"net/http"
     8  	"net/url"
     9  	"strconv"
    10  	"testing"
    11  	"time"
    12  
    13  	"github.com/docker/docker/api/types"
    14  	"github.com/docker/docker/api/types/filters"
    15  	"github.com/docker/docker/api/types/strslice"
    16  	"github.com/docker/docker/api/types/versions"
    17  	"github.com/docker/docker/integration/internal/container"
    18  	"github.com/docker/docker/pkg/jsonmessage"
    19  	"github.com/docker/docker/testutil/request"
    20  	req "github.com/docker/docker/testutil/request"
    21  	"gotest.tools/v3/assert"
    22  	is "gotest.tools/v3/assert/cmp"
    23  	"gotest.tools/v3/skip"
    24  )
    25  
    26  func TestEventsExecDie(t *testing.T) {
    27  	skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.36"), "broken in earlier versions")
    28  	skip.If(t, testEnv.OSType == "windows", "FIXME. Suspect may need to wait until container is running before exec")
    29  	defer setupTest(t)()
    30  	ctx := context.Background()
    31  	client := testEnv.APIClient()
    32  
    33  	cID := container.Run(ctx, t, client)
    34  
    35  	id, err := client.ContainerExecCreate(ctx, cID,
    36  		types.ExecConfig{
    37  			Cmd: strslice.StrSlice([]string{"echo", "hello"}),
    38  		},
    39  	)
    40  	assert.NilError(t, err)
    41  
    42  	filters := filters.NewArgs(
    43  		filters.Arg("container", cID),
    44  		filters.Arg("event", "exec_die"),
    45  	)
    46  	msg, errors := client.Events(ctx, types.EventsOptions{
    47  		Filters: filters,
    48  	})
    49  
    50  	err = client.ContainerExecStart(ctx, id.ID,
    51  		types.ExecStartCheck{
    52  			Detach: true,
    53  			Tty:    false,
    54  		},
    55  	)
    56  	assert.NilError(t, err)
    57  
    58  	select {
    59  	case m := <-msg:
    60  		assert.Equal(t, m.Type, "container")
    61  		assert.Equal(t, m.Actor.ID, cID)
    62  		assert.Equal(t, m.Action, "exec_die")
    63  		assert.Equal(t, m.Actor.Attributes["execID"], id.ID)
    64  		assert.Equal(t, m.Actor.Attributes["exitCode"], "0")
    65  	case err = <-errors:
    66  		assert.NilError(t, err)
    67  	case <-time.After(time.Second * 3):
    68  		t.Fatal("timeout hit")
    69  	}
    70  
    71  }
    72  
    73  // Test case for #18888: Events messages have been switched from generic
    74  // `JSONMessage` to `events.Message` types. The switch does not break the
    75  // backward compatibility so old `JSONMessage` could still be used.
    76  // This test verifies that backward compatibility maintains.
    77  func TestEventsBackwardsCompatible(t *testing.T) {
    78  	skip.If(t, testEnv.OSType == "windows", "Windows doesn't support back-compat messages")
    79  	defer setupTest(t)()
    80  	ctx := context.Background()
    81  	client := testEnv.APIClient()
    82  
    83  	since := request.DaemonTime(ctx, t, client, testEnv)
    84  	ts := strconv.FormatInt(since.Unix(), 10)
    85  
    86  	cID := container.Create(ctx, t, client)
    87  
    88  	// In case there is no events, the API should have responded immediately (not blocking),
    89  	// The test here makes sure the response time is less than 3 sec.
    90  	expectedTime := time.Now().Add(3 * time.Second)
    91  	emptyResp, emptyBody, err := req.Get("/events")
    92  	assert.NilError(t, err)
    93  	defer emptyBody.Close()
    94  	assert.Check(t, is.DeepEqual(http.StatusOK, emptyResp.StatusCode))
    95  	assert.Check(t, time.Now().Before(expectedTime), "timeout waiting for events api to respond, should have responded immediately")
    96  
    97  	// We also test to make sure the `events.Message` is compatible with `JSONMessage`
    98  	q := url.Values{}
    99  	q.Set("since", ts)
   100  	_, body, err := req.Get("/events?" + q.Encode())
   101  	assert.NilError(t, err)
   102  	defer body.Close()
   103  
   104  	dec := json.NewDecoder(body)
   105  	var containerCreateEvent *jsonmessage.JSONMessage
   106  	for {
   107  		var event jsonmessage.JSONMessage
   108  		if err := dec.Decode(&event); err != nil {
   109  			if err == io.EOF {
   110  				break
   111  			}
   112  			assert.NilError(t, err)
   113  		}
   114  		if event.Status == "create" && event.ID == cID {
   115  			containerCreateEvent = &event
   116  			break
   117  		}
   118  	}
   119  
   120  	assert.Check(t, containerCreateEvent != nil)
   121  	assert.Check(t, is.Equal("create", containerCreateEvent.Status))
   122  	assert.Check(t, is.Equal(cID, containerCreateEvent.ID))
   123  	assert.Check(t, is.Equal("busybox", containerCreateEvent.From))
   124  }