コード例 #1
0
ファイル: archiver_test.go プロジェクト: shishkander/luci-go
func TestArchiverCancel(t *testing.T) {
	t.Parallel()
	server := isolatedfake.New()
	ts := httptest.NewServer(server)
	defer ts.Close()
	a := New(isolatedclient.New(ts.URL, "default-gzip"), nil)

	tmpDir, err := ioutil.TempDir("", "archiver")
	ut.AssertEqual(t, nil, err)
	defer func() {
		if err := os.RemoveAll(tmpDir); err != nil {
			t.Fail()
		}
	}()

	// This will trigger an eventual Cancel().
	nonexistent := filepath.Join(tmpDir, "nonexistent")
	future1 := a.PushFile("foo", nonexistent, 0)
	ut.AssertEqual(t, "foo", future1.DisplayName())

	fileName := filepath.Join(tmpDir, "existent")
	ut.AssertEqual(t, nil, ioutil.WriteFile(fileName, []byte("foo"), 0600))
	future2 := a.PushFile("existent", fileName, 0)
	future1.WaitForHashed()
	future2.WaitForHashed()
	expected := fmt.Errorf("hash(foo) failed: open %s: no such file or directory\n", nonexistent)
	if common.IsWindows() {
		expected = fmt.Errorf("hash(foo) failed: open %s: The system cannot find the file specified.\n", nonexistent)
	}
	ut.AssertEqual(t, expected, <-a.Channel())
	ut.AssertEqual(t, expected, a.Close())
	ut.AssertEqual(t, nil, server.Error())
}
コード例 #2
0
ファイル: format_test.go プロジェクト: shishkander/luci-go
func TestLoadIsolateAsConfig(t *testing.T) {
	t.Parallel()
	root := "/dir"
	if common.IsWindows() {
		root = "x:\\dir"
	}
	isolate, err := LoadIsolateAsConfig(root, []byte(sampleIsolateData))
	ut.AssertEqual(t, nil, err)
	ut.AssertEqual(t, []string{"OS", "bit"}, isolate.ConfigVariables)
}
コード例 #3
0
ファイル: isolate.go プロジェクト: shishkander/luci-go
// Init initializes with non-nil values.
func (a *ArchiveOptions) Init() {
	a.Blacklist = common.Strings{}
	a.PathVariables = map[string]string{}
	if common.IsWindows() {
		a.PathVariables["EXECUTABLE_SUFFIX"] = ".exe"
	} else {
		a.PathVariables["EXECUTABLE_SUFFIX"] = ""
	}
	a.ExtraVariables = map[string]string{}
	a.ConfigVariables = map[string]string{}
}
コード例 #4
0
ファイル: format.go プロジェクト: shishkander/luci-go
func loadIncludedIsolate(isolateDir, include string) (*Configs, error) {
	if filepath.IsAbs(include) {
		return nil, fmt.Errorf("failed to load configuration; absolute include path %s", include)
	}
	includedIsolate := filepath.Clean(filepath.Join(isolateDir, include))
	if common.IsWindows() && (strings.ToLower(includedIsolate)[0] != strings.ToLower(isolateDir)[0]) {
		return nil, errors.New("can't reference a .isolate file from another drive")
	}
	content, err := ioutil.ReadFile(includedIsolate)
	if err != nil {
		return nil, err
	}
	return LoadIsolateAsConfig(filepath.Dir(includedIsolate), content)
}
コード例 #5
0
ファイル: format_test.go プロジェクト: shishkander/luci-go
func TestLoadIsolateForConfig(t *testing.T) {
	t.Parallel()
	// Case linux64, matches first condition.
	root := "/dir"
	if common.IsWindows() {
		root = "x:\\dir"
	}
	vars := map[string]string{"bit": "64", "OS": "linux"}
	cmd, deps, ro, dir, err := LoadIsolateForConfig(root, []byte(sampleIsolateData), vars)
	ut.AssertEqual(t, nil, err)
	ut.AssertEqual(t, root, dir)
	ut.AssertEqual(t, NotSet, ro) // first condition has no read_only specified.
	ut.AssertEqual(t, []string{"python", "64linuxOrWin"}, cmd)
	ut.AssertEqual(t, []string{"64linuxOrWin", filepath.Join("<(PRODUCT_DIR)", "unittest<(EXECUTABLE_SUFFIX)")}, deps)

	// Case win64, matches only first condition.
	vars = map[string]string{"bit": "64", "OS": "win"}
	cmd, deps, ro, dir, err = LoadIsolateForConfig(root, []byte(sampleIsolateData), vars)
	ut.AssertEqual(t, nil, err)
	ut.AssertEqual(t, root, dir)
	ut.AssertEqual(t, NotSet, ro) // first condition has no read_only specified.
	ut.AssertEqual(t, []string{"python", "64linuxOrWin"}, cmd)
	ut.AssertEqual(t, []string{
		"64linuxOrWin",
		filepath.Join("<(PRODUCT_DIR)", "unittest<(EXECUTABLE_SUFFIX)"),
	}, deps)

	// Case mac64, matches only second condition.
	vars = map[string]string{"bit": "64", "OS": "mac"}
	cmd, deps, ro, dir, err = LoadIsolateForConfig(root, []byte(sampleIsolateData), vars)
	ut.AssertEqual(t, nil, err)
	ut.AssertEqual(t, root, dir)
	ut.AssertEqual(t, DirsReadOnly, ro) // second condition has read_only 2.
	ut.AssertEqual(t, []string{"python", "32orMac64"}, cmd)
	ut.AssertEqual(t, []string{}, deps)

	// Case win32, both first and second condition match.
	vars = map[string]string{"bit": "32", "OS": "win"}
	cmd, deps, ro, dir, err = LoadIsolateForConfig(root, []byte(sampleIsolateData), vars)
	ut.AssertEqual(t, nil, err)
	ut.AssertEqual(t, root, dir)
	ut.AssertEqual(t, DirsReadOnly, ro) // first condition no read_only, but second has 2.
	ut.AssertEqual(t, []string{"python", "32orMac64"}, cmd)
	ut.AssertEqual(t, []string{
		"64linuxOrWin",
		filepath.Join("<(PRODUCT_DIR)", "unittest<(EXECUTABLE_SUFFIX)"),
	}, deps)
}
コード例 #6
0
ファイル: format_test.go プロジェクト: shishkander/luci-go
func TestLoadIsolateForConfigMissingVars(t *testing.T) {
	t.Parallel()
	isoData := []byte(sampleIsolateData)
	root := "/dir"
	if common.IsWindows() {
		root = "x:\\dir"
	}
	_, _, _, _, err := LoadIsolateForConfig(root, isoData, nil)
	ut.AssertEqual(t, true, err != nil)
	ut.AssertEqualf(t, true, strings.Contains(err.Error(), "variables were missing"), "%s", err)
	ut.AssertEqualf(t, true, strings.Contains(err.Error(), "bit"), "%s", err)
	ut.AssertEqualf(t, true, strings.Contains(err.Error(), "OS"), "%s", err)
	_, _, _, _, err = LoadIsolateForConfig(root, isoData, map[string]string{"bit": "32"})
	ut.AssertEqual(t, true, err != nil)
	ut.AssertEqualf(t, true, strings.Contains(err.Error(), "variables were missing"), "%s", err)
	ut.AssertEqualf(t, true, strings.Contains(err.Error(), "OS"), "%s", err)
}
コード例 #7
0
ファイル: utils_test.go プロジェクト: shishkander/luci-go
func TestWalkInexistent(t *testing.T) {
	ch := make(chan *walkItem)
	var wg sync.WaitGroup
	wg.Add(1)
	go func() {
		defer wg.Done()
		defer close(ch)
		walk("inexistent_directory", nil, ch)
	}()
	item := <-ch
	err := errors.New("walk(inexistent_directory): lstat inexistent_directory: no such file or directory")
	if common.IsWindows() {
		err = errors.New("walk(inexistent_directory): GetFileAttributesEx inexistent_directory: The system cannot find the file specified.")
	}
	ut.AssertEqual(t, &walkItem{err: err}, item)
	item, ok := <-ch
	ut.AssertEqual(t, (*walkItem)(nil), item)
	ut.AssertEqual(t, false, ok)
	wg.Wait()
}
コード例 #8
0
func TestArchiveCMDParsing(t *testing.T) {
	t.Parallel()
	args := []string{
		"--isolated", "../biz/bar.isolated",
		"--isolate", "../boz/bar.isolate",
		"--path-variable", "DEPTH", "../..",
		"--path-variable", "PRODUCT_DIR", "../../out/Release",
		"--extra-variable", "version_full=42.0.2284.0",
		"--config-variable", "OS=linux",
	}
	root := absToOS("e:", "/tmp/bar")
	opts, err := parseArchiveCMD(args, root)
	base := filepath.Dir(root)
	ut.AssertEqual(t, filepath.Join(base, "boz", "bar.isolate"), opts.Isolate)
	ut.AssertEqual(t, filepath.Join(base, "biz", "bar.isolated"), opts.Isolated)
	ut.AssertEqual(t, nil, err)
	ut.AssertEqual(t, opts.ConfigVariables, stringmapflag.Value{"OS": "linux"})
	if common.IsWindows() {
		ut.AssertEqual(t, opts.PathVariables, stringmapflag.Value{"PRODUCT_DIR": "../../out/Release", "EXECUTABLE_SUFFIX": ".exe", "DEPTH": "../.."})
	} else {
		ut.AssertEqual(t, opts.PathVariables, stringmapflag.Value{"PRODUCT_DIR": "../../out/Release", "EXECUTABLE_SUFFIX": "", "DEPTH": "../.."})
	}
	ut.AssertEqual(t, opts.ExtraVariables, stringmapflag.Value{"version_full": "42.0.2284.0"})
}
コード例 #9
0
ファイル: format_test.go プロジェクト: shishkander/luci-go
// absToOS converts a POSIX path to OS specific format.
func absToOS(p string) string {
	if common.IsWindows() {
		return "e:" + strings.Replace(p, "/", "\\", -1)
	}
	return p
}
コード例 #10
0
ファイル: format.go プロジェクト: shishkander/luci-go
// union merges two config settings together into a new instance.
//
// A new instance is not created and self or rhs is returned if the other
// object is the empty object.
//
// self has priority over rhs for Command. Use the same IsolateDir as the
// one having a Command.
//
// Dependencies listed in rhs are patch adjusted ONLY if they don't start with
// a path variable, e.g. the characters '<('.
func (lhs *ConfigSettings) union(rhs *ConfigSettings) (*ConfigSettings, error) {
	// When an object has IsolateDir == "", it means it is the empty object.
	if lhs.IsolateDir == "" {
		return rhs, nil
	}
	if rhs.IsolateDir == "" {
		return lhs, nil
	}

	if common.IsWindows() && strings.ToLower(lhs.IsolateDir)[0] != strings.ToLower(rhs.IsolateDir)[0] {
		return nil, errors.New("All .isolate files must be on same drive")
	}

	// Takes the difference between the two isolateDir. Note that while
	// isolateDir is in native path case, all other references are in posix.
	useRHS := false
	var command []string
	if len(lhs.Command) > 0 {
		useRHS = false
		command = lhs.Command
	} else if len(rhs.Command) > 0 {
		useRHS = true
		command = rhs.Command
	} else {
		// If self doesn't define any file, use rhs.
		useRHS = len(lhs.Files) == 0
	}

	readOnly := rhs.ReadOnly
	if lhs.ReadOnly != NotSet {
		readOnly = lhs.ReadOnly
	}

	lRelCwd, rRelCwd := lhs.IsolateDir, rhs.IsolateDir
	lFiles, rFiles := lhs.Files, rhs.Files
	if useRHS {
		// Rebase files in rhs.
		lRelCwd, rRelCwd = rhs.IsolateDir, lhs.IsolateDir
		lFiles, rFiles = rhs.Files, lhs.Files
	}

	rebasePath, err := filepath.Rel(lRelCwd, rRelCwd)
	if err != nil {
		return nil, err
	}
	rebasePath = strings.Replace(rebasePath, osPathSeparator, "/", -1)

	filesSet := map[string]bool{}
	for _, f := range lFiles {
		filesSet[f] = true
	}
	for _, f := range rFiles {
		// Rebase item.
		if !(strings.HasPrefix(f, "<(") || rebasePath == ".") {
			// paths are posix here.
			trailingSlash := strings.HasSuffix(f, "/")
			f = path.Join(rebasePath, f)
			if trailingSlash {
				f += "/"
			}
		}
		filesSet[f] = true
	}
	// Remove duplicates.
	files := make([]string, 0, len(filesSet))
	for f := range filesSet {
		files = append(files, f)
	}
	sort.Strings(files)
	return &ConfigSettings{files, command, readOnly, lRelCwd}, nil
}
コード例 #11
0
ファイル: isolate_test.go プロジェクト: shishkander/luci-go
func TestArchive(t *testing.T) {
	// Create a .isolate file and archive it.
	t.Parallel()
	server := isolatedfake.New()
	ts := httptest.NewServer(server)
	defer ts.Close()
	a := archiver.New(isolatedclient.New(ts.URL, "default-gzip"), nil)

	// Setup temporary directory.
	//   /base/bar
	//   /base/ignored
	//   /foo/baz.isolate
	//   /link -> /base/bar
	// Result:
	//   /baz.isolated
	tmpDir, err := ioutil.TempDir("", "isolate")
	ut.AssertEqual(t, nil, err)
	defer func() {
		if err := os.RemoveAll(tmpDir); err != nil {
			t.Fail()
		}
	}()
	baseDir := filepath.Join(tmpDir, "base")
	fooDir := filepath.Join(tmpDir, "foo")
	ut.AssertEqual(t, nil, os.Mkdir(baseDir, 0700))
	ut.AssertEqual(t, nil, os.Mkdir(fooDir, 0700))
	ut.AssertEqual(t, nil, ioutil.WriteFile(filepath.Join(baseDir, "bar"), []byte("foo"), 0600))
	ut.AssertEqual(t, nil, ioutil.WriteFile(filepath.Join(baseDir, "ignored"), []byte("ignored"), 0600))
	isolate := `{
		'variables': {
			'files': [
				'../base/',
				'../link',
			],
		},
		'conditions': [
			['OS=="amiga"', {
				'variables': {
					'command': ['amiga', '<(EXTRA)'],
				},
			}],
			['OS=="win"', {
				'variables': {
					'command': ['win'],
				},
			}],
		],
	}`
	isolatePath := filepath.Join(fooDir, "baz.isolate")
	ut.AssertEqual(t, nil, ioutil.WriteFile(isolatePath, []byte(isolate), 0600))
	if !common.IsWindows() {
		ut.AssertEqual(t, nil, os.Symlink(filepath.Join("base", "bar"), filepath.Join(tmpDir, "link")))
	} else {
		ut.AssertEqual(t, nil, ioutil.WriteFile(filepath.Join(tmpDir, "link"), []byte("no link on Windows"), 0600))
	}
	opts := &ArchiveOptions{
		Isolate:         isolatePath,
		Isolated:        filepath.Join(tmpDir, "baz.isolated"),
		Blacklist:       common.Strings{"ignored", "*.isolate"},
		PathVariables:   map[string]string{"VAR": "wonderful"},
		ExtraVariables:  map[string]string{"EXTRA": "really"},
		ConfigVariables: map[string]string{"OS": "amiga"},
	}
	future := Archive(a, opts)
	ut.AssertEqual(t, "baz.isolated", future.DisplayName())
	future.WaitForHashed()
	ut.AssertEqual(t, nil, future.Error())
	ut.AssertEqual(t, nil, a.Close())

	mode := 0600
	if common.IsWindows() {
		mode = 0666
	}
	//   /base/
	isolatedDirData := isolated.Isolated{
		Algo: "sha-1",
		Files: map[string]isolated.File{
			filepath.Join("base", "bar"): {Digest: "0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33", Mode: newInt(mode), Size: newInt64(3)},
		},
		Version: isolated.IsolatedFormatVersion,
	}
	encoded, err := json.Marshal(isolatedDirData)
	ut.AssertEqual(t, nil, err)
	isolatedDirEncoded := string(encoded) + "\n"
	isolatedDirHash := isolated.HashBytes([]byte(isolatedDirEncoded))

	isolatedData := isolated.Isolated{
		Algo:        "sha-1",
		Command:     []string{"amiga", "really"},
		Files:       map[string]isolated.File{},
		Includes:    []isolated.HexDigest{isolatedDirHash},
		RelativeCwd: "foo",
		Version:     isolated.IsolatedFormatVersion,
	}
	if !common.IsWindows() {
		isolatedData.Files["link"] = isolated.File{Link: newString(filepath.Join("base", "bar"))}
	} else {
		isolatedData.Files["link"] = isolated.File{Digest: "12339b9756c2994f85c310d560bc8c142a6b79a1", Mode: newInt(0666), Size: newInt64(18)}
	}
	encoded, err = json.Marshal(isolatedData)
	ut.AssertEqual(t, nil, err)
	isolatedEncoded := string(encoded) + "\n"
	isolatedHash := isolated.HashBytes([]byte(isolatedEncoded))

	expected := map[string]string{
		"0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33": "foo",
		string(isolatedDirHash):                    isolatedDirEncoded,
		string(isolatedHash):                       isolatedEncoded,
	}
	if common.IsWindows() {
		expected["12339b9756c2994f85c310d560bc8c142a6b79a1"] = "no link on Windows"
	}
	actual := map[string]string{}
	for k, v := range server.Contents() {
		actual[string(k)] = string(v)
		ut.AssertEqualf(t, expected[string(k)], actual[string(k)], "%s: %#v", k, actual[string(k)])
	}
	ut.AssertEqual(t, expected, actual)
	ut.AssertEqual(t, isolatedHash, future.Digest())

	stats := a.Stats()
	ut.AssertEqual(t, 0, stats.TotalHits())
	ut.AssertEqual(t, common.Size(0), stats.TotalBytesHits())
	if !common.IsWindows() {
		ut.AssertEqual(t, 3, stats.TotalMisses())
		ut.AssertEqual(t, common.Size(3+len(isolatedDirEncoded)+len(isolatedEncoded)), stats.TotalBytesPushed())
	} else {
		ut.AssertEqual(t, 4, stats.TotalMisses())
		ut.AssertEqual(t, common.Size(3+18+len(isolatedDirEncoded)+len(isolatedEncoded)), stats.TotalBytesPushed())
	}

	ut.AssertEqual(t, nil, server.Error())
	digest, err := isolated.HashFile(filepath.Join(tmpDir, "baz.isolated"))
	ut.AssertEqual(t, isolated.DigestItem{isolatedHash, false, int64(len(isolatedEncoded))}, digest)
	ut.AssertEqual(t, nil, err)
}
コード例 #12
0
ファイル: utils_test.go プロジェクト: shishkander/luci-go
func TestPushDirectory(t *testing.T) {
	// Uploads a real directory. 2 times the same file.
	t.Parallel()
	server := isolatedfake.New()
	ts := httptest.NewServer(server)
	defer ts.Close()
	a := New(isolatedclient.New(ts.URL, "default-gzip"), nil)

	// Setup temporary directory.
	tmpDir, err := ioutil.TempDir("", "archiver")
	ut.AssertEqual(t, nil, err)
	defer func() {
		if err := os.RemoveAll(tmpDir); err != nil {
			t.Fail()
		}
	}()
	baseDir := filepath.Join(tmpDir, "base")
	ignoredDir := filepath.Join(tmpDir, "ignored1")
	ut.AssertEqual(t, nil, os.Mkdir(baseDir, 0700))
	ut.AssertEqual(t, nil, ioutil.WriteFile(filepath.Join(baseDir, "bar"), []byte("foo"), 0600))
	ut.AssertEqual(t, nil, ioutil.WriteFile(filepath.Join(baseDir, "bar_dupe"), []byte("foo"), 0600))
	if !common.IsWindows() {
		ut.AssertEqual(t, nil, os.Symlink("bar", filepath.Join(baseDir, "link")))
	}
	ut.AssertEqual(t, nil, ioutil.WriteFile(filepath.Join(baseDir, "ignored2"), []byte("ignored"), 0600))
	ut.AssertEqual(t, nil, os.Mkdir(ignoredDir, 0700))
	ut.AssertEqual(t, nil, ioutil.WriteFile(filepath.Join(ignoredDir, "really"), []byte("ignored"), 0600))

	future := PushDirectory(a, tmpDir, "", []string{"ignored1", filepath.Join("*", "ignored2")})
	ut.AssertEqual(t, filepath.Base(tmpDir)+".isolated", future.DisplayName())
	future.WaitForHashed()
	ut.AssertEqual(t, nil, a.Close())

	mode := 0600
	if common.IsWindows() {
		mode = 0666
	}
	isolatedData := isolated.Isolated{
		Algo: "sha-1",
		Files: map[string]isolated.File{
			filepath.Join("base", "bar"):      {Digest: "0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33", Mode: newInt(mode), Size: newInt64(3)},
			filepath.Join("base", "bar_dupe"): {Digest: "0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33", Mode: newInt(mode), Size: newInt64(3)},
		},
		Version: isolated.IsolatedFormatVersion,
	}
	if !common.IsWindows() {
		isolatedData.Files[filepath.Join("base", "link")] = isolated.File{Link: newString("bar")}
	}
	encoded, err := json.Marshal(isolatedData)
	ut.AssertEqual(t, nil, err)
	isolatedEncoded := string(encoded) + "\n"
	isolatedHash := isolated.HashBytes([]byte(isolatedEncoded))

	expected := map[string]string{
		"0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33": "foo",
		string(isolatedHash):                       isolatedEncoded,
	}
	actual := map[string]string{}
	for k, v := range server.Contents() {
		actual[string(k)] = string(v)
	}
	ut.AssertEqual(t, expected, actual)
	ut.AssertEqual(t, isolatedHash, future.Digest())

	stats := a.Stats()
	ut.AssertEqual(t, 0, stats.TotalHits())
	// There're 3 cache misses even if the same content is looked up twice.
	ut.AssertEqual(t, 3, stats.TotalMisses())
	ut.AssertEqual(t, common.Size(0), stats.TotalBytesHits())
	ut.AssertEqual(t, common.Size(3+3+len(isolatedEncoded)), stats.TotalBytesPushed())

	ut.AssertEqual(t, nil, server.Error())
}
コード例 #13
0
// absToOS converts a POSIX path to OS specific format.
func absToOS(drive, p string) string {
	if common.IsWindows() {
		return drive + strings.Replace(p, "/", "\\", -1)
	}
	return p
}