From 8e067f593e9df7a74044cb73557235372305d0f6 Mon Sep 17 00:00:00 2001 From: parauliya Date: Tue, 18 Aug 2020 18:32:16 +0530 Subject: [PATCH 1/6] Fix #257 : Added following test cases: 1. One workflow with one worker where all the actions are successful 2. One workflow with one worker where an action gets failed 3. One workflow with one worker where an action gets timed out Signed-off-by: parauliya --- go.mod | 6 + test/_vagrant/data.json | 30 +++ test/_vagrant/failedWorkflow.tmpl | 18 ++ test/_vagrant/hello-world.tmpl | 10 + test/_vagrant/timeout.tmpl | 18 ++ test/_vagrant/vagrant_test.go | 363 +++++++++++++++++++++++++----- 6 files changed, 392 insertions(+), 53 deletions(-) create mode 100644 test/_vagrant/data.json create mode 100644 test/_vagrant/failedWorkflow.tmpl create mode 100644 test/_vagrant/hello-world.tmpl create mode 100644 test/_vagrant/timeout.tmpl diff --git a/go.mod b/go.mod index 90e9266b2..9e4f5a49d 100644 --- a/go.mod +++ b/go.mod @@ -33,6 +33,12 @@ require ( github.com/spf13/viper v1.4.0 github.com/stretchr/testify v1.3.0 go.mongodb.org/mongo-driver v1.1.2 // indirect +<<<<<<< HEAD +======= + go.uber.org/atomic v1.2.0 // indirect + go.uber.org/multierr v1.1.0 // indirect + go.uber.org/zap v1.7.1 // indirect +>>>>>>> Fix #257 : Added following test cases: golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e // indirect golang.org/x/sys v0.0.0-20200331124033-c3d80250170d // indirect diff --git a/test/_vagrant/data.json b/test/_vagrant/data.json new file mode 100644 index 000000000..7510ba2ca --- /dev/null +++ b/test/_vagrant/data.json @@ -0,0 +1,30 @@ +{ + "id": "ce2e62ed-826f-4485-a39f-a82bb74338e2", + "metadata": { + "facility": { + "facility_code": "onprem" + }, + "instance": {}, + "state": "" + }, + "network": { + "interfaces": [ + { + "dhcp": { + "arch": "x86_64", + "ip": { + "address": "192.168.1.5", + "gateway": "192.168.1.1", + "netmask": "255.255.255.248" + }, + "mac": "08:00:27:00:00:01", + "uefi": false + }, + "netboot": { + "allow_pxe": true, + "allow_workflow": true + } + } + ] + } +} diff --git a/test/_vagrant/failedWorkflow.tmpl b/test/_vagrant/failedWorkflow.tmpl new file mode 100644 index 000000000..25cbbec41 --- /dev/null +++ b/test/_vagrant/failedWorkflow.tmpl @@ -0,0 +1,18 @@ +version: '0.1' +name: packet_osie_provision +global_timeout: 600 +tasks: +- name: "timeout-task" + worker: "{{.device_1}}" + actions: + - name: "hello_world" + image: hello-world + timeout: 10 + on-timeout: ["echo", "Timeout"] + on-failure: ["echo", "Failure"] + - name: "sleep-till-timeout" + image: bash + command: ["sleepys", "20"] + timeout: 6 + on-timeout: ["echo", "Timeout"] + on-failure: ["echo", "Failure"] diff --git a/test/_vagrant/hello-world.tmpl b/test/_vagrant/hello-world.tmpl new file mode 100644 index 000000000..fb5218830 --- /dev/null +++ b/test/_vagrant/hello-world.tmpl @@ -0,0 +1,10 @@ +version: "0.1" +name: hello_world_workflow +global_timeout: 600 +tasks: + - name: "hello world" + worker: "{{.device_1}}" + actions: + - name: "hello_world" + image: hello-world + timeout: 60 diff --git a/test/_vagrant/timeout.tmpl b/test/_vagrant/timeout.tmpl new file mode 100644 index 000000000..c95aba8fd --- /dev/null +++ b/test/_vagrant/timeout.tmpl @@ -0,0 +1,18 @@ +version: '0.1' +name: packet_osie_provision +global_timeout: 600 +tasks: +- name: "timeout-task" + worker: "{{.device_1}}" + actions: + - name: "hello_world" + image: hello-world + timeout: 10 + on-timeout: ["echo", "Timeout"] + on-failure: ["echo", "Failure"] + - name: "sleep-till-timeout" + image: bash + command: ["sleep", "20"] + timeout: 6 + on-timeout: ["echo", "Timeout"] + on-failure: ["echo", "Failure"] diff --git a/test/_vagrant/vagrant_test.go b/test/_vagrant/vagrant_test.go index 4cc8d99cb..872bc869d 100644 --- a/test/_vagrant/vagrant_test.go +++ b/test/_vagrant/vagrant_test.go @@ -3,8 +3,10 @@ package vagrant_test import ( "context" "encoding/json" + "io/ioutil" "net/http" "os" + "strings" "testing" "time" @@ -16,7 +18,7 @@ import ( "github.com/tinkerbell/tink/util" ) -func TestVagrantSetupGuide(t *testing.T) { +func TestSuccess(t *testing.T) { ctx := context.Background() machine, err := vagrant.Up(ctx, @@ -76,12 +78,14 @@ func TestVagrantSetupGuide(t *testing.T) { if err != nil { t.Fatal(err) } - err = registerHardware(ctx) + hwDataFile := "data.json" + + err = registerHardwares(ctx, hwDataFile) if err != nil { t.Fatal(err) } - templateID, err := registerTemplate(ctx) + templateID, err := registerTemplates(ctx, "hello-world.tmpl") if err != nil { t.Fatal(err) } @@ -130,6 +134,273 @@ func TestVagrantSetupGuide(t *testing.T) { } t.Fatal("Workflow never got to a complite state or it didn't make it on time (10m)") } +func TestTimeout(t *testing.T) { + ctx := context.Background() + + machine, err := vagrant.Up(ctx, + vagrant.WithLogger(t.Logf), + vagrant.WithMachineName("provisioner"), + vagrant.WithWorkdir("../../deploy/vagrant"), + ) + if err != nil { + t.Fatal(err) + } + + defer func() { + err := machine.Destroy(ctx) + if err != nil { + t.Error(err) + } + }() + + _, err = machine.Exec(ctx, "cd /vagrant/deploy && source ../envrc && docker-compose up -d") + if err != nil { + t.Fatal(err) + } + + _, err = machine.Exec(ctx, "docker pull hello-world") + if err != nil { + t.Fatal(err) + } + + _, err = machine.Exec(ctx, "docker pull bash") + if err != nil { + t.Fatal(err) + } + _, err = machine.Exec(ctx, "docker tag hello-world 192.168.1.1/hello-world") + if err != nil { + t.Fatal(err) + } + + _, err = machine.Exec(ctx, "docker tag bash 192.168.1.1/bash") + if err != nil { + t.Fatal(err) + } + _, err = machine.Exec(ctx, "docker push 192.168.1.1/hello-world") + if err != nil { + t.Fatal(err) + } + + _, err = machine.Exec(ctx, "docker push 192.168.1.1/bash") + if err != nil { + t.Fatal(err) + } + + for ii := 0; ii < 5; ii++ { + resp, err := http.Get("http://localhost:42114/_packet/healthcheck") + if err != nil || resp.StatusCode != http.StatusOK { + if err != nil { + t.Logf("err tinkerbell healthcheck... retrying: %s", err) + } else { + t.Logf("err tinkerbell healthcheck... expected status code 200 got %d retrying", resp.StatusCode) + } + time.Sleep(10 * time.Second) + } + } + + t.Log("Tinkerbell is up and running") + + os.Setenv("TINKERBELL_CERT_URL", "http://127.0.0.1:42114/cert") + os.Setenv("TINKERBELL_GRPC_AUTHORITY", "127.0.0.1:42113") + client.Setup() + _, err = client.HardwareClient.All(ctx, &hardware.Empty{}) + if err != nil { + t.Fatal(err) + } + hwDataFile := "data.json" + + err = registerHardwares(ctx, hwDataFile) + if err != nil { + t.Fatal(err) + } + + templateID, err := registerTemplates(ctx, "timeout.tmpl") + if err != nil { + t.Fatal(err) + } + + t.Logf("templateID: %s", templateID) + + workflowID, err := createWorkflow(ctx, templateID) + if err != nil { + t.Fatal(err) + } + + t.Logf("WorkflowID: %s", workflowID) + + os.Setenv("VAGRANT_WORKER_GUI", "false") + worker, err := vagrant.Up(ctx, + vagrant.WithLogger(t.Logf), + vagrant.WithMachineName("worker"), + vagrant.WithWorkdir("../../deploy/vagrant"), + vagrant.RunAsync(), + ) + if err != nil { + t.Fatal(err) + } + + defer func() { + err := worker.Destroy(ctx) + if err != nil { + t.Error(err) + } + }() + + for iii := 0; iii < 30; iii++ { + events, err := client.WorkflowClient.ShowWorkflowEvents(ctx, &workflow.GetRequest{ + Id: workflowID, + }) + if err != nil { + t.Fatal(err) + } + for event, err := events.Recv(); err == nil && event != nil; event, err = events.Recv() { + if event.ActionName == "hello_world" && event.ActionStatus == workflow.ActionState_ACTION_SUCCESS { + t.Logf("action %s SUCCESSFULL as expected", event.ActionName) + continue + } + if event.ActionName == "sleep-till-timeout" && event.ActionStatus == workflow.ActionState_ACTION_TIMEOUT { + t.Logf("action %s TIMEDOUT as expected", event.ActionName) + return + } + } + time.Sleep(5 * time.Second) + } + t.Fatal("Workflow never got to a complite state or it didn't make it on time (5m)") +} + +func TestFailed(t *testing.T) { + ctx := context.Background() + + machine, err := vagrant.Up(ctx, + vagrant.WithLogger(t.Logf), + vagrant.WithMachineName("provisioner"), + vagrant.WithWorkdir("../../deploy/vagrant"), + ) + if err != nil { + t.Fatal(err) + } + + defer func() { + err := machine.Destroy(ctx) + if err != nil { + t.Error(err) + } + }() + + _, err = machine.Exec(ctx, "cd /vagrant/deploy && source ../envrc && docker-compose up -d") + if err != nil { + t.Fatal(err) + } + + _, err = machine.Exec(ctx, "docker pull hello-world") + if err != nil { + t.Fatal(err) + } + + _, err = machine.Exec(ctx, "docker pull bash") + if err != nil { + t.Fatal(err) + } + _, err = machine.Exec(ctx, "docker tag hello-world 192.168.1.1/hello-world") + if err != nil { + t.Fatal(err) + } + + _, err = machine.Exec(ctx, "docker tag bash 192.168.1.1/bash") + if err != nil { + t.Fatal(err) + } + _, err = machine.Exec(ctx, "docker push 192.168.1.1/hello-world") + if err != nil { + t.Fatal(err) + } + + _, err = machine.Exec(ctx, "docker push 192.168.1.1/bash") + if err != nil { + t.Fatal(err) + } + + for ii := 0; ii < 5; ii++ { + resp, err := http.Get("http://localhost:42114/_packet/healthcheck") + if err != nil || resp.StatusCode != http.StatusOK { + if err != nil { + t.Logf("err tinkerbell healthcheck... retrying: %s", err) + } else { + t.Logf("err tinkerbell healthcheck... expected status code 200 got %d retrying", resp.StatusCode) + } + time.Sleep(10 * time.Second) + } + } + + t.Log("Tinkerbell is up and running") + + os.Setenv("TINKERBELL_CERT_URL", "http://127.0.0.1:42114/cert") + os.Setenv("TINKERBELL_GRPC_AUTHORITY", "127.0.0.1:42113") + client.Setup() + _, err = client.HardwareClient.All(ctx, &hardware.Empty{}) + if err != nil { + t.Fatal(err) + } + hwDataFile := "data.json" + + err = registerHardwares(ctx, hwDataFile) + if err != nil { + t.Fatal(err) + } + + templateID, err := registerTemplates(ctx, "failedWorkflow.tmpl") + if err != nil { + t.Fatal(err) + } + + t.Logf("templateID: %s", templateID) + + workflowID, err := createWorkflow(ctx, templateID) + if err != nil { + t.Fatal(err) + } + + t.Logf("WorkflowID: %s", workflowID) + + os.Setenv("VAGRANT_WORKER_GUI", "false") + worker, err := vagrant.Up(ctx, + vagrant.WithLogger(t.Logf), + vagrant.WithMachineName("worker"), + vagrant.WithWorkdir("../../deploy/vagrant"), + vagrant.RunAsync(), + ) + if err != nil { + t.Fatal(err) + } + + defer func() { + err := worker.Destroy(ctx) + if err != nil { + t.Error(err) + } + }() + + for iii := 0; iii < 30; iii++ { + events, err := client.WorkflowClient.ShowWorkflowEvents(ctx, &workflow.GetRequest{ + Id: workflowID, + }) + if err != nil { + t.Fatal(err) + } + for event, err := events.Recv(); err == nil && event != nil; event, err = events.Recv() { + if event.ActionName == "hello_world" && event.ActionStatus == workflow.ActionState_ACTION_SUCCESS { + t.Logf("action %s SUCCESSFULL as expected", event.ActionName) + continue + } + if event.ActionName == "sleep-till-timeout" && event.ActionStatus == workflow.ActionState_ACTION_FAILED { + t.Logf("action %s FAILED as expected", event.ActionName) + return + } + } + time.Sleep(5 * time.Second) + } + t.Fatal("Workflow never got to a complite state or it didn't make it on time (5m)") +} func createWorkflow(ctx context.Context, templateID string) (string, error) { res, err := client.WorkflowClient.CreateWorkflow(ctx, &workflow.CreateRequest{ @@ -142,63 +413,49 @@ func createWorkflow(ctx context.Context, templateID string) (string, error) { return res.Id, nil } -func registerTemplate(ctx context.Context) (string, error) { - resp, err := client.TemplateClient.CreateTemplate(ctx, &template.WorkflowTemplate{ - Name: "hello-world", - Data: `version: "0.1" -name: hello_world_workflow -global_timeout: 600 -tasks: - - name: "hello world" - worker: "{{.device_1}}" - actions: - - name: "hello_world" - image: hello-world - timeout: 60`, - }) +func readData(file string) ([]byte, error) { + f, err := os.Open(file) if err != nil { - return "", err + return []byte(""), err } + defer f.Close() - return resp.Id, nil + data, err := ioutil.ReadAll(f) + if err != nil { + return []byte(""), err + } + return data, nil } -func registerHardware(ctx context.Context) error { - data := []byte(`{ - "id": "ce2e62ed-826f-4485-a39f-a82bb74338e2", - "metadata": { - "facility": { - "facility_code": "onprem" - }, - "instance": {}, - "state": "" - }, - "network": { - "interfaces": [ - { - "dhcp": { - "arch": "x86_64", - "ip": { - "address": "192.168.1.5", - "gateway": "192.168.1.1", - "netmask": "255.255.255.248" - }, - "mac": "08:00:27:00:00:01", - "uefi": false - }, - "netboot": { - "allow_pxe": true, - "allow_workflow": true - } - } - ] - } -}`) - hw := util.HardwareWrapper{Hardware: &hardware.Hardware{}} - err := json.Unmarshal(data, &hw) +// push hardware data through file +func registerHardwares(ctx context.Context, hwDatafile string) error { + //for _, hwFile := range hwDataFiles { + //filepath := "../data/hardware/" + hwFile + data, err := readData(hwDatafile) if err != nil { return err } + hw := util.HardwareWrapper{Hardware: &hardware.Hardware{}} + if err := json.Unmarshal(data, &hw); err != nil { + return err + } _, err = client.HardwareClient.Push(context.Background(), &hardware.PushRequest{Data: hw.Hardware}) - return err + if err != nil { + return err + } + //} + return nil +} + +func registerTemplates(ctx context.Context, templateFile string) (string, error) { + data, err := readData(templateFile) + if err != nil { + return "", err + } + name := strings.SplitN(templateFile, ".", -1)[0] + resp, err := client.TemplateClient.CreateTemplate(ctx, &template.WorkflowTemplate{Name: name, Data: string(data)}) + if err != nil { + return "", err + } + return resp.Id, nil } From f8736904e4d9815a1880421fa9cfc0b741e0b9a2 Mon Sep 17 00:00:00 2001 From: parauliya Date: Tue, 18 Aug 2020 19:14:05 +0530 Subject: [PATCH 2/6] Incorporate review comments Signed-off-by: parauliya --- test/_vagrant/vagrant_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/_vagrant/vagrant_test.go b/test/_vagrant/vagrant_test.go index 872bc869d..46c105238 100644 --- a/test/_vagrant/vagrant_test.go +++ b/test/_vagrant/vagrant_test.go @@ -18,7 +18,7 @@ import ( "github.com/tinkerbell/tink/util" ) -func TestSuccess(t *testing.T) { +func TestVagrantSetupGuide(t *testing.T) { ctx := context.Background() machine, err := vagrant.Up(ctx, @@ -134,7 +134,7 @@ func TestSuccess(t *testing.T) { } t.Fatal("Workflow never got to a complite state or it didn't make it on time (10m)") } -func TestTimeout(t *testing.T) { +func TestOneTimeoutWorkflow(t *testing.T) { ctx := context.Background() machine, err := vagrant.Up(ctx, @@ -268,7 +268,7 @@ func TestTimeout(t *testing.T) { t.Fatal("Workflow never got to a complite state or it didn't make it on time (5m)") } -func TestFailed(t *testing.T) { +func TestOneFailedWorkflow(t *testing.T) { ctx := context.Background() machine, err := vagrant.Up(ctx, From c1862ba4e9035ba3531caa9ecb15202e96f8d886 Mon Sep 17 00:00:00 2001 From: parauliya Date: Wed, 19 Aug 2020 11:57:24 +0530 Subject: [PATCH 3/6] Added test cases for the scenario where there are two successfull workflows for one worker Signed-off-by: parauliya --- test/_vagrant/hello-world-again.tmpl | 10 ++ test/_vagrant/vagrant_test.go | 157 ++++++++++++++++++++++++++- 2 files changed, 165 insertions(+), 2 deletions(-) create mode 100644 test/_vagrant/hello-world-again.tmpl diff --git a/test/_vagrant/hello-world-again.tmpl b/test/_vagrant/hello-world-again.tmpl new file mode 100644 index 000000000..2e660d451 --- /dev/null +++ b/test/_vagrant/hello-world-again.tmpl @@ -0,0 +1,10 @@ +version: "0.1" +name: hello_world_again_workflow +global_timeout: 600 +tasks: + - name: "hello world" + worker: "{{.device_1}}" + actions: + - name: "hello_world_again" + image: hello-world-again + timeout: 60 diff --git a/test/_vagrant/vagrant_test.go b/test/_vagrant/vagrant_test.go index 46c105238..cdfd0e1d1 100644 --- a/test/_vagrant/vagrant_test.go +++ b/test/_vagrant/vagrant_test.go @@ -255,7 +255,7 @@ func TestOneTimeoutWorkflow(t *testing.T) { } for event, err := events.Recv(); err == nil && event != nil; event, err = events.Recv() { if event.ActionName == "hello_world" && event.ActionStatus == workflow.ActionState_ACTION_SUCCESS { - t.Logf("action %s SUCCESSFULL as expected", event.ActionName) + t.Logf("action %s SUCCESSFUL as expected", event.ActionName) continue } if event.ActionName == "sleep-till-timeout" && event.ActionStatus == workflow.ActionState_ACTION_TIMEOUT { @@ -389,7 +389,7 @@ func TestOneFailedWorkflow(t *testing.T) { } for event, err := events.Recv(); err == nil && event != nil; event, err = events.Recv() { if event.ActionName == "hello_world" && event.ActionStatus == workflow.ActionState_ACTION_SUCCESS { - t.Logf("action %s SUCCESSFULL as expected", event.ActionName) + t.Logf("action %s SUCCESSFUL as expected", event.ActionName) continue } if event.ActionName == "sleep-till-timeout" && event.ActionStatus == workflow.ActionState_ACTION_FAILED { @@ -402,6 +402,159 @@ func TestOneFailedWorkflow(t *testing.T) { t.Fatal("Workflow never got to a complite state or it didn't make it on time (5m)") } +func TestTwoSuccessfulWorkflows(t *testing.T) { + ctx := context.Background() + + machine, err := vagrant.Up(ctx, + vagrant.WithLogger(t.Logf), + vagrant.WithMachineName("provisioner"), + vagrant.WithWorkdir("../../deploy/vagrant"), + ) + if err != nil { + t.Fatal(err) + } + + defer func() { + err := machine.Destroy(ctx) + if err != nil { + t.Error(err) + } + }() + + _, err = machine.Exec(ctx, "cd /vagrant/deploy && source ../envrc && docker-compose up -d") + if err != nil { + t.Fatal(err) + } + + _, err = machine.Exec(ctx, "docker pull hello-world") + if err != nil { + t.Fatal(err) + } + + _, err = machine.Exec(ctx, "docker tag hello-world 192.168.1.1/hello-world") + if err != nil { + t.Fatal(err) + } + + _, err = machine.Exec(ctx, "docker push 192.168.1.1/hello-world") + if err != nil { + t.Fatal(err) + } + + _, err = machine.Exec(ctx, "docker tag hello-world 192.168.1.1/hello-world-again") + if err != nil { + t.Fatal(err) + } + + _, err = machine.Exec(ctx, "docker push 192.168.1.1/hello-world-again") + if err != nil { + t.Fatal(err) + } + + for ii := 0; ii < 5; ii++ { + resp, err := http.Get("http://localhost:42114/_packet/healthcheck") + if err != nil || resp.StatusCode != http.StatusOK { + if err != nil { + t.Logf("err tinkerbell healthcheck... retrying: %s", err) + } else { + t.Logf("err tinkerbell healthcheck... expected status code 200 got %d retrying", resp.StatusCode) + } + time.Sleep(10 * time.Second) + } + } + + t.Log("Tinkerbell is up and running") + + os.Setenv("TINKERBELL_CERT_URL", "http://127.0.0.1:42114/cert") + os.Setenv("TINKERBELL_GRPC_AUTHORITY", "127.0.0.1:42113") + client.Setup() + _, err = client.HardwareClient.All(ctx, &hardware.Empty{}) + if err != nil { + t.Fatal(err) + } + hwDataFile := "data.json" + + err = registerHardwares(ctx, hwDataFile) + if err != nil { + t.Fatal(err) + } + + templateID, err := registerTemplates(ctx, "hello-world.tmpl") + if err != nil { + t.Fatal(err) + } + + t.Logf("templateID: %s", templateID) + + firstWorkflowID, err := createWorkflow(ctx, templateID) + if err != nil { + t.Fatal(err) + } + + t.Logf("First WorkflowID: %s", firstWorkflowID) + + templateID, err = registerTemplates(ctx, "hello-world-again.tmpl") + if err != nil { + t.Fatal(err) + } + + t.Logf("templateID: %s", templateID) + + secondWorkflowID, err := createWorkflow(ctx, templateID) + if err != nil { + t.Fatal(err) + } + + t.Logf("Second WorkflowID: %s", secondWorkflowID) + + os.Setenv("VAGRANT_WORKER_GUI", "false") + worker, err := vagrant.Up(ctx, + vagrant.WithLogger(t.Logf), + vagrant.WithMachineName("worker"), + vagrant.WithWorkdir("../../deploy/vagrant"), + vagrant.RunAsync(), + ) + if err != nil { + t.Fatal(err) + } + + defer func() { + err := worker.Destroy(ctx) + if err != nil { + t.Error(err) + } + }() + + for iii := 0; iii < 30; iii++ { + events, err := client.WorkflowClient.ShowWorkflowEvents(ctx, &workflow.GetRequest{ + Id: firstWorkflowID, + }) + if err != nil { + t.Fatal(err) + } + for event, err := events.Recv(); err == nil && event != nil; event, err = events.Recv() { + if event.ActionName == "hello_world" && event.ActionStatus == workflow.ActionState_ACTION_SUCCESS { + t.Logf("action %s SUCCESSFUL as expected", event.ActionName) + } + } + + events, err = client.WorkflowClient.ShowWorkflowEvents(ctx, &workflow.GetRequest{ + Id: secondWorkflowID, + }) + if err != nil { + t.Fatal(err) + } + for event, err := events.Recv(); err == nil && event != nil; event, err = events.Recv() { + if event.ActionName == "hello_world_again" && event.ActionStatus == workflow.ActionState_ACTION_SUCCESS { + t.Logf("action %s SUCCESSFUL as expected", event.ActionName) + return + } + } + time.Sleep(5 * time.Second) + } + t.Fatal("Workflow never got to a complite state or it didn't make it on time (5m)") +} + func createWorkflow(ctx context.Context, templateID string) (string, error) { res, err := client.WorkflowClient.CreateWorkflow(ctx, &workflow.CreateRequest{ Template: templateID, From 59ac6b0601993db64dce73f8e83ac6b4155c129d Mon Sep 17 00:00:00 2001 From: parauliya Date: Wed, 19 Aug 2020 18:40:51 +0530 Subject: [PATCH 4/6] Added test cases for the scenario where there are two workflows for one worker. Out of two workflows one fails and one runs successfully. Signed-off-by: parauliya --- test/_vagrant/vagrant_test.go | 143 ++++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) diff --git a/test/_vagrant/vagrant_test.go b/test/_vagrant/vagrant_test.go index cdfd0e1d1..0dcc75c12 100644 --- a/test/_vagrant/vagrant_test.go +++ b/test/_vagrant/vagrant_test.go @@ -555,6 +555,149 @@ func TestTwoSuccessfulWorkflows(t *testing.T) { t.Fatal("Workflow never got to a complite state or it didn't make it on time (5m)") } +func TestOneFailedAndOneSuccessWorkflow(t *testing.T) { + ctx := context.Background() + + machine, err := vagrant.Up(ctx, + vagrant.WithLogger(t.Logf), + vagrant.WithMachineName("provisioner"), + vagrant.WithWorkdir("../../deploy/vagrant"), + ) + if err != nil { + t.Fatal(err) + } + + defer func() { + err := machine.Destroy(ctx) + if err != nil { + t.Error(err) + } + }() + + _, err = machine.Exec(ctx, "cd /vagrant/deploy && source ../envrc && docker-compose up -d") + if err != nil { + t.Fatal(err) + } + + _, err = machine.Exec(ctx, "docker pull hello-world") + if err != nil { + t.Fatal(err) + } + + _, err = machine.Exec(ctx, "docker tag hello-world 192.168.1.1/hello-world") + if err != nil { + t.Fatal(err) + } + + _, err = machine.Exec(ctx, "docker push 192.168.1.1/hello-world") + if err != nil { + t.Fatal(err) + } + + for ii := 0; ii < 5; ii++ { + resp, err := http.Get("http://localhost:42114/_packet/healthcheck") + if err != nil || resp.StatusCode != http.StatusOK { + if err != nil { + t.Logf("err tinkerbell healthcheck... retrying: %s", err) + } else { + t.Logf("err tinkerbell healthcheck... expected status code 200 got %d retrying", resp.StatusCode) + } + time.Sleep(10 * time.Second) + } + } + + t.Log("Tinkerbell is up and running") + + os.Setenv("TINKERBELL_CERT_URL", "http://127.0.0.1:42114/cert") + os.Setenv("TINKERBELL_GRPC_AUTHORITY", "127.0.0.1:42113") + client.Setup() + _, err = client.HardwareClient.All(ctx, &hardware.Empty{}) + if err != nil { + t.Fatal(err) + } + hwDataFile := "data.json" + + err = registerHardwares(ctx, hwDataFile) + if err != nil { + t.Fatal(err) + } + + templateID, err := registerTemplates(ctx, "hello-world.tmpl") + if err != nil { + t.Fatal(err) + } + + t.Logf("templateID: %s", templateID) + + firstWorkflowID, err := createWorkflow(ctx, templateID) + if err != nil { + t.Fatal(err) + } + + t.Logf("First WorkflowID: %s", firstWorkflowID) + + templateID, err = registerTemplates(ctx, "failedWorkflow.tmpl") + if err != nil { + t.Fatal(err) + } + + t.Logf("templateID: %s", templateID) + + secondWorkflowID, err := createWorkflow(ctx, templateID) + if err != nil { + t.Fatal(err) + } + + t.Logf("Second WorkflowID: %s", secondWorkflowID) + + os.Setenv("VAGRANT_WORKER_GUI", "false") + worker, err := vagrant.Up(ctx, + vagrant.WithLogger(t.Logf), + vagrant.WithMachineName("worker"), + vagrant.WithWorkdir("../../deploy/vagrant"), + vagrant.RunAsync(), + ) + if err != nil { + t.Fatal(err) + } + + defer func() { + err := worker.Destroy(ctx) + if err != nil { + t.Error(err) + } + }() + + for iii := 0; iii < 30; iii++ { + events, err := client.WorkflowClient.ShowWorkflowEvents(ctx, &workflow.GetRequest{ + Id: firstWorkflowID, + }) + if err != nil { + t.Fatal(err) + } + for event, err := events.Recv(); err == nil && event != nil; event, err = events.Recv() { + if event.ActionName == "hello_world" && event.ActionStatus == workflow.ActionState_ACTION_SUCCESS { + t.Logf("action %s SUCCESSFUL as expected", event.ActionName) + } + } + + events, err = client.WorkflowClient.ShowWorkflowEvents(ctx, &workflow.GetRequest{ + Id: secondWorkflowID, + }) + if err != nil { + t.Fatal(err) + } + for event, err := events.Recv(); err == nil && event != nil; event, err = events.Recv() { + if event.ActionName == "sleep-till-timeout" && event.ActionStatus == workflow.ActionState_ACTION_FAILED { + t.Logf("action %s FAILED as expected", event.ActionName) + return + } + } + time.Sleep(5 * time.Second) + } + t.Fatal("Workflow never got to a complite state or it didn't make it on time (5m)") +} + func createWorkflow(ctx context.Context, templateID string) (string, error) { res, err := client.WorkflowClient.CreateWorkflow(ctx, &workflow.CreateRequest{ Template: templateID, From 7187bab16247d674b0355007dea35616bb85b0ae Mon Sep 17 00:00:00 2001 From: parauliya Date: Fri, 21 Aug 2020 13:24:33 +0530 Subject: [PATCH 5/6] Added test case where one workflow is successful and one workflow is timed out for same worker Signed-off-by: parauliya --- go.mod | 6 -- go.sum | 2 + test/_vagrant/vagrant_test.go | 143 ++++++++++++++++++++++++++++++++++ 3 files changed, 145 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 9e4f5a49d..90e9266b2 100644 --- a/go.mod +++ b/go.mod @@ -33,12 +33,6 @@ require ( github.com/spf13/viper v1.4.0 github.com/stretchr/testify v1.3.0 go.mongodb.org/mongo-driver v1.1.2 // indirect -<<<<<<< HEAD -======= - go.uber.org/atomic v1.2.0 // indirect - go.uber.org/multierr v1.1.0 // indirect - go.uber.org/zap v1.7.1 // indirect ->>>>>>> Fix #257 : Added following test cases: golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e // indirect golang.org/x/sys v0.0.0-20200331124033-c3d80250170d // indirect diff --git a/go.sum b/go.sum index acc6534e2..302e17fd8 100644 --- a/go.sum +++ b/go.sum @@ -222,10 +222,12 @@ go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mongodb.org/mongo-driver v1.1.2 h1:jxcFYjlkl8xaERsgLo+RNquI0epW6zuy/ZRQs6jnrFA= go.mongodb.org/mongo-driver v1.1.2/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= +go.uber.org/atomic v1.2.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/zap v1.7.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= diff --git a/test/_vagrant/vagrant_test.go b/test/_vagrant/vagrant_test.go index 0dcc75c12..9c5a40fe3 100644 --- a/test/_vagrant/vagrant_test.go +++ b/test/_vagrant/vagrant_test.go @@ -698,6 +698,149 @@ func TestOneFailedAndOneSuccessWorkflow(t *testing.T) { t.Fatal("Workflow never got to a complite state or it didn't make it on time (5m)") } +func TestOneTimeoutAndOneSuccessWorkflow(t *testing.T) { + ctx := context.Background() + + machine, err := vagrant.Up(ctx, + vagrant.WithLogger(t.Logf), + vagrant.WithMachineName("provisioner"), + vagrant.WithWorkdir("../../deploy/vagrant"), + ) + if err != nil { + t.Fatal(err) + } + + defer func() { + err := machine.Destroy(ctx) + if err != nil { + t.Error(err) + } + }() + + _, err = machine.Exec(ctx, "cd /vagrant/deploy && source ../envrc && docker-compose up -d") + if err != nil { + t.Fatal(err) + } + + _, err = machine.Exec(ctx, "docker pull hello-world") + if err != nil { + t.Fatal(err) + } + + _, err = machine.Exec(ctx, "docker tag hello-world 192.168.1.1/hello-world") + if err != nil { + t.Fatal(err) + } + + _, err = machine.Exec(ctx, "docker push 192.168.1.1/hello-world") + if err != nil { + t.Fatal(err) + } + + for ii := 0; ii < 5; ii++ { + resp, err := http.Get("http://localhost:42114/_packet/healthcheck") + if err != nil || resp.StatusCode != http.StatusOK { + if err != nil { + t.Logf("err tinkerbell healthcheck... retrying: %s", err) + } else { + t.Logf("err tinkerbell healthcheck... expected status code 200 got %d retrying", resp.StatusCode) + } + time.Sleep(10 * time.Second) + } + } + + t.Log("Tinkerbell is up and running") + + os.Setenv("TINKERBELL_CERT_URL", "http://127.0.0.1:42114/cert") + os.Setenv("TINKERBELL_GRPC_AUTHORITY", "127.0.0.1:42113") + client.Setup() + _, err = client.HardwareClient.All(ctx, &hardware.Empty{}) + if err != nil { + t.Fatal(err) + } + hwDataFile := "data.json" + + err = registerHardwares(ctx, hwDataFile) + if err != nil { + t.Fatal(err) + } + + templateID, err := registerTemplates(ctx, "hello-world.tmpl") + if err != nil { + t.Fatal(err) + } + + t.Logf("templateID: %s", templateID) + + firstWorkflowID, err := createWorkflow(ctx, templateID) + if err != nil { + t.Fatal(err) + } + + t.Logf("First WorkflowID: %s", firstWorkflowID) + + templateID, err = registerTemplates(ctx, "timeout.tmpl") + if err != nil { + t.Fatal(err) + } + + t.Logf("templateID: %s", templateID) + + secondWorkflowID, err := createWorkflow(ctx, templateID) + if err != nil { + t.Fatal(err) + } + + t.Logf("Second WorkflowID: %s", secondWorkflowID) + + os.Setenv("VAGRANT_WORKER_GUI", "false") + worker, err := vagrant.Up(ctx, + vagrant.WithLogger(t.Logf), + vagrant.WithMachineName("worker"), + vagrant.WithWorkdir("../../deploy/vagrant"), + vagrant.RunAsync(), + ) + if err != nil { + t.Fatal(err) + } + + defer func() { + err := worker.Destroy(ctx) + if err != nil { + t.Error(err) + } + }() + + for iii := 0; iii < 30; iii++ { + events, err := client.WorkflowClient.ShowWorkflowEvents(ctx, &workflow.GetRequest{ + Id: firstWorkflowID, + }) + if err != nil { + t.Fatal(err) + } + for event, err := events.Recv(); err == nil && event != nil; event, err = events.Recv() { + if event.ActionName == "hello_world" && event.ActionStatus == workflow.ActionState_ACTION_SUCCESS { + t.Logf("action %s SUCCESSFUL as expected", event.ActionName) + } + } + + events, err = client.WorkflowClient.ShowWorkflowEvents(ctx, &workflow.GetRequest{ + Id: secondWorkflowID, + }) + if err != nil { + t.Fatal(err) + } + for event, err := events.Recv(); err == nil && event != nil; event, err = events.Recv() { + if event.ActionName == "sleep-till-timeout" && event.ActionStatus == workflow.ActionState_ACTION_TIMEOUT { + t.Logf("action %s TIMEDOUT as expected", event.ActionName) + return + } + } + time.Sleep(5 * time.Second) + } + t.Fatal("Workflow never got to a complite state or it didn't make it on time (5m)") +} + func createWorkflow(ctx context.Context, templateID string) (string, error) { res, err := client.WorkflowClient.CreateWorkflow(ctx, &workflow.CreateRequest{ Template: templateID, From 7cc4c5220b0b447e4827166d3ee4c122661c0082 Mon Sep 17 00:00:00 2001 From: parauliya Date: Fri, 21 Aug 2020 19:51:40 +0530 Subject: [PATCH 6/6] Increase the test time from 5 sec to 10 secs Signed-off-by: parauliya --- test/_vagrant/vagrant_test.go | 48 +++++++++++++++++++++++++++-------- 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/test/_vagrant/vagrant_test.go b/test/_vagrant/vagrant_test.go index 9c5a40fe3..7ecb495d3 100644 --- a/test/_vagrant/vagrant_test.go +++ b/test/_vagrant/vagrant_test.go @@ -132,7 +132,7 @@ func TestVagrantSetupGuide(t *testing.T) { } time.Sleep(10 * time.Second) } - t.Fatal("Workflow never got to a complite state or it didn't make it on time (10m)") + t.Fatal("Workflow never got to a complete state or it didn't make it on time (10m)") } func TestOneTimeoutWorkflow(t *testing.T) { ctx := context.Background() @@ -263,9 +263,9 @@ func TestOneTimeoutWorkflow(t *testing.T) { return } } - time.Sleep(5 * time.Second) + time.Sleep(10 * time.Second) } - t.Fatal("Workflow never got to a complite state or it didn't make it on time (5m)") + t.Fatal("Workflow never got to a complete state or it didn't make it on time (10m)") } func TestOneFailedWorkflow(t *testing.T) { @@ -397,9 +397,9 @@ func TestOneFailedWorkflow(t *testing.T) { return } } - time.Sleep(5 * time.Second) + time.Sleep(10 * time.Second) } - t.Fatal("Workflow never got to a complite state or it didn't make it on time (5m)") + t.Fatal("Workflow never got to a complete state or it didn't make it on time (10m)") } func TestTwoSuccessfulWorkflows(t *testing.T) { @@ -550,9 +550,9 @@ func TestTwoSuccessfulWorkflows(t *testing.T) { return } } - time.Sleep(5 * time.Second) + time.Sleep(10 * time.Second) } - t.Fatal("Workflow never got to a complite state or it didn't make it on time (5m)") + t.Fatal("Workflow never got to a complete state or it didn't make it on time (10m)") } func TestOneFailedAndOneSuccessWorkflow(t *testing.T) { @@ -584,16 +584,29 @@ func TestOneFailedAndOneSuccessWorkflow(t *testing.T) { t.Fatal(err) } + _, err = machine.Exec(ctx, "docker pull bash") + if err != nil { + t.Fatal(err) + } _, err = machine.Exec(ctx, "docker tag hello-world 192.168.1.1/hello-world") if err != nil { t.Fatal(err) } + _, err = machine.Exec(ctx, "docker tag bash 192.168.1.1/bash") + if err != nil { + t.Fatal(err) + } _, err = machine.Exec(ctx, "docker push 192.168.1.1/hello-world") if err != nil { t.Fatal(err) } + _, err = machine.Exec(ctx, "docker push 192.168.1.1/bash") + if err != nil { + t.Fatal(err) + } + for ii := 0; ii < 5; ii++ { resp, err := http.Get("http://localhost:42114/_packet/healthcheck") if err != nil || resp.StatusCode != http.StatusOK { @@ -693,9 +706,9 @@ func TestOneFailedAndOneSuccessWorkflow(t *testing.T) { return } } - time.Sleep(5 * time.Second) + time.Sleep(10 * time.Second) } - t.Fatal("Workflow never got to a complite state or it didn't make it on time (5m)") + t.Fatal("Workflow never got to a complete state or it didn't make it on time (10m)") } func TestOneTimeoutAndOneSuccessWorkflow(t *testing.T) { @@ -727,16 +740,29 @@ func TestOneTimeoutAndOneSuccessWorkflow(t *testing.T) { t.Fatal(err) } + _, err = machine.Exec(ctx, "docker pull bash") + if err != nil { + t.Fatal(err) + } _, err = machine.Exec(ctx, "docker tag hello-world 192.168.1.1/hello-world") if err != nil { t.Fatal(err) } + _, err = machine.Exec(ctx, "docker tag bash 192.168.1.1/bash") + if err != nil { + t.Fatal(err) + } _, err = machine.Exec(ctx, "docker push 192.168.1.1/hello-world") if err != nil { t.Fatal(err) } + _, err = machine.Exec(ctx, "docker push 192.168.1.1/bash") + if err != nil { + t.Fatal(err) + } + for ii := 0; ii < 5; ii++ { resp, err := http.Get("http://localhost:42114/_packet/healthcheck") if err != nil || resp.StatusCode != http.StatusOK { @@ -836,9 +862,9 @@ func TestOneTimeoutAndOneSuccessWorkflow(t *testing.T) { return } } - time.Sleep(5 * time.Second) + time.Sleep(10 * time.Second) } - t.Fatal("Workflow never got to a complite state or it didn't make it on time (5m)") + t.Fatal("Workflow never got to a complete state or it didn't make it on time (10m)") } func createWorkflow(ctx context.Context, templateID string) (string, error) {