Skip to content

Commit

Permalink
Initial changes for e2e testing framework (#553)
Browse files Browse the repository at this point in the history
* e2e init tests

* build pipeline changes and more tests
  • Loading branch information
patilpankaj212 committed Feb 19, 2021
1 parent 6b79a9c commit bbe97ce
Show file tree
Hide file tree
Showing 18 changed files with 379 additions and 2 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/gobuild.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ jobs:
- name: Run unit tests
run: make unit-tests

- name: Run e2e tests
run: make e2e-tests

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v1

Expand Down
6 changes: 5 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ help:
@echo "staticcheck\n\trun static code analysis"
@echo "test\n\texecute unit and integration tests"
@echo "unit-tests\n\texecute unit tests"
@echo "e2e-tests\n\texecute e2e tests"
@echo "validate\n\trun all validations"

# build terrascan binary
Expand All @@ -46,7 +47,7 @@ cicd: validate build test docker-build


# run all unit and integration tests
test: unit-tests
test: unit-tests e2e-tests


# run all validation tests
Expand Down Expand Up @@ -82,6 +83,9 @@ staticcheck:
unit-tests:
./scripts/generate-coverage.sh

# run e2e tests
e2e-tests: build
./scripts/run-e2e.sh

# build terrascan docker image
docker-build:
Expand Down
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ require (
github.com/hashicorp/terraform v0.14.4
github.com/iancoleman/strcase v0.1.3
github.com/mattn/go-isatty v0.0.12
github.com/onsi/ginkgo v1.12.1
github.com/onsi/gomega v1.10.5
github.com/open-policy-agent/opa v0.22.0
github.com/pelletier/go-toml v1.8.1
github.com/pkg/errors v0.9.1
Expand Down
11 changes: 11 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -761,6 +761,8 @@ github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OS
github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU=
github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM=
github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d/go.mod h1:YUTz3bUH2ZwIWBy3CJBeOBEugqcmXREj14T+iG/4k4U=
github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
Expand All @@ -773,10 +775,15 @@ github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.11.0 h1:JAKSXpt1YjtLA7YpPiqO9ss6sNXEsPfSGdwN0UHqzrw=
github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.1 h1:mFwc4LvZ0xpSvDZ3E+k8Yte0hLOMxXUlP+yXtJqkYfQ=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME=
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.5 h1:7n6FEkpFmfCoo2t+YYqXH0evK+a9ICQz0xcAy9dYcaQ=
github.com/onsi/gomega v1.10.5/go.mod h1:gza4q3jKQJijlu05nKWRCW/GavJumGt8aNRxWg7mt48=
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
github.com/open-policy-agent/opa v0.22.0 h1:KZvn0uMQIorBIwYk8Vc89dp8No9FIEF8eFl0sc1r/1U=
github.com/open-policy-agent/opa v0.22.0/go.mod h1:rrwxoT/b011T0cyj+gg2VvxqTtn6N3gp/jzmr3fjW44=
Expand Down Expand Up @@ -1152,6 +1159,8 @@ golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81R
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201021035429-f5854403a974 h1:IX6qOQeG5uLjB/hjjwjedwfjND0hgjPMMyO1RoIXQNI=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb h1:eBmm0M9fYhWpKZLjQUUKka/LtIxf46G4fxeEz5KJr9U=
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
Expand Down Expand Up @@ -1197,12 +1206,14 @@ golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191002063906-3421d5a6bb1c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191128015809-6d18c012aee9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
Expand Down
2 changes: 1 addition & 1 deletion scripts/generate-coverage.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ set -o errexit
set -o nounset
set -o pipefail

go test -v -coverpkg=./... -coverprofile=coverage.out ./...
go test -v -coverpkg=./pkg/... -coverprofile=coverage.out ./pkg/...
go tool cover -func coverage.out
9 changes: 9 additions & 0 deletions scripts/run-e2e.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/bin/bash

set -o errexit
set -o nounset
set -o pipefail

export TERRASCAN_BIN_PATH=${PWD}/bin/terrascan

go test -v ./test/...
2 changes: 2 additions & 0 deletions test/e2e/init/config/invalid_branch.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[policy]
branch = "invalid-branch"
2 changes: 2 additions & 0 deletions test/e2e/init/config/invalid_path.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[policy]
path = "invalid/path"
2 changes: 2 additions & 0 deletions test/e2e/init/config/invalid_rego_subdir.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[policy]
rego_subdir = "invalid/path"
2 changes: 2 additions & 0 deletions test/e2e/init/config/invalid_repo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[policy]
repo_url = "https://repository/url"
3 changes: 3 additions & 0 deletions test/e2e/init/config/valid_config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[policy]
repo_url = "https://github.com/accurics/KaiMonkey.git"
branch = "master"
15 changes: 15 additions & 0 deletions test/e2e/init/golden/init_help.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
Terrascan

Initializes Terrascan and clones policies from the Terrascan GitHub repository.

Usage:
terrascan init [flags]

Flags:
-h, --help help for init

Global Flags:
-c, --config-path string config file path
-l, --log-level string log level (debug, info, warn, error, panic, fatal) (default "info")
-x, --log-type string log output type (console, json) (default "console")
-o, --output string output type (human, json, yaml, xml, junit-xml) (default "human")
6 changes: 6 additions & 0 deletions test/e2e/init/golden/init_typo_help.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Error: unknown command "inti" for "terrascan"

Did you mean this?
init

Run 'terrascan --help' for usage.
13 changes: 13 additions & 0 deletions test/e2e/init/init_suite_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package init_test

import (
"testing"

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)

func TestInit(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Init Suite")
}
202 changes: 202 additions & 0 deletions test/e2e/init/init_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
package init_test

import (
"io"
"os"
"path/filepath"
"time"

initUtil "github.com/accurics/terrascan/test/e2e/init"
"github.com/accurics/terrascan/test/helper"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/onsi/gomega/gbytes"
"github.com/onsi/gomega/gexec"
"gopkg.in/src-d/go-git.v4"
)

var (
initCommand string = "init"
defaultPolicyRepoPath string = os.Getenv("HOME") + "/.terrascan"
terrascanGitURL string = "https://github.com/accurics/terrascan.git"
terrascanDefaultBranch string = "master"
terrascanConfigEnvName string = "TERRASCAN_CONFIG"
kaiMoneyGitURL string = "https://github.com/accurics/KaiMonkey.git"
)

var _ = Describe("Init", func() {
var session *gexec.Session
var terrascanBinaryPath string

var outWriter, errWriter io.Writer

BeforeSuite(func() {
os.RemoveAll(defaultPolicyRepoPath)
terrascanBinaryPath = helper.GetTerrascanBinaryPath()
})

BeforeEach(func() {
outWriter = gbytes.NewBuffer()
errWriter = gbytes.NewBuffer()
})

AfterEach(func() {
outWriter = nil
errWriter = nil
})

Describe("terrascan init is run", func() {
When("without any flags", func() {
It("should download policies and exit with status code 0", func() {
session = initUtil.RunInitCommand(terrascanBinaryPath, outWriter, errWriter, 0)
Expect(outWriter).Should(gbytes.Say(""))
})

It("should download policies at TERRASCAN's base location", func() {
BeADirectory().Match(defaultPolicyRepoPath)
})

Context("git repo should be validated", func() {
var repo *git.Repository
var err error
It("should be a valid git repo", func() {
repo = initUtil.OpenGitRepo(defaultPolicyRepoPath)
})
It("should be terrascan git repo", func() {
initUtil.ValidateGitRepo(repo, terrascanGitURL)
})
It("master branch should be present", func() {
_, err = repo.Branch(terrascanDefaultBranch)
Expect(err).NotTo(HaveOccurred())
})
})
})

When("terrascan init is run with -h flag", func() {
It("should print help", func() {
session = helper.RunCommand(terrascanBinaryPath, outWriter, errWriter, initCommand, "-h")
goldenFileAbsPath, err := filepath.Abs("golden/init_help.txt")
Expect(err).NotTo(HaveOccurred())
helper.CompareActualWithGolden(session, goldenFileAbsPath, true)
})

It("should exit with status code 0", func() {
session = helper.RunCommand(terrascanBinaryPath, outWriter, errWriter, initCommand, "-h")
Eventually(session).Should(gexec.Exit(0))
})
})

When("terrascan init command has typo. eg: inti", func() {
It("should print command suggestion", func() {
session = helper.RunCommand(terrascanBinaryPath, outWriter, errWriter, "inti")
goldenFileAbsPath, err := filepath.Abs("golden/init_typo_help.txt")
Expect(err).NotTo(HaveOccurred())
helper.CompareActualWithGolden(session, goldenFileAbsPath, false)
})

It("should exit with status code 1", func() {
session = helper.RunCommand(terrascanBinaryPath, outWriter, errWriter, "inti")
Eventually(session, 5).Should(gexec.Exit(1))
})
})

When("terrascan init is run with -c flag", func() {
Context("config file has valid policy config data", func() {
It("should download policies as per the policy config in the config file", func() {
Skip("skipping this test due to https://github.com/accurics/terrascan/issues/550, should be implemented when fixed")
})
})
})
})

Describe("terrascan init is run when TERRASCAN_CONFIG is set", func() {
When("the config file has invalid repo url", func() {
JustBeforeEach(func() {
os.Setenv(terrascanConfigEnvName, "config/invalid_repo.toml")
})
JustAfterEach(func() {
os.Setenv(terrascanConfigEnvName, "")
})
It("should error out and exit with status code 1", func() {
session = initUtil.RunInitCommand(terrascanBinaryPath, outWriter, errWriter, 1)
helper.ContainsErrorSubString(session, `failed to download policies. error: 'Get "https://repository/url/info/refs?service=git-upload-pack": dial tcp:`)
})
})
When("the config file has invalid branch name", func() {
JustBeforeEach(func() {
os.Setenv(terrascanConfigEnvName, "config/invalid_branch.toml")
})
JustAfterEach(func() {
os.Setenv(terrascanConfigEnvName, "")
})
It("should error out and exit with status code 1", func() {
session = initUtil.RunInitCommand(terrascanBinaryPath, outWriter, errWriter, 1)
helper.ContainsErrorSubString(session, `failed to initialize terrascan. error : failed to checkout git branch 'invalid-branch'. error: 'reference not found'`)
})
})
When("the config file has invalid rego subdir", func() {
JustBeforeEach(func() {
os.Setenv(terrascanConfigEnvName, "config/invalid_rego_subdir.toml")
})
JustAfterEach(func() {
os.Setenv(terrascanConfigEnvName, "")
})
It("should error out and exit with status code 1", func() {
session = initUtil.RunInitCommand(terrascanBinaryPath, outWriter, errWriter, 1)
helper.ContainsErrorSubString(session, "invalid/path: no such file or directory")
})
})
When("the config file has invalid path", func() {
JustBeforeEach(func() {
os.Setenv(terrascanConfigEnvName, "config/invalid_path.toml")
})
JustAfterEach(func() {
os.Setenv(terrascanConfigEnvName, "")
})
It("should should download policies and exit with status code 0", func() {
initUtil.RunInitCommand(terrascanBinaryPath, outWriter, errWriter, 0)
})
})
Context("the config file has valid data", func() {
When("config file has different git repo and branch", func() {
JustBeforeEach(func() {
os.Setenv(terrascanConfigEnvName, "config/valid_config.toml")
})
JustAfterEach(func() {
os.Setenv(terrascanConfigEnvName, "")
})
It("init should download the repo provided in the config file", func() {
initUtil.RunInitCommand(terrascanBinaryPath, outWriter, errWriter, 0)
})
Context("Kai Monkey git repo is downloaded", func() {
It("should validate Kai Monkey repo in the policy path", func() {
repo := initUtil.OpenGitRepo(defaultPolicyRepoPath)
initUtil.ValidateGitRepo(repo, kaiMoneyGitURL)
})
})
})
})
})

Describe("terrascan init is run multiple times", func() {
Context("init clones the git repo to a temp dir, deletes policy path and renames tempdir to policy path", func() {
Context("running init the first time", func() {
var modifiedTime time.Time
It("should download policies at the default policy path", func() {
initUtil.RunInitCommand(terrascanBinaryPath, outWriter, errWriter, 0)
fi, err := os.Stat(defaultPolicyRepoPath)
Expect(err).ToNot(HaveOccurred())
modifiedTime = fi.ModTime()
})
Context("running init the second time", func() {
It("should download policies again at the default policy path", func() {
initUtil.RunInitCommand(terrascanBinaryPath, outWriter, errWriter, 0)
fi, err := os.Stat(defaultPolicyRepoPath)
Expect(err).ToNot(HaveOccurred())
Expect(fi.ModTime()).To(BeTemporally(">", modifiedTime))
})
})
})
})
})
})

0 comments on commit bbe97ce

Please sign in to comment.