From b4538574ad1154389e1177f2355578c6ba57a1b9 Mon Sep 17 00:00:00 2001 From: parauliya Date: Thu, 18 Jun 2020 20:39:14 +0530 Subject: [PATCH] Fixed Issue 80: Modified the test framework for tink repo This framework was written a while ago but is commented and there have been a lot of changes since then. 1. Remove the target concepts completely 2. Changed the way of writting templates 3. Changed the way of creating workflows 4. Generating certs are not the part of docker-compose anymore TODO: This framework works well for single worker. There are few changes required in the framework to make it work for multiple workers --- .drone.yml | 9 +- go.mod | 1 + test-docker-compose.yml | 158 ---------------------------- test/actions/update_data/Dockerfile | 5 +- test/data/hardware/hardware_1.json | 128 ++++------------------ test/data/hardware/hardware_2.json | 128 ++++------------------ test/data/template/sample_1 | 2 +- test/e2e_test.go | 152 ++++++++++++++------------ test/framework/setup.go | 15 +-- test/framework/tearDown.go | 2 +- test/framework/utils.go | 5 +- test/framework/worker.go | 3 +- test/generate_certs.sh | 67 ++++++++++++ test/push_images.sh | 7 +- test/test_wf_timeout.go | 98 ++++++++--------- test/test_wf_with_worker.go | 108 ++++++++++--------- 16 files changed, 332 insertions(+), 556 deletions(-) delete mode 100644 test-docker-compose.yml create mode 100755 test/generate_certs.sh diff --git a/.drone.yml b/.drone.yml index 27f098a5c..08d2be33a 100644 --- a/.drone.yml +++ b/.drone.yml @@ -46,6 +46,7 @@ quay_settings_pr: &quay_settings_pr password: from_secret: public_docker_password + kind: pipeline type: docker name: default @@ -54,7 +55,13 @@ steps: - name: test image: golang:1.13-alpine3.11 commands: - - CGO_ENABLED=0 go test -v ./... + - apk add --update make + - apk add docker + - apk add docker-compose + - CGO_ENABLED=0 make test + volumes: + - name: docker_sock + path: /var/run/docker.sock - name: ci-checks image: nixos/nix:2.3.4 diff --git a/go.mod b/go.mod index 7bc4b2776..bdd856dc2 100644 --- a/go.mod +++ b/go.mod @@ -42,6 +42,7 @@ require ( github.com/spf13/jwalterweatherman v0.0.0-20180109140146-7c0cea34c8ec // indirect github.com/spf13/pflag v1.0.1 // indirect github.com/spf13/viper v1.0.2 + github.com/stretchr/testify v1.3.0 go.mongodb.org/mongo-driver v1.1.2 // indirect go.uber.org/atomic v1.2.0 // indirect go.uber.org/multierr v1.1.0 // indirect diff --git a/test-docker-compose.yml b/test-docker-compose.yml deleted file mode 100644 index e31c410d0..000000000 --- a/test-docker-compose.yml +++ /dev/null @@ -1,158 +0,0 @@ -version: "2.1" -services: - certs: - build: tls - volumes: - - ./certs:/certs - - tinkerbell: - build: . - environment: - FACILITY: ${FACILITY:-lab1} - PACKET_ENV: ${PACKET_ENV:-testing} - PACKET_VERSION: ${PACKET_VERSION:-5efab5ef3a42cb88f2d54f4ed3201c2dd6797b7d} - ROLLBAR_TOKEN: ${ROLLBAR_TOKEN:-9b78d0ad01d1467aa92c49c3a349b79d} - ROLLBAR_DISABLE: ${ROLLBAR_DISABLE:-0} - PGDATABASE: tinkerbell - PGHOST: db - PGPASSWORD: tinkerbell - PGPORT: 5432 - PGSSLMODE: disable - PGUSER: tinkerbell - depends_on: - certs: - condition: service_started - fluentbit: - condition: service_started - db: - condition: service_healthy - healthcheck: - test: ["CMD-SHELL", "wget -qO- 127.0.0.1:42114/cert"] - interval: 5s - timeout: 2s - retries: 30 - volumes: - - ./certs:/certs/${FACILITY} - #logging: - #driver: fluentd - #options: - #tag: tinkerbell - ports: - - 42113:42113/tcp - - 42114:42114/tcp - - db: - build: - context: deploy - environment: - POSTGRES_DB: tinkerbell - POSTGRES_PASSWORD: tinkerbell - POSTGRES_USER: tinkerbell - ports: - - 5432:5432 - depends_on: - - "fluentbit" - healthcheck: - test: ["CMD-SHELL", "pg_isready -U tinkerbell"] - #test: ["CMD-SHELL","psql -U tinkerbell -c \"select COUNT(*) from hardware;\""] - interval: 1s - timeout: 1s - retries: 30 - logging: - driver: fluentd - options: - tag: db - - registry: - build: - context: registry - args: - REGISTRY_USERNAME: username - REGISTRY_PASSWORD: password - environment: - REGISTRY_HTTP_ADDR: localhost:443 - REGISTRY_HTTP_TLS_CERTIFICATE: /certs/server.pem - REGISTRY_HTTP_TLS_KEY: /certs/server-key.pem - REGISTRY_AUTH: htpasswd - REGISTRY_AUTH_HTPASSWD_REALM: "Registry Realm" - REGISTRY_AUTH_HTPASSWD_PATH: /auth/htpasswd - volumes: - - ./certs:/certs - depends_on: - - fluentbit - logging: - driver: fluentd - options: - tag: registry - network_mode: host - - boots: - build: - context: ../boots - network_mode: host - command: -dhcp-addr 0.0.0.0:67 -tftp-addr 127.0.0.1:69 -http-addr 127.0.0.1:8080 -log-level DEBUG - environment: - API_AUTH_TOKEN: ${PACKET_API_AUTH_TOKEN:-PcyR6MvHb7wMmyYf9p8dJ2Dvnb9HxX8E} - API_CONSUMER_TOKEN: ${PACKET_CONSUMER_TOKEN:-djR2TAvbnkY92i8Ea2KFMZW6MusW1fk7qzeCUHgtnQRSsXnqxoCr6V2vhSxpqASf} - FACILITY_CODE: ${FACILITY:-lab1} - PACKET_ENV: ${PACKET_ENV:-testing} - PACKET_VERSION: ${PACKET_VERSION:-5efab5ef3a42cb88f2d54f4ed3201c2dd6797b7d} - ROLLBAR_TOKEN: ${ROLLBAR_TOKEN:-9b78d0ad01d1467aa92c49c3a349b79d} - ROLLBAR_DISABLE: ${ROLLBAR_DISABLE:-0} - MIRROR_HOST: ${MIRROR_HOST:-127.0.0.1} - DNS_SERVERS: 8.8.8.8 - PUBLIC_IP: 127.0.0.1 - BOOTP_BIND: 127.0.0.1:67 - HTTP_BIND: 127.0.0.1:80 - SYSLOG_BIND: 127.0.0.1:514 - TFTP_BIND: 127.0.0.1:69 - DOCKER_REGISTRY: 127.0.0.1 - REGISTRY_USERNAME: username - REGISTRY_PASSWORD: password - TINKERBELL_GRPC_AUTHORITY: 127.0.0.1:42113 - TINKERBELL_CERT_URL: http://127.0.0.1:42114/cert - ELASTIC_SEARCH_URL: 127.0.0.1:9200 - depends_on: - db: - condition: service_healthy - tinkerbell: - condition: service_healthy - fluentbit: - condition: service_started - logging: - driver: fluentd - options: - tag: boots - ports: - - 127.0.0.1:80:80/tcp - - 67:67/udp - - 69:69/udp - - elasticsearch: - image: elasticsearch:7.3.0 - ports: - - 9200:9200 - - 9300:9300 - environment: - - "ES_JAVA_OPTS=-Xms512m -Xmx512m" - - discovery.type=single-node - - kibana: - image: kibana:7.3.0 - depends_on: - - elasticsearch - restart: always - environment: - ELASTICSEARCH_URL: http://elasticsearch:9200 - ports: - - 5601:5601 - - fluentbit: - image: fluent/fluent-bit:1.3 - ports: - - 24224:24224 - - 24224:24224/udp - depends_on: - - kibana - volumes: - - ./fluent-bit.conf:/fluent-bit/etc/fluent-bit.conf diff --git a/test/actions/update_data/Dockerfile b/test/actions/update_data/Dockerfile index 9098c195e..7a909b5b8 100644 --- a/test/actions/update_data/Dockerfile +++ b/test/actions/update_data/Dockerfile @@ -1,5 +1,2 @@ FROM bash -ADD hello_world.sh /bin/hello_world.sh -RUN chmod +x /bin/hello_world.sh -#CMD echo '{"action_01": "data_01"}' > /workflow/data -ENTRYPOINT [ "/bin/hello_world.sh" ] +CMD echo '{"action_01": "data_01"}' > /workflow/data diff --git a/test/data/hardware/hardware_1.json b/test/data/hardware/hardware_1.json index 38ef714c9..c01ffa127 100644 --- a/test/data/hardware/hardware_1.json +++ b/test/data/hardware/hardware_1.json @@ -1,112 +1,30 @@ { - "allow_pxe": true, - "arch": "x86_64", - "bonding_mode": 4, - "efi_boot": true, - "facility_code": "ewr1", "id": "f9f56dff-098a-4c5f-a51c-19ad35de85d1", - "instance": { - "allow_pxe": true, - "always_pxe": true, - "customdata": {}, - "hostname": "sample-machine", - "id": "3b2cccf1-1906-4d82-9fe0-c6d5188e70eb", - "ip_addresses": [], - "ipxe_script_url": "https://boot.netboot.xyz", - "network_ready": false, - "operating_system_version": { - "distro": "custom_ipxe", - "image_tag": null, - "os_slug": "custom_ipxe", - "slug": "custom_ipxe", - "version": "1" + "metadata": { + "facility": { + "facility_code": "onprem" }, - "project": {}, - "rescue": false, - "ssh_keys": [], - "state": "active", - "storage": {}, - "tags": [], - "userdata": "" + "instance": {}, + "state": "" }, - "ip_addresses": [ - { - "address": "172.24.7.50", - "address_family": 4, - "cidr": 30, - "enabled": true, - "gateway": "172.24.7.49", - "management": true, - "netmask": "255.255.255.252", - "network": "172.24.7.48", - "public": false, - "type": "data" - }, - { - "address": "10.250.42.38", - "gateway": "10.250.42.1", - "netmask": "255.255.255.0", - "type": "ipmi" - } - ], - "management": { - "address": "10.250.42.38", - "gateway": "10.250.42.1", - "netmask": "255.255.255.0", - "type": "ipmi" - }, - "manufacturer": { - "id": "5c6dc6d1-0b75-4e77-811e-e2d3b4e5312a", - "slug": "dell" - }, - "network_ports": [ - { - "connected_ports": [ - { - "data": { - "bond": null, - "mac": null + "network": { + "interfaces": [ + { + "dhcp": { + "arch": "x86_64", + "ip": { + "address": "192.168.1.5", + "gateway": "192.168.1.1", + "netmask": "255.255.255.248" }, - "hostname": "", - "id": "421f34e5-b141-4c4a-8234-239996bf7a1a", - "name": "xe-0/0/28", - "type": "data" + "mac": "98:03:9b:89:d7:ba", + "uefi": false + }, + "netboot": { + "allow_pxe": true, + "allow_workflow": true } - ], - "data": { - "bond": null, - "mac": "98:03:9b:89:d7:ba" - }, - "id": "213394d4-8642-443d-9140-c625cfaeb354", - "name": "eth0", - "type": "data" - }, - { - "connected_ports": [], - "data": { - "bond": null, - "mac": "98:03:9b:89:d7:bb" - }, - "id": "da245720-aa41-4368-9eca-7fb5af8bd492", - "name": "eth1", - "type": "data" - }, - { - "connected_ports": [], - "data": { - "bond": null, - "mac": "4c:d9:8f:42:21:f3" - }, - "id": "b1b7c29c-41d0-479d-9dbc-392250b8b36f", - "name": "ipmi0", - "type": "ipmi" - } - ], - "plan_slug": "c2.medium.x86", - "plan_version_slug": "c2.medium.x86.01", - "preinstalled_operating_system_version": {}, - "services": {}, - "state": "in_use", - "type": "server", - "vlan_id": null + } + ] + } } diff --git a/test/data/hardware/hardware_2.json b/test/data/hardware/hardware_2.json index fb85ab269..dbd7a1f96 100644 --- a/test/data/hardware/hardware_2.json +++ b/test/data/hardware/hardware_2.json @@ -1,112 +1,30 @@ { - "allow_pxe": true, - "arch": "x86_64", - "bonding_mode": 4, - "efi_boot": true, - "facility_code": "ewr1", "id": "f9f56dff-098a-4c5f-a51c-19ad35de85d2", - "instance": { - "allow_pxe": true, - "always_pxe": true, - "customdata": {}, - "hostname": "sample-machine2", - "id": "3b2cccf1-1906-4d82-9fe0-c6d5188e70ec", - "ip_addresses": [], - "ipxe_script_url": "https://boot.netboot.xyz", - "network_ready": false, - "operating_system_version": { - "distro": "custom_ipxe", - "image_tag": null, - "os_slug": "custom_ipxe", - "slug": "custom_ipxe", - "version": "1" + "metadata": { + "facility": { + "facility_code": "ewr1" }, - "project": {}, - "rescue": false, - "ssh_keys": [], - "state": "active", - "storage": {}, - "tags": [], - "userdata": "" + "instance": {}, + "state": "" }, - "ip_addresses": [ - { - "address": "172.24.7.51", - "address_family": 4, - "cidr": 30, - "enabled": true, - "gateway": "172.24.7.49", - "management": true, - "netmask": "255.255.255.252", - "network": "172.24.7.48", - "public": false, - "type": "data" - }, - { - "address": "10.250.42.39", - "gateway": "10.250.42.1", - "netmask": "255.255.255.0", - "type": "ipmi" - } - ], - "management": { - "address": "10.250.42.39", - "gateway": "10.250.42.1", - "netmask": "255.255.255.0", - "type": "ipmi" - }, - "manufacturer": { - "id": "5c6dc6d1-0b75-4e77-811e-e2d3b4e5312b", - "slug": "dell" - }, - "network_ports": [ - { - "connected_ports": [ - { - "data": { - "bond": null, - "mac": null + "network": { + "interfaces": [ + { + "dhcp": { + "arch": "x86_64", + "ip": { + "address": "192.168.1.4", + "gateway": "192.168.1.1", + "netmask": "255.255.255.248" }, - "hostname": "", - "id": "421f34e5-b141-4c4a-8234-239996bf7a1b", - "name": "xe-0/0/28", - "type": "data" + "mac": "98:03:9b:89:d7:da", + "uefi": false + }, + "netboot": { + "allow_pxe": true, + "allow_workflow": true } - ], - "data": { - "bond": null, - "mac": "98:03:9b:89:d7:da" - }, - "id": "213394d4-8642-443d-9140-c625cfaeb354", - "name": "eth0", - "type": "data" - }, - { - "connected_ports": [], - "data": { - "bond": null, - "mac": "98:03:9b:89:d7:db" - }, - "id": "da245720-aa41-4368-9eca-7fb5af8bd493", - "name": "eth1", - "type": "data" - }, - { - "connected_ports": [], - "data": { - "bond": null, - "mac": "4c:d9:8f:42:21:f4" - }, - "id": "b1b7c29c-41d0-479d-9dbc-392250b8b37f", - "name": "ipmi0", - "type": "ipmi" - } - ], - "plan_slug": "c2.medium.x86", - "plan_version_slug": "c2.medium.x86.01", - "preinstalled_operating_system_version": {}, - "services": {}, - "state": "in_use", - "type": "server", - "vlan_id": null + } + ] + } } diff --git a/test/data/template/sample_1 b/test/data/template/sample_1 index b0c3b1fcd..be2baf2b2 100644 --- a/test/data/template/sample_1 +++ b/test/data/template/sample_1 @@ -13,7 +13,7 @@ tasks: environment: NGINX_HOST: 192.168.1.2 - name: "update_db" - image: update-data + image: overwrite-data timeout: 50 environment: MIRROR_HOST: 192.168.1.3 diff --git a/test/e2e_test.go b/test/e2e_test.go index bf903c464..b9817560b 100644 --- a/test/e2e_test.go +++ b/test/e2e_test.go @@ -1,72 +1,84 @@ package e2e -//import ( -// "os" -// "time" -// "testing" -// -// "github.com/tinkerbell/tink/client" -// "github.com/tinkerbell/tink/protos/workflow" -// "github.com/tinkerbell/tink/test/framework" -// "github.com/sirupsen/logrus" -//) -// -//var log *logrus.Logger = framework.Log -// -//func TestMain(m *testing.M) { -// log.Infoln("########Creating Setup########") -// time.Sleep(10 * time.Second) -// err := framework.StartStack() -// if err != nil { -// os.Exit(1) -// } -// os.Setenv("TINKERBELL_GRPC_AUTHORITY", "127.0.0.1:42113") -// os.Setenv("TINKERBELL_CERT_URL", "http://127.0.0.1:42114/cert") -// client.Setup() -// log.Infoln("########Setup Created########") -// -// log.Infoln("Creating hardware inventory") -// //push hardware data into hardware table -// hwData := []string{"hardware_1.json", "hardware_2.json"} -// err = framework.PushHardwareData(hwData) -// if err != nil { -// log.Errorln("Failed to push hardware inventory : ", err) -// os.Exit(2) -// } -// log.Infoln("Hardware inventory created") -// -// log.Infoln("########Starting Tests########") -// status := m.Run() -// log.Infoln("########Finished Tests########") -// log.Infoln("########Removing setup########") -// //err = framework.TearDown() -// if err != nil { -// os.Exit(3) -// } -// log.Infoln("########Setup removed########") -// os.Exit(status) -//} -// -//var testCases = map[string]struct { -// hardware string -// template string -// workers int64 -// expected workflow.ActionState -// ephData string -//}{ -// "testWfWithWorker": {"hardware_1.json", "sample_1", 1, workflow.ActionState_ACTION_SUCCESS, `{"action_02": "data_02"}`}, -// "testWfTimeout": {"hardware_1.json", "sample_2", 1, workflow.ActionState_ACTION_TIMEOUT, `{"action_01": "data_01"}`}, -// //"testWfWithMultiWorkers": {"hardware_1.json", "sample_3", 2, workflow.ActionState_ACTION_SUCCESS, `{"action_01": "data_01"}`}, -//} -// -//var runTestMap = map[string]func(t *testing.T){ -// "testWfWithWorker": TestWfWithWorker, -// "testWfTimeout": TestWfTimeout, -// //"testWfWithMultiWorkers": TestWfWithMultiWorkers, -//} -// -//func TestE2E(t *testing.T) { -// for key, val := range runTestMap { -// t.Run(key, val) -// } -//} +import ( + "os" + "testing" + "time" + + "github.com/sirupsen/logrus" + "github.com/tinkerbell/tink/client" + "github.com/tinkerbell/tink/protos/workflow" + "github.com/tinkerbell/tink/test/framework" +) + +var log *logrus.Logger = framework.Log + +func sourceEnvs() { + os.Setenv("TINKERBELL_REGISTRY_USERNAME", "admin") + os.Setenv("TINKERBELL_REGISTRY_PASSWORD", "admin123") + os.Setenv("TINKERBELL_HOST_IP", "127.0.0.1") + os.Setenv("TINKERBELL_NGINX_IP", "127.0.0.2") + os.Setenv("FACILITY", "onprem") + os.Setenv("TINKERBELL_TINK_USERNAME", "admin") + os.Setenv("TINKERBELL_TINK_PASSWORD", "admin123") +} + +func TestMain(m *testing.M) { + log.Infoln("########Creating Setup########") + time.Sleep(10 * time.Second) + sourceEnvs() + err := framework.StartStack() + if err != nil { + os.Exit(1) + } + os.Setenv("TINKERBELL_GRPC_AUTHORITY", "127.0.0.1:42113") + os.Setenv("TINKERBELL_CERT_URL", "http://127.0.0.1:42114/cert") + client.Setup() + log.Infoln("########Setup Created########") + + log.Infoln("Creating hardware inventory") + //push hardware data into hardware table + hwData := []string{"hardware_1.json", "hardware_2.json"} + err = framework.PushHardwareData(hwData) + if err != nil { + log.Errorln("Failed to push hardware inventory : ", err) + os.Exit(2) + } + log.Infoln("Hardware inventory created") + + log.Infoln("########Starting Tests########") + status := m.Run() + log.Infoln("########Finished Tests########") + log.Infoln("########Removing setup########") + //err = framework.TearDown() + if err != nil { + os.Exit(3) + } + log.Infoln("########Setup removed########") + os.Exit(status) +} + +var testCases = map[string]struct { + hardware string + hMAC string + template string + workers int64 + expected workflow.ActionState + ephData string +}{ + "testWfWithWorker": {"hardware_1.json", "98:03:9b:89:d7:ba", "sample_1", 1, workflow.ActionState_ACTION_SUCCESS, `{"action_02": "data_02"}`}, + "testWfTimeout": {"hardware_1.json", "98:03:9b:89:d7:ba", "sample_2", 1, workflow.ActionState_ACTION_TIMEOUT, `{"action_01": "data_01"}`}, + //"testWfWithMultiWorkers": {"hardware_1.json", "sample_3", 2, workflow.ActionState_ACTION_SUCCESS, `{"action_01": "data_01"}`}, +} + +var runTestMap = map[string]func(t *testing.T){ + "testWfWithWorker": TestWfWithWorker, + "testWfTimeout": TestWfTimeout, + //"testWfWithMultiWorkers": TestWfWithMultiWorkers, +} + +func TestE2E(t *testing.T) { + for key, val := range runTestMap { + t.Run(key, val) + } +} diff --git a/test/framework/setup.go b/test/framework/setup.go index a2226b9eb..ac9dcc49e 100644 --- a/test/framework/setup.go +++ b/test/framework/setup.go @@ -9,8 +9,8 @@ import ( "github.com/sirupsen/logrus" ) -func buildCerts(filepath string) error { - cmd := exec.Command("/bin/sh", "-c", "docker-compose -f "+filepath+" up --build certs") +func buildCerts() error { + cmd := exec.Command("/bin/sh", "-c", "./generate_certs.sh") cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr err := cmd.Run() @@ -59,7 +59,7 @@ func removeWorkerImage() error { } func createWorkerImage() error { - cmd := exec.Command("/bin/sh", "-c", "docker build -t worker ../worker/") + cmd := exec.Command("/bin/sh", "-c", "docker build -t worker ../cmd/tink-worker/") cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr err := cmd.Run() @@ -94,7 +94,7 @@ func initializeLogger() { } } else { logger.SetLevel(logrus.InfoLevel) - logger.Errorln("Variable TEST_LOG_LEVEL is not set. Default is Info.") + logger.Errorln("Variable TEST_LOG_LEVEL is not set. Default is INFO.") } logger.SetFormatter(&logrus.JSONFormatter{}) } @@ -102,7 +102,7 @@ func initializeLogger() { // StartStack : Starting stack func StartStack() error { // Docker compose file for starting the containers - filepath := "../test-docker-compose.yml" + filepath := "../deploy/docker-compose.yml" // Initialize logger initializeLogger() @@ -114,7 +114,7 @@ func StartStack() error { } // Building certs - err = buildCerts(filepath) + err = buildCerts() if err != nil { return err } @@ -153,9 +153,10 @@ func StartStack() error { initializeLogger() // Start other containers - cmd := exec.Command("/bin/sh", "-c", "docker-compose -f "+filepath+" up --build -d") + cmd := exec.Command("/bin/sh", "-c", "docker-compose -f "+filepath+" up --build -d tink-server ") cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr err = cmd.Run() + //sleep(10) return nil } diff --git a/test/framework/tearDown.go b/test/framework/tearDown.go index 8132d98c9..07fc1cfa1 100644 --- a/test/framework/tearDown.go +++ b/test/framework/tearDown.go @@ -7,7 +7,7 @@ import ( // TearDown : remove the setup func TearDown() error { - cmd := exec.Command("/bin/sh", "-c", "docker-compose rm -svf") + cmd := exec.Command("/bin/sh", "-c", "docker-compose -f ../deploy/docker-compose rm -svf") cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr err := cmd.Run() diff --git a/test/framework/utils.go b/test/framework/utils.go index 4390fdd7d..be896bf7e 100644 --- a/test/framework/utils.go +++ b/test/framework/utils.go @@ -11,14 +11,15 @@ var log *logrus.Entry var Log = logger // SetupWorkflow ... Set up workflow -func SetupWorkflow(tar string, tmpl string) (string, error) { - hardwareID := "c9d6faa4-08a2-4285-ae6c-f3401211bd56" +func SetupWorkflow(hMAC string, tmpl string) (string, error) { + //hardwareID := `{"device_1":"98:03:9b:89:d7:ba"}` //Add template in template table templateID, err := CreateTemplate(tmpl) if err != nil { return "", err } logger.Infoln("Template Created : ", templateID) + hardwareID := `{"device_1":"` + hMAC + `"}` workflowID, err := CreateWorkflow(templateID, hardwareID) if err != nil { logger.Debugln("Workflow is not Created because : ", err) diff --git a/test/framework/worker.go b/test/framework/worker.go index 8cacc2476..3bbbdbecf 100644 --- a/test/framework/worker.go +++ b/test/framework/worker.go @@ -4,6 +4,7 @@ import ( "bufio" "context" "fmt" + "os" "sync" "github.com/docker/docker/api/types" @@ -33,7 +34,7 @@ func createWorkerContainer(ctx context.Context, cli *dc.Client, workerID string, AttachStderr: true, Tty: true, Volumes: volume, - Env: []string{"TINKERBELL_GRPC_AUTHORITY=127.0.0.1:42113", "TINKERBELL_CERT_URL=http://127.0.0.1:42114/cert", "WORKER_ID=" + workerID, "DOCKER_REGISTRY=localhost:443", "DOCKER_API_VERSION=v1.40", "REGISTRY_USERNAME=username", "REGISTRY_PASSWORD=password"}, + Env: []string{"TINKERBELL_GRPC_AUTHORITY=127.0.0.1:42113", "TINKERBELL_CERT_URL=http://127.0.0.1:42114/cert", "WORKER_ID=" + workerID, "DOCKER_REGISTRY=localhost:443", "DOCKER_API_VERSION=v1.40", "REGISTRY_USERNAME=" + os.Getenv("TINKERBELL_REGISTRY_USERNAME"), "REGISTRY_PASSWORD=" + os.Getenv("TINKERBELL_REGISTRY_PASSWORD")}, } hostConfig := &container.HostConfig{ NetworkMode: "host", diff --git a/test/generate_certs.sh b/test/generate_certs.sh new file mode 100755 index 000000000..e2189c5f2 --- /dev/null +++ b/test/generate_certs.sh @@ -0,0 +1,67 @@ +#!/bin/bash + +generate_certificates() ( + mkdir -p "$STATEDIR/certs" + + if [ ! -f "$STATEDIR/certs/ca.json" ]; then + jq \ + '. + | .names[0].L = $facility + ' \ + "$DEPLOYDIR/tls/ca.in.json" \ + --arg ip "$TINKERBELL_HOST_IP" \ + --arg facility "$FACILITY" \ + >"$STATEDIR/certs/ca.json" + fi + + if [ ! -f "$STATEDIR/certs/server-csr.json" ]; then + jq \ + '. + | .hosts += [ $ip, "tinkerbell.\($facility).packet.net" ] + | .names[0].L = $facility + | .hosts = (.hosts | sort | unique) + ' \ + "$DEPLOYDIR/tls/server-csr.in.json" \ + --arg ip "$TINKERBELL_HOST_IP" \ + --arg facility "$FACILITY" \ + >"$STATEDIR/certs/server-csr.json" + fi + + docker build --tag "tinkerbell-certs" "$DEPLOYDIR/tls" + docker run --rm \ + --volume "$STATEDIR/certs:/certs" \ + --user "$UID:$(id -g)" \ + tinkerbell-certs + + local certs_dir="/etc/docker/certs.d/$TINKERBELL_HOST_IP" + + # copy public key to NGINX for workers + #if ! cmp --quiet "$STATEDIR"/certs/ca.pem "$STATEDIR/webroot/workflow/ca.pem"; then + # cp "$STATEDIR"/certs/ca.pem "$STATEDIR/webroot/workflow/ca.pem" + #fi + + # update host to trust registry certificate + if ! cmp --quiet "$STATEDIR/certs/ca.pem" "$certs_dir/tinkerbell.crt"; then + if [ ! -d "$certs_dir/tinkerbell.crt" ]; then + # The user will be told to create the directory + # in the next block, if copying the certs there + # fails. + sudo mkdir -p "$certs_dir" || true >/dev/null 2>&1 + fi + if ! sudo cp "$STATEDIR/certs/ca.pem" "$certs_dir/tinkerbell.crt"; then + echo "$ERR please copy $STATEDIR/certs/ca.pem to $certs_dir/tinkerbell.crt" + echo "$BLANK and run $0 again:" + + if [ ! -d "$certs_dir" ]; then + echo "sudo mkdir -p '$certs_dir'" + fi + echo "sudo cp '$STATEDIR/certs/ca.pem' '$certs_dir/tinkerbell.crt'" + + exit 1 + fi + fi +) + +DEPLOYDIR=${PWD//test/deploy} +STATEDIR="$DEPLOYDIR"/state +generate_certificates diff --git a/test/push_images.sh b/test/push_images.sh index 52deb3e2d..e102f7680 100755 --- a/test/push_images.sh +++ b/test/push_images.sh @@ -1,7 +1,10 @@ #!/bin/bash -while ! docker login -u username -p password localhost; do - sleep 1 +for i in {1..10}; do + if docker login -u "$TINKERBELL_REGISTRY_USERNAME" -p "$TINKERBELL_REGISTRY_PASSWORD" localhost; then + break + fi + sleep $i done docker push localhost/update-data docker push localhost/overwrite-data diff --git a/test/test_wf_timeout.go b/test/test_wf_timeout.go index 0b5283f22..16d73e85b 100644 --- a/test/test_wf_timeout.go +++ b/test/test_wf_timeout.go @@ -1,49 +1,53 @@ package e2e -//import ( -// "context" -// "testing" -// -// "github.com/tinkerbell/tink/client" -// "github.com/tinkerbell/tink/protos/workflow" -// "github.com/tinkerbell/tink/test/framework" -// "github.com/stretchr/testify/assert" -//) -// -//// TestWfTimeout : Timeout Test -//func TestWfTimeout(t *testing.T) { -// // Start test only if the test case exist in the table -// if test, ok := testCases["testWfTimeout"]; ok { -// wfID, err := framework.SetupWorkflow(test.hardware, test.template) -// -// if err != nil { -// t.Error(err) -// } -// assert.NoError(t, err, "Create Workflow") -// -// // Start the Worker -// workerStatus := make(chan int64, test.workers) -// wfStatus, err := framework.StartWorkers(test.workers, workerStatus, wfID) -// if err != nil { -// log.Errorf("Test Failed\n") -// t.Error(err) -// } -// assert.Equal(t, test.expected, wfStatus) -// assert.NoError(t, err, "Workers Failed") -// -// for i := int64(0); i < test.workers; i++ { -// if len(workerStatus) > 0 { -// // Check for worker exit status -// status := <-workerStatus -// expected := 0 -// assert.Equal(t, int64(expected), status) -// -// //checking for ephemeral data validation -// resp, err := client.WorkflowClient.GetWorkflowData(context.Background(), &workflow.GetWorkflowDataRequest{WorkflowID: wfID, Version: 0}) -// if err != nil { -// assert.Equal(t, test.ephData, string(resp.GetData())) -// } -// } -// } -// } -//} +import ( + "context" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/tinkerbell/tink/client" + "github.com/tinkerbell/tink/protos/workflow" + "github.com/tinkerbell/tink/test/framework" +) + +// TestWfTimeout : Timeout Test +func TestWfTimeout(t *testing.T) { + // Start test only if the test case exist in the table + if test, ok := testCases["testWfTimeout"]; ok { + wfID, err := framework.SetupWorkflow(test.hMAC, test.template) + + if err != nil { + t.Error(err) + } + assert.NoError(t, err, "Create Workflow") + + // Start the Worker + workerStatus := make(chan int64, test.workers) + wfStatus, err := framework.StartWorkers(test.workers, workerStatus, wfID) + if err != nil { + log.Error("Test Failed\n") + t.Error(err) + } + assert.Equal(t, test.expected, wfStatus) + assert.NoError(t, err, "Workers Failed") + + for i := int64(0); i < test.workers; i++ { + if len(workerStatus) > 0 { + // Check for worker exit status + status := <-workerStatus + expected := 0 + assert.Equal(t, int64(expected), status) + + //checking for ephemeral data validation + resp, err := client.WorkflowClient.GetWorkflowData(context.Background(), &workflow.GetWorkflowDataRequest{WorkflowID: wfID, Version: 0}) + if err != nil { + log.Error("Check for ephemeral data failed : ", err) + assert.Equal(t, nil, err) + } else { + log.Info("Check for ephemeral data") + assert.Equal(t, test.ephData, string(resp.GetData())) + } + } + } + } +} diff --git a/test/test_wf_with_worker.go b/test/test_wf_with_worker.go index c15369ede..8fb3b222c 100644 --- a/test/test_wf_with_worker.go +++ b/test/test_wf_with_worker.go @@ -1,54 +1,58 @@ package e2e -//import ( -// "context" -// "testing" -// -// "github.com/tinkerbell/tink/client" -// "github.com/tinkerbell/tink/protos/workflow" -// "github.com/tinkerbell/tink/test/framework" -// "github.com/stretchr/testify/assert" -//) -// -//// TestWfWithWorker : One Worker Test -//func TestWfWithWorker(t *testing.T) { -// -// // Start test only if the test case exist in the table -// if test, ok := testCases["testWfWithWorker"]; ok { -// wfID, err := framework.SetupWorkflow(test.hardware, test.template) -// -// if err != nil { -// t.Error(err) -// } -// if !assert.NoError(t, err, "Create Workflow") { -// t.Fatal(err) -// } -// -// // Start the Worker -// workerStatus := make(chan int64, test.workers) -// wfStatus, err := framework.StartWorkers(test.workers, workerStatus, wfID) -// if err != nil { -// log.Errorf("Test Failed\n") -// t.Error(err) -// } -// assert.Equal(t, test.expected, wfStatus) -// assert.NoError(t, err, "Workers Failed") -// -// for i := int64(0); i < test.workers; i++ { -// if len(workerStatus) > 0 { -// //Check for worker exit status -// status := <-workerStatus -// expected := 0 -// if test.expected != workflow.ActionState_ACTION_SUCCESS { -// expected = 1 -// } -// assert.Equal(t, int64(expected), status) -// //checking for ephemeral data validation -// resp, err := client.WorkflowClient.GetWorkflowData(context.Background(), &workflow.GetWorkflowDataRequest{WorkflowID: wfID, Version: 0}) -// if err != nil { -// assert.Equal(t, test.ephData, string(resp.GetData())) -// } -// } -// } -// } -//} +import ( + "context" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/tinkerbell/tink/client" + "github.com/tinkerbell/tink/protos/workflow" + "github.com/tinkerbell/tink/test/framework" +) + +// TestWfWithWorker : One Worker Test +func TestWfWithWorker(t *testing.T) { + + // Start test only if the test case exist in the table + if test, ok := testCases["testWfWithWorker"]; ok { + wfID, err := framework.SetupWorkflow(test.hMAC, test.template) + + if err != nil { + t.Error(err) + } + if !assert.NoError(t, err, "Create Workflow") { + t.Fatal(err) + } + + // Start the Worker + workerStatus := make(chan int64, test.workers) + wfStatus, err := framework.StartWorkers(test.workers, workerStatus, wfID) + if err != nil { + log.Info("Test Failed") + t.Error(err) + } + assert.Equal(t, test.expected, wfStatus) + assert.NoError(t, err, "Workers Failed") + + for i := int64(0); i < test.workers; i++ { + if len(workerStatus) > 0 { + //Check for worker exit status + status := <-workerStatus + expected := 0 + if test.expected != workflow.ActionState_ACTION_SUCCESS { + expected = 1 + } + assert.Equal(t, int64(expected), status) + //checking for ephemeral data validation + resp, err := client.WorkflowClient.GetWorkflowData(context.Background(), &workflow.GetWorkflowDataRequest{WorkflowID: wfID, Version: 0}) + if err == nil { + log.Info("Comparing EPH data") + assert.Equal(t, test.ephData, string(resp.GetData())) + } else { + log.Error("Get EPH data failed") + log.Error(err) + } + } + } + } +}