github.com/noxiouz/docker@v0.7.3-0.20160629055221-3d231c78e8c5/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  	NotArm = testRequirement{
    42  		func() bool { return os.Getenv("DOCKER_ENGINE_GOARCH") != "arm" },
    43  		"Test requires a daemon not running on ARM",
    44  	}
    45  	NotPpc64le = testRequirement{
    46  		func() bool { return os.Getenv("DOCKER_ENGINE_GOARCH") != "ppc64le" },
    47  		"Test requires a daemon not running on ppc64le",
    48  	}
    49  	NotS390X = testRequirement{
    50  		func() bool { return os.Getenv("DOCKER_ENGINE_GOARCH") != "s390x" },
    51  		"Test requires a daemon not running on s390x",
    52  	}
    53  	SameHostDaemon = testRequirement{
    54  		func() bool { return isLocalDaemon },
    55  		"Test requires docker daemon to run on the same machine as CLI",
    56  	}
    57  	UnixCli = testRequirement{
    58  		func() bool { return isUnixCli },
    59  		"Test requires posix utilities or functionality to run.",
    60  	}
    61  	ExecSupport = testRequirement{
    62  		func() bool { return supportsExec },
    63  		"Test requires 'docker exec' capabilities on the tested daemon.",
    64  	}
    65  	Network = testRequirement{
    66  		func() bool {
    67  			// Set a timeout on the GET at 15s
    68  			var timeout = time.Duration(15 * time.Second)
    69  			var url = "https://hub.docker.com"
    70  
    71  			client := http.Client{
    72  				Timeout: timeout,
    73  			}
    74  
    75  			resp, err := client.Get(url)
    76  			if err != nil && strings.Contains(err.Error(), "use of closed network connection") {
    77  				panic(fmt.Sprintf("Timeout for GET request on %s", url))
    78  			}
    79  			if resp != nil {
    80  				resp.Body.Close()
    81  			}
    82  			return err == nil
    83  		},
    84  		"Test requires network availability, environment variable set to none to run in a non-network enabled mode.",
    85  	}
    86  	Apparmor = testRequirement{
    87  		func() bool {
    88  			buf, err := ioutil.ReadFile("/sys/module/apparmor/parameters/enabled")
    89  			return err == nil && len(buf) > 1 && buf[0] == 'Y'
    90  		},
    91  		"Test requires apparmor is enabled.",
    92  	}
    93  	RegistryHosting = testRequirement{
    94  		func() bool {
    95  			// for now registry binary is built only if we're running inside
    96  			// container through `make test`. Figure that out by testing if
    97  			// registry binary is in PATH.
    98  			_, err := exec.LookPath(v2binary)
    99  			return err == nil
   100  		},
   101  		fmt.Sprintf("Test requires an environment that can host %s in the same host", v2binary),
   102  	}
   103  	NotaryHosting = testRequirement{
   104  		func() bool {
   105  			// for now notary binary is built only if we're running inside
   106  			// container through `make test`. Figure that out by testing if
   107  			// notary-server binary is in PATH.
   108  			_, err := exec.LookPath(notaryServerBinary)
   109  			return err == nil
   110  		},
   111  		fmt.Sprintf("Test requires an environment that can host %s in the same host", notaryServerBinary),
   112  	}
   113  	NotaryServerHosting = testRequirement{
   114  		func() bool {
   115  			// for now notary-server binary is built only if we're running inside
   116  			// container through `make test`. Figure that out by testing if
   117  			// notary-server binary is in PATH.
   118  			_, err := exec.LookPath(notaryServerBinary)
   119  			return err == nil
   120  		},
   121  		fmt.Sprintf("Test requires an environment that can host %s in the same host", notaryServerBinary),
   122  	}
   123  	NotOverlay = testRequirement{
   124  		func() bool {
   125  			return !strings.HasPrefix(daemonStorageDriver, "overlay")
   126  		},
   127  		"Test requires underlying root filesystem not be backed by overlay.",
   128  	}
   129  
   130  	Devicemapper = testRequirement{
   131  		func() bool {
   132  			return strings.HasPrefix(daemonStorageDriver, "devicemapper")
   133  		},
   134  		"Test requires underlying root filesystem to be backed by devicemapper.",
   135  	}
   136  
   137  	IPv6 = testRequirement{
   138  		func() bool {
   139  			cmd := exec.Command("test", "-f", "/proc/net/if_inet6")
   140  
   141  			if err := cmd.Run(); err != nil {
   142  				return true
   143  			}
   144  			return false
   145  		},
   146  		"Test requires support for IPv6",
   147  	}
   148  	NotGCCGO = testRequirement{
   149  		func() bool {
   150  			out, err := exec.Command("go", "version").Output()
   151  			if err == nil && strings.Contains(string(out), "gccgo") {
   152  				return false
   153  			}
   154  			return true
   155  		},
   156  		"Test requires native Golang compiler instead of GCCGO",
   157  	}
   158  	UserNamespaceInKernel = testRequirement{
   159  		func() bool {
   160  			if _, err := os.Stat("/proc/self/uid_map"); os.IsNotExist(err) {
   161  				/*
   162  				 * This kernel-provided file only exists if user namespaces are
   163  				 * supported
   164  				 */
   165  				return false
   166  			}
   167  
   168  			// We need extra check on redhat based distributions
   169  			if f, err := os.Open("/sys/module/user_namespace/parameters/enable"); err == nil {
   170  				b := make([]byte, 1)
   171  				_, _ = f.Read(b)
   172  				if string(b) == "N" {
   173  					return false
   174  				}
   175  				return true
   176  			}
   177  
   178  			return true
   179  		},
   180  		"Kernel must have user namespaces configured and enabled.",
   181  	}
   182  	NotUserNamespace = testRequirement{
   183  		func() bool {
   184  			root := os.Getenv("DOCKER_REMAP_ROOT")
   185  			if root != "" {
   186  				return false
   187  			}
   188  			return true
   189  		},
   190  		"Test cannot be run when remapping root",
   191  	}
   192  )
   193  
   194  // testRequires checks if the environment satisfies the requirements
   195  // for the test to run or skips the tests.
   196  func testRequires(c *check.C, requirements ...testRequirement) {
   197  	for _, r := range requirements {
   198  		if !r.Condition() {
   199  			c.Skip(r.SkipMessage)
   200  		}
   201  	}
   202  }