mirror of
https://github.com/thegeeklab/wp-opentofu.git
synced 2024-11-09 18:00:40 +00:00
commit
4423c336c5
64
DOCS.md
64
DOCS.md
@ -29,8 +29,11 @@ pipeline:
|
||||
+ app_version: 1.0.0
|
||||
```
|
||||
|
||||
Example configuration passing secrets to terraform via `vars`. The following
|
||||
example will call `terraform apply -var my_secret=${TERRAFORM_SECRET}`:
|
||||
Example configuration passing secrets to terraform. Please read
|
||||
https://www.terraform.io/docs/configuration/variables.html#environment-variables
|
||||
for more details.
|
||||
|
||||
**Drone 0.6+**:
|
||||
|
||||
```diff
|
||||
pipeline:
|
||||
@ -38,7 +41,26 @@ pipeline:
|
||||
image: jmccann/drone-terraform:1
|
||||
plan: false
|
||||
+ secrets:
|
||||
+ my_secret: TERRAFORM_SECRET
|
||||
+ - source: terraform_secret
|
||||
+ target: tf_var_my_secret
|
||||
```
|
||||
|
||||
**Drone 0.5**:
|
||||
|
||||
```diff
|
||||
pipeline:
|
||||
terraform_1:
|
||||
image: jmccann/drone-terraform:1
|
||||
plan: false
|
||||
+ environment:
|
||||
+ TF_VAR_MY_SECRET: ${TERRAFORM_SECRET}
|
||||
|
||||
terraform_2:
|
||||
image: jmccann/drone-terraform:1
|
||||
plan: false
|
||||
+ sensitive: true
|
||||
+ vars:
|
||||
+ my_secret: ${TERRAFORM_SECRET}
|
||||
```
|
||||
|
||||
You may be passing sensitive vars to your terraform commands. If you do not want
|
||||
@ -138,36 +160,6 @@ pipeline:
|
||||
+ parallelism: 2
|
||||
```
|
||||
|
||||
If you need to set different ENV secrets for multiple `terraform` steps you can utilize `secrets`.
|
||||
The following example shows using different remotes secrets each step.
|
||||
|
||||
```yaml
|
||||
pipeline:
|
||||
dev_terraform:
|
||||
image: jmccann/drone-terraform:1
|
||||
plan: false
|
||||
init_options:
|
||||
backend_config:
|
||||
- "bucket=my-terraform-config-bucket"
|
||||
- "key=tf-states/my-project"
|
||||
- "region=us-east-1"
|
||||
+ secrets:
|
||||
+ AWS_ACCESS_KEY_ID: DEV_AWS_ACCESS_KEY_ID
|
||||
+ AWS_SECRET_ACCESS_KEY: DEV_AWS_SECRET_ACCESS_KEY
|
||||
|
||||
prod_terraform:
|
||||
image: jmccann/drone-terraform:1
|
||||
plan: false
|
||||
init_options:
|
||||
backend_config:
|
||||
- "bucket=my-terraform-config-bucket"
|
||||
- "key=tf-states/my-project"
|
||||
- "region=us-east-1"
|
||||
+ secrets:
|
||||
+ AWS_ACCESS_KEY_ID: PROD_AWS_ACCESS_KEY_ID
|
||||
+ AWS_SECRET_ACCESS_KEY: PROD_AWS_SECRET_ACCESS_KEY
|
||||
```
|
||||
|
||||
Destroying the service can be done using the boolean `destory` option. Keep in mind that Fastly won't allow a service with active version be destoryed. Use `force_destroy` option in the service definition for terraform to handle it.
|
||||
|
||||
```yaml
|
||||
@ -205,12 +197,6 @@ var_files
|
||||
: a list of variable files to pass to the Terraform `plan` and `apply` commands.
|
||||
Each value is passed as a `-var-file <value>` option.
|
||||
|
||||
secrets
|
||||
: a map of variables to pass to the Terraform `plan` and `apply` commands as well as setting envvars.
|
||||
The `key` is the var and ENV to set. The `value` is the ENV to read the value from.
|
||||
* Each entry generate a terraform var as follows: `-var <key>=$<value>`
|
||||
* Additionally each entry generate sets and envvar as follows: `key=$value`
|
||||
|
||||
ca_cert
|
||||
: ca cert to add to your environment to allow terraform to use internal/private resources
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
# Docker image for the Drone Terraform plugin
|
||||
#
|
||||
# docker build --rm=true -t jmccann/drone-terraform:latest .
|
||||
# docker build -t jmccann/drone-terraform:latest .
|
||||
FROM golang:1.8-alpine AS builder
|
||||
COPY ./*.go ./src/
|
||||
COPY ./vendor/ ./src/
|
||||
|
20
plugin.go
20
plugin.go
@ -5,6 +5,7 @@ import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@ -53,9 +54,7 @@ func (p Plugin) Exec() error {
|
||||
|
||||
var commands []*exec.Cmd
|
||||
|
||||
if len(p.Config.Secrets) != 0 {
|
||||
exportSecrets(p.Config.Secrets)
|
||||
}
|
||||
CopyTfEnv()
|
||||
|
||||
if p.Config.Cacert != "" {
|
||||
commands = append(commands, installCaCert(p.Config.Cacert))
|
||||
@ -108,9 +107,14 @@ func installCaCert(cacert string) *exec.Cmd {
|
||||
)
|
||||
}
|
||||
|
||||
func exportSecrets(secrets map[string]string) {
|
||||
for k, v := range secrets {
|
||||
os.Setenv(fmt.Sprintf("%s", k), fmt.Sprintf("%s", os.Getenv(v)))
|
||||
func CopyTfEnv() {
|
||||
tfVar := regexp.MustCompile(`^TF_VAR_.*$`)
|
||||
for _, e := range os.Environ() {
|
||||
pair := strings.SplitN(e, "=", 2)
|
||||
if tfVar.MatchString(pair[0]) {
|
||||
name := strings.Split(pair[0], "TF_VAR_")
|
||||
os.Setenv(fmt.Sprintf("TF_VAR_%s", strings.ToLower(name[1])), pair[1])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -187,10 +191,6 @@ func planCommand(config Config) *exec.Cmd {
|
||||
args = append(args, "-var")
|
||||
args = append(args, fmt.Sprintf("%s=%s", k, v))
|
||||
}
|
||||
for k, v := range config.Secrets {
|
||||
args = append(args, "-var")
|
||||
args = append(args, fmt.Sprintf("%s=%s", k, os.Getenv(v)))
|
||||
}
|
||||
if config.Parallelism > 0 {
|
||||
args = append(args, fmt.Sprintf("-parallelism=%d", config.Parallelism))
|
||||
}
|
||||
|
@ -1,9 +1,12 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
. "github.com/franela/goblin"
|
||||
)
|
||||
|
||||
func Test_destroyCommand(t *testing.T) {
|
||||
@ -131,3 +134,23 @@ func Test_planCommand(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestPlugin(t *testing.T) {
|
||||
g := Goblin(t)
|
||||
|
||||
g.Describe("CopyTfEnv", func() {
|
||||
g.It("Should create copies of TF_VAR_ to lowercase", func() {
|
||||
// Set some initial TF_VAR_ that are uppercase
|
||||
os.Setenv("TF_VAR_SOMETHING", "some value")
|
||||
os.Setenv("TF_VAR_SOMETHING_ELSE", "some other value")
|
||||
os.Setenv("TF_VAR_BASE64", "dGVzdA==")
|
||||
|
||||
CopyTfEnv()
|
||||
|
||||
// Make sure new env vars exist with proper values
|
||||
g.Assert(os.Getenv("TF_VAR_something")).Equal("some value")
|
||||
g.Assert(os.Getenv("TF_VAR_something_else")).Equal("some other value")
|
||||
g.Assert(os.Getenv("TF_VAR_base64")).Equal("dGVzdA==")
|
||||
})
|
||||
})
|
||||
}
|
||||
|
19
vendor/github.com/franela/goblin/LICENSE
generated
vendored
Normal file
19
vendor/github.com/franela/goblin/LICENSE
generated
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
Copyright (c) 2013 Marcos Lilljedahl and Jonathan Leibiusky
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
3
vendor/github.com/franela/goblin/Makefile
generated
vendored
Normal file
3
vendor/github.com/franela/goblin/Makefile
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
export GOPATH=$(shell pwd)
|
||||
test:
|
||||
go test -v
|
141
vendor/github.com/franela/goblin/README.md
generated
vendored
Normal file
141
vendor/github.com/franela/goblin/README.md
generated
vendored
Normal file
@ -0,0 +1,141 @@
|
||||
[![Build Status](https://travis-ci.org/franela/goblin.png?branch=master)](https://travis-ci.org/franela/goblin)
|
||||
Goblin
|
||||
======
|
||||
|
||||
![](https://github.com/marcosnils/goblin/blob/master/goblin_logo.jpg?raw=true)
|
||||
|
||||
A [Mocha](http://mochajs.org/) like BDD testing framework for Go
|
||||
|
||||
No extensive documentation nor complicated steps to get it running
|
||||
|
||||
Run tests as usual with `go test`
|
||||
|
||||
Colorful reports and beautiful syntax
|
||||
|
||||
|
||||
Why Goblin?
|
||||
-----------
|
||||
|
||||
Inspired by the flexibility and simplicity of Node BDD and frustrated by the
|
||||
rigorousness of Go way of testing, we wanted to bring a new tool to
|
||||
write self-describing and comprehensive code.
|
||||
|
||||
|
||||
|
||||
What do I get with it?
|
||||
----------------------
|
||||
|
||||
- Preserve the exact same syntax and behaviour as Node's Mocha
|
||||
- Nest as many `Describe` and `It` blocks as you want
|
||||
- Use `Before`, `BeforeEach`, `After` and `AfterEach` for setup and teardown your tests
|
||||
- No need to remember confusing parameters in `Describe` and `It` blocks
|
||||
- Use a declarative and expressive language to write your tests
|
||||
- Plug different assertion libraries ([Gomega](https://github.com/onsi/gomega) supported so far)
|
||||
- Skip your tests the same way as you would do in Mocha
|
||||
- Automatic terminal support for colored outputs
|
||||
- Two line setup is all you need to get up running
|
||||
|
||||
|
||||
|
||||
How do I use it?
|
||||
----------------
|
||||
|
||||
Since ```go test``` is not currently extensive, you will have to hook Goblin to it. You do that by
|
||||
adding a single test method in your test file. All your goblin tests will be implemented inside this function.
|
||||
|
||||
```go
|
||||
package foobar
|
||||
|
||||
import (
|
||||
"testing"
|
||||
. "github.com/franela/goblin"
|
||||
)
|
||||
|
||||
func Test(t *testing.T) {
|
||||
g := Goblin(t)
|
||||
g.Describe("Numbers", func() {
|
||||
g.It("Should add two numbers ", func() {
|
||||
g.Assert(1+1).Equal(2)
|
||||
})
|
||||
g.It("Should match equal numbers", func() {
|
||||
g.Assert(2).Equal(4)
|
||||
})
|
||||
g.It("Should substract two numbers")
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
Ouput will be something like:
|
||||
|
||||
![](https://github.com/marcosnils/goblin/blob/master/goblin_output.png?raw=true)
|
||||
|
||||
Nice and easy, right?
|
||||
|
||||
Can I do asynchronous tests?
|
||||
----------------------------
|
||||
|
||||
Yes! Goblin will help you to test asynchronous things, like goroutines, etc. You just need to add a ```done``` parameter to the handler function of your ```It```. This handler function should be called when your test passes.
|
||||
|
||||
```go
|
||||
...
|
||||
g.Describe("Numbers", func() {
|
||||
g.It("Should add two numbers asynchronously", func(done Done) {
|
||||
go func() {
|
||||
g.Assert(1+1).Equal(2)
|
||||
done()
|
||||
}()
|
||||
})
|
||||
})
|
||||
...
|
||||
```
|
||||
|
||||
Goblin will wait for the ```done``` call, a ```Fail``` call or any false assertion.
|
||||
|
||||
How do I use it with Gomega?
|
||||
----------------------------
|
||||
|
||||
Gomega is a nice assertion framework. But it doesn't provide a nice way to hook it to testing frameworks. It should just panic instead of requiring a fail function. There is an issue about that [here](https://github.com/onsi/gomega/issues/5).
|
||||
While this is being discussed and hopefully fixed, the way to use Gomega with Goblin is:
|
||||
|
||||
```go
|
||||
package foobar
|
||||
|
||||
import (
|
||||
"testing"
|
||||
. "github.com/franela/goblin"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
func Test(t *testing.T) {
|
||||
g := Goblin(t)
|
||||
|
||||
//special hook for gomega
|
||||
RegisterFailHandler(func(m string, _ ...int) { g.Fail(m) })
|
||||
|
||||
g.Describe("lala", func() {
|
||||
g.It("lslslslsls", func() {
|
||||
Expect(1).To(Equal(10))
|
||||
})
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
FAQ:
|
||||
----
|
||||
|
||||
### How do I run specific tests?
|
||||
|
||||
If `-goblin.run=$REGES` is supplied to the `go test` command then only tests that match the supplied regex will run
|
||||
|
||||
|
||||
TODO:
|
||||
-----
|
||||
|
||||
We do have a couple of [issues](https://github.com/franela/goblin/issues) pending we'll be addressing soon. But feel free to
|
||||
contribute and send us PRs (with tests please :smile:).
|
||||
|
||||
Contributions:
|
||||
------------
|
||||
|
||||
Special thanks to [Leandro Reox](https://github.com/leandroreox) (Leitan) for the goblin logo.
|
59
vendor/github.com/franela/goblin/assertions.go
generated
vendored
Normal file
59
vendor/github.com/franela/goblin/assertions.go
generated
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
package goblin
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Assertion struct {
|
||||
src interface{}
|
||||
fail func(interface{})
|
||||
}
|
||||
|
||||
func objectsAreEqual(a, b interface{}) bool {
|
||||
if reflect.TypeOf(a) != reflect.TypeOf(b) {
|
||||
return false
|
||||
}
|
||||
|
||||
if reflect.DeepEqual(a, b) {
|
||||
return true
|
||||
}
|
||||
|
||||
if fmt.Sprintf("%#v", a) == fmt.Sprintf("%#v", b) {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func formatMessages(messages ...string) string {
|
||||
if len(messages) > 0 {
|
||||
return ", " + strings.Join(messages, " ")
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (a *Assertion) Eql(dst interface{}) {
|
||||
a.Equal(dst)
|
||||
}
|
||||
|
||||
func (a *Assertion) Equal(dst interface{}) {
|
||||
if !objectsAreEqual(a.src, dst) {
|
||||
a.fail(fmt.Sprintf("%#v %s %#v", a.src, "does not equal", dst))
|
||||
}
|
||||
}
|
||||
|
||||
func (a *Assertion) IsTrue(messages ...string) {
|
||||
if !objectsAreEqual(a.src, true) {
|
||||
message := fmt.Sprintf("%v %s%s", a.src, "expected false to be truthy", formatMessages(messages...))
|
||||
a.fail(message)
|
||||
}
|
||||
}
|
||||
|
||||
func (a *Assertion) IsFalse(messages ...string) {
|
||||
if !objectsAreEqual(a.src, false) {
|
||||
message := fmt.Sprintf("%v %s%s", a.src, "expected true to be falsey", formatMessages(messages...))
|
||||
a.fail(message)
|
||||
}
|
||||
}
|
36
vendor/github.com/franela/goblin/go.snippets
generated
vendored
Normal file
36
vendor/github.com/franela/goblin/go.snippets
generated
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
snippet gd
|
||||
g.Describe("${1:name}", func() {
|
||||
${2}
|
||||
})
|
||||
${0}
|
||||
snippet git
|
||||
g.It("${1:name}", func() {
|
||||
${2}
|
||||
})
|
||||
${0}
|
||||
snippet gait
|
||||
g.It("${1:name}", func(done Done) {
|
||||
done()
|
||||
${2}
|
||||
})
|
||||
${0}
|
||||
snippet gb
|
||||
g.Before(func() {
|
||||
${1}
|
||||
})
|
||||
${0}
|
||||
snippet gbe
|
||||
g.BeforeEach(func() {
|
||||
${1}
|
||||
})
|
||||
${0}
|
||||
snippet ga
|
||||
g.After(func() {
|
||||
${1}
|
||||
})
|
||||
${0}
|
||||
snippet gae
|
||||
g.AfterEach(func() {
|
||||
${1}
|
||||
})
|
||||
${0}
|
302
vendor/github.com/franela/goblin/goblin.go
generated
vendored
Normal file
302
vendor/github.com/franela/goblin/goblin.go
generated
vendored
Normal file
@ -0,0 +1,302 @@
|
||||
package goblin
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Done func(error ...interface{})
|
||||
|
||||
type Runnable interface {
|
||||
run(*G) bool
|
||||
}
|
||||
|
||||
func (g *G) Describe(name string, h func()) {
|
||||
d := &Describe{name: name, h: h, parent: g.parent}
|
||||
|
||||
if d.parent != nil {
|
||||
d.parent.children = append(d.parent.children, Runnable(d))
|
||||
}
|
||||
|
||||
g.parent = d
|
||||
|
||||
h()
|
||||
|
||||
g.parent = d.parent
|
||||
|
||||
if g.parent == nil && d.hasTests {
|
||||
g.reporter.begin()
|
||||
if d.run(g) {
|
||||
g.t.Fail()
|
||||
}
|
||||
g.reporter.end()
|
||||
}
|
||||
}
|
||||
func (g *G) Timeout(time time.Duration) {
|
||||
g.timeout = time
|
||||
g.timer.Reset(time)
|
||||
}
|
||||
|
||||
type Describe struct {
|
||||
name string
|
||||
h func()
|
||||
children []Runnable
|
||||
befores []func()
|
||||
afters []func()
|
||||
afterEach []func()
|
||||
beforeEach []func()
|
||||
hasTests bool
|
||||
parent *Describe
|
||||
}
|
||||
|
||||
func (d *Describe) runBeforeEach() {
|
||||
if d.parent != nil {
|
||||
d.parent.runBeforeEach()
|
||||
}
|
||||
|
||||
for _, b := range d.beforeEach {
|
||||
b()
|
||||
}
|
||||
}
|
||||
|
||||
func (d *Describe) runAfterEach() {
|
||||
|
||||
if d.parent != nil {
|
||||
d.parent.runAfterEach()
|
||||
}
|
||||
|
||||
for _, a := range d.afterEach {
|
||||
a()
|
||||
}
|
||||
}
|
||||
|
||||
func (d *Describe) run(g *G) bool {
|
||||
failed := false
|
||||
if d.hasTests {
|
||||
g.reporter.beginDescribe(d.name)
|
||||
|
||||
for _, b := range d.befores {
|
||||
b()
|
||||
}
|
||||
|
||||
for _, r := range d.children {
|
||||
if r.run(g) {
|
||||
failed = true
|
||||
}
|
||||
}
|
||||
|
||||
for _, a := range d.afters {
|
||||
a()
|
||||
}
|
||||
|
||||
g.reporter.endDescribe()
|
||||
}
|
||||
|
||||
return failed
|
||||
}
|
||||
|
||||
type Failure struct {
|
||||
stack []string
|
||||
testName string
|
||||
message string
|
||||
}
|
||||
|
||||
type It struct {
|
||||
h interface{}
|
||||
name string
|
||||
parent *Describe
|
||||
failure *Failure
|
||||
reporter Reporter
|
||||
isAsync bool
|
||||
}
|
||||
|
||||
func (it *It) run(g *G) bool {
|
||||
g.currentIt = it
|
||||
|
||||
if it.h == nil {
|
||||
g.reporter.itIsPending(it.name)
|
||||
return false
|
||||
}
|
||||
//TODO: should handle errors for beforeEach
|
||||
it.parent.runBeforeEach()
|
||||
|
||||
runIt(g, it.h)
|
||||
|
||||
it.parent.runAfterEach()
|
||||
|
||||
failed := false
|
||||
if it.failure != nil {
|
||||
failed = true
|
||||
}
|
||||
|
||||
if failed {
|
||||
g.reporter.itFailed(it.name)
|
||||
g.reporter.failure(it.failure)
|
||||
} else {
|
||||
g.reporter.itPassed(it.name)
|
||||
}
|
||||
return failed
|
||||
}
|
||||
|
||||
func (it *It) failed(msg string, stack []string) {
|
||||
it.failure = &Failure{stack: stack, message: msg, testName: it.parent.name + " " + it.name}
|
||||
}
|
||||
|
||||
func parseFlags() {
|
||||
//Flag parsing
|
||||
flag.Parse()
|
||||
if *regexParam != "" {
|
||||
runRegex = regexp.MustCompile(*regexParam)
|
||||
} else {
|
||||
runRegex = nil
|
||||
}
|
||||
}
|
||||
|
||||
var timeout = flag.Duration("goblin.timeout", 5*time.Second, "Sets default timeouts for all tests")
|
||||
var isTty = flag.Bool("goblin.tty", true, "Sets the default output format (color / monochrome)")
|
||||
var regexParam = flag.String("goblin.run", "", "Runs only tests which match the supplied regex")
|
||||
var runRegex *regexp.Regexp
|
||||
|
||||
func init() {
|
||||
parseFlags()
|
||||
}
|
||||
|
||||
func Goblin(t *testing.T, arguments ...string) *G {
|
||||
g := &G{t: t, timeout: *timeout}
|
||||
var fancy TextFancier
|
||||
if *isTty {
|
||||
fancy = &TerminalFancier{}
|
||||
} else {
|
||||
fancy = &Monochrome{}
|
||||
}
|
||||
|
||||
g.reporter = Reporter(&DetailedReporter{fancy: fancy})
|
||||
return g
|
||||
}
|
||||
|
||||
func runIt(g *G, h interface{}) {
|
||||
defer timeTrack(time.Now(), g)
|
||||
g.mutex.Lock()
|
||||
g.timedOut = false
|
||||
g.mutex.Unlock()
|
||||
g.timer = time.NewTimer(g.timeout)
|
||||
g.shouldContinue = make(chan bool)
|
||||
if call, ok := h.(func()); ok {
|
||||
// the test is synchronous
|
||||
go func(c chan bool) { call(); c <- true }(g.shouldContinue)
|
||||
} else if call, ok := h.(func(Done)); ok {
|
||||
doneCalled := 0
|
||||
go func(c chan bool) {
|
||||
call(func(msg ...interface{}) {
|
||||
if len(msg) > 0 {
|
||||
g.Fail(msg)
|
||||
} else {
|
||||
doneCalled++
|
||||
if doneCalled > 1 {
|
||||
g.Fail("Done called multiple times")
|
||||
}
|
||||
c <- true
|
||||
}
|
||||
})
|
||||
}(g.shouldContinue)
|
||||
} else {
|
||||
panic("Not implemented.")
|
||||
}
|
||||
select {
|
||||
case <-g.shouldContinue:
|
||||
case <-g.timer.C:
|
||||
//Set to nil as it shouldn't continue
|
||||
g.shouldContinue = nil
|
||||
g.timedOut = true
|
||||
g.Fail("Test exceeded " + fmt.Sprintf("%s", g.timeout))
|
||||
}
|
||||
// Reset timeout value
|
||||
g.timeout = *timeout
|
||||
}
|
||||
|
||||
type G struct {
|
||||
t *testing.T
|
||||
parent *Describe
|
||||
currentIt *It
|
||||
timeout time.Duration
|
||||
reporter Reporter
|
||||
timedOut bool
|
||||
shouldContinue chan bool
|
||||
mutex sync.Mutex
|
||||
timer *time.Timer
|
||||
}
|
||||
|
||||
func (g *G) SetReporter(r Reporter) {
|
||||
g.reporter = r
|
||||
}
|
||||
|
||||
func (g *G) It(name string, h ...interface{}) {
|
||||
if matchesRegex(name) {
|
||||
it := &It{name: name, parent: g.parent, reporter: g.reporter}
|
||||
notifyParents(g.parent)
|
||||
if len(h) > 0 {
|
||||
it.h = h[0]
|
||||
}
|
||||
g.parent.children = append(g.parent.children, Runnable(it))
|
||||
}
|
||||
}
|
||||
|
||||
func matchesRegex(value string) bool {
|
||||
if runRegex != nil {
|
||||
return runRegex.MatchString(value)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func notifyParents(d *Describe) {
|
||||
d.hasTests = true
|
||||
if d.parent != nil {
|
||||
notifyParents(d.parent)
|
||||
}
|
||||
}
|
||||
|
||||
func (g *G) Before(h func()) {
|
||||
g.parent.befores = append(g.parent.befores, h)
|
||||
}
|
||||
|
||||
func (g *G) BeforeEach(h func()) {
|
||||
g.parent.beforeEach = append(g.parent.beforeEach, h)
|
||||
}
|
||||
|
||||
func (g *G) After(h func()) {
|
||||
g.parent.afters = append(g.parent.afters, h)
|
||||
}
|
||||
|
||||
func (g *G) AfterEach(h func()) {
|
||||
g.parent.afterEach = append(g.parent.afterEach, h)
|
||||
}
|
||||
|
||||
func (g *G) Assert(src interface{}) *Assertion {
|
||||
return &Assertion{src: src, fail: g.Fail}
|
||||
}
|
||||
|
||||
func timeTrack(start time.Time, g *G) {
|
||||
g.reporter.itTook(time.Since(start))
|
||||
}
|
||||
|
||||
func (g *G) Fail(error interface{}) {
|
||||
//Skips 7 stacks due to the functions between the stack and the test
|
||||
stack := ResolveStack(7)
|
||||
message := fmt.Sprintf("%v", error)
|
||||
g.currentIt.failed(message, stack)
|
||||
if g.shouldContinue != nil {
|
||||
g.shouldContinue <- true
|
||||
}
|
||||
g.mutex.Lock()
|
||||
defer g.mutex.Unlock()
|
||||
if !g.timedOut {
|
||||
//Stop test function execution
|
||||
runtime.Goexit()
|
||||
}
|
||||
|
||||
}
|
BIN
vendor/github.com/franela/goblin/goblin_logo.jpg
generated
vendored
Normal file
BIN
vendor/github.com/franela/goblin/goblin_logo.jpg
generated
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 36 KiB |
BIN
vendor/github.com/franela/goblin/goblin_output.png
generated
vendored
Normal file
BIN
vendor/github.com/franela/goblin/goblin_output.png
generated
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 18 KiB |
26
vendor/github.com/franela/goblin/mono_reporter.go
generated
vendored
Normal file
26
vendor/github.com/franela/goblin/mono_reporter.go
generated
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
package goblin
|
||||
|
||||
import ()
|
||||
|
||||
type Monochrome struct {
|
||||
}
|
||||
|
||||
func (self *Monochrome) Red(text string) string {
|
||||
return "!" + text
|
||||
}
|
||||
|
||||
func (self *Monochrome) Gray(text string) string {
|
||||
return text
|
||||
}
|
||||
|
||||
func (self *Monochrome) Cyan(text string) string {
|
||||
return text
|
||||
}
|
||||
|
||||
func (self *Monochrome) WithCheck(text string) string {
|
||||
return ">>>" + text
|
||||
}
|
||||
|
||||
func (self *Monochrome) Green(text string) string {
|
||||
return text
|
||||
}
|
137
vendor/github.com/franela/goblin/reporting.go
generated
vendored
Normal file
137
vendor/github.com/franela/goblin/reporting.go
generated
vendored
Normal file
@ -0,0 +1,137 @@
|
||||
package goblin
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Reporter interface {
|
||||
beginDescribe(string)
|
||||
endDescribe()
|
||||
begin()
|
||||
end()
|
||||
failure(*Failure)
|
||||
itTook(time.Duration)
|
||||
itFailed(string)
|
||||
itPassed(string)
|
||||
itIsPending(string)
|
||||
}
|
||||
|
||||
type TextFancier interface {
|
||||
Red(text string) string
|
||||
Gray(text string) string
|
||||
Cyan(text string) string
|
||||
Green(text string) string
|
||||
WithCheck(text string) string
|
||||
}
|
||||
|
||||
type DetailedReporter struct {
|
||||
level, failed, passed, pending int
|
||||
failures []*Failure
|
||||
executionTime, totalExecutionTime time.Duration
|
||||
fancy TextFancier
|
||||
}
|
||||
|
||||
func (r *DetailedReporter) SetTextFancier(f TextFancier) {
|
||||
r.fancy = f
|
||||
}
|
||||
|
||||
type TerminalFancier struct {
|
||||
}
|
||||
|
||||
func (self *TerminalFancier) Red(text string) string {
|
||||
return "\033[31m" + text + "\033[0m"
|
||||
}
|
||||
|
||||
func (self *TerminalFancier) Gray(text string) string {
|
||||
return "\033[90m" + text + "\033[0m"
|
||||
}
|
||||
|
||||
func (self *TerminalFancier) Cyan(text string) string {
|
||||
return "\033[36m" + text + "\033[0m"
|
||||
}
|
||||
|
||||
func (self *TerminalFancier) Green(text string) string {
|
||||
return "\033[32m" + text + "\033[0m"
|
||||
}
|
||||
|
||||
func (self *TerminalFancier) WithCheck(text string) string {
|
||||
return "\033[32m\u2713\033[0m " + text
|
||||
}
|
||||
|
||||
func (r *DetailedReporter) getSpace() string {
|
||||
return strings.Repeat(" ", (r.level+1)*2)
|
||||
}
|
||||
|
||||
func (r *DetailedReporter) failure(failure *Failure) {
|
||||
r.failures = append(r.failures, failure)
|
||||
}
|
||||
|
||||
func (r *DetailedReporter) print(text string) {
|
||||
fmt.Printf("%v%v\n", r.getSpace(), text)
|
||||
}
|
||||
|
||||
func (r *DetailedReporter) printWithCheck(text string) {
|
||||
fmt.Printf("%v%v\n", r.getSpace(), r.fancy.WithCheck(text))
|
||||
}
|
||||
|
||||
func (r *DetailedReporter) beginDescribe(name string) {
|
||||
fmt.Println("")
|
||||
r.print(name)
|
||||
r.level++
|
||||
}
|
||||
|
||||
func (r *DetailedReporter) endDescribe() {
|
||||
r.level--
|
||||
}
|
||||
|
||||
func (r *DetailedReporter) itTook(duration time.Duration) {
|
||||
r.executionTime = duration
|
||||
r.totalExecutionTime += duration
|
||||
}
|
||||
|
||||
func (r *DetailedReporter) itFailed(name string) {
|
||||
r.failed++
|
||||
r.print(r.fancy.Red(strconv.Itoa(r.failed) + ") " + name))
|
||||
}
|
||||
|
||||
func (r *DetailedReporter) itPassed(name string) {
|
||||
r.passed++
|
||||
r.printWithCheck(r.fancy.Gray(name))
|
||||
}
|
||||
|
||||
func (r *DetailedReporter) itIsPending(name string) {
|
||||
r.pending++
|
||||
r.print(r.fancy.Cyan("- " + name))
|
||||
}
|
||||
|
||||
func (r *DetailedReporter) begin() {
|
||||
}
|
||||
|
||||
func (r *DetailedReporter) end() {
|
||||
comp := fmt.Sprintf("%d tests complete", r.passed)
|
||||
t := fmt.Sprintf("(%d ms)", r.totalExecutionTime/time.Millisecond)
|
||||
|
||||
//fmt.Printf("\n\n \033[32m%d tests complete\033[0m \033[90m(%d ms)\033[0m\n", r.passed, r.totalExecutionTime/time.Millisecond)
|
||||
fmt.Printf("\n\n %v %v\n", r.fancy.Green(comp), r.fancy.Gray(t))
|
||||
|
||||
if r.pending > 0 {
|
||||
pend := fmt.Sprintf("%d test(s) pending", r.pending)
|
||||
fmt.Printf(" %v\n\n", r.fancy.Cyan(pend))
|
||||
}
|
||||
|
||||
if len(r.failures) > 0 {
|
||||
fmt.Printf("%s \n\n", r.fancy.Red(fmt.Sprintf(" %d tests failed:", len(r.failures))))
|
||||
|
||||
}
|
||||
|
||||
for i, failure := range r.failures {
|
||||
fmt.Printf(" %d) %s:\n\n", i+1, failure.testName)
|
||||
fmt.Printf(" %s\n", r.fancy.Red(failure.message))
|
||||
for _, stackItem := range failure.stack {
|
||||
fmt.Printf(" %s\n", r.fancy.Gray(stackItem))
|
||||
}
|
||||
}
|
||||
}
|
21
vendor/github.com/franela/goblin/resolver.go
generated
vendored
Normal file
21
vendor/github.com/franela/goblin/resolver.go
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
package goblin
|
||||
|
||||
import (
|
||||
"runtime/debug"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func ResolveStack(skip int) []string {
|
||||
return cleanStack(debug.Stack(), skip)
|
||||
}
|
||||
|
||||
func cleanStack(stack []byte, skip int) []string {
|
||||
arrayStack := strings.Split(string(stack), "\n")
|
||||
var finalStack []string
|
||||
for i := skip; i < len(arrayStack); i++ {
|
||||
if strings.Contains(arrayStack[i], ".go") {
|
||||
finalStack = append(finalStack, arrayStack[i])
|
||||
}
|
||||
}
|
||||
return finalStack
|
||||
}
|
8
vendor/vendor.json
vendored
8
vendor/vendor.json
vendored
@ -144,6 +144,12 @@
|
||||
"revision": "c0d7d3282e4c14991a4814de7eae4774e388de61",
|
||||
"revisionTime": "2016-10-07T22:43:33Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "ip3Xz/dILw2RMM6Z0MzAj5TUZ/c=",
|
||||
"path": "github.com/franela/goblin",
|
||||
"revision": "2fa789fd0c6b7975acbfb89a04830b4081a7b0e9",
|
||||
"revisionTime": "2017-01-11T05:10:28Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "cVyhKIRI2gQrgpn5qrBeAqErmWM=",
|
||||
"path": "github.com/go-ini/ini",
|
||||
@ -175,5 +181,5 @@
|
||||
"revisionTime": "2016-10-06T02:47:49Z"
|
||||
}
|
||||
],
|
||||
"rootPath": "github.com/drone-plugins/drone-terraform"
|
||||
"rootPath": "github.com/jmccann/drone-terraform"
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user