From 963abc2eaa7acc679cda9c378ef51c2d596f7e94 Mon Sep 17 00:00:00 2001 From: Daisuke Taniwaki Date: Tue, 26 Mar 2019 09:36:19 +0900 Subject: [PATCH] E2e tests (#249) * Create e2e helper scripts * Implement e2e tests * Remove comment in e2e manifests * Create RoleBinding in e2e namespaces * Keep e2e namespaces optionally * Do not automatically build images before e2e * Update e2e tests * Update e2e script * Run e2e in a kind cluster * Move e2e manifests * Fix e2e script * Install kubectl in travis * Wait kind startup more * Set env in CI * Show cluster info * Fix kubeconfig path in CI * Cache image layers * Fix range expression * Use kubeconfig of KUBECONFIG if it exists * Adjust port forwarding delay * Fix e2e client initialization * Exclude e2e tests from make test * Create namespace per test case * Exclude e2e tests from make coverage --- .travis.yml | 32 +- Gopkg.lock | 434 ++++++++++++++++-- Makefile | 15 +- hack/e2e/cleanup-e2e.sh | 5 + hack/e2e/kind-run-e2e.sh | 30 ++ .../manifests/argo-events-cluster-roles.yaml | 94 ++++ hack/e2e/manifests/argo-events-sa.yaml | 5 + .../gateway-controller-configmap.yaml | 9 + .../gateway-controller-deployment.yaml | 26 ++ .../sensor-controller-configmap.yaml | 9 + .../sensor-controller-deployment.yaml | 26 ++ hack/e2e/run-e2e.sh | 22 + hack/e2e/setup-e2e.sh | 45 ++ test/e2e/common/client.go | 314 +++++++++++++ test/e2e/common/constants.go | 6 + test/e2e/common/manifests/namespace.yaml | 7 + test/e2e/common/manifests/rolebinding.yaml | 13 + test/e2e/common/misc.go | 28 ++ test/e2e/core/main_test.go | 204 ++++++++ .../webhook-gateway-configmap.yaml | 9 + .../general-use-case/webhook-gateway.yaml | 45 ++ .../general-use-case/webhook-sensor.yaml | 41 ++ 22 files changed, 1367 insertions(+), 52 deletions(-) create mode 100755 hack/e2e/cleanup-e2e.sh create mode 100755 hack/e2e/kind-run-e2e.sh create mode 100644 hack/e2e/manifests/argo-events-cluster-roles.yaml create mode 100644 hack/e2e/manifests/argo-events-sa.yaml create mode 100644 hack/e2e/manifests/gateway-controller-configmap.yaml create mode 100644 hack/e2e/manifests/gateway-controller-deployment.yaml create mode 100644 hack/e2e/manifests/sensor-controller-configmap.yaml create mode 100644 hack/e2e/manifests/sensor-controller-deployment.yaml create mode 100755 hack/e2e/run-e2e.sh create mode 100755 hack/e2e/setup-e2e.sh create mode 100644 test/e2e/common/client.go create mode 100644 test/e2e/common/constants.go create mode 100644 test/e2e/common/manifests/namespace.yaml create mode 100644 test/e2e/common/manifests/rolebinding.yaml create mode 100644 test/e2e/common/misc.go create mode 100644 test/e2e/core/main_test.go create mode 100644 test/e2e/core/manifests/general-use-case/webhook-gateway-configmap.yaml create mode 100644 test/e2e/core/manifests/general-use-case/webhook-gateway.yaml create mode 100644 test/e2e/core/manifests/general-use-case/webhook-sensor.yaml diff --git a/.travis.yml b/.travis.yml index f6ac7583f6..908f8b86ed 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,8 +2,36 @@ language: go go: - 1.x +services: + - docker + +cache: + directories: + - $HOME/bin + - $HOME/docker + +env: + global: + - DOCKER_PUSH=false + - IMAGE_TAG=latest + - PATH=$HOME/bin:$PATH + before_install: + # Load cached docker images + - if [[ -d $HOME/docker ]]; then ls $HOME/docker/*.tar.gz | xargs -I {file} sh -c "zcat {file} | docker load"; fi - go get github.com/mattn/goveralls + - go get sigs.k8s.io/kind + - if [ ! -d $HOME/bin/kubectl ]; then + mkdir -p $HOME/bin; + curl -o $HOME/bin/kubectl -L https://storage.googleapis.com/kubernetes-release/release/v1.13.4/bin/linux/amd64/kubectl; + chmod +x $HOME/bin/kubectl; + fi + +before_cache: + # Save tagged docker images + - > + mkdir -p $HOME/docker && docker images -a --filter='dangling=false' --format '{{.Repository}}:{{.Tag}} {{.ID}}' + | xargs -n 2 -t sh -c 'test -e $HOME/docker/$1.tar.gz || docker save $0 | gzip -2 > $HOME/docker/$1.tar.gz' install: - curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh @@ -14,10 +42,12 @@ script: - make all - make test coverage - $GOPATH/bin/goveralls -coverprofile=profile.cov -service=travis-ci + - make build-e2e-images + - make kind-e2e deploy: provider: releases api_key: $GITHUB_OAUTH_TOKEN skip_cleanup: true on: - tags: true \ No newline at end of file + tags: true diff --git a/Gopkg.lock b/Gopkg.lock index 5c7489e7bf..e586f17975 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -3,6 +3,7 @@ [[projects]] branch = "master" + digest = "1:ce6b6155cb0e2a5cda58a7b3ba130d10642ce178715dc1925c54c449cefbfc1a" name = "cloud.google.com/go" packages = [ "compute/metadata", @@ -11,57 +12,73 @@ "internal/version", "pubsub", "pubsub/apiv1", - "pubsub/internal/distribution" + "pubsub/internal/distribution", ] + pruneopts = "UT" revision = "88dee6a1ef5aea45e2fadf8f96c828c78b02a958" [[projects]] + digest = "1:ed77032e4241e3b8329c9304d66452ed196e795876e14be677a546f36b94e67a" name = "github.com/DataDog/zstd" packages = ["."] + pruneopts = "UT" revision = "c7161f8c63c045cbc7ca051dcc969dd0e4054de2" version = "v1.3.5" [[projects]] branch = "master" + digest = "1:dc648facc1e7aac5086f749c84c9b9263345c08161fadd9cf92ae3309c9fcaa6" name = "github.com/Knetic/govaluate" packages = ["."] + pruneopts = "UT" revision = "9aa49832a739dcd78a5542ff189fb82c3e423116" [[projects]] + digest = "1:a2682518d905d662d984ef9959984ef87cecb777d379bfa9d9fe40e78069b3e4" name = "github.com/PuerkitoBio/purell" packages = ["."] + pruneopts = "UT" revision = "44968752391892e1b0d0b821ee79e9a85fa13049" version = "v1.1.1" [[projects]] branch = "master" + digest = "1:c739832d67eb1e9cc478a19cc1a1ccd78df0397bf8a32978b759152e205f644b" name = "github.com/PuerkitoBio/urlesc" packages = ["."] + pruneopts = "UT" revision = "de5bf2ad457846296e2031421a34e2568e304e35" [[projects]] + digest = "1:82a18170c9c41e36939cb5d26da1546b2cfa786aa030a978d3bf183519849230" name = "github.com/Shopify/sarama" packages = ["."] + pruneopts = "UT" revision = "4602b5a8c6e826f9e0737865818dd43b2339a092" version = "v1.21.0" [[projects]] branch = "master" + digest = "1:797da30d559e1fbc24acfe026226cfb49f129216fb65db1fa6b786f2ace0cc2c" name = "github.com/adlio/trello" packages = ["."] + pruneopts = "UT" revision = "b0faddb69566d3b80c1b70aa6daf2677b3f7a551" [[projects]] + digest = "1:4b9792d4bd04b67ce23f3d8a896df2f3ae49e1574ea2722501959f2b86f35002" name = "github.com/argoproj/argo" packages = [ "pkg/apis/workflow", - "pkg/apis/workflow/v1alpha1" + "pkg/apis/workflow/v1alpha1", ] + pruneopts = "UT" revision = "0a928e93dac6d8522682931a0a68c52add310cdb" version = "v2.2.1" [[projects]] branch = "master" + digest = "1:e1fb8946562caa84a5571b5807010513732f28848abca9467487a40785b37a4e" name = "github.com/aws/aws-sdk-go" packages = [ "aws", @@ -94,69 +111,98 @@ "private/protocol/xml/xmlutil", "service/sns", "service/sqs", - "service/sts" + "service/sts", ] + pruneopts = "UT" revision = "06b6ff7a2d1360d3504c1ad6e7d3d073e1bc4619" [[projects]] + digest = "1:357f4baa5f50bb2a9d9d01600c8dadebf1cb890b59b53a4c810301fc7bf3736c" name = "github.com/colinmarc/hdfs" packages = [ ".", "protocol/hadoop_common", "protocol/hadoop_hdfs", - "rpc" + "rpc", ] + pruneopts = "UT" revision = "48eb8d6c34a97ffc73b406356f0f2e1c569b42a5" [[projects]] + digest = "1:ffe9824d294da03b391f44e1ae8281281b4afc1bdaa9588c9097785e3af10cec" name = "github.com/davecgh/go-spew" packages = ["spew"] + pruneopts = "UT" revision = "8991bc29aa16c548c550c7ff78260e27b9ab7c73" version = "v1.1.1" [[projects]] + branch = "master" + digest = "1:ecdc8e0fe3bc7d549af1c9c36acf3820523b707d6c071b6d0c3860882c6f7b42" + name = "github.com/docker/spdystream" + packages = [ + ".", + "spdy", + ] + pruneopts = "UT" + revision = "6480d4af844c189cf5dd913db24ddd339d3a4f85" + +[[projects]] + digest = "1:6f9339c912bbdda81302633ad7e99a28dfa5a639c864061f1929510a9a64aa74" name = "github.com/dustin/go-humanize" packages = ["."] + pruneopts = "UT" revision = "9f541cc9db5d55bce703bd99987c9d5cb8eea45e" version = "v1.0.0" [[projects]] + digest = "1:1f0c7ab489b407a7f8f9ad16c25a504d28ab461517a971d341388a56156c1bd7" name = "github.com/eapache/go-resiliency" packages = ["breaker"] + pruneopts = "UT" revision = "ea41b0fad31007accc7f806884dcdf3da98b79ce" version = "v1.1.0" [[projects]] branch = "master" + digest = "1:79f16588b5576b1b3cd90e48d2374cc9a1a8776862d28d8fd0f23b0e15534967" name = "github.com/eapache/go-xerial-snappy" packages = ["."] + pruneopts = "UT" revision = "776d5712da21bc4762676d614db1d8a64f4238b0" [[projects]] + digest = "1:444b82bfe35c83bbcaf84e310fb81a1f9ece03edfed586483c869e2c046aef69" name = "github.com/eapache/queue" packages = ["."] + pruneopts = "UT" revision = "44cc805cf13205b55f69e14bcb69867d1ae92f98" version = "v1.1.0" [[projects]] + digest = "1:184008c955d6a3226b700c13ed0e875a7a051a759618f9bccba9b5c99f17faa5" name = "github.com/eclipse/paho.mqtt.golang" packages = [ ".", - "packets" + "packets", ] + pruneopts = "UT" revision = "36d01c2b4cbeb3d2a12063e4880ce30800af9560" version = "v1.1.1" [[projects]] + digest = "1:8ee7b41ace3ba875c17e38ba7780e7cf0d29882338637861e9f13f04f60ecc5c" name = "github.com/emicklei/go-restful" packages = [ ".", - "log" + "log", ] + pruneopts = "UT" revision = "85d198d05a92d31823b852b4a5928114912e8949" version = "v2.9.0" [[projects]] + digest = "1:b498b36dbb2b306d1c5205ee5236c9e60352be8f9eea9bf08186723a9f75b4f3" name = "github.com/emirpasic/gods" packages = [ "containers", @@ -164,48 +210,62 @@ "lists/arraylist", "trees", "trees/binaryheap", - "utils" + "utils", ] + pruneopts = "UT" revision = "1615341f118ae12f353cc8a983f35b584342c9b3" version = "v1.12.0" [[projects]] branch = "master" + digest = "1:78a5b63751bd99054bee07a498f6aa54da0a909922f9365d1aa3339091efa70a" name = "github.com/fsnotify/fsnotify" packages = ["."] + pruneopts = "UT" revision = "1485a34d5d5723fea214f5710708e19a831720e4" [[projects]] branch = "master" + digest = "1:08188cf7ce7027b22e88cc23da27f17349a0ba7746271a60cbe0a70266c2346f" name = "github.com/ghodss/yaml" packages = ["."] + pruneopts = "UT" revision = "25d852aebe32c875e9c044af3eef9c7dc6bc777f" [[projects]] + digest = "1:953a2628e4c5c72856b53f5470ed5e071c55eccf943d798d42908102af2a610f" name = "github.com/go-openapi/jsonpointer" packages = ["."] + pruneopts = "UT" revision = "ef5f0afec364d3b9396b7b77b43dbe26bf1f8004" version = "v0.18.0" [[projects]] + digest = "1:81210e0af657a0fb3638932ec68e645236bceefa4c839823db0c4d918f080895" name = "github.com/go-openapi/jsonreference" packages = ["."] + pruneopts = "UT" revision = "8483a886a90412cd6858df4ea3483dce9c8e35a3" version = "v0.18.0" [[projects]] + digest = "1:08656ef9c5a45ddccb7f206ca2d67e12e9fcda4122a83dc0544b5c967267cefa" name = "github.com/go-openapi/spec" packages = ["."] + pruneopts = "UT" revision = "5b6cdde3200976e3ecceb2868706ee39b6aff3e4" version = "v0.18.0" [[projects]] + digest = "1:0005186c6608dd542239ac8e4f4f1e2e7c24d493e999113c46b93332f0362fc0" name = "github.com/go-openapi/swag" packages = ["."] + pruneopts = "UT" revision = "1d29f06aebd59ccdf11ae04aa0334ded96e2d909" version = "v0.18.0" [[projects]] + digest = "1:b9faadd7c7214340381f24f8f97d4c6d6b5d7d5eeddc30c14c3b06045a821bde" name = "github.com/gogo/protobuf" packages = [ "gogoproto", @@ -235,18 +295,23 @@ "protoc-gen-gogofast", "sortkeys", "vanity", - "vanity/command" + "vanity/command", ] + pruneopts = "UT" revision = "ba06b47c162d49f2af050fb4c75bcbc86a159d5c" version = "v1.2.1" [[projects]] branch = "master" + digest = "1:1ba1d79f2810270045c328ae5d674321db34e3aae468eb4233883b473c5c0467" name = "github.com/golang/glog" packages = ["."] + pruneopts = "UT" revision = "23def4e6c14b4da8ac2ed8007337bc5eb5007998" [[projects]] + branch = "master" + digest = "1:0f706d0fce1cc828f5f8868813e2130c5bf9742999f5f7310ca927d474844b33" name = "github.com/golang/protobuf" packages = [ "proto", @@ -260,150 +325,193 @@ "ptypes/any", "ptypes/duration", "ptypes/empty", - "ptypes/timestamp" + "ptypes/timestamp", ] - revision = "b5d812f8a3706043e23a9cd5babf2e5423744d30" - version = "v1.3.1" + pruneopts = "UT" + revision = "d3c38a4eb4970272b87a425ae00ccc4548e2f9bb" [[projects]] + digest = "1:e4f5819333ac698d294fe04dbf640f84719658d5c7ce195b10060cc37292ce79" name = "github.com/golang/snappy" packages = ["."] + pruneopts = "UT" revision = "2a8bb927dd31d8daada140a5d09578521ce5c36a" version = "v0.0.1" [[projects]] + digest = "1:a848ff8a9a04616f385520da14d031468ad24e4a9a38f84241d92bd045593251" name = "github.com/google/go-github" packages = ["github"] + pruneopts = "UT" revision = "50be09d24ee31a2b0868265e76c24b9545a6eb7a" [[projects]] + digest = "1:a63cff6b5d8b95638bfe300385d93b2a6d9d687734b863da8e09dc834510a690" name = "github.com/google/go-querystring" packages = ["query"] + pruneopts = "UT" revision = "44c6ddd0a2342c386950e880b658017258da92fc" version = "v1.0.0" [[projects]] branch = "master" + digest = "1:3ee90c0d94da31b442dde97c99635aaafec68d0b8a3c12ee2075c6bdabeec6bb" name = "github.com/google/gofuzz" packages = ["."] + pruneopts = "UT" revision = "24818f796faf91cd76ec7bddd72458fbced7a6c1" [[projects]] + digest = "1:f1f70abea1ab125d48396343b4c053f8fecfbdb943037bf3d29dc80c90fe60b3" name = "github.com/googleapis/gax-go" packages = ["v2"] + pruneopts = "UT" revision = "beaecbbdd8af86aa3acf14180d53828ce69400b2" version = "v2.0.4" [[projects]] + digest = "1:65c4414eeb350c47b8de71110150d0ea8a281835b1f386eacaa3ad7325929c21" name = "github.com/googleapis/gnostic" packages = [ "OpenAPIv2", "compiler", - "extensions" + "extensions", ] + pruneopts = "UT" revision = "7c663266750e7d82587642f65e60bc4083f1f84e" version = "v0.2.0" [[projects]] branch = "master" + digest = "1:f14d1b50e0075fb00177f12a96dd7addf93d1e2883c25befd17285b779549795" name = "github.com/gopherjs/gopherjs" packages = ["js"] + pruneopts = "UT" revision = "847fc94819f9d5a4e7154e2203b36f6dbace6f48" [[projects]] + digest = "1:7b5c6e2eeaa9ae5907c391a91c132abfd5c9e8a784a341b5625e750c67e6825d" name = "github.com/gorilla/websocket" packages = ["."] + pruneopts = "UT" revision = "66b9c49e59c6c48f0ffce28c2d8b8a5678502c6d" version = "v1.4.0" [[projects]] + digest = "1:f14364057165381ea296e49f8870a9ffce2b8a95e34d6ae06c759106aaef428c" name = "github.com/hashicorp/go-uuid" packages = ["."] + pruneopts = "UT" revision = "4f571afc59f3043a65f8fe6bf46d887b10a01d43" version = "v1.0.1" [[projects]] + digest = "1:d15ee511aa0f56baacc1eb4c6b922fa1c03b38413b6be18166b996d82a0156ea" name = "github.com/hashicorp/golang-lru" packages = [ ".", - "simplelru" + "simplelru", ] + pruneopts = "UT" revision = "7087cb70de9f7a8bc0a10c375cb0d2280a8edf9c" version = "v0.5.1" [[projects]] branch = "master" + digest = "1:0778dc7fce1b4669a8bfa7ae506ec1f595b6ab0f8989c1c0d22a8ca1144e9972" name = "github.com/howeyc/gopass" packages = ["."] + pruneopts = "UT" revision = "bf9dde6d0d2c004a008c27aaee91170c786f6db8" [[projects]] + digest = "1:a0cefd27d12712af4b5018dc7046f245e1e3b5760e2e848c30b171b570708f9b" name = "github.com/imdario/mergo" packages = ["."] + pruneopts = "UT" revision = "7c29201646fa3de8506f701213473dd407f19646" version = "v0.3.7" [[projects]] branch = "master" + digest = "1:62fe3a7ea2050ecbd753a71889026f83d73329337ada66325cbafd5dea5f713d" name = "github.com/jbenet/go-context" packages = ["io"] + pruneopts = "UT" revision = "d14ea06fba99483203c19d92cfcd13ebe73135f4" [[projects]] branch = "master" + digest = "1:ae221758bdddd57f5c76f4ee5e4110af32ee62583c46299094697f8f127e63da" name = "github.com/jcmturner/gofork" packages = [ "encoding/asn1", - "x/crypto/pbkdf2" + "x/crypto/pbkdf2", ] + pruneopts = "UT" revision = "2aebee971930cd0dd525873330952ab7df5ac95c" [[projects]] + digest = "1:bb81097a5b62634f3e9fec1014657855610c82d19b9a40c17612e32651e35dca" name = "github.com/jmespath/go-jmespath" packages = ["."] + pruneopts = "UT" revision = "c2b33e84" [[projects]] branch = "master" + digest = "1:3daa28dd53624e04229a3499b6bb547b4c467d488e8293b1fc9d67a922713896" name = "github.com/joncalhoun/qson" packages = ["."] + pruneopts = "UT" revision = "8a9cab3a62b1b693e7dfa590a215dc6217552803" [[projects]] + digest = "1:f5a2051c55d05548d2d4fd23d244027b59fbd943217df8aa3b5e170ac2fd6e1b" name = "github.com/json-iterator/go" packages = ["."] + pruneopts = "UT" revision = "0ff49de124c6f76f8494e194af75bde0f1a49a29" version = "v1.1.6" [[projects]] + digest = "1:4b63210654b1f2b664f74ec434a1bb1cb442b3d75742cc064a10808d1cca6361" name = "github.com/jtolds/gls" packages = ["."] + pruneopts = "UT" revision = "b4936e06046bbecbb94cae9c18127ebe510a2cb9" version = "v4.20" [[projects]] + digest = "1:ae5f4d0779a45e2cb3075d8b3ece6c623e171407f4aac83521392ff06d188871" name = "github.com/kevinburke/ssh_config" packages = ["."] + pruneopts = "UT" revision = "81db2a75821ed34e682567d48be488a1c3121088" version = "0.5" [[projects]] + digest = "1:31e761d97c76151dde79e9d28964a812c46efc5baee4085b86f68f0c654450de" name = "github.com/konsorten/go-windows-terminal-sequences" packages = ["."] + pruneopts = "UT" revision = "f55edac94c9bbba5d6182a4be46d86a2c9b5b50e" version = "v1.0.2" [[projects]] branch = "master" + digest = "1:df495c9184b4e6cbb9d55652236dbcbe72c65a1c8b6469da50722628cea474e7" name = "github.com/mailru/easyjson" packages = [ "buffer", "jlexer", - "jwriter" + "jwriter", ] + pruneopts = "UT" revision = "1de009706dbeb9d05f18586f0735fcdb7c524481" [[projects]] + digest = "1:c70f3fece365ee3e884eeff6829879fcd3fc9d9ed41371514c6af1b0e3dd525e" name = "github.com/minio/minio-go" packages = [ ".", @@ -411,238 +519,304 @@ "pkg/encrypt", "pkg/s3signer", "pkg/s3utils", - "pkg/set" + "pkg/set", ] + pruneopts = "UT" revision = "5df22878d3cdee48fbb086449268b1a465147c7d" version = "v6.0.20" [[projects]] + digest = "1:5d231480e1c64a726869bc4142d270184c419749d34f167646baa21008eb0a79" name = "github.com/mitchellh/go-homedir" packages = ["."] + pruneopts = "UT" revision = "af06845cf3004701891bf4fdb884bfe4920b3727" version = "v1.1.0" [[projects]] + digest = "1:53bc4cd4914cd7cd52139990d5170d6dc99067ae31c56530621b18b35fc30318" name = "github.com/mitchellh/mapstructure" packages = ["."] + pruneopts = "UT" revision = "3536a929edddb9a5b34bd6861dc4a9647cb459fe" version = "v1.1.2" [[projects]] + digest = "1:33422d238f147d247752996a26574ac48dcf472976eda7f5134015f06bf16563" name = "github.com/modern-go/concurrent" packages = ["."] + pruneopts = "UT" revision = "bacd9c7ef1dd9b15be4a9909b8ac7a4e313eec94" version = "1.0.3" [[projects]] + digest = "1:e32bdbdb7c377a07a9a46378290059822efdce5c8d96fe71940d87cb4f918855" name = "github.com/modern-go/reflect2" packages = ["."] + pruneopts = "UT" revision = "4b7aa43c6742a2c18fdef89dd197aaae7dac7ccd" version = "1.0.1" [[projects]] + digest = "1:2ca73053216eb11c8eea2855c8099ad82773638522f91cc0542ec9759163ff3c" name = "github.com/nats-io/go-nats" packages = [ ".", "encoders/builtin", - "util" + "util", ] + pruneopts = "UT" revision = "70fe06cee50d4b6f98248d9675fb55f2a3aa7228" version = "v1.7.2" [[projects]] + branch = "master" + digest = "1:b793fd7b6887b8b275e87fc816433e4f4c1aedc663407964cbc9de00f281c661" name = "github.com/nats-io/go-nats-streaming" packages = [ ".", - "pb" + "pb", ] - revision = "4366d43a0648b4997ed32080f937e8702ab86c48" - version = "v0.4.2" + pruneopts = "UT" + revision = "6a8470f970a0f01992927611aed618e6c3f2cc57" [[projects]] + digest = "1:0b5d91120efc54504bc253fda90b08c4be88cd78a4023ef60019e95bb0cdc136" name = "github.com/nats-io/nkeys" packages = ["."] + pruneopts = "UT" revision = "1546a3320a8f195a5b5c84aef8309377c2e411d5" version = "v0.0.2" [[projects]] + digest = "1:c3cd663f2f30b92536b9f290ac85c6310dae36a14cb8961553ae9ccf0d85ae41" name = "github.com/nats-io/nuid" packages = ["."] + pruneopts = "UT" revision = "289cccf02c178dc782430d534e3c1f5b72af807f" version = "v1.0.0" [[projects]] branch = "master" + digest = "1:6dd624a8671468c160bae2737e8f4976741cb76b86c15153242097e1b3e36a0e" name = "github.com/nlopes/slack" packages = [ ".", "slackevents", - "slackutilsx" + "slackutilsx", ] + pruneopts = "UT" revision = "71a00675abf36a35bb4ff7c0fdd3172c9b191b23" [[projects]] + digest = "1:b2ee62e09bec113cf086d2ce0769efcc7bf79481aba8373fd8f7884e94df3462" name = "github.com/pelletier/go-buffruneio" packages = ["."] + pruneopts = "UT" revision = "c37440a7cf42ac63b919c752ca73a85067e05992" version = "v0.2.0" [[projects]] + digest = "1:d4c88b5ad20151a96c1e5a55547a944b6af623aa315f69ee0d172b00f95d27fb" name = "github.com/pierrec/lz4" packages = [ ".", - "internal/xxh32" + "internal/xxh32", ] + pruneopts = "UT" revision = "062282ea0dcff40c9fb8525789eef9644b1fbd6e" version = "v2.1.0" [[projects]] + digest = "1:cf31692c14422fa27c83a05292eb5cbe0fb2775972e8f1f8446a71549bd8980b" name = "github.com/pkg/errors" packages = ["."] + pruneopts = "UT" revision = "ba968bfe8b2f7e042a574c888954fccecfa385b4" version = "v0.8.1" [[projects]] + digest = "1:0028cb19b2e4c3112225cd871870f2d9cf49b9b4276531f03438a88e94be86fe" name = "github.com/pmezard/go-difflib" packages = ["difflib"] + pruneopts = "UT" revision = "792786c7400a136282c1664665ae0a8db921c6c2" version = "v1.0.0" [[projects]] branch = "master" + digest = "1:d38f81081a389f1466ec98192cf9115a82158854d6f01e1c23e2e7554b97db71" name = "github.com/rcrowley/go-metrics" packages = ["."] + pruneopts = "UT" revision = "3113b8401b8a98917cde58f8bbd42a1b1c03b1fd" [[projects]] + digest = "1:ed615c5430ecabbb0fb7629a182da65ecee6523900ac1ac932520860878ffcad" name = "github.com/robfig/cron" packages = ["."] + pruneopts = "UT" revision = "b41be1df696709bb6395fe435af20370037c0b4c" version = "v1.1" [[projects]] + digest = "1:9be615b2a72fc4a99e623c6776cce3afe3451741c34ea1805ea4a9b58604b9df" name = "github.com/rs/zerolog" packages = [ ".", "internal/cbor", - "internal/json" + "internal/json", ] + pruneopts = "UT" revision = "6d6350a51143b5c0d0a6a3b736ee2b41315f7269" version = "v1.12.0" [[projects]] + digest = "1:274f67cb6fed9588ea2521ecdac05a6d62a8c51c074c1fccc6a49a40ba80e925" name = "github.com/satori/go.uuid" packages = ["."] + pruneopts = "UT" revision = "f58768cc1a7a7e77a3bd49e98cdd21419399b6a3" version = "v1.2.0" [[projects]] + digest = "1:d917313f309bda80d27274d53985bc65651f81a5b66b820749ac7f8ef061fd04" name = "github.com/sergi/go-diff" packages = ["diffmatchpatch"] + pruneopts = "UT" revision = "1744e2970ca51c86172c8190fadad617561ed6e7" version = "v1.0.0" [[projects]] + digest = "1:e4c72127d910a96daf869a44f3dd563b86dbe6931a172863a0e99c5ff04b59e4" name = "github.com/sirupsen/logrus" packages = ["."] + pruneopts = "UT" revision = "dae0fa8d5b0c810a8ab733fbd5510c7cae84eca4" version = "v1.4.0" [[projects]] + digest = "1:cc1c574c9cb5e99b123888c12b828e2d19224ab6c2244bda34647f230bf33243" name = "github.com/smartystreets/assertions" packages = [ ".", "internal/go-render/render", - "internal/oglematchers" + "internal/oglematchers", ] + pruneopts = "UT" revision = "7678a5452ebea5b7090a6b163f844c133f523da2" version = "1.8.3" [[projects]] + digest = "1:a3e081e593ee8e3b0a9af6a5dcac964c67a40c4f2034b5345b2ad78d05920728" name = "github.com/smartystreets/goconvey" packages = [ "convey", "convey/gotest", - "convey/reporting" + "convey/reporting", ] + pruneopts = "UT" revision = "9e8dc3f972df6c8fcc0375ef492c24d0bb204857" version = "1.6.3" [[projects]] + digest = "1:c1b1102241e7f645bc8e0c22ae352e8f0dc6484b6cb4d132fa9f24174e0119e2" name = "github.com/spf13/pflag" packages = ["."] + pruneopts = "UT" revision = "298182f68c66c05229eb03ac171abe6e309ee79a" version = "v1.0.3" [[projects]] + digest = "1:e4ed0afd67bf7be353921665cdac50834c867ff1bba153efc0745b755a7f5905" name = "github.com/src-d/gcfg" packages = [ ".", "scanner", "token", - "types" + "types", ] + pruneopts = "UT" revision = "1ac3a1ac202429a54835fe8408a92880156b489d" version = "v1.4.0" [[projects]] branch = "master" + digest = "1:d6bb6f3240a488ffe5bb6952b513569d009927dcb20ff94885f87b76cef2b698" name = "github.com/streadway/amqp" packages = ["."] + pruneopts = "UT" revision = "14f78b41ce6da3d698c2ef2cc8c0ea7ce9e26688" [[projects]] + digest = "1:ac83cf90d08b63ad5f7e020ef480d319ae890c208f8524622a2f3136e2686b02" name = "github.com/stretchr/objx" packages = ["."] + pruneopts = "UT" revision = "477a77ecc69700c7cdeb1fa9e129548e1c1c393c" version = "v0.1.1" [[projects]] + digest = "1:0bcc464dabcfad5393daf87c3f8142911d0f6c52569b837e91a1c15e890265f3" name = "github.com/stretchr/testify" packages = [ "assert", - "mock" + "mock", ] + pruneopts = "UT" revision = "ffdc059bfe9ce6a4e144ba849dbedead332c6053" version = "v1.3.0" [[projects]] + digest = "1:7df351557a6d5c30804e7d6f7ed87f2fccb0619c08fcc84869a93f22bec96c11" name = "github.com/tidwall/gjson" packages = ["."] + pruneopts = "UT" revision = "eee0b6226f0d1db2675a176fdfaa8419bcad4ca8" version = "v1.2.1" [[projects]] + digest = "1:8453ddbed197809ee8ca28b06bd04e127bec9912deb4ba451fea7a1eca578328" name = "github.com/tidwall/match" packages = ["."] + pruneopts = "UT" revision = "33827db735fff6510490d69a8622612558a557ed" version = "v1.0.1" [[projects]] branch = "master" + digest = "1:88611438dc87bda5862e2d12d8e901bac8ebfd4a9034a896d2f69835360439a7" name = "github.com/tidwall/pretty" packages = ["."] + pruneopts = "UT" revision = "65a9db5fad5105a89e17f38adcc9878685be6d78" [[projects]] + digest = "1:b70c951ba6fdeecfbd50dabe95aa5e1b973866ae9abbece46ad60348112214f2" name = "github.com/tidwall/sjson" packages = ["."] + pruneopts = "UT" revision = "25fb082a20e29e83fb7b7ef5f5919166aad1f084" version = "v1.0.4" [[projects]] + digest = "1:e362dddd08e6e894835074b6de49515939dbfb590c7198980639291bab62db4f" name = "github.com/xanzy/go-gitlab" packages = ["."] + pruneopts = "UT" revision = "be70cf752294cc5c6ee89a18d6ba0caca08aa5c7" version = "v0.16.1" [[projects]] + digest = "1:172f94a6b3644a8f9e6b5e5b7fc9fe1e42d424f52a0300b2e7ab1e57db73f85d" name = "github.com/xanzy/ssh-agent" packages = ["."] + pruneopts = "UT" revision = "6a3e2ff9e7c564f36873c2e36413f634534f1c44" version = "v0.2.1" [[projects]] + digest = "1:1381b8539f9abce35487c1df5619c42d6920073a98aab88b68f33a4c8a0c7acc" name = "go.opencensus.io" packages = [ ".", @@ -659,13 +833,15 @@ "trace", "trace/internal", "trace/propagation", - "trace/tracestate" + "trace/tracestate", ] + pruneopts = "UT" revision = "f305e5c4e2cf345eba88de13d10de1126fa45a61" version = "v0.19.1" [[projects]] branch = "master" + digest = "1:7efe22127f18ed47cffc2d564f09d18695ac5396352e6a41be197b5d3ae6ee23" name = "golang.org/x/crypto" packages = [ "argon2", @@ -688,12 +864,14 @@ "ssh", "ssh/agent", "ssh/knownhosts", - "ssh/terminal" + "ssh/terminal", ] + pruneopts = "UT" revision = "a1f597ede03a7bef967a422b5b3a5bd08805a01e" [[projects]] branch = "master" + digest = "1:75634c8443f7435a3d0c5e936d5935b48523c831130b60d67d42df8a1dfd6c14" name = "golang.org/x/net" packages = [ "context", @@ -707,42 +885,50 @@ "proxy", "publicsuffix", "trace", - "websocket" + "websocket", ] + pruneopts = "UT" revision = "9f648a60d9775ef5c977e7669d1673a7a67bef33" [[projects]] branch = "master" + digest = "1:5e9f22cf754ab20a5dff0ae04b12516b112c5b81cd44dccccde148865084d730" name = "golang.org/x/oauth2" packages = [ ".", "google", "internal", "jws", - "jwt" + "jwt", ] + pruneopts = "UT" revision = "e64efc72b421e893cbf63f17ba2221e7d6d0b0f3" [[projects]] branch = "master" + digest = "1:04a5b0e4138f98eef79ce12a955a420ee358e9f787044cc3a553ac3c3ade997e" name = "golang.org/x/sync" packages = [ "errgroup", - "semaphore" + "semaphore", ] + pruneopts = "UT" revision = "e225da77a7e68af35c70ccbf71af2b83e6acac3c" [[projects]] branch = "master" + digest = "1:426092407910bee4a539be5d377abbaf629bae216c8eb2f80409c8cbe2647508" name = "golang.org/x/sys" packages = [ "cpu", "unix", - "windows" + "windows", ] + pruneopts = "UT" revision = "fead79001313d15903fb4605b4a1b781532cd93e" [[projects]] + digest = "1:0c56024909189aee3364b7f21a95a27459f718aa7c199a5c111c36cfffd9eaef" name = "golang.org/x/text" packages = [ "collate", @@ -759,19 +945,23 @@ "unicode/cldr", "unicode/norm", "unicode/rangetable", - "width" + "width", ] + pruneopts = "UT" revision = "f21a4dfb5e38f5895301dc265a8def02365cc3d0" version = "v0.3.0" [[projects]] branch = "master" + digest = "1:9fdc2b55e8e0fafe4b41884091e51e77344f7dc511c5acedcfd98200003bff90" name = "golang.org/x/time" packages = ["rate"] + pruneopts = "UT" revision = "9d24e82272b4f38b78bc8cff74fa936d31ccd8ef" [[projects]] branch = "master" + digest = "1:e46d8e20161401a9cf8765dfa428494a3492a0b56fe114156b7da792bf41ba78" name = "golang.org/x/tools" packages = [ "go/ast/astutil", @@ -785,11 +975,13 @@ "internal/fastwalk", "internal/gopathwalk", "internal/module", - "internal/semver" + "internal/semver", ] + pruneopts = "UT" revision = "1286b2016bb195031cab5657d3244bc996b3f2dd" [[projects]] + digest = "1:dd6e1a70c3d069cb58cb5cd234a6aca65c31b87eecce857b0b140aec96fcee91" name = "google.golang.org/api" packages = [ "googleapi/transport", @@ -800,12 +992,14 @@ "transport", "transport/grpc", "transport/http", - "transport/http/internal/propagation" + "transport/http/internal/propagation", ] + pruneopts = "UT" revision = "e742f5a8defa1f9f5d723dfa04c962e680dc33f0" version = "v0.2.0" [[projects]] + digest = "1:c4eaa5f79d36f76ef4bd0c4f96e36bc1b7b5a359528d1267f0cb7a5d58b7b5bb" name = "google.golang.org/appengine" packages = [ ".", @@ -819,24 +1013,28 @@ "internal/socket", "internal/urlfetch", "socket", - "urlfetch" + "urlfetch", ] + pruneopts = "UT" revision = "e9657d882bb81064595ca3b56cbe2546bbabf7b1" version = "v1.4.0" [[projects]] branch = "master" + digest = "1:7ba623745e0f553da646f5f7c1338fa271c91c4be1cf1a9978369216f7be0c5b" name = "google.golang.org/genproto" packages = [ "googleapis/api/annotations", "googleapis/iam/v1", "googleapis/pubsub/v1", "googleapis/rpc/status", - "protobuf/field_mask" + "protobuf/field_mask", ] + pruneopts = "UT" revision = "5fe7a883aa19554f42890211544aa549836af7b7" [[projects]] + digest = "1:9153ffce82afcac3bf963f2aac8df53a34859e293e7329b00ef42eea00fe100f" name = "google.golang.org/grpc" packages = [ ".", @@ -870,36 +1068,46 @@ "resolver/passthrough", "stats", "status", - "tap" + "tap", ] + pruneopts = "UT" revision = "2fdaae294f38ed9a121193c51ec99fecd3b13eb7" version = "v1.19.0" [[projects]] + digest = "1:2d1fbdc6777e5408cabeb02bf336305e724b925ff4546ded0fa8715a7267922a" name = "gopkg.in/inf.v0" packages = ["."] + pruneopts = "UT" revision = "d2d2541c53f18d2a059457998ce2876cc8e67cbf" version = "v0.9.1" [[projects]] + digest = "1:d37c61a335d13bc49b3f90e9e13c8686e4548839b69c58549e727afb2245c454" name = "gopkg.in/ini.v1" packages = ["."] + pruneopts = "UT" revision = "c85607071cf08ca1adaf48319cd1aa322e81d8c1" version = "v1.42.0" [[projects]] + digest = "1:c902038ee2d6f964d3b9f2c718126571410c5d81251cbab9fe58abd37803513c" name = "gopkg.in/jcmturner/aescts.v1" packages = ["."] + pruneopts = "UT" revision = "f6abebb3171c4c1b1fea279cb7c7325020a26290" version = "v1.0.1" [[projects]] + digest = "1:a1a3e185c03d79a7452d5d5b4c91be4cc433f55e6ed3a35233d852c966e39013" name = "gopkg.in/jcmturner/dnsutils.v1" packages = ["."] + pruneopts = "UT" revision = "13eeb8d49ffb74d7a75784c35e4d900607a3943c" version = "v1.0.1" [[projects]] + digest = "1:653c1ef9be253f28c38612cc0fb0571dd440a3d61a97f82e6205d53942a7b4a9" name = "gopkg.in/jcmturner/gokrb5.v5" packages = [ "asn1tools", @@ -932,30 +1140,36 @@ "messages", "mstypes", "pac", - "types" + "types", ] + pruneopts = "UT" revision = "32ba44ca5b42f17a4a9f33ff4305e70665a1bc0f" version = "v5.3.0" [[projects]] + digest = "1:917e312d1c83bac01db5771433a141f7e4754df0ebe83d2e8edc821320aff849" name = "gopkg.in/jcmturner/rpc.v0" packages = ["ndr"] + pruneopts = "UT" revision = "4480c480c9cd343b54b0acb5b62261cbd33d7adf" version = "v0.0.2" [[projects]] + digest = "1:866df945fc92cd221d2b384dca7de5f3131a6113b9f72a7a8019ae5046abe828" name = "gopkg.in/src-d/go-billy.v4" packages = [ ".", "helper/chroot", "helper/polyfill", "osfs", - "util" + "util", ] + pruneopts = "UT" revision = "982626487c60a5252e7d0b695ca23fb0fa2fd670" version = "v4.3.0" [[projects]] + digest = "1:44801e4be7066a82dc7a7f608d31f99c5c0f5a65a0215b37401a5657ce52940d" name = "gopkg.in/src-d/go-git.v4" packages = [ ".", @@ -998,25 +1212,31 @@ "utils/merkletrie/filesystem", "utils/merkletrie/index", "utils/merkletrie/internal/frame", - "utils/merkletrie/noder" + "utils/merkletrie/noder", ] + pruneopts = "UT" revision = "db6c41c156481962abf9a55a324858674c25ab08" version = "v4.10.0" [[projects]] + digest = "1:78d374b493e747afa9fbb2119687e3740a7fb8d0ebabddfef0a012593aaecbb3" name = "gopkg.in/warnings.v0" packages = ["."] + pruneopts = "UT" revision = "ec4a0fea49c7b46c2aeb0b51aac55779c607e52b" version = "v0.1.2" [[projects]] + digest = "1:4d2e5a73dc1500038e504a8d78b986630e3626dc027bc030ba5c75da257cdb96" name = "gopkg.in/yaml.v2" packages = ["."] + pruneopts = "UT" revision = "51d6538a90f86fe93ac480b35f37b2be17fef232" version = "v2.2.2" [[projects]] branch = "release-1.10" + digest = "1:6ba59e3d220d8f97e1b5e76e20f3f8ef994e8fb43b12fffe404fefbb86249c9a" name = "k8s.io/api" packages = [ "admissionregistration/v1alpha1", @@ -1046,12 +1266,14 @@ "settings/v1alpha1", "storage/v1", "storage/v1alpha1", - "storage/v1beta1" + "storage/v1beta1", ] + pruneopts = "UT" revision = "c89978d5f86d7427bef2fc7752732c8c60b1d188" [[projects]] branch = "release-1.10" + digest = "1:5152b37e3e1beea113d41e6e24e5695c10cec21d3bf6378f87231d8c6462204e" name = "k8s.io/apimachinery" packages = [ "pkg/api/errors", @@ -1080,6 +1302,8 @@ "pkg/util/diff", "pkg/util/errors", "pkg/util/framer", + "pkg/util/httpstream", + "pkg/util/httpstream/spdy", "pkg/util/intstr", "pkg/util/json", "pkg/util/net", @@ -1091,12 +1315,15 @@ "pkg/util/yaml", "pkg/version", "pkg/watch", - "third_party/forked/golang/reflect" + "third_party/forked/golang/netutil", + "third_party/forked/golang/reflect", ] + pruneopts = "UT" revision = "d49e237a2683fa6dc43a86c7b1b766e0219fb6e7" [[projects]] branch = "release-7.0" + digest = "1:f1b5a36c7f39f2d2e7a6ac3f3aa1ccb05de9ba48ad5719275a34fce5fb12766f" name = "k8s.io/client-go" packages = [ "discovery", @@ -1241,20 +1468,24 @@ "tools/clientcmd/api/v1", "tools/metrics", "tools/pager", + "tools/portforward", "tools/reference", "transport", + "transport/spdy", "util/buffer", "util/cert", "util/flowcontrol", "util/homedir", "util/integer", "util/retry", - "util/workqueue" + "util/workqueue", ] + pruneopts = "UT" revision = "36368dede29baa5ecd253416d70ddc0c76bde69b" [[projects]] branch = "release-1.10" + digest = "1:34dc31e1809c951ca635f1e593088b43ad347ba379121b631961bf22737884bb" name = "k8s.io/code-generator" packages = [ "cmd/client-gen", @@ -1281,11 +1512,13 @@ "cmd/openapi-gen", "cmd/openapi-gen/args", "pkg/util", - "third_party/forked/golang/reflect" + "third_party/forked/golang/reflect", ] + pruneopts = "T" revision = "edc41f23fa918716df540b1486477d62237010e4" [[projects]] + digest = "1:a9f99f1c11620be972d49d2e4e296031a5fbc168ada49a9e618d9b35f751f119" name = "k8s.io/gengo" packages = [ "args", @@ -1296,31 +1529,134 @@ "generator", "namer", "parser", - "types" + "types", ] + pruneopts = "T" revision = "b90029ef6cd877cb3f422d75b3a07707e3aac6b7" [[projects]] + digest = "1:72fd56341405f53c745377e0ebc4abeff87f1a048e0eea6568a20212650f5a82" name = "k8s.io/klog" packages = ["."] + pruneopts = "UT" revision = "71442cd4037d612096940ceb0f3fec3f7fff66e0" version = "v0.2.0" [[projects]] branch = "master" + digest = "1:64b9d42751d0965263661eb9d07be8ee56ab5df05e27a5f092d42e6fa3b37b08" name = "k8s.io/kube-openapi" packages = [ "cmd/openapi-gen/args", "pkg/common", "pkg/generators", "pkg/generators/rules", - "pkg/util/sets" + "pkg/util/sets", ] + pruneopts = "UT" revision = "15615b16d372105f0c69ff47dfe7402926a65aaa" [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "c293ab2c7a55af4a7da20b9f2d4944243d7405988de952dc92bed3596dc25205" + input-imports = [ + "cloud.google.com/go/pubsub", + "github.com/Knetic/govaluate", + "github.com/Shopify/sarama", + "github.com/adlio/trello", + "github.com/argoproj/argo/pkg/apis/workflow/v1alpha1", + "github.com/aws/aws-sdk-go/aws", + "github.com/aws/aws-sdk-go/aws/credentials", + "github.com/aws/aws-sdk-go/aws/session", + "github.com/aws/aws-sdk-go/service/sns", + "github.com/aws/aws-sdk-go/service/sqs", + "github.com/colinmarc/hdfs", + "github.com/eclipse/paho.mqtt.golang", + "github.com/fsnotify/fsnotify", + "github.com/ghodss/yaml", + "github.com/go-openapi/spec", + "github.com/gogo/protobuf/protoc-gen-gofast", + "github.com/gogo/protobuf/protoc-gen-gogofast", + "github.com/golang/glog", + "github.com/golang/protobuf/proto", + "github.com/golang/protobuf/protoc-gen-go", + "github.com/google/go-github/github", + "github.com/joncalhoun/qson", + "github.com/minio/minio-go", + "github.com/mitchellh/mapstructure", + "github.com/nats-io/go-nats", + "github.com/nats-io/go-nats-streaming", + "github.com/nlopes/slack/slackevents", + "github.com/pkg/errors", + "github.com/robfig/cron", + "github.com/rs/zerolog", + "github.com/satori/go.uuid", + "github.com/sirupsen/logrus", + "github.com/smartystreets/goconvey/convey", + "github.com/streadway/amqp", + "github.com/stretchr/testify/assert", + "github.com/stretchr/testify/mock", + "github.com/tidwall/gjson", + "github.com/tidwall/sjson", + "github.com/xanzy/go-gitlab", + "golang.org/x/crypto/ssh", + "google.golang.org/api/option", + "google.golang.org/grpc", + "google.golang.org/grpc/connectivity", + "google.golang.org/grpc/metadata", + "gopkg.in/jcmturner/gokrb5.v5/client", + "gopkg.in/jcmturner/gokrb5.v5/config", + "gopkg.in/jcmturner/gokrb5.v5/credentials", + "gopkg.in/jcmturner/gokrb5.v5/keytab", + "gopkg.in/src-d/go-git.v4", + "gopkg.in/src-d/go-git.v4/config", + "gopkg.in/src-d/go-git.v4/plumbing", + "gopkg.in/src-d/go-git.v4/plumbing/transport", + "gopkg.in/src-d/go-git.v4/plumbing/transport/http", + "gopkg.in/src-d/go-git.v4/plumbing/transport/ssh", + "k8s.io/api/core/v1", + "k8s.io/api/rbac/v1", + "k8s.io/apimachinery/pkg/api/errors", + "k8s.io/apimachinery/pkg/api/meta", + "k8s.io/apimachinery/pkg/apis/meta/v1", + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured", + "k8s.io/apimachinery/pkg/fields", + "k8s.io/apimachinery/pkg/labels", + "k8s.io/apimachinery/pkg/runtime", + "k8s.io/apimachinery/pkg/runtime/schema", + "k8s.io/apimachinery/pkg/runtime/serializer", + "k8s.io/apimachinery/pkg/selection", + "k8s.io/apimachinery/pkg/types", + "k8s.io/apimachinery/pkg/util/intstr", + "k8s.io/apimachinery/pkg/util/wait", + "k8s.io/apimachinery/pkg/watch", + "k8s.io/client-go/discovery", + "k8s.io/client-go/discovery/fake", + "k8s.io/client-go/dynamic", + "k8s.io/client-go/dynamic/fake", + "k8s.io/client-go/informers", + "k8s.io/client-go/informers/core/v1", + "k8s.io/client-go/kubernetes", + "k8s.io/client-go/kubernetes/fake", + "k8s.io/client-go/kubernetes/scheme", + "k8s.io/client-go/rest", + "k8s.io/client-go/testing", + "k8s.io/client-go/tools/cache", + "k8s.io/client-go/tools/clientcmd", + "k8s.io/client-go/tools/portforward", + "k8s.io/client-go/transport/spdy", + "k8s.io/client-go/util/flowcontrol", + "k8s.io/client-go/util/workqueue", + "k8s.io/code-generator/cmd/client-gen", + "k8s.io/code-generator/cmd/deepcopy-gen", + "k8s.io/code-generator/cmd/defaulter-gen", + "k8s.io/code-generator/cmd/go-to-protobuf", + "k8s.io/code-generator/cmd/go-to-protobuf/protoc-gen-gogo", + "k8s.io/code-generator/cmd/informer-gen", + "k8s.io/code-generator/cmd/lister-gen", + "k8s.io/code-generator/cmd/openapi-gen", + "k8s.io/gengo/examples/deepcopy-gen", + "k8s.io/kube-openapi/pkg/common", + ] solver-name = "gps-cdcl" solver-version = 1 diff --git a/Makefile b/Makefile index 05bf13e337..c6bb094a1c 100644 --- a/Makefile +++ b/Makefile @@ -274,10 +274,10 @@ slack-image: slack-linux @if [ "$(DOCKER_PUSH)" = "true" ] ; then docker push $(IMAGE_PREFIX)slack-gateway:$(IMAGE_TAG) ; fi test: - go test $(shell go list ./... | grep -v /vendor/) -race -short -v + go test $(shell go list ./... | grep -v /vendor/ | grep -v /test/e2e/) -race -short -v coverage: - go test -covermode=count -coverprofile=profile.cov $(shell go list ./... | grep -v /vendor/) + go test -covermode=count -coverprofile=profile.cov $(shell go list ./... | grep -v /vendor/ | grep -v /test/e2e/) go tool cover -func=profile.cov clean: @@ -297,3 +297,14 @@ openapi-gen: .PHONY: codegen codegen: clientgen openapigen protogen + +.PHONY: e2e +e2e: + ./hack/e2e/run-e2e.sh + +.PHONY: kind-e2e +kind-e2e: + ./hack/e2e/kind-run-e2e.sh + +.PHONY: build-e2e-images +build-e2e-images: sensor-controller-image gateway-controller-image gateway-client-image webhook-image diff --git a/hack/e2e/cleanup-e2e.sh b/hack/e2e/cleanup-e2e.sh new file mode 100755 index 0000000000..e990bdbbbc --- /dev/null +++ b/hack/e2e/cleanup-e2e.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +set -e + +kubectl delete ns -l argo-events-e2e diff --git a/hack/e2e/kind-run-e2e.sh b/hack/e2e/kind-run-e2e.sh new file mode 100755 index 0000000000..5b1d41b513 --- /dev/null +++ b/hack/e2e/kind-run-e2e.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +set -e + +PROJECT_ROOT=$(cd $(dirname ${BASH_SOURCE})/../..; pwd) +KUBERNETES_VERSION=${KUBERNETES_VERSION:-kindest/node:v1.13.4} +CLUSTER_NAME=${CLUSTER_NAME:-kind-argo-events} +IMAGE_PREFIX=${IMAGE_PREFIX:-argoproj/} +IMAGE_TAG=${IMAGE_TAG:-latest} + +kind create cluster --name $CLUSTER_NAME --image $KUBERNETES_VERSION +export KUBECONFIG="$(kind get kubeconfig-path --name=$CLUSTER_NAME)" +kubectl cluster-info + +function cleanup { + if [[ -z "$KEEP_CLUSTER" ]]; then + echo "* Cleaning up the e2e cluter..." + kind delete cluster --name $CLUSTER_NAME + else + echo "* Skip e2e cluster cleanup for $CLUSTER_NAME." + fi +} +trap cleanup EXIT + +kind load docker-image --name $CLUSTER_NAME ${IMAGE_PREFIX}sensor-controller:${IMAGE_TAG} ${IMAGE_PREFIX}gateway-controller:${IMAGE_TAG} ${IMAGE_PREFIX}webhook-gateway:${IMAGE_TAG} ${IMAGE_PREFIX}gateway-client:${IMAGE_TAG} + +# Avoid too early access +sleep 1 + +$PROJECT_ROOT/hack/e2e/run-e2e.sh diff --git a/hack/e2e/manifests/argo-events-cluster-roles.yaml b/hack/e2e/manifests/argo-events-cluster-roles.yaml new file mode 100644 index 0000000000..9d728eec57 --- /dev/null +++ b/hack/e2e/manifests/argo-events-cluster-roles.yaml @@ -0,0 +1,94 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: argo-events-binding + namespace: "__E2E_ID__" +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: argo-events-role +subjects: +- kind: ServiceAccount + name: argo-events-sa + namespace: "__E2E_ID__" +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: argo-events-role + namespace: "__E2E_ID__" +rules: + - apiGroups: + - apiextensions.k8s.io + - apiextensions.k8s.io/v1beta1 + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch + resources: + - customresourcedefinitions + - apiGroups: + - argoproj.io + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch + resources: + - gateways + - gateways/finalizers + - sensors + - sensors/finalizers + - apiGroups: + - "" + resources: + - pods + - pods/exec + - configmaps + - secrets + - services + - events + - persistentvolumeclaims + verbs: + - create + - get + - list + - watch + - update + - patch + - delete + - apiGroups: + - "batch" + resources: + - jobs + verbs: + - create + - get + - list + - watch + - update + - patch + - delete + - apiGroups: + - "apps/v1" + - "apps/v1beta2" + - "apps/v1beta1" + resources: + - deployments + verbs: + - create + - get + - list + - watch + - update + - patch + - delete diff --git a/hack/e2e/manifests/argo-events-sa.yaml b/hack/e2e/manifests/argo-events-sa.yaml new file mode 100644 index 0000000000..c3c7bd3013 --- /dev/null +++ b/hack/e2e/manifests/argo-events-sa.yaml @@ -0,0 +1,5 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: argo-events-sa + namespace: "__E2E_ID__" diff --git a/hack/e2e/manifests/gateway-controller-configmap.yaml b/hack/e2e/manifests/gateway-controller-configmap.yaml new file mode 100644 index 0000000000..75227674f7 --- /dev/null +++ b/hack/e2e/manifests/gateway-controller-configmap.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: gateway-controller-configmap + namespace: "__E2E_ID__" +data: + config: | + instanceID: "__E2E_ID__" + namespace: "" diff --git a/hack/e2e/manifests/gateway-controller-deployment.yaml b/hack/e2e/manifests/gateway-controller-deployment.yaml new file mode 100644 index 0000000000..d855fcdd83 --- /dev/null +++ b/hack/e2e/manifests/gateway-controller-deployment.yaml @@ -0,0 +1,26 @@ +apiVersion: apps/v1beta1 +kind: Deployment +metadata: + name: gateway-controller + namespace: "__E2E_ID__" + labels: + gateways.argoproj.io/sensor-controller-instanceid: "__E2E_ID__" +spec: + replicas: 1 + template: + metadata: + labels: + app: gateway-controller + spec: + serviceAccountName: argo-events-sa + containers: + - name: gateway-controller + image: argoproj/gateway-controller + imagePullPolicy: Always + env: + - name: GATEWAY_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: GATEWAY_CONTROLLER_CONFIG_MAP + value: gateway-controller-configmap diff --git a/hack/e2e/manifests/sensor-controller-configmap.yaml b/hack/e2e/manifests/sensor-controller-configmap.yaml new file mode 100644 index 0000000000..e86e6b811b --- /dev/null +++ b/hack/e2e/manifests/sensor-controller-configmap.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: sensor-controller-configmap + namespace: "__E2E_ID__" +data: + config: | + instanceID: "__E2E_ID__" + namespace: "" diff --git a/hack/e2e/manifests/sensor-controller-deployment.yaml b/hack/e2e/manifests/sensor-controller-deployment.yaml new file mode 100644 index 0000000000..dce7fb8510 --- /dev/null +++ b/hack/e2e/manifests/sensor-controller-deployment.yaml @@ -0,0 +1,26 @@ +apiVersion: apps/v1beta1 +kind: Deployment +metadata: + name: sensor-controller + namespace: "__E2E_ID__" + labels: + sensors.argoproj.io/sensor-controller-instanceid: "__E2E_ID__" +spec: + replicas: 1 + template: + metadata: + labels: + app: sensor-controller + spec: + serviceAccountName: argo-events-sa + containers: + - name: sensor-controller + image: argoproj/sensor-controller + imagePullPolicy: Always + env: + - name: SENSOR_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: SENSOR_CONFIG_MAP + value: sensor-controller-configmap diff --git a/hack/e2e/run-e2e.sh b/hack/e2e/run-e2e.sh new file mode 100755 index 0000000000..018f686bf7 --- /dev/null +++ b/hack/e2e/run-e2e.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +set -e + +PROJECT_ROOT=$(cd $(dirname ${BASH_SOURCE})/../..; pwd) + +export E2E_ID=${E2E_ID:-argo-events-e2e-$(date +%s)} + +$PROJECT_ROOT/hack/e2e/setup-e2e.sh + +function cleanup { + if [[ -z "$KEEP_NAMESPACE" ]]; then + echo "* Cleaning up the e2e environment..." + kubectl delete ns $E2E_ID + else + echo "* Skip e2e environment cleanup for $E2E_ID." + fi +} +trap cleanup EXIT + +echo "* Run e2e tests." +go test -v ./test/e2e/... diff --git a/hack/e2e/setup-e2e.sh b/hack/e2e/setup-e2e.sh new file mode 100755 index 0000000000..7a27289ef5 --- /dev/null +++ b/hack/e2e/setup-e2e.sh @@ -0,0 +1,45 @@ +#!/bin/bash + +set -e + +PROJECT_ROOT=$(cd $(dirname ${BASH_SOURCE})/../..; pwd) + +if [[ -z "$E2E_ID" ]]; then + E2E_ID="argo-events-e2e" +fi + +echo "* Set up e2e test $E2E_ID" + +kubectl apply -f $PROJECT_ROOT/hack/k8s/manifests/gateway-crd.yaml +kubectl apply -f $PROJECT_ROOT/hack/k8s/manifests/sensor-crd.yaml + +echo "* Creating the e2e environment..." +kubectl apply -f - << EOS +apiVersion: v1 +kind: Namespace +metadata: + name: "$E2E_ID" + labels: + argo-events-e2e: "$E2E_ID" +EOS + +# ls $PROJECT_ROOT/hack/e2e/manifests/* | xargs -I {} sed -e "s|__E2E_ID__|$E2E_ID|g" {} | kubectl apply -f - +manifests=$(ls $PROJECT_ROOT/hack/e2e/manifests/*) +for m in $manifests; do + sed -e "s|__E2E_ID__|$E2E_ID|g" $m | kubectl apply -f - +done + +# wait for controllers up +echo "* Wait for controllers startup..." +sleep 3 +for i in {1..60}; do + pods_cnt=$(kubectl get pod -n "$E2E_ID" --no-headers --field-selector "status.phase=Running" 2> /dev/null | wc -l | xargs) + if [[ $pods_cnt -eq 2 ]]; then + break + fi + if [[ $i -eq 60 ]]; then + echo "* The controllers didn't start up within the time limit." + exit 1 + fi + sleep 1 +done diff --git a/test/e2e/common/client.go b/test/e2e/common/client.go new file mode 100644 index 0000000000..76c3ce0e58 --- /dev/null +++ b/test/e2e/common/client.go @@ -0,0 +1,314 @@ +package common + +import ( + "bytes" + "fmt" + "io/ioutil" + "math/rand" + "net/http" + "net/url" + "os" + "path/filepath" + "strconv" + "strings" + "time" + + "github.com/pkg/errors" + + corev1 "k8s.io/api/core/v1" + rbacv1 "k8s.io/api/rbac/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/discovery" + "k8s.io/client-go/dynamic" + "k8s.io/client-go/kubernetes/scheme" + restclient "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" + "k8s.io/client-go/tools/portforward" + "k8s.io/client-go/transport/spdy" + + gwv1 "github.com/argoproj/argo-events/pkg/apis/gateway/v1alpha1" + sv1 "github.com/argoproj/argo-events/pkg/apis/sensor/v1alpha1" +) + +func init() { + // Add custom schemes + if err := sv1.AddToScheme(scheme.Scheme); err != nil { + panic(err) + } + if err := gwv1.AddToScheme(scheme.Scheme); err != nil { + panic(err) + } +} + +type E2EClient struct { + Config *restclient.Config + dynamic.ClientPool + discovery.DiscoveryClient + E2EID string + ClientID string +} + +func NewE2EClient(e2eID string) (*E2EClient, error) { + var kubeconfig string + if os.Getenv("KUBECONFIG") != "" { + kubeconfig = os.Getenv("KUBECONFIG") + } else { + kubeconfig = filepath.Join(os.Getenv("HOME"), ".kube/config") + } + config, err := clientcmd.BuildConfigFromFlags("", kubeconfig) + if err != nil { + return nil, err + } + clientPool := dynamic.NewDynamicClientPool(config) + + disco, err := discovery.NewDiscoveryClientForConfig(config) + if err != nil { + return nil, err + } + + myrand := rand.New(rand.NewSource(time.Now().UnixNano())) + clientID := strconv.FormatUint(myrand.Uint64(), 16) + + return &E2EClient{ + Config: config, + ClientPool: clientPool, + DiscoveryClient: *disco, + E2EID: e2eID, + ClientID: clientID, + }, nil +} + +func (clpl *E2EClient) CreateTmpNamespace() (string, error) { + namespace := &corev1.Namespace{ + TypeMeta: metav1.TypeMeta{ + Kind: "Namespace", + APIVersion: "v1", + }, + ObjectMeta: metav1.ObjectMeta{ + GenerateName: fmt.Sprintf("%s-", clpl.E2EID), + Labels: map[string]string{ + ArgoEventsE2ETestLabelKey: clpl.E2EID, + ArgoEventsE2ETestClientIDLabelKey: clpl.ClientID, + }, + }, + } + ns, err := clpl.Create("", namespace) + if err != nil { + return "", err + } + + nsName := ns.GetName() + binding := &rbacv1.RoleBinding{ + TypeMeta: metav1.TypeMeta{ + Kind: "RoleBinding", + APIVersion: "rbac.authorization.k8s.io/v1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: nsName, + Namespace: nsName, + }, + Subjects: []rbacv1.Subject{ + { + Kind: "ServiceAccount", + Name: "default", + Namespace: nsName, + }, + }, + RoleRef: rbacv1.RoleRef{ + APIGroup: "rbac.authorization.k8s.io", + Kind: "ClusterRole", + Name: "argo-events-role", + }, + } + + _, err = clpl.Create(nsName, binding) + if err != nil { + return "", err + } + + return nsName, nil +} + +func (clpl *E2EClient) DeleteNamespaces() error { + client, err := clpl.GetClient("", schema.GroupVersionKind{Group: "", Version: "v1", Kind: "Namespace"}) + if err != nil { + return err + } + // DeleteCollection is not supported for namespaces, + // so list namespaces and delete them one by one. + labelSelector := labels.Set(map[string]string{ArgoEventsE2ETestClientIDLabelKey: clpl.ClientID}).String() + obj, err := client.List(metav1.ListOptions{LabelSelector: labelSelector}) + if err != nil { + return err + } + uObj, err := runtime.DefaultUnstructuredConverter.ToUnstructured(obj) + if err != nil { + return err + } + for _, ns := range (unstructured.UnstructuredList{Object: uObj}).Items { + err := client.Delete(ns.GetName(), &metav1.DeleteOptions{}) + if err != nil { + return err + } + } + return nil +} + +func (clpl *E2EClient) GetClient(namespace string, gvk schema.GroupVersionKind) (dynamic.ResourceInterface, error) { + client, err := clpl.ClientPool.ClientForGroupVersionKind(gvk) + if err != nil { + return nil, err + } + + resources, err := clpl.DiscoveryClient.ServerResourcesForGroupVersion(gvk.GroupVersion().String()) + if err != nil { + return nil, err + } + + for _, resource := range resources.APIResources { + if resource.Kind == gvk.Kind { + return client.Resource(&resource, namespace), nil + } + } + + return nil, fmt.Errorf("resource not found: %v", gvk) +} + +func (clpl *E2EClient) Create(namespace string, obj runtime.Object) (*unstructured.Unstructured, error) { + uObj, err := runtime.DefaultUnstructuredConverter.ToUnstructured(obj) + if err != nil { + return nil, err + } + unstructuredObj := &unstructured.Unstructured{Object: uObj} + + client, err := clpl.GetClient(namespace, obj.GetObjectKind().GroupVersionKind()) + if err != nil { + return nil, err + } + + return client.Create(unstructuredObj) +} + +func (clpl *E2EClient) CreateResourceFromYaml(namespace, path string, modFunc func(*unstructured.Unstructured) error) (*unstructured.Unstructured, error) { + bytes, err := ioutil.ReadFile(path) + if err != nil { + return nil, err + } + + obj, _, err := scheme.Codecs.UniversalDeserializer().Decode(bytes, nil, nil) + if err != nil { + return nil, err + } + + uObj, err := runtime.DefaultUnstructuredConverter.ToUnstructured(obj) + if err != nil { + return nil, err + } + + unstructuredObj := &unstructured.Unstructured{Object: uObj} + + if modFunc != nil { + err = modFunc(unstructuredObj) + if err != nil { + return nil, err + } + } + + return clpl.Create(namespace, unstructuredObj) +} + +func (clpl *E2EClient) Get(namespace string, gvk schema.GroupVersionKind, name string) (*unstructured.Unstructured, error) { + client, err := clpl.GetClient(namespace, gvk) + if err != nil { + return nil, err + } + + return client.Get(name, metav1.GetOptions{}) +} + +func (clpl *E2EClient) GetPod(namespace string, name string) (*corev1.Pod, error) { + client, err := clpl.GetClient(namespace, schema.GroupVersionKind{Version: "v1", Kind: "Pod"}) + if err != nil { + return nil, err + } + + uObj, err := client.Get(name, metav1.GetOptions{}) + if err != nil { + return nil, err + } + + newObj := &corev1.Pod{} + err = runtime.DefaultUnstructuredConverter.FromUnstructured(uObj.Object, newObj) + if err != nil { + return nil, err + } + return newObj, nil +} + +func (clpl *E2EClient) GetService(namespace string, name string) (*corev1.Service, error) { + client, err := clpl.GetClient(namespace, schema.GroupVersionKind{Version: "v1", Kind: "Service"}) + if err != nil { + return nil, err + } + + uObj, err := client.Get(name, metav1.GetOptions{}) + if err != nil { + return nil, err + } + + newObj := &corev1.Service{} + err = runtime.DefaultUnstructuredConverter.FromUnstructured(uObj.Object, newObj) + if err != nil { + return nil, err + } + return newObj, nil +} + +func (clpl *E2EClient) ForwardServicePort(tmpNamespace, podName string, localPort, targetPort int) (chan struct{}, error) { + // Implementation ref: https://github.com/kubernetes/client-go/issues/51#issuecomment-436200428 + roundTripper, upgrader, err := spdy.RoundTripperFor(clpl.Config) + if err != nil { + return nil, err + } + + path := fmt.Sprintf("/api/v1/namespaces/%s/pods/%s/portforward", tmpNamespace, podName) + hostIP := strings.TrimLeft(clpl.Config.Host, "https://") + serverURL := url.URL{Scheme: "https", Path: path, Host: hostIP} + + dialer := spdy.NewDialer(upgrader, &http.Client{Transport: roundTripper}, http.MethodPost, &serverURL) + + stopChan, readyChan := make(chan struct{}, 1), make(chan struct{}, 1) + + portDesc := fmt.Sprintf("%d:%d", localPort, targetPort) + out, errOut := new(bytes.Buffer), new(bytes.Buffer) + forwarder, err := portforward.New(dialer, []string{portDesc}, stopChan, readyChan, out, errOut) + if err != nil { + return nil, err + } + + go func() { + err = forwarder.ForwardPorts() + if err != nil { + fmt.Printf("%+v\n", err) + } + }() + + err = nil +L: + for { + select { + case <-time.After(10 * time.Second): + err = errors.New("timed out port forwarding") + break L + case <-readyChan: + break L + default: + } + } + + return stopChan, err +} diff --git a/test/e2e/common/constants.go b/test/e2e/common/constants.go new file mode 100644 index 0000000000..47e633a158 --- /dev/null +++ b/test/e2e/common/constants.go @@ -0,0 +1,6 @@ +package common + +const ( + ArgoEventsE2ETestLabelKey = "argo-events-e2e" + ArgoEventsE2ETestClientIDLabelKey = "argo-events-e2e-client-id" +) diff --git a/test/e2e/common/manifests/namespace.yaml b/test/e2e/common/manifests/namespace.yaml new file mode 100644 index 0000000000..08210fa8b7 --- /dev/null +++ b/test/e2e/common/manifests/namespace.yaml @@ -0,0 +1,7 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: "TBA" + labels: + argo-events-e2e: "TBA" + argo-events-e2e-client-id: "TBA" diff --git a/test/e2e/common/manifests/rolebinding.yaml b/test/e2e/common/manifests/rolebinding.yaml new file mode 100644 index 0000000000..1cd6a50a0a --- /dev/null +++ b/test/e2e/common/manifests/rolebinding.yaml @@ -0,0 +1,13 @@ +apiVersion: "rbac.authorization.k8s.io/v1" +kind: RoleBinding +metadata: + name: "argo-events-role" + namespace: "__E2E_ID__" +subjects: +- kind: ServiceAccount + name: "default" + namespace: "__E2E_ID__" +roleRef: + apiGroup: "rbac.authorization.k8s.io" + kind: ClusterRole + name: "argo-events-role" diff --git a/test/e2e/common/misc.go b/test/e2e/common/misc.go new file mode 100644 index 0000000000..fe5c585f85 --- /dev/null +++ b/test/e2e/common/misc.go @@ -0,0 +1,28 @@ +package common + +import ( + "os" + + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" +) + +func GetE2EID() string { + e2eID := os.Getenv("E2E_ID") + if e2eID == "" { + e2eID = "argo-events-e2e" + } + return e2eID +} + +func KeepNamespace() bool { + return os.Getenv("KEEP_NAMESPACE") != "" +} + +func SetLabel(obj *unstructured.Unstructured, key, val string) { + labels := obj.GetLabels() + if labels == nil { + labels = make(map[string]string) + } + labels[key] = val + obj.SetLabels(labels) +} diff --git a/test/e2e/core/main_test.go b/test/e2e/core/main_test.go new file mode 100644 index 0000000000..2b53263cb6 --- /dev/null +++ b/test/e2e/core/main_test.go @@ -0,0 +1,204 @@ +package core + +import ( + "fmt" + "net" + "net/http" + "os" + "path/filepath" + "runtime" + "strings" + "testing" + "time" + + "github.com/smartystreets/goconvey/convey" + + "github.com/argoproj/argo-events/common" + e2ecommon "github.com/argoproj/argo-events/test/e2e/common" + corev1 "k8s.io/api/core/v1" + apierr "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" +) + +var ( + client *e2ecommon.E2EClient + e2eID string +) + +func setup() error { + e2eID = e2ecommon.GetE2EID() + cli, err := e2ecommon.NewE2EClient(e2eID) + if err != nil { + return err + } + client = cli + return nil +} + +func teardown() { + if !e2ecommon.KeepNamespace() { + if client != nil { + err := client.DeleteNamespaces() + if err != nil { + fmt.Printf("%+v\n", err) + } + } + } +} + +func TestMain(m *testing.M) { + err := setup() + if err != nil { + teardown() + panic(err) + } + ret := m.Run() + teardown() + os.Exit(ret) +} + +func TestGeneralUseCase(t *testing.T) { + tmpNamespace, err := client.CreateTmpNamespace() + if err != nil { + t.Fatal(err) + } + + _, filename, _, _ := runtime.Caller(0) + dir, err := filepath.Abs(filepath.Dir(filename)) + if err != nil { + t.Fatal(err) + } + manifestsDir := filepath.Join(dir, "manifests", "general-use-case") + + convey.Convey("Test the general use case", t, func() { + convey.Convey("Create a gateway.", func() { + _, err := client.CreateResourceFromYaml(tmpNamespace, filepath.Join(manifestsDir, "webhook-gateway.yaml"), func(obj *unstructured.Unstructured) error { + e2ecommon.SetLabel(obj, common.LabelKeyGatewayControllerInstanceID, e2eID) + return nil + }) + if err != nil { + t.Fatal(err) + } + _, err = client.CreateResourceFromYaml(tmpNamespace, filepath.Join(manifestsDir, "webhook-gateway-configmap.yaml"), nil) + if err != nil { + t.Fatal(err) + } + }) + + convey.Convey("Create a sensor.", func() { + _, err := client.CreateResourceFromYaml(tmpNamespace, filepath.Join(manifestsDir, "webhook-sensor.yaml"), func(obj *unstructured.Unstructured) error { + e2ecommon.SetLabel(obj, common.LabelKeySensorControllerInstanceID, e2eID) + return nil + }) + if err != nil { + t.Fatal(err) + } + }) + + convey.Convey("Wait for corresponding resources.", func() { + ticker := time.NewTicker(time.Second) + defer ticker.Stop() + var gwpod, spod *corev1.Pod + var gwsvc *corev1.Service + L: + for { + select { + case _ = <-ticker.C: + if gwpod == nil { + pod, err := client.GetPod(tmpNamespace, "webhook-gateway") + if err != nil && !apierr.IsNotFound(err) { + t.Error(err) + break L + } + if pod != nil && pod.Status.Phase == corev1.PodRunning { + gwpod = pod + } + } + if gwsvc == nil { + svc, err := client.GetService(tmpNamespace, "webhook-gateway-svc") + if err != nil && !apierr.IsNotFound(err) { + t.Error(err) + break L + } + gwsvc = svc + } + if spod == nil { + pod, err := client.GetPod(tmpNamespace, "webhook-sensor") + if err != nil && !apierr.IsNotFound(err) { + t.Error(err) + break L + } + if pod != nil && pod.Status.Phase == corev1.PodRunning { + spod = pod + } + } + if gwpod != nil && gwsvc != nil && spod != nil { + break L + } + case <-time.After(10 * time.Second): + t.Error("timed out gateway and sensor startup") + break L + } + } + if t.Failed() { + t.FailNow() + } + }) + + convey.Convey("Make a request to the gateway.", func() { + // Avoid too early access + time.Sleep(5 * time.Second) + + // Use available port + l, _ := net.Listen("tcp", ":0") + port := l.Addr().(*net.TCPAddr).Port + l.Close() + + // Use port forwarding to access pods in minikube + stopChan, err := client.ForwardServicePort(tmpNamespace, "webhook-gateway", port, 12000) + if err != nil { + t.Fatal(err) + } + defer close(stopChan) + + url := fmt.Sprintf("http://localhost:%d/foo", port) + req, err := http.NewRequest("POST", url, strings.NewReader("e2e")) + if err != nil { + t.Fatal(err) + } + + resp, err := new(http.Client).Do(req) + if err != nil { + t.Fatal(err) + } + defer resp.Body.Close() + + if t.Failed() { + t.FailNow() + } + }) + + convey.Convey("Check if the sensor trigggered a pod.", func() { + ticker2 := time.NewTicker(time.Second) + defer ticker2.Stop() + L: + for { + select { + case _ = <-ticker2.C: + pod, err := client.GetPod(tmpNamespace, "webhook-sensor-triggered-pod") + if err != nil && !apierr.IsNotFound(err) { + t.Error(err) + break L + } + if pod != nil && pod.Status.Phase == corev1.PodSucceeded { + convey.So(pod.Spec.Containers[0].Args[0], convey.ShouldEqual, "e2e") + break L + } + case <-time.After(10 * time.Second): + t.Error("timed out gateway and sensor startup") + break L + } + } + }) + }) +} diff --git a/test/e2e/core/manifests/general-use-case/webhook-gateway-configmap.yaml b/test/e2e/core/manifests/general-use-case/webhook-gateway-configmap.yaml new file mode 100644 index 0000000000..2f49c9d6f0 --- /dev/null +++ b/test/e2e/core/manifests/general-use-case/webhook-gateway-configmap.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: webhook-gateway-configmap +data: + foo: |- + port: "12000" + endpoint: "/foo" + method: "POST" diff --git a/test/e2e/core/manifests/general-use-case/webhook-gateway.yaml b/test/e2e/core/manifests/general-use-case/webhook-gateway.yaml new file mode 100644 index 0000000000..588dbe745c --- /dev/null +++ b/test/e2e/core/manifests/general-use-case/webhook-gateway.yaml @@ -0,0 +1,45 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Gateway +metadata: + name: webhook-gateway + labels: + gateways.argoproj.io/gateway-controller-instanceid: "__E2E_ID__" +spec: + configMap: "webhook-gateway-configmap" + type: "webhook" + processorPort: "9330" + eventProtocol: + type: "HTTP" + http: + port: "9300" + eventVersion: "1.0" + template: + metadata: + name: "webhook-gateway" + labels: + gateway-name: "webhook-gateway" + spec: + containers: + - name: "gateway-client" + image: "argoproj/gateway-client" + imagePullPolicy: "IfNotPresent" + command: ["/bin/gateway-client"] + - name: "webhook-events" + image: "argoproj/webhook-gateway" + imagePullPolicy: "IfNotPresent" + command: ["/bin/webhook-gateway"] + # ports: + # - containerPort: 12000 + service: + metadata: + name: "webhook-gateway-svc" + spec: + selector: + gateway-name: "webhook-gateway" + ports: + - port: 12000 + targetPort: 12000 + type: ClusterIP + watchers: + sensors: + - name: "webhook-sensor" diff --git a/test/e2e/core/manifests/general-use-case/webhook-sensor.yaml b/test/e2e/core/manifests/general-use-case/webhook-sensor.yaml new file mode 100644 index 0000000000..adfab2bbfd --- /dev/null +++ b/test/e2e/core/manifests/general-use-case/webhook-sensor.yaml @@ -0,0 +1,41 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Sensor +metadata: + name: webhook-sensor + labels: + sensors.argoproj.io/sensor-controller-instanceid: "__E2E_ID__" +spec: + template: + spec: + containers: + - name: "sensor" + image: "argoproj/sensor" + imagePullPolicy: "IfNotPresent" + dependencies: + - name: "webhook-gateway:foo" + eventProtocol: + type: "HTTP" + http: + port: "9300" + triggers: + - template: + name: webhook-pod-trigger + version: v1 + kind: Pod + source: + inline: | + apiVersion: v1 + kind: Pod + metadata: + name: webhook-sensor-triggered-pod + spec: + containers: + - name: whalesay + image: docker/whalesay:latest + command: [cowsay] + args: ["TO_BE_PASSED"] + restartPolicy: "Never" + resourceParameters: + - src: + event: "webhook-gateway:foo" + dest: spec.containers.0.args.0