diff --git a/cmd/build-pass-fail/main_test.go b/cmd/build-pass-fail/main_test.go index 6d462d4..060714d 100644 --- a/cmd/build-pass-fail/main_test.go +++ b/cmd/build-pass-fail/main_test.go @@ -41,7 +41,6 @@ func TestBuildPassFail(t *testing.T) { gt.Expect(err).NotTo(gomega.MatchError("unsuccessful: file exists")) } - err = os.Mkdir("invalid", os.ModeDir|os.ModePerm) if err != nil { gt.Expect(err).NotTo(gomega.MatchError("invalid: file exists")) diff --git a/cmd/show-logs/main.go b/cmd/show-logs/main.go index f40ea4a..fc2f51f 100644 --- a/cmd/show-logs/main.go +++ b/cmd/show-logs/main.go @@ -5,17 +5,33 @@ import ( "path/filepath" "fmt" "io/ioutil" + "os" + "strings" ) func main() { - path := filepath.Join("build", "events.log") + var jsonpath, cleanpath string + if len(os.Args) > 1 { + jsonpath = os.Args[1] - contents, err := ioutil.ReadFile(path) + cleanpath = filepath.Clean(jsonpath) + if strings.HasPrefix(cleanpath, "/") || + strings.Contains(cleanpath, "..") || + strings.Count(cleanpath, "/") > 1 { + log.Fatalf("malformed path") + } + + cleanpath = filepath.Join(cleanpath, "events.log") + } else { + cleanpath = filepath.Join("build", "events.log") + } + + contents, err := ioutil.ReadFile(cleanpath) if err != nil { - log.Fatalf("could not open %s: %s", path, err.Error()) + log.Fatalf("could not open %s: %s", cleanpath, err.Error()) } - fmt.Println("*********************************** [ begin log ] ***********************************") - fmt.Print(string(contents)) - fmt.Println("************************************ [ end log ] ************************************") + fmt.Println("----------------------------------- [ begin log ] -----------------------------------") + fmt.Println(string(contents)) + fmt.Println("------------------------------------ [ end log ] ------------------------------------") } diff --git a/cmd/show-logs/main_test.go b/cmd/show-logs/main_test.go new file mode 100644 index 0000000..f7cb208 --- /dev/null +++ b/cmd/show-logs/main_test.go @@ -0,0 +1,163 @@ +package main_test + +import ( + "testing" + "github.com/onsi/gomega" + "github.com/onsi/gomega/gexec" + "os" + "github.com/sclevine/spec" + "github.com/sclevine/spec/report" + "path/filepath" + "os/exec" + "github.com/onsi/gomega/gbytes" +) + +func TestShowLogs(t *testing.T) { + gt := gomega.NewGomegaWithT(t) + + compiledPath, err := gexec.Build("github.com/jchesterpivotal/concourse-build-resource/cmd/show-logs") + if err != nil { + gt.Expect(err).NotTo(gomega.HaveOccurred()) + } + + err = os.Mkdir("build", os.ModeDir|os.ModePerm) + if err != nil { + gt.Expect(err).NotTo(gomega.MatchError("build: file exists")) + } + + err = os.Mkdir("successful", os.ModeDir|os.ModePerm) + if err != nil { + gt.Expect(err).NotTo(gomega.MatchError("successful: file exists")) + } + + err = os.Mkdir("empty", os.ModeDir|os.ModePerm) + if err != nil { + gt.Expect(err).NotTo(gomega.MatchError("empty: file exists")) + } + + err = os.Mkdir("wrappers", os.ModeDir|os.ModePerm) + if err != nil { + gt.Expect(err).NotTo(gomega.MatchError("wrappers: file exists")) + } + + spec.Run(t, "show-logs", func(t *testing.T, when spec.G, it spec.S) { + when("a resource name is given", func() { + gt = gomega.NewGomegaWithT(t) + + when("the directory exists and contains an events.log", func() { + var session *gexec.Session + + it.Before(func() { + logfile, err := os.Create(filepath.Join("successful", "events.log")) + gt.Expect(err).NotTo(gomega.HaveOccurred()) + + _, err = logfile.WriteString("successful/events.log log line 1\nlog line the 2nd\n") + gt.Expect(err).NotTo(gomega.HaveOccurred()) + + cmd := exec.Command(compiledPath, "successful") + session, err = gexec.Start(cmd, it.Out(), it.Out()) + gt.Expect(err).NotTo(gomega.HaveOccurred()) + }) + + it("prints the logs to stdout", func() { + gt.Eventually(session.Out).Should(gbytes.Say(`successful/events.log log line 1 +log line the 2nd +`)) + }) + }, spec.Nested()) + + when("the directory exists but does not contain an events.log", func() { + var session *gexec.Session + + it.Before(func() { + cmd := exec.Command(compiledPath, "empty") + session, err = gexec.Start(cmd, it.Out(), it.Out()) + gt.Expect(err).NotTo(gomega.HaveOccurred()) + }) + + it("prints a failure message", func() { + gt.Eventually(session.Err).Should(gbytes.Say("could not open empty/events.log")) + }) + + it("exits 1", func() { + gt.Eventually(session).Should(gexec.Exit(1)) + }) + }, spec.Nested()) + }, spec.Nested()) + + when("a resource name is not given", func() { + gt = gomega.NewGomegaWithT(t) + + when("there is no build/events.log", func() { + var session *gexec.Session + + it.Before(func() { + cmd := exec.Command(compiledPath) + session, err = gexec.Start(cmd, it.Out(), it.Out()) + gt.Expect(err).NotTo(gomega.HaveOccurred()) + }) + + it("prints a failure message", func() { + gt.Eventually(session.Err).Should(gbytes.Say("could not open build/events.log")) + }) + + it("exits 1", func() { + gt.Eventually(session).Should(gexec.Exit(1)) + }) + }, spec.Nested()) + + when("there is a build/events.log", func() { + var session *gexec.Session + + it.Before(func() { + logfile, err := os.Create(filepath.Join("build", "events.log")) + gt.Expect(err).NotTo(gomega.HaveOccurred()) + + _, err = logfile.WriteString("build/events.log log line 1\nlog line the 2nd\n") + gt.Expect(err).NotTo(gomega.HaveOccurred()) + + cmd := exec.Command(compiledPath) + session, err = gexec.Start(cmd, it.Out(), it.Out()) + gt.Expect(err).NotTo(gomega.HaveOccurred()) + }) + + it("prints the logs to stdout", func() { + gt.Eventually(session.Out).Should(gbytes.Say(`build/events.log log line 1 +log line the 2nd +`)) + }) + }, spec.Nested(), spec.Sequential()) + + + }, spec.Nested()) + + when("printing any events.log file", func() { + gt = gomega.NewGomegaWithT(t) + var session *gexec.Session + + it.Before(func() { + logfile, err := os.Create(filepath.Join("wrappers", "events.log")) + gt.Expect(err).NotTo(gomega.HaveOccurred()) + + _, err = logfile.WriteString("wrappers/events.log log line 1") + gt.Expect(err).NotTo(gomega.HaveOccurred()) + + cmd := exec.Command(compiledPath, "wrappers") + session, err = gexec.Start(cmd, it.Out(), it.Out()) + gt.Expect(err).NotTo(gomega.HaveOccurred()) + }) + + it("wraps the printed logs with 'begin' and 'end' lines for clarity", func() { + gt.Eventually(session.Out).Should(gbytes.Say(`----------------------------------- \[ begin log \] -----------------------------------`)) + gt.Eventually(session.Out).Should(gbytes.Say(`wrappers/events\.log log line 1`)) + gt.Eventually(session.Out).Should(gbytes.Say(`------------------------------------ \[ end log \] ------------------------------------`)) + }) + }, spec.Nested()) + }, spec.Report(report.Terminal{})) + + gexec.CleanupBuildArtifacts() + gt.Expect(os.RemoveAll("build")).To(gomega.Succeed()) + gt.Expect(os.RemoveAll("successful")).To(gomega.Succeed()) + gt.Expect(os.RemoveAll("empty")).To(gomega.Succeed()) + gt.Expect(os.RemoveAll("wrappers")).To(gomega.Succeed()) +}