Skip to content

Commit 120aa03

Browse files
authored
test(e2e): add end to end testing (#785)
This PR adds end to end tests. Tests are located in `test/e2e/`. The `HCLOUD_TOKEN` environment variable should contain an API token to an empty project for the tests to work.
1 parent 74e3ae5 commit 120aa03

15 files changed

+1544
-0
lines changed

.github/workflows/ci.yml

+28
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,34 @@ jobs:
5252
uses: codecov/codecov-action@v4
5353
with:
5454
token: ${{ secrets.CODECOV_TOKEN }}
55+
flags: unit
56+
57+
test-e2e:
58+
runs-on: ubuntu-latest
59+
permissions:
60+
id-token: write
61+
steps:
62+
- name: Checkout
63+
uses: actions/checkout@v4
64+
65+
- name: Set up Go
66+
uses: actions/setup-go@v5
67+
with:
68+
go-version: "1.23"
69+
70+
- uses: hetznercloud/tps-action@main
71+
72+
- name: Run tests
73+
run: go test -tags e2e -coverpkg=./... -coverprofile=coverage.txt -v -race ./test/e2e
74+
75+
- name: Upload coverage reports to Codecov
76+
if: >
77+
!startsWith(github.head_ref, 'renovate/') &&
78+
!startsWith(github.head_ref, 'release-please--')
79+
uses: codecov/codecov-action@v4
80+
with:
81+
token: ${{ secrets.CODECOV_TOKEN }}
82+
flags: e2e
5583

5684
generate:
5785
runs-on: ubuntu-latest

.github/workflows/e2e_test.yml

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
name: E2E Tests
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
8+
jobs:
9+
test:

go.mod

+7
Original file line numberDiff line numberDiff line change
@@ -21,23 +21,27 @@ require (
2121
github.com/spf13/pflag v1.0.5
2222
github.com/spf13/viper v1.19.0
2323
github.com/stretchr/testify v1.9.0
24+
github.com/swaggest/assertjson v1.9.0
2425
golang.org/x/crypto v0.27.0
2526
golang.org/x/term v0.24.0
2627
)
2728

2829
require (
2930
github.com/VividCortex/ewma v1.2.0 // indirect
3031
github.com/beorn7/perks v1.0.1 // indirect
32+
github.com/bool64/shared v0.1.5 // indirect
3133
github.com/cespare/xxhash/v2 v2.2.0 // indirect
3234
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
3335
github.com/fsnotify/fsnotify v1.7.0 // indirect
3436
github.com/hashicorp/hcl v1.0.0 // indirect
37+
github.com/iancoleman/orderedmap v0.3.0 // indirect
3538
github.com/inconshreveable/mousetrap v1.1.0 // indirect
3639
github.com/magiconair/properties v1.8.7 // indirect
3740
github.com/mattn/go-colorable v0.1.13 // indirect
3841
github.com/mattn/go-isatty v0.0.20 // indirect
3942
github.com/mattn/go-runewidth v0.0.15 // indirect
4043
github.com/mitchellh/mapstructure v1.5.0 // indirect
44+
github.com/nxadm/tail v1.4.11 // indirect
4145
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
4246
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
4347
github.com/prometheus/client_golang v1.19.1 // indirect
@@ -47,9 +51,12 @@ require (
4751
github.com/rivo/uniseg v0.2.0 // indirect
4852
github.com/sagikazarmark/locafero v0.4.0 // indirect
4953
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
54+
github.com/sergi/go-diff v1.1.0 // indirect
5055
github.com/sourcegraph/conc v0.3.0 // indirect
5156
github.com/spf13/afero v1.11.0 // indirect
5257
github.com/subosito/gotenv v1.6.0 // indirect
58+
github.com/yudai/gojsondiff v1.0.0 // indirect
59+
github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 // indirect
5360
go.uber.org/atomic v1.9.0 // indirect
5461
go.uber.org/multierr v1.9.0 // indirect
5562
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect

go.sum

+35
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1o
44
github.com/VividCortex/ewma v1.2.0/go.mod h1:nz4BbCtbLyFDeC9SUHbtcT5644juEuWfUAUnGx7j5l4=
55
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
66
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
7+
github.com/bool64/dev v0.2.29 h1:x+syGyh+0eWtOzQ1ItvLzOGIWyNWnyjXpHIcpF2HvL4=
8+
github.com/bool64/dev v0.2.29/go.mod h1:iJbh1y/HkunEPhgebWRNcs8wfGq7sjvJ6W5iabL8ACg=
9+
github.com/bool64/shared v0.1.5 h1:fp3eUhBsrSjNCQPcSdQqZxxh9bBwrYiZ+zOKFkM0/2E=
10+
github.com/bool64/shared v0.1.5/go.mod h1:081yz68YC9jeFB3+Bbmno2RFWvGKv1lPKkMP6MHJlPs=
711
github.com/boumenot/gocover-cobertura v1.2.0 h1:g+VROIASoEHBrEilIyaCmgo7HGm+AV5yKEPLk0qIY+s=
812
github.com/boumenot/gocover-cobertura v1.2.0/go.mod h1:fz7ly8dslE42VRR5ZWLt2OHGDHjkTiA2oNvKgJEjLT0=
913
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
@@ -23,6 +27,7 @@ github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo=
2327
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
2428
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
2529
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
30+
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
2631
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
2732
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
2833
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
@@ -43,12 +48,17 @@ github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
4348
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
4449
github.com/hetznercloud/hcloud-go/v2 v2.13.1 h1:jq0GP4QaYE5d8xR/Zw17s9qoaESRJMXfGmtD1a/qckQ=
4550
github.com/hetznercloud/hcloud-go/v2 v2.13.1/go.mod h1:dhix40Br3fDiBhwaSG/zgaYOFFddpfBm/6R1Zz0IiF0=
51+
github.com/iancoleman/orderedmap v0.3.0 h1:5cbR2grmZR/DiVt+VJopEhtVs9YGInGIxAoMJn+Ichc=
52+
github.com/iancoleman/orderedmap v0.3.0/go.mod h1:XuLcCUkdL5owUCQeF2Ue9uuw1EptkJDkXXS7VoV7XGE=
4653
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
4754
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
4855
github.com/jedib0t/go-pretty/v6 v6.5.9 h1:ACteMBRrrmm1gMsXe9PSTOClQ63IXDUt03H5U+UV8OU=
4956
github.com/jedib0t/go-pretty/v6 v6.5.9/go.mod h1:zbn98qrYlh95FIhwwsbIip0LYpwSG8SUOScs+v9/t0E=
57+
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
5058
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
5159
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
60+
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
61+
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
5262
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
5363
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
5464
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
@@ -64,6 +74,12 @@ github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZ
6474
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
6575
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
6676
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
77+
github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY=
78+
github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc=
79+
github.com/onsi/ginkgo v1.15.2 h1:l77YT15o814C2qVL47NOyjV/6RbaP7kKdrvZnxQ3Org=
80+
github.com/onsi/ginkgo v1.15.2/go.mod h1:Dd6YFfwBW84ETqqtL0CPyPXillHgY6XhQH3uuCCTr/o=
81+
github.com/onsi/gomega v1.11.0 h1:+CqWgvj0OZycCaqclBD1pxKHAU+tOkHmQIWvDHq2aug=
82+
github.com/onsi/gomega v1.11.0/go.mod h1:azGKhqFUon9Vuj0YmTfLSmx0FUwqXYSTl5re8lQLTUg=
6783
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
6884
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
6985
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
@@ -86,6 +102,8 @@ github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6ke
86102
github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4=
87103
github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE=
88104
github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ=
105+
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
106+
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
89107
github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
90108
github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
91109
github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8=
@@ -103,6 +121,7 @@ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSS
103121
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
104122
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
105123
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
124+
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
106125
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
107126
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
108127
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
@@ -111,6 +130,14 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT
111130
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
112131
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
113132
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
133+
github.com/swaggest/assertjson v1.9.0 h1:dKu0BfJkIxv/xe//mkCrK5yZbs79jL7OVf9Ija7o2xQ=
134+
github.com/swaggest/assertjson v1.9.0/go.mod h1:b+ZKX2VRiUjxfUIal0HDN85W0nHPAYUbYH5WkkSsFsU=
135+
github.com/yudai/gojsondiff v1.0.0 h1:27cbfqXLVEJ1o8I6v3y9lg8Ydm53EKqHXAOMxEGlCOA=
136+
github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg=
137+
github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 h1:BHyfKlQyqbsFN5p3IfnEUduWvb9is428/nNb5L3U01M=
138+
github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM=
139+
github.com/yudai/pp v2.0.1+incompatible h1:Q4//iY4pNF6yPLZIigmvcl7k/bPgrcTPIFIcmawg5bI=
140+
github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc=
114141
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
115142
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
116143
go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
@@ -144,6 +171,7 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w
144171
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
145172
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
146173
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
174+
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
147175
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
148176
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
149177
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
@@ -169,10 +197,17 @@ golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6f
169197
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
170198
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
171199
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
200+
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
172201
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
173202
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
174203
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
175204
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
205+
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
206+
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
207+
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
208+
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
209+
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
210+
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
176211
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
177212
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
178213
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

test/e2e/combined_test.go

+109
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
//go:build e2e
2+
3+
package e2e
4+
5+
import (
6+
"fmt"
7+
"strconv"
8+
"testing"
9+
10+
"github.com/stretchr/testify/assert"
11+
"github.com/stretchr/testify/require"
12+
)
13+
14+
func TestCombined(t *testing.T) {
15+
// combined tests combine multiple resources and can thus not be run in parallel
16+
serverName := withSuffix("test-server")
17+
serverID, err := createServer(t, serverName, TestServerType, TestImage)
18+
require.NoError(t, err)
19+
20+
firewallName := withSuffix("test-firewall")
21+
firewallID, err := createFirewall(t, firewallName)
22+
require.NoError(t, err)
23+
24+
t.Run("firewall", func(t *testing.T) {
25+
t.Run("apply-to-server", func(t *testing.T) {
26+
out, err := runCommand(t, "firewall", "apply-to-resource", "--type", "server", "--server", serverName, strconv.FormatInt(firewallID, 10))
27+
require.NoError(t, err)
28+
assert.Equal(t, fmt.Sprintf("Firewall %d applied to resource\n", firewallID), out)
29+
})
30+
31+
t.Run("delete-in-use", func(t *testing.T) {
32+
out, err := runCommand(t, "firewall", "delete", strconv.FormatInt(firewallID, 10))
33+
assert.Regexp(t, `^firewall with ID [0-9]+ is still in use \(resource_in_use, [0-9a-f]+\)$`, err.Error())
34+
assert.Empty(t, out)
35+
})
36+
37+
t.Run("remove-from-server", func(t *testing.T) {
38+
out, err := runCommand(t, "firewall", "remove-from-resource", "--type", "server", "--server", serverName, strconv.FormatInt(firewallID, 10))
39+
require.NoError(t, err)
40+
assert.Equal(t, fmt.Sprintf("Firewall %d removed from resource\n", firewallID), out)
41+
})
42+
43+
t.Run("delete", func(t *testing.T) {
44+
out, err := runCommand(t, "firewall", "delete", strconv.FormatInt(firewallID, 10))
45+
require.NoError(t, err)
46+
assert.Equal(t, fmt.Sprintf("firewall %d deleted\n", firewallID), out)
47+
})
48+
49+
})
50+
51+
floatingIPName := withSuffix("test-floating-ip")
52+
floatingIP, err := createFloatingIP(t, floatingIPName, "ipv4", "--server", strconv.FormatInt(serverID, 10))
53+
require.NoError(t, err)
54+
55+
t.Run("floating-ip", func(t *testing.T) {
56+
t.Run("unassign", func(t *testing.T) {
57+
out, err := runCommand(t, "floating-ip", "unassign", strconv.FormatInt(floatingIP, 10))
58+
require.NoError(t, err)
59+
assert.Equal(t, fmt.Sprintf("Floating IP %d unassigned\n", floatingIP), out)
60+
})
61+
62+
t.Run("assign", func(t *testing.T) {
63+
out, err := runCommand(t, "floating-ip", "assign", strconv.FormatInt(floatingIP, 10), strconv.FormatInt(serverID, 10))
64+
require.NoError(t, err)
65+
assert.Equal(t, fmt.Sprintf("Floating IP %d assigned to server %d\n", floatingIP, serverID), out)
66+
})
67+
68+
t.Run("describe", func(t *testing.T) {
69+
out, err := runCommand(t, "floating-ip", "describe", strconv.FormatInt(floatingIP, 10))
70+
require.NoError(t, err)
71+
assert.Regexp(t, `ID:\s+[0-9]+
72+
Type:\s+ipv4
73+
Name:\s+test-floating-ip-[0-9a-f]{8}
74+
Description:\s+-
75+
Created:.*?
76+
IP:\s+(?:[0-9]{1,3}\.){3}[0-9]{1,3}
77+
Blocked:\s+no
78+
Home Location:\s+[a-z]{3}[0-9]*
79+
Server:
80+
\s+ID:\s+[0-9]+
81+
\s+Name:\s+test-server-[0-9a-f]{8}
82+
DNS:
83+
.*?
84+
Protection:
85+
\s+Delete:\s+no
86+
Labels:
87+
\s+No labels
88+
`, out)
89+
})
90+
91+
t.Run("list", func(t *testing.T) {
92+
out, err := runCommand(t, "floating-ip", "list", "-o", "columns=server", "-o", "noheader")
93+
require.NoError(t, err)
94+
assert.Equal(t, fmt.Sprintf("%s\n", serverName), out)
95+
})
96+
97+
t.Run("delete", func(t *testing.T) {
98+
out, err := runCommand(t, "floating-ip", "delete", strconv.FormatInt(floatingIP, 10))
99+
require.NoError(t, err)
100+
assert.Equal(t, fmt.Sprintf("Floating IP %d deleted\n", floatingIP), out)
101+
})
102+
})
103+
104+
t.Run("delete-server", func(t *testing.T) {
105+
out, err := runCommand(t, "server", "delete", strconv.FormatInt(serverID, 10))
106+
require.NoError(t, err)
107+
assert.Equal(t, fmt.Sprintf("Server %d deleted\n", serverID), out)
108+
})
109+
}

test/e2e/config.toml

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# config for tests goes here

test/e2e/datacenter_test.go

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
//go:build e2e
2+
3+
package e2e
4+
5+
import (
6+
"encoding/json"
7+
"testing"
8+
9+
"github.com/stretchr/testify/assert"
10+
"github.com/stretchr/testify/require"
11+
)
12+
13+
func TestDatacenter(t *testing.T) {
14+
t.Parallel()
15+
16+
t.Run("list", func(t *testing.T) {
17+
t.Run("table", func(t *testing.T) {
18+
out, err := runCommand(t, "datacenter", "list")
19+
require.NoError(t, err)
20+
assert.Regexp(t, `ID +NAME +DESCRIPTION +LOCATION
21+
([0-9]+ +[a-z0-9\-]+ +[a-zA-Z0-9\- ]+ +[a-z0-9\-]+\n)+`, out)
22+
})
23+
24+
t.Run("json", func(t *testing.T) {
25+
out, err := runCommand(t, "datacenter", "list", "-o=json")
26+
require.NoError(t, err)
27+
require.NoError(t, json.Unmarshal([]byte(out), new([]any)))
28+
})
29+
})
30+
31+
t.Run("describe", func(t *testing.T) {
32+
t.Run("non-existing", func(t *testing.T) {
33+
out, err := runCommand(t, "datacenter", "describe", "123456")
34+
require.EqualError(t, err, "datacenter not found: 123456")
35+
assert.Empty(t, out)
36+
})
37+
38+
t.Run("normal", func(t *testing.T) {
39+
out, err := runCommand(t, "datacenter", "describe", TestDatacenterID)
40+
require.NoError(t, err)
41+
assert.Regexp(t, `ID:\s+[0-9]+
42+
Name:\s+[a-z0-9\-]+
43+
Description:\s+[a-zA-Z0-9\- ]+
44+
Location:
45+
+Name:\s+[a-z0-9]+
46+
+Description:\s+[a-zA-Z0-9\- ]+
47+
+Country:\s+[A-Z]{2}
48+
+City:\s+[A-Za-z]+
49+
+Latitude:\s+[0-9\.]+
50+
+Longitude:\s+[0-9\.]+
51+
Server Types:
52+
(\s+- ID: [0-9]+\s+Name: [a-z0-9]+\s+Supported: (true|false)\s+Available: (true|false))+
53+
`, out)
54+
})
55+
})
56+
}

0 commit comments

Comments
 (0)