github.com/scorpionis/docker@v1.6.0-rc7/integration-cli/docker_cli_events_test.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  	"os/exec"
     6  	"regexp"
     7  	"strconv"
     8  	"strings"
     9  	"testing"
    10  	"time"
    11  )
    12  
    13  func TestEventsUntag(t *testing.T) {
    14  	image := "busybox"
    15  	dockerCmd(t, "tag", image, "utest:tag1")
    16  	dockerCmd(t, "tag", image, "utest:tag2")
    17  	dockerCmd(t, "rmi", "utest:tag1")
    18  	dockerCmd(t, "rmi", "utest:tag2")
    19  	eventsCmd := exec.Command(dockerBinary, "events", "--since=1")
    20  	out, exitCode, _, err := runCommandWithOutputForDuration(eventsCmd, time.Duration(time.Millisecond*200))
    21  	if exitCode != 0 || err != nil {
    22  		t.Fatalf("Failed to get events - exit code %d: %s", exitCode, err)
    23  	}
    24  	events := strings.Split(out, "\n")
    25  	nEvents := len(events)
    26  	// The last element after the split above will be an empty string, so we
    27  	// get the two elements before the last, which are the untags we're
    28  	// looking for.
    29  	for _, v := range events[nEvents-3 : nEvents-1] {
    30  		if !strings.Contains(v, "untag") {
    31  			t.Fatalf("event should be untag, not %#v", v)
    32  		}
    33  	}
    34  	logDone("events - untags are logged")
    35  }
    36  
    37  func TestEventsContainerFailStartDie(t *testing.T) {
    38  	defer deleteAllContainers()
    39  
    40  	out, _, _ := dockerCmd(t, "images", "-q")
    41  	image := strings.Split(out, "\n")[0]
    42  	eventsCmd := exec.Command(dockerBinary, "run", "--name", "testeventdie", image, "blerg")
    43  	_, _, err := runCommandWithOutput(eventsCmd)
    44  	if err == nil {
    45  		t.Fatalf("Container run with command blerg should have failed, but it did not")
    46  	}
    47  
    48  	eventsCmd = exec.Command(dockerBinary, "events", "--since=0", fmt.Sprintf("--until=%d", daemonTime(t).Unix()))
    49  	out, _, _ = runCommandWithOutput(eventsCmd)
    50  	events := strings.Split(out, "\n")
    51  	if len(events) <= 1 {
    52  		t.Fatalf("Missing expected event")
    53  	}
    54  
    55  	startEvent := strings.Fields(events[len(events)-3])
    56  	dieEvent := strings.Fields(events[len(events)-2])
    57  
    58  	if startEvent[len(startEvent)-1] != "start" {
    59  		t.Fatalf("event should be start, not %#v", startEvent)
    60  	}
    61  	if dieEvent[len(dieEvent)-1] != "die" {
    62  		t.Fatalf("event should be die, not %#v", dieEvent)
    63  	}
    64  
    65  	logDone("events - container unwilling to start logs die")
    66  }
    67  
    68  func TestEventsLimit(t *testing.T) {
    69  	defer deleteAllContainers()
    70  	for i := 0; i < 30; i++ {
    71  		dockerCmd(t, "run", "busybox", "echo", strconv.Itoa(i))
    72  	}
    73  	eventsCmd := exec.Command(dockerBinary, "events", "--since=0", fmt.Sprintf("--until=%d", daemonTime(t).Unix()))
    74  	out, _, _ := runCommandWithOutput(eventsCmd)
    75  	events := strings.Split(out, "\n")
    76  	nEvents := len(events) - 1
    77  	if nEvents != 64 {
    78  		t.Fatalf("events should be limited to 64, but received %d", nEvents)
    79  	}
    80  	logDone("events - limited to 64 entries")
    81  }
    82  
    83  func TestEventsContainerEvents(t *testing.T) {
    84  	dockerCmd(t, "run", "--rm", "busybox", "true")
    85  	eventsCmd := exec.Command(dockerBinary, "events", "--since=0", fmt.Sprintf("--until=%d", daemonTime(t).Unix()))
    86  	out, exitCode, err := runCommandWithOutput(eventsCmd)
    87  	if exitCode != 0 || err != nil {
    88  		t.Fatalf("Failed to get events with exit code %d: %s", exitCode, err)
    89  	}
    90  	events := strings.Split(out, "\n")
    91  	events = events[:len(events)-1]
    92  	if len(events) < 4 {
    93  		t.Fatalf("Missing expected event")
    94  	}
    95  	createEvent := strings.Fields(events[len(events)-4])
    96  	startEvent := strings.Fields(events[len(events)-3])
    97  	dieEvent := strings.Fields(events[len(events)-2])
    98  	destroyEvent := strings.Fields(events[len(events)-1])
    99  	if createEvent[len(createEvent)-1] != "create" {
   100  		t.Fatalf("event should be create, not %#v", createEvent)
   101  	}
   102  	if startEvent[len(startEvent)-1] != "start" {
   103  		t.Fatalf("event should be start, not %#v", startEvent)
   104  	}
   105  	if dieEvent[len(dieEvent)-1] != "die" {
   106  		t.Fatalf("event should be die, not %#v", dieEvent)
   107  	}
   108  	if destroyEvent[len(destroyEvent)-1] != "destroy" {
   109  		t.Fatalf("event should be destroy, not %#v", destroyEvent)
   110  	}
   111  
   112  	logDone("events - container create, start, die, destroy is logged")
   113  }
   114  
   115  func TestEventsImageUntagDelete(t *testing.T) {
   116  	name := "testimageevents"
   117  	defer deleteImages(name)
   118  	_, err := buildImage(name,
   119  		`FROM scratch
   120  		MAINTAINER "docker"`,
   121  		true)
   122  	if err != nil {
   123  		t.Fatal(err)
   124  	}
   125  	if err := deleteImages(name); err != nil {
   126  		t.Fatal(err)
   127  	}
   128  	eventsCmd := exec.Command(dockerBinary, "events", "--since=0", fmt.Sprintf("--until=%d", daemonTime(t).Unix()))
   129  	out, exitCode, err := runCommandWithOutput(eventsCmd)
   130  	if exitCode != 0 || err != nil {
   131  		t.Fatalf("Failed to get events with exit code %d: %s", exitCode, err)
   132  	}
   133  	events := strings.Split(out, "\n")
   134  
   135  	events = events[:len(events)-1]
   136  	if len(events) < 2 {
   137  		t.Fatalf("Missing expected event")
   138  	}
   139  	untagEvent := strings.Fields(events[len(events)-2])
   140  	deleteEvent := strings.Fields(events[len(events)-1])
   141  	if untagEvent[len(untagEvent)-1] != "untag" {
   142  		t.Fatalf("untag should be untag, not %#v", untagEvent)
   143  	}
   144  	if deleteEvent[len(deleteEvent)-1] != "delete" {
   145  		t.Fatalf("delete should be delete, not %#v", deleteEvent)
   146  	}
   147  	logDone("events - image untag, delete is logged")
   148  }
   149  
   150  func TestEventsImagePull(t *testing.T) {
   151  	since := daemonTime(t).Unix()
   152  
   153  	defer deleteImages("hello-world")
   154  
   155  	pullCmd := exec.Command(dockerBinary, "pull", "hello-world")
   156  	if out, _, err := runCommandWithOutput(pullCmd); err != nil {
   157  		t.Fatalf("pulling the hello-world image from has failed: %s, %v", out, err)
   158  	}
   159  
   160  	eventsCmd := exec.Command(dockerBinary, "events",
   161  		fmt.Sprintf("--since=%d", since),
   162  		fmt.Sprintf("--until=%d", daemonTime(t).Unix()))
   163  	out, _, _ := runCommandWithOutput(eventsCmd)
   164  
   165  	events := strings.Split(strings.TrimSpace(out), "\n")
   166  	event := strings.TrimSpace(events[len(events)-1])
   167  
   168  	if !strings.HasSuffix(event, "hello-world:latest: pull") {
   169  		t.Fatalf("Missing pull event - got:%q", event)
   170  	}
   171  
   172  	logDone("events - image pull is logged")
   173  }
   174  
   175  func TestEventsImageImport(t *testing.T) {
   176  	defer deleteAllContainers()
   177  	since := daemonTime(t).Unix()
   178  
   179  	runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "true")
   180  	out, _, err := runCommandWithOutput(runCmd)
   181  	if err != nil {
   182  		t.Fatal("failed to create a container", out, err)
   183  	}
   184  	cleanedContainerID := stripTrailingCharacters(out)
   185  
   186  	out, _, err = runCommandPipelineWithOutput(
   187  		exec.Command(dockerBinary, "export", cleanedContainerID),
   188  		exec.Command(dockerBinary, "import", "-"),
   189  	)
   190  	if err != nil {
   191  		t.Errorf("import failed with errors: %v, output: %q", err, out)
   192  	}
   193  
   194  	eventsCmd := exec.Command(dockerBinary, "events",
   195  		fmt.Sprintf("--since=%d", since),
   196  		fmt.Sprintf("--until=%d", daemonTime(t).Unix()))
   197  	out, _, _ = runCommandWithOutput(eventsCmd)
   198  
   199  	events := strings.Split(strings.TrimSpace(out), "\n")
   200  	event := strings.TrimSpace(events[len(events)-1])
   201  
   202  	if !strings.HasSuffix(event, ": import") {
   203  		t.Fatalf("Missing pull event - got:%q", event)
   204  	}
   205  
   206  	logDone("events - image import is logged")
   207  }
   208  
   209  func TestEventsFilters(t *testing.T) {
   210  	parseEvents := func(out, match string) {
   211  		events := strings.Split(out, "\n")
   212  		events = events[:len(events)-1]
   213  		for _, event := range events {
   214  			eventFields := strings.Fields(event)
   215  			eventName := eventFields[len(eventFields)-1]
   216  			if ok, err := regexp.MatchString(match, eventName); err != nil || !ok {
   217  				t.Fatalf("event should match %s, got %#v, err: %v", match, eventFields, err)
   218  			}
   219  		}
   220  	}
   221  
   222  	since := daemonTime(t).Unix()
   223  	out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "--rm", "busybox", "true"))
   224  	if err != nil {
   225  		t.Fatal(out, err)
   226  	}
   227  	out, _, err = runCommandWithOutput(exec.Command(dockerBinary, "run", "--rm", "busybox", "true"))
   228  	if err != nil {
   229  		t.Fatal(out, err)
   230  	}
   231  	out, _, err = runCommandWithOutput(exec.Command(dockerBinary, "events", fmt.Sprintf("--since=%d", since), fmt.Sprintf("--until=%d", daemonTime(t).Unix()), "--filter", "event=die"))
   232  	if err != nil {
   233  		t.Fatalf("Failed to get events: %s", err)
   234  	}
   235  	parseEvents(out, "die")
   236  
   237  	out, _, err = runCommandWithOutput(exec.Command(dockerBinary, "events", fmt.Sprintf("--since=%d", since), fmt.Sprintf("--until=%d", daemonTime(t).Unix()), "--filter", "event=die", "--filter", "event=start"))
   238  	if err != nil {
   239  		t.Fatalf("Failed to get events: %s", err)
   240  	}
   241  	parseEvents(out, "((die)|(start))")
   242  
   243  	// make sure we at least got 2 start events
   244  	count := strings.Count(out, "start")
   245  	if count < 2 {
   246  		t.Fatalf("should have had 2 start events but had %d, out: %s", count, out)
   247  	}
   248  
   249  	logDone("events - filters")
   250  }
   251  
   252  func TestEventsFilterImageName(t *testing.T) {
   253  	since := daemonTime(t).Unix()
   254  	defer deleteAllContainers()
   255  
   256  	out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "--name", "container_1", "-d", "busybox", "true"))
   257  	if err != nil {
   258  		t.Fatal(out, err)
   259  	}
   260  	container1 := stripTrailingCharacters(out)
   261  
   262  	out, _, err = runCommandWithOutput(exec.Command(dockerBinary, "run", "--name", "container_2", "-d", "busybox", "true"))
   263  	if err != nil {
   264  		t.Fatal(out, err)
   265  	}
   266  	container2 := stripTrailingCharacters(out)
   267  
   268  	for _, s := range []string{"busybox", "busybox:latest"} {
   269  		eventsCmd := exec.Command(dockerBinary, "events", fmt.Sprintf("--since=%d", since), fmt.Sprintf("--until=%d", daemonTime(t).Unix()), "--filter", fmt.Sprintf("image=%s", s))
   270  		out, _, err := runCommandWithOutput(eventsCmd)
   271  		if err != nil {
   272  			t.Fatalf("Failed to get events, error: %s(%s)", err, out)
   273  		}
   274  		events := strings.Split(out, "\n")
   275  		events = events[:len(events)-1]
   276  		if len(events) == 0 {
   277  			t.Fatalf("Expected events but found none for the image busybox:latest")
   278  		}
   279  		count1 := 0
   280  		count2 := 0
   281  		for _, e := range events {
   282  			if strings.Contains(e, container1) {
   283  				count1++
   284  			} else if strings.Contains(e, container2) {
   285  				count2++
   286  			}
   287  		}
   288  		if count1 == 0 || count2 == 0 {
   289  			t.Fatalf("Expected events from each container but got %d from %s and %d from %s", count1, container1, count2, container2)
   290  		}
   291  	}
   292  
   293  	logDone("events - filters using image")
   294  }
   295  
   296  func TestEventsFilterContainerID(t *testing.T) {
   297  	since := daemonTime(t).Unix()
   298  	defer deleteAllContainers()
   299  
   300  	out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "-d", "busybox", "true"))
   301  	if err != nil {
   302  		t.Fatal(out, err)
   303  	}
   304  	container1 := stripTrailingCharacters(out)
   305  
   306  	out, _, err = runCommandWithOutput(exec.Command(dockerBinary, "run", "-d", "busybox", "true"))
   307  	if err != nil {
   308  		t.Fatal(out, err)
   309  	}
   310  	container2 := stripTrailingCharacters(out)
   311  
   312  	for _, s := range []string{container1, container2, container1[:12], container2[:12]} {
   313  		eventsCmd := exec.Command(dockerBinary, "events", fmt.Sprintf("--since=%d", since), fmt.Sprintf("--until=%d", daemonTime(t).Unix()), "--filter", fmt.Sprintf("container=%s", s))
   314  		out, _, err := runCommandWithOutput(eventsCmd)
   315  		if err != nil {
   316  			t.Fatalf("Failed to get events, error: %s(%s)", err, out)
   317  		}
   318  		events := strings.Split(out, "\n")
   319  		events = events[:len(events)-1]
   320  		if len(events) == 0 || len(events) > 3 {
   321  			t.Fatalf("Expected 3 events, got %d: %v", len(events), events)
   322  		}
   323  		createEvent := strings.Fields(events[0])
   324  		if createEvent[len(createEvent)-1] != "create" {
   325  			t.Fatalf("first event should be create, not %#v", createEvent)
   326  		}
   327  		if len(events) > 1 {
   328  			startEvent := strings.Fields(events[1])
   329  			if startEvent[len(startEvent)-1] != "start" {
   330  				t.Fatalf("second event should be start, not %#v", startEvent)
   331  			}
   332  		}
   333  		if len(events) == 3 {
   334  			dieEvent := strings.Fields(events[len(events)-1])
   335  			if dieEvent[len(dieEvent)-1] != "die" {
   336  				t.Fatalf("event should be die, not %#v", dieEvent)
   337  			}
   338  		}
   339  	}
   340  
   341  	logDone("events - filters using container id")
   342  }
   343  
   344  func TestEventsFilterContainerName(t *testing.T) {
   345  	since := daemonTime(t).Unix()
   346  	defer deleteAllContainers()
   347  
   348  	_, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "--name", "container_1", "busybox", "true"))
   349  	if err != nil {
   350  		t.Fatal(err)
   351  	}
   352  
   353  	_, _, err = runCommandWithOutput(exec.Command(dockerBinary, "run", "--name", "container_2", "busybox", "true"))
   354  	if err != nil {
   355  		t.Fatal(err)
   356  	}
   357  
   358  	for _, s := range []string{"container_1", "container_2"} {
   359  		eventsCmd := exec.Command(dockerBinary, "events", fmt.Sprintf("--since=%d", since), fmt.Sprintf("--until=%d", daemonTime(t).Unix()), "--filter", fmt.Sprintf("container=%s", s))
   360  		out, _, err := runCommandWithOutput(eventsCmd)
   361  		if err != nil {
   362  			t.Fatalf("Failed to get events, error : %s(%s)", err, out)
   363  		}
   364  		events := strings.Split(out, "\n")
   365  		events = events[:len(events)-1]
   366  		if len(events) == 0 || len(events) > 3 {
   367  			t.Fatalf("Expected 3 events, got %d: %v", len(events), events)
   368  		}
   369  		createEvent := strings.Fields(events[0])
   370  		if createEvent[len(createEvent)-1] != "create" {
   371  			t.Fatalf("first event should be create, not %#v", createEvent)
   372  		}
   373  		if len(events) > 1 {
   374  			startEvent := strings.Fields(events[1])
   375  			if startEvent[len(startEvent)-1] != "start" {
   376  				t.Fatalf("second event should be start, not %#v", startEvent)
   377  			}
   378  		}
   379  		if len(events) == 3 {
   380  			dieEvent := strings.Fields(events[len(events)-1])
   381  			if dieEvent[len(dieEvent)-1] != "die" {
   382  				t.Fatalf("event should be die, not %#v", dieEvent)
   383  			}
   384  		}
   385  	}
   386  
   387  	logDone("events - filters using container name")
   388  }