package config_test
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
"gerrit.wikimedia.org/r/blubber/build"
|
|
"gerrit.wikimedia.org/r/blubber/config"
|
|
)
|
|
|
|
func TestVariantConfigYAML(t *testing.T) {
|
|
cfg, err := config.ReadYAMLConfig([]byte(`---
|
|
version: v4
|
|
base: foo
|
|
variants:
|
|
build:
|
|
copies: [local]
|
|
production:
|
|
copies:
|
|
- from: build
|
|
source: /foo/src
|
|
destination: /foo/dst
|
|
- from: build
|
|
source: /bar/src
|
|
destination: /bar/dst`))
|
|
|
|
if assert.NoError(t, err) {
|
|
variant, err := config.ExpandVariant(cfg, "build")
|
|
|
|
if assert.NoError(t, err) {
|
|
assert.Len(t, variant.Copies, 1)
|
|
}
|
|
|
|
variant, err = config.ExpandVariant(cfg, "production")
|
|
|
|
if assert.NoError(t, err) {
|
|
assert.Len(t, variant.Copies, 2)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestVariantLoops(t *testing.T) {
|
|
cfg := config.Config{
|
|
Variants: map[string]config.VariantConfig{
|
|
"foo": config.VariantConfig{Includes: []string{"bar"}},
|
|
"bar": config.VariantConfig{Includes: []string{"foo"}}}}
|
|
|
|
cfgTwo := config.Config{
|
|
Variants: map[string]config.VariantConfig{
|
|
"foo": config.VariantConfig{},
|
|
"bar": config.VariantConfig{Includes: []string{"foo"}}}}
|
|
|
|
// Configuration that contains a loop in "Includes" should error
|
|
_, err := config.ExpandVariant(&cfg, "bar")
|
|
assert.Error(t, err)
|
|
|
|
_, errTwo := config.ExpandVariant(&cfgTwo, "bar")
|
|
assert.NoError(t, errTwo)
|
|
}
|
|
|
|
func TestVariantConfigInstructions(t *testing.T) {
|
|
t.Run("PhaseInstall", func(t *testing.T) {
|
|
t.Run("without copies", func(t *testing.T) {
|
|
cfg := config.VariantConfig{}
|
|
|
|
assert.Empty(t, cfg.InstructionsForPhase(build.PhaseInstall))
|
|
})
|
|
|
|
t.Run("with copies", func(t *testing.T) {
|
|
cfg := config.VariantConfig{
|
|
CommonConfig: config.CommonConfig{
|
|
Lives: config.LivesConfig{UserConfig: config.UserConfig{UID: 123, GID: 223}},
|
|
},
|
|
Copies: config.CopiesConfig{
|
|
{From: "local"},
|
|
{From: "build", Source: "/foo/src", Destination: "/foo/dst"},
|
|
},
|
|
}
|
|
|
|
assert.Equal(t,
|
|
[]build.Instruction{
|
|
build.CopyAs{123, 223, build.Copy{[]string{"."}, "."}},
|
|
build.CopyAs{123, 223, build.CopyFrom{"build", build.Copy{[]string{"/foo/src"}, "/foo/dst"}}},
|
|
},
|
|
cfg.InstructionsForPhase(build.PhaseInstall),
|
|
)
|
|
})
|
|
})
|
|
|
|
t.Run("PhasePostInstall", func(t *testing.T) {
|
|
t.Run("with entrypoint", func(t *testing.T) {
|
|
cfg := config.VariantConfig{
|
|
CommonConfig: config.CommonConfig{
|
|
EntryPoint: []string{"/foo", "bar"},
|
|
},
|
|
}
|
|
|
|
assert.Equal(t,
|
|
[]build.Instruction{
|
|
build.EntryPoint{[]string{"/foo", "bar"}},
|
|
},
|
|
cfg.InstructionsForPhase(build.PhasePostInstall),
|
|
)
|
|
})
|
|
|
|
t.Run("without Runs.Insecurely", func(t *testing.T) {
|
|
cfg := config.VariantConfig{
|
|
CommonConfig: config.CommonConfig{
|
|
Lives: config.LivesConfig{
|
|
UserConfig: config.UserConfig{
|
|
As: "foouser",
|
|
},
|
|
},
|
|
Runs: config.RunsConfig{
|
|
Insecurely: config.Flag{True: false},
|
|
UserConfig: config.UserConfig{
|
|
As: "baruser",
|
|
},
|
|
},
|
|
EntryPoint: []string{"/foo", "bar"},
|
|
},
|
|
}
|
|
|
|
assert.Equal(t,
|
|
[]build.Instruction{
|
|
build.User{"baruser"},
|
|
build.Env{map[string]string{"HOME": "/home/baruser"}},
|
|
build.EntryPoint{[]string{"/foo", "bar"}},
|
|
},
|
|
cfg.InstructionsForPhase(build.PhasePostInstall),
|
|
)
|
|
})
|
|
|
|
t.Run("with Runs.Insecurely", func(t *testing.T) {
|
|
cfg := config.VariantConfig{
|
|
CommonConfig: config.CommonConfig{
|
|
Lives: config.LivesConfig{
|
|
UserConfig: config.UserConfig{
|
|
As: "foouser",
|
|
},
|
|
},
|
|
Runs: config.RunsConfig{
|
|
Insecurely: config.Flag{True: true},
|
|
UserConfig: config.UserConfig{
|
|
As: "baruser",
|
|
},
|
|
},
|
|
EntryPoint: []string{"/foo", "bar"},
|
|
},
|
|
}
|
|
|
|
assert.Equal(t,
|
|
[]build.Instruction{
|
|
build.EntryPoint{[]string{"/foo", "bar"}},
|
|
},
|
|
cfg.InstructionsForPhase(build.PhasePostInstall),
|
|
)
|
|
})
|
|
})
|
|
}
|
|
|
|
func TestVariantConfigValidation(t *testing.T) {
|
|
t.Run("includes", func(t *testing.T) {
|
|
t.Run("ok", func(t *testing.T) {
|
|
_, err := config.ReadYAMLConfig([]byte(`---
|
|
version: v4
|
|
variants:
|
|
build: {}
|
|
foo: { includes: [build] }`))
|
|
|
|
assert.False(t, config.IsValidationError(err))
|
|
})
|
|
|
|
t.Run("optional", func(t *testing.T) {
|
|
_, err := config.ReadYAMLConfig([]byte(`---
|
|
version: v4
|
|
variants:
|
|
build: {}
|
|
foo: {}`))
|
|
|
|
assert.False(t, config.IsValidationError(err))
|
|
})
|
|
|
|
t.Run("bad", func(t *testing.T) {
|
|
_, err := config.ReadYAMLConfig([]byte(`---
|
|
version: v4
|
|
variants:
|
|
build: {}
|
|
foo: { includes: [build, foobuild, foo_build] }`))
|
|
|
|
if assert.True(t, config.IsValidationError(err)) {
|
|
msg := config.HumanizeValidationError(err)
|
|
|
|
assert.Equal(t, strings.Join([]string{
|
|
`includes[1]: references an unknown variant "foobuild"`,
|
|
`includes[2]: references an unknown variant "foo_build"`,
|
|
}, "\n"), msg)
|
|
}
|
|
})
|
|
})
|
|
|
|
t.Run("copies", func(t *testing.T) {
|
|
|
|
t.Run("should not contain duplicates", func(t *testing.T) {
|
|
_, err := config.ReadYAMLConfig([]byte(`---
|
|
version: v4
|
|
variants:
|
|
build: {}
|
|
foo: { copies: [foo, bar, foo] }`))
|
|
|
|
if assert.True(t, config.IsValidationError(err)) {
|
|
msg := config.HumanizeValidationError(err)
|
|
|
|
assert.Equal(t, `copies: cannot contain duplicates`, msg)
|
|
}
|
|
})
|
|
})
|
|
}
|