| package runconfig |
| |
| import ( |
| "bytes" |
| "encoding/json" |
| "fmt" |
| "io/ioutil" |
| "runtime" |
| "strings" |
| "testing" |
| |
| "github.com/docker/engine-api/types/container" |
| networktypes "github.com/docker/engine-api/types/network" |
| "github.com/docker/engine-api/types/strslice" |
| ) |
| |
| type f struct { |
| file string |
| entrypoint strslice.StrSlice |
| } |
| |
| func TestDecodeContainerConfig(t *testing.T) { |
| |
| var ( |
| fixtures []f |
| image string |
| ) |
| |
| if runtime.GOOS != "windows" { |
| image = "ubuntu" |
| fixtures = []f{ |
| {"fixtures/unix/container_config_1_14.json", strslice.StrSlice{}}, |
| {"fixtures/unix/container_config_1_17.json", strslice.StrSlice{"bash"}}, |
| {"fixtures/unix/container_config_1_19.json", strslice.StrSlice{"bash"}}, |
| } |
| } else { |
| image = "windows" |
| fixtures = []f{ |
| {"fixtures/windows/container_config_1_19.json", strslice.StrSlice{"cmd"}}, |
| } |
| } |
| |
| for _, f := range fixtures { |
| b, err := ioutil.ReadFile(f.file) |
| if err != nil { |
| t.Fatal(err) |
| } |
| |
| c, h, _, err := DecodeContainerConfig(bytes.NewReader(b)) |
| if err != nil { |
| t.Fatal(fmt.Errorf("Error parsing %s: %v", f, err)) |
| } |
| |
| if c.Image != image { |
| t.Fatalf("Expected %s image, found %s\n", image, c.Image) |
| } |
| |
| if len(c.Entrypoint) != len(f.entrypoint) { |
| t.Fatalf("Expected %v, found %v\n", f.entrypoint, c.Entrypoint) |
| } |
| |
| if h != nil && h.Memory != 1000 { |
| t.Fatalf("Expected memory to be 1000, found %d\n", h.Memory) |
| } |
| } |
| } |
| |
| // TestDecodeContainerConfigIsolation validates isolation passed |
| // to the daemon in the hostConfig structure. Note this is platform specific |
| // as to what level of container isolation is supported. |
| func TestDecodeContainerConfigIsolation(t *testing.T) { |
| |
| // An invalid isolation level |
| if _, _, _, err := callDecodeContainerConfigIsolation("invalid"); err != nil { |
| if !strings.Contains(err.Error(), `invalid --isolation: "invalid"`) { |
| t.Fatal(err) |
| } |
| } |
| |
| // Blank isolation (== default) |
| if _, _, _, err := callDecodeContainerConfigIsolation(""); err != nil { |
| t.Fatal("Blank isolation should have succeeded") |
| } |
| |
| // Default isolation |
| if _, _, _, err := callDecodeContainerConfigIsolation("default"); err != nil { |
| t.Fatal("default isolation should have succeeded") |
| } |
| |
| // Process isolation (Valid on Windows only) |
| if runtime.GOOS == "windows" { |
| if _, _, _, err := callDecodeContainerConfigIsolation("process"); err != nil { |
| t.Fatal("process isolation should have succeeded") |
| } |
| } else { |
| if _, _, _, err := callDecodeContainerConfigIsolation("process"); err != nil { |
| if !strings.Contains(err.Error(), `invalid --isolation: "process"`) { |
| t.Fatal(err) |
| } |
| } |
| } |
| |
| // Hyper-V Containers isolation (Valid on Windows only) |
| if runtime.GOOS == "windows" { |
| if _, _, _, err := callDecodeContainerConfigIsolation("hyperv"); err != nil { |
| t.Fatal("hyperv isolation should have succeeded") |
| } |
| } else { |
| if _, _, _, err := callDecodeContainerConfigIsolation("hyperv"); err != nil { |
| if !strings.Contains(err.Error(), `invalid --isolation: "hyperv"`) { |
| t.Fatal(err) |
| } |
| } |
| } |
| } |
| |
| // callDecodeContainerConfigIsolation is a utility function to call |
| // DecodeContainerConfig for validating isolation |
| func callDecodeContainerConfigIsolation(isolation string) (*container.Config, *container.HostConfig, *networktypes.NetworkingConfig, error) { |
| var ( |
| b []byte |
| err error |
| ) |
| w := ContainerConfigWrapper{ |
| Config: &container.Config{}, |
| HostConfig: &container.HostConfig{ |
| NetworkMode: "none", |
| Isolation: container.Isolation(isolation)}, |
| } |
| if b, err = json.Marshal(w); err != nil { |
| return nil, nil, nil, fmt.Errorf("Error on marshal %s", err.Error()) |
| } |
| return DecodeContainerConfig(bytes.NewReader(b)) |
| } |