From f4fa5180616593bcebeb408626291a3e314806e4 Mon Sep 17 00:00:00 2001 From: Dongsu Park Date: Wed, 22 Jun 2016 12:37:55 +0200 Subject: [PATCH 1/3] glide: initial configuration for using glide Use glide for package management, instead of govendor. Package management policy of fleet is to keep vendor files checked in as before, although glide also allows to remove the vendors from git repos. Commands used for the conversion: $ glide init $ glide update --strip-vendor --strip-vcs --update-vendored $ glide vc --only-code --no-tests Fixes: https://github.com/coreos/fleet/issues/1610 --- glide.lock | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ glide.yaml | 32 +++++++++++++++++++ 2 files changed, 124 insertions(+) create mode 100644 glide.lock create mode 100644 glide.yaml diff --git a/glide.lock b/glide.lock new file mode 100644 index 000000000..04cffc2b8 --- /dev/null +++ b/glide.lock @@ -0,0 +1,92 @@ +hash: 761e443b236a2651920ea60a7ed23e0547842be2e7f61e19fe1fe37ce76486c9 +updated: 2016-06-22T11:56:09.50904802+02:00 +imports: +- name: github.com/beorn7/perks + version: 3ac7bf7a47d159a033b107610db8a1b6575507a4 + subpackages: + - quantile +- name: github.com/coreos/etcd + version: 0b5ea3ec947a649d39b25c96e33ac1c743355be3 + subpackages: + - client + - pkg/pathutil + - pkg/types +- name: github.com/coreos/go-semver + version: 294930c1e79c64e7dbe360054274fdad492c8cf5 + subpackages: + - semver +- name: github.com/coreos/go-systemd + version: b32b8467dbea18858bfebf65c1a6a761090f2c31 + subpackages: + - activation + - dbus + - unit +- name: github.com/godbus/dbus + version: 32c6cc29c14570de4cf6d7e7737d68fb2d01ad15 +- name: github.com/golang/protobuf + version: 0c1f6d65b5a189c2250d10e71a5506f06f9fa0a0 + subpackages: + - proto +- name: github.com/inconshreveable/mousetrap + version: 76626ae9c91c4f2a10f34cad8ce83ea42c93bb75 +- name: github.com/jonboulle/clockwork + version: 2eee05ed794112d45db504eb05aa693efd2b8b09 +- name: github.com/matttproud/golang_protobuf_extensions + version: c12348ce28de40eed0136aa2b644d0ee0650e56c + subpackages: + - pbutil +- name: github.com/pborman/uuid + version: c55201b036063326c5b1b89ccfe45a184973d073 +- name: github.com/prometheus/client_golang + version: 488edd04dc224ba64c401747cd0a4b5f05dfb234 + subpackages: + - prometheus +- name: github.com/prometheus/client_model + version: fa8ad6fec33561be4280a8f0514318c79d7f6cb6 + subpackages: + - go +- name: github.com/prometheus/common + version: 3a184ff7dfd46b9091030bf2e56c71112b0ddb0e + subpackages: + - expfmt + - internal/bitbucket.org/ww/goautoneg + - model +- name: github.com/prometheus/procfs + version: abf152e5f3e97f2fafac028d2cc06c1feb87ffa5 +- name: github.com/rakyll/globalconf + version: 415abc325023f1a00cd2d9fa512e0e71745791a2 +- name: github.com/rakyll/goini + version: 907cca0f578a5316fb864ec6992dc3d9730ec58c +- name: github.com/spf13/cobra + version: 6a8bd97bdb1fc0d08a83459940498ea49d3e8c93 +- name: github.com/spf13/pflag + version: 367864438f1b1a3c7db4da06a2f55b144e6784e0 +- name: github.com/ugorji/go + version: b94837a2404ab90efe9289e77a70694c355739cb + subpackages: + - codec +- name: github.com/vishvananda/netlink + version: 734d02c3e202f682c74b71314b2c61eec0170fd4 + subpackages: + - nl +- name: github.com/vishvananda/netns + version: 8ba1072b58e0c2a240eb5f6120165c7776c3e7b8 +- name: golang.org/x/crypto + version: f3241ce8505855877cc8a9717bd61a0f7c4ea83c + subpackages: + - ssh + - ssh/agent + - ssh/terminal + - curve25519 + - ed25519 + - ed25519/internal/edwards25519 +- name: golang.org/x/net + version: bc3663df0ac92f928d419e31e0d2af22e683a5a2 + subpackages: + - context +- name: google.golang.org/api + version: 63ade871fd3aec1225809d496e81ec91ab76ea29 + subpackages: + - googleapi + - googleapi/internal/uritemplates +devImports: [] diff --git a/glide.yaml b/glide.yaml new file mode 100644 index 000000000..104cae5dc --- /dev/null +++ b/glide.yaml @@ -0,0 +1,32 @@ +package: github.com/coreos/fleet +import: +- package: github.com/coreos/etcd + subpackages: + - client +- package: github.com/coreos/go-semver + subpackages: + - semver +- package: github.com/coreos/go-systemd + subpackages: + - activation + - dbus + - unit +- package: github.com/jonboulle/clockwork +- package: github.com/pborman/uuid +- package: github.com/prometheus/client_golang + subpackages: + - prometheus +- package: github.com/rakyll/globalconf +- package: github.com/spf13/cobra +- package: github.com/vishvananda/netlink +- package: golang.org/x/crypto + subpackages: + - ssh + - ssh/agent + - ssh/terminal +- package: golang.org/x/net + subpackages: + - context +- package: google.golang.org/api + subpackages: + - googleapi From f2ed85a8f7f319daea366a0d86adf2a330be4dd5 Mon Sep 17 00:00:00 2001 From: Dongsu Park Date: Wed, 22 Jun 2016 12:38:27 +0200 Subject: [PATCH 2/3] vendor: update vendor according to conversion into glide As glide is set up, we also need to update vendors. --- .../beorn7/perks/quantile/exampledata.txt | 2388 - vendor/github.com/coreos/etcd/LICENSE | 202 + vendor/github.com/coreos/etcd/NOTICE | 5 + .../github.com/coreos/etcd/client/README.md | 94 - .../coreos/etcd/client/auth_role.go | 36 +- .../coreos/etcd/client/auth_user.go | 69 +- .../coreos/etcd/client/cancelreq.go | 2 - .../coreos/etcd/client/cancelreq_go14.go | 17 - .../github.com/coreos/etcd/client/client.go | 108 +- .../coreos/etcd/client/client_test.go | 896 - .../coreos/etcd/client/cluster_error.go | 2 +- vendor/github.com/coreos/etcd/client/curl.go | 2 +- .../github.com/coreos/etcd/client/discover.go | 4 +- vendor/github.com/coreos/etcd/client/doc.go | 4 +- .../etcd/client/fake_transport_go14_test.go | 41 - .../coreos/etcd/client/fake_transport_test.go | 42 - .../coreos/etcd/client/keys.generated.go | 1000 + vendor/github.com/coreos/etcd/client/keys.go | 32 +- .../coreos/etcd/client/keys_test.go | 1407 - .../github.com/coreos/etcd/client/members.go | 34 +- .../coreos/etcd/client/members_test.go | 522 - vendor/github.com/coreos/etcd/client/srv.go | 8 +- .../github.com/coreos/etcd/client/srv_test.go | 102 - .../pathutil/path_test.go => client/util.go} | 29 +- vendor/github.com/coreos/etcd/main.go | 29 + .../coreos/etcd/pkg/pathutil/path.go | 2 + .../etcd/pkg/types/{slice_test.go => doc.go} | 19 +- vendor/github.com/coreos/etcd/pkg/types/id.go | 2 +- .../coreos/etcd/pkg/types/id_test.go | 95 - .../github.com/coreos/etcd/pkg/types/set.go | 2 +- .../coreos/etcd/pkg/types/set_test.go | 186 - .../github.com/coreos/etcd/pkg/types/slice.go | 2 +- .../github.com/coreos/etcd/pkg/types/urls.go | 10 +- .../coreos/etcd/pkg/types/urls_test.go | 169 - .../coreos/etcd/pkg/types/urlsmap.go | 58 +- .../coreos/etcd/pkg/types/urlsmap_test.go | 69 - vendor/github.com/coreos/go-semver/LICENSE | 202 + vendor/github.com/coreos/go-semver/example.go | 20 + .../coreos/go-semver/semver/semver.go | 107 +- .../coreos/go-semver/semver/semver_test.go | 125 - .../coreos/go-semver/semver/sort.go | 14 + vendor/github.com/coreos/go-systemd/LICENSE | 191 + .../go-systemd/activation/files_test.go | 82 - .../go-systemd/activation/listeners_test.go | 86 - .../go-systemd/activation/packetconns_test.go | 68 - .../coreos/go-systemd/dbus/dbus_test.go | 77 - .../coreos/go-systemd/dbus/methods_test.go | 518 - .../coreos/go-systemd/dbus/set_test.go | 53 - .../go-systemd/dbus/subscription_set_test.go | 82 - .../go-systemd/dbus/subscription_test.go | 105 - .../go-systemd/unit/deserialize_test.go | 381 - .../coreos/go-systemd/unit/end_to_end_test.go | 88 - .../coreos/go-systemd/unit/escape_test.go | 211 - .../coreos/go-systemd/unit/option_test.go | 214 - .../coreos/go-systemd/unit/serialize_test.go | 170 - vendor/github.com/godbus/dbus/CONTRIBUTING.md | 50 - vendor/github.com/godbus/dbus/MAINTAINERS | 2 - vendor/github.com/godbus/dbus/README.markdown | 41 - vendor/github.com/godbus/dbus/conn.go | 54 +- vendor/github.com/godbus/dbus/conn_other.go | 6 +- vendor/github.com/godbus/dbus/conn_test.go | 199 - vendor/github.com/godbus/dbus/encoder_test.go | 58 - .../github.com/godbus/dbus/examples_test.go | 50 - vendor/github.com/godbus/dbus/export.go | 167 +- vendor/github.com/godbus/dbus/export_test.go | 374 - .../github.com/godbus/dbus/introspect/call.go | 27 - .../godbus/dbus/introspect/introspect.go | 86 - .../godbus/dbus/introspect/introspectable.go | 76 - vendor/github.com/godbus/dbus/message.go | 9 +- vendor/github.com/godbus/dbus/object.go | 10 + vendor/github.com/godbus/dbus/prop/prop.go | 264 - vendor/github.com/godbus/dbus/proto_test.go | 369 - vendor/github.com/godbus/dbus/sig_test.go | 70 - .../github.com/godbus/dbus/transport_tcp.go | 43 + .../github.com/godbus/dbus/transport_unix.go | 2 +- .../godbus/dbus/transport_unix_test.go | 49 - .../godbus/dbus/transport_unixcred_openbsd.go | 14 + vendor/github.com/godbus/dbus/variant_test.go | 78 - .../github.com/golang/protobuf/proto/Makefile | 43 - .../github.com/golang/protobuf/proto/clone.go | 12 +- .../golang/protobuf/proto/decode.go | 7 +- .../golang/protobuf/proto/encode.go | 52 +- .../github.com/golang/protobuf/proto/equal.go | 26 +- .../golang/protobuf/proto/extensions.go | 196 +- .../github.com/golang/protobuf/proto/lib.go | 4 + .../golang/protobuf/proto/message_set.go | 43 +- .../golang/protobuf/proto/pointer_reflect.go | 5 + .../golang/protobuf/proto/pointer_unsafe.go | 4 + .../golang/protobuf/proto/properties.go | 46 +- .../github.com/golang/protobuf/proto/text.go | 15 +- .../golang/protobuf/proto/text_parser.go | 69 +- .../inconshreveable/mousetrap/LICENSE | 13 + .../inconshreveable/mousetrap/trap_others.go | 15 + .../inconshreveable/mousetrap/trap_windows.go | 98 + .../mousetrap/trap_windows_1.4.go | 46 + .../github.com/jonboulle/clockwork/.gitignore | 25 - .../jonboulle/clockwork/.travis.yml | 3 - .../github.com/jonboulle/clockwork/README.md | 61 - .../jonboulle/clockwork/clockwork.go | 18 +- .../jonboulle/clockwork/clockwork_test.go | 106 - .../jonboulle/clockwork/example_test.go | 49 - .../pbutil/decode.go | 2 +- .../pbutil/encode.go | 4 +- vendor/github.com/pborman/uuid/.travis.yml | 10 - .../github.com/pborman/uuid/CONTRIBUTING.md | 10 - vendor/github.com/pborman/uuid/CONTRIBUTORS | 1 - vendor/github.com/pborman/uuid/README.md | 13 - vendor/github.com/pborman/uuid/dce.go | 0 vendor/github.com/pborman/uuid/doc.go | 0 vendor/github.com/pborman/uuid/node.go | 0 vendor/github.com/pborman/uuid/time.go | 0 .../client_golang/prometheus/.gitignore | 1 - .../client_golang/prometheus/README.md | 53 - .../client_golang/prometheus/doc.go | 4 +- .../client_golang/prometheus/http.go | 42 +- .../client_golang/prometheus/registry.go | 3 + .../prometheus/common/expfmt/decode.go | 2 +- .../prometheus/common/expfmt/fuzz.go | 4 +- .../bitbucket.org/ww/goautoneg/README.txt | 67 - .../prometheus/common/model/model.go | 2 +- .../prometheus/common/model/value.go | 18 +- .../github.com/prometheus/procfs/.travis.yml | 7 - .../github.com/prometheus/procfs/AUTHORS.md | 20 - .../prometheus/procfs/CONTRIBUTING.md | 18 - vendor/github.com/prometheus/procfs/Makefile | 6 - vendor/github.com/prometheus/procfs/README.md | 10 - vendor/github.com/prometheus/procfs/proc.go | 4 +- .../prometheus/procfs/proc_limits.go | 2 +- .../github.com/rakyll/globalconf/.travis.yml | 2 - vendor/github.com/rakyll/globalconf/README.md | 134 - .../rakyll/globalconf/globalconf.go | 2 + .../rakyll/globalconf/globalconf_test.go | 238 - .../rakyll/globalconf/testdata/custom.ini | 2 - .../rakyll/globalconf/testdata/global.ini | 3 - .../globalconf/testdata/globalandcustom.ini | 6 - vendor/github.com/rakyll/goini/.gitignore | 8 - vendor/github.com/rakyll/goini/Makefile | 7 - vendor/github.com/rakyll/goini/empty.ini | 0 vendor/github.com/rakyll/goini/example.ini | 18 - vendor/github.com/rakyll/goini/ini_test.go | 169 - vendor/github.com/spf13/cobra/README.md | 892 - .../spf13/cobra/bash_completions.go | 42 +- .../spf13/cobra/bash_completions.md | 206 - .../spf13/cobra/bash_completions_test.go | 140 - vendor/github.com/spf13/cobra/cobra.go | 4 + vendor/github.com/spf13/cobra/cobra_test.go | 1188 - vendor/github.com/spf13/cobra/command.go | 43 +- vendor/github.com/spf13/cobra/command_test.go | 114 - vendor/github.com/spf13/pflag/README.md | 256 - vendor/github.com/spf13/pflag/bool_test.go | 180 - vendor/github.com/spf13/pflag/count_test.go | 55 - vendor/github.com/spf13/pflag/example_test.go | 77 - vendor/github.com/spf13/pflag/export_test.go | 29 - vendor/github.com/spf13/pflag/flag_test.go | 913 - .../github.com/spf13/pflag/golangflag_test.go | 39 - .../github.com/spf13/pflag/int_slice_test.go | 162 - vendor/github.com/spf13/pflag/ip_test.go | 63 - vendor/github.com/spf13/pflag/ipnet_test.go | 70 - .../spf13/pflag/string_slice_test.go | 161 - vendor/github.com/spf13/pflag/verify/all.sh | 69 - vendor/github.com/spf13/pflag/verify/gofmt.sh | 19 - .../github.com/spf13/pflag/verify/golint.sh | 15 - vendor/github.com/ugorji/go/LICENSE | 22 + vendor/github.com/ugorji/go/codec/0doc.go | 199 + vendor/github.com/ugorji/go/codec/binc.go | 922 + vendor/github.com/ugorji/go/codec/cbor.go | 585 + vendor/github.com/ugorji/go/codec/decode.go | 2019 + vendor/github.com/ugorji/go/codec/encode.go | 1422 + .../ugorji/go/codec/fast-path.generated.go | 39352 ++++++++++++++++ .../ugorji/go/codec/fast-path.not.go | 34 + .../ugorji/go/codec/gen-helper.generated.go | 233 + .../ugorji/go/codec/gen.generated.go | 175 + vendor/github.com/ugorji/go/codec/gen.go | 1995 + vendor/github.com/ugorji/go/codec/gen_15.go | 12 + vendor/github.com/ugorji/go/codec/gen_16.go | 12 + vendor/github.com/ugorji/go/codec/helper.go | 1309 + .../ugorji/go/codec/helper_internal.go | 242 + .../ugorji/go/codec/helper_not_unsafe.go | 20 + .../ugorji/go/codec/helper_unsafe.go | 49 + vendor/github.com/ugorji/go/codec/json.go | 1213 + vendor/github.com/ugorji/go/codec/msgpack.go | 845 + vendor/github.com/ugorji/go/codec/noop.go | 213 + vendor/github.com/ugorji/go/codec/prebuild.go | 3 + vendor/github.com/ugorji/go/codec/rpc.go | 180 + vendor/github.com/ugorji/go/codec/simple.go | 519 + vendor/github.com/ugorji/go/codec/time.go | 233 + .../vishvananda/netlink/.travis.yml | 8 - .../github.com/vishvananda/netlink/Makefile | 29 - .../github.com/vishvananda/netlink/README.md | 89 - .../vishvananda/netlink/addr_test.go | 112 - .../vishvananda/netlink/class_test.go | 406 - .../vishvananda/netlink/filter_test.go | 472 - .../vishvananda/netlink/handle_linux.go | 70 +- .../vishvananda/netlink/handle_test.go | 286 - .../vishvananda/netlink/link_test.go | 863 - .../vishvananda/netlink/neigh_test.go | 104 - .../vishvananda/netlink/netlink_test.go | 34 - .../vishvananda/netlink/nl/addr_linux_test.go | 39 - .../vishvananda/netlink/nl/link_linux_test.go | 199 - .../vishvananda/netlink/nl/nl_linux.go | 35 +- .../vishvananda/netlink/nl/nl_linux_test.go | 60 - .../netlink/nl/route_linux_test.go | 43 - .../vishvananda/netlink/nl/tc_linux_test.go | 173 - .../vishvananda/netlink/nl/xfrm_linux_test.go | 161 - .../netlink/nl/xfrm_policy_linux_test.go | 109 - .../netlink/nl/xfrm_state_linux_test.go | 233 - .../vishvananda/netlink/protinfo_test.go | 98 - .../vishvananda/netlink/qdisc_test.go | 345 - .../vishvananda/netlink/route_test.go | 247 - .../vishvananda/netlink/rule_test.go | 66 - .../vishvananda/netlink/xfrm_policy_test.go | 197 - .../vishvananda/netlink/xfrm_state_test.go | 202 - vendor/github.com/vishvananda/netns/README.md | 50 - .../vishvananda/netns/netns_test.go | 66 - vendor/golang.org/x/crypto/LICENSE | 27 + vendor/golang.org/x/crypto/PATENTS | 22 + vendor/golang.org/x/crypto/curve25519/doc.go | 2 +- vendor/golang.org/x/crypto/ed25519/ed25519.go | 181 + .../ed25519/internal/edwards25519/const.go | 1422 + .../internal/edwards25519/edwards25519.go | 1771 + .../golang.org/x/crypto/ssh/agent/client.go | 83 +- .../golang.org/x/crypto/ssh/agent/server.go | 247 +- vendor/golang.org/x/crypto/ssh/certs.go | 4 +- vendor/golang.org/x/crypto/ssh/channel.go | 4 +- vendor/golang.org/x/crypto/ssh/cipher.go | 39 +- vendor/golang.org/x/crypto/ssh/client.go | 8 +- vendor/golang.org/x/crypto/ssh/common.go | 2 + vendor/golang.org/x/crypto/ssh/doc.go | 2 +- vendor/golang.org/x/crypto/ssh/handshake.go | 109 +- vendor/golang.org/x/crypto/ssh/kex.go | 2 +- vendor/golang.org/x/crypto/ssh/keys.go | 142 +- vendor/golang.org/x/crypto/ssh/messages.go | 75 +- vendor/golang.org/x/crypto/ssh/mux.go | 6 +- vendor/golang.org/x/crypto/ssh/server.go | 10 +- vendor/golang.org/x/crypto/ssh/session.go | 9 +- .../golang.org/x/crypto/ssh/terminal/util.go | 2 +- .../x/crypto/ssh/terminal/util_plan9.go | 58 + .../x/crypto/ssh/terminal/util_windows.go | 4 +- vendor/golang.org/x/crypto/ssh/transport.go | 30 +- vendor/golang.org/x/net/LICENSE | 27 + vendor/golang.org/x/net/PATENTS | 22 + vendor/golang.org/x/net/context/context.go | 297 +- .../golang.org/x/net/context/context_test.go | 575 - vendor/golang.org/x/net/context/go17.go | 72 + vendor/golang.org/x/net/context/pre_go17.go | 300 + .../x/net/context/withtimeout_test.go | 26 - vendor/google.golang.org/api/LICENSE | 27 + .../api/googleapi/googleapi.go | 277 +- .../api/googleapi/googleapi_test.go | 361 - .../internal/uritemplates/uritemplates.go | 247 +- .../googleapi/internal/uritemplates/utils.go | 14 +- .../api/googleapi/transport/apikey.go | 38 - .../google.golang.org/api/googleapi/types.go | 32 + .../api/googleapi/types_test.go | 44 - 254 files changed, 59665 insertions(+), 22725 deletions(-) delete mode 100644 vendor/github.com/beorn7/perks/quantile/exampledata.txt create mode 100644 vendor/github.com/coreos/etcd/LICENSE create mode 100644 vendor/github.com/coreos/etcd/NOTICE delete mode 100644 vendor/github.com/coreos/etcd/client/README.md delete mode 100644 vendor/github.com/coreos/etcd/client/cancelreq_go14.go delete mode 100644 vendor/github.com/coreos/etcd/client/client_test.go delete mode 100644 vendor/github.com/coreos/etcd/client/fake_transport_go14_test.go delete mode 100644 vendor/github.com/coreos/etcd/client/fake_transport_test.go create mode 100644 vendor/github.com/coreos/etcd/client/keys.generated.go delete mode 100644 vendor/github.com/coreos/etcd/client/keys_test.go delete mode 100644 vendor/github.com/coreos/etcd/client/members_test.go delete mode 100644 vendor/github.com/coreos/etcd/client/srv_test.go rename vendor/github.com/coreos/etcd/{pkg/pathutil/path_test.go => client/util.go} (56%) create mode 100644 vendor/github.com/coreos/etcd/main.go rename vendor/github.com/coreos/etcd/pkg/types/{slice_test.go => doc.go} (65%) delete mode 100644 vendor/github.com/coreos/etcd/pkg/types/id_test.go delete mode 100644 vendor/github.com/coreos/etcd/pkg/types/set_test.go delete mode 100644 vendor/github.com/coreos/etcd/pkg/types/urls_test.go delete mode 100644 vendor/github.com/coreos/etcd/pkg/types/urlsmap_test.go create mode 100644 vendor/github.com/coreos/go-semver/LICENSE create mode 100644 vendor/github.com/coreos/go-semver/example.go delete mode 100644 vendor/github.com/coreos/go-semver/semver/semver_test.go create mode 100644 vendor/github.com/coreos/go-systemd/LICENSE delete mode 100644 vendor/github.com/coreos/go-systemd/activation/files_test.go delete mode 100644 vendor/github.com/coreos/go-systemd/activation/listeners_test.go delete mode 100644 vendor/github.com/coreos/go-systemd/activation/packetconns_test.go delete mode 100644 vendor/github.com/coreos/go-systemd/dbus/dbus_test.go delete mode 100644 vendor/github.com/coreos/go-systemd/dbus/methods_test.go delete mode 100644 vendor/github.com/coreos/go-systemd/dbus/set_test.go delete mode 100644 vendor/github.com/coreos/go-systemd/dbus/subscription_set_test.go delete mode 100644 vendor/github.com/coreos/go-systemd/dbus/subscription_test.go delete mode 100644 vendor/github.com/coreos/go-systemd/unit/deserialize_test.go delete mode 100644 vendor/github.com/coreos/go-systemd/unit/end_to_end_test.go delete mode 100644 vendor/github.com/coreos/go-systemd/unit/escape_test.go delete mode 100644 vendor/github.com/coreos/go-systemd/unit/option_test.go delete mode 100644 vendor/github.com/coreos/go-systemd/unit/serialize_test.go delete mode 100644 vendor/github.com/godbus/dbus/CONTRIBUTING.md delete mode 100644 vendor/github.com/godbus/dbus/MAINTAINERS delete mode 100644 vendor/github.com/godbus/dbus/README.markdown delete mode 100644 vendor/github.com/godbus/dbus/conn_test.go delete mode 100644 vendor/github.com/godbus/dbus/encoder_test.go delete mode 100644 vendor/github.com/godbus/dbus/examples_test.go delete mode 100644 vendor/github.com/godbus/dbus/export_test.go delete mode 100644 vendor/github.com/godbus/dbus/introspect/call.go delete mode 100644 vendor/github.com/godbus/dbus/introspect/introspect.go delete mode 100644 vendor/github.com/godbus/dbus/introspect/introspectable.go delete mode 100644 vendor/github.com/godbus/dbus/prop/prop.go delete mode 100644 vendor/github.com/godbus/dbus/proto_test.go delete mode 100644 vendor/github.com/godbus/dbus/sig_test.go create mode 100644 vendor/github.com/godbus/dbus/transport_tcp.go delete mode 100644 vendor/github.com/godbus/dbus/transport_unix_test.go create mode 100644 vendor/github.com/godbus/dbus/transport_unixcred_openbsd.go delete mode 100644 vendor/github.com/godbus/dbus/variant_test.go delete mode 100644 vendor/github.com/golang/protobuf/proto/Makefile create mode 100644 vendor/github.com/inconshreveable/mousetrap/LICENSE create mode 100644 vendor/github.com/inconshreveable/mousetrap/trap_others.go create mode 100644 vendor/github.com/inconshreveable/mousetrap/trap_windows.go create mode 100644 vendor/github.com/inconshreveable/mousetrap/trap_windows_1.4.go delete mode 100644 vendor/github.com/jonboulle/clockwork/.gitignore delete mode 100644 vendor/github.com/jonboulle/clockwork/.travis.yml delete mode 100644 vendor/github.com/jonboulle/clockwork/README.md delete mode 100644 vendor/github.com/jonboulle/clockwork/clockwork_test.go delete mode 100644 vendor/github.com/jonboulle/clockwork/example_test.go delete mode 100644 vendor/github.com/pborman/uuid/.travis.yml delete mode 100644 vendor/github.com/pborman/uuid/CONTRIBUTING.md delete mode 100644 vendor/github.com/pborman/uuid/CONTRIBUTORS delete mode 100644 vendor/github.com/pborman/uuid/README.md mode change 100644 => 100755 vendor/github.com/pborman/uuid/dce.go mode change 100644 => 100755 vendor/github.com/pborman/uuid/doc.go mode change 100644 => 100755 vendor/github.com/pborman/uuid/node.go mode change 100644 => 100755 vendor/github.com/pborman/uuid/time.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/.gitignore delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/README.md delete mode 100644 vendor/github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg/README.txt delete mode 100644 vendor/github.com/prometheus/procfs/.travis.yml delete mode 100644 vendor/github.com/prometheus/procfs/AUTHORS.md delete mode 100644 vendor/github.com/prometheus/procfs/CONTRIBUTING.md delete mode 100644 vendor/github.com/prometheus/procfs/Makefile delete mode 100644 vendor/github.com/prometheus/procfs/README.md delete mode 100644 vendor/github.com/rakyll/globalconf/.travis.yml delete mode 100644 vendor/github.com/rakyll/globalconf/README.md delete mode 100644 vendor/github.com/rakyll/globalconf/globalconf_test.go delete mode 100644 vendor/github.com/rakyll/globalconf/testdata/custom.ini delete mode 100644 vendor/github.com/rakyll/globalconf/testdata/global.ini delete mode 100644 vendor/github.com/rakyll/globalconf/testdata/globalandcustom.ini delete mode 100644 vendor/github.com/rakyll/goini/.gitignore delete mode 100644 vendor/github.com/rakyll/goini/Makefile delete mode 100644 vendor/github.com/rakyll/goini/empty.ini delete mode 100644 vendor/github.com/rakyll/goini/example.ini delete mode 100644 vendor/github.com/rakyll/goini/ini_test.go delete mode 100644 vendor/github.com/spf13/cobra/README.md delete mode 100644 vendor/github.com/spf13/cobra/bash_completions.md delete mode 100644 vendor/github.com/spf13/cobra/bash_completions_test.go delete mode 100644 vendor/github.com/spf13/cobra/cobra_test.go delete mode 100644 vendor/github.com/spf13/cobra/command_test.go delete mode 100644 vendor/github.com/spf13/pflag/README.md delete mode 100644 vendor/github.com/spf13/pflag/bool_test.go delete mode 100644 vendor/github.com/spf13/pflag/count_test.go delete mode 100644 vendor/github.com/spf13/pflag/example_test.go delete mode 100644 vendor/github.com/spf13/pflag/export_test.go delete mode 100644 vendor/github.com/spf13/pflag/flag_test.go delete mode 100644 vendor/github.com/spf13/pflag/golangflag_test.go delete mode 100644 vendor/github.com/spf13/pflag/int_slice_test.go delete mode 100644 vendor/github.com/spf13/pflag/ip_test.go delete mode 100644 vendor/github.com/spf13/pflag/ipnet_test.go delete mode 100644 vendor/github.com/spf13/pflag/string_slice_test.go delete mode 100755 vendor/github.com/spf13/pflag/verify/all.sh delete mode 100755 vendor/github.com/spf13/pflag/verify/gofmt.sh delete mode 100755 vendor/github.com/spf13/pflag/verify/golint.sh create mode 100644 vendor/github.com/ugorji/go/LICENSE create mode 100644 vendor/github.com/ugorji/go/codec/0doc.go create mode 100644 vendor/github.com/ugorji/go/codec/binc.go create mode 100644 vendor/github.com/ugorji/go/codec/cbor.go create mode 100644 vendor/github.com/ugorji/go/codec/decode.go create mode 100644 vendor/github.com/ugorji/go/codec/encode.go create mode 100644 vendor/github.com/ugorji/go/codec/fast-path.generated.go create mode 100644 vendor/github.com/ugorji/go/codec/fast-path.not.go create mode 100644 vendor/github.com/ugorji/go/codec/gen-helper.generated.go create mode 100644 vendor/github.com/ugorji/go/codec/gen.generated.go create mode 100644 vendor/github.com/ugorji/go/codec/gen.go create mode 100644 vendor/github.com/ugorji/go/codec/gen_15.go create mode 100644 vendor/github.com/ugorji/go/codec/gen_16.go create mode 100644 vendor/github.com/ugorji/go/codec/helper.go create mode 100644 vendor/github.com/ugorji/go/codec/helper_internal.go create mode 100644 vendor/github.com/ugorji/go/codec/helper_not_unsafe.go create mode 100644 vendor/github.com/ugorji/go/codec/helper_unsafe.go create mode 100644 vendor/github.com/ugorji/go/codec/json.go create mode 100644 vendor/github.com/ugorji/go/codec/msgpack.go create mode 100644 vendor/github.com/ugorji/go/codec/noop.go create mode 100644 vendor/github.com/ugorji/go/codec/prebuild.go create mode 100644 vendor/github.com/ugorji/go/codec/rpc.go create mode 100644 vendor/github.com/ugorji/go/codec/simple.go create mode 100644 vendor/github.com/ugorji/go/codec/time.go delete mode 100644 vendor/github.com/vishvananda/netlink/.travis.yml delete mode 100644 vendor/github.com/vishvananda/netlink/Makefile delete mode 100644 vendor/github.com/vishvananda/netlink/README.md delete mode 100644 vendor/github.com/vishvananda/netlink/addr_test.go delete mode 100644 vendor/github.com/vishvananda/netlink/class_test.go delete mode 100644 vendor/github.com/vishvananda/netlink/filter_test.go delete mode 100644 vendor/github.com/vishvananda/netlink/handle_test.go delete mode 100644 vendor/github.com/vishvananda/netlink/link_test.go delete mode 100644 vendor/github.com/vishvananda/netlink/neigh_test.go delete mode 100644 vendor/github.com/vishvananda/netlink/netlink_test.go delete mode 100644 vendor/github.com/vishvananda/netlink/nl/addr_linux_test.go delete mode 100644 vendor/github.com/vishvananda/netlink/nl/link_linux_test.go delete mode 100644 vendor/github.com/vishvananda/netlink/nl/nl_linux_test.go delete mode 100644 vendor/github.com/vishvananda/netlink/nl/route_linux_test.go delete mode 100644 vendor/github.com/vishvananda/netlink/nl/tc_linux_test.go delete mode 100644 vendor/github.com/vishvananda/netlink/nl/xfrm_linux_test.go delete mode 100644 vendor/github.com/vishvananda/netlink/nl/xfrm_policy_linux_test.go delete mode 100644 vendor/github.com/vishvananda/netlink/nl/xfrm_state_linux_test.go delete mode 100644 vendor/github.com/vishvananda/netlink/protinfo_test.go delete mode 100644 vendor/github.com/vishvananda/netlink/qdisc_test.go delete mode 100644 vendor/github.com/vishvananda/netlink/route_test.go delete mode 100644 vendor/github.com/vishvananda/netlink/rule_test.go delete mode 100644 vendor/github.com/vishvananda/netlink/xfrm_policy_test.go delete mode 100644 vendor/github.com/vishvananda/netlink/xfrm_state_test.go delete mode 100644 vendor/github.com/vishvananda/netns/README.md delete mode 100644 vendor/github.com/vishvananda/netns/netns_test.go create mode 100644 vendor/golang.org/x/crypto/LICENSE create mode 100644 vendor/golang.org/x/crypto/PATENTS create mode 100644 vendor/golang.org/x/crypto/ed25519/ed25519.go create mode 100644 vendor/golang.org/x/crypto/ed25519/internal/edwards25519/const.go create mode 100644 vendor/golang.org/x/crypto/ed25519/internal/edwards25519/edwards25519.go create mode 100644 vendor/golang.org/x/crypto/ssh/terminal/util_plan9.go create mode 100644 vendor/golang.org/x/net/LICENSE create mode 100644 vendor/golang.org/x/net/PATENTS delete mode 100644 vendor/golang.org/x/net/context/context_test.go create mode 100644 vendor/golang.org/x/net/context/go17.go create mode 100644 vendor/golang.org/x/net/context/pre_go17.go delete mode 100644 vendor/golang.org/x/net/context/withtimeout_test.go create mode 100644 vendor/google.golang.org/api/LICENSE delete mode 100644 vendor/google.golang.org/api/googleapi/googleapi_test.go delete mode 100644 vendor/google.golang.org/api/googleapi/transport/apikey.go delete mode 100644 vendor/google.golang.org/api/googleapi/types_test.go diff --git a/vendor/github.com/beorn7/perks/quantile/exampledata.txt b/vendor/github.com/beorn7/perks/quantile/exampledata.txt deleted file mode 100644 index 1602287d7..000000000 --- a/vendor/github.com/beorn7/perks/quantile/exampledata.txt +++ /dev/null @@ -1,2388 +0,0 @@ -8 -5 -26 -12 -5 -235 -13 -6 -28 -30 -3 -3 -3 -3 -5 -2 -33 -7 -2 -4 -7 -12 -14 -5 -8 -3 -10 -4 -5 -3 -6 -6 -209 -20 -3 -10 -14 -3 -4 -6 -8 -5 -11 -7 -3 -2 -3 -3 -212 -5 -222 -4 -10 -10 -5 -6 -3 -8 -3 -10 -254 -220 -2 -3 -5 -24 -5 -4 -222 -7 -3 -3 -223 -8 -15 -12 -14 -14 -3 -2 -2 -3 -13 -3 -11 -4 -4 -6 -5 -7 -13 -5 -3 -5 -2 -5 -3 -5 -2 -7 -15 -17 -14 -3 -6 -6 -3 -17 -5 -4 -7 -6 -4 -4 -8 -6 -8 -3 -9 -3 -6 -3 -4 -5 -3 -3 -660 -4 -6 -10 -3 -6 -3 -2 -5 -13 -2 -4 -4 -10 -4 -8 -4 -3 -7 -9 -9 -3 -10 -37 -3 -13 -4 -12 -3 -6 -10 -8 -5 -21 -2 -3 -8 -3 -2 -3 -3 -4 -12 -2 -4 -8 -8 -4 -3 -2 -20 -1 -6 -32 -2 -11 -6 -18 -3 -8 -11 -3 -212 -3 -4 -2 -6 -7 -12 -11 -3 -2 -16 -10 -6 -4 -6 -3 -2 -7 -3 -2 -2 -2 -2 -5 -6 -4 -3 -10 -3 -4 -6 -5 -3 -4 -4 -5 -6 -4 -3 -4 -4 -5 -7 -5 -5 -3 -2 -7 -2 -4 -12 -4 -5 -6 -2 -4 -4 -8 -4 -15 -13 -7 -16 -5 -3 -23 -5 -5 -7 -3 -2 -9 -8 -7 -5 -8 -11 -4 -10 -76 -4 -47 -4 -3 -2 -7 -4 -2 -3 -37 -10 -4 -2 -20 -5 -4 -4 -10 -10 -4 -3 -7 -23 -240 -7 -13 -5 -5 -3 -3 -2 -5 -4 -2 -8 -7 -19 -2 -23 -8 -7 -2 -5 -3 -8 -3 -8 -13 -5 -5 -5 -2 -3 -23 -4 -9 -8 -4 -3 -3 -5 -220 -2 -3 -4 -6 -14 -3 -53 -6 -2 -5 -18 -6 -3 -219 -6 -5 -2 -5 -3 -6 -5 -15 -4 -3 -17 -3 -2 -4 -7 -2 -3 -3 -4 -4 -3 -2 -664 -6 -3 -23 -5 -5 -16 -5 -8 -2 -4 -2 -24 -12 -3 -2 -3 -5 -8 -3 -5 -4 -3 -14 -3 -5 -8 -2 -3 -7 -9 -4 -2 -3 -6 -8 -4 -3 -4 -6 -5 -3 -3 -6 -3 -19 -4 -4 -6 -3 -6 -3 -5 -22 -5 -4 -4 -3 -8 -11 -4 -9 -7 -6 -13 -4 -4 -4 -6 -17 -9 -3 -3 -3 -4 -3 -221 -5 -11 -3 -4 -2 -12 -6 -3 -5 -7 -5 -7 -4 -9 -7 -14 -37 -19 -217 -16 -3 -5 -2 -2 -7 -19 -7 -6 -7 -4 -24 -5 -11 -4 -7 -7 -9 -13 -3 -4 -3 -6 -28 -4 -4 -5 -5 -2 -5 -6 -4 -4 -6 -10 -5 -4 -3 -2 -3 -3 -6 -5 -5 -4 -3 -2 -3 -7 -4 -6 -18 -16 -8 -16 -4 -5 -8 -6 -9 -13 -1545 -6 -215 -6 -5 -6 -3 -45 -31 -5 -2 -2 -4 -3 -3 -2 -5 -4 -3 -5 -7 -7 -4 -5 -8 -5 -4 -749 -2 -31 -9 -11 -2 -11 -5 -4 -4 -7 -9 -11 -4 -5 -4 -7 -3 -4 -6 -2 -15 -3 -4 -3 -4 -3 -5 -2 -13 -5 -5 -3 -3 -23 -4 -4 -5 -7 -4 -13 -2 -4 -3 -4 -2 -6 -2 -7 -3 -5 -5 -3 -29 -5 -4 -4 -3 -10 -2 -3 -79 -16 -6 -6 -7 -7 -3 -5 -5 -7 -4 -3 -7 -9 -5 -6 -5 -9 -6 -3 -6 -4 -17 -2 -10 -9 -3 -6 -2 -3 -21 -22 -5 -11 -4 -2 -17 -2 -224 -2 -14 -3 -4 -4 -2 -4 -4 -4 -4 -5 -3 -4 -4 -10 -2 -6 -3 -3 -5 -7 -2 -7 -5 -6 -3 -218 -2 -2 -5 -2 -6 -3 -5 -222 -14 -6 -33 -3 -2 -5 -3 -3 -3 -9 -5 -3 -3 -2 -7 -4 -3 -4 -3 -5 -6 -5 -26 -4 -13 -9 -7 -3 -221 -3 -3 -4 -4 -4 -4 -2 -18 -5 -3 -7 -9 -6 -8 -3 -10 -3 -11 -9 -5 -4 -17 -5 -5 -6 -6 -3 -2 -4 -12 -17 -6 -7 -218 -4 -2 -4 -10 -3 -5 -15 -3 -9 -4 -3 -3 -6 -29 -3 -3 -4 -5 -5 -3 -8 -5 -6 -6 -7 -5 -3 -5 -3 -29 -2 -31 -5 -15 -24 -16 -5 -207 -4 -3 -3 -2 -15 -4 -4 -13 -5 -5 -4 -6 -10 -2 -7 -8 -4 -6 -20 -5 -3 -4 -3 -12 -12 -5 -17 -7 -3 -3 -3 -6 -10 -3 -5 -25 -80 -4 -9 -3 -2 -11 -3 -3 -2 -3 -8 -7 -5 -5 -19 -5 -3 -3 -12 -11 -2 -6 -5 -5 -5 -3 -3 -3 -4 -209 -14 -3 -2 -5 -19 -4 -4 -3 -4 -14 -5 -6 -4 -13 -9 -7 -4 -7 -10 -2 -9 -5 -7 -2 -8 -4 -6 -5 -5 -222 -8 -7 -12 -5 -216 -3 -4 -4 -6 -3 -14 -8 -7 -13 -4 -3 -3 -3 -3 -17 -5 -4 -3 -33 -6 -6 -33 -7 -5 -3 -8 -7 -5 -2 -9 -4 -2 -233 -24 -7 -4 -8 -10 -3 -4 -15 -2 -16 -3 -3 -13 -12 -7 -5 -4 -207 -4 -2 -4 -27 -15 -2 -5 -2 -25 -6 -5 -5 -6 -13 -6 -18 -6 -4 -12 -225 -10 -7 -5 -2 -2 -11 -4 -14 -21 -8 -10 -3 -5 -4 -232 -2 -5 -5 -3 -7 -17 -11 -6 -6 -23 -4 -6 -3 -5 -4 -2 -17 -3 -6 -5 -8 -3 -2 -2 -14 -9 -4 -4 -2 -5 -5 -3 -7 -6 -12 -6 -10 -3 -6 -2 -2 -19 -5 -4 -4 -9 -2 -4 -13 -3 -5 -6 -3 -6 -5 -4 -9 -6 -3 -5 -7 -3 -6 -6 -4 -3 -10 -6 -3 -221 -3 -5 -3 -6 -4 -8 -5 -3 -6 -4 -4 -2 -54 -5 -6 -11 -3 -3 -4 -4 -4 -3 -7 -3 -11 -11 -7 -10 -6 -13 -223 -213 -15 -231 -7 -3 -7 -228 -2 -3 -4 -4 -5 -6 -7 -4 -13 -3 -4 -5 -3 -6 -4 -6 -7 -2 -4 -3 -4 -3 -3 -6 -3 -7 -3 -5 -18 -5 -6 -8 -10 -3 -3 -3 -2 -4 -2 -4 -4 -5 -6 -6 -4 -10 -13 -3 -12 -5 -12 -16 -8 -4 -19 -11 -2 -4 -5 -6 -8 -5 -6 -4 -18 -10 -4 -2 -216 -6 -6 -6 -2 -4 -12 -8 -3 -11 -5 -6 -14 -5 -3 -13 -4 -5 -4 -5 -3 -28 -6 -3 -7 -219 -3 -9 -7 -3 -10 -6 -3 -4 -19 -5 -7 -11 -6 -15 -19 -4 -13 -11 -3 -7 -5 -10 -2 -8 -11 -2 -6 -4 -6 -24 -6 -3 -3 -3 -3 -6 -18 -4 -11 -4 -2 -5 -10 -8 -3 -9 -5 -3 -4 -5 -6 -2 -5 -7 -4 -4 -14 -6 -4 -4 -5 -5 -7 -2 -4 -3 -7 -3 -3 -6 -4 -5 -4 -4 -4 -3 -3 -3 -3 -8 -14 -2 -3 -5 -3 -2 -4 -5 -3 -7 -3 -3 -18 -3 -4 -4 -5 -7 -3 -3 -3 -13 -5 -4 -8 -211 -5 -5 -3 -5 -2 -5 -4 -2 -655 -6 -3 -5 -11 -2 -5 -3 -12 -9 -15 -11 -5 -12 -217 -2 -6 -17 -3 -3 -207 -5 -5 -4 -5 -9 -3 -2 -8 -5 -4 -3 -2 -5 -12 -4 -14 -5 -4 -2 -13 -5 -8 -4 -225 -4 -3 -4 -5 -4 -3 -3 -6 -23 -9 -2 -6 -7 -233 -4 -4 -6 -18 -3 -4 -6 -3 -4 -4 -2 -3 -7 -4 -13 -227 -4 -3 -5 -4 -2 -12 -9 -17 -3 -7 -14 -6 -4 -5 -21 -4 -8 -9 -2 -9 -25 -16 -3 -6 -4 -7 -8 -5 -2 -3 -5 -4 -3 -3 -5 -3 -3 -3 -2 -3 -19 -2 -4 -3 -4 -2 -3 -4 -4 -2 -4 -3 -3 -3 -2 -6 -3 -17 -5 -6 -4 -3 -13 -5 -3 -3 -3 -4 -9 -4 -2 -14 -12 -4 -5 -24 -4 -3 -37 -12 -11 -21 -3 -4 -3 -13 -4 -2 -3 -15 -4 -11 -4 -4 -3 -8 -3 -4 -4 -12 -8 -5 -3 -3 -4 -2 -220 -3 -5 -223 -3 -3 -3 -10 -3 -15 -4 -241 -9 -7 -3 -6 -6 -23 -4 -13 -7 -3 -4 -7 -4 -9 -3 -3 -4 -10 -5 -5 -1 -5 -24 -2 -4 -5 -5 -6 -14 -3 -8 -2 -3 -5 -13 -13 -3 -5 -2 -3 -15 -3 -4 -2 -10 -4 -4 -4 -5 -5 -3 -5 -3 -4 -7 -4 -27 -3 -6 -4 -15 -3 -5 -6 -6 -5 -4 -8 -3 -9 -2 -6 -3 -4 -3 -7 -4 -18 -3 -11 -3 -3 -8 -9 -7 -24 -3 -219 -7 -10 -4 -5 -9 -12 -2 -5 -4 -4 -4 -3 -3 -19 -5 -8 -16 -8 -6 -22 -3 -23 -3 -242 -9 -4 -3 -3 -5 -7 -3 -3 -5 -8 -3 -7 -5 -14 -8 -10 -3 -4 -3 -7 -4 -6 -7 -4 -10 -4 -3 -11 -3 -7 -10 -3 -13 -6 -8 -12 -10 -5 -7 -9 -3 -4 -7 -7 -10 -8 -30 -9 -19 -4 -3 -19 -15 -4 -13 -3 -215 -223 -4 -7 -4 -8 -17 -16 -3 -7 -6 -5 -5 -4 -12 -3 -7 -4 -4 -13 -4 -5 -2 -5 -6 -5 -6 -6 -7 -10 -18 -23 -9 -3 -3 -6 -5 -2 -4 -2 -7 -3 -3 -2 -5 -5 -14 -10 -224 -6 -3 -4 -3 -7 -5 -9 -3 -6 -4 -2 -5 -11 -4 -3 -3 -2 -8 -4 -7 -4 -10 -7 -3 -3 -18 -18 -17 -3 -3 -3 -4 -5 -3 -3 -4 -12 -7 -3 -11 -13 -5 -4 -7 -13 -5 -4 -11 -3 -12 -3 -6 -4 -4 -21 -4 -6 -9 -5 -3 -10 -8 -4 -6 -4 -4 -6 -5 -4 -8 -6 -4 -6 -4 -4 -5 -9 -6 -3 -4 -2 -9 -3 -18 -2 -4 -3 -13 -3 -6 -6 -8 -7 -9 -3 -2 -16 -3 -4 -6 -3 -2 -33 -22 -14 -4 -9 -12 -4 -5 -6 -3 -23 -9 -4 -3 -5 -5 -3 -4 -5 -3 -5 -3 -10 -4 -5 -5 -8 -4 -4 -6 -8 -5 -4 -3 -4 -6 -3 -3 -3 -5 -9 -12 -6 -5 -9 -3 -5 -3 -2 -2 -2 -18 -3 -2 -21 -2 -5 -4 -6 -4 -5 -10 -3 -9 -3 -2 -10 -7 -3 -6 -6 -4 -4 -8 -12 -7 -3 -7 -3 -3 -9 -3 -4 -5 -4 -4 -5 -5 -10 -15 -4 -4 -14 -6 -227 -3 -14 -5 -216 -22 -5 -4 -2 -2 -6 -3 -4 -2 -9 -9 -4 -3 -28 -13 -11 -4 -5 -3 -3 -2 -3 -3 -5 -3 -4 -3 -5 -23 -26 -3 -4 -5 -6 -4 -6 -3 -5 -5 -3 -4 -3 -2 -2 -2 -7 -14 -3 -6 -7 -17 -2 -2 -15 -14 -16 -4 -6 -7 -13 -6 -4 -5 -6 -16 -3 -3 -28 -3 -6 -15 -3 -9 -2 -4 -6 -3 -3 -22 -4 -12 -6 -7 -2 -5 -4 -10 -3 -16 -6 -9 -2 -5 -12 -7 -5 -5 -5 -5 -2 -11 -9 -17 -4 -3 -11 -7 -3 -5 -15 -4 -3 -4 -211 -8 -7 -5 -4 -7 -6 -7 -6 -3 -6 -5 -6 -5 -3 -4 -4 -26 -4 -6 -10 -4 -4 -3 -2 -3 -3 -4 -5 -9 -3 -9 -4 -4 -5 -5 -8 -2 -4 -2 -3 -8 -4 -11 -19 -5 -8 -6 -3 -5 -6 -12 -3 -2 -4 -16 -12 -3 -4 -4 -8 -6 -5 -6 -6 -219 -8 -222 -6 -16 -3 -13 -19 -5 -4 -3 -11 -6 -10 -4 -7 -7 -12 -5 -3 -3 -5 -6 -10 -3 -8 -2 -5 -4 -7 -2 -4 -4 -2 -12 -9 -6 -4 -2 -40 -2 -4 -10 -4 -223 -4 -2 -20 -6 -7 -24 -5 -4 -5 -2 -20 -16 -6 -5 -13 -2 -3 -3 -19 -3 -2 -4 -5 -6 -7 -11 -12 -5 -6 -7 -7 -3 -5 -3 -5 -3 -14 -3 -4 -4 -2 -11 -1 -7 -3 -9 -6 -11 -12 -5 -8 -6 -221 -4 -2 -12 -4 -3 -15 -4 -5 -226 -7 -218 -7 -5 -4 -5 -18 -4 -5 -9 -4 -4 -2 -9 -18 -18 -9 -5 -6 -6 -3 -3 -7 -3 -5 -4 -4 -4 -12 -3 -6 -31 -5 -4 -7 -3 -6 -5 -6 -5 -11 -2 -2 -11 -11 -6 -7 -5 -8 -7 -10 -5 -23 -7 -4 -3 -5 -34 -2 -5 -23 -7 -3 -6 -8 -4 -4 -4 -2 -5 -3 -8 -5 -4 -8 -25 -2 -3 -17 -8 -3 -4 -8 -7 -3 -15 -6 -5 -7 -21 -9 -5 -6 -6 -5 -3 -2 -3 -10 -3 -6 -3 -14 -7 -4 -4 -8 -7 -8 -2 -6 -12 -4 -213 -6 -5 -21 -8 -2 -5 -23 -3 -11 -2 -3 -6 -25 -2 -3 -6 -7 -6 -6 -4 -4 -6 -3 -17 -9 -7 -6 -4 -3 -10 -7 -2 -3 -3 -3 -11 -8 -3 -7 -6 -4 -14 -36 -3 -4 -3 -3 -22 -13 -21 -4 -2 -7 -4 -4 -17 -15 -3 -7 -11 -2 -4 -7 -6 -209 -6 -3 -2 -2 -24 -4 -9 -4 -3 -3 -3 -29 -2 -2 -4 -3 -3 -5 -4 -6 -3 -3 -2 -4 diff --git a/vendor/github.com/coreos/etcd/LICENSE b/vendor/github.com/coreos/etcd/LICENSE new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/vendor/github.com/coreos/etcd/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/coreos/etcd/NOTICE b/vendor/github.com/coreos/etcd/NOTICE new file mode 100644 index 000000000..b39ddfa5c --- /dev/null +++ b/vendor/github.com/coreos/etcd/NOTICE @@ -0,0 +1,5 @@ +CoreOS Project +Copyright 2014 CoreOS, Inc + +This product includes software developed at CoreOS, Inc. +(http://www.coreos.com/). diff --git a/vendor/github.com/coreos/etcd/client/README.md b/vendor/github.com/coreos/etcd/client/README.md deleted file mode 100644 index 672b8c13f..000000000 --- a/vendor/github.com/coreos/etcd/client/README.md +++ /dev/null @@ -1,94 +0,0 @@ -# etcd/client - -etcd/client is the Go client library for etcd. - -[![GoDoc](https://godoc.org/github.com/coreos/etcd/client?status.png)](https://godoc.org/github.com/coreos/etcd/client) - -## Install - -```bash -go get github.com/coreos/etcd/client -``` - -## Usage - -```go -package main - -import ( - "log" - "time" - - "github.com/coreos/etcd/Godeps/_workspace/src/golang.org/x/net/context" - "github.com/coreos/etcd/client" -) - -func main() { - cfg := client.Config{ - Endpoints: []string{"http://127.0.0.1:2379"}, - Transport: client.DefaultTransport, - // set timeout per request to fail fast when the target endpoint is unavailable - HeaderTimeoutPerRequest: time.Second, - } - c, err := client.New(cfg) - if err != nil { - log.Fatal(err) - } - kapi := client.NewKeysAPI(c) - resp, err := kapi.Set(context.Background(), "foo", "bar", nil) - if err != nil { - log.Fatal(err) - } -} -``` - -## Error Handling - -etcd client might return three types of errors. - -- context error - -Each API call has its first parameter as `context`. A context can be canceled or have an attached deadline. If the context is canceled or reaches its deadline, the responding context error will be returned no matter what internal errors the API call has already encountered. - -- cluster error - -Each API call tries to send request to the cluster endpoints one by one until it successfully gets a response. If a requests to an endpoint fails, due to exceeding per request timeout or connection issues, the error will be added into a list of errors. If all possible endpoints fail, a cluster error that includes all encountered errors will be returned. - -- response error - -If the response gets from the cluster is invalid, a plain string error will be returned. For example, it might be a invalid JSON error. - -Here is the example code to handle client errors: - -```go -cfg := client.Config{Endpoints: []string{"http://etcd1:2379,http://etcd2:2379,http://etcd3:2379"}} -c, err := client.New(cfg) -if err != nil { - log.Fatal(err) -} - -kapi := client.NewKeysAPI(c) -resp, err := kapi.Set(ctx, "test", "bar", nil) -if err != nil { - if err == context.Canceled { - // ctx is canceled by another routine - } else if err == context.DeadlineExceeded { - // ctx is attached with a deadline and it exceeded - } else if cerr, ok := err.(*client.ClusterError); ok { - // process (cerr.Errors) - } else { - // bad cluster endpoints, which are not etcd servers - } -} -``` - - -## Caveat - -1. etcd/client prefers to use the same endpoint as long as the endpoint continues to work well. This saves socket resources, and improves efficiency for both client and server side. This preference doesn't remove consistency from the data consumed by the client because data replicated to each etcd member has already passed through the consensus process. - -2. etcd/client does round-robin rotation on other available endpoints if the preferred endpoint isn't functioning properly. For example, if the member that etcd/client connects to is hard killed, etcd/client will fail on the first attempt with the killed member, and succeed on the second attempt with another member. If it fails to talk to all available endpoints, it will return all errors happened. - -3. Default etcd/client cannot handle the case that the remote server is SIGSTOPed now. TCP keepalive mechanism doesn't help in this scenario because operating system may still send TCP keep-alive packets. Over time we'd like to improve this functionality, but solving this issue isn't high priority because a real-life case in which a server is stopped, but the connection is kept alive, hasn't been brought to our attention. - -4. etcd/client cannot detect whether the member in use is healthy when doing read requests. If the member is isolated from the cluster, etcd/client may retrieve outdated data. As a workaround, users could monitor experimental /health endpoint for member healthy information. We are improving it at [#3265](https://github.com/coreos/etcd/issues/3265). diff --git a/vendor/github.com/coreos/etcd/client/auth_role.go b/vendor/github.com/coreos/etcd/client/auth_role.go index 8de58afcf..d15e00dd7 100644 --- a/vendor/github.com/coreos/etcd/client/auth_role.go +++ b/vendor/github.com/coreos/etcd/client/auth_role.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 The etcd Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -56,22 +56,22 @@ func NewAuthRoleAPI(c Client) AuthRoleAPI { } type AuthRoleAPI interface { - // Add a role. + // AddRole adds a role. AddRole(ctx context.Context, role string) error - // Remove a role. + // RemoveRole removes a role. RemoveRole(ctx context.Context, role string) error - // Get role details. + // GetRole retrieves role details. GetRole(ctx context.Context, role string) (*Role, error) - // Grant a role some permission prefixes for the KV store. + // GrantRoleKV grants a role some permission prefixes for the KV store. GrantRoleKV(ctx context.Context, role string, prefixes []string, permType PermissionType) (*Role, error) - // Revoke some some permission prefixes for a role on the KV store. + // RevokeRoleKV revokes some permission prefixes for a role on the KV store. RevokeRoleKV(ctx context.Context, role string, prefixes []string, permType PermissionType) (*Role, error) - // List roles. + // ListRoles lists roles. ListRoles(ctx context.Context) ([]string, error) } @@ -115,17 +115,20 @@ func (r *httpAuthRoleAPI) ListRoles(ctx context.Context) ([]string, error) { if err != nil { return nil, err } - if err := assertStatusCode(resp.StatusCode, http.StatusOK); err != nil { + if err = assertStatusCode(resp.StatusCode, http.StatusOK); err != nil { return nil, err } - var userList struct { - Roles []string `json:"roles"` + var roleList struct { + Roles []Role `json:"roles"` } - err = json.Unmarshal(body, &userList) - if err != nil { + if err = json.Unmarshal(body, &roleList); err != nil { return nil, err } - return userList.Roles, nil + ret := make([]string, 0, len(roleList.Roles)) + for _, r := range roleList.Roles { + ret = append(ret, r.Role) + } + return ret, nil } func (r *httpAuthRoleAPI) AddRole(ctx context.Context, rolename string) error { @@ -218,17 +221,16 @@ func (r *httpAuthRoleAPI) modRole(ctx context.Context, req *authRoleAPIAction) ( if err != nil { return nil, err } - if err := assertStatusCode(resp.StatusCode, http.StatusOK); err != nil { + if err = assertStatusCode(resp.StatusCode, http.StatusOK); err != nil { var sec authError - err := json.Unmarshal(body, &sec) + err = json.Unmarshal(body, &sec) if err != nil { return nil, err } return nil, sec } var role Role - err = json.Unmarshal(body, &role) - if err != nil { + if err = json.Unmarshal(body, &role); err != nil { return nil, err } return &role, nil diff --git a/vendor/github.com/coreos/etcd/client/auth_user.go b/vendor/github.com/coreos/etcd/client/auth_user.go index 6e0e4c596..97c3f3181 100644 --- a/vendor/github.com/coreos/etcd/client/auth_user.go +++ b/vendor/github.com/coreos/etcd/client/auth_user.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 The etcd Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -36,6 +36,17 @@ type User struct { Revoke []string `json:"revoke,omitempty"` } +// userListEntry is the user representation given by the server for ListUsers +type userListEntry struct { + User string `json:"user"` + Roles []Role `json:"roles"` +} + +type UserRoles struct { + User string `json:"user"` + Roles []Role `json:"roles"` +} + func v2AuthURL(ep url.URL, action string, name string) *url.URL { if name != "" { ep.Path = path.Join(ep.Path, defaultV2AuthPrefix, action, name) @@ -78,9 +89,9 @@ func (s *httpAuthAPI) enableDisable(ctx context.Context, req httpAction) error { if err != nil { return err } - if err := assertStatusCode(resp.StatusCode, http.StatusOK, http.StatusCreated); err != nil { + if err = assertStatusCode(resp.StatusCode, http.StatusOK, http.StatusCreated); err != nil { var sec authError - err := json.Unmarshal(body, &sec) + err = json.Unmarshal(body, &sec) if err != nil { return err } @@ -117,25 +128,25 @@ func NewAuthUserAPI(c Client) AuthUserAPI { } type AuthUserAPI interface { - // Add a user. + // AddUser adds a user. AddUser(ctx context.Context, username string, password string) error - // Remove a user. + // RemoveUser removes a user. RemoveUser(ctx context.Context, username string) error - // Get user details. + // GetUser retrieves user details. GetUser(ctx context.Context, username string) (*User, error) - // Grant a user some permission roles. + // GrantUser grants a user some permission roles. GrantUser(ctx context.Context, username string, roles []string) (*User, error) - // Revoke some permission roles from a user. + // RevokeUser revokes some permission roles from a user. RevokeUser(ctx context.Context, username string, roles []string) (*User, error) - // Change the user's password. + // ChangePassword changes the user's password. ChangePassword(ctx context.Context, username string, password string) (*User, error) - // List users. + // ListUsers lists the users. ListUsers(ctx context.Context) ([]string, error) } @@ -179,22 +190,28 @@ func (u *httpAuthUserAPI) ListUsers(ctx context.Context) ([]string, error) { if err != nil { return nil, err } - if err := assertStatusCode(resp.StatusCode, http.StatusOK); err != nil { + if err = assertStatusCode(resp.StatusCode, http.StatusOK); err != nil { var sec authError - err := json.Unmarshal(body, &sec) + err = json.Unmarshal(body, &sec) if err != nil { return nil, err } return nil, sec } + var userList struct { - Users []string `json:"users"` + Users []userListEntry `json:"users"` } - err = json.Unmarshal(body, &userList) - if err != nil { + + if err = json.Unmarshal(body, &userList); err != nil { return nil, err } - return userList.Users, nil + + ret := make([]string, 0, len(userList.Users)) + for _, u := range userList.Users { + ret = append(ret, u.User) + } + return ret, nil } func (u *httpAuthUserAPI) AddUser(ctx context.Context, username string, password string) error { @@ -221,9 +238,9 @@ func (u *httpAuthUserAPI) addRemoveUser(ctx context.Context, req *authUserAPIAct if err != nil { return err } - if err := assertStatusCode(resp.StatusCode, http.StatusOK, http.StatusCreated); err != nil { + if err = assertStatusCode(resp.StatusCode, http.StatusOK, http.StatusCreated); err != nil { var sec authError - err := json.Unmarshal(body, &sec) + err = json.Unmarshal(body, &sec) if err != nil { return err } @@ -280,18 +297,24 @@ func (u *httpAuthUserAPI) modUser(ctx context.Context, req *authUserAPIAction) ( if err != nil { return nil, err } - if err := assertStatusCode(resp.StatusCode, http.StatusOK); err != nil { + if err = assertStatusCode(resp.StatusCode, http.StatusOK); err != nil { var sec authError - err := json.Unmarshal(body, &sec) + err = json.Unmarshal(body, &sec) if err != nil { return nil, err } return nil, sec } var user User - err = json.Unmarshal(body, &user) - if err != nil { - return nil, err + if err = json.Unmarshal(body, &user); err != nil { + var userR UserRoles + if urerr := json.Unmarshal(body, &userR); urerr != nil { + return nil, err + } + user.User = userR.User + for _, r := range userR.Roles { + user.Roles = append(user.Roles, r.Role) + } } return &user, nil } diff --git a/vendor/github.com/coreos/etcd/client/cancelreq.go b/vendor/github.com/coreos/etcd/client/cancelreq.go index fefdb40e4..76d1f0401 100644 --- a/vendor/github.com/coreos/etcd/client/cancelreq.go +++ b/vendor/github.com/coreos/etcd/client/cancelreq.go @@ -4,8 +4,6 @@ // borrowed from golang/net/context/ctxhttp/cancelreq.go -// +build go1.5 - package client import "net/http" diff --git a/vendor/github.com/coreos/etcd/client/cancelreq_go14.go b/vendor/github.com/coreos/etcd/client/cancelreq_go14.go deleted file mode 100644 index 2bed38a41..000000000 --- a/vendor/github.com/coreos/etcd/client/cancelreq_go14.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// borrowed from golang/net/context/ctxhttp/cancelreq_go14.go - -// +build !go1.5 - -package client - -import "net/http" - -func requestCanceler(tr CancelableTransport, req *http.Request) func() { - return func() { - tr.CancelRequest(req) - } -} diff --git a/vendor/github.com/coreos/etcd/client/client.go b/vendor/github.com/coreos/etcd/client/client.go index 34adb82b0..fb9c4599c 100644 --- a/vendor/github.com/coreos/etcd/client/client.go +++ b/vendor/github.com/coreos/etcd/client/client.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 The etcd Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -24,6 +24,7 @@ import ( "net/url" "reflect" "sort" + "strconv" "sync" "time" @@ -34,6 +35,7 @@ var ( ErrNoEndpoints = errors.New("client: no endpoints available") ErrTooManyRedirects = errors.New("client: too many redirects") ErrClusterUnavailable = errors.New("client: etcd cluster is unavailable or misconfigured") + ErrNoLeaderEndpoint = errors.New("client: no leader endpoint available") errTooManyRedirectChecks = errors.New("client: too many redirect checks") ) @@ -48,6 +50,29 @@ var DefaultTransport CancelableTransport = &http.Transport{ TLSHandshakeTimeout: 10 * time.Second, } +type EndpointSelectionMode int + +const ( + // EndpointSelectionRandom is the default value of the 'SelectionMode'. + // As the name implies, the client object will pick a node from the members + // of the cluster in a random fashion. If the cluster has three members, A, B, + // and C, the client picks any node from its three members as its request + // destination. + EndpointSelectionRandom EndpointSelectionMode = iota + + // If 'SelectionMode' is set to 'EndpointSelectionPrioritizeLeader', + // requests are sent directly to the cluster leader. This reduces + // forwarding roundtrips compared to making requests to etcd followers + // who then forward them to the cluster leader. In the event of a leader + // failure, however, clients configured this way cannot prioritize among + // the remaining etcd followers. Therefore, when a client sets 'SelectionMode' + // to 'EndpointSelectionPrioritizeLeader', it must use 'client.AutoSync()' to + // maintain its knowledge of current cluster state. + // + // This mode should be used with Client.AutoSync(). + EndpointSelectionPrioritizeLeader +) + type Config struct { // Endpoints defines a set of URLs (schemes, hosts and ports only) // that can be used to communicate with a logical etcd cluster. For @@ -73,7 +98,7 @@ type Config struct { // CheckRedirect specifies the policy for handling HTTP redirects. // If CheckRedirect is not nil, the Client calls it before // following an HTTP redirect. The sole argument is the number of - // requests that have alrady been made. If CheckRedirect returns + // requests that have already been made. If CheckRedirect returns // an error, Client.Do will not make any further requests and return // the error back it to the caller. // @@ -99,11 +124,17 @@ type Config struct { // watch start. But if server is behind some kind of proxy, the response // header may be cached at proxy, and Client cannot rely on this behavior. // + // Especially, wait request will ignore this timeout. + // // One API call may send multiple requests to different etcd servers until it // succeeds. Use context of the API to specify the overall timeout. // // A HeaderTimeoutPerRequest of zero means no timeout. HeaderTimeoutPerRequest time.Duration + + // SelectionMode is an EndpointSelectionMode enum that specifies the + // policy for choosing the etcd cluster node to which requests are sent. + SelectionMode EndpointSelectionMode } func (cfg *Config) transport() CancelableTransport { @@ -162,6 +193,11 @@ type Client interface { // this may differ from the initial Endpoints provided in the Config. Endpoints() []string + // SetEndpoints sets the set of API endpoints used by Client to resolve + // HTTP requests. If the given endpoints are not valid, an error will be + // returned + SetEndpoints(eps []string) error + httpClient } @@ -169,6 +205,7 @@ func New(cfg Config) (Client, error) { c := &httpClusterClient{ clientFactory: newHTTPClientFactory(cfg.transport(), cfg.checkRedirect(), cfg.HeaderTimeoutPerRequest), rand: rand.New(rand.NewSource(int64(time.Now().Nanosecond()))), + selectionMode: cfg.SelectionMode, } if cfg.Username != "" { c.credentials = &credentials{ @@ -176,7 +213,7 @@ func New(cfg Config) (Client, error) { password: cfg.Password, } } - if err := c.reset(cfg.Endpoints); err != nil { + if err := c.SetEndpoints(cfg.Endpoints); err != nil { return nil, err } return c, nil @@ -216,10 +253,21 @@ type httpClusterClient struct { pinned int credentials *credentials sync.RWMutex - rand *rand.Rand + rand *rand.Rand + selectionMode EndpointSelectionMode +} + +func (c *httpClusterClient) getLeaderEndpoint() (string, error) { + mAPI := NewMembersAPI(c) + leader, err := mAPI.Leader(context.Background()) + if err != nil { + return "", err + } + + return leader.ClientURLs[0], nil // TODO: how to handle multiple client URLs? } -func (c *httpClusterClient) reset(eps []string) error { +func (c *httpClusterClient) SetEndpoints(eps []string) error { if len(eps) == 0 { return ErrNoEndpoints } @@ -233,9 +281,28 @@ func (c *httpClusterClient) reset(eps []string) error { neps[i] = *u } - c.endpoints = shuffleEndpoints(c.rand, neps) - // TODO: pin old endpoint if possible, and rebalance when new endpoint appears - c.pinned = 0 + switch c.selectionMode { + case EndpointSelectionRandom: + c.endpoints = shuffleEndpoints(c.rand, neps) + c.pinned = 0 + case EndpointSelectionPrioritizeLeader: + c.endpoints = neps + lep, err := c.getLeaderEndpoint() + if err != nil { + return ErrNoLeaderEndpoint + } + + for i := range c.endpoints { + if c.endpoints[i].String() == lep { + c.pinned = i + break + } + } + // If endpoints doesn't have the lu, just keep c.pinned = 0. + // Forwarding between follower and leader would be required but it works. + default: + return errors.New(fmt.Sprintf("invalid endpoint selection mode: %d", c.selectionMode)) + } return nil } @@ -275,7 +342,9 @@ func (c *httpClusterClient) Do(ctx context.Context, act httpAction) (*http.Respo resp, body, err = hc.Do(ctx, action) if err != nil { cerr.Errors = append(cerr.Errors, err) - // mask previous errors with context error, which is controlled by user + if err == ctx.Err() { + return nil, nil, ctx.Err() + } if err == context.Canceled || err == context.DeadlineExceeded { return nil, nil, err } @@ -341,7 +410,7 @@ func (c *httpClusterClient) Sync(ctx context.Context) error { return nil } - return c.reset(eps) + return c.SetEndpoints(eps) } func (c *httpClusterClient) AutoSync(ctx context.Context, interval time.Duration) error { @@ -378,9 +447,24 @@ func (c *simpleHTTPClient) Do(ctx context.Context, act httpAction) (*http.Respon return nil, nil, err } - hctx, hcancel := context.WithCancel(ctx) - if c.headerTimeout > 0 { + isWait := false + if req != nil && req.URL != nil { + ws := req.URL.Query().Get("wait") + if len(ws) != 0 { + var err error + isWait, err = strconv.ParseBool(ws) + if err != nil { + return nil, nil, fmt.Errorf("wrong wait value %s (%v for %+v)", ws, err, req) + } + } + } + + var hctx context.Context + var hcancel context.CancelFunc + if !isWait && c.headerTimeout > 0 { hctx, hcancel = context.WithTimeout(ctx, c.headerTimeout) + } else { + hctx, hcancel = context.WithCancel(ctx) } defer hcancel() diff --git a/vendor/github.com/coreos/etcd/client/client_test.go b/vendor/github.com/coreos/etcd/client/client_test.go deleted file mode 100644 index b2b46d1b1..000000000 --- a/vendor/github.com/coreos/etcd/client/client_test.go +++ /dev/null @@ -1,896 +0,0 @@ -// Copyright 2015 CoreOS, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package client - -import ( - "errors" - "io" - "io/ioutil" - "math/rand" - "net/http" - "net/url" - "reflect" - "sort" - "strings" - "testing" - "time" - - "github.com/coreos/etcd/pkg/testutil" - "golang.org/x/net/context" -) - -type actionAssertingHTTPClient struct { - t *testing.T - num int - act httpAction - - resp http.Response - body []byte - err error -} - -func (a *actionAssertingHTTPClient) Do(_ context.Context, act httpAction) (*http.Response, []byte, error) { - if !reflect.DeepEqual(a.act, act) { - a.t.Errorf("#%d: unexpected httpAction: want=%#v got=%#v", a.num, a.act, act) - } - - return &a.resp, a.body, a.err -} - -type staticHTTPClient struct { - resp http.Response - body []byte - err error -} - -func (s *staticHTTPClient) Do(context.Context, httpAction) (*http.Response, []byte, error) { - return &s.resp, s.body, s.err -} - -type staticHTTPAction struct { - request http.Request -} - -func (s *staticHTTPAction) HTTPRequest(url.URL) *http.Request { - return &s.request -} - -type staticHTTPResponse struct { - resp http.Response - body []byte - err error -} - -type multiStaticHTTPClient struct { - responses []staticHTTPResponse - cur int -} - -func (s *multiStaticHTTPClient) Do(context.Context, httpAction) (*http.Response, []byte, error) { - r := s.responses[s.cur] - s.cur++ - return &r.resp, r.body, r.err -} - -func newStaticHTTPClientFactory(responses []staticHTTPResponse) httpClientFactory { - var cur int - return func(url.URL) httpClient { - r := responses[cur] - cur++ - return &staticHTTPClient{resp: r.resp, body: r.body, err: r.err} - } -} - -type fakeTransport struct { - respchan chan *http.Response - errchan chan error - startCancel chan struct{} - finishCancel chan struct{} -} - -func newFakeTransport() *fakeTransport { - return &fakeTransport{ - respchan: make(chan *http.Response, 1), - errchan: make(chan error, 1), - startCancel: make(chan struct{}, 1), - finishCancel: make(chan struct{}, 1), - } -} - -func (t *fakeTransport) CancelRequest(*http.Request) { - t.startCancel <- struct{}{} -} - -type fakeAction struct{} - -func (a *fakeAction) HTTPRequest(url.URL) *http.Request { - return &http.Request{} -} - -func TestSimpleHTTPClientDoSuccess(t *testing.T) { - tr := newFakeTransport() - c := &simpleHTTPClient{transport: tr} - - tr.respchan <- &http.Response{ - StatusCode: http.StatusTeapot, - Body: ioutil.NopCloser(strings.NewReader("foo")), - } - - resp, body, err := c.Do(context.Background(), &fakeAction{}) - if err != nil { - t.Fatalf("incorrect error value: want=nil got=%v", err) - } - - wantCode := http.StatusTeapot - if wantCode != resp.StatusCode { - t.Fatalf("invalid response code: want=%d got=%d", wantCode, resp.StatusCode) - } - - wantBody := []byte("foo") - if !reflect.DeepEqual(wantBody, body) { - t.Fatalf("invalid response body: want=%q got=%q", wantBody, body) - } -} - -func TestSimpleHTTPClientDoError(t *testing.T) { - tr := newFakeTransport() - c := &simpleHTTPClient{transport: tr} - - tr.errchan <- errors.New("fixture") - - _, _, err := c.Do(context.Background(), &fakeAction{}) - if err == nil { - t.Fatalf("expected non-nil error, got nil") - } -} - -func TestSimpleHTTPClientDoCancelContext(t *testing.T) { - tr := newFakeTransport() - c := &simpleHTTPClient{transport: tr} - - tr.startCancel <- struct{}{} - tr.finishCancel <- struct{}{} - - _, _, err := c.Do(context.Background(), &fakeAction{}) - if err == nil { - t.Fatalf("expected non-nil error, got nil") - } -} - -type checkableReadCloser struct { - io.ReadCloser - closed bool -} - -func (c *checkableReadCloser) Close() error { - if !c.closed { - c.closed = true - return c.ReadCloser.Close() - } - return nil -} - -func TestSimpleHTTPClientDoCancelContextResponseBodyClosed(t *testing.T) { - tr := newFakeTransport() - c := &simpleHTTPClient{transport: tr} - - // create an already-cancelled context - ctx, cancel := context.WithCancel(context.Background()) - cancel() - - body := &checkableReadCloser{ReadCloser: ioutil.NopCloser(strings.NewReader("foo"))} - go func() { - // wait that simpleHTTPClient knows the context is already timed out, - // and calls CancelRequest - testutil.WaitSchedule() - - // response is returned before cancel effects - tr.respchan <- &http.Response{Body: body} - }() - - _, _, err := c.Do(ctx, &fakeAction{}) - if err == nil { - t.Fatalf("expected non-nil error, got nil") - } - - if !body.closed { - t.Fatalf("expected closed body") - } -} - -type blockingBody struct { - c chan struct{} -} - -func (bb *blockingBody) Read(p []byte) (n int, err error) { - <-bb.c - return 0, errors.New("closed") -} - -func (bb *blockingBody) Close() error { - close(bb.c) - return nil -} - -func TestSimpleHTTPClientDoCancelContextResponseBodyClosedWithBlockingBody(t *testing.T) { - tr := newFakeTransport() - c := &simpleHTTPClient{transport: tr} - - ctx, cancel := context.WithCancel(context.Background()) - body := &checkableReadCloser{ReadCloser: &blockingBody{c: make(chan struct{})}} - go func() { - tr.respchan <- &http.Response{Body: body} - time.Sleep(2 * time.Millisecond) - // cancel after the body is received - cancel() - }() - - _, _, err := c.Do(ctx, &fakeAction{}) - if err != context.Canceled { - t.Fatalf("expected %+v, got %+v", context.Canceled, err) - } - - if !body.closed { - t.Fatalf("expected closed body") - } -} - -func TestSimpleHTTPClientDoCancelContextWaitForRoundTrip(t *testing.T) { - tr := newFakeTransport() - c := &simpleHTTPClient{transport: tr} - - donechan := make(chan struct{}) - ctx, cancel := context.WithCancel(context.Background()) - go func() { - c.Do(ctx, &fakeAction{}) - close(donechan) - }() - - // This should call CancelRequest and begin the cancellation process - cancel() - - select { - case <-donechan: - t.Fatalf("simpleHTTPClient.Do should not have exited yet") - default: - } - - tr.finishCancel <- struct{}{} - - select { - case <-donechan: - //expected behavior - return - case <-time.After(time.Second): - t.Fatalf("simpleHTTPClient.Do did not exit within 1s") - } -} - -func TestSimpleHTTPClientDoHeaderTimeout(t *testing.T) { - tr := newFakeTransport() - tr.finishCancel <- struct{}{} - c := &simpleHTTPClient{transport: tr, headerTimeout: time.Millisecond} - - errc := make(chan error) - go func() { - _, _, err := c.Do(context.Background(), &fakeAction{}) - errc <- err - }() - - select { - case err := <-errc: - if err == nil { - t.Fatalf("expected non-nil error, got nil") - } - case <-time.After(time.Second): - t.Fatalf("unexpected timeout when waitting for the test to finish") - } -} - -func TestHTTPClusterClientDo(t *testing.T) { - fakeErr := errors.New("fake!") - fakeURL := url.URL{} - tests := []struct { - client *httpClusterClient - wantCode int - wantErr error - wantPinned int - }{ - // first good response short-circuits Do - { - client: &httpClusterClient{ - endpoints: []url.URL{fakeURL, fakeURL}, - clientFactory: newStaticHTTPClientFactory( - []staticHTTPResponse{ - {resp: http.Response{StatusCode: http.StatusTeapot}}, - {err: fakeErr}, - }, - ), - rand: rand.New(rand.NewSource(0)), - }, - wantCode: http.StatusTeapot, - }, - - // fall through to good endpoint if err is arbitrary - { - client: &httpClusterClient{ - endpoints: []url.URL{fakeURL, fakeURL}, - clientFactory: newStaticHTTPClientFactory( - []staticHTTPResponse{ - {err: fakeErr}, - {resp: http.Response{StatusCode: http.StatusTeapot}}, - }, - ), - rand: rand.New(rand.NewSource(0)), - }, - wantCode: http.StatusTeapot, - wantPinned: 1, - }, - - // context.Canceled short-circuits Do - { - client: &httpClusterClient{ - endpoints: []url.URL{fakeURL, fakeURL}, - clientFactory: newStaticHTTPClientFactory( - []staticHTTPResponse{ - {err: context.Canceled}, - {resp: http.Response{StatusCode: http.StatusTeapot}}, - }, - ), - rand: rand.New(rand.NewSource(0)), - }, - wantErr: context.Canceled, - }, - - // return err if there are no endpoints - { - client: &httpClusterClient{ - endpoints: []url.URL{}, - clientFactory: newHTTPClientFactory(nil, nil, 0), - rand: rand.New(rand.NewSource(0)), - }, - wantErr: ErrNoEndpoints, - }, - - // return err if all endpoints return arbitrary errors - { - client: &httpClusterClient{ - endpoints: []url.URL{fakeURL, fakeURL}, - clientFactory: newStaticHTTPClientFactory( - []staticHTTPResponse{ - {err: fakeErr}, - {err: fakeErr}, - }, - ), - rand: rand.New(rand.NewSource(0)), - }, - wantErr: &ClusterError{Errors: []error{fakeErr, fakeErr}}, - }, - - // 500-level errors cause Do to fallthrough to next endpoint - { - client: &httpClusterClient{ - endpoints: []url.URL{fakeURL, fakeURL}, - clientFactory: newStaticHTTPClientFactory( - []staticHTTPResponse{ - {resp: http.Response{StatusCode: http.StatusBadGateway}}, - {resp: http.Response{StatusCode: http.StatusTeapot}}, - }, - ), - rand: rand.New(rand.NewSource(0)), - }, - wantCode: http.StatusTeapot, - wantPinned: 1, - }, - } - - for i, tt := range tests { - resp, _, err := tt.client.Do(context.Background(), nil) - if !reflect.DeepEqual(tt.wantErr, err) { - t.Errorf("#%d: got err=%v, want=%v", i, err, tt.wantErr) - continue - } - - if resp == nil { - if tt.wantCode != 0 { - t.Errorf("#%d: resp is nil, want=%d", i, tt.wantCode) - } - continue - } - - if resp.StatusCode != tt.wantCode { - t.Errorf("#%d: resp code=%d, want=%d", i, resp.StatusCode, tt.wantCode) - continue - } - - if tt.client.pinned != tt.wantPinned { - t.Errorf("#%d: pinned=%d, want=%d", i, tt.client.pinned, tt.wantPinned) - } - } -} - -func TestHTTPClusterClientDoDeadlineExceedContext(t *testing.T) { - fakeURL := url.URL{} - tr := newFakeTransport() - tr.finishCancel <- struct{}{} - c := &httpClusterClient{ - clientFactory: newHTTPClientFactory(tr, DefaultCheckRedirect, 0), - endpoints: []url.URL{fakeURL}, - } - - errc := make(chan error) - go func() { - ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond) - defer cancel() - _, _, err := c.Do(ctx, &fakeAction{}) - errc <- err - }() - - select { - case err := <-errc: - if err != context.DeadlineExceeded { - t.Errorf("err = %+v, want %+v", err, context.DeadlineExceeded) - } - case <-time.After(time.Second): - t.Fatalf("unexpected timeout when waitting for request to deadline exceed") - } -} - -func TestRedirectedHTTPAction(t *testing.T) { - act := &redirectedHTTPAction{ - action: &staticHTTPAction{ - request: http.Request{ - Method: "DELETE", - URL: &url.URL{ - Scheme: "https", - Host: "foo.example.com", - Path: "/ping", - }, - }, - }, - location: url.URL{ - Scheme: "https", - Host: "bar.example.com", - Path: "/pong", - }, - } - - want := &http.Request{ - Method: "DELETE", - URL: &url.URL{ - Scheme: "https", - Host: "bar.example.com", - Path: "/pong", - }, - } - got := act.HTTPRequest(url.URL{Scheme: "http", Host: "baz.example.com", Path: "/pang"}) - - if !reflect.DeepEqual(want, got) { - t.Fatalf("HTTPRequest is %#v, want %#v", want, got) - } -} - -func TestRedirectFollowingHTTPClient(t *testing.T) { - tests := []struct { - checkRedirect CheckRedirectFunc - client httpClient - wantCode int - wantErr error - }{ - // errors bubbled up - { - checkRedirect: func(int) error { return ErrTooManyRedirects }, - client: &multiStaticHTTPClient{ - responses: []staticHTTPResponse{ - { - err: errors.New("fail!"), - }, - }, - }, - wantErr: errors.New("fail!"), - }, - - // no need to follow redirect if none given - { - checkRedirect: func(int) error { return ErrTooManyRedirects }, - client: &multiStaticHTTPClient{ - responses: []staticHTTPResponse{ - { - resp: http.Response{ - StatusCode: http.StatusTeapot, - }, - }, - }, - }, - wantCode: http.StatusTeapot, - }, - - // redirects if less than max - { - checkRedirect: func(via int) error { - if via >= 2 { - return ErrTooManyRedirects - } - return nil - }, - client: &multiStaticHTTPClient{ - responses: []staticHTTPResponse{ - { - resp: http.Response{ - StatusCode: http.StatusTemporaryRedirect, - Header: http.Header{"Location": []string{"http://example.com"}}, - }, - }, - { - resp: http.Response{ - StatusCode: http.StatusTeapot, - }, - }, - }, - }, - wantCode: http.StatusTeapot, - }, - - // succeed after reaching max redirects - { - checkRedirect: func(via int) error { - if via >= 3 { - return ErrTooManyRedirects - } - return nil - }, - client: &multiStaticHTTPClient{ - responses: []staticHTTPResponse{ - { - resp: http.Response{ - StatusCode: http.StatusTemporaryRedirect, - Header: http.Header{"Location": []string{"http://example.com"}}, - }, - }, - { - resp: http.Response{ - StatusCode: http.StatusTemporaryRedirect, - Header: http.Header{"Location": []string{"http://example.com"}}, - }, - }, - { - resp: http.Response{ - StatusCode: http.StatusTeapot, - }, - }, - }, - }, - wantCode: http.StatusTeapot, - }, - - // fail if too many redirects - { - checkRedirect: func(via int) error { - if via >= 2 { - return ErrTooManyRedirects - } - return nil - }, - client: &multiStaticHTTPClient{ - responses: []staticHTTPResponse{ - { - resp: http.Response{ - StatusCode: http.StatusTemporaryRedirect, - Header: http.Header{"Location": []string{"http://example.com"}}, - }, - }, - { - resp: http.Response{ - StatusCode: http.StatusTemporaryRedirect, - Header: http.Header{"Location": []string{"http://example.com"}}, - }, - }, - { - resp: http.Response{ - StatusCode: http.StatusTeapot, - }, - }, - }, - }, - wantErr: ErrTooManyRedirects, - }, - - // fail if Location header not set - { - checkRedirect: func(int) error { return ErrTooManyRedirects }, - client: &multiStaticHTTPClient{ - responses: []staticHTTPResponse{ - { - resp: http.Response{ - StatusCode: http.StatusTemporaryRedirect, - }, - }, - }, - }, - wantErr: errors.New("Location header not set"), - }, - - // fail if Location header is invalid - { - checkRedirect: func(int) error { return ErrTooManyRedirects }, - client: &multiStaticHTTPClient{ - responses: []staticHTTPResponse{ - { - resp: http.Response{ - StatusCode: http.StatusTemporaryRedirect, - Header: http.Header{"Location": []string{":"}}, - }, - }, - }, - }, - wantErr: errors.New("Location header not valid URL: :"), - }, - - // fail if redirects checked way too many times - { - checkRedirect: func(int) error { return nil }, - client: &staticHTTPClient{ - resp: http.Response{ - StatusCode: http.StatusTemporaryRedirect, - Header: http.Header{"Location": []string{"http://example.com"}}, - }, - }, - wantErr: errTooManyRedirectChecks, - }, - } - - for i, tt := range tests { - client := &redirectFollowingHTTPClient{client: tt.client, checkRedirect: tt.checkRedirect} - resp, _, err := client.Do(context.Background(), nil) - if !reflect.DeepEqual(tt.wantErr, err) { - t.Errorf("#%d: got err=%v, want=%v", i, err, tt.wantErr) - continue - } - - if resp == nil { - if tt.wantCode != 0 { - t.Errorf("#%d: resp is nil, want=%d", i, tt.wantCode) - } - continue - } - - if resp.StatusCode != tt.wantCode { - t.Errorf("#%d: resp code=%d, want=%d", i, resp.StatusCode, tt.wantCode) - continue - } - } -} - -func TestDefaultCheckRedirect(t *testing.T) { - tests := []struct { - num int - err error - }{ - {0, nil}, - {5, nil}, - {10, nil}, - {11, ErrTooManyRedirects}, - {29, ErrTooManyRedirects}, - } - - for i, tt := range tests { - err := DefaultCheckRedirect(tt.num) - if !reflect.DeepEqual(tt.err, err) { - t.Errorf("#%d: want=%#v got=%#v", i, tt.err, err) - } - } -} - -func TestHTTPClusterClientSync(t *testing.T) { - cf := newStaticHTTPClientFactory([]staticHTTPResponse{ - { - resp: http.Response{StatusCode: http.StatusOK, Header: http.Header{"Content-Type": []string{"application/json"}}}, - body: []byte(`{"members":[{"id":"2745e2525fce8fe","peerURLs":["http://127.0.0.1:7003"],"name":"node3","clientURLs":["http://127.0.0.1:4003"]},{"id":"42134f434382925","peerURLs":["http://127.0.0.1:2380","http://127.0.0.1:7001"],"name":"node1","clientURLs":["http://127.0.0.1:2379","http://127.0.0.1:4001"]},{"id":"94088180e21eb87b","peerURLs":["http://127.0.0.1:7002"],"name":"node2","clientURLs":["http://127.0.0.1:4002"]}]}`), - }, - }) - - hc := &httpClusterClient{ - clientFactory: cf, - rand: rand.New(rand.NewSource(0)), - } - err := hc.reset([]string{"http://127.0.0.1:2379"}) - if err != nil { - t.Fatalf("unexpected error during setup: %#v", err) - } - - want := []string{"http://127.0.0.1:2379"} - got := hc.Endpoints() - if !reflect.DeepEqual(want, got) { - t.Fatalf("incorrect endpoints: want=%#v got=%#v", want, got) - } - - err = hc.Sync(context.Background()) - if err != nil { - t.Fatalf("unexpected error during Sync: %#v", err) - } - - want = []string{"http://127.0.0.1:2379", "http://127.0.0.1:4001", "http://127.0.0.1:4002", "http://127.0.0.1:4003"} - got = hc.Endpoints() - sort.Sort(sort.StringSlice(got)) - if !reflect.DeepEqual(want, got) { - t.Fatalf("incorrect endpoints post-Sync: want=%#v got=%#v", want, got) - } - - err = hc.reset([]string{"http://127.0.0.1:4009"}) - if err != nil { - t.Fatalf("unexpected error during reset: %#v", err) - } - - want = []string{"http://127.0.0.1:4009"} - got = hc.Endpoints() - if !reflect.DeepEqual(want, got) { - t.Fatalf("incorrect endpoints post-reset: want=%#v got=%#v", want, got) - } -} - -func TestHTTPClusterClientSyncFail(t *testing.T) { - cf := newStaticHTTPClientFactory([]staticHTTPResponse{ - {err: errors.New("fail!")}, - }) - - hc := &httpClusterClient{ - clientFactory: cf, - rand: rand.New(rand.NewSource(0)), - } - err := hc.reset([]string{"http://127.0.0.1:2379"}) - if err != nil { - t.Fatalf("unexpected error during setup: %#v", err) - } - - want := []string{"http://127.0.0.1:2379"} - got := hc.Endpoints() - if !reflect.DeepEqual(want, got) { - t.Fatalf("incorrect endpoints: want=%#v got=%#v", want, got) - } - - err = hc.Sync(context.Background()) - if err == nil { - t.Fatalf("got nil error during Sync") - } - - got = hc.Endpoints() - if !reflect.DeepEqual(want, got) { - t.Fatalf("incorrect endpoints after failed Sync: want=%#v got=%#v", want, got) - } -} - -func TestHTTPClusterClientAutoSyncCancelContext(t *testing.T) { - cf := newStaticHTTPClientFactory([]staticHTTPResponse{ - { - resp: http.Response{StatusCode: http.StatusOK, Header: http.Header{"Content-Type": []string{"application/json"}}}, - body: []byte(`{"members":[{"id":"2745e2525fce8fe","peerURLs":["http://127.0.0.1:7003"],"name":"node3","clientURLs":["http://127.0.0.1:4003"]},{"id":"42134f434382925","peerURLs":["http://127.0.0.1:2380","http://127.0.0.1:7001"],"name":"node1","clientURLs":["http://127.0.0.1:2379","http://127.0.0.1:4001"]},{"id":"94088180e21eb87b","peerURLs":["http://127.0.0.1:7002"],"name":"node2","clientURLs":["http://127.0.0.1:4002"]}]}`), - }, - }) - - hc := &httpClusterClient{ - clientFactory: cf, - rand: rand.New(rand.NewSource(0)), - } - err := hc.reset([]string{"http://127.0.0.1:2379"}) - if err != nil { - t.Fatalf("unexpected error during setup: %#v", err) - } - ctx, cancel := context.WithCancel(context.Background()) - cancel() - - err = hc.AutoSync(ctx, time.Hour) - if err != context.Canceled { - t.Fatalf("incorrect error value: want=%v got=%v", context.Canceled, err) - } -} - -func TestHTTPClusterClientAutoSyncFail(t *testing.T) { - cf := newStaticHTTPClientFactory([]staticHTTPResponse{ - {err: errors.New("fail!")}, - }) - - hc := &httpClusterClient{ - clientFactory: cf, - rand: rand.New(rand.NewSource(0)), - } - err := hc.reset([]string{"http://127.0.0.1:2379"}) - if err != nil { - t.Fatalf("unexpected error during setup: %#v", err) - } - - err = hc.AutoSync(context.Background(), time.Hour) - if err.Error() != ErrClusterUnavailable.Error() { - t.Fatalf("incorrect error value: want=%v got=%v", ErrClusterUnavailable, err) - } -} - -// TestHTTPClusterClientSyncPinEndpoint tests that Sync() pins the endpoint when -// it gets the exactly same member list as before. -func TestHTTPClusterClientSyncPinEndpoint(t *testing.T) { - cf := newStaticHTTPClientFactory([]staticHTTPResponse{ - { - resp: http.Response{StatusCode: http.StatusOK, Header: http.Header{"Content-Type": []string{"application/json"}}}, - body: []byte(`{"members":[{"id":"2745e2525fce8fe","peerURLs":["http://127.0.0.1:7003"],"name":"node3","clientURLs":["http://127.0.0.1:4003"]},{"id":"42134f434382925","peerURLs":["http://127.0.0.1:2380","http://127.0.0.1:7001"],"name":"node1","clientURLs":["http://127.0.0.1:2379","http://127.0.0.1:4001"]},{"id":"94088180e21eb87b","peerURLs":["http://127.0.0.1:7002"],"name":"node2","clientURLs":["http://127.0.0.1:4002"]}]}`), - }, - { - resp: http.Response{StatusCode: http.StatusOK, Header: http.Header{"Content-Type": []string{"application/json"}}}, - body: []byte(`{"members":[{"id":"2745e2525fce8fe","peerURLs":["http://127.0.0.1:7003"],"name":"node3","clientURLs":["http://127.0.0.1:4003"]},{"id":"42134f434382925","peerURLs":["http://127.0.0.1:2380","http://127.0.0.1:7001"],"name":"node1","clientURLs":["http://127.0.0.1:2379","http://127.0.0.1:4001"]},{"id":"94088180e21eb87b","peerURLs":["http://127.0.0.1:7002"],"name":"node2","clientURLs":["http://127.0.0.1:4002"]}]}`), - }, - { - resp: http.Response{StatusCode: http.StatusOK, Header: http.Header{"Content-Type": []string{"application/json"}}}, - body: []byte(`{"members":[{"id":"2745e2525fce8fe","peerURLs":["http://127.0.0.1:7003"],"name":"node3","clientURLs":["http://127.0.0.1:4003"]},{"id":"42134f434382925","peerURLs":["http://127.0.0.1:2380","http://127.0.0.1:7001"],"name":"node1","clientURLs":["http://127.0.0.1:2379","http://127.0.0.1:4001"]},{"id":"94088180e21eb87b","peerURLs":["http://127.0.0.1:7002"],"name":"node2","clientURLs":["http://127.0.0.1:4002"]}]}`), - }, - }) - - hc := &httpClusterClient{ - clientFactory: cf, - rand: rand.New(rand.NewSource(0)), - } - err := hc.reset([]string{"http://127.0.0.1:4003", "http://127.0.0.1:2379", "http://127.0.0.1:4001", "http://127.0.0.1:4002"}) - if err != nil { - t.Fatalf("unexpected error during setup: %#v", err) - } - pinnedEndpoint := hc.endpoints[hc.pinned] - - for i := 0; i < 3; i++ { - err = hc.Sync(context.Background()) - if err != nil { - t.Fatalf("#%d: unexpected error during Sync: %#v", i, err) - } - - if g := hc.endpoints[hc.pinned]; g != pinnedEndpoint { - t.Errorf("#%d: pinned endpoint = %s, want %s", i, g, pinnedEndpoint) - } - } -} - -func TestHTTPClusterClientResetFail(t *testing.T) { - tests := [][]string{ - // need at least one endpoint - {}, - - // urls must be valid - {":"}, - } - - for i, tt := range tests { - hc := &httpClusterClient{rand: rand.New(rand.NewSource(0))} - err := hc.reset(tt) - if err == nil { - t.Errorf("#%d: expected non-nil error", i) - } - } -} - -func TestHTTPClusterClientResetPinRandom(t *testing.T) { - round := 2000 - pinNum := 0 - for i := 0; i < round; i++ { - hc := &httpClusterClient{rand: rand.New(rand.NewSource(int64(i)))} - err := hc.reset([]string{"http://127.0.0.1:4001", "http://127.0.0.1:4002", "http://127.0.0.1:4003"}) - if err != nil { - t.Fatalf("#%d: reset error (%v)", i, err) - } - if hc.endpoints[hc.pinned].String() == "http://127.0.0.1:4001" { - pinNum++ - } - } - - min := 1.0/3.0 - 0.05 - max := 1.0/3.0 + 0.05 - if ratio := float64(pinNum) / float64(round); ratio > max || ratio < min { - t.Errorf("pinned ratio = %v, want [%v, %v]", ratio, min, max) - } -} diff --git a/vendor/github.com/coreos/etcd/client/cluster_error.go b/vendor/github.com/coreos/etcd/client/cluster_error.go index 957ed4624..aef5bf755 100644 --- a/vendor/github.com/coreos/etcd/client/cluster_error.go +++ b/vendor/github.com/coreos/etcd/client/cluster_error.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 The etcd Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/vendor/github.com/coreos/etcd/client/curl.go b/vendor/github.com/coreos/etcd/client/curl.go index 5a5a69a94..c8bc9fba2 100644 --- a/vendor/github.com/coreos/etcd/client/curl.go +++ b/vendor/github.com/coreos/etcd/client/curl.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 The etcd Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/vendor/github.com/coreos/etcd/client/discover.go b/vendor/github.com/coreos/etcd/client/discover.go index 269491c8d..bfd7aec93 100644 --- a/vendor/github.com/coreos/etcd/client/discover.go +++ b/vendor/github.com/coreos/etcd/client/discover.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 The etcd Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -16,6 +16,6 @@ package client // Discoverer is an interface that wraps the Discover method. type Discoverer interface { - // Dicover looks up the etcd servers for the domain. + // Discover looks up the etcd servers for the domain. Discover(domain string) ([]string, error) } diff --git a/vendor/github.com/coreos/etcd/client/doc.go b/vendor/github.com/coreos/etcd/client/doc.go index 70111cace..32fdfb52c 100644 --- a/vendor/github.com/coreos/etcd/client/doc.go +++ b/vendor/github.com/coreos/etcd/client/doc.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 The etcd Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -34,6 +34,8 @@ Create a Config and exchange it for a Client: // handle error } +Clients are safe for concurrent use by multiple goroutines. + Create a KeysAPI using the Client, then use it to interact with etcd: kAPI := client.NewKeysAPI(c) diff --git a/vendor/github.com/coreos/etcd/client/fake_transport_go14_test.go b/vendor/github.com/coreos/etcd/client/fake_transport_go14_test.go deleted file mode 100644 index 4a99a7d37..000000000 --- a/vendor/github.com/coreos/etcd/client/fake_transport_go14_test.go +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2015 CoreOS, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// +build !go1.5 - -package client - -import ( - "errors" - "net/http" -) - -func (t *fakeTransport) RoundTrip(req *http.Request) (*http.Response, error) { - select { - case resp := <-t.respchan: - return resp, nil - case err := <-t.errchan: - return nil, err - case <-t.startCancel: - select { - // this simulates that the request is finished before cancel effects - case resp := <-t.respchan: - return resp, nil - // wait on finishCancel to simulate taking some amount of - // time while calling CancelRequest - case <-t.finishCancel: - return nil, errors.New("cancelled") - } - } -} diff --git a/vendor/github.com/coreos/etcd/client/fake_transport_test.go b/vendor/github.com/coreos/etcd/client/fake_transport_test.go deleted file mode 100644 index 06761e266..000000000 --- a/vendor/github.com/coreos/etcd/client/fake_transport_test.go +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2015 CoreOS, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// +build go1.5 - -package client - -import ( - "errors" - "net/http" -) - -func (t *fakeTransport) RoundTrip(req *http.Request) (*http.Response, error) { - select { - case resp := <-t.respchan: - return resp, nil - case err := <-t.errchan: - return nil, err - case <-t.startCancel: - case <-req.Cancel: - } - select { - // this simulates that the request is finished before cancel effects - case resp := <-t.respchan: - return resp, nil - // wait on finishCancel to simulate taking some amount of - // time while calling CancelRequest - case <-t.finishCancel: - return nil, errors.New("cancelled") - } -} diff --git a/vendor/github.com/coreos/etcd/client/keys.generated.go b/vendor/github.com/coreos/etcd/client/keys.generated.go new file mode 100644 index 000000000..748283aa9 --- /dev/null +++ b/vendor/github.com/coreos/etcd/client/keys.generated.go @@ -0,0 +1,1000 @@ +// ************************************************************ +// DO NOT EDIT. +// THIS FILE IS AUTO-GENERATED BY codecgen. +// ************************************************************ + +package client + +import ( + "errors" + "fmt" + codec1978 "github.com/ugorji/go/codec" + "reflect" + "runtime" + time "time" +) + +const ( + // ----- content types ---- + codecSelferC_UTF81819 = 1 + codecSelferC_RAW1819 = 0 + // ----- value types used ---- + codecSelferValueTypeArray1819 = 10 + codecSelferValueTypeMap1819 = 9 + // ----- containerStateValues ---- + codecSelfer_containerMapKey1819 = 2 + codecSelfer_containerMapValue1819 = 3 + codecSelfer_containerMapEnd1819 = 4 + codecSelfer_containerArrayElem1819 = 6 + codecSelfer_containerArrayEnd1819 = 7 +) + +var ( + codecSelferBitsize1819 = uint8(reflect.TypeOf(uint(0)).Bits()) + codecSelferOnlyMapOrArrayEncodeToStructErr1819 = errors.New(`only encoded map or array can be decoded into a struct`) +) + +type codecSelfer1819 struct{} + +func init() { + if codec1978.GenVersion != 5 { + _, file, _, _ := runtime.Caller(0) + err := fmt.Errorf("codecgen version mismatch: current: %v, need %v. Re-generate file: %v", + 5, codec1978.GenVersion, file) + panic(err) + } + if false { // reference the types, but skip this branch at build/run time + var v0 time.Time + _ = v0 + } +} + +func (x *Response) CodecEncodeSelf(e *codec1978.Encoder) { + var h codecSelfer1819 + z, r := codec1978.GenHelperEncoder(e) + _, _, _ = h, z, r + if x == nil { + r.EncodeNil() + } else { + yym1 := z.EncBinary() + _ = yym1 + if false { + } else if z.HasExtensions() && z.EncExt(x) { + } else { + yysep2 := !z.EncBinary() + yy2arr2 := z.EncBasicHandle().StructToArray + var yyq2 [3]bool + _, _, _ = yysep2, yyq2, yy2arr2 + const yyr2 bool = false + var yynn2 int + if yyr2 || yy2arr2 { + r.EncodeArrayStart(3) + } else { + yynn2 = 3 + for _, b := range yyq2 { + if b { + yynn2++ + } + } + r.EncodeMapStart(yynn2) + yynn2 = 0 + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1819) + yym4 := z.EncBinary() + _ = yym4 + if false { + } else { + r.EncodeString(codecSelferC_UTF81819, string(x.Action)) + } + } else { + z.EncSendContainerState(codecSelfer_containerMapKey1819) + r.EncodeString(codecSelferC_UTF81819, string("action")) + z.EncSendContainerState(codecSelfer_containerMapValue1819) + yym5 := z.EncBinary() + _ = yym5 + if false { + } else { + r.EncodeString(codecSelferC_UTF81819, string(x.Action)) + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1819) + if x.Node == nil { + r.EncodeNil() + } else { + x.Node.CodecEncodeSelf(e) + } + } else { + z.EncSendContainerState(codecSelfer_containerMapKey1819) + r.EncodeString(codecSelferC_UTF81819, string("node")) + z.EncSendContainerState(codecSelfer_containerMapValue1819) + if x.Node == nil { + r.EncodeNil() + } else { + x.Node.CodecEncodeSelf(e) + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1819) + if x.PrevNode == nil { + r.EncodeNil() + } else { + x.PrevNode.CodecEncodeSelf(e) + } + } else { + z.EncSendContainerState(codecSelfer_containerMapKey1819) + r.EncodeString(codecSelferC_UTF81819, string("prevNode")) + z.EncSendContainerState(codecSelfer_containerMapValue1819) + if x.PrevNode == nil { + r.EncodeNil() + } else { + x.PrevNode.CodecEncodeSelf(e) + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayEnd1819) + } else { + z.EncSendContainerState(codecSelfer_containerMapEnd1819) + } + } + } +} + +func (x *Response) CodecDecodeSelf(d *codec1978.Decoder) { + var h codecSelfer1819 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + yym8 := z.DecBinary() + _ = yym8 + if false { + } else if z.HasExtensions() && z.DecExt(x) { + } else { + yyct9 := r.ContainerType() + if yyct9 == codecSelferValueTypeMap1819 { + yyl9 := r.ReadMapStart() + if yyl9 == 0 { + z.DecSendContainerState(codecSelfer_containerMapEnd1819) + } else { + x.codecDecodeSelfFromMap(yyl9, d) + } + } else if yyct9 == codecSelferValueTypeArray1819 { + yyl9 := r.ReadArrayStart() + if yyl9 == 0 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1819) + } else { + x.codecDecodeSelfFromArray(yyl9, d) + } + } else { + panic(codecSelferOnlyMapOrArrayEncodeToStructErr1819) + } + } +} + +func (x *Response) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { + var h codecSelfer1819 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + var yys10Slc = z.DecScratchBuffer() // default slice to decode into + _ = yys10Slc + var yyhl10 bool = l >= 0 + for yyj10 := 0; ; yyj10++ { + if yyhl10 { + if yyj10 >= l { + break + } + } else { + if r.CheckBreak() { + break + } + } + z.DecSendContainerState(codecSelfer_containerMapKey1819) + yys10Slc = r.DecodeBytes(yys10Slc, true, true) + yys10 := string(yys10Slc) + z.DecSendContainerState(codecSelfer_containerMapValue1819) + switch yys10 { + case "action": + if r.TryDecodeAsNil() { + x.Action = "" + } else { + x.Action = string(r.DecodeString()) + } + case "node": + if r.TryDecodeAsNil() { + if x.Node != nil { + x.Node = nil + } + } else { + if x.Node == nil { + x.Node = new(Node) + } + x.Node.CodecDecodeSelf(d) + } + case "prevNode": + if r.TryDecodeAsNil() { + if x.PrevNode != nil { + x.PrevNode = nil + } + } else { + if x.PrevNode == nil { + x.PrevNode = new(Node) + } + x.PrevNode.CodecDecodeSelf(d) + } + default: + z.DecStructFieldNotFound(-1, yys10) + } // end switch yys10 + } // end for yyj10 + z.DecSendContainerState(codecSelfer_containerMapEnd1819) +} + +func (x *Response) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { + var h codecSelfer1819 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + var yyj14 int + var yyb14 bool + var yyhl14 bool = l >= 0 + yyj14++ + if yyhl14 { + yyb14 = yyj14 > l + } else { + yyb14 = r.CheckBreak() + } + if yyb14 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1819) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1819) + if r.TryDecodeAsNil() { + x.Action = "" + } else { + x.Action = string(r.DecodeString()) + } + yyj14++ + if yyhl14 { + yyb14 = yyj14 > l + } else { + yyb14 = r.CheckBreak() + } + if yyb14 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1819) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1819) + if r.TryDecodeAsNil() { + if x.Node != nil { + x.Node = nil + } + } else { + if x.Node == nil { + x.Node = new(Node) + } + x.Node.CodecDecodeSelf(d) + } + yyj14++ + if yyhl14 { + yyb14 = yyj14 > l + } else { + yyb14 = r.CheckBreak() + } + if yyb14 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1819) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1819) + if r.TryDecodeAsNil() { + if x.PrevNode != nil { + x.PrevNode = nil + } + } else { + if x.PrevNode == nil { + x.PrevNode = new(Node) + } + x.PrevNode.CodecDecodeSelf(d) + } + for { + yyj14++ + if yyhl14 { + yyb14 = yyj14 > l + } else { + yyb14 = r.CheckBreak() + } + if yyb14 { + break + } + z.DecSendContainerState(codecSelfer_containerArrayElem1819) + z.DecStructFieldNotFound(yyj14-1, "") + } + z.DecSendContainerState(codecSelfer_containerArrayEnd1819) +} + +func (x *Node) CodecEncodeSelf(e *codec1978.Encoder) { + var h codecSelfer1819 + z, r := codec1978.GenHelperEncoder(e) + _, _, _ = h, z, r + if x == nil { + r.EncodeNil() + } else { + yym18 := z.EncBinary() + _ = yym18 + if false { + } else if z.HasExtensions() && z.EncExt(x) { + } else { + yysep19 := !z.EncBinary() + yy2arr19 := z.EncBasicHandle().StructToArray + var yyq19 [8]bool + _, _, _ = yysep19, yyq19, yy2arr19 + const yyr19 bool = false + yyq19[1] = x.Dir != false + yyq19[6] = x.Expiration != nil + yyq19[7] = x.TTL != 0 + var yynn19 int + if yyr19 || yy2arr19 { + r.EncodeArrayStart(8) + } else { + yynn19 = 5 + for _, b := range yyq19 { + if b { + yynn19++ + } + } + r.EncodeMapStart(yynn19) + yynn19 = 0 + } + if yyr19 || yy2arr19 { + z.EncSendContainerState(codecSelfer_containerArrayElem1819) + yym21 := z.EncBinary() + _ = yym21 + if false { + } else { + r.EncodeString(codecSelferC_UTF81819, string(x.Key)) + } + } else { + z.EncSendContainerState(codecSelfer_containerMapKey1819) + r.EncodeString(codecSelferC_UTF81819, string("key")) + z.EncSendContainerState(codecSelfer_containerMapValue1819) + yym22 := z.EncBinary() + _ = yym22 + if false { + } else { + r.EncodeString(codecSelferC_UTF81819, string(x.Key)) + } + } + if yyr19 || yy2arr19 { + z.EncSendContainerState(codecSelfer_containerArrayElem1819) + if yyq19[1] { + yym24 := z.EncBinary() + _ = yym24 + if false { + } else { + r.EncodeBool(bool(x.Dir)) + } + } else { + r.EncodeBool(false) + } + } else { + if yyq19[1] { + z.EncSendContainerState(codecSelfer_containerMapKey1819) + r.EncodeString(codecSelferC_UTF81819, string("dir")) + z.EncSendContainerState(codecSelfer_containerMapValue1819) + yym25 := z.EncBinary() + _ = yym25 + if false { + } else { + r.EncodeBool(bool(x.Dir)) + } + } + } + if yyr19 || yy2arr19 { + z.EncSendContainerState(codecSelfer_containerArrayElem1819) + yym27 := z.EncBinary() + _ = yym27 + if false { + } else { + r.EncodeString(codecSelferC_UTF81819, string(x.Value)) + } + } else { + z.EncSendContainerState(codecSelfer_containerMapKey1819) + r.EncodeString(codecSelferC_UTF81819, string("value")) + z.EncSendContainerState(codecSelfer_containerMapValue1819) + yym28 := z.EncBinary() + _ = yym28 + if false { + } else { + r.EncodeString(codecSelferC_UTF81819, string(x.Value)) + } + } + if yyr19 || yy2arr19 { + z.EncSendContainerState(codecSelfer_containerArrayElem1819) + if x.Nodes == nil { + r.EncodeNil() + } else { + x.Nodes.CodecEncodeSelf(e) + } + } else { + z.EncSendContainerState(codecSelfer_containerMapKey1819) + r.EncodeString(codecSelferC_UTF81819, string("nodes")) + z.EncSendContainerState(codecSelfer_containerMapValue1819) + if x.Nodes == nil { + r.EncodeNil() + } else { + x.Nodes.CodecEncodeSelf(e) + } + } + if yyr19 || yy2arr19 { + z.EncSendContainerState(codecSelfer_containerArrayElem1819) + yym31 := z.EncBinary() + _ = yym31 + if false { + } else { + r.EncodeUint(uint64(x.CreatedIndex)) + } + } else { + z.EncSendContainerState(codecSelfer_containerMapKey1819) + r.EncodeString(codecSelferC_UTF81819, string("createdIndex")) + z.EncSendContainerState(codecSelfer_containerMapValue1819) + yym32 := z.EncBinary() + _ = yym32 + if false { + } else { + r.EncodeUint(uint64(x.CreatedIndex)) + } + } + if yyr19 || yy2arr19 { + z.EncSendContainerState(codecSelfer_containerArrayElem1819) + yym34 := z.EncBinary() + _ = yym34 + if false { + } else { + r.EncodeUint(uint64(x.ModifiedIndex)) + } + } else { + z.EncSendContainerState(codecSelfer_containerMapKey1819) + r.EncodeString(codecSelferC_UTF81819, string("modifiedIndex")) + z.EncSendContainerState(codecSelfer_containerMapValue1819) + yym35 := z.EncBinary() + _ = yym35 + if false { + } else { + r.EncodeUint(uint64(x.ModifiedIndex)) + } + } + if yyr19 || yy2arr19 { + z.EncSendContainerState(codecSelfer_containerArrayElem1819) + if yyq19[6] { + if x.Expiration == nil { + r.EncodeNil() + } else { + yym37 := z.EncBinary() + _ = yym37 + if false { + } else if yym38 := z.TimeRtidIfBinc(); yym38 != 0 { + r.EncodeBuiltin(yym38, x.Expiration) + } else if z.HasExtensions() && z.EncExt(x.Expiration) { + } else if yym37 { + z.EncBinaryMarshal(x.Expiration) + } else if !yym37 && z.IsJSONHandle() { + z.EncJSONMarshal(x.Expiration) + } else { + z.EncFallback(x.Expiration) + } + } + } else { + r.EncodeNil() + } + } else { + if yyq19[6] { + z.EncSendContainerState(codecSelfer_containerMapKey1819) + r.EncodeString(codecSelferC_UTF81819, string("expiration")) + z.EncSendContainerState(codecSelfer_containerMapValue1819) + if x.Expiration == nil { + r.EncodeNil() + } else { + yym39 := z.EncBinary() + _ = yym39 + if false { + } else if yym40 := z.TimeRtidIfBinc(); yym40 != 0 { + r.EncodeBuiltin(yym40, x.Expiration) + } else if z.HasExtensions() && z.EncExt(x.Expiration) { + } else if yym39 { + z.EncBinaryMarshal(x.Expiration) + } else if !yym39 && z.IsJSONHandle() { + z.EncJSONMarshal(x.Expiration) + } else { + z.EncFallback(x.Expiration) + } + } + } + } + if yyr19 || yy2arr19 { + z.EncSendContainerState(codecSelfer_containerArrayElem1819) + if yyq19[7] { + yym42 := z.EncBinary() + _ = yym42 + if false { + } else { + r.EncodeInt(int64(x.TTL)) + } + } else { + r.EncodeInt(0) + } + } else { + if yyq19[7] { + z.EncSendContainerState(codecSelfer_containerMapKey1819) + r.EncodeString(codecSelferC_UTF81819, string("ttl")) + z.EncSendContainerState(codecSelfer_containerMapValue1819) + yym43 := z.EncBinary() + _ = yym43 + if false { + } else { + r.EncodeInt(int64(x.TTL)) + } + } + } + if yyr19 || yy2arr19 { + z.EncSendContainerState(codecSelfer_containerArrayEnd1819) + } else { + z.EncSendContainerState(codecSelfer_containerMapEnd1819) + } + } + } +} + +func (x *Node) CodecDecodeSelf(d *codec1978.Decoder) { + var h codecSelfer1819 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + yym44 := z.DecBinary() + _ = yym44 + if false { + } else if z.HasExtensions() && z.DecExt(x) { + } else { + yyct45 := r.ContainerType() + if yyct45 == codecSelferValueTypeMap1819 { + yyl45 := r.ReadMapStart() + if yyl45 == 0 { + z.DecSendContainerState(codecSelfer_containerMapEnd1819) + } else { + x.codecDecodeSelfFromMap(yyl45, d) + } + } else if yyct45 == codecSelferValueTypeArray1819 { + yyl45 := r.ReadArrayStart() + if yyl45 == 0 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1819) + } else { + x.codecDecodeSelfFromArray(yyl45, d) + } + } else { + panic(codecSelferOnlyMapOrArrayEncodeToStructErr1819) + } + } +} + +func (x *Node) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { + var h codecSelfer1819 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + var yys46Slc = z.DecScratchBuffer() // default slice to decode into + _ = yys46Slc + var yyhl46 bool = l >= 0 + for yyj46 := 0; ; yyj46++ { + if yyhl46 { + if yyj46 >= l { + break + } + } else { + if r.CheckBreak() { + break + } + } + z.DecSendContainerState(codecSelfer_containerMapKey1819) + yys46Slc = r.DecodeBytes(yys46Slc, true, true) + yys46 := string(yys46Slc) + z.DecSendContainerState(codecSelfer_containerMapValue1819) + switch yys46 { + case "key": + if r.TryDecodeAsNil() { + x.Key = "" + } else { + x.Key = string(r.DecodeString()) + } + case "dir": + if r.TryDecodeAsNil() { + x.Dir = false + } else { + x.Dir = bool(r.DecodeBool()) + } + case "value": + if r.TryDecodeAsNil() { + x.Value = "" + } else { + x.Value = string(r.DecodeString()) + } + case "nodes": + if r.TryDecodeAsNil() { + x.Nodes = nil + } else { + yyv50 := &x.Nodes + yyv50.CodecDecodeSelf(d) + } + case "createdIndex": + if r.TryDecodeAsNil() { + x.CreatedIndex = 0 + } else { + x.CreatedIndex = uint64(r.DecodeUint(64)) + } + case "modifiedIndex": + if r.TryDecodeAsNil() { + x.ModifiedIndex = 0 + } else { + x.ModifiedIndex = uint64(r.DecodeUint(64)) + } + case "expiration": + if r.TryDecodeAsNil() { + if x.Expiration != nil { + x.Expiration = nil + } + } else { + if x.Expiration == nil { + x.Expiration = new(time.Time) + } + yym54 := z.DecBinary() + _ = yym54 + if false { + } else if yym55 := z.TimeRtidIfBinc(); yym55 != 0 { + r.DecodeBuiltin(yym55, x.Expiration) + } else if z.HasExtensions() && z.DecExt(x.Expiration) { + } else if yym54 { + z.DecBinaryUnmarshal(x.Expiration) + } else if !yym54 && z.IsJSONHandle() { + z.DecJSONUnmarshal(x.Expiration) + } else { + z.DecFallback(x.Expiration, false) + } + } + case "ttl": + if r.TryDecodeAsNil() { + x.TTL = 0 + } else { + x.TTL = int64(r.DecodeInt(64)) + } + default: + z.DecStructFieldNotFound(-1, yys46) + } // end switch yys46 + } // end for yyj46 + z.DecSendContainerState(codecSelfer_containerMapEnd1819) +} + +func (x *Node) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { + var h codecSelfer1819 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + var yyj57 int + var yyb57 bool + var yyhl57 bool = l >= 0 + yyj57++ + if yyhl57 { + yyb57 = yyj57 > l + } else { + yyb57 = r.CheckBreak() + } + if yyb57 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1819) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1819) + if r.TryDecodeAsNil() { + x.Key = "" + } else { + x.Key = string(r.DecodeString()) + } + yyj57++ + if yyhl57 { + yyb57 = yyj57 > l + } else { + yyb57 = r.CheckBreak() + } + if yyb57 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1819) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1819) + if r.TryDecodeAsNil() { + x.Dir = false + } else { + x.Dir = bool(r.DecodeBool()) + } + yyj57++ + if yyhl57 { + yyb57 = yyj57 > l + } else { + yyb57 = r.CheckBreak() + } + if yyb57 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1819) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1819) + if r.TryDecodeAsNil() { + x.Value = "" + } else { + x.Value = string(r.DecodeString()) + } + yyj57++ + if yyhl57 { + yyb57 = yyj57 > l + } else { + yyb57 = r.CheckBreak() + } + if yyb57 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1819) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1819) + if r.TryDecodeAsNil() { + x.Nodes = nil + } else { + yyv61 := &x.Nodes + yyv61.CodecDecodeSelf(d) + } + yyj57++ + if yyhl57 { + yyb57 = yyj57 > l + } else { + yyb57 = r.CheckBreak() + } + if yyb57 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1819) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1819) + if r.TryDecodeAsNil() { + x.CreatedIndex = 0 + } else { + x.CreatedIndex = uint64(r.DecodeUint(64)) + } + yyj57++ + if yyhl57 { + yyb57 = yyj57 > l + } else { + yyb57 = r.CheckBreak() + } + if yyb57 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1819) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1819) + if r.TryDecodeAsNil() { + x.ModifiedIndex = 0 + } else { + x.ModifiedIndex = uint64(r.DecodeUint(64)) + } + yyj57++ + if yyhl57 { + yyb57 = yyj57 > l + } else { + yyb57 = r.CheckBreak() + } + if yyb57 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1819) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1819) + if r.TryDecodeAsNil() { + if x.Expiration != nil { + x.Expiration = nil + } + } else { + if x.Expiration == nil { + x.Expiration = new(time.Time) + } + yym65 := z.DecBinary() + _ = yym65 + if false { + } else if yym66 := z.TimeRtidIfBinc(); yym66 != 0 { + r.DecodeBuiltin(yym66, x.Expiration) + } else if z.HasExtensions() && z.DecExt(x.Expiration) { + } else if yym65 { + z.DecBinaryUnmarshal(x.Expiration) + } else if !yym65 && z.IsJSONHandle() { + z.DecJSONUnmarshal(x.Expiration) + } else { + z.DecFallback(x.Expiration, false) + } + } + yyj57++ + if yyhl57 { + yyb57 = yyj57 > l + } else { + yyb57 = r.CheckBreak() + } + if yyb57 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1819) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1819) + if r.TryDecodeAsNil() { + x.TTL = 0 + } else { + x.TTL = int64(r.DecodeInt(64)) + } + for { + yyj57++ + if yyhl57 { + yyb57 = yyj57 > l + } else { + yyb57 = r.CheckBreak() + } + if yyb57 { + break + } + z.DecSendContainerState(codecSelfer_containerArrayElem1819) + z.DecStructFieldNotFound(yyj57-1, "") + } + z.DecSendContainerState(codecSelfer_containerArrayEnd1819) +} + +func (x Nodes) CodecEncodeSelf(e *codec1978.Encoder) { + var h codecSelfer1819 + z, r := codec1978.GenHelperEncoder(e) + _, _, _ = h, z, r + if x == nil { + r.EncodeNil() + } else { + yym68 := z.EncBinary() + _ = yym68 + if false { + } else if z.HasExtensions() && z.EncExt(x) { + } else { + h.encNodes((Nodes)(x), e) + } + } +} + +func (x *Nodes) CodecDecodeSelf(d *codec1978.Decoder) { + var h codecSelfer1819 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + yym69 := z.DecBinary() + _ = yym69 + if false { + } else if z.HasExtensions() && z.DecExt(x) { + } else { + h.decNodes((*Nodes)(x), d) + } +} + +func (x codecSelfer1819) encNodes(v Nodes, e *codec1978.Encoder) { + var h codecSelfer1819 + z, r := codec1978.GenHelperEncoder(e) + _, _, _ = h, z, r + r.EncodeArrayStart(len(v)) + for _, yyv70 := range v { + z.EncSendContainerState(codecSelfer_containerArrayElem1819) + if yyv70 == nil { + r.EncodeNil() + } else { + yyv70.CodecEncodeSelf(e) + } + } + z.EncSendContainerState(codecSelfer_containerArrayEnd1819) +} + +func (x codecSelfer1819) decNodes(v *Nodes, d *codec1978.Decoder) { + var h codecSelfer1819 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + + yyv71 := *v + yyh71, yyl71 := z.DecSliceHelperStart() + var yyc71 bool + if yyl71 == 0 { + if yyv71 == nil { + yyv71 = []*Node{} + yyc71 = true + } else if len(yyv71) != 0 { + yyv71 = yyv71[:0] + yyc71 = true + } + } else if yyl71 > 0 { + var yyrr71, yyrl71 int + var yyrt71 bool + if yyl71 > cap(yyv71) { + + yyrg71 := len(yyv71) > 0 + yyv271 := yyv71 + yyrl71, yyrt71 = z.DecInferLen(yyl71, z.DecBasicHandle().MaxInitLen, 8) + if yyrt71 { + if yyrl71 <= cap(yyv71) { + yyv71 = yyv71[:yyrl71] + } else { + yyv71 = make([]*Node, yyrl71) + } + } else { + yyv71 = make([]*Node, yyrl71) + } + yyc71 = true + yyrr71 = len(yyv71) + if yyrg71 { + copy(yyv71, yyv271) + } + } else if yyl71 != len(yyv71) { + yyv71 = yyv71[:yyl71] + yyc71 = true + } + yyj71 := 0 + for ; yyj71 < yyrr71; yyj71++ { + yyh71.ElemContainerState(yyj71) + if r.TryDecodeAsNil() { + if yyv71[yyj71] != nil { + *yyv71[yyj71] = Node{} + } + } else { + if yyv71[yyj71] == nil { + yyv71[yyj71] = new(Node) + } + yyw72 := yyv71[yyj71] + yyw72.CodecDecodeSelf(d) + } + + } + if yyrt71 { + for ; yyj71 < yyl71; yyj71++ { + yyv71 = append(yyv71, nil) + yyh71.ElemContainerState(yyj71) + if r.TryDecodeAsNil() { + if yyv71[yyj71] != nil { + *yyv71[yyj71] = Node{} + } + } else { + if yyv71[yyj71] == nil { + yyv71[yyj71] = new(Node) + } + yyw73 := yyv71[yyj71] + yyw73.CodecDecodeSelf(d) + } + + } + } + + } else { + yyj71 := 0 + for ; !r.CheckBreak(); yyj71++ { + + if yyj71 >= len(yyv71) { + yyv71 = append(yyv71, nil) // var yyz71 *Node + yyc71 = true + } + yyh71.ElemContainerState(yyj71) + if yyj71 < len(yyv71) { + if r.TryDecodeAsNil() { + if yyv71[yyj71] != nil { + *yyv71[yyj71] = Node{} + } + } else { + if yyv71[yyj71] == nil { + yyv71[yyj71] = new(Node) + } + yyw74 := yyv71[yyj71] + yyw74.CodecDecodeSelf(d) + } + + } else { + z.DecSwallow() + } + + } + if yyj71 < len(yyv71) { + yyv71 = yyv71[:yyj71] + yyc71 = true + } else if yyj71 == 0 && yyv71 == nil { + yyv71 = []*Node{} + yyc71 = true + } + } + yyh71.End() + if yyc71 { + *v = yyv71 + } +} diff --git a/vendor/github.com/coreos/etcd/client/keys.go b/vendor/github.com/coreos/etcd/client/keys.go index f1a41ace5..5c7a3d57d 100644 --- a/vendor/github.com/coreos/etcd/client/keys.go +++ b/vendor/github.com/coreos/etcd/client/keys.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 The etcd Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,6 +14,8 @@ package client +//go:generate codecgen -d 1819 -r "Node|Response|Nodes" -o keys.generated.go keys.go + import ( "encoding/json" "errors" @@ -25,6 +27,7 @@ import ( "time" "github.com/coreos/etcd/pkg/pathutil" + "github.com/ugorji/go/codec" "golang.org/x/net/context" ) @@ -103,7 +106,7 @@ type KeysAPI interface { // Set assigns a new value to a Node identified by a given key. The caller // may define a set of conditions in the SetOptions. If SetOptions.Dir=true - // than value is ignored. + // then value is ignored. Set(ctx context.Context, key, value string, opts *SetOptions) (*Response, error) // Delete removes a Node identified by the given key, optionally destroying @@ -181,6 +184,11 @@ type SetOptions struct { // a TTL of 0. TTL time.Duration + // Refresh set to true means a TTL value can be updated + // without firing a watch or changing the node value. A + // value must not be provided when refreshing a key. + Refresh bool + // Dir specifies whether or not this Node should be created as a directory. Dir bool } @@ -231,7 +239,7 @@ type DeleteOptions struct { type Watcher interface { // Next blocks until an etcd event occurs, then returns a Response - // represeting that event. The behavior of Next depends on the + // representing that event. The behavior of Next depends on the // WatcherOptions used to construct the Watcher. Next is designed to // be called repeatedly, each time blocking until a subsequent event // is available. @@ -276,7 +284,7 @@ type Node struct { // Nodes holds the children of this Node, only if this Node is a directory. // This slice of will be arbitrarily deep (children, grandchildren, great- // grandchildren, etc.) if a recursive Get or Watch request were made. - Nodes []*Node `json:"nodes"` + Nodes Nodes `json:"nodes"` // CreatedIndex is the etcd index at-which this Node was created. CreatedIndex uint64 `json:"createdIndex"` @@ -300,6 +308,14 @@ func (n *Node) TTLDuration() time.Duration { return time.Duration(n.TTL) * time.Second } +type Nodes []*Node + +// interfaces for sorting + +func (ns Nodes) Len() int { return len(ns) } +func (ns Nodes) Less(i, j int) bool { return ns[i].Key < ns[j].Key } +func (ns Nodes) Swap(i, j int) { ns[i], ns[j] = ns[j], ns[i] } + type httpKeysAPI struct { client httpClient prefix string @@ -317,6 +333,7 @@ func (k *httpKeysAPI) Set(ctx context.Context, key, val string, opts *SetOptions act.PrevIndex = opts.PrevIndex act.PrevExist = opts.PrevExist act.TTL = opts.TTL + act.Refresh = opts.Refresh act.Dir = opts.Dir } @@ -508,6 +525,7 @@ type setAction struct { PrevIndex uint64 PrevExist PrevExistType TTL time.Duration + Refresh bool Dir bool } @@ -539,6 +557,10 @@ func (a *setAction) HTTPRequest(ep url.URL) *http.Request { form.Add("ttl", strconv.FormatUint(uint64(a.TTL.Seconds()), 10)) } + if a.Refresh { + form.Add("refresh", "true") + } + u.RawQuery = params.Encode() body := strings.NewReader(form.Encode()) @@ -619,7 +641,7 @@ func unmarshalHTTPResponse(code int, header http.Header, body []byte) (res *Resp func unmarshalSuccessfulKeysResponse(header http.Header, body []byte) (*Response, error) { var res Response - err := json.Unmarshal(body, &res) + err := codec.NewDecoderBytes(body, new(codec.JsonHandle)).Decode(&res) if err != nil { return nil, ErrInvalidJSON } diff --git a/vendor/github.com/coreos/etcd/client/keys_test.go b/vendor/github.com/coreos/etcd/client/keys_test.go deleted file mode 100644 index 80d7a554c..000000000 --- a/vendor/github.com/coreos/etcd/client/keys_test.go +++ /dev/null @@ -1,1407 +0,0 @@ -// Copyright 2015 CoreOS, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package client - -import ( - "errors" - "fmt" - "io/ioutil" - "net/http" - "net/url" - "reflect" - "testing" - "time" - - "golang.org/x/net/context" -) - -func TestV2KeysURLHelper(t *testing.T) { - tests := []struct { - endpoint url.URL - prefix string - key string - want url.URL - }{ - // key is empty, no problem - { - endpoint: url.URL{Scheme: "http", Host: "example.com", Path: "/v2/keys"}, - prefix: "", - key: "", - want: url.URL{Scheme: "http", Host: "example.com", Path: "/v2/keys"}, - }, - - // key is joined to path - { - endpoint: url.URL{Scheme: "http", Host: "example.com", Path: "/v2/keys"}, - prefix: "", - key: "/foo/bar", - want: url.URL{Scheme: "http", Host: "example.com", Path: "/v2/keys/foo/bar"}, - }, - - // key is joined to path when path is empty - { - endpoint: url.URL{Scheme: "http", Host: "example.com", Path: ""}, - prefix: "", - key: "/foo/bar", - want: url.URL{Scheme: "http", Host: "example.com", Path: "/foo/bar"}, - }, - - // Host field carries through with port - { - endpoint: url.URL{Scheme: "http", Host: "example.com:8080", Path: "/v2/keys"}, - prefix: "", - key: "", - want: url.URL{Scheme: "http", Host: "example.com:8080", Path: "/v2/keys"}, - }, - - // Scheme carries through - { - endpoint: url.URL{Scheme: "https", Host: "example.com", Path: "/v2/keys"}, - prefix: "", - key: "", - want: url.URL{Scheme: "https", Host: "example.com", Path: "/v2/keys"}, - }, - // Prefix is applied - { - endpoint: url.URL{Scheme: "https", Host: "example.com", Path: "/foo"}, - prefix: "/bar", - key: "/baz", - want: url.URL{Scheme: "https", Host: "example.com", Path: "/foo/bar/baz"}, - }, - // Prefix is joined to path - { - endpoint: url.URL{Scheme: "https", Host: "example.com", Path: "/foo"}, - prefix: "/bar", - key: "", - want: url.URL{Scheme: "https", Host: "example.com", Path: "/foo/bar"}, - }, - // Keep trailing slash - { - endpoint: url.URL{Scheme: "https", Host: "example.com", Path: "/foo"}, - prefix: "/bar", - key: "/baz/", - want: url.URL{Scheme: "https", Host: "example.com", Path: "/foo/bar/baz/"}, - }, - } - - for i, tt := range tests { - got := v2KeysURL(tt.endpoint, tt.prefix, tt.key) - if tt.want != *got { - t.Errorf("#%d: want=%#v, got=%#v", i, tt.want, *got) - } - } -} - -func TestGetAction(t *testing.T) { - ep := url.URL{Scheme: "http", Host: "example.com", Path: "/v2/keys"} - baseWantURL := &url.URL{ - Scheme: "http", - Host: "example.com", - Path: "/v2/keys/foo/bar", - } - wantHeader := http.Header{} - - tests := []struct { - recursive bool - sorted bool - quorum bool - wantQuery string - }{ - { - recursive: false, - sorted: false, - quorum: false, - wantQuery: "quorum=false&recursive=false&sorted=false", - }, - { - recursive: true, - sorted: false, - quorum: false, - wantQuery: "quorum=false&recursive=true&sorted=false", - }, - { - recursive: false, - sorted: true, - quorum: false, - wantQuery: "quorum=false&recursive=false&sorted=true", - }, - { - recursive: true, - sorted: true, - quorum: false, - wantQuery: "quorum=false&recursive=true&sorted=true", - }, - { - recursive: false, - sorted: false, - quorum: true, - wantQuery: "quorum=true&recursive=false&sorted=false", - }, - } - - for i, tt := range tests { - f := getAction{ - Key: "/foo/bar", - Recursive: tt.recursive, - Sorted: tt.sorted, - Quorum: tt.quorum, - } - got := *f.HTTPRequest(ep) - - wantURL := baseWantURL - wantURL.RawQuery = tt.wantQuery - - err := assertRequest(got, "GET", wantURL, wantHeader, nil) - if err != nil { - t.Errorf("#%d: %v", i, err) - } - } -} - -func TestWaitAction(t *testing.T) { - ep := url.URL{Scheme: "http", Host: "example.com", Path: "/v2/keys"} - baseWantURL := &url.URL{ - Scheme: "http", - Host: "example.com", - Path: "/v2/keys/foo/bar", - } - wantHeader := http.Header{} - - tests := []struct { - waitIndex uint64 - recursive bool - wantQuery string - }{ - { - recursive: false, - waitIndex: uint64(0), - wantQuery: "recursive=false&wait=true&waitIndex=0", - }, - { - recursive: false, - waitIndex: uint64(12), - wantQuery: "recursive=false&wait=true&waitIndex=12", - }, - { - recursive: true, - waitIndex: uint64(12), - wantQuery: "recursive=true&wait=true&waitIndex=12", - }, - } - - for i, tt := range tests { - f := waitAction{ - Key: "/foo/bar", - WaitIndex: tt.waitIndex, - Recursive: tt.recursive, - } - got := *f.HTTPRequest(ep) - - wantURL := baseWantURL - wantURL.RawQuery = tt.wantQuery - - err := assertRequest(got, "GET", wantURL, wantHeader, nil) - if err != nil { - t.Errorf("#%d: unexpected error: %#v", i, err) - } - } -} - -func TestSetAction(t *testing.T) { - wantHeader := http.Header(map[string][]string{ - "Content-Type": {"application/x-www-form-urlencoded"}, - }) - - tests := []struct { - act setAction - wantURL string - wantBody string - }{ - // default prefix - { - act: setAction{ - Prefix: defaultV2KeysPrefix, - Key: "foo", - }, - wantURL: "http://example.com/v2/keys/foo", - wantBody: "value=", - }, - - // non-default prefix - { - act: setAction{ - Prefix: "/pfx", - Key: "foo", - }, - wantURL: "http://example.com/pfx/foo", - wantBody: "value=", - }, - - // no prefix - { - act: setAction{ - Key: "foo", - }, - wantURL: "http://example.com/foo", - wantBody: "value=", - }, - - // Key with path separators - { - act: setAction{ - Prefix: defaultV2KeysPrefix, - Key: "foo/bar/baz", - }, - wantURL: "http://example.com/v2/keys/foo/bar/baz", - wantBody: "value=", - }, - - // Key with leading slash, Prefix with trailing slash - { - act: setAction{ - Prefix: "/foo/", - Key: "/bar", - }, - wantURL: "http://example.com/foo/bar", - wantBody: "value=", - }, - - // Key with trailing slash - { - act: setAction{ - Key: "/foo/", - }, - wantURL: "http://example.com/foo/", - wantBody: "value=", - }, - - // Value is set - { - act: setAction{ - Key: "foo", - Value: "baz", - }, - wantURL: "http://example.com/foo", - wantBody: "value=baz", - }, - - // PrevExist set, but still ignored - { - act: setAction{ - Key: "foo", - PrevExist: PrevIgnore, - }, - wantURL: "http://example.com/foo", - wantBody: "value=", - }, - - // PrevExist set to true - { - act: setAction{ - Key: "foo", - PrevExist: PrevExist, - }, - wantURL: "http://example.com/foo?prevExist=true", - wantBody: "value=", - }, - - // PrevExist set to false - { - act: setAction{ - Key: "foo", - PrevExist: PrevNoExist, - }, - wantURL: "http://example.com/foo?prevExist=false", - wantBody: "value=", - }, - - // PrevValue is urlencoded - { - act: setAction{ - Key: "foo", - PrevValue: "bar baz", - }, - wantURL: "http://example.com/foo?prevValue=bar+baz", - wantBody: "value=", - }, - - // PrevIndex is set - { - act: setAction{ - Key: "foo", - PrevIndex: uint64(12), - }, - wantURL: "http://example.com/foo?prevIndex=12", - wantBody: "value=", - }, - - // TTL is set - { - act: setAction{ - Key: "foo", - TTL: 3 * time.Minute, - }, - wantURL: "http://example.com/foo", - wantBody: "ttl=180&value=", - }, - // Dir is set - { - act: setAction{ - Key: "foo", - Dir: true, - }, - wantURL: "http://example.com/foo?dir=true", - wantBody: "", - }, - // Dir is set with a value - { - act: setAction{ - Key: "foo", - Value: "bar", - Dir: true, - }, - wantURL: "http://example.com/foo?dir=true", - wantBody: "", - }, - // Dir is set with PrevExist set to true - { - act: setAction{ - Key: "foo", - PrevExist: PrevExist, - Dir: true, - }, - wantURL: "http://example.com/foo?dir=true&prevExist=true", - wantBody: "", - }, - // Dir is set with PrevValue - { - act: setAction{ - Key: "foo", - PrevValue: "bar", - Dir: true, - }, - wantURL: "http://example.com/foo?dir=true", - wantBody: "", - }, - } - - for i, tt := range tests { - u, err := url.Parse(tt.wantURL) - if err != nil { - t.Errorf("#%d: unable to use wantURL fixture: %v", i, err) - } - - got := tt.act.HTTPRequest(url.URL{Scheme: "http", Host: "example.com"}) - if err := assertRequest(*got, "PUT", u, wantHeader, []byte(tt.wantBody)); err != nil { - t.Errorf("#%d: %v", i, err) - } - } -} - -func TestCreateInOrderAction(t *testing.T) { - wantHeader := http.Header(map[string][]string{ - "Content-Type": {"application/x-www-form-urlencoded"}, - }) - - tests := []struct { - act createInOrderAction - wantURL string - wantBody string - }{ - // default prefix - { - act: createInOrderAction{ - Prefix: defaultV2KeysPrefix, - Dir: "foo", - }, - wantURL: "http://example.com/v2/keys/foo", - wantBody: "value=", - }, - - // non-default prefix - { - act: createInOrderAction{ - Prefix: "/pfx", - Dir: "foo", - }, - wantURL: "http://example.com/pfx/foo", - wantBody: "value=", - }, - - // no prefix - { - act: createInOrderAction{ - Dir: "foo", - }, - wantURL: "http://example.com/foo", - wantBody: "value=", - }, - - // Key with path separators - { - act: createInOrderAction{ - Prefix: defaultV2KeysPrefix, - Dir: "foo/bar/baz", - }, - wantURL: "http://example.com/v2/keys/foo/bar/baz", - wantBody: "value=", - }, - - // Key with leading slash, Prefix with trailing slash - { - act: createInOrderAction{ - Prefix: "/foo/", - Dir: "/bar", - }, - wantURL: "http://example.com/foo/bar", - wantBody: "value=", - }, - - // Key with trailing slash - { - act: createInOrderAction{ - Dir: "/foo/", - }, - wantURL: "http://example.com/foo/", - wantBody: "value=", - }, - - // Value is set - { - act: createInOrderAction{ - Dir: "foo", - Value: "baz", - }, - wantURL: "http://example.com/foo", - wantBody: "value=baz", - }, - // TTL is set - { - act: createInOrderAction{ - Dir: "foo", - TTL: 3 * time.Minute, - }, - wantURL: "http://example.com/foo", - wantBody: "ttl=180&value=", - }, - } - - for i, tt := range tests { - u, err := url.Parse(tt.wantURL) - if err != nil { - t.Errorf("#%d: unable to use wantURL fixture: %v", i, err) - } - - got := tt.act.HTTPRequest(url.URL{Scheme: "http", Host: "example.com"}) - if err := assertRequest(*got, "POST", u, wantHeader, []byte(tt.wantBody)); err != nil { - t.Errorf("#%d: %v", i, err) - } - } -} - -func TestDeleteAction(t *testing.T) { - wantHeader := http.Header(map[string][]string{ - "Content-Type": {"application/x-www-form-urlencoded"}, - }) - - tests := []struct { - act deleteAction - wantURL string - }{ - // default prefix - { - act: deleteAction{ - Prefix: defaultV2KeysPrefix, - Key: "foo", - }, - wantURL: "http://example.com/v2/keys/foo", - }, - - // non-default prefix - { - act: deleteAction{ - Prefix: "/pfx", - Key: "foo", - }, - wantURL: "http://example.com/pfx/foo", - }, - - // no prefix - { - act: deleteAction{ - Key: "foo", - }, - wantURL: "http://example.com/foo", - }, - - // Key with path separators - { - act: deleteAction{ - Prefix: defaultV2KeysPrefix, - Key: "foo/bar/baz", - }, - wantURL: "http://example.com/v2/keys/foo/bar/baz", - }, - - // Key with leading slash, Prefix with trailing slash - { - act: deleteAction{ - Prefix: "/foo/", - Key: "/bar", - }, - wantURL: "http://example.com/foo/bar", - }, - - // Key with trailing slash - { - act: deleteAction{ - Key: "/foo/", - }, - wantURL: "http://example.com/foo/", - }, - - // Recursive set to true - { - act: deleteAction{ - Key: "foo", - Recursive: true, - }, - wantURL: "http://example.com/foo?recursive=true", - }, - - // PrevValue is urlencoded - { - act: deleteAction{ - Key: "foo", - PrevValue: "bar baz", - }, - wantURL: "http://example.com/foo?prevValue=bar+baz", - }, - - // PrevIndex is set - { - act: deleteAction{ - Key: "foo", - PrevIndex: uint64(12), - }, - wantURL: "http://example.com/foo?prevIndex=12", - }, - } - - for i, tt := range tests { - u, err := url.Parse(tt.wantURL) - if err != nil { - t.Errorf("#%d: unable to use wantURL fixture: %v", i, err) - } - - got := tt.act.HTTPRequest(url.URL{Scheme: "http", Host: "example.com"}) - if err := assertRequest(*got, "DELETE", u, wantHeader, nil); err != nil { - t.Errorf("#%d: %v", i, err) - } - } -} - -func assertRequest(got http.Request, wantMethod string, wantURL *url.URL, wantHeader http.Header, wantBody []byte) error { - if wantMethod != got.Method { - return fmt.Errorf("want.Method=%#v got.Method=%#v", wantMethod, got.Method) - } - - if !reflect.DeepEqual(wantURL, got.URL) { - return fmt.Errorf("want.URL=%#v got.URL=%#v", wantURL, got.URL) - } - - if !reflect.DeepEqual(wantHeader, got.Header) { - return fmt.Errorf("want.Header=%#v got.Header=%#v", wantHeader, got.Header) - } - - if got.Body == nil { - if wantBody != nil { - return fmt.Errorf("want.Body=%v got.Body=%v", wantBody, got.Body) - } - } else { - if wantBody == nil { - return fmt.Errorf("want.Body=%v got.Body=%s", wantBody, got.Body) - } else { - gotBytes, err := ioutil.ReadAll(got.Body) - if err != nil { - return err - } - - if !reflect.DeepEqual(wantBody, gotBytes) { - return fmt.Errorf("want.Body=%s got.Body=%s", wantBody, gotBytes) - } - } - } - - return nil -} - -func TestUnmarshalSuccessfulResponse(t *testing.T) { - var expiration time.Time - expiration.UnmarshalText([]byte("2015-04-07T04:40:23.044979686Z")) - - tests := []struct { - hdr string - body string - wantRes *Response - wantErr bool - }{ - // Neither PrevNode or Node - { - hdr: "1", - body: `{"action":"delete"}`, - wantRes: &Response{Action: "delete", Index: 1}, - wantErr: false, - }, - - // PrevNode - { - hdr: "15", - body: `{"action":"delete", "prevNode": {"key": "/foo", "value": "bar", "modifiedIndex": 12, "createdIndex": 10}}`, - wantRes: &Response{ - Action: "delete", - Index: 15, - Node: nil, - PrevNode: &Node{ - Key: "/foo", - Value: "bar", - ModifiedIndex: 12, - CreatedIndex: 10, - }, - }, - wantErr: false, - }, - - // Node - { - hdr: "15", - body: `{"action":"get", "node": {"key": "/foo", "value": "bar", "modifiedIndex": 12, "createdIndex": 10, "ttl": 10, "expiration": "2015-04-07T04:40:23.044979686Z"}}`, - wantRes: &Response{ - Action: "get", - Index: 15, - Node: &Node{ - Key: "/foo", - Value: "bar", - ModifiedIndex: 12, - CreatedIndex: 10, - TTL: 10, - Expiration: &expiration, - }, - PrevNode: nil, - }, - wantErr: false, - }, - - // Node Dir - { - hdr: "15", - body: `{"action":"get", "node": {"key": "/foo", "dir": true, "modifiedIndex": 12, "createdIndex": 10}}`, - wantRes: &Response{ - Action: "get", - Index: 15, - Node: &Node{ - Key: "/foo", - Dir: true, - ModifiedIndex: 12, - CreatedIndex: 10, - }, - PrevNode: nil, - }, - wantErr: false, - }, - - // PrevNode and Node - { - hdr: "15", - body: `{"action":"update", "prevNode": {"key": "/foo", "value": "baz", "modifiedIndex": 10, "createdIndex": 10}, "node": {"key": "/foo", "value": "bar", "modifiedIndex": 12, "createdIndex": 10}}`, - wantRes: &Response{ - Action: "update", - Index: 15, - PrevNode: &Node{ - Key: "/foo", - Value: "baz", - ModifiedIndex: 10, - CreatedIndex: 10, - }, - Node: &Node{ - Key: "/foo", - Value: "bar", - ModifiedIndex: 12, - CreatedIndex: 10, - }, - }, - wantErr: false, - }, - - // Garbage in body - { - hdr: "", - body: `garbage`, - wantRes: nil, - wantErr: true, - }, - - // non-integer index - { - hdr: "poo", - body: `{}`, - wantRes: nil, - wantErr: true, - }, - } - - for i, tt := range tests { - h := make(http.Header) - h.Add("X-Etcd-Index", tt.hdr) - res, err := unmarshalSuccessfulKeysResponse(h, []byte(tt.body)) - if tt.wantErr != (err != nil) { - t.Errorf("#%d: wantErr=%t, err=%v", i, tt.wantErr, err) - } - - if (res == nil) != (tt.wantRes == nil) { - t.Errorf("#%d: received res=%#v, but expected res=%#v", i, res, tt.wantRes) - continue - } else if tt.wantRes == nil { - // expected and successfully got nil response - continue - } - - if res.Action != tt.wantRes.Action { - t.Errorf("#%d: Action=%s, expected %s", i, res.Action, tt.wantRes.Action) - } - if res.Index != tt.wantRes.Index { - t.Errorf("#%d: Index=%d, expected %d", i, res.Index, tt.wantRes.Index) - } - if !reflect.DeepEqual(res.Node, tt.wantRes.Node) { - t.Errorf("#%d: Node=%v, expected %v", i, res.Node, tt.wantRes.Node) - } - } -} - -func TestUnmarshalFailedKeysResponse(t *testing.T) { - body := []byte(`{"errorCode":100,"message":"Key not found","cause":"/foo","index":18}`) - - wantErr := Error{ - Code: 100, - Message: "Key not found", - Cause: "/foo", - Index: uint64(18), - } - - gotErr := unmarshalFailedKeysResponse(body) - if !reflect.DeepEqual(wantErr, gotErr) { - t.Errorf("unexpected error: want=%#v got=%#v", wantErr, gotErr) - } -} - -func TestUnmarshalFailedKeysResponseBadJSON(t *testing.T) { - err := unmarshalFailedKeysResponse([]byte(`{"er`)) - if err == nil { - t.Errorf("got nil error") - } else if _, ok := err.(Error); ok { - t.Errorf("error is of incorrect type *Error: %#v", err) - } -} - -func TestHTTPWatcherNextWaitAction(t *testing.T) { - initAction := waitAction{ - Prefix: "/pants", - Key: "/foo/bar", - Recursive: true, - WaitIndex: 19, - } - - client := &actionAssertingHTTPClient{ - t: t, - act: &initAction, - resp: http.Response{ - StatusCode: http.StatusOK, - Header: http.Header{"X-Etcd-Index": []string{"42"}}, - }, - body: []byte(`{"action":"update","node":{"key":"/pants/foo/bar/baz","value":"snarf","modifiedIndex":21,"createdIndex":19},"prevNode":{"key":"/pants/foo/bar/baz","value":"snazz","modifiedIndex":20,"createdIndex":19}}`), - } - - wantResponse := &Response{ - Action: "update", - Node: &Node{Key: "/pants/foo/bar/baz", Value: "snarf", CreatedIndex: uint64(19), ModifiedIndex: uint64(21)}, - PrevNode: &Node{Key: "/pants/foo/bar/baz", Value: "snazz", CreatedIndex: uint64(19), ModifiedIndex: uint64(20)}, - Index: uint64(42), - } - - wantNextWait := waitAction{ - Prefix: "/pants", - Key: "/foo/bar", - Recursive: true, - WaitIndex: 22, - } - - watcher := &httpWatcher{ - client: client, - nextWait: initAction, - } - - resp, err := watcher.Next(context.Background()) - if err != nil { - t.Errorf("non-nil error: %#v", err) - } - - if !reflect.DeepEqual(wantResponse, resp) { - t.Errorf("received incorrect Response: want=%#v got=%#v", wantResponse, resp) - } - - if !reflect.DeepEqual(wantNextWait, watcher.nextWait) { - t.Errorf("nextWait incorrect: want=%#v got=%#v", wantNextWait, watcher.nextWait) - } -} - -func TestHTTPWatcherNextFail(t *testing.T) { - tests := []httpClient{ - // generic HTTP client failure - &staticHTTPClient{ - err: errors.New("fail!"), - }, - - // unusable status code - &staticHTTPClient{ - resp: http.Response{ - StatusCode: http.StatusTeapot, - }, - }, - - // etcd Error response - &staticHTTPClient{ - resp: http.Response{ - StatusCode: http.StatusNotFound, - }, - body: []byte(`{"errorCode":100,"message":"Key not found","cause":"/foo","index":18}`), - }, - } - - for i, tt := range tests { - act := waitAction{ - Prefix: "/pants", - Key: "/foo/bar", - Recursive: true, - WaitIndex: 19, - } - - watcher := &httpWatcher{ - client: tt, - nextWait: act, - } - - resp, err := watcher.Next(context.Background()) - if err == nil { - t.Errorf("#%d: expected non-nil error", i) - } - if resp != nil { - t.Errorf("#%d: expected nil Response, got %#v", i, resp) - } - if !reflect.DeepEqual(act, watcher.nextWait) { - t.Errorf("#%d: nextWait changed: want=%#v got=%#v", i, act, watcher.nextWait) - } - } -} - -func TestHTTPKeysAPIWatcherAction(t *testing.T) { - tests := []struct { - key string - opts *WatcherOptions - want waitAction - }{ - { - key: "/foo", - opts: nil, - want: waitAction{ - Key: "/foo", - Recursive: false, - WaitIndex: 0, - }, - }, - - { - key: "/foo", - opts: &WatcherOptions{ - Recursive: false, - AfterIndex: 0, - }, - want: waitAction{ - Key: "/foo", - Recursive: false, - WaitIndex: 0, - }, - }, - - { - key: "/foo", - opts: &WatcherOptions{ - Recursive: true, - AfterIndex: 0, - }, - want: waitAction{ - Key: "/foo", - Recursive: true, - WaitIndex: 0, - }, - }, - - { - key: "/foo", - opts: &WatcherOptions{ - Recursive: false, - AfterIndex: 19, - }, - want: waitAction{ - Key: "/foo", - Recursive: false, - WaitIndex: 20, - }, - }, - } - - for i, tt := range tests { - kAPI := &httpKeysAPI{ - client: &staticHTTPClient{err: errors.New("fail!")}, - } - - want := &httpWatcher{ - client: &staticHTTPClient{err: errors.New("fail!")}, - nextWait: tt.want, - } - - got := kAPI.Watcher(tt.key, tt.opts) - if !reflect.DeepEqual(want, got) { - t.Errorf("#%d: incorrect watcher: want=%#v got=%#v", i, want, got) - } - } -} - -func TestHTTPKeysAPISetAction(t *testing.T) { - tests := []struct { - key string - value string - opts *SetOptions - wantAction httpAction - }{ - // nil SetOptions - { - key: "/foo", - value: "bar", - opts: nil, - wantAction: &setAction{ - Key: "/foo", - Value: "bar", - PrevValue: "", - PrevIndex: 0, - PrevExist: PrevIgnore, - TTL: 0, - }, - }, - // empty SetOptions - { - key: "/foo", - value: "bar", - opts: &SetOptions{}, - wantAction: &setAction{ - Key: "/foo", - Value: "bar", - PrevValue: "", - PrevIndex: 0, - PrevExist: PrevIgnore, - TTL: 0, - }, - }, - // populated SetOptions - { - key: "/foo", - value: "bar", - opts: &SetOptions{ - PrevValue: "baz", - PrevIndex: 13, - PrevExist: PrevExist, - TTL: time.Minute, - Dir: true, - }, - wantAction: &setAction{ - Key: "/foo", - Value: "bar", - PrevValue: "baz", - PrevIndex: 13, - PrevExist: PrevExist, - TTL: time.Minute, - Dir: true, - }, - }, - } - - for i, tt := range tests { - client := &actionAssertingHTTPClient{t: t, num: i, act: tt.wantAction} - kAPI := httpKeysAPI{client: client} - kAPI.Set(context.Background(), tt.key, tt.value, tt.opts) - } -} - -func TestHTTPKeysAPISetError(t *testing.T) { - tests := []httpClient{ - // generic HTTP client failure - &staticHTTPClient{ - err: errors.New("fail!"), - }, - - // unusable status code - &staticHTTPClient{ - resp: http.Response{ - StatusCode: http.StatusTeapot, - }, - }, - - // etcd Error response - &staticHTTPClient{ - resp: http.Response{ - StatusCode: http.StatusInternalServerError, - }, - body: []byte(`{"errorCode":300,"message":"Raft internal error","cause":"/foo","index":18}`), - }, - } - - for i, tt := range tests { - kAPI := httpKeysAPI{client: tt} - resp, err := kAPI.Set(context.Background(), "/foo", "bar", nil) - if err == nil { - t.Errorf("#%d: received nil error", i) - } - if resp != nil { - t.Errorf("#%d: received non-nil Response: %#v", i, resp) - } - } -} - -func TestHTTPKeysAPISetResponse(t *testing.T) { - client := &staticHTTPClient{ - resp: http.Response{ - StatusCode: http.StatusOK, - Header: http.Header{"X-Etcd-Index": []string{"21"}}, - }, - body: []byte(`{"action":"set","node":{"key":"/pants/foo/bar/baz","value":"snarf","modifiedIndex":21,"createdIndex":21},"prevNode":{"key":"/pants/foo/bar/baz","value":"snazz","modifiedIndex":20,"createdIndex":19}}`), - } - - wantResponse := &Response{ - Action: "set", - Node: &Node{Key: "/pants/foo/bar/baz", Value: "snarf", CreatedIndex: uint64(21), ModifiedIndex: uint64(21)}, - PrevNode: &Node{Key: "/pants/foo/bar/baz", Value: "snazz", CreatedIndex: uint64(19), ModifiedIndex: uint64(20)}, - Index: uint64(21), - } - - kAPI := &httpKeysAPI{client: client, prefix: "/pants"} - resp, err := kAPI.Set(context.Background(), "/foo/bar/baz", "snarf", nil) - if err != nil { - t.Errorf("non-nil error: %#v", err) - } - if !reflect.DeepEqual(wantResponse, resp) { - t.Errorf("incorrect Response: want=%#v got=%#v", wantResponse, resp) - } -} - -func TestHTTPKeysAPIGetAction(t *testing.T) { - tests := []struct { - key string - opts *GetOptions - wantAction httpAction - }{ - // nil GetOptions - { - key: "/foo", - opts: nil, - wantAction: &getAction{ - Key: "/foo", - Sorted: false, - Recursive: false, - }, - }, - // empty GetOptions - { - key: "/foo", - opts: &GetOptions{}, - wantAction: &getAction{ - Key: "/foo", - Sorted: false, - Recursive: false, - }, - }, - // populated GetOptions - { - key: "/foo", - opts: &GetOptions{ - Sort: true, - Recursive: true, - Quorum: true, - }, - wantAction: &getAction{ - Key: "/foo", - Sorted: true, - Recursive: true, - Quorum: true, - }, - }, - } - - for i, tt := range tests { - client := &actionAssertingHTTPClient{t: t, num: i, act: tt.wantAction} - kAPI := httpKeysAPI{client: client} - kAPI.Get(context.Background(), tt.key, tt.opts) - } -} - -func TestHTTPKeysAPIGetError(t *testing.T) { - tests := []httpClient{ - // generic HTTP client failure - &staticHTTPClient{ - err: errors.New("fail!"), - }, - - // unusable status code - &staticHTTPClient{ - resp: http.Response{ - StatusCode: http.StatusTeapot, - }, - }, - - // etcd Error response - &staticHTTPClient{ - resp: http.Response{ - StatusCode: http.StatusInternalServerError, - }, - body: []byte(`{"errorCode":300,"message":"Raft internal error","cause":"/foo","index":18}`), - }, - } - - for i, tt := range tests { - kAPI := httpKeysAPI{client: tt} - resp, err := kAPI.Get(context.Background(), "/foo", nil) - if err == nil { - t.Errorf("#%d: received nil error", i) - } - if resp != nil { - t.Errorf("#%d: received non-nil Response: %#v", i, resp) - } - } -} - -func TestHTTPKeysAPIGetResponse(t *testing.T) { - client := &staticHTTPClient{ - resp: http.Response{ - StatusCode: http.StatusOK, - Header: http.Header{"X-Etcd-Index": []string{"42"}}, - }, - body: []byte(`{"action":"get","node":{"key":"/pants/foo/bar","modifiedIndex":25,"createdIndex":19,"nodes":[{"key":"/pants/foo/bar/baz","value":"snarf","createdIndex":21,"modifiedIndex":25}]}}`), - } - - wantResponse := &Response{ - Action: "get", - Node: &Node{ - Key: "/pants/foo/bar", - Nodes: []*Node{ - {Key: "/pants/foo/bar/baz", Value: "snarf", CreatedIndex: 21, ModifiedIndex: 25}, - }, - CreatedIndex: uint64(19), - ModifiedIndex: uint64(25), - }, - Index: uint64(42), - } - - kAPI := &httpKeysAPI{client: client, prefix: "/pants"} - resp, err := kAPI.Get(context.Background(), "/foo/bar", &GetOptions{Recursive: true}) - if err != nil { - t.Errorf("non-nil error: %#v", err) - } - if !reflect.DeepEqual(wantResponse, resp) { - t.Errorf("incorrect Response: want=%#v got=%#v", wantResponse, resp) - } -} - -func TestHTTPKeysAPIDeleteAction(t *testing.T) { - tests := []struct { - key string - value string - opts *DeleteOptions - wantAction httpAction - }{ - // nil DeleteOptions - { - key: "/foo", - opts: nil, - wantAction: &deleteAction{ - Key: "/foo", - PrevValue: "", - PrevIndex: 0, - Recursive: false, - }, - }, - // empty DeleteOptions - { - key: "/foo", - opts: &DeleteOptions{}, - wantAction: &deleteAction{ - Key: "/foo", - PrevValue: "", - PrevIndex: 0, - Recursive: false, - }, - }, - // populated DeleteOptions - { - key: "/foo", - opts: &DeleteOptions{ - PrevValue: "baz", - PrevIndex: 13, - Recursive: true, - }, - wantAction: &deleteAction{ - Key: "/foo", - PrevValue: "baz", - PrevIndex: 13, - Recursive: true, - }, - }, - } - - for i, tt := range tests { - client := &actionAssertingHTTPClient{t: t, num: i, act: tt.wantAction} - kAPI := httpKeysAPI{client: client} - kAPI.Delete(context.Background(), tt.key, tt.opts) - } -} - -func TestHTTPKeysAPIDeleteError(t *testing.T) { - tests := []httpClient{ - // generic HTTP client failure - &staticHTTPClient{ - err: errors.New("fail!"), - }, - - // unusable status code - &staticHTTPClient{ - resp: http.Response{ - StatusCode: http.StatusTeapot, - }, - }, - - // etcd Error response - &staticHTTPClient{ - resp: http.Response{ - StatusCode: http.StatusInternalServerError, - }, - body: []byte(`{"errorCode":300,"message":"Raft internal error","cause":"/foo","index":18}`), - }, - } - - for i, tt := range tests { - kAPI := httpKeysAPI{client: tt} - resp, err := kAPI.Delete(context.Background(), "/foo", nil) - if err == nil { - t.Errorf("#%d: received nil error", i) - } - if resp != nil { - t.Errorf("#%d: received non-nil Response: %#v", i, resp) - } - } -} - -func TestHTTPKeysAPIDeleteResponse(t *testing.T) { - client := &staticHTTPClient{ - resp: http.Response{ - StatusCode: http.StatusOK, - Header: http.Header{"X-Etcd-Index": []string{"22"}}, - }, - body: []byte(`{"action":"delete","node":{"key":"/pants/foo/bar/baz","value":"snarf","modifiedIndex":22,"createdIndex":19},"prevNode":{"key":"/pants/foo/bar/baz","value":"snazz","modifiedIndex":20,"createdIndex":19}}`), - } - - wantResponse := &Response{ - Action: "delete", - Node: &Node{Key: "/pants/foo/bar/baz", Value: "snarf", CreatedIndex: uint64(19), ModifiedIndex: uint64(22)}, - PrevNode: &Node{Key: "/pants/foo/bar/baz", Value: "snazz", CreatedIndex: uint64(19), ModifiedIndex: uint64(20)}, - Index: uint64(22), - } - - kAPI := &httpKeysAPI{client: client, prefix: "/pants"} - resp, err := kAPI.Delete(context.Background(), "/foo/bar/baz", nil) - if err != nil { - t.Errorf("non-nil error: %#v", err) - } - if !reflect.DeepEqual(wantResponse, resp) { - t.Errorf("incorrect Response: want=%#v got=%#v", wantResponse, resp) - } -} - -func TestHTTPKeysAPICreateAction(t *testing.T) { - act := &setAction{ - Key: "/foo", - Value: "bar", - PrevExist: PrevNoExist, - PrevIndex: 0, - PrevValue: "", - TTL: 0, - } - - kAPI := httpKeysAPI{client: &actionAssertingHTTPClient{t: t, act: act}} - kAPI.Create(context.Background(), "/foo", "bar") -} - -func TestHTTPKeysAPICreateInOrderAction(t *testing.T) { - act := &createInOrderAction{ - Dir: "/foo", - Value: "bar", - TTL: 0, - } - kAPI := httpKeysAPI{client: &actionAssertingHTTPClient{t: t, act: act}} - kAPI.CreateInOrder(context.Background(), "/foo", "bar", nil) -} - -func TestHTTPKeysAPIUpdateAction(t *testing.T) { - act := &setAction{ - Key: "/foo", - Value: "bar", - PrevExist: PrevExist, - PrevIndex: 0, - PrevValue: "", - TTL: 0, - } - - kAPI := httpKeysAPI{client: &actionAssertingHTTPClient{t: t, act: act}} - kAPI.Update(context.Background(), "/foo", "bar") -} - -func TestNodeTTLDuration(t *testing.T) { - tests := []struct { - node *Node - want time.Duration - }{ - { - node: &Node{TTL: 0}, - want: 0, - }, - { - node: &Node{TTL: 97}, - want: 97 * time.Second, - }, - } - - for i, tt := range tests { - got := tt.node.TTLDuration() - if tt.want != got { - t.Errorf("#%d: incorrect duration: want=%v got=%v", i, tt.want, got) - } - } -} diff --git a/vendor/github.com/coreos/etcd/client/members.go b/vendor/github.com/coreos/etcd/client/members.go index c1c78409a..23adf07ad 100644 --- a/vendor/github.com/coreos/etcd/client/members.go +++ b/vendor/github.com/coreos/etcd/client/members.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 The etcd Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -29,6 +29,7 @@ import ( var ( defaultV2MembersPrefix = "/v2/members" + defaultLeaderSuffix = "/leader" ) type Member struct { @@ -105,6 +106,9 @@ type MembersAPI interface { // Update instructs etcd to update an existing Member in the cluster. Update(ctx context.Context, mID string, peerURLs []string) error + + // Leader gets current leader of the cluster + Leader(ctx context.Context) (*Member, error) } type httpMembersAPI struct { @@ -199,6 +203,25 @@ func (m *httpMembersAPI) Remove(ctx context.Context, memberID string) error { return assertStatusCode(resp.StatusCode, http.StatusNoContent, http.StatusGone) } +func (m *httpMembersAPI) Leader(ctx context.Context) (*Member, error) { + req := &membersAPIActionLeader{} + resp, body, err := m.client.Do(ctx, req) + if err != nil { + return nil, err + } + + if err := assertStatusCode(resp.StatusCode, http.StatusOK); err != nil { + return nil, err + } + + var leader Member + if err := json.Unmarshal(body, &leader); err != nil { + return nil, err + } + + return &leader, nil +} + type membersAPIActionList struct{} func (l *membersAPIActionList) HTTPRequest(ep url.URL) *http.Request { @@ -255,6 +278,15 @@ func assertStatusCode(got int, want ...int) (err error) { return fmt.Errorf("unexpected status code %d", got) } +type membersAPIActionLeader struct{} + +func (l *membersAPIActionLeader) HTTPRequest(ep url.URL) *http.Request { + u := v2MembersURL(ep) + u.Path = path.Join(u.Path, defaultLeaderSuffix) + req, _ := http.NewRequest("GET", u.String(), nil) + return req +} + // v2MembersURL add the necessary path to the provided endpoint // to route requests to the default v2 members API. func v2MembersURL(ep url.URL) *url.URL { diff --git a/vendor/github.com/coreos/etcd/client/members_test.go b/vendor/github.com/coreos/etcd/client/members_test.go deleted file mode 100644 index e892b7696..000000000 --- a/vendor/github.com/coreos/etcd/client/members_test.go +++ /dev/null @@ -1,522 +0,0 @@ -// Copyright 2015 CoreOS, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package client - -import ( - "encoding/json" - "errors" - "net/http" - "net/url" - "reflect" - "testing" - - "golang.org/x/net/context" - - "github.com/coreos/etcd/pkg/types" -) - -func TestMembersAPIActionList(t *testing.T) { - ep := url.URL{Scheme: "http", Host: "example.com"} - act := &membersAPIActionList{} - - wantURL := &url.URL{ - Scheme: "http", - Host: "example.com", - Path: "/v2/members", - } - - got := *act.HTTPRequest(ep) - err := assertRequest(got, "GET", wantURL, http.Header{}, nil) - if err != nil { - t.Error(err.Error()) - } -} - -func TestMembersAPIActionAdd(t *testing.T) { - ep := url.URL{Scheme: "http", Host: "example.com"} - act := &membersAPIActionAdd{ - peerURLs: types.URLs([]url.URL{ - {Scheme: "https", Host: "127.0.0.1:8081"}, - {Scheme: "http", Host: "127.0.0.1:8080"}, - }), - } - - wantURL := &url.URL{ - Scheme: "http", - Host: "example.com", - Path: "/v2/members", - } - wantHeader := http.Header{ - "Content-Type": []string{"application/json"}, - } - wantBody := []byte(`{"peerURLs":["https://127.0.0.1:8081","http://127.0.0.1:8080"]}`) - - got := *act.HTTPRequest(ep) - err := assertRequest(got, "POST", wantURL, wantHeader, wantBody) - if err != nil { - t.Error(err.Error()) - } -} - -func TestMembersAPIActionUpdate(t *testing.T) { - ep := url.URL{Scheme: "http", Host: "example.com"} - act := &membersAPIActionUpdate{ - memberID: "0xabcd", - peerURLs: types.URLs([]url.URL{ - {Scheme: "https", Host: "127.0.0.1:8081"}, - {Scheme: "http", Host: "127.0.0.1:8080"}, - }), - } - - wantURL := &url.URL{ - Scheme: "http", - Host: "example.com", - Path: "/v2/members/0xabcd", - } - wantHeader := http.Header{ - "Content-Type": []string{"application/json"}, - } - wantBody := []byte(`{"peerURLs":["https://127.0.0.1:8081","http://127.0.0.1:8080"]}`) - - got := *act.HTTPRequest(ep) - err := assertRequest(got, "PUT", wantURL, wantHeader, wantBody) - if err != nil { - t.Error(err.Error()) - } -} - -func TestMembersAPIActionRemove(t *testing.T) { - ep := url.URL{Scheme: "http", Host: "example.com"} - act := &membersAPIActionRemove{memberID: "XXX"} - - wantURL := &url.URL{ - Scheme: "http", - Host: "example.com", - Path: "/v2/members/XXX", - } - - got := *act.HTTPRequest(ep) - err := assertRequest(got, "DELETE", wantURL, http.Header{}, nil) - if err != nil { - t.Error(err.Error()) - } -} - -func TestAssertStatusCode(t *testing.T) { - if err := assertStatusCode(404, 400); err == nil { - t.Errorf("assertStatusCode failed to detect conflict in 400 vs 404") - } - - if err := assertStatusCode(404, 400, 404); err != nil { - t.Errorf("assertStatusCode found conflict in (404,400) vs 400: %v", err) - } -} - -func TestV2MembersURL(t *testing.T) { - got := v2MembersURL(url.URL{ - Scheme: "http", - Host: "foo.example.com:4002", - Path: "/pants", - }) - want := &url.URL{ - Scheme: "http", - Host: "foo.example.com:4002", - Path: "/pants/v2/members", - } - - if !reflect.DeepEqual(want, got) { - t.Fatalf("v2MembersURL got %#v, want %#v", got, want) - } -} - -func TestMemberUnmarshal(t *testing.T) { - tests := []struct { - body []byte - wantMember Member - wantError bool - }{ - // no URLs, just check ID & Name - { - body: []byte(`{"id": "c", "name": "dungarees"}`), - wantMember: Member{ID: "c", Name: "dungarees", PeerURLs: nil, ClientURLs: nil}, - }, - - // both client and peer URLs - { - body: []byte(`{"peerURLs": ["http://127.0.0.1:2379"], "clientURLs": ["http://127.0.0.1:2379"]}`), - wantMember: Member{ - PeerURLs: []string{ - "http://127.0.0.1:2379", - }, - ClientURLs: []string{ - "http://127.0.0.1:2379", - }, - }, - }, - - // multiple peer URLs - { - body: []byte(`{"peerURLs": ["http://127.0.0.1:2379", "https://example.com"]}`), - wantMember: Member{ - PeerURLs: []string{ - "http://127.0.0.1:2379", - "https://example.com", - }, - ClientURLs: nil, - }, - }, - - // multiple client URLs - { - body: []byte(`{"clientURLs": ["http://127.0.0.1:2379", "https://example.com"]}`), - wantMember: Member{ - PeerURLs: nil, - ClientURLs: []string{ - "http://127.0.0.1:2379", - "https://example.com", - }, - }, - }, - - // invalid JSON - { - body: []byte(`{"peerU`), - wantError: true, - }, - } - - for i, tt := range tests { - got := Member{} - err := json.Unmarshal(tt.body, &got) - if tt.wantError != (err != nil) { - t.Errorf("#%d: want error %t, got %v", i, tt.wantError, err) - continue - } - - if !reflect.DeepEqual(tt.wantMember, got) { - t.Errorf("#%d: incorrect output: want=%#v, got=%#v", i, tt.wantMember, got) - } - } -} - -func TestMemberCollectionUnmarshalFail(t *testing.T) { - mc := &memberCollection{} - if err := mc.UnmarshalJSON([]byte(`{`)); err == nil { - t.Errorf("got nil error") - } -} - -func TestMemberCollectionUnmarshal(t *testing.T) { - tests := []struct { - body []byte - want memberCollection - }{ - { - body: []byte(`{}`), - want: memberCollection([]Member{}), - }, - { - body: []byte(`{"members":[]}`), - want: memberCollection([]Member{}), - }, - { - body: []byte(`{"members":[{"id":"2745e2525fce8fe","peerURLs":["http://127.0.0.1:7003"],"name":"node3","clientURLs":["http://127.0.0.1:4003"]},{"id":"42134f434382925","peerURLs":["http://127.0.0.1:2380","http://127.0.0.1:7001"],"name":"node1","clientURLs":["http://127.0.0.1:2379","http://127.0.0.1:4001"]},{"id":"94088180e21eb87b","peerURLs":["http://127.0.0.1:7002"],"name":"node2","clientURLs":["http://127.0.0.1:4002"]}]}`), - want: memberCollection( - []Member{ - { - ID: "2745e2525fce8fe", - Name: "node3", - PeerURLs: []string{ - "http://127.0.0.1:7003", - }, - ClientURLs: []string{ - "http://127.0.0.1:4003", - }, - }, - { - ID: "42134f434382925", - Name: "node1", - PeerURLs: []string{ - "http://127.0.0.1:2380", - "http://127.0.0.1:7001", - }, - ClientURLs: []string{ - "http://127.0.0.1:2379", - "http://127.0.0.1:4001", - }, - }, - { - ID: "94088180e21eb87b", - Name: "node2", - PeerURLs: []string{ - "http://127.0.0.1:7002", - }, - ClientURLs: []string{ - "http://127.0.0.1:4002", - }, - }, - }, - ), - }, - } - - for i, tt := range tests { - var got memberCollection - err := json.Unmarshal(tt.body, &got) - if err != nil { - t.Errorf("#%d: unexpected error: %v", i, err) - continue - } - - if !reflect.DeepEqual(tt.want, got) { - t.Errorf("#%d: incorrect output: want=%#v, got=%#v", i, tt.want, got) - } - } -} - -func TestMemberCreateRequestMarshal(t *testing.T) { - req := memberCreateOrUpdateRequest{ - PeerURLs: types.URLs([]url.URL{ - {Scheme: "http", Host: "127.0.0.1:8081"}, - {Scheme: "https", Host: "127.0.0.1:8080"}, - }), - } - want := []byte(`{"peerURLs":["http://127.0.0.1:8081","https://127.0.0.1:8080"]}`) - - got, err := json.Marshal(&req) - if err != nil { - t.Fatalf("Marshal returned unexpected err=%v", err) - } - - if !reflect.DeepEqual(want, got) { - t.Fatalf("Failed to marshal memberCreateRequest: want=%s, got=%s", want, got) - } -} - -func TestHTTPMembersAPIAddSuccess(t *testing.T) { - wantAction := &membersAPIActionAdd{ - peerURLs: types.URLs([]url.URL{ - {Scheme: "http", Host: "127.0.0.1:7002"}, - }), - } - - mAPI := &httpMembersAPI{ - client: &actionAssertingHTTPClient{ - t: t, - act: wantAction, - resp: http.Response{ - StatusCode: http.StatusCreated, - }, - body: []byte(`{"id":"94088180e21eb87b","peerURLs":["http://127.0.0.1:7002"]}`), - }, - } - - wantResponseMember := &Member{ - ID: "94088180e21eb87b", - PeerURLs: []string{"http://127.0.0.1:7002"}, - } - - m, err := mAPI.Add(context.Background(), "http://127.0.0.1:7002") - if err != nil { - t.Errorf("got non-nil err: %#v", err) - } - if !reflect.DeepEqual(wantResponseMember, m) { - t.Errorf("incorrect Member: want=%#v got=%#v", wantResponseMember, m) - } -} - -func TestHTTPMembersAPIAddError(t *testing.T) { - okPeer := "http://example.com:2379" - tests := []struct { - peerURL string - client httpClient - - // if wantErr == nil, assert that the returned error is non-nil - // if wantErr != nil, assert that the returned error matches - wantErr error - }{ - // malformed peer URL - { - peerURL: ":", - }, - - // generic httpClient failure - { - peerURL: okPeer, - client: &staticHTTPClient{err: errors.New("fail!")}, - }, - - // unrecognized HTTP status code - { - peerURL: okPeer, - client: &staticHTTPClient{ - resp: http.Response{StatusCode: http.StatusTeapot}, - }, - }, - - // unmarshal body into membersError on StatusConflict - { - peerURL: okPeer, - client: &staticHTTPClient{ - resp: http.Response{ - StatusCode: http.StatusConflict, - }, - body: []byte(`{"message":"fail!"}`), - }, - wantErr: membersError{Message: "fail!"}, - }, - - // fail to unmarshal body on StatusConflict - { - peerURL: okPeer, - client: &staticHTTPClient{ - resp: http.Response{ - StatusCode: http.StatusConflict, - }, - body: []byte(`{"`), - }, - }, - - // fail to unmarshal body on StatusCreated - { - peerURL: okPeer, - client: &staticHTTPClient{ - resp: http.Response{ - StatusCode: http.StatusCreated, - }, - body: []byte(`{"id":"XX`), - }, - }, - } - - for i, tt := range tests { - mAPI := &httpMembersAPI{client: tt.client} - m, err := mAPI.Add(context.Background(), tt.peerURL) - if err == nil { - t.Errorf("#%d: got nil err", i) - } - if tt.wantErr != nil && !reflect.DeepEqual(tt.wantErr, err) { - t.Errorf("#%d: incorrect error: want=%#v got=%#v", i, tt.wantErr, err) - } - if m != nil { - t.Errorf("#%d: got non-nil Member", i) - } - } -} - -func TestHTTPMembersAPIRemoveSuccess(t *testing.T) { - wantAction := &membersAPIActionRemove{ - memberID: "94088180e21eb87b", - } - - mAPI := &httpMembersAPI{ - client: &actionAssertingHTTPClient{ - t: t, - act: wantAction, - resp: http.Response{ - StatusCode: http.StatusNoContent, - }, - }, - } - - if err := mAPI.Remove(context.Background(), "94088180e21eb87b"); err != nil { - t.Errorf("got non-nil err: %#v", err) - } -} - -func TestHTTPMembersAPIRemoveFail(t *testing.T) { - tests := []httpClient{ - // generic error - &staticHTTPClient{ - err: errors.New("fail!"), - }, - - // unexpected HTTP status code - &staticHTTPClient{ - resp: http.Response{ - StatusCode: http.StatusInternalServerError, - }, - }, - } - - for i, tt := range tests { - mAPI := &httpMembersAPI{client: tt} - if err := mAPI.Remove(context.Background(), "94088180e21eb87b"); err == nil { - t.Errorf("#%d: got nil err", i) - } - } -} - -func TestHTTPMembersAPIListSuccess(t *testing.T) { - wantAction := &membersAPIActionList{} - mAPI := &httpMembersAPI{ - client: &actionAssertingHTTPClient{ - t: t, - act: wantAction, - resp: http.Response{ - StatusCode: http.StatusOK, - }, - body: []byte(`{"members":[{"id":"94088180e21eb87b","name":"node2","peerURLs":["http://127.0.0.1:7002"],"clientURLs":["http://127.0.0.1:4002"]}]}`), - }, - } - - wantResponseMembers := []Member{ - { - ID: "94088180e21eb87b", - Name: "node2", - PeerURLs: []string{"http://127.0.0.1:7002"}, - ClientURLs: []string{"http://127.0.0.1:4002"}, - }, - } - - m, err := mAPI.List(context.Background()) - if err != nil { - t.Errorf("got non-nil err: %#v", err) - } - if !reflect.DeepEqual(wantResponseMembers, m) { - t.Errorf("incorrect Members: want=%#v got=%#v", wantResponseMembers, m) - } -} - -func TestHTTPMembersAPIListError(t *testing.T) { - tests := []httpClient{ - // generic httpClient failure - &staticHTTPClient{err: errors.New("fail!")}, - - // unrecognized HTTP status code - &staticHTTPClient{ - resp: http.Response{StatusCode: http.StatusTeapot}, - }, - - // fail to unmarshal body on StatusOK - &staticHTTPClient{ - resp: http.Response{ - StatusCode: http.StatusOK, - }, - body: []byte(`[{"id":"XX`), - }, - } - - for i, tt := range tests { - mAPI := &httpMembersAPI{client: tt} - ms, err := mAPI.List(context.Background()) - if err == nil { - t.Errorf("#%d: got nil err", i) - } - if ms != nil { - t.Errorf("#%d: got non-nil Member slice", i) - } - } -} diff --git a/vendor/github.com/coreos/etcd/client/srv.go b/vendor/github.com/coreos/etcd/client/srv.go index f74c1220b..fdfa34359 100644 --- a/vendor/github.com/coreos/etcd/client/srv.go +++ b/vendor/github.com/coreos/etcd/client/srv.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 The etcd Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -27,7 +27,7 @@ var ( type srvDiscover struct{} -// NewSRVDiscover constructs a new Dicoverer that uses the stdlib to lookup SRV records. +// NewSRVDiscover constructs a new Discoverer that uses the stdlib to lookup SRV records. func NewSRVDiscover() Discoverer { return &srvDiscover{} } @@ -50,8 +50,8 @@ func (d *srvDiscover) Discover(domain string) ([]string, error) { return nil } - errHTTPS := updateURLs("etcd-server-ssl", "https") - errHTTP := updateURLs("etcd-server", "http") + errHTTPS := updateURLs("etcd-client-ssl", "https") + errHTTP := updateURLs("etcd-client", "http") if errHTTPS != nil && errHTTP != nil { return nil, fmt.Errorf("dns lookup errors: %s and %s", errHTTPS, errHTTP) diff --git a/vendor/github.com/coreos/etcd/client/srv_test.go b/vendor/github.com/coreos/etcd/client/srv_test.go deleted file mode 100644 index a4a27f108..000000000 --- a/vendor/github.com/coreos/etcd/client/srv_test.go +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright 2015 CoreOS, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package client - -import ( - "errors" - "net" - "reflect" - "testing" -) - -func TestSRVDiscover(t *testing.T) { - defer func() { lookupSRV = net.LookupSRV }() - - tests := []struct { - withSSL []*net.SRV - withoutSSL []*net.SRV - expected []string - }{ - { - []*net.SRV{}, - []*net.SRV{}, - []string{}, - }, - { - []*net.SRV{ - {Target: "10.0.0.1", Port: 2480}, - {Target: "10.0.0.2", Port: 2480}, - {Target: "10.0.0.3", Port: 2480}, - }, - []*net.SRV{}, - []string{"https://10.0.0.1:2480", "https://10.0.0.2:2480", "https://10.0.0.3:2480"}, - }, - { - []*net.SRV{ - {Target: "10.0.0.1", Port: 2480}, - {Target: "10.0.0.2", Port: 2480}, - {Target: "10.0.0.3", Port: 2480}, - }, - []*net.SRV{ - {Target: "10.0.0.1", Port: 7001}, - }, - []string{"https://10.0.0.1:2480", "https://10.0.0.2:2480", "https://10.0.0.3:2480", "http://10.0.0.1:7001"}, - }, - { - []*net.SRV{ - {Target: "10.0.0.1", Port: 2480}, - {Target: "10.0.0.2", Port: 2480}, - {Target: "10.0.0.3", Port: 2480}, - }, - []*net.SRV{ - {Target: "10.0.0.1", Port: 7001}, - }, - []string{"https://10.0.0.1:2480", "https://10.0.0.2:2480", "https://10.0.0.3:2480", "http://10.0.0.1:7001"}, - }, - { - []*net.SRV{ - {Target: "a.example.com", Port: 2480}, - {Target: "b.example.com", Port: 2480}, - {Target: "c.example.com", Port: 2480}, - }, - []*net.SRV{}, - []string{"https://a.example.com:2480", "https://b.example.com:2480", "https://c.example.com:2480"}, - }, - } - - for i, tt := range tests { - lookupSRV = func(service string, proto string, domain string) (string, []*net.SRV, error) { - if service == "etcd-server-ssl" { - return "", tt.withSSL, nil - } - if service == "etcd-server" { - return "", tt.withoutSSL, nil - } - return "", nil, errors.New("Unkown service in mock") - } - - d := NewSRVDiscover() - - endpoints, err := d.Discover("example.com") - if err != nil { - t.Fatalf("%d: err: %#v", i, err) - } - - if !reflect.DeepEqual(endpoints, tt.expected) { - t.Errorf("#%d: endpoints = %v, want %v", i, endpoints, tt.expected) - } - - } -} diff --git a/vendor/github.com/coreos/etcd/pkg/pathutil/path_test.go b/vendor/github.com/coreos/etcd/client/util.go similarity index 56% rename from vendor/github.com/coreos/etcd/pkg/pathutil/path_test.go rename to vendor/github.com/coreos/etcd/client/util.go index 6d3d803cf..198bff965 100644 --- a/vendor/github.com/coreos/etcd/pkg/pathutil/path_test.go +++ b/vendor/github.com/coreos/etcd/client/util.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2016 The etcd Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -12,27 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. -package pathutil +package client -import "testing" - -func TestCanonicalURLPath(t *testing.T) { - tests := []struct { - p string - wp string - }{ - {"/a", "/a"}, - {"", "/"}, - {"a", "/a"}, - {"//a", "/a"}, - {"/a/.", "/a"}, - {"/a/..", "/"}, - {"/a/", "/a/"}, - {"/a//", "/a/"}, - } - for i, tt := range tests { - if g := CanonicalURLPath(tt.p); g != tt.wp { - t.Errorf("#%d: canonical path = %s, want %s", i, g, tt.wp) - } +// IsKeyNotFound returns true if the error code is ErrorCodeKeyNotFound. +func IsKeyNotFound(err error) bool { + if cErr, ok := err.(Error); ok { + return cErr.Code == ErrorCodeKeyNotFound } + return false } diff --git a/vendor/github.com/coreos/etcd/main.go b/vendor/github.com/coreos/etcd/main.go new file mode 100644 index 000000000..0b7357376 --- /dev/null +++ b/vendor/github.com/coreos/etcd/main.go @@ -0,0 +1,29 @@ +// Copyright 2015 The etcd Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package main is a simple wrapper of the real etcd entrypoint package +// (located at github.com/coreos/etcd/etcdmain) to ensure that etcd is still +// "go getable"; e.g. `go get github.com/coreos/etcd` works as expected and +// builds a binary in $GOBIN/etcd +// +// This package should NOT be extended or modified in any way; to modify the +// etcd binary, work in the `github.com/coreos/etcd/etcdmain` package. +// +package main + +import "github.com/coreos/etcd/etcdmain" + +func main() { + etcdmain.Main() +} diff --git a/vendor/github.com/coreos/etcd/pkg/pathutil/path.go b/vendor/github.com/coreos/etcd/pkg/pathutil/path.go index 82fd1db39..f26254ba9 100644 --- a/vendor/github.com/coreos/etcd/pkg/pathutil/path.go +++ b/vendor/github.com/coreos/etcd/pkg/pathutil/path.go @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +// Package pathutil implements utility functions for handling slash-separated +// paths. package pathutil import "path" diff --git a/vendor/github.com/coreos/etcd/pkg/types/slice_test.go b/vendor/github.com/coreos/etcd/pkg/types/doc.go similarity index 65% rename from vendor/github.com/coreos/etcd/pkg/types/slice_test.go rename to vendor/github.com/coreos/etcd/pkg/types/doc.go index 95e37e04d..de8ef0bd7 100644 --- a/vendor/github.com/coreos/etcd/pkg/types/slice_test.go +++ b/vendor/github.com/coreos/etcd/pkg/types/doc.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 The etcd Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -12,19 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. +// Package types declares various data types and implements type-checking +// functions. package types - -import ( - "reflect" - "sort" - "testing" -) - -func TestUint64Slice(t *testing.T) { - g := Uint64Slice{10, 500, 5, 1, 100, 25} - w := Uint64Slice{1, 5, 10, 25, 100, 500} - sort.Sort(g) - if !reflect.DeepEqual(g, w) { - t.Errorf("slice after sort = %#v, want %#v", g, w) - } -} diff --git a/vendor/github.com/coreos/etcd/pkg/types/id.go b/vendor/github.com/coreos/etcd/pkg/types/id.go index 88cb9e634..1b042d9ce 100644 --- a/vendor/github.com/coreos/etcd/pkg/types/id.go +++ b/vendor/github.com/coreos/etcd/pkg/types/id.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 The etcd Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/vendor/github.com/coreos/etcd/pkg/types/id_test.go b/vendor/github.com/coreos/etcd/pkg/types/id_test.go deleted file mode 100644 index 97d168f58..000000000 --- a/vendor/github.com/coreos/etcd/pkg/types/id_test.go +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright 2015 CoreOS, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package types - -import ( - "reflect" - "sort" - "testing" -) - -func TestIDString(t *testing.T) { - tests := []struct { - input ID - want string - }{ - { - input: 12, - want: "c", - }, - { - input: 4918257920282737594, - want: "444129853c343bba", - }, - } - - for i, tt := range tests { - got := tt.input.String() - if tt.want != got { - t.Errorf("#%d: ID.String failure: want=%v, got=%v", i, tt.want, got) - } - } -} - -func TestIDFromString(t *testing.T) { - tests := []struct { - input string - want ID - }{ - { - input: "17", - want: 23, - }, - { - input: "612840dae127353", - want: 437557308098245459, - }, - } - - for i, tt := range tests { - got, err := IDFromString(tt.input) - if err != nil { - t.Errorf("#%d: IDFromString failure: err=%v", i, err) - continue - } - if tt.want != got { - t.Errorf("#%d: IDFromString failure: want=%v, got=%v", i, tt.want, got) - } - } -} - -func TestIDFromStringFail(t *testing.T) { - tests := []string{ - "", - "XXX", - "612840dae127353612840dae127353", - } - - for i, tt := range tests { - _, err := IDFromString(tt) - if err == nil { - t.Fatalf("#%d: IDFromString expected error, but err=nil", i) - } - } -} - -func TestIDSlice(t *testing.T) { - g := []ID{10, 500, 5, 1, 100, 25} - w := []ID{1, 5, 10, 25, 100, 500} - sort.Sort(IDSlice(g)) - if !reflect.DeepEqual(g, w) { - t.Errorf("slice after sort = %#v, want %#v", g, w) - } -} diff --git a/vendor/github.com/coreos/etcd/pkg/types/set.go b/vendor/github.com/coreos/etcd/pkg/types/set.go index bb997174c..73ef431be 100644 --- a/vendor/github.com/coreos/etcd/pkg/types/set.go +++ b/vendor/github.com/coreos/etcd/pkg/types/set.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 The etcd Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/vendor/github.com/coreos/etcd/pkg/types/set_test.go b/vendor/github.com/coreos/etcd/pkg/types/set_test.go deleted file mode 100644 index ff1ecc68d..000000000 --- a/vendor/github.com/coreos/etcd/pkg/types/set_test.go +++ /dev/null @@ -1,186 +0,0 @@ -// Copyright 2015 CoreOS, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package types - -import ( - "reflect" - "sort" - "testing" -) - -func TestUnsafeSet(t *testing.T) { - driveSetTests(t, NewUnsafeSet()) -} - -func TestThreadsafeSet(t *testing.T) { - driveSetTests(t, NewThreadsafeSet()) -} - -// Check that two slices contents are equal; order is irrelevant -func equal(a, b []string) bool { - as := sort.StringSlice(a) - bs := sort.StringSlice(b) - as.Sort() - bs.Sort() - return reflect.DeepEqual(as, bs) -} - -func driveSetTests(t *testing.T, s Set) { - // Verify operations on an empty set - eValues := []string{} - values := s.Values() - if !reflect.DeepEqual(values, eValues) { - t.Fatalf("Expect values=%v got %v", eValues, values) - } - if l := s.Length(); l != 0 { - t.Fatalf("Expected length=0, got %d", l) - } - for _, v := range []string{"foo", "bar", "baz"} { - if s.Contains(v) { - t.Fatalf("Expect s.Contains(%q) to be fale, got true", v) - } - } - - // Add three items, ensure they show up - s.Add("foo") - s.Add("bar") - s.Add("baz") - - eValues = []string{"foo", "bar", "baz"} - values = s.Values() - if !equal(values, eValues) { - t.Fatalf("Expect values=%v got %v", eValues, values) - } - - for _, v := range eValues { - if !s.Contains(v) { - t.Fatalf("Expect s.Contains(%q) to be true, got false", v) - } - } - - if l := s.Length(); l != 3 { - t.Fatalf("Expected length=3, got %d", l) - } - - // Add the same item a second time, ensuring it is not duplicated - s.Add("foo") - - values = s.Values() - if !equal(values, eValues) { - t.Fatalf("Expect values=%v got %v", eValues, values) - } - if l := s.Length(); l != 3 { - t.Fatalf("Expected length=3, got %d", l) - } - - // Remove all items, ensure they are gone - s.Remove("foo") - s.Remove("bar") - s.Remove("baz") - - eValues = []string{} - values = s.Values() - if !equal(values, eValues) { - t.Fatalf("Expect values=%v got %v", eValues, values) - } - - if l := s.Length(); l != 0 { - t.Fatalf("Expected length=0, got %d", l) - } - - // Create new copies of the set, and ensure they are unlinked to the - // original Set by making modifications - s.Add("foo") - s.Add("bar") - cp1 := s.Copy() - cp2 := s.Copy() - s.Remove("foo") - cp3 := s.Copy() - cp1.Add("baz") - - for i, tt := range []struct { - want []string - got []string - }{ - {[]string{"bar"}, s.Values()}, - {[]string{"foo", "bar", "baz"}, cp1.Values()}, - {[]string{"foo", "bar"}, cp2.Values()}, - {[]string{"bar"}, cp3.Values()}, - } { - if !equal(tt.want, tt.got) { - t.Fatalf("case %d: expect values=%v got %v", i, tt.want, tt.got) - } - } - - for i, tt := range []struct { - want bool - got bool - }{ - {true, s.Equals(cp3)}, - {true, cp3.Equals(s)}, - {false, s.Equals(cp2)}, - {false, s.Equals(cp1)}, - {false, cp1.Equals(s)}, - {false, cp2.Equals(s)}, - {false, cp2.Equals(cp1)}, - } { - if tt.got != tt.want { - t.Fatalf("case %d: want %t, got %t", i, tt.want, tt.got) - - } - } - - // Subtract values from a Set, ensuring a new Set is created and - // the original Sets are unmodified - sub1 := cp1.Sub(s) - sub2 := cp2.Sub(cp1) - - for i, tt := range []struct { - want []string - got []string - }{ - {[]string{"foo", "bar", "baz"}, cp1.Values()}, - {[]string{"foo", "bar"}, cp2.Values()}, - {[]string{"bar"}, s.Values()}, - {[]string{"foo", "baz"}, sub1.Values()}, - {[]string{}, sub2.Values()}, - } { - if !equal(tt.want, tt.got) { - t.Fatalf("case %d: expect values=%v got %v", i, tt.want, tt.got) - } - } -} - -func TestUnsafeSetContainsAll(t *testing.T) { - vals := []string{"foo", "bar", "baz"} - s := NewUnsafeSet(vals...) - - tests := []struct { - strs []string - wcontain bool - }{ - {[]string{}, true}, - {vals[:1], true}, - {vals[:2], true}, - {vals, true}, - {[]string{"cuz"}, false}, - {[]string{vals[0], "cuz"}, false}, - } - for i, tt := range tests { - if g := s.ContainsAll(tt.strs); g != tt.wcontain { - t.Errorf("#%d: ok = %v, want %v", i, g, tt.wcontain) - } - } -} diff --git a/vendor/github.com/coreos/etcd/pkg/types/slice.go b/vendor/github.com/coreos/etcd/pkg/types/slice.go index 0327950f7..0dd9ca798 100644 --- a/vendor/github.com/coreos/etcd/pkg/types/slice.go +++ b/vendor/github.com/coreos/etcd/pkg/types/slice.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 The etcd Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/vendor/github.com/coreos/etcd/pkg/types/urls.go b/vendor/github.com/coreos/etcd/pkg/types/urls.go index ce2483ffa..e532722ac 100644 --- a/vendor/github.com/coreos/etcd/pkg/types/urls.go +++ b/vendor/github.com/coreos/etcd/pkg/types/urls.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 The etcd Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -53,6 +53,14 @@ func NewURLs(strs []string) (URLs, error) { return us, nil } +func MustNewURLs(strs []string) URLs { + urls, err := NewURLs(strs) + if err != nil { + panic(err) + } + return urls +} + func (us URLs) String() string { return strings.Join(us.StringSlice(), ",") } diff --git a/vendor/github.com/coreos/etcd/pkg/types/urls_test.go b/vendor/github.com/coreos/etcd/pkg/types/urls_test.go deleted file mode 100644 index ffa2cf007..000000000 --- a/vendor/github.com/coreos/etcd/pkg/types/urls_test.go +++ /dev/null @@ -1,169 +0,0 @@ -// Copyright 2015 CoreOS, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package types - -import ( - "reflect" - "testing" - - "github.com/coreos/etcd/pkg/testutil" -) - -func TestNewURLs(t *testing.T) { - tests := []struct { - strs []string - wurls URLs - }{ - { - []string{"http://127.0.0.1:2379"}, - testutil.MustNewURLs(t, []string{"http://127.0.0.1:2379"}), - }, - // it can trim space - { - []string{" http://127.0.0.1:2379 "}, - testutil.MustNewURLs(t, []string{"http://127.0.0.1:2379"}), - }, - // it does sort - { - []string{ - "http://127.0.0.2:2379", - "http://127.0.0.1:2379", - }, - testutil.MustNewURLs(t, []string{ - "http://127.0.0.1:2379", - "http://127.0.0.2:2379", - }), - }, - } - for i, tt := range tests { - urls, _ := NewURLs(tt.strs) - if !reflect.DeepEqual(urls, tt.wurls) { - t.Errorf("#%d: urls = %+v, want %+v", i, urls, tt.wurls) - } - } -} - -func TestURLsString(t *testing.T) { - tests := []struct { - us URLs - wstr string - }{ - { - URLs{}, - "", - }, - { - testutil.MustNewURLs(t, []string{"http://127.0.0.1:2379"}), - "http://127.0.0.1:2379", - }, - { - testutil.MustNewURLs(t, []string{ - "http://127.0.0.1:2379", - "http://127.0.0.2:2379", - }), - "http://127.0.0.1:2379,http://127.0.0.2:2379", - }, - { - testutil.MustNewURLs(t, []string{ - "http://127.0.0.2:2379", - "http://127.0.0.1:2379", - }), - "http://127.0.0.2:2379,http://127.0.0.1:2379", - }, - } - for i, tt := range tests { - g := tt.us.String() - if g != tt.wstr { - t.Errorf("#%d: string = %s, want %s", i, g, tt.wstr) - } - } -} - -func TestURLsSort(t *testing.T) { - g := testutil.MustNewURLs(t, []string{ - "http://127.0.0.4:2379", - "http://127.0.0.2:2379", - "http://127.0.0.1:2379", - "http://127.0.0.3:2379", - }) - w := testutil.MustNewURLs(t, []string{ - "http://127.0.0.1:2379", - "http://127.0.0.2:2379", - "http://127.0.0.3:2379", - "http://127.0.0.4:2379", - }) - gurls := URLs(g) - gurls.Sort() - if !reflect.DeepEqual(g, w) { - t.Errorf("URLs after sort = %#v, want %#v", g, w) - } -} - -func TestURLsStringSlice(t *testing.T) { - tests := []struct { - us URLs - wstr []string - }{ - { - URLs{}, - []string{}, - }, - { - testutil.MustNewURLs(t, []string{"http://127.0.0.1:2379"}), - []string{"http://127.0.0.1:2379"}, - }, - { - testutil.MustNewURLs(t, []string{ - "http://127.0.0.1:2379", - "http://127.0.0.2:2379", - }), - []string{"http://127.0.0.1:2379", "http://127.0.0.2:2379"}, - }, - { - testutil.MustNewURLs(t, []string{ - "http://127.0.0.2:2379", - "http://127.0.0.1:2379", - }), - []string{"http://127.0.0.2:2379", "http://127.0.0.1:2379"}, - }, - } - for i, tt := range tests { - g := tt.us.StringSlice() - if !reflect.DeepEqual(g, tt.wstr) { - t.Errorf("#%d: string slice = %+v, want %+v", i, g, tt.wstr) - } - } -} - -func TestNewURLsFail(t *testing.T) { - tests := [][]string{ - // no urls given - {}, - // missing protocol scheme - {"://127.0.0.1:2379"}, - // unsupported scheme - {"mailto://127.0.0.1:2379"}, - // not conform to host:port - {"http://127.0.0.1"}, - // contain a path - {"http://127.0.0.1:2379/path"}, - } - for i, tt := range tests { - _, err := NewURLs(tt) - if err == nil { - t.Errorf("#%d: err = nil, but error", i) - } - } -} diff --git a/vendor/github.com/coreos/etcd/pkg/types/urlsmap.go b/vendor/github.com/coreos/etcd/pkg/types/urlsmap.go index a2aa7fe66..47690cc38 100644 --- a/vendor/github.com/coreos/etcd/pkg/types/urlsmap.go +++ b/vendor/github.com/coreos/etcd/pkg/types/urlsmap.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 The etcd Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -16,26 +16,21 @@ package types import ( "fmt" - "net/url" "sort" "strings" ) +// URLsMap is a map from a name to its URLs. type URLsMap map[string]URLs // NewURLsMap returns a URLsMap instantiated from the given string, // which consists of discovery-formatted names-to-URLs, like: // mach0=http://1.1.1.1:2380,mach0=http://2.2.2.2::2380,mach1=http://3.3.3.3:2380,mach2=http://4.4.4.4:2380 func NewURLsMap(s string) (URLsMap, error) { + m := parse(s) + cl := URLsMap{} - v, err := url.ParseQuery(strings.Replace(s, ",", "&", -1)) - if err != nil { - return nil, err - } - for name, urls := range v { - if len(urls) == 0 || urls[0] == "" { - return nil, fmt.Errorf("empty URL given for %q", name) - } + for name, urls := range m { us, err := NewURLs(urls) if err != nil { return nil, err @@ -45,9 +40,23 @@ func NewURLsMap(s string) (URLsMap, error) { return cl, nil } -// String returns NameURLPairs into discovery-formatted name-to-URLs sorted by name. +// NewURLsMapFromStringMap takes a map of strings and returns a URLsMap. The +// string values in the map can be multiple values separated by the sep string. +func NewURLsMapFromStringMap(m map[string]string, sep string) (URLsMap, error) { + var err error + um := URLsMap{} + for k, v := range m { + um[k], err = NewURLs(strings.Split(v, sep)) + if err != nil { + return nil, err + } + } + return um, nil +} + +// String turns URLsMap into discovery-formatted name-to-URLs sorted by name. func (c URLsMap) String() string { - pairs := make([]string, 0) + var pairs []string for name, urls := range c { for _, url := range urls { pairs = append(pairs, fmt.Sprintf("%s=%s", name, url.String())) @@ -60,7 +69,7 @@ func (c URLsMap) String() string { // URLs returns a list of all URLs. // The returned list is sorted in ascending lexicographical order. func (c URLsMap) URLs() []string { - urls := make([]string, 0) + var urls []string for _, us := range c { for _, u := range us { urls = append(urls, u.String()) @@ -70,6 +79,29 @@ func (c URLsMap) URLs() []string { return urls } +// Len returns the size of URLsMap. func (c URLsMap) Len() int { return len(c) } + +// parse parses the given string and returns a map listing the values specified for each key. +func parse(s string) map[string][]string { + m := make(map[string][]string) + for s != "" { + key := s + if i := strings.IndexAny(key, ","); i >= 0 { + key, s = key[:i], key[i+1:] + } else { + s = "" + } + if key == "" { + continue + } + value := "" + if i := strings.Index(key, "="); i >= 0 { + key, value = key[:i], key[i+1:] + } + m[key] = append(m[key], value) + } + return m +} diff --git a/vendor/github.com/coreos/etcd/pkg/types/urlsmap_test.go b/vendor/github.com/coreos/etcd/pkg/types/urlsmap_test.go deleted file mode 100644 index 8b52dc17b..000000000 --- a/vendor/github.com/coreos/etcd/pkg/types/urlsmap_test.go +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright 2015 CoreOS, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package types - -import ( - "reflect" - "testing" - - "github.com/coreos/etcd/pkg/testutil" -) - -func TestParseInitialCluster(t *testing.T) { - c, err := NewURLsMap("mem1=http://10.0.0.1:2379,mem1=http://128.193.4.20:2379,mem2=http://10.0.0.2:2379,default=http://127.0.0.1:2379") - if err != nil { - t.Fatalf("unexpected parse error: %v", err) - } - wc := URLsMap(map[string]URLs{ - "mem1": testutil.MustNewURLs(t, []string{"http://10.0.0.1:2379", "http://128.193.4.20:2379"}), - "mem2": testutil.MustNewURLs(t, []string{"http://10.0.0.2:2379"}), - "default": testutil.MustNewURLs(t, []string{"http://127.0.0.1:2379"}), - }) - if !reflect.DeepEqual(c, wc) { - t.Errorf("cluster = %+v, want %+v", c, wc) - } -} - -func TestParseInitialClusterBad(t *testing.T) { - tests := []string{ - // invalid URL - "%^", - // no URL defined for member - "mem1=,mem2=http://128.193.4.20:2379,mem3=http://10.0.0.2:2379", - "mem1,mem2=http://128.193.4.20:2379,mem3=http://10.0.0.2:2379", - // bad URL for member - "default=http://localhost/", - } - for i, tt := range tests { - if _, err := NewURLsMap(tt); err == nil { - t.Errorf("#%d: unexpected successful parse, want err", i) - } - } -} - -func TestNameURLPairsString(t *testing.T) { - cls := URLsMap(map[string]URLs{ - "abc": testutil.MustNewURLs(t, []string{"http://1.1.1.1:1111", "http://0.0.0.0:0000"}), - "def": testutil.MustNewURLs(t, []string{"http://2.2.2.2:2222"}), - "ghi": testutil.MustNewURLs(t, []string{"http://3.3.3.3:1234", "http://127.0.0.1:2380"}), - // no PeerURLs = not included - "four": testutil.MustNewURLs(t, []string{}), - "five": testutil.MustNewURLs(t, nil), - }) - w := "abc=http://0.0.0.0:0000,abc=http://1.1.1.1:1111,def=http://2.2.2.2:2222,ghi=http://127.0.0.1:2380,ghi=http://3.3.3.3:1234" - if g := cls.String(); g != w { - t.Fatalf("NameURLPairs.String():\ngot %#v\nwant %#v", g, w) - } -} diff --git a/vendor/github.com/coreos/go-semver/LICENSE b/vendor/github.com/coreos/go-semver/LICENSE new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/vendor/github.com/coreos/go-semver/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/coreos/go-semver/example.go b/vendor/github.com/coreos/go-semver/example.go new file mode 100644 index 000000000..fd2ee5af2 --- /dev/null +++ b/vendor/github.com/coreos/go-semver/example.go @@ -0,0 +1,20 @@ +package main + +import ( + "fmt" + "github.com/coreos/go-semver/semver" + "os" +) + +func main() { + vA, err := semver.NewVersion(os.Args[1]) + if err != nil { + fmt.Println(err.Error()) + } + vB, err := semver.NewVersion(os.Args[2]) + if err != nil { + fmt.Println(err.Error()) + } + + fmt.Printf("%s < %s == %t\n", vA, vB, vA.LessThan(*vB)) +} diff --git a/vendor/github.com/coreos/go-semver/semver/semver.go b/vendor/github.com/coreos/go-semver/semver/semver.go index 26ca40e69..000a02058 100644 --- a/vendor/github.com/coreos/go-semver/semver/semver.go +++ b/vendor/github.com/coreos/go-semver/semver/semver.go @@ -1,3 +1,18 @@ +// Copyright 2013-2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Semantic Versions http://semver.org package semver import ( @@ -32,15 +47,15 @@ func splitOff(input *string, delim string) (val string) { func NewVersion(version string) (*Version, error) { v := Version{} + v.Metadata = splitOff(&version, "+") + v.PreRelease = PreRelease(splitOff(&version, "-")) + dotParts := strings.SplitN(version, ".", 3) if len(dotParts) != 3 { return nil, errors.New(fmt.Sprintf("%s is not in dotted-tri format", version)) } - v.Metadata = splitOff(&dotParts[2], "+") - v.PreRelease = PreRelease(splitOff(&dotParts[2], "-")) - parsed := make([]int64, 3, 3) for i, v := range dotParts[:3] { @@ -58,25 +73,64 @@ func NewVersion(version string) (*Version, error) { return &v, nil } -func (v *Version) String() string { +func Must(v *Version, err error) *Version { + if err != nil { + panic(err) + } + return v +} + +func (v Version) String() string { var buffer bytes.Buffer - base := fmt.Sprintf("%d.%d.%d", v.Major, v.Minor, v.Patch) - buffer.WriteString(base) + fmt.Fprintf(&buffer, "%d.%d.%d", v.Major, v.Minor, v.Patch) if v.PreRelease != "" { - buffer.WriteString(fmt.Sprintf("-%s", v.PreRelease)) + fmt.Fprintf(&buffer, "-%s", v.PreRelease) } if v.Metadata != "" { - buffer.WriteString(fmt.Sprintf("+%s", v.Metadata)) + fmt.Fprintf(&buffer, "+%s", v.Metadata) } return buffer.String() } -func (v *Version) LessThan(versionB Version) bool { - versionA := *v +func (v *Version) UnmarshalYAML(unmarshal func(interface{}) error) error { + var data string + if err := unmarshal(&data); err != nil { + return err + } + vv, err := NewVersion(data) + if err != nil { + return err + } + *v = *vv + return nil +} + +func (v Version) MarshalJSON() ([]byte, error) { + return []byte(`"` + v.String() + `"`), nil +} + +func (v *Version) UnmarshalJSON(data []byte) error { + l := len(data) + if l == 0 || string(data) == `""` { + return nil + } + if l < 2 || data[0] != '"' || data[l-1] != '"' { + return errors.New("invalid semver string") + } + vv, err := NewVersion(string(data[1 : l-1])) + if err != nil { + return err + } + *v = *vv + return nil +} + +func (v Version) LessThan(versionB Version) bool { + versionA := v cmp := recursiveCompare(versionA.Slice(), versionB.Slice()) if cmp == 0 { @@ -91,12 +145,12 @@ func (v *Version) LessThan(versionB Version) bool { } /* Slice converts the comparable parts of the semver into a slice of strings */ -func (v *Version) Slice() []int64 { +func (v Version) Slice() []int64 { return []int64{v.Major, v.Minor, v.Patch} } -func (p *PreRelease) Slice() []string { - preRelease := string(*p) +func (p PreRelease) Slice() []string { + preRelease := string(p) return strings.Split(preRelease, ".") } @@ -146,7 +200,8 @@ func recursivePreReleaseCompare(versionA []string, versionB []string) int { a := versionA[0] b := versionB[0] - aInt := false; bInt := false + aInt := false + bInt := false aI, err := strconv.Atoi(versionA[0]) if err == nil { @@ -176,3 +231,27 @@ func recursivePreReleaseCompare(versionA []string, versionB []string) int { return recursivePreReleaseCompare(versionA[1:], versionB[1:]) } + +// BumpMajor increments the Major field by 1 and resets all other fields to their default values +func (v *Version) BumpMajor() { + v.Major += 1 + v.Minor = 0 + v.Patch = 0 + v.PreRelease = PreRelease("") + v.Metadata = "" +} + +// BumpMinor increments the Minor field by 1 and resets all other fields to their default values +func (v *Version) BumpMinor() { + v.Minor += 1 + v.Patch = 0 + v.PreRelease = PreRelease("") + v.Metadata = "" +} + +// BumpPatch increments the Patch field by 1 and resets all other fields to their default values +func (v *Version) BumpPatch() { + v.Patch += 1 + v.PreRelease = PreRelease("") + v.Metadata = "" +} diff --git a/vendor/github.com/coreos/go-semver/semver/semver_test.go b/vendor/github.com/coreos/go-semver/semver/semver_test.go deleted file mode 100644 index 06700741b..000000000 --- a/vendor/github.com/coreos/go-semver/semver/semver_test.go +++ /dev/null @@ -1,125 +0,0 @@ -package semver - -import ( - "math/rand" - "testing" - "time" -) - -type fixture struct { - greaterVersion string - lesserVersion string -} - -var fixtures = []fixture{ - fixture{"0.0.0", "0.0.0-foo"}, - fixture{"0.0.1", "0.0.0"}, - fixture{"1.0.0", "0.9.9"}, - fixture{"0.10.0", "0.9.0"}, - fixture{"0.99.0", "0.10.0"}, - fixture{"2.0.0", "1.2.3"}, - fixture{"0.0.0", "0.0.0-foo"}, - fixture{"0.0.1", "0.0.0"}, - fixture{"1.0.0", "0.9.9"}, - fixture{"0.10.0", "0.9.0"}, - fixture{"0.99.0", "0.10.0"}, - fixture{"2.0.0", "1.2.3"}, - fixture{"0.0.0", "0.0.0-foo"}, - fixture{"0.0.1", "0.0.0"}, - fixture{"1.0.0", "0.9.9"}, - fixture{"0.10.0", "0.9.0"}, - fixture{"0.99.0", "0.10.0"}, - fixture{"2.0.0", "1.2.3"}, - fixture{"1.2.3", "1.2.3-asdf"}, - fixture{"1.2.3", "1.2.3-4"}, - fixture{"1.2.3", "1.2.3-4-foo"}, - fixture{"1.2.3-5-foo", "1.2.3-5"}, - fixture{"1.2.3-5", "1.2.3-4"}, - fixture{"1.2.3-5-foo", "1.2.3-5-Foo"}, - fixture{"3.0.0", "2.7.2+asdf"}, - fixture{"3.0.0+foobar", "2.7.2"}, - fixture{"1.2.3-a.10", "1.2.3-a.5"}, - fixture{"1.2.3-a.b", "1.2.3-a.5"}, - fixture{"1.2.3-a.b", "1.2.3-a"}, - fixture{"1.2.3-a.b.c.10.d.5", "1.2.3-a.b.c.5.d.100"}, - fixture{"1.0.0", "1.0.0-rc.1"}, - fixture{"1.0.0-rc.2", "1.0.0-rc.1"}, - fixture{"1.0.0-rc.1", "1.0.0-beta.11"}, - fixture{"1.0.0-beta.11", "1.0.0-beta.2"}, - fixture{"1.0.0-beta.2", "1.0.0-beta"}, - fixture{"1.0.0-beta", "1.0.0-alpha.beta"}, - fixture{"1.0.0-alpha.beta", "1.0.0-alpha.1"}, - fixture{"1.0.0-alpha.1", "1.0.0-alpha"}, -} - -func TestCompare(t *testing.T) { - for _, v := range fixtures { - gt, err := NewVersion(v.greaterVersion) - if err != nil { - t.Error(err) - } - - lt, err := NewVersion(v.lesserVersion) - if err != nil { - t.Error(err) - } - - if gt.LessThan(*lt) == true { - t.Errorf("%s should not be less than %s", gt, lt) - } - } -} - -func testString(t *testing.T, orig string, version *Version) { - if orig != version.String() { - t.Errorf("%s != %s", orig, version) - } -} - -func TestString(t *testing.T) { - for _, v := range fixtures { - gt, err := NewVersion(v.greaterVersion) - if err != nil { - t.Error(err) - } - testString(t, v.greaterVersion, gt) - - lt, err := NewVersion(v.lesserVersion) - if err != nil { - t.Error(err) - } - testString(t, v.lesserVersion, lt) - } -} - -func shuffleStringSlice(src []string) []string { - dest := make([]string, len(src)) - rand.Seed(time.Now().Unix()) - perm := rand.Perm(len(src)) - for i, v := range perm { - dest[v] = src[i] - } - return dest -} - -func TestSort(t *testing.T) { - sortedVersions := []string{"1.0.0", "1.0.2", "1.2.0", "3.1.1"} - unsortedVersions := shuffleStringSlice(sortedVersions) - - semvers := []*Version{} - for _, v := range unsortedVersions { - sv, err := NewVersion(v) - if err != nil { - t.Fatal(err) - } - semvers = append(semvers, sv) - } - - Sort(semvers) - - for idx, sv := range semvers { - if sv.String() != sortedVersions[idx] { - t.Fatalf("incorrect sort at index %v", idx) - } - } -} diff --git a/vendor/github.com/coreos/go-semver/semver/sort.go b/vendor/github.com/coreos/go-semver/semver/sort.go index 86203007a..e256b41a5 100644 --- a/vendor/github.com/coreos/go-semver/semver/sort.go +++ b/vendor/github.com/coreos/go-semver/semver/sort.go @@ -1,3 +1,17 @@ +// Copyright 2013-2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package semver import ( diff --git a/vendor/github.com/coreos/go-systemd/LICENSE b/vendor/github.com/coreos/go-systemd/LICENSE new file mode 100644 index 000000000..37ec93a14 --- /dev/null +++ b/vendor/github.com/coreos/go-systemd/LICENSE @@ -0,0 +1,191 @@ +Apache License +Version 2.0, January 2004 +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and +distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright +owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities +that control, are controlled by, or are under common control with that entity. +For the purposes of this definition, "control" means (i) the power, direct or +indirect, to cause the direction or management of such entity, whether by +contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the +outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising +permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including +but not limited to software source code, documentation source, and configuration +files. + +"Object" form shall mean any form resulting from mechanical transformation or +translation of a Source form, including but not limited to compiled object code, +generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made +available under the License, as indicated by a copyright notice that is included +in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that +is based on (or derived from) the Work and for which the editorial revisions, +annotations, elaborations, or other modifications represent, as a whole, an +original work of authorship. For the purposes of this License, Derivative Works +shall not include works that remain separable from, or merely link (or bind by +name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version +of the Work and any modifications or additions to that Work or Derivative Works +thereof, that is intentionally submitted to Licensor for inclusion in the Work +by the copyright owner or by an individual or Legal Entity authorized to submit +on behalf of the copyright owner. For the purposes of this definition, +"submitted" means any form of electronic, verbal, or written communication sent +to the Licensor or its representatives, including but not limited to +communication on electronic mailing lists, source code control systems, and +issue tracking systems that are managed by, or on behalf of, the Licensor for +the purpose of discussing and improving the Work, but excluding communication +that is conspicuously marked or otherwise designated in writing by the copyright +owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf +of whom a Contribution has been received by Licensor and subsequently +incorporated within the Work. + +2. Grant of Copyright License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable copyright license to reproduce, prepare Derivative Works of, +publicly display, publicly perform, sublicense, and distribute the Work and such +Derivative Works in Source or Object form. + +3. Grant of Patent License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable (except as stated in this section) patent license to make, have +made, use, offer to sell, sell, import, and otherwise transfer the Work, where +such license applies only to those patent claims licensable by such Contributor +that are necessarily infringed by their Contribution(s) alone or by combination +of their Contribution(s) with the Work to which such Contribution(s) was +submitted. If You institute patent litigation against any entity (including a +cross-claim or counterclaim in a lawsuit) alleging that the Work or a +Contribution incorporated within the Work constitutes direct or contributory +patent infringement, then any patent licenses granted to You under this License +for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. + +You may reproduce and distribute copies of the Work or Derivative Works thereof +in any medium, with or without modifications, and in Source or Object form, +provided that You meet the following conditions: + +You must give any other recipients of the Work or Derivative Works a copy of +this License; and +You must cause any modified files to carry prominent notices stating that You +changed the files; and +You must retain, in the Source form of any Derivative Works that You distribute, +all copyright, patent, trademark, and attribution notices from the Source form +of the Work, excluding those notices that do not pertain to any part of the +Derivative Works; and +If the Work includes a "NOTICE" text file as part of its distribution, then any +Derivative Works that You distribute must include a readable copy of the +attribution notices contained within such NOTICE file, excluding those notices +that do not pertain to any part of the Derivative Works, in at least one of the +following places: within a NOTICE text file distributed as part of the +Derivative Works; within the Source form or documentation, if provided along +with the Derivative Works; or, within a display generated by the Derivative +Works, if and wherever such third-party notices normally appear. The contents of +the NOTICE file are for informational purposes only and do not modify the +License. You may add Your own attribution notices within Derivative Works that +You distribute, alongside or as an addendum to the NOTICE text from the Work, +provided that such additional attribution notices cannot be construed as +modifying the License. +You may add Your own copyright statement to Your modifications and may provide +additional or different license terms and conditions for use, reproduction, or +distribution of Your modifications, or for any such Derivative Works as a whole, +provided Your use, reproduction, and distribution of the Work otherwise complies +with the conditions stated in this License. + +5. Submission of Contributions. + +Unless You explicitly state otherwise, any Contribution intentionally submitted +for inclusion in the Work by You to the Licensor shall be under the terms and +conditions of this License, without any additional terms or conditions. +Notwithstanding the above, nothing herein shall supersede or modify the terms of +any separate license agreement you may have executed with Licensor regarding +such Contributions. + +6. Trademarks. + +This License does not grant permission to use the trade names, trademarks, +service marks, or product names of the Licensor, except as required for +reasonable and customary use in describing the origin of the Work and +reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. + +Unless required by applicable law or agreed to in writing, Licensor provides the +Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, +including, without limitation, any warranties or conditions of TITLE, +NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are +solely responsible for determining the appropriateness of using or +redistributing the Work and assume any risks associated with Your exercise of +permissions under this License. + +8. Limitation of Liability. + +In no event and under no legal theory, whether in tort (including negligence), +contract, or otherwise, unless required by applicable law (such as deliberate +and grossly negligent acts) or agreed to in writing, shall any Contributor be +liable to You for damages, including any direct, indirect, special, incidental, +or consequential damages of any character arising as a result of this License or +out of the use or inability to use the Work (including but not limited to +damages for loss of goodwill, work stoppage, computer failure or malfunction, or +any and all other commercial damages or losses), even if such Contributor has +been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. + +While redistributing the Work or Derivative Works thereof, You may choose to +offer, and charge a fee for, acceptance of support, warranty, indemnity, or +other liability obligations and/or rights consistent with this License. However, +in accepting such obligations, You may act only on Your own behalf and on Your +sole responsibility, not on behalf of any other Contributor, and only if You +agree to indemnify, defend, and hold each Contributor harmless for any liability +incurred by, or claims asserted against, such Contributor by reason of your +accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work + +To apply the Apache License to your work, attach the following boilerplate +notice, with the fields enclosed by brackets "[]" replaced with your own +identifying information. (Don't include the brackets!) The text should be +enclosed in the appropriate comment syntax for the file format. We also +recommend that a file or class name and description of purpose be included on +the same "printed page" as the copyright notice for easier identification within +third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/coreos/go-systemd/activation/files_test.go b/vendor/github.com/coreos/go-systemd/activation/files_test.go deleted file mode 100644 index 8e15f2a10..000000000 --- a/vendor/github.com/coreos/go-systemd/activation/files_test.go +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright 2015 CoreOS, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package activation - -import ( - "bytes" - "io" - "os" - "os/exec" - "testing" -) - -// correctStringWritten fails the text if the correct string wasn't written -// to the other side of the pipe. -func correctStringWritten(t *testing.T, r *os.File, expected string) bool { - bytes := make([]byte, len(expected)) - io.ReadAtLeast(r, bytes, len(expected)) - - if string(bytes) != expected { - t.Fatalf("Unexpected string %s", string(bytes)) - } - - return true -} - -// TestActivation forks out a copy of activation.go example and reads back two -// strings from the pipes that are passed in. -func TestActivation(t *testing.T) { - cmd := exec.Command("go", "run", "../examples/activation/activation.go") - - r1, w1, _ := os.Pipe() - r2, w2, _ := os.Pipe() - cmd.ExtraFiles = []*os.File{ - w1, - w2, - } - - cmd.Env = os.Environ() - cmd.Env = append(cmd.Env, "LISTEN_FDS=2", "FIX_LISTEN_PID=1") - - err := cmd.Run() - if err != nil { - t.Fatalf(err.Error()) - } - - correctStringWritten(t, r1, "Hello world") - correctStringWritten(t, r2, "Goodbye world") -} - -func TestActivationNoFix(t *testing.T) { - cmd := exec.Command("go", "run", "../examples/activation/activation.go") - cmd.Env = os.Environ() - cmd.Env = append(cmd.Env, "LISTEN_FDS=2") - - out, _ := cmd.CombinedOutput() - if bytes.Contains(out, []byte("No files")) == false { - t.Fatalf("Child didn't error out as expected") - } -} - -func TestActivationNoFiles(t *testing.T) { - cmd := exec.Command("go", "run", "../examples/activation/activation.go") - cmd.Env = os.Environ() - cmd.Env = append(cmd.Env, "LISTEN_FDS=0", "FIX_LISTEN_PID=1") - - out, _ := cmd.CombinedOutput() - if bytes.Contains(out, []byte("No files")) == false { - t.Fatalf("Child didn't error out as expected") - } -} diff --git a/vendor/github.com/coreos/go-systemd/activation/listeners_test.go b/vendor/github.com/coreos/go-systemd/activation/listeners_test.go deleted file mode 100644 index 72fb0ff62..000000000 --- a/vendor/github.com/coreos/go-systemd/activation/listeners_test.go +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright 2015 CoreOS, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package activation - -import ( - "io" - "net" - "os" - "os/exec" - "testing" -) - -// correctStringWritten fails the text if the correct string wasn't written -// to the other side of the pipe. -func correctStringWrittenNet(t *testing.T, r net.Conn, expected string) bool { - bytes := make([]byte, len(expected)) - io.ReadAtLeast(r, bytes, len(expected)) - - if string(bytes) != expected { - t.Fatalf("Unexpected string %s", string(bytes)) - } - - return true -} - -// TestActivation forks out a copy of activation.go example and reads back two -// strings from the pipes that are passed in. -func TestListeners(t *testing.T) { - cmd := exec.Command("go", "run", "../examples/activation/listen.go") - - l1, err := net.Listen("tcp", ":9999") - if err != nil { - t.Fatalf(err.Error()) - } - l2, err := net.Listen("tcp", ":1234") - if err != nil { - t.Fatalf(err.Error()) - } - - t1 := l1.(*net.TCPListener) - t2 := l2.(*net.TCPListener) - - f1, _ := t1.File() - f2, _ := t2.File() - - cmd.ExtraFiles = []*os.File{ - f1, - f2, - } - - r1, err := net.Dial("tcp", "127.0.0.1:9999") - if err != nil { - t.Fatalf(err.Error()) - } - r1.Write([]byte("Hi")) - - r2, err := net.Dial("tcp", "127.0.0.1:1234") - if err != nil { - t.Fatalf(err.Error()) - } - r2.Write([]byte("Hi")) - - cmd.Env = os.Environ() - cmd.Env = append(cmd.Env, "LISTEN_FDS=2", "FIX_LISTEN_PID=1") - - out, err := cmd.Output() - if err != nil { - println(string(out)) - t.Fatalf(err.Error()) - } - - correctStringWrittenNet(t, r1, "Hello world") - correctStringWrittenNet(t, r2, "Goodbye world") -} diff --git a/vendor/github.com/coreos/go-systemd/activation/packetconns_test.go b/vendor/github.com/coreos/go-systemd/activation/packetconns_test.go deleted file mode 100644 index 8449756cb..000000000 --- a/vendor/github.com/coreos/go-systemd/activation/packetconns_test.go +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright 2015 CoreOS, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package activation - -import ( - "net" - "os" - "os/exec" - "testing" -) - -// TestActivation forks out a copy of activation.go example and reads back two -// strings from the pipes that are passed in. -func TestPacketConns(t *testing.T) { - cmd := exec.Command("go", "run", "../examples/activation/udpconn.go") - - u1, err := net.ListenUDP("udp", &net.UDPAddr{Port: 9999}) - if err != nil { - t.Fatalf(err.Error()) - } - u2, err := net.ListenUDP("udp", &net.UDPAddr{Port: 1234}) - if err != nil { - t.Fatalf(err.Error()) - } - - f1, _ := u1.File() - f2, _ := u2.File() - - cmd.ExtraFiles = []*os.File{ - f1, - f2, - } - - r1, err := net.Dial("udp", "127.0.0.1:9999") - if err != nil { - t.Fatalf(err.Error()) - } - r1.Write([]byte("Hi")) - - r2, err := net.Dial("udp", "127.0.0.1:1234") - if err != nil { - t.Fatalf(err.Error()) - } - r2.Write([]byte("Hi")) - - cmd.Env = os.Environ() - cmd.Env = append(cmd.Env, "LISTEN_FDS=2", "FIX_LISTEN_PID=1") - - out, err := cmd.CombinedOutput() - if err != nil { - t.Fatalf("Cmd output '%s', err: '%s'\n", out, err) - } - - correctStringWrittenNet(t, r1, "Hello world") - correctStringWrittenNet(t, r2, "Goodbye world") -} diff --git a/vendor/github.com/coreos/go-systemd/dbus/dbus_test.go b/vendor/github.com/coreos/go-systemd/dbus/dbus_test.go deleted file mode 100644 index 3ea131e20..000000000 --- a/vendor/github.com/coreos/go-systemd/dbus/dbus_test.go +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright 2015 CoreOS, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package dbus - -import ( - "testing" -) - -func TestNeedsEscape(t *testing.T) { - // Anything not 0-9a-zA-Z should always be escaped - for want, vals := range map[bool][]byte{ - false: []byte{'a', 'b', 'z', 'A', 'Q', '1', '4', '9'}, - true: []byte{'#', '%', '$', '!', '.', '_', '-', '%', '\\'}, - } { - for i := 1; i < 10; i++ { - for _, b := range vals { - got := needsEscape(i, b) - if got != want { - t.Errorf("needsEscape(%d, %c) returned %t, want %t", i, b, got, want) - } - } - } - } - - // 0-9 in position 0 should be escaped - for want, vals := range map[bool][]byte{ - false: []byte{'A', 'a', 'e', 'x', 'Q', 'Z'}, - true: []byte{'0', '4', '5', '9'}, - } { - for _, b := range vals { - got := needsEscape(0, b) - if got != want { - t.Errorf("needsEscape(0, %c) returned %t, want %t", b, got, want) - } - } - } - -} - -func TestPathBusEscape(t *testing.T) { - for in, want := range map[string]string{ - "": "_", - "foo.service": "foo_2eservice", - "foobar": "foobar", - "woof@woof.service": "woof_40woof_2eservice", - "0123456": "_30123456", - "account_db.service": "account_5fdb_2eservice", - "got-dashes": "got_2ddashes", - } { - got := PathBusEscape(in) - if got != want { - t.Errorf("bad result for PathBusEscape(%s): got %q, want %q", in, got, want) - } - } - -} - -// TestNew ensures that New() works without errors. -func TestNew(t *testing.T) { - _, err := New() - - if err != nil { - t.Fatal(err) - } -} diff --git a/vendor/github.com/coreos/go-systemd/dbus/methods_test.go b/vendor/github.com/coreos/go-systemd/dbus/methods_test.go deleted file mode 100644 index 4da8fc93f..000000000 --- a/vendor/github.com/coreos/go-systemd/dbus/methods_test.go +++ /dev/null @@ -1,518 +0,0 @@ -// Copyright 2015 CoreOS, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package dbus - -import ( - "fmt" - "math/rand" - "os" - "path" - "path/filepath" - "reflect" - "testing" - - "github.com/godbus/dbus" -) - -func setupConn(t *testing.T) *Conn { - conn, err := New() - if err != nil { - t.Fatal(err) - } - - return conn -} - -func findFixture(target string, t *testing.T) string { - abs, err := filepath.Abs("../fixtures/" + target) - if err != nil { - t.Fatal(err) - } - return abs -} - -func setupUnit(target string, conn *Conn, t *testing.T) { - // Blindly stop the unit in case it is running - conn.StopUnit(target, "replace", nil) - - // Blindly remove the symlink in case it exists - targetRun := filepath.Join("/run/systemd/system/", target) - os.Remove(targetRun) -} - -func linkUnit(target string, conn *Conn, t *testing.T) { - abs := findFixture(target, t) - fixture := []string{abs} - - changes, err := conn.LinkUnitFiles(fixture, true, true) - if err != nil { - t.Fatal(err) - } - - if len(changes) < 1 { - t.Fatalf("Expected one change, got %v", changes) - } - - runPath := filepath.Join("/run/systemd/system/", target) - if changes[0].Filename != runPath { - t.Fatal("Unexpected target filename") - } -} - -func getUnitStatus(units []UnitStatus, name string) *UnitStatus { - for _, u := range units { - if u.Name == name { - return &u - } - } - return nil -} - -func getUnitFile(units []UnitFile, name string) *UnitFile { - for _, u := range units { - if path.Base(u.Path) == name { - return &u - } - } - return nil -} - -// Ensure that basic unit starting and stopping works. -func TestStartStopUnit(t *testing.T) { - target := "start-stop.service" - conn := setupConn(t) - - setupUnit(target, conn, t) - linkUnit(target, conn, t) - - // 2. Start the unit - reschan := make(chan string) - _, err := conn.StartUnit(target, "replace", reschan) - if err != nil { - t.Fatal(err) - } - - job := <-reschan - if job != "done" { - t.Fatal("Job is not done:", job) - } - - units, err := conn.ListUnits() - - unit := getUnitStatus(units, target) - - if unit == nil { - t.Fatalf("Test unit not found in list") - } else if unit.ActiveState != "active" { - t.Fatalf("Test unit not active") - } - - // 3. Stop the unit - _, err = conn.StopUnit(target, "replace", reschan) - if err != nil { - t.Fatal(err) - } - - // wait for StopUnit job to complete - <-reschan - - units, err = conn.ListUnits() - - unit = getUnitStatus(units, target) - - if unit != nil { - t.Fatalf("Test unit found in list, should be stopped") - } -} - -// Ensure that ListUnitsByNames works. -func TestListUnitsByNames(t *testing.T) { - target1 := "systemd-journald.service" - target2 := "unexisting.service" - - conn := setupConn(t) - - units, err := conn.ListUnitsByNames([]string{target1, target2}) - - if err != nil { - t.Skip(err) - } - - unit := getUnitStatus(units, target1) - - if unit == nil { - t.Fatalf("%s unit not found in list", target1) - } else if unit.ActiveState != "active" { - t.Fatalf("%s unit should be active but it is %s", target1, unit.ActiveState) - } - - unit = getUnitStatus(units, target2) - - if unit == nil { - t.Fatalf("Unexisting test unit not found in list") - } else if unit.ActiveState != "inactive" { - t.Fatalf("Test unit should be inactive") - } -} - -// Ensure that ListUnitsByPatterns works. -func TestListUnitsByPatterns(t *testing.T) { - target1 := "systemd-journald.service" - target2 := "unexisting.service" - - conn := setupConn(t) - - units, err := conn.ListUnitsByPatterns([]string{}, []string{"systemd-journald*", target2}) - - if err != nil { - t.Skip(err) - } - - unit := getUnitStatus(units, target1) - - if unit == nil { - t.Fatalf("%s unit not found in list", target1) - } else if unit.ActiveState != "active" { - t.Fatalf("Test unit should be active") - } - - unit = getUnitStatus(units, target2) - - if unit != nil { - t.Fatalf("Unexisting test unit found in list") - } -} - -// Ensure that ListUnitsFiltered works. -func TestListUnitsFiltered(t *testing.T) { - target := "systemd-journald.service" - - conn := setupConn(t) - - units, err := conn.ListUnitsFiltered([]string{"active"}) - - if err != nil { - t.Fatal(err) - } - - unit := getUnitStatus(units, target) - - if unit == nil { - t.Fatalf("%s unit not found in list", target) - } else if unit.ActiveState != "active" { - t.Fatalf("Test unit should be active") - } - - units, err = conn.ListUnitsFiltered([]string{"inactive"}) - - if err != nil { - t.Fatal(err) - } - - unit = getUnitStatus(units, target) - - if unit != nil { - t.Fatalf("Inactive unit should not be found in list") - } -} - -// Ensure that ListUnitFilesByPatterns works. -func TestListUnitFilesByPatterns(t *testing.T) { - target1 := "systemd-journald.service" - target2 := "exit.target" - - conn := setupConn(t) - - units, err := conn.ListUnitFilesByPatterns([]string{"static"}, []string{"systemd-journald*", target2}) - - if err != nil { - t.Skip(err) - } - - unit := getUnitFile(units, target1) - - if unit == nil { - t.Fatalf("%s unit not found in list", target1) - } else if unit.Type != "static" { - t.Fatalf("Test unit file should be static") - } - - units, err = conn.ListUnitFilesByPatterns([]string{"disabled"}, []string{"systemd-journald*", target2}) - - if err != nil { - t.Fatal(err) - } - - unit = getUnitFile(units, target2) - - if unit == nil { - t.Fatalf("%s unit not found in list", target2) - } else if unit.Type != "disabled" { - t.Fatalf("%s unit file should be disabled", target2) - } -} - -func TestListUnitFiles(t *testing.T) { - target1 := "systemd-journald.service" - target2 := "exit.target" - - conn := setupConn(t) - - units, err := conn.ListUnitFiles() - - if err != nil { - t.Fatal(err) - } - - unit := getUnitFile(units, target1) - - if unit == nil { - t.Fatalf("%s unit not found in list", target1) - } else if unit.Type != "static" { - t.Fatalf("Test unit file should be static") - } - - unit = getUnitFile(units, target2) - - if unit == nil { - t.Fatalf("%s unit not found in list", target2) - } else if unit.Type != "disabled" { - t.Fatalf("%s unit file should be disabled", target2) - } -} - -// Enables a unit and then immediately tears it down -func TestEnableDisableUnit(t *testing.T) { - target := "enable-disable.service" - conn := setupConn(t) - - setupUnit(target, conn, t) - abs := findFixture(target, t) - runPath := filepath.Join("/run/systemd/system/", target) - - // 1. Enable the unit - install, changes, err := conn.EnableUnitFiles([]string{abs}, true, true) - if err != nil { - t.Fatal(err) - } - - if install != false { - t.Fatal("Install was true") - } - - if len(changes) < 1 { - t.Fatalf("Expected one change, got %v", changes) - } - - if changes[0].Filename != runPath { - t.Fatal("Unexpected target filename") - } - - // 2. Disable the unit - dChanges, err := conn.DisableUnitFiles([]string{abs}, true) - if err != nil { - t.Fatal(err) - } - - if len(dChanges) != 1 { - t.Fatalf("Changes should include the path, %v", dChanges) - } - if dChanges[0].Filename != runPath { - t.Fatalf("Change should include correct filename, %+v", dChanges[0]) - } - if dChanges[0].Destination != "" { - t.Fatalf("Change destination should be empty, %+v", dChanges[0]) - } -} - -// TestGetUnitProperties reads the `-.mount` which should exist on all systemd -// systems and ensures that one of its properties is valid. -func TestGetUnitProperties(t *testing.T) { - conn := setupConn(t) - - unit := "-.mount" - - info, err := conn.GetUnitProperties(unit) - if err != nil { - t.Fatal(err) - } - - names := info["Wants"].([]string) - - if len(names) < 1 { - t.Fatal("/ is unwanted") - } - - if names[0] != "system.slice" { - t.Fatal("unexpected wants for /") - } - - prop, err := conn.GetUnitProperty(unit, "Wants") - if err != nil { - t.Fatal(err) - } - - if prop.Name != "Wants" { - t.Fatal("unexpected property name") - } - - val := prop.Value.Value().([]string) - if !reflect.DeepEqual(val, names) { - t.Fatal("unexpected property value") - } -} - -// TestGetUnitPropertiesRejectsInvalidName attempts to get the properties for a -// unit with an invalid name. This test should be run with --test.timeout set, -// as a fail will manifest as GetUnitProperties hanging indefinitely. -func TestGetUnitPropertiesRejectsInvalidName(t *testing.T) { - conn := setupConn(t) - - unit := "//invalid#$^/" - - _, err := conn.GetUnitProperties(unit) - if err == nil { - t.Fatal("Expected an error, got nil") - } - - _, err = conn.GetUnitProperty(unit, "Wants") - if err == nil { - t.Fatal("Expected an error, got nil") - } -} - -// TestGetServiceProperty reads the `systemd-udevd.service` which should exist -// on all systemd systems and ensures that one of its property is valid. -func TestGetServiceProperty(t *testing.T) { - conn := setupConn(t) - - service := "systemd-udevd.service" - - prop, err := conn.GetServiceProperty(service, "Type") - if err != nil { - t.Fatal(err) - } - - if prop.Name != "Type" { - t.Fatal("unexpected property name") - } - - value := prop.Value.Value().(string) - if value != "notify" { - t.Fatal("unexpected property value") - } -} - -// TestSetUnitProperties changes a cgroup setting on the `tmp.mount` -// which should exist on all systemd systems and ensures that the -// property was set. -func TestSetUnitProperties(t *testing.T) { - conn := setupConn(t) - - unit := "tmp.mount" - - if err := conn.SetUnitProperties(unit, true, Property{"CPUShares", dbus.MakeVariant(uint64(1023))}); err != nil { - t.Fatal(err) - } - - info, err := conn.GetUnitTypeProperties(unit, "Mount") - if err != nil { - t.Fatal(err) - } - - value := info["CPUShares"].(uint64) - if value != 1023 { - t.Fatal("CPUShares of unit is not 1023:", value) - } -} - -// Ensure that basic transient unit starting and stopping works. -func TestStartStopTransientUnit(t *testing.T) { - conn := setupConn(t) - - props := []Property{ - PropExecStart([]string{"/bin/sleep", "400"}, false), - } - target := fmt.Sprintf("testing-transient-%d.service", rand.Int()) - - // Start the unit - reschan := make(chan string) - _, err := conn.StartTransientUnit(target, "replace", props, reschan) - if err != nil { - t.Fatal(err) - } - - job := <-reschan - if job != "done" { - t.Fatal("Job is not done:", job) - } - - units, err := conn.ListUnits() - - unit := getUnitStatus(units, target) - - if unit == nil { - t.Fatalf("Test unit not found in list") - } else if unit.ActiveState != "active" { - t.Fatalf("Test unit not active") - } - - // 3. Stop the unit - _, err = conn.StopUnit(target, "replace", reschan) - if err != nil { - t.Fatal(err) - } - - // wait for StopUnit job to complete - <-reschan - - units, err = conn.ListUnits() - - unit = getUnitStatus(units, target) - - if unit != nil { - t.Fatalf("Test unit found in list, should be stopped") - } -} - -func TestConnJobListener(t *testing.T) { - target := "start-stop.service" - conn := setupConn(t) - - setupUnit(target, conn, t) - linkUnit(target, conn, t) - - jobSize := len(conn.jobListener.jobs) - - reschan := make(chan string) - _, err := conn.StartUnit(target, "replace", reschan) - if err != nil { - t.Fatal(err) - } - - <-reschan - - _, err = conn.StopUnit(target, "replace", reschan) - if err != nil { - t.Fatal(err) - } - - <-reschan - - currentJobSize := len(conn.jobListener.jobs) - if jobSize != currentJobSize { - t.Fatal("JobListener jobs leaked") - } -} diff --git a/vendor/github.com/coreos/go-systemd/dbus/set_test.go b/vendor/github.com/coreos/go-systemd/dbus/set_test.go deleted file mode 100644 index 2f04096f9..000000000 --- a/vendor/github.com/coreos/go-systemd/dbus/set_test.go +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2015 CoreOS, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package dbus - -import ( - "testing" -) - -// TestBasicSetActions asserts that Add & Remove behavior is correct -func TestBasicSetActions(t *testing.T) { - s := newSet() - - if s.Contains("foo") { - t.Fatal("set should not contain 'foo'") - } - - s.Add("foo") - - if !s.Contains("foo") { - t.Fatal("set should contain 'foo'") - } - - v := s.Values() - if len(v) != 1 { - t.Fatal("set.Values did not report correct number of values") - } - if v[0] != "foo" { - t.Fatal("set.Values did not report value") - } - - s.Remove("foo") - - if s.Contains("foo") { - t.Fatal("set should not contain 'foo'") - } - - v = s.Values() - if len(v) != 0 { - t.Fatal("set.Values did not report correct number of values") - } -} diff --git a/vendor/github.com/coreos/go-systemd/dbus/subscription_set_test.go b/vendor/github.com/coreos/go-systemd/dbus/subscription_set_test.go deleted file mode 100644 index 53f75dfb2..000000000 --- a/vendor/github.com/coreos/go-systemd/dbus/subscription_set_test.go +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright 2015 CoreOS, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package dbus - -import ( - "testing" - "time" -) - -// TestSubscribeUnit exercises the basics of subscription of a particular unit. -func TestSubscriptionSetUnit(t *testing.T) { - target := "subscribe-events-set.service" - - conn, err := New() - - if err != nil { - t.Fatal(err) - } - - err = conn.Subscribe() - if err != nil { - t.Fatal(err) - } - - subSet := conn.NewSubscriptionSet() - evChan, errChan := subSet.Subscribe() - - subSet.Add(target) - setupUnit(target, conn, t) - linkUnit(target, conn, t) - - reschan := make(chan string) - _, err = conn.StartUnit(target, "replace", reschan) - if err != nil { - t.Fatal(err) - } - - job := <-reschan - if job != "done" { - t.Fatal("Couldn't start", target) - } - - timeout := make(chan bool, 1) - go func() { - time.Sleep(3 * time.Second) - close(timeout) - }() - - for { - select { - case changes := <-evChan: - tCh, ok := changes[target] - - if !ok { - t.Fatal("Unexpected event:", changes) - } - - if tCh.ActiveState == "active" && tCh.Name == target { - goto success - } - case err = <-errChan: - t.Fatal(err) - case <-timeout: - t.Fatal("Reached timeout") - } - } - -success: - return -} diff --git a/vendor/github.com/coreos/go-systemd/dbus/subscription_test.go b/vendor/github.com/coreos/go-systemd/dbus/subscription_test.go deleted file mode 100644 index e50fc6f96..000000000 --- a/vendor/github.com/coreos/go-systemd/dbus/subscription_test.go +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright 2015 CoreOS, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package dbus - -import ( - "testing" - "time" -) - -// TestSubscribe exercises the basics of subscription -func TestSubscribe(t *testing.T) { - conn, err := New() - - if err != nil { - t.Fatal(err) - } - - err = conn.Subscribe() - if err != nil { - t.Fatal(err) - } - - err = conn.Unsubscribe() - if err != nil { - t.Fatal(err) - } -} - -// TestSubscribeUnit exercises the basics of subscription of a particular unit. -func TestSubscribeUnit(t *testing.T) { - target := "subscribe-events.service" - - conn, err := New() - - if err != nil { - t.Fatal(err) - } - - err = conn.Subscribe() - if err != nil { - t.Fatal(err) - } - - err = conn.Unsubscribe() - if err != nil { - t.Fatal(err) - } - - evChan, errChan := conn.SubscribeUnits(time.Second) - - setupUnit(target, conn, t) - linkUnit(target, conn, t) - - reschan := make(chan string) - _, err = conn.StartUnit(target, "replace", reschan) - if err != nil { - t.Fatal(err) - } - - job := <-reschan - if job != "done" { - t.Fatal("Couldn't start", target) - } - - timeout := make(chan bool, 1) - go func() { - time.Sleep(3 * time.Second) - close(timeout) - }() - - for { - select { - case changes := <-evChan: - tCh, ok := changes[target] - - // Just continue until we see our event. - if !ok { - continue - } - - if tCh.ActiveState == "active" && tCh.Name == target { - goto success - } - case err = <-errChan: - t.Fatal(err) - case <-timeout: - t.Fatal("Reached timeout") - } - } - -success: - return -} diff --git a/vendor/github.com/coreos/go-systemd/unit/deserialize_test.go b/vendor/github.com/coreos/go-systemd/unit/deserialize_test.go deleted file mode 100644 index 84b7169fc..000000000 --- a/vendor/github.com/coreos/go-systemd/unit/deserialize_test.go +++ /dev/null @@ -1,381 +0,0 @@ -// Copyright 2015 CoreOS, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package unit - -import ( - "bytes" - "fmt" - "reflect" - "testing" -) - -func TestDeserialize(t *testing.T) { - tests := []struct { - input []byte - output []*UnitOption - }{ - // multiple options underneath a section - { - []byte(`[Unit] -Description=Foo -Description=Bar -Requires=baz.service -After=baz.service -`), - []*UnitOption{ - &UnitOption{"Unit", "Description", "Foo"}, - &UnitOption{"Unit", "Description", "Bar"}, - &UnitOption{"Unit", "Requires", "baz.service"}, - &UnitOption{"Unit", "After", "baz.service"}, - }, - }, - - // multiple sections - { - []byte(`[Unit] -Description=Foo - -[Service] -ExecStart=/usr/bin/sleep infinity - -[X-Third-Party] -Pants=on - -`), - []*UnitOption{ - &UnitOption{"Unit", "Description", "Foo"}, - &UnitOption{"Service", "ExecStart", "/usr/bin/sleep infinity"}, - &UnitOption{"X-Third-Party", "Pants", "on"}, - }, - }, - - // multiple sections with no options - { - []byte(`[Unit] -[Service] -[X-Third-Party] -`), - []*UnitOption{}, - }, - - // multiple values not special-cased - { - []byte(`[Service] -Environment= "FOO=BAR" "BAZ=QUX" -`), - []*UnitOption{ - &UnitOption{"Service", "Environment", "\"FOO=BAR\" \"BAZ=QUX\""}, - }, - }, - - // line continuations unmodified - { - []byte(`[Unit] -Description= Unnecessarily wrapped \ - words here -`), - []*UnitOption{ - &UnitOption{"Unit", "Description", `Unnecessarily wrapped \ - words here`}, - }, - }, - - // comments ignored - { - []byte(`; comment alpha -# comment bravo -[Unit] -; comment charlie -# comment delta -#Description=Foo -Description=Bar -; comment echo -# comment foxtrot -`), - []*UnitOption{ - &UnitOption{"Unit", "Description", "Bar"}, - }, - }, - - // apparent comment lines inside of line continuations not ignored - { - []byte(`[Unit] -Description=Bar\ -# comment alpha - -Description=Bar\ -# comment bravo \ -Baz -`), - []*UnitOption{ - &UnitOption{"Unit", "Description", "Bar\\\n# comment alpha"}, - &UnitOption{"Unit", "Description", "Bar\\\n# comment bravo \\\nBaz"}, - }, - }, - - // options outside of sections are ignored - { - []byte(`Description=Foo -[Unit] -Description=Bar -`), - []*UnitOption{ - &UnitOption{"Unit", "Description", "Bar"}, - }, - }, - - // garbage outside of sections are ignored - { - []byte(`<<<<<<<< -[Unit] -Description=Bar -`), - []*UnitOption{ - &UnitOption{"Unit", "Description", "Bar"}, - }, - }, - - // garbage used as unit option - { - []byte(`[Unit] -<<<<<<<<=Bar -`), - []*UnitOption{ - &UnitOption{"Unit", "<<<<<<<<", "Bar"}, - }, - }, - - // option name with spaces are valid - { - []byte(`[Unit] -Some Thing = Bar -`), - []*UnitOption{ - &UnitOption{"Unit", "Some Thing", "Bar"}, - }, - }, - - // lack of trailing newline doesn't cause problem for non-continued file - { - []byte(`[Unit] -Description=Bar`), - []*UnitOption{ - &UnitOption{"Unit", "Description", "Bar"}, - }, - }, - - // unit file with continuation but no following line is ok, too - { - []byte(`[Unit] -Description=Bar \`), - []*UnitOption{ - &UnitOption{"Unit", "Description", "Bar \\"}, - }, - }, - - // Assert utf8 characters are preserved - { - []byte(`[©] -µ☃=ÇôrèÕ$`), - []*UnitOption{ - &UnitOption{"©", "µ☃", "ÇôrèÕ$"}, - }, - }, - - // whitespace removed around option name - { - []byte(`[Unit] - Description =words here -`), - []*UnitOption{ - &UnitOption{"Unit", "Description", "words here"}, - }, - }, - - // whitespace around option value stripped - { - []byte(`[Unit] -Description= words here `), - []*UnitOption{ - &UnitOption{"Unit", "Description", "words here"}, - }, - }, - - // whitespace around option value stripped, regardless of continuation - { - []byte(`[Unit] -Description= words here \ - `), - []*UnitOption{ - &UnitOption{"Unit", "Description", "words here \\\n"}, - }, - }, - - // backslash not considered continuation if followed by text - { - []byte(`[Service] -ExecStart=/bin/bash -c "while true; do echo \"ping\"; sleep 1; done" -`), - []*UnitOption{ - &UnitOption{"Service", "ExecStart", `/bin/bash -c "while true; do echo \"ping\"; sleep 1; done"`}, - }, - }, - - // backslash not considered continuation if followed by whitespace, but still trimmed - { - []byte(`[Service] -ExecStart=/bin/bash echo poof \ `), - []*UnitOption{ - &UnitOption{"Service", "ExecStart", `/bin/bash echo poof \`}, - }, - }, - // a long unit file line that's just equal to the maximum permitted length - { - []byte(`[Service] -ExecStart=/bin/bash -c "echo ................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................."`), - []*UnitOption{ - &UnitOption{"Service", "ExecStart", `/bin/bash -c "echo ................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................."`}, - }, - }, - // the same, but with a trailing newline - { - []byte(`[Service] -ExecStart=/bin/bash -c "echo ................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................." -Option=value -`), - []*UnitOption{ - &UnitOption{"Service", "ExecStart", `/bin/bash -c "echo ................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................."`}, - &UnitOption{"Service", "Option", "value"}, - }, - }, - } - - assert := func(expect, output []*UnitOption) error { - if len(expect) != len(output) { - return fmt.Errorf("expected %d items, got %d", len(expect), len(output)) - } - - for i, _ := range expect { - if !reflect.DeepEqual(expect[i], output[i]) { - return fmt.Errorf("item %d: expected %v, got %v", i, expect[i], output[i]) - } - } - - return nil - } - - for i, tt := range tests { - output, err := Deserialize(bytes.NewReader(tt.input)) - if err != nil { - t.Errorf("case %d: unexpected error parsing unit: %v", i, err) - continue - } - - err = assert(tt.output, output) - if err != nil { - t.Errorf("case %d: %v", i, err) - t.Log("Expected options:") - logUnitOptionSlice(t, tt.output) - t.Log("Actual options:") - logUnitOptionSlice(t, output) - } - } -} - -func TestDeserializeFail(t *testing.T) { - tests := [][]byte{ - // malformed section header - []byte(`[Unit -Description=Foo -`), - - // garbage following section header - []byte(`[Unit] pants -Description=Foo -`), - - // option without value - []byte(`[Unit] -Description -`), - - // garbage inside of section - []byte(`[Unit] -<<<<<< -Description=Foo -`), - } - - for i, tt := range tests { - output, err := Deserialize(bytes.NewReader(tt)) - if err == nil { - t.Errorf("case %d: unexpected nil error", i) - t.Log("Output:") - logUnitOptionSlice(t, output) - } - } -} - -func logUnitOptionSlice(t *testing.T, opts []*UnitOption) { - for idx, opt := range opts { - t.Logf("%d: %v", idx, opt) - } -} - -func TestDeserializeLineTooLong(t *testing.T) { - tests := [][]byte{ - // section header that's far too long - []byte(`[Seeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeervice] -`), - // sane-looking unit file with a line just greater than the maximum allowed (currently, 2048) - []byte(`[Service] -ExecStart=/bin/bash -c "echo ..................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................." -`), - // sane-looking unit file with option value way too long - []byte(` -# test unit file - -[Service] -ExecStartPre=-/usr/bin/docker rm %p -ExecStartPre=-/usr/bin/docker pull busybox -ExecStart=/usr/bin/docker run --rm --name %p --net=host \ - -e "test=1123t" \ - -e "test=1123t" \ - -e "fiz=1123t" \ - -e "buz=1123t" \ - -e "FOO=BARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBABARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARRBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBAR"BARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBABARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARRBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBARBAR" \ - busybox sleep 10 -ExecStop=-/usr/bin/docker kill %p -SyslogIdentifier=busybox -Restart=always -RestartSec=10s -`), - // single arbitrary line that's way too long - []byte(`arbitrary and extraordinarily long line that is far greater than 2048 characters arbitrary and extraordinarily long line that is far greater than 2048 character arbitrary and extraordinarily long line that is far greater than 2048 characters arbitrary and extraordinarily long line that is far greater than 2048 characters arbitrary and extraordinarily long line that is far greater than 2048 characters arbitrary and extraordinarily long line that is far greater than 2048 characters arbitrary and extraordinarily long line that is far greater than 2048 characters arbitrary and extraordinarily long line that is far greater than 2048 characters arbitrary and extraordinarily long line that is far greater than 2048 characters arbitrary and extraordinarily long line that is far greater than 2048 characters arbitrary and extraordinarily long line that is far greater than 2048 characters arbitrary and extraordinarily long line that is far greater than 2048 characters arbitrary and extraordinarily long line that is far greater than 2048 characters arbitrary and extraordinarily long line that is far greater than 2048 characters arbitrary and extraordinarily long line that is far greater than 2048 characters arbitrary and extraordinarily long line that is far greater than 2048 character arbitrary and extraordinarily long line that is far greater than 2048 characters arbitrary and extraordinarily long line that is far greater than 2048 characters arbitrary and extraordinarily long line that is far greater than 2048 characters arbitrary and extraordinarily long line that is far greater than 2048 characters arbitrary and extraordinarily long line that is far greater than 2048 characters arbitrary and extraordinarily long line that is far greater than 2048 characters arbitrary and extraordinarily long line that is far greater than 2048 characters arbitrary and extraordinarily long line that is far greater than 2048 characters arbitrary and extraordinarily long line that is far greater than 2048 characters arbitrary and extraordinarily long line that is far greater than 2048 characters arbitrary and extraordinarily long line that is far greater than 2048 characters arbitrary and extraordinarily long line that is far greater than 2048 characters arbitrary and extraordinarily long line that is far greater than 2048 characters arbitrary and extraordinarily long line that is far greater than 2048 character arbitrary and extraordinarily long line that is far greater than 2048 characters arbitrary and extraordinarily long line that is far greater than 2048 characters arbitrary and extraordinarily long line that is far greater than 2048 characters arbitrary and extraordinarily long line that is far greater than 2048 characters arbitrary and extraordinarily long line that is far greater than 2048 characters arbitrary and extraordinarily long line that is far greater than 2048 characters arbitrary and extraordinarily long line that is far greater than 2048 characters arbitrary and extraordinarily long line that is far greater than 2048 characters arbitrary and extraordinarily long line that is far greater than 2048 characters arbitrary and extraordinarily long line that is far greater than 2048 characters arbitrary and extraordinarily long line that is far greater than 2048 characters arbitrary and extraordinarily long line that is far greater than 2048 characters arbitrary and extraordinarily long line that is far greater than 2048 characters arbitrary and extraordinarily long line that is far greater than 2048 character arbitrary and extraordinarily long line that is far greater than 2048 characters arbitrary and extraordinarily long line that is far greater than 2048 characters arbitrary and extraordinarily long line that is far greater than 2048 characters arbitrary and extraordinarily long line that is far greater than 2048 characters arbitrary and extraordinarily long line that is far greater than 2048 characters arbitrary and extraordinarily long line that is far greater than 2048 characters arbitrary and extraordinarily long line that is far greater than 2048 characters arbitrary and extraordinarily long line that is far greater than 2048 characters arbitrary and extraordinarily long line that is far greater than 2048 characters arbitrary and extraordinarily long line that is far greater than 2048 characters arbitrary and extraordinarily long line that is far greater than 2048 characters arbitrary and extraordinarily long line that is far greater than 2048 characters`), - // sane-looking unit file with option name way too long - []byte(`[Service] -ExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStartExecStart=/bin/true -`), - } - - for i, tt := range tests { - output, err := Deserialize(bytes.NewReader(tt)) - if err != ErrLineTooLong { - t.Errorf("case %d: unexpected err: %v", i, err) - t.Log("Output:") - logUnitOptionSlice(t, output) - } - } -} diff --git a/vendor/github.com/coreos/go-systemd/unit/end_to_end_test.go b/vendor/github.com/coreos/go-systemd/unit/end_to_end_test.go deleted file mode 100644 index 7182327ad..000000000 --- a/vendor/github.com/coreos/go-systemd/unit/end_to_end_test.go +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright 2015 CoreOS, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package unit - -import ( - "bytes" - "io/ioutil" - "testing" -) - -func TestDeserializeAndReserialize(t *testing.T) { - tests := []struct { - in string - wout string - }{ - { - `[Service] -ExecStart=/bin/bash -c "while true; do echo \"ping\"; sleep 1; done" -`, - `[Service] -ExecStart=/bin/bash -c "while true; do echo \"ping\"; sleep 1; done" -`}, - { - `[Unit] -Description= Unnecessarily wrapped \ - words here`, - `[Unit] -Description=Unnecessarily wrapped \ - words here -`, - }, - { - `[Unit] -Description=Demo \ - -Requires=docker.service -`, - `[Unit] -Description=Demo \ - -Requires=docker.service -`, - }, - { - `; comment alpha -# comment bravo -[Unit] -; comment charlie -# comment delta -#Description=Foo -Description=Bar -; comment echo -# comment foxtrot -`, - `[Unit] -Description=Bar -`}, - } - for i, tt := range tests { - ds, err := Deserialize(bytes.NewBufferString(tt.in)) - if err != nil { - t.Errorf("case %d: unexpected error parsing unit: %v", i, err) - continue - } - out, err := ioutil.ReadAll(Serialize(ds)) - if err != nil { - t.Errorf("case %d: unexpected error serializing unit: %v", i, err) - continue - } - if g := string(out); g != tt.wout { - t.Errorf("case %d: incorrect output", i) - t.Logf("Expected:\n%#v", tt.wout) - t.Logf("Actual:\n%#v", g) - } - } -} diff --git a/vendor/github.com/coreos/go-systemd/unit/escape_test.go b/vendor/github.com/coreos/go-systemd/unit/escape_test.go deleted file mode 100644 index 36b1a7d37..000000000 --- a/vendor/github.com/coreos/go-systemd/unit/escape_test.go +++ /dev/null @@ -1,211 +0,0 @@ -// Copyright 2015 CoreOS, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package unit - -import ( - "testing" -) - -func TestUnitNameEscape(t *testing.T) { - tests := []struct { - in string - out string - isPath bool - }{ - // turn empty string path into escaped / - { - in: "", - out: "-", - isPath: true, - }, - // turn redundant ////s into single escaped / - { - in: "/////////", - out: "-", - isPath: true, - }, - // remove all redundant ////s - { - in: "///foo////bar/////tail//////", - out: "foo-bar-tail", - isPath: true, - }, - // leave empty string empty - { - in: "", - out: "", - isPath: false, - }, - // escape leading dot - { - in: ".", - out: `\x2e`, - isPath: true, - }, - // escape leading dot - { - in: "/.", - out: `\x2e`, - isPath: true, - }, - // escape leading dot - { - in: "/////////.", - out: `\x2e`, - isPath: true, - }, - // escape leading dot - { - in: "/////////.///////////////", - out: `\x2e`, - isPath: true, - }, - // escape leading dot - { - in: ".....", - out: `\x2e....`, - isPath: true, - }, - // escape leading dot - { - in: "/.foo/.bar", - out: `\x2efoo-.bar`, - isPath: true, - }, - // escape leading dot - { - in: ".foo/.bar", - out: `\x2efoo-.bar`, - isPath: true, - }, - // escape leading dot - { - in: ".foo/.bar", - out: `\x2efoo-.bar`, - isPath: false, - }, - // escape disallowed - { - in: `///..\-!#??///`, - out: `---..\x5c\x2d\x21\x23\x3f\x3f---`, - isPath: false, - }, - // escape disallowed - { - in: `///..\-!#??///`, - out: `\x2e.\x5c\x2d\x21\x23\x3f\x3f`, - isPath: true, - }, - // escape real-world example - { - in: `user-cloudinit@/var/lib/coreos/vagrant/vagrantfile-user-data.service`, - out: `user\x2dcloudinit\x40-var-lib-coreos-vagrant-vagrantfile\x2duser\x2ddata.service`, - isPath: false, - }, - } - - for i, tt := range tests { - var s string - if tt.isPath { - s = UnitNamePathEscape(tt.in) - } else { - s = UnitNameEscape(tt.in) - } - if s != tt.out { - t.Errorf("case %d: failed escaping %v isPath: %v - expected %v, got %v", i, tt.in, tt.isPath, tt.out, s) - } - } -} - -func TestUnitNameUnescape(t *testing.T) { - tests := []struct { - in string - out string - isPath bool - }{ - // turn empty string path into / - { - in: "", - out: "/", - isPath: true, - }, - // leave empty string empty - { - in: "", - out: "", - isPath: false, - }, - // turn ////s into - { - in: "---------", - out: "/////////", - isPath: true, - }, - // unescape hex - { - in: `---..\x5c\x2d\x21\x23\x3f\x3f---`, - out: `///..\-!#??///`, - isPath: false, - }, - // unescape hex - { - in: `\x2e.\x5c\x2d\x21\x23\x3f\x3f`, - out: `/..\-!#??`, - isPath: true, - }, - // unescape hex, retain invalids - { - in: `\x2e.\x5c\x2d\xaZ\x.o\x21\x23\x3f\x3f`, - out: `/..\-\xaZ\x.o!#??`, - isPath: true, - }, - // unescape hex, retain invalids, partial tail - { - in: `\x2e.\x5c\x\x2d\xaZ\x.o\x21\x23\x3f\x3f\x3`, - out: `/..\\x-\xaZ\x.o!#??\x3`, - isPath: true, - }, - // unescape hex, retain invalids, partial tail - { - in: `\x2e.\x5c\x\x2d\xaZ\x.o\x21\x23\x3f\x3f\x`, - out: `/..\\x-\xaZ\x.o!#??\x`, - isPath: true, - }, - // unescape hex, retain invalids, partial tail - { - in: `\x2e.\x5c\x\x2d\xaZ\x.o\x21\x23\x3f\x3f\`, - out: `/..\\x-\xaZ\x.o!#??\`, - isPath: true, - }, - // unescape real-world example - { - in: `user\x2dcloudinit\x40-var-lib-coreos-vagrant-vagrantfile\x2duser\x2ddata.service`, - out: `user-cloudinit@/var/lib/coreos/vagrant/vagrantfile-user-data.service`, - isPath: false, - }, - } - - for i, tt := range tests { - var s string - if tt.isPath { - s = UnitNamePathUnescape(tt.in) - } else { - s = UnitNameUnescape(tt.in) - } - if s != tt.out { - t.Errorf("case %d: failed unescaping %v isPath: %v - expected %v, got %v", i, tt.in, tt.isPath, tt.out, s) - } - } -} diff --git a/vendor/github.com/coreos/go-systemd/unit/option_test.go b/vendor/github.com/coreos/go-systemd/unit/option_test.go deleted file mode 100644 index 0765f03ae..000000000 --- a/vendor/github.com/coreos/go-systemd/unit/option_test.go +++ /dev/null @@ -1,214 +0,0 @@ -// Copyright 2015 CoreOS, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package unit - -import ( - "testing" -) - -func TestAllMatch(t *testing.T) { - tests := []struct { - u1 []*UnitOption - u2 []*UnitOption - match bool - }{ - // empty lists match - { - u1: []*UnitOption{}, - u2: []*UnitOption{}, - match: true, - }, - - // simple match of a single option - { - u1: []*UnitOption{ - {Section: "Unit", Name: "Description", Value: "FOO"}, - }, - u2: []*UnitOption{ - {Section: "Unit", Name: "Description", Value: "FOO"}, - }, - match: true, - }, - - // single option mismatched - { - u1: []*UnitOption{ - {Section: "Unit", Name: "Description", Value: "FOO"}, - }, - u2: []*UnitOption{ - {Section: "Unit", Name: "Description", Value: "BAR"}, - }, - match: false, - }, - - // multiple options match - { - u1: []*UnitOption{ - {Section: "Unit", Name: "Description", Value: "FOO"}, - {Section: "Unit", Name: "BindsTo", Value: "bar.service"}, - {Section: "Service", Name: "ExecStart", Value: "/bin/true"}, - }, - u2: []*UnitOption{ - {Section: "Unit", Name: "Description", Value: "FOO"}, - {Section: "Unit", Name: "BindsTo", Value: "bar.service"}, - {Section: "Service", Name: "ExecStart", Value: "/bin/true"}, - }, - match: true, - }, - - // mismatch length - { - u1: []*UnitOption{ - {Section: "Unit", Name: "Description", Value: "FOO"}, - {Section: "Unit", Name: "BindsTo", Value: "bar.service"}, - }, - u2: []*UnitOption{ - {Section: "Unit", Name: "Description", Value: "FOO"}, - {Section: "Unit", Name: "BindsTo", Value: "bar.service"}, - {Section: "Service", Name: "ExecStart", Value: "/bin/true"}, - }, - match: false, - }, - - // multiple options misordered - { - u1: []*UnitOption{ - {Section: "Unit", Name: "Description", Value: "FOO"}, - {Section: "Service", Name: "ExecStart", Value: "/bin/true"}, - }, - u2: []*UnitOption{ - {Section: "Service", Name: "ExecStart", Value: "/bin/true"}, - {Section: "Unit", Name: "Description", Value: "FOO"}, - }, - match: false, - }, - - // interleaved sections mismatch - { - u1: []*UnitOption{ - {Section: "Unit", Name: "Description", Value: "FOO"}, - {Section: "Unit", Name: "BindsTo", Value: "bar.service"}, - {Section: "Service", Name: "ExecStart", Value: "/bin/true"}, - {Section: "Service", Name: "ExecStop", Value: "/bin/true"}, - }, - u2: []*UnitOption{ - {Section: "Unit", Name: "Description", Value: "FOO"}, - {Section: "Service", Name: "ExecStart", Value: "/bin/true"}, - {Section: "Unit", Name: "BindsTo", Value: "bar.service"}, - {Section: "Service", Name: "ExecStop", Value: "/bin/true"}, - }, - match: false, - }, - } - - for i, tt := range tests { - match := AllMatch(tt.u1, tt.u2) - if match != tt.match { - t.Errorf("case %d: failed comparing u1 to u2 - expected match=%t, got %t", i, tt.match, match) - } - - match = AllMatch(tt.u2, tt.u1) - if match != tt.match { - t.Errorf("case %d: failed comparing u2 to u1 - expected match=%t, got %t", i, tt.match, match) - } - } -} - -func TestMatch(t *testing.T) { - tests := []struct { - o1 *UnitOption - o2 *UnitOption - match bool - }{ - // empty options match - { - o1: &UnitOption{}, - o2: &UnitOption{}, - match: true, - }, - - // all fields match - { - o1: &UnitOption{ - Section: "Unit", - Name: "Description", - Value: "FOO", - }, - o2: &UnitOption{ - Section: "Unit", - Name: "Description", - Value: "FOO", - }, - match: true, - }, - - // Section mismatch - { - o1: &UnitOption{ - Section: "Unit", - Name: "Description", - Value: "FOO", - }, - o2: &UnitOption{ - Section: "X-Other", - Name: "Description", - Value: "FOO", - }, - match: false, - }, - - // Name mismatch - { - o1: &UnitOption{ - Section: "Unit", - Name: "Description", - Value: "FOO", - }, - o2: &UnitOption{ - Section: "Unit", - Name: "BindsTo", - Value: "FOO", - }, - match: false, - }, - - // Value mismatch - { - o1: &UnitOption{ - Section: "Unit", - Name: "Description", - Value: "FOO", - }, - o2: &UnitOption{ - Section: "Unit", - Name: "Description", - Value: "BAR", - }, - match: false, - }, - } - - for i, tt := range tests { - match := tt.o1.Match(tt.o2) - if match != tt.match { - t.Errorf("case %d: failed comparing o1 to o2 - expected match=%t, got %t", i, tt.match, match) - } - - match = tt.o2.Match(tt.o1) - if match != tt.match { - t.Errorf("case %d: failed comparing o2 to o1 - expected match=%t, got %t", i, tt.match, match) - } - } -} diff --git a/vendor/github.com/coreos/go-systemd/unit/serialize_test.go b/vendor/github.com/coreos/go-systemd/unit/serialize_test.go deleted file mode 100644 index bd492b0d4..000000000 --- a/vendor/github.com/coreos/go-systemd/unit/serialize_test.go +++ /dev/null @@ -1,170 +0,0 @@ -// Copyright 2015 CoreOS, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package unit - -import ( - "io/ioutil" - "testing" -) - -func TestSerialize(t *testing.T) { - tests := []struct { - input []*UnitOption - output string - }{ - // no options results in empty file - { - []*UnitOption{}, - ``, - }, - - // options with same section share the header - { - []*UnitOption{ - &UnitOption{"Unit", "Description", "Foo"}, - &UnitOption{"Unit", "BindsTo", "bar.service"}, - }, - `[Unit] -Description=Foo -BindsTo=bar.service -`, - }, - - // options with same name are not combined - { - []*UnitOption{ - &UnitOption{"Unit", "Description", "Foo"}, - &UnitOption{"Unit", "Description", "Bar"}, - }, - `[Unit] -Description=Foo -Description=Bar -`, - }, - - // multiple options printed under different section headers - { - []*UnitOption{ - &UnitOption{"Unit", "Description", "Foo"}, - &UnitOption{"Service", "ExecStart", "/usr/bin/sleep infinity"}, - }, - `[Unit] -Description=Foo - -[Service] -ExecStart=/usr/bin/sleep infinity -`, - }, - - // options are grouped into sections - { - []*UnitOption{ - &UnitOption{"Unit", "Description", "Foo"}, - &UnitOption{"Service", "ExecStart", "/usr/bin/sleep infinity"}, - &UnitOption{"Unit", "BindsTo", "bar.service"}, - }, - `[Unit] -Description=Foo -BindsTo=bar.service - -[Service] -ExecStart=/usr/bin/sleep infinity -`, - }, - - // options are ordered within groups, and sections are ordered in the order in which they were first seen - { - []*UnitOption{ - &UnitOption{"Unit", "Description", "Foo"}, - &UnitOption{"Service", "ExecStart", "/usr/bin/sleep infinity"}, - &UnitOption{"Unit", "BindsTo", "bar.service"}, - &UnitOption{"X-Foo", "Bar", "baz"}, - &UnitOption{"Service", "ExecStop", "/usr/bin/sleep 1"}, - &UnitOption{"Unit", "Documentation", "https://foo.com"}, - }, - `[Unit] -Description=Foo -BindsTo=bar.service -Documentation=https://foo.com - -[Service] -ExecStart=/usr/bin/sleep infinity -ExecStop=/usr/bin/sleep 1 - -[X-Foo] -Bar=baz -`, - }, - - // utf8 characters are not a problem - { - []*UnitOption{ - &UnitOption{"©", "µ☃", "ÇôrèÕ$"}, - }, - `[©] -µ☃=ÇôrèÕ$ -`, - }, - - // no verification is done on section names - { - []*UnitOption{ - &UnitOption{"Un\nit", "Description", "Foo"}, - }, - `[Un -it] -Description=Foo -`, - }, - - // no verification is done on option names - { - []*UnitOption{ - &UnitOption{"Unit", "Desc\nription", "Foo"}, - }, - `[Unit] -Desc -ription=Foo -`, - }, - - // no verification is done on option values - { - []*UnitOption{ - &UnitOption{"Unit", "Description", "Fo\no"}, - }, - `[Unit] -Description=Fo -o -`, - }, - } - - for i, tt := range tests { - outReader := Serialize(tt.input) - outBytes, err := ioutil.ReadAll(outReader) - if err != nil { - t.Errorf("case %d: encountered error while reading output: %v", i, err) - continue - } - - output := string(outBytes) - if tt.output != output { - t.Errorf("case %d: incorrect output", i) - t.Logf("Expected:\n%s", tt.output) - t.Logf("Actual:\n%s", output) - } - } -} diff --git a/vendor/github.com/godbus/dbus/CONTRIBUTING.md b/vendor/github.com/godbus/dbus/CONTRIBUTING.md deleted file mode 100644 index c88f9b2bd..000000000 --- a/vendor/github.com/godbus/dbus/CONTRIBUTING.md +++ /dev/null @@ -1,50 +0,0 @@ -# How to Contribute - -## Getting Started - -- Fork the repository on GitHub -- Read the [README](README.markdown) for build and test instructions -- Play with the project, submit bugs, submit patches! - -## Contribution Flow - -This is a rough outline of what a contributor's workflow looks like: - -- Create a topic branch from where you want to base your work (usually master). -- Make commits of logical units. -- Make sure your commit messages are in the proper format (see below). -- Push your changes to a topic branch in your fork of the repository. -- Make sure the tests pass, and add any new tests as appropriate. -- Submit a pull request to the original repository. - -Thanks for your contributions! - -### Format of the Commit Message - -We follow a rough convention for commit messages that is designed to answer two -questions: what changed and why. The subject line should feature the what and -the body of the commit should describe the why. - -``` -scripts: add the test-cluster command - -this uses tmux to setup a test cluster that you can easily kill and -start for debugging. - -Fixes #38 -``` - -The format can be described more formally as follows: - -``` -: - - - -