github.com/zhouyu0/docker-note@v0.0.0-20190722021225-b8d3825084db/integration/container/create_test.go (about)

     1  package container // import "github.com/docker/docker/integration/container"
     2  
     3  import (
     4  	"context"
     5  	"encoding/json"
     6  	"fmt"
     7  	"strconv"
     8  	"testing"
     9  	"time"
    10  
    11  	"github.com/docker/docker/api/types"
    12  	"github.com/docker/docker/api/types/container"
    13  	"github.com/docker/docker/api/types/network"
    14  	ctr "github.com/docker/docker/integration/internal/container"
    15  	"github.com/docker/docker/oci"
    16  	"gotest.tools/assert"
    17  	is "gotest.tools/assert/cmp"
    18  	"gotest.tools/poll"
    19  	"gotest.tools/skip"
    20  )
    21  
    22  func TestCreateFailsWhenIdentifierDoesNotExist(t *testing.T) {
    23  	defer setupTest(t)()
    24  	client := testEnv.APIClient()
    25  
    26  	testCases := []struct {
    27  		doc           string
    28  		image         string
    29  		expectedError string
    30  	}{
    31  		{
    32  			doc:           "image and tag",
    33  			image:         "test456:v1",
    34  			expectedError: "No such image: test456:v1",
    35  		},
    36  		{
    37  			doc:           "image no tag",
    38  			image:         "test456",
    39  			expectedError: "No such image: test456",
    40  		},
    41  		{
    42  			doc:           "digest",
    43  			image:         "sha256:0cb40641836c461bc97c793971d84d758371ed682042457523e4ae701efeaaaa",
    44  			expectedError: "No such image: sha256:0cb40641836c461bc97c793971d84d758371ed682042457523e4ae701efeaaaa",
    45  		},
    46  	}
    47  
    48  	for _, tc := range testCases {
    49  		tc := tc
    50  		t.Run(tc.doc, func(t *testing.T) {
    51  			t.Parallel()
    52  			_, err := client.ContainerCreate(context.Background(),
    53  				&container.Config{Image: tc.image},
    54  				&container.HostConfig{},
    55  				&network.NetworkingConfig{},
    56  				"",
    57  			)
    58  			assert.Check(t, is.ErrorContains(err, tc.expectedError))
    59  		})
    60  	}
    61  }
    62  
    63  func TestCreateWithInvalidEnv(t *testing.T) {
    64  	defer setupTest(t)()
    65  	client := testEnv.APIClient()
    66  
    67  	testCases := []struct {
    68  		env           string
    69  		expectedError string
    70  	}{
    71  		{
    72  			env:           "",
    73  			expectedError: "invalid environment variable:",
    74  		},
    75  		{
    76  			env:           "=",
    77  			expectedError: "invalid environment variable: =",
    78  		},
    79  		{
    80  			env:           "=foo",
    81  			expectedError: "invalid environment variable: =foo",
    82  		},
    83  	}
    84  
    85  	for index, tc := range testCases {
    86  		tc := tc
    87  		t.Run(strconv.Itoa(index), func(t *testing.T) {
    88  			t.Parallel()
    89  			_, err := client.ContainerCreate(context.Background(),
    90  				&container.Config{
    91  					Image: "busybox",
    92  					Env:   []string{tc.env},
    93  				},
    94  				&container.HostConfig{},
    95  				&network.NetworkingConfig{},
    96  				"",
    97  			)
    98  			assert.Check(t, is.ErrorContains(err, tc.expectedError))
    99  		})
   100  	}
   101  }
   102  
   103  // Test case for #30166 (target was not validated)
   104  func TestCreateTmpfsMountsTarget(t *testing.T) {
   105  	skip.If(t, testEnv.DaemonInfo.OSType == "windows")
   106  
   107  	defer setupTest(t)()
   108  	client := testEnv.APIClient()
   109  
   110  	testCases := []struct {
   111  		target        string
   112  		expectedError string
   113  	}{
   114  		{
   115  			target:        ".",
   116  			expectedError: "mount path must be absolute",
   117  		},
   118  		{
   119  			target:        "foo",
   120  			expectedError: "mount path must be absolute",
   121  		},
   122  		{
   123  			target:        "/",
   124  			expectedError: "destination can't be '/'",
   125  		},
   126  		{
   127  			target:        "//",
   128  			expectedError: "destination can't be '/'",
   129  		},
   130  	}
   131  
   132  	for _, tc := range testCases {
   133  		_, err := client.ContainerCreate(context.Background(),
   134  			&container.Config{
   135  				Image: "busybox",
   136  			},
   137  			&container.HostConfig{
   138  				Tmpfs: map[string]string{tc.target: ""},
   139  			},
   140  			&network.NetworkingConfig{},
   141  			"",
   142  		)
   143  		assert.Check(t, is.ErrorContains(err, tc.expectedError))
   144  	}
   145  }
   146  func TestCreateWithCustomMaskedPaths(t *testing.T) {
   147  	skip.If(t, testEnv.DaemonInfo.OSType != "linux")
   148  
   149  	defer setupTest(t)()
   150  	client := testEnv.APIClient()
   151  	ctx := context.Background()
   152  
   153  	testCases := []struct {
   154  		maskedPaths []string
   155  		expected    []string
   156  	}{
   157  		{
   158  			maskedPaths: []string{},
   159  			expected:    []string{},
   160  		},
   161  		{
   162  			maskedPaths: nil,
   163  			expected:    oci.DefaultSpec().Linux.MaskedPaths,
   164  		},
   165  		{
   166  			maskedPaths: []string{"/proc/kcore", "/proc/keys"},
   167  			expected:    []string{"/proc/kcore", "/proc/keys"},
   168  		},
   169  	}
   170  
   171  	checkInspect := func(t *testing.T, ctx context.Context, name string, expected []string) {
   172  		_, b, err := client.ContainerInspectWithRaw(ctx, name, false)
   173  		assert.NilError(t, err)
   174  
   175  		var inspectJSON map[string]interface{}
   176  		err = json.Unmarshal(b, &inspectJSON)
   177  		assert.NilError(t, err)
   178  
   179  		cfg, ok := inspectJSON["HostConfig"].(map[string]interface{})
   180  		assert.Check(t, is.Equal(true, ok), name)
   181  
   182  		maskedPaths, ok := cfg["MaskedPaths"].([]interface{})
   183  		assert.Check(t, is.Equal(true, ok), name)
   184  
   185  		mps := []string{}
   186  		for _, mp := range maskedPaths {
   187  			mps = append(mps, mp.(string))
   188  		}
   189  
   190  		assert.DeepEqual(t, expected, mps)
   191  	}
   192  
   193  	for i, tc := range testCases {
   194  		name := fmt.Sprintf("create-masked-paths-%d", i)
   195  		config := container.Config{
   196  			Image: "busybox",
   197  			Cmd:   []string{"true"},
   198  		}
   199  		hc := container.HostConfig{}
   200  		if tc.maskedPaths != nil {
   201  			hc.MaskedPaths = tc.maskedPaths
   202  		}
   203  
   204  		// Create the container.
   205  		c, err := client.ContainerCreate(context.Background(),
   206  			&config,
   207  			&hc,
   208  			&network.NetworkingConfig{},
   209  			name,
   210  		)
   211  		assert.NilError(t, err)
   212  
   213  		checkInspect(t, ctx, name, tc.expected)
   214  
   215  		// Start the container.
   216  		err = client.ContainerStart(ctx, c.ID, types.ContainerStartOptions{})
   217  		assert.NilError(t, err)
   218  
   219  		poll.WaitOn(t, ctr.IsInState(ctx, client, c.ID, "exited"), poll.WithDelay(100*time.Millisecond))
   220  
   221  		checkInspect(t, ctx, name, tc.expected)
   222  	}
   223  }
   224  
   225  func TestCreateWithCustomReadonlyPaths(t *testing.T) {
   226  	skip.If(t, testEnv.DaemonInfo.OSType != "linux")
   227  
   228  	defer setupTest(t)()
   229  	client := testEnv.APIClient()
   230  	ctx := context.Background()
   231  
   232  	testCases := []struct {
   233  		doc           string
   234  		readonlyPaths []string
   235  		expected      []string
   236  	}{
   237  		{
   238  			readonlyPaths: []string{},
   239  			expected:      []string{},
   240  		},
   241  		{
   242  			readonlyPaths: nil,
   243  			expected:      oci.DefaultSpec().Linux.ReadonlyPaths,
   244  		},
   245  		{
   246  			readonlyPaths: []string{"/proc/asound", "/proc/bus"},
   247  			expected:      []string{"/proc/asound", "/proc/bus"},
   248  		},
   249  	}
   250  
   251  	checkInspect := func(t *testing.T, ctx context.Context, name string, expected []string) {
   252  		_, b, err := client.ContainerInspectWithRaw(ctx, name, false)
   253  		assert.NilError(t, err)
   254  
   255  		var inspectJSON map[string]interface{}
   256  		err = json.Unmarshal(b, &inspectJSON)
   257  		assert.NilError(t, err)
   258  
   259  		cfg, ok := inspectJSON["HostConfig"].(map[string]interface{})
   260  		assert.Check(t, is.Equal(true, ok), name)
   261  
   262  		readonlyPaths, ok := cfg["ReadonlyPaths"].([]interface{})
   263  		assert.Check(t, is.Equal(true, ok), name)
   264  
   265  		rops := []string{}
   266  		for _, rop := range readonlyPaths {
   267  			rops = append(rops, rop.(string))
   268  		}
   269  		assert.DeepEqual(t, expected, rops)
   270  	}
   271  
   272  	for i, tc := range testCases {
   273  		name := fmt.Sprintf("create-readonly-paths-%d", i)
   274  		config := container.Config{
   275  			Image: "busybox",
   276  			Cmd:   []string{"true"},
   277  		}
   278  		hc := container.HostConfig{}
   279  		if tc.readonlyPaths != nil {
   280  			hc.ReadonlyPaths = tc.readonlyPaths
   281  		}
   282  
   283  		// Create the container.
   284  		c, err := client.ContainerCreate(context.Background(),
   285  			&config,
   286  			&hc,
   287  			&network.NetworkingConfig{},
   288  			name,
   289  		)
   290  		assert.NilError(t, err)
   291  
   292  		checkInspect(t, ctx, name, tc.expected)
   293  
   294  		// Start the container.
   295  		err = client.ContainerStart(ctx, c.ID, types.ContainerStartOptions{})
   296  		assert.NilError(t, err)
   297  
   298  		poll.WaitOn(t, ctr.IsInState(ctx, client, c.ID, "exited"), poll.WithDelay(100*time.Millisecond))
   299  
   300  		checkInspect(t, ctx, name, tc.expected)
   301  	}
   302  }