github.com/olljanat/moby@v1.13.1/cli/command/formatter/image_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 TestImageContext(t *testing.T) {
    16  	imageID := stringid.GenerateRandomID()
    17  	unix := time.Now().Unix()
    18  
    19  	var ctx imageContext
    20  	cases := []struct {
    21  		imageCtx  imageContext
    22  		expValue  string
    23  		expHeader string
    24  		call      func() string
    25  	}{
    26  		{imageContext{
    27  			i:     types.ImageSummary{ID: imageID},
    28  			trunc: true,
    29  		}, stringid.TruncateID(imageID), imageIDHeader, ctx.ID},
    30  		{imageContext{
    31  			i:     types.ImageSummary{ID: imageID},
    32  			trunc: false,
    33  		}, imageID, imageIDHeader, ctx.ID},
    34  		{imageContext{
    35  			i:     types.ImageSummary{Size: 10, VirtualSize: 10},
    36  			trunc: true,
    37  		}, "10 B", sizeHeader, ctx.Size},
    38  		{imageContext{
    39  			i:     types.ImageSummary{Created: unix},
    40  			trunc: true,
    41  		}, time.Unix(unix, 0).String(), createdAtHeader, ctx.CreatedAt},
    42  		// FIXME
    43  		// {imageContext{
    44  		// 	i:     types.ImageSummary{Created: unix},
    45  		// 	trunc: true,
    46  		// }, units.HumanDuration(time.Unix(unix, 0)), createdSinceHeader, ctx.CreatedSince},
    47  		{imageContext{
    48  			i:    types.ImageSummary{},
    49  			repo: "busybox",
    50  		}, "busybox", repositoryHeader, ctx.Repository},
    51  		{imageContext{
    52  			i:   types.ImageSummary{},
    53  			tag: "latest",
    54  		}, "latest", tagHeader, ctx.Tag},
    55  		{imageContext{
    56  			i:      types.ImageSummary{},
    57  			digest: "sha256:d149ab53f8718e987c3a3024bb8aa0e2caadf6c0328f1d9d850b2a2a67f2819a",
    58  		}, "sha256:d149ab53f8718e987c3a3024bb8aa0e2caadf6c0328f1d9d850b2a2a67f2819a", digestHeader, ctx.Digest},
    59  	}
    60  
    61  	for _, c := range cases {
    62  		ctx = c.imageCtx
    63  		v := c.call()
    64  		if strings.Contains(v, ",") {
    65  			compareMultipleValues(t, v, c.expValue)
    66  		} else if v != c.expValue {
    67  			t.Fatalf("Expected %s, was %s\n", c.expValue, v)
    68  		}
    69  
    70  		h := ctx.FullHeader()
    71  		if h != c.expHeader {
    72  			t.Fatalf("Expected %s, was %s\n", c.expHeader, h)
    73  		}
    74  	}
    75  }
    76  
    77  func TestImageContextWrite(t *testing.T) {
    78  	unixTime := time.Now().AddDate(0, 0, -1).Unix()
    79  	expectedTime := time.Unix(unixTime, 0).String()
    80  
    81  	cases := []struct {
    82  		context  ImageContext
    83  		expected string
    84  	}{
    85  		// Errors
    86  		{
    87  			ImageContext{
    88  				Context: Context{
    89  					Format: "{{InvalidFunction}}",
    90  				},
    91  			},
    92  			`Template parsing error: template: :1: function "InvalidFunction" not defined
    93  `,
    94  		},
    95  		{
    96  			ImageContext{
    97  				Context: Context{
    98  					Format: "{{nil}}",
    99  				},
   100  			},
   101  			`Template parsing error: template: :1:2: executing "" at <nil>: nil is not a command
   102  `,
   103  		},
   104  		// Table Format
   105  		{
   106  			ImageContext{
   107  				Context: Context{
   108  					Format: NewImageFormat("table", false, false),
   109  				},
   110  			},
   111  			`REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
   112  image               tag1                imageID1            24 hours ago        0 B
   113  image               tag2                imageID2            24 hours ago        0 B
   114  <none>              <none>              imageID3            24 hours ago        0 B
   115  `,
   116  		},
   117  		{
   118  			ImageContext{
   119  				Context: Context{
   120  					Format: NewImageFormat("table {{.Repository}}", false, false),
   121  				},
   122  			},
   123  			"REPOSITORY\nimage\nimage\n<none>\n",
   124  		},
   125  		{
   126  			ImageContext{
   127  				Context: Context{
   128  					Format: NewImageFormat("table {{.Repository}}", false, true),
   129  				},
   130  				Digest: true,
   131  			},
   132  			`REPOSITORY          DIGEST
   133  image               sha256:cbbf2f9a99b47fc460d422812b6a5adff7dfee951d8fa2e4a98caa0382cfbdbf
   134  image               <none>
   135  <none>              <none>
   136  `,
   137  		},
   138  		{
   139  			ImageContext{
   140  				Context: Context{
   141  					Format: NewImageFormat("table {{.Repository}}", true, false),
   142  				},
   143  			},
   144  			"REPOSITORY\nimage\nimage\n<none>\n",
   145  		},
   146  		{
   147  			ImageContext{
   148  				Context: Context{
   149  					Format: NewImageFormat("table", true, false),
   150  				},
   151  			},
   152  			"imageID1\nimageID2\nimageID3\n",
   153  		},
   154  		{
   155  			ImageContext{
   156  				Context: Context{
   157  					Format: NewImageFormat("table", false, true),
   158  				},
   159  				Digest: true,
   160  			},
   161  			`REPOSITORY          TAG                 DIGEST                                                                    IMAGE ID            CREATED             SIZE
   162  image               tag1                sha256:cbbf2f9a99b47fc460d422812b6a5adff7dfee951d8fa2e4a98caa0382cfbdbf   imageID1            24 hours ago        0 B
   163  image               tag2                <none>                                                                    imageID2            24 hours ago        0 B
   164  <none>              <none>              <none>                                                                    imageID3            24 hours ago        0 B
   165  `,
   166  		},
   167  		{
   168  			ImageContext{
   169  				Context: Context{
   170  					Format: NewImageFormat("table", true, true),
   171  				},
   172  				Digest: true,
   173  			},
   174  			"imageID1\nimageID2\nimageID3\n",
   175  		},
   176  		// Raw Format
   177  		{
   178  			ImageContext{
   179  				Context: Context{
   180  					Format: NewImageFormat("raw", false, false),
   181  				},
   182  			},
   183  			fmt.Sprintf(`repository: image
   184  tag: tag1
   185  image_id: imageID1
   186  created_at: %s
   187  virtual_size: 0 B
   188  
   189  repository: image
   190  tag: tag2
   191  image_id: imageID2
   192  created_at: %s
   193  virtual_size: 0 B
   194  
   195  repository: <none>
   196  tag: <none>
   197  image_id: imageID3
   198  created_at: %s
   199  virtual_size: 0 B
   200  
   201  `, expectedTime, expectedTime, expectedTime),
   202  		},
   203  		{
   204  			ImageContext{
   205  				Context: Context{
   206  					Format: NewImageFormat("raw", false, true),
   207  				},
   208  				Digest: true,
   209  			},
   210  			fmt.Sprintf(`repository: image
   211  tag: tag1
   212  digest: sha256:cbbf2f9a99b47fc460d422812b6a5adff7dfee951d8fa2e4a98caa0382cfbdbf
   213  image_id: imageID1
   214  created_at: %s
   215  virtual_size: 0 B
   216  
   217  repository: image
   218  tag: tag2
   219  digest: <none>
   220  image_id: imageID2
   221  created_at: %s
   222  virtual_size: 0 B
   223  
   224  repository: <none>
   225  tag: <none>
   226  digest: <none>
   227  image_id: imageID3
   228  created_at: %s
   229  virtual_size: 0 B
   230  
   231  `, expectedTime, expectedTime, expectedTime),
   232  		},
   233  		{
   234  			ImageContext{
   235  				Context: Context{
   236  					Format: NewImageFormat("raw", true, false),
   237  				},
   238  			},
   239  			`image_id: imageID1
   240  image_id: imageID2
   241  image_id: imageID3
   242  `,
   243  		},
   244  		// Custom Format
   245  		{
   246  			ImageContext{
   247  				Context: Context{
   248  					Format: NewImageFormat("{{.Repository}}", false, false),
   249  				},
   250  			},
   251  			"image\nimage\n<none>\n",
   252  		},
   253  		{
   254  			ImageContext{
   255  				Context: Context{
   256  					Format: NewImageFormat("{{.Repository}}", false, true),
   257  				},
   258  				Digest: true,
   259  			},
   260  			"image\nimage\n<none>\n",
   261  		},
   262  	}
   263  
   264  	for _, testcase := range cases {
   265  		images := []types.ImageSummary{
   266  			{ID: "imageID1", RepoTags: []string{"image:tag1"}, RepoDigests: []string{"image@sha256:cbbf2f9a99b47fc460d422812b6a5adff7dfee951d8fa2e4a98caa0382cfbdbf"}, Created: unixTime},
   267  			{ID: "imageID2", RepoTags: []string{"image:tag2"}, Created: unixTime},
   268  			{ID: "imageID3", RepoTags: []string{"<none>:<none>"}, RepoDigests: []string{"<none>@<none>"}, Created: unixTime},
   269  		}
   270  		out := bytes.NewBufferString("")
   271  		testcase.context.Output = out
   272  		err := ImageWrite(testcase.context, images)
   273  		if err != nil {
   274  			assert.Error(t, err, testcase.expected)
   275  		} else {
   276  			assert.Equal(t, out.String(), testcase.expected)
   277  		}
   278  	}
   279  }
   280  
   281  func TestImageContextWriteWithNoImage(t *testing.T) {
   282  	out := bytes.NewBufferString("")
   283  	images := []types.ImageSummary{}
   284  
   285  	contexts := []struct {
   286  		context  ImageContext
   287  		expected string
   288  	}{
   289  		{
   290  			ImageContext{
   291  				Context: Context{
   292  					Format: NewImageFormat("{{.Repository}}", false, false),
   293  					Output: out,
   294  				},
   295  			},
   296  			"",
   297  		},
   298  		{
   299  			ImageContext{
   300  				Context: Context{
   301  					Format: NewImageFormat("table {{.Repository}}", false, false),
   302  					Output: out,
   303  				},
   304  			},
   305  			"REPOSITORY\n",
   306  		},
   307  		{
   308  			ImageContext{
   309  				Context: Context{
   310  					Format: NewImageFormat("{{.Repository}}", false, true),
   311  					Output: out,
   312  				},
   313  			},
   314  			"",
   315  		},
   316  		{
   317  			ImageContext{
   318  				Context: Context{
   319  					Format: NewImageFormat("table {{.Repository}}", false, true),
   320  					Output: out,
   321  				},
   322  			},
   323  			"REPOSITORY          DIGEST\n",
   324  		},
   325  	}
   326  
   327  	for _, context := range contexts {
   328  		ImageWrite(context.context, images)
   329  		assert.Equal(t, out.String(), context.expected)
   330  		// Clean buffer
   331  		out.Reset()
   332  	}
   333  }