github.com/vieux/docker@v0.6.3-0.20161004191708-e097c2a938c7/cli/command/formatter/container_test.go (about)

     1  package formatter
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"strings"
     7  	"testing"
     8  	"time"
     9  
    10  	"github.com/docker/docker/api/types"
    11  	"github.com/docker/docker/pkg/stringid"
    12  	"github.com/docker/docker/pkg/testutil/assert"
    13  )
    14  
    15  func TestContainerPsContext(t *testing.T) {
    16  	containerID := stringid.GenerateRandomID()
    17  	unix := time.Now().Add(-65 * time.Second).Unix()
    18  
    19  	var ctx containerContext
    20  	cases := []struct {
    21  		container types.Container
    22  		trunc     bool
    23  		expValue  string
    24  		expHeader string
    25  		call      func() string
    26  	}{
    27  		{types.Container{ID: containerID}, true, stringid.TruncateID(containerID), containerIDHeader, ctx.ID},
    28  		{types.Container{ID: containerID}, false, containerID, containerIDHeader, ctx.ID},
    29  		{types.Container{Names: []string{"/foobar_baz"}}, true, "foobar_baz", namesHeader, ctx.Names},
    30  		{types.Container{Image: "ubuntu"}, true, "ubuntu", imageHeader, ctx.Image},
    31  		{types.Container{Image: "verylongimagename"}, true, "verylongimagename", imageHeader, ctx.Image},
    32  		{types.Container{Image: "verylongimagename"}, false, "verylongimagename", imageHeader, ctx.Image},
    33  		{types.Container{
    34  			Image:   "a5a665ff33eced1e0803148700880edab4",
    35  			ImageID: "a5a665ff33eced1e0803148700880edab4269067ed77e27737a708d0d293fbf5",
    36  		},
    37  			true,
    38  			"a5a665ff33ec",
    39  			imageHeader,
    40  			ctx.Image,
    41  		},
    42  		{types.Container{
    43  			Image:   "a5a665ff33eced1e0803148700880edab4",
    44  			ImageID: "a5a665ff33eced1e0803148700880edab4269067ed77e27737a708d0d293fbf5",
    45  		},
    46  			false,
    47  			"a5a665ff33eced1e0803148700880edab4",
    48  			imageHeader,
    49  			ctx.Image,
    50  		},
    51  		{types.Container{Image: ""}, true, "<no image>", imageHeader, ctx.Image},
    52  		{types.Container{Command: "sh -c 'ls -la'"}, true, `"sh -c 'ls -la'"`, commandHeader, ctx.Command},
    53  		{types.Container{Created: unix}, true, time.Unix(unix, 0).String(), createdAtHeader, ctx.CreatedAt},
    54  		{types.Container{Ports: []types.Port{{PrivatePort: 8080, PublicPort: 8080, Type: "tcp"}}}, true, "8080/tcp", portsHeader, ctx.Ports},
    55  		{types.Container{Status: "RUNNING"}, true, "RUNNING", statusHeader, ctx.Status},
    56  		{types.Container{SizeRw: 10}, true, "10 B", sizeHeader, ctx.Size},
    57  		{types.Container{SizeRw: 10, SizeRootFs: 20}, true, "10 B (virtual 20 B)", sizeHeader, ctx.Size},
    58  		{types.Container{}, true, "", labelsHeader, ctx.Labels},
    59  		{types.Container{Labels: map[string]string{"cpu": "6", "storage": "ssd"}}, true, "cpu=6,storage=ssd", labelsHeader, ctx.Labels},
    60  		{types.Container{Created: unix}, true, "About a minute", runningForHeader, ctx.RunningFor},
    61  		{types.Container{
    62  			Mounts: []types.MountPoint{
    63  				{
    64  					Name:   "this-is-a-long-volume-name-and-will-be-truncated-if-trunc-is-set",
    65  					Driver: "local",
    66  					Source: "/a/path",
    67  				},
    68  			},
    69  		}, true, "this-is-a-lo...", mountsHeader, ctx.Mounts},
    70  		{types.Container{
    71  			Mounts: []types.MountPoint{
    72  				{
    73  					Driver: "local",
    74  					Source: "/a/path",
    75  				},
    76  			},
    77  		}, false, "/a/path", mountsHeader, ctx.Mounts},
    78  		{types.Container{
    79  			Mounts: []types.MountPoint{
    80  				{
    81  					Name:   "733908409c91817de8e92b0096373245f329f19a88e2c849f02460e9b3d1c203",
    82  					Driver: "local",
    83  					Source: "/a/path",
    84  				},
    85  			},
    86  		}, false, "733908409c91817de8e92b0096373245f329f19a88e2c849f02460e9b3d1c203", mountsHeader, ctx.Mounts},
    87  	}
    88  
    89  	for _, c := range cases {
    90  		ctx = containerContext{c: c.container, trunc: c.trunc}
    91  		v := c.call()
    92  		if strings.Contains(v, ",") {
    93  			compareMultipleValues(t, v, c.expValue)
    94  		} else if v != c.expValue {
    95  			t.Fatalf("Expected %s, was %s\n", c.expValue, v)
    96  		}
    97  
    98  		h := ctx.FullHeader()
    99  		if h != c.expHeader {
   100  			t.Fatalf("Expected %s, was %s\n", c.expHeader, h)
   101  		}
   102  	}
   103  
   104  	c1 := types.Container{Labels: map[string]string{"com.docker.swarm.swarm-id": "33", "com.docker.swarm.node_name": "ubuntu"}}
   105  	ctx = containerContext{c: c1, trunc: true}
   106  
   107  	sid := ctx.Label("com.docker.swarm.swarm-id")
   108  	node := ctx.Label("com.docker.swarm.node_name")
   109  	if sid != "33" {
   110  		t.Fatalf("Expected 33, was %s\n", sid)
   111  	}
   112  
   113  	if node != "ubuntu" {
   114  		t.Fatalf("Expected ubuntu, was %s\n", node)
   115  	}
   116  
   117  	h := ctx.FullHeader()
   118  	if h != "SWARM ID\tNODE NAME" {
   119  		t.Fatalf("Expected %s, was %s\n", "SWARM ID\tNODE NAME", h)
   120  
   121  	}
   122  
   123  	c2 := types.Container{}
   124  	ctx = containerContext{c: c2, trunc: true}
   125  
   126  	label := ctx.Label("anything.really")
   127  	if label != "" {
   128  		t.Fatalf("Expected an empty string, was %s", label)
   129  	}
   130  
   131  	ctx = containerContext{c: c2, trunc: true}
   132  	FullHeader := ctx.FullHeader()
   133  	if FullHeader != "" {
   134  		t.Fatalf("Expected FullHeader to be empty, was %s", FullHeader)
   135  	}
   136  
   137  }
   138  
   139  func TestContainerContextWrite(t *testing.T) {
   140  	unixTime := time.Now().AddDate(0, 0, -1).Unix()
   141  	expectedTime := time.Unix(unixTime, 0).String()
   142  
   143  	cases := []struct {
   144  		context  Context
   145  		expected string
   146  	}{
   147  		// Errors
   148  		{
   149  			Context{Format: "{{InvalidFunction}}"},
   150  			`Template parsing error: template: :1: function "InvalidFunction" not defined
   151  `,
   152  		},
   153  		{
   154  			Context{Format: "{{nil}}"},
   155  			`Template parsing error: template: :1:2: executing "" at <nil>: nil is not a command
   156  `,
   157  		},
   158  		// Table Format
   159  		{
   160  			Context{Format: NewContainerFormat("table", false, true)},
   161  			`CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES               SIZE
   162  containerID1        ubuntu              ""                  24 hours ago                                                foobar_baz          0 B
   163  containerID2        ubuntu              ""                  24 hours ago                                                foobar_bar          0 B
   164  `,
   165  		},
   166  		{
   167  			Context{Format: NewContainerFormat("table", false, false)},
   168  			`CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
   169  containerID1        ubuntu              ""                  24 hours ago                                                foobar_baz
   170  containerID2        ubuntu              ""                  24 hours ago                                                foobar_bar
   171  `,
   172  		},
   173  		{
   174  			Context{Format: NewContainerFormat("table {{.Image}}", false, false)},
   175  			"IMAGE\nubuntu\nubuntu\n",
   176  		},
   177  		{
   178  			Context{Format: NewContainerFormat("table {{.Image}}", false, true)},
   179  			"IMAGE\nubuntu\nubuntu\n",
   180  		},
   181  		{
   182  			Context{Format: NewContainerFormat("table {{.Image}}", true, false)},
   183  			"IMAGE\nubuntu\nubuntu\n",
   184  		},
   185  		{
   186  			Context{Format: NewContainerFormat("table", true, false)},
   187  			"containerID1\ncontainerID2\n",
   188  		},
   189  		// Raw Format
   190  		{
   191  			Context{Format: NewContainerFormat("raw", false, false)},
   192  			fmt.Sprintf(`container_id: containerID1
   193  image: ubuntu
   194  command: ""
   195  created_at: %s
   196  status:
   197  names: foobar_baz
   198  labels:
   199  ports:
   200  
   201  container_id: containerID2
   202  image: ubuntu
   203  command: ""
   204  created_at: %s
   205  status:
   206  names: foobar_bar
   207  labels:
   208  ports:
   209  
   210  `, expectedTime, expectedTime),
   211  		},
   212  		{
   213  			Context{Format: NewContainerFormat("raw", false, true)},
   214  			fmt.Sprintf(`container_id: containerID1
   215  image: ubuntu
   216  command: ""
   217  created_at: %s
   218  status:
   219  names: foobar_baz
   220  labels:
   221  ports:
   222  size: 0 B
   223  
   224  container_id: containerID2
   225  image: ubuntu
   226  command: ""
   227  created_at: %s
   228  status:
   229  names: foobar_bar
   230  labels:
   231  ports:
   232  size: 0 B
   233  
   234  `, expectedTime, expectedTime),
   235  		},
   236  		{
   237  			Context{Format: NewContainerFormat("raw", true, false)},
   238  			"container_id: containerID1\ncontainer_id: containerID2\n",
   239  		},
   240  		// Custom Format
   241  		{
   242  			Context{Format: "{{.Image}}"},
   243  			"ubuntu\nubuntu\n",
   244  		},
   245  		{
   246  			Context{Format: NewContainerFormat("{{.Image}}", false, true)},
   247  			"ubuntu\nubuntu\n",
   248  		},
   249  	}
   250  
   251  	for _, testcase := range cases {
   252  		containers := []types.Container{
   253  			{ID: "containerID1", Names: []string{"/foobar_baz"}, Image: "ubuntu", Created: unixTime},
   254  			{ID: "containerID2", Names: []string{"/foobar_bar"}, Image: "ubuntu", Created: unixTime},
   255  		}
   256  		out := bytes.NewBufferString("")
   257  		testcase.context.Output = out
   258  		err := ContainerWrite(testcase.context, containers)
   259  		if err != nil {
   260  			assert.Error(t, err, testcase.expected)
   261  		} else {
   262  			assert.Equal(t, out.String(), testcase.expected)
   263  		}
   264  	}
   265  }
   266  
   267  func TestContainerContextWriteWithNoContainers(t *testing.T) {
   268  	out := bytes.NewBufferString("")
   269  	containers := []types.Container{}
   270  
   271  	contexts := []struct {
   272  		context  Context
   273  		expected string
   274  	}{
   275  		{
   276  			Context{
   277  				Format: "{{.Image}}",
   278  				Output: out,
   279  			},
   280  			"",
   281  		},
   282  		{
   283  			Context{
   284  				Format: "table {{.Image}}",
   285  				Output: out,
   286  			},
   287  			"IMAGE\n",
   288  		},
   289  		{
   290  			Context{
   291  				Format: NewContainerFormat("{{.Image}}", false, true),
   292  				Output: out,
   293  			},
   294  			"",
   295  		},
   296  		{
   297  			Context{
   298  				Format: NewContainerFormat("table {{.Image}}", false, true),
   299  				Output: out,
   300  			},
   301  			"IMAGE\n",
   302  		},
   303  		{
   304  			Context{
   305  				Format: "table {{.Image}}\t{{.Size}}",
   306  				Output: out,
   307  			},
   308  			"IMAGE               SIZE\n",
   309  		},
   310  		{
   311  			Context{
   312  				Format: NewContainerFormat("table {{.Image}}\t{{.Size}}", false, true),
   313  				Output: out,
   314  			},
   315  			"IMAGE               SIZE\n",
   316  		},
   317  	}
   318  
   319  	for _, context := range contexts {
   320  		ContainerWrite(context.context, containers)
   321  		assert.Equal(t, context.expected, out.String())
   322  		// Clean buffer
   323  		out.Reset()
   324  	}
   325  }