func Test_shell(t *testing.T) { g := goblin.Goblin(t) g.Describe("shell containers", func() { g.It("should ignore plugin steps", func() { root := parse.NewRootNode() c := root.NewPluginNode() c.Container = runner.Container{} ops := NewShellOp(Linux_adm64) ops.VisitContainer(c) g.Assert(len(c.Container.Entrypoint)).Equal(0) g.Assert(len(c.Container.Command)).Equal(0) g.Assert(c.Container.Environment["DRONE_SCRIPT"]).Equal("") }) g.It("should set entrypoint, command and environment variables", func() { root := parse.NewRootNode() root.Base = "/go" root.Path = "/go/src/github.com/octocat/hello-world" c := root.NewShellNode() c.Commands = []string{"go build"} ops := NewShellOp(Linux_adm64) ops.VisitContainer(c) g.Assert(c.Container.Entrypoint).Equal([]string{"/bin/sh", "-c"}) g.Assert(c.Container.Command).Equal([]string{"echo $DRONE_SCRIPT | base64 -d | /bin/sh -e"}) g.Assert(c.Container.Environment["DRONE_SCRIPT"] != "").IsTrue() }) }) }
func Test_args(t *testing.T) { g := goblin.Goblin(t) g.Describe("plugins arguments", func() { g.It("should ignore non-plugin containers", func() { root := parse.NewRootNode() c := root.NewShellNode() c.Container = runner.Container{} c.Vargs = map[string]interface{}{ "depth": 50, } ops := NewArgsOp() ops.VisitContainer(c) g.Assert(c.Container.Environment["PLUGIN_DEPTH"]).Equal("") }) g.It("should include args as environment variable", func() { root := parse.NewRootNode() c := root.NewPluginNode() c.Container = runner.Container{} c.Vargs = map[string]interface{}{ "depth": 50, } ops := NewArgsOp() ops.VisitContainer(c) g.Assert(c.Container.Environment["PLUGIN_DEPTH"]).Equal("50") }) }) }
func Test_env(t *testing.T) { root := parse.NewRootNode() g := goblin.Goblin(t) g.Describe("environment variables", func() { g.It("should be copied", func() { envs := map[string]string{"CI": "drone"} c := root.NewContainerNode() c.Container = runner.Container{} op := NewEnvOp(envs) op.VisitContainer(c) g.Assert(c.Container.Environment["CI"]).Equal("drone") }) g.It("should include http proxy variables", func() { httpProxy = "foo" httpsProxy = "bar" noProxy = "baz" c := root.NewContainerNode() c.Container = runner.Container{} op := NewEnvOp(map[string]string{}) op.VisitContainer(c) g.Assert(c.Container.Environment["HTTP_PROXY"]).Equal("foo") g.Assert(c.Container.Environment["HTTPS_PROXY"]).Equal("bar") g.Assert(c.Container.Environment["NO_PROXY"]).Equal("baz") }) }) }
func Test_pull(t *testing.T) { root := parse.NewRootNode() g := goblin.Goblin(t) g.Describe("pull image", func() { g.It("should be enabled for plugins", func() { c := root.NewPluginNode() c.Container = runner.Container{} op := NewPullOp(true) op.VisitContainer(c) g.Assert(c.Container.Pull).IsTrue() }) g.It("should be disabled for plugins", func() { c := root.NewPluginNode() c.Container = runner.Container{} op := NewPullOp(false) op.VisitContainer(c) g.Assert(c.Container.Pull).IsFalse() }) g.It("should be disabled for non-plugins", func() { c := root.NewShellNode() c.Container = runner.Container{} op := NewPullOp(true) op.VisitContainer(c) g.Assert(c.Container.Pull).IsFalse() }) }) }
func Test_escalate(t *testing.T) { root := parse.NewRootNode() g := goblin.Goblin(t) g.Describe("privileged transform", func() { g.It("should handle matches", func() { c := root.NewPluginNode() c.Container = runner.Container{Image: "plugins/docker"} op := NewEscalateOp([]string{"plugins/docker"}) op.VisitContainer(c) g.Assert(c.Container.Privileged).IsTrue() }) g.It("should handle glob matches", func() { c := root.NewPluginNode() c.Container = runner.Container{Image: "plugins/docker"} op := NewEscalateOp([]string{"plugins/*"}) op.VisitContainer(c) g.Assert(c.Container.Privileged).IsTrue() }) g.It("should handle non matches", func() { c := root.NewPluginNode() c.Container = runner.Container{Image: "plugins/git"} op := NewEscalateOp([]string{"plugins/docker"}) op.VisitContainer(c) g.Assert(c.Container.Privileged).IsFalse() }) g.It("should handle non glob matches", func() { c := root.NewPluginNode() c.Container = runner.Container{Image: "plugins/docker:develop"} op := NewEscalateOp([]string{"plugins/docker"}) op.VisitContainer(c) g.Assert(c.Container.Privileged).IsFalse() }) }) }
func Test_validate(t *testing.T) { root := parse.NewRootNode() g := goblin.Goblin(t) g.Describe("validating", func() { g.Describe("privileged attributes", func() { g.It("should not error when trusted build", func() { c := root.NewContainerNode() c.Container = runner.Container{} ops := NewValidateOp(true, []string{"plugins/*"}) err := ops.VisitContainer(c) g.Assert(err == nil).IsTrue("error should be nil") }) g.It("should error when privleged mode", func() { c := root.NewContainerNode() c.Container = runner.Container{} c.Container.Privileged = true ops := NewValidateOp(false, []string{"plugins/*"}) err := ops.VisitContainer(c) g.Assert(err != nil).IsTrue("error should not be nil") g.Assert(err.Error()).Equal("Insufficient privileges to use privileged mode") }) g.It("should error when dns configured", func() { c := root.NewContainerNode() c.Container = runner.Container{} c.Container.DNS = []string{"8.8.8.8"} ops := NewValidateOp(false, []string{"plugins/*"}) err := ops.VisitContainer(c) g.Assert(err != nil).IsTrue("error should not be nil") g.Assert(err.Error()).Equal("Insufficient privileges to use custom dns") }) g.It("should error when dns_search configured", func() { c := root.NewContainerNode() c.Container = runner.Container{} c.Container.DNSSearch = []string{"8.8.8.8"} ops := NewValidateOp(false, []string{"plugins/*"}) err := ops.VisitContainer(c) g.Assert(err != nil).IsTrue("error should not be nil") g.Assert(err.Error()).Equal("Insufficient privileges to use dns_search") }) g.It("should error when devices configured", func() { c := root.NewContainerNode() c.Container = runner.Container{} c.Container.Devices = []string{"/dev/foo"} ops := NewValidateOp(false, []string{"plugins/*"}) err := ops.VisitContainer(c) g.Assert(err != nil).IsTrue("error should not be nil") g.Assert(err.Error()).Equal("Insufficient privileges to use devices") }) g.It("should error when extra_hosts configured", func() { c := root.NewContainerNode() c.Container = runner.Container{} c.Container.ExtraHosts = []string{"1.2.3.4 foo.com"} ops := NewValidateOp(false, []string{"plugins/*"}) err := ops.VisitContainer(c) g.Assert(err != nil).IsTrue("error should not be nil") g.Assert(err.Error()).Equal("Insufficient privileges to use extra_hosts") }) g.It("should error when network configured", func() { c := root.NewContainerNode() c.Container = runner.Container{} c.Container.Network = "host" ops := NewValidateOp(false, []string{"plugins/*"}) err := ops.VisitContainer(c) g.Assert(err != nil).IsTrue("error should not be nil") g.Assert(err.Error()).Equal("Insufficient privileges to override the network") }) g.It("should error when oom_kill_disabled configured", func() { c := root.NewContainerNode() c.Container = runner.Container{} c.Container.OomKillDisable = true ops := NewValidateOp(false, []string{"plugins/*"}) err := ops.VisitContainer(c) g.Assert(err != nil).IsTrue("error should not be nil") g.Assert(err.Error()).Equal("Insufficient privileges to disable oom_kill") }) g.It("should error when volumes configured", func() { c := root.NewContainerNode() c.Container = runner.Container{} c.Container.Volumes = []string{"/:/tmp"} ops := NewValidateOp(false, []string{"plugins/*"}) err := ops.VisitContainer(c) g.Assert(err != nil).IsTrue("error should not be nil") g.Assert(err.Error()).Equal("Insufficient privileges to use volumes") }) g.It("should error when volumes_from configured", func() { c := root.NewContainerNode() c.Container = runner.Container{} c.Container.VolumesFrom = []string{"drone"} ops := NewValidateOp(false, []string{"plugins/*"}) err := ops.VisitContainer(c) g.Assert(err != nil).IsTrue("error should not be nil") g.Assert(err.Error()).Equal("Insufficient privileges to use volumes_from") }) }) g.Describe("plugin configuration", func() { g.It("should error when entrypoint is configured", func() { c := root.NewPluginNode() c.Container = runner.Container{Image: "plugins/git"} c.Container.Entrypoint = []string{"/bin/sh"} ops := NewValidateOp(false, []string{"plugins/*"}) err := ops.VisitContainer(c) g.Assert(err != nil).IsTrue("error should not be nil") g.Assert(err.Error()).Equal("Cannot set plugin Entrypoint") }) g.It("should error when command is configured", func() { c := root.NewPluginNode() c.Container = runner.Container{Image: "plugins/git"} c.Container.Command = []string{"cat", "/proc/1/status"} ops := NewValidateOp(false, []string{"plugins/*"}) err := ops.VisitContainer(c) g.Assert(err != nil).IsTrue("error should not be nil") g.Assert(err.Error()).Equal("Cannot set plugin Command") }) g.It("should not error when empty entrypoint, command", func() { c := root.NewPluginNode() c.Container = runner.Container{Image: "plugins/git"} ops := NewValidateOp(false, []string{"plugins/*"}) err := ops.VisitContainer(c) g.Assert(err == nil).IsTrue("error should be nil") }) }) g.Describe("plugin whitelist", func() { g.It("should error when no match found", func() { c := root.NewPluginNode() c.Container = runner.Container{} c.Container.Image = "custom/git" ops := NewValidateOp(false, []string{"plugins/*"}) err := ops.VisitContainer(c) g.Assert(err != nil).IsTrue("error should be nil") g.Assert(err.Error()).Equal("Plugin custom/git is not in the whitelist") }) g.It("should not error when match found", func() { c := root.NewPluginNode() c.Container = runner.Container{} c.Container.Image = "plugins/git" ops := NewValidateOp(false, []string{"plugins/*"}) err := ops.VisitContainer(c) g.Assert(err == nil).IsTrue("error should be nil") }) g.It("should ignore build images", func() { c := root.NewShellNode() c.Container = runner.Container{} c.Container.Image = "google/golang" ops := NewValidateOp(false, []string{"plugins/*"}) err := ops.VisitContainer(c) g.Assert(err == nil).IsTrue("error should be nil") }) }) }) }
func Test_workspace(t *testing.T) { g := goblin.Goblin(t) g.Describe("workspace", func() { var defaultBase = "/go" var defaultPath = "src/github.com/octocat/hello-world" g.It("should not override user paths", func() { var base = "/drone" var path = "/drone/src/github.com/octocat/hello-world" op := NewWorkspaceOp(defaultBase, defaultPath) root := parse.NewRootNode() root.Base = base root.Path = path op.VisitRoot(root) g.Assert(root.Base).Equal(base) g.Assert(root.Path).Equal(path) }) g.It("should convert user paths to absolute", func() { var base = "/drone" var path = "src/github.com/octocat/hello-world" var abs = "/drone/src/github.com/octocat/hello-world" op := NewWorkspaceOp(defaultBase, defaultPath) root := parse.NewRootNode() root.Base = base root.Path = path op.VisitRoot(root) g.Assert(root.Base).Equal(base) g.Assert(root.Path).Equal(abs) }) g.It("should set the default path", func() { var base = "/go" var path = "/go/src/github.com/octocat/hello-world" op := NewWorkspaceOp(defaultBase, defaultPath) root := parse.NewRootNode() op.VisitRoot(root) g.Assert(root.Base).Equal(base) g.Assert(root.Path).Equal(path) }) g.It("should use workspace as working_dir", func() { var base = "/drone" var path = "/drone/src/github.com/octocat/hello-world" root := parse.NewRootNode() root.Base = base root.Path = path c := root.NewContainerNode() op := NewWorkspaceOp(defaultBase, defaultPath) op.VisitContainer(c) g.Assert(c.Container.WorkingDir).Equal(root.Path) }) g.It("should not use workspace as working_dir for services", func() { var base = "/drone" var path = "/drone/src/github.com/octocat/hello-world" root := parse.NewRootNode() root.Base = base root.Path = path c := root.NewServiceNode() op := NewWorkspaceOp(defaultBase, defaultPath) op.VisitContainer(c) g.Assert(c.Container.WorkingDir).Equal("") }) }) }
func Test_normalize(t *testing.T) { root := parse.NewRootNode() g := goblin.Goblin(t) g.Describe("normalizing", func() { g.Describe("images", func() { g.It("should append tag if empty", func() { c := root.NewContainerNode() c.Container = runner.Container{Image: "golang"} op := NewNormalizeOp("") op.VisitContainer(c) g.Assert(c.Container.Image).Equal("golang:latest") }) g.It("should not override existing tag", func() { c := root.NewContainerNode() c.Container = runner.Container{Image: "golang:1.5"} op := NewNormalizeOp("") op.VisitContainer(c) g.Assert(c.Container.Image).Equal("golang:1.5") }) }) g.Describe("plugins", func() { g.It("should prepend namespace", func() { c := root.NewPluginNode() c.Container = runner.Container{Image: "git"} op := NewNormalizeOp("plugins") op.VisitContainer(c) g.Assert(c.Container.Image).Equal("plugins/git:latest") }) g.It("should not override existing namespace", func() { c := root.NewPluginNode() c.Container = runner.Container{Image: "index.docker.io/drone/git"} op := NewNormalizeOp("plugins") op.VisitContainer(c) g.Assert(c.Container.Image).Equal("index.docker.io/drone/git:latest") }) g.It("should replace underscores with dashes", func() { c := root.NewPluginNode() c.Container = runner.Container{Image: "gh_pages"} op := NewNormalizeOp("plugins") op.VisitContainer(c) g.Assert(c.Container.Image).Equal("plugins/gh-pages:latest") }) g.It("should ignore shell or service types", func() { c := root.NewShellNode() c.Container = runner.Container{Image: "golang"} op := NewNormalizeOp("plugins") op.VisitContainer(c) g.Assert(c.Container.Image).Equal("golang:latest") }) }) }) }