123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687 |
- package utils
- import (
- "fmt"
- "io/ioutil"
- "os"
- "runtime"
- "strings"
- "github.com/docker/docker/pkg/archive"
- "github.com/docker/docker/pkg/stringid"
- )
- var globalTestID string
- // TestDirectory creates a new temporary directory and returns its path.
- // The contents of directory at path `templateDir` is copied into the
- // new directory.
- func TestDirectory(templateDir string) (dir string, err error) {
- if globalTestID == "" {
- globalTestID = stringid.GenerateNonCryptoID()[:4]
- }
- prefix := fmt.Sprintf("docker-test%s-%s-", globalTestID, GetCallerName(2))
- if prefix == "" {
- prefix = "docker-test-"
- }
- dir, err = ioutil.TempDir("", prefix)
- if err = os.Remove(dir); err != nil {
- return
- }
- if templateDir != "" {
- if err = archive.CopyWithTar(templateDir, dir); err != nil {
- return
- }
- }
- return
- }
- // GetCallerName introspects the call stack and returns the name of the
- // function `depth` levels down in the stack.
- func GetCallerName(depth int) string {
- // Use the caller function name as a prefix.
- // This helps trace temp directories back to their test.
- pc, _, _, _ := runtime.Caller(depth + 1)
- callerLongName := runtime.FuncForPC(pc).Name()
- parts := strings.Split(callerLongName, ".")
- callerShortName := parts[len(parts)-1]
- return callerShortName
- }
- // ReplaceOrAppendEnvValues returns the defaults with the overrides either
- // replaced by env key or appended to the list
- func ReplaceOrAppendEnvValues(defaults, overrides []string) []string {
- cache := make(map[string]int, len(defaults))
- for i, e := range defaults {
- parts := strings.SplitN(e, "=", 2)
- cache[parts[0]] = i
- }
- for _, value := range overrides {
- // Values w/o = means they want this env to be removed/unset.
- if !strings.Contains(value, "=") {
- if i, exists := cache[value]; exists {
- defaults[i] = "" // Used to indicate it should be removed
- }
- continue
- }
- // Just do a normal set/update
- parts := strings.SplitN(value, "=", 2)
- if i, exists := cache[parts[0]]; exists {
- defaults[i] = value
- } else {
- defaults = append(defaults, value)
- }
- }
- // Now remove all entries that we want to "unset"
- for i := 0; i < len(defaults); i++ {
- if defaults[i] == "" {
- defaults = append(defaults[:i], defaults[i+1:]...)
- i--
- }
- }
- return defaults
- }
|