76d8bfdff4
This field was added in f0e5b3d7d8
to
account for older versions of the engine (Docker EE LTS versions), which
did not yet provide the OSType field in Docker info, and had to be manually
set using the TEST_OSTYPE env-var.
This patch removes the field in favor of the equivalent in DaemonInfo. It's
more verbose, but also less ambiguous what information we're using (i.e.,
the platform the daemon is running on, not the local platform).
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
183 lines
5.1 KiB
Go
183 lines
5.1 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/docker/docker/testutil"
|
|
"github.com/pkg/errors"
|
|
"gotest.tools/v3/icmd"
|
|
)
|
|
|
|
func getPrefixAndSlashFromDaemonPlatform() (prefix, slash string) {
|
|
if testEnv.DaemonInfo.OSType == "windows" {
|
|
return "c:", `\`
|
|
}
|
|
return "", "/"
|
|
}
|
|
|
|
// TODO: update code to call cmd.RunCmd directly, and remove this function
|
|
// Deprecated: use gotest.tools/icmd
|
|
func runCommandWithOutput(execCmd *exec.Cmd) (string, int, error) {
|
|
result := icmd.RunCmd(transformCmd(execCmd))
|
|
return result.Combined(), result.ExitCode, result.Error
|
|
}
|
|
|
|
// Temporary shim for migrating commands to the new function
|
|
func transformCmd(execCmd *exec.Cmd) icmd.Cmd {
|
|
return icmd.Cmd{
|
|
Command: execCmd.Args,
|
|
Env: execCmd.Env,
|
|
Dir: execCmd.Dir,
|
|
Stdin: execCmd.Stdin,
|
|
Stdout: execCmd.Stdout,
|
|
}
|
|
}
|
|
|
|
// ParseCgroupPaths parses 'procCgroupData', which is output of '/proc/<pid>/cgroup', and returns
|
|
// a map which cgroup name as key and path as value.
|
|
func ParseCgroupPaths(procCgroupData string) map[string]string {
|
|
cgroupPaths := map[string]string{}
|
|
for _, line := range strings.Split(procCgroupData, "\n") {
|
|
parts := strings.Split(line, ":")
|
|
if len(parts) != 3 {
|
|
continue
|
|
}
|
|
cgroupPaths[parts[1]] = parts[2]
|
|
}
|
|
return cgroupPaths
|
|
}
|
|
|
|
// RandomTmpDirPath provides a temporary path with rand string appended.
|
|
// does not create or checks if it exists.
|
|
func RandomTmpDirPath(s string, platform string) string {
|
|
// TODO: why doesn't this use os.TempDir() ?
|
|
tmp := "/tmp"
|
|
if platform == "windows" {
|
|
tmp = os.Getenv("TEMP")
|
|
}
|
|
path := filepath.Join(tmp, fmt.Sprintf("%s.%s", s, testutil.GenerateRandomAlphaOnlyString(10)))
|
|
if platform == "windows" {
|
|
return filepath.FromSlash(path) // Using \
|
|
}
|
|
return filepath.ToSlash(path) // Using /
|
|
}
|
|
|
|
// RunCommandPipelineWithOutput runs the array of commands with the output
|
|
// of each pipelined with the following (like cmd1 | cmd2 | cmd3 would do).
|
|
// It returns the final output, the exitCode different from 0 and the error
|
|
// if something bad happened.
|
|
// Deprecated: use icmd instead
|
|
func RunCommandPipelineWithOutput(cmds ...*exec.Cmd) (output string, err error) {
|
|
if len(cmds) < 2 {
|
|
return "", errors.New("pipeline does not have multiple cmds")
|
|
}
|
|
|
|
// connect stdin of each cmd to stdout pipe of previous cmd
|
|
for i, cmd := range cmds {
|
|
if i > 0 {
|
|
prevCmd := cmds[i-1]
|
|
cmd.Stdin, err = prevCmd.StdoutPipe()
|
|
|
|
if err != nil {
|
|
return "", fmt.Errorf("cannot set stdout pipe for %s: %v", cmd.Path, err)
|
|
}
|
|
}
|
|
}
|
|
|
|
// start all cmds except the last
|
|
for _, cmd := range cmds[:len(cmds)-1] {
|
|
if err = cmd.Start(); err != nil {
|
|
return "", fmt.Errorf("starting %s failed with error: %v", cmd.Path, err)
|
|
}
|
|
}
|
|
|
|
defer func() {
|
|
var pipeErrMsgs []string
|
|
// wait all cmds except the last to release their resources
|
|
for _, cmd := range cmds[:len(cmds)-1] {
|
|
if pipeErr := cmd.Wait(); pipeErr != nil {
|
|
pipeErrMsgs = append(pipeErrMsgs, fmt.Sprintf("command %s failed with error: %v", cmd.Path, pipeErr))
|
|
}
|
|
}
|
|
if len(pipeErrMsgs) > 0 && err == nil {
|
|
err = fmt.Errorf("pipelineError from Wait: %v", strings.Join(pipeErrMsgs, ", "))
|
|
}
|
|
}()
|
|
|
|
// wait on last cmd
|
|
out, err := cmds[len(cmds)-1].CombinedOutput()
|
|
return string(out), err
|
|
}
|
|
|
|
type elementListOptions struct {
|
|
element, format string
|
|
}
|
|
|
|
func existingElements(c *testing.T, opts elementListOptions) []string {
|
|
var args []string
|
|
switch opts.element {
|
|
case "container":
|
|
args = append(args, "ps", "-a")
|
|
case "image":
|
|
args = append(args, "images", "-a")
|
|
case "network":
|
|
args = append(args, "network", "ls")
|
|
case "plugin":
|
|
args = append(args, "plugin", "ls")
|
|
case "volume":
|
|
args = append(args, "volume", "ls")
|
|
}
|
|
if opts.format != "" {
|
|
args = append(args, "--format", opts.format)
|
|
}
|
|
out, _ := dockerCmd(c, args...)
|
|
var lines []string
|
|
for _, l := range strings.Split(out, "\n") {
|
|
if l != "" {
|
|
lines = append(lines, l)
|
|
}
|
|
}
|
|
return lines
|
|
}
|
|
|
|
// ExistingContainerIDs returns a list of currently existing container IDs.
|
|
func ExistingContainerIDs(c *testing.T) []string {
|
|
return existingElements(c, elementListOptions{element: "container", format: "{{.ID}}"})
|
|
}
|
|
|
|
// ExistingContainerNames returns a list of existing container names.
|
|
func ExistingContainerNames(c *testing.T) []string {
|
|
return existingElements(c, elementListOptions{element: "container", format: "{{.Names}}"})
|
|
}
|
|
|
|
// RemoveLinesForExistingElements removes existing elements from the output of a
|
|
// docker command.
|
|
// This function takes an output []string and returns a []string.
|
|
func RemoveLinesForExistingElements(output, existing []string) []string {
|
|
for _, e := range existing {
|
|
index := -1
|
|
for i, line := range output {
|
|
if strings.Contains(line, e) {
|
|
index = i
|
|
break
|
|
}
|
|
}
|
|
if index != -1 {
|
|
output = append(output[:index], output[index+1:]...)
|
|
}
|
|
}
|
|
return output
|
|
}
|
|
|
|
// RemoveOutputForExistingElements removes existing elements from the output of
|
|
// a docker command.
|
|
// This function takes an output string and returns a string.
|
|
func RemoveOutputForExistingElements(output string, existing []string) string {
|
|
res := RemoveLinesForExistingElements(strings.Split(output, "\n"), existing)
|
|
return strings.Join(res, "\n")
|
|
}
|