├── .gitignore ├── Procfile ├── README.md ├── broker ├── api.go ├── api_test.go ├── backends.go ├── broker.go ├── broker_suite_test.go └── route_requests.go ├── build.yml ├── ci ├── pipeline.yml └── scripts │ ├── build-backend-broker.sh │ ├── build-backend-broker.yml │ ├── cfmanifests │ ├── haash-broker-1.yml │ ├── haash-broker-2.yml │ ├── subway-broker-simple.yml │ ├── subway-syslog-broker.yml │ └── worlds-simplest-syslog-broker.yml │ ├── deploy-docker-backend.sh │ ├── deploy-docker-backend.yml │ ├── stop-backend-brokers.sh │ ├── stop-backend-brokers.yml │ ├── test-subway-broker-simple.sh │ ├── test-subway-broker-simple.yml │ ├── test-subway-broker-syslog.sh │ ├── test-subway-broker-syslog.yml │ └── test.sh ├── fixtures └── catalog.json ├── main.go ├── manifest.yml └── vendor ├── code.cloudfoundry.org └── lager │ ├── LICENSE │ ├── NOTICE │ ├── README.md │ ├── logger.go │ ├── models.go │ ├── package.go │ ├── reconfigurable_sink.go │ └── writer_sink.go ├── github.com ├── codegangsta │ └── cli │ │ ├── CHANGELOG.md │ │ ├── LICENSE │ │ ├── README.md │ │ ├── app.go │ │ ├── appveyor.yml │ │ ├── category.go │ │ ├── cli.go │ │ ├── command.go │ │ ├── context.go │ │ ├── errors.go │ │ ├── flag-types.json │ │ ├── flag.go │ │ ├── flag_generated.go │ │ ├── funcs.go │ │ ├── generate-flag-types │ │ ├── help.go │ │ └── runtests ├── frodenas │ └── brokerapi │ │ ├── api.go │ │ └── auth │ │ └── auth.go ├── gorilla │ ├── context │ │ ├── LICENSE │ │ ├── README.md │ │ ├── context.go │ │ └── doc.go │ └── mux │ │ ├── LICENSE │ │ ├── README.md │ │ ├── context_gorilla.go │ │ ├── context_native.go │ │ ├── doc.go │ │ ├── mux.go │ │ ├── regexp.go │ │ └── route.go ├── mitchellh │ └── mapstructure │ │ ├── LICENSE │ │ ├── README.md │ │ ├── decode_hooks.go │ │ ├── error.go │ │ └── mapstructure.go ├── onsi │ ├── ginkgo │ │ ├── CHANGELOG.md │ │ ├── LICENSE │ │ ├── README.md │ │ ├── config │ │ │ └── config.go │ │ ├── ginkgo │ │ │ ├── bootstrap_command.go │ │ │ ├── build_command.go │ │ │ ├── convert_command.go │ │ │ ├── generate_command.go │ │ │ ├── help_command.go │ │ │ ├── main.go │ │ │ ├── nodot_command.go │ │ │ ├── notifications.go │ │ │ ├── run_command.go │ │ │ ├── run_watch_and_build_command_flags.go │ │ │ ├── suite_runner.go │ │ │ ├── unfocus_command.go │ │ │ ├── version_command.go │ │ │ └── watch_command.go │ │ ├── ginkgo_dsl.go │ │ ├── internal │ │ │ ├── codelocation │ │ │ │ └── code_location.go │ │ │ ├── containernode │ │ │ │ └── container_node.go │ │ │ ├── failer │ │ │ │ └── failer.go │ │ │ ├── leafnodes │ │ │ │ ├── benchmarker.go │ │ │ │ ├── interfaces.go │ │ │ │ ├── it_node.go │ │ │ │ ├── measure_node.go │ │ │ │ ├── runner.go │ │ │ │ ├── setup_nodes.go │ │ │ │ ├── suite_nodes.go │ │ │ │ ├── synchronized_after_suite_node.go │ │ │ │ └── synchronized_before_suite_node.go │ │ │ ├── remote │ │ │ │ ├── aggregator.go │ │ │ │ ├── forwarding_reporter.go │ │ │ │ ├── output_interceptor.go │ │ │ │ ├── output_interceptor_unix.go │ │ │ │ ├── output_interceptor_win.go │ │ │ │ ├── server.go │ │ │ │ ├── syscall_dup_linux_arm64.go │ │ │ │ └── syscall_dup_unix.go │ │ │ ├── spec │ │ │ │ ├── index_computer.go │ │ │ │ ├── spec.go │ │ │ │ └── specs.go │ │ │ ├── specrunner │ │ │ │ ├── random_id.go │ │ │ │ └── spec_runner.go │ │ │ ├── suite │ │ │ │ └── suite.go │ │ │ ├── testingtproxy │ │ │ │ └── testing_t_proxy.go │ │ │ └── writer │ │ │ │ ├── fake_writer.go │ │ │ │ └── writer.go │ │ ├── reporters │ │ │ ├── default_reporter.go │ │ │ ├── fake_reporter.go │ │ │ ├── junit_reporter.go │ │ │ ├── reporter.go │ │ │ ├── stenographer │ │ │ │ ├── console_logging.go │ │ │ │ ├── fake_stenographer.go │ │ │ │ └── stenographer.go │ │ │ └── teamcity_reporter.go │ │ └── types │ │ │ ├── code_location.go │ │ │ ├── synchronization.go │ │ │ └── types.go │ └── gomega │ │ ├── CHANGELOG.md │ │ ├── LICENSE │ │ ├── README.md │ │ ├── format │ │ └── format.go │ │ ├── gomega_dsl.go │ │ ├── internal │ │ ├── assertion │ │ │ └── assertion.go │ │ ├── asyncassertion │ │ │ └── async_assertion.go │ │ ├── oraclematcher │ │ │ └── oracle_matcher.go │ │ └── testingtsupport │ │ │ └── testing_t_support.go │ │ ├── matchers.go │ │ ├── matchers │ │ ├── and.go │ │ ├── assignable_to_type_of_matcher.go │ │ ├── be_a_directory.go │ │ ├── be_a_regular_file.go │ │ ├── be_an_existing_file.go │ │ ├── be_closed_matcher.go │ │ ├── be_empty_matcher.go │ │ ├── be_equivalent_to_matcher.go │ │ ├── be_false_matcher.go │ │ ├── be_identical_to.go │ │ ├── be_nil_matcher.go │ │ ├── be_numerically_matcher.go │ │ ├── be_sent_matcher.go │ │ ├── be_temporally_matcher.go │ │ ├── be_true_matcher.go │ │ ├── be_zero_matcher.go │ │ ├── consist_of.go │ │ ├── contain_element_matcher.go │ │ ├── contain_substring_matcher.go │ │ ├── equal_matcher.go │ │ ├── have_cap_matcher.go │ │ ├── have_key_matcher.go │ │ ├── have_key_with_value_matcher.go │ │ ├── have_len_matcher.go │ │ ├── have_occurred_matcher.go │ │ ├── have_prefix_matcher.go │ │ ├── have_suffix_matcher.go │ │ ├── match_error_matcher.go │ │ ├── match_json_matcher.go │ │ ├── match_regexp_matcher.go │ │ ├── not.go │ │ ├── or.go │ │ ├── panic_matcher.go │ │ ├── receive_matcher.go │ │ ├── succeed_matcher.go │ │ ├── support │ │ │ └── goraph │ │ │ │ ├── bipartitegraph │ │ │ │ ├── bipartitegraph.go │ │ │ │ └── bipartitegraphmatching.go │ │ │ │ ├── edge │ │ │ │ └── edge.go │ │ │ │ ├── node │ │ │ │ └── node.go │ │ │ │ └── util │ │ │ │ └── util.go │ │ ├── type_support.go │ │ └── with_transform.go │ │ └── types │ │ └── types.go └── pivotal-cf │ └── brokerapi │ ├── LICENSE │ ├── NOTICE │ ├── README.md │ ├── api.go │ ├── auth │ └── auth.go │ ├── catalog.go │ ├── response.go │ └── service_broker.go ├── gopkg.in └── yaml.v2 │ ├── LICENSE │ ├── LICENSE.libyaml │ ├── README.md │ ├── apic.go │ ├── decode.go │ ├── emitterc.go │ ├── encode.go │ ├── parserc.go │ ├── readerc.go │ ├── resolve.go │ ├── scannerc.go │ ├── sorter.go │ ├── writerc.go │ ├── yaml.go │ ├── yamlh.go │ └── yamlprivateh.go └── vendor.json /.gitignore: -------------------------------------------------------------------------------- 1 | .envrc 2 | gin-bin 3 | credentials.yml 4 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: cf-subway broker 2 | -------------------------------------------------------------------------------- /broker/backends.go: -------------------------------------------------------------------------------- 1 | package broker 2 | 3 | import ( 4 | "fmt" 5 | "net/url" 6 | "os" 7 | "strings" 8 | 9 | "code.cloudfoundry.org/lager" 10 | ) 11 | 12 | // BackendBroker describes the location/creds for a backend broker providing actual services 13 | type BackendBroker struct { 14 | URI string 15 | Username string 16 | Password string 17 | } 18 | 19 | // LoadBackendBrokersFromEnv allows registration of backend brokers via environment variables 20 | // BACKEND_BROKER_1=https://username1:password1@hostname1 21 | // BACKEND_BROKER_2=https://username2:password2@hostname2 22 | func (subway *Broker) LoadBackendBrokersFromEnv() { 23 | for _, e := range os.Environ() { 24 | pair := strings.Split(e, "=") 25 | if strings.HasPrefix(pair[0], "BACKEND_BROKER") { 26 | backendURI := pair[1] 27 | uri, err := url.Parse(backendURI) 28 | if err != nil { 29 | subway.Logger.Error("backend-brokers", fmt.Errorf("Could not parse $%s %s", pair[0], backendURI)) 30 | continue 31 | } 32 | if uri.User == nil { 33 | subway.Logger.Error("backend-brokers", fmt.Errorf("Missing username:password in URL: %s", backendURI)) 34 | continue 35 | } 36 | password, _ := uri.User.Password() 37 | username := uri.User.Username() 38 | if username == "" || password == "" { 39 | subway.Logger.Error("backend-brokers", fmt.Errorf("Missing username:password in URL: %s", backendURI)) 40 | continue 41 | } 42 | url := fmt.Sprintf("%s://%s", uri.Scheme, uri.Host) 43 | backendBroker := BackendBroker{url, username, password} 44 | subway.BackendBrokers = append(subway.BackendBrokers, &backendBroker) 45 | subway.Logger.Info("backend-brokers", lager.Data{"backend-broker": backendURI}) 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /broker/broker.go: -------------------------------------------------------------------------------- 1 | package broker 2 | 3 | import ( 4 | "encoding/json" 5 | "errors" 6 | "fmt" 7 | "net/http" 8 | "os" 9 | 10 | "code.cloudfoundry.org/lager" 11 | "github.com/pivotal-cf/brokerapi" 12 | ) 13 | 14 | // Broker is the core struct for the Broker webapp 15 | type Broker struct { 16 | BackendCatalog []brokerapi.Service 17 | BackendBrokers []*BackendBroker 18 | 19 | Logger lager.Logger 20 | } 21 | 22 | // NewBroker is a constructor for a Broker webapp struct 23 | func NewBroker() (subway *Broker) { 24 | subway = &Broker{} 25 | subway.Logger = lager.NewLogger("cf-subway") 26 | subway.Logger.RegisterSink(lager.NewWriterSink(os.Stdout, lager.DEBUG)) 27 | subway.Logger.RegisterSink(lager.NewWriterSink(os.Stderr, lager.ERROR)) 28 | return subway 29 | } 30 | 31 | // LoadCatalog loads the homogenous catalog from one of the brokers 32 | func (subway *Broker) LoadCatalog() error { 33 | if len(subway.BackendBrokers) == 0 { 34 | return errors.New("No backend broker available for plan") 35 | } 36 | backendBroker := subway.BackendBrokers[0] 37 | 38 | client := &http.Client{} 39 | url := fmt.Sprintf("%s/v2/catalog", backendBroker.URI) 40 | req, err := http.NewRequest("GET", url, nil) 41 | if err != nil { 42 | subway.Logger.Error("backend-catalog-req", err) 43 | return err 44 | } 45 | req.SetBasicAuth(backendBroker.Username, backendBroker.Password) 46 | 47 | resp, err := client.Do(req) 48 | if err != nil { 49 | subway.Logger.Error("backend-catalog-resp", err) 50 | return err 51 | } 52 | defer resp.Body.Close() 53 | 54 | catalogResponse := brokerapi.CatalogResponse{} 55 | dec := json.NewDecoder(resp.Body) 56 | if err := dec.Decode(&catalogResponse); err != nil { 57 | return err 58 | } 59 | subway.BackendCatalog = catalogResponse.Services 60 | return nil 61 | } 62 | 63 | func (subway *Broker) plans() []brokerapi.ServicePlan { 64 | if len(subway.BackendCatalog) == 0 { 65 | subway.LoadCatalog() 66 | } 67 | plans := []brokerapi.ServicePlan{} 68 | for _, service := range subway.BackendCatalog { 69 | for _, plan := range service.Plans { 70 | plans = append(plans, plan) 71 | } 72 | } 73 | return plans 74 | } 75 | 76 | // Run starts the Martini webapp handler 77 | func (subway *Broker) Run() { 78 | username := os.Getenv("SUBWAY_USERNAME") 79 | if username == "" { 80 | username = "username" 81 | } 82 | 83 | password := os.Getenv("SUBWAY_PASSWORD") 84 | if password == "" { 85 | password = "password" 86 | } 87 | 88 | credentials := brokerapi.BrokerCredentials{ 89 | Username: username, 90 | Password: password, 91 | } 92 | fmt.Println(credentials) 93 | 94 | port := os.Getenv("PORT") 95 | if port == "" { 96 | port = "3000" 97 | } 98 | 99 | brokerAPI := brokerapi.New(subway, subway.Logger, credentials) 100 | http.Handle("/", brokerAPI) 101 | subway.Logger.Fatal("http-listen", http.ListenAndServe(fmt.Sprintf("0.0.0.0:%s", port), nil)) 102 | } 103 | -------------------------------------------------------------------------------- /broker/broker_suite_test.go: -------------------------------------------------------------------------------- 1 | package broker_test 2 | 3 | import ( 4 | "testing" 5 | 6 | . "github.com/onsi/ginkgo" 7 | . "github.com/onsi/gomega" 8 | ) 9 | 10 | func TestBroker(t *testing.T) { 11 | RegisterFailHandler(Fail) 12 | RunSpecs(t, "Broker Suite") 13 | } 14 | -------------------------------------------------------------------------------- /broker/route_requests.go: -------------------------------------------------------------------------------- 1 | package broker 2 | 3 | import ( 4 | "bytes" 5 | "encoding/json" 6 | "errors" 7 | "fmt" 8 | "log" 9 | "math/rand" 10 | "net/http" 11 | "net/http/httputil" 12 | 13 | "github.com/pivotal-cf/brokerapi" 14 | "code.cloudfoundry.org/lager" 15 | ) 16 | 17 | func (subway *Broker) routeProvision(instanceID string, details brokerapi.ProvisionDetails) (err error) { 18 | if len(subway.BackendBrokers) == 0 { 19 | return errors.New("No backend broker available for plan") 20 | } 21 | 22 | list := rand.Perm(len(subway.BackendBrokers)) 23 | for _, i := range list { 24 | backendBroker := subway.BackendBrokers[i] 25 | err := subway.routeProvisionToBackendBroker(backendBroker, instanceID, details) 26 | if err == nil { 27 | return nil 28 | } 29 | } 30 | return brokerapi.ErrInstanceLimitMet 31 | } 32 | 33 | func debug(data []byte, err error) { 34 | if err == nil { 35 | fmt.Printf("%s\n\n", data) 36 | } else { 37 | log.Fatalf("%s\n\n", err) 38 | } 39 | } 40 | 41 | func (subway *Broker) routeProvisionToBackendBroker(backendBroker *BackendBroker, instanceID string, details brokerapi.ProvisionDetails) (err error) { 42 | subway.Logger.Info("provision", lager.Data{ 43 | "instance-id": instanceID, 44 | "plan-id": details.PlanID, 45 | "backend-uri": backendBroker.URI, 46 | }) 47 | 48 | // Dummy URI to generate test results 49 | if backendBroker.URI == "TEST-SUCCESS" { 50 | return nil 51 | } 52 | if backendBroker.URI == "TEST-NO-CAPACITY" { 53 | return brokerapi.ErrInstanceLimitMet 54 | } 55 | 56 | client := &http.Client{} 57 | url := fmt.Sprintf("%s/v2/service_instances/%s", backendBroker.URI, instanceID) 58 | buffer := &bytes.Buffer{} 59 | if err = json.NewEncoder(buffer).Encode(details); err != nil { 60 | subway.Logger.Error("backend-provision-encode-details", err) 61 | return err 62 | } 63 | req, err := http.NewRequest("PUT", url, buffer) 64 | if err != nil { 65 | subway.Logger.Error("backend-provision-req", err) 66 | return err 67 | } 68 | req.Header.Set("Content-Type", "application/json") 69 | req.SetBasicAuth(backendBroker.Username, backendBroker.Password) 70 | debug(httputil.DumpRequestOut(req, true)) 71 | 72 | resp, err := client.Do(req) 73 | if err != nil { 74 | subway.Logger.Error("backend-provision-resp", err) 75 | return err 76 | } 77 | debug(httputil.DumpResponse(resp, true)) 78 | defer resp.Body.Close() 79 | 80 | // FIXME: If resp.StatusCode not 200 or 201, then try next 81 | if resp.StatusCode >= 400 { 82 | // FIXME: allow return of this error to end user 83 | return errors.New("unknown plan") 84 | } 85 | 86 | // TODO: ProvisioningResponse not supported by brokerapi as 9f368e578 87 | return err 88 | } 89 | -------------------------------------------------------------------------------- /build.yml: -------------------------------------------------------------------------------- 1 | platform: linux 2 | 3 | image: docker:///concourse/static-golang 4 | 5 | inputs: 6 | - name: cf-subway 7 | path: gopath/src/github.com/cloudfoundry-community/cf-subway 8 | 9 | run: 10 | path: gopath/src/github.com/cloudfoundry-community/cf-subway/ci/scripts/test.sh 11 | -------------------------------------------------------------------------------- /ci/scripts/build-backend-broker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd haash-broker 4 | 5 | export TERM=${TERM:-dumb} 6 | ./gradlew assemble 7 | -------------------------------------------------------------------------------- /ci/scripts/build-backend-broker.yml: -------------------------------------------------------------------------------- 1 | platform: linux 2 | 3 | image: docker:///java 4 | 5 | inputs: 6 | - name: cf-subway 7 | - name: haash-broker 8 | 9 | run: 10 | path: cf-subway/scripts/build-backend-broker.sh 11 | -------------------------------------------------------------------------------- /ci/scripts/cfmanifests/haash-broker-1.yml: -------------------------------------------------------------------------------- 1 | --- 2 | applications: 3 | - name: haash-broker-1 4 | memory: 512M 5 | path: build/libs/haash-broker-0.0.1-SNAPSHOT.jar 6 | -------------------------------------------------------------------------------- /ci/scripts/cfmanifests/haash-broker-2.yml: -------------------------------------------------------------------------------- 1 | --- 2 | applications: 3 | - name: haash-broker-2 4 | memory: 512M 5 | path: build/libs/haash-broker-0.0.1-SNAPSHOT.jar 6 | -------------------------------------------------------------------------------- /ci/scripts/cfmanifests/subway-broker-simple.yml: -------------------------------------------------------------------------------- 1 | --- 2 | applications: 3 | - name: subway-broker-simple 4 | memory: 128M 5 | -------------------------------------------------------------------------------- /ci/scripts/cfmanifests/subway-syslog-broker.yml: -------------------------------------------------------------------------------- 1 | --- 2 | applications: 3 | - name: subway-syslog-broker 4 | memory: 128M 5 | -------------------------------------------------------------------------------- /ci/scripts/cfmanifests/worlds-simplest-syslog-broker.yml: -------------------------------------------------------------------------------- 1 | --- 2 | applications: 3 | - name: worlds-simplest-syslog-broker 4 | memory: 128M 5 | path: . 6 | env: 7 | BASE_GUID: 1 8 | CREDENTIALS: '{"port": "4000", "host": "1.2.3.4"}' 9 | SERVICE_NAME: my-syslog 10 | SERVICE_PLAN_NAME: shared 11 | TAGS: syslog 12 | SYSLOG_DRAIN_URL: syslog://1.2.3.4:514 13 | -------------------------------------------------------------------------------- /ci/scripts/deploy-docker-backend.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [[ "${BOSH_TARGET}X" == "X" ]]; then 4 | echo "Required \$BOSH_TARGET, \$BOSH_USERNAME, \$BOSH_PASSWORD" 5 | exit 1 6 | fi 7 | 8 | BOSH_DEPLOYMENT_NAME=${BOSH_DEPLOYMENT_NAME:-subway-postgresql-docker} 9 | 10 | cat > $HOME/.bosh_config << YAML 11 | --- 12 | auth: 13 | ${BOSH_TARGET}: 14 | username: ${BOSH_USERNAME} 15 | password: ${BOSH_PASSWORD} 16 | YAML 17 | 18 | bosh target $BOSH_TARGET 19 | 20 | if [[ "$(bosh releases | grep ' docker ')X" == "X" ]]; then 21 | bosh upload release https://bosh.io/d/github.com/cf-platform-eng/docker-boshrelease 22 | fi 23 | if [[ "$(bosh releases | grep ' postgresql-docker ')X" == "X" ]]; then 24 | bosh upload release https://bosh.io/d/github.com/cloudfoundry-community/postgresql-docker-boshrelease 25 | fi 26 | 27 | set -e 28 | 29 | cd /tmp 30 | git clone https://github.com/cloudfoundry-community/postgresql-docker-boshrelease.git postgresql-docker 31 | cd postgresql-docker 32 | 33 | mkdir -p tmp 34 | cat > tmp/scaling.yml << YAML 35 | --- 36 | name: ${BOSH_DEPLOYMENT_NAME} 37 | update: 38 | canaries: 0 39 | 40 | jobs: 41 | - name: postgresql_docker_z1 42 | instances: 3 43 | YAML 44 | 45 | 46 | ./templates/make_manifest garden broker embedded tmp/scaling.yml 47 | 48 | set +e 49 | bosh -n deploy 50 | set -e 51 | 52 | backend_ips=$(bosh vms ${BOSH_DEPLOYMENT_NAME} | grep running | awk '{print $8}') 53 | cd - 54 | 55 | counter=1 56 | for ip in $backend_ips; do 57 | echo "export BACKEND_BROKER_${counter}=http://containers:containers@${ip}" >> backends.env 58 | echo "http://containers:containers@${ip}" >> backends 59 | counter=$((counter + 1)) 60 | done 61 | -------------------------------------------------------------------------------- /ci/scripts/deploy-docker-backend.yml: -------------------------------------------------------------------------------- 1 | platform: linux 2 | 3 | image: docker:///concourse/concourse-ci 4 | 5 | inputs: 6 | - name: cf-subway 7 | 8 | params: 9 | BOSH_TARGET: 10 | BOSH_USERNAME: admin 11 | BOSH_PASSWORD: admin 12 | 13 | run: 14 | path: cf-subway/scripts/deploy-test-backend.sh 15 | -------------------------------------------------------------------------------- /ci/scripts/stop-backend-brokers.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | sudo apt-get update 6 | sudo apt-get install -y ca-certificates 7 | 8 | cf login -a ${api} -u ${username} -p ${password} -o ${organization} -s ${space} 9 | 10 | cf a | grep started | awk '{print $1}' | xargs -L1 cf stop 11 | -------------------------------------------------------------------------------- /ci/scripts/stop-backend-brokers.yml: -------------------------------------------------------------------------------- 1 | platform: linux 2 | 3 | # https://github.com/starkandwayne/docker-cf 4 | image: docker:///starkandwayne/cf 5 | 6 | inputs: 7 | - name: cf-subway 8 | 9 | params: 10 | api: https://api.run.pivotal.io 11 | skip_cert_check: false 12 | username: 13 | password: 14 | organization: 15 | space: 16 | 17 | run: 18 | path: cf-subway/scripts/stop-backend-brokers.sh 19 | -------------------------------------------------------------------------------- /ci/scripts/test-subway-broker-simple.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | set -x 5 | 6 | SUBWAY_USERNAME=${SUBWAY_USERNAME:-username} 7 | SUBWAY_PASSWORD=${SUBWAY_PASSWORD:-password} 8 | SUBWAY_HOST=${SUBWAY_HOST} 9 | 10 | sudo apt-get update 11 | sudo apt-get install curl uuid -y 12 | 13 | backend_catalog=$(curl -sf -X GET https://$BACKEND/v2/catalog) 14 | echo $backend_catalog 15 | subway_catalog=$(curl -sf -X GET https://$SUBWAY_USERNAME:$SUBWAY_PASSWORD@$SUBWAY_HOST/v2/catalog) 16 | echo $subway_catalog 17 | # [[ ${subway_catalog} == ${backend_catalog} ]] || exit 1 18 | 19 | id=$(uuid) 20 | curl -f -X PUT https://$SUBWAY_USERNAME:$SUBWAY_PASSWORD@$SUBWAY_HOST/v2/service_instances/$id -d "{\"plan_id\": \"$PLAN_ID\", \"service_id\":\"$SERVICE_ID\"}" 21 | curl -f -X PUT https://$SUBWAY_USERNAME:$SUBWAY_PASSWORD@$SUBWAY_HOST/v2/service_instances/$id/service_bindings/$id -d "{\"plan_id\": \"$PLAN_ID\", \"service_id\":\"$SERVICE_ID\", \"app_guid\": \"x\"}" 22 | # curl -fv -X DELETE https://$SUBWAY_USERNAME:$SUBWAY_PASSWORD@$SUBWAY_HOST/v2/service_instances/$id/service_bindings/$id -d "{\"plan_id\": \"$PLAN_ID\", \"service_id\":\"$SERVICE_ID\"}" 23 | # curl -fv -X DELETE https://$SUBWAY_USERNAME:$SUBWAY_PASSWORD@$SUBWAY_HOST/v2/service_instances/$id -d "{\"plan_id\": \"$PLAN_ID\", \"service_id\":\"$SERVICE_ID\"}" 24 | 25 | id=$(uuid) 26 | curl -f -X PUT https://$SUBWAY_USERNAME:$SUBWAY_PASSWORD@$SUBWAY_HOST/v2/service_instances/$id -d "{\"plan_id\": \"$PLAN_ID\", \"service_id\":\"$SERVICE_ID\"}" 27 | curl -f -X PUT https://$SUBWAY_USERNAME:$SUBWAY_PASSWORD@$SUBWAY_HOST/v2/service_instances/$id/service_bindings/$id -d "{\"plan_id\": \"$PLAN_ID\", \"service_id\":\"$SERVICE_ID\", \"app_guid\": \"x\"}" 28 | 29 | id=$(uuid) 30 | curl -f -X PUT https://$SUBWAY_USERNAME:$SUBWAY_PASSWORD@$SUBWAY_HOST/v2/service_instances/$id -d "{\"plan_id\": \"$PLAN_ID\", \"service_id\":\"$SERVICE_ID\"}" 31 | 32 | curl -f -X PUT https://$SUBWAY_USERNAME:$SUBWAY_PASSWORD@$SUBWAY_HOST/v2/service_instances/$id/service_bindings/$id -d "{\"plan_id\": \"$PLAN_ID\", \"service_id\":\"$SERVICE_ID\", \"app_guid\": \"x\"}" 33 | -------------------------------------------------------------------------------- /ci/scripts/test-subway-broker-simple.yml: -------------------------------------------------------------------------------- 1 | platform: linux 2 | 3 | image: docker:///concourse/concourse-ci 4 | 5 | inputs: 6 | - name: cf-subway 7 | 8 | run: 9 | path: cf-subway/scripts/test-subway-broker-simple.sh 10 | -------------------------------------------------------------------------------- /ci/scripts/test-subway-broker-syslog.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | set -x 5 | 6 | SUBWAY_USERNAME=${SUBWAY_USERNAME:-username} 7 | SUBWAY_PASSWORD=${SUBWAY_PASSWORD:-password} 8 | SUBWAY_HOST=${SUBWAY_HOST} 9 | 10 | sudo apt-get update 11 | sudo apt-get install curl uuid -y 12 | 13 | backend_catalog=$(curl -sf -X GET https://$BACKEND/v2/catalog) 14 | echo $backend_catalog 15 | subway_catalog=$(curl -sf -X GET https://$SUBWAY_USERNAME:$SUBWAY_PASSWORD@$SUBWAY_HOST/v2/catalog) 16 | echo $subway_catalog 17 | # [[ ${subway_catalog} == ${backend_catalog} ]] || exit 1 18 | 19 | id=$(uuid) 20 | curl -f -X PUT https://$SUBWAY_USERNAME:$SUBWAY_PASSWORD@$SUBWAY_HOST/v2/service_instances/$id -d "{\"plan_id\": \"$PLAN_ID\", \"service_id\":\"$SERVICE_ID\"}" 21 | curl -f -X PUT https://$SUBWAY_USERNAME:$SUBWAY_PASSWORD@$SUBWAY_HOST/v2/service_instances/$id/service_bindings/$id -d "{\"plan_id\": \"$PLAN_ID\", \"service_id\":\"$SERVICE_ID\", \"app_guid\": \"x\"}" 22 | # curl -fv -X DELETE https://$SUBWAY_USERNAME:$SUBWAY_PASSWORD@$SUBWAY_HOST/v2/service_instances/$id/service_bindings/$id -d "{\"plan_id\": \"$PLAN_ID\", \"service_id\":\"$SERVICE_ID\"}" 23 | # curl -fv -X DELETE https://$SUBWAY_USERNAME:$SUBWAY_PASSWORD@$SUBWAY_HOST/v2/service_instances/$id -d "{\"plan_id\": \"$PLAN_ID\", \"service_id\":\"$SERVICE_ID\"}" 24 | 25 | id=$(uuid) 26 | curl -f -X PUT https://$SUBWAY_USERNAME:$SUBWAY_PASSWORD@$SUBWAY_HOST/v2/service_instances/$id -d "{\"plan_id\": \"$PLAN_ID\", \"service_id\":\"$SERVICE_ID\"}" 27 | curl -f -X PUT https://$SUBWAY_USERNAME:$SUBWAY_PASSWORD@$SUBWAY_HOST/v2/service_instances/$id/service_bindings/$id -d "{\"plan_id\": \"$PLAN_ID\", \"service_id\":\"$SERVICE_ID\", \"app_guid\": \"x\"}" 28 | 29 | id=$(uuid) 30 | curl -f -X PUT https://$SUBWAY_USERNAME:$SUBWAY_PASSWORD@$SUBWAY_HOST/v2/service_instances/$id -d "{\"plan_id\": \"$PLAN_ID\", \"service_id\":\"$SERVICE_ID\"}" 31 | 32 | echo create binding to subway should be same as to backend 33 | subway=$(curl -f -X PUT https://$SUBWAY_USERNAME:$SUBWAY_PASSWORD@$SUBWAY_HOST/v2/service_instances/$id/service_bindings/$id -d "{\"plan_id\": \"$PLAN_ID\", \"service_id\":\"$SERVICE_ID\", \"app_guid\": \"x\"}") 34 | echo $subway 35 | backend=$(curl -f -X PUT https://$BACKEND/v2/service_instances/$id/service_bindings/$id -d "{\"plan_id\": \"$PLAN_ID\", \"service_id\":\"$SERVICE_ID\", \"app_guid\": \"x\"}") 36 | echo $backend 37 | [[ ${subway} == ${backend} ]] || exit 1 38 | -------------------------------------------------------------------------------- /ci/scripts/test-subway-broker-syslog.yml: -------------------------------------------------------------------------------- 1 | platform: linux 2 | 3 | image: docker:///concourse/concourse-ci 4 | 5 | inputs: 6 | - name: cf-subway 7 | 8 | run: 9 | path: cf-subway/scripts/test-subway-broker-syslog.sh 10 | -------------------------------------------------------------------------------- /ci/scripts/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -eu 4 | 5 | export GOPATH=$PWD/gopath 6 | export PATH=$GOPATH/bin:$PATH 7 | 8 | cd $GOPATH/src/github.com/cloudfoundry-community/cf-subway 9 | 10 | go test $(go list ./... | grep -v /vendor/) 11 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "math/rand" 5 | "os" 6 | 7 | "github.com/cloudfoundry-community/cf-subway/broker" 8 | "github.com/codegangsta/cli" 9 | ) 10 | 11 | func runBroker(c *cli.Context) { 12 | subway := broker.NewBroker() 13 | subway.LoadBackendBrokersFromEnv() 14 | 15 | subway.Run() 16 | } 17 | 18 | func main() { 19 | rand.Seed(4200) 20 | 21 | app := cli.NewApp() 22 | app.Name = "cf-subway" 23 | app.Version = "0.1.0" 24 | app.Usage = "Underground tunnel to multiplex multiple homogenous service brokers" 25 | app.Commands = []cli.Command{ 26 | { 27 | Name: "broker", 28 | Usage: "run the broker", 29 | Flags: []cli.Flag{}, 30 | Action: runBroker, 31 | }, 32 | } 33 | app.Run(os.Args) 34 | 35 | } 36 | -------------------------------------------------------------------------------- /manifest.yml: -------------------------------------------------------------------------------- 1 | --- 2 | applications: 3 | - name: subway-broker 4 | memory: 128M 5 | buildpack: go_buildpack 6 | -------------------------------------------------------------------------------- /vendor/code.cloudfoundry.org/lager/NOTICE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015-Present CloudFoundry.org Foundation, Inc. All Rights Reserved. 2 | 3 | This project contains software that is Copyright (c) 2014-2015 Pivotal Software, Inc. 4 | 5 | Licensed under the Apache License, Version 2.0 (the "License"); 6 | you may not use this file except in compliance with the License. 7 | You may obtain a copy of the License at 8 | 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | Unless required by applicable law or agreed to in writing, software 12 | distributed under the License is distributed on an "AS IS" BASIS, 13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | See the License for the specific language governing permissions and 15 | limitations under the License. 16 | 17 | This project may include a number of subcomponents with separate 18 | copyright notices and license terms. Your use of these subcomponents 19 | is subject to the terms and conditions of each subcomponent's license, 20 | as noted in the LICENSE file. 21 | -------------------------------------------------------------------------------- /vendor/code.cloudfoundry.org/lager/README.md: -------------------------------------------------------------------------------- 1 | lager 2 | ===== 3 | 4 | **Note**: This repository should be imported as `code.cloudfoundry.org/lager`. 5 | 6 | Lager is a logging library for go. 7 | 8 | ## Usage 9 | 10 | Instantiate a logger with the name of your component. 11 | 12 | ```go 13 | import ( 14 | "code.cloudfoundry.org/lager" 15 | ) 16 | 17 | logger := lager.NewLogger("my-app") 18 | ``` 19 | 20 | ### Sinks 21 | 22 | Lager can write logs to a variety of destinations. You can specify the destinations 23 | using Lager sinks: 24 | 25 | To write to an arbitrary `Writer` object: 26 | 27 | ```go 28 | logger.RegisterSink(lager.NewWriterSink(myWriter, lager.INFO)) 29 | ``` 30 | 31 | ### Emitting logs 32 | 33 | Lager supports the usual level-based logging, with an optional argument for arbitrary key-value data. 34 | 35 | ```go 36 | logger.Info("doing-stuff", lager.Data{ 37 | "informative": true, 38 | }) 39 | ``` 40 | 41 | output: 42 | ```json 43 | { "source": "my-app", "message": "doing-stuff", "data": { "informative": true }, "timestamp": 1232345, "log_level": 1 } 44 | ``` 45 | 46 | Error messages also take an `Error` object: 47 | 48 | ```go 49 | logger.Error("failed-to-do-stuff", errors.New("Something went wrong")) 50 | ``` 51 | 52 | output: 53 | ```json 54 | { "source": "my-app", "message": "failed-to-do-stuff", "data": { "error": "Something went wrong" }, "timestamp": 1232345, "log_level": 1 } 55 | ``` 56 | 57 | ### Sessions 58 | 59 | You can avoid repetition of contextual data using 'Sessions': 60 | 61 | ```go 62 | 63 | contextualLogger := logger.Session("my-task", lager.Data{ 64 | "request-id": 5, 65 | }) 66 | 67 | contextualLogger.Info("my-action") 68 | ``` 69 | 70 | output: 71 | 72 | ```json 73 | { "source": "my-app", "message": "my-task.my-action", "data": { "request-id": 5 }, "timestamp": 1232345, "log_level": 1 } 74 | ``` 75 | 76 | ## License 77 | 78 | Lager is [Apache 2.0](https://github.com/cloudfoundry/lager/blob/master/LICENSE) licensed. 79 | -------------------------------------------------------------------------------- /vendor/code.cloudfoundry.org/lager/models.go: -------------------------------------------------------------------------------- 1 | package lager 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | ) 7 | 8 | type LogLevel int 9 | 10 | const ( 11 | DEBUG LogLevel = iota 12 | INFO 13 | ERROR 14 | FATAL 15 | ) 16 | 17 | type Data map[string]interface{} 18 | 19 | type LogFormat struct { 20 | Timestamp string `json:"timestamp"` 21 | Source string `json:"source"` 22 | Message string `json:"message"` 23 | LogLevel LogLevel `json:"log_level"` 24 | Data Data `json:"data"` 25 | } 26 | 27 | func (log LogFormat) ToJSON() []byte { 28 | content, err := json.Marshal(log) 29 | if err != nil { 30 | if _, ok := err.(*json.UnsupportedTypeError); ok { 31 | log.Data = map[string]interface{}{"lager serialisation error": err.Error(), "data_dump": fmt.Sprintf("%#v", log.Data)} 32 | content, err = json.Marshal(log) 33 | } 34 | if err != nil { 35 | panic(err) 36 | } 37 | } 38 | return content 39 | } 40 | -------------------------------------------------------------------------------- /vendor/code.cloudfoundry.org/lager/package.go: -------------------------------------------------------------------------------- 1 | package lager // import "code.cloudfoundry.org/lager" 2 | -------------------------------------------------------------------------------- /vendor/code.cloudfoundry.org/lager/reconfigurable_sink.go: -------------------------------------------------------------------------------- 1 | package lager 2 | 3 | import "sync/atomic" 4 | 5 | type ReconfigurableSink struct { 6 | sink Sink 7 | 8 | minLogLevel int32 9 | } 10 | 11 | func NewReconfigurableSink(sink Sink, initialMinLogLevel LogLevel) *ReconfigurableSink { 12 | return &ReconfigurableSink{ 13 | sink: sink, 14 | 15 | minLogLevel: int32(initialMinLogLevel), 16 | } 17 | } 18 | 19 | func (sink *ReconfigurableSink) Log(log LogFormat) { 20 | minLogLevel := LogLevel(atomic.LoadInt32(&sink.minLogLevel)) 21 | 22 | if log.LogLevel < minLogLevel { 23 | return 24 | } 25 | 26 | sink.sink.Log(log) 27 | } 28 | 29 | func (sink *ReconfigurableSink) SetMinLevel(level LogLevel) { 30 | atomic.StoreInt32(&sink.minLogLevel, int32(level)) 31 | } 32 | 33 | func (sink *ReconfigurableSink) GetMinLevel() LogLevel { 34 | return LogLevel(atomic.LoadInt32(&sink.minLogLevel)) 35 | } 36 | -------------------------------------------------------------------------------- /vendor/code.cloudfoundry.org/lager/writer_sink.go: -------------------------------------------------------------------------------- 1 | package lager 2 | 3 | import ( 4 | "io" 5 | "sync" 6 | ) 7 | 8 | // A Sink represents a write destination for a Logger. It provides 9 | // a thread-safe interface for writing logs 10 | type Sink interface { 11 | //Log to the sink. Best effort -- no need to worry about errors. 12 | Log(LogFormat) 13 | } 14 | 15 | type writerSink struct { 16 | writer io.Writer 17 | minLogLevel LogLevel 18 | writeL *sync.Mutex 19 | } 20 | 21 | func NewWriterSink(writer io.Writer, minLogLevel LogLevel) Sink { 22 | return &writerSink{ 23 | writer: writer, 24 | minLogLevel: minLogLevel, 25 | writeL: new(sync.Mutex), 26 | } 27 | } 28 | 29 | func (sink *writerSink) Log(log LogFormat) { 30 | if log.LogLevel < sink.minLogLevel { 31 | return 32 | } 33 | 34 | sink.writeL.Lock() 35 | sink.writer.Write(log.ToJSON()) 36 | sink.writer.Write([]byte("\n")) 37 | sink.writeL.Unlock() 38 | } 39 | -------------------------------------------------------------------------------- /vendor/github.com/codegangsta/cli/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Jeremy Saenz & Contributors 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/codegangsta/cli/appveyor.yml: -------------------------------------------------------------------------------- 1 | version: "{build}" 2 | 3 | os: Windows Server 2012 R2 4 | 5 | clone_folder: c:\gopath\src\github.com\urfave\cli 6 | 7 | environment: 8 | GOPATH: C:\gopath 9 | GOVERSION: 1.6 10 | PYTHON: C:\Python27-x64 11 | PYTHON_VERSION: 2.7.x 12 | PYTHON_ARCH: 64 13 | 14 | install: 15 | - set PATH=%GOPATH%\bin;C:\go\bin;%PATH% 16 | - go version 17 | - go env 18 | - go get github.com/urfave/gfmrun/... 19 | - go get -v -t ./... 20 | 21 | build_script: 22 | - python runtests vet 23 | - python runtests test 24 | - python runtests gfmrun 25 | -------------------------------------------------------------------------------- /vendor/github.com/codegangsta/cli/category.go: -------------------------------------------------------------------------------- 1 | package cli 2 | 3 | // CommandCategories is a slice of *CommandCategory. 4 | type CommandCategories []*CommandCategory 5 | 6 | // CommandCategory is a category containing commands. 7 | type CommandCategory struct { 8 | Name string 9 | Commands Commands 10 | } 11 | 12 | func (c CommandCategories) Less(i, j int) bool { 13 | return c[i].Name < c[j].Name 14 | } 15 | 16 | func (c CommandCategories) Len() int { 17 | return len(c) 18 | } 19 | 20 | func (c CommandCategories) Swap(i, j int) { 21 | c[i], c[j] = c[j], c[i] 22 | } 23 | 24 | // AddCommand adds a command to a category. 25 | func (c CommandCategories) AddCommand(category string, command Command) CommandCategories { 26 | for _, commandCategory := range c { 27 | if commandCategory.Name == category { 28 | commandCategory.Commands = append(commandCategory.Commands, command) 29 | return c 30 | } 31 | } 32 | return append(c, &CommandCategory{Name: category, Commands: []Command{command}}) 33 | } 34 | 35 | // VisibleCommands returns a slice of the Commands with Hidden=false 36 | func (c *CommandCategory) VisibleCommands() []Command { 37 | ret := []Command{} 38 | for _, command := range c.Commands { 39 | if !command.Hidden { 40 | ret = append(ret, command) 41 | } 42 | } 43 | return ret 44 | } 45 | -------------------------------------------------------------------------------- /vendor/github.com/codegangsta/cli/cli.go: -------------------------------------------------------------------------------- 1 | // Package cli provides a minimal framework for creating and organizing command line 2 | // Go applications. cli is designed to be easy to understand and write, the most simple 3 | // cli application can be written as follows: 4 | // func main() { 5 | // cli.NewApp().Run(os.Args) 6 | // } 7 | // 8 | // Of course this application does not do much, so let's make this an actual application: 9 | // func main() { 10 | // app := cli.NewApp() 11 | // app.Name = "greet" 12 | // app.Usage = "say a greeting" 13 | // app.Action = func(c *cli.Context) error { 14 | // println("Greetings") 15 | // } 16 | // 17 | // app.Run(os.Args) 18 | // } 19 | package cli 20 | 21 | //go:generate python ./generate-flag-types cli -i flag-types.json -o flag_generated.go 22 | -------------------------------------------------------------------------------- /vendor/github.com/codegangsta/cli/errors.go: -------------------------------------------------------------------------------- 1 | package cli 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "os" 7 | "strings" 8 | ) 9 | 10 | // OsExiter is the function used when the app exits. If not set defaults to os.Exit. 11 | var OsExiter = os.Exit 12 | 13 | // ErrWriter is used to write errors to the user. This can be anything 14 | // implementing the io.Writer interface and defaults to os.Stderr. 15 | var ErrWriter io.Writer = os.Stderr 16 | 17 | // MultiError is an error that wraps multiple errors. 18 | type MultiError struct { 19 | Errors []error 20 | } 21 | 22 | // NewMultiError creates a new MultiError. Pass in one or more errors. 23 | func NewMultiError(err ...error) MultiError { 24 | return MultiError{Errors: err} 25 | } 26 | 27 | // Error implements the error interface. 28 | func (m MultiError) Error() string { 29 | errs := make([]string, len(m.Errors)) 30 | for i, err := range m.Errors { 31 | errs[i] = err.Error() 32 | } 33 | 34 | return strings.Join(errs, "\n") 35 | } 36 | 37 | type ErrorFormatter interface { 38 | Format(s fmt.State, verb rune) 39 | } 40 | 41 | // ExitCoder is the interface checked by `App` and `Command` for a custom exit 42 | // code 43 | type ExitCoder interface { 44 | error 45 | ExitCode() int 46 | } 47 | 48 | // ExitError fulfills both the builtin `error` interface and `ExitCoder` 49 | type ExitError struct { 50 | exitCode int 51 | message interface{} 52 | } 53 | 54 | // NewExitError makes a new *ExitError 55 | func NewExitError(message interface{}, exitCode int) *ExitError { 56 | return &ExitError{ 57 | exitCode: exitCode, 58 | message: message, 59 | } 60 | } 61 | 62 | // Error returns the string message, fulfilling the interface required by 63 | // `error` 64 | func (ee *ExitError) Error() string { 65 | return fmt.Sprintf("%v", ee.message) 66 | } 67 | 68 | // ExitCode returns the exit code, fulfilling the interface required by 69 | // `ExitCoder` 70 | func (ee *ExitError) ExitCode() int { 71 | return ee.exitCode 72 | } 73 | 74 | // HandleExitCoder checks if the error fulfills the ExitCoder interface, and if 75 | // so prints the error to stderr (if it is non-empty) and calls OsExiter with the 76 | // given exit code. If the given error is a MultiError, then this func is 77 | // called on all members of the Errors slice and calls OsExiter with the last exit code. 78 | func HandleExitCoder(err error) { 79 | if err == nil { 80 | return 81 | } 82 | 83 | if exitErr, ok := err.(ExitCoder); ok { 84 | if err.Error() != "" { 85 | if _, ok := exitErr.(ErrorFormatter); ok { 86 | fmt.Fprintf(ErrWriter, "%+v\n", err) 87 | } else { 88 | fmt.Fprintln(ErrWriter, err) 89 | } 90 | } 91 | OsExiter(exitErr.ExitCode()) 92 | return 93 | } 94 | 95 | if multiErr, ok := err.(MultiError); ok { 96 | code := handleMultiError(multiErr) 97 | OsExiter(code) 98 | return 99 | } 100 | } 101 | 102 | func handleMultiError(multiErr MultiError) int { 103 | code := 1 104 | for _, merr := range multiErr.Errors { 105 | if multiErr2, ok := merr.(MultiError); ok { 106 | code = handleMultiError(multiErr2) 107 | } else { 108 | fmt.Fprintln(ErrWriter, merr) 109 | if exitErr, ok := merr.(ExitCoder); ok { 110 | code = exitErr.ExitCode() 111 | } 112 | } 113 | } 114 | return code 115 | } 116 | -------------------------------------------------------------------------------- /vendor/github.com/codegangsta/cli/flag-types.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "Bool", 4 | "type": "bool", 5 | "value": false, 6 | "context_default": "false", 7 | "parser": "strconv.ParseBool(f.Value.String())" 8 | }, 9 | { 10 | "name": "BoolT", 11 | "type": "bool", 12 | "value": false, 13 | "doctail": " that is true by default", 14 | "context_default": "false", 15 | "parser": "strconv.ParseBool(f.Value.String())" 16 | }, 17 | { 18 | "name": "Duration", 19 | "type": "time.Duration", 20 | "doctail": " (see https://golang.org/pkg/time/#ParseDuration)", 21 | "context_default": "0", 22 | "parser": "time.ParseDuration(f.Value.String())" 23 | }, 24 | { 25 | "name": "Float64", 26 | "type": "float64", 27 | "context_default": "0", 28 | "parser": "strconv.ParseFloat(f.Value.String(), 64)" 29 | }, 30 | { 31 | "name": "Generic", 32 | "type": "Generic", 33 | "dest": false, 34 | "context_default": "nil", 35 | "context_type": "interface{}" 36 | }, 37 | { 38 | "name": "Int64", 39 | "type": "int64", 40 | "context_default": "0", 41 | "parser": "strconv.ParseInt(f.Value.String(), 0, 64)" 42 | }, 43 | { 44 | "name": "Int", 45 | "type": "int", 46 | "context_default": "0", 47 | "parser": "strconv.ParseInt(f.Value.String(), 0, 64)", 48 | "parser_cast": "int(parsed)" 49 | }, 50 | { 51 | "name": "IntSlice", 52 | "type": "*IntSlice", 53 | "dest": false, 54 | "context_default": "nil", 55 | "context_type": "[]int", 56 | "parser": "(f.Value.(*IntSlice)).Value(), error(nil)" 57 | }, 58 | { 59 | "name": "Int64Slice", 60 | "type": "*Int64Slice", 61 | "dest": false, 62 | "context_default": "nil", 63 | "context_type": "[]int64", 64 | "parser": "(f.Value.(*Int64Slice)).Value(), error(nil)" 65 | }, 66 | { 67 | "name": "String", 68 | "type": "string", 69 | "context_default": "\"\"", 70 | "parser": "f.Value.String(), error(nil)" 71 | }, 72 | { 73 | "name": "StringSlice", 74 | "type": "*StringSlice", 75 | "dest": false, 76 | "context_default": "nil", 77 | "context_type": "[]string", 78 | "parser": "(f.Value.(*StringSlice)).Value(), error(nil)" 79 | }, 80 | { 81 | "name": "Uint64", 82 | "type": "uint64", 83 | "context_default": "0", 84 | "parser": "strconv.ParseUint(f.Value.String(), 0, 64)" 85 | }, 86 | { 87 | "name": "Uint", 88 | "type": "uint", 89 | "context_default": "0", 90 | "parser": "strconv.ParseUint(f.Value.String(), 0, 64)", 91 | "parser_cast": "uint(parsed)" 92 | } 93 | ] 94 | -------------------------------------------------------------------------------- /vendor/github.com/codegangsta/cli/funcs.go: -------------------------------------------------------------------------------- 1 | package cli 2 | 3 | // BashCompleteFunc is an action to execute when the bash-completion flag is set 4 | type BashCompleteFunc func(*Context) 5 | 6 | // BeforeFunc is an action to execute before any subcommands are run, but after 7 | // the context is ready if a non-nil error is returned, no subcommands are run 8 | type BeforeFunc func(*Context) error 9 | 10 | // AfterFunc is an action to execute after any subcommands are run, but after the 11 | // subcommand has finished it is run even if Action() panics 12 | type AfterFunc func(*Context) error 13 | 14 | // ActionFunc is the action to execute when no subcommands are specified 15 | type ActionFunc func(*Context) error 16 | 17 | // CommandNotFoundFunc is executed if the proper command cannot be found 18 | type CommandNotFoundFunc func(*Context, string) 19 | 20 | // OnUsageErrorFunc is executed if an usage error occurs. This is useful for displaying 21 | // customized usage error messages. This function is able to replace the 22 | // original error messages. If this function is not set, the "Incorrect usage" 23 | // is displayed and the execution is interrupted. 24 | type OnUsageErrorFunc func(context *Context, err error, isSubcommand bool) error 25 | 26 | // FlagStringFunc is used by the help generation to display a flag, which is 27 | // expected to be a single line. 28 | type FlagStringFunc func(Flag) string 29 | -------------------------------------------------------------------------------- /vendor/github.com/codegangsta/cli/runtests: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from __future__ import print_function 3 | 4 | import argparse 5 | import os 6 | import sys 7 | import tempfile 8 | 9 | from subprocess import check_call, check_output 10 | 11 | 12 | PACKAGE_NAME = os.environ.get( 13 | 'CLI_PACKAGE_NAME', 'github.com/urfave/cli' 14 | ) 15 | 16 | 17 | def main(sysargs=sys.argv[:]): 18 | targets = { 19 | 'vet': _vet, 20 | 'test': _test, 21 | 'gfmrun': _gfmrun, 22 | 'toc': _toc, 23 | 'gen': _gen, 24 | } 25 | 26 | parser = argparse.ArgumentParser() 27 | parser.add_argument( 28 | 'target', nargs='?', choices=tuple(targets.keys()), default='test' 29 | ) 30 | args = parser.parse_args(sysargs[1:]) 31 | 32 | targets[args.target]() 33 | return 0 34 | 35 | 36 | def _test(): 37 | if check_output('go version'.split()).split()[2] < 'go1.2': 38 | _run('go test -v .') 39 | return 40 | 41 | coverprofiles = [] 42 | for subpackage in ['', 'altsrc']: 43 | coverprofile = 'cli.coverprofile' 44 | if subpackage != '': 45 | coverprofile = '{}.coverprofile'.format(subpackage) 46 | 47 | coverprofiles.append(coverprofile) 48 | 49 | _run('go test -v'.split() + [ 50 | '-coverprofile={}'.format(coverprofile), 51 | ('{}/{}'.format(PACKAGE_NAME, subpackage)).rstrip('/') 52 | ]) 53 | 54 | combined_name = _combine_coverprofiles(coverprofiles) 55 | _run('go tool cover -func={}'.format(combined_name)) 56 | os.remove(combined_name) 57 | 58 | 59 | def _gfmrun(): 60 | go_version = check_output('go version'.split()).split()[2] 61 | if go_version < 'go1.3': 62 | print('runtests: skip on {}'.format(go_version), file=sys.stderr) 63 | return 64 | _run(['gfmrun', '-c', str(_gfmrun_count()), '-s', 'README.md']) 65 | 66 | 67 | def _vet(): 68 | _run('go vet ./...') 69 | 70 | 71 | def _toc(): 72 | _run('node_modules/.bin/markdown-toc -i README.md') 73 | _run('git diff --exit-code') 74 | 75 | 76 | def _gen(): 77 | go_version = check_output('go version'.split()).split()[2] 78 | if go_version < 'go1.5': 79 | print('runtests: skip on {}'.format(go_version), file=sys.stderr) 80 | return 81 | 82 | _run('go generate ./...') 83 | _run('git diff --exit-code') 84 | 85 | 86 | def _run(command): 87 | if hasattr(command, 'split'): 88 | command = command.split() 89 | print('runtests: {}'.format(' '.join(command)), file=sys.stderr) 90 | check_call(command) 91 | 92 | 93 | def _gfmrun_count(): 94 | with open('README.md') as infile: 95 | lines = infile.read().splitlines() 96 | return len(filter(_is_go_runnable, lines)) 97 | 98 | 99 | def _is_go_runnable(line): 100 | return line.startswith('package main') 101 | 102 | 103 | def _combine_coverprofiles(coverprofiles): 104 | combined = tempfile.NamedTemporaryFile( 105 | suffix='.coverprofile', delete=False 106 | ) 107 | combined.write('mode: set\n') 108 | 109 | for coverprofile in coverprofiles: 110 | with open(coverprofile, 'r') as infile: 111 | for line in infile.readlines(): 112 | if not line.startswith('mode: '): 113 | combined.write(line) 114 | 115 | combined.flush() 116 | name = combined.name 117 | combined.close() 118 | return name 119 | 120 | 121 | if __name__ == '__main__': 122 | sys.exit(main()) 123 | -------------------------------------------------------------------------------- /vendor/github.com/frodenas/brokerapi/auth/auth.go: -------------------------------------------------------------------------------- 1 | package auth 2 | 3 | import "net/http" 4 | 5 | type Wrapper struct { 6 | username string 7 | password string 8 | } 9 | 10 | func NewWrapper(username, password string) *Wrapper { 11 | return &Wrapper{ 12 | username: username, 13 | password: password, 14 | } 15 | } 16 | 17 | const notAuthorized = "Not Authorized" 18 | 19 | func (wrapper *Wrapper) Wrap(handler http.Handler) http.Handler { 20 | return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 21 | if !authorized(wrapper, r) { 22 | http.Error(w, notAuthorized, http.StatusUnauthorized) 23 | return 24 | } 25 | 26 | handler.ServeHTTP(w, r) 27 | }) 28 | } 29 | 30 | func (wrapper *Wrapper) WrapFunc(handlerFunc http.HandlerFunc) http.HandlerFunc { 31 | return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 32 | if !authorized(wrapper, r) { 33 | http.Error(w, notAuthorized, http.StatusUnauthorized) 34 | return 35 | } 36 | 37 | handlerFunc(w, r) 38 | }) 39 | } 40 | 41 | func authorized(wrapper *Wrapper, r *http.Request) bool { 42 | username, password, isOk := r.BasicAuth() 43 | return isOk && username == wrapper.username && password == wrapper.password 44 | } 45 | -------------------------------------------------------------------------------- /vendor/github.com/gorilla/context/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 Rodrigo Moraes. 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 | -------------------------------------------------------------------------------- /vendor/github.com/gorilla/context/README.md: -------------------------------------------------------------------------------- 1 | context 2 | ======= 3 | [![Build Status](https://travis-ci.org/gorilla/context.png?branch=master)](https://travis-ci.org/gorilla/context) 4 | 5 | gorilla/context is a general purpose registry for global request variables. 6 | 7 | > Note: gorilla/context, having been born well before `context.Context` existed, does not play well 8 | > with the shallow copying of the request that [`http.Request.WithContext`](https://golang.org/pkg/net/http/#Request.WithContext) (added to net/http Go 1.7 onwards) performs. You should either use *just* gorilla/context, or moving forward, the new `http.Request.Context()`. 9 | 10 | Read the full documentation here: http://www.gorillatoolkit.org/pkg/context 11 | -------------------------------------------------------------------------------- /vendor/github.com/gorilla/context/context.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Gorilla Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package context 6 | 7 | import ( 8 | "net/http" 9 | "sync" 10 | "time" 11 | ) 12 | 13 | var ( 14 | mutex sync.RWMutex 15 | data = make(map[*http.Request]map[interface{}]interface{}) 16 | datat = make(map[*http.Request]int64) 17 | ) 18 | 19 | // Set stores a value for a given key in a given request. 20 | func Set(r *http.Request, key, val interface{}) { 21 | mutex.Lock() 22 | if data[r] == nil { 23 | data[r] = make(map[interface{}]interface{}) 24 | datat[r] = time.Now().Unix() 25 | } 26 | data[r][key] = val 27 | mutex.Unlock() 28 | } 29 | 30 | // Get returns a value stored for a given key in a given request. 31 | func Get(r *http.Request, key interface{}) interface{} { 32 | mutex.RLock() 33 | if ctx := data[r]; ctx != nil { 34 | value := ctx[key] 35 | mutex.RUnlock() 36 | return value 37 | } 38 | mutex.RUnlock() 39 | return nil 40 | } 41 | 42 | // GetOk returns stored value and presence state like multi-value return of map access. 43 | func GetOk(r *http.Request, key interface{}) (interface{}, bool) { 44 | mutex.RLock() 45 | if _, ok := data[r]; ok { 46 | value, ok := data[r][key] 47 | mutex.RUnlock() 48 | return value, ok 49 | } 50 | mutex.RUnlock() 51 | return nil, false 52 | } 53 | 54 | // GetAll returns all stored values for the request as a map. Nil is returned for invalid requests. 55 | func GetAll(r *http.Request) map[interface{}]interface{} { 56 | mutex.RLock() 57 | if context, ok := data[r]; ok { 58 | result := make(map[interface{}]interface{}, len(context)) 59 | for k, v := range context { 60 | result[k] = v 61 | } 62 | mutex.RUnlock() 63 | return result 64 | } 65 | mutex.RUnlock() 66 | return nil 67 | } 68 | 69 | // GetAllOk returns all stored values for the request as a map and a boolean value that indicates if 70 | // the request was registered. 71 | func GetAllOk(r *http.Request) (map[interface{}]interface{}, bool) { 72 | mutex.RLock() 73 | context, ok := data[r] 74 | result := make(map[interface{}]interface{}, len(context)) 75 | for k, v := range context { 76 | result[k] = v 77 | } 78 | mutex.RUnlock() 79 | return result, ok 80 | } 81 | 82 | // Delete removes a value stored for a given key in a given request. 83 | func Delete(r *http.Request, key interface{}) { 84 | mutex.Lock() 85 | if data[r] != nil { 86 | delete(data[r], key) 87 | } 88 | mutex.Unlock() 89 | } 90 | 91 | // Clear removes all values stored for a given request. 92 | // 93 | // This is usually called by a handler wrapper to clean up request 94 | // variables at the end of a request lifetime. See ClearHandler(). 95 | func Clear(r *http.Request) { 96 | mutex.Lock() 97 | clear(r) 98 | mutex.Unlock() 99 | } 100 | 101 | // clear is Clear without the lock. 102 | func clear(r *http.Request) { 103 | delete(data, r) 104 | delete(datat, r) 105 | } 106 | 107 | // Purge removes request data stored for longer than maxAge, in seconds. 108 | // It returns the amount of requests removed. 109 | // 110 | // If maxAge <= 0, all request data is removed. 111 | // 112 | // This is only used for sanity check: in case context cleaning was not 113 | // properly set some request data can be kept forever, consuming an increasing 114 | // amount of memory. In case this is detected, Purge() must be called 115 | // periodically until the problem is fixed. 116 | func Purge(maxAge int) int { 117 | mutex.Lock() 118 | count := 0 119 | if maxAge <= 0 { 120 | count = len(data) 121 | data = make(map[*http.Request]map[interface{}]interface{}) 122 | datat = make(map[*http.Request]int64) 123 | } else { 124 | min := time.Now().Unix() - int64(maxAge) 125 | for r := range data { 126 | if datat[r] < min { 127 | clear(r) 128 | count++ 129 | } 130 | } 131 | } 132 | mutex.Unlock() 133 | return count 134 | } 135 | 136 | // ClearHandler wraps an http.Handler and clears request values at the end 137 | // of a request lifetime. 138 | func ClearHandler(h http.Handler) http.Handler { 139 | return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 140 | defer Clear(r) 141 | h.ServeHTTP(w, r) 142 | }) 143 | } 144 | -------------------------------------------------------------------------------- /vendor/github.com/gorilla/context/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Gorilla Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | /* 6 | Package context stores values shared during a request lifetime. 7 | 8 | Note: gorilla/context, having been born well before `context.Context` existed, 9 | does not play well > with the shallow copying of the request that 10 | [`http.Request.WithContext`](https://golang.org/pkg/net/http/#Request.WithContext) 11 | (added to net/http Go 1.7 onwards) performs. You should either use *just* 12 | gorilla/context, or moving forward, the new `http.Request.Context()`. 13 | 14 | For example, a router can set variables extracted from the URL and later 15 | application handlers can access those values, or it can be used to store 16 | sessions values to be saved at the end of a request. There are several 17 | others common uses. 18 | 19 | The idea was posted by Brad Fitzpatrick to the go-nuts mailing list: 20 | 21 | http://groups.google.com/group/golang-nuts/msg/e2d679d303aa5d53 22 | 23 | Here's the basic usage: first define the keys that you will need. The key 24 | type is interface{} so a key can be of any type that supports equality. 25 | Here we define a key using a custom int type to avoid name collisions: 26 | 27 | package foo 28 | 29 | import ( 30 | "github.com/gorilla/context" 31 | ) 32 | 33 | type key int 34 | 35 | const MyKey key = 0 36 | 37 | Then set a variable. Variables are bound to an http.Request object, so you 38 | need a request instance to set a value: 39 | 40 | context.Set(r, MyKey, "bar") 41 | 42 | The application can later access the variable using the same key you provided: 43 | 44 | func MyHandler(w http.ResponseWriter, r *http.Request) { 45 | // val is "bar". 46 | val := context.Get(r, foo.MyKey) 47 | 48 | // returns ("bar", true) 49 | val, ok := context.GetOk(r, foo.MyKey) 50 | // ... 51 | } 52 | 53 | And that's all about the basic usage. We discuss some other ideas below. 54 | 55 | Any type can be stored in the context. To enforce a given type, make the key 56 | private and wrap Get() and Set() to accept and return values of a specific 57 | type: 58 | 59 | type key int 60 | 61 | const mykey key = 0 62 | 63 | // GetMyKey returns a value for this package from the request values. 64 | func GetMyKey(r *http.Request) SomeType { 65 | if rv := context.Get(r, mykey); rv != nil { 66 | return rv.(SomeType) 67 | } 68 | return nil 69 | } 70 | 71 | // SetMyKey sets a value for this package in the request values. 72 | func SetMyKey(r *http.Request, val SomeType) { 73 | context.Set(r, mykey, val) 74 | } 75 | 76 | Variables must be cleared at the end of a request, to remove all values 77 | that were stored. This can be done in an http.Handler, after a request was 78 | served. Just call Clear() passing the request: 79 | 80 | context.Clear(r) 81 | 82 | ...or use ClearHandler(), which conveniently wraps an http.Handler to clear 83 | variables at the end of a request lifetime. 84 | 85 | The Routers from the packages gorilla/mux and gorilla/pat call Clear() 86 | so if you are using either of them you don't need to clear the context manually. 87 | */ 88 | package context 89 | -------------------------------------------------------------------------------- /vendor/github.com/gorilla/mux/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 Rodrigo Moraes. 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 | -------------------------------------------------------------------------------- /vendor/github.com/gorilla/mux/context_gorilla.go: -------------------------------------------------------------------------------- 1 | // +build !go1.7 2 | 3 | package mux 4 | 5 | import ( 6 | "net/http" 7 | 8 | "github.com/gorilla/context" 9 | ) 10 | 11 | func contextGet(r *http.Request, key interface{}) interface{} { 12 | return context.Get(r, key) 13 | } 14 | 15 | func contextSet(r *http.Request, key, val interface{}) *http.Request { 16 | if val == nil { 17 | return r 18 | } 19 | 20 | context.Set(r, key, val) 21 | return r 22 | } 23 | 24 | func contextClear(r *http.Request) { 25 | context.Clear(r) 26 | } 27 | -------------------------------------------------------------------------------- /vendor/github.com/gorilla/mux/context_native.go: -------------------------------------------------------------------------------- 1 | // +build go1.7 2 | 3 | package mux 4 | 5 | import ( 6 | "context" 7 | "net/http" 8 | ) 9 | 10 | func contextGet(r *http.Request, key interface{}) interface{} { 11 | return r.Context().Value(key) 12 | } 13 | 14 | func contextSet(r *http.Request, key, val interface{}) *http.Request { 15 | if val == nil { 16 | return r 17 | } 18 | 19 | return r.WithContext(context.WithValue(r.Context(), key, val)) 20 | } 21 | 22 | func contextClear(r *http.Request) { 23 | return 24 | } 25 | -------------------------------------------------------------------------------- /vendor/github.com/mitchellh/mapstructure/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013 Mitchell Hashimoto 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 13 | all 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 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /vendor/github.com/mitchellh/mapstructure/README.md: -------------------------------------------------------------------------------- 1 | # mapstructure 2 | 3 | mapstructure is a Go library for decoding generic map values to structures 4 | and vice versa, while providing helpful error handling. 5 | 6 | This library is most useful when decoding values from some data stream (JSON, 7 | Gob, etc.) where you don't _quite_ know the structure of the underlying data 8 | until you read a part of it. You can therefore read a `map[string]interface{}` 9 | and use this library to decode it into the proper underlying native Go 10 | structure. 11 | 12 | ## Installation 13 | 14 | Standard `go get`: 15 | 16 | ``` 17 | $ go get github.com/mitchellh/mapstructure 18 | ``` 19 | 20 | ## Usage & Example 21 | 22 | For usage and examples see the [Godoc](http://godoc.org/github.com/mitchellh/mapstructure). 23 | 24 | The `Decode` function has examples associated with it there. 25 | 26 | ## But Why?! 27 | 28 | Go offers fantastic standard libraries for decoding formats such as JSON. 29 | The standard method is to have a struct pre-created, and populate that struct 30 | from the bytes of the encoded format. This is great, but the problem is if 31 | you have configuration or an encoding that changes slightly depending on 32 | specific fields. For example, consider this JSON: 33 | 34 | ```json 35 | { 36 | "type": "person", 37 | "name": "Mitchell" 38 | } 39 | ``` 40 | 41 | Perhaps we can't populate a specific structure without first reading 42 | the "type" field from the JSON. We could always do two passes over the 43 | decoding of the JSON (reading the "type" first, and the rest later). 44 | However, it is much simpler to just decode this into a `map[string]interface{}` 45 | structure, read the "type" key, then use something like this library 46 | to decode it into the proper structure. 47 | -------------------------------------------------------------------------------- /vendor/github.com/mitchellh/mapstructure/error.go: -------------------------------------------------------------------------------- 1 | package mapstructure 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "sort" 7 | "strings" 8 | ) 9 | 10 | // Error implements the error interface and can represents multiple 11 | // errors that occur in the course of a single decode. 12 | type Error struct { 13 | Errors []string 14 | } 15 | 16 | func (e *Error) Error() string { 17 | points := make([]string, len(e.Errors)) 18 | for i, err := range e.Errors { 19 | points[i] = fmt.Sprintf("* %s", err) 20 | } 21 | 22 | sort.Strings(points) 23 | return fmt.Sprintf( 24 | "%d error(s) decoding:\n\n%s", 25 | len(e.Errors), strings.Join(points, "\n")) 26 | } 27 | 28 | // WrappedErrors implements the errwrap.Wrapper interface to make this 29 | // return value more useful with the errwrap and go-multierror libraries. 30 | func (e *Error) WrappedErrors() []error { 31 | if e == nil { 32 | return nil 33 | } 34 | 35 | result := make([]error, len(e.Errors)) 36 | for i, e := range e.Errors { 37 | result[i] = errors.New(e) 38 | } 39 | 40 | return result 41 | } 42 | 43 | func appendErrors(errors []string, err error) []string { 44 | switch e := err.(type) { 45 | case *Error: 46 | return append(errors, e.Errors...) 47 | default: 48 | return append(errors, e.Error()) 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/ginkgo/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013-2014 Onsi Fakhouri 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/ginkgo/ginkgo/build_command.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "os" 7 | "path/filepath" 8 | 9 | "github.com/onsi/ginkgo/ginkgo/interrupthandler" 10 | "github.com/onsi/ginkgo/ginkgo/testrunner" 11 | ) 12 | 13 | func BuildBuildCommand() *Command { 14 | commandFlags := NewBuildCommandFlags(flag.NewFlagSet("build", flag.ExitOnError)) 15 | interruptHandler := interrupthandler.NewInterruptHandler() 16 | builder := &SpecBuilder{ 17 | commandFlags: commandFlags, 18 | interruptHandler: interruptHandler, 19 | } 20 | 21 | return &Command{ 22 | Name: "build", 23 | FlagSet: commandFlags.FlagSet, 24 | UsageCommand: "ginkgo build ", 25 | Usage: []string{ 26 | "Build the passed in (or the package in the current directory if left blank).", 27 | "Accepts the following flags:", 28 | }, 29 | Command: builder.BuildSpecs, 30 | } 31 | } 32 | 33 | type SpecBuilder struct { 34 | commandFlags *RunWatchAndBuildCommandFlags 35 | interruptHandler *interrupthandler.InterruptHandler 36 | } 37 | 38 | func (r *SpecBuilder) BuildSpecs(args []string, additionalArgs []string) { 39 | r.commandFlags.computeNodes() 40 | 41 | suites, _ := findSuites(args, r.commandFlags.Recurse, r.commandFlags.SkipPackage, false) 42 | 43 | if len(suites) == 0 { 44 | complainAndQuit("Found no test suites") 45 | } 46 | 47 | passed := true 48 | for _, suite := range suites { 49 | runner := testrunner.New(suite, 1, false, r.commandFlags.Race, r.commandFlags.Cover, r.commandFlags.CoverPkg, r.commandFlags.Tags, nil) 50 | fmt.Printf("Compiling %s...\n", suite.PackageName) 51 | 52 | path, _ := filepath.Abs(filepath.Join(suite.Path, fmt.Sprintf("%s.test", suite.PackageName))) 53 | err := runner.CompileTo(path) 54 | if err != nil { 55 | fmt.Println(err.Error()) 56 | passed = false 57 | } else { 58 | fmt.Printf(" compiled %s.test\n", suite.PackageName) 59 | } 60 | 61 | runner.CleanUp() 62 | } 63 | 64 | if passed { 65 | os.Exit(0) 66 | } 67 | os.Exit(1) 68 | } 69 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/ginkgo/ginkgo/convert_command.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "github.com/onsi/ginkgo/ginkgo/convert" 7 | "os" 8 | ) 9 | 10 | func BuildConvertCommand() *Command { 11 | return &Command{ 12 | Name: "convert", 13 | FlagSet: flag.NewFlagSet("convert", flag.ExitOnError), 14 | UsageCommand: "ginkgo convert /path/to/package", 15 | Usage: []string{ 16 | "Convert the package at the passed in path from an XUnit-style test to a Ginkgo-style test", 17 | }, 18 | Command: convertPackage, 19 | } 20 | } 21 | 22 | func convertPackage(args []string, additionalArgs []string) { 23 | if len(args) != 1 { 24 | println(fmt.Sprintf("usage: ginkgo convert /path/to/your/package")) 25 | os.Exit(1) 26 | } 27 | 28 | defer func() { 29 | err := recover() 30 | if err != nil { 31 | switch err := err.(type) { 32 | case error: 33 | println(err.Error()) 34 | case string: 35 | println(err) 36 | default: 37 | println(fmt.Sprintf("unexpected error: %#v", err)) 38 | } 39 | os.Exit(1) 40 | } 41 | }() 42 | 43 | convert.RewritePackage(args[0]) 44 | } 45 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/ginkgo/ginkgo/help_command.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | ) 7 | 8 | func BuildHelpCommand() *Command { 9 | return &Command{ 10 | Name: "help", 11 | FlagSet: flag.NewFlagSet("help", flag.ExitOnError), 12 | UsageCommand: "ginkgo help ", 13 | Usage: []string{ 14 | "Print usage information. If a command is passed in, print usage information just for that command.", 15 | }, 16 | Command: printHelp, 17 | } 18 | } 19 | 20 | func printHelp(args []string, additionalArgs []string) { 21 | if len(args) == 0 { 22 | usage() 23 | } else { 24 | command, found := commandMatching(args[0]) 25 | if !found { 26 | complainAndQuit(fmt.Sprintf("Unknown command: %s", args[0])) 27 | } 28 | 29 | usageForCommand(command, true) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/ginkgo/ginkgo/nodot_command.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "flag" 6 | "github.com/onsi/ginkgo/ginkgo/nodot" 7 | "io/ioutil" 8 | "os" 9 | "path/filepath" 10 | "regexp" 11 | ) 12 | 13 | func BuildNodotCommand() *Command { 14 | return &Command{ 15 | Name: "nodot", 16 | FlagSet: flag.NewFlagSet("bootstrap", flag.ExitOnError), 17 | UsageCommand: "ginkgo nodot", 18 | Usage: []string{ 19 | "Update the nodot declarations in your test suite", 20 | "Any missing declarations (from, say, a recently added matcher) will be added to your bootstrap file.", 21 | "If you've renamed a declaration, that name will be honored and not overwritten.", 22 | }, 23 | Command: updateNodot, 24 | } 25 | } 26 | 27 | func updateNodot(args []string, additionalArgs []string) { 28 | suiteFile, perm := findSuiteFile() 29 | 30 | data, err := ioutil.ReadFile(suiteFile) 31 | if err != nil { 32 | complainAndQuit("Failed to update nodot declarations: " + err.Error()) 33 | } 34 | 35 | content, err := nodot.ApplyNoDot(data) 36 | if err != nil { 37 | complainAndQuit("Failed to update nodot declarations: " + err.Error()) 38 | } 39 | ioutil.WriteFile(suiteFile, content, perm) 40 | 41 | goFmt(suiteFile) 42 | } 43 | 44 | func findSuiteFile() (string, os.FileMode) { 45 | workingDir, err := os.Getwd() 46 | if err != nil { 47 | complainAndQuit("Could not find suite file for nodot: " + err.Error()) 48 | } 49 | 50 | files, err := ioutil.ReadDir(workingDir) 51 | if err != nil { 52 | complainAndQuit("Could not find suite file for nodot: " + err.Error()) 53 | } 54 | 55 | re := regexp.MustCompile(`RunSpecs\(|RunSpecsWithDefaultAndCustomReporters\(|RunSpecsWithCustomReporters\(`) 56 | 57 | for _, file := range files { 58 | if file.IsDir() { 59 | continue 60 | } 61 | path := filepath.Join(workingDir, file.Name()) 62 | f, err := os.Open(path) 63 | if err != nil { 64 | complainAndQuit("Could not find suite file for nodot: " + err.Error()) 65 | } 66 | defer f.Close() 67 | 68 | if re.MatchReader(bufio.NewReader(f)) { 69 | return path, file.Mode() 70 | } 71 | } 72 | 73 | complainAndQuit("Could not find a suite file for nodot: you need a bootstrap file that call's Ginkgo's RunSpecs() command.\nTry running ginkgo bootstrap first.") 74 | 75 | return "", 0 76 | } 77 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/ginkgo/ginkgo/notifications.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "os/exec" 7 | "regexp" 8 | "runtime" 9 | "strings" 10 | 11 | "github.com/onsi/ginkgo/config" 12 | "github.com/onsi/ginkgo/ginkgo/testsuite" 13 | ) 14 | 15 | type Notifier struct { 16 | commandFlags *RunWatchAndBuildCommandFlags 17 | } 18 | 19 | func NewNotifier(commandFlags *RunWatchAndBuildCommandFlags) *Notifier { 20 | return &Notifier{ 21 | commandFlags: commandFlags, 22 | } 23 | } 24 | 25 | func (n *Notifier) VerifyNotificationsAreAvailable() { 26 | if n.commandFlags.Notify { 27 | onLinux := (runtime.GOOS == "linux") 28 | onOSX := (runtime.GOOS == "darwin") 29 | if onOSX { 30 | 31 | _, err := exec.LookPath("terminal-notifier") 32 | if err != nil { 33 | fmt.Printf(`--notify requires terminal-notifier, which you don't seem to have installed. 34 | 35 | OSX: 36 | 37 | To remedy this: 38 | 39 | brew install terminal-notifier 40 | 41 | To learn more about terminal-notifier: 42 | 43 | https://github.com/alloy/terminal-notifier 44 | `) 45 | os.Exit(1) 46 | } 47 | 48 | } else if onLinux { 49 | 50 | _, err := exec.LookPath("notify-send") 51 | if err != nil { 52 | fmt.Printf(`--notify requires terminal-notifier or notify-send, which you don't seem to have installed. 53 | 54 | Linux: 55 | 56 | Download and install notify-send for your distribution 57 | `) 58 | os.Exit(1) 59 | } 60 | 61 | } 62 | } 63 | } 64 | 65 | func (n *Notifier) SendSuiteCompletionNotification(suite testsuite.TestSuite, suitePassed bool) { 66 | if suitePassed { 67 | n.SendNotification("Ginkgo [PASS]", fmt.Sprintf(`Test suite for "%s" passed.`, suite.PackageName)) 68 | } else { 69 | n.SendNotification("Ginkgo [FAIL]", fmt.Sprintf(`Test suite for "%s" failed.`, suite.PackageName)) 70 | } 71 | } 72 | 73 | func (n *Notifier) SendNotification(title string, subtitle string) { 74 | 75 | if n.commandFlags.Notify { 76 | onLinux := (runtime.GOOS == "linux") 77 | onOSX := (runtime.GOOS == "darwin") 78 | 79 | if onOSX { 80 | 81 | _, err := exec.LookPath("terminal-notifier") 82 | if err == nil { 83 | args := []string{"-title", title, "-subtitle", subtitle, "-group", "com.onsi.ginkgo"} 84 | terminal := os.Getenv("TERM_PROGRAM") 85 | if terminal == "iTerm.app" { 86 | args = append(args, "-activate", "com.googlecode.iterm2") 87 | } else if terminal == "Apple_Terminal" { 88 | args = append(args, "-activate", "com.apple.Terminal") 89 | } 90 | 91 | exec.Command("terminal-notifier", args...).Run() 92 | } 93 | 94 | } else if onLinux { 95 | 96 | _, err := exec.LookPath("notify-send") 97 | if err == nil { 98 | args := []string{"-a", "ginkgo", title, subtitle} 99 | exec.Command("notify-send", args...).Run() 100 | } 101 | 102 | } 103 | } 104 | } 105 | 106 | func (n *Notifier) RunCommand(suite testsuite.TestSuite, suitePassed bool) { 107 | 108 | command := n.commandFlags.AfterSuiteHook 109 | if command != "" { 110 | 111 | // Allow for string replacement to pass input to the command 112 | passed := "[FAIL]" 113 | if suitePassed { 114 | passed = "[PASS]" 115 | } 116 | command = strings.Replace(command, "(ginkgo-suite-passed)", passed, -1) 117 | command = strings.Replace(command, "(ginkgo-suite-name)", suite.PackageName, -1) 118 | 119 | // Must break command into parts 120 | splitArgs := regexp.MustCompile(`'.+'|".+"|\S+`) 121 | parts := splitArgs.FindAllString(command, -1) 122 | 123 | output, err := exec.Command(parts[0], parts[1:]...).CombinedOutput() 124 | if err != nil { 125 | fmt.Println("Post-suite command failed:") 126 | if config.DefaultReporterConfig.NoColor { 127 | fmt.Printf("\t%s\n", output) 128 | } else { 129 | fmt.Printf("\t%s%s%s\n", redColor, string(output), defaultStyle) 130 | } 131 | n.SendNotification("Ginkgo [ERROR]", fmt.Sprintf(`After suite command "%s" failed`, n.commandFlags.AfterSuiteHook)) 132 | } else { 133 | fmt.Println("Post-suite command succeeded:") 134 | if config.DefaultReporterConfig.NoColor { 135 | fmt.Printf("\t%s\n", output) 136 | } else { 137 | fmt.Printf("\t%s%s%s\n", greenColor, string(output), defaultStyle) 138 | } 139 | } 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/ginkgo/ginkgo/unfocus_command.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "os/exec" 7 | ) 8 | 9 | func BuildUnfocusCommand() *Command { 10 | return &Command{ 11 | Name: "unfocus", 12 | AltName: "blur", 13 | FlagSet: flag.NewFlagSet("unfocus", flag.ExitOnError), 14 | UsageCommand: "ginkgo unfocus (or ginkgo blur)", 15 | Usage: []string{ 16 | "Recursively unfocuses any focused tests under the current directory", 17 | }, 18 | Command: unfocusSpecs, 19 | } 20 | } 21 | 22 | func unfocusSpecs([]string, []string) { 23 | unfocus("Describe") 24 | unfocus("Context") 25 | unfocus("It") 26 | unfocus("Measure") 27 | unfocus("DescribeTable") 28 | unfocus("Entry") 29 | } 30 | 31 | func unfocus(component string) { 32 | fmt.Printf("Removing F%s...\n", component) 33 | cmd := exec.Command("gofmt", fmt.Sprintf("-r=F%s -> %s", component, component), "-w", ".") 34 | out, _ := cmd.CombinedOutput() 35 | if string(out) != "" { 36 | println(string(out)) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/ginkgo/ginkgo/version_command.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "github.com/onsi/ginkgo/config" 7 | ) 8 | 9 | func BuildVersionCommand() *Command { 10 | return &Command{ 11 | Name: "version", 12 | FlagSet: flag.NewFlagSet("version", flag.ExitOnError), 13 | UsageCommand: "ginkgo version", 14 | Usage: []string{ 15 | "Print Ginkgo's version", 16 | }, 17 | Command: printVersion, 18 | } 19 | } 20 | 21 | func printVersion([]string, []string) { 22 | fmt.Printf("Ginkgo Version %s\n", config.VERSION) 23 | } 24 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/ginkgo/internal/codelocation/code_location.go: -------------------------------------------------------------------------------- 1 | package codelocation 2 | 3 | import ( 4 | "regexp" 5 | "runtime" 6 | "runtime/debug" 7 | "strings" 8 | 9 | "github.com/onsi/ginkgo/types" 10 | ) 11 | 12 | func New(skip int) types.CodeLocation { 13 | _, file, line, _ := runtime.Caller(skip + 1) 14 | stackTrace := PruneStack(string(debug.Stack()), skip) 15 | return types.CodeLocation{FileName: file, LineNumber: line, FullStackTrace: stackTrace} 16 | } 17 | 18 | func PruneStack(fullStackTrace string, skip int) string { 19 | stack := strings.Split(fullStackTrace, "\n") 20 | if len(stack) > 2*(skip+1) { 21 | stack = stack[2*(skip+1):] 22 | } 23 | prunedStack := []string{} 24 | re := regexp.MustCompile(`\/ginkgo\/|\/pkg\/testing\/|\/pkg\/runtime\/`) 25 | for i := 0; i < len(stack)/2; i++ { 26 | if !re.Match([]byte(stack[i*2])) { 27 | prunedStack = append(prunedStack, stack[i*2]) 28 | prunedStack = append(prunedStack, stack[i*2+1]) 29 | } 30 | } 31 | return strings.Join(prunedStack, "\n") 32 | } 33 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/ginkgo/internal/failer/failer.go: -------------------------------------------------------------------------------- 1 | package failer 2 | 3 | import ( 4 | "fmt" 5 | "sync" 6 | 7 | "github.com/onsi/ginkgo/types" 8 | ) 9 | 10 | type Failer struct { 11 | lock *sync.Mutex 12 | failure types.SpecFailure 13 | state types.SpecState 14 | } 15 | 16 | func New() *Failer { 17 | return &Failer{ 18 | lock: &sync.Mutex{}, 19 | state: types.SpecStatePassed, 20 | } 21 | } 22 | 23 | func (f *Failer) Panic(location types.CodeLocation, forwardedPanic interface{}) { 24 | f.lock.Lock() 25 | defer f.lock.Unlock() 26 | 27 | if f.state == types.SpecStatePassed { 28 | f.state = types.SpecStatePanicked 29 | f.failure = types.SpecFailure{ 30 | Message: "Test Panicked", 31 | Location: location, 32 | ForwardedPanic: fmt.Sprintf("%v", forwardedPanic), 33 | } 34 | } 35 | } 36 | 37 | func (f *Failer) Timeout(location types.CodeLocation) { 38 | f.lock.Lock() 39 | defer f.lock.Unlock() 40 | 41 | if f.state == types.SpecStatePassed { 42 | f.state = types.SpecStateTimedOut 43 | f.failure = types.SpecFailure{ 44 | Message: "Timed out", 45 | Location: location, 46 | } 47 | } 48 | } 49 | 50 | func (f *Failer) Fail(message string, location types.CodeLocation) { 51 | f.lock.Lock() 52 | defer f.lock.Unlock() 53 | 54 | if f.state == types.SpecStatePassed { 55 | f.state = types.SpecStateFailed 56 | f.failure = types.SpecFailure{ 57 | Message: message, 58 | Location: location, 59 | } 60 | } 61 | } 62 | 63 | func (f *Failer) Drain(componentType types.SpecComponentType, componentIndex int, componentCodeLocation types.CodeLocation) (types.SpecFailure, types.SpecState) { 64 | f.lock.Lock() 65 | defer f.lock.Unlock() 66 | 67 | failure := f.failure 68 | outcome := f.state 69 | if outcome != types.SpecStatePassed { 70 | failure.ComponentType = componentType 71 | failure.ComponentIndex = componentIndex 72 | failure.ComponentCodeLocation = componentCodeLocation 73 | } 74 | 75 | f.state = types.SpecStatePassed 76 | f.failure = types.SpecFailure{} 77 | 78 | return failure, outcome 79 | } 80 | 81 | func (f *Failer) Skip(message string, location types.CodeLocation) { 82 | f.lock.Lock() 83 | defer f.lock.Unlock() 84 | 85 | if f.state == types.SpecStatePassed { 86 | f.state = types.SpecStateSkipped 87 | f.failure = types.SpecFailure{ 88 | Message: message, 89 | Location: location, 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/ginkgo/internal/leafnodes/benchmarker.go: -------------------------------------------------------------------------------- 1 | package leafnodes 2 | 3 | import ( 4 | "math" 5 | "time" 6 | 7 | "sync" 8 | 9 | "github.com/onsi/ginkgo/types" 10 | ) 11 | 12 | type benchmarker struct { 13 | mu sync.Mutex 14 | measurements map[string]*types.SpecMeasurement 15 | orderCounter int 16 | } 17 | 18 | func newBenchmarker() *benchmarker { 19 | return &benchmarker{ 20 | measurements: make(map[string]*types.SpecMeasurement, 0), 21 | } 22 | } 23 | 24 | func (b *benchmarker) Time(name string, body func(), info ...interface{}) (elapsedTime time.Duration) { 25 | t := time.Now() 26 | body() 27 | elapsedTime = time.Since(t) 28 | 29 | b.mu.Lock() 30 | defer b.mu.Unlock() 31 | measurement := b.getMeasurement(name, "Fastest Time", "Slowest Time", "Average Time", "s", info...) 32 | measurement.Results = append(measurement.Results, elapsedTime.Seconds()) 33 | 34 | return 35 | } 36 | 37 | func (b *benchmarker) RecordValue(name string, value float64, info ...interface{}) { 38 | measurement := b.getMeasurement(name, "Smallest", " Largest", " Average", "", info...) 39 | b.mu.Lock() 40 | defer b.mu.Unlock() 41 | measurement.Results = append(measurement.Results, value) 42 | } 43 | 44 | func (b *benchmarker) getMeasurement(name string, smallestLabel string, largestLabel string, averageLabel string, units string, info ...interface{}) *types.SpecMeasurement { 45 | measurement, ok := b.measurements[name] 46 | if !ok { 47 | var computedInfo interface{} 48 | computedInfo = nil 49 | if len(info) > 0 { 50 | computedInfo = info[0] 51 | } 52 | measurement = &types.SpecMeasurement{ 53 | Name: name, 54 | Info: computedInfo, 55 | Order: b.orderCounter, 56 | SmallestLabel: smallestLabel, 57 | LargestLabel: largestLabel, 58 | AverageLabel: averageLabel, 59 | Units: units, 60 | Results: make([]float64, 0), 61 | } 62 | b.measurements[name] = measurement 63 | b.orderCounter++ 64 | } 65 | 66 | return measurement 67 | } 68 | 69 | func (b *benchmarker) measurementsReport() map[string]*types.SpecMeasurement { 70 | b.mu.Lock() 71 | defer b.mu.Unlock() 72 | for _, measurement := range b.measurements { 73 | measurement.Smallest = math.MaxFloat64 74 | measurement.Largest = -math.MaxFloat64 75 | sum := float64(0) 76 | sumOfSquares := float64(0) 77 | 78 | for _, result := range measurement.Results { 79 | if result > measurement.Largest { 80 | measurement.Largest = result 81 | } 82 | if result < measurement.Smallest { 83 | measurement.Smallest = result 84 | } 85 | sum += result 86 | sumOfSquares += result * result 87 | } 88 | 89 | n := float64(len(measurement.Results)) 90 | measurement.Average = sum / n 91 | measurement.StdDeviation = math.Sqrt(sumOfSquares/n - (sum/n)*(sum/n)) 92 | } 93 | 94 | return b.measurements 95 | } 96 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/ginkgo/internal/leafnodes/interfaces.go: -------------------------------------------------------------------------------- 1 | package leafnodes 2 | 3 | import ( 4 | "github.com/onsi/ginkgo/types" 5 | ) 6 | 7 | type BasicNode interface { 8 | Type() types.SpecComponentType 9 | Run() (types.SpecState, types.SpecFailure) 10 | CodeLocation() types.CodeLocation 11 | } 12 | 13 | type SubjectNode interface { 14 | BasicNode 15 | 16 | Text() string 17 | Flag() types.FlagType 18 | Samples() int 19 | } 20 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/ginkgo/internal/leafnodes/it_node.go: -------------------------------------------------------------------------------- 1 | package leafnodes 2 | 3 | import ( 4 | "github.com/onsi/ginkgo/internal/failer" 5 | "github.com/onsi/ginkgo/types" 6 | "time" 7 | ) 8 | 9 | type ItNode struct { 10 | runner *runner 11 | 12 | flag types.FlagType 13 | text string 14 | } 15 | 16 | func NewItNode(text string, body interface{}, flag types.FlagType, codeLocation types.CodeLocation, timeout time.Duration, failer *failer.Failer, componentIndex int) *ItNode { 17 | return &ItNode{ 18 | runner: newRunner(body, codeLocation, timeout, failer, types.SpecComponentTypeIt, componentIndex), 19 | flag: flag, 20 | text: text, 21 | } 22 | } 23 | 24 | func (node *ItNode) Run() (outcome types.SpecState, failure types.SpecFailure) { 25 | return node.runner.run() 26 | } 27 | 28 | func (node *ItNode) Type() types.SpecComponentType { 29 | return types.SpecComponentTypeIt 30 | } 31 | 32 | func (node *ItNode) Text() string { 33 | return node.text 34 | } 35 | 36 | func (node *ItNode) Flag() types.FlagType { 37 | return node.flag 38 | } 39 | 40 | func (node *ItNode) CodeLocation() types.CodeLocation { 41 | return node.runner.codeLocation 42 | } 43 | 44 | func (node *ItNode) Samples() int { 45 | return 1 46 | } 47 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/ginkgo/internal/leafnodes/measure_node.go: -------------------------------------------------------------------------------- 1 | package leafnodes 2 | 3 | import ( 4 | "github.com/onsi/ginkgo/internal/failer" 5 | "github.com/onsi/ginkgo/types" 6 | "reflect" 7 | ) 8 | 9 | type MeasureNode struct { 10 | runner *runner 11 | 12 | text string 13 | flag types.FlagType 14 | samples int 15 | benchmarker *benchmarker 16 | } 17 | 18 | func NewMeasureNode(text string, body interface{}, flag types.FlagType, codeLocation types.CodeLocation, samples int, failer *failer.Failer, componentIndex int) *MeasureNode { 19 | benchmarker := newBenchmarker() 20 | 21 | wrappedBody := func() { 22 | reflect.ValueOf(body).Call([]reflect.Value{reflect.ValueOf(benchmarker)}) 23 | } 24 | 25 | return &MeasureNode{ 26 | runner: newRunner(wrappedBody, codeLocation, 0, failer, types.SpecComponentTypeMeasure, componentIndex), 27 | 28 | text: text, 29 | flag: flag, 30 | samples: samples, 31 | benchmarker: benchmarker, 32 | } 33 | } 34 | 35 | func (node *MeasureNode) Run() (outcome types.SpecState, failure types.SpecFailure) { 36 | return node.runner.run() 37 | } 38 | 39 | func (node *MeasureNode) MeasurementsReport() map[string]*types.SpecMeasurement { 40 | return node.benchmarker.measurementsReport() 41 | } 42 | 43 | func (node *MeasureNode) Type() types.SpecComponentType { 44 | return types.SpecComponentTypeMeasure 45 | } 46 | 47 | func (node *MeasureNode) Text() string { 48 | return node.text 49 | } 50 | 51 | func (node *MeasureNode) Flag() types.FlagType { 52 | return node.flag 53 | } 54 | 55 | func (node *MeasureNode) CodeLocation() types.CodeLocation { 56 | return node.runner.codeLocation 57 | } 58 | 59 | func (node *MeasureNode) Samples() int { 60 | return node.samples 61 | } 62 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/ginkgo/internal/leafnodes/runner.go: -------------------------------------------------------------------------------- 1 | package leafnodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/onsi/ginkgo/internal/codelocation" 6 | "github.com/onsi/ginkgo/internal/failer" 7 | "github.com/onsi/ginkgo/types" 8 | "reflect" 9 | "time" 10 | ) 11 | 12 | type runner struct { 13 | isAsync bool 14 | asyncFunc func(chan<- interface{}) 15 | syncFunc func() 16 | codeLocation types.CodeLocation 17 | timeoutThreshold time.Duration 18 | nodeType types.SpecComponentType 19 | componentIndex int 20 | failer *failer.Failer 21 | } 22 | 23 | func newRunner(body interface{}, codeLocation types.CodeLocation, timeout time.Duration, failer *failer.Failer, nodeType types.SpecComponentType, componentIndex int) *runner { 24 | bodyType := reflect.TypeOf(body) 25 | if bodyType.Kind() != reflect.Func { 26 | panic(fmt.Sprintf("Expected a function but got something else at %v", codeLocation)) 27 | } 28 | 29 | runner := &runner{ 30 | codeLocation: codeLocation, 31 | timeoutThreshold: timeout, 32 | failer: failer, 33 | nodeType: nodeType, 34 | componentIndex: componentIndex, 35 | } 36 | 37 | switch bodyType.NumIn() { 38 | case 0: 39 | runner.syncFunc = body.(func()) 40 | return runner 41 | case 1: 42 | if !(bodyType.In(0).Kind() == reflect.Chan && bodyType.In(0).Elem().Kind() == reflect.Interface) { 43 | panic(fmt.Sprintf("Must pass a Done channel to function at %v", codeLocation)) 44 | } 45 | 46 | wrappedBody := func(done chan<- interface{}) { 47 | bodyValue := reflect.ValueOf(body) 48 | bodyValue.Call([]reflect.Value{reflect.ValueOf(done)}) 49 | } 50 | 51 | runner.isAsync = true 52 | runner.asyncFunc = wrappedBody 53 | return runner 54 | } 55 | 56 | panic(fmt.Sprintf("Too many arguments to function at %v", codeLocation)) 57 | } 58 | 59 | func (r *runner) run() (outcome types.SpecState, failure types.SpecFailure) { 60 | if r.isAsync { 61 | return r.runAsync() 62 | } else { 63 | return r.runSync() 64 | } 65 | } 66 | 67 | func (r *runner) runAsync() (outcome types.SpecState, failure types.SpecFailure) { 68 | done := make(chan interface{}, 1) 69 | 70 | go func() { 71 | finished := false 72 | 73 | defer func() { 74 | if e := recover(); e != nil || !finished { 75 | r.failer.Panic(codelocation.New(2), e) 76 | select { 77 | case <-done: 78 | break 79 | default: 80 | close(done) 81 | } 82 | } 83 | }() 84 | 85 | r.asyncFunc(done) 86 | finished = true 87 | }() 88 | 89 | select { 90 | case <-done: 91 | case <-time.After(r.timeoutThreshold): 92 | r.failer.Timeout(r.codeLocation) 93 | } 94 | 95 | failure, outcome = r.failer.Drain(r.nodeType, r.componentIndex, r.codeLocation) 96 | return 97 | } 98 | func (r *runner) runSync() (outcome types.SpecState, failure types.SpecFailure) { 99 | finished := false 100 | 101 | defer func() { 102 | if e := recover(); e != nil || !finished { 103 | r.failer.Panic(codelocation.New(2), e) 104 | } 105 | 106 | failure, outcome = r.failer.Drain(r.nodeType, r.componentIndex, r.codeLocation) 107 | }() 108 | 109 | r.syncFunc() 110 | finished = true 111 | 112 | return 113 | } 114 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/ginkgo/internal/leafnodes/setup_nodes.go: -------------------------------------------------------------------------------- 1 | package leafnodes 2 | 3 | import ( 4 | "github.com/onsi/ginkgo/internal/failer" 5 | "github.com/onsi/ginkgo/types" 6 | "time" 7 | ) 8 | 9 | type SetupNode struct { 10 | runner *runner 11 | } 12 | 13 | func (node *SetupNode) Run() (outcome types.SpecState, failure types.SpecFailure) { 14 | return node.runner.run() 15 | } 16 | 17 | func (node *SetupNode) Type() types.SpecComponentType { 18 | return node.runner.nodeType 19 | } 20 | 21 | func (node *SetupNode) CodeLocation() types.CodeLocation { 22 | return node.runner.codeLocation 23 | } 24 | 25 | func NewBeforeEachNode(body interface{}, codeLocation types.CodeLocation, timeout time.Duration, failer *failer.Failer, componentIndex int) *SetupNode { 26 | return &SetupNode{ 27 | runner: newRunner(body, codeLocation, timeout, failer, types.SpecComponentTypeBeforeEach, componentIndex), 28 | } 29 | } 30 | 31 | func NewAfterEachNode(body interface{}, codeLocation types.CodeLocation, timeout time.Duration, failer *failer.Failer, componentIndex int) *SetupNode { 32 | return &SetupNode{ 33 | runner: newRunner(body, codeLocation, timeout, failer, types.SpecComponentTypeAfterEach, componentIndex), 34 | } 35 | } 36 | 37 | func NewJustBeforeEachNode(body interface{}, codeLocation types.CodeLocation, timeout time.Duration, failer *failer.Failer, componentIndex int) *SetupNode { 38 | return &SetupNode{ 39 | runner: newRunner(body, codeLocation, timeout, failer, types.SpecComponentTypeJustBeforeEach, componentIndex), 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/ginkgo/internal/leafnodes/suite_nodes.go: -------------------------------------------------------------------------------- 1 | package leafnodes 2 | 3 | import ( 4 | "github.com/onsi/ginkgo/internal/failer" 5 | "github.com/onsi/ginkgo/types" 6 | "time" 7 | ) 8 | 9 | type SuiteNode interface { 10 | Run(parallelNode int, parallelTotal int, syncHost string) bool 11 | Passed() bool 12 | Summary() *types.SetupSummary 13 | } 14 | 15 | type simpleSuiteNode struct { 16 | runner *runner 17 | outcome types.SpecState 18 | failure types.SpecFailure 19 | runTime time.Duration 20 | } 21 | 22 | func (node *simpleSuiteNode) Run(parallelNode int, parallelTotal int, syncHost string) bool { 23 | t := time.Now() 24 | node.outcome, node.failure = node.runner.run() 25 | node.runTime = time.Since(t) 26 | 27 | return node.outcome == types.SpecStatePassed 28 | } 29 | 30 | func (node *simpleSuiteNode) Passed() bool { 31 | return node.outcome == types.SpecStatePassed 32 | } 33 | 34 | func (node *simpleSuiteNode) Summary() *types.SetupSummary { 35 | return &types.SetupSummary{ 36 | ComponentType: node.runner.nodeType, 37 | CodeLocation: node.runner.codeLocation, 38 | State: node.outcome, 39 | RunTime: node.runTime, 40 | Failure: node.failure, 41 | } 42 | } 43 | 44 | func NewBeforeSuiteNode(body interface{}, codeLocation types.CodeLocation, timeout time.Duration, failer *failer.Failer) SuiteNode { 45 | return &simpleSuiteNode{ 46 | runner: newRunner(body, codeLocation, timeout, failer, types.SpecComponentTypeBeforeSuite, 0), 47 | } 48 | } 49 | 50 | func NewAfterSuiteNode(body interface{}, codeLocation types.CodeLocation, timeout time.Duration, failer *failer.Failer) SuiteNode { 51 | return &simpleSuiteNode{ 52 | runner: newRunner(body, codeLocation, timeout, failer, types.SpecComponentTypeAfterSuite, 0), 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/ginkgo/internal/leafnodes/synchronized_after_suite_node.go: -------------------------------------------------------------------------------- 1 | package leafnodes 2 | 3 | import ( 4 | "encoding/json" 5 | "github.com/onsi/ginkgo/internal/failer" 6 | "github.com/onsi/ginkgo/types" 7 | "io/ioutil" 8 | "net/http" 9 | "time" 10 | ) 11 | 12 | type synchronizedAfterSuiteNode struct { 13 | runnerA *runner 14 | runnerB *runner 15 | 16 | outcome types.SpecState 17 | failure types.SpecFailure 18 | runTime time.Duration 19 | } 20 | 21 | func NewSynchronizedAfterSuiteNode(bodyA interface{}, bodyB interface{}, codeLocation types.CodeLocation, timeout time.Duration, failer *failer.Failer) SuiteNode { 22 | return &synchronizedAfterSuiteNode{ 23 | runnerA: newRunner(bodyA, codeLocation, timeout, failer, types.SpecComponentTypeAfterSuite, 0), 24 | runnerB: newRunner(bodyB, codeLocation, timeout, failer, types.SpecComponentTypeAfterSuite, 0), 25 | } 26 | } 27 | 28 | func (node *synchronizedAfterSuiteNode) Run(parallelNode int, parallelTotal int, syncHost string) bool { 29 | node.outcome, node.failure = node.runnerA.run() 30 | 31 | if parallelNode == 1 { 32 | if parallelTotal > 1 { 33 | node.waitUntilOtherNodesAreDone(syncHost) 34 | } 35 | 36 | outcome, failure := node.runnerB.run() 37 | 38 | if node.outcome == types.SpecStatePassed { 39 | node.outcome, node.failure = outcome, failure 40 | } 41 | } 42 | 43 | return node.outcome == types.SpecStatePassed 44 | } 45 | 46 | func (node *synchronizedAfterSuiteNode) Passed() bool { 47 | return node.outcome == types.SpecStatePassed 48 | } 49 | 50 | func (node *synchronizedAfterSuiteNode) Summary() *types.SetupSummary { 51 | return &types.SetupSummary{ 52 | ComponentType: node.runnerA.nodeType, 53 | CodeLocation: node.runnerA.codeLocation, 54 | State: node.outcome, 55 | RunTime: node.runTime, 56 | Failure: node.failure, 57 | } 58 | } 59 | 60 | func (node *synchronizedAfterSuiteNode) waitUntilOtherNodesAreDone(syncHost string) { 61 | for { 62 | if node.canRun(syncHost) { 63 | return 64 | } 65 | 66 | time.Sleep(50 * time.Millisecond) 67 | } 68 | } 69 | 70 | func (node *synchronizedAfterSuiteNode) canRun(syncHost string) bool { 71 | resp, err := http.Get(syncHost + "/RemoteAfterSuiteData") 72 | if err != nil || resp.StatusCode != http.StatusOK { 73 | return false 74 | } 75 | 76 | body, err := ioutil.ReadAll(resp.Body) 77 | if err != nil { 78 | return false 79 | } 80 | resp.Body.Close() 81 | 82 | afterSuiteData := types.RemoteAfterSuiteData{} 83 | err = json.Unmarshal(body, &afterSuiteData) 84 | if err != nil { 85 | return false 86 | } 87 | 88 | return afterSuiteData.CanRun 89 | } 90 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/ginkgo/internal/remote/forwarding_reporter.go: -------------------------------------------------------------------------------- 1 | package remote 2 | 3 | import ( 4 | "bytes" 5 | "encoding/json" 6 | "io" 7 | "net/http" 8 | 9 | "github.com/onsi/ginkgo/config" 10 | "github.com/onsi/ginkgo/types" 11 | ) 12 | 13 | //An interface to net/http's client to allow the injection of fakes under test 14 | type Poster interface { 15 | Post(url string, bodyType string, body io.Reader) (resp *http.Response, err error) 16 | } 17 | 18 | /* 19 | The ForwardingReporter is a Ginkgo reporter that forwards information to 20 | a Ginkgo remote server. 21 | 22 | When streaming parallel test output, this repoter is automatically installed by Ginkgo. 23 | 24 | This is accomplished by passing in the GINKGO_REMOTE_REPORTING_SERVER environment variable to `go test`, the Ginkgo test runner 25 | detects this environment variable (which should contain the host of the server) and automatically installs a ForwardingReporter 26 | in place of Ginkgo's DefaultReporter. 27 | */ 28 | 29 | type ForwardingReporter struct { 30 | serverHost string 31 | poster Poster 32 | outputInterceptor OutputInterceptor 33 | } 34 | 35 | func NewForwardingReporter(serverHost string, poster Poster, outputInterceptor OutputInterceptor) *ForwardingReporter { 36 | return &ForwardingReporter{ 37 | serverHost: serverHost, 38 | poster: poster, 39 | outputInterceptor: outputInterceptor, 40 | } 41 | } 42 | 43 | func (reporter *ForwardingReporter) post(path string, data interface{}) { 44 | encoded, _ := json.Marshal(data) 45 | buffer := bytes.NewBuffer(encoded) 46 | reporter.poster.Post(reporter.serverHost+path, "application/json", buffer) 47 | } 48 | 49 | func (reporter *ForwardingReporter) SpecSuiteWillBegin(conf config.GinkgoConfigType, summary *types.SuiteSummary) { 50 | data := struct { 51 | Config config.GinkgoConfigType `json:"config"` 52 | Summary *types.SuiteSummary `json:"suite-summary"` 53 | }{ 54 | conf, 55 | summary, 56 | } 57 | 58 | reporter.outputInterceptor.StartInterceptingOutput() 59 | reporter.post("/SpecSuiteWillBegin", data) 60 | } 61 | 62 | func (reporter *ForwardingReporter) BeforeSuiteDidRun(setupSummary *types.SetupSummary) { 63 | output, _ := reporter.outputInterceptor.StopInterceptingAndReturnOutput() 64 | reporter.outputInterceptor.StartInterceptingOutput() 65 | setupSummary.CapturedOutput = output 66 | reporter.post("/BeforeSuiteDidRun", setupSummary) 67 | } 68 | 69 | func (reporter *ForwardingReporter) SpecWillRun(specSummary *types.SpecSummary) { 70 | reporter.post("/SpecWillRun", specSummary) 71 | } 72 | 73 | func (reporter *ForwardingReporter) SpecDidComplete(specSummary *types.SpecSummary) { 74 | output, _ := reporter.outputInterceptor.StopInterceptingAndReturnOutput() 75 | reporter.outputInterceptor.StartInterceptingOutput() 76 | specSummary.CapturedOutput = output 77 | reporter.post("/SpecDidComplete", specSummary) 78 | } 79 | 80 | func (reporter *ForwardingReporter) AfterSuiteDidRun(setupSummary *types.SetupSummary) { 81 | output, _ := reporter.outputInterceptor.StopInterceptingAndReturnOutput() 82 | reporter.outputInterceptor.StartInterceptingOutput() 83 | setupSummary.CapturedOutput = output 84 | reporter.post("/AfterSuiteDidRun", setupSummary) 85 | } 86 | 87 | func (reporter *ForwardingReporter) SpecSuiteDidEnd(summary *types.SuiteSummary) { 88 | reporter.outputInterceptor.StopInterceptingAndReturnOutput() 89 | reporter.post("/SpecSuiteDidEnd", summary) 90 | } 91 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor.go: -------------------------------------------------------------------------------- 1 | package remote 2 | 3 | /* 4 | The OutputInterceptor is used by the ForwardingReporter to 5 | intercept and capture all stdin and stderr output during a test run. 6 | */ 7 | type OutputInterceptor interface { 8 | StartInterceptingOutput() error 9 | StopInterceptingAndReturnOutput() (string, error) 10 | } 11 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_unix.go: -------------------------------------------------------------------------------- 1 | // +build freebsd openbsd netbsd dragonfly darwin linux 2 | 3 | package remote 4 | 5 | import ( 6 | "errors" 7 | "io/ioutil" 8 | "os" 9 | ) 10 | 11 | func NewOutputInterceptor() OutputInterceptor { 12 | return &outputInterceptor{} 13 | } 14 | 15 | type outputInterceptor struct { 16 | redirectFile *os.File 17 | intercepting bool 18 | } 19 | 20 | func (interceptor *outputInterceptor) StartInterceptingOutput() error { 21 | if interceptor.intercepting { 22 | return errors.New("Already intercepting output!") 23 | } 24 | interceptor.intercepting = true 25 | 26 | var err error 27 | 28 | interceptor.redirectFile, err = ioutil.TempFile("", "ginkgo-output") 29 | if err != nil { 30 | return err 31 | } 32 | 33 | // Call a function in ./syscall_dup_*.go 34 | // If building for everything other than linux_arm64, 35 | // use a "normal" syscall.Dup2(oldfd, newfd) call. If building for linux_arm64 (which doesn't have syscall.Dup2) 36 | // call syscall.Dup3(oldfd, newfd, 0). They are nearly identical, see: http://linux.die.net/man/2/dup3 37 | syscallDup(int(interceptor.redirectFile.Fd()), 1) 38 | syscallDup(int(interceptor.redirectFile.Fd()), 2) 39 | 40 | return nil 41 | } 42 | 43 | func (interceptor *outputInterceptor) StopInterceptingAndReturnOutput() (string, error) { 44 | if !interceptor.intercepting { 45 | return "", errors.New("Not intercepting output!") 46 | } 47 | 48 | interceptor.redirectFile.Close() 49 | output, err := ioutil.ReadFile(interceptor.redirectFile.Name()) 50 | os.Remove(interceptor.redirectFile.Name()) 51 | 52 | interceptor.intercepting = false 53 | 54 | return string(output), err 55 | } 56 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_win.go: -------------------------------------------------------------------------------- 1 | // +build windows 2 | 3 | package remote 4 | 5 | import ( 6 | "errors" 7 | ) 8 | 9 | func NewOutputInterceptor() OutputInterceptor { 10 | return &outputInterceptor{} 11 | } 12 | 13 | type outputInterceptor struct { 14 | intercepting bool 15 | } 16 | 17 | func (interceptor *outputInterceptor) StartInterceptingOutput() error { 18 | if interceptor.intercepting { 19 | return errors.New("Already intercepting output!") 20 | } 21 | interceptor.intercepting = true 22 | 23 | // not working on windows... 24 | 25 | return nil 26 | } 27 | 28 | func (interceptor *outputInterceptor) StopInterceptingAndReturnOutput() (string, error) { 29 | // not working on windows... 30 | interceptor.intercepting = false 31 | 32 | return "", nil 33 | } 34 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/ginkgo/internal/remote/syscall_dup_linux_arm64.go: -------------------------------------------------------------------------------- 1 | // +build linux,arm64 2 | 3 | package remote 4 | 5 | import "syscall" 6 | 7 | // linux_arm64 doesn't have syscall.Dup2 which ginkgo uses, so 8 | // use the nearly identical syscall.Dup3 instead 9 | func syscallDup(oldfd int, newfd int) (err error) { 10 | return syscall.Dup3(oldfd, newfd, 0) 11 | } -------------------------------------------------------------------------------- /vendor/github.com/onsi/ginkgo/internal/remote/syscall_dup_unix.go: -------------------------------------------------------------------------------- 1 | // +build !linux !arm64 2 | // +build !windows 3 | 4 | package remote 5 | 6 | import "syscall" 7 | 8 | func syscallDup(oldfd int, newfd int) (err error) { 9 | return syscall.Dup2(oldfd, newfd) 10 | } -------------------------------------------------------------------------------- /vendor/github.com/onsi/ginkgo/internal/spec/index_computer.go: -------------------------------------------------------------------------------- 1 | package spec 2 | 3 | func ParallelizedIndexRange(length int, parallelTotal int, parallelNode int) (startIndex int, count int) { 4 | if length == 0 { 5 | return 0, 0 6 | } 7 | 8 | // We have more nodes than tests. Trivial case. 9 | if parallelTotal >= length { 10 | if parallelNode > length { 11 | return 0, 0 12 | } else { 13 | return parallelNode - 1, 1 14 | } 15 | } 16 | 17 | // This is the minimum amount of tests that a node will be required to run 18 | minTestsPerNode := length / parallelTotal 19 | 20 | // This is the maximum amount of tests that a node will be required to run 21 | // The algorithm guarantees that this would be equal to at least the minimum amount 22 | // and at most one more 23 | maxTestsPerNode := minTestsPerNode 24 | if length%parallelTotal != 0 { 25 | maxTestsPerNode++ 26 | } 27 | 28 | // Number of nodes that will have to run the maximum amount of tests per node 29 | numMaxLoadNodes := length % parallelTotal 30 | 31 | // Number of nodes that precede the current node and will have to run the maximum amount of tests per node 32 | var numPrecedingMaxLoadNodes int 33 | if parallelNode > numMaxLoadNodes { 34 | numPrecedingMaxLoadNodes = numMaxLoadNodes 35 | } else { 36 | numPrecedingMaxLoadNodes = parallelNode - 1 37 | } 38 | 39 | // Number of nodes that precede the current node and will have to run the minimum amount of tests per node 40 | var numPrecedingMinLoadNodes int 41 | if parallelNode <= numMaxLoadNodes { 42 | numPrecedingMinLoadNodes = 0 43 | } else { 44 | numPrecedingMinLoadNodes = parallelNode - numMaxLoadNodes - 1 45 | } 46 | 47 | // Evaluate the test start index and number of tests to run 48 | startIndex = numPrecedingMaxLoadNodes*maxTestsPerNode + numPrecedingMinLoadNodes*minTestsPerNode 49 | if parallelNode > numMaxLoadNodes { 50 | count = minTestsPerNode 51 | } else { 52 | count = maxTestsPerNode 53 | } 54 | return 55 | } 56 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/ginkgo/internal/spec/specs.go: -------------------------------------------------------------------------------- 1 | package spec 2 | 3 | import ( 4 | "math/rand" 5 | "regexp" 6 | "sort" 7 | ) 8 | 9 | type Specs struct { 10 | specs []*Spec 11 | numberOfOriginalSpecs int 12 | hasProgrammaticFocus bool 13 | } 14 | 15 | func NewSpecs(specs []*Spec) *Specs { 16 | return &Specs{ 17 | specs: specs, 18 | numberOfOriginalSpecs: len(specs), 19 | } 20 | } 21 | 22 | func (e *Specs) Specs() []*Spec { 23 | return e.specs 24 | } 25 | 26 | func (e *Specs) NumberOfOriginalSpecs() int { 27 | return e.numberOfOriginalSpecs 28 | } 29 | 30 | func (e *Specs) HasProgrammaticFocus() bool { 31 | return e.hasProgrammaticFocus 32 | } 33 | 34 | func (e *Specs) Shuffle(r *rand.Rand) { 35 | sort.Sort(e) 36 | permutation := r.Perm(len(e.specs)) 37 | shuffledSpecs := make([]*Spec, len(e.specs)) 38 | for i, j := range permutation { 39 | shuffledSpecs[i] = e.specs[j] 40 | } 41 | e.specs = shuffledSpecs 42 | } 43 | 44 | func (e *Specs) ApplyFocus(description string, focusString string, skipString string) { 45 | if focusString == "" && skipString == "" { 46 | e.applyProgrammaticFocus() 47 | } else { 48 | e.applyRegExpFocus(description, focusString, skipString) 49 | } 50 | } 51 | 52 | func (e *Specs) applyProgrammaticFocus() { 53 | e.hasProgrammaticFocus = false 54 | for _, spec := range e.specs { 55 | if spec.Focused() && !spec.Pending() { 56 | e.hasProgrammaticFocus = true 57 | break 58 | } 59 | } 60 | 61 | if e.hasProgrammaticFocus { 62 | for _, spec := range e.specs { 63 | if !spec.Focused() { 64 | spec.Skip() 65 | } 66 | } 67 | } 68 | } 69 | 70 | func (e *Specs) applyRegExpFocus(description string, focusString string, skipString string) { 71 | for _, spec := range e.specs { 72 | matchesFocus := true 73 | matchesSkip := false 74 | 75 | toMatch := []byte(description + " " + spec.ConcatenatedString()) 76 | 77 | if focusString != "" { 78 | focusFilter := regexp.MustCompile(focusString) 79 | matchesFocus = focusFilter.Match([]byte(toMatch)) 80 | } 81 | 82 | if skipString != "" { 83 | skipFilter := regexp.MustCompile(skipString) 84 | matchesSkip = skipFilter.Match([]byte(toMatch)) 85 | } 86 | 87 | if !matchesFocus || matchesSkip { 88 | spec.Skip() 89 | } 90 | } 91 | } 92 | 93 | func (e *Specs) SkipMeasurements() { 94 | for _, spec := range e.specs { 95 | if spec.IsMeasurement() { 96 | spec.Skip() 97 | } 98 | } 99 | } 100 | 101 | func (e *Specs) TrimForParallelization(total int, node int) { 102 | startIndex, count := ParallelizedIndexRange(len(e.specs), total, node) 103 | if count == 0 { 104 | e.specs = make([]*Spec, 0) 105 | } else { 106 | e.specs = e.specs[startIndex : startIndex+count] 107 | } 108 | } 109 | 110 | //sort.Interface 111 | 112 | func (e *Specs) Len() int { 113 | return len(e.specs) 114 | } 115 | 116 | func (e *Specs) Less(i, j int) bool { 117 | return e.specs[i].ConcatenatedString() < e.specs[j].ConcatenatedString() 118 | } 119 | 120 | func (e *Specs) Swap(i, j int) { 121 | e.specs[i], e.specs[j] = e.specs[j], e.specs[i] 122 | } 123 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/ginkgo/internal/specrunner/random_id.go: -------------------------------------------------------------------------------- 1 | package specrunner 2 | 3 | import ( 4 | "crypto/rand" 5 | "fmt" 6 | ) 7 | 8 | func randomID() string { 9 | b := make([]byte, 8) 10 | _, err := rand.Read(b) 11 | if err != nil { 12 | return "" 13 | } 14 | return fmt.Sprintf("%x-%x-%x-%x", b[0:2], b[2:4], b[4:6], b[6:8]) 15 | } 16 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/ginkgo/internal/testingtproxy/testing_t_proxy.go: -------------------------------------------------------------------------------- 1 | package testingtproxy 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | ) 7 | 8 | type failFunc func(message string, callerSkip ...int) 9 | 10 | func New(writer io.Writer, fail failFunc, offset int) *ginkgoTestingTProxy { 11 | return &ginkgoTestingTProxy{ 12 | fail: fail, 13 | offset: offset, 14 | writer: writer, 15 | } 16 | } 17 | 18 | type ginkgoTestingTProxy struct { 19 | fail failFunc 20 | offset int 21 | writer io.Writer 22 | } 23 | 24 | func (t *ginkgoTestingTProxy) Error(args ...interface{}) { 25 | t.fail(fmt.Sprintln(args...), t.offset) 26 | } 27 | 28 | func (t *ginkgoTestingTProxy) Errorf(format string, args ...interface{}) { 29 | t.fail(fmt.Sprintf(format, args...), t.offset) 30 | } 31 | 32 | func (t *ginkgoTestingTProxy) Fail() { 33 | t.fail("failed", t.offset) 34 | } 35 | 36 | func (t *ginkgoTestingTProxy) FailNow() { 37 | t.fail("failed", t.offset) 38 | } 39 | 40 | func (t *ginkgoTestingTProxy) Fatal(args ...interface{}) { 41 | t.fail(fmt.Sprintln(args...), t.offset) 42 | } 43 | 44 | func (t *ginkgoTestingTProxy) Fatalf(format string, args ...interface{}) { 45 | t.fail(fmt.Sprintf(format, args...), t.offset) 46 | } 47 | 48 | func (t *ginkgoTestingTProxy) Log(args ...interface{}) { 49 | fmt.Fprintln(t.writer, args...) 50 | } 51 | 52 | func (t *ginkgoTestingTProxy) Logf(format string, args ...interface{}) { 53 | fmt.Fprintf(t.writer, format, args...) 54 | } 55 | 56 | func (t *ginkgoTestingTProxy) Failed() bool { 57 | return false 58 | } 59 | 60 | func (t *ginkgoTestingTProxy) Parallel() { 61 | } 62 | 63 | func (t *ginkgoTestingTProxy) Skip(args ...interface{}) { 64 | fmt.Println(args...) 65 | } 66 | 67 | func (t *ginkgoTestingTProxy) Skipf(format string, args ...interface{}) { 68 | fmt.Printf(format, args...) 69 | } 70 | 71 | func (t *ginkgoTestingTProxy) SkipNow() { 72 | } 73 | 74 | func (t *ginkgoTestingTProxy) Skipped() bool { 75 | return false 76 | } 77 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/ginkgo/internal/writer/fake_writer.go: -------------------------------------------------------------------------------- 1 | package writer 2 | 3 | type FakeGinkgoWriter struct { 4 | EventStream []string 5 | } 6 | 7 | func NewFake() *FakeGinkgoWriter { 8 | return &FakeGinkgoWriter{ 9 | EventStream: []string{}, 10 | } 11 | } 12 | 13 | func (writer *FakeGinkgoWriter) AddEvent(event string) { 14 | writer.EventStream = append(writer.EventStream, event) 15 | } 16 | 17 | func (writer *FakeGinkgoWriter) Truncate() { 18 | writer.EventStream = append(writer.EventStream, "TRUNCATE") 19 | } 20 | 21 | func (writer *FakeGinkgoWriter) DumpOut() { 22 | writer.EventStream = append(writer.EventStream, "DUMP") 23 | } 24 | 25 | func (writer *FakeGinkgoWriter) DumpOutWithHeader(header string) { 26 | writer.EventStream = append(writer.EventStream, "DUMP_WITH_HEADER: "+header) 27 | } 28 | 29 | func (writer *FakeGinkgoWriter) Write(data []byte) (n int, err error) { 30 | return 0, nil 31 | } 32 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/ginkgo/internal/writer/writer.go: -------------------------------------------------------------------------------- 1 | package writer 2 | 3 | import ( 4 | "bytes" 5 | "io" 6 | "sync" 7 | ) 8 | 9 | type WriterInterface interface { 10 | io.Writer 11 | 12 | Truncate() 13 | DumpOut() 14 | DumpOutWithHeader(header string) 15 | } 16 | 17 | type Writer struct { 18 | buffer *bytes.Buffer 19 | outWriter io.Writer 20 | lock *sync.Mutex 21 | stream bool 22 | } 23 | 24 | func New(outWriter io.Writer) *Writer { 25 | return &Writer{ 26 | buffer: &bytes.Buffer{}, 27 | lock: &sync.Mutex{}, 28 | outWriter: outWriter, 29 | stream: true, 30 | } 31 | } 32 | 33 | func (w *Writer) SetStream(stream bool) { 34 | w.lock.Lock() 35 | defer w.lock.Unlock() 36 | w.stream = stream 37 | } 38 | 39 | func (w *Writer) Write(b []byte) (n int, err error) { 40 | w.lock.Lock() 41 | defer w.lock.Unlock() 42 | 43 | if w.stream { 44 | return w.outWriter.Write(b) 45 | } else { 46 | return w.buffer.Write(b) 47 | } 48 | } 49 | 50 | func (w *Writer) Truncate() { 51 | w.lock.Lock() 52 | defer w.lock.Unlock() 53 | w.buffer.Reset() 54 | } 55 | 56 | func (w *Writer) DumpOut() { 57 | w.lock.Lock() 58 | defer w.lock.Unlock() 59 | if !w.stream { 60 | w.buffer.WriteTo(w.outWriter) 61 | } 62 | } 63 | 64 | func (w *Writer) DumpOutWithHeader(header string) { 65 | w.lock.Lock() 66 | defer w.lock.Unlock() 67 | if !w.stream && w.buffer.Len() > 0 { 68 | w.outWriter.Write([]byte(header)) 69 | w.buffer.WriteTo(w.outWriter) 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/ginkgo/reporters/default_reporter.go: -------------------------------------------------------------------------------- 1 | /* 2 | Ginkgo's Default Reporter 3 | 4 | A number of command line flags are available to tweak Ginkgo's default output. 5 | 6 | These are documented [here](http://onsi.github.io/ginkgo/#running_tests) 7 | */ 8 | package reporters 9 | 10 | import ( 11 | "github.com/onsi/ginkgo/config" 12 | "github.com/onsi/ginkgo/reporters/stenographer" 13 | "github.com/onsi/ginkgo/types" 14 | ) 15 | 16 | type DefaultReporter struct { 17 | config config.DefaultReporterConfigType 18 | stenographer stenographer.Stenographer 19 | specSummaries []*types.SpecSummary 20 | } 21 | 22 | func NewDefaultReporter(config config.DefaultReporterConfigType, stenographer stenographer.Stenographer) *DefaultReporter { 23 | return &DefaultReporter{ 24 | config: config, 25 | stenographer: stenographer, 26 | } 27 | } 28 | 29 | func (reporter *DefaultReporter) SpecSuiteWillBegin(config config.GinkgoConfigType, summary *types.SuiteSummary) { 30 | reporter.stenographer.AnnounceSuite(summary.SuiteDescription, config.RandomSeed, config.RandomizeAllSpecs, reporter.config.Succinct) 31 | if config.ParallelTotal > 1 { 32 | reporter.stenographer.AnnounceParallelRun(config.ParallelNode, config.ParallelTotal, summary.NumberOfTotalSpecs, summary.NumberOfSpecsBeforeParallelization, reporter.config.Succinct) 33 | } 34 | reporter.stenographer.AnnounceNumberOfSpecs(summary.NumberOfSpecsThatWillBeRun, summary.NumberOfTotalSpecs, reporter.config.Succinct) 35 | } 36 | 37 | func (reporter *DefaultReporter) BeforeSuiteDidRun(setupSummary *types.SetupSummary) { 38 | if setupSummary.State != types.SpecStatePassed { 39 | reporter.stenographer.AnnounceBeforeSuiteFailure(setupSummary, reporter.config.Succinct, reporter.config.FullTrace) 40 | } 41 | } 42 | 43 | func (reporter *DefaultReporter) AfterSuiteDidRun(setupSummary *types.SetupSummary) { 44 | if setupSummary.State != types.SpecStatePassed { 45 | reporter.stenographer.AnnounceAfterSuiteFailure(setupSummary, reporter.config.Succinct, reporter.config.FullTrace) 46 | } 47 | } 48 | 49 | func (reporter *DefaultReporter) SpecWillRun(specSummary *types.SpecSummary) { 50 | if reporter.config.Verbose && !reporter.config.Succinct && specSummary.State != types.SpecStatePending && specSummary.State != types.SpecStateSkipped { 51 | reporter.stenographer.AnnounceSpecWillRun(specSummary) 52 | } 53 | } 54 | 55 | func (reporter *DefaultReporter) SpecDidComplete(specSummary *types.SpecSummary) { 56 | switch specSummary.State { 57 | case types.SpecStatePassed: 58 | if specSummary.IsMeasurement { 59 | reporter.stenographer.AnnounceSuccesfulMeasurement(specSummary, reporter.config.Succinct) 60 | } else if specSummary.RunTime.Seconds() >= reporter.config.SlowSpecThreshold { 61 | reporter.stenographer.AnnounceSuccesfulSlowSpec(specSummary, reporter.config.Succinct) 62 | } else { 63 | reporter.stenographer.AnnounceSuccesfulSpec(specSummary) 64 | } 65 | case types.SpecStatePending: 66 | reporter.stenographer.AnnouncePendingSpec(specSummary, reporter.config.NoisyPendings && !reporter.config.Succinct) 67 | case types.SpecStateSkipped: 68 | reporter.stenographer.AnnounceSkippedSpec(specSummary, reporter.config.Succinct, reporter.config.FullTrace) 69 | case types.SpecStateTimedOut: 70 | reporter.stenographer.AnnounceSpecTimedOut(specSummary, reporter.config.Succinct, reporter.config.FullTrace) 71 | case types.SpecStatePanicked: 72 | reporter.stenographer.AnnounceSpecPanicked(specSummary, reporter.config.Succinct, reporter.config.FullTrace) 73 | case types.SpecStateFailed: 74 | reporter.stenographer.AnnounceSpecFailed(specSummary, reporter.config.Succinct, reporter.config.FullTrace) 75 | } 76 | 77 | reporter.specSummaries = append(reporter.specSummaries, specSummary) 78 | } 79 | 80 | func (reporter *DefaultReporter) SpecSuiteDidEnd(summary *types.SuiteSummary) { 81 | reporter.stenographer.SummarizeFailures(reporter.specSummaries) 82 | reporter.stenographer.AnnounceSpecRunCompletion(summary, reporter.config.Succinct) 83 | } 84 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/ginkgo/reporters/fake_reporter.go: -------------------------------------------------------------------------------- 1 | package reporters 2 | 3 | import ( 4 | "github.com/onsi/ginkgo/config" 5 | "github.com/onsi/ginkgo/types" 6 | ) 7 | 8 | //FakeReporter is useful for testing purposes 9 | type FakeReporter struct { 10 | Config config.GinkgoConfigType 11 | 12 | BeginSummary *types.SuiteSummary 13 | BeforeSuiteSummary *types.SetupSummary 14 | SpecWillRunSummaries []*types.SpecSummary 15 | SpecSummaries []*types.SpecSummary 16 | AfterSuiteSummary *types.SetupSummary 17 | EndSummary *types.SuiteSummary 18 | 19 | SpecWillRunStub func(specSummary *types.SpecSummary) 20 | SpecDidCompleteStub func(specSummary *types.SpecSummary) 21 | } 22 | 23 | func NewFakeReporter() *FakeReporter { 24 | return &FakeReporter{ 25 | SpecWillRunSummaries: make([]*types.SpecSummary, 0), 26 | SpecSummaries: make([]*types.SpecSummary, 0), 27 | } 28 | } 29 | 30 | func (fakeR *FakeReporter) SpecSuiteWillBegin(config config.GinkgoConfigType, summary *types.SuiteSummary) { 31 | fakeR.Config = config 32 | fakeR.BeginSummary = summary 33 | } 34 | 35 | func (fakeR *FakeReporter) BeforeSuiteDidRun(setupSummary *types.SetupSummary) { 36 | fakeR.BeforeSuiteSummary = setupSummary 37 | } 38 | 39 | func (fakeR *FakeReporter) SpecWillRun(specSummary *types.SpecSummary) { 40 | if fakeR.SpecWillRunStub != nil { 41 | fakeR.SpecWillRunStub(specSummary) 42 | } 43 | fakeR.SpecWillRunSummaries = append(fakeR.SpecWillRunSummaries, specSummary) 44 | } 45 | 46 | func (fakeR *FakeReporter) SpecDidComplete(specSummary *types.SpecSummary) { 47 | if fakeR.SpecDidCompleteStub != nil { 48 | fakeR.SpecDidCompleteStub(specSummary) 49 | } 50 | fakeR.SpecSummaries = append(fakeR.SpecSummaries, specSummary) 51 | } 52 | 53 | func (fakeR *FakeReporter) AfterSuiteDidRun(setupSummary *types.SetupSummary) { 54 | fakeR.AfterSuiteSummary = setupSummary 55 | } 56 | 57 | func (fakeR *FakeReporter) SpecSuiteDidEnd(summary *types.SuiteSummary) { 58 | fakeR.EndSummary = summary 59 | } 60 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/ginkgo/reporters/reporter.go: -------------------------------------------------------------------------------- 1 | package reporters 2 | 3 | import ( 4 | "github.com/onsi/ginkgo/config" 5 | "github.com/onsi/ginkgo/types" 6 | ) 7 | 8 | type Reporter interface { 9 | SpecSuiteWillBegin(config config.GinkgoConfigType, summary *types.SuiteSummary) 10 | BeforeSuiteDidRun(setupSummary *types.SetupSummary) 11 | SpecWillRun(specSummary *types.SpecSummary) 12 | SpecDidComplete(specSummary *types.SpecSummary) 13 | AfterSuiteDidRun(setupSummary *types.SetupSummary) 14 | SpecSuiteDidEnd(summary *types.SuiteSummary) 15 | } 16 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/ginkgo/reporters/stenographer/console_logging.go: -------------------------------------------------------------------------------- 1 | package stenographer 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | ) 7 | 8 | func (s *consoleStenographer) colorize(colorCode string, format string, args ...interface{}) string { 9 | var out string 10 | 11 | if len(args) > 0 { 12 | out = fmt.Sprintf(format, args...) 13 | } else { 14 | out = format 15 | } 16 | 17 | if s.color { 18 | return fmt.Sprintf("%s%s%s", colorCode, out, defaultStyle) 19 | } else { 20 | return out 21 | } 22 | } 23 | 24 | func (s *consoleStenographer) printBanner(text string, bannerCharacter string) { 25 | fmt.Println(text) 26 | fmt.Println(strings.Repeat(bannerCharacter, len(text))) 27 | } 28 | 29 | func (s *consoleStenographer) printNewLine() { 30 | fmt.Println("") 31 | } 32 | 33 | func (s *consoleStenographer) printDelimiter() { 34 | fmt.Println(s.colorize(grayColor, "%s", strings.Repeat("-", 30))) 35 | } 36 | 37 | func (s *consoleStenographer) print(indentation int, format string, args ...interface{}) { 38 | fmt.Print(s.indent(indentation, format, args...)) 39 | } 40 | 41 | func (s *consoleStenographer) println(indentation int, format string, args ...interface{}) { 42 | fmt.Println(s.indent(indentation, format, args...)) 43 | } 44 | 45 | func (s *consoleStenographer) indent(indentation int, format string, args ...interface{}) string { 46 | var text string 47 | 48 | if len(args) > 0 { 49 | text = fmt.Sprintf(format, args...) 50 | } else { 51 | text = format 52 | } 53 | 54 | stringArray := strings.Split(text, "\n") 55 | padding := "" 56 | if indentation >= 0 { 57 | padding = strings.Repeat(" ", indentation) 58 | } 59 | for i, s := range stringArray { 60 | stringArray[i] = fmt.Sprintf("%s%s", padding, s) 61 | } 62 | 63 | return strings.Join(stringArray, "\n") 64 | } 65 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/ginkgo/reporters/teamcity_reporter.go: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | TeamCity Reporter for Ginkgo 4 | 5 | Makes use of TeamCity's support for Service Messages 6 | http://confluence.jetbrains.com/display/TCD7/Build+Script+Interaction+with+TeamCity#BuildScriptInteractionwithTeamCity-ReportingTests 7 | */ 8 | 9 | package reporters 10 | 11 | import ( 12 | "fmt" 13 | "github.com/onsi/ginkgo/config" 14 | "github.com/onsi/ginkgo/types" 15 | "io" 16 | "strings" 17 | ) 18 | 19 | const ( 20 | messageId = "##teamcity" 21 | ) 22 | 23 | type TeamCityReporter struct { 24 | writer io.Writer 25 | testSuiteName string 26 | } 27 | 28 | func NewTeamCityReporter(writer io.Writer) *TeamCityReporter { 29 | return &TeamCityReporter{ 30 | writer: writer, 31 | } 32 | } 33 | 34 | func (reporter *TeamCityReporter) SpecSuiteWillBegin(config config.GinkgoConfigType, summary *types.SuiteSummary) { 35 | reporter.testSuiteName = escape(summary.SuiteDescription) 36 | fmt.Fprintf(reporter.writer, "%s[testSuiteStarted name='%s']", messageId, reporter.testSuiteName) 37 | } 38 | 39 | func (reporter *TeamCityReporter) BeforeSuiteDidRun(setupSummary *types.SetupSummary) { 40 | reporter.handleSetupSummary("BeforeSuite", setupSummary) 41 | } 42 | 43 | func (reporter *TeamCityReporter) AfterSuiteDidRun(setupSummary *types.SetupSummary) { 44 | reporter.handleSetupSummary("AfterSuite", setupSummary) 45 | } 46 | 47 | func (reporter *TeamCityReporter) handleSetupSummary(name string, setupSummary *types.SetupSummary) { 48 | if setupSummary.State != types.SpecStatePassed { 49 | testName := escape(name) 50 | fmt.Fprintf(reporter.writer, "%s[testStarted name='%s']", messageId, testName) 51 | message := escape(setupSummary.Failure.ComponentCodeLocation.String()) 52 | details := escape(setupSummary.Failure.Message) 53 | fmt.Fprintf(reporter.writer, "%s[testFailed name='%s' message='%s' details='%s']", messageId, testName, message, details) 54 | durationInMilliseconds := setupSummary.RunTime.Seconds() * 1000 55 | fmt.Fprintf(reporter.writer, "%s[testFinished name='%s' duration='%v']", messageId, testName, durationInMilliseconds) 56 | } 57 | } 58 | 59 | func (reporter *TeamCityReporter) SpecWillRun(specSummary *types.SpecSummary) { 60 | testName := escape(strings.Join(specSummary.ComponentTexts[1:], " ")) 61 | fmt.Fprintf(reporter.writer, "%s[testStarted name='%s']", messageId, testName) 62 | } 63 | 64 | func (reporter *TeamCityReporter) SpecDidComplete(specSummary *types.SpecSummary) { 65 | testName := escape(strings.Join(specSummary.ComponentTexts[1:], " ")) 66 | 67 | if specSummary.State == types.SpecStateFailed || specSummary.State == types.SpecStateTimedOut || specSummary.State == types.SpecStatePanicked { 68 | message := escape(specSummary.Failure.ComponentCodeLocation.String()) 69 | details := escape(specSummary.Failure.Message) 70 | fmt.Fprintf(reporter.writer, "%s[testFailed name='%s' message='%s' details='%s']", messageId, testName, message, details) 71 | } 72 | if specSummary.State == types.SpecStateSkipped || specSummary.State == types.SpecStatePending { 73 | fmt.Fprintf(reporter.writer, "%s[testIgnored name='%s']", messageId, testName) 74 | } 75 | 76 | durationInMilliseconds := specSummary.RunTime.Seconds() * 1000 77 | fmt.Fprintf(reporter.writer, "%s[testFinished name='%s' duration='%v']", messageId, testName, durationInMilliseconds) 78 | } 79 | 80 | func (reporter *TeamCityReporter) SpecSuiteDidEnd(summary *types.SuiteSummary) { 81 | fmt.Fprintf(reporter.writer, "%s[testSuiteFinished name='%s']", messageId, reporter.testSuiteName) 82 | } 83 | 84 | func escape(output string) string { 85 | output = strings.Replace(output, "|", "||", -1) 86 | output = strings.Replace(output, "'", "|'", -1) 87 | output = strings.Replace(output, "\n", "|n", -1) 88 | output = strings.Replace(output, "\r", "|r", -1) 89 | output = strings.Replace(output, "[", "|[", -1) 90 | output = strings.Replace(output, "]", "|]", -1) 91 | return output 92 | } 93 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/ginkgo/types/code_location.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | type CodeLocation struct { 8 | FileName string 9 | LineNumber int 10 | FullStackTrace string 11 | } 12 | 13 | func (codeLocation CodeLocation) String() string { 14 | return fmt.Sprintf("%s:%d", codeLocation.FileName, codeLocation.LineNumber) 15 | } 16 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/ginkgo/types/synchronization.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "encoding/json" 5 | ) 6 | 7 | type RemoteBeforeSuiteState int 8 | 9 | const ( 10 | RemoteBeforeSuiteStateInvalid RemoteBeforeSuiteState = iota 11 | 12 | RemoteBeforeSuiteStatePending 13 | RemoteBeforeSuiteStatePassed 14 | RemoteBeforeSuiteStateFailed 15 | RemoteBeforeSuiteStateDisappeared 16 | ) 17 | 18 | type RemoteBeforeSuiteData struct { 19 | Data []byte 20 | State RemoteBeforeSuiteState 21 | } 22 | 23 | func (r RemoteBeforeSuiteData) ToJSON() []byte { 24 | data, _ := json.Marshal(r) 25 | return data 26 | } 27 | 28 | type RemoteAfterSuiteData struct { 29 | CanRun bool 30 | } 31 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/ginkgo/types/types.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import "time" 4 | 5 | const GINKGO_FOCUS_EXIT_CODE = 197 6 | 7 | type SuiteSummary struct { 8 | SuiteDescription string 9 | SuiteSucceeded bool 10 | SuiteID string 11 | 12 | NumberOfSpecsBeforeParallelization int 13 | NumberOfTotalSpecs int 14 | NumberOfSpecsThatWillBeRun int 15 | NumberOfPendingSpecs int 16 | NumberOfSkippedSpecs int 17 | NumberOfPassedSpecs int 18 | NumberOfFailedSpecs int 19 | RunTime time.Duration 20 | } 21 | 22 | type SpecSummary struct { 23 | ComponentTexts []string 24 | ComponentCodeLocations []CodeLocation 25 | 26 | State SpecState 27 | RunTime time.Duration 28 | Failure SpecFailure 29 | IsMeasurement bool 30 | NumberOfSamples int 31 | Measurements map[string]*SpecMeasurement 32 | 33 | CapturedOutput string 34 | SuiteID string 35 | } 36 | 37 | func (s SpecSummary) HasFailureState() bool { 38 | return s.State.IsFailure() 39 | } 40 | 41 | func (s SpecSummary) TimedOut() bool { 42 | return s.State == SpecStateTimedOut 43 | } 44 | 45 | func (s SpecSummary) Panicked() bool { 46 | return s.State == SpecStatePanicked 47 | } 48 | 49 | func (s SpecSummary) Failed() bool { 50 | return s.State == SpecStateFailed 51 | } 52 | 53 | func (s SpecSummary) Passed() bool { 54 | return s.State == SpecStatePassed 55 | } 56 | 57 | func (s SpecSummary) Skipped() bool { 58 | return s.State == SpecStateSkipped 59 | } 60 | 61 | func (s SpecSummary) Pending() bool { 62 | return s.State == SpecStatePending 63 | } 64 | 65 | type SetupSummary struct { 66 | ComponentType SpecComponentType 67 | CodeLocation CodeLocation 68 | 69 | State SpecState 70 | RunTime time.Duration 71 | Failure SpecFailure 72 | 73 | CapturedOutput string 74 | SuiteID string 75 | } 76 | 77 | type SpecFailure struct { 78 | Message string 79 | Location CodeLocation 80 | ForwardedPanic string 81 | 82 | ComponentIndex int 83 | ComponentType SpecComponentType 84 | ComponentCodeLocation CodeLocation 85 | } 86 | 87 | type SpecMeasurement struct { 88 | Name string 89 | Info interface{} 90 | Order int 91 | 92 | Results []float64 93 | 94 | Smallest float64 95 | Largest float64 96 | Average float64 97 | StdDeviation float64 98 | 99 | SmallestLabel string 100 | LargestLabel string 101 | AverageLabel string 102 | Units string 103 | } 104 | 105 | type SpecState uint 106 | 107 | const ( 108 | SpecStateInvalid SpecState = iota 109 | 110 | SpecStatePending 111 | SpecStateSkipped 112 | SpecStatePassed 113 | SpecStateFailed 114 | SpecStatePanicked 115 | SpecStateTimedOut 116 | ) 117 | 118 | func (state SpecState) IsFailure() bool { 119 | return state == SpecStateTimedOut || state == SpecStatePanicked || state == SpecStateFailed 120 | } 121 | 122 | type SpecComponentType uint 123 | 124 | const ( 125 | SpecComponentTypeInvalid SpecComponentType = iota 126 | 127 | SpecComponentTypeContainer 128 | SpecComponentTypeBeforeSuite 129 | SpecComponentTypeAfterSuite 130 | SpecComponentTypeBeforeEach 131 | SpecComponentTypeJustBeforeEach 132 | SpecComponentTypeAfterEach 133 | SpecComponentTypeIt 134 | SpecComponentTypeMeasure 135 | ) 136 | 137 | type FlagType uint 138 | 139 | const ( 140 | FlagTypeNone FlagType = iota 141 | FlagTypeFocused 142 | FlagTypePending 143 | ) 144 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/gomega/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## HEAD 2 | 3 | Improvements: 4 | 5 | - Added `BeSent` which attempts to send a value down a channel and fails if the attempt blocks. Can be paired with `Eventually` to safely send a value down a channel with a timeout. 6 | - `Ω`, `Expect`, `Eventually`, and `Consistently` now immediately `panic` if there is no registered fail handler. This is always a mistake that can hide failing tests. 7 | - `Receive()` no longer errors when passed a closed channel, it's perfectly fine to attempt to read from a closed channel so Ω(c).Should(Receive()) always fails and Ω(c).ShoudlNot(Receive()) always passes with a closed channel. 8 | - Added `HavePrefix` and `HaveSuffix` matchers. 9 | - `ghttp` can now handle concurrent requests. 10 | - Added `Succeed` which allows one to write `Ω(MyFunction()).Should(Succeed())`. 11 | - Improved `ghttp`'s behavior around failing assertions and panics: 12 | - If a registered handler makes a failing assertion `ghttp` will return `500`. 13 | - If a registered handler panics, `ghttp` will return `500` *and* fail the test. This is new behavior that may cause existing code to break. This code is almost certainly incorrect and creating a false positive. 14 | - `ghttp` servers can take an `io.Writer`. `ghttp` will write a line to the writer when each request arrives. 15 | - Added `WithTransform` matcher to allow munging input data before feeding into the relevant matcher 16 | - Added boolean `And`, `Or`, and `Not` matchers to allow creating composite matchers 17 | 18 | Bug Fixes: 19 | - gexec: `session.Wait` now uses `EventuallyWithOffset` to get the right line number in the failure. 20 | - `ContainElement` no longer bails if a passed-in matcher errors. 21 | 22 | ## 1.0 (8/2/2014) 23 | 24 | No changes. Dropping "beta" from the version number. 25 | 26 | ## 1.0.0-beta (7/8/2014) 27 | Breaking Changes: 28 | 29 | - Changed OmegaMatcher interface. Instead of having `Match` return failure messages, two new methods `FailureMessage` and `NegatedFailureMessage` are called instead. 30 | - Moved and renamed OmegaFailHandler to types.GomegaFailHandler and OmegaMatcher to types.GomegaMatcher. Any references to OmegaMatcher in any custom matchers will need to be changed to point to types.GomegaMatcher 31 | 32 | New Test-Support Features: 33 | 34 | - `ghttp`: supports testing http clients 35 | - Provides a flexible fake http server 36 | - Provides a collection of chainable http handlers that perform assertions. 37 | - `gbytes`: supports making ordered assertions against streams of data 38 | - Provides a `gbytes.Buffer` 39 | - Provides a `Say` matcher to perform ordered assertions against output data 40 | - `gexec`: supports testing external processes 41 | - Provides support for building Go binaries 42 | - Wraps and starts `exec.Cmd` commands 43 | - Makes it easy to assert against stdout and stderr 44 | - Makes it easy to send signals and wait for processes to exit 45 | - Provides an `Exit` matcher to assert against exit code. 46 | 47 | DSL Changes: 48 | 49 | - `Eventually` and `Consistently` can accept `time.Duration` interval and polling inputs. 50 | - The default timeouts for `Eventually` and `Consistently` are now configurable. 51 | 52 | New Matchers: 53 | 54 | - `ConsistOf`: order-independent assertion against the elements of an array/slice or keys of a map. 55 | - `BeTemporally`: like `BeNumerically` but for `time.Time` 56 | - `HaveKeyWithValue`: asserts a map has a given key with the given value. 57 | 58 | Updated Matchers: 59 | 60 | - `Receive` matcher can take a matcher as an argument and passes only if the channel under test receives an objet that satisfies the passed-in matcher. 61 | - Matchers that implement `MatchMayChangeInTheFuture(actual interface{}) bool` can inform `Eventually` and/or `Consistently` when a match has no chance of changing status in the future. For example, `Receive` returns `false` when a channel is closed. 62 | 63 | Misc: 64 | 65 | - Start using semantic versioning 66 | - Start maintaining changelog 67 | 68 | Major refactor: 69 | 70 | - Pull out Gomega's internal to `internal` 71 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/gomega/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013-2014 Onsi Fakhouri 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/gomega/README.md: -------------------------------------------------------------------------------- 1 | ![Gomega: Ginkgo's Preferred Matcher Library](http://onsi.github.io/gomega/images/gomega.png) 2 | 3 | [![Build Status](https://travis-ci.org/onsi/gomega.png)](https://travis-ci.org/onsi/gomega) 4 | 5 | Jump straight to the [docs](http://onsi.github.io/gomega/) to learn about Gomega, including a list of [all available matchers](http://onsi.github.io/gomega/#provided-matchers). 6 | 7 | To discuss Gomega and get updates, join the [google group](https://groups.google.com/d/forum/ginkgo-and-gomega). 8 | 9 | ## [Ginkgo](http://github.com/onsi/ginkgo): a BDD Testing Framework for Golang 10 | 11 | Learn more about Ginkgo [here](http://onsi.github.io/ginkgo/) 12 | 13 | ## License 14 | 15 | Gomega is MIT-Licensed 16 | 17 | The `ConsistOf` matcher uses [goraph](https://github.com/amitkgupta/goraph) which is embedded in the source to simplify distribution. goraph has an MIT license. 18 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/gomega/internal/assertion/assertion.go: -------------------------------------------------------------------------------- 1 | package assertion 2 | 3 | import ( 4 | "fmt" 5 | "reflect" 6 | 7 | "github.com/onsi/gomega/types" 8 | ) 9 | 10 | type Assertion struct { 11 | actualInput interface{} 12 | fail types.GomegaFailHandler 13 | offset int 14 | extra []interface{} 15 | } 16 | 17 | func New(actualInput interface{}, fail types.GomegaFailHandler, offset int, extra ...interface{}) *Assertion { 18 | return &Assertion{ 19 | actualInput: actualInput, 20 | fail: fail, 21 | offset: offset, 22 | extra: extra, 23 | } 24 | } 25 | 26 | func (assertion *Assertion) Should(matcher types.GomegaMatcher, optionalDescription ...interface{}) bool { 27 | return assertion.vetExtras(optionalDescription...) && assertion.match(matcher, true, optionalDescription...) 28 | } 29 | 30 | func (assertion *Assertion) ShouldNot(matcher types.GomegaMatcher, optionalDescription ...interface{}) bool { 31 | return assertion.vetExtras(optionalDescription...) && assertion.match(matcher, false, optionalDescription...) 32 | } 33 | 34 | func (assertion *Assertion) To(matcher types.GomegaMatcher, optionalDescription ...interface{}) bool { 35 | return assertion.vetExtras(optionalDescription...) && assertion.match(matcher, true, optionalDescription...) 36 | } 37 | 38 | func (assertion *Assertion) ToNot(matcher types.GomegaMatcher, optionalDescription ...interface{}) bool { 39 | return assertion.vetExtras(optionalDescription...) && assertion.match(matcher, false, optionalDescription...) 40 | } 41 | 42 | func (assertion *Assertion) NotTo(matcher types.GomegaMatcher, optionalDescription ...interface{}) bool { 43 | return assertion.vetExtras(optionalDescription...) && assertion.match(matcher, false, optionalDescription...) 44 | } 45 | 46 | func (assertion *Assertion) buildDescription(optionalDescription ...interface{}) string { 47 | switch len(optionalDescription) { 48 | case 0: 49 | return "" 50 | default: 51 | return fmt.Sprintf(optionalDescription[0].(string), optionalDescription[1:]...) + "\n" 52 | } 53 | } 54 | 55 | func (assertion *Assertion) match(matcher types.GomegaMatcher, desiredMatch bool, optionalDescription ...interface{}) bool { 56 | matches, err := matcher.Match(assertion.actualInput) 57 | description := assertion.buildDescription(optionalDescription...) 58 | if err != nil { 59 | assertion.fail(description+err.Error(), 2+assertion.offset) 60 | return false 61 | } 62 | if matches != desiredMatch { 63 | var message string 64 | if desiredMatch { 65 | message = matcher.FailureMessage(assertion.actualInput) 66 | } else { 67 | message = matcher.NegatedFailureMessage(assertion.actualInput) 68 | } 69 | assertion.fail(description+message, 2+assertion.offset) 70 | return false 71 | } 72 | 73 | return true 74 | } 75 | 76 | func (assertion *Assertion) vetExtras(optionalDescription ...interface{}) bool { 77 | success, message := vetExtras(assertion.extra) 78 | if success { 79 | return true 80 | } 81 | 82 | description := assertion.buildDescription(optionalDescription...) 83 | assertion.fail(description+message, 2+assertion.offset) 84 | return false 85 | } 86 | 87 | func vetExtras(extras []interface{}) (bool, string) { 88 | for i, extra := range extras { 89 | if extra != nil { 90 | zeroValue := reflect.Zero(reflect.TypeOf(extra)).Interface() 91 | if !reflect.DeepEqual(zeroValue, extra) { 92 | message := fmt.Sprintf("Unexpected non-nil/non-zero extra argument at index %d:\n\t<%T>: %#v", i+1, extra, extra) 93 | return false, message 94 | } 95 | } 96 | } 97 | return true, "" 98 | } 99 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/gomega/internal/oraclematcher/oracle_matcher.go: -------------------------------------------------------------------------------- 1 | package oraclematcher 2 | 3 | import "github.com/onsi/gomega/types" 4 | 5 | /* 6 | GomegaMatchers that also match the OracleMatcher interface can convey information about 7 | whether or not their result will change upon future attempts. 8 | 9 | This allows `Eventually` and `Consistently` to short circuit if success becomes impossible. 10 | 11 | For example, a process' exit code can never change. So, gexec's Exit matcher returns `true` 12 | for `MatchMayChangeInTheFuture` until the process exits, at which point it returns `false` forevermore. 13 | */ 14 | type OracleMatcher interface { 15 | MatchMayChangeInTheFuture(actual interface{}) bool 16 | } 17 | 18 | func MatchMayChangeInTheFuture(matcher types.GomegaMatcher, value interface{}) bool { 19 | oracleMatcher, ok := matcher.(OracleMatcher) 20 | if !ok { 21 | return true 22 | } 23 | 24 | return oracleMatcher.MatchMayChangeInTheFuture(value) 25 | } 26 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/gomega/internal/testingtsupport/testing_t_support.go: -------------------------------------------------------------------------------- 1 | package testingtsupport 2 | 3 | import ( 4 | "regexp" 5 | "runtime/debug" 6 | "strings" 7 | 8 | "github.com/onsi/gomega/types" 9 | ) 10 | 11 | type gomegaTestingT interface { 12 | Errorf(format string, args ...interface{}) 13 | } 14 | 15 | func BuildTestingTGomegaFailHandler(t gomegaTestingT) types.GomegaFailHandler { 16 | return func(message string, callerSkip ...int) { 17 | skip := 1 18 | if len(callerSkip) > 0 { 19 | skip = callerSkip[0] 20 | } 21 | stackTrace := pruneStack(string(debug.Stack()), skip) 22 | t.Errorf("\n%s\n%s", stackTrace, message) 23 | } 24 | } 25 | 26 | func pruneStack(fullStackTrace string, skip int) string { 27 | stack := strings.Split(fullStackTrace, "\n") 28 | if len(stack) > 2*(skip+1) { 29 | stack = stack[2*(skip+1):] 30 | } 31 | prunedStack := []string{} 32 | re := regexp.MustCompile(`\/ginkgo\/|\/pkg\/testing\/|\/pkg\/runtime\/`) 33 | for i := 0; i < len(stack)/2; i++ { 34 | if !re.Match([]byte(stack[i*2])) { 35 | prunedStack = append(prunedStack, stack[i*2]) 36 | prunedStack = append(prunedStack, stack[i*2+1]) 37 | } 38 | } 39 | return strings.Join(prunedStack, "\n") 40 | } 41 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/gomega/matchers/and.go: -------------------------------------------------------------------------------- 1 | package matchers 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/onsi/gomega/format" 7 | "github.com/onsi/gomega/internal/oraclematcher" 8 | "github.com/onsi/gomega/types" 9 | ) 10 | 11 | type AndMatcher struct { 12 | Matchers []types.GomegaMatcher 13 | 14 | // state 15 | firstFailedMatcher types.GomegaMatcher 16 | } 17 | 18 | func (m *AndMatcher) Match(actual interface{}) (success bool, err error) { 19 | m.firstFailedMatcher = nil 20 | for _, matcher := range m.Matchers { 21 | success, err := matcher.Match(actual) 22 | if !success || err != nil { 23 | m.firstFailedMatcher = matcher 24 | return false, err 25 | } 26 | } 27 | return true, nil 28 | } 29 | 30 | func (m *AndMatcher) FailureMessage(actual interface{}) (message string) { 31 | return m.firstFailedMatcher.FailureMessage(actual) 32 | } 33 | 34 | func (m *AndMatcher) NegatedFailureMessage(actual interface{}) (message string) { 35 | // not the most beautiful list of matchers, but not bad either... 36 | return format.Message(actual, fmt.Sprintf("To not satisfy all of these matchers: %s", m.Matchers)) 37 | } 38 | 39 | func (m *AndMatcher) MatchMayChangeInTheFuture(actual interface{}) bool { 40 | /* 41 | Example with 3 matchers: A, B, C 42 | 43 | Match evaluates them: T, F, => F 44 | So match is currently F, what should MatchMayChangeInTheFuture() return? 45 | Seems like it only depends on B, since currently B MUST change to allow the result to become T 46 | 47 | Match eval: T, T, T => T 48 | So match is currently T, what should MatchMayChangeInTheFuture() return? 49 | Seems to depend on ANY of them being able to change to F. 50 | */ 51 | 52 | if m.firstFailedMatcher == nil { 53 | // so all matchers succeeded.. Any one of them changing would change the result. 54 | for _, matcher := range m.Matchers { 55 | if oraclematcher.MatchMayChangeInTheFuture(matcher, actual) { 56 | return true 57 | } 58 | } 59 | return false // none of were going to change 60 | } else { 61 | // one of the matchers failed.. it must be able to change in order to affect the result 62 | return oraclematcher.MatchMayChangeInTheFuture(m.firstFailedMatcher, actual) 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/gomega/matchers/assignable_to_type_of_matcher.go: -------------------------------------------------------------------------------- 1 | package matchers 2 | 3 | import ( 4 | "fmt" 5 | "reflect" 6 | 7 | "github.com/onsi/gomega/format" 8 | ) 9 | 10 | type AssignableToTypeOfMatcher struct { 11 | Expected interface{} 12 | } 13 | 14 | func (matcher *AssignableToTypeOfMatcher) Match(actual interface{}) (success bool, err error) { 15 | if actual == nil || matcher.Expected == nil { 16 | return false, fmt.Errorf("Refusing to compare to .\nBe explicit and use BeNil() instead. This is to avoid mistakes where both sides of an assertion are erroneously uninitialized.") 17 | } 18 | 19 | actualType := reflect.TypeOf(actual) 20 | expectedType := reflect.TypeOf(matcher.Expected) 21 | 22 | return actualType.AssignableTo(expectedType), nil 23 | } 24 | 25 | func (matcher *AssignableToTypeOfMatcher) FailureMessage(actual interface{}) string { 26 | return format.Message(actual, fmt.Sprintf("to be assignable to the type: %T", matcher.Expected)) 27 | } 28 | 29 | func (matcher *AssignableToTypeOfMatcher) NegatedFailureMessage(actual interface{}) string { 30 | return format.Message(actual, fmt.Sprintf("not to be assignable to the type: %T", matcher.Expected)) 31 | } 32 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/gomega/matchers/be_a_directory.go: -------------------------------------------------------------------------------- 1 | package matchers 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | 7 | "github.com/onsi/gomega/format" 8 | ) 9 | 10 | type notADirectoryError struct { 11 | os.FileInfo 12 | } 13 | 14 | func (t notADirectoryError) Error() string { 15 | fileInfo := os.FileInfo(t) 16 | switch { 17 | case fileInfo.Mode().IsRegular(): 18 | return "file is a regular file" 19 | default: 20 | return fmt.Sprintf("file mode is: %s", fileInfo.Mode().String()) 21 | } 22 | } 23 | 24 | type BeADirectoryMatcher struct { 25 | expected interface{} 26 | err error 27 | } 28 | 29 | func (matcher *BeADirectoryMatcher) Match(actual interface{}) (success bool, err error) { 30 | actualFilename, ok := actual.(string) 31 | if !ok { 32 | return false, fmt.Errorf("BeADirectoryMatcher matcher expects a file path") 33 | } 34 | 35 | fileInfo, err := os.Stat(actualFilename) 36 | if err != nil { 37 | matcher.err = err 38 | return false, nil 39 | } 40 | 41 | if !fileInfo.Mode().IsDir() { 42 | matcher.err = notADirectoryError{fileInfo} 43 | return false, nil 44 | } 45 | return true, nil 46 | } 47 | 48 | func (matcher *BeADirectoryMatcher) FailureMessage(actual interface{}) (message string) { 49 | return format.Message(actual, fmt.Sprintf("to be a directory: %s", matcher.err)) 50 | } 51 | 52 | func (matcher *BeADirectoryMatcher) NegatedFailureMessage(actual interface{}) (message string) { 53 | return format.Message(actual, fmt.Sprintf("not be a directory")) 54 | } 55 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/gomega/matchers/be_a_regular_file.go: -------------------------------------------------------------------------------- 1 | package matchers 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | 7 | "github.com/onsi/gomega/format" 8 | ) 9 | 10 | type notARegularFileError struct { 11 | os.FileInfo 12 | } 13 | 14 | func (t notARegularFileError) Error() string { 15 | fileInfo := os.FileInfo(t) 16 | switch { 17 | case fileInfo.IsDir(): 18 | return "file is a directory" 19 | default: 20 | return fmt.Sprintf("file mode is: %s", fileInfo.Mode().String()) 21 | } 22 | } 23 | 24 | type BeARegularFileMatcher struct { 25 | expected interface{} 26 | err error 27 | } 28 | 29 | func (matcher *BeARegularFileMatcher) Match(actual interface{}) (success bool, err error) { 30 | actualFilename, ok := actual.(string) 31 | if !ok { 32 | return false, fmt.Errorf("BeARegularFileMatcher matcher expects a file path") 33 | } 34 | 35 | fileInfo, err := os.Stat(actualFilename) 36 | if err != nil { 37 | matcher.err = err 38 | return false, nil 39 | } 40 | 41 | if !fileInfo.Mode().IsRegular() { 42 | matcher.err = notARegularFileError{fileInfo} 43 | return false, nil 44 | } 45 | return true, nil 46 | } 47 | 48 | func (matcher *BeARegularFileMatcher) FailureMessage(actual interface{}) (message string) { 49 | return format.Message(actual, fmt.Sprintf("to be a regular file: %s", matcher.err)) 50 | } 51 | 52 | func (matcher *BeARegularFileMatcher) NegatedFailureMessage(actual interface{}) (message string) { 53 | return format.Message(actual, fmt.Sprintf("not be a regular file")) 54 | } 55 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/gomega/matchers/be_an_existing_file.go: -------------------------------------------------------------------------------- 1 | package matchers 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | 7 | "github.com/onsi/gomega/format" 8 | ) 9 | 10 | type BeAnExistingFileMatcher struct { 11 | expected interface{} 12 | } 13 | 14 | func (matcher *BeAnExistingFileMatcher) Match(actual interface{}) (success bool, err error) { 15 | actualFilename, ok := actual.(string) 16 | if !ok { 17 | return false, fmt.Errorf("BeAnExistingFileMatcher matcher expects a file path") 18 | } 19 | 20 | if _, err = os.Stat(actualFilename); err != nil { 21 | switch { 22 | case os.IsNotExist(err): 23 | return false, nil 24 | default: 25 | return false, err 26 | } 27 | } 28 | 29 | return true, nil 30 | } 31 | 32 | func (matcher *BeAnExistingFileMatcher) FailureMessage(actual interface{}) (message string) { 33 | return format.Message(actual, fmt.Sprintf("to exist")) 34 | } 35 | 36 | func (matcher *BeAnExistingFileMatcher) NegatedFailureMessage(actual interface{}) (message string) { 37 | return format.Message(actual, fmt.Sprintf("not to exist")) 38 | } 39 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/gomega/matchers/be_closed_matcher.go: -------------------------------------------------------------------------------- 1 | package matchers 2 | 3 | import ( 4 | "fmt" 5 | "github.com/onsi/gomega/format" 6 | "reflect" 7 | ) 8 | 9 | type BeClosedMatcher struct { 10 | } 11 | 12 | func (matcher *BeClosedMatcher) Match(actual interface{}) (success bool, err error) { 13 | if !isChan(actual) { 14 | return false, fmt.Errorf("BeClosed matcher expects a channel. Got:\n%s", format.Object(actual, 1)) 15 | } 16 | 17 | channelType := reflect.TypeOf(actual) 18 | channelValue := reflect.ValueOf(actual) 19 | 20 | if channelType.ChanDir() == reflect.SendDir { 21 | return false, fmt.Errorf("BeClosed matcher cannot determine if a send-only channel is closed or open. Got:\n%s", format.Object(actual, 1)) 22 | } 23 | 24 | winnerIndex, _, open := reflect.Select([]reflect.SelectCase{ 25 | reflect.SelectCase{Dir: reflect.SelectRecv, Chan: channelValue}, 26 | reflect.SelectCase{Dir: reflect.SelectDefault}, 27 | }) 28 | 29 | var closed bool 30 | if winnerIndex == 0 { 31 | closed = !open 32 | } else if winnerIndex == 1 { 33 | closed = false 34 | } 35 | 36 | return closed, nil 37 | } 38 | 39 | func (matcher *BeClosedMatcher) FailureMessage(actual interface{}) (message string) { 40 | return format.Message(actual, "to be closed") 41 | } 42 | 43 | func (matcher *BeClosedMatcher) NegatedFailureMessage(actual interface{}) (message string) { 44 | return format.Message(actual, "to be open") 45 | } 46 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/gomega/matchers/be_empty_matcher.go: -------------------------------------------------------------------------------- 1 | package matchers 2 | 3 | import ( 4 | "fmt" 5 | "github.com/onsi/gomega/format" 6 | ) 7 | 8 | type BeEmptyMatcher struct { 9 | } 10 | 11 | func (matcher *BeEmptyMatcher) Match(actual interface{}) (success bool, err error) { 12 | length, ok := lengthOf(actual) 13 | if !ok { 14 | return false, fmt.Errorf("BeEmpty matcher expects a string/array/map/channel/slice. Got:\n%s", format.Object(actual, 1)) 15 | } 16 | 17 | return length == 0, nil 18 | } 19 | 20 | func (matcher *BeEmptyMatcher) FailureMessage(actual interface{}) (message string) { 21 | return format.Message(actual, "to be empty") 22 | } 23 | 24 | func (matcher *BeEmptyMatcher) NegatedFailureMessage(actual interface{}) (message string) { 25 | return format.Message(actual, "not to be empty") 26 | } 27 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/gomega/matchers/be_equivalent_to_matcher.go: -------------------------------------------------------------------------------- 1 | package matchers 2 | 3 | import ( 4 | "fmt" 5 | "github.com/onsi/gomega/format" 6 | "reflect" 7 | ) 8 | 9 | type BeEquivalentToMatcher struct { 10 | Expected interface{} 11 | } 12 | 13 | func (matcher *BeEquivalentToMatcher) Match(actual interface{}) (success bool, err error) { 14 | if actual == nil && matcher.Expected == nil { 15 | return false, fmt.Errorf("Both actual and expected must not be nil.") 16 | } 17 | 18 | convertedActual := actual 19 | 20 | if actual != nil && matcher.Expected != nil && reflect.TypeOf(actual).ConvertibleTo(reflect.TypeOf(matcher.Expected)) { 21 | convertedActual = reflect.ValueOf(actual).Convert(reflect.TypeOf(matcher.Expected)).Interface() 22 | } 23 | 24 | return reflect.DeepEqual(convertedActual, matcher.Expected), nil 25 | } 26 | 27 | func (matcher *BeEquivalentToMatcher) FailureMessage(actual interface{}) (message string) { 28 | return format.Message(actual, "to be equivalent to", matcher.Expected) 29 | } 30 | 31 | func (matcher *BeEquivalentToMatcher) NegatedFailureMessage(actual interface{}) (message string) { 32 | return format.Message(actual, "not to be equivalent to", matcher.Expected) 33 | } 34 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/gomega/matchers/be_false_matcher.go: -------------------------------------------------------------------------------- 1 | package matchers 2 | 3 | import ( 4 | "fmt" 5 | "github.com/onsi/gomega/format" 6 | ) 7 | 8 | type BeFalseMatcher struct { 9 | } 10 | 11 | func (matcher *BeFalseMatcher) Match(actual interface{}) (success bool, err error) { 12 | if !isBool(actual) { 13 | return false, fmt.Errorf("Expected a boolean. Got:\n%s", format.Object(actual, 1)) 14 | } 15 | 16 | return actual == false, nil 17 | } 18 | 19 | func (matcher *BeFalseMatcher) FailureMessage(actual interface{}) (message string) { 20 | return format.Message(actual, "to be false") 21 | } 22 | 23 | func (matcher *BeFalseMatcher) NegatedFailureMessage(actual interface{}) (message string) { 24 | return format.Message(actual, "not to be false") 25 | } 26 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/gomega/matchers/be_identical_to.go: -------------------------------------------------------------------------------- 1 | package matchers 2 | 3 | import ( 4 | "fmt" 5 | "runtime" 6 | 7 | "github.com/onsi/gomega/format" 8 | ) 9 | 10 | type BeIdenticalToMatcher struct { 11 | Expected interface{} 12 | } 13 | 14 | func (matcher *BeIdenticalToMatcher) Match(actual interface{}) (success bool, matchErr error) { 15 | if actual == nil && matcher.Expected == nil { 16 | return false, fmt.Errorf("Refusing to compare to .\nBe explicit and use BeNil() instead. This is to avoid mistakes where both sides of an assertion are erroneously uninitialized.") 17 | } 18 | 19 | defer func() { 20 | if r := recover(); r != nil { 21 | if _, ok := r.(runtime.Error); ok { 22 | success = false 23 | matchErr = nil 24 | } 25 | } 26 | }() 27 | 28 | return actual == matcher.Expected, nil 29 | } 30 | 31 | func (matcher *BeIdenticalToMatcher) FailureMessage(actual interface{}) string { 32 | return format.Message(actual, "to be identical to", matcher.Expected) 33 | } 34 | 35 | func (matcher *BeIdenticalToMatcher) NegatedFailureMessage(actual interface{}) string { 36 | return format.Message(actual, "not to be identical to", matcher.Expected) 37 | } 38 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/gomega/matchers/be_nil_matcher.go: -------------------------------------------------------------------------------- 1 | package matchers 2 | 3 | import "github.com/onsi/gomega/format" 4 | 5 | type BeNilMatcher struct { 6 | } 7 | 8 | func (matcher *BeNilMatcher) Match(actual interface{}) (success bool, err error) { 9 | return isNil(actual), nil 10 | } 11 | 12 | func (matcher *BeNilMatcher) FailureMessage(actual interface{}) (message string) { 13 | return format.Message(actual, "to be nil") 14 | } 15 | 16 | func (matcher *BeNilMatcher) NegatedFailureMessage(actual interface{}) (message string) { 17 | return format.Message(actual, "not to be nil") 18 | } 19 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/gomega/matchers/be_numerically_matcher.go: -------------------------------------------------------------------------------- 1 | package matchers 2 | 3 | import ( 4 | "fmt" 5 | "github.com/onsi/gomega/format" 6 | "math" 7 | ) 8 | 9 | type BeNumericallyMatcher struct { 10 | Comparator string 11 | CompareTo []interface{} 12 | } 13 | 14 | func (matcher *BeNumericallyMatcher) FailureMessage(actual interface{}) (message string) { 15 | return format.Message(actual, fmt.Sprintf("to be %s", matcher.Comparator), matcher.CompareTo[0]) 16 | } 17 | 18 | func (matcher *BeNumericallyMatcher) NegatedFailureMessage(actual interface{}) (message string) { 19 | return format.Message(actual, fmt.Sprintf("not to be %s", matcher.Comparator), matcher.CompareTo[0]) 20 | } 21 | 22 | func (matcher *BeNumericallyMatcher) Match(actual interface{}) (success bool, err error) { 23 | if len(matcher.CompareTo) == 0 || len(matcher.CompareTo) > 2 { 24 | return false, fmt.Errorf("BeNumerically requires 1 or 2 CompareTo arguments. Got:\n%s", format.Object(matcher.CompareTo, 1)) 25 | } 26 | if !isNumber(actual) { 27 | return false, fmt.Errorf("Expected a number. Got:\n%s", format.Object(actual, 1)) 28 | } 29 | if !isNumber(matcher.CompareTo[0]) { 30 | return false, fmt.Errorf("Expected a number. Got:\n%s", format.Object(matcher.CompareTo[0], 1)) 31 | } 32 | if len(matcher.CompareTo) == 2 && !isNumber(matcher.CompareTo[1]) { 33 | return false, fmt.Errorf("Expected a number. Got:\n%s", format.Object(matcher.CompareTo[0], 1)) 34 | } 35 | 36 | switch matcher.Comparator { 37 | case "==", "~", ">", ">=", "<", "<=": 38 | default: 39 | return false, fmt.Errorf("Unknown comparator: %s", matcher.Comparator) 40 | } 41 | 42 | if isFloat(actual) || isFloat(matcher.CompareTo[0]) { 43 | var secondOperand float64 = 1e-8 44 | if len(matcher.CompareTo) == 2 { 45 | secondOperand = toFloat(matcher.CompareTo[1]) 46 | } 47 | success = matcher.matchFloats(toFloat(actual), toFloat(matcher.CompareTo[0]), secondOperand) 48 | } else if isInteger(actual) { 49 | var secondOperand int64 = 0 50 | if len(matcher.CompareTo) == 2 { 51 | secondOperand = toInteger(matcher.CompareTo[1]) 52 | } 53 | success = matcher.matchIntegers(toInteger(actual), toInteger(matcher.CompareTo[0]), secondOperand) 54 | } else if isUnsignedInteger(actual) { 55 | var secondOperand uint64 = 0 56 | if len(matcher.CompareTo) == 2 { 57 | secondOperand = toUnsignedInteger(matcher.CompareTo[1]) 58 | } 59 | success = matcher.matchUnsignedIntegers(toUnsignedInteger(actual), toUnsignedInteger(matcher.CompareTo[0]), secondOperand) 60 | } else { 61 | return false, fmt.Errorf("Failed to compare:\n%s\n%s:\n%s", format.Object(actual, 1), matcher.Comparator, format.Object(matcher.CompareTo[0], 1)) 62 | } 63 | 64 | return success, nil 65 | } 66 | 67 | func (matcher *BeNumericallyMatcher) matchIntegers(actual, compareTo, threshold int64) (success bool) { 68 | switch matcher.Comparator { 69 | case "==", "~": 70 | diff := actual - compareTo 71 | return -threshold <= diff && diff <= threshold 72 | case ">": 73 | return (actual > compareTo) 74 | case ">=": 75 | return (actual >= compareTo) 76 | case "<": 77 | return (actual < compareTo) 78 | case "<=": 79 | return (actual <= compareTo) 80 | } 81 | return false 82 | } 83 | 84 | func (matcher *BeNumericallyMatcher) matchUnsignedIntegers(actual, compareTo, threshold uint64) (success bool) { 85 | switch matcher.Comparator { 86 | case "==", "~": 87 | if actual < compareTo { 88 | actual, compareTo = compareTo, actual 89 | } 90 | return actual-compareTo <= threshold 91 | case ">": 92 | return (actual > compareTo) 93 | case ">=": 94 | return (actual >= compareTo) 95 | case "<": 96 | return (actual < compareTo) 97 | case "<=": 98 | return (actual <= compareTo) 99 | } 100 | return false 101 | } 102 | 103 | func (matcher *BeNumericallyMatcher) matchFloats(actual, compareTo, threshold float64) (success bool) { 104 | switch matcher.Comparator { 105 | case "~": 106 | return math.Abs(actual-compareTo) <= threshold 107 | case "==": 108 | return (actual == compareTo) 109 | case ">": 110 | return (actual > compareTo) 111 | case ">=": 112 | return (actual >= compareTo) 113 | case "<": 114 | return (actual < compareTo) 115 | case "<=": 116 | return (actual <= compareTo) 117 | } 118 | return false 119 | } 120 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/gomega/matchers/be_sent_matcher.go: -------------------------------------------------------------------------------- 1 | package matchers 2 | 3 | import ( 4 | "fmt" 5 | "reflect" 6 | 7 | "github.com/onsi/gomega/format" 8 | ) 9 | 10 | type BeSentMatcher struct { 11 | Arg interface{} 12 | channelClosed bool 13 | } 14 | 15 | func (matcher *BeSentMatcher) Match(actual interface{}) (success bool, err error) { 16 | if !isChan(actual) { 17 | return false, fmt.Errorf("BeSent expects a channel. Got:\n%s", format.Object(actual, 1)) 18 | } 19 | 20 | channelType := reflect.TypeOf(actual) 21 | channelValue := reflect.ValueOf(actual) 22 | 23 | if channelType.ChanDir() == reflect.RecvDir { 24 | return false, fmt.Errorf("BeSent matcher cannot be passed a receive-only channel. Got:\n%s", format.Object(actual, 1)) 25 | } 26 | 27 | argType := reflect.TypeOf(matcher.Arg) 28 | assignable := argType.AssignableTo(channelType.Elem()) 29 | 30 | if !assignable { 31 | return false, fmt.Errorf("Cannot pass:\n%s to the channel:\n%s\nThe types don't match.", format.Object(matcher.Arg, 1), format.Object(actual, 1)) 32 | } 33 | 34 | argValue := reflect.ValueOf(matcher.Arg) 35 | 36 | defer func() { 37 | if e := recover(); e != nil { 38 | success = false 39 | err = fmt.Errorf("Cannot send to a closed channel") 40 | matcher.channelClosed = true 41 | } 42 | }() 43 | 44 | winnerIndex, _, _ := reflect.Select([]reflect.SelectCase{ 45 | reflect.SelectCase{Dir: reflect.SelectSend, Chan: channelValue, Send: argValue}, 46 | reflect.SelectCase{Dir: reflect.SelectDefault}, 47 | }) 48 | 49 | var didSend bool 50 | if winnerIndex == 0 { 51 | didSend = true 52 | } 53 | 54 | return didSend, nil 55 | } 56 | 57 | func (matcher *BeSentMatcher) FailureMessage(actual interface{}) (message string) { 58 | return format.Message(actual, "to send:", matcher.Arg) 59 | } 60 | 61 | func (matcher *BeSentMatcher) NegatedFailureMessage(actual interface{}) (message string) { 62 | return format.Message(actual, "not to send:", matcher.Arg) 63 | } 64 | 65 | func (matcher *BeSentMatcher) MatchMayChangeInTheFuture(actual interface{}) bool { 66 | if !isChan(actual) { 67 | return false 68 | } 69 | 70 | return !matcher.channelClosed 71 | } 72 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/gomega/matchers/be_temporally_matcher.go: -------------------------------------------------------------------------------- 1 | package matchers 2 | 3 | import ( 4 | "fmt" 5 | "github.com/onsi/gomega/format" 6 | "time" 7 | ) 8 | 9 | type BeTemporallyMatcher struct { 10 | Comparator string 11 | CompareTo time.Time 12 | Threshold []time.Duration 13 | } 14 | 15 | func (matcher *BeTemporallyMatcher) FailureMessage(actual interface{}) (message string) { 16 | return format.Message(actual, fmt.Sprintf("to be %s", matcher.Comparator), matcher.CompareTo) 17 | } 18 | 19 | func (matcher *BeTemporallyMatcher) NegatedFailureMessage(actual interface{}) (message string) { 20 | return format.Message(actual, fmt.Sprintf("not to be %s", matcher.Comparator), matcher.CompareTo) 21 | } 22 | 23 | func (matcher *BeTemporallyMatcher) Match(actual interface{}) (bool, error) { 24 | // predicate to test for time.Time type 25 | isTime := func(t interface{}) bool { 26 | _, ok := t.(time.Time) 27 | return ok 28 | } 29 | 30 | if !isTime(actual) { 31 | return false, fmt.Errorf("Expected a time.Time. Got:\n%s", format.Object(actual, 1)) 32 | } 33 | 34 | switch matcher.Comparator { 35 | case "==", "~", ">", ">=", "<", "<=": 36 | default: 37 | return false, fmt.Errorf("Unknown comparator: %s", matcher.Comparator) 38 | } 39 | 40 | var threshold = time.Millisecond 41 | if len(matcher.Threshold) == 1 { 42 | threshold = matcher.Threshold[0] 43 | } 44 | 45 | return matcher.matchTimes(actual.(time.Time), matcher.CompareTo, threshold), nil 46 | } 47 | 48 | func (matcher *BeTemporallyMatcher) matchTimes(actual, compareTo time.Time, threshold time.Duration) (success bool) { 49 | switch matcher.Comparator { 50 | case "==": 51 | return actual.Equal(compareTo) 52 | case "~": 53 | diff := actual.Sub(compareTo) 54 | return -threshold <= diff && diff <= threshold 55 | case ">": 56 | return actual.After(compareTo) 57 | case ">=": 58 | return !actual.Before(compareTo) 59 | case "<": 60 | return actual.Before(compareTo) 61 | case "<=": 62 | return !actual.After(compareTo) 63 | } 64 | return false 65 | } 66 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/gomega/matchers/be_true_matcher.go: -------------------------------------------------------------------------------- 1 | package matchers 2 | 3 | import ( 4 | "fmt" 5 | "github.com/onsi/gomega/format" 6 | ) 7 | 8 | type BeTrueMatcher struct { 9 | } 10 | 11 | func (matcher *BeTrueMatcher) Match(actual interface{}) (success bool, err error) { 12 | if !isBool(actual) { 13 | return false, fmt.Errorf("Expected a boolean. Got:\n%s", format.Object(actual, 1)) 14 | } 15 | 16 | return actual.(bool), nil 17 | } 18 | 19 | func (matcher *BeTrueMatcher) FailureMessage(actual interface{}) (message string) { 20 | return format.Message(actual, "to be true") 21 | } 22 | 23 | func (matcher *BeTrueMatcher) NegatedFailureMessage(actual interface{}) (message string) { 24 | return format.Message(actual, "not to be true") 25 | } 26 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/gomega/matchers/be_zero_matcher.go: -------------------------------------------------------------------------------- 1 | package matchers 2 | 3 | import ( 4 | "github.com/onsi/gomega/format" 5 | "reflect" 6 | ) 7 | 8 | type BeZeroMatcher struct { 9 | } 10 | 11 | func (matcher *BeZeroMatcher) Match(actual interface{}) (success bool, err error) { 12 | if actual == nil { 13 | return true, nil 14 | } 15 | zeroValue := reflect.Zero(reflect.TypeOf(actual)).Interface() 16 | 17 | return reflect.DeepEqual(zeroValue, actual), nil 18 | 19 | } 20 | 21 | func (matcher *BeZeroMatcher) FailureMessage(actual interface{}) (message string) { 22 | return format.Message(actual, "to be zero-valued") 23 | } 24 | 25 | func (matcher *BeZeroMatcher) NegatedFailureMessage(actual interface{}) (message string) { 26 | return format.Message(actual, "not to be zero-valued") 27 | } 28 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/gomega/matchers/consist_of.go: -------------------------------------------------------------------------------- 1 | package matchers 2 | 3 | import ( 4 | "fmt" 5 | "reflect" 6 | 7 | "github.com/onsi/gomega/format" 8 | "github.com/onsi/gomega/matchers/support/goraph/bipartitegraph" 9 | ) 10 | 11 | type ConsistOfMatcher struct { 12 | Elements []interface{} 13 | } 14 | 15 | func (matcher *ConsistOfMatcher) Match(actual interface{}) (success bool, err error) { 16 | if !isArrayOrSlice(actual) && !isMap(actual) { 17 | return false, fmt.Errorf("ConsistOf matcher expects an array/slice/map. Got:\n%s", format.Object(actual, 1)) 18 | } 19 | 20 | elements := matcher.Elements 21 | if len(matcher.Elements) == 1 && isArrayOrSlice(matcher.Elements[0]) { 22 | elements = []interface{}{} 23 | value := reflect.ValueOf(matcher.Elements[0]) 24 | for i := 0; i < value.Len(); i++ { 25 | elements = append(elements, value.Index(i).Interface()) 26 | } 27 | } 28 | 29 | matchers := []interface{}{} 30 | for _, element := range elements { 31 | matcher, isMatcher := element.(omegaMatcher) 32 | if !isMatcher { 33 | matcher = &EqualMatcher{Expected: element} 34 | } 35 | matchers = append(matchers, matcher) 36 | } 37 | 38 | values := matcher.valuesOf(actual) 39 | 40 | if len(values) != len(matchers) { 41 | return false, nil 42 | } 43 | 44 | neighbours := func(v, m interface{}) (bool, error) { 45 | match, err := m.(omegaMatcher).Match(v) 46 | return match && err == nil, nil 47 | } 48 | 49 | bipartiteGraph, err := bipartitegraph.NewBipartiteGraph(values, matchers, neighbours) 50 | if err != nil { 51 | return false, err 52 | } 53 | 54 | return len(bipartiteGraph.LargestMatching()) == len(values), nil 55 | } 56 | 57 | func (matcher *ConsistOfMatcher) valuesOf(actual interface{}) []interface{} { 58 | value := reflect.ValueOf(actual) 59 | values := []interface{}{} 60 | if isMap(actual) { 61 | keys := value.MapKeys() 62 | for i := 0; i < value.Len(); i++ { 63 | values = append(values, value.MapIndex(keys[i]).Interface()) 64 | } 65 | } else { 66 | for i := 0; i < value.Len(); i++ { 67 | values = append(values, value.Index(i).Interface()) 68 | } 69 | } 70 | 71 | return values 72 | } 73 | 74 | func (matcher *ConsistOfMatcher) FailureMessage(actual interface{}) (message string) { 75 | return format.Message(actual, "to consist of", matcher.Elements) 76 | } 77 | 78 | func (matcher *ConsistOfMatcher) NegatedFailureMessage(actual interface{}) (message string) { 79 | return format.Message(actual, "not to consist of", matcher.Elements) 80 | } 81 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/gomega/matchers/contain_element_matcher.go: -------------------------------------------------------------------------------- 1 | package matchers 2 | 3 | import ( 4 | "fmt" 5 | "reflect" 6 | 7 | "github.com/onsi/gomega/format" 8 | ) 9 | 10 | type ContainElementMatcher struct { 11 | Element interface{} 12 | } 13 | 14 | func (matcher *ContainElementMatcher) Match(actual interface{}) (success bool, err error) { 15 | if !isArrayOrSlice(actual) && !isMap(actual) { 16 | return false, fmt.Errorf("ContainElement matcher expects an array/slice/map. Got:\n%s", format.Object(actual, 1)) 17 | } 18 | 19 | elemMatcher, elementIsMatcher := matcher.Element.(omegaMatcher) 20 | if !elementIsMatcher { 21 | elemMatcher = &EqualMatcher{Expected: matcher.Element} 22 | } 23 | 24 | value := reflect.ValueOf(actual) 25 | var keys []reflect.Value 26 | if isMap(actual) { 27 | keys = value.MapKeys() 28 | } 29 | var lastError error 30 | for i := 0; i < value.Len(); i++ { 31 | var success bool 32 | var err error 33 | if isMap(actual) { 34 | success, err = elemMatcher.Match(value.MapIndex(keys[i]).Interface()) 35 | } else { 36 | success, err = elemMatcher.Match(value.Index(i).Interface()) 37 | } 38 | if err != nil { 39 | lastError = err 40 | continue 41 | } 42 | if success { 43 | return true, nil 44 | } 45 | } 46 | 47 | return false, lastError 48 | } 49 | 50 | func (matcher *ContainElementMatcher) FailureMessage(actual interface{}) (message string) { 51 | return format.Message(actual, "to contain element matching", matcher.Element) 52 | } 53 | 54 | func (matcher *ContainElementMatcher) NegatedFailureMessage(actual interface{}) (message string) { 55 | return format.Message(actual, "not to contain element matching", matcher.Element) 56 | } 57 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/gomega/matchers/contain_substring_matcher.go: -------------------------------------------------------------------------------- 1 | package matchers 2 | 3 | import ( 4 | "fmt" 5 | "github.com/onsi/gomega/format" 6 | "strings" 7 | ) 8 | 9 | type ContainSubstringMatcher struct { 10 | Substr string 11 | Args []interface{} 12 | } 13 | 14 | func (matcher *ContainSubstringMatcher) Match(actual interface{}) (success bool, err error) { 15 | actualString, ok := toString(actual) 16 | if !ok { 17 | return false, fmt.Errorf("ContainSubstring matcher requires a string or stringer. Got:\n%s", format.Object(actual, 1)) 18 | } 19 | 20 | return strings.Contains(actualString, matcher.stringToMatch()), nil 21 | } 22 | 23 | func (matcher *ContainSubstringMatcher) stringToMatch() string { 24 | stringToMatch := matcher.Substr 25 | if len(matcher.Args) > 0 { 26 | stringToMatch = fmt.Sprintf(matcher.Substr, matcher.Args...) 27 | } 28 | return stringToMatch 29 | } 30 | 31 | func (matcher *ContainSubstringMatcher) FailureMessage(actual interface{}) (message string) { 32 | return format.Message(actual, "to contain substring", matcher.stringToMatch()) 33 | } 34 | 35 | func (matcher *ContainSubstringMatcher) NegatedFailureMessage(actual interface{}) (message string) { 36 | return format.Message(actual, "not to contain substring", matcher.stringToMatch()) 37 | } 38 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/gomega/matchers/equal_matcher.go: -------------------------------------------------------------------------------- 1 | package matchers 2 | 3 | import ( 4 | "fmt" 5 | "reflect" 6 | 7 | "github.com/onsi/gomega/format" 8 | ) 9 | 10 | type EqualMatcher struct { 11 | Expected interface{} 12 | } 13 | 14 | func (matcher *EqualMatcher) Match(actual interface{}) (success bool, err error) { 15 | if actual == nil && matcher.Expected == nil { 16 | return false, fmt.Errorf("Refusing to compare to .\nBe explicit and use BeNil() instead. This is to avoid mistakes where both sides of an assertion are erroneously uninitialized.") 17 | } 18 | return reflect.DeepEqual(actual, matcher.Expected), nil 19 | } 20 | 21 | func (matcher *EqualMatcher) FailureMessage(actual interface{}) (message string) { 22 | return format.Message(actual, "to equal", matcher.Expected) 23 | } 24 | 25 | func (matcher *EqualMatcher) NegatedFailureMessage(actual interface{}) (message string) { 26 | return format.Message(actual, "not to equal", matcher.Expected) 27 | } 28 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/gomega/matchers/have_cap_matcher.go: -------------------------------------------------------------------------------- 1 | package matchers 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/onsi/gomega/format" 7 | ) 8 | 9 | type HaveCapMatcher struct { 10 | Count int 11 | } 12 | 13 | func (matcher *HaveCapMatcher) Match(actual interface{}) (success bool, err error) { 14 | length, ok := capOf(actual) 15 | if !ok { 16 | return false, fmt.Errorf("HaveCap matcher expects a array/channel/slice. Got:\n%s", format.Object(actual, 1)) 17 | } 18 | 19 | return length == matcher.Count, nil 20 | } 21 | 22 | func (matcher *HaveCapMatcher) FailureMessage(actual interface{}) (message string) { 23 | return fmt.Sprintf("Expected\n%s\nto have capacity %d", format.Object(actual, 1), matcher.Count) 24 | } 25 | 26 | func (matcher *HaveCapMatcher) NegatedFailureMessage(actual interface{}) (message string) { 27 | return fmt.Sprintf("Expected\n%s\nnot to have capacity %d", format.Object(actual, 1), matcher.Count) 28 | } 29 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/gomega/matchers/have_key_matcher.go: -------------------------------------------------------------------------------- 1 | package matchers 2 | 3 | import ( 4 | "fmt" 5 | "github.com/onsi/gomega/format" 6 | "reflect" 7 | ) 8 | 9 | type HaveKeyMatcher struct { 10 | Key interface{} 11 | } 12 | 13 | func (matcher *HaveKeyMatcher) Match(actual interface{}) (success bool, err error) { 14 | if !isMap(actual) { 15 | return false, fmt.Errorf("HaveKey matcher expects a map. Got:%s", format.Object(actual, 1)) 16 | } 17 | 18 | keyMatcher, keyIsMatcher := matcher.Key.(omegaMatcher) 19 | if !keyIsMatcher { 20 | keyMatcher = &EqualMatcher{Expected: matcher.Key} 21 | } 22 | 23 | keys := reflect.ValueOf(actual).MapKeys() 24 | for i := 0; i < len(keys); i++ { 25 | success, err := keyMatcher.Match(keys[i].Interface()) 26 | if err != nil { 27 | return false, fmt.Errorf("HaveKey's key matcher failed with:\n%s%s", format.Indent, err.Error()) 28 | } 29 | if success { 30 | return true, nil 31 | } 32 | } 33 | 34 | return false, nil 35 | } 36 | 37 | func (matcher *HaveKeyMatcher) FailureMessage(actual interface{}) (message string) { 38 | switch matcher.Key.(type) { 39 | case omegaMatcher: 40 | return format.Message(actual, "to have key matching", matcher.Key) 41 | default: 42 | return format.Message(actual, "to have key", matcher.Key) 43 | } 44 | } 45 | 46 | func (matcher *HaveKeyMatcher) NegatedFailureMessage(actual interface{}) (message string) { 47 | switch matcher.Key.(type) { 48 | case omegaMatcher: 49 | return format.Message(actual, "not to have key matching", matcher.Key) 50 | default: 51 | return format.Message(actual, "not to have key", matcher.Key) 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/gomega/matchers/have_key_with_value_matcher.go: -------------------------------------------------------------------------------- 1 | package matchers 2 | 3 | import ( 4 | "fmt" 5 | "github.com/onsi/gomega/format" 6 | "reflect" 7 | ) 8 | 9 | type HaveKeyWithValueMatcher struct { 10 | Key interface{} 11 | Value interface{} 12 | } 13 | 14 | func (matcher *HaveKeyWithValueMatcher) Match(actual interface{}) (success bool, err error) { 15 | if !isMap(actual) { 16 | return false, fmt.Errorf("HaveKeyWithValue matcher expects a map. Got:%s", format.Object(actual, 1)) 17 | } 18 | 19 | keyMatcher, keyIsMatcher := matcher.Key.(omegaMatcher) 20 | if !keyIsMatcher { 21 | keyMatcher = &EqualMatcher{Expected: matcher.Key} 22 | } 23 | 24 | valueMatcher, valueIsMatcher := matcher.Value.(omegaMatcher) 25 | if !valueIsMatcher { 26 | valueMatcher = &EqualMatcher{Expected: matcher.Value} 27 | } 28 | 29 | keys := reflect.ValueOf(actual).MapKeys() 30 | for i := 0; i < len(keys); i++ { 31 | success, err := keyMatcher.Match(keys[i].Interface()) 32 | if err != nil { 33 | return false, fmt.Errorf("HaveKeyWithValue's key matcher failed with:\n%s%s", format.Indent, err.Error()) 34 | } 35 | if success { 36 | actualValue := reflect.ValueOf(actual).MapIndex(keys[i]) 37 | success, err := valueMatcher.Match(actualValue.Interface()) 38 | if err != nil { 39 | return false, fmt.Errorf("HaveKeyWithValue's value matcher failed with:\n%s%s", format.Indent, err.Error()) 40 | } 41 | return success, nil 42 | } 43 | } 44 | 45 | return false, nil 46 | } 47 | 48 | func (matcher *HaveKeyWithValueMatcher) FailureMessage(actual interface{}) (message string) { 49 | str := "to have {key: value}" 50 | if _, ok := matcher.Key.(omegaMatcher); ok { 51 | str += " matching" 52 | } else if _, ok := matcher.Value.(omegaMatcher); ok { 53 | str += " matching" 54 | } 55 | 56 | expect := make(map[interface{}]interface{}, 1) 57 | expect[matcher.Key] = matcher.Value 58 | return format.Message(actual, str, expect) 59 | } 60 | 61 | func (matcher *HaveKeyWithValueMatcher) NegatedFailureMessage(actual interface{}) (message string) { 62 | kStr := "not to have key" 63 | if _, ok := matcher.Key.(omegaMatcher); ok { 64 | kStr = "not to have key matching" 65 | } 66 | 67 | vStr := "or that key's value not be" 68 | if _, ok := matcher.Value.(omegaMatcher); ok { 69 | vStr = "or to have that key's value not matching" 70 | } 71 | 72 | return format.Message(actual, kStr, matcher.Key, vStr, matcher.Value) 73 | } 74 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/gomega/matchers/have_len_matcher.go: -------------------------------------------------------------------------------- 1 | package matchers 2 | 3 | import ( 4 | "fmt" 5 | "github.com/onsi/gomega/format" 6 | ) 7 | 8 | type HaveLenMatcher struct { 9 | Count int 10 | } 11 | 12 | func (matcher *HaveLenMatcher) Match(actual interface{}) (success bool, err error) { 13 | length, ok := lengthOf(actual) 14 | if !ok { 15 | return false, fmt.Errorf("HaveLen matcher expects a string/array/map/channel/slice. Got:\n%s", format.Object(actual, 1)) 16 | } 17 | 18 | return length == matcher.Count, nil 19 | } 20 | 21 | func (matcher *HaveLenMatcher) FailureMessage(actual interface{}) (message string) { 22 | return fmt.Sprintf("Expected\n%s\nto have length %d", format.Object(actual, 1), matcher.Count) 23 | } 24 | 25 | func (matcher *HaveLenMatcher) NegatedFailureMessage(actual interface{}) (message string) { 26 | return fmt.Sprintf("Expected\n%s\nnot to have length %d", format.Object(actual, 1), matcher.Count) 27 | } 28 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/gomega/matchers/have_occurred_matcher.go: -------------------------------------------------------------------------------- 1 | package matchers 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/onsi/gomega/format" 7 | ) 8 | 9 | type HaveOccurredMatcher struct { 10 | } 11 | 12 | func (matcher *HaveOccurredMatcher) Match(actual interface{}) (success bool, err error) { 13 | // is purely nil? 14 | if actual == nil { 15 | return false, nil 16 | } 17 | 18 | // must be an 'error' type 19 | if !isError(actual) { 20 | return false, fmt.Errorf("Expected an error-type. Got:\n%s", format.Object(actual, 1)) 21 | } 22 | 23 | // must be non-nil (or a pointer to a non-nil) 24 | return !isNil(actual), nil 25 | } 26 | 27 | func (matcher *HaveOccurredMatcher) FailureMessage(actual interface{}) (message string) { 28 | return fmt.Sprintf("Expected an error to have occurred. Got:\n%s", format.Object(actual, 1)) 29 | } 30 | 31 | func (matcher *HaveOccurredMatcher) NegatedFailureMessage(actual interface{}) (message string) { 32 | return fmt.Sprintf("Expected error:\n%s\n%s\n%s", format.Object(actual, 1), format.IndentString(actual.(error).Error(), 1), "not to have occurred") 33 | } 34 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/gomega/matchers/have_prefix_matcher.go: -------------------------------------------------------------------------------- 1 | package matchers 2 | 3 | import ( 4 | "fmt" 5 | "github.com/onsi/gomega/format" 6 | ) 7 | 8 | type HavePrefixMatcher struct { 9 | Prefix string 10 | Args []interface{} 11 | } 12 | 13 | func (matcher *HavePrefixMatcher) Match(actual interface{}) (success bool, err error) { 14 | actualString, ok := toString(actual) 15 | if !ok { 16 | return false, fmt.Errorf("HavePrefix matcher requires a string or stringer. Got:\n%s", format.Object(actual, 1)) 17 | } 18 | prefix := matcher.prefix() 19 | return len(actualString) >= len(prefix) && actualString[0:len(prefix)] == prefix, nil 20 | } 21 | 22 | func (matcher *HavePrefixMatcher) prefix() string { 23 | if len(matcher.Args) > 0 { 24 | return fmt.Sprintf(matcher.Prefix, matcher.Args...) 25 | } 26 | return matcher.Prefix 27 | } 28 | 29 | func (matcher *HavePrefixMatcher) FailureMessage(actual interface{}) (message string) { 30 | return format.Message(actual, "to have prefix", matcher.prefix()) 31 | } 32 | 33 | func (matcher *HavePrefixMatcher) NegatedFailureMessage(actual interface{}) (message string) { 34 | return format.Message(actual, "not to have prefix", matcher.prefix()) 35 | } 36 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/gomega/matchers/have_suffix_matcher.go: -------------------------------------------------------------------------------- 1 | package matchers 2 | 3 | import ( 4 | "fmt" 5 | "github.com/onsi/gomega/format" 6 | ) 7 | 8 | type HaveSuffixMatcher struct { 9 | Suffix string 10 | Args []interface{} 11 | } 12 | 13 | func (matcher *HaveSuffixMatcher) Match(actual interface{}) (success bool, err error) { 14 | actualString, ok := toString(actual) 15 | if !ok { 16 | return false, fmt.Errorf("HaveSuffix matcher requires a string or stringer. Got:\n%s", format.Object(actual, 1)) 17 | } 18 | suffix := matcher.suffix() 19 | return len(actualString) >= len(suffix) && actualString[len(actualString)-len(suffix):] == suffix, nil 20 | } 21 | 22 | func (matcher *HaveSuffixMatcher) suffix() string { 23 | if len(matcher.Args) > 0 { 24 | return fmt.Sprintf(matcher.Suffix, matcher.Args...) 25 | } 26 | return matcher.Suffix 27 | } 28 | 29 | func (matcher *HaveSuffixMatcher) FailureMessage(actual interface{}) (message string) { 30 | return format.Message(actual, "to have suffix", matcher.suffix()) 31 | } 32 | 33 | func (matcher *HaveSuffixMatcher) NegatedFailureMessage(actual interface{}) (message string) { 34 | return format.Message(actual, "not to have suffix", matcher.suffix()) 35 | } 36 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/gomega/matchers/match_error_matcher.go: -------------------------------------------------------------------------------- 1 | package matchers 2 | 3 | import ( 4 | "fmt" 5 | "github.com/onsi/gomega/format" 6 | "reflect" 7 | ) 8 | 9 | type MatchErrorMatcher struct { 10 | Expected interface{} 11 | } 12 | 13 | func (matcher *MatchErrorMatcher) Match(actual interface{}) (success bool, err error) { 14 | if isNil(actual) { 15 | return false, fmt.Errorf("Expected an error, got nil") 16 | } 17 | 18 | if !isError(actual) { 19 | return false, fmt.Errorf("Expected an error. Got:\n%s", format.Object(actual, 1)) 20 | } 21 | 22 | actualErr := actual.(error) 23 | 24 | if isString(matcher.Expected) { 25 | return reflect.DeepEqual(actualErr.Error(), matcher.Expected), nil 26 | } 27 | 28 | if isError(matcher.Expected) { 29 | return reflect.DeepEqual(actualErr, matcher.Expected), nil 30 | } 31 | 32 | var subMatcher omegaMatcher 33 | var hasSubMatcher bool 34 | if matcher.Expected != nil { 35 | subMatcher, hasSubMatcher = (matcher.Expected).(omegaMatcher) 36 | if hasSubMatcher { 37 | return subMatcher.Match(actualErr.Error()) 38 | } 39 | } 40 | 41 | return false, fmt.Errorf("MatchError must be passed an error, string, or Matcher that can match on strings. Got:\n%s", format.Object(matcher.Expected, 1)) 42 | } 43 | 44 | func (matcher *MatchErrorMatcher) FailureMessage(actual interface{}) (message string) { 45 | return format.Message(actual, "to match error", matcher.Expected) 46 | } 47 | 48 | func (matcher *MatchErrorMatcher) NegatedFailureMessage(actual interface{}) (message string) { 49 | return format.Message(actual, "not to match error", matcher.Expected) 50 | } 51 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/gomega/matchers/match_json_matcher.go: -------------------------------------------------------------------------------- 1 | package matchers 2 | 3 | import ( 4 | "bytes" 5 | "encoding/json" 6 | "fmt" 7 | "reflect" 8 | 9 | "github.com/onsi/gomega/format" 10 | ) 11 | 12 | type MatchJSONMatcher struct { 13 | JSONToMatch interface{} 14 | } 15 | 16 | func (matcher *MatchJSONMatcher) Match(actual interface{}) (success bool, err error) { 17 | actualString, expectedString, err := matcher.prettyPrint(actual) 18 | if err != nil { 19 | return false, err 20 | } 21 | 22 | var aval interface{} 23 | var eval interface{} 24 | 25 | // this is guarded by prettyPrint 26 | json.Unmarshal([]byte(actualString), &aval) 27 | json.Unmarshal([]byte(expectedString), &eval) 28 | 29 | return reflect.DeepEqual(aval, eval), nil 30 | } 31 | 32 | func (matcher *MatchJSONMatcher) FailureMessage(actual interface{}) (message string) { 33 | actualString, expectedString, _ := matcher.prettyPrint(actual) 34 | return format.Message(actualString, "to match JSON of", expectedString) 35 | } 36 | 37 | func (matcher *MatchJSONMatcher) NegatedFailureMessage(actual interface{}) (message string) { 38 | actualString, expectedString, _ := matcher.prettyPrint(actual) 39 | return format.Message(actualString, "not to match JSON of", expectedString) 40 | } 41 | 42 | func (matcher *MatchJSONMatcher) prettyPrint(actual interface{}) (actualFormatted, expectedFormatted string, err error) { 43 | actualString, aok := toString(actual) 44 | expectedString, eok := toString(matcher.JSONToMatch) 45 | 46 | if !(aok && eok) { 47 | return "", "", fmt.Errorf("MatchJSONMatcher matcher requires a string or stringer. Got:\n%s", format.Object(actual, 1)) 48 | } 49 | 50 | abuf := new(bytes.Buffer) 51 | ebuf := new(bytes.Buffer) 52 | 53 | if err := json.Indent(abuf, []byte(actualString), "", " "); err != nil { 54 | return "", "", fmt.Errorf("Actual '%s' should be valid JSON, but it is not.\nUnderlying error:%s", actualString, err) 55 | } 56 | 57 | if err := json.Indent(ebuf, []byte(expectedString), "", " "); err != nil { 58 | return "", "", fmt.Errorf("Expected '%s' should be valid JSON, but it is not.\nUnderlying error:%s", expectedString, err) 59 | } 60 | 61 | return abuf.String(), ebuf.String(), nil 62 | } 63 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/gomega/matchers/match_regexp_matcher.go: -------------------------------------------------------------------------------- 1 | package matchers 2 | 3 | import ( 4 | "fmt" 5 | "github.com/onsi/gomega/format" 6 | "regexp" 7 | ) 8 | 9 | type MatchRegexpMatcher struct { 10 | Regexp string 11 | Args []interface{} 12 | } 13 | 14 | func (matcher *MatchRegexpMatcher) Match(actual interface{}) (success bool, err error) { 15 | actualString, ok := toString(actual) 16 | if !ok { 17 | return false, fmt.Errorf("RegExp matcher requires a string or stringer.\nGot:%s", format.Object(actual, 1)) 18 | } 19 | 20 | match, err := regexp.Match(matcher.regexp(), []byte(actualString)) 21 | if err != nil { 22 | return false, fmt.Errorf("RegExp match failed to compile with error:\n\t%s", err.Error()) 23 | } 24 | 25 | return match, nil 26 | } 27 | 28 | func (matcher *MatchRegexpMatcher) FailureMessage(actual interface{}) (message string) { 29 | return format.Message(actual, "to match regular expression", matcher.regexp()) 30 | } 31 | 32 | func (matcher *MatchRegexpMatcher) NegatedFailureMessage(actual interface{}) (message string) { 33 | return format.Message(actual, "not to match regular expression", matcher.regexp()) 34 | } 35 | 36 | func (matcher *MatchRegexpMatcher) regexp() string { 37 | re := matcher.Regexp 38 | if len(matcher.Args) > 0 { 39 | re = fmt.Sprintf(matcher.Regexp, matcher.Args...) 40 | } 41 | return re 42 | } 43 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/gomega/matchers/not.go: -------------------------------------------------------------------------------- 1 | package matchers 2 | 3 | import ( 4 | "github.com/onsi/gomega/internal/oraclematcher" 5 | "github.com/onsi/gomega/types" 6 | ) 7 | 8 | type NotMatcher struct { 9 | Matcher types.GomegaMatcher 10 | } 11 | 12 | func (m *NotMatcher) Match(actual interface{}) (bool, error) { 13 | success, err := m.Matcher.Match(actual) 14 | if err != nil { 15 | return false, err 16 | } 17 | return !success, nil 18 | } 19 | 20 | func (m *NotMatcher) FailureMessage(actual interface{}) (message string) { 21 | return m.Matcher.NegatedFailureMessage(actual) // works beautifully 22 | } 23 | 24 | func (m *NotMatcher) NegatedFailureMessage(actual interface{}) (message string) { 25 | return m.Matcher.FailureMessage(actual) // works beautifully 26 | } 27 | 28 | func (m *NotMatcher) MatchMayChangeInTheFuture(actual interface{}) bool { 29 | return oraclematcher.MatchMayChangeInTheFuture(m.Matcher, actual) // just return m.Matcher's value 30 | } 31 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/gomega/matchers/or.go: -------------------------------------------------------------------------------- 1 | package matchers 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/onsi/gomega/format" 7 | "github.com/onsi/gomega/internal/oraclematcher" 8 | "github.com/onsi/gomega/types" 9 | ) 10 | 11 | type OrMatcher struct { 12 | Matchers []types.GomegaMatcher 13 | 14 | // state 15 | firstSuccessfulMatcher types.GomegaMatcher 16 | } 17 | 18 | func (m *OrMatcher) Match(actual interface{}) (success bool, err error) { 19 | m.firstSuccessfulMatcher = nil 20 | for _, matcher := range m.Matchers { 21 | success, err := matcher.Match(actual) 22 | if err != nil { 23 | return false, err 24 | } 25 | if success { 26 | m.firstSuccessfulMatcher = matcher 27 | return true, nil 28 | } 29 | } 30 | return false, nil 31 | } 32 | 33 | func (m *OrMatcher) FailureMessage(actual interface{}) (message string) { 34 | // not the most beautiful list of matchers, but not bad either... 35 | return format.Message(actual, fmt.Sprintf("To satisfy at least one of these matchers: %s", m.Matchers)) 36 | } 37 | 38 | func (m *OrMatcher) NegatedFailureMessage(actual interface{}) (message string) { 39 | return m.firstSuccessfulMatcher.NegatedFailureMessage(actual) 40 | } 41 | 42 | func (m *OrMatcher) MatchMayChangeInTheFuture(actual interface{}) bool { 43 | /* 44 | Example with 3 matchers: A, B, C 45 | 46 | Match evaluates them: F, T, => T 47 | So match is currently T, what should MatchMayChangeInTheFuture() return? 48 | Seems like it only depends on B, since currently B MUST change to allow the result to become F 49 | 50 | Match eval: F, F, F => F 51 | So match is currently F, what should MatchMayChangeInTheFuture() return? 52 | Seems to depend on ANY of them being able to change to T. 53 | */ 54 | 55 | if m.firstSuccessfulMatcher != nil { 56 | // one of the matchers succeeded.. it must be able to change in order to affect the result 57 | return oraclematcher.MatchMayChangeInTheFuture(m.firstSuccessfulMatcher, actual) 58 | } else { 59 | // so all matchers failed.. Any one of them changing would change the result. 60 | for _, matcher := range m.Matchers { 61 | if oraclematcher.MatchMayChangeInTheFuture(matcher, actual) { 62 | return true 63 | } 64 | } 65 | return false // none of were going to change 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/gomega/matchers/panic_matcher.go: -------------------------------------------------------------------------------- 1 | package matchers 2 | 3 | import ( 4 | "fmt" 5 | "github.com/onsi/gomega/format" 6 | "reflect" 7 | ) 8 | 9 | type PanicMatcher struct{} 10 | 11 | func (matcher *PanicMatcher) Match(actual interface{}) (success bool, err error) { 12 | if actual == nil { 13 | return false, fmt.Errorf("PanicMatcher expects a non-nil actual.") 14 | } 15 | 16 | actualType := reflect.TypeOf(actual) 17 | if actualType.Kind() != reflect.Func { 18 | return false, fmt.Errorf("PanicMatcher expects a function. Got:\n%s", format.Object(actual, 1)) 19 | } 20 | if !(actualType.NumIn() == 0 && actualType.NumOut() == 0) { 21 | return false, fmt.Errorf("PanicMatcher expects a function with no arguments and no return value. Got:\n%s", format.Object(actual, 1)) 22 | } 23 | 24 | success = false 25 | defer func() { 26 | if e := recover(); e != nil { 27 | success = true 28 | } 29 | }() 30 | 31 | reflect.ValueOf(actual).Call([]reflect.Value{}) 32 | 33 | return 34 | } 35 | 36 | func (matcher *PanicMatcher) FailureMessage(actual interface{}) (message string) { 37 | return format.Message(actual, "to panic") 38 | } 39 | 40 | func (matcher *PanicMatcher) NegatedFailureMessage(actual interface{}) (message string) { 41 | return format.Message(actual, "not to panic") 42 | } 43 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/gomega/matchers/receive_matcher.go: -------------------------------------------------------------------------------- 1 | package matchers 2 | 3 | import ( 4 | "fmt" 5 | "reflect" 6 | 7 | "github.com/onsi/gomega/format" 8 | ) 9 | 10 | type ReceiveMatcher struct { 11 | Arg interface{} 12 | receivedValue reflect.Value 13 | channelClosed bool 14 | } 15 | 16 | func (matcher *ReceiveMatcher) Match(actual interface{}) (success bool, err error) { 17 | if !isChan(actual) { 18 | return false, fmt.Errorf("ReceiveMatcher expects a channel. Got:\n%s", format.Object(actual, 1)) 19 | } 20 | 21 | channelType := reflect.TypeOf(actual) 22 | channelValue := reflect.ValueOf(actual) 23 | 24 | if channelType.ChanDir() == reflect.SendDir { 25 | return false, fmt.Errorf("ReceiveMatcher matcher cannot be passed a send-only channel. Got:\n%s", format.Object(actual, 1)) 26 | } 27 | 28 | var subMatcher omegaMatcher 29 | var hasSubMatcher bool 30 | 31 | if matcher.Arg != nil { 32 | subMatcher, hasSubMatcher = (matcher.Arg).(omegaMatcher) 33 | if !hasSubMatcher { 34 | argType := reflect.TypeOf(matcher.Arg) 35 | if argType.Kind() != reflect.Ptr { 36 | return false, fmt.Errorf("Cannot assign a value from the channel:\n%s\nTo:\n%s\nYou need to pass a pointer!", format.Object(actual, 1), format.Object(matcher.Arg, 1)) 37 | } 38 | 39 | assignable := channelType.Elem().AssignableTo(argType.Elem()) 40 | if !assignable { 41 | return false, fmt.Errorf("Cannot assign a value from the channel:\n%s\nTo:\n%s", format.Object(actual, 1), format.Object(matcher.Arg, 1)) 42 | } 43 | } 44 | } 45 | 46 | winnerIndex, value, open := reflect.Select([]reflect.SelectCase{ 47 | reflect.SelectCase{Dir: reflect.SelectRecv, Chan: channelValue}, 48 | reflect.SelectCase{Dir: reflect.SelectDefault}, 49 | }) 50 | 51 | var closed bool 52 | var didReceive bool 53 | if winnerIndex == 0 { 54 | closed = !open 55 | didReceive = open 56 | } 57 | matcher.channelClosed = closed 58 | 59 | if closed { 60 | return false, nil 61 | } 62 | 63 | if hasSubMatcher { 64 | if didReceive { 65 | matcher.receivedValue = value 66 | return subMatcher.Match(matcher.receivedValue.Interface()) 67 | } else { 68 | return false, nil 69 | } 70 | } 71 | 72 | if didReceive { 73 | if matcher.Arg != nil { 74 | outValue := reflect.ValueOf(matcher.Arg) 75 | reflect.Indirect(outValue).Set(value) 76 | } 77 | 78 | return true, nil 79 | } else { 80 | return false, nil 81 | } 82 | } 83 | 84 | func (matcher *ReceiveMatcher) FailureMessage(actual interface{}) (message string) { 85 | subMatcher, hasSubMatcher := (matcher.Arg).(omegaMatcher) 86 | 87 | closedAddendum := "" 88 | if matcher.channelClosed { 89 | closedAddendum = " The channel is closed." 90 | } 91 | 92 | if hasSubMatcher { 93 | if matcher.receivedValue.IsValid() { 94 | return subMatcher.FailureMessage(matcher.receivedValue.Interface()) 95 | } 96 | return "When passed a matcher, ReceiveMatcher's channel *must* receive something." 97 | } else { 98 | return format.Message(actual, "to receive something."+closedAddendum) 99 | } 100 | } 101 | 102 | func (matcher *ReceiveMatcher) NegatedFailureMessage(actual interface{}) (message string) { 103 | subMatcher, hasSubMatcher := (matcher.Arg).(omegaMatcher) 104 | 105 | closedAddendum := "" 106 | if matcher.channelClosed { 107 | closedAddendum = " The channel is closed." 108 | } 109 | 110 | if hasSubMatcher { 111 | if matcher.receivedValue.IsValid() { 112 | return subMatcher.NegatedFailureMessage(matcher.receivedValue.Interface()) 113 | } 114 | return "When passed a matcher, ReceiveMatcher's channel *must* receive something." 115 | } else { 116 | return format.Message(actual, "not to receive anything."+closedAddendum) 117 | } 118 | } 119 | 120 | func (matcher *ReceiveMatcher) MatchMayChangeInTheFuture(actual interface{}) bool { 121 | if !isChan(actual) { 122 | return false 123 | } 124 | 125 | return !matcher.channelClosed 126 | } 127 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/gomega/matchers/succeed_matcher.go: -------------------------------------------------------------------------------- 1 | package matchers 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/onsi/gomega/format" 7 | ) 8 | 9 | type SucceedMatcher struct { 10 | } 11 | 12 | func (matcher *SucceedMatcher) Match(actual interface{}) (success bool, err error) { 13 | // is purely nil? 14 | if actual == nil { 15 | return true, nil 16 | } 17 | 18 | // must be an 'error' type 19 | if !isError(actual) { 20 | return false, fmt.Errorf("Expected an error-type. Got:\n%s", format.Object(actual, 1)) 21 | } 22 | 23 | // must be nil (or a pointer to a nil) 24 | return isNil(actual), nil 25 | } 26 | 27 | func (matcher *SucceedMatcher) FailureMessage(actual interface{}) (message string) { 28 | return fmt.Sprintf("Expected success, but got an error:\n%s\n%s", format.Object(actual, 1), format.IndentString(actual.(error).Error(), 1)) 29 | } 30 | 31 | func (matcher *SucceedMatcher) NegatedFailureMessage(actual interface{}) (message string) { 32 | return "Expected failure, but got no error." 33 | } 34 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/gomega/matchers/support/goraph/bipartitegraph/bipartitegraph.go: -------------------------------------------------------------------------------- 1 | package bipartitegraph 2 | 3 | import "errors" 4 | import "fmt" 5 | 6 | import . "github.com/onsi/gomega/matchers/support/goraph/node" 7 | import . "github.com/onsi/gomega/matchers/support/goraph/edge" 8 | 9 | type BipartiteGraph struct { 10 | Left NodeOrderedSet 11 | Right NodeOrderedSet 12 | Edges EdgeSet 13 | } 14 | 15 | func NewBipartiteGraph(leftValues, rightValues []interface{}, neighbours func(interface{}, interface{}) (bool, error)) (*BipartiteGraph, error) { 16 | left := NodeOrderedSet{} 17 | for i, _ := range leftValues { 18 | left = append(left, Node{i}) 19 | } 20 | 21 | right := NodeOrderedSet{} 22 | for j, _ := range rightValues { 23 | right = append(right, Node{j + len(left)}) 24 | } 25 | 26 | edges := EdgeSet{} 27 | for i, leftValue := range leftValues { 28 | for j, rightValue := range rightValues { 29 | neighbours, err := neighbours(leftValue, rightValue) 30 | if err != nil { 31 | return nil, errors.New(fmt.Sprintf("error determining adjacency for %v and %v: %s", leftValue, rightValue, err.Error())) 32 | } 33 | 34 | if neighbours { 35 | edges = append(edges, Edge{left[i], right[j]}) 36 | } 37 | } 38 | } 39 | 40 | return &BipartiteGraph{left, right, edges}, nil 41 | } 42 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/gomega/matchers/support/goraph/edge/edge.go: -------------------------------------------------------------------------------- 1 | package edge 2 | 3 | import . "github.com/onsi/gomega/matchers/support/goraph/node" 4 | 5 | type Edge struct { 6 | Node1 Node 7 | Node2 Node 8 | } 9 | 10 | type EdgeSet []Edge 11 | 12 | func (ec EdgeSet) Free(node Node) bool { 13 | for _, e := range ec { 14 | if e.Node1 == node || e.Node2 == node { 15 | return false 16 | } 17 | } 18 | 19 | return true 20 | } 21 | 22 | func (ec EdgeSet) Contains(edge Edge) bool { 23 | for _, e := range ec { 24 | if e == edge { 25 | return true 26 | } 27 | } 28 | 29 | return false 30 | } 31 | 32 | func (ec EdgeSet) FindByNodes(node1, node2 Node) (Edge, bool) { 33 | for _, e := range ec { 34 | if (e.Node1 == node1 && e.Node2 == node2) || (e.Node1 == node2 && e.Node2 == node1) { 35 | return e, true 36 | } 37 | } 38 | 39 | return Edge{}, false 40 | } 41 | 42 | func (ec EdgeSet) SymmetricDifference(ec2 EdgeSet) EdgeSet { 43 | edgesToInclude := make(map[Edge]bool) 44 | 45 | for _, e := range ec { 46 | edgesToInclude[e] = true 47 | } 48 | 49 | for _, e := range ec2 { 50 | edgesToInclude[e] = !edgesToInclude[e] 51 | } 52 | 53 | result := EdgeSet{} 54 | for e, include := range edgesToInclude { 55 | if include { 56 | result = append(result, e) 57 | } 58 | } 59 | 60 | return result 61 | } 62 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/gomega/matchers/support/goraph/node/node.go: -------------------------------------------------------------------------------- 1 | package node 2 | 3 | type Node struct { 4 | Id int 5 | } 6 | 7 | type NodeOrderedSet []Node 8 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/gomega/matchers/support/goraph/util/util.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import "math" 4 | 5 | func Odd(n int) bool { 6 | return math.Mod(float64(n), 2.0) == 1.0 7 | } 8 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/gomega/matchers/with_transform.go: -------------------------------------------------------------------------------- 1 | package matchers 2 | 3 | import ( 4 | "fmt" 5 | "reflect" 6 | 7 | "github.com/onsi/gomega/internal/oraclematcher" 8 | "github.com/onsi/gomega/types" 9 | ) 10 | 11 | type WithTransformMatcher struct { 12 | // input 13 | Transform interface{} // must be a function of one parameter that returns one value 14 | Matcher types.GomegaMatcher 15 | 16 | // cached value 17 | transformArgType reflect.Type 18 | 19 | // state 20 | transformedValue interface{} 21 | } 22 | 23 | func NewWithTransformMatcher(transform interface{}, matcher types.GomegaMatcher) *WithTransformMatcher { 24 | if transform == nil { 25 | panic("transform function cannot be nil") 26 | } 27 | txType := reflect.TypeOf(transform) 28 | if txType.NumIn() != 1 { 29 | panic("transform function must have 1 argument") 30 | } 31 | if txType.NumOut() != 1 { 32 | panic("transform function must have 1 return value") 33 | } 34 | 35 | return &WithTransformMatcher{ 36 | Transform: transform, 37 | Matcher: matcher, 38 | transformArgType: reflect.TypeOf(transform).In(0), 39 | } 40 | } 41 | 42 | func (m *WithTransformMatcher) Match(actual interface{}) (bool, error) { 43 | // return error if actual's type is incompatible with Transform function's argument type 44 | actualType := reflect.TypeOf(actual) 45 | if !actualType.AssignableTo(m.transformArgType) { 46 | return false, fmt.Errorf("Transform function expects '%s' but we have '%s'", m.transformArgType, actualType) 47 | } 48 | 49 | // call the Transform function with `actual` 50 | fn := reflect.ValueOf(m.Transform) 51 | result := fn.Call([]reflect.Value{reflect.ValueOf(actual)}) 52 | m.transformedValue = result[0].Interface() // expect exactly one value 53 | 54 | return m.Matcher.Match(m.transformedValue) 55 | } 56 | 57 | func (m *WithTransformMatcher) FailureMessage(_ interface{}) (message string) { 58 | return m.Matcher.FailureMessage(m.transformedValue) 59 | } 60 | 61 | func (m *WithTransformMatcher) NegatedFailureMessage(_ interface{}) (message string) { 62 | return m.Matcher.NegatedFailureMessage(m.transformedValue) 63 | } 64 | 65 | func (m *WithTransformMatcher) MatchMayChangeInTheFuture(_ interface{}) bool { 66 | // TODO: Maybe this should always just return true? (Only an issue for non-deterministic transformers.) 67 | // 68 | // Querying the next matcher is fine if the transformer always will return the same value. 69 | // But if the transformer is non-deterministic and returns a different value each time, then there 70 | // is no point in querying the next matcher, since it can only comment on the last transformed value. 71 | return oraclematcher.MatchMayChangeInTheFuture(m.Matcher, m.transformedValue) 72 | } 73 | -------------------------------------------------------------------------------- /vendor/github.com/onsi/gomega/types/types.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | type GomegaFailHandler func(message string, callerSkip ...int) 4 | 5 | //A simple *testing.T interface wrapper 6 | type GomegaTestingT interface { 7 | Errorf(format string, args ...interface{}) 8 | } 9 | 10 | //All Gomega matchers must implement the GomegaMatcher interface 11 | // 12 | //For details on writing custom matchers, check out: http://onsi.github.io/gomega/#adding_your_own_matchers 13 | type GomegaMatcher interface { 14 | Match(actual interface{}) (success bool, err error) 15 | FailureMessage(actual interface{}) (message string) 16 | NegatedFailureMessage(actual interface{}) (message string) 17 | } 18 | -------------------------------------------------------------------------------- /vendor/github.com/pivotal-cf/brokerapi/NOTICE: -------------------------------------------------------------------------------- 1 | brokerapi 2 | 3 | Copyright (c) 2014-2015 Pivotal Software, Inc. All Rights Reserved. 4 | 5 | This product is licensed to you under the Apache License, Version 2.0 (the "License"). 6 | You may not use this product except in compliance with the License. 7 | 8 | This product may include a number of subcomponents with separate copyright notices 9 | and license terms. Your use of these subcomponents is subject to the terms and 10 | conditions of the subcomponent's license, as noted in the LICENSE file. 11 | -------------------------------------------------------------------------------- /vendor/github.com/pivotal-cf/brokerapi/README.md: -------------------------------------------------------------------------------- 1 | # brokerapi 2 | 3 | [![Build Status](https://travis-ci.org/pivotal-cf/brokerapi.svg?branch=master)](https://travis-ci.org/pivotal-cf/brokerapi) 4 | 5 | A Go package for building [V2 Cloud Foundry Service Brokers](https://docs.cloudfoundry.org/services/api.html). 6 | 7 | ## [Docs](https://godoc.org/github.com/pivotal-cf/brokerapi) 8 | 9 | ## Dependencies 10 | 11 | - Go 1.7+ 12 | - [lager](https://github.com/cloudfoundry/lager) 13 | - [gorilla/mux](https://github.com/gorilla/mux) 14 | 15 | ## Usage 16 | 17 | `brokerapi` defines a [`ServiceBroker`](https://godoc.org/github.com/pivotal-cf/brokerapi#ServiceBroker) interface. Pass an implementation of this to [`brokerapi.New`](https://godoc.org/github.com/pivotal-cf/brokerapi#New), which returns an `http.Handler` that you can use to serve handle HTTP requests. 18 | 19 | Alternatively, if you already have a `*mux.Router` that you want to attach service broker routes to, you can use [`brokerapi.AttachRoutes`](https://godoc.org/github.com/pivotal-cf/brokerapi#AttachRoutes). 20 | 21 | ## Error types 22 | 23 | `brokerapi` defines a handful of error types in `service_broker.go` for some common error cases that your service broker may encounter. Return these from your `ServiceBroker` methods where appropriate, and `brokerapi` will do the "right thing" (™), and give Cloud Foundry an appropriate status code, as per the [Service Broker API specification](https://docs.cloudfoundry.org/services/api.html). 24 | 25 | ## Example Service Broker 26 | 27 | You can see the [cf-redis](https://github.com/pivotal-cf/cf-redis-broker/blob/2f0e9a8ebb1012a9be74bbef2d411b0b3b60352f/broker/broker.go) service broker uses the BrokerAPI package to create a service broker for Redis. 28 | -------------------------------------------------------------------------------- /vendor/github.com/pivotal-cf/brokerapi/auth/auth.go: -------------------------------------------------------------------------------- 1 | package auth 2 | 3 | import "net/http" 4 | 5 | type Wrapper struct { 6 | username string 7 | password string 8 | } 9 | 10 | func NewWrapper(username, password string) *Wrapper { 11 | return &Wrapper{ 12 | username: username, 13 | password: password, 14 | } 15 | } 16 | 17 | const notAuthorized = "Not Authorized" 18 | 19 | func (wrapper *Wrapper) Wrap(handler http.Handler) http.Handler { 20 | return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 21 | if !authorized(wrapper, r) { 22 | http.Error(w, notAuthorized, http.StatusUnauthorized) 23 | return 24 | } 25 | 26 | handler.ServeHTTP(w, r) 27 | }) 28 | } 29 | 30 | func (wrapper *Wrapper) WrapFunc(handlerFunc http.HandlerFunc) http.HandlerFunc { 31 | return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 32 | if !authorized(wrapper, r) { 33 | http.Error(w, notAuthorized, http.StatusUnauthorized) 34 | return 35 | } 36 | 37 | handlerFunc(w, r) 38 | }) 39 | } 40 | 41 | func authorized(wrapper *Wrapper, r *http.Request) bool { 42 | username, password, isOk := r.BasicAuth() 43 | return isOk && username == wrapper.username && password == wrapper.password 44 | } 45 | -------------------------------------------------------------------------------- /vendor/github.com/pivotal-cf/brokerapi/catalog.go: -------------------------------------------------------------------------------- 1 | package brokerapi 2 | 3 | type Service struct { 4 | ID string `json:"id"` 5 | Name string `json:"name"` 6 | Description string `json:"description"` 7 | Bindable bool `json:"bindable"` 8 | Tags []string `json:"tags,omitempty"` 9 | PlanUpdatable bool `json:"plan_updateable"` 10 | Plans []ServicePlan `json:"plans"` 11 | Requires []RequiredPermission `json:"requires,omitempty"` 12 | Metadata *ServiceMetadata `json:"metadata,omitempty"` 13 | DashboardClient *ServiceDashboardClient `json:"dashboard_client,omitempty"` 14 | } 15 | 16 | type ServiceDashboardClient struct { 17 | ID string `json:"id"` 18 | Secret string `json:"secret"` 19 | RedirectURI string `json:"redirect_uri"` 20 | } 21 | 22 | type ServicePlan struct { 23 | ID string `json:"id"` 24 | Name string `json:"name"` 25 | Description string `json:"description"` 26 | Free *bool `json:"free,omitempty"` 27 | Bindable *bool `json:"bindable,omitempty"` 28 | Metadata *ServicePlanMetadata `json:"metadata,omitempty"` 29 | } 30 | 31 | type ServicePlanMetadata struct { 32 | DisplayName string `json:"displayName,omitempty"` 33 | Bullets []string `json:"bullets,omitempty"` 34 | Costs []ServicePlanCost `json:"costs,omitempty"` 35 | } 36 | 37 | type ServicePlanCost struct { 38 | Amount map[string]float64 `json:"amount"` 39 | Unit string `json:"unit"` 40 | } 41 | 42 | type ServiceMetadata struct { 43 | DisplayName string `json:"displayName,omitempty"` 44 | ImageUrl string `json:"imageUrl,omitempty"` 45 | LongDescription string `json:"longDescription,omitempty"` 46 | ProviderDisplayName string `json:"providerDisplayName,omitempty"` 47 | DocumentationUrl string `json:"documentationUrl,omitempty"` 48 | SupportUrl string `json:"supportUrl,omitempty"` 49 | } 50 | 51 | func FreeValue(v bool) *bool { 52 | return &v 53 | } 54 | 55 | func BindableValue(v bool) *bool { 56 | return &v 57 | } 58 | 59 | type RequiredPermission string 60 | 61 | const ( 62 | PermissionRouteForwarding = RequiredPermission("route_forwarding") 63 | PermissionSyslogDrain = RequiredPermission("syslog_drain") 64 | PermissionVolumeMount = RequiredPermission("volume_mount") 65 | ) 66 | -------------------------------------------------------------------------------- /vendor/github.com/pivotal-cf/brokerapi/response.go: -------------------------------------------------------------------------------- 1 | package brokerapi 2 | 3 | type EmptyResponse struct{} 4 | 5 | type ErrorResponse struct { 6 | Error string `json:"error,omitempty"` 7 | Description string `json:"description"` 8 | } 9 | 10 | type CatalogResponse struct { 11 | Services []Service `json:"services"` 12 | } 13 | 14 | type ProvisioningResponse struct { 15 | DashboardURL string `json:"dashboard_url,omitempty"` 16 | OperationData string `json:"operation,omitempty"` 17 | } 18 | 19 | type UpdateResponse struct { 20 | OperationData string `json:"operation,omitempty"` 21 | } 22 | 23 | type DeprovisionResponse struct { 24 | OperationData string `json:"operation,omitempty"` 25 | } 26 | 27 | type LastOperationResponse struct { 28 | State LastOperationState `json:"state"` 29 | Description string `json:"description,omitempty"` 30 | } 31 | 32 | type ExperimentalVolumeMountBindingResponse struct { 33 | Credentials interface{} `json:"credentials"` 34 | SyslogDrainURL string `json:"syslog_drain_url,omitempty"` 35 | RouteServiceURL string `json:"route_service_url,omitempty"` 36 | VolumeMounts []ExperimentalVolumeMount `json:"volume_mounts,omitempty"` 37 | } 38 | 39 | type ExperimentalVolumeMount struct { 40 | ContainerPath string `json:"container_path"` 41 | Mode string `json:"mode"` 42 | Private ExperimentalVolumeMountPrivate `json:"private"` 43 | } 44 | 45 | type ExperimentalVolumeMountPrivate struct { 46 | Driver string `json:"driver"` 47 | GroupID string `json:"group_id"` 48 | Config string `json:"config"` 49 | } 50 | -------------------------------------------------------------------------------- /vendor/gopkg.in/yaml.v2/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2011-2016 Canonical Ltd. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | -------------------------------------------------------------------------------- /vendor/gopkg.in/yaml.v2/LICENSE.libyaml: -------------------------------------------------------------------------------- 1 | The following files were ported to Go from C files of libyaml, and thus 2 | are still covered by their original copyright and license: 3 | 4 | apic.go 5 | emitterc.go 6 | parserc.go 7 | readerc.go 8 | scannerc.go 9 | writerc.go 10 | yamlh.go 11 | yamlprivateh.go 12 | 13 | Copyright (c) 2006 Kirill Simonov 14 | 15 | Permission is hereby granted, free of charge, to any person obtaining a copy of 16 | this software and associated documentation files (the "Software"), to deal in 17 | the Software without restriction, including without limitation the rights to 18 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 19 | of the Software, and to permit persons to whom the Software is furnished to do 20 | so, subject to the following conditions: 21 | 22 | The above copyright notice and this permission notice shall be included in all 23 | copies or substantial portions of the Software. 24 | 25 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 28 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 29 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 30 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 31 | SOFTWARE. 32 | -------------------------------------------------------------------------------- /vendor/gopkg.in/yaml.v2/README.md: -------------------------------------------------------------------------------- 1 | # YAML support for the Go language 2 | 3 | Introduction 4 | ------------ 5 | 6 | The yaml package enables Go programs to comfortably encode and decode YAML 7 | values. It was developed within [Canonical](https://www.canonical.com) as 8 | part of the [juju](https://juju.ubuntu.com) project, and is based on a 9 | pure Go port of the well-known [libyaml](http://pyyaml.org/wiki/LibYAML) 10 | C library to parse and generate YAML data quickly and reliably. 11 | 12 | Compatibility 13 | ------------- 14 | 15 | The yaml package supports most of YAML 1.1 and 1.2, including support for 16 | anchors, tags, map merging, etc. Multi-document unmarshalling is not yet 17 | implemented, and base-60 floats from YAML 1.1 are purposefully not 18 | supported since they're a poor design and are gone in YAML 1.2. 19 | 20 | Installation and usage 21 | ---------------------- 22 | 23 | The import path for the package is *gopkg.in/yaml.v2*. 24 | 25 | To install it, run: 26 | 27 | go get gopkg.in/yaml.v2 28 | 29 | API documentation 30 | ----------------- 31 | 32 | If opened in a browser, the import path itself leads to the API documentation: 33 | 34 | * [https://gopkg.in/yaml.v2](https://gopkg.in/yaml.v2) 35 | 36 | API stability 37 | ------------- 38 | 39 | The package API for yaml v2 will remain stable as described in [gopkg.in](https://gopkg.in). 40 | 41 | 42 | License 43 | ------- 44 | 45 | The yaml package is licensed under the Apache License 2.0. Please see the LICENSE file for details. 46 | 47 | 48 | Example 49 | ------- 50 | 51 | ```Go 52 | package main 53 | 54 | import ( 55 | "fmt" 56 | "log" 57 | 58 | "gopkg.in/yaml.v2" 59 | ) 60 | 61 | var data = ` 62 | a: Easy! 63 | b: 64 | c: 2 65 | d: [3, 4] 66 | ` 67 | 68 | type T struct { 69 | A string 70 | B struct { 71 | RenamedC int `yaml:"c"` 72 | D []int `yaml:",flow"` 73 | } 74 | } 75 | 76 | func main() { 77 | t := T{} 78 | 79 | err := yaml.Unmarshal([]byte(data), &t) 80 | if err != nil { 81 | log.Fatalf("error: %v", err) 82 | } 83 | fmt.Printf("--- t:\n%v\n\n", t) 84 | 85 | d, err := yaml.Marshal(&t) 86 | if err != nil { 87 | log.Fatalf("error: %v", err) 88 | } 89 | fmt.Printf("--- t dump:\n%s\n\n", string(d)) 90 | 91 | m := make(map[interface{}]interface{}) 92 | 93 | err = yaml.Unmarshal([]byte(data), &m) 94 | if err != nil { 95 | log.Fatalf("error: %v", err) 96 | } 97 | fmt.Printf("--- m:\n%v\n\n", m) 98 | 99 | d, err = yaml.Marshal(&m) 100 | if err != nil { 101 | log.Fatalf("error: %v", err) 102 | } 103 | fmt.Printf("--- m dump:\n%s\n\n", string(d)) 104 | } 105 | ``` 106 | 107 | This example will generate the following output: 108 | 109 | ``` 110 | --- t: 111 | {Easy! {2 [3 4]}} 112 | 113 | --- t dump: 114 | a: Easy! 115 | b: 116 | c: 2 117 | d: [3, 4] 118 | 119 | 120 | --- m: 121 | map[a:Easy! b:map[c:2 d:[3 4]]] 122 | 123 | --- m dump: 124 | a: Easy! 125 | b: 126 | c: 2 127 | d: 128 | - 3 129 | - 4 130 | ``` 131 | 132 | -------------------------------------------------------------------------------- /vendor/gopkg.in/yaml.v2/sorter.go: -------------------------------------------------------------------------------- 1 | package yaml 2 | 3 | import ( 4 | "reflect" 5 | "unicode" 6 | ) 7 | 8 | type keyList []reflect.Value 9 | 10 | func (l keyList) Len() int { return len(l) } 11 | func (l keyList) Swap(i, j int) { l[i], l[j] = l[j], l[i] } 12 | func (l keyList) Less(i, j int) bool { 13 | a := l[i] 14 | b := l[j] 15 | ak := a.Kind() 16 | bk := b.Kind() 17 | for (ak == reflect.Interface || ak == reflect.Ptr) && !a.IsNil() { 18 | a = a.Elem() 19 | ak = a.Kind() 20 | } 21 | for (bk == reflect.Interface || bk == reflect.Ptr) && !b.IsNil() { 22 | b = b.Elem() 23 | bk = b.Kind() 24 | } 25 | af, aok := keyFloat(a) 26 | bf, bok := keyFloat(b) 27 | if aok && bok { 28 | if af != bf { 29 | return af < bf 30 | } 31 | if ak != bk { 32 | return ak < bk 33 | } 34 | return numLess(a, b) 35 | } 36 | if ak != reflect.String || bk != reflect.String { 37 | return ak < bk 38 | } 39 | ar, br := []rune(a.String()), []rune(b.String()) 40 | for i := 0; i < len(ar) && i < len(br); i++ { 41 | if ar[i] == br[i] { 42 | continue 43 | } 44 | al := unicode.IsLetter(ar[i]) 45 | bl := unicode.IsLetter(br[i]) 46 | if al && bl { 47 | return ar[i] < br[i] 48 | } 49 | if al || bl { 50 | return bl 51 | } 52 | var ai, bi int 53 | var an, bn int64 54 | for ai = i; ai < len(ar) && unicode.IsDigit(ar[ai]); ai++ { 55 | an = an*10 + int64(ar[ai]-'0') 56 | } 57 | for bi = i; bi < len(br) && unicode.IsDigit(br[bi]); bi++ { 58 | bn = bn*10 + int64(br[bi]-'0') 59 | } 60 | if an != bn { 61 | return an < bn 62 | } 63 | if ai != bi { 64 | return ai < bi 65 | } 66 | return ar[i] < br[i] 67 | } 68 | return len(ar) < len(br) 69 | } 70 | 71 | // keyFloat returns a float value for v if it is a number/bool 72 | // and whether it is a number/bool or not. 73 | func keyFloat(v reflect.Value) (f float64, ok bool) { 74 | switch v.Kind() { 75 | case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 76 | return float64(v.Int()), true 77 | case reflect.Float32, reflect.Float64: 78 | return v.Float(), true 79 | case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 80 | return float64(v.Uint()), true 81 | case reflect.Bool: 82 | if v.Bool() { 83 | return 1, true 84 | } 85 | return 0, true 86 | } 87 | return 0, false 88 | } 89 | 90 | // numLess returns whether a < b. 91 | // a and b must necessarily have the same kind. 92 | func numLess(a, b reflect.Value) bool { 93 | switch a.Kind() { 94 | case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 95 | return a.Int() < b.Int() 96 | case reflect.Float32, reflect.Float64: 97 | return a.Float() < b.Float() 98 | case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 99 | return a.Uint() < b.Uint() 100 | case reflect.Bool: 101 | return !a.Bool() && b.Bool() 102 | } 103 | panic("not a number") 104 | } 105 | -------------------------------------------------------------------------------- /vendor/gopkg.in/yaml.v2/writerc.go: -------------------------------------------------------------------------------- 1 | package yaml 2 | 3 | // Set the writer error and return false. 4 | func yaml_emitter_set_writer_error(emitter *yaml_emitter_t, problem string) bool { 5 | emitter.error = yaml_WRITER_ERROR 6 | emitter.problem = problem 7 | return false 8 | } 9 | 10 | // Flush the output buffer. 11 | func yaml_emitter_flush(emitter *yaml_emitter_t) bool { 12 | if emitter.write_handler == nil { 13 | panic("write handler not set") 14 | } 15 | 16 | // Check if the buffer is empty. 17 | if emitter.buffer_pos == 0 { 18 | return true 19 | } 20 | 21 | // If the output encoding is UTF-8, we don't need to recode the buffer. 22 | if emitter.encoding == yaml_UTF8_ENCODING { 23 | if err := emitter.write_handler(emitter, emitter.buffer[:emitter.buffer_pos]); err != nil { 24 | return yaml_emitter_set_writer_error(emitter, "write error: "+err.Error()) 25 | } 26 | emitter.buffer_pos = 0 27 | return true 28 | } 29 | 30 | // Recode the buffer into the raw buffer. 31 | var low, high int 32 | if emitter.encoding == yaml_UTF16LE_ENCODING { 33 | low, high = 0, 1 34 | } else { 35 | high, low = 1, 0 36 | } 37 | 38 | pos := 0 39 | for pos < emitter.buffer_pos { 40 | // See the "reader.c" code for more details on UTF-8 encoding. Note 41 | // that we assume that the buffer contains a valid UTF-8 sequence. 42 | 43 | // Read the next UTF-8 character. 44 | octet := emitter.buffer[pos] 45 | 46 | var w int 47 | var value rune 48 | switch { 49 | case octet&0x80 == 0x00: 50 | w, value = 1, rune(octet&0x7F) 51 | case octet&0xE0 == 0xC0: 52 | w, value = 2, rune(octet&0x1F) 53 | case octet&0xF0 == 0xE0: 54 | w, value = 3, rune(octet&0x0F) 55 | case octet&0xF8 == 0xF0: 56 | w, value = 4, rune(octet&0x07) 57 | } 58 | for k := 1; k < w; k++ { 59 | octet = emitter.buffer[pos+k] 60 | value = (value << 6) + (rune(octet) & 0x3F) 61 | } 62 | pos += w 63 | 64 | // Write the character. 65 | if value < 0x10000 { 66 | var b [2]byte 67 | b[high] = byte(value >> 8) 68 | b[low] = byte(value & 0xFF) 69 | emitter.raw_buffer = append(emitter.raw_buffer, b[0], b[1]) 70 | } else { 71 | // Write the character using a surrogate pair (check "reader.c"). 72 | var b [4]byte 73 | value -= 0x10000 74 | b[high] = byte(0xD8 + (value >> 18)) 75 | b[low] = byte((value >> 10) & 0xFF) 76 | b[high+2] = byte(0xDC + ((value >> 8) & 0xFF)) 77 | b[low+2] = byte(value & 0xFF) 78 | emitter.raw_buffer = append(emitter.raw_buffer, b[0], b[1], b[2], b[3]) 79 | } 80 | } 81 | 82 | // Write the raw buffer. 83 | if err := emitter.write_handler(emitter, emitter.raw_buffer); err != nil { 84 | return yaml_emitter_set_writer_error(emitter, "write error: "+err.Error()) 85 | } 86 | emitter.buffer_pos = 0 87 | emitter.raw_buffer = emitter.raw_buffer[:0] 88 | return true 89 | } 90 | --------------------------------------------------------------------------------