grim/convey

closing merged branch
hostnames
2017-10-13, Gary Kramlich
33eae19fcbbe
closing merged branch
/*
* Convey
* Copyright 2016-2017 Gary Kramlich <grim@reaperworld.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package convey
import (
"github.com/aphistic/sweet"
. "github.com/onsi/gomega"
cConfig "bitbucket.org/rw_grim/convey/config"
"bitbucket.org/rw_grim/convey/intrinsic"
)
// This test suite tests
type extendSuite struct{}
func (d *extendSuite) TestSimple(t sweet.T) {
data := `
tasks:
a:
image: alpine:3.6
environment:
- X=1
- Y=2
b:
type: extend
task: a
environment:
- X=3
plans:
default:
stages:
- tasks: [a, b]
`
loader := &Loader{}
cfg, err := loader.Load(".", ".", []byte(data))
Expect(err).To(BeNil())
Expect(cfg.Tasks).To(HaveLen(2))
Expect(cfg.Tasks).To(HaveKey("a"))
Expect(cfg.Tasks).To(HaveKey("b"))
Expect(cfg.Tasks["b"].(*intrinsic.Extend).InnerTask).NotTo(BeIdenticalTo(cfg.Tasks["a"]))
Expect(cfg.Tasks["b"].(*intrinsic.Extend).InnerTask).To(BeEquivalentTo(cfg.Tasks["a"]))
}
func (d *extendSuite) TestExtendChain(t sweet.T) {
data := `
tasks:
a:
image: alpine:3.6
environment:
- X=1
- Y=2
b:
type: extend
task: a
environment:
- X=3
c:
type: extend
task: b
environment:
- X=4
plans:
default:
stages:
- tasks: [a, b, c]
`
loader := &Loader{}
cfg, err := loader.Load(".", ".", []byte(data))
Expect(err).To(BeNil())
Expect(cfg.Tasks).To(HaveLen(3))
Expect(cfg.Tasks).To(HaveKey("a"))
Expect(cfg.Tasks).To(HaveKey("b"))
Expect(cfg.Tasks).To(HaveKey("c"))
Expect(cfg.Tasks["c"].(*intrinsic.Extend).InnerTask).NotTo(BeIdenticalTo(cfg.Tasks["b"]))
Expect(cfg.Tasks["c"].(*intrinsic.Extend).InnerTask).To(BeEquivalentTo(cfg.Tasks["b"]))
Expect(cfg.Tasks["b"].(*intrinsic.Extend).InnerTask).NotTo(BeIdenticalTo(cfg.Tasks["a"]))
Expect(cfg.Tasks["b"].(*intrinsic.Extend).InnerTask).To(BeEquivalentTo(cfg.Tasks["a"]))
Expect(cfg.Tasks["c"].(*intrinsic.Extend).InnerTask.(*intrinsic.Extend).InnerTask).NotTo(BeIdenticalTo(cfg.Tasks["a"]))
Expect(cfg.Tasks["c"].(*intrinsic.Extend).InnerTask.(*intrinsic.Extend).InnerTask).To(BeEquivalentTo(cfg.Tasks["a"]))
}
func (d *extendSuite) TestCycle(t sweet.T) {
data := `
tasks:
a:
type: extend
task: b
b:
type: extend
task: a
plans:
default:
stages:
- tasks: [a, b]
`
loader := &Loader{}
_, err := loader.Load(".", ".", []byte(data))
Expect(err).To(MatchError("The following tasks are part of a dependency cycle: a, b"))
}
func (d *extendSuite) TestMissingTask(t sweet.T) {
data := `
tasks:
b:
type: extend
task: a
plans:
default:
stages:
- tasks: [a, b]
`
loader := &Loader{}
_, err := loader.Load(".", ".", []byte(data))
Expect(err).To(MatchError("b: Extending undeclared task 'a'"))
}
func (d *extendSuite) TestExtendExtends(t sweet.T) {
baseData := `
environment:
- x=1
tasks:
foo:
image: imaginary
environment:
- x=2
`
extendedData := `
extends: base.yaml
environment:
- x=3
tasks:
bar:
type: extend
task: foo
environment:
- x=3
plans:
plan:
stages:
- tasks: [foo, bar]
`
loader := &Loader{
fileLoader: func(name string, c *Loader) (*cConfig.Config, error) {
return c.Load(".", name, []byte(baseData))
},
}
cfg, err := loader.Load(".", ".", []byte(extendedData))
Expect(err).To(BeNil())
Expect(cfg.Tasks).To(HaveLen(2))
Expect(cfg.Tasks).To(HaveKey("foo"))
Expect(cfg.Tasks).To(HaveKey("bar"))
Expect(cfg.Tasks).To(HaveKey("foo"))
Expect(cfg.Tasks).To(HaveKey("bar"))
Expect(cfg.Tasks["bar"].(*intrinsic.Extend).InnerTask).NotTo(BeIdenticalTo(cfg.Tasks["foo"]))
Expect(cfg.Tasks["bar"].(*intrinsic.Extend).InnerTask).To(BeEquivalentTo(cfg.Tasks["foo"]))
}
func (s *conveySuite) TestReplaceStage(t sweet.T) {
data1 := `
tasks:
pre:
image: pre
post:
image: post
foo:
image: foo
plans:
plan1:
stages:
- name: pre
tasks:
- pre
- name: real-work
tasks:
- foo
- name: post
tasks:
- post
plan2:
stages:
- tasks:
- pre
- foo
- post
`
data2 := `
extends: base1.yaml
tasks:
bar:
image: bar
plans:
plan1:
merge: true
stages:
- name: real-work
tasks:
- bar
plan2:
stages:
- name: real-work
tasks:
- bar
`
data3 := `
extends: base2.yaml
tasks:
baz:
image: baz
plans:
plan1:
merge: true
stages:
- name: post
tasks:
- baz
`
loader := &Loader{
fileLoader: func(name string, c *Loader) (*cConfig.Config, error) {
m := map[string]string{
"base1.yaml": data1,
"base2.yaml": data2,
}
return c.Load(".", name, []byte(m[name]))
},
}
cfg, err := loader.Load(".", ".", []byte(data3))
Expect(err).To(BeNil())
Expect(cfg.Plans).To(HaveLen(2))
Expect(cfg.Plans).To(HaveKey("plan1"))
Expect(cfg.Plans).To(HaveKey("plan2"))
Expect(cfg.Plans["plan1"].Stages).To(HaveLen(3))
Expect(cfg.Plans["plan1"].Stages[0].Name).To(Equal("pre"))
Expect(cfg.Plans["plan1"].Stages[1].Name).To(Equal("real-work"))
Expect(cfg.Plans["plan1"].Stages[2].Name).To(Equal("post"))
Expect(cfg.Plans["plan1"].Stages[0].Tasks).To(HaveLen(1))
Expect(cfg.Plans["plan1"].Stages[1].Tasks).To(HaveLen(1))
Expect(cfg.Plans["plan1"].Stages[2].Tasks).To(HaveLen(1))
Expect(cfg.Plans["plan1"].Stages[0].Tasks).To(ConsistOf("pre"))
Expect(cfg.Plans["plan1"].Stages[1].Tasks).To(ConsistOf("bar"))
Expect(cfg.Plans["plan1"].Stages[2].Tasks).To(ConsistOf("baz"))
Expect(cfg.Plans["plan2"].Stages).To(HaveLen(1))
Expect(cfg.Plans["plan2"].Stages[0].Tasks).To(HaveLen(1))
Expect(cfg.Plans["plan2"].Stages[0].Tasks).To(ConsistOf("bar"))
}
func (s *conveySuite) TestMergeMissingPlan(t sweet.T) {
data1 := `
tasks:
foo:
image: foo
plans:
plan1:
stages:
- tasks: [foo]
`
data2 := `
extends: base1.yaml
tasks:
bar:
image: bar
plans:
plan2:
merge: true
stages:
- tasks: [foo, bar]
`
loader := &Loader{
fileLoader: func(name string, c *Loader) (*cConfig.Config, error) {
return c.Load(".", name, []byte(data1))
},
}
_, err := loader.Load(".", ".", []byte(data2))
Expect(err).To(MatchError("cannot merge with unknown plan 'plan2'"))
}
func (s *conveySuite) TestMergeMissingStage(t sweet.T) {
data1 := `
tasks:
foo:
image: foo
plans:
plan1:
stages:
- name: only
tasks:
- foo
`
data2 := `
extends: base1.yaml
tasks:
bar:
image: bar
plans:
plan1:
merge: true
stages:
- name: missing
tasks:
- bar
`
loader := &Loader{
fileLoader: func(name string, c *Loader) (*cConfig.Config, error) {
return c.Load(".", name, []byte(data1))
},
}
_, err := loader.Load(".", ".", []byte(data2))
Expect(err).To(MatchError("cannot overwrite stage 'missing' in plan 'plan1' (no such stage in parent)"))
}
func (s *conveySuite) TestMergePlanEnvironment(t sweet.T) {
data1 := `
tasks:
foo:
image: foo
plans:
plan1:
stages:
- name: only
tasks:
- foo
environment:
- FOO=BAR
- BAR=BAZ
`
data2 := `
extends: base1.yaml
plans:
plan1:
merge: true
environment:
- BAR=BONK
`
loader := &Loader{
fileLoader: func(name string, c *Loader) (*cConfig.Config, error) {
return c.Load(".", name, []byte(data1))
},
}
cfg, err := loader.Load(".", ".", []byte(data2))
Expect(err).To(BeNil())
Expect(cfg.Plans["plan1"].Stages[0].Tasks).To(ConsistOf("foo"))
Expect(cfg.Plans["plan1"].Environment).To(ConsistOf("FOO=BAR", "BAR=BONK"))
}