github.com/vieux/docker@v0.6.3-0.20161004191708-e097c2a938c7/integration-cli/requirements.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"net/http"
     7  	"os"
     8  	"os/exec"
     9  	"strings"
    10  	"time"
    11  
    12  	"github.com/docker/docker/utils"
    13  	"github.com/go-check/check"
    14  )
    15  
    16  type testCondition func() bool
    17  
    18  type testRequirement struct {
    19  	Condition   testCondition
    20  	SkipMessage string
    21  }
    22  
    23  // List test requirements
    24  var (
    25  	DaemonIsWindows = testRequirement{
    26  		func() bool { return daemonPlatform == "windows" },
    27  		"Test requires a Windows daemon",
    28  	}
    29  	DaemonIsLinux = testRequirement{
    30  		func() bool { return daemonPlatform == "linux" },
    31  		"Test requires a Linux daemon",
    32  	}
    33  	ExperimentalDaemon = testRequirement{
    34  		func() bool { return utils.ExperimentalBuild() },
    35  		"Test requires an experimental daemon",
    36  	}
    37  	NotExperimentalDaemon = testRequirement{
    38  		func() bool { return !utils.ExperimentalBuild() },
    39  		"Test requires a non experimental daemon",
    40  	}
    41  	IsAmd64 = testRequirement{
    42  		func() bool { return os.Getenv("DOCKER_ENGINE_GOARCH") == "amd64" },
    43  		"Test requires a daemon running on amd64",
    44  	}
    45  	NotArm = testRequirement{
    46  		func() bool { return os.Getenv("DOCKER_ENGINE_GOARCH") != "arm" },
    47  		"Test requires a daemon not running on ARM",
    48  	}
    49  	NotArm64 = testRequirement{
    50  		func() bool { return os.Getenv("DOCKER_ENGINE_GOARCH") != "arm64" },
    51  		"Test requires a daemon not running on arm64",
    52  	}
    53  	NotPpc64le = testRequirement{
    54  		func() bool { return os.Getenv("DOCKER_ENGINE_GOARCH") != "ppc64le" },
    55  		"Test requires a daemon not running on ppc64le",
    56  	}
    57  	NotS390X = testRequirement{
    58  		func() bool { return os.Getenv("DOCKER_ENGINE_GOARCH") != "s390x" },
    59  		"Test requires a daemon not running on s390x",
    60  	}
    61  	SameHostDaemon = testRequirement{
    62  		func() bool { return isLocalDaemon },
    63  		"Test requires docker daemon to run on the same machine as CLI",
    64  	}
    65  	UnixCli = testRequirement{
    66  		func() bool { return isUnixCli },
    67  		"Test requires posix utilities or functionality to run.",
    68  	}
    69  	ExecSupport = testRequirement{
    70  		func() bool { return supportsExec },
    71  		"Test requires 'docker exec' capabilities on the tested daemon.",
    72  	}
    73  	Network = testRequirement{
    74  		func() bool {
    75  			// Set a timeout on the GET at 15s
    76  			var timeout = time.Duration(15 * time.Second)
    77  			var url = "https://hub.docker.com"
    78  
    79  			client := http.Client{
    80  				Timeout: timeout,
    81  			}
    82  
    83  			resp, err := client.Get(url)
    84  			if err != nil && strings.Contains(err.Error(), "use of closed network connection") {
    85  				panic(fmt.Sprintf("Timeout for GET request on %s", url))
    86  			}
    87  			if resp != nil {
    88  				resp.Body.Close()
    89  			}
    90  			return err == nil
    91  		},
    92  		"Test requires network availability, environment variable set to none to run in a non-network enabled mode.",
    93  	}
    94  	Apparmor = testRequirement{
    95  		func() bool {
    96  			buf, err := ioutil.ReadFile("/sys/module/apparmor/parameters/enabled")
    97  			return err == nil && len(buf) > 1 && buf[0] == 'Y'
    98  		},
    99  		"Test requires apparmor is enabled.",
   100  	}
   101  	RegistryHosting = testRequirement{
   102  		func() bool {
   103  			// for now registry binary is built only if we're running inside
   104  			// container through `make test`. Figure that out by testing if
   105  			// registry binary is in PATH.
   106  			_, err := exec.LookPath(v2binary)
   107  			return err == nil
   108  		},
   109  		fmt.Sprintf("Test requires an environment that can host %s in the same host", v2binary),
   110  	}
   111  	NotaryHosting = testRequirement{
   112  		func() bool {
   113  			// for now notary binary is built only if we're running inside
   114  			// container through `make test`. Figure that out by testing if
   115  			// notary-server binary is in PATH.
   116  			_, err := exec.LookPath(notaryServerBinary)
   117  			return err == nil
   118  		},
   119  		fmt.Sprintf("Test requires an environment that can host %s in the same host", notaryServerBinary),
   120  	}
   121  	NotaryServerHosting = testRequirement{
   122  		func() bool {
   123  			// for now notary-server binary is built only if we're running inside
   124  			// container through `make test`. Figure that out by testing if
   125  			// notary-server binary is in PATH.
   126  			_, err := exec.LookPath(notaryServerBinary)
   127  			return err == nil
   128  		},
   129  		fmt.Sprintf("Test requires an environment that can host %s in the same host", notaryServerBinary),
   130  	}
   131  	NotOverlay = testRequirement{
   132  		func() bool {
   133  			return !strings.HasPrefix(daemonStorageDriver, "overlay")
   134  		},
   135  		"Test requires underlying root filesystem not be backed by overlay.",
   136  	}
   137  
   138  	Devicemapper = testRequirement{
   139  		func() bool {
   140  			return strings.HasPrefix(daemonStorageDriver, "devicemapper")
   141  		},
   142  		"Test requires underlying root filesystem to be backed by devicemapper.",
   143  	}
   144  
   145  	IPv6 = testRequirement{
   146  		func() bool {
   147  			cmd := exec.Command("test", "-f", "/proc/net/if_inet6")
   148  
   149  			if err := cmd.Run(); err != nil {
   150  				return true
   151  			}
   152  			return false
   153  		},
   154  		"Test requires support for IPv6",
   155  	}
   156  	UserNamespaceROMount = testRequirement{
   157  		func() bool {
   158  			// quick case--userns not enabled in this test run
   159  			if os.Getenv("DOCKER_REMAP_ROOT") == "" {
   160  				return true
   161  			}
   162  			if _, _, err := dockerCmdWithError("run", "--rm", "--read-only", "busybox", "date"); err != nil {
   163  				return false
   164  			}
   165  			return true
   166  		},
   167  		"Test cannot be run if user namespaces enabled but readonly mounts fail on this kernel.",
   168  	}
   169  	UserNamespaceInKernel = testRequirement{
   170  		func() bool {
   171  			if _, err := os.Stat("/proc/self/uid_map"); os.IsNotExist(err) {
   172  				/*
   173  				 * This kernel-provided file only exists if user namespaces are
   174  				 * supported
   175  				 */
   176  				return false
   177  			}
   178  
   179  			// We need extra check on redhat based distributions
   180  			if f, err := os.Open("/sys/module/user_namespace/parameters/enable"); err == nil {
   181  				defer f.Close()
   182  				b := make([]byte, 1)
   183  				_, _ = f.Read(b)
   184  				if string(b) == "N" {
   185  					return false
   186  				}
   187  				return true
   188  			}
   189  
   190  			return true
   191  		},
   192  		"Kernel must have user namespaces configured and enabled.",
   193  	}
   194  	NotUserNamespace = testRequirement{
   195  		func() bool {
   196  			root := os.Getenv("DOCKER_REMAP_ROOT")
   197  			if root != "" {
   198  				return false
   199  			}
   200  			return true
   201  		},
   202  		"Test cannot be run when remapping root",
   203  	}
   204  )
   205  
   206  // testRequires checks if the environment satisfies the requirements
   207  // for the test to run or skips the tests.
   208  func testRequires(c *check.C, requirements ...testRequirement) {
   209  	for _, r := range requirements {
   210  		if !r.Condition() {
   211  			c.Skip(r.SkipMessage)
   212  		}
   213  	}
   214  }