github.com/sijibomii/docker@v0.0.0-20231230191044-5cf6ca554647/api/client/formatter/formatter_test.go (about)

     1  package formatter
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/docker/engine-api/types"
    10  )
    11  
    12  func TestContainerContextWrite(t *testing.T) {
    13  	unixTime := time.Now().AddDate(0, 0, -1).Unix()
    14  	expectedTime := time.Unix(unixTime, 0).String()
    15  
    16  	contexts := []struct {
    17  		context  ContainerContext
    18  		expected string
    19  	}{
    20  		// Errors
    21  		{
    22  			ContainerContext{
    23  				Context: Context{
    24  					Format: "{{InvalidFunction}}",
    25  				},
    26  			},
    27  			`Template parsing error: template: :1: function "InvalidFunction" not defined
    28  `,
    29  		},
    30  		{
    31  			ContainerContext{
    32  				Context: Context{
    33  					Format: "{{nil}}",
    34  				},
    35  			},
    36  			`Template parsing error: template: :1:2: executing "" at <nil>: nil is not a command
    37  `,
    38  		},
    39  		// Table Format
    40  		{
    41  			ContainerContext{
    42  				Context: Context{
    43  					Format: "table",
    44  				},
    45  			},
    46  			`CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
    47  containerID1        ubuntu              ""                  24 hours ago                                                foobar_baz
    48  containerID2        ubuntu              ""                  24 hours ago                                                foobar_bar
    49  `,
    50  		},
    51  		{
    52  			ContainerContext{
    53  				Context: Context{
    54  					Format: "table {{.Image}}",
    55  				},
    56  			},
    57  			"IMAGE\nubuntu\nubuntu\n",
    58  		},
    59  		{
    60  			ContainerContext{
    61  				Context: Context{
    62  					Format: "table {{.Image}}",
    63  				},
    64  				Size: true,
    65  			},
    66  			"IMAGE               SIZE\nubuntu              0 B\nubuntu              0 B\n",
    67  		},
    68  		{
    69  			ContainerContext{
    70  				Context: Context{
    71  					Format: "table {{.Image}}",
    72  					Quiet:  true,
    73  				},
    74  			},
    75  			"IMAGE\nubuntu\nubuntu\n",
    76  		},
    77  		{
    78  			ContainerContext{
    79  				Context: Context{
    80  					Format: "table",
    81  					Quiet:  true,
    82  				},
    83  			},
    84  			"containerID1\ncontainerID2\n",
    85  		},
    86  		// Raw Format
    87  		{
    88  			ContainerContext{
    89  				Context: Context{
    90  					Format: "raw",
    91  				},
    92  			},
    93  			fmt.Sprintf(`container_id: containerID1
    94  image: ubuntu
    95  command: ""
    96  created_at: %s
    97  status: 
    98  names: foobar_baz
    99  labels: 
   100  ports: 
   101  
   102  container_id: containerID2
   103  image: ubuntu
   104  command: ""
   105  created_at: %s
   106  status: 
   107  names: foobar_bar
   108  labels: 
   109  ports: 
   110  
   111  `, expectedTime, expectedTime),
   112  		},
   113  		{
   114  			ContainerContext{
   115  				Context: Context{
   116  					Format: "raw",
   117  				},
   118  				Size: true,
   119  			},
   120  			fmt.Sprintf(`container_id: containerID1
   121  image: ubuntu
   122  command: ""
   123  created_at: %s
   124  status: 
   125  names: foobar_baz
   126  labels: 
   127  ports: 
   128  size: 0 B
   129  
   130  container_id: containerID2
   131  image: ubuntu
   132  command: ""
   133  created_at: %s
   134  status: 
   135  names: foobar_bar
   136  labels: 
   137  ports: 
   138  size: 0 B
   139  
   140  `, expectedTime, expectedTime),
   141  		},
   142  		{
   143  			ContainerContext{
   144  				Context: Context{
   145  					Format: "raw",
   146  					Quiet:  true,
   147  				},
   148  			},
   149  			"container_id: containerID1\ncontainer_id: containerID2\n",
   150  		},
   151  		// Custom Format
   152  		{
   153  			ContainerContext{
   154  				Context: Context{
   155  					Format: "{{.Image}}",
   156  				},
   157  			},
   158  			"ubuntu\nubuntu\n",
   159  		},
   160  		{
   161  			ContainerContext{
   162  				Context: Context{
   163  					Format: "{{.Image}}",
   164  				},
   165  				Size: true,
   166  			},
   167  			"ubuntu\nubuntu\n",
   168  		},
   169  	}
   170  
   171  	for _, context := range contexts {
   172  		containers := []types.Container{
   173  			{ID: "containerID1", Names: []string{"/foobar_baz"}, Image: "ubuntu", Created: unixTime},
   174  			{ID: "containerID2", Names: []string{"/foobar_bar"}, Image: "ubuntu", Created: unixTime},
   175  		}
   176  		out := bytes.NewBufferString("")
   177  		context.context.Output = out
   178  		context.context.Containers = containers
   179  		context.context.Write()
   180  		actual := out.String()
   181  		if actual != context.expected {
   182  			t.Fatalf("Expected \n%s, got \n%s", context.expected, actual)
   183  		}
   184  		// Clean buffer
   185  		out.Reset()
   186  	}
   187  }
   188  
   189  func TestContainerContextWriteWithNoContainers(t *testing.T) {
   190  	out := bytes.NewBufferString("")
   191  	containers := []types.Container{}
   192  
   193  	contexts := []struct {
   194  		context  ContainerContext
   195  		expected string
   196  	}{
   197  		{
   198  			ContainerContext{
   199  				Context: Context{
   200  					Format: "{{.Image}}",
   201  					Output: out,
   202  				},
   203  			},
   204  			"",
   205  		},
   206  		{
   207  			ContainerContext{
   208  				Context: Context{
   209  					Format: "table {{.Image}}",
   210  					Output: out,
   211  				},
   212  			},
   213  			"IMAGE\n",
   214  		},
   215  		{
   216  			ContainerContext{
   217  				Context: Context{
   218  					Format: "{{.Image}}",
   219  					Output: out,
   220  				},
   221  				Size: true,
   222  			},
   223  			"",
   224  		},
   225  		{
   226  			ContainerContext{
   227  				Context: Context{
   228  					Format: "table {{.Image}}",
   229  					Output: out,
   230  				},
   231  				Size: true,
   232  			},
   233  			"IMAGE               SIZE\n",
   234  		},
   235  	}
   236  
   237  	for _, context := range contexts {
   238  		context.context.Containers = containers
   239  		context.context.Write()
   240  		actual := out.String()
   241  		if actual != context.expected {
   242  			t.Fatalf("Expected \n%s, got \n%s", context.expected, actual)
   243  		}
   244  		// Clean buffer
   245  		out.Reset()
   246  	}
   247  }
   248  
   249  func TestImageContextWrite(t *testing.T) {
   250  	unixTime := time.Now().AddDate(0, 0, -1).Unix()
   251  	expectedTime := time.Unix(unixTime, 0).String()
   252  
   253  	contexts := []struct {
   254  		context  ImageContext
   255  		expected string
   256  	}{
   257  		// Errors
   258  		{
   259  			ImageContext{
   260  				Context: Context{
   261  					Format: "{{InvalidFunction}}",
   262  				},
   263  			},
   264  			`Template parsing error: template: :1: function "InvalidFunction" not defined
   265  `,
   266  		},
   267  		{
   268  			ImageContext{
   269  				Context: Context{
   270  					Format: "{{nil}}",
   271  				},
   272  			},
   273  			`Template parsing error: template: :1:2: executing "" at <nil>: nil is not a command
   274  `,
   275  		},
   276  		// Table Format
   277  		{
   278  			ImageContext{
   279  				Context: Context{
   280  					Format: "table",
   281  				},
   282  			},
   283  			`REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
   284  image               tag1                imageID1            24 hours ago        0 B
   285  image               <none>              imageID1            24 hours ago        0 B
   286  image               tag2                imageID2            24 hours ago        0 B
   287  <none>              <none>              imageID3            24 hours ago        0 B
   288  `,
   289  		},
   290  		{
   291  			ImageContext{
   292  				Context: Context{
   293  					Format: "table {{.Repository}}",
   294  				},
   295  			},
   296  			"REPOSITORY\nimage\nimage\nimage\n<none>\n",
   297  		},
   298  		{
   299  			ImageContext{
   300  				Context: Context{
   301  					Format: "table {{.Repository}}",
   302  				},
   303  				Digest: true,
   304  			},
   305  			`REPOSITORY          DIGEST
   306  image               <none>
   307  image               sha256:cbbf2f9a99b47fc460d422812b6a5adff7dfee951d8fa2e4a98caa0382cfbdbf
   308  image               <none>
   309  <none>              <none>
   310  `,
   311  		},
   312  		{
   313  			ImageContext{
   314  				Context: Context{
   315  					Format: "table {{.Repository}}",
   316  					Quiet:  true,
   317  				},
   318  			},
   319  			"REPOSITORY\nimage\nimage\nimage\n<none>\n",
   320  		},
   321  		{
   322  			ImageContext{
   323  				Context: Context{
   324  					Format: "table",
   325  					Quiet:  true,
   326  				},
   327  			},
   328  			"imageID1\nimageID1\nimageID2\nimageID3\n",
   329  		},
   330  		{
   331  			ImageContext{
   332  				Context: Context{
   333  					Format: "table",
   334  					Quiet:  false,
   335  				},
   336  				Digest: true,
   337  			},
   338  			`REPOSITORY          TAG                 DIGEST                                                                    IMAGE ID            CREATED             SIZE
   339  image               tag1                <none>                                                                    imageID1            24 hours ago        0 B
   340  image               <none>              sha256:cbbf2f9a99b47fc460d422812b6a5adff7dfee951d8fa2e4a98caa0382cfbdbf   imageID1            24 hours ago        0 B
   341  image               tag2                <none>                                                                    imageID2            24 hours ago        0 B
   342  <none>              <none>              <none>                                                                    imageID3            24 hours ago        0 B
   343  `,
   344  		},
   345  		{
   346  			ImageContext{
   347  				Context: Context{
   348  					Format: "table",
   349  					Quiet:  true,
   350  				},
   351  				Digest: true,
   352  			},
   353  			"imageID1\nimageID1\nimageID2\nimageID3\n",
   354  		},
   355  		// Raw Format
   356  		{
   357  			ImageContext{
   358  				Context: Context{
   359  					Format: "raw",
   360  				},
   361  			},
   362  			fmt.Sprintf(`repository: image
   363  tag: tag1
   364  image_id: imageID1
   365  created_at: %s
   366  virtual_size: 0 B
   367  
   368  repository: image
   369  tag: <none>
   370  image_id: imageID1
   371  created_at: %s
   372  virtual_size: 0 B
   373  
   374  repository: image
   375  tag: tag2
   376  image_id: imageID2
   377  created_at: %s
   378  virtual_size: 0 B
   379  
   380  repository: <none>
   381  tag: <none>
   382  image_id: imageID3
   383  created_at: %s
   384  virtual_size: 0 B
   385  
   386  `, expectedTime, expectedTime, expectedTime, expectedTime),
   387  		},
   388  		{
   389  			ImageContext{
   390  				Context: Context{
   391  					Format: "raw",
   392  				},
   393  				Digest: true,
   394  			},
   395  			fmt.Sprintf(`repository: image
   396  tag: tag1
   397  digest: <none>
   398  image_id: imageID1
   399  created_at: %s
   400  virtual_size: 0 B
   401  
   402  repository: image
   403  tag: <none>
   404  digest: sha256:cbbf2f9a99b47fc460d422812b6a5adff7dfee951d8fa2e4a98caa0382cfbdbf
   405  image_id: imageID1
   406  created_at: %s
   407  virtual_size: 0 B
   408  
   409  repository: image
   410  tag: tag2
   411  digest: <none>
   412  image_id: imageID2
   413  created_at: %s
   414  virtual_size: 0 B
   415  
   416  repository: <none>
   417  tag: <none>
   418  digest: <none>
   419  image_id: imageID3
   420  created_at: %s
   421  virtual_size: 0 B
   422  
   423  `, expectedTime, expectedTime, expectedTime, expectedTime),
   424  		},
   425  		{
   426  			ImageContext{
   427  				Context: Context{
   428  					Format: "raw",
   429  					Quiet:  true,
   430  				},
   431  			},
   432  			`image_id: imageID1
   433  image_id: imageID1
   434  image_id: imageID2
   435  image_id: imageID3
   436  `,
   437  		},
   438  		// Custom Format
   439  		{
   440  			ImageContext{
   441  				Context: Context{
   442  					Format: "{{.Repository}}",
   443  				},
   444  			},
   445  			"image\nimage\nimage\n<none>\n",
   446  		},
   447  		{
   448  			ImageContext{
   449  				Context: Context{
   450  					Format: "{{.Repository}}",
   451  				},
   452  				Digest: true,
   453  			},
   454  			"image\nimage\nimage\n<none>\n",
   455  		},
   456  	}
   457  
   458  	for _, context := range contexts {
   459  		images := []types.Image{
   460  			{ID: "imageID1", RepoTags: []string{"image:tag1"}, RepoDigests: []string{"image@sha256:cbbf2f9a99b47fc460d422812b6a5adff7dfee951d8fa2e4a98caa0382cfbdbf"}, Created: unixTime},
   461  			{ID: "imageID2", RepoTags: []string{"image:tag2"}, Created: unixTime},
   462  			{ID: "imageID3", RepoTags: []string{"<none>:<none>"}, RepoDigests: []string{"<none>@<none>"}, Created: unixTime},
   463  		}
   464  		out := bytes.NewBufferString("")
   465  		context.context.Output = out
   466  		context.context.Images = images
   467  		context.context.Write()
   468  		actual := out.String()
   469  		if actual != context.expected {
   470  			t.Fatalf("Expected \n%s, got \n%s", context.expected, actual)
   471  		}
   472  		// Clean buffer
   473  		out.Reset()
   474  	}
   475  }
   476  
   477  func TestImageContextWriteWithNoImage(t *testing.T) {
   478  	out := bytes.NewBufferString("")
   479  	images := []types.Image{}
   480  
   481  	contexts := []struct {
   482  		context  ImageContext
   483  		expected string
   484  	}{
   485  		{
   486  			ImageContext{
   487  				Context: Context{
   488  					Format: "{{.Repository}}",
   489  					Output: out,
   490  				},
   491  			},
   492  			"",
   493  		},
   494  		{
   495  			ImageContext{
   496  				Context: Context{
   497  					Format: "table {{.Repository}}",
   498  					Output: out,
   499  				},
   500  			},
   501  			"REPOSITORY\n",
   502  		},
   503  		{
   504  			ImageContext{
   505  				Context: Context{
   506  					Format: "{{.Repository}}",
   507  					Output: out,
   508  				},
   509  				Digest: true,
   510  			},
   511  			"",
   512  		},
   513  		{
   514  			ImageContext{
   515  				Context: Context{
   516  					Format: "table {{.Repository}}",
   517  					Output: out,
   518  				},
   519  				Digest: true,
   520  			},
   521  			"REPOSITORY          DIGEST\n",
   522  		},
   523  	}
   524  
   525  	for _, context := range contexts {
   526  		context.context.Images = images
   527  		context.context.Write()
   528  		actual := out.String()
   529  		if actual != context.expected {
   530  			t.Fatalf("Expected \n%s, got \n%s", context.expected, actual)
   531  		}
   532  		// Clean buffer
   533  		out.Reset()
   534  	}
   535  }