Skip to content
This repository was archived by the owner on Jun 27, 2025. It is now read-only.

Commit aacc9ed

Browse files
committed
test: add count and canary integration tests
1 parent 33581e0 commit aacc9ed

File tree

8 files changed

+271
-15
lines changed

8 files changed

+271
-15
lines changed

test/acctest/acctest.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,28 @@ func CheckDeploymentStatus(status string) TestStateFunc {
123123
}
124124
}
125125

126+
// CheckTaskGroupCount is a TestStateFunc to check a TaskGroup count
127+
func CheckTaskGroupCount(groupName string, count int) TestStateFunc {
128+
return func(s *TestState) error {
129+
job, _, err := s.Nomad.Jobs().Info(s.JobName, nil)
130+
if err != nil {
131+
return err
132+
}
133+
134+
for _, group := range job.TaskGroups {
135+
if groupName == *group.Name {
136+
if *group.Count == count {
137+
return nil
138+
}
139+
140+
return fmt.Errorf("task group %s count is %d, expected %d", groupName, *group.Count, count)
141+
}
142+
}
143+
144+
return fmt.Errorf("unable to find task group %s", groupName)
145+
}
146+
}
147+
126148
// newNomadClient creates a Nomad API client configrable by NOMAD_
127149
// env variables or returns an error if Nomad is in an unhealthy state
128150
func newNomadClient() (*nomad.Client, error) {

test/acctest/deploy.go

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,24 +12,30 @@ import (
1212
type DeployTestStepRunner struct {
1313
FixtureName string
1414

15-
Canary int
16-
ForceBatch bool
17-
ForceCounts bool
15+
Vars map[string]string
16+
17+
Canary int
18+
ForceBatch bool
19+
ForceCount bool
1820
}
1921

2022
// Run renders the job fixture and triggers a deployment
2123
func (c DeployTestStepRunner) Run(s *TestState) error {
22-
vars := map[string]string{
23-
"job_name": s.JobName,
24+
if c.Vars == nil {
25+
c.Vars = map[string]string{}
2426
}
25-
job, err := template.RenderJob("fixtures/"+c.FixtureName, []string{}, "", &vars)
27+
c.Vars["job_name"] = s.JobName
28+
29+
job, err := template.RenderJob("fixtures/"+c.FixtureName, []string{}, "", &c.Vars)
2630
if err != nil {
2731
return fmt.Errorf("error rendering template: %s", err)
2832
}
2933

3034
cfg := &levant.DeployConfig{
3135
Deploy: &structs.DeployConfig{
32-
Canary: c.Canary,
36+
Canary: c.Canary,
37+
ForceBatch: c.ForceBatch,
38+
ForceCount: c.ForceCount,
3339
},
3440
Client: &structs.ClientConfig{},
3541
Template: &structs.TemplateConfig{

test/deploy_test.go

Lines changed: 95 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@ func TestDeploy_basic(t *testing.T) {
2020
})
2121
}
2222

23-
func TestDeploy_failure(t *testing.T) {
23+
func TestDeploy_driverError(t *testing.T) {
2424
acctest.Test(t, acctest.TestCase{
2525
Steps: []acctest.TestStep{
2626
{
2727
Runner: acctest.DeployTestStepRunner{
28-
FixtureName: "deploy_failure.nomad",
28+
FixtureName: "deploy_driver_error.nomad",
2929
},
3030
ExpectErr: true,
3131
CheckErr: func(err error) bool {
@@ -41,3 +41,96 @@ func TestDeploy_failure(t *testing.T) {
4141
CleanupFunc: acctest.CleanupPurgeJob,
4242
})
4343
}
44+
45+
func TestDeploy_allocError(t *testing.T) {
46+
acctest.Test(t, acctest.TestCase{
47+
Steps: []acctest.TestStep{
48+
{
49+
Runner: acctest.DeployTestStepRunner{
50+
FixtureName: "deploy_alloc_error.nomad",
51+
},
52+
ExpectErr: true,
53+
CheckErr: func(err error) bool {
54+
// this is a bit pointless without the error bubbled up from levant
55+
return true
56+
},
57+
},
58+
{
59+
// allows us to check a job was registered and previous step error wasn't a parse failure etc.
60+
Check: acctest.CheckDeploymentStatus("failed"),
61+
},
62+
},
63+
CleanupFunc: acctest.CleanupPurgeJob,
64+
})
65+
}
66+
67+
func TestDeploy_count(t *testing.T) {
68+
acctest.Test(t, acctest.TestCase{
69+
Steps: []acctest.TestStep{
70+
{
71+
Runner: acctest.DeployTestStepRunner{
72+
FixtureName: "deploy_count.nomad",
73+
Vars: map[string]string{
74+
"count": "3",
75+
},
76+
},
77+
Check: acctest.CheckDeploymentStatus("successful"),
78+
},
79+
{
80+
Runner: acctest.DeployTestStepRunner{
81+
FixtureName: "deploy_count.nomad",
82+
Vars: map[string]string{
83+
"count": "1",
84+
},
85+
},
86+
Check: acctest.CheckDeploymentStatus("successful"),
87+
},
88+
{
89+
// expect levant to read counts from the api
90+
Check: acctest.CheckTaskGroupCount("test", 3),
91+
},
92+
{
93+
Runner: acctest.DeployTestStepRunner{
94+
FixtureName: "deploy_count.nomad",
95+
Vars: map[string]string{
96+
"count": "1",
97+
},
98+
ForceCount: true,
99+
},
100+
Check: acctest.CheckDeploymentStatus("successful"),
101+
},
102+
{
103+
Check: acctest.CheckTaskGroupCount("test", 1),
104+
},
105+
},
106+
CleanupFunc: acctest.CleanupPurgeJob,
107+
})
108+
}
109+
110+
func TestDeploy_canary(t *testing.T) {
111+
acctest.Test(t, acctest.TestCase{
112+
Steps: []acctest.TestStep{
113+
{
114+
Runner: acctest.DeployTestStepRunner{
115+
FixtureName: "deploy_canary.nomad",
116+
Canary: 10,
117+
Vars: map[string]string{
118+
"env_version": "1",
119+
},
120+
},
121+
Check: acctest.CheckDeploymentStatus("successful"),
122+
},
123+
{
124+
Runner: acctest.DeployTestStepRunner{
125+
FixtureName: "deploy_canary.nomad",
126+
Canary: 10,
127+
Vars: map[string]string{
128+
"env_version": "2",
129+
},
130+
},
131+
Check: acctest.CheckDeploymentStatus("successful"),
132+
},
133+
},
134+
CleanupFunc: acctest.CleanupPurgeJob,
135+
})
136+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# test alloc error with a command failure
2+
3+
job "[[.job_name]]" {
4+
datacenters = ["dc1"]
5+
type = "service"
6+
update {
7+
max_parallel = 1
8+
min_healthy_time = "10s"
9+
healthy_deadline = "15s"
10+
progress_deadline = "20s"
11+
}
12+
13+
group "test" {
14+
count = 1
15+
restart {
16+
attempts = 1
17+
interval = "10s"
18+
delay = "5s"
19+
mode = "fail"
20+
}
21+
ephemeral_disk {
22+
size = 300
23+
}
24+
task "alpine" {
25+
driver = "docker"
26+
config {
27+
image = "alpine"
28+
command = "badcommandname"
29+
}
30+
resources {
31+
cpu = 100
32+
memory = 128
33+
network {
34+
mbits = 10
35+
}
36+
}
37+
}
38+
}
39+
}

test/fixtures/deploy_basic.nomad

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# tests a healthy deployment
2+
13
job "[[.job_name]]" {
24
datacenters = ["dc1"]
35
type = "service"
@@ -8,7 +10,7 @@ job "[[.job_name]]" {
810
auto_revert = true
911
}
1012

11-
group "cache" {
13+
group "test" {
1214
count = 1
1315
restart {
1416
attempts = 10
@@ -19,10 +21,14 @@ job "[[.job_name]]" {
1921
ephemeral_disk {
2022
size = 300
2123
}
22-
task "redis" {
24+
task "alpine" {
2325
driver = "docker"
2426
config {
25-
image = "redis:alpine"
27+
image = "alpine"
28+
command = "tail"
29+
args = [
30+
"-f", "/dev/null"
31+
]
2632
}
2733
resources {
2834
cpu = 100

test/fixtures/deploy_canary.nomad

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# tests a canary deployment
2+
3+
job "[[.job_name]]" {
4+
datacenters = ["dc1"]
5+
type = "service"
6+
update {
7+
max_parallel = 1
8+
min_healthy_time = "2s"
9+
healthy_deadline = "1m"
10+
auto_revert = true
11+
canary = 1
12+
}
13+
14+
group "test" {
15+
count = 1
16+
restart {
17+
attempts = 10
18+
interval = "5m"
19+
delay = "25s"
20+
mode = "delay"
21+
}
22+
ephemeral_disk {
23+
size = 300
24+
}
25+
task "alpine" {
26+
driver = "docker"
27+
config {
28+
image = "alpine"
29+
command = "tail"
30+
args = [
31+
"-f", "/dev/null"
32+
]
33+
}
34+
env {
35+
version = "[[ .env_version ]]"
36+
}
37+
resources {
38+
cpu = 100
39+
memory = 128
40+
network {
41+
mbits = 10
42+
}
43+
}
44+
}
45+
}
46+
}

test/fixtures/deploy_count.nomad

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# tests a healthy deployment with a count
2+
3+
job "[[.job_name]]" {
4+
datacenters = ["dc1"]
5+
type = "service"
6+
update {
7+
max_parallel = 1
8+
min_healthy_time = "10s"
9+
healthy_deadline = "1m"
10+
auto_revert = true
11+
}
12+
13+
group "test" {
14+
count = [[.count]]
15+
restart {
16+
attempts = 10
17+
interval = "5m"
18+
delay = "25s"
19+
mode = "delay"
20+
}
21+
ephemeral_disk {
22+
size = 300
23+
}
24+
task "alpine" {
25+
driver = "docker"
26+
config {
27+
image = "alpine"
28+
command = "tail"
29+
args = [
30+
"-f", "/dev/null"
31+
]
32+
}
33+
resources {
34+
cpu = 100
35+
memory = 128
36+
network {
37+
mbits = 10
38+
}
39+
}
40+
}
41+
}
42+
}
Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# tests driver error with an invalid docker image tag
2+
13
job "[[.job_name]]" {
24
datacenters = ["dc1"]
35
type = "service"
@@ -8,7 +10,7 @@ job "[[.job_name]]" {
810
progress_deadline = "20s"
911
}
1012

11-
group "cache" {
13+
group "test" {
1214
count = 1
1315
restart {
1416
attempts = 1
@@ -19,10 +21,10 @@ job "[[.job_name]]" {
1921
ephemeral_disk {
2022
size = 300
2123
}
22-
task "redis" {
24+
task "alpine" {
2325
driver = "docker"
2426
config {
25-
image = "redis:badimagetag"
27+
image = "alpine:badimagetag"
2628
}
2729
resources {
2830
cpu = 100

0 commit comments

Comments
 (0)