├── ecs ├── doc.go ├── ecs_test.go └── test_fixtures │ └── task.json ├── vendor ├── gopkg.in │ └── check.v1 │ │ ├── TODO │ │ ├── README.md │ │ ├── export_test.go │ │ ├── LICENSE │ │ ├── bootstrap_test.go │ │ ├── reporter.go │ │ ├── printer_test.go │ │ ├── benchmark_test.go │ │ ├── printer.go │ │ ├── reporter_test.go │ │ ├── benchmark.go │ │ ├── check_test.go │ │ ├── run.go │ │ ├── helpers.go │ │ ├── foundation_test.go │ │ └── checkers_test.go ├── github.com │ ├── stretchrcom │ │ └── testify │ │ │ ├── assert │ │ │ ├── assertion_forward.go.tmpl │ │ │ ├── errors.go │ │ │ ├── forward_assertions.go │ │ │ ├── doc.go │ │ │ ├── http_assertions_test.go │ │ │ └── http_assertions.go │ │ │ └── LICENSE │ ├── davecgh │ │ └── go-spew │ │ │ ├── LICENSE │ │ │ └── spew │ │ │ ├── dumpnocgo_test.go │ │ │ ├── bypasssafe.go │ │ │ ├── internal_test.go │ │ │ ├── testdata │ │ │ └── dumpcgo.go │ │ │ ├── internalunsafe_test.go │ │ │ ├── dumpcgo_test.go │ │ │ ├── bypass.go │ │ │ ├── spew.go │ │ │ ├── example_test.go │ │ │ ├── doc.go │ │ │ ├── common_test.go │ │ │ ├── spew_test.go │ │ │ └── common.go │ └── pmezard │ │ └── go-difflib │ │ ├── LICENSE │ │ └── difflib │ │ └── difflib_test.go └── vendor.json ├── compose ├── doc.go ├── compose_test.go ├── test_fixtures │ └── docker-compose.yaml └── compose.go ├── doc.go ├── script ├── doc.go ├── script_test.go ├── test_fixtures │ ├── compose.out │ └── docker-compose.yaml ├── script.go └── template.go ├── transform ├── doc.go └── base.go ├── .dockerignore ├── .gitignore ├── .travis.yml ├── Dockerfile ├── LICENSE ├── main.go └── README.md /ecs/doc.go: -------------------------------------------------------------------------------- 1 | // Package ecs is for ingesting and emitting ECS task files 2 | package ecs 3 | -------------------------------------------------------------------------------- /vendor/gopkg.in/check.v1/TODO: -------------------------------------------------------------------------------- 1 | - Assert(slice, Contains, item) 2 | - Parallel test support 3 | -------------------------------------------------------------------------------- /compose/doc.go: -------------------------------------------------------------------------------- 1 | // Package compose is for ingesting and emitting docker-compose files 2 | package compose 3 | -------------------------------------------------------------------------------- /doc.go: -------------------------------------------------------------------------------- 1 | // A tool for converting docker container information between various formats 2 | package main 3 | -------------------------------------------------------------------------------- /script/doc.go: -------------------------------------------------------------------------------- 1 | // Package script for emitting docker containers to the command line 2 | package script 3 | -------------------------------------------------------------------------------- /transform/doc.go: -------------------------------------------------------------------------------- 1 | // Package transform is for representing groups of docker containers in transition between 2 | // various formats 3 | package transform 4 | -------------------------------------------------------------------------------- /vendor/github.com/stretchrcom/testify/assert/assertion_forward.go.tmpl: -------------------------------------------------------------------------------- 1 | {{.CommentWithoutT "a"}} 2 | func (a *Assertions) {{.DocInfo.Name}}({{.Params}}) bool { 3 | return {{.DocInfo.Name}}(a.t, {{.ForwardedParams}}) 4 | } 5 | -------------------------------------------------------------------------------- /vendor/github.com/stretchrcom/testify/assert/errors.go: -------------------------------------------------------------------------------- 1 | package assert 2 | 3 | import ( 4 | "errors" 5 | ) 6 | 7 | // AnError is an error instance useful for testing. If the code does not care 8 | // about error specifics, and only needs to return the error for example, this 9 | // error should be used to make the test code more readable. 10 | var AnError = errors.New("assert.AnError general error for testing") 11 | -------------------------------------------------------------------------------- /vendor/gopkg.in/check.v1/README.md: -------------------------------------------------------------------------------- 1 | Instructions 2 | ============ 3 | 4 | Install the package with: 5 | 6 | go get gopkg.in/check.v1 7 | 8 | Import it with: 9 | 10 | import "gopkg.in/check.v1" 11 | 12 | and use _check_ as the package name inside the code. 13 | 14 | For more details, visit the project page: 15 | 16 | * http://labix.org/gocheck 17 | 18 | and the API documentation: 19 | 20 | * https://gopkg.in/check.v1 21 | -------------------------------------------------------------------------------- /vendor/github.com/stretchrcom/testify/assert/forward_assertions.go: -------------------------------------------------------------------------------- 1 | package assert 2 | 3 | // Assertions provides assertion methods around the 4 | // TestingT interface. 5 | type Assertions struct { 6 | t TestingT 7 | } 8 | 9 | // New makes a new Assertions object for the specified TestingT. 10 | func New(t TestingT) *Assertions { 11 | return &Assertions{ 12 | t: t, 13 | } 14 | } 15 | 16 | //go:generate go run ../_codegen/main.go -output-package=assert -template=assertion_forward.go.tmpl 17 | -------------------------------------------------------------------------------- /vendor/gopkg.in/check.v1/export_test.go: -------------------------------------------------------------------------------- 1 | package check 2 | 3 | import "io" 4 | 5 | func PrintLine(filename string, line int) (string, error) { 6 | return printLine(filename, line) 7 | } 8 | 9 | func Indent(s, with string) string { 10 | return indent(s, with) 11 | } 12 | 13 | func NewOutputWriter(writer io.Writer, stream, verbose bool) *outputWriter { 14 | return newOutputWriter(writer, stream, verbose) 15 | } 16 | 17 | func (c *C) FakeSkip(reason string) { 18 | c.reason = reason 19 | } 20 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 2 | *.o 3 | *.a 4 | *.so 5 | 6 | # Folders 7 | _obj 8 | _test 9 | 10 | # Coverage output 11 | coverage.out 12 | profile.cov 13 | 14 | # Architecture specific extensions/prefixes 15 | *.[568vq] 16 | [568vq].out 17 | 18 | *.cgo1.go 19 | *.cgo2.c 20 | _cgo_defun.c 21 | _cgo_gotypes.go 22 | _cgo_export.* 23 | 24 | _testmain.go 25 | 26 | *.exe 27 | *.test 28 | *.prof 29 | 30 | # vim files 31 | *.swp 32 | 33 | # Pycharm/IDEA 34 | .idea/ 35 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 2 | *.o 3 | *.a 4 | *.so 5 | 6 | # Folders 7 | _obj 8 | _test 9 | 10 | # Coverage 11 | coverage.out 12 | 13 | # Bild artifacts 14 | container-tx 15 | 16 | # Architecture specific extensions/prefixes 17 | *.[568vq] 18 | [568vq].out 19 | 20 | *.cgo1.go 21 | *.cgo2.c 22 | _cgo_defun.c 23 | _cgo_gotypes.go 24 | _cgo_export.* 25 | 26 | _testmain.go 27 | 28 | *.exe 29 | *.test 30 | *.prof 31 | 32 | .idea/ 33 | 34 | # Ignore vim files 35 | *.swp 36 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: go 3 | 4 | go: 5 | - 1.7 6 | - tip 7 | 8 | before_install: 9 | - go get golang.org/x/tools/cmd/cover 10 | - go get -u github.com/golang/lint/golint 11 | 12 | script: 13 | - go test -coverprofile=coverage.out ./compose 14 | - go tool cover -func=coverage.out 15 | - go test -coverprofile=coverage.out ./ecs 16 | - go tool cover -func=coverage.out 17 | - go test -coverprofile=coverage.out ./script 18 | - go tool cover -func=coverage.out 19 | - go test -race $(go list ./... | grep -v /vendor/) 20 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # To build: 2 | # $ docker run --rm -v $(pwd):/go/src/github.com/micahhausler/container-tx -w /go/src/github.com/micahhausler/container-tx golang:1.7 go build -v -a -tags netgo -installsuffix netgo -ldflags '-w' 3 | # $ docker build -t micahhausler/container-tx . 4 | # 5 | # To run: 6 | # $ docker run micahhausler/container-tx 7 | 8 | FROM busybox 9 | 10 | MAINTAINER Micah Hausler, 11 | 12 | COPY container-tx /bin/container-tx 13 | RUN chmod 755 /bin/container-tx 14 | 15 | ENTRYPOINT ["/bin/container-tx"] 16 | -------------------------------------------------------------------------------- /vendor/github.com/davecgh/go-spew/LICENSE: -------------------------------------------------------------------------------- 1 | ISC License 2 | 3 | Copyright (c) 2012-2013 Dave Collins 4 | 5 | Permission to use, copy, modify, and distribute this software for any 6 | purpose with or without fee is hereby granted, provided that the above 7 | copyright notice and this permission notice appear in all copies. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 | -------------------------------------------------------------------------------- /ecs/ecs_test.go: -------------------------------------------------------------------------------- 1 | package ecs 2 | 3 | import ( 4 | "os" 5 | "testing" 6 | ) 7 | 8 | func TestIngestContainers(t *testing.T) { 9 | pod := Task{} 10 | 11 | f, err := os.Open("./test_fixtures/task.json") 12 | if err != nil { 13 | t.Errorf("Failed to open fixture: %s", err) 14 | } 15 | 16 | _, err = pod.IngestContainers(f) 17 | if err != nil { 18 | t.Errorf("Failed to ingest containers: %s", err) 19 | } 20 | } 21 | 22 | func TestEmitContainers(t *testing.T) { 23 | pod := Task{} 24 | 25 | f, err := os.Open("./test_fixtures/task.json") 26 | if err != nil { 27 | t.Errorf("Failed to open fixture: %s", err) 28 | } 29 | 30 | bp, err := pod.IngestContainers(f) 31 | if err != nil { 32 | t.Errorf("Failed to ingest containers: %s", err) 33 | } 34 | 35 | _, err = Task{}.EmitContainers(bp) 36 | if err != nil { 37 | t.Errorf("Failed to ingest containers: %s", err) 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /compose/compose_test.go: -------------------------------------------------------------------------------- 1 | package compose 2 | 3 | import ( 4 | "os" 5 | "testing" 6 | ) 7 | 8 | func TestIngestContainers(t *testing.T) { 9 | cf := DockerCompose{} 10 | 11 | f, err := os.Open("./test_fixtures/docker-compose.yaml") 12 | if err != nil { 13 | t.Errorf("Failed to open fixture: %s", err) 14 | } 15 | 16 | _, err = cf.IngestContainers(f) 17 | if err != nil { 18 | t.Errorf("Failed to ingest containers: %s", err) 19 | } 20 | } 21 | 22 | func TestEmitContainers(t *testing.T) { 23 | cf := DockerCompose{} 24 | 25 | f, err := os.Open("./test_fixtures/docker-compose.yaml") 26 | if err != nil { 27 | t.Errorf("Failed to open fixture: %s", err) 28 | } 29 | 30 | bp, err := cf.IngestContainers(f) 31 | if err != nil { 32 | t.Errorf("Failed to ingest containers: %s", err) 33 | } 34 | 35 | _, err = DockerCompose{}.EmitContainers(bp) 36 | if err != nil { 37 | t.Errorf("Failed to ingest containers: %s", err) 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /script/script_test.go: -------------------------------------------------------------------------------- 1 | package script 2 | 3 | import ( 4 | "bytes" 5 | "io/ioutil" 6 | "os" 7 | "testing" 8 | 9 | "github.com/micahhausler/container-tx/compose" 10 | "github.com/sergi/go-diff/diffmatchpatch" 11 | ) 12 | 13 | func TestEmitContainers(t *testing.T) { 14 | cf := compose.DockerCompose{} 15 | 16 | f, err := os.Open("./test_fixtures/docker-compose.yaml") 17 | if err != nil { 18 | t.Errorf("Failed to open fixture: %s", err) 19 | } 20 | 21 | bp, err := cf.IngestContainers(f) 22 | if err != nil { 23 | t.Errorf("Failed to ingest containers: %s", err) 24 | } 25 | 26 | got, err := Script{}.EmitContainers(bp) 27 | if err != nil { 28 | t.Errorf("Failed to emit containers: %s", err) 29 | } 30 | 31 | expected, err := ioutil.ReadFile("./test_fixtures/compose.out") 32 | if err != nil { 33 | t.Errorf("Failed to open file: %s", err) 34 | } 35 | 36 | if bytes.Compare(got, expected) != 0 { 37 | diff := diffmatchpatch.New() 38 | diffs := diff.DiffMain(string(expected), string(got), false) 39 | t.Errorf("Input differs from output: %s", diff.PatchToText(diff.PatchMake(diffs))) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Micah Hausler 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /vendor/github.com/stretchrcom/testify/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell 2 | 3 | Please consider promoting this project if you find it useful. 4 | 5 | Permission is hereby granted, free of charge, to any person 6 | obtaining a copy of this software and associated documentation 7 | files (the "Software"), to deal in the Software without restriction, 8 | including without limitation the rights to use, copy, modify, merge, 9 | publish, distribute, sublicense, and/or sell copies of the Software, 10 | and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included 14 | in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 20 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT 21 | OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 22 | OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /vendor/vendor.json: -------------------------------------------------------------------------------- 1 | { 2 | "comment": "", 3 | "ignore": "", 4 | "package": [ 5 | { 6 | "checksumSHA1": "UCxv3FbbHHrmOX4dj4dswcfd6KM=", 7 | "path": "github.com/davecgh/go-spew/spew", 8 | "revision": "6cf5744a041a0022271cefed95ba843f6d87fd51", 9 | "revisionTime": "2016-08-16T17:40:47Z" 10 | }, 11 | { 12 | "checksumSHA1": "a2yC46a1qsJomgY6rb+FkTFiqmE=", 13 | "path": "github.com/davecgh/go-spew/spew/testdata", 14 | "revision": "6cf5744a041a0022271cefed95ba843f6d87fd51", 15 | "revisionTime": "2016-08-16T17:40:47Z" 16 | }, 17 | { 18 | "checksumSHA1": "RZOdTSZN/PgcTqko5LzIAzw+UT4=", 19 | "path": "github.com/pmezard/go-difflib/difflib", 20 | "revision": "792786c7400a136282c1664665ae0a8db921c6c2", 21 | "revisionTime": "2016-01-10T10:55:54Z" 22 | }, 23 | { 24 | "checksumSHA1": "DYaXTB3rqugbG4/U1LapkcI5mz0=", 25 | "path": "github.com/stretchrcom/testify/assert", 26 | "revision": "d77da356e56a7428ad25149ca77381849a6a5232", 27 | "revisionTime": "2016-06-15T09:26:46Z" 28 | }, 29 | { 30 | "checksumSHA1": "YzHkxW3fGe5Oc5AVatDNn1g5Ung=", 31 | "path": "gopkg.in/check.v1", 32 | "revision": "4f90aeace3a26ad7021961c297b22c42160c7b25", 33 | "revisionTime": "2016-01-05T16:49:36Z" 34 | } 35 | ], 36 | "rootPath": "github.com/micahhausler/container-tx" 37 | } 38 | -------------------------------------------------------------------------------- /vendor/github.com/davecgh/go-spew/spew/dumpnocgo_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Dave Collins 2 | // 3 | // Permission to use, copy, modify, and distribute this software for any 4 | // purpose with or without fee is hereby granted, provided that the above 5 | // copyright notice and this permission notice appear in all copies. 6 | // 7 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 | // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 | // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 10 | // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 | // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 12 | // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 13 | // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 | 15 | // NOTE: Due to the following build constraints, this file will only be compiled 16 | // when either cgo is not supported or "-tags testcgo" is not added to the go 17 | // test command line. This file intentionally does not setup any cgo tests in 18 | // this scenario. 19 | // +build !cgo !testcgo 20 | 21 | package spew_test 22 | 23 | func addCgoDumpTests() { 24 | // Don't add any tests for cgo since this file is only compiled when 25 | // there should not be any cgo tests. 26 | } 27 | -------------------------------------------------------------------------------- /vendor/gopkg.in/check.v1/LICENSE: -------------------------------------------------------------------------------- 1 | Gocheck - A rich testing framework for Go 2 | 3 | Copyright (c) 2010-2013 Gustavo Niemeyer 4 | 5 | All rights reserved. 6 | 7 | Redistribution and use in source and binary forms, with or without 8 | modification, are permitted provided that the following conditions are met: 9 | 10 | 1. Redistributions of source code must retain the above copyright notice, this 11 | list of conditions and the following disclaimer. 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 20 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | -------------------------------------------------------------------------------- /vendor/github.com/pmezard/go-difflib/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013, Patrick Mezard 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | The names of its contributors may not be used to endorse or promote 14 | products derived from this software without specific prior written 15 | permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 18 | IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 19 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 20 | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 23 | TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 24 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 25 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 26 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /script/test_fixtures/compose.out: -------------------------------------------------------------------------------- 1 | ######## web ######## 2 | docker run \ 3 | --cpu-shares=200 \ 4 | --dns 8.8.8.8 \ 5 | --dns-search cluster.local \ 6 | --entrypoint=/bin/myapp \ 7 | --env PGHOST=database.cluster.local \ 8 | --env PGUSER=postgres \ 9 | --expose 8080 \ 10 | --hostname=webserver \ 11 | --label com.example.department=Finance \ 12 | --label com.example.description=Accounting webapp \ 13 | --label com.example.label-with-empty-value= \ 14 | --log-driver gelf \ 15 | --log-opt gelf-address=udp://127.0.0.1:12900 \ 16 | --log-opt tag=web \ 17 | --memory=67108864b \ 18 | --name web \ 19 | --net-alias some-network \ 20 | --net-alias other-network \ 21 | --net bridge \ 22 | --pid host \ 23 | --publish 127.0.0.1:5000:5000 \ 24 | --publish 5000:5000 \ 25 | --publish 5000 \ 26 | --publish 53:53/udp \ 27 | --privileged \ 28 | --user=root \ 29 | --volume /etc/ssl \ 30 | --volume /etc/ssl:/etc/ssl:ro \ 31 | --volume .:/code \ 32 | --volumes-from worker \ 33 | alpine \ 34 | -port 8080 35 | ######## worker ######## 36 | docker run \ 37 | --label com.example.department=Finance \ 38 | --label com.example.description=Accounting webapp \ 39 | --label com.example.label-with-empty-value= \ 40 | --name worker \ 41 | 42 | ######## worker2 ######## 43 | docker run \ 44 | --label com.example.department=Finance \ 45 | --label com.example.description=Accounting webapp \ 46 | --label com.example.label-with-empty-value= \ 47 | --name worker2 \ 48 | 49 | -------------------------------------------------------------------------------- /vendor/github.com/stretchrcom/testify/assert/doc.go: -------------------------------------------------------------------------------- 1 | // Package assert provides a set of comprehensive testing tools for use with the normal Go testing system. 2 | // 3 | // Example Usage 4 | // 5 | // The following is a complete example using assert in a standard test function: 6 | // import ( 7 | // "testing" 8 | // "github.com/stretchr/testify/assert" 9 | // ) 10 | // 11 | // func TestSomething(t *testing.T) { 12 | // 13 | // var a string = "Hello" 14 | // var b string = "Hello" 15 | // 16 | // assert.Equal(t, a, b, "The two words should be the same.") 17 | // 18 | // } 19 | // 20 | // if you assert many times, use the format below: 21 | // 22 | // import ( 23 | // "testing" 24 | // "github.com/stretchr/testify/assert" 25 | // ) 26 | // 27 | // func TestSomething(t *testing.T) { 28 | // assert := assert.New(t) 29 | // 30 | // var a string = "Hello" 31 | // var b string = "Hello" 32 | // 33 | // assert.Equal(a, b, "The two words should be the same.") 34 | // } 35 | // 36 | // Assertions 37 | // 38 | // Assertions allow you to easily write test code, and are global funcs in the `assert` package. 39 | // All assertion functions take, as the first argument, the `*testing.T` object provided by the 40 | // testing framework. This allows the assertion funcs to write the failings and other details to 41 | // the correct place. 42 | // 43 | // Every assertion function also takes an optional string message as the final argument, 44 | // allowing custom error messages to be appended to the message the assertion method outputs. 45 | package assert 46 | -------------------------------------------------------------------------------- /script/test_fixtures/docker-compose.yaml: -------------------------------------------------------------------------------- 1 | version: '2.0' 2 | services: 3 | web: 4 | entrypoint: /bin/myapp 5 | command: -port 8080 6 | cpu_shares: 200 7 | dns: 8 | - 8.8.8.8 9 | dns_search: 10 | - cluster.local 11 | environment: 12 | PGHOST: database.cluster.local 13 | PGUSER: postgres 14 | expose: 15 | - 8080 16 | hostname: webserver 17 | image: "alpine" 18 | labels: 19 | com.example.description: "Accounting webapp" 20 | com.example.department: "Finance" 21 | com.example.label-with-empty-value: "" 22 | logging: 23 | driver: gelf 24 | options: 25 | tag: web 26 | gelf-address: "udp://127.0.0.1:12900" 27 | mem_limit: 67108864 28 | networks: 29 | - some-network 30 | - other-network 31 | network_mode: bridge 32 | pid: host 33 | ports: 34 | - "127.0.0.1:5000:5000" 35 | - "5000:5000" 36 | - "5000" 37 | - "53:53/udp" 38 | privileged: true 39 | user: root 40 | volumes_from: 41 | - worker 42 | volumes: 43 | - "/etc/ssl" 44 | - "/etc/ssl:/etc/ssl:ro" 45 | - .:/code 46 | worker: 47 | build: 48 | context: ./app 49 | dockerfile: Dockerfile.worker 50 | args: 51 | env: prod 52 | labels: 53 | - com.example.description=Accounting webapp 54 | - com.example.department=Finance 55 | - com.example.label-with-empty-value 56 | worker2: 57 | build: "./app" 58 | labels: 59 | - com.example.description=Accounting webapp 60 | - com.example.department=Finance 61 | - com.example.label-with-empty-value 62 | -------------------------------------------------------------------------------- /compose/test_fixtures/docker-compose.yaml: -------------------------------------------------------------------------------- 1 | version: '2.0' 2 | services: 3 | web: 4 | entrypoint: /bin/myapp 5 | command: -port 8080 6 | cpu_shares: 200 7 | dns: 8 | - 8.8.8.8 9 | dns_search: 10 | - cluster.local 11 | environment: 12 | PGHOST: database.cluster.local 13 | PGUSER: postgres 14 | expose: 15 | - 8080 16 | hostname: webserver 17 | image: "alpine" 18 | labels: 19 | com.example.description: "Accounting webapp" 20 | com.example.department: "Finance" 21 | com.example.label-with-empty-value: "" 22 | logging: 23 | driver: gelf 24 | options: 25 | tag: web 26 | gelf-address: "udp://127.0.0.1:12900" 27 | mem_limit: 67108864 28 | networks: 29 | - some-network 30 | - other-network 31 | network_mode: bridge 32 | pid: host 33 | ports: 34 | - "127.0.0.1:5000:5000" 35 | - "5000:5000" 36 | - "5000" 37 | - "53:53/udp" 38 | privileged: true 39 | user: root 40 | volumes_from: 41 | - worker 42 | volumes: 43 | - "/etc/ssl" 44 | - "/etc/ssl:/etc/ssl:ro" 45 | - .:/code 46 | worker: 47 | build: 48 | context: ./app 49 | dockerfile: Dockerfile.worker 50 | args: 51 | env: prod 52 | labels: 53 | - com.example.description=Accounting webapp 54 | - com.example.department=Finance 55 | - com.example.label-with-empty-value 56 | worker2: 57 | build: "./app" 58 | labels: 59 | - com.example.description=Accounting webapp 60 | - com.example.department=Finance 61 | - com.example.label-with-empty-value 62 | -------------------------------------------------------------------------------- /vendor/github.com/davecgh/go-spew/spew/bypasssafe.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Dave Collins 2 | // 3 | // Permission to use, copy, modify, and distribute this software for any 4 | // purpose with or without fee is hereby granted, provided that the above 5 | // copyright notice and this permission notice appear in all copies. 6 | // 7 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 | // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 | // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 10 | // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 | // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 12 | // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 13 | // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 | 15 | // NOTE: Due to the following build constraints, this file will only be compiled 16 | // when either the code is running on Google App Engine or "-tags disableunsafe" 17 | // is added to the go build command line. 18 | // +build appengine disableunsafe 19 | 20 | package spew 21 | 22 | import "reflect" 23 | 24 | const ( 25 | // UnsafeDisabled is a build-time constant which specifies whether or 26 | // not access to the unsafe package is available. 27 | UnsafeDisabled = true 28 | ) 29 | 30 | // unsafeReflectValue typically converts the passed reflect.Value into a one 31 | // that bypasses the typical safety restrictions preventing access to 32 | // unaddressable and unexported data. However, doing this relies on access to 33 | // the unsafe package. This is a stub version which simply returns the passed 34 | // reflect.Value when the unsafe package is not available. 35 | func unsafeReflectValue(v reflect.Value) reflect.Value { 36 | return v 37 | } 38 | -------------------------------------------------------------------------------- /script/script.go: -------------------------------------------------------------------------------- 1 | package script 2 | 3 | import ( 4 | "bytes" 5 | "log" 6 | "strconv" 7 | "strings" 8 | "text/template" 9 | 10 | "github.com/micahhausler/container-tx/transform" 11 | ) 12 | 13 | func stringifyPortMapping(mapping transform.PortMapping) string { 14 | response := "" 15 | if len(mapping.HostIP) > 0 { 16 | response += mapping.HostIP 17 | response += ":" 18 | } 19 | if mapping.HostPort > 0 { 20 | response += strconv.Itoa(mapping.HostPort) 21 | } 22 | if mapping.HostPort > 0 && mapping.ContainerPort > 0 { 23 | response += ":" 24 | } 25 | if mapping.ContainerPort > 0 { 26 | response += strconv.Itoa(mapping.ContainerPort) 27 | } 28 | if strings.Compare(strings.ToLower(mapping.Protocol), "udp") == 0 { 29 | response += "/udp" 30 | } 31 | return response 32 | } 33 | 34 | func stringifyVolume(volume transform.IntermediateVolume) string { 35 | readOnly := "" 36 | if volume.ReadOnly { 37 | readOnly = "ro" 38 | } 39 | volStr := []string{volume.Host, volume.Container, readOnly} 40 | return strings.Trim(strings.Join(volStr, ":"), ":") 41 | } 42 | 43 | // Script represents a list of docker container run commands. 44 | // It implements OutputFormat 45 | type Script struct{} 46 | 47 | // EmitContainers satisfies OutputFormat so ECS tasks can be emitted 48 | func (s Script) EmitContainers(input *transform.PodData) ([]byte, error) { 49 | 50 | funcMap := template.FuncMap{ 51 | "stringifyPort": stringifyPortMapping, 52 | "stringifyVolume": stringifyVolume, 53 | } 54 | 55 | t := template.Must(template.New("container").Funcs(funcMap).Parse(dockerRunTemplate)) 56 | 57 | var buffer bytes.Buffer 58 | for _, c := range *input.Containers { 59 | err := t.Execute(&buffer, c) 60 | if err != nil { 61 | log.Println("Error executing template:", err) 62 | } 63 | } 64 | 65 | return buffer.Bytes(), nil 66 | } 67 | -------------------------------------------------------------------------------- /script/template.go: -------------------------------------------------------------------------------- 1 | package script 2 | 3 | const dockerRunTemplate = `######## {{ .Name }} ######## 4 | docker run \ 5 | {{ if .CPU }}--cpu-shares={{.CPU}} \ 6 | {{end -}} 7 | {{ range .DNS -}} 8 | --dns {{.}} \ 9 | {{end -}} 10 | {{ range .Domain -}} 11 | --dns-search {{.}} \ 12 | {{end -}} 13 | {{ if .Entrypoint }}--entrypoint={{.Entrypoint}} \ 14 | {{end -}} 15 | {{ range .EnvFile -}} 16 | --env-file {{.}} \ 17 | {{end -}} 18 | {{ range $key, $value := .Environment -}} 19 | --env {{$key}}={{$value}} \ 20 | {{end -}} 21 | {{ range .Expose -}} 22 | --expose {{.}} \ 23 | {{end -}} 24 | {{ if .Hostname }}--hostname={{.Hostname}} \ 25 | {{end -}} 26 | {{ range $key, $value := .Labels -}} 27 | --label {{$key}}={{$value}} \ 28 | {{end -}} 29 | {{ range .Links -}} 30 | --link {{.}} \ 31 | {{end -}} 32 | {{ if .Logging }}--log-driver {{.Logging.Driver}} \ 33 | {{ range $key, $value := .Logging.Options -}} 34 | --log-opt {{$key}}={{$value}} \ 35 | {{end -}} 36 | {{end -}} 37 | {{ if .Memory }}--memory={{.Memory}}b \ 38 | {{end -}} 39 | {{ if .Name }}--name {{.Name}} \ 40 | {{end -}} 41 | {{ range .Network -}} 42 | --net-alias {{.}} \ 43 | {{end -}} 44 | {{ if .NetworkMode }}--net {{.NetworkMode}} \ 45 | {{end -}} 46 | {{ if .Pid }}--pid {{.Pid}} \ 47 | {{end -}} 48 | {{if .PortMappings}}{{ range .PortMappings -}} 49 | --publish {{ stringifyPort . }} \ 50 | {{end}}{{end -}} 51 | {{ if .Privileged }}--privileged \ 52 | {{end -}} 53 | {{ if .StopSignal }}--stop-signal={{.StopSignal}} \ 54 | {{end -}} 55 | {{ if .User }}--user={{.User}} \ 56 | {{end -}} 57 | {{ if .Volumes }}{{ range .Volumes -}} 58 | --volume {{ stringifyVolume . }} \ 59 | {{end}}{{end -}} 60 | {{ range .VolumesFrom -}} 61 | --volumes-from {{ . }} \ 62 | {{end -}} 63 | {{ if .WorkDir }}--workdir={{.WorkDir}} \ 64 | {{end -}} 65 | {{.Image }} {{- with .Command }} \ 66 | {{.}} 67 | {{- end }} 68 | ` 69 | -------------------------------------------------------------------------------- /vendor/gopkg.in/check.v1/bootstrap_test.go: -------------------------------------------------------------------------------- 1 | // These initial tests are for bootstrapping. They verify that we can 2 | // basically use the testing infrastructure itself to check if the test 3 | // system is working. 4 | // 5 | // These tests use will break down the test runner badly in case of 6 | // errors because if they simply fail, we can't be sure the developer 7 | // will ever see anything (because failing means the failing system 8 | // somehow isn't working! :-) 9 | // 10 | // Do not assume *any* internal functionality works as expected besides 11 | // what's actually tested here. 12 | 13 | package check_test 14 | 15 | import ( 16 | "fmt" 17 | "gopkg.in/check.v1" 18 | "strings" 19 | ) 20 | 21 | type BootstrapS struct{} 22 | 23 | var boostrapS = check.Suite(&BootstrapS{}) 24 | 25 | func (s *BootstrapS) TestCountSuite(c *check.C) { 26 | suitesRun += 1 27 | } 28 | 29 | func (s *BootstrapS) TestFailedAndFail(c *check.C) { 30 | if c.Failed() { 31 | critical("c.Failed() must be false first!") 32 | } 33 | c.Fail() 34 | if !c.Failed() { 35 | critical("c.Fail() didn't put the test in a failed state!") 36 | } 37 | c.Succeed() 38 | } 39 | 40 | func (s *BootstrapS) TestFailedAndSucceed(c *check.C) { 41 | c.Fail() 42 | c.Succeed() 43 | if c.Failed() { 44 | critical("c.Succeed() didn't put the test back in a non-failed state") 45 | } 46 | } 47 | 48 | func (s *BootstrapS) TestLogAndGetTestLog(c *check.C) { 49 | c.Log("Hello there!") 50 | log := c.GetTestLog() 51 | if log != "Hello there!\n" { 52 | critical(fmt.Sprintf("Log() or GetTestLog() is not working! Got: %#v", log)) 53 | } 54 | } 55 | 56 | func (s *BootstrapS) TestLogfAndGetTestLog(c *check.C) { 57 | c.Logf("Hello %v", "there!") 58 | log := c.GetTestLog() 59 | if log != "Hello there!\n" { 60 | critical(fmt.Sprintf("Logf() or GetTestLog() is not working! Got: %#v", log)) 61 | } 62 | } 63 | 64 | func (s *BootstrapS) TestRunShowsErrors(c *check.C) { 65 | output := String{} 66 | check.Run(&FailHelper{}, &check.RunConf{Output: &output}) 67 | if strings.Index(output.value, "Expected failure!") == -1 { 68 | critical(fmt.Sprintf("RunWithWriter() output did not contain the "+ 69 | "expected failure! Got: %#v", 70 | output.value)) 71 | } 72 | } 73 | 74 | func (s *BootstrapS) TestRunDoesntShowSuccesses(c *check.C) { 75 | output := String{} 76 | check.Run(&SuccessHelper{}, &check.RunConf{Output: &output}) 77 | if strings.Index(output.value, "Expected success!") != -1 { 78 | critical(fmt.Sprintf("RunWithWriter() output contained a successful "+ 79 | "test! Got: %#v", 80 | output.value)) 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /vendor/gopkg.in/check.v1/reporter.go: -------------------------------------------------------------------------------- 1 | package check 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "sync" 7 | ) 8 | 9 | // ----------------------------------------------------------------------- 10 | // Output writer manages atomic output writing according to settings. 11 | 12 | type outputWriter struct { 13 | m sync.Mutex 14 | writer io.Writer 15 | wroteCallProblemLast bool 16 | Stream bool 17 | Verbose bool 18 | } 19 | 20 | func newOutputWriter(writer io.Writer, stream, verbose bool) *outputWriter { 21 | return &outputWriter{writer: writer, Stream: stream, Verbose: verbose} 22 | } 23 | 24 | func (ow *outputWriter) Write(content []byte) (n int, err error) { 25 | ow.m.Lock() 26 | n, err = ow.writer.Write(content) 27 | ow.m.Unlock() 28 | return 29 | } 30 | 31 | func (ow *outputWriter) WriteCallStarted(label string, c *C) { 32 | if ow.Stream { 33 | header := renderCallHeader(label, c, "", "\n") 34 | ow.m.Lock() 35 | ow.writer.Write([]byte(header)) 36 | ow.m.Unlock() 37 | } 38 | } 39 | 40 | func (ow *outputWriter) WriteCallProblem(label string, c *C) { 41 | var prefix string 42 | if !ow.Stream { 43 | prefix = "\n-----------------------------------" + 44 | "-----------------------------------\n" 45 | } 46 | header := renderCallHeader(label, c, prefix, "\n\n") 47 | ow.m.Lock() 48 | ow.wroteCallProblemLast = true 49 | ow.writer.Write([]byte(header)) 50 | if !ow.Stream { 51 | c.logb.WriteTo(ow.writer) 52 | } 53 | ow.m.Unlock() 54 | } 55 | 56 | func (ow *outputWriter) WriteCallSuccess(label string, c *C) { 57 | if ow.Stream || (ow.Verbose && c.kind == testKd) { 58 | // TODO Use a buffer here. 59 | var suffix string 60 | if c.reason != "" { 61 | suffix = " (" + c.reason + ")" 62 | } 63 | if c.status() == succeededSt { 64 | suffix += "\t" + c.timerString() 65 | } 66 | suffix += "\n" 67 | if ow.Stream { 68 | suffix += "\n" 69 | } 70 | header := renderCallHeader(label, c, "", suffix) 71 | ow.m.Lock() 72 | // Resist temptation of using line as prefix above due to race. 73 | if !ow.Stream && ow.wroteCallProblemLast { 74 | header = "\n-----------------------------------" + 75 | "-----------------------------------\n" + 76 | header 77 | } 78 | ow.wroteCallProblemLast = false 79 | ow.writer.Write([]byte(header)) 80 | ow.m.Unlock() 81 | } 82 | } 83 | 84 | func renderCallHeader(label string, c *C, prefix, suffix string) string { 85 | pc := c.method.PC() 86 | return fmt.Sprintf("%s%s: %s: %s%s", prefix, label, niceFuncPath(pc), 87 | niceFuncName(pc), suffix) 88 | } 89 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "os" 7 | 8 | "github.com/micahhausler/container-tx/compose" 9 | "github.com/micahhausler/container-tx/ecs" 10 | "github.com/micahhausler/container-tx/script" 11 | "github.com/micahhausler/container-tx/transform" 12 | flag "github.com/ogier/pflag" 13 | ) 14 | 15 | const versionNum = "0.0.1" 16 | 17 | var version = flag.Bool("version", false, "print version and exit") 18 | 19 | var inputType = flag.StringP("input", "i", "compose", "The format of the input.") 20 | var outputType = flag.StringP("output", "o", "ecs", "The format of the output.") 21 | 22 | var inputMap = map[string]transform.InputFormat{ 23 | "compose": compose.DockerCompose{}, 24 | "ecs": ecs.Task{}, 25 | } 26 | 27 | var outputMap = map[string]transform.OutputFormat{ 28 | "compose": compose.DockerCompose{}, 29 | "ecs": ecs.Task{}, 30 | "cli": script.Script{}, 31 | } 32 | 33 | func main() { 34 | inputKeys := []string{} 35 | for it := range inputMap { 36 | inputKeys = append(inputKeys, it) 37 | } 38 | outputKeys := []string{} 39 | for it := range outputMap { 40 | outputKeys = append(outputKeys, it) 41 | } 42 | 43 | flag.Usage = func() { 44 | fmt.Fprintf(os.Stderr, "Usage of %s: [flags] \n\n", os.Args[0]) 45 | fmt.Fprintf(os.Stderr, " Valid input types: %s\n", inputKeys) 46 | fmt.Fprintf(os.Stderr, " Valid output types: %s\n\n", outputKeys) 47 | fmt.Fprint(os.Stderr, " If no file is specified, defaults to STDIN\n\n") 48 | flag.PrintDefaults() 49 | os.Exit(0) 50 | } 51 | 52 | flag.Parse() 53 | 54 | if *version { 55 | fmt.Printf("container-tx %s\n", versionNum) 56 | os.Exit(0) 57 | } 58 | 59 | var f io.ReadCloser 60 | if fileName := flag.Arg(0); len(fileName) > 0 { 61 | var err error 62 | f, err = os.Open(fileName) 63 | if err != nil { 64 | fmt.Printf("Error opening file: %s \n", err) 65 | os.Exit(1) 66 | } 67 | } else { 68 | f = os.Stdin 69 | } 70 | 71 | input, ok := inputMap[*inputType] 72 | if !ok { 73 | fmt.Printf("Input type %s invalid: must be one of %s\n", *inputType, inputKeys) 74 | os.Exit(1) 75 | } 76 | 77 | outputFormat, ok := outputMap[*outputType] 78 | if !ok { 79 | fmt.Printf("Output type %s invalid: must be one of %s\n", *outputType, outputKeys) 80 | os.Exit(1) 81 | } 82 | 83 | basePod, err := input.IngestContainers(f) 84 | if err != nil { 85 | fmt.Printf("Error ingesting file: %s \n", err) 86 | os.Exit(1) 87 | } 88 | resp, err := outputFormat.EmitContainers(basePod) 89 | 90 | if err != nil { 91 | fmt.Printf("Error converting file: %s \n", err) 92 | os.Exit(1) 93 | } 94 | fmt.Println(string(resp)) 95 | } 96 | -------------------------------------------------------------------------------- /vendor/github.com/davecgh/go-spew/spew/internal_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013 Dave Collins 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | /* 18 | This test file is part of the spew package rather than than the spew_test 19 | package because it needs access to internals to properly test certain cases 20 | which are not possible via the public interface since they should never happen. 21 | */ 22 | 23 | package spew 24 | 25 | import ( 26 | "bytes" 27 | "reflect" 28 | "testing" 29 | ) 30 | 31 | // dummyFmtState implements a fake fmt.State to use for testing invalid 32 | // reflect.Value handling. This is necessary because the fmt package catches 33 | // invalid values before invoking the formatter on them. 34 | type dummyFmtState struct { 35 | bytes.Buffer 36 | } 37 | 38 | func (dfs *dummyFmtState) Flag(f int) bool { 39 | if f == int('+') { 40 | return true 41 | } 42 | return false 43 | } 44 | 45 | func (dfs *dummyFmtState) Precision() (int, bool) { 46 | return 0, false 47 | } 48 | 49 | func (dfs *dummyFmtState) Width() (int, bool) { 50 | return 0, false 51 | } 52 | 53 | // TestInvalidReflectValue ensures the dump and formatter code handles an 54 | // invalid reflect value properly. This needs access to internal state since it 55 | // should never happen in real code and therefore can't be tested via the public 56 | // API. 57 | func TestInvalidReflectValue(t *testing.T) { 58 | i := 1 59 | 60 | // Dump invalid reflect value. 61 | v := new(reflect.Value) 62 | buf := new(bytes.Buffer) 63 | d := dumpState{w: buf, cs: &Config} 64 | d.dump(*v) 65 | s := buf.String() 66 | want := "" 67 | if s != want { 68 | t.Errorf("InvalidReflectValue #%d\n got: %s want: %s", i, s, want) 69 | } 70 | i++ 71 | 72 | // Formatter invalid reflect value. 73 | buf2 := new(dummyFmtState) 74 | f := formatState{value: *v, cs: &Config, fs: buf2} 75 | f.format(*v) 76 | s = buf2.String() 77 | want = "" 78 | if s != want { 79 | t.Errorf("InvalidReflectValue #%d got: %s want: %s", i, s, want) 80 | } 81 | } 82 | 83 | // SortValues makes the internal sortValues function available to the test 84 | // package. 85 | func SortValues(values []reflect.Value, cs *ConfigState) { 86 | sortValues(values, cs) 87 | } 88 | -------------------------------------------------------------------------------- /vendor/gopkg.in/check.v1/printer_test.go: -------------------------------------------------------------------------------- 1 | package check_test 2 | 3 | import ( 4 | . "gopkg.in/check.v1" 5 | ) 6 | 7 | var _ = Suite(&PrinterS{}) 8 | 9 | type PrinterS struct{} 10 | 11 | func (s *PrinterS) TestCountSuite(c *C) { 12 | suitesRun += 1 13 | } 14 | 15 | var printTestFuncLine int 16 | 17 | func init() { 18 | printTestFuncLine = getMyLine() + 3 19 | } 20 | 21 | func printTestFunc() { 22 | println(1) // Comment1 23 | if 2 == 2 { // Comment2 24 | println(3) // Comment3 25 | } 26 | switch 5 { 27 | case 6: println(6) // Comment6 28 | println(7) 29 | } 30 | switch interface{}(9).(type) {// Comment9 31 | case int: println(10) 32 | println(11) 33 | } 34 | select { 35 | case <-(chan bool)(nil): println(14) 36 | println(15) 37 | default: println(16) 38 | println(17) 39 | } 40 | println(19, 41 | 20) 42 | _ = func() { println(21) 43 | println(22) 44 | } 45 | println(24, func() { 46 | println(25) 47 | }) 48 | // Leading comment 49 | // with multiple lines. 50 | println(29) // Comment29 51 | } 52 | 53 | var printLineTests = []struct { 54 | line int 55 | output string 56 | }{ 57 | {1, "println(1) // Comment1"}, 58 | {2, "if 2 == 2 { // Comment2\n ...\n}"}, 59 | {3, "println(3) // Comment3"}, 60 | {5, "switch 5 {\n...\n}"}, 61 | {6, "case 6:\n println(6) // Comment6\n ..."}, 62 | {7, "println(7)"}, 63 | {9, "switch interface{}(9).(type) { // Comment9\n...\n}"}, 64 | {10, "case int:\n println(10)\n ..."}, 65 | {14, "case <-(chan bool)(nil):\n println(14)\n ..."}, 66 | {15, "println(15)"}, 67 | {16, "default:\n println(16)\n ..."}, 68 | {17, "println(17)"}, 69 | {19, "println(19,\n 20)"}, 70 | {20, "println(19,\n 20)"}, 71 | {21, "_ = func() {\n println(21)\n println(22)\n}"}, 72 | {22, "println(22)"}, 73 | {24, "println(24, func() {\n println(25)\n})"}, 74 | {25, "println(25)"}, 75 | {26, "println(24, func() {\n println(25)\n})"}, 76 | {29, "// Leading comment\n// with multiple lines.\nprintln(29) // Comment29"}, 77 | } 78 | 79 | func (s *PrinterS) TestPrintLine(c *C) { 80 | for _, test := range printLineTests { 81 | output, err := PrintLine("printer_test.go", printTestFuncLine+test.line) 82 | c.Assert(err, IsNil) 83 | c.Assert(output, Equals, test.output) 84 | } 85 | } 86 | 87 | var indentTests = []struct { 88 | in, out string 89 | }{ 90 | {"", ""}, 91 | {"\n", "\n"}, 92 | {"a", ">>>a"}, 93 | {"a\n", ">>>a\n"}, 94 | {"a\nb", ">>>a\n>>>b"}, 95 | {" ", ">>> "}, 96 | } 97 | 98 | func (s *PrinterS) TestIndent(c *C) { 99 | for _, test := range indentTests { 100 | out := Indent(test.in, ">>>") 101 | c.Assert(out, Equals, test.out) 102 | } 103 | 104 | } 105 | -------------------------------------------------------------------------------- /vendor/gopkg.in/check.v1/benchmark_test.go: -------------------------------------------------------------------------------- 1 | // These tests verify the test running logic. 2 | 3 | package check_test 4 | 5 | import ( 6 | "time" 7 | . "gopkg.in/check.v1" 8 | ) 9 | 10 | var benchmarkS = Suite(&BenchmarkS{}) 11 | 12 | type BenchmarkS struct{} 13 | 14 | func (s *BenchmarkS) TestCountSuite(c *C) { 15 | suitesRun += 1 16 | } 17 | 18 | func (s *BenchmarkS) TestBasicTestTiming(c *C) { 19 | helper := FixtureHelper{sleepOn: "Test1", sleep: 1000000 * time.Nanosecond} 20 | output := String{} 21 | runConf := RunConf{Output: &output, Verbose: true} 22 | Run(&helper, &runConf) 23 | 24 | expected := "PASS: check_test\\.go:[0-9]+: FixtureHelper\\.Test1\t0\\.001s\n" + 25 | "PASS: check_test\\.go:[0-9]+: FixtureHelper\\.Test2\t0\\.000s\n" 26 | c.Assert(output.value, Matches, expected) 27 | } 28 | 29 | func (s *BenchmarkS) TestStreamTestTiming(c *C) { 30 | helper := FixtureHelper{sleepOn: "SetUpSuite", sleep: 1000000 * time.Nanosecond} 31 | output := String{} 32 | runConf := RunConf{Output: &output, Stream: true} 33 | Run(&helper, &runConf) 34 | 35 | expected := "(?s).*\nPASS: check_test\\.go:[0-9]+: FixtureHelper\\.SetUpSuite\t *0\\.001s\n.*" 36 | c.Assert(output.value, Matches, expected) 37 | } 38 | 39 | func (s *BenchmarkS) TestBenchmark(c *C) { 40 | helper := FixtureHelper{sleep: 100000} 41 | output := String{} 42 | runConf := RunConf{ 43 | Output: &output, 44 | Benchmark: true, 45 | BenchmarkTime: 10000000, 46 | Filter: "Benchmark1", 47 | } 48 | Run(&helper, &runConf) 49 | c.Check(helper.calls[0], Equals, "SetUpSuite") 50 | c.Check(helper.calls[1], Equals, "SetUpTest") 51 | c.Check(helper.calls[2], Equals, "Benchmark1") 52 | c.Check(helper.calls[3], Equals, "TearDownTest") 53 | c.Check(helper.calls[4], Equals, "SetUpTest") 54 | c.Check(helper.calls[5], Equals, "Benchmark1") 55 | c.Check(helper.calls[6], Equals, "TearDownTest") 56 | // ... and more. 57 | 58 | expected := "PASS: check_test\\.go:[0-9]+: FixtureHelper\\.Benchmark1\t *100\t *[12][0-9]{5} ns/op\n" 59 | c.Assert(output.value, Matches, expected) 60 | } 61 | 62 | func (s *BenchmarkS) TestBenchmarkBytes(c *C) { 63 | helper := FixtureHelper{sleep: 100000} 64 | output := String{} 65 | runConf := RunConf{ 66 | Output: &output, 67 | Benchmark: true, 68 | BenchmarkTime: 10000000, 69 | Filter: "Benchmark2", 70 | } 71 | Run(&helper, &runConf) 72 | 73 | expected := "PASS: check_test\\.go:[0-9]+: FixtureHelper\\.Benchmark2\t *100\t *[12][0-9]{5} ns/op\t *[4-9]\\.[0-9]{2} MB/s\n" 74 | c.Assert(output.value, Matches, expected) 75 | } 76 | 77 | func (s *BenchmarkS) TestBenchmarkMem(c *C) { 78 | helper := FixtureHelper{sleep: 100000} 79 | output := String{} 80 | runConf := RunConf{ 81 | Output: &output, 82 | Benchmark: true, 83 | BenchmarkMem: true, 84 | BenchmarkTime: 10000000, 85 | Filter: "Benchmark3", 86 | } 87 | Run(&helper, &runConf) 88 | 89 | expected := "PASS: check_test\\.go:[0-9]+: FixtureHelper\\.Benchmark3\t *100\t *[12][0-9]{5} ns/op\t *[0-9]+ B/op\t *[1-9] allocs/op\n" 90 | c.Assert(output.value, Matches, expected) 91 | } 92 | -------------------------------------------------------------------------------- /vendor/github.com/davecgh/go-spew/spew/testdata/dumpcgo.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Dave Collins 2 | // 3 | // Permission to use, copy, modify, and distribute this software for any 4 | // purpose with or without fee is hereby granted, provided that the above 5 | // copyright notice and this permission notice appear in all copies. 6 | // 7 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 | // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 | // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 10 | // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 | // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 12 | // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 13 | // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 | 15 | // NOTE: Due to the following build constraints, this file will only be compiled 16 | // when both cgo is supported and "-tags testcgo" is added to the go test 17 | // command line. This code should really only be in the dumpcgo_test.go file, 18 | // but unfortunately Go will not allow cgo in test files, so this is a 19 | // workaround to allow cgo types to be tested. This configuration is used 20 | // because spew itself does not require cgo to run even though it does handle 21 | // certain cgo types specially. Rather than forcing all clients to require cgo 22 | // and an external C compiler just to run the tests, this scheme makes them 23 | // optional. 24 | // +build cgo,testcgo 25 | 26 | package testdata 27 | 28 | /* 29 | #include 30 | typedef unsigned char custom_uchar_t; 31 | 32 | char *ncp = 0; 33 | char *cp = "test"; 34 | char ca[6] = {'t', 'e', 's', 't', '2', '\0'}; 35 | unsigned char uca[6] = {'t', 'e', 's', 't', '3', '\0'}; 36 | signed char sca[6] = {'t', 'e', 's', 't', '4', '\0'}; 37 | uint8_t ui8ta[6] = {'t', 'e', 's', 't', '5', '\0'}; 38 | custom_uchar_t tuca[6] = {'t', 'e', 's', 't', '6', '\0'}; 39 | */ 40 | import "C" 41 | 42 | // GetCgoNullCharPointer returns a null char pointer via cgo. This is only 43 | // used for tests. 44 | func GetCgoNullCharPointer() interface{} { 45 | return C.ncp 46 | } 47 | 48 | // GetCgoCharPointer returns a char pointer via cgo. This is only used for 49 | // tests. 50 | func GetCgoCharPointer() interface{} { 51 | return C.cp 52 | } 53 | 54 | // GetCgoCharArray returns a char array via cgo and the array's len and cap. 55 | // This is only used for tests. 56 | func GetCgoCharArray() (interface{}, int, int) { 57 | return C.ca, len(C.ca), cap(C.ca) 58 | } 59 | 60 | // GetCgoUnsignedCharArray returns an unsigned char array via cgo and the 61 | // array's len and cap. This is only used for tests. 62 | func GetCgoUnsignedCharArray() (interface{}, int, int) { 63 | return C.uca, len(C.uca), cap(C.uca) 64 | } 65 | 66 | // GetCgoSignedCharArray returns a signed char array via cgo and the array's len 67 | // and cap. This is only used for tests. 68 | func GetCgoSignedCharArray() (interface{}, int, int) { 69 | return C.sca, len(C.sca), cap(C.sca) 70 | } 71 | 72 | // GetCgoUint8tArray returns a uint8_t array via cgo and the array's len and 73 | // cap. This is only used for tests. 74 | func GetCgoUint8tArray() (interface{}, int, int) { 75 | return C.ui8ta, len(C.ui8ta), cap(C.ui8ta) 76 | } 77 | 78 | // GetCgoTypdefedUnsignedCharArray returns a typedefed unsigned char array via 79 | // cgo and the array's len and cap. This is only used for tests. 80 | func GetCgoTypdefedUnsignedCharArray() (interface{}, int, int) { 81 | return C.tuca, len(C.tuca), cap(C.tuca) 82 | } 83 | -------------------------------------------------------------------------------- /vendor/github.com/davecgh/go-spew/spew/internalunsafe_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2015 Dave Collins 2 | 3 | // Permission to use, copy, modify, and distribute this software for any 4 | // purpose with or without fee is hereby granted, provided that the above 5 | // copyright notice and this permission notice appear in all copies. 6 | 7 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 | // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 | // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 10 | // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 | // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 12 | // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 13 | // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 | 15 | // NOTE: Due to the following build constraints, this file will only be compiled 16 | // when the code is not running on Google App Engine and "-tags disableunsafe" 17 | // is not added to the go build command line. 18 | // +build !appengine,!disableunsafe 19 | 20 | /* 21 | This test file is part of the spew package rather than than the spew_test 22 | package because it needs access to internals to properly test certain cases 23 | which are not possible via the public interface since they should never happen. 24 | */ 25 | 26 | package spew 27 | 28 | import ( 29 | "bytes" 30 | "reflect" 31 | "testing" 32 | "unsafe" 33 | ) 34 | 35 | // changeKind uses unsafe to intentionally change the kind of a reflect.Value to 36 | // the maximum kind value which does not exist. This is needed to test the 37 | // fallback code which punts to the standard fmt library for new types that 38 | // might get added to the language. 39 | func changeKind(v *reflect.Value, readOnly bool) { 40 | rvf := (*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(v)) + offsetFlag)) 41 | *rvf = *rvf | ((1<= http.StatusOK && code <= http.StatusPartialContent 34 | } 35 | 36 | // HTTPRedirect asserts that a specified handler returns a redirect status code. 37 | // 38 | // assert.HTTPRedirect(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} 39 | // 40 | // Returns whether the assertion was successful (true) or not (false). 41 | func HTTPRedirect(t TestingT, handler http.HandlerFunc, method, url string, values url.Values) bool { 42 | code := httpCode(handler, method, url, values) 43 | if code == -1 { 44 | return false 45 | } 46 | return code >= http.StatusMultipleChoices && code <= http.StatusTemporaryRedirect 47 | } 48 | 49 | // HTTPError asserts that a specified handler returns an error status code. 50 | // 51 | // assert.HTTPError(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} 52 | // 53 | // Returns whether the assertion was successful (true) or not (false). 54 | func HTTPError(t TestingT, handler http.HandlerFunc, method, url string, values url.Values) bool { 55 | code := httpCode(handler, method, url, values) 56 | if code == -1 { 57 | return false 58 | } 59 | return code >= http.StatusBadRequest 60 | } 61 | 62 | // HTTPBody is a helper that returns HTTP body of the response. It returns 63 | // empty string if building a new request fails. 64 | func HTTPBody(handler http.HandlerFunc, method, url string, values url.Values) string { 65 | w := httptest.NewRecorder() 66 | req, err := http.NewRequest(method, url+"?"+values.Encode(), nil) 67 | if err != nil { 68 | return "" 69 | } 70 | handler(w, req) 71 | return w.Body.String() 72 | } 73 | 74 | // HTTPBodyContains asserts that a specified handler returns a 75 | // body that contains a string. 76 | // 77 | // assert.HTTPBodyContains(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky") 78 | // 79 | // Returns whether the assertion was successful (true) or not (false). 80 | func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}) bool { 81 | body := HTTPBody(handler, method, url, values) 82 | 83 | contains := strings.Contains(body, fmt.Sprint(str)) 84 | if !contains { 85 | Fail(t, fmt.Sprintf("Expected response body for \"%s\" to contain \"%s\" but found \"%s\"", url+"?"+values.Encode(), str, body)) 86 | } 87 | 88 | return contains 89 | } 90 | 91 | // HTTPBodyNotContains asserts that a specified handler returns a 92 | // body that does not contain a string. 93 | // 94 | // assert.HTTPBodyNotContains(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky") 95 | // 96 | // Returns whether the assertion was successful (true) or not (false). 97 | func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}) bool { 98 | body := HTTPBody(handler, method, url, values) 99 | 100 | contains := strings.Contains(body, fmt.Sprint(str)) 101 | if contains { 102 | Fail(t, "Expected response body for %s to NOT contain \"%s\" but found \"%s\"", url+"?"+values.Encode(), str, body) 103 | } 104 | 105 | return !contains 106 | } 107 | -------------------------------------------------------------------------------- /vendor/github.com/davecgh/go-spew/spew/dumpcgo_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Dave Collins 2 | // 3 | // Permission to use, copy, modify, and distribute this software for any 4 | // purpose with or without fee is hereby granted, provided that the above 5 | // copyright notice and this permission notice appear in all copies. 6 | // 7 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 | // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 | // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 10 | // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 | // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 12 | // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 13 | // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 | 15 | // NOTE: Due to the following build constraints, this file will only be compiled 16 | // when both cgo is supported and "-tags testcgo" is added to the go test 17 | // command line. This means the cgo tests are only added (and hence run) when 18 | // specifially requested. This configuration is used because spew itself 19 | // does not require cgo to run even though it does handle certain cgo types 20 | // specially. Rather than forcing all clients to require cgo and an external 21 | // C compiler just to run the tests, this scheme makes them optional. 22 | // +build cgo,testcgo 23 | 24 | package spew_test 25 | 26 | import ( 27 | "fmt" 28 | 29 | "github.com/davecgh/go-spew/spew/testdata" 30 | ) 31 | 32 | func addCgoDumpTests() { 33 | // C char pointer. 34 | v := testdata.GetCgoCharPointer() 35 | nv := testdata.GetCgoNullCharPointer() 36 | pv := &v 37 | vcAddr := fmt.Sprintf("%p", v) 38 | vAddr := fmt.Sprintf("%p", pv) 39 | pvAddr := fmt.Sprintf("%p", &pv) 40 | vt := "*testdata._Ctype_char" 41 | vs := "116" 42 | addDumpTest(v, "("+vt+")("+vcAddr+")("+vs+")\n") 43 | addDumpTest(pv, "(*"+vt+")("+vAddr+"->"+vcAddr+")("+vs+")\n") 44 | addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+"->"+vcAddr+")("+vs+")\n") 45 | addDumpTest(nv, "("+vt+")()\n") 46 | 47 | // C char array. 48 | v2, v2l, v2c := testdata.GetCgoCharArray() 49 | v2Len := fmt.Sprintf("%d", v2l) 50 | v2Cap := fmt.Sprintf("%d", v2c) 51 | v2t := "[6]testdata._Ctype_char" 52 | v2s := "(len=" + v2Len + " cap=" + v2Cap + ") " + 53 | "{\n 00000000 74 65 73 74 32 00 " + 54 | " |test2.|\n}" 55 | addDumpTest(v2, "("+v2t+") "+v2s+"\n") 56 | 57 | // C unsigned char array. 58 | v3, v3l, v3c := testdata.GetCgoUnsignedCharArray() 59 | v3Len := fmt.Sprintf("%d", v3l) 60 | v3Cap := fmt.Sprintf("%d", v3c) 61 | v3t := "[6]testdata._Ctype_unsignedchar" 62 | v3t2 := "[6]testdata._Ctype_uchar" 63 | v3s := "(len=" + v3Len + " cap=" + v3Cap + ") " + 64 | "{\n 00000000 74 65 73 74 33 00 " + 65 | " |test3.|\n}" 66 | addDumpTest(v3, "("+v3t+") "+v3s+"\n", "("+v3t2+") "+v3s+"\n") 67 | 68 | // C signed char array. 69 | v4, v4l, v4c := testdata.GetCgoSignedCharArray() 70 | v4Len := fmt.Sprintf("%d", v4l) 71 | v4Cap := fmt.Sprintf("%d", v4c) 72 | v4t := "[6]testdata._Ctype_schar" 73 | v4t2 := "testdata._Ctype_schar" 74 | v4s := "(len=" + v4Len + " cap=" + v4Cap + ") " + 75 | "{\n (" + v4t2 + ") 116,\n (" + v4t2 + ") 101,\n (" + v4t2 + 76 | ") 115,\n (" + v4t2 + ") 116,\n (" + v4t2 + ") 52,\n (" + v4t2 + 77 | ") 0\n}" 78 | addDumpTest(v4, "("+v4t+") "+v4s+"\n") 79 | 80 | // C uint8_t array. 81 | v5, v5l, v5c := testdata.GetCgoUint8tArray() 82 | v5Len := fmt.Sprintf("%d", v5l) 83 | v5Cap := fmt.Sprintf("%d", v5c) 84 | v5t := "[6]testdata._Ctype_uint8_t" 85 | v5s := "(len=" + v5Len + " cap=" + v5Cap + ") " + 86 | "{\n 00000000 74 65 73 74 35 00 " + 87 | " |test5.|\n}" 88 | addDumpTest(v5, "("+v5t+") "+v5s+"\n") 89 | 90 | // C typedefed unsigned char array. 91 | v6, v6l, v6c := testdata.GetCgoTypdefedUnsignedCharArray() 92 | v6Len := fmt.Sprintf("%d", v6l) 93 | v6Cap := fmt.Sprintf("%d", v6c) 94 | v6t := "[6]testdata._Ctype_custom_uchar_t" 95 | v6s := "(len=" + v6Len + " cap=" + v6Cap + ") " + 96 | "{\n 00000000 74 65 73 74 36 00 " + 97 | " |test6.|\n}" 98 | addDumpTest(v6, "("+v6t+") "+v6s+"\n") 99 | } 100 | -------------------------------------------------------------------------------- /transform/base.go: -------------------------------------------------------------------------------- 1 | package transform 2 | 3 | import ( 4 | "io" 5 | "strings" 6 | ) 7 | 8 | // Logging is an intermediate representation for logging information 9 | type Logging struct { 10 | Driver string 11 | Options map[string]string 12 | } 13 | 14 | // PortMapping is an intermediate representation for port mapping information 15 | type PortMapping struct { 16 | HostIP string 17 | HostPort int 18 | ContainerIP string 19 | ContainerPort int 20 | Protocol string 21 | Name string 22 | } 23 | 24 | // PortMappings is a composite type for slices of PortMapping 25 | type PortMappings []PortMapping 26 | 27 | func (pm PortMappings) Len() int { return len(pm) } 28 | func (pm PortMappings) Swap(i, j int) { pm[i], pm[j] = pm[j], pm[i] } 29 | func (pm PortMappings) Less(i, j int) bool { return pm[i].ContainerPort < pm[j].ContainerPort } 30 | 31 | // IntermediateVolume is an intermediate representation for volume information 32 | type IntermediateVolume struct { 33 | Host string 34 | Container string 35 | SourceVolume string 36 | ReadOnly bool 37 | } 38 | 39 | // IntermediateVolumes is a composite type for slices of IntermediateVolume 40 | type IntermediateVolumes []IntermediateVolume 41 | 42 | func (iv IntermediateVolumes) Len() int { return len(iv) } 43 | func (iv IntermediateVolumes) Swap(i, j int) { iv[i], iv[j] = iv[j], iv[i] } 44 | func (iv IntermediateVolumes) Less(i, j int) bool { 45 | return strings.Compare(iv[i].Container, iv[j].Container) < 0 46 | } 47 | 48 | // Fetch is an intermediate representation for fetching information 49 | type Fetch struct { 50 | URI string 51 | } 52 | 53 | // HealthCheck is an intermediate representation for health check information 54 | type HealthCheck struct { 55 | Exec string 56 | 57 | HTTPPath string 58 | Port int 59 | Host string 60 | Scheme string 61 | Headers map[string]string 62 | 63 | Interval int 64 | Timeout int 65 | FailureThreshold int 66 | } 67 | 68 | // BuildContext is an intermediary representation for build information 69 | type BuildContext struct { 70 | Context string 71 | Dockerfile string 72 | Args map[string]string 73 | } 74 | 75 | // Container represents the intermediate format in between input and output formats 76 | type Container struct { 77 | Build *BuildContext 78 | Command string 79 | CPU int // out of 1024 80 | DNS []string 81 | Domain []string 82 | Entrypoint string 83 | EnvFile []string 84 | Environment map[string]string 85 | Essential bool 86 | Expose []int 87 | Fetch []*Fetch // TODO make a struct 88 | HealthChecks []*HealthCheck // TODO make a struct 89 | Hostname string 90 | Image string 91 | Labels map[string]string 92 | Links []string 93 | Logging *Logging 94 | Memory int // in bytes 95 | Name string 96 | Network []string 97 | NetworkMode string 98 | Pid string 99 | PortMappings *PortMappings 100 | Privileged bool 101 | PullImagePolicy string 102 | Replicas int 103 | StopSignal string 104 | User string 105 | Volumes *IntermediateVolumes 106 | VolumesFrom []string // todo make a struct 107 | WorkDir string 108 | } 109 | 110 | // Containers is for storing and sorting slices of Container 111 | type Containers []Container 112 | 113 | func (cs Containers) Len() int { return len(cs) } 114 | func (cs Containers) Swap(i, j int) { cs[i], cs[j] = cs[j], cs[i] } 115 | func (cs Containers) Less(i, j int) bool { 116 | return strings.Compare(cs[i].Name, cs[j].Name) < 0 117 | } 118 | 119 | // PodData is the intermediary between each container format 120 | type PodData struct { 121 | Name string 122 | Containers *Containers 123 | GlobalLabels map[string]string 124 | HostNetwork bool 125 | HostPID bool 126 | Replicas int 127 | } 128 | 129 | // InputFormat is an interface for other container formats to ingest containers 130 | type InputFormat interface { 131 | IngestContainers(input io.ReadCloser) (*PodData, error) 132 | } 133 | 134 | // OutputFormat is an interface for other container formats to emit containers 135 | type OutputFormat interface { 136 | EmitContainers(input *PodData) ([]byte, error) 137 | } 138 | -------------------------------------------------------------------------------- /vendor/gopkg.in/check.v1/printer.go: -------------------------------------------------------------------------------- 1 | package check 2 | 3 | import ( 4 | "bytes" 5 | "go/ast" 6 | "go/parser" 7 | "go/printer" 8 | "go/token" 9 | "os" 10 | ) 11 | 12 | func indent(s, with string) (r string) { 13 | eol := true 14 | for i := 0; i != len(s); i++ { 15 | c := s[i] 16 | switch { 17 | case eol && c == '\n' || c == '\r': 18 | case c == '\n' || c == '\r': 19 | eol = true 20 | case eol: 21 | eol = false 22 | s = s[:i] + with + s[i:] 23 | i += len(with) 24 | } 25 | } 26 | return s 27 | } 28 | 29 | func printLine(filename string, line int) (string, error) { 30 | fset := token.NewFileSet() 31 | file, err := os.Open(filename) 32 | if err != nil { 33 | return "", err 34 | } 35 | fnode, err := parser.ParseFile(fset, filename, file, parser.ParseComments) 36 | if err != nil { 37 | return "", err 38 | } 39 | config := &printer.Config{Mode: printer.UseSpaces, Tabwidth: 4} 40 | lp := &linePrinter{fset: fset, fnode: fnode, line: line, config: config} 41 | ast.Walk(lp, fnode) 42 | result := lp.output.Bytes() 43 | // Comments leave \n at the end. 44 | n := len(result) 45 | for n > 0 && result[n-1] == '\n' { 46 | n-- 47 | } 48 | return string(result[:n]), nil 49 | } 50 | 51 | type linePrinter struct { 52 | config *printer.Config 53 | fset *token.FileSet 54 | fnode *ast.File 55 | line int 56 | output bytes.Buffer 57 | stmt ast.Stmt 58 | } 59 | 60 | func (lp *linePrinter) emit() bool { 61 | if lp.stmt != nil { 62 | lp.trim(lp.stmt) 63 | lp.printWithComments(lp.stmt) 64 | lp.stmt = nil 65 | return true 66 | } 67 | return false 68 | } 69 | 70 | func (lp *linePrinter) printWithComments(n ast.Node) { 71 | nfirst := lp.fset.Position(n.Pos()).Line 72 | nlast := lp.fset.Position(n.End()).Line 73 | for _, g := range lp.fnode.Comments { 74 | cfirst := lp.fset.Position(g.Pos()).Line 75 | clast := lp.fset.Position(g.End()).Line 76 | if clast == nfirst-1 && lp.fset.Position(n.Pos()).Column == lp.fset.Position(g.Pos()).Column { 77 | for _, c := range g.List { 78 | lp.output.WriteString(c.Text) 79 | lp.output.WriteByte('\n') 80 | } 81 | } 82 | if cfirst >= nfirst && cfirst <= nlast && n.End() <= g.List[0].Slash { 83 | // The printer will not include the comment if it starts past 84 | // the node itself. Trick it into printing by overlapping the 85 | // slash with the end of the statement. 86 | g.List[0].Slash = n.End() - 1 87 | } 88 | } 89 | node := &printer.CommentedNode{n, lp.fnode.Comments} 90 | lp.config.Fprint(&lp.output, lp.fset, node) 91 | } 92 | 93 | func (lp *linePrinter) Visit(n ast.Node) (w ast.Visitor) { 94 | if n == nil { 95 | if lp.output.Len() == 0 { 96 | lp.emit() 97 | } 98 | return nil 99 | } 100 | first := lp.fset.Position(n.Pos()).Line 101 | last := lp.fset.Position(n.End()).Line 102 | if first <= lp.line && last >= lp.line { 103 | // Print the innermost statement containing the line. 104 | if stmt, ok := n.(ast.Stmt); ok { 105 | if _, ok := n.(*ast.BlockStmt); !ok { 106 | lp.stmt = stmt 107 | } 108 | } 109 | if first == lp.line && lp.emit() { 110 | return nil 111 | } 112 | return lp 113 | } 114 | return nil 115 | } 116 | 117 | func (lp *linePrinter) trim(n ast.Node) bool { 118 | stmt, ok := n.(ast.Stmt) 119 | if !ok { 120 | return true 121 | } 122 | line := lp.fset.Position(n.Pos()).Line 123 | if line != lp.line { 124 | return false 125 | } 126 | switch stmt := stmt.(type) { 127 | case *ast.IfStmt: 128 | stmt.Body = lp.trimBlock(stmt.Body) 129 | case *ast.SwitchStmt: 130 | stmt.Body = lp.trimBlock(stmt.Body) 131 | case *ast.TypeSwitchStmt: 132 | stmt.Body = lp.trimBlock(stmt.Body) 133 | case *ast.CaseClause: 134 | stmt.Body = lp.trimList(stmt.Body) 135 | case *ast.CommClause: 136 | stmt.Body = lp.trimList(stmt.Body) 137 | case *ast.BlockStmt: 138 | stmt.List = lp.trimList(stmt.List) 139 | } 140 | return true 141 | } 142 | 143 | func (lp *linePrinter) trimBlock(stmt *ast.BlockStmt) *ast.BlockStmt { 144 | if !lp.trim(stmt) { 145 | return lp.emptyBlock(stmt) 146 | } 147 | stmt.Rbrace = stmt.Lbrace 148 | return stmt 149 | } 150 | 151 | func (lp *linePrinter) trimList(stmts []ast.Stmt) []ast.Stmt { 152 | for i := 0; i != len(stmts); i++ { 153 | if !lp.trim(stmts[i]) { 154 | stmts[i] = lp.emptyStmt(stmts[i]) 155 | break 156 | } 157 | } 158 | return stmts 159 | } 160 | 161 | func (lp *linePrinter) emptyStmt(n ast.Node) *ast.ExprStmt { 162 | return &ast.ExprStmt{&ast.Ellipsis{n.Pos(), nil}} 163 | } 164 | 165 | func (lp *linePrinter) emptyBlock(n ast.Node) *ast.BlockStmt { 166 | p := n.Pos() 167 | return &ast.BlockStmt{p, []ast.Stmt{lp.emptyStmt(n)}, p} 168 | } 169 | -------------------------------------------------------------------------------- /vendor/gopkg.in/check.v1/reporter_test.go: -------------------------------------------------------------------------------- 1 | package check_test 2 | 3 | import ( 4 | "fmt" 5 | "path/filepath" 6 | "runtime" 7 | 8 | . "gopkg.in/check.v1" 9 | ) 10 | 11 | var _ = Suite(&reporterS{}) 12 | 13 | type reporterS struct { 14 | testFile string 15 | } 16 | 17 | func (s *reporterS) SetUpSuite(c *C) { 18 | _, fileName, _, ok := runtime.Caller(0) 19 | c.Assert(ok, Equals, true) 20 | s.testFile = filepath.Base(fileName) 21 | } 22 | 23 | func (s *reporterS) TestWrite(c *C) { 24 | testString := "test string" 25 | output := String{} 26 | 27 | dummyStream := true 28 | dummyVerbose := true 29 | o := NewOutputWriter(&output, dummyStream, dummyVerbose) 30 | 31 | o.Write([]byte(testString)) 32 | c.Assert(output.value, Equals, testString) 33 | } 34 | 35 | func (s *reporterS) TestWriteCallStartedWithStreamFlag(c *C) { 36 | testLabel := "test started label" 37 | stream := true 38 | output := String{} 39 | 40 | dummyVerbose := true 41 | o := NewOutputWriter(&output, stream, dummyVerbose) 42 | 43 | o.WriteCallStarted(testLabel, c) 44 | expected := fmt.Sprintf("%s: %s:\\d+: %s\n", testLabel, s.testFile, c.TestName()) 45 | c.Assert(output.value, Matches, expected) 46 | } 47 | 48 | func (s *reporterS) TestWriteCallStartedWithoutStreamFlag(c *C) { 49 | stream := false 50 | output := String{} 51 | 52 | dummyLabel := "dummy" 53 | dummyVerbose := true 54 | o := NewOutputWriter(&output, stream, dummyVerbose) 55 | 56 | o.WriteCallStarted(dummyLabel, c) 57 | c.Assert(output.value, Equals, "") 58 | } 59 | 60 | func (s *reporterS) TestWriteCallProblemWithStreamFlag(c *C) { 61 | testLabel := "test problem label" 62 | stream := true 63 | output := String{} 64 | 65 | dummyVerbose := true 66 | o := NewOutputWriter(&output, stream, dummyVerbose) 67 | 68 | o.WriteCallProblem(testLabel, c) 69 | expected := fmt.Sprintf("%s: %s:\\d+: %s\n\n", testLabel, s.testFile, c.TestName()) 70 | c.Assert(output.value, Matches, expected) 71 | } 72 | 73 | func (s *reporterS) TestWriteCallProblemWithoutStreamFlag(c *C) { 74 | testLabel := "test problem label" 75 | stream := false 76 | output := String{} 77 | 78 | dummyVerbose := true 79 | o := NewOutputWriter(&output, stream, dummyVerbose) 80 | 81 | o.WriteCallProblem(testLabel, c) 82 | expected := fmt.Sprintf(""+ 83 | "\n"+ 84 | "----------------------------------------------------------------------\n"+ 85 | "%s: %s:\\d+: %s\n\n", testLabel, s.testFile, c.TestName()) 86 | c.Assert(output.value, Matches, expected) 87 | } 88 | 89 | func (s *reporterS) TestWriteCallProblemWithoutStreamFlagWithLog(c *C) { 90 | testLabel := "test problem label" 91 | testLog := "test log" 92 | stream := false 93 | output := String{} 94 | 95 | dummyVerbose := true 96 | o := NewOutputWriter(&output, stream, dummyVerbose) 97 | 98 | c.Log(testLog) 99 | o.WriteCallProblem(testLabel, c) 100 | expected := fmt.Sprintf(""+ 101 | "\n"+ 102 | "----------------------------------------------------------------------\n"+ 103 | "%s: %s:\\d+: %s\n\n%s\n", testLabel, s.testFile, c.TestName(), testLog) 104 | c.Assert(output.value, Matches, expected) 105 | } 106 | 107 | func (s *reporterS) TestWriteCallSuccessWithStreamFlag(c *C) { 108 | testLabel := "test success label" 109 | stream := true 110 | output := String{} 111 | 112 | dummyVerbose := true 113 | o := NewOutputWriter(&output, stream, dummyVerbose) 114 | 115 | o.WriteCallSuccess(testLabel, c) 116 | expected := fmt.Sprintf("%s: %s:\\d+: %s\t\\d\\.\\d+s\n\n", testLabel, s.testFile, c.TestName()) 117 | c.Assert(output.value, Matches, expected) 118 | } 119 | 120 | func (s *reporterS) TestWriteCallSuccessWithStreamFlagAndReason(c *C) { 121 | testLabel := "test success label" 122 | testReason := "test skip reason" 123 | stream := true 124 | output := String{} 125 | 126 | dummyVerbose := true 127 | o := NewOutputWriter(&output, stream, dummyVerbose) 128 | c.FakeSkip(testReason) 129 | 130 | o.WriteCallSuccess(testLabel, c) 131 | expected := fmt.Sprintf("%s: %s:\\d+: %s \\(%s\\)\t\\d\\.\\d+s\n\n", 132 | testLabel, s.testFile, c.TestName(), testReason) 133 | c.Assert(output.value, Matches, expected) 134 | } 135 | 136 | func (s *reporterS) TestWriteCallSuccessWithoutStreamFlagWithVerboseFlag(c *C) { 137 | testLabel := "test success label" 138 | stream := false 139 | verbose := true 140 | output := String{} 141 | 142 | o := NewOutputWriter(&output, stream, verbose) 143 | 144 | o.WriteCallSuccess(testLabel, c) 145 | expected := fmt.Sprintf("%s: %s:\\d+: %s\t\\d\\.\\d+s\n", testLabel, s.testFile, c.TestName()) 146 | c.Assert(output.value, Matches, expected) 147 | } 148 | 149 | func (s *reporterS) TestWriteCallSuccessWithoutStreamFlagWithoutVerboseFlag(c *C) { 150 | testLabel := "test success label" 151 | stream := false 152 | verbose := false 153 | output := String{} 154 | 155 | o := NewOutputWriter(&output, stream, verbose) 156 | 157 | o.WriteCallSuccess(testLabel, c) 158 | c.Assert(output.value, Equals, "") 159 | } 160 | -------------------------------------------------------------------------------- /vendor/gopkg.in/check.v1/benchmark.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012 The Go Authors. All rights reserved. 2 | // 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are 5 | // met: 6 | // 7 | // * Redistributions of source code must retain the above copyright 8 | // notice, this list of conditions and the following disclaimer. 9 | // * Redistributions in binary form must reproduce the above 10 | // copyright notice, this list of conditions and the following disclaimer 11 | // in the documentation and/or other materials provided with the 12 | // distribution. 13 | // * Neither the name of Google Inc. nor the names of its 14 | // contributors may be used to endorse or promote products derived from 15 | // this software without specific prior written permission. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | package check 30 | 31 | import ( 32 | "fmt" 33 | "runtime" 34 | "time" 35 | ) 36 | 37 | var memStats runtime.MemStats 38 | 39 | // testingB is a type passed to Benchmark functions to manage benchmark 40 | // timing and to specify the number of iterations to run. 41 | type timer struct { 42 | start time.Time // Time test or benchmark started 43 | duration time.Duration 44 | N int 45 | bytes int64 46 | timerOn bool 47 | benchTime time.Duration 48 | // The initial states of memStats.Mallocs and memStats.TotalAlloc. 49 | startAllocs uint64 50 | startBytes uint64 51 | // The net total of this test after being run. 52 | netAllocs uint64 53 | netBytes uint64 54 | } 55 | 56 | // StartTimer starts timing a test. This function is called automatically 57 | // before a benchmark starts, but it can also used to resume timing after 58 | // a call to StopTimer. 59 | func (c *C) StartTimer() { 60 | if !c.timerOn { 61 | c.start = time.Now() 62 | c.timerOn = true 63 | 64 | runtime.ReadMemStats(&memStats) 65 | c.startAllocs = memStats.Mallocs 66 | c.startBytes = memStats.TotalAlloc 67 | } 68 | } 69 | 70 | // StopTimer stops timing a test. This can be used to pause the timer 71 | // while performing complex initialization that you don't 72 | // want to measure. 73 | func (c *C) StopTimer() { 74 | if c.timerOn { 75 | c.duration += time.Now().Sub(c.start) 76 | c.timerOn = false 77 | runtime.ReadMemStats(&memStats) 78 | c.netAllocs += memStats.Mallocs - c.startAllocs 79 | c.netBytes += memStats.TotalAlloc - c.startBytes 80 | } 81 | } 82 | 83 | // ResetTimer sets the elapsed benchmark time to zero. 84 | // It does not affect whether the timer is running. 85 | func (c *C) ResetTimer() { 86 | if c.timerOn { 87 | c.start = time.Now() 88 | runtime.ReadMemStats(&memStats) 89 | c.startAllocs = memStats.Mallocs 90 | c.startBytes = memStats.TotalAlloc 91 | } 92 | c.duration = 0 93 | c.netAllocs = 0 94 | c.netBytes = 0 95 | } 96 | 97 | // SetBytes informs the number of bytes that the benchmark processes 98 | // on each iteration. If this is called in a benchmark it will also 99 | // report MB/s. 100 | func (c *C) SetBytes(n int64) { 101 | c.bytes = n 102 | } 103 | 104 | func (c *C) nsPerOp() int64 { 105 | if c.N <= 0 { 106 | return 0 107 | } 108 | return c.duration.Nanoseconds() / int64(c.N) 109 | } 110 | 111 | func (c *C) mbPerSec() float64 { 112 | if c.bytes <= 0 || c.duration <= 0 || c.N <= 0 { 113 | return 0 114 | } 115 | return (float64(c.bytes) * float64(c.N) / 1e6) / c.duration.Seconds() 116 | } 117 | 118 | func (c *C) timerString() string { 119 | if c.N <= 0 { 120 | return fmt.Sprintf("%3.3fs", float64(c.duration.Nanoseconds())/1e9) 121 | } 122 | mbs := c.mbPerSec() 123 | mb := "" 124 | if mbs != 0 { 125 | mb = fmt.Sprintf("\t%7.2f MB/s", mbs) 126 | } 127 | nsop := c.nsPerOp() 128 | ns := fmt.Sprintf("%10d ns/op", nsop) 129 | if c.N > 0 && nsop < 100 { 130 | // The format specifiers here make sure that 131 | // the ones digits line up for all three possible formats. 132 | if nsop < 10 { 133 | ns = fmt.Sprintf("%13.2f ns/op", float64(c.duration.Nanoseconds())/float64(c.N)) 134 | } else { 135 | ns = fmt.Sprintf("%12.1f ns/op", float64(c.duration.Nanoseconds())/float64(c.N)) 136 | } 137 | } 138 | memStats := "" 139 | if c.benchMem { 140 | allocedBytes := fmt.Sprintf("%8d B/op", int64(c.netBytes)/int64(c.N)) 141 | allocs := fmt.Sprintf("%8d allocs/op", int64(c.netAllocs)/int64(c.N)) 142 | memStats = fmt.Sprintf("\t%s\t%s", allocedBytes, allocs) 143 | } 144 | return fmt.Sprintf("%8d\t%s%s%s", c.N, ns, mb, memStats) 145 | } 146 | 147 | func min(x, y int) int { 148 | if x > y { 149 | return y 150 | } 151 | return x 152 | } 153 | 154 | func max(x, y int) int { 155 | if x < y { 156 | return y 157 | } 158 | return x 159 | } 160 | 161 | // roundDown10 rounds a number down to the nearest power of 10. 162 | func roundDown10(n int) int { 163 | var tens = 0 164 | // tens = floor(log_10(n)) 165 | for n > 10 { 166 | n = n / 10 167 | tens++ 168 | } 169 | // result = 10^tens 170 | result := 1 171 | for i := 0; i < tens; i++ { 172 | result *= 10 173 | } 174 | return result 175 | } 176 | 177 | // roundUp rounds x up to a number of the form [1eX, 2eX, 5eX]. 178 | func roundUp(n int) int { 179 | base := roundDown10(n) 180 | if n < (2 * base) { 181 | return 2 * base 182 | } 183 | if n < (5 * base) { 184 | return 5 * base 185 | } 186 | return 10 * base 187 | } 188 | -------------------------------------------------------------------------------- /vendor/gopkg.in/check.v1/check_test.go: -------------------------------------------------------------------------------- 1 | // This file contains just a few generic helpers which are used by the 2 | // other test files. 3 | 4 | package check_test 5 | 6 | import ( 7 | "flag" 8 | "fmt" 9 | "os" 10 | "regexp" 11 | "runtime" 12 | "testing" 13 | "time" 14 | 15 | "gopkg.in/check.v1" 16 | ) 17 | 18 | // We count the number of suites run at least to get a vague hint that the 19 | // test suite is behaving as it should. Otherwise a bug introduced at the 20 | // very core of the system could go unperceived. 21 | const suitesRunExpected = 8 22 | 23 | var suitesRun int = 0 24 | 25 | func Test(t *testing.T) { 26 | check.TestingT(t) 27 | if suitesRun != suitesRunExpected && flag.Lookup("check.f").Value.String() == "" { 28 | critical(fmt.Sprintf("Expected %d suites to run rather than %d", 29 | suitesRunExpected, suitesRun)) 30 | } 31 | } 32 | 33 | // ----------------------------------------------------------------------- 34 | // Helper functions. 35 | 36 | // Break down badly. This is used in test cases which can't yet assume 37 | // that the fundamental bits are working. 38 | func critical(error string) { 39 | fmt.Fprintln(os.Stderr, "CRITICAL: "+error) 40 | os.Exit(1) 41 | } 42 | 43 | // Return the file line where it's called. 44 | func getMyLine() int { 45 | if _, _, line, ok := runtime.Caller(1); ok { 46 | return line 47 | } 48 | return -1 49 | } 50 | 51 | // ----------------------------------------------------------------------- 52 | // Helper type implementing a basic io.Writer for testing output. 53 | 54 | // Type implementing the io.Writer interface for analyzing output. 55 | type String struct { 56 | value string 57 | } 58 | 59 | // The only function required by the io.Writer interface. Will append 60 | // written data to the String.value string. 61 | func (s *String) Write(p []byte) (n int, err error) { 62 | s.value += string(p) 63 | return len(p), nil 64 | } 65 | 66 | // Trivial wrapper to test errors happening on a different file 67 | // than the test itself. 68 | func checkEqualWrapper(c *check.C, obtained, expected interface{}) (result bool, line int) { 69 | return c.Check(obtained, check.Equals, expected), getMyLine() 70 | } 71 | 72 | // ----------------------------------------------------------------------- 73 | // Helper suite for testing basic fail behavior. 74 | 75 | type FailHelper struct { 76 | testLine int 77 | } 78 | 79 | func (s *FailHelper) TestLogAndFail(c *check.C) { 80 | s.testLine = getMyLine() - 1 81 | c.Log("Expected failure!") 82 | c.Fail() 83 | } 84 | 85 | // ----------------------------------------------------------------------- 86 | // Helper suite for testing basic success behavior. 87 | 88 | type SuccessHelper struct{} 89 | 90 | func (s *SuccessHelper) TestLogAndSucceed(c *check.C) { 91 | c.Log("Expected success!") 92 | } 93 | 94 | // ----------------------------------------------------------------------- 95 | // Helper suite for testing ordering and behavior of fixture. 96 | 97 | type FixtureHelper struct { 98 | calls []string 99 | panicOn string 100 | skip bool 101 | skipOnN int 102 | sleepOn string 103 | sleep time.Duration 104 | bytes int64 105 | } 106 | 107 | func (s *FixtureHelper) trace(name string, c *check.C) { 108 | s.calls = append(s.calls, name) 109 | if name == s.panicOn { 110 | panic(name) 111 | } 112 | if s.sleep > 0 && s.sleepOn == name { 113 | time.Sleep(s.sleep) 114 | } 115 | if s.skip && s.skipOnN == len(s.calls)-1 { 116 | c.Skip("skipOnN == n") 117 | } 118 | } 119 | 120 | func (s *FixtureHelper) SetUpSuite(c *check.C) { 121 | s.trace("SetUpSuite", c) 122 | } 123 | 124 | func (s *FixtureHelper) TearDownSuite(c *check.C) { 125 | s.trace("TearDownSuite", c) 126 | } 127 | 128 | func (s *FixtureHelper) SetUpTest(c *check.C) { 129 | s.trace("SetUpTest", c) 130 | } 131 | 132 | func (s *FixtureHelper) TearDownTest(c *check.C) { 133 | s.trace("TearDownTest", c) 134 | } 135 | 136 | func (s *FixtureHelper) Test1(c *check.C) { 137 | s.trace("Test1", c) 138 | } 139 | 140 | func (s *FixtureHelper) Test2(c *check.C) { 141 | s.trace("Test2", c) 142 | } 143 | 144 | func (s *FixtureHelper) Benchmark1(c *check.C) { 145 | s.trace("Benchmark1", c) 146 | for i := 0; i < c.N; i++ { 147 | time.Sleep(s.sleep) 148 | } 149 | } 150 | 151 | func (s *FixtureHelper) Benchmark2(c *check.C) { 152 | s.trace("Benchmark2", c) 153 | c.SetBytes(1024) 154 | for i := 0; i < c.N; i++ { 155 | time.Sleep(s.sleep) 156 | } 157 | } 158 | 159 | func (s *FixtureHelper) Benchmark3(c *check.C) { 160 | var x []int64 161 | s.trace("Benchmark3", c) 162 | for i := 0; i < c.N; i++ { 163 | time.Sleep(s.sleep) 164 | x = make([]int64, 5) 165 | _ = x 166 | } 167 | } 168 | 169 | // ----------------------------------------------------------------------- 170 | // Helper which checks the state of the test and ensures that it matches 171 | // the given expectations. Depends on c.Errorf() working, so shouldn't 172 | // be used to test this one function. 173 | 174 | type expectedState struct { 175 | name string 176 | result interface{} 177 | failed bool 178 | log string 179 | } 180 | 181 | // Verify the state of the test. Note that since this also verifies if 182 | // the test is supposed to be in a failed state, no other checks should 183 | // be done in addition to what is being tested. 184 | func checkState(c *check.C, result interface{}, expected *expectedState) { 185 | failed := c.Failed() 186 | c.Succeed() 187 | log := c.GetTestLog() 188 | matched, matchError := regexp.MatchString("^"+expected.log+"$", log) 189 | if matchError != nil { 190 | c.Errorf("Error in matching expression used in testing %s", 191 | expected.name) 192 | } else if !matched { 193 | c.Errorf("%s logged:\n----------\n%s----------\n\nExpected:\n----------\n%s\n----------", 194 | expected.name, log, expected.log) 195 | } 196 | if result != expected.result { 197 | c.Errorf("%s returned %#v rather than %#v", 198 | expected.name, result, expected.result) 199 | } 200 | if failed != expected.failed { 201 | if failed { 202 | c.Errorf("%s has failed when it shouldn't", expected.name) 203 | } else { 204 | c.Errorf("%s has not failed when it should", expected.name) 205 | } 206 | } 207 | } 208 | -------------------------------------------------------------------------------- /vendor/gopkg.in/check.v1/run.go: -------------------------------------------------------------------------------- 1 | package check 2 | 3 | import ( 4 | "bufio" 5 | "flag" 6 | "fmt" 7 | "os" 8 | "testing" 9 | "time" 10 | ) 11 | 12 | // ----------------------------------------------------------------------- 13 | // Test suite registry. 14 | 15 | var allSuites []interface{} 16 | 17 | // Suite registers the given value as a test suite to be run. Any methods 18 | // starting with the Test prefix in the given value will be considered as 19 | // a test method. 20 | func Suite(suite interface{}) interface{} { 21 | allSuites = append(allSuites, suite) 22 | return suite 23 | } 24 | 25 | // ----------------------------------------------------------------------- 26 | // Public running interface. 27 | 28 | var ( 29 | oldFilterFlag = flag.String("gocheck.f", "", "Regular expression selecting which tests and/or suites to run") 30 | oldVerboseFlag = flag.Bool("gocheck.v", false, "Verbose mode") 31 | oldStreamFlag = flag.Bool("gocheck.vv", false, "Super verbose mode (disables output caching)") 32 | oldBenchFlag = flag.Bool("gocheck.b", false, "Run benchmarks") 33 | oldBenchTime = flag.Duration("gocheck.btime", 1*time.Second, "approximate run time for each benchmark") 34 | oldListFlag = flag.Bool("gocheck.list", false, "List the names of all tests that will be run") 35 | oldWorkFlag = flag.Bool("gocheck.work", false, "Display and do not remove the test working directory") 36 | 37 | newFilterFlag = flag.String("check.f", "", "Regular expression selecting which tests and/or suites to run") 38 | newVerboseFlag = flag.Bool("check.v", false, "Verbose mode") 39 | newStreamFlag = flag.Bool("check.vv", false, "Super verbose mode (disables output caching)") 40 | newBenchFlag = flag.Bool("check.b", false, "Run benchmarks") 41 | newBenchTime = flag.Duration("check.btime", 1*time.Second, "approximate run time for each benchmark") 42 | newBenchMem = flag.Bool("check.bmem", false, "Report memory benchmarks") 43 | newListFlag = flag.Bool("check.list", false, "List the names of all tests that will be run") 44 | newWorkFlag = flag.Bool("check.work", false, "Display and do not remove the test working directory") 45 | ) 46 | 47 | // TestingT runs all test suites registered with the Suite function, 48 | // printing results to stdout, and reporting any failures back to 49 | // the "testing" package. 50 | func TestingT(testingT *testing.T) { 51 | benchTime := *newBenchTime 52 | if benchTime == 1*time.Second { 53 | benchTime = *oldBenchTime 54 | } 55 | conf := &RunConf{ 56 | Filter: *oldFilterFlag + *newFilterFlag, 57 | Verbose: *oldVerboseFlag || *newVerboseFlag, 58 | Stream: *oldStreamFlag || *newStreamFlag, 59 | Benchmark: *oldBenchFlag || *newBenchFlag, 60 | BenchmarkTime: benchTime, 61 | BenchmarkMem: *newBenchMem, 62 | KeepWorkDir: *oldWorkFlag || *newWorkFlag, 63 | } 64 | if *oldListFlag || *newListFlag { 65 | w := bufio.NewWriter(os.Stdout) 66 | for _, name := range ListAll(conf) { 67 | fmt.Fprintln(w, name) 68 | } 69 | w.Flush() 70 | return 71 | } 72 | result := RunAll(conf) 73 | println(result.String()) 74 | if !result.Passed() { 75 | testingT.Fail() 76 | } 77 | } 78 | 79 | // RunAll runs all test suites registered with the Suite function, using the 80 | // provided run configuration. 81 | func RunAll(runConf *RunConf) *Result { 82 | result := Result{} 83 | for _, suite := range allSuites { 84 | result.Add(Run(suite, runConf)) 85 | } 86 | return &result 87 | } 88 | 89 | // Run runs the provided test suite using the provided run configuration. 90 | func Run(suite interface{}, runConf *RunConf) *Result { 91 | runner := newSuiteRunner(suite, runConf) 92 | return runner.run() 93 | } 94 | 95 | // ListAll returns the names of all the test functions registered with the 96 | // Suite function that will be run with the provided run configuration. 97 | func ListAll(runConf *RunConf) []string { 98 | var names []string 99 | for _, suite := range allSuites { 100 | names = append(names, List(suite, runConf)...) 101 | } 102 | return names 103 | } 104 | 105 | // List returns the names of the test functions in the given 106 | // suite that will be run with the provided run configuration. 107 | func List(suite interface{}, runConf *RunConf) []string { 108 | var names []string 109 | runner := newSuiteRunner(suite, runConf) 110 | for _, t := range runner.tests { 111 | names = append(names, t.String()) 112 | } 113 | return names 114 | } 115 | 116 | // ----------------------------------------------------------------------- 117 | // Result methods. 118 | 119 | func (r *Result) Add(other *Result) { 120 | r.Succeeded += other.Succeeded 121 | r.Skipped += other.Skipped 122 | r.Failed += other.Failed 123 | r.Panicked += other.Panicked 124 | r.FixturePanicked += other.FixturePanicked 125 | r.ExpectedFailures += other.ExpectedFailures 126 | r.Missed += other.Missed 127 | if r.WorkDir != "" && other.WorkDir != "" { 128 | r.WorkDir += ":" + other.WorkDir 129 | } else if other.WorkDir != "" { 130 | r.WorkDir = other.WorkDir 131 | } 132 | } 133 | 134 | func (r *Result) Passed() bool { 135 | return (r.Failed == 0 && r.Panicked == 0 && 136 | r.FixturePanicked == 0 && r.Missed == 0 && 137 | r.RunError == nil) 138 | } 139 | 140 | func (r *Result) String() string { 141 | if r.RunError != nil { 142 | return "ERROR: " + r.RunError.Error() 143 | } 144 | 145 | var value string 146 | if r.Failed == 0 && r.Panicked == 0 && r.FixturePanicked == 0 && 147 | r.Missed == 0 { 148 | value = "OK: " 149 | } else { 150 | value = "OOPS: " 151 | } 152 | value += fmt.Sprintf("%d passed", r.Succeeded) 153 | if r.Skipped != 0 { 154 | value += fmt.Sprintf(", %d skipped", r.Skipped) 155 | } 156 | if r.ExpectedFailures != 0 { 157 | value += fmt.Sprintf(", %d expected failures", r.ExpectedFailures) 158 | } 159 | if r.Failed != 0 { 160 | value += fmt.Sprintf(", %d FAILED", r.Failed) 161 | } 162 | if r.Panicked != 0 { 163 | value += fmt.Sprintf(", %d PANICKED", r.Panicked) 164 | } 165 | if r.FixturePanicked != 0 { 166 | value += fmt.Sprintf(", %d FIXTURE-PANICKED", r.FixturePanicked) 167 | } 168 | if r.Missed != 0 { 169 | value += fmt.Sprintf(", %d MISSED", r.Missed) 170 | } 171 | if r.WorkDir != "" { 172 | value += "\nWORK=" + r.WorkDir 173 | } 174 | return value 175 | } 176 | -------------------------------------------------------------------------------- /vendor/github.com/davecgh/go-spew/spew/bypass.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Dave Collins 2 | // 3 | // Permission to use, copy, modify, and distribute this software for any 4 | // purpose with or without fee is hereby granted, provided that the above 5 | // copyright notice and this permission notice appear in all copies. 6 | // 7 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 | // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 | // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 10 | // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 | // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 12 | // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 13 | // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 | 15 | // NOTE: Due to the following build constraints, this file will only be compiled 16 | // when the code is not running on Google App Engine and "-tags disableunsafe" 17 | // is not added to the go build command line. 18 | // +build !appengine,!disableunsafe 19 | 20 | package spew 21 | 22 | import ( 23 | "reflect" 24 | "unsafe" 25 | ) 26 | 27 | const ( 28 | // UnsafeDisabled is a build-time constant which specifies whether or 29 | // not access to the unsafe package is available. 30 | UnsafeDisabled = false 31 | 32 | // ptrSize is the size of a pointer on the current arch. 33 | ptrSize = unsafe.Sizeof((*byte)(nil)) 34 | ) 35 | 36 | var ( 37 | // offsetPtr, offsetScalar, and offsetFlag are the offsets for the 38 | // internal reflect.Value fields. These values are valid before golang 39 | // commit ecccf07e7f9d which changed the format. The are also valid 40 | // after commit 82f48826c6c7 which changed the format again to mirror 41 | // the original format. Code in the init function updates these offsets 42 | // as necessary. 43 | offsetPtr = uintptr(ptrSize) 44 | offsetScalar = uintptr(0) 45 | offsetFlag = uintptr(ptrSize * 2) 46 | 47 | // flagKindWidth and flagKindShift indicate various bits that the 48 | // reflect package uses internally to track kind information. 49 | // 50 | // flagRO indicates whether or not the value field of a reflect.Value is 51 | // read-only. 52 | // 53 | // flagIndir indicates whether the value field of a reflect.Value is 54 | // the actual data or a pointer to the data. 55 | // 56 | // These values are valid before golang commit 90a7c3c86944 which 57 | // changed their positions. Code in the init function updates these 58 | // flags as necessary. 59 | flagKindWidth = uintptr(5) 60 | flagKindShift = uintptr(flagKindWidth - 1) 61 | flagRO = uintptr(1 << 0) 62 | flagIndir = uintptr(1 << 1) 63 | ) 64 | 65 | func init() { 66 | // Older versions of reflect.Value stored small integers directly in the 67 | // ptr field (which is named val in the older versions). Versions 68 | // between commits ecccf07e7f9d and 82f48826c6c7 added a new field named 69 | // scalar for this purpose which unfortunately came before the flag 70 | // field, so the offset of the flag field is different for those 71 | // versions. 72 | // 73 | // This code constructs a new reflect.Value from a known small integer 74 | // and checks if the size of the reflect.Value struct indicates it has 75 | // the scalar field. When it does, the offsets are updated accordingly. 76 | vv := reflect.ValueOf(0xf00) 77 | if unsafe.Sizeof(vv) == (ptrSize * 4) { 78 | offsetScalar = ptrSize * 2 79 | offsetFlag = ptrSize * 3 80 | } 81 | 82 | // Commit 90a7c3c86944 changed the flag positions such that the low 83 | // order bits are the kind. This code extracts the kind from the flags 84 | // field and ensures it's the correct type. When it's not, the flag 85 | // order has been changed to the newer format, so the flags are updated 86 | // accordingly. 87 | upf := unsafe.Pointer(uintptr(unsafe.Pointer(&vv)) + offsetFlag) 88 | upfv := *(*uintptr)(upf) 89 | flagKindMask := uintptr((1<>flagKindShift != uintptr(reflect.Int) { 91 | flagKindShift = 0 92 | flagRO = 1 << 5 93 | flagIndir = 1 << 6 94 | 95 | // Commit adf9b30e5594 modified the flags to separate the 96 | // flagRO flag into two bits which specifies whether or not the 97 | // field is embedded. This causes flagIndir to move over a bit 98 | // and means that flagRO is the combination of either of the 99 | // original flagRO bit and the new bit. 100 | // 101 | // This code detects the change by extracting what used to be 102 | // the indirect bit to ensure it's set. When it's not, the flag 103 | // order has been changed to the newer format, so the flags are 104 | // updated accordingly. 105 | if upfv&flagIndir == 0 { 106 | flagRO = 3 << 5 107 | flagIndir = 1 << 7 108 | } 109 | } 110 | } 111 | 112 | // unsafeReflectValue converts the passed reflect.Value into a one that bypasses 113 | // the typical safety restrictions preventing access to unaddressable and 114 | // unexported data. It works by digging the raw pointer to the underlying 115 | // value out of the protected value and generating a new unprotected (unsafe) 116 | // reflect.Value to it. 117 | // 118 | // This allows us to check for implementations of the Stringer and error 119 | // interfaces to be used for pretty printing ordinarily unaddressable and 120 | // inaccessible values such as unexported struct fields. 121 | func unsafeReflectValue(v reflect.Value) (rv reflect.Value) { 122 | indirects := 1 123 | vt := v.Type() 124 | upv := unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + offsetPtr) 125 | rvf := *(*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + offsetFlag)) 126 | if rvf&flagIndir != 0 { 127 | vt = reflect.PtrTo(v.Type()) 128 | indirects++ 129 | } else if offsetScalar != 0 { 130 | // The value is in the scalar field when it's not one of the 131 | // reference types. 132 | switch vt.Kind() { 133 | case reflect.Uintptr: 134 | case reflect.Chan: 135 | case reflect.Func: 136 | case reflect.Map: 137 | case reflect.Ptr: 138 | case reflect.UnsafePointer: 139 | default: 140 | upv = unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + 141 | offsetScalar) 142 | } 143 | } 144 | 145 | pv := reflect.NewAt(vt, upv) 146 | rv = pv 147 | for i := 0; i < indirects; i++ { 148 | rv = rv.Elem() 149 | } 150 | return rv 151 | } 152 | -------------------------------------------------------------------------------- /vendor/github.com/davecgh/go-spew/spew/spew.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013 Dave Collins 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | package spew 18 | 19 | import ( 20 | "fmt" 21 | "io" 22 | ) 23 | 24 | // Errorf is a wrapper for fmt.Errorf that treats each argument as if it were 25 | // passed with a default Formatter interface returned by NewFormatter. It 26 | // returns the formatted string as a value that satisfies error. See 27 | // NewFormatter for formatting details. 28 | // 29 | // This function is shorthand for the following syntax: 30 | // 31 | // fmt.Errorf(format, spew.NewFormatter(a), spew.NewFormatter(b)) 32 | func Errorf(format string, a ...interface{}) (err error) { 33 | return fmt.Errorf(format, convertArgs(a)...) 34 | } 35 | 36 | // Fprint is a wrapper for fmt.Fprint that treats each argument as if it were 37 | // passed with a default Formatter interface returned by NewFormatter. It 38 | // returns the number of bytes written and any write error encountered. See 39 | // NewFormatter for formatting details. 40 | // 41 | // This function is shorthand for the following syntax: 42 | // 43 | // fmt.Fprint(w, spew.NewFormatter(a), spew.NewFormatter(b)) 44 | func Fprint(w io.Writer, a ...interface{}) (n int, err error) { 45 | return fmt.Fprint(w, convertArgs(a)...) 46 | } 47 | 48 | // Fprintf is a wrapper for fmt.Fprintf that treats each argument as if it were 49 | // passed with a default Formatter interface returned by NewFormatter. It 50 | // returns the number of bytes written and any write error encountered. See 51 | // NewFormatter for formatting details. 52 | // 53 | // This function is shorthand for the following syntax: 54 | // 55 | // fmt.Fprintf(w, format, spew.NewFormatter(a), spew.NewFormatter(b)) 56 | func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) { 57 | return fmt.Fprintf(w, format, convertArgs(a)...) 58 | } 59 | 60 | // Fprintln is a wrapper for fmt.Fprintln that treats each argument as if it 61 | // passed with a default Formatter interface returned by NewFormatter. See 62 | // NewFormatter for formatting details. 63 | // 64 | // This function is shorthand for the following syntax: 65 | // 66 | // fmt.Fprintln(w, spew.NewFormatter(a), spew.NewFormatter(b)) 67 | func Fprintln(w io.Writer, a ...interface{}) (n int, err error) { 68 | return fmt.Fprintln(w, convertArgs(a)...) 69 | } 70 | 71 | // Print is a wrapper for fmt.Print that treats each argument as if it were 72 | // passed with a default Formatter interface returned by NewFormatter. It 73 | // returns the number of bytes written and any write error encountered. See 74 | // NewFormatter for formatting details. 75 | // 76 | // This function is shorthand for the following syntax: 77 | // 78 | // fmt.Print(spew.NewFormatter(a), spew.NewFormatter(b)) 79 | func Print(a ...interface{}) (n int, err error) { 80 | return fmt.Print(convertArgs(a)...) 81 | } 82 | 83 | // Printf is a wrapper for fmt.Printf that treats each argument as if it were 84 | // passed with a default Formatter interface returned by NewFormatter. It 85 | // returns the number of bytes written and any write error encountered. See 86 | // NewFormatter for formatting details. 87 | // 88 | // This function is shorthand for the following syntax: 89 | // 90 | // fmt.Printf(format, spew.NewFormatter(a), spew.NewFormatter(b)) 91 | func Printf(format string, a ...interface{}) (n int, err error) { 92 | return fmt.Printf(format, convertArgs(a)...) 93 | } 94 | 95 | // Println is a wrapper for fmt.Println that treats each argument as if it were 96 | // passed with a default Formatter interface returned by NewFormatter. It 97 | // returns the number of bytes written and any write error encountered. See 98 | // NewFormatter for formatting details. 99 | // 100 | // This function is shorthand for the following syntax: 101 | // 102 | // fmt.Println(spew.NewFormatter(a), spew.NewFormatter(b)) 103 | func Println(a ...interface{}) (n int, err error) { 104 | return fmt.Println(convertArgs(a)...) 105 | } 106 | 107 | // Sprint is a wrapper for fmt.Sprint that treats each argument as if it were 108 | // passed with a default Formatter interface returned by NewFormatter. It 109 | // returns the resulting string. See NewFormatter for formatting details. 110 | // 111 | // This function is shorthand for the following syntax: 112 | // 113 | // fmt.Sprint(spew.NewFormatter(a), spew.NewFormatter(b)) 114 | func Sprint(a ...interface{}) string { 115 | return fmt.Sprint(convertArgs(a)...) 116 | } 117 | 118 | // Sprintf is a wrapper for fmt.Sprintf that treats each argument as if it were 119 | // passed with a default Formatter interface returned by NewFormatter. It 120 | // returns the resulting string. See NewFormatter for formatting details. 121 | // 122 | // This function is shorthand for the following syntax: 123 | // 124 | // fmt.Sprintf(format, spew.NewFormatter(a), spew.NewFormatter(b)) 125 | func Sprintf(format string, a ...interface{}) string { 126 | return fmt.Sprintf(format, convertArgs(a)...) 127 | } 128 | 129 | // Sprintln is a wrapper for fmt.Sprintln that treats each argument as if it 130 | // were passed with a default Formatter interface returned by NewFormatter. It 131 | // returns the resulting string. See NewFormatter for formatting details. 132 | // 133 | // This function is shorthand for the following syntax: 134 | // 135 | // fmt.Sprintln(spew.NewFormatter(a), spew.NewFormatter(b)) 136 | func Sprintln(a ...interface{}) string { 137 | return fmt.Sprintln(convertArgs(a)...) 138 | } 139 | 140 | // convertArgs accepts a slice of arguments and returns a slice of the same 141 | // length with each argument converted to a default spew Formatter interface. 142 | func convertArgs(args []interface{}) (formatters []interface{}) { 143 | formatters = make([]interface{}, len(args)) 144 | for index, arg := range args { 145 | formatters[index] = NewFormatter(arg) 146 | } 147 | return formatters 148 | } 149 | -------------------------------------------------------------------------------- /vendor/github.com/davecgh/go-spew/spew/example_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013 Dave Collins 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | package spew_test 18 | 19 | import ( 20 | "fmt" 21 | 22 | "github.com/davecgh/go-spew/spew" 23 | ) 24 | 25 | type Flag int 26 | 27 | const ( 28 | flagOne Flag = iota 29 | flagTwo 30 | ) 31 | 32 | var flagStrings = map[Flag]string{ 33 | flagOne: "flagOne", 34 | flagTwo: "flagTwo", 35 | } 36 | 37 | func (f Flag) String() string { 38 | if s, ok := flagStrings[f]; ok { 39 | return s 40 | } 41 | return fmt.Sprintf("Unknown flag (%d)", int(f)) 42 | } 43 | 44 | type Bar struct { 45 | data uintptr 46 | } 47 | 48 | type Foo struct { 49 | unexportedField Bar 50 | ExportedField map[interface{}]interface{} 51 | } 52 | 53 | // This example demonstrates how to use Dump to dump variables to stdout. 54 | func ExampleDump() { 55 | // The following package level declarations are assumed for this example: 56 | /* 57 | type Flag int 58 | 59 | const ( 60 | flagOne Flag = iota 61 | flagTwo 62 | ) 63 | 64 | var flagStrings = map[Flag]string{ 65 | flagOne: "flagOne", 66 | flagTwo: "flagTwo", 67 | } 68 | 69 | func (f Flag) String() string { 70 | if s, ok := flagStrings[f]; ok { 71 | return s 72 | } 73 | return fmt.Sprintf("Unknown flag (%d)", int(f)) 74 | } 75 | 76 | type Bar struct { 77 | data uintptr 78 | } 79 | 80 | type Foo struct { 81 | unexportedField Bar 82 | ExportedField map[interface{}]interface{} 83 | } 84 | */ 85 | 86 | // Setup some sample data structures for the example. 87 | bar := Bar{uintptr(0)} 88 | s1 := Foo{bar, map[interface{}]interface{}{"one": true}} 89 | f := Flag(5) 90 | b := []byte{ 91 | 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 92 | 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 93 | 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 94 | 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 95 | 0x31, 0x32, 96 | } 97 | 98 | // Dump! 99 | spew.Dump(s1, f, b) 100 | 101 | // Output: 102 | // (spew_test.Foo) { 103 | // unexportedField: (spew_test.Bar) { 104 | // data: (uintptr) 105 | // }, 106 | // ExportedField: (map[interface {}]interface {}) (len=1) { 107 | // (string) (len=3) "one": (bool) true 108 | // } 109 | // } 110 | // (spew_test.Flag) Unknown flag (5) 111 | // ([]uint8) (len=34 cap=34) { 112 | // 00000000 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 |............... | 113 | // 00000010 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 |!"#$%&'()*+,-./0| 114 | // 00000020 31 32 |12| 115 | // } 116 | // 117 | } 118 | 119 | // This example demonstrates how to use Printf to display a variable with a 120 | // format string and inline formatting. 121 | func ExamplePrintf() { 122 | // Create a double pointer to a uint 8. 123 | ui8 := uint8(5) 124 | pui8 := &ui8 125 | ppui8 := &pui8 126 | 127 | // Create a circular data type. 128 | type circular struct { 129 | ui8 uint8 130 | c *circular 131 | } 132 | c := circular{ui8: 1} 133 | c.c = &c 134 | 135 | // Print! 136 | spew.Printf("ppui8: %v\n", ppui8) 137 | spew.Printf("circular: %v\n", c) 138 | 139 | // Output: 140 | // ppui8: <**>5 141 | // circular: {1 <*>{1 <*>}} 142 | } 143 | 144 | // This example demonstrates how to use a ConfigState. 145 | func ExampleConfigState() { 146 | // Modify the indent level of the ConfigState only. The global 147 | // configuration is not modified. 148 | scs := spew.ConfigState{Indent: "\t"} 149 | 150 | // Output using the ConfigState instance. 151 | v := map[string]int{"one": 1} 152 | scs.Printf("v: %v\n", v) 153 | scs.Dump(v) 154 | 155 | // Output: 156 | // v: map[one:1] 157 | // (map[string]int) (len=1) { 158 | // (string) (len=3) "one": (int) 1 159 | // } 160 | } 161 | 162 | // This example demonstrates how to use ConfigState.Dump to dump variables to 163 | // stdout 164 | func ExampleConfigState_Dump() { 165 | // See the top-level Dump example for details on the types used in this 166 | // example. 167 | 168 | // Create two ConfigState instances with different indentation. 169 | scs := spew.ConfigState{Indent: "\t"} 170 | scs2 := spew.ConfigState{Indent: " "} 171 | 172 | // Setup some sample data structures for the example. 173 | bar := Bar{uintptr(0)} 174 | s1 := Foo{bar, map[interface{}]interface{}{"one": true}} 175 | 176 | // Dump using the ConfigState instances. 177 | scs.Dump(s1) 178 | scs2.Dump(s1) 179 | 180 | // Output: 181 | // (spew_test.Foo) { 182 | // unexportedField: (spew_test.Bar) { 183 | // data: (uintptr) 184 | // }, 185 | // ExportedField: (map[interface {}]interface {}) (len=1) { 186 | // (string) (len=3) "one": (bool) true 187 | // } 188 | // } 189 | // (spew_test.Foo) { 190 | // unexportedField: (spew_test.Bar) { 191 | // data: (uintptr) 192 | // }, 193 | // ExportedField: (map[interface {}]interface {}) (len=1) { 194 | // (string) (len=3) "one": (bool) true 195 | // } 196 | // } 197 | // 198 | } 199 | 200 | // This example demonstrates how to use ConfigState.Printf to display a variable 201 | // with a format string and inline formatting. 202 | func ExampleConfigState_Printf() { 203 | // See the top-level Dump example for details on the types used in this 204 | // example. 205 | 206 | // Create two ConfigState instances and modify the method handling of the 207 | // first ConfigState only. 208 | scs := spew.NewDefaultConfig() 209 | scs2 := spew.NewDefaultConfig() 210 | scs.DisableMethods = true 211 | 212 | // Alternatively 213 | // scs := spew.ConfigState{Indent: " ", DisableMethods: true} 214 | // scs2 := spew.ConfigState{Indent: " "} 215 | 216 | // This is of type Flag which implements a Stringer and has raw value 1. 217 | f := flagTwo 218 | 219 | // Dump using the ConfigState instances. 220 | scs.Printf("f: %v\n", f) 221 | scs2.Printf("f: %v\n", f) 222 | 223 | // Output: 224 | // f: 1 225 | // f: flagTwo 226 | } 227 | -------------------------------------------------------------------------------- /ecs/test_fixtures/task.json: -------------------------------------------------------------------------------- 1 | { 2 | "family": "pythonapp", 3 | "volumes": [ 4 | { 5 | "name": "host_etc", 6 | "host": { 7 | "sourcePath": "/etc" 8 | } 9 | }, 10 | { 11 | "name": "host_log", 12 | "host": { 13 | "sourcePath": "/var/log" 14 | }, 15 | "readOnly": true 16 | }, 17 | { 18 | "name": "empty", 19 | "host": {} 20 | } 21 | ], 22 | "containerDefinitions": [ 23 | { 24 | "cpu": 200, 25 | "essential": true, 26 | "name": "db", 27 | "memory": 2048, 28 | "image": "postgres:9.3" 29 | }, 30 | { 31 | "cpu": 200, 32 | "essential": true, 33 | "name": "dns", 34 | "memory": 1024, 35 | "image": "consul", 36 | "portMappings": [ 37 | { 38 | "protocol": "udp", 39 | "hostPort": 53, 40 | "containerPort": 53 41 | } 42 | ] 43 | }, 44 | { 45 | "cpu": 200, 46 | "entryPoint": [ 47 | "uwsgi" 48 | ], 49 | "command": [ 50 | "--json", 51 | "uwsgi.json" 52 | ], 53 | "essential": true, 54 | "name": "web2", 55 | "memory": 4, 56 | "image": "me/myapp" 57 | }, 58 | { 59 | "cpu": 200, 60 | "essential": true, 61 | "name": "logs", 62 | "memory": 4, 63 | "image": "me/mylogs", 64 | "volumesFrom": [ 65 | { 66 | "sourceContainer": "web", 67 | "readOnly": true 68 | }, 69 | { 70 | "sourceContainer": "web2" 71 | } 72 | ], 73 | "mountPoints": [ 74 | { 75 | "sourceVolume": "host_etc", 76 | "containerPath": "/usr/local/apache2/htdocs/host_etc" 77 | }, 78 | { 79 | "sourceVolume": "empty", 80 | "containerPath": "/usr/local/apache2/htdocs/empty_volume" 81 | }, 82 | { 83 | "sourceVolume": "host_log", 84 | "containerPath": "/var/log2/" 85 | } 86 | ] 87 | }, 88 | { 89 | "cpu": 200, 90 | "links": [ 91 | "db", 92 | "redis" 93 | ], 94 | "portMappings": [ 95 | { 96 | "hostPort": 8000, 97 | "containerPort": 8000 98 | }, 99 | { 100 | "hostPort": 8000, 101 | "containerPort": 8000 102 | }, 103 | { 104 | "hostPort": 8001, 105 | "containerPort": 8001 106 | }, 107 | { 108 | "hostPort": 8002, 109 | "containerPort": 8002 110 | }, 111 | { 112 | "containerPort": 8003 113 | } 114 | ], 115 | "memory": 64, 116 | "command": [ 117 | "uwsgi", 118 | "--json", 119 | "uwsgi.json" 120 | ], 121 | "environment": [ 122 | { 123 | "name": "AWS_SECRET_ACCESS_KEY", 124 | "value": "1111111111111111111111111111111111111111" 125 | }, 126 | { 127 | "name": "BROKER_URL", 128 | "value": "redis://redis:6379/0" 129 | }, 130 | { 131 | "name": "DB_PASS", 132 | "value": "postgres" 133 | }, 134 | { 135 | "name": "DB_USER", 136 | "value": "postgres" 137 | }, 138 | { 139 | "name": "AWS_EC2_REGION", 140 | "value": "us-east-1" 141 | }, 142 | { 143 | "name": "AWS_ACCESS_KEY_ID", 144 | "value": "AAAAAAAAAAAAAAAAAAAA" 145 | }, 146 | { 147 | "name": "DB_HOST", 148 | "value": "db" 149 | }, 150 | { 151 | "name": "DB_NAME", 152 | "value": "postgres" 153 | } 154 | ], 155 | "name": "web", 156 | "essential": true, 157 | "image": "me/myapp" 158 | }, 159 | { 160 | "cpu": 200, 161 | "links": [ 162 | "db", 163 | "redis", 164 | "web" 165 | ], 166 | "environment": [ 167 | { 168 | "name": "AWS_SECRET_ACCESS_KEY", 169 | "value": "1111111111111111111111111111111111111111" 170 | }, 171 | { 172 | "name": "BROKER_URL", 173 | "value": "redis://redis:6379/0" 174 | }, 175 | { 176 | "name": "DB_PAS", 177 | "value": "postgres" 178 | }, 179 | { 180 | "name": "DB_NAME", 181 | "value": "postgres" 182 | }, 183 | { 184 | "name": "AWS_EC2_REGION", 185 | "value": "us-east-1" 186 | }, 187 | { 188 | "name": "DB_USER", 189 | "value": "postgres" 190 | }, 191 | { 192 | "name": "AWS_ACCESS_KEY_ID", 193 | "value": "AAAAAAAAAAAAAAAAAAAA" 194 | }, 195 | { 196 | "name": "DB_HOST", 197 | "value": "db" 198 | } 199 | ], 200 | "memory": 64, 201 | "command": [ 202 | "celery", 203 | "worker" 204 | ], 205 | "essential": true, 206 | "name": "worker", 207 | "image": "me/myapp" 208 | }, 209 | { 210 | "cpu": 200, 211 | "essential": true, 212 | "name": "redis", 213 | "memory": 64, 214 | "dockerLabels": { 215 | "com.example.emptyvalue": "", 216 | "com.example.name": "web" 217 | }, 218 | "logConfiguration": { 219 | "logDriver": "gelf", 220 | "options": { 221 | "gelf-address": "udp://127.0.0.1:12900", 222 | "tag": "redis" 223 | } 224 | }, 225 | "entryPoint": [ 226 | "redis" 227 | ], 228 | "image": "redis:latest" 229 | 230 | } 231 | ] 232 | } 233 | -------------------------------------------------------------------------------- /vendor/gopkg.in/check.v1/helpers.go: -------------------------------------------------------------------------------- 1 | package check 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | "time" 7 | ) 8 | 9 | // TestName returns the current test name in the form "SuiteName.TestName" 10 | func (c *C) TestName() string { 11 | return c.testName 12 | } 13 | 14 | // ----------------------------------------------------------------------- 15 | // Basic succeeding/failing logic. 16 | 17 | // Failed returns whether the currently running test has already failed. 18 | func (c *C) Failed() bool { 19 | return c.status() == failedSt 20 | } 21 | 22 | // Fail marks the currently running test as failed. 23 | // 24 | // Something ought to have been previously logged so the developer can tell 25 | // what went wrong. The higher level helper functions will fail the test 26 | // and do the logging properly. 27 | func (c *C) Fail() { 28 | c.setStatus(failedSt) 29 | } 30 | 31 | // FailNow marks the currently running test as failed and stops running it. 32 | // Something ought to have been previously logged so the developer can tell 33 | // what went wrong. The higher level helper functions will fail the test 34 | // and do the logging properly. 35 | func (c *C) FailNow() { 36 | c.Fail() 37 | c.stopNow() 38 | } 39 | 40 | // Succeed marks the currently running test as succeeded, undoing any 41 | // previous failures. 42 | func (c *C) Succeed() { 43 | c.setStatus(succeededSt) 44 | } 45 | 46 | // SucceedNow marks the currently running test as succeeded, undoing any 47 | // previous failures, and stops running the test. 48 | func (c *C) SucceedNow() { 49 | c.Succeed() 50 | c.stopNow() 51 | } 52 | 53 | // ExpectFailure informs that the running test is knowingly broken for 54 | // the provided reason. If the test does not fail, an error will be reported 55 | // to raise attention to this fact. This method is useful to temporarily 56 | // disable tests which cover well known problems until a better time to 57 | // fix the problem is found, without forgetting about the fact that a 58 | // failure still exists. 59 | func (c *C) ExpectFailure(reason string) { 60 | if reason == "" { 61 | panic("Missing reason why the test is expected to fail") 62 | } 63 | c.mustFail = true 64 | c.reason = reason 65 | } 66 | 67 | // Skip skips the running test for the provided reason. If run from within 68 | // SetUpTest, the individual test being set up will be skipped, and if run 69 | // from within SetUpSuite, the whole suite is skipped. 70 | func (c *C) Skip(reason string) { 71 | if reason == "" { 72 | panic("Missing reason why the test is being skipped") 73 | } 74 | c.reason = reason 75 | c.setStatus(skippedSt) 76 | c.stopNow() 77 | } 78 | 79 | // ----------------------------------------------------------------------- 80 | // Basic logging. 81 | 82 | // GetTestLog returns the current test error output. 83 | func (c *C) GetTestLog() string { 84 | return c.logb.String() 85 | } 86 | 87 | // Log logs some information into the test error output. 88 | // The provided arguments are assembled together into a string with fmt.Sprint. 89 | func (c *C) Log(args ...interface{}) { 90 | c.log(args...) 91 | } 92 | 93 | // Log logs some information into the test error output. 94 | // The provided arguments are assembled together into a string with fmt.Sprintf. 95 | func (c *C) Logf(format string, args ...interface{}) { 96 | c.logf(format, args...) 97 | } 98 | 99 | // Output enables *C to be used as a logger in functions that require only 100 | // the minimum interface of *log.Logger. 101 | func (c *C) Output(calldepth int, s string) error { 102 | d := time.Now().Sub(c.startTime) 103 | msec := d / time.Millisecond 104 | sec := d / time.Second 105 | min := d / time.Minute 106 | 107 | c.Logf("[LOG] %d:%02d.%03d %s", min, sec%60, msec%1000, s) 108 | return nil 109 | } 110 | 111 | // Error logs an error into the test error output and marks the test as failed. 112 | // The provided arguments are assembled together into a string with fmt.Sprint. 113 | func (c *C) Error(args ...interface{}) { 114 | c.logCaller(1) 115 | c.logString(fmt.Sprint("Error: ", fmt.Sprint(args...))) 116 | c.logNewLine() 117 | c.Fail() 118 | } 119 | 120 | // Errorf logs an error into the test error output and marks the test as failed. 121 | // The provided arguments are assembled together into a string with fmt.Sprintf. 122 | func (c *C) Errorf(format string, args ...interface{}) { 123 | c.logCaller(1) 124 | c.logString(fmt.Sprintf("Error: "+format, args...)) 125 | c.logNewLine() 126 | c.Fail() 127 | } 128 | 129 | // Fatal logs an error into the test error output, marks the test as failed, and 130 | // stops the test execution. The provided arguments are assembled together into 131 | // a string with fmt.Sprint. 132 | func (c *C) Fatal(args ...interface{}) { 133 | c.logCaller(1) 134 | c.logString(fmt.Sprint("Error: ", fmt.Sprint(args...))) 135 | c.logNewLine() 136 | c.FailNow() 137 | } 138 | 139 | // Fatlaf logs an error into the test error output, marks the test as failed, and 140 | // stops the test execution. The provided arguments are assembled together into 141 | // a string with fmt.Sprintf. 142 | func (c *C) Fatalf(format string, args ...interface{}) { 143 | c.logCaller(1) 144 | c.logString(fmt.Sprint("Error: ", fmt.Sprintf(format, args...))) 145 | c.logNewLine() 146 | c.FailNow() 147 | } 148 | 149 | // ----------------------------------------------------------------------- 150 | // Generic checks and assertions based on checkers. 151 | 152 | // Check verifies if the first value matches the expected value according 153 | // to the provided checker. If they do not match, an error is logged, the 154 | // test is marked as failed, and the test execution continues. 155 | // 156 | // Some checkers may not need the expected argument (e.g. IsNil). 157 | // 158 | // Extra arguments provided to the function are logged next to the reported 159 | // problem when the matching fails. 160 | func (c *C) Check(obtained interface{}, checker Checker, args ...interface{}) bool { 161 | return c.internalCheck("Check", obtained, checker, args...) 162 | } 163 | 164 | // Assert ensures that the first value matches the expected value according 165 | // to the provided checker. If they do not match, an error is logged, the 166 | // test is marked as failed, and the test execution stops. 167 | // 168 | // Some checkers may not need the expected argument (e.g. IsNil). 169 | // 170 | // Extra arguments provided to the function are logged next to the reported 171 | // problem when the matching fails. 172 | func (c *C) Assert(obtained interface{}, checker Checker, args ...interface{}) { 173 | if !c.internalCheck("Assert", obtained, checker, args...) { 174 | c.stopNow() 175 | } 176 | } 177 | 178 | func (c *C) internalCheck(funcName string, obtained interface{}, checker Checker, args ...interface{}) bool { 179 | if checker == nil { 180 | c.logCaller(2) 181 | c.logString(fmt.Sprintf("%s(obtained, nil!?, ...):", funcName)) 182 | c.logString("Oops.. you've provided a nil checker!") 183 | c.logNewLine() 184 | c.Fail() 185 | return false 186 | } 187 | 188 | // If the last argument is a bug info, extract it out. 189 | var comment CommentInterface 190 | if len(args) > 0 { 191 | if c, ok := args[len(args)-1].(CommentInterface); ok { 192 | comment = c 193 | args = args[:len(args)-1] 194 | } 195 | } 196 | 197 | params := append([]interface{}{obtained}, args...) 198 | info := checker.Info() 199 | 200 | if len(params) != len(info.Params) { 201 | names := append([]string{info.Params[0], info.Name}, info.Params[1:]...) 202 | c.logCaller(2) 203 | c.logString(fmt.Sprintf("%s(%s):", funcName, strings.Join(names, ", "))) 204 | c.logString(fmt.Sprintf("Wrong number of parameters for %s: want %d, got %d", info.Name, len(names), len(params)+1)) 205 | c.logNewLine() 206 | c.Fail() 207 | return false 208 | } 209 | 210 | // Copy since it may be mutated by Check. 211 | names := append([]string{}, info.Params...) 212 | 213 | // Do the actual check. 214 | result, error := checker.Check(params, names) 215 | if !result || error != "" { 216 | c.logCaller(2) 217 | for i := 0; i != len(params); i++ { 218 | c.logValue(names[i], params[i]) 219 | } 220 | if comment != nil { 221 | c.logString(comment.CheckCommentString()) 222 | } 223 | if error != "" { 224 | c.logString(error) 225 | } 226 | c.logNewLine() 227 | c.Fail() 228 | return false 229 | } 230 | return true 231 | } 232 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://travis-ci.org/micahhausler/container-tx.svg)](https://travis-ci.org/micahhausler/container-tx) 2 | [![https://img.shields.io/badge/godoc-reference-5272B4.svg?style=flat-square](https://img.shields.io/badge/godoc-reference-5272B4.svg?style=flat-square)](http://godoc.org/github.com/micahhausler/container-tx/) 3 | 4 | # container-tx 5 | 6 | container-tx is a small utility to transform various docker container 7 | formats to one another. 8 | 9 | Currently, container-tx can accept and output to: 10 | 11 | * Docker-compose configuration files 12 | * ECS task definitions 13 | 14 | and it can output to: 15 | 16 | * docker cli run commmand 17 | 18 | Future support is planned for: 19 | 20 | * Marathon Application Definitions or Groups of Applications 21 | * Chronos Task Definitions 22 | * Kubernetes Deployment spec 23 | * Systemd unit files (output only) 24 | 25 | This is a re-implementation of [container-transform](https://github.com/micahhausler/container-transform) in go. 26 | 27 | ## Usage 28 | 29 | ``` 30 | Usage of ./container-tx: [flags] 31 | 32 | Valid input types: [compose ecs] 33 | Valid output types: [compose ecs cli] 34 | 35 | If no file is specified, defaults to STDIN 36 | 37 | -i, --input string 38 | The format of the input. (default "compose") 39 | -o, --output string 40 | The format of the output. (default "ecs") 41 | --version 42 | print version and exit 43 | ``` 44 | 45 | ## Examples 46 | 47 | * [Compose --> ECS](#docker-compose-to-ecs-Task) 48 | * [Compose --> CLI](#docker-compose-to-docker-cli) 49 | * [ECS --> Compose](#ecs-to-compose) 50 | 51 | ### docker-compose to ECS Task 52 | 53 | ``` 54 | $ cat docker-compose.yaml 55 | version: '2.0' 56 | services: 57 | web: 58 | dns: 59 | - 8.8.8.8 60 | image: "alpine" 61 | labels: 62 | com.example.description: "Accounting webapp" 63 | com.example.department: "Finance" 64 | com.example.label-with-empty-value: "" 65 | logging: 66 | driver: gelf 67 | options: 68 | tag: web 69 | gelf-address: "udp://127.0.0.1:12900" 70 | ports: 71 | - "5000:5000" 72 | - "5000" 73 | - "53:53/udp" 74 | volumes: 75 | - "/etc/ssl:/etc/ssl:ro" 76 | - .:/code 77 | $ cat docker-compose.yaml | ./container-tx 78 | { 79 | "family": "", 80 | "containerDefinitions": [ 81 | { 82 | "dnsServers": [ 83 | "8.8.8.8" 84 | ], 85 | "image": "alpine", 86 | "dockerLabels": { 87 | "com.example.department": "Finance", 88 | "com.example.description": "Accounting webapp", 89 | "com.example.label-with-empty-value": "" 90 | }, 91 | "logConfiguration": { 92 | "logDriver": "gelf", 93 | "options": { 94 | "gelf-address": "udp://127.0.0.1:12900", 95 | "tag": "web" 96 | } 97 | }, 98 | "memory": 4, 99 | "name": "web", 100 | "portMappings": [ 101 | { 102 | "hostPort": 53, 103 | "containerPort": 53, 104 | "protocol": "udp" 105 | }, 106 | { 107 | "hostPort": 5000, 108 | "containerPort": 5000, 109 | "protocol": "tcp" 110 | }, 111 | { 112 | "containerPort": 5000, 113 | "protocol": "tcp" 114 | } 115 | ], 116 | "mountPoints": [ 117 | { 118 | "sourceVolume": ".", 119 | "containerPath": "/code" 120 | }, 121 | { 122 | "sourceVolume": "etc-ssl", 123 | "containerPath": "/etc/ssl", 124 | "readOnly": true 125 | } 126 | ] 127 | } 128 | ], 129 | "volumes": [ 130 | { 131 | "name": "etc-ssl", 132 | "host": { 133 | "sourcePath": "/etc/ssl" 134 | } 135 | }, 136 | { 137 | "name": ".", 138 | "host": { 139 | "sourcePath": "." 140 | } 141 | } 142 | ] 143 | } 144 | ``` 145 | 146 | ### docker-compose to docker cli 147 | 148 | ``` 149 | $ cat docker-compose.yaml 150 | version: '2.0' 151 | services: 152 | web: 153 | dns: 154 | - 8.8.8.8 155 | image: "alpine" 156 | labels: 157 | com.example.description: "Accounting webapp" 158 | com.example.department: "Finance" 159 | com.example.label-with-empty-value: "" 160 | logging: 161 | driver: gelf 162 | options: 163 | tag: web 164 | gelf-address: "udp://127.0.0.1:12900" 165 | ports: 166 | - "5000:5000" 167 | - "5000" 168 | - "53:53/udp" 169 | volumes: 170 | - "/etc/ssl:/etc/ssl:ro" 171 | - .:/code 172 | $ container-tx -o script docker-compose.yaml 173 | ######## web ######## 174 | docker run \ 175 | --dns 8.8.8.8 \ 176 | --label com.example.department=Finance \ 177 | --label com.example.description=Accounting webapp \ 178 | --label com.example.label-with-empty-value= \ 179 | --log-driver gelf \ 180 | --log-opt gelf-address=udp://127.0.0.1:12900 \ 181 | --log-opt tag=web \ 182 | --name web \ 183 | --publish 5000:5000 \ 184 | --publish 5000 \ 185 | --publish 53:53/udp \ 186 | --volume /etc/ssl:/etc/ssl:ro \ 187 | --volume .:/code \ 188 | alpine 189 | ``` 190 | 191 | ### ECS to Compose 192 | 193 | ``` 194 | $ cat task.json 195 | { 196 | "family": "pythonapp", 197 | "volumes": [ 198 | { 199 | "name": "host_etc", 200 | "host": { 201 | "sourcePath": "/etc" 202 | } 203 | } 204 | ], 205 | "containerDefinitions": [ 206 | { 207 | "cpu": 200, 208 | "essential": true, 209 | "name": "db", 210 | "memory": 2048, 211 | "image": "postgres:9.3" 212 | }, 213 | { 214 | "cpu": 400, 215 | "links": [ 216 | "db" 217 | ], 218 | "mountPoints": [ 219 | { 220 | "sourceVolume": "host_etc", 221 | "containerPath": "/usr/local/etc", 222 | "readOnly": true 223 | } 224 | ], 225 | "portMappings": [ 226 | { 227 | "hostPort": 8000, 228 | "containerPort": 8000 229 | } 230 | ], 231 | "memory": 64, 232 | "entrypoint": [ 233 | "uwsgi" 234 | ], 235 | "command": [ 236 | "--json", 237 | "uwsgi.json" 238 | ], 239 | "environment": [ 240 | 241 | { 242 | "name": "BROKER_URL", 243 | "value": "redis://redis:6379/0" 244 | }, 245 | { 246 | "name": "PGPASSWORD", 247 | "value": "postgres" 248 | }, 249 | { 250 | "name": "PGUSER", 251 | "value": "postgres" 252 | }, 253 | { 254 | "name": "PGHOST", 255 | "value": "db" 256 | } 257 | ], 258 | "name": "web", 259 | "essential": true, 260 | "image": "me/myapp" 261 | } 262 | ] 263 | } 264 | $ ./container-tx -i ecs -o compose task.json 265 | version: "2" 266 | services: 267 | db: 268 | cpu_shares: 200 269 | image: postgres:9.3 270 | mem_limit: 2147483648 271 | web: 272 | command: --json uwsgi.json 273 | cpu_shares: 400 274 | entrypoint: uwsgi 275 | environment: 276 | values: 277 | BROKER_URL: redis://redis:6379/0 278 | PGHOST: db 279 | PGPASSWORD: postgres 280 | PGUSER: postgres 281 | image: me/myapp 282 | links: 283 | - db 284 | mem_limit: 67108864 285 | ports: 286 | - 8000:8000 287 | volumes: 288 | - /etc:/usr/local/etc:ro 289 | ``` 290 | 291 | ## Wishlist 292 | 293 | - [ ] Add tests/CI 294 | - [ ] Add docker builds to CI 295 | - [ ] Add a CHANGELOG 296 | - [ ] Script GitHub releases 297 | 298 | ## License 299 | MIT License. See [License](/LICENSE) for full text 300 | -------------------------------------------------------------------------------- /vendor/github.com/davecgh/go-spew/spew/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013 Dave Collins 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | /* 18 | Package spew implements a deep pretty printer for Go data structures to aid in 19 | debugging. 20 | 21 | A quick overview of the additional features spew provides over the built-in 22 | printing facilities for Go data types are as follows: 23 | 24 | * Pointers are dereferenced and followed 25 | * Circular data structures are detected and handled properly 26 | * Custom Stringer/error interfaces are optionally invoked, including 27 | on unexported types 28 | * Custom types which only implement the Stringer/error interfaces via 29 | a pointer receiver are optionally invoked when passing non-pointer 30 | variables 31 | * Byte arrays and slices are dumped like the hexdump -C command which 32 | includes offsets, byte values in hex, and ASCII output (only when using 33 | Dump style) 34 | 35 | There are two different approaches spew allows for dumping Go data structures: 36 | 37 | * Dump style which prints with newlines, customizable indentation, 38 | and additional debug information such as types and all pointer addresses 39 | used to indirect to the final value 40 | * A custom Formatter interface that integrates cleanly with the standard fmt 41 | package and replaces %v, %+v, %#v, and %#+v to provide inline printing 42 | similar to the default %v while providing the additional functionality 43 | outlined above and passing unsupported format verbs such as %x and %q 44 | along to fmt 45 | 46 | Quick Start 47 | 48 | This section demonstrates how to quickly get started with spew. See the 49 | sections below for further details on formatting and configuration options. 50 | 51 | To dump a variable with full newlines, indentation, type, and pointer 52 | information use Dump, Fdump, or Sdump: 53 | spew.Dump(myVar1, myVar2, ...) 54 | spew.Fdump(someWriter, myVar1, myVar2, ...) 55 | str := spew.Sdump(myVar1, myVar2, ...) 56 | 57 | Alternatively, if you would prefer to use format strings with a compacted inline 58 | printing style, use the convenience wrappers Printf, Fprintf, etc with 59 | %v (most compact), %+v (adds pointer addresses), %#v (adds types), or 60 | %#+v (adds types and pointer addresses): 61 | spew.Printf("myVar1: %v -- myVar2: %+v", myVar1, myVar2) 62 | spew.Printf("myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) 63 | spew.Fprintf(someWriter, "myVar1: %v -- myVar2: %+v", myVar1, myVar2) 64 | spew.Fprintf(someWriter, "myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) 65 | 66 | Configuration Options 67 | 68 | Configuration of spew is handled by fields in the ConfigState type. For 69 | convenience, all of the top-level functions use a global state available 70 | via the spew.Config global. 71 | 72 | It is also possible to create a ConfigState instance that provides methods 73 | equivalent to the top-level functions. This allows concurrent configuration 74 | options. See the ConfigState documentation for more details. 75 | 76 | The following configuration options are available: 77 | * Indent 78 | String to use for each indentation level for Dump functions. 79 | It is a single space by default. A popular alternative is "\t". 80 | 81 | * MaxDepth 82 | Maximum number of levels to descend into nested data structures. 83 | There is no limit by default. 84 | 85 | * DisableMethods 86 | Disables invocation of error and Stringer interface methods. 87 | Method invocation is enabled by default. 88 | 89 | * DisablePointerMethods 90 | Disables invocation of error and Stringer interface methods on types 91 | which only accept pointer receivers from non-pointer variables. 92 | Pointer method invocation is enabled by default. 93 | 94 | * ContinueOnMethod 95 | Enables recursion into types after invoking error and Stringer interface 96 | methods. Recursion after method invocation is disabled by default. 97 | 98 | * SortKeys 99 | Specifies map keys should be sorted before being printed. Use 100 | this to have a more deterministic, diffable output. Note that 101 | only native types (bool, int, uint, floats, uintptr and string) 102 | and types which implement error or Stringer interfaces are 103 | supported with other types sorted according to the 104 | reflect.Value.String() output which guarantees display 105 | stability. Natural map order is used by default. 106 | 107 | * SpewKeys 108 | Specifies that, as a last resort attempt, map keys should be 109 | spewed to strings and sorted by those strings. This is only 110 | considered if SortKeys is true. 111 | 112 | Dump Usage 113 | 114 | Simply call spew.Dump with a list of variables you want to dump: 115 | 116 | spew.Dump(myVar1, myVar2, ...) 117 | 118 | You may also call spew.Fdump if you would prefer to output to an arbitrary 119 | io.Writer. For example, to dump to standard error: 120 | 121 | spew.Fdump(os.Stderr, myVar1, myVar2, ...) 122 | 123 | A third option is to call spew.Sdump to get the formatted output as a string: 124 | 125 | str := spew.Sdump(myVar1, myVar2, ...) 126 | 127 | Sample Dump Output 128 | 129 | See the Dump example for details on the setup of the types and variables being 130 | shown here. 131 | 132 | (main.Foo) { 133 | unexportedField: (*main.Bar)(0xf84002e210)({ 134 | flag: (main.Flag) flagTwo, 135 | data: (uintptr) 136 | }), 137 | ExportedField: (map[interface {}]interface {}) (len=1) { 138 | (string) (len=3) "one": (bool) true 139 | } 140 | } 141 | 142 | Byte (and uint8) arrays and slices are displayed uniquely like the hexdump -C 143 | command as shown. 144 | ([]uint8) (len=32 cap=32) { 145 | 00000000 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 |............... | 146 | 00000010 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 |!"#$%&'()*+,-./0| 147 | 00000020 31 32 |12| 148 | } 149 | 150 | Custom Formatter 151 | 152 | Spew provides a custom formatter that implements the fmt.Formatter interface 153 | so that it integrates cleanly with standard fmt package printing functions. The 154 | formatter is useful for inline printing of smaller data types similar to the 155 | standard %v format specifier. 156 | 157 | The custom formatter only responds to the %v (most compact), %+v (adds pointer 158 | addresses), %#v (adds types), or %#+v (adds types and pointer addresses) verb 159 | combinations. Any other verbs such as %x and %q will be sent to the the 160 | standard fmt package for formatting. In addition, the custom formatter ignores 161 | the width and precision arguments (however they will still work on the format 162 | specifiers not handled by the custom formatter). 163 | 164 | Custom Formatter Usage 165 | 166 | The simplest way to make use of the spew custom formatter is to call one of the 167 | convenience functions such as spew.Printf, spew.Println, or spew.Printf. The 168 | functions have syntax you are most likely already familiar with: 169 | 170 | spew.Printf("myVar1: %v -- myVar2: %+v", myVar1, myVar2) 171 | spew.Printf("myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) 172 | spew.Println(myVar, myVar2) 173 | spew.Fprintf(os.Stderr, "myVar1: %v -- myVar2: %+v", myVar1, myVar2) 174 | spew.Fprintf(os.Stderr, "myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) 175 | 176 | See the Index for the full list convenience functions. 177 | 178 | Sample Formatter Output 179 | 180 | Double pointer to a uint8: 181 | %v: <**>5 182 | %+v: <**>(0xf8400420d0->0xf8400420c8)5 183 | %#v: (**uint8)5 184 | %#+v: (**uint8)(0xf8400420d0->0xf8400420c8)5 185 | 186 | Pointer to circular struct with a uint8 field and a pointer to itself: 187 | %v: <*>{1 <*>} 188 | %+v: <*>(0xf84003e260){ui8:1 c:<*>(0xf84003e260)} 189 | %#v: (*main.circular){ui8:(uint8)1 c:(*main.circular)} 190 | %#+v: (*main.circular)(0xf84003e260){ui8:(uint8)1 c:(*main.circular)(0xf84003e260)} 191 | 192 | See the Printf example for details on the setup of variables being shown 193 | here. 194 | 195 | Errors 196 | 197 | Since it is possible for custom Stringer/error interfaces to panic, spew 198 | detects them and handles them internally by printing the panic information 199 | inline with the output. Since spew is intended to provide deep pretty printing 200 | capabilities on structures, it intentionally does not return any errors. 201 | */ 202 | package spew 203 | -------------------------------------------------------------------------------- /vendor/github.com/davecgh/go-spew/spew/common_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013 Dave Collins 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | package spew_test 18 | 19 | import ( 20 | "fmt" 21 | "reflect" 22 | "testing" 23 | 24 | "github.com/davecgh/go-spew/spew" 25 | ) 26 | 27 | // custom type to test Stinger interface on non-pointer receiver. 28 | type stringer string 29 | 30 | // String implements the Stringer interface for testing invocation of custom 31 | // stringers on types with non-pointer receivers. 32 | func (s stringer) String() string { 33 | return "stringer " + string(s) 34 | } 35 | 36 | // custom type to test Stinger interface on pointer receiver. 37 | type pstringer string 38 | 39 | // String implements the Stringer interface for testing invocation of custom 40 | // stringers on types with only pointer receivers. 41 | func (s *pstringer) String() string { 42 | return "stringer " + string(*s) 43 | } 44 | 45 | // xref1 and xref2 are cross referencing structs for testing circular reference 46 | // detection. 47 | type xref1 struct { 48 | ps2 *xref2 49 | } 50 | type xref2 struct { 51 | ps1 *xref1 52 | } 53 | 54 | // indirCir1, indirCir2, and indirCir3 are used to generate an indirect circular 55 | // reference for testing detection. 56 | type indirCir1 struct { 57 | ps2 *indirCir2 58 | } 59 | type indirCir2 struct { 60 | ps3 *indirCir3 61 | } 62 | type indirCir3 struct { 63 | ps1 *indirCir1 64 | } 65 | 66 | // embed is used to test embedded structures. 67 | type embed struct { 68 | a string 69 | } 70 | 71 | // embedwrap is used to test embedded structures. 72 | type embedwrap struct { 73 | *embed 74 | e *embed 75 | } 76 | 77 | // panicer is used to intentionally cause a panic for testing spew properly 78 | // handles them 79 | type panicer int 80 | 81 | func (p panicer) String() string { 82 | panic("test panic") 83 | } 84 | 85 | // customError is used to test custom error interface invocation. 86 | type customError int 87 | 88 | func (e customError) Error() string { 89 | return fmt.Sprintf("error: %d", int(e)) 90 | } 91 | 92 | // stringizeWants converts a slice of wanted test output into a format suitable 93 | // for a test error message. 94 | func stringizeWants(wants []string) string { 95 | s := "" 96 | for i, want := range wants { 97 | if i > 0 { 98 | s += fmt.Sprintf("want%d: %s", i+1, want) 99 | } else { 100 | s += "want: " + want 101 | } 102 | } 103 | return s 104 | } 105 | 106 | // testFailed returns whether or not a test failed by checking if the result 107 | // of the test is in the slice of wanted strings. 108 | func testFailed(result string, wants []string) bool { 109 | for _, want := range wants { 110 | if result == want { 111 | return false 112 | } 113 | } 114 | return true 115 | } 116 | 117 | type sortableStruct struct { 118 | x int 119 | } 120 | 121 | func (ss sortableStruct) String() string { 122 | return fmt.Sprintf("ss.%d", ss.x) 123 | } 124 | 125 | type unsortableStruct struct { 126 | x int 127 | } 128 | 129 | type sortTestCase struct { 130 | input []reflect.Value 131 | expected []reflect.Value 132 | } 133 | 134 | func helpTestSortValues(tests []sortTestCase, cs *spew.ConfigState, t *testing.T) { 135 | getInterfaces := func(values []reflect.Value) []interface{} { 136 | interfaces := []interface{}{} 137 | for _, v := range values { 138 | interfaces = append(interfaces, v.Interface()) 139 | } 140 | return interfaces 141 | } 142 | 143 | for _, test := range tests { 144 | spew.SortValues(test.input, cs) 145 | // reflect.DeepEqual cannot really make sense of reflect.Value, 146 | // probably because of all the pointer tricks. For instance, 147 | // v(2.0) != v(2.0) on a 32-bits system. Turn them into interface{} 148 | // instead. 149 | input := getInterfaces(test.input) 150 | expected := getInterfaces(test.expected) 151 | if !reflect.DeepEqual(input, expected) { 152 | t.Errorf("Sort mismatch:\n %v != %v", input, expected) 153 | } 154 | } 155 | } 156 | 157 | // TestSortValues ensures the sort functionality for relect.Value based sorting 158 | // works as intended. 159 | func TestSortValues(t *testing.T) { 160 | v := reflect.ValueOf 161 | 162 | a := v("a") 163 | b := v("b") 164 | c := v("c") 165 | embedA := v(embed{"a"}) 166 | embedB := v(embed{"b"}) 167 | embedC := v(embed{"c"}) 168 | tests := []sortTestCase{ 169 | // No values. 170 | { 171 | []reflect.Value{}, 172 | []reflect.Value{}, 173 | }, 174 | // Bools. 175 | { 176 | []reflect.Value{v(false), v(true), v(false)}, 177 | []reflect.Value{v(false), v(false), v(true)}, 178 | }, 179 | // Ints. 180 | { 181 | []reflect.Value{v(2), v(1), v(3)}, 182 | []reflect.Value{v(1), v(2), v(3)}, 183 | }, 184 | // Uints. 185 | { 186 | []reflect.Value{v(uint8(2)), v(uint8(1)), v(uint8(3))}, 187 | []reflect.Value{v(uint8(1)), v(uint8(2)), v(uint8(3))}, 188 | }, 189 | // Floats. 190 | { 191 | []reflect.Value{v(2.0), v(1.0), v(3.0)}, 192 | []reflect.Value{v(1.0), v(2.0), v(3.0)}, 193 | }, 194 | // Strings. 195 | { 196 | []reflect.Value{b, a, c}, 197 | []reflect.Value{a, b, c}, 198 | }, 199 | // Array 200 | { 201 | []reflect.Value{v([3]int{3, 2, 1}), v([3]int{1, 3, 2}), v([3]int{1, 2, 3})}, 202 | []reflect.Value{v([3]int{1, 2, 3}), v([3]int{1, 3, 2}), v([3]int{3, 2, 1})}, 203 | }, 204 | // Uintptrs. 205 | { 206 | []reflect.Value{v(uintptr(2)), v(uintptr(1)), v(uintptr(3))}, 207 | []reflect.Value{v(uintptr(1)), v(uintptr(2)), v(uintptr(3))}, 208 | }, 209 | // SortableStructs. 210 | { 211 | // Note: not sorted - DisableMethods is set. 212 | []reflect.Value{v(sortableStruct{2}), v(sortableStruct{1}), v(sortableStruct{3})}, 213 | []reflect.Value{v(sortableStruct{2}), v(sortableStruct{1}), v(sortableStruct{3})}, 214 | }, 215 | // UnsortableStructs. 216 | { 217 | // Note: not sorted - SpewKeys is false. 218 | []reflect.Value{v(unsortableStruct{2}), v(unsortableStruct{1}), v(unsortableStruct{3})}, 219 | []reflect.Value{v(unsortableStruct{2}), v(unsortableStruct{1}), v(unsortableStruct{3})}, 220 | }, 221 | // Invalid. 222 | { 223 | []reflect.Value{embedB, embedA, embedC}, 224 | []reflect.Value{embedB, embedA, embedC}, 225 | }, 226 | } 227 | cs := spew.ConfigState{DisableMethods: true, SpewKeys: false} 228 | helpTestSortValues(tests, &cs, t) 229 | } 230 | 231 | // TestSortValuesWithMethods ensures the sort functionality for relect.Value 232 | // based sorting works as intended when using string methods. 233 | func TestSortValuesWithMethods(t *testing.T) { 234 | v := reflect.ValueOf 235 | 236 | a := v("a") 237 | b := v("b") 238 | c := v("c") 239 | tests := []sortTestCase{ 240 | // Ints. 241 | { 242 | []reflect.Value{v(2), v(1), v(3)}, 243 | []reflect.Value{v(1), v(2), v(3)}, 244 | }, 245 | // Strings. 246 | { 247 | []reflect.Value{b, a, c}, 248 | []reflect.Value{a, b, c}, 249 | }, 250 | // SortableStructs. 251 | { 252 | []reflect.Value{v(sortableStruct{2}), v(sortableStruct{1}), v(sortableStruct{3})}, 253 | []reflect.Value{v(sortableStruct{1}), v(sortableStruct{2}), v(sortableStruct{3})}, 254 | }, 255 | // UnsortableStructs. 256 | { 257 | // Note: not sorted - SpewKeys is false. 258 | []reflect.Value{v(unsortableStruct{2}), v(unsortableStruct{1}), v(unsortableStruct{3})}, 259 | []reflect.Value{v(unsortableStruct{2}), v(unsortableStruct{1}), v(unsortableStruct{3})}, 260 | }, 261 | } 262 | cs := spew.ConfigState{DisableMethods: false, SpewKeys: false} 263 | helpTestSortValues(tests, &cs, t) 264 | } 265 | 266 | // TestSortValuesWithSpew ensures the sort functionality for relect.Value 267 | // based sorting works as intended when using spew to stringify keys. 268 | func TestSortValuesWithSpew(t *testing.T) { 269 | v := reflect.ValueOf 270 | 271 | a := v("a") 272 | b := v("b") 273 | c := v("c") 274 | tests := []sortTestCase{ 275 | // Ints. 276 | { 277 | []reflect.Value{v(2), v(1), v(3)}, 278 | []reflect.Value{v(1), v(2), v(3)}, 279 | }, 280 | // Strings. 281 | { 282 | []reflect.Value{b, a, c}, 283 | []reflect.Value{a, b, c}, 284 | }, 285 | // SortableStructs. 286 | { 287 | []reflect.Value{v(sortableStruct{2}), v(sortableStruct{1}), v(sortableStruct{3})}, 288 | []reflect.Value{v(sortableStruct{1}), v(sortableStruct{2}), v(sortableStruct{3})}, 289 | }, 290 | // UnsortableStructs. 291 | { 292 | []reflect.Value{v(unsortableStruct{2}), v(unsortableStruct{1}), v(unsortableStruct{3})}, 293 | []reflect.Value{v(unsortableStruct{1}), v(unsortableStruct{2}), v(unsortableStruct{3})}, 294 | }, 295 | } 296 | cs := spew.ConfigState{DisableMethods: true, SpewKeys: true} 297 | helpTestSortValues(tests, &cs, t) 298 | } 299 | -------------------------------------------------------------------------------- /vendor/github.com/davecgh/go-spew/spew/spew_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013 Dave Collins 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | package spew_test 18 | 19 | import ( 20 | "bytes" 21 | "fmt" 22 | "io/ioutil" 23 | "os" 24 | "testing" 25 | 26 | "github.com/davecgh/go-spew/spew" 27 | ) 28 | 29 | // spewFunc is used to identify which public function of the spew package or 30 | // ConfigState a test applies to. 31 | type spewFunc int 32 | 33 | const ( 34 | fCSFdump spewFunc = iota 35 | fCSFprint 36 | fCSFprintf 37 | fCSFprintln 38 | fCSPrint 39 | fCSPrintln 40 | fCSSdump 41 | fCSSprint 42 | fCSSprintf 43 | fCSSprintln 44 | fCSErrorf 45 | fCSNewFormatter 46 | fErrorf 47 | fFprint 48 | fFprintln 49 | fPrint 50 | fPrintln 51 | fSdump 52 | fSprint 53 | fSprintf 54 | fSprintln 55 | ) 56 | 57 | // Map of spewFunc values to names for pretty printing. 58 | var spewFuncStrings = map[spewFunc]string{ 59 | fCSFdump: "ConfigState.Fdump", 60 | fCSFprint: "ConfigState.Fprint", 61 | fCSFprintf: "ConfigState.Fprintf", 62 | fCSFprintln: "ConfigState.Fprintln", 63 | fCSSdump: "ConfigState.Sdump", 64 | fCSPrint: "ConfigState.Print", 65 | fCSPrintln: "ConfigState.Println", 66 | fCSSprint: "ConfigState.Sprint", 67 | fCSSprintf: "ConfigState.Sprintf", 68 | fCSSprintln: "ConfigState.Sprintln", 69 | fCSErrorf: "ConfigState.Errorf", 70 | fCSNewFormatter: "ConfigState.NewFormatter", 71 | fErrorf: "spew.Errorf", 72 | fFprint: "spew.Fprint", 73 | fFprintln: "spew.Fprintln", 74 | fPrint: "spew.Print", 75 | fPrintln: "spew.Println", 76 | fSdump: "spew.Sdump", 77 | fSprint: "spew.Sprint", 78 | fSprintf: "spew.Sprintf", 79 | fSprintln: "spew.Sprintln", 80 | } 81 | 82 | func (f spewFunc) String() string { 83 | if s, ok := spewFuncStrings[f]; ok { 84 | return s 85 | } 86 | return fmt.Sprintf("Unknown spewFunc (%d)", int(f)) 87 | } 88 | 89 | // spewTest is used to describe a test to be performed against the public 90 | // functions of the spew package or ConfigState. 91 | type spewTest struct { 92 | cs *spew.ConfigState 93 | f spewFunc 94 | format string 95 | in interface{} 96 | want string 97 | } 98 | 99 | // spewTests houses the tests to be performed against the public functions of 100 | // the spew package and ConfigState. 101 | // 102 | // These tests are only intended to ensure the public functions are exercised 103 | // and are intentionally not exhaustive of types. The exhaustive type 104 | // tests are handled in the dump and format tests. 105 | var spewTests []spewTest 106 | 107 | // redirStdout is a helper function to return the standard output from f as a 108 | // byte slice. 109 | func redirStdout(f func()) ([]byte, error) { 110 | tempFile, err := ioutil.TempFile("", "ss-test") 111 | if err != nil { 112 | return nil, err 113 | } 114 | fileName := tempFile.Name() 115 | defer os.Remove(fileName) // Ignore error 116 | 117 | origStdout := os.Stdout 118 | os.Stdout = tempFile 119 | f() 120 | os.Stdout = origStdout 121 | tempFile.Close() 122 | 123 | return ioutil.ReadFile(fileName) 124 | } 125 | 126 | func initSpewTests() { 127 | // Config states with various settings. 128 | scsDefault := spew.NewDefaultConfig() 129 | scsNoMethods := &spew.ConfigState{Indent: " ", DisableMethods: true} 130 | scsNoPmethods := &spew.ConfigState{Indent: " ", DisablePointerMethods: true} 131 | scsMaxDepth := &spew.ConfigState{Indent: " ", MaxDepth: 1} 132 | scsContinue := &spew.ConfigState{Indent: " ", ContinueOnMethod: true} 133 | 134 | // Variables for tests on types which implement Stringer interface with and 135 | // without a pointer receiver. 136 | ts := stringer("test") 137 | tps := pstringer("test") 138 | 139 | // depthTester is used to test max depth handling for structs, array, slices 140 | // and maps. 141 | type depthTester struct { 142 | ic indirCir1 143 | arr [1]string 144 | slice []string 145 | m map[string]int 146 | } 147 | dt := depthTester{indirCir1{nil}, [1]string{"arr"}, []string{"slice"}, 148 | map[string]int{"one": 1}} 149 | 150 | // Variable for tests on types which implement error interface. 151 | te := customError(10) 152 | 153 | spewTests = []spewTest{ 154 | {scsDefault, fCSFdump, "", int8(127), "(int8) 127\n"}, 155 | {scsDefault, fCSFprint, "", int16(32767), "32767"}, 156 | {scsDefault, fCSFprintf, "%v", int32(2147483647), "2147483647"}, 157 | {scsDefault, fCSFprintln, "", int(2147483647), "2147483647\n"}, 158 | {scsDefault, fCSPrint, "", int64(9223372036854775807), "9223372036854775807"}, 159 | {scsDefault, fCSPrintln, "", uint8(255), "255\n"}, 160 | {scsDefault, fCSSdump, "", uint8(64), "(uint8) 64\n"}, 161 | {scsDefault, fCSSprint, "", complex(1, 2), "(1+2i)"}, 162 | {scsDefault, fCSSprintf, "%v", complex(float32(3), 4), "(3+4i)"}, 163 | {scsDefault, fCSSprintln, "", complex(float64(5), 6), "(5+6i)\n"}, 164 | {scsDefault, fCSErrorf, "%#v", uint16(65535), "(uint16)65535"}, 165 | {scsDefault, fCSNewFormatter, "%v", uint32(4294967295), "4294967295"}, 166 | {scsDefault, fErrorf, "%v", uint64(18446744073709551615), "18446744073709551615"}, 167 | {scsDefault, fFprint, "", float32(3.14), "3.14"}, 168 | {scsDefault, fFprintln, "", float64(6.28), "6.28\n"}, 169 | {scsDefault, fPrint, "", true, "true"}, 170 | {scsDefault, fPrintln, "", false, "false\n"}, 171 | {scsDefault, fSdump, "", complex(-10, -20), "(complex128) (-10-20i)\n"}, 172 | {scsDefault, fSprint, "", complex(-1, -2), "(-1-2i)"}, 173 | {scsDefault, fSprintf, "%v", complex(float32(-3), -4), "(-3-4i)"}, 174 | {scsDefault, fSprintln, "", complex(float64(-5), -6), "(-5-6i)\n"}, 175 | {scsNoMethods, fCSFprint, "", ts, "test"}, 176 | {scsNoMethods, fCSFprint, "", &ts, "<*>test"}, 177 | {scsNoMethods, fCSFprint, "", tps, "test"}, 178 | {scsNoMethods, fCSFprint, "", &tps, "<*>test"}, 179 | {scsNoPmethods, fCSFprint, "", ts, "stringer test"}, 180 | {scsNoPmethods, fCSFprint, "", &ts, "<*>stringer test"}, 181 | {scsNoPmethods, fCSFprint, "", tps, "test"}, 182 | {scsNoPmethods, fCSFprint, "", &tps, "<*>stringer test"}, 183 | {scsMaxDepth, fCSFprint, "", dt, "{{} [] [] map[]}"}, 184 | {scsMaxDepth, fCSFdump, "", dt, "(spew_test.depthTester) {\n" + 185 | " ic: (spew_test.indirCir1) {\n \n },\n" + 186 | " arr: ([1]string) (len=1 cap=1) {\n \n },\n" + 187 | " slice: ([]string) (len=1 cap=1) {\n \n },\n" + 188 | " m: (map[string]int) (len=1) {\n \n }\n}\n"}, 189 | {scsContinue, fCSFprint, "", ts, "(stringer test) test"}, 190 | {scsContinue, fCSFdump, "", ts, "(spew_test.stringer) " + 191 | "(len=4) (stringer test) \"test\"\n"}, 192 | {scsContinue, fCSFprint, "", te, "(error: 10) 10"}, 193 | {scsContinue, fCSFdump, "", te, "(spew_test.customError) " + 194 | "(error: 10) 10\n"}, 195 | } 196 | } 197 | 198 | // TestSpew executes all of the tests described by spewTests. 199 | func TestSpew(t *testing.T) { 200 | initSpewTests() 201 | 202 | t.Logf("Running %d tests", len(spewTests)) 203 | for i, test := range spewTests { 204 | buf := new(bytes.Buffer) 205 | switch test.f { 206 | case fCSFdump: 207 | test.cs.Fdump(buf, test.in) 208 | 209 | case fCSFprint: 210 | test.cs.Fprint(buf, test.in) 211 | 212 | case fCSFprintf: 213 | test.cs.Fprintf(buf, test.format, test.in) 214 | 215 | case fCSFprintln: 216 | test.cs.Fprintln(buf, test.in) 217 | 218 | case fCSPrint: 219 | b, err := redirStdout(func() { test.cs.Print(test.in) }) 220 | if err != nil { 221 | t.Errorf("%v #%d %v", test.f, i, err) 222 | continue 223 | } 224 | buf.Write(b) 225 | 226 | case fCSPrintln: 227 | b, err := redirStdout(func() { test.cs.Println(test.in) }) 228 | if err != nil { 229 | t.Errorf("%v #%d %v", test.f, i, err) 230 | continue 231 | } 232 | buf.Write(b) 233 | 234 | case fCSSdump: 235 | str := test.cs.Sdump(test.in) 236 | buf.WriteString(str) 237 | 238 | case fCSSprint: 239 | str := test.cs.Sprint(test.in) 240 | buf.WriteString(str) 241 | 242 | case fCSSprintf: 243 | str := test.cs.Sprintf(test.format, test.in) 244 | buf.WriteString(str) 245 | 246 | case fCSSprintln: 247 | str := test.cs.Sprintln(test.in) 248 | buf.WriteString(str) 249 | 250 | case fCSErrorf: 251 | err := test.cs.Errorf(test.format, test.in) 252 | buf.WriteString(err.Error()) 253 | 254 | case fCSNewFormatter: 255 | fmt.Fprintf(buf, test.format, test.cs.NewFormatter(test.in)) 256 | 257 | case fErrorf: 258 | err := spew.Errorf(test.format, test.in) 259 | buf.WriteString(err.Error()) 260 | 261 | case fFprint: 262 | spew.Fprint(buf, test.in) 263 | 264 | case fFprintln: 265 | spew.Fprintln(buf, test.in) 266 | 267 | case fPrint: 268 | b, err := redirStdout(func() { spew.Print(test.in) }) 269 | if err != nil { 270 | t.Errorf("%v #%d %v", test.f, i, err) 271 | continue 272 | } 273 | buf.Write(b) 274 | 275 | case fPrintln: 276 | b, err := redirStdout(func() { spew.Println(test.in) }) 277 | if err != nil { 278 | t.Errorf("%v #%d %v", test.f, i, err) 279 | continue 280 | } 281 | buf.Write(b) 282 | 283 | case fSdump: 284 | str := spew.Sdump(test.in) 285 | buf.WriteString(str) 286 | 287 | case fSprint: 288 | str := spew.Sprint(test.in) 289 | buf.WriteString(str) 290 | 291 | case fSprintf: 292 | str := spew.Sprintf(test.format, test.in) 293 | buf.WriteString(str) 294 | 295 | case fSprintln: 296 | str := spew.Sprintln(test.in) 297 | buf.WriteString(str) 298 | 299 | default: 300 | t.Errorf("%v #%d unrecognized function", test.f, i) 301 | continue 302 | } 303 | s := buf.String() 304 | if test.want != s { 305 | t.Errorf("ConfigState #%d\n got: %s want: %s", i, s, test.want) 306 | continue 307 | } 308 | } 309 | } 310 | -------------------------------------------------------------------------------- /vendor/gopkg.in/check.v1/foundation_test.go: -------------------------------------------------------------------------------- 1 | // These tests check that the foundations of gocheck are working properly. 2 | // They already assume that fundamental failing is working already, though, 3 | // since this was tested in bootstrap_test.go. Even then, some care may 4 | // still have to be taken when using external functions, since they should 5 | // of course not rely on functionality tested here. 6 | 7 | package check_test 8 | 9 | import ( 10 | "fmt" 11 | "gopkg.in/check.v1" 12 | "log" 13 | "os" 14 | "regexp" 15 | "strings" 16 | ) 17 | 18 | // ----------------------------------------------------------------------- 19 | // Foundation test suite. 20 | 21 | type FoundationS struct{} 22 | 23 | var foundationS = check.Suite(&FoundationS{}) 24 | 25 | func (s *FoundationS) TestCountSuite(c *check.C) { 26 | suitesRun += 1 27 | } 28 | 29 | func (s *FoundationS) TestErrorf(c *check.C) { 30 | // Do not use checkState() here. It depends on Errorf() working. 31 | expectedLog := fmt.Sprintf("foundation_test.go:%d:\n"+ 32 | " c.Errorf(\"Error %%v!\", \"message\")\n"+ 33 | "... Error: Error message!\n\n", 34 | getMyLine()+1) 35 | c.Errorf("Error %v!", "message") 36 | failed := c.Failed() 37 | c.Succeed() 38 | if log := c.GetTestLog(); log != expectedLog { 39 | c.Logf("Errorf() logged %#v rather than %#v", log, expectedLog) 40 | c.Fail() 41 | } 42 | if !failed { 43 | c.Logf("Errorf() didn't put the test in a failed state") 44 | c.Fail() 45 | } 46 | } 47 | 48 | func (s *FoundationS) TestError(c *check.C) { 49 | expectedLog := fmt.Sprintf("foundation_test.go:%d:\n"+ 50 | " c\\.Error\\(\"Error \", \"message!\"\\)\n"+ 51 | "\\.\\.\\. Error: Error message!\n\n", 52 | getMyLine()+1) 53 | c.Error("Error ", "message!") 54 | checkState(c, nil, 55 | &expectedState{ 56 | name: "Error(`Error `, `message!`)", 57 | failed: true, 58 | log: expectedLog, 59 | }) 60 | } 61 | 62 | func (s *FoundationS) TestFailNow(c *check.C) { 63 | defer (func() { 64 | if !c.Failed() { 65 | c.Error("FailNow() didn't fail the test") 66 | } else { 67 | c.Succeed() 68 | if c.GetTestLog() != "" { 69 | c.Error("Something got logged:\n" + c.GetTestLog()) 70 | } 71 | } 72 | })() 73 | 74 | c.FailNow() 75 | c.Log("FailNow() didn't stop the test") 76 | } 77 | 78 | func (s *FoundationS) TestSucceedNow(c *check.C) { 79 | defer (func() { 80 | if c.Failed() { 81 | c.Error("SucceedNow() didn't succeed the test") 82 | } 83 | if c.GetTestLog() != "" { 84 | c.Error("Something got logged:\n" + c.GetTestLog()) 85 | } 86 | })() 87 | 88 | c.Fail() 89 | c.SucceedNow() 90 | c.Log("SucceedNow() didn't stop the test") 91 | } 92 | 93 | func (s *FoundationS) TestFailureHeader(c *check.C) { 94 | output := String{} 95 | failHelper := FailHelper{} 96 | check.Run(&failHelper, &check.RunConf{Output: &output}) 97 | header := fmt.Sprintf(""+ 98 | "\n-----------------------------------"+ 99 | "-----------------------------------\n"+ 100 | "FAIL: check_test.go:%d: FailHelper.TestLogAndFail\n", 101 | failHelper.testLine) 102 | if strings.Index(output.value, header) == -1 { 103 | c.Errorf(""+ 104 | "Failure didn't print a proper header.\n"+ 105 | "... Got:\n%s... Expected something with:\n%s", 106 | output.value, header) 107 | } 108 | } 109 | 110 | func (s *FoundationS) TestFatal(c *check.C) { 111 | var line int 112 | defer (func() { 113 | if !c.Failed() { 114 | c.Error("Fatal() didn't fail the test") 115 | } else { 116 | c.Succeed() 117 | expected := fmt.Sprintf("foundation_test.go:%d:\n"+ 118 | " c.Fatal(\"Die \", \"now!\")\n"+ 119 | "... Error: Die now!\n\n", 120 | line) 121 | if c.GetTestLog() != expected { 122 | c.Error("Incorrect log:", c.GetTestLog()) 123 | } 124 | } 125 | })() 126 | 127 | line = getMyLine() + 1 128 | c.Fatal("Die ", "now!") 129 | c.Log("Fatal() didn't stop the test") 130 | } 131 | 132 | func (s *FoundationS) TestFatalf(c *check.C) { 133 | var line int 134 | defer (func() { 135 | if !c.Failed() { 136 | c.Error("Fatalf() didn't fail the test") 137 | } else { 138 | c.Succeed() 139 | expected := fmt.Sprintf("foundation_test.go:%d:\n"+ 140 | " c.Fatalf(\"Die %%s!\", \"now\")\n"+ 141 | "... Error: Die now!\n\n", 142 | line) 143 | if c.GetTestLog() != expected { 144 | c.Error("Incorrect log:", c.GetTestLog()) 145 | } 146 | } 147 | })() 148 | 149 | line = getMyLine() + 1 150 | c.Fatalf("Die %s!", "now") 151 | c.Log("Fatalf() didn't stop the test") 152 | } 153 | 154 | func (s *FoundationS) TestCallerLoggingInsideTest(c *check.C) { 155 | log := fmt.Sprintf(""+ 156 | "foundation_test.go:%d:\n"+ 157 | " result := c.Check\\(10, check.Equals, 20\\)\n"+ 158 | "\\.\\.\\. obtained int = 10\n"+ 159 | "\\.\\.\\. expected int = 20\n\n", 160 | getMyLine()+1) 161 | result := c.Check(10, check.Equals, 20) 162 | checkState(c, result, 163 | &expectedState{ 164 | name: "Check(10, Equals, 20)", 165 | result: false, 166 | failed: true, 167 | log: log, 168 | }) 169 | } 170 | 171 | func (s *FoundationS) TestCallerLoggingInDifferentFile(c *check.C) { 172 | result, line := checkEqualWrapper(c, 10, 20) 173 | testLine := getMyLine() - 1 174 | log := fmt.Sprintf(""+ 175 | "foundation_test.go:%d:\n"+ 176 | " result, line := checkEqualWrapper\\(c, 10, 20\\)\n"+ 177 | "check_test.go:%d:\n"+ 178 | " return c.Check\\(obtained, check.Equals, expected\\), getMyLine\\(\\)\n"+ 179 | "\\.\\.\\. obtained int = 10\n"+ 180 | "\\.\\.\\. expected int = 20\n\n", 181 | testLine, line) 182 | checkState(c, result, 183 | &expectedState{ 184 | name: "Check(10, Equals, 20)", 185 | result: false, 186 | failed: true, 187 | log: log, 188 | }) 189 | } 190 | 191 | // ----------------------------------------------------------------------- 192 | // ExpectFailure() inverts the logic of failure. 193 | 194 | type ExpectFailureSucceedHelper struct{} 195 | 196 | func (s *ExpectFailureSucceedHelper) TestSucceed(c *check.C) { 197 | c.ExpectFailure("It booms!") 198 | c.Error("Boom!") 199 | } 200 | 201 | type ExpectFailureFailHelper struct{} 202 | 203 | func (s *ExpectFailureFailHelper) TestFail(c *check.C) { 204 | c.ExpectFailure("Bug #XYZ") 205 | } 206 | 207 | func (s *FoundationS) TestExpectFailureFail(c *check.C) { 208 | helper := ExpectFailureFailHelper{} 209 | output := String{} 210 | result := check.Run(&helper, &check.RunConf{Output: &output}) 211 | 212 | expected := "" + 213 | "^\n-+\n" + 214 | "FAIL: foundation_test\\.go:[0-9]+:" + 215 | " ExpectFailureFailHelper\\.TestFail\n\n" + 216 | "\\.\\.\\. Error: Test succeeded, but was expected to fail\n" + 217 | "\\.\\.\\. Reason: Bug #XYZ\n$" 218 | 219 | matched, err := regexp.MatchString(expected, output.value) 220 | if err != nil { 221 | c.Error("Bad expression: ", expected) 222 | } else if !matched { 223 | c.Error("ExpectFailure() didn't log properly:\n", output.value) 224 | } 225 | 226 | c.Assert(result.ExpectedFailures, check.Equals, 0) 227 | } 228 | 229 | func (s *FoundationS) TestExpectFailureSucceed(c *check.C) { 230 | helper := ExpectFailureSucceedHelper{} 231 | output := String{} 232 | result := check.Run(&helper, &check.RunConf{Output: &output}) 233 | 234 | c.Assert(output.value, check.Equals, "") 235 | c.Assert(result.ExpectedFailures, check.Equals, 1) 236 | } 237 | 238 | func (s *FoundationS) TestExpectFailureSucceedVerbose(c *check.C) { 239 | helper := ExpectFailureSucceedHelper{} 240 | output := String{} 241 | result := check.Run(&helper, &check.RunConf{Output: &output, Verbose: true}) 242 | 243 | expected := "" + 244 | "FAIL EXPECTED: foundation_test\\.go:[0-9]+:" + 245 | " ExpectFailureSucceedHelper\\.TestSucceed \\(It booms!\\)\t *[.0-9]+s\n" 246 | 247 | matched, err := regexp.MatchString(expected, output.value) 248 | if err != nil { 249 | c.Error("Bad expression: ", expected) 250 | } else if !matched { 251 | c.Error("ExpectFailure() didn't log properly:\n", output.value) 252 | } 253 | 254 | c.Assert(result.ExpectedFailures, check.Equals, 1) 255 | } 256 | 257 | // ----------------------------------------------------------------------- 258 | // Skip() allows stopping a test without positive/negative results. 259 | 260 | type SkipTestHelper struct{} 261 | 262 | func (s *SkipTestHelper) TestFail(c *check.C) { 263 | c.Skip("Wrong platform or whatever") 264 | c.Error("Boom!") 265 | } 266 | 267 | func (s *FoundationS) TestSkip(c *check.C) { 268 | helper := SkipTestHelper{} 269 | output := String{} 270 | check.Run(&helper, &check.RunConf{Output: &output}) 271 | 272 | if output.value != "" { 273 | c.Error("Skip() logged something:\n", output.value) 274 | } 275 | } 276 | 277 | func (s *FoundationS) TestSkipVerbose(c *check.C) { 278 | helper := SkipTestHelper{} 279 | output := String{} 280 | check.Run(&helper, &check.RunConf{Output: &output, Verbose: true}) 281 | 282 | expected := "SKIP: foundation_test\\.go:[0-9]+: SkipTestHelper\\.TestFail" + 283 | " \\(Wrong platform or whatever\\)" 284 | matched, err := regexp.MatchString(expected, output.value) 285 | if err != nil { 286 | c.Error("Bad expression: ", expected) 287 | } else if !matched { 288 | c.Error("Skip() didn't log properly:\n", output.value) 289 | } 290 | } 291 | 292 | // ----------------------------------------------------------------------- 293 | // Check minimum *log.Logger interface provided by *check.C. 294 | 295 | type minLogger interface { 296 | Output(calldepth int, s string) error 297 | } 298 | 299 | func (s *BootstrapS) TestMinLogger(c *check.C) { 300 | var logger minLogger 301 | logger = log.New(os.Stderr, "", 0) 302 | logger = c 303 | logger.Output(0, "Hello there") 304 | expected := `\[LOG\] [0-9]+:[0-9][0-9]\.[0-9][0-9][0-9] +Hello there\n` 305 | output := c.GetTestLog() 306 | c.Assert(output, check.Matches, expected) 307 | } 308 | 309 | // ----------------------------------------------------------------------- 310 | // Ensure that suites with embedded types are working fine, including the 311 | // the workaround for issue 906. 312 | 313 | type EmbeddedInternalS struct { 314 | called bool 315 | } 316 | 317 | type EmbeddedS struct { 318 | EmbeddedInternalS 319 | } 320 | 321 | var embeddedS = check.Suite(&EmbeddedS{}) 322 | 323 | func (s *EmbeddedS) TestCountSuite(c *check.C) { 324 | suitesRun += 1 325 | } 326 | 327 | func (s *EmbeddedInternalS) TestMethod(c *check.C) { 328 | c.Error("TestMethod() of the embedded type was called!?") 329 | } 330 | 331 | func (s *EmbeddedS) TestMethod(c *check.C) { 332 | // http://code.google.com/p/go/issues/detail?id=906 333 | c.Check(s.called, check.Equals, false) // Go issue 906 is affecting the runner? 334 | s.called = true 335 | } 336 | -------------------------------------------------------------------------------- /vendor/gopkg.in/check.v1/checkers_test.go: -------------------------------------------------------------------------------- 1 | package check_test 2 | 3 | import ( 4 | "errors" 5 | "gopkg.in/check.v1" 6 | "reflect" 7 | "runtime" 8 | ) 9 | 10 | type CheckersS struct{} 11 | 12 | var _ = check.Suite(&CheckersS{}) 13 | 14 | func testInfo(c *check.C, checker check.Checker, name string, paramNames []string) { 15 | info := checker.Info() 16 | if info.Name != name { 17 | c.Fatalf("Got name %s, expected %s", info.Name, name) 18 | } 19 | if !reflect.DeepEqual(info.Params, paramNames) { 20 | c.Fatalf("Got param names %#v, expected %#v", info.Params, paramNames) 21 | } 22 | } 23 | 24 | func testCheck(c *check.C, checker check.Checker, result bool, error string, params ...interface{}) ([]interface{}, []string) { 25 | info := checker.Info() 26 | if len(params) != len(info.Params) { 27 | c.Fatalf("unexpected param count in test; expected %d got %d", len(info.Params), len(params)) 28 | } 29 | names := append([]string{}, info.Params...) 30 | result_, error_ := checker.Check(params, names) 31 | if result_ != result || error_ != error { 32 | c.Fatalf("%s.Check(%#v) returned (%#v, %#v) rather than (%#v, %#v)", 33 | info.Name, params, result_, error_, result, error) 34 | } 35 | return params, names 36 | } 37 | 38 | func (s *CheckersS) TestComment(c *check.C) { 39 | bug := check.Commentf("a %d bc", 42) 40 | comment := bug.CheckCommentString() 41 | if comment != "a 42 bc" { 42 | c.Fatalf("Commentf returned %#v", comment) 43 | } 44 | } 45 | 46 | func (s *CheckersS) TestIsNil(c *check.C) { 47 | testInfo(c, check.IsNil, "IsNil", []string{"value"}) 48 | 49 | testCheck(c, check.IsNil, true, "", nil) 50 | testCheck(c, check.IsNil, false, "", "a") 51 | 52 | testCheck(c, check.IsNil, true, "", (chan int)(nil)) 53 | testCheck(c, check.IsNil, false, "", make(chan int)) 54 | testCheck(c, check.IsNil, true, "", (error)(nil)) 55 | testCheck(c, check.IsNil, false, "", errors.New("")) 56 | testCheck(c, check.IsNil, true, "", ([]int)(nil)) 57 | testCheck(c, check.IsNil, false, "", make([]int, 1)) 58 | testCheck(c, check.IsNil, false, "", int(0)) 59 | } 60 | 61 | func (s *CheckersS) TestNotNil(c *check.C) { 62 | testInfo(c, check.NotNil, "NotNil", []string{"value"}) 63 | 64 | testCheck(c, check.NotNil, false, "", nil) 65 | testCheck(c, check.NotNil, true, "", "a") 66 | 67 | testCheck(c, check.NotNil, false, "", (chan int)(nil)) 68 | testCheck(c, check.NotNil, true, "", make(chan int)) 69 | testCheck(c, check.NotNil, false, "", (error)(nil)) 70 | testCheck(c, check.NotNil, true, "", errors.New("")) 71 | testCheck(c, check.NotNil, false, "", ([]int)(nil)) 72 | testCheck(c, check.NotNil, true, "", make([]int, 1)) 73 | } 74 | 75 | func (s *CheckersS) TestNot(c *check.C) { 76 | testInfo(c, check.Not(check.IsNil), "Not(IsNil)", []string{"value"}) 77 | 78 | testCheck(c, check.Not(check.IsNil), false, "", nil) 79 | testCheck(c, check.Not(check.IsNil), true, "", "a") 80 | } 81 | 82 | type simpleStruct struct { 83 | i int 84 | } 85 | 86 | func (s *CheckersS) TestEquals(c *check.C) { 87 | testInfo(c, check.Equals, "Equals", []string{"obtained", "expected"}) 88 | 89 | // The simplest. 90 | testCheck(c, check.Equals, true, "", 42, 42) 91 | testCheck(c, check.Equals, false, "", 42, 43) 92 | 93 | // Different native types. 94 | testCheck(c, check.Equals, false, "", int32(42), int64(42)) 95 | 96 | // With nil. 97 | testCheck(c, check.Equals, false, "", 42, nil) 98 | 99 | // Slices 100 | testCheck(c, check.Equals, false, "runtime error: comparing uncomparable type []uint8", []byte{1, 2}, []byte{1, 2}) 101 | 102 | // Struct values 103 | testCheck(c, check.Equals, true, "", simpleStruct{1}, simpleStruct{1}) 104 | testCheck(c, check.Equals, false, "", simpleStruct{1}, simpleStruct{2}) 105 | 106 | // Struct pointers 107 | testCheck(c, check.Equals, false, "", &simpleStruct{1}, &simpleStruct{1}) 108 | testCheck(c, check.Equals, false, "", &simpleStruct{1}, &simpleStruct{2}) 109 | } 110 | 111 | func (s *CheckersS) TestDeepEquals(c *check.C) { 112 | testInfo(c, check.DeepEquals, "DeepEquals", []string{"obtained", "expected"}) 113 | 114 | // The simplest. 115 | testCheck(c, check.DeepEquals, true, "", 42, 42) 116 | testCheck(c, check.DeepEquals, false, "", 42, 43) 117 | 118 | // Different native types. 119 | testCheck(c, check.DeepEquals, false, "", int32(42), int64(42)) 120 | 121 | // With nil. 122 | testCheck(c, check.DeepEquals, false, "", 42, nil) 123 | 124 | // Slices 125 | testCheck(c, check.DeepEquals, true, "", []byte{1, 2}, []byte{1, 2}) 126 | testCheck(c, check.DeepEquals, false, "", []byte{1, 2}, []byte{1, 3}) 127 | 128 | // Struct values 129 | testCheck(c, check.DeepEquals, true, "", simpleStruct{1}, simpleStruct{1}) 130 | testCheck(c, check.DeepEquals, false, "", simpleStruct{1}, simpleStruct{2}) 131 | 132 | // Struct pointers 133 | testCheck(c, check.DeepEquals, true, "", &simpleStruct{1}, &simpleStruct{1}) 134 | testCheck(c, check.DeepEquals, false, "", &simpleStruct{1}, &simpleStruct{2}) 135 | } 136 | 137 | func (s *CheckersS) TestHasLen(c *check.C) { 138 | testInfo(c, check.HasLen, "HasLen", []string{"obtained", "n"}) 139 | 140 | testCheck(c, check.HasLen, true, "", "abcd", 4) 141 | testCheck(c, check.HasLen, true, "", []int{1, 2}, 2) 142 | testCheck(c, check.HasLen, false, "", []int{1, 2}, 3) 143 | 144 | testCheck(c, check.HasLen, false, "n must be an int", []int{1, 2}, "2") 145 | testCheck(c, check.HasLen, false, "obtained value type has no length", nil, 2) 146 | } 147 | 148 | func (s *CheckersS) TestErrorMatches(c *check.C) { 149 | testInfo(c, check.ErrorMatches, "ErrorMatches", []string{"value", "regex"}) 150 | 151 | testCheck(c, check.ErrorMatches, false, "Error value is nil", nil, "some error") 152 | testCheck(c, check.ErrorMatches, false, "Value is not an error", 1, "some error") 153 | testCheck(c, check.ErrorMatches, true, "", errors.New("some error"), "some error") 154 | testCheck(c, check.ErrorMatches, true, "", errors.New("some error"), "so.*or") 155 | 156 | // Verify params mutation 157 | params, names := testCheck(c, check.ErrorMatches, false, "", errors.New("some error"), "other error") 158 | c.Assert(params[0], check.Equals, "some error") 159 | c.Assert(names[0], check.Equals, "error") 160 | } 161 | 162 | func (s *CheckersS) TestMatches(c *check.C) { 163 | testInfo(c, check.Matches, "Matches", []string{"value", "regex"}) 164 | 165 | // Simple matching 166 | testCheck(c, check.Matches, true, "", "abc", "abc") 167 | testCheck(c, check.Matches, true, "", "abc", "a.c") 168 | 169 | // Must match fully 170 | testCheck(c, check.Matches, false, "", "abc", "ab") 171 | testCheck(c, check.Matches, false, "", "abc", "bc") 172 | 173 | // String()-enabled values accepted 174 | testCheck(c, check.Matches, true, "", reflect.ValueOf("abc"), "a.c") 175 | testCheck(c, check.Matches, false, "", reflect.ValueOf("abc"), "a.d") 176 | 177 | // Some error conditions. 178 | testCheck(c, check.Matches, false, "Obtained value is not a string and has no .String()", 1, "a.c") 179 | testCheck(c, check.Matches, false, "Can't compile regex: error parsing regexp: missing closing ]: `[c$`", "abc", "a[c") 180 | } 181 | 182 | func (s *CheckersS) TestPanics(c *check.C) { 183 | testInfo(c, check.Panics, "Panics", []string{"function", "expected"}) 184 | 185 | // Some errors. 186 | testCheck(c, check.Panics, false, "Function has not panicked", func() bool { return false }, "BOOM") 187 | testCheck(c, check.Panics, false, "Function must take zero arguments", 1, "BOOM") 188 | 189 | // Plain strings. 190 | testCheck(c, check.Panics, true, "", func() { panic("BOOM") }, "BOOM") 191 | testCheck(c, check.Panics, false, "", func() { panic("KABOOM") }, "BOOM") 192 | testCheck(c, check.Panics, true, "", func() bool { panic("BOOM") }, "BOOM") 193 | 194 | // Error values. 195 | testCheck(c, check.Panics, true, "", func() { panic(errors.New("BOOM")) }, errors.New("BOOM")) 196 | testCheck(c, check.Panics, false, "", func() { panic(errors.New("KABOOM")) }, errors.New("BOOM")) 197 | 198 | type deep struct{ i int } 199 | // Deep value 200 | testCheck(c, check.Panics, true, "", func() { panic(&deep{99}) }, &deep{99}) 201 | 202 | // Verify params/names mutation 203 | params, names := testCheck(c, check.Panics, false, "", func() { panic(errors.New("KABOOM")) }, errors.New("BOOM")) 204 | c.Assert(params[0], check.ErrorMatches, "KABOOM") 205 | c.Assert(names[0], check.Equals, "panic") 206 | 207 | // Verify a nil panic 208 | testCheck(c, check.Panics, true, "", func() { panic(nil) }, nil) 209 | testCheck(c, check.Panics, false, "", func() { panic(nil) }, "NOPE") 210 | } 211 | 212 | func (s *CheckersS) TestPanicMatches(c *check.C) { 213 | testInfo(c, check.PanicMatches, "PanicMatches", []string{"function", "expected"}) 214 | 215 | // Error matching. 216 | testCheck(c, check.PanicMatches, true, "", func() { panic(errors.New("BOOM")) }, "BO.M") 217 | testCheck(c, check.PanicMatches, false, "", func() { panic(errors.New("KABOOM")) }, "BO.M") 218 | 219 | // Some errors. 220 | testCheck(c, check.PanicMatches, false, "Function has not panicked", func() bool { return false }, "BOOM") 221 | testCheck(c, check.PanicMatches, false, "Function must take zero arguments", 1, "BOOM") 222 | 223 | // Plain strings. 224 | testCheck(c, check.PanicMatches, true, "", func() { panic("BOOM") }, "BO.M") 225 | testCheck(c, check.PanicMatches, false, "", func() { panic("KABOOM") }, "BOOM") 226 | testCheck(c, check.PanicMatches, true, "", func() bool { panic("BOOM") }, "BO.M") 227 | 228 | // Verify params/names mutation 229 | params, names := testCheck(c, check.PanicMatches, false, "", func() { panic(errors.New("KABOOM")) }, "BOOM") 230 | c.Assert(params[0], check.Equals, "KABOOM") 231 | c.Assert(names[0], check.Equals, "panic") 232 | 233 | // Verify a nil panic 234 | testCheck(c, check.PanicMatches, false, "Panic value is not a string or an error", func() { panic(nil) }, "") 235 | } 236 | 237 | func (s *CheckersS) TestFitsTypeOf(c *check.C) { 238 | testInfo(c, check.FitsTypeOf, "FitsTypeOf", []string{"obtained", "sample"}) 239 | 240 | // Basic types 241 | testCheck(c, check.FitsTypeOf, true, "", 1, 0) 242 | testCheck(c, check.FitsTypeOf, false, "", 1, int64(0)) 243 | 244 | // Aliases 245 | testCheck(c, check.FitsTypeOf, false, "", 1, errors.New("")) 246 | testCheck(c, check.FitsTypeOf, false, "", "error", errors.New("")) 247 | testCheck(c, check.FitsTypeOf, true, "", errors.New("error"), errors.New("")) 248 | 249 | // Structures 250 | testCheck(c, check.FitsTypeOf, false, "", 1, simpleStruct{}) 251 | testCheck(c, check.FitsTypeOf, false, "", simpleStruct{42}, &simpleStruct{}) 252 | testCheck(c, check.FitsTypeOf, true, "", simpleStruct{42}, simpleStruct{}) 253 | testCheck(c, check.FitsTypeOf, true, "", &simpleStruct{42}, &simpleStruct{}) 254 | 255 | // Some bad values 256 | testCheck(c, check.FitsTypeOf, false, "Invalid sample value", 1, interface{}(nil)) 257 | testCheck(c, check.FitsTypeOf, false, "", interface{}(nil), 0) 258 | } 259 | 260 | func (s *CheckersS) TestImplements(c *check.C) { 261 | testInfo(c, check.Implements, "Implements", []string{"obtained", "ifaceptr"}) 262 | 263 | var e error 264 | var re runtime.Error 265 | testCheck(c, check.Implements, true, "", errors.New(""), &e) 266 | testCheck(c, check.Implements, false, "", errors.New(""), &re) 267 | 268 | // Some bad values 269 | testCheck(c, check.Implements, false, "ifaceptr should be a pointer to an interface variable", 0, errors.New("")) 270 | testCheck(c, check.Implements, false, "ifaceptr should be a pointer to an interface variable", 0, interface{}(nil)) 271 | testCheck(c, check.Implements, false, "", interface{}(nil), &e) 272 | } 273 | -------------------------------------------------------------------------------- /compose/compose.go: -------------------------------------------------------------------------------- 1 | package compose 2 | 3 | import ( 4 | "io" 5 | "io/ioutil" 6 | "sort" 7 | "strconv" 8 | "strings" 9 | 10 | "github.com/micahhausler/container-tx/transform" 11 | "gopkg.in/yaml.v2" 12 | ) 13 | 14 | // UnmarshalYAML implements a custom unmarshal to accommodate both of compose's 15 | // string and struct formats 16 | func (b *Build) UnmarshalYAML(unmarshal func(interface{}) error) error { 17 | var bc BuildContext 18 | err := unmarshal(&bc) 19 | if err != nil { 20 | var ctx string 21 | err := unmarshal(&ctx) 22 | if err != nil { 23 | return err 24 | } 25 | bc.Context = ctx 26 | } 27 | b.Ctx = bc 28 | return nil 29 | } 30 | 31 | // Build is a struct for Compose build info 32 | type Build struct { 33 | Ctx BuildContext 34 | } 35 | 36 | // BuildContext is a build context type for Compose 37 | type BuildContext struct { 38 | Context string `yaml:"context,omitempty"` 39 | Dockerfile string `yaml:"dockerfile,omitempty"` 40 | Args map[string]string `yaml:"args,omitempty"` 41 | } 42 | 43 | func (c Container) ingestBuild() *transform.BuildContext { 44 | if c.Build != nil { 45 | bc := &transform.BuildContext{ 46 | Context: c.Build.Ctx.Context, 47 | Dockerfile: c.Build.Ctx.Dockerfile, 48 | Args: c.Build.Ctx.Args, 49 | } 50 | return bc 51 | } 52 | return nil 53 | } 54 | 55 | func (c *Container) emitBuild(in *transform.BuildContext) { 56 | if in != nil { 57 | c.Build = &Build{ 58 | BuildContext{ 59 | Context: in.Context, 60 | Dockerfile: in.Dockerfile, 61 | Args: in.Args, 62 | }, 63 | } 64 | } 65 | } 66 | 67 | func parseComposePortMapping(line string) *transform.PortMapping { 68 | pm := &transform.PortMapping{Protocol: "tcp"} 69 | if strings.HasSuffix(line, "/udp") { 70 | line = strings.TrimSuffix(line, "/udp") 71 | pm.Protocol = "udp" 72 | } 73 | parts := strings.Split(line, ":") 74 | if len(parts) == 1 { 75 | port, err := strconv.Atoi(parts[0]) 76 | if err != nil { 77 | panic(err) 78 | } 79 | pm.ContainerPort = port 80 | } else if len(parts) == 2 { 81 | port, err := strconv.Atoi(parts[0]) 82 | if err != nil { 83 | panic(err) 84 | } 85 | pm.HostPort = port 86 | port, err = strconv.Atoi(parts[1]) 87 | if err != nil { 88 | panic(err) 89 | } 90 | pm.ContainerPort = port 91 | } else if len(parts) == 3 { 92 | pm.HostIP = parts[0] 93 | port, err := strconv.Atoi(parts[1]) 94 | if err != nil { 95 | panic(err) 96 | } 97 | pm.HostPort = port 98 | port, err = strconv.Atoi(parts[2]) 99 | if err != nil { 100 | panic(err) 101 | } 102 | pm.ContainerPort = port 103 | } 104 | return pm 105 | } 106 | 107 | func (c Container) ingestPortMappings() *transform.PortMappings { 108 | if len(c.PortMappings) > 0 { 109 | response := transform.PortMappings{} 110 | for _, pm := range c.PortMappings { 111 | response = append(response, *parseComposePortMapping(pm)) 112 | } 113 | return &response 114 | } 115 | return nil 116 | } 117 | 118 | func (c *Container) emitPortMappings(mappings *transform.PortMappings) { 119 | if mappings == nil { 120 | return 121 | } 122 | output := []string{} 123 | for _, mapping := range *mappings { 124 | portStr := []string{} 125 | if mapping.HostPort > 0 { 126 | portStr = append(portStr, mapping.HostIP) 127 | 128 | } 129 | if mapping.HostPort > 0 { 130 | portStr = append(portStr, strconv.Itoa(mapping.HostPort)) 131 | } 132 | if mapping.ContainerPort > 0 { 133 | portStr = append(portStr, strconv.Itoa(mapping.ContainerPort)) 134 | } 135 | 136 | portData := strings.Trim(strings.Join(portStr, ":"), ":") 137 | if len(portData) > 0 { 138 | if strings.Compare(mapping.Protocol, "udp") == 0 { 139 | portData = portData + "/udp" 140 | } 141 | output = append(output, portData) 142 | } 143 | } 144 | if len(output) > 0 { 145 | c.PortMappings = output 146 | } 147 | } 148 | 149 | // Logging is a logging type for compose 150 | type Logging struct { 151 | Driver string 152 | Options map[string]string 153 | } 154 | 155 | func (c Container) ingestLogging() *transform.Logging { 156 | if c.Logging != nil { 157 | return &transform.Logging{ 158 | Driver: c.Logging.Driver, 159 | Options: c.Logging.Options, 160 | } 161 | } 162 | return nil 163 | } 164 | 165 | func (c *Container) emitLogging(l *transform.Logging) { 166 | if l != nil { 167 | c.Logging = &Logging{ 168 | Driver: l.Driver, 169 | Options: l.Options, 170 | } 171 | } 172 | } 173 | 174 | // UnmarshalYAML allows for deserializing compose's "k=v" and "k: v" formats 175 | func (kv *KV) UnmarshalYAML(unmarshal func(interface{}) error) error { 176 | err := unmarshal(&kv.Values) 177 | if err != nil { 178 | var keyValues []string 179 | err = unmarshal(&keyValues) 180 | if err != nil { 181 | return err 182 | } 183 | response := map[string]string{} 184 | for _, kvString := range keyValues { 185 | parts := strings.SplitN(kvString, "=", 2) 186 | if len(parts) > 1 { 187 | response[parts[0]] = parts[1] 188 | } else { 189 | response[parts[0]] = "" 190 | } 191 | } 192 | kv.Values = response 193 | } 194 | return nil 195 | } 196 | 197 | // KV is a special type for Labels and Environment variables 198 | // since compose allows "k=v" and "k: v" formats 199 | type KV struct { 200 | Values map[string]string 201 | } 202 | 203 | func (c Container) ingestVolumes() *transform.IntermediateVolumes { 204 | if len(c.Volumes) > 0 { 205 | response := transform.IntermediateVolumes{} 206 | for _, vol := range c.Volumes { 207 | iv := transform.IntermediateVolume{ReadOnly: false} 208 | parts := strings.Split(vol, ":") 209 | if len(parts) == 1 { 210 | iv.Container = parts[0] 211 | } else if len(parts) == 2 { 212 | iv.Host = parts[0] 213 | iv.Container = parts[1] 214 | } else if len(parts) == 3 { 215 | iv.Host = parts[0] 216 | iv.Container = parts[1] 217 | if parts[2] == "ro" { 218 | iv.ReadOnly = true 219 | } 220 | } 221 | response = append(response, iv) 222 | } 223 | return &response 224 | } 225 | return nil 226 | } 227 | 228 | func (c *Container) emitVolumes(vols *transform.IntermediateVolumes) { 229 | if vols == nil { 230 | return 231 | } 232 | output := []string{} 233 | for _, volume := range *vols { 234 | readOnly := "" 235 | if volume.ReadOnly { 236 | readOnly = "ro" 237 | } 238 | volStr := []string{volume.Host, volume.Container, readOnly} 239 | volData := strings.Trim(strings.Join(volStr, ":"), ":") 240 | output = append(output, volData) 241 | } 242 | 243 | if len(output) > 0 { 244 | c.Volumes = output 245 | } 246 | } 247 | 248 | // Container is a type for deserializing docker-compose containers 249 | type Container struct { 250 | Build *Build `yaml:"build,omitempty"` 251 | Command string `yaml:"command,omitempty"` 252 | CPU int `yaml:"cpu_shares,omitempty"` 253 | DNS []string `yaml:"dns,omitempty"` 254 | Domain []string `yaml:"dns_search,omitempty"` 255 | Entrypoint string `yaml:"entrypoint,omitempty"` 256 | EnvFile []string `yaml:"env_file,omitempty"` 257 | Environment KV `yaml:"environment,omitempty"` 258 | Expose []int `yaml:"expose,omitempty"` 259 | Hostname string `yaml:"hostname,omitempty"` 260 | Image string `yaml:"image,omitempty"` 261 | Labels KV `yaml:"labels,omitempty"` 262 | Links []string `yaml:"links,omitempty"` 263 | Logging *Logging `yaml:"logging,omitempty"` 264 | Memory int `yaml:"mem_limit,omitempty"` 265 | Name string `yaml:"-"` 266 | Network []string `yaml:"networks,omitempty"` 267 | NetworkMode string `yaml:"network_mode,omitempty"` 268 | Pid string `yaml:"pid,omitempty"` 269 | PortMappings []string `yaml:"ports,omitempty"` 270 | Privileged bool `yaml:"privileged,omitempty"` 271 | User string `yaml:"user,omitempty"` 272 | Volumes []string `yaml:"volumes,omitempty"` 273 | VolumesFrom []string `yaml:"volumes_from,omitempty"` 274 | WorkDir string `yaml:"working_dir,omitempty"` 275 | } 276 | 277 | // DockerCompose implements InputFormat and OutputFormat 278 | type DockerCompose struct { 279 | Version string `yaml:"version"` 280 | Services map[string]*Container `yaml:"services"` 281 | } 282 | 283 | // IngestContainers satisfies InputFormat so docker-compose containers can be ingested 284 | func (dc DockerCompose) IngestContainers(input io.ReadCloser) (*transform.PodData, error) { 285 | 286 | body, err := ioutil.ReadAll(input) 287 | defer input.Close() 288 | if err != nil && err != io.EOF { 289 | return nil, err 290 | } 291 | err = yaml.Unmarshal(body, &dc) 292 | if err != nil { 293 | return nil, err 294 | } 295 | 296 | outputPod := transform.PodData{} 297 | 298 | containers := transform.Containers{} 299 | 300 | for serviceName, container := range dc.Services { 301 | 302 | ir := transform.Container{} 303 | ir.Build = container.ingestBuild() 304 | ir.Command = container.Command 305 | ir.CPU = container.CPU 306 | ir.DNS = container.DNS 307 | ir.Domain = container.Domain 308 | ir.Entrypoint = container.Entrypoint 309 | ir.EnvFile = container.EnvFile 310 | ir.Environment = container.Environment.Values 311 | ir.Expose = container.Expose 312 | ir.Hostname = container.Hostname 313 | ir.Image = container.Image 314 | ir.Labels = container.Labels.Values 315 | ir.Links = container.Links 316 | ir.Logging = container.ingestLogging() 317 | ir.Memory = container.Memory 318 | ir.Name = serviceName 319 | ir.Network = container.Network 320 | ir.NetworkMode = container.NetworkMode 321 | ir.Pid = container.Pid 322 | ir.PortMappings = container.ingestPortMappings() 323 | ir.Privileged = container.Privileged 324 | ir.User = container.User 325 | ir.Volumes = container.ingestVolumes() 326 | ir.VolumesFrom = container.VolumesFrom 327 | ir.WorkDir = container.WorkDir 328 | containers = append(containers, ir) 329 | 330 | } 331 | sort.Sort(containers) 332 | outputPod.Containers = &containers 333 | return &outputPod, nil 334 | } 335 | 336 | // EmitContainers satisfies OutputFormat so docker-compose containers can be emitted 337 | func (dc DockerCompose) EmitContainers(input *transform.PodData) ([]byte, error) { 338 | output := &DockerCompose{Version: "2"} 339 | output.Services = map[string]*Container{} 340 | 341 | for _, container := range *input.Containers { 342 | composeContainer := Container{} 343 | output.Services[container.Name] = &composeContainer 344 | 345 | composeContainer.emitBuild(container.Build) 346 | composeContainer.Command = container.Command 347 | composeContainer.CPU = container.CPU 348 | composeContainer.DNS = container.DNS 349 | composeContainer.Domain = container.Domain 350 | composeContainer.Entrypoint = container.Entrypoint 351 | composeContainer.EnvFile = container.EnvFile 352 | composeContainer.Environment = KV{Values: container.Environment} 353 | composeContainer.Expose = container.Expose 354 | composeContainer.Hostname = container.Hostname 355 | composeContainer.Image = container.Image 356 | composeContainer.Labels = KV{Values: container.Labels} 357 | composeContainer.Links = container.Links 358 | composeContainer.emitLogging(container.Logging) 359 | composeContainer.Memory = container.Memory 360 | composeContainer.Network = container.Network 361 | composeContainer.NetworkMode = container.NetworkMode 362 | composeContainer.Pid = container.Pid 363 | composeContainer.emitPortMappings(container.PortMappings) 364 | composeContainer.Privileged = container.Privileged 365 | composeContainer.User = container.User 366 | composeContainer.emitVolumes(container.Volumes) 367 | composeContainer.VolumesFrom = container.VolumesFrom 368 | composeContainer.WorkDir = container.WorkDir 369 | } 370 | return yaml.Marshal(output) 371 | } 372 | -------------------------------------------------------------------------------- /vendor/github.com/davecgh/go-spew/spew/common.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013 Dave Collins 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | package spew 18 | 19 | import ( 20 | "bytes" 21 | "fmt" 22 | "io" 23 | "reflect" 24 | "sort" 25 | "strconv" 26 | ) 27 | 28 | // Some constants in the form of bytes to avoid string overhead. This mirrors 29 | // the technique used in the fmt package. 30 | var ( 31 | panicBytes = []byte("(PANIC=") 32 | plusBytes = []byte("+") 33 | iBytes = []byte("i") 34 | trueBytes = []byte("true") 35 | falseBytes = []byte("false") 36 | interfaceBytes = []byte("(interface {})") 37 | commaNewlineBytes = []byte(",\n") 38 | newlineBytes = []byte("\n") 39 | openBraceBytes = []byte("{") 40 | openBraceNewlineBytes = []byte("{\n") 41 | closeBraceBytes = []byte("}") 42 | asteriskBytes = []byte("*") 43 | colonBytes = []byte(":") 44 | colonSpaceBytes = []byte(": ") 45 | openParenBytes = []byte("(") 46 | closeParenBytes = []byte(")") 47 | spaceBytes = []byte(" ") 48 | pointerChainBytes = []byte("->") 49 | nilAngleBytes = []byte("") 50 | maxNewlineBytes = []byte("\n") 51 | maxShortBytes = []byte("") 52 | circularBytes = []byte("") 53 | circularShortBytes = []byte("") 54 | invalidAngleBytes = []byte("") 55 | openBracketBytes = []byte("[") 56 | closeBracketBytes = []byte("]") 57 | percentBytes = []byte("%") 58 | precisionBytes = []byte(".") 59 | openAngleBytes = []byte("<") 60 | closeAngleBytes = []byte(">") 61 | openMapBytes = []byte("map[") 62 | closeMapBytes = []byte("]") 63 | lenEqualsBytes = []byte("len=") 64 | capEqualsBytes = []byte("cap=") 65 | ) 66 | 67 | // hexDigits is used to map a decimal value to a hex digit. 68 | var hexDigits = "0123456789abcdef" 69 | 70 | // catchPanic handles any panics that might occur during the handleMethods 71 | // calls. 72 | func catchPanic(w io.Writer, v reflect.Value) { 73 | if err := recover(); err != nil { 74 | w.Write(panicBytes) 75 | fmt.Fprintf(w, "%v", err) 76 | w.Write(closeParenBytes) 77 | } 78 | } 79 | 80 | // handleMethods attempts to call the Error and String methods on the underlying 81 | // type the passed reflect.Value represents and outputes the result to Writer w. 82 | // 83 | // It handles panics in any called methods by catching and displaying the error 84 | // as the formatted value. 85 | func handleMethods(cs *ConfigState, w io.Writer, v reflect.Value) (handled bool) { 86 | // We need an interface to check if the type implements the error or 87 | // Stringer interface. However, the reflect package won't give us an 88 | // interface on certain things like unexported struct fields in order 89 | // to enforce visibility rules. We use unsafe, when it's available, 90 | // to bypass these restrictions since this package does not mutate the 91 | // values. 92 | if !v.CanInterface() { 93 | if UnsafeDisabled { 94 | return false 95 | } 96 | 97 | v = unsafeReflectValue(v) 98 | } 99 | 100 | // Choose whether or not to do error and Stringer interface lookups against 101 | // the base type or a pointer to the base type depending on settings. 102 | // Technically calling one of these methods with a pointer receiver can 103 | // mutate the value, however, types which choose to satisify an error or 104 | // Stringer interface with a pointer receiver should not be mutating their 105 | // state inside these interface methods. 106 | if !cs.DisablePointerMethods && !UnsafeDisabled && !v.CanAddr() { 107 | v = unsafeReflectValue(v) 108 | } 109 | if v.CanAddr() { 110 | v = v.Addr() 111 | } 112 | 113 | // Is it an error or Stringer? 114 | switch iface := v.Interface().(type) { 115 | case error: 116 | defer catchPanic(w, v) 117 | if cs.ContinueOnMethod { 118 | w.Write(openParenBytes) 119 | w.Write([]byte(iface.Error())) 120 | w.Write(closeParenBytes) 121 | w.Write(spaceBytes) 122 | return false 123 | } 124 | 125 | w.Write([]byte(iface.Error())) 126 | return true 127 | 128 | case fmt.Stringer: 129 | defer catchPanic(w, v) 130 | if cs.ContinueOnMethod { 131 | w.Write(openParenBytes) 132 | w.Write([]byte(iface.String())) 133 | w.Write(closeParenBytes) 134 | w.Write(spaceBytes) 135 | return false 136 | } 137 | w.Write([]byte(iface.String())) 138 | return true 139 | } 140 | return false 141 | } 142 | 143 | // printBool outputs a boolean value as true or false to Writer w. 144 | func printBool(w io.Writer, val bool) { 145 | if val { 146 | w.Write(trueBytes) 147 | } else { 148 | w.Write(falseBytes) 149 | } 150 | } 151 | 152 | // printInt outputs a signed integer value to Writer w. 153 | func printInt(w io.Writer, val int64, base int) { 154 | w.Write([]byte(strconv.FormatInt(val, base))) 155 | } 156 | 157 | // printUint outputs an unsigned integer value to Writer w. 158 | func printUint(w io.Writer, val uint64, base int) { 159 | w.Write([]byte(strconv.FormatUint(val, base))) 160 | } 161 | 162 | // printFloat outputs a floating point value using the specified precision, 163 | // which is expected to be 32 or 64bit, to Writer w. 164 | func printFloat(w io.Writer, val float64, precision int) { 165 | w.Write([]byte(strconv.FormatFloat(val, 'g', -1, precision))) 166 | } 167 | 168 | // printComplex outputs a complex value using the specified float precision 169 | // for the real and imaginary parts to Writer w. 170 | func printComplex(w io.Writer, c complex128, floatPrecision int) { 171 | r := real(c) 172 | w.Write(openParenBytes) 173 | w.Write([]byte(strconv.FormatFloat(r, 'g', -1, floatPrecision))) 174 | i := imag(c) 175 | if i >= 0 { 176 | w.Write(plusBytes) 177 | } 178 | w.Write([]byte(strconv.FormatFloat(i, 'g', -1, floatPrecision))) 179 | w.Write(iBytes) 180 | w.Write(closeParenBytes) 181 | } 182 | 183 | // printHexPtr outputs a uintptr formatted as hexidecimal with a leading '0x' 184 | // prefix to Writer w. 185 | func printHexPtr(w io.Writer, p uintptr) { 186 | // Null pointer. 187 | num := uint64(p) 188 | if num == 0 { 189 | w.Write(nilAngleBytes) 190 | return 191 | } 192 | 193 | // Max uint64 is 16 bytes in hex + 2 bytes for '0x' prefix 194 | buf := make([]byte, 18) 195 | 196 | // It's simpler to construct the hex string right to left. 197 | base := uint64(16) 198 | i := len(buf) - 1 199 | for num >= base { 200 | buf[i] = hexDigits[num%base] 201 | num /= base 202 | i-- 203 | } 204 | buf[i] = hexDigits[num] 205 | 206 | // Add '0x' prefix. 207 | i-- 208 | buf[i] = 'x' 209 | i-- 210 | buf[i] = '0' 211 | 212 | // Strip unused leading bytes. 213 | buf = buf[i:] 214 | w.Write(buf) 215 | } 216 | 217 | // valuesSorter implements sort.Interface to allow a slice of reflect.Value 218 | // elements to be sorted. 219 | type valuesSorter struct { 220 | values []reflect.Value 221 | strings []string // either nil or same len and values 222 | cs *ConfigState 223 | } 224 | 225 | // newValuesSorter initializes a valuesSorter instance, which holds a set of 226 | // surrogate keys on which the data should be sorted. It uses flags in 227 | // ConfigState to decide if and how to populate those surrogate keys. 228 | func newValuesSorter(values []reflect.Value, cs *ConfigState) sort.Interface { 229 | vs := &valuesSorter{values: values, cs: cs} 230 | if canSortSimply(vs.values[0].Kind()) { 231 | return vs 232 | } 233 | if !cs.DisableMethods { 234 | vs.strings = make([]string, len(values)) 235 | for i := range vs.values { 236 | b := bytes.Buffer{} 237 | if !handleMethods(cs, &b, vs.values[i]) { 238 | vs.strings = nil 239 | break 240 | } 241 | vs.strings[i] = b.String() 242 | } 243 | } 244 | if vs.strings == nil && cs.SpewKeys { 245 | vs.strings = make([]string, len(values)) 246 | for i := range vs.values { 247 | vs.strings[i] = Sprintf("%#v", vs.values[i].Interface()) 248 | } 249 | } 250 | return vs 251 | } 252 | 253 | // canSortSimply tests whether a reflect.Kind is a primitive that can be sorted 254 | // directly, or whether it should be considered for sorting by surrogate keys 255 | // (if the ConfigState allows it). 256 | func canSortSimply(kind reflect.Kind) bool { 257 | // This switch parallels valueSortLess, except for the default case. 258 | switch kind { 259 | case reflect.Bool: 260 | return true 261 | case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: 262 | return true 263 | case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: 264 | return true 265 | case reflect.Float32, reflect.Float64: 266 | return true 267 | case reflect.String: 268 | return true 269 | case reflect.Uintptr: 270 | return true 271 | case reflect.Array: 272 | return true 273 | } 274 | return false 275 | } 276 | 277 | // Len returns the number of values in the slice. It is part of the 278 | // sort.Interface implementation. 279 | func (s *valuesSorter) Len() int { 280 | return len(s.values) 281 | } 282 | 283 | // Swap swaps the values at the passed indices. It is part of the 284 | // sort.Interface implementation. 285 | func (s *valuesSorter) Swap(i, j int) { 286 | s.values[i], s.values[j] = s.values[j], s.values[i] 287 | if s.strings != nil { 288 | s.strings[i], s.strings[j] = s.strings[j], s.strings[i] 289 | } 290 | } 291 | 292 | // valueSortLess returns whether the first value should sort before the second 293 | // value. It is used by valueSorter.Less as part of the sort.Interface 294 | // implementation. 295 | func valueSortLess(a, b reflect.Value) bool { 296 | switch a.Kind() { 297 | case reflect.Bool: 298 | return !a.Bool() && b.Bool() 299 | case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: 300 | return a.Int() < b.Int() 301 | case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: 302 | return a.Uint() < b.Uint() 303 | case reflect.Float32, reflect.Float64: 304 | return a.Float() < b.Float() 305 | case reflect.String: 306 | return a.String() < b.String() 307 | case reflect.Uintptr: 308 | return a.Uint() < b.Uint() 309 | case reflect.Array: 310 | // Compare the contents of both arrays. 311 | l := a.Len() 312 | for i := 0; i < l; i++ { 313 | av := a.Index(i) 314 | bv := b.Index(i) 315 | if av.Interface() == bv.Interface() { 316 | continue 317 | } 318 | return valueSortLess(av, bv) 319 | } 320 | } 321 | return a.String() < b.String() 322 | } 323 | 324 | // Less returns whether the value at index i should sort before the 325 | // value at index j. It is part of the sort.Interface implementation. 326 | func (s *valuesSorter) Less(i, j int) bool { 327 | if s.strings == nil { 328 | return valueSortLess(s.values[i], s.values[j]) 329 | } 330 | return s.strings[i] < s.strings[j] 331 | } 332 | 333 | // sortValues is a sort function that handles both native types and any type that 334 | // can be converted to error or Stringer. Other inputs are sorted according to 335 | // their Value.String() value to ensure display stability. 336 | func sortValues(values []reflect.Value, cs *ConfigState) { 337 | if len(values) == 0 { 338 | return 339 | } 340 | sort.Sort(newValuesSorter(values, cs)) 341 | } 342 | -------------------------------------------------------------------------------- /vendor/github.com/pmezard/go-difflib/difflib/difflib_test.go: -------------------------------------------------------------------------------- 1 | package difflib 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "math" 7 | "reflect" 8 | "strings" 9 | "testing" 10 | ) 11 | 12 | func assertAlmostEqual(t *testing.T, a, b float64, places int) { 13 | if math.Abs(a-b) > math.Pow10(-places) { 14 | t.Errorf("%.7f != %.7f", a, b) 15 | } 16 | } 17 | 18 | func assertEqual(t *testing.T, a, b interface{}) { 19 | if !reflect.DeepEqual(a, b) { 20 | t.Errorf("%v != %v", a, b) 21 | } 22 | } 23 | 24 | func splitChars(s string) []string { 25 | chars := make([]string, 0, len(s)) 26 | // Assume ASCII inputs 27 | for i := 0; i != len(s); i++ { 28 | chars = append(chars, string(s[i])) 29 | } 30 | return chars 31 | } 32 | 33 | func TestSequenceMatcherRatio(t *testing.T) { 34 | s := NewMatcher(splitChars("abcd"), splitChars("bcde")) 35 | assertEqual(t, s.Ratio(), 0.75) 36 | assertEqual(t, s.QuickRatio(), 0.75) 37 | assertEqual(t, s.RealQuickRatio(), 1.0) 38 | } 39 | 40 | func TestGetOptCodes(t *testing.T) { 41 | a := "qabxcd" 42 | b := "abycdf" 43 | s := NewMatcher(splitChars(a), splitChars(b)) 44 | w := &bytes.Buffer{} 45 | for _, op := range s.GetOpCodes() { 46 | fmt.Fprintf(w, "%s a[%d:%d], (%s) b[%d:%d] (%s)\n", string(op.Tag), 47 | op.I1, op.I2, a[op.I1:op.I2], op.J1, op.J2, b[op.J1:op.J2]) 48 | } 49 | result := string(w.Bytes()) 50 | expected := `d a[0:1], (q) b[0:0] () 51 | e a[1:3], (ab) b[0:2] (ab) 52 | r a[3:4], (x) b[2:3] (y) 53 | e a[4:6], (cd) b[3:5] (cd) 54 | i a[6:6], () b[5:6] (f) 55 | ` 56 | if expected != result { 57 | t.Errorf("unexpected op codes: \n%s", result) 58 | } 59 | } 60 | 61 | func TestGroupedOpCodes(t *testing.T) { 62 | a := []string{} 63 | for i := 0; i != 39; i++ { 64 | a = append(a, fmt.Sprintf("%02d", i)) 65 | } 66 | b := []string{} 67 | b = append(b, a[:8]...) 68 | b = append(b, " i") 69 | b = append(b, a[8:19]...) 70 | b = append(b, " x") 71 | b = append(b, a[20:22]...) 72 | b = append(b, a[27:34]...) 73 | b = append(b, " y") 74 | b = append(b, a[35:]...) 75 | s := NewMatcher(a, b) 76 | w := &bytes.Buffer{} 77 | for _, g := range s.GetGroupedOpCodes(-1) { 78 | fmt.Fprintf(w, "group\n") 79 | for _, op := range g { 80 | fmt.Fprintf(w, " %s, %d, %d, %d, %d\n", string(op.Tag), 81 | op.I1, op.I2, op.J1, op.J2) 82 | } 83 | } 84 | result := string(w.Bytes()) 85 | expected := `group 86 | e, 5, 8, 5, 8 87 | i, 8, 8, 8, 9 88 | e, 8, 11, 9, 12 89 | group 90 | e, 16, 19, 17, 20 91 | r, 19, 20, 20, 21 92 | e, 20, 22, 21, 23 93 | d, 22, 27, 23, 23 94 | e, 27, 30, 23, 26 95 | group 96 | e, 31, 34, 27, 30 97 | r, 34, 35, 30, 31 98 | e, 35, 38, 31, 34 99 | ` 100 | if expected != result { 101 | t.Errorf("unexpected op codes: \n%s", result) 102 | } 103 | } 104 | 105 | func ExampleGetUnifiedDiffCode() { 106 | a := `one 107 | two 108 | three 109 | four 110 | fmt.Printf("%s,%T",a,b)` 111 | b := `zero 112 | one 113 | three 114 | four` 115 | diff := UnifiedDiff{ 116 | A: SplitLines(a), 117 | B: SplitLines(b), 118 | FromFile: "Original", 119 | FromDate: "2005-01-26 23:30:50", 120 | ToFile: "Current", 121 | ToDate: "2010-04-02 10:20:52", 122 | Context: 3, 123 | } 124 | result, _ := GetUnifiedDiffString(diff) 125 | fmt.Println(strings.Replace(result, "\t", " ", -1)) 126 | // Output: 127 | // --- Original 2005-01-26 23:30:50 128 | // +++ Current 2010-04-02 10:20:52 129 | // @@ -1,5 +1,4 @@ 130 | // +zero 131 | // one 132 | // -two 133 | // three 134 | // four 135 | // -fmt.Printf("%s,%T",a,b) 136 | } 137 | 138 | func ExampleGetContextDiffCode() { 139 | a := `one 140 | two 141 | three 142 | four 143 | fmt.Printf("%s,%T",a,b)` 144 | b := `zero 145 | one 146 | tree 147 | four` 148 | diff := ContextDiff{ 149 | A: SplitLines(a), 150 | B: SplitLines(b), 151 | FromFile: "Original", 152 | ToFile: "Current", 153 | Context: 3, 154 | Eol: "\n", 155 | } 156 | result, _ := GetContextDiffString(diff) 157 | fmt.Print(strings.Replace(result, "\t", " ", -1)) 158 | // Output: 159 | // *** Original 160 | // --- Current 161 | // *************** 162 | // *** 1,5 **** 163 | // one 164 | // ! two 165 | // ! three 166 | // four 167 | // - fmt.Printf("%s,%T",a,b) 168 | // --- 1,4 ---- 169 | // + zero 170 | // one 171 | // ! tree 172 | // four 173 | } 174 | 175 | func ExampleGetContextDiffString() { 176 | a := `one 177 | two 178 | three 179 | four` 180 | b := `zero 181 | one 182 | tree 183 | four` 184 | diff := ContextDiff{ 185 | A: SplitLines(a), 186 | B: SplitLines(b), 187 | FromFile: "Original", 188 | ToFile: "Current", 189 | Context: 3, 190 | Eol: "\n", 191 | } 192 | result, _ := GetContextDiffString(diff) 193 | fmt.Printf(strings.Replace(result, "\t", " ", -1)) 194 | // Output: 195 | // *** Original 196 | // --- Current 197 | // *************** 198 | // *** 1,4 **** 199 | // one 200 | // ! two 201 | // ! three 202 | // four 203 | // --- 1,4 ---- 204 | // + zero 205 | // one 206 | // ! tree 207 | // four 208 | } 209 | 210 | func rep(s string, count int) string { 211 | return strings.Repeat(s, count) 212 | } 213 | 214 | func TestWithAsciiOneInsert(t *testing.T) { 215 | sm := NewMatcher(splitChars(rep("b", 100)), 216 | splitChars("a"+rep("b", 100))) 217 | assertAlmostEqual(t, sm.Ratio(), 0.995, 3) 218 | assertEqual(t, sm.GetOpCodes(), 219 | []OpCode{{'i', 0, 0, 0, 1}, {'e', 0, 100, 1, 101}}) 220 | assertEqual(t, len(sm.bPopular), 0) 221 | 222 | sm = NewMatcher(splitChars(rep("b", 100)), 223 | splitChars(rep("b", 50)+"a"+rep("b", 50))) 224 | assertAlmostEqual(t, sm.Ratio(), 0.995, 3) 225 | assertEqual(t, sm.GetOpCodes(), 226 | []OpCode{{'e', 0, 50, 0, 50}, {'i', 50, 50, 50, 51}, {'e', 50, 100, 51, 101}}) 227 | assertEqual(t, len(sm.bPopular), 0) 228 | } 229 | 230 | func TestWithAsciiOnDelete(t *testing.T) { 231 | sm := NewMatcher(splitChars(rep("a", 40)+"c"+rep("b", 40)), 232 | splitChars(rep("a", 40)+rep("b", 40))) 233 | assertAlmostEqual(t, sm.Ratio(), 0.994, 3) 234 | assertEqual(t, sm.GetOpCodes(), 235 | []OpCode{{'e', 0, 40, 0, 40}, {'d', 40, 41, 40, 40}, {'e', 41, 81, 40, 80}}) 236 | } 237 | 238 | func TestWithAsciiBJunk(t *testing.T) { 239 | isJunk := func(s string) bool { 240 | return s == " " 241 | } 242 | sm := NewMatcherWithJunk(splitChars(rep("a", 40)+rep("b", 40)), 243 | splitChars(rep("a", 44)+rep("b", 40)), true, isJunk) 244 | assertEqual(t, sm.bJunk, map[string]struct{}{}) 245 | 246 | sm = NewMatcherWithJunk(splitChars(rep("a", 40)+rep("b", 40)), 247 | splitChars(rep("a", 44)+rep("b", 40)+rep(" ", 20)), false, isJunk) 248 | assertEqual(t, sm.bJunk, map[string]struct{}{" ": struct{}{}}) 249 | 250 | isJunk = func(s string) bool { 251 | return s == " " || s == "b" 252 | } 253 | sm = NewMatcherWithJunk(splitChars(rep("a", 40)+rep("b", 40)), 254 | splitChars(rep("a", 44)+rep("b", 40)+rep(" ", 20)), false, isJunk) 255 | assertEqual(t, sm.bJunk, map[string]struct{}{" ": struct{}{}, "b": struct{}{}}) 256 | } 257 | 258 | func TestSFBugsRatioForNullSeqn(t *testing.T) { 259 | sm := NewMatcher(nil, nil) 260 | assertEqual(t, sm.Ratio(), 1.0) 261 | assertEqual(t, sm.QuickRatio(), 1.0) 262 | assertEqual(t, sm.RealQuickRatio(), 1.0) 263 | } 264 | 265 | func TestSFBugsComparingEmptyLists(t *testing.T) { 266 | groups := NewMatcher(nil, nil).GetGroupedOpCodes(-1) 267 | assertEqual(t, len(groups), 0) 268 | diff := UnifiedDiff{ 269 | FromFile: "Original", 270 | ToFile: "Current", 271 | Context: 3, 272 | } 273 | result, err := GetUnifiedDiffString(diff) 274 | assertEqual(t, err, nil) 275 | assertEqual(t, result, "") 276 | } 277 | 278 | func TestOutputFormatRangeFormatUnified(t *testing.T) { 279 | // Per the diff spec at http://www.unix.org/single_unix_specification/ 280 | // 281 | // Each field shall be of the form: 282 | // %1d", if the range contains exactly one line, 283 | // and: 284 | // "%1d,%1d", , otherwise. 285 | // If a range is empty, its beginning line number shall be the number of 286 | // the line just before the range, or 0 if the empty range starts the file. 287 | fm := formatRangeUnified 288 | assertEqual(t, fm(3, 3), "3,0") 289 | assertEqual(t, fm(3, 4), "4") 290 | assertEqual(t, fm(3, 5), "4,2") 291 | assertEqual(t, fm(3, 6), "4,3") 292 | assertEqual(t, fm(0, 0), "0,0") 293 | } 294 | 295 | func TestOutputFormatRangeFormatContext(t *testing.T) { 296 | // Per the diff spec at http://www.unix.org/single_unix_specification/ 297 | // 298 | // The range of lines in file1 shall be written in the following format 299 | // if the range contains two or more lines: 300 | // "*** %d,%d ****\n", , 301 | // and the following format otherwise: 302 | // "*** %d ****\n", 303 | // The ending line number of an empty range shall be the number of the preceding line, 304 | // or 0 if the range is at the start of the file. 305 | // 306 | // Next, the range of lines in file2 shall be written in the following format 307 | // if the range contains two or more lines: 308 | // "--- %d,%d ----\n", , 309 | // and the following format otherwise: 310 | // "--- %d ----\n", 311 | fm := formatRangeContext 312 | assertEqual(t, fm(3, 3), "3") 313 | assertEqual(t, fm(3, 4), "4") 314 | assertEqual(t, fm(3, 5), "4,5") 315 | assertEqual(t, fm(3, 6), "4,6") 316 | assertEqual(t, fm(0, 0), "0") 317 | } 318 | 319 | func TestOutputFormatTabDelimiter(t *testing.T) { 320 | diff := UnifiedDiff{ 321 | A: splitChars("one"), 322 | B: splitChars("two"), 323 | FromFile: "Original", 324 | FromDate: "2005-01-26 23:30:50", 325 | ToFile: "Current", 326 | ToDate: "2010-04-12 10:20:52", 327 | Eol: "\n", 328 | } 329 | ud, err := GetUnifiedDiffString(diff) 330 | assertEqual(t, err, nil) 331 | assertEqual(t, SplitLines(ud)[:2], []string{ 332 | "--- Original\t2005-01-26 23:30:50\n", 333 | "+++ Current\t2010-04-12 10:20:52\n", 334 | }) 335 | cd, err := GetContextDiffString(ContextDiff(diff)) 336 | assertEqual(t, err, nil) 337 | assertEqual(t, SplitLines(cd)[:2], []string{ 338 | "*** Original\t2005-01-26 23:30:50\n", 339 | "--- Current\t2010-04-12 10:20:52\n", 340 | }) 341 | } 342 | 343 | func TestOutputFormatNoTrailingTabOnEmptyFiledate(t *testing.T) { 344 | diff := UnifiedDiff{ 345 | A: splitChars("one"), 346 | B: splitChars("two"), 347 | FromFile: "Original", 348 | ToFile: "Current", 349 | Eol: "\n", 350 | } 351 | ud, err := GetUnifiedDiffString(diff) 352 | assertEqual(t, err, nil) 353 | assertEqual(t, SplitLines(ud)[:2], []string{"--- Original\n", "+++ Current\n"}) 354 | 355 | cd, err := GetContextDiffString(ContextDiff(diff)) 356 | assertEqual(t, err, nil) 357 | assertEqual(t, SplitLines(cd)[:2], []string{"*** Original\n", "--- Current\n"}) 358 | } 359 | 360 | func TestOmitFilenames(t *testing.T) { 361 | diff := UnifiedDiff{ 362 | A: SplitLines("o\nn\ne\n"), 363 | B: SplitLines("t\nw\no\n"), 364 | Eol: "\n", 365 | } 366 | ud, err := GetUnifiedDiffString(diff) 367 | assertEqual(t, err, nil) 368 | assertEqual(t, SplitLines(ud), []string{ 369 | "@@ -0,0 +1,2 @@\n", 370 | "+t\n", 371 | "+w\n", 372 | "@@ -2,2 +3,0 @@\n", 373 | "-n\n", 374 | "-e\n", 375 | "\n", 376 | }) 377 | 378 | cd, err := GetContextDiffString(ContextDiff(diff)) 379 | assertEqual(t, err, nil) 380 | assertEqual(t, SplitLines(cd), []string{ 381 | "***************\n", 382 | "*** 0 ****\n", 383 | "--- 1,2 ----\n", 384 | "+ t\n", 385 | "+ w\n", 386 | "***************\n", 387 | "*** 2,3 ****\n", 388 | "- n\n", 389 | "- e\n", 390 | "--- 3 ----\n", 391 | "\n", 392 | }) 393 | } 394 | 395 | func TestSplitLines(t *testing.T) { 396 | allTests := []struct { 397 | input string 398 | want []string 399 | }{ 400 | {"foo", []string{"foo\n"}}, 401 | {"foo\nbar", []string{"foo\n", "bar\n"}}, 402 | {"foo\nbar\n", []string{"foo\n", "bar\n", "\n"}}, 403 | } 404 | for _, test := range allTests { 405 | assertEqual(t, SplitLines(test.input), test.want) 406 | } 407 | } 408 | 409 | func benchmarkSplitLines(b *testing.B, count int) { 410 | str := strings.Repeat("foo\n", count) 411 | 412 | b.ResetTimer() 413 | 414 | n := 0 415 | for i := 0; i < b.N; i++ { 416 | n += len(SplitLines(str)) 417 | } 418 | } 419 | 420 | func BenchmarkSplitLines100(b *testing.B) { 421 | benchmarkSplitLines(b, 100) 422 | } 423 | 424 | func BenchmarkSplitLines10000(b *testing.B) { 425 | benchmarkSplitLines(b, 10000) 426 | } 427 | --------------------------------------------------------------------------------