blob: 3fe1c5ddf704f2e4c9050cfb1c2214c1c5afbdd6 [file] [log] [blame]
package deps_parser
import (
"strings"
"testing"
"github.com/go-python/gpython/ast"
"github.com/stretchr/testify/require"
"go.skia.org/infra/go/deepequal/assertdeep"
)
const fakeDepsContent = `# This is a fake DEPS file.
# Extraneous declarations shouldn't trip us up.
unknown_thing = 'ok'
vars = {
'variable_repo': 'https://my-host/var-repo.git',
'variable_revision': 'var-revision',
'format_repo': 'https://my-host/format-repo.git',
'format_revision': 'format-revision',
'dict_revision': 'dict-revision',
'expr_prefix': 'expr/',
}
deps = {
'simple/dep': 'https://my-host/simple-repo.git@simple-revision',
'variable/dep': Var('variable_repo') + '@' + Var('variable_revision'),
'format/dep' : '{format_repo}@{format_revision}',
'dict/dep': {
'url': 'https://my-host/dict-repo.git@' + Var('dict_revision'),
'condition': 'always!!!1',
},
'cipd/deps': {
'packages': [
{
'package': 'package1',
'version': 'version1',
},
{
'package': 'package2/${{platform}}',
'version': 'version2',
},
{
'package': 'package3/' + Var('host_os') + '-' + Var('host_cpu'),
'version': 'pkg3-version',
}
],
'dep_type': 'cipd',
},
'gcs/example-gcs-dep': {
'bucket': 'my-gcs-bucket',
'objects': [
{
'object_name': 'some/gcs/object',
'sha256sum': 'abc123',
'size_bytes': 3203922,
'generation': 1664794206824773,
'output_file': 'gcs-dep-output-file1',
},
{
'object_name': 'another/gcs/object',
'sha256sum': 'def456',
'size_bytes': 55555,
'generation': 1664794206824382,
'output_file': 'gcs-dep-output-file2',
},
],
},
Var('expr_prefix')+'dep': 'https://my-host/expr-dep.git@version',
}
`
func TestParseDeps(t *testing.T) {
// Verify that we parse the DEPS content successfully and get the
// correct results for our toy example.
deps, poss, err := parseDeps(fakeDepsContent)
require.NoError(t, err)
require.Equal(t, len(deps), len(poss))
assertdeep.Equal(t, DepsEntries{
"my-host/simple-repo": {
Id: "my-host/simple-repo",
Version: "simple-revision",
Path: "simple/dep",
},
"my-host/var-repo": {
Id: "my-host/var-repo",
Version: "var-revision",
Path: "variable/dep",
},
"my-host/format-repo": {
Id: "my-host/format-repo",
Version: "format-revision",
Path: "format/dep",
},
"my-host/dict-repo": {
Id: "my-host/dict-repo",
Version: "dict-revision",
Path: "dict/dep",
},
"package1": {
Id: "package1",
Version: "version1",
Path: "cipd/deps",
},
"package2": {
Id: "package2",
Version: "version2",
Path: "cipd/deps",
},
"package3/linux-x64": {
Id: "package3/linux-x64",
Version: "pkg3-version",
Path: "cipd/deps",
},
"my-host/expr-dep": {
Id: "my-host/expr-dep",
Version: "version",
Path: "expr/dep",
},
"my-gcs-bucket/some/gcs/object": {
Id: "my-gcs-bucket/some/gcs/object",
Version: "abc123",
Path: "gcs/example-gcs-dep",
},
"my-gcs-bucket/another/gcs/object": {
Id: "my-gcs-bucket/another/gcs/object",
Version: "def456",
Path: "gcs/example-gcs-dep",
},
}, deps)
// Positions should point to where the versions are defined.
depsLines := strings.Split(fakeDepsContent, "\n")
for idx, dep := range deps {
pos := poss[idx]
// Lineno starts at 1.
lineIdx := pos.Lineno - 1
str := depsLines[lineIdx][pos.ColOffset:]
require.True(t, strings.Contains(str, dep.Version))
}
}
func TestSetDep(t *testing.T) {
before, beforePos, err := parseDeps(fakeDepsContent)
require.NoError(t, err)
beforeSplit := strings.Split(fakeDepsContent, "\n")
// testSetDep runs SetDep and verifies that it performed the correct
// modification.
testSetDep := func(id, version string) {
newDepsContent, err := SetDep(fakeDepsContent, id, version)
require.NoError(t, err)
after, afterPos, err := parseDeps(newDepsContent)
require.NoError(t, err)
var modifiedDepPos *ast.Pos
for depId, dep := range after {
expect := before[depId]
if depId == NormalizeDep(id) {
require.Equal(t, version, dep.Version)
// Set the version back so we can use assertdeep.Equal.
dep.Version = expect.Version
modifiedDepPos = afterPos[depId]
}
assertdeep.Equal(t, expect, dep)
assertdeep.Equal(t, beforePos[depId], afterPos[depId])
}
require.NotNil(t, modifiedDepPos, "Failed to find modified dep %q", id)
modifiedLineIdx := modifiedDepPos.Lineno - 1 // Lineno starts at 1.
// Ensure that we changed exactly one line.
afterSplit := strings.Split(newDepsContent, "\n")
require.Equal(t, len(beforeSplit), len(afterSplit))
for idx, expectLine := range beforeSplit {
actualLine := afterSplit[idx]
if idx == modifiedLineIdx {
require.NotEqual(t, expectLine, actualLine)
require.True(t, strings.Contains(actualLine, version))
} else {
require.Equal(t, expectLine, actualLine)
}
}
}
// Run testSetDep for each dependency in fakeDepsContent.
testSetDep("https://my-host/simple-repo.git", "newrev")
testSetDep("my-host/simple-repo", "newrev") // Already normalized.
testSetDep("https://my-host/var-repo.git", "newrev")
testSetDep("https://my-host/dict-repo.git", "newrev")
testSetDep("package1", "newrev")
testSetDep("package2", "newrev")
}
func TestHasGitSubmodules(t *testing.T) {
testHasSubmodule := func(testName, depsContent string, expected bool) {
t.Run(testName, func(t *testing.T) {
hasSubmodules, err := HasGitSubmodules(depsContent)
require.Nil(t, err)
require.Equal(t, expected, hasSubmodules)
})
}
testHasSubmodule("not defined", fakeDepsContent, false)
testHasSubmodule("explicit DEPS", `git_dependencies = "DEPS"`, false)
testHasSubmodule("in sync", `git_dependencies = "SYNC"`, true)
testHasSubmodule("just submodules", `git_dependencies = "SUBMODULES"`, true)
}