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