Merge branch 'master' into cn
* master: (546 commits) chore(deps): bump gunicorn in /tests/apps/dockerfile-release chore(deps): bump github.com/traefik/traefik/v2 chore(deps): bump gunicorn from 26.0.0 to 26.1.0 in /tests/apps/multi chore(deps): bump gunicorn in /tests/apps/python-flask chore(deps): bump pygments from 2.20.0 to 2.21.0 in /docs/_build chore: bump herokuish to 0.11.16 chore: bump go modules chore(deps): bump golang.org/x/crypto in /plugins/common chore(deps): bump sqlparse in /tests/apps/dockerfile-release chore(deps): bump helm.sh/helm/v3 in /plugins/scheduler-k3s chore(deps): bump golang in /tests/apps/zombies-dockerfile-no-tini chore(deps): bump golang in /tests/apps/go-fail-postdeploy chore(deps): bump golang in /tests/apps/go-fail-predeploy chore(deps): bump golang from 1.26.5 to 1.26.6 in /tests/apps/gogrpc chore(deps): bump golang in /tests/apps/zombies-dockerfile-tini chore(deps): bump google.golang.org/protobuf in /tests/apps/gogrpc fix: retire cron containers past their active deadline Release 0.38.27 fix: report traefik dns-provider env vars as global keys fix: do not require a local image for k3s deploys ... # Conflicts: # common.mk # contrib/dependencies.json
This commit is contained in:
70
tests/apps/checks-root/package-lock.json
generated
70
tests/apps/checks-root/package-lock.json
generated
@@ -28,20 +28,20 @@
|
||||
}
|
||||
},
|
||||
"node_modules/body-parser": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.1.tgz",
|
||||
"integrity": "sha512-nfDwkulwiZYQIGwxdy0RUmowMhKcFVcYXUU7m4QlKYim1rUtg83xm2yjZ40QjDuc291AJjjeSc9b++AWHSgSHw==",
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.3.0.tgz",
|
||||
"integrity": "sha512-2cGmJupaNgg+QUwVLAucDuWuoMZ6EX9iHDRswZ5lsNYEmwPaRknMPCLZz07yTzVq/83p4o/wzbDZbBrTvGGTIw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"bytes": "^3.1.2",
|
||||
"content-type": "^1.0.5",
|
||||
"content-type": "^2.0.0",
|
||||
"debug": "^4.4.3",
|
||||
"http-errors": "^2.0.0",
|
||||
"iconv-lite": "^0.7.0",
|
||||
"http-errors": "^2.0.1",
|
||||
"iconv-lite": "^0.7.2",
|
||||
"on-finished": "^2.4.1",
|
||||
"qs": "^6.14.0",
|
||||
"raw-body": "^3.0.1",
|
||||
"type-is": "^2.0.1"
|
||||
"qs": "^6.15.2",
|
||||
"raw-body": "^3.0.2",
|
||||
"type-is": "^2.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
@@ -51,6 +51,19 @@
|
||||
"url": "https://opencollective.com/express"
|
||||
}
|
||||
},
|
||||
"node_modules/body-parser/node_modules/content-type": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/content-type/-/content-type-2.0.0.tgz",
|
||||
"integrity": "sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/express"
|
||||
}
|
||||
},
|
||||
"node_modules/bytes": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
|
||||
@@ -408,9 +421,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/iconv-lite": {
|
||||
"version": "0.7.0",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.0.tgz",
|
||||
"integrity": "sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==",
|
||||
"version": "0.7.3",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.3.tgz",
|
||||
"integrity": "sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"safer-buffer": ">= 2.1.2 < 3.0.0"
|
||||
@@ -576,9 +589,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/qs": {
|
||||
"version": "6.15.0",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.15.0.tgz",
|
||||
"integrity": "sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ==",
|
||||
"version": "6.15.2",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.15.2.tgz",
|
||||
"integrity": "sha512-Rzq0KEyX/w/tEybncDgdkZrJgVUsUMk3xjh3t5bv3S1HTAtg+uOYt72+ZfwiQwKdysThkTBdL/rTi6HDmX9Ddw==",
|
||||
"license": "BSD-3-Clause",
|
||||
"dependencies": {
|
||||
"side-channel": "^1.1.0"
|
||||
@@ -790,17 +803,34 @@
|
||||
}
|
||||
},
|
||||
"node_modules/type-is": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz",
|
||||
"integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==",
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/type-is/-/type-is-2.1.0.tgz",
|
||||
"integrity": "sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"content-type": "^1.0.5",
|
||||
"content-type": "^2.0.0",
|
||||
"media-typer": "^1.1.0",
|
||||
"mime-types": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
"node": ">= 18"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/express"
|
||||
}
|
||||
},
|
||||
"node_modules/type-is/node_modules/content-type": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/content-type/-/content-type-2.0.0.tgz",
|
||||
"integrity": "sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/express"
|
||||
}
|
||||
},
|
||||
"node_modules/unpipe": {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM node:25-alpine
|
||||
FROM node:26-alpine
|
||||
|
||||
RUN apk add --no-cache bash
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM ruby:4.0.3
|
||||
FROM ruby:4.0.6
|
||||
|
||||
RUN mkdir /app
|
||||
WORKDIR /app
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM node:25-alpine
|
||||
FROM node:26-alpine
|
||||
|
||||
RUN apk add --no-cache bash
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM node:25-alpine
|
||||
FROM node:26-alpine
|
||||
|
||||
RUN apk add --no-cache bash
|
||||
|
||||
|
||||
@@ -5,8 +5,4 @@
|
||||
# Procfile for development using the new threaded worker (scheduler, twitter stream and delayed job)
|
||||
cron: node worker.js
|
||||
web: node web.js
|
||||
<<<<<<< HEAD=0
|
||||
worker: node worker.js
|
||||
========0
|
||||
worker: node worker-2.js
|
||||
>>>>>>> 5bb7ec3e2a8f4f6565432a4fc82c92d4a3603d28=0
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM node:25-alpine
|
||||
FROM node:26-alpine
|
||||
|
||||
RUN apk add --no-cache bash
|
||||
|
||||
|
||||
21
tests/apps/dockerfile-procfile/app-cron-procfile.json
Normal file
21
tests/apps/dockerfile-procfile/app-cron-procfile.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"cron": [
|
||||
{
|
||||
"command": "release",
|
||||
"schedule": "5 5 5 5 5"
|
||||
}
|
||||
],
|
||||
"healthchecks": {
|
||||
"web": [
|
||||
{
|
||||
"attempts": 2,
|
||||
"content": "nodejs/express",
|
||||
"name": "check-1",
|
||||
"path": "/",
|
||||
"timeout": 5,
|
||||
"type": "startup",
|
||||
"wait": 2
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
27
tests/apps/dockerfile-procfile/app-cron.json
Normal file
27
tests/apps/dockerfile-procfile/app-cron.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"cron": [
|
||||
{
|
||||
"command": "echo hello-from-cron",
|
||||
"schedule": "5 5 5 5 5"
|
||||
}
|
||||
],
|
||||
"healthchecks": {
|
||||
"web": [
|
||||
{
|
||||
"attempts": 2,
|
||||
"content": "nodejs/express",
|
||||
"name": "check-1",
|
||||
"path": "/",
|
||||
"timeout": 5,
|
||||
"type": "startup",
|
||||
"wait": 2
|
||||
}
|
||||
]
|
||||
},
|
||||
"scripts": {
|
||||
"dokku": {
|
||||
"postdeploy": "touch /app/postdeploy.test",
|
||||
"predeploy": "touch /app/predeploy.test"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM python:3.14.3-bookworm
|
||||
FROM python:3.15.0rc1-bookworm
|
||||
|
||||
RUN pip install --user pipenv
|
||||
ENV PATH="${PATH}:/root/.local/bin"
|
||||
|
||||
49
tests/apps/dockerfile-release/Pipfile.lock
generated
49
tests/apps/dockerfile-release/Pipfile.lock
generated
@@ -18,11 +18,11 @@
|
||||
"default": {
|
||||
"asgiref": {
|
||||
"hashes": [
|
||||
"sha256:5f184dc43b7e763efe848065441eac62229c9f7b0475f41f80e207a114eda4ce",
|
||||
"sha256:e8667a091e69529631969fd45dc268fa79b99c92c5fcdda727757e52146ec133"
|
||||
"sha256:59dcb51c272ad209d59bed5708a64a333083e86017d7fcdd67498eeab7784340",
|
||||
"sha256:fe386d1c2bff7259ea95929266d12a8cf9a8b5a1c2598402967d8792e7a7c094"
|
||||
],
|
||||
"markers": "python_version >= '3.9'",
|
||||
"version": "==3.11.1"
|
||||
"markers": "python_version >= '3.10'",
|
||||
"version": "==3.12.1"
|
||||
},
|
||||
"dj-database-url": {
|
||||
"hashes": [
|
||||
@@ -35,38 +35,38 @@
|
||||
},
|
||||
"django": {
|
||||
"hashes": [
|
||||
"sha256:5788fce61da23788a8ce6f02583765ab060d396720924789f97fa42119d37f7a",
|
||||
"sha256:a31589db5188d074c63f0945c3888fad104627dfcc236fb2b97f71f89da33bc4"
|
||||
"sha256:9d4d93be539a18ab80d058eb515900e10951e04c537c5a6b394fc49528d3251f",
|
||||
"sha256:f04fb3b36ee119e1af4fa1d397d5fd6cf12700f49321e84d4f4c642c5b1973db"
|
||||
],
|
||||
"index": "pypi",
|
||||
"markers": "python_version >= '3.10'",
|
||||
"version": "==5.2.13"
|
||||
"version": "==5.2.17"
|
||||
},
|
||||
"djangorestframework": {
|
||||
"hashes": [
|
||||
"sha256:a6def5f447fe78ff853bff1d47a3c59bf38f5434b031780b351b0c73a62db1a5",
|
||||
"sha256:c3c74dd3e83a5a3efc37b3c18d92bd6f86a6791c7b7d4dff62bb068500e76457"
|
||||
"sha256:2323a5111837e0b784dcb8323abc78ecc54fa2a5af7aff2677cf50cdd849477f",
|
||||
"sha256:381fc44d3249c9565c5f723850855b734e99030eb30957a49f506d3fe11d7dcb"
|
||||
],
|
||||
"index": "pypi",
|
||||
"markers": "python_version >= '3.10'",
|
||||
"version": "==3.17.1"
|
||||
"version": "==3.18.0"
|
||||
},
|
||||
"gunicorn": {
|
||||
"hashes": [
|
||||
"sha256:cacea387dab08cd6776501621c295a904fe8e3b7aae9a1a3cbb26f4e7ed54660",
|
||||
"sha256:f74e1b2f9f76f6cd1ca01198968bd2dd65830edc24b6e8e4d78de8320e2fe889"
|
||||
"sha256:1413d777bf99d31ebeb08acd354b01f1ecc44db0aa7b811ae7b86c669232e4f7",
|
||||
"sha256:9f45bcddec5e9dc7a25a3bdccb0c6832f11fd5d4739b1ee36c8d2fec25f1dc86"
|
||||
],
|
||||
"index": "pypi",
|
||||
"markers": "python_version >= '3.10'",
|
||||
"version": "==25.3.0"
|
||||
"version": "==26.1.0"
|
||||
},
|
||||
"packaging": {
|
||||
"hashes": [
|
||||
"sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4",
|
||||
"sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529"
|
||||
"sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e",
|
||||
"sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661"
|
||||
],
|
||||
"markers": "python_version >= '3.8'",
|
||||
"version": "==26.0"
|
||||
"version": "==26.2"
|
||||
},
|
||||
"psycopg2-binary": {
|
||||
"hashes": [
|
||||
@@ -151,20 +151,21 @@
|
||||
},
|
||||
"setuptools": {
|
||||
"hashes": [
|
||||
"sha256:c3a9c4211ff4c309edb8b8c4f1cbfa7ae324c4ba9f91ff254e3d305b9fd54561",
|
||||
"sha256:fcc17fd9cd898242f6b4adfaca46137a9edef687f43e6f78469692a5e70d851d"
|
||||
"sha256:025bccbbf0fa05b6192bc64ae1e7b16e001fd6d6d4d5de03c97b1c1ade523bef",
|
||||
"sha256:29b23c360f22f414dc7336bb39178cc7bcbf6021ed2733cde173f09dba19abb3"
|
||||
],
|
||||
"index": "pypi",
|
||||
"markers": "python_version >= '3.9'",
|
||||
"version": "==78.1.1"
|
||||
"markers": "python_version >= '3.10'",
|
||||
"version": "==83.0.0"
|
||||
},
|
||||
"sqlparse": {
|
||||
"hashes": [
|
||||
"sha256:12a08b3bf3eec877c519589833aed092e2444e68240a3577e8e26148acc7b1ba",
|
||||
"sha256:e20d4a9b0b8585fdf63b10d30066c7c94c5d7a7ec47c889a2d83a3caa93ff28e"
|
||||
"sha256:113c35c75365ab9cc9c7231d68c6428fb11c085fc8e9eb1ad659b7ddbf6cd2b9",
|
||||
"sha256:b861c0288ce2fa56209a9a6412d2e066ac664b3873b89c26c9d8415e8e32996f"
|
||||
],
|
||||
"markers": "python_version >= '3.8'",
|
||||
"version": "==0.5.5"
|
||||
"index": "pypi",
|
||||
"markers": "python_version >= '3.10'",
|
||||
"version": "==0.6.0"
|
||||
},
|
||||
"whitenoise": {
|
||||
"hashes": [
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM node:25-alpine
|
||||
FROM node:26-alpine
|
||||
|
||||
RUN apk add --no-cache bash
|
||||
|
||||
|
||||
@@ -3,11 +3,6 @@
|
||||
"dokku-postgres",
|
||||
"dokku-redis"
|
||||
],
|
||||
"buildpacks": [
|
||||
{
|
||||
"url": "https://github.com/heroku/heroku-buildpack-nodejs"
|
||||
}
|
||||
],
|
||||
"description": "Used in dokku's test suite",
|
||||
"env": {
|
||||
"SECRET_TOKEN": {
|
||||
@@ -16,7 +11,7 @@
|
||||
},
|
||||
"WEB_CONCURRENCY": {
|
||||
"description": "The number of processes to run.",
|
||||
"generator": "echo 5"
|
||||
"value": "5"
|
||||
}
|
||||
},
|
||||
"healthchecks": {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM node:25-alpine
|
||||
FROM node:26-alpine
|
||||
|
||||
RUN apk add --no-cache bash
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM golang:1.26.2
|
||||
FROM golang:1.26.6
|
||||
|
||||
EXPOSE 3000/tcp
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM golang:1.26.2
|
||||
FROM golang:1.26.6
|
||||
|
||||
EXPOSE 3000/tcp
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM golang:1.26.2
|
||||
FROM golang:1.26.6
|
||||
|
||||
RUN mkdir /app
|
||||
WORKDIR /app
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
module github.com/dokku/dokko/tests/apps/gorpc
|
||||
|
||||
go 1.25.5
|
||||
go 1.26.2
|
||||
|
||||
require (
|
||||
golang.org/x/net v0.49.0 // indirect
|
||||
golang.org/x/sys v0.40.0 // indirect
|
||||
golang.org/x/text v0.33.0 // indirect
|
||||
google.golang.org/grpc v1.80.0
|
||||
golang.org/x/net v0.55.0 // indirect
|
||||
golang.org/x/sys v0.45.0 // indirect
|
||||
golang.org/x/text v0.37.0 // indirect
|
||||
google.golang.org/grpc v1.83.0
|
||||
)
|
||||
|
||||
require (
|
||||
google.golang.org/grpc/examples v0.0.0-20240118175532-987df1309236
|
||||
google.golang.org/protobuf v1.36.11
|
||||
google.golang.org/protobuf v1.36.12
|
||||
)
|
||||
|
||||
require google.golang.org/genproto/googleapis/rpc v0.0.0-20260120221211-b8f7ae30c516 // indirect
|
||||
require google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa // indirect
|
||||
|
||||
@@ -12,29 +12,29 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
|
||||
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
|
||||
go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48=
|
||||
go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8=
|
||||
go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0=
|
||||
go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs=
|
||||
go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18=
|
||||
go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew=
|
||||
go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI=
|
||||
go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA=
|
||||
golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o=
|
||||
golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8=
|
||||
golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=
|
||||
golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE=
|
||||
golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8=
|
||||
go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU=
|
||||
go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc=
|
||||
go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc=
|
||||
go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo=
|
||||
go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58=
|
||||
go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA=
|
||||
go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk=
|
||||
go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE=
|
||||
golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8=
|
||||
golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww=
|
||||
golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY=
|
||||
golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
||||
golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc=
|
||||
golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38=
|
||||
gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4=
|
||||
gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260120221211-b8f7ae30c516 h1:sNrWoksmOyF5bvJUcnmbeAmQi8baNhqg5IWaI3llQqU=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260120221211-b8f7ae30c516/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ=
|
||||
google.golang.org/grpc v1.80.0 h1:Xr6m2WmWZLETvUNvIUmeD5OAagMw3FiKmMlTdViWsHM=
|
||||
google.golang.org/grpc v1.80.0/go.mod h1:ho/dLnxwi3EDJA4Zghp7k2Ec1+c2jqup0bFkw07bwF4=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa h1:mZHHdPZl0dbGHCflZgAq/Q468DWVFcU2whhB2KAo8fk=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
|
||||
google.golang.org/grpc v1.83.0 h1:JeNZEKJFbQxArAMl+hiytHauacDNqJUllNfmIMmpqnQ=
|
||||
google.golang.org/grpc v1.83.0/go.mod h1:kDyl6SKsiHKt0uylY5gtn5cEjkrIOhQOGDgIc4JGwzQ=
|
||||
google.golang.org/grpc/examples v0.0.0-20240118175532-987df1309236 h1:wTUkwrodi4IuWD3kYkMUwCU8BhwFaqDywrXmsthCvQA=
|
||||
google.golang.org/grpc/examples v0.0.0-20240118175532-987df1309236/go.mod h1:j5uROIAAgi3YmtiETMt1LW0d/lHqQ7wwrIY4uGRXLQ4=
|
||||
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
|
||||
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||
google.golang.org/protobuf v1.36.12 h1:pJOKDDOyeXErUroCihFAd5LQuwXBSpVnKGrj5o/fwxc=
|
||||
google.golang.org/protobuf v1.36.12/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-dependency-plugin</artifactId>
|
||||
<version>3.10.0</version>
|
||||
<version>3.11.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>copy-dependencies</id>
|
||||
|
||||
54
tests/apps/multi/package-lock.json
generated
54
tests/apps/multi/package-lock.json
generated
@@ -11,7 +11,7 @@
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"bootstrap": "^5.3.8",
|
||||
"sass": "^1.99.0"
|
||||
"sass": "^1.102.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "24.x.x",
|
||||
@@ -141,9 +141,6 @@
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -164,9 +161,6 @@
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -187,9 +181,6 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -210,9 +201,6 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -233,9 +221,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -256,9 +241,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -363,15 +345,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/chokidar": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
|
||||
"integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz",
|
||||
"integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"readdirp": "^4.0.1"
|
||||
"readdirp": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 14.16.0"
|
||||
"node": ">= 20.19.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
@@ -388,9 +370,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/immutable": {
|
||||
"version": "5.1.5",
|
||||
"resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.5.tgz",
|
||||
"integrity": "sha512-t7xcm2siw+hlUM68I+UEOK+z84RzmN59as9DZ7P1l0994DKUWV7UXBMQZVxaoMSRQ+PBZbHCOoBt7a2wxOMt+A==",
|
||||
"version": "5.1.9",
|
||||
"resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.9.tgz",
|
||||
"integrity": "sha512-m8nVez3rwrgmWxtLMt1ZYXB2Lv7OKYn/disyxAlSDYAlKSlFoPPfIAmAM/M5xqL4m4C/wAPw7S2/CNaUii1Hxg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/is-extglob": {
|
||||
@@ -437,12 +419,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/readdirp": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz",
|
||||
"integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==",
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.0.0.tgz",
|
||||
"integrity": "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 14.18.0"
|
||||
"node": ">= 20.19.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "individual",
|
||||
@@ -450,12 +432,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/sass": {
|
||||
"version": "1.99.0",
|
||||
"resolved": "https://registry.npmjs.org/sass/-/sass-1.99.0.tgz",
|
||||
"integrity": "sha512-kgW13M54DUB7IsIRM5LvJkNlpH+WhMpooUcaWGFARkF1Tc82v9mIWkCbCYf+MBvpIUBSeSOTilpZjEPr2VYE6Q==",
|
||||
"version": "1.102.0",
|
||||
"resolved": "https://registry.npmjs.org/sass/-/sass-1.102.0.tgz",
|
||||
"integrity": "sha512-NSOyTnaQF7rTAEOtI2fwb386vL+akyiQLBZu8Na7hXCb+umJy0GAqlcMIaqACZ6Z1VgTBS4K9PG6B3IdjHGJsw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"chokidar": "^4.0.0",
|
||||
"chokidar": "^5.0.0",
|
||||
"immutable": "^5.1.5",
|
||||
"source-map-js": ">=0.6.2 <2.0.0"
|
||||
},
|
||||
@@ -463,7 +445,7 @@
|
||||
"sass": "sass.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
"node": ">=20.19.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@parcel/watcher": "^2.4.1"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"author": "Al Johri",
|
||||
"dependencies": {
|
||||
"bootstrap": "^5.3.8",
|
||||
"sass": "^1.99.0"
|
||||
"sass": "^1.102.0"
|
||||
},
|
||||
"description": "Test application for heroku multi buildpack.",
|
||||
"engines": {
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
Flask==3.1.3
|
||||
gunicorn==25.3.0
|
||||
gunicorn==26.1.0
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
},
|
||||
"WEB_CONCURRENCY": {
|
||||
"description": "The number of processes to run.",
|
||||
"generator": "echo 5"
|
||||
"value": "5"
|
||||
}
|
||||
},
|
||||
"healthchecks": {
|
||||
|
||||
22
tests/apps/php/composer.lock
generated
22
tests/apps/php/composer.lock
generated
@@ -485,16 +485,16 @@
|
||||
},
|
||||
{
|
||||
"name": "slim/slim",
|
||||
"version": "4.15.1",
|
||||
"version": "4.15.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/slimphp/Slim.git",
|
||||
"reference": "887893516557506f254d950425ce7f5387a26970"
|
||||
"reference": "e12cb05ca2a14e8f459d019e87a31dc915b80470"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/slimphp/Slim/zipball/887893516557506f254d950425ce7f5387a26970",
|
||||
"reference": "887893516557506f254d950425ce7f5387a26970",
|
||||
"url": "https://api.github.com/repos/slimphp/Slim/zipball/e12cb05ca2a14e8f459d019e87a31dc915b80470",
|
||||
"reference": "e12cb05ca2a14e8f459d019e87a31dc915b80470",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -597,22 +597,22 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-11-21T12:23:44+00:00"
|
||||
"time": "2026-05-22T08:00:12+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [
|
||||
{
|
||||
"name": "heroku/heroku-buildpack-php",
|
||||
"version": "v287",
|
||||
"version": "v294",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/heroku/heroku-buildpack-php.git",
|
||||
"reference": "4f53d131bd04d41a1c6ab861d74fd1a16dbbf2cb"
|
||||
"reference": "2a8f9567a34acc79b6ebc1118196cfeda031ca2a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/heroku/heroku-buildpack-php/zipball/4f53d131bd04d41a1c6ab861d74fd1a16dbbf2cb",
|
||||
"reference": "4f53d131bd04d41a1c6ab861d74fd1a16dbbf2cb",
|
||||
"url": "https://api.github.com/repos/heroku/heroku-buildpack-php/zipball/2a8f9567a34acc79b6ebc1118196cfeda031ca2a",
|
||||
"reference": "2a8f9567a34acc79b6ebc1118196cfeda031ca2a",
|
||||
"shasum": ""
|
||||
},
|
||||
"bin": [
|
||||
@@ -642,9 +642,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/heroku/heroku-buildpack-php/issues",
|
||||
"source": "https://github.com/heroku/heroku-buildpack-php/tree/v287"
|
||||
"source": "https://github.com/heroku/heroku-buildpack-php/tree/v294"
|
||||
},
|
||||
"time": "2026-04-17T14:51:42+00:00"
|
||||
"time": "2026-07-31T14:30:30+00:00"
|
||||
}
|
||||
],
|
||||
"aliases": [],
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
Flask==3.1.3
|
||||
Jinja2==3.1.6
|
||||
Werkzeug==3.1.8
|
||||
gunicorn==25.3.0
|
||||
gunicorn==26.1.0
|
||||
|
||||
|
||||
21
tests/apps/python/app-cnb-cron-procfile.json
Normal file
21
tests/apps/python/app-cnb-cron-procfile.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"cron": [
|
||||
{
|
||||
"command": "task",
|
||||
"schedule": "5 5 5 5 5"
|
||||
}
|
||||
],
|
||||
"healthchecks": {
|
||||
"web": [
|
||||
{
|
||||
"attempts": 2,
|
||||
"content": "python/http.server",
|
||||
"name": "check-1",
|
||||
"path": "/",
|
||||
"timeout": 5,
|
||||
"type": "startup",
|
||||
"wait": 2
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
21
tests/apps/python/app-cron-procfile.json
Normal file
21
tests/apps/python/app-cron-procfile.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"cron": [
|
||||
{
|
||||
"command": "task",
|
||||
"schedule": "5 5 5 5 5"
|
||||
}
|
||||
],
|
||||
"healthchecks": {
|
||||
"web": [
|
||||
{
|
||||
"attempts": 2,
|
||||
"content": "python/http.server",
|
||||
"name": "check-1",
|
||||
"path": "/",
|
||||
"timeout": 5,
|
||||
"type": "startup",
|
||||
"wait": 2
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
8
tests/apps/python/app-env-required.json
Normal file
8
tests/apps/python/app-env-required.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"env": {
|
||||
"REQUIRED_VAR": {
|
||||
"description": "A required variable with no default",
|
||||
"required": true
|
||||
}
|
||||
}
|
||||
}
|
||||
27
tests/apps/python/app-env.json
Normal file
27
tests/apps/python/app-env.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"env": {
|
||||
"SIMPLE_VAR": "simple_value",
|
||||
"OBJECT_VAR": {
|
||||
"description": "A variable with a default value",
|
||||
"value": "object_default"
|
||||
},
|
||||
"SECRET_VAR": {
|
||||
"description": "A generated secret",
|
||||
"generator": "secret"
|
||||
},
|
||||
"OPTIONAL_VAR": {
|
||||
"description": "An optional variable",
|
||||
"required": false
|
||||
},
|
||||
"SYNC_VAR": {
|
||||
"description": "A variable that syncs on every deploy",
|
||||
"value": "sync_value",
|
||||
"sync": true
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"dokku": {
|
||||
"predeploy": "echo ENV_CHECK: SIMPLE_VAR=$SIMPLE_VAR OBJECT_VAR=$OBJECT_VAR"
|
||||
}
|
||||
}
|
||||
}
|
||||
16
tests/apps/python/cron_task.py
Normal file
16
tests/apps/python/cron_task.py
Normal file
@@ -0,0 +1,16 @@
|
||||
import sys
|
||||
import time
|
||||
|
||||
|
||||
def main(args):
|
||||
# a log shipper attaches to a container after it receives the start event,
|
||||
# and a cron container is removed the moment it exits. sleep on either side
|
||||
# of the output so that the shipper has time to attach before the line is
|
||||
# written and time to read it before the container is gone.
|
||||
time.sleep(5)
|
||||
print(' '.join(args[1:]), flush=True)
|
||||
time.sleep(3)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main(sys.argv)
|
||||
@@ -1,3 +1,3 @@
|
||||
module dokku.me/web
|
||||
|
||||
go 1.25.5
|
||||
go 1.26.2
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM golang:1.26.2
|
||||
FROM golang:1.26.6
|
||||
|
||||
ADD . /go/src/github.com/dokku/apps/web
|
||||
WORKDIR /go/src/github.com/dokku/apps/web
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
module dokku.me/web
|
||||
|
||||
go 1.25.5
|
||||
go 1.26.2
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM golang:1.26.2
|
||||
FROM golang:1.26.6
|
||||
|
||||
ADD . /go/src/github.com/dokku/apps/web
|
||||
WORKDIR /go/src/github.com/dokku/apps/web
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
module dokku.me/web
|
||||
|
||||
go 1.25.5
|
||||
go 1.26.2
|
||||
|
||||
128
tests/image/healthcheck.sh
Executable file
128
tests/image/healthcheck.sh
Executable file
@@ -0,0 +1,128 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
IMAGE_TAG="${IMAGE_TAG:-dokku/dokku:latest}"
|
||||
CONTAINER_NAME="${CONTAINER_NAME:-dokku-healthcheck-smoke}"
|
||||
START_TIMEOUT_SECONDS="${START_TIMEOUT_SECONDS:-360}"
|
||||
UNHEALTHY_TIMEOUT_SECONDS="${UNHEALTHY_TIMEOUT_SECONDS:-180}"
|
||||
|
||||
log-info() {
|
||||
echo "-----> $*"
|
||||
}
|
||||
|
||||
log-fail() {
|
||||
echo " ! $*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
docker rm -f "$CONTAINER_NAME" >/dev/null 2>&1 || true
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
require-image() {
|
||||
if ! docker image inspect "$IMAGE_TAG" >/dev/null 2>&1; then
|
||||
log-fail "Image '$IMAGE_TAG' not found in local docker daemon. Build it first (eg. 'docker build -t $IMAGE_TAG .')."
|
||||
fi
|
||||
}
|
||||
|
||||
start-container() {
|
||||
log-info "Starting container '$CONTAINER_NAME' from image '$IMAGE_TAG'"
|
||||
docker rm -f "$CONTAINER_NAME" >/dev/null 2>&1 || true
|
||||
docker run -d \
|
||||
--name "$CONTAINER_NAME" \
|
||||
--env DOKKU_HOSTNAME=dokku.me \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||
"$IMAGE_TAG" >/dev/null
|
||||
}
|
||||
|
||||
wait-for-catchall-vhost() {
|
||||
local deadline=$((SECONDS + 30))
|
||||
while ((SECONDS < deadline)); do
|
||||
if docker exec "$CONTAINER_NAME" test -f /etc/nginx/conf.d/00-default-vhost.conf; then
|
||||
return 0
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
|
||||
log-fail "Catch-all default vhost /etc/nginx/conf.d/00-default-vhost.conf was never created. \
|
||||
Likely cause: a stale build/package/dokku-*.deb that predates the catch-all template shipped in \
|
||||
plugins/nginx-vhosts/templates/default-site.conf. Rebuild the deb before running this test."
|
||||
}
|
||||
|
||||
wait-for-healthy() {
|
||||
local deadline=$((SECONDS + START_TIMEOUT_SECONDS))
|
||||
local status
|
||||
while ((SECONDS < deadline)); do
|
||||
status=$(docker inspect --format='{{.State.Health.Status}}' "$CONTAINER_NAME" 2>/dev/null || echo "missing")
|
||||
if [[ "$status" == "healthy" ]]; then
|
||||
log-info "Container reached healthy status"
|
||||
return 0
|
||||
fi
|
||||
sleep 5
|
||||
done
|
||||
|
||||
log-info "Container failed to become healthy within ${START_TIMEOUT_SECONDS}s. Last logs:"
|
||||
docker logs --tail 100 "$CONTAINER_NAME" || true
|
||||
log-fail "Container '$CONTAINER_NAME' did not reach healthy status (last status: ${status:-unknown})"
|
||||
}
|
||||
|
||||
assert-endpoint-ok() {
|
||||
log-info "Verifying /_dokku/health returns ok from inside the container"
|
||||
local body
|
||||
body=$(docker exec "$CONTAINER_NAME" curl -fsS http://127.0.0.1:18080/_dokku/health)
|
||||
if [[ "$body" != "ok" ]]; then
|
||||
log-fail "Expected health endpoint body 'ok', got: ${body}"
|
||||
fi
|
||||
}
|
||||
|
||||
assert-port-not-published() {
|
||||
log-info "Verifying port 18080 is not published to the host"
|
||||
local ports
|
||||
ports=$(docker inspect --format='{{json .NetworkSettings.Ports}}' "$CONTAINER_NAME")
|
||||
if echo "$ports" | grep -q "18080/tcp"; then
|
||||
log-fail "Port 18080/tcp should not be published to the host. Inspect output: $ports"
|
||||
fi
|
||||
|
||||
if curl --max-time 2 -fsS http://127.0.0.1:18080/_dokku/health >/dev/null 2>&1; then
|
||||
log-fail "Health endpoint is reachable from the host on 127.0.0.1:18080 - it must be loopback-only inside the container."
|
||||
fi
|
||||
}
|
||||
|
||||
assert-unhealthy-after-sentinel-removed() {
|
||||
log-info "Removing /var/run/dokku/ready and confirming endpoint returns failure"
|
||||
docker exec "$CONTAINER_NAME" rm -f /var/run/dokku/ready
|
||||
|
||||
local exit_code=0
|
||||
docker exec "$CONTAINER_NAME" curl -fsS http://127.0.0.1:18080/_dokku/health >/dev/null 2>&1 || exit_code=$?
|
||||
if ((exit_code == 0)); then
|
||||
log-fail "Health endpoint still returned success after the readiness sentinel was removed"
|
||||
fi
|
||||
|
||||
log-info "Waiting for docker to flip the health status to unhealthy"
|
||||
local deadline=$((SECONDS + UNHEALTHY_TIMEOUT_SECONDS))
|
||||
local status
|
||||
while ((SECONDS < deadline)); do
|
||||
status=$(docker inspect --format='{{.State.Health.Status}}' "$CONTAINER_NAME" 2>/dev/null || echo "missing")
|
||||
if [[ "$status" == "unhealthy" ]]; then
|
||||
log-info "Container flipped to unhealthy"
|
||||
return 0
|
||||
fi
|
||||
sleep 5
|
||||
done
|
||||
|
||||
log-fail "Container did not flip to unhealthy within ${UNHEALTHY_TIMEOUT_SECONDS}s (last status: ${status:-unknown})"
|
||||
}
|
||||
|
||||
main() {
|
||||
require-image
|
||||
start-container
|
||||
wait-for-catchall-vhost
|
||||
wait-for-healthy
|
||||
assert-endpoint-ok
|
||||
assert-port-not-published
|
||||
assert-unhealthy-after-sentinel-removed
|
||||
log-info "All healthcheck smoke tests passed."
|
||||
}
|
||||
|
||||
main "$@"
|
||||
198
tests/unit/app-json-5.bats
Normal file
198
tests/unit/app-json-5.bats
Normal file
@@ -0,0 +1,198 @@
|
||||
#!/usr/bin/env bats
|
||||
load test_helper
|
||||
|
||||
setup() {
|
||||
global_setup
|
||||
create_app
|
||||
}
|
||||
|
||||
teardown() {
|
||||
destroy_app
|
||||
global_teardown
|
||||
}
|
||||
|
||||
@test "(app-json) app.json env simple value" {
|
||||
run /bin/bash -c "dokku app-json:set $TEST_APP appjson-path app-env.json"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run deploy_app python dokku@$DOKKU_DOMAIN:$TEST_APP
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "Processing app.json env vars"
|
||||
assert_output_contains "Setting 4 env var(s) from app.json"
|
||||
|
||||
run /bin/bash -c "dokku config:get $TEST_APP SIMPLE_VAR"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "simple_value"
|
||||
|
||||
run /bin/bash -c "dokku config:get $TEST_APP OBJECT_VAR"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "object_default"
|
||||
}
|
||||
|
||||
@test "(app-json) app.json env secret generator" {
|
||||
run /bin/bash -c "dokku app-json:set $TEST_APP appjson-path app-env.json"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run deploy_app python dokku@$DOKKU_DOMAIN:$TEST_APP
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku config:get $TEST_APP SECRET_VAR"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
# Secret should be 64 characters (hex encoded 32 bytes)
|
||||
[[ ${#output} -eq 64 ]]
|
||||
}
|
||||
|
||||
@test "(app-json) app.json env does not overwrite on redeploy" {
|
||||
run /bin/bash -c "dokku app-json:set $TEST_APP appjson-path app-env.json"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run deploy_app python dokku@$DOKKU_DOMAIN:$TEST_APP
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
# Get the original secret
|
||||
run /bin/bash -c "dokku config:get $TEST_APP SECRET_VAR"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
local original_secret="$output"
|
||||
|
||||
# Change SIMPLE_VAR manually
|
||||
run /bin/bash -c "dokku config:set --no-restart $TEST_APP SIMPLE_VAR=changed_value"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
# Rebuild the app
|
||||
run /bin/bash -c "dokku ps:rebuild $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
# Verify SIMPLE_VAR was NOT overwritten
|
||||
run /bin/bash -c "dokku config:get $TEST_APP SIMPLE_VAR"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "changed_value"
|
||||
|
||||
# Verify SECRET_VAR was NOT regenerated
|
||||
run /bin/bash -c "dokku config:get $TEST_APP SECRET_VAR"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "$original_secret"
|
||||
}
|
||||
|
||||
@test "(app-json) app.json env sync overwrites on redeploy" {
|
||||
run /bin/bash -c "dokku app-json:set $TEST_APP appjson-path app-env.json"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run deploy_app python dokku@$DOKKU_DOMAIN:$TEST_APP
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
# Verify SYNC_VAR is set
|
||||
run /bin/bash -c "dokku config:get $TEST_APP SYNC_VAR"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "sync_value"
|
||||
|
||||
# Change SYNC_VAR manually
|
||||
run /bin/bash -c "dokku config:set --no-restart $TEST_APP SYNC_VAR=manual_value"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
# Rebuild the app
|
||||
run /bin/bash -c "dokku ps:rebuild $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
# Verify SYNC_VAR WAS overwritten back to sync_value
|
||||
run /bin/bash -c "dokku config:get $TEST_APP SYNC_VAR"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "sync_value"
|
||||
}
|
||||
|
||||
@test "(app-json) app.json env required without value fails" {
|
||||
run /bin/bash -c "dokku app-json:set $TEST_APP appjson-path app-env-required.json"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run deploy_app python dokku@$DOKKU_DOMAIN:$TEST_APP
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output_contains "required env var REQUIRED_VAR has no value"
|
||||
}
|
||||
|
||||
@test "(app-json) app.json env skips optional without value" {
|
||||
run /bin/bash -c "dokku app-json:set $TEST_APP appjson-path app-env.json"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run deploy_app python dokku@$DOKKU_DOMAIN:$TEST_APP
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
# OPTIONAL_VAR should not be set since it has no default and is optional
|
||||
# config:get returns exit code 1 when a variable is not set
|
||||
run /bin/bash -c "dokku config:get $TEST_APP OPTIONAL_VAR"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output ""
|
||||
}
|
||||
|
||||
@test "(app-json) app.json env respects pre-set values on first deploy" {
|
||||
run /bin/bash -c "dokku app-json:set $TEST_APP appjson-path app-env.json"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
# Pre-set SIMPLE_VAR before first deploy
|
||||
run /bin/bash -c "dokku config:set --no-restart $TEST_APP SIMPLE_VAR=preset_value"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run deploy_app python dokku@$DOKKU_DOMAIN:$TEST_APP
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
# Verify SIMPLE_VAR was NOT overwritten
|
||||
run /bin/bash -c "dokku config:get $TEST_APP SIMPLE_VAR"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "preset_value"
|
||||
}
|
||||
@@ -139,7 +139,7 @@ teardown() {
|
||||
assert_success
|
||||
fi
|
||||
|
||||
run /bin/bash -c "dokku config:set $TEST_APP SECRET_KEY_BASE=derp OTP_SECRET=1234"
|
||||
run /bin/bash -c "dokku config:set $TEST_APP SECRET_KEY_BASE=derp OTP_SECRET=1234 LOCAL_DOMAIN=dokku.me"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
@@ -256,6 +256,115 @@ teardown() {
|
||||
assert_output_contains "touch /app/predeploy3.test"
|
||||
}
|
||||
|
||||
@test "(app-json:report) appjson-path round-trip" {
|
||||
run /bin/bash -c "dokku app-json:set $TEST_APP appjson-path app2.json"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku app-json:report $TEST_APP --app-json-appjson-path"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "app2.json"
|
||||
|
||||
run /bin/bash -c "dokku app-json:report $TEST_APP --app-json-computed-appjson-path"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "app2.json"
|
||||
|
||||
run /bin/bash -c "dokku app-json:report $TEST_APP --app-json-global-appjson-path"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku app-json:report $TEST_APP --format json"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains '"app-json-appjson-path":"app2.json"'
|
||||
assert_output_contains '"app-json-computed-appjson-path":"app2.json"'
|
||||
assert_output_contains '"app-json-global-appjson-path":""'
|
||||
assert_output_contains '"appjson-path":"app2.json"'
|
||||
assert_output_contains '"computed-appjson-path":"app2.json"'
|
||||
assert_output_contains '"global-appjson-path":""'
|
||||
assert_output_contains "app-json-selected" 0
|
||||
|
||||
run /bin/bash -c "dokku app-json:report $TEST_APP --app-json-selected"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output_contains "Invalid flag passed"
|
||||
|
||||
run /bin/bash -c "dokku app-json:set $TEST_APP appjson-path"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku app-json:report $TEST_APP --app-json-appjson-path"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku app-json:report $TEST_APP --app-json-computed-appjson-path"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "app.json"
|
||||
}
|
||||
|
||||
@test "(app-json:report) appjson-path raw vs computed vs global" {
|
||||
run /bin/bash -c "dokku app-json:set --global appjson-path"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku app-json:report $TEST_APP --app-json-appjson-path"
|
||||
assert_success
|
||||
assert_output_not_exists
|
||||
|
||||
run /bin/bash -c "dokku app-json:report $TEST_APP --app-json-global-appjson-path"
|
||||
assert_success
|
||||
assert_output_not_exists
|
||||
|
||||
run /bin/bash -c "dokku app-json:report $TEST_APP --app-json-computed-appjson-path"
|
||||
assert_success
|
||||
assert_output "app.json"
|
||||
|
||||
run /bin/bash -c "dokku app-json:set --global appjson-path app.global.json"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku app-json:report $TEST_APP --app-json-global-appjson-path"
|
||||
assert_success
|
||||
assert_output "app.global.json"
|
||||
|
||||
run /bin/bash -c "dokku app-json:report $TEST_APP --app-json-computed-appjson-path"
|
||||
assert_success
|
||||
assert_output "app.global.json"
|
||||
|
||||
run /bin/bash -c "dokku app-json:set $TEST_APP appjson-path app.app.json"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku app-json:report $TEST_APP --app-json-appjson-path"
|
||||
assert_success
|
||||
assert_output "app.app.json"
|
||||
|
||||
run /bin/bash -c "dokku app-json:report $TEST_APP --app-json-global-appjson-path"
|
||||
assert_success
|
||||
assert_output "app.global.json"
|
||||
|
||||
run /bin/bash -c "dokku app-json:report $TEST_APP --app-json-computed-appjson-path"
|
||||
assert_success
|
||||
assert_output "app.app.json"
|
||||
|
||||
run /bin/bash -c "dokku app-json:set $TEST_APP appjson-path"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku app-json:set --global appjson-path"
|
||||
assert_success
|
||||
}
|
||||
|
||||
copy_app_json_to_sub_app() {
|
||||
local APP="$1"
|
||||
local APP_REPO_DIR="$2"
|
||||
|
||||
@@ -50,6 +50,36 @@ teardown() {
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(apps) apps:list --format json" {
|
||||
run /bin/bash -c "dokku apps:list --format json"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "[]"
|
||||
|
||||
run /bin/bash -c "dokku apps:create $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku apps:list --format json | jq '. | length'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "1"
|
||||
|
||||
run /bin/bash -c "dokku apps:list --format json | jq -r '.[0]'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "$TEST_APP"
|
||||
|
||||
run /bin/bash -c "dokku --force apps:destroy $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(apps) apps:create" {
|
||||
run /bin/bash -c "dokku apps:create $TEST_APP"
|
||||
echo "output: $output"
|
||||
@@ -96,6 +126,26 @@ teardown() {
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
|
||||
run /bin/bash -c "dokku apps:create 'test;id'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
|
||||
run /bin/bash -c "dokku apps:create 'test\$cmd'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
|
||||
run /bin/bash -c "dokku apps:create 'test|cmd'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
|
||||
run /bin/bash -c "dokku apps:create 'test&cmd'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
|
||||
run /bin/bash -c "dokku --app $TEST_APP apps:create"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
@@ -113,7 +163,7 @@ teardown() {
|
||||
}
|
||||
|
||||
@test "(apps) app autocreate disabled" {
|
||||
run /bin/bash -c "dokku config:set --no-restart --global DOKKU_DISABLE_APP_AUTOCREATION='true'"
|
||||
run /bin/bash -c "dokku apps:set --global disable-autocreation true"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
@@ -122,7 +172,7 @@ teardown() {
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
run /bin/bash -c "dokku config:unset --no-restart --global DOKKU_DISABLE_APP_AUTOCREATION"
|
||||
run /bin/bash -c "dokku apps:set --global disable-autocreation"
|
||||
}
|
||||
|
||||
@test "(apps) apps:destroy" {
|
||||
@@ -156,7 +206,7 @@ teardown() {
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "git-hook $TEST_APP"
|
||||
assert_output_contains "git-hook \"$TEST_APP\""
|
||||
run /bin/bash -c "dokku apps:rename $TEST_APP great-test-name"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
@@ -165,7 +215,7 @@ teardown() {
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "git-hook great-test-name"
|
||||
assert_output_contains "git-hook \"great-test-name\""
|
||||
run /bin/bash -c "dokku apps:list | grep $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
@@ -347,3 +397,95 @@ teardown() {
|
||||
|
||||
destroy_app
|
||||
}
|
||||
|
||||
@test "(apps:report) emits new stripped JSON keys alongside legacy" {
|
||||
create_app
|
||||
|
||||
run /bin/bash -c "dokku apps:report $TEST_APP --format json | jq -r 'has(\"dir\") and has(\"app-dir\")'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku apps:report $TEST_APP --format json | jq -r 'has(\"locked\") and has(\"app-locked\")'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku apps:report $TEST_APP --format json | jq -r 'has(\"deploy-source\") and has(\"app-deploy-source\")'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku apps:report $TEST_APP --format json | jq -r 'has(\"global-disable-autocreation\") and has(\"app-global-disable-autocreation\")'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
destroy_app
|
||||
}
|
||||
|
||||
@test "(apps:report --global) emits global-disable-autocreation" {
|
||||
run /bin/bash -c "dokku apps:report --global --app-global-disable-autocreation"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku apps:set --global disable-autocreation true"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku apps:report --global --app-global-disable-autocreation"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku apps:report --global --format json | jq -r '.\"global-disable-autocreation\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku apps:report --global --format json | jq -r '.\"app-global-disable-autocreation\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
create_app
|
||||
|
||||
run /bin/bash -c "dokku apps:report $TEST_APP --format json | jq -r '.\"global-disable-autocreation\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
destroy_app
|
||||
|
||||
run /bin/bash -c "dokku apps:set --global disable-autocreation"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(apps:set) rejects dead writes" {
|
||||
run /bin/bash -c "dokku apps:set --global deploy-source git"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output_contains "Property cannot be specified globally"
|
||||
|
||||
run /bin/bash -c "dokku apps:set --global deploy-source-metadata foo"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output_contains "Property cannot be specified globally"
|
||||
|
||||
create_app
|
||||
|
||||
run /bin/bash -c "dokku apps:set $TEST_APP disable-autocreation true"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output_contains "Property can only be specified globally"
|
||||
|
||||
destroy_app
|
||||
}
|
||||
|
||||
@@ -116,7 +116,7 @@ teardown() {
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
run /bin/bash -c "dokku config:set --no-restart $TEST_APP DOKKU_PROXY_SSL_PORT=443"
|
||||
run /bin/bash -c "dokku proxy:set $TEST_APP proxy-ssl-port 443"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
@@ -132,10 +132,6 @@ teardown() {
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output "http 80 5000"
|
||||
run /bin/bash -c "dokku config:get app-without-ssl DOKKU_PROXY_SSL_PORT"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output_not_exists
|
||||
run /bin/bash -c "dokku --force apps:destroy app-without-ssl"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
@@ -166,7 +162,7 @@ teardown() {
|
||||
assert_success
|
||||
assert_output "http://$TEST_APP.$DOKKU_DOMAIN"
|
||||
assert_http_localhost_response "http" "$TEST_APP.$DOKKU_DOMAIN" "80" "/hello"
|
||||
assert_http_localhost_response "http" "great-test-name.dokku.me" "80" "/hello" "" "404"
|
||||
assert_http_localhost_response "http" "great-test-name.dokku.me" "80" "/hello" "" "502"
|
||||
run /bin/bash -c "dokku --force apps:destroy great-test-name"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
|
||||
267
tests/unit/archive-security.bats
Normal file
267
tests/unit/archive-security.bats
Normal file
@@ -0,0 +1,267 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
ARCHIVE_TMP_DIR="${BATS_TMPDIR}/archive-security"
|
||||
|
||||
setup() {
|
||||
global_setup
|
||||
create_app
|
||||
mkdir -p "$ARCHIVE_TMP_DIR"
|
||||
}
|
||||
|
||||
teardown() {
|
||||
rm -rf "$ARCHIVE_TMP_DIR"
|
||||
rm -f /tmp/dokku-archive-security-canary.txt
|
||||
dokku git:set --global archive-max-size "" >/dev/null 2>&1 || true
|
||||
dokku git:set --global archive-max-files "" >/dev/null 2>&1 || true
|
||||
destroy_app
|
||||
global_teardown
|
||||
}
|
||||
|
||||
create_absolute_symlink_tar() {
|
||||
local OUTPUT="$1" FORMAT="${2:-tar}"
|
||||
python3 - "$OUTPUT" "$FORMAT" <<'PY'
|
||||
import io, sys, tarfile
|
||||
output, fmt = sys.argv[1], sys.argv[2]
|
||||
mode = "w:gz" if fmt == "tar.gz" else "w"
|
||||
with tarfile.open(output, mode) as t:
|
||||
link = tarfile.TarInfo("pwn")
|
||||
link.type = tarfile.SYMTYPE
|
||||
link.linkname = "/tmp"
|
||||
t.addfile(link)
|
||||
payload = b"canary content\n"
|
||||
fi = tarfile.TarInfo("pwn/dokku-archive-security-canary.txt")
|
||||
fi.size = len(payload)
|
||||
t.addfile(fi, io.BytesIO(payload))
|
||||
readme = b"# dummy\n"
|
||||
ri = tarfile.TarInfo("README.md")
|
||||
ri.size = len(readme)
|
||||
t.addfile(ri, io.BytesIO(readme))
|
||||
PY
|
||||
}
|
||||
|
||||
create_relative_traversal_symlink_tar() {
|
||||
local OUTPUT="$1" FORMAT="${2:-tar}"
|
||||
python3 - "$OUTPUT" "$FORMAT" <<'PY'
|
||||
import io, sys, tarfile
|
||||
output, fmt = sys.argv[1], sys.argv[2]
|
||||
mode = "w:gz" if fmt == "tar.gz" else "w"
|
||||
with tarfile.open(output, mode) as t:
|
||||
link = tarfile.TarInfo("pwn")
|
||||
link.type = tarfile.SYMTYPE
|
||||
link.linkname = "../../../../tmp"
|
||||
t.addfile(link)
|
||||
payload = b"canary content\n"
|
||||
fi = tarfile.TarInfo("pwn/dokku-archive-security-canary.txt")
|
||||
fi.size = len(payload)
|
||||
t.addfile(fi, io.BytesIO(payload))
|
||||
PY
|
||||
}
|
||||
|
||||
create_absolute_path_tar() {
|
||||
local OUTPUT="$1" FORMAT="${2:-tar}"
|
||||
python3 - "$OUTPUT" "$FORMAT" <<'PY'
|
||||
import io, sys, tarfile
|
||||
output, fmt = sys.argv[1], sys.argv[2]
|
||||
mode = "w:gz" if fmt == "tar.gz" else "w"
|
||||
with tarfile.open(output, mode) as t:
|
||||
payload = b"absolute path payload\n"
|
||||
fi = tarfile.TarInfo("/tmp/dokku-archive-security-canary.txt")
|
||||
fi.size = len(payload)
|
||||
t.addfile(fi, io.BytesIO(payload))
|
||||
PY
|
||||
}
|
||||
|
||||
create_traversal_path_tar() {
|
||||
local OUTPUT="$1" FORMAT="${2:-tar}"
|
||||
python3 - "$OUTPUT" "$FORMAT" <<'PY'
|
||||
import io, sys, tarfile
|
||||
output, fmt = sys.argv[1], sys.argv[2]
|
||||
mode = "w:gz" if fmt == "tar.gz" else "w"
|
||||
with tarfile.open(output, mode) as t:
|
||||
payload = b"traversal payload\n"
|
||||
fi = tarfile.TarInfo("../../../tmp/dokku-archive-security-canary.txt")
|
||||
fi.size = len(payload)
|
||||
t.addfile(fi, io.BytesIO(payload))
|
||||
PY
|
||||
}
|
||||
|
||||
create_safe_multi_file_tar() {
|
||||
local OUTPUT="$1"
|
||||
python3 - "$OUTPUT" <<'PY'
|
||||
import io, sys, tarfile
|
||||
output = sys.argv[1]
|
||||
with tarfile.open(output, "w") as t:
|
||||
for name in ("README.md", "Procfile", "app.py", "requirements.txt"):
|
||||
payload = (name + " contents\n").encode()
|
||||
ti = tarfile.TarInfo(name)
|
||||
ti.size = len(payload)
|
||||
t.addfile(ti, io.BytesIO(payload))
|
||||
PY
|
||||
}
|
||||
|
||||
create_evil_certs_tar() {
|
||||
local OUTPUT="$1"
|
||||
python3 - "$OUTPUT" <<'PY'
|
||||
import io, sys, tarfile
|
||||
output = sys.argv[1]
|
||||
with tarfile.open(output, "w") as t:
|
||||
link = tarfile.TarInfo("pwn")
|
||||
link.type = tarfile.SYMTYPE
|
||||
link.linkname = "/tmp"
|
||||
t.addfile(link)
|
||||
payload = b"canary content\n"
|
||||
fi = tarfile.TarInfo("pwn/dokku-archive-security-canary.txt")
|
||||
fi.size = len(payload)
|
||||
t.addfile(fi, io.BytesIO(payload))
|
||||
crt = b"-----BEGIN CERTIFICATE-----\nfake\n-----END CERTIFICATE-----\n"
|
||||
key = b"-----BEGIN PRIVATE KEY-----\nfake\n-----END PRIVATE KEY-----\n"
|
||||
tcrt = tarfile.TarInfo("server.crt")
|
||||
tcrt.size = len(crt)
|
||||
t.addfile(tcrt, io.BytesIO(crt))
|
||||
tkey = tarfile.TarInfo("server.key")
|
||||
tkey.size = len(key)
|
||||
t.addfile(tkey, io.BytesIO(key))
|
||||
PY
|
||||
}
|
||||
|
||||
@test "(archive-security) git:from-archive rejects tar with absolute symlink target" {
|
||||
create_absolute_symlink_tar "$ARCHIVE_TMP_DIR/evil.tar" "tar"
|
||||
run /bin/bash -c "cat $ARCHIVE_TMP_DIR/evil.tar | dokku git:from-archive $TEST_APP --"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output_contains "absolute targets"
|
||||
[[ ! -f /tmp/dokku-archive-security-canary.txt ]]
|
||||
}
|
||||
|
||||
@test "(archive-security) git:from-archive rejects tar.gz with absolute symlink target" {
|
||||
create_absolute_symlink_tar "$ARCHIVE_TMP_DIR/evil.tar.gz" "tar.gz"
|
||||
run /bin/bash -c "cat $ARCHIVE_TMP_DIR/evil.tar.gz | dokku git:from-archive --archive-type tar.gz $TEST_APP --"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output_contains "absolute targets"
|
||||
[[ ! -f /tmp/dokku-archive-security-canary.txt ]]
|
||||
}
|
||||
|
||||
@test "(archive-security) git:from-archive rejects tar with relative traversal symlink" {
|
||||
create_relative_traversal_symlink_tar "$ARCHIVE_TMP_DIR/evil.tar" "tar"
|
||||
run /bin/bash -c "cat $ARCHIVE_TMP_DIR/evil.tar | dokku git:from-archive $TEST_APP --"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output_contains "symlinks pointing outside extraction directory"
|
||||
[[ ! -f /tmp/dokku-archive-security-canary.txt ]]
|
||||
}
|
||||
|
||||
@test "(archive-security) git:from-archive rejects tar with absolute paths" {
|
||||
create_absolute_path_tar "$ARCHIVE_TMP_DIR/evil.tar" "tar"
|
||||
run /bin/bash -c "cat $ARCHIVE_TMP_DIR/evil.tar | dokku git:from-archive $TEST_APP --"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output_contains "absolute paths"
|
||||
[[ ! -f /tmp/dokku-archive-security-canary.txt ]]
|
||||
}
|
||||
|
||||
@test "(archive-security) git:from-archive rejects tar with parent traversal" {
|
||||
create_traversal_path_tar "$ARCHIVE_TMP_DIR/evil.tar" "tar"
|
||||
run /bin/bash -c "cat $ARCHIVE_TMP_DIR/evil.tar | dokku git:from-archive $TEST_APP --"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output_contains "Archive contains entries with parent directory traversal"
|
||||
[[ ! -f /tmp/dokku-archive-security-canary.txt ]]
|
||||
}
|
||||
|
||||
@test "(archive-security) certs:add rejects tar with absolute symlink target" {
|
||||
create_evil_certs_tar "$ARCHIVE_TMP_DIR/evil-certs.tar"
|
||||
run /bin/bash -c "cat $ARCHIVE_TMP_DIR/evil-certs.tar | dokku certs:add $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output_contains "absolute targets"
|
||||
[[ ! -f /tmp/dokku-archive-security-canary.txt ]]
|
||||
}
|
||||
|
||||
@test "(archive-security) certs:add still works with legitimate tarball" {
|
||||
run /bin/bash -c "dokku certs:add $TEST_APP < $BATS_TEST_DIRNAME/server_ssl.tar"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(archive-security) git:from-archive enforces archive-max-size property" {
|
||||
create_safe_multi_file_tar "$ARCHIVE_TMP_DIR/safe.tar"
|
||||
run /bin/bash -c "dokku git:set --global archive-max-size 1"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "cat $ARCHIVE_TMP_DIR/safe.tar | dokku git:from-archive $TEST_APP --"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output_contains "Archive exceeds maximum allowed size of 1 bytes"
|
||||
|
||||
run /bin/bash -c "dokku git:set --global archive-max-size"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(archive-security) git:from-archive enforces archive-max-files property" {
|
||||
create_safe_multi_file_tar "$ARCHIVE_TMP_DIR/safe.tar"
|
||||
run /bin/bash -c "dokku git:set --global archive-max-files 1"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "cat $ARCHIVE_TMP_DIR/safe.tar | dokku git:from-archive $TEST_APP --"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output_contains "exceeds the maximum of 1"
|
||||
|
||||
run /bin/bash -c "dokku git:set --global archive-max-files"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(archive-security) git:report exposes archive-max-size and archive-max-files" {
|
||||
run /bin/bash -c "dokku git:report --global --git-global-archive-max-size"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku git:report --global --git-computed-archive-max-size"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "1073741824"
|
||||
|
||||
run /bin/bash -c "dokku git:report --global --git-global-archive-max-files"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku git:report --global --git-computed-archive-max-files"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "10000"
|
||||
|
||||
run /bin/bash -c "dokku git:set --global archive-max-size 2147483648"
|
||||
assert_success
|
||||
run /bin/bash -c "dokku git:report --global --git-global-archive-max-size"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "2147483648"
|
||||
|
||||
run /bin/bash -c "dokku git:report --global --git-computed-archive-max-size"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "2147483648"
|
||||
|
||||
run /bin/bash -c "dokku git:set --global archive-max-size"
|
||||
assert_success
|
||||
}
|
||||
@@ -12,6 +12,130 @@ teardown() {
|
||||
destroy_app
|
||||
}
|
||||
|
||||
@test "(builder-dockerfile:report) info-flag works before deploy" {
|
||||
run /bin/bash -c "dokku builder-dockerfile:report $TEST_APP --builder-dockerfile-dockerfile-path"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builder-dockerfile:set $TEST_APP dockerfile-path second.Dockerfile"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builder-dockerfile:report $TEST_APP --builder-dockerfile-dockerfile-path"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "second.Dockerfile"
|
||||
|
||||
run /bin/bash -c "dokku builder-dockerfile:report $TEST_APP --builder-dockerfile-invalid-flag"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output_contains "Invalid flag passed"
|
||||
}
|
||||
|
||||
@test "(builder-dockerfile:report) --global --format json" {
|
||||
run /bin/bash -c "dokku builder-dockerfile:report --global --format json | jq -e ."
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builder-dockerfile:report --global --format json | jq -r '.\"global-dockerfile-path\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku builder-dockerfile:report --global --format json | jq -r 'has(\"dockerfile-path\")'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "false"
|
||||
|
||||
run /bin/bash -c "dokku builder-dockerfile:report --global"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "global builder-dockerfile information"
|
||||
|
||||
run /bin/bash -c "dokku builder-dockerfile:report --global --builder-dockerfile-global-dockerfile-path"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku builder-dockerfile:set --global dockerfile-path Dockerfile.custom"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builder-dockerfile:report --global --builder-dockerfile-global-dockerfile-path"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "Dockerfile.custom"
|
||||
|
||||
run /bin/bash -c "dokku builder-dockerfile:set --global dockerfile-path"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(builder-dockerfile:report) dockerfile-path raw vs computed vs global" {
|
||||
run /bin/bash -c "dokku builder-dockerfile:set --global dockerfile-path"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builder-dockerfile:report $TEST_APP --builder-dockerfile-dockerfile-path"
|
||||
assert_success
|
||||
assert_output_not_exists
|
||||
|
||||
run /bin/bash -c "dokku builder-dockerfile:report $TEST_APP --builder-dockerfile-global-dockerfile-path"
|
||||
assert_success
|
||||
assert_output_not_exists
|
||||
|
||||
run /bin/bash -c "dokku builder-dockerfile:report $TEST_APP --builder-dockerfile-computed-dockerfile-path"
|
||||
assert_success
|
||||
assert_output "Dockerfile"
|
||||
|
||||
run /bin/bash -c "dokku builder-dockerfile:set --global dockerfile-path Dockerfile.global"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builder-dockerfile:report $TEST_APP --builder-dockerfile-global-dockerfile-path"
|
||||
assert_success
|
||||
assert_output "Dockerfile.global"
|
||||
|
||||
run /bin/bash -c "dokku builder-dockerfile:report $TEST_APP --builder-dockerfile-computed-dockerfile-path"
|
||||
assert_success
|
||||
assert_output "Dockerfile.global"
|
||||
|
||||
run /bin/bash -c "dokku builder-dockerfile:set $TEST_APP dockerfile-path Dockerfile.app"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builder-dockerfile:report $TEST_APP --builder-dockerfile-dockerfile-path"
|
||||
assert_success
|
||||
assert_output "Dockerfile.app"
|
||||
|
||||
run /bin/bash -c "dokku builder-dockerfile:report $TEST_APP --builder-dockerfile-global-dockerfile-path"
|
||||
assert_success
|
||||
assert_output "Dockerfile.global"
|
||||
|
||||
run /bin/bash -c "dokku builder-dockerfile:report $TEST_APP --builder-dockerfile-computed-dockerfile-path"
|
||||
assert_success
|
||||
assert_output "Dockerfile.app"
|
||||
|
||||
run /bin/bash -c "dokku builder-dockerfile:set $TEST_APP dockerfile-path"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builder-dockerfile:set --global dockerfile-path"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builder-dockerfile:report $TEST_APP --builder-dockerfile-computed-dockerfile-path"
|
||||
assert_success
|
||||
assert_output "Dockerfile"
|
||||
}
|
||||
|
||||
@test "(builder-dockerfile:set)" {
|
||||
run deploy_app dockerfile
|
||||
echo "output: $output"
|
||||
@@ -124,6 +248,26 @@ EOF
|
||||
assert_output "3001/udp 3000/tcp 3003"
|
||||
}
|
||||
|
||||
@test "(builder-dockerfile) core-post-extract renames the configured dockerfile" {
|
||||
echo "FROM scratch" >"$BATS_TEST_TMPDIR/second.Dockerfile"
|
||||
|
||||
run /bin/bash -c "dokku builder-dockerfile:set $TEST_APP dockerfile-path second.Dockerfile"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run_plugin_script builder-dockerfile core-post-extract "$TEST_APP" "$BATS_TEST_TMPDIR" HEAD
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "test -f $BATS_TEST_TMPDIR/Dockerfile"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "test ! -e $BATS_TEST_TMPDIR/second.Dockerfile"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(builder-dockerfile) ps:rebuild fetches files from image" {
|
||||
run /bin/bash -c "dokku --trace git:from-image $TEST_APP dokku/smoke-test-app:dockerfile"
|
||||
echo "output: $output"
|
||||
|
||||
@@ -10,7 +10,106 @@ teardown() {
|
||||
destroy_app
|
||||
}
|
||||
|
||||
@test "(builder-herokuish:report) info-flag works before deploy" {
|
||||
run /bin/bash -c "dokku builder-herokuish:report $TEST_APP --builder-herokuish-allowed"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builder-herokuish:set $TEST_APP allowed false"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builder-herokuish:report $TEST_APP --builder-herokuish-allowed"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "false"
|
||||
|
||||
run /bin/bash -c "dokku builder-herokuish:report $TEST_APP --builder-herokuish-invalid-flag"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output_contains "Invalid flag passed"
|
||||
}
|
||||
|
||||
@test "(builder-herokuish:report) --global --builder-herokuish-global-allowed" {
|
||||
run /bin/bash -c "dokku builder-herokuish:set --global allowed false"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builder-herokuish:report --global --builder-herokuish-global-allowed"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "false"
|
||||
|
||||
run /bin/bash -c "dokku builder-herokuish:set --global allowed"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(builder-herokuish:report) allowed raw vs computed vs global" {
|
||||
local default_allowed="true"
|
||||
[[ "$(dpkg --print-architecture 2>/dev/null || true)" != "amd64" ]] && default_allowed="false"
|
||||
|
||||
run /bin/bash -c "dokku builder-herokuish:set --global allowed"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builder-herokuish:report $TEST_APP --builder-herokuish-allowed"
|
||||
assert_success
|
||||
assert_output_not_exists
|
||||
|
||||
run /bin/bash -c "dokku builder-herokuish:report $TEST_APP --builder-herokuish-global-allowed"
|
||||
assert_success
|
||||
assert_output_not_exists
|
||||
|
||||
run /bin/bash -c "dokku builder-herokuish:report $TEST_APP --builder-herokuish-computed-allowed"
|
||||
assert_success
|
||||
assert_output "$default_allowed"
|
||||
|
||||
run /bin/bash -c "dokku builder-herokuish:set --global allowed false"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builder-herokuish:report $TEST_APP --builder-herokuish-global-allowed"
|
||||
assert_success
|
||||
assert_output "false"
|
||||
|
||||
run /bin/bash -c "dokku builder-herokuish:report $TEST_APP --builder-herokuish-computed-allowed"
|
||||
assert_success
|
||||
assert_output "false"
|
||||
|
||||
run /bin/bash -c "dokku builder-herokuish:set $TEST_APP allowed true"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builder-herokuish:report $TEST_APP --builder-herokuish-allowed"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku builder-herokuish:report $TEST_APP --builder-herokuish-global-allowed"
|
||||
assert_success
|
||||
assert_output "false"
|
||||
|
||||
run /bin/bash -c "dokku builder-herokuish:report $TEST_APP --builder-herokuish-computed-allowed"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku builder-herokuish:set $TEST_APP allowed"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builder-herokuish:set --global allowed"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(builder-herouish:build .env)" {
|
||||
run /bin/bash -c "dokku docker-options:add $TEST_APP build '--label=com.dokku.build-test=safe'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run deploy_app python dokku@$DOKKU_DOMAIN:$TEST_APP
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
|
||||
@@ -10,6 +10,97 @@ teardown() {
|
||||
destroy_app
|
||||
}
|
||||
|
||||
@test "(builder-lambda:report) info-flag works before deploy" {
|
||||
run /bin/bash -c "dokku builder-lambda:report $TEST_APP --builder-lambda-lambdayml-path"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builder-lambda:set $TEST_APP lambdayml-path lambda.alt.yml"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builder-lambda:report $TEST_APP --builder-lambda-lambdayml-path"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "lambda.alt.yml"
|
||||
|
||||
run /bin/bash -c "dokku builder-lambda:report $TEST_APP --builder-lambda-invalid-flag"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output_contains "Invalid flag passed"
|
||||
}
|
||||
|
||||
@test "(builder-lambda:report) --global --builder-lambda-global-lambdayml-path" {
|
||||
run /bin/bash -c "dokku builder-lambda:set --global lambdayml-path lambda.alt.yml"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builder-lambda:report --global --builder-lambda-global-lambdayml-path"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "lambda.alt.yml"
|
||||
|
||||
run /bin/bash -c "dokku builder-lambda:set --global lambdayml-path"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(builder-lambda:report) lambdayml-path raw vs computed vs global" {
|
||||
run /bin/bash -c "dokku builder-lambda:set --global lambdayml-path"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builder-lambda:report $TEST_APP --builder-lambda-lambdayml-path"
|
||||
assert_success
|
||||
assert_output_not_exists
|
||||
|
||||
run /bin/bash -c "dokku builder-lambda:report $TEST_APP --builder-lambda-global-lambdayml-path"
|
||||
assert_success
|
||||
assert_output_not_exists
|
||||
|
||||
run /bin/bash -c "dokku builder-lambda:report $TEST_APP --builder-lambda-computed-lambdayml-path"
|
||||
assert_success
|
||||
assert_output "lambda.yml"
|
||||
|
||||
run /bin/bash -c "dokku builder-lambda:set --global lambdayml-path lambda.global.yml"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builder-lambda:report $TEST_APP --builder-lambda-global-lambdayml-path"
|
||||
assert_success
|
||||
assert_output "lambda.global.yml"
|
||||
|
||||
run /bin/bash -c "dokku builder-lambda:report $TEST_APP --builder-lambda-computed-lambdayml-path"
|
||||
assert_success
|
||||
assert_output "lambda.global.yml"
|
||||
|
||||
run /bin/bash -c "dokku builder-lambda:set $TEST_APP lambdayml-path lambda.app.yml"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builder-lambda:report $TEST_APP --builder-lambda-lambdayml-path"
|
||||
assert_success
|
||||
assert_output "lambda.app.yml"
|
||||
|
||||
run /bin/bash -c "dokku builder-lambda:report $TEST_APP --builder-lambda-global-lambdayml-path"
|
||||
assert_success
|
||||
assert_output "lambda.global.yml"
|
||||
|
||||
run /bin/bash -c "dokku builder-lambda:report $TEST_APP --builder-lambda-computed-lambdayml-path"
|
||||
assert_success
|
||||
assert_output "lambda.app.yml"
|
||||
|
||||
run /bin/bash -c "dokku builder-lambda:set $TEST_APP lambdayml-path"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builder-lambda:set --global lambdayml-path"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(builder-lambda:set)" {
|
||||
run /bin/bash -c "dokku config:set $TEST_APP SECRET_KEY=fjdkslafjdk"
|
||||
echo "output: $output"
|
||||
@@ -134,6 +225,26 @@ teardown() {
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(builder-lambda) core-post-extract renames the configured lambda.yml" {
|
||||
echo "---" >"$BATS_TEST_TMPDIR/lambda2.yml"
|
||||
|
||||
run /bin/bash -c "dokku builder-lambda:set $TEST_APP lambdayml-path lambda2.yml"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run_plugin_script builder-lambda core-post-extract "$TEST_APP" "$BATS_TEST_TMPDIR" HEAD
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "test -f $BATS_TEST_TMPDIR/lambda.yml"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "test ! -e $BATS_TEST_TMPDIR/lambda2.yml"
|
||||
assert_success
|
||||
}
|
||||
|
||||
inject_lambda_yml() {
|
||||
local APP="$1"
|
||||
local APP_REPO_DIR="$2"
|
||||
|
||||
@@ -14,6 +14,97 @@ teardown() {
|
||||
destroy_app
|
||||
}
|
||||
|
||||
@test "(builder-nixpacks:report) info-flag works before deploy" {
|
||||
run /bin/bash -c "dokku builder-nixpacks:report $TEST_APP --builder-nixpacks-nixpackstoml-path"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builder-nixpacks:set $TEST_APP nixpackstoml-path nixpacks.alt.toml"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builder-nixpacks:report $TEST_APP --builder-nixpacks-nixpackstoml-path"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "nixpacks.alt.toml"
|
||||
|
||||
run /bin/bash -c "dokku builder-nixpacks:report $TEST_APP --builder-nixpacks-invalid-flag"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output_contains "Invalid flag passed"
|
||||
}
|
||||
|
||||
@test "(builder-nixpacks:report) --global --builder-nixpacks-global-nixpackstoml-path" {
|
||||
run /bin/bash -c "dokku builder-nixpacks:set --global nixpackstoml-path nixpacks.alt.toml"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builder-nixpacks:report --global --builder-nixpacks-global-nixpackstoml-path"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "nixpacks.alt.toml"
|
||||
|
||||
run /bin/bash -c "dokku builder-nixpacks:set --global nixpackstoml-path"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(builder-nixpacks:report) nixpackstoml-path raw vs computed vs global" {
|
||||
run /bin/bash -c "dokku builder-nixpacks:set --global nixpackstoml-path"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builder-nixpacks:report $TEST_APP --builder-nixpacks-nixpackstoml-path"
|
||||
assert_success
|
||||
assert_output_not_exists
|
||||
|
||||
run /bin/bash -c "dokku builder-nixpacks:report $TEST_APP --builder-nixpacks-global-nixpackstoml-path"
|
||||
assert_success
|
||||
assert_output_not_exists
|
||||
|
||||
run /bin/bash -c "dokku builder-nixpacks:report $TEST_APP --builder-nixpacks-computed-nixpackstoml-path"
|
||||
assert_success
|
||||
assert_output "nixpacks.toml"
|
||||
|
||||
run /bin/bash -c "dokku builder-nixpacks:set --global nixpackstoml-path nixpacks.global.toml"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builder-nixpacks:report $TEST_APP --builder-nixpacks-global-nixpackstoml-path"
|
||||
assert_success
|
||||
assert_output "nixpacks.global.toml"
|
||||
|
||||
run /bin/bash -c "dokku builder-nixpacks:report $TEST_APP --builder-nixpacks-computed-nixpackstoml-path"
|
||||
assert_success
|
||||
assert_output "nixpacks.global.toml"
|
||||
|
||||
run /bin/bash -c "dokku builder-nixpacks:set $TEST_APP nixpackstoml-path nixpacks.app.toml"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builder-nixpacks:report $TEST_APP --builder-nixpacks-nixpackstoml-path"
|
||||
assert_success
|
||||
assert_output "nixpacks.app.toml"
|
||||
|
||||
run /bin/bash -c "dokku builder-nixpacks:report $TEST_APP --builder-nixpacks-global-nixpackstoml-path"
|
||||
assert_success
|
||||
assert_output "nixpacks.global.toml"
|
||||
|
||||
run /bin/bash -c "dokku builder-nixpacks:report $TEST_APP --builder-nixpacks-computed-nixpackstoml-path"
|
||||
assert_success
|
||||
assert_output "nixpacks.app.toml"
|
||||
|
||||
run /bin/bash -c "dokku builder-nixpacks:set $TEST_APP nixpackstoml-path"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builder-nixpacks:set --global nixpackstoml-path"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(builder-nixpacks:set)" {
|
||||
run /bin/bash -c "dokku config:set $TEST_APP SECRET_KEY=fjdkslafjdk"
|
||||
echo "output: $output"
|
||||
@@ -55,6 +146,11 @@ teardown() {
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku docker-options:add $TEST_APP build '--label=com.dokku.build-test=safe'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run deploy_app python dokku@$DOKKU_DOMAIN:$TEST_APP add_requirements_txt
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
@@ -113,6 +209,26 @@ teardown() {
|
||||
assert_output "['task.py', 'some', 'cron', 'task']"
|
||||
}
|
||||
|
||||
@test "(builder-nixpacks) core-post-extract renames the configured nixpacks.toml" {
|
||||
echo "" >"$BATS_TEST_TMPDIR/nixpacks.alt.toml"
|
||||
|
||||
run /bin/bash -c "dokku builder-nixpacks:set $TEST_APP nixpackstoml-path nixpacks.alt.toml"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run_plugin_script builder-nixpacks core-post-extract "$TEST_APP" "$BATS_TEST_TMPDIR" HEAD
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "test -f $BATS_TEST_TMPDIR/nixpacks.toml"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "test ! -e $BATS_TEST_TMPDIR/nixpacks.alt.toml"
|
||||
assert_success
|
||||
}
|
||||
|
||||
cron_run_wrapper() {
|
||||
local APP="$1"
|
||||
local APP_REPO_DIR="$2"
|
||||
|
||||
@@ -16,6 +16,97 @@ teardown() {
|
||||
global_teardown
|
||||
}
|
||||
|
||||
@test "(builder-pack:report) info-flag works before deploy" {
|
||||
run /bin/bash -c "dokku builder-pack:report $TEST_APP --builder-pack-projecttoml-path"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builder-pack:set $TEST_APP projecttoml-path project.alt.toml"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builder-pack:report $TEST_APP --builder-pack-projecttoml-path"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "project.alt.toml"
|
||||
|
||||
run /bin/bash -c "dokku builder-pack:report $TEST_APP --builder-pack-invalid-flag"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output_contains "Invalid flag passed"
|
||||
}
|
||||
|
||||
@test "(builder-pack:report) --global --builder-pack-global-projecttoml-path" {
|
||||
run /bin/bash -c "dokku builder-pack:set --global projecttoml-path project.alt.toml"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builder-pack:report --global --builder-pack-global-projecttoml-path"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "project.alt.toml"
|
||||
|
||||
run /bin/bash -c "dokku builder-pack:set --global projecttoml-path"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(builder-pack:report) projecttoml-path raw vs computed vs global" {
|
||||
run /bin/bash -c "dokku builder-pack:set --global projecttoml-path"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builder-pack:report $TEST_APP --builder-pack-projecttoml-path"
|
||||
assert_success
|
||||
assert_output_not_exists
|
||||
|
||||
run /bin/bash -c "dokku builder-pack:report $TEST_APP --builder-pack-global-projecttoml-path"
|
||||
assert_success
|
||||
assert_output_not_exists
|
||||
|
||||
run /bin/bash -c "dokku builder-pack:report $TEST_APP --builder-pack-computed-projecttoml-path"
|
||||
assert_success
|
||||
assert_output "project.toml"
|
||||
|
||||
run /bin/bash -c "dokku builder-pack:set --global projecttoml-path project.global.toml"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builder-pack:report $TEST_APP --builder-pack-global-projecttoml-path"
|
||||
assert_success
|
||||
assert_output "project.global.toml"
|
||||
|
||||
run /bin/bash -c "dokku builder-pack:report $TEST_APP --builder-pack-computed-projecttoml-path"
|
||||
assert_success
|
||||
assert_output "project.global.toml"
|
||||
|
||||
run /bin/bash -c "dokku builder-pack:set $TEST_APP projecttoml-path project.app.toml"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builder-pack:report $TEST_APP --builder-pack-projecttoml-path"
|
||||
assert_success
|
||||
assert_output "project.app.toml"
|
||||
|
||||
run /bin/bash -c "dokku builder-pack:report $TEST_APP --builder-pack-global-projecttoml-path"
|
||||
assert_success
|
||||
assert_output "project.global.toml"
|
||||
|
||||
run /bin/bash -c "dokku builder-pack:report $TEST_APP --builder-pack-computed-projecttoml-path"
|
||||
assert_success
|
||||
assert_output "project.app.toml"
|
||||
|
||||
run /bin/bash -c "dokku builder-pack:set $TEST_APP projecttoml-path"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builder-pack:set --global projecttoml-path"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(builder-pack:set)" {
|
||||
run /bin/bash -c "dokku config:set $TEST_APP SECRET_KEY=fjdkslafjdk"
|
||||
echo "output: $output"
|
||||
@@ -87,6 +178,11 @@ teardown() {
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku docker-options:add $TEST_APP build '--label=com.dokku.build-test=safe'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run deploy_app python dokku@$DOKKU_DOMAIN:$TEST_APP add_requirements_txt_cnb
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
@@ -177,6 +273,59 @@ teardown() {
|
||||
assert_output "['task.py', 'some', 'cron', 'task']"
|
||||
}
|
||||
|
||||
@test "(builder-pack) cron:run with Procfile reference" {
|
||||
run /bin/bash -c "dokku config:set $TEST_APP SECRET_KEY=fjdkslafjdk"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builder:set $TEST_APP selected pack"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run deploy_app python dokku@$DOKKU_DOMAIN:$TEST_APP cron_run_procfile_wrapper
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains 'from cnb stack'
|
||||
assert_output_contains 'Building with buildpack 1' 0
|
||||
assert_output_contains 'Installing dependencies using pip'
|
||||
|
||||
cron_id="$(dokku cron:list $TEST_APP --format json | jq -r '.[0].id')"
|
||||
run /bin/bash -c "echo $cron_id"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_exists
|
||||
|
||||
run /bin/bash -c "dokku --quiet cron:run $TEST_APP $cron_id"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "['task.py', 'test']"
|
||||
}
|
||||
|
||||
@test "(builder-pack) core-post-extract renames the configured project.toml" {
|
||||
echo "" >"$BATS_TEST_TMPDIR/project2.toml"
|
||||
|
||||
run /bin/bash -c "dokku builder-pack:set $TEST_APP projecttoml-path project2.toml"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run_plugin_script builder-pack core-post-extract "$TEST_APP" "$BATS_TEST_TMPDIR" HEAD
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "test -f $BATS_TEST_TMPDIR/project.toml"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "test ! -e $BATS_TEST_TMPDIR/project2.toml"
|
||||
assert_success
|
||||
}
|
||||
|
||||
cron_run_wrapper() {
|
||||
local APP="$1"
|
||||
local APP_REPO_DIR="$2"
|
||||
@@ -187,3 +336,14 @@ cron_run_wrapper() {
|
||||
ls -lah "$APP_REPO_DIR"
|
||||
mv -f "$APP_REPO_DIR/app-cnb-cron.json" "$APP_REPO_DIR/app.json"
|
||||
}
|
||||
|
||||
cron_run_procfile_wrapper() {
|
||||
local APP="$1"
|
||||
local APP_REPO_DIR="$2"
|
||||
[[ -z "$APP" ]] && local APP="$TEST_APP"
|
||||
APP_REPO_DIR="$(realpath "$APP_REPO_DIR")"
|
||||
|
||||
add_requirements_txt "$APP" "$APP_REPO_DIR"
|
||||
ls -lah "$APP_REPO_DIR"
|
||||
mv -f "$APP_REPO_DIR/app-cnb-cron-procfile.json" "$APP_REPO_DIR/app.json"
|
||||
}
|
||||
|
||||
@@ -25,6 +25,97 @@ teardown() {
|
||||
global_teardown
|
||||
}
|
||||
|
||||
@test "(builder-railpack:report) info-flag works before deploy" {
|
||||
run /bin/bash -c "dokku builder-railpack:report $TEST_APP --builder-railpack-railpackjson-path"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builder-railpack:set $TEST_APP railpackjson-path railpack.alt.json"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builder-railpack:report $TEST_APP --builder-railpack-railpackjson-path"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "railpack.alt.json"
|
||||
|
||||
run /bin/bash -c "dokku builder-railpack:report $TEST_APP --builder-railpack-invalid-flag"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output_contains "Invalid flag passed"
|
||||
}
|
||||
|
||||
@test "(builder-railpack:report) --global --builder-railpack-global-railpackjson-path" {
|
||||
run /bin/bash -c "dokku builder-railpack:set --global railpackjson-path railpack.alt.json"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builder-railpack:report --global --builder-railpack-global-railpackjson-path"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "railpack.alt.json"
|
||||
|
||||
run /bin/bash -c "dokku builder-railpack:set --global railpackjson-path"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(builder-railpack:report) railpackjson-path raw vs computed vs global" {
|
||||
run /bin/bash -c "dokku builder-railpack:set --global railpackjson-path"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builder-railpack:report $TEST_APP --builder-railpack-railpackjson-path"
|
||||
assert_success
|
||||
assert_output_not_exists
|
||||
|
||||
run /bin/bash -c "dokku builder-railpack:report $TEST_APP --builder-railpack-global-railpackjson-path"
|
||||
assert_success
|
||||
assert_output_not_exists
|
||||
|
||||
run /bin/bash -c "dokku builder-railpack:report $TEST_APP --builder-railpack-computed-railpackjson-path"
|
||||
assert_success
|
||||
assert_output "railpack.json"
|
||||
|
||||
run /bin/bash -c "dokku builder-railpack:set --global railpackjson-path railpack.global.json"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builder-railpack:report $TEST_APP --builder-railpack-global-railpackjson-path"
|
||||
assert_success
|
||||
assert_output "railpack.global.json"
|
||||
|
||||
run /bin/bash -c "dokku builder-railpack:report $TEST_APP --builder-railpack-computed-railpackjson-path"
|
||||
assert_success
|
||||
assert_output "railpack.global.json"
|
||||
|
||||
run /bin/bash -c "dokku builder-railpack:set $TEST_APP railpackjson-path railpack.app.json"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builder-railpack:report $TEST_APP --builder-railpack-railpackjson-path"
|
||||
assert_success
|
||||
assert_output "railpack.app.json"
|
||||
|
||||
run /bin/bash -c "dokku builder-railpack:report $TEST_APP --builder-railpack-global-railpackjson-path"
|
||||
assert_success
|
||||
assert_output "railpack.global.json"
|
||||
|
||||
run /bin/bash -c "dokku builder-railpack:report $TEST_APP --builder-railpack-computed-railpackjson-path"
|
||||
assert_success
|
||||
assert_output "railpack.app.json"
|
||||
|
||||
run /bin/bash -c "dokku builder-railpack:set $TEST_APP railpackjson-path"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builder-railpack:set --global railpackjson-path"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(builder-railpack:set)" {
|
||||
run /bin/bash -c "dokku config:set $TEST_APP SECRET_KEY=fjdkslafjdk"
|
||||
echo "output: $output"
|
||||
@@ -66,6 +157,11 @@ teardown() {
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku docker-options:add $TEST_APP build '--label=com.dokku.build-test=safe'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run deploy_app python dokku@$DOKKU_DOMAIN:$TEST_APP add_requirements_txt
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
@@ -124,6 +220,26 @@ teardown() {
|
||||
assert_output "['task.py', 'some', 'cron', 'task']"
|
||||
}
|
||||
|
||||
@test "(builder-railpack) core-post-extract renames the configured railpack.json" {
|
||||
echo "{}" >"$BATS_TEST_TMPDIR/railpack.alt.json"
|
||||
|
||||
run /bin/bash -c "dokku builder-railpack:set $TEST_APP railpackjson-path railpack.alt.json"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run_plugin_script builder-railpack core-post-extract "$TEST_APP" "$BATS_TEST_TMPDIR" HEAD
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "test -f $BATS_TEST_TMPDIR/railpack.json"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "test ! -e $BATS_TEST_TMPDIR/railpack.alt.json"
|
||||
assert_success
|
||||
}
|
||||
|
||||
cron_run_wrapper() {
|
||||
local APP="$1"
|
||||
local APP_REPO_DIR="$2"
|
||||
|
||||
@@ -7,6 +7,7 @@ setup() {
|
||||
}
|
||||
|
||||
teardown() {
|
||||
dokku builder:set --global skip-cleanup >/dev/null 2>/dev/null || true
|
||||
destroy_app
|
||||
}
|
||||
|
||||
@@ -175,6 +176,205 @@ teardown() {
|
||||
assert_line 0 "herokuish"
|
||||
}
|
||||
|
||||
@test "(builder:report) --global --format json" {
|
||||
run /bin/bash -c "dokku builder:set --global selected dockerfile"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builder:report --global --format json | jq -e ."
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builder:report --global --format json | jq -r '.\"builder-global-selected\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "dockerfile"
|
||||
|
||||
run /bin/bash -c "dokku builder:report --global --format json | jq -r '.\"global-selected\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "dockerfile"
|
||||
|
||||
run /bin/bash -c "dokku builder:report --global --format json | jq -r 'has(\"builder-selected\")'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "false"
|
||||
|
||||
run /bin/bash -c "dokku builder:report --global --format json | jq -r 'has(\"selected\") and has(\"builder-global-selected\")'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "false"
|
||||
|
||||
run /bin/bash -c "dokku builder:report --global --format json | jq -r 'has(\"computed-skip-cleanup\") and has(\"builder-computed-skip-cleanup\")'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku builder:report --global"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builder:set --global selected"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(builder:report) selected raw vs computed vs global" {
|
||||
run /bin/bash -c "dokku builder:set --global selected"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builder:report $TEST_APP --builder-selected"
|
||||
assert_success
|
||||
assert_output_not_exists
|
||||
|
||||
run /bin/bash -c "dokku builder:report $TEST_APP --builder-global-selected"
|
||||
assert_success
|
||||
assert_output_not_exists
|
||||
|
||||
run /bin/bash -c "dokku builder:report $TEST_APP --builder-computed-selected"
|
||||
assert_success
|
||||
assert_output_not_exists
|
||||
|
||||
run /bin/bash -c "dokku builder:set --global selected dockerfile"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builder:report $TEST_APP --builder-global-selected"
|
||||
assert_success
|
||||
assert_output "dockerfile"
|
||||
|
||||
run /bin/bash -c "dokku builder:report $TEST_APP --builder-computed-selected"
|
||||
assert_success
|
||||
assert_output "dockerfile"
|
||||
|
||||
run /bin/bash -c "dokku builder:set $TEST_APP selected herokuish"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builder:report $TEST_APP --builder-selected"
|
||||
assert_success
|
||||
assert_output "herokuish"
|
||||
|
||||
run /bin/bash -c "dokku builder:report $TEST_APP --builder-global-selected"
|
||||
assert_success
|
||||
assert_output "dockerfile"
|
||||
|
||||
run /bin/bash -c "dokku builder:report $TEST_APP --builder-computed-selected"
|
||||
assert_success
|
||||
assert_output "herokuish"
|
||||
|
||||
run /bin/bash -c "dokku builder:set $TEST_APP selected"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builder:set --global selected"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(builder:report) build-dir raw vs computed vs global" {
|
||||
run /bin/bash -c "dokku builder:set --global build-dir"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builder:report $TEST_APP --builder-build-dir"
|
||||
assert_success
|
||||
assert_output_not_exists
|
||||
|
||||
run /bin/bash -c "dokku builder:report $TEST_APP --builder-global-build-dir"
|
||||
assert_success
|
||||
assert_output_not_exists
|
||||
|
||||
run /bin/bash -c "dokku builder:report $TEST_APP --builder-computed-build-dir"
|
||||
assert_success
|
||||
assert_output_not_exists
|
||||
|
||||
run /bin/bash -c "dokku builder:set --global build-dir global/subdir"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builder:report $TEST_APP --builder-global-build-dir"
|
||||
assert_success
|
||||
assert_output "global/subdir"
|
||||
|
||||
run /bin/bash -c "dokku builder:report $TEST_APP --builder-computed-build-dir"
|
||||
assert_success
|
||||
assert_output "global/subdir"
|
||||
|
||||
run /bin/bash -c "dokku builder:set $TEST_APP build-dir app/subdir"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builder:report $TEST_APP --builder-build-dir"
|
||||
assert_success
|
||||
assert_output "app/subdir"
|
||||
|
||||
run /bin/bash -c "dokku builder:report $TEST_APP --builder-global-build-dir"
|
||||
assert_success
|
||||
assert_output "global/subdir"
|
||||
|
||||
run /bin/bash -c "dokku builder:report $TEST_APP --builder-computed-build-dir"
|
||||
assert_success
|
||||
assert_output "app/subdir"
|
||||
|
||||
run /bin/bash -c "dokku builder:set $TEST_APP build-dir"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builder:set --global build-dir"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(builder:report) skip-cleanup raw vs computed vs global" {
|
||||
run /bin/bash -c "dokku builder:set --global skip-cleanup"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builder:report $TEST_APP --builder-skip-cleanup"
|
||||
assert_success
|
||||
assert_output_not_exists
|
||||
|
||||
run /bin/bash -c "dokku builder:report $TEST_APP --builder-global-skip-cleanup"
|
||||
assert_success
|
||||
assert_output_not_exists
|
||||
|
||||
run /bin/bash -c "dokku builder:report $TEST_APP --builder-computed-skip-cleanup"
|
||||
assert_success
|
||||
assert_output "false"
|
||||
|
||||
run /bin/bash -c "dokku builder:set --global skip-cleanup true"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builder:report $TEST_APP --builder-global-skip-cleanup"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku builder:report $TEST_APP --builder-computed-skip-cleanup"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku builder:set $TEST_APP skip-cleanup false"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builder:report $TEST_APP --builder-skip-cleanup"
|
||||
assert_success
|
||||
assert_output "false"
|
||||
|
||||
run /bin/bash -c "dokku builder:report $TEST_APP --builder-global-skip-cleanup"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku builder:report $TEST_APP --builder-computed-skip-cleanup"
|
||||
assert_success
|
||||
assert_output "false"
|
||||
|
||||
run /bin/bash -c "dokku builder:set $TEST_APP skip-cleanup"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builder:set --global skip-cleanup"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(builder:set)" {
|
||||
run deploy_app python
|
||||
echo "output: $output"
|
||||
|
||||
@@ -184,6 +184,75 @@ teardown() {
|
||||
assert_output "https://github.com/heroku/heroku-buildpack-golang.git https://github.com/heroku/heroku-buildpack-python.git https://github.com/heroku/heroku-buildpack-php.git"
|
||||
}
|
||||
|
||||
@test "(buildpacks) buildpacks:set --replace - failure" {
|
||||
run /bin/bash -c "dokku buildpacks:set --replace $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output_contains "buildpacks:clear"
|
||||
|
||||
run /bin/bash -c "dokku buildpacks:set --replace --index 1 $TEST_APP heroku/nodejs"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output_contains "--index"
|
||||
|
||||
run /bin/bash -c "dokku buildpacks:set $TEST_APP heroku/nodejs heroku/ruby"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output_contains "--replace"
|
||||
}
|
||||
|
||||
@test "(buildpacks) buildpacks:set --replace - atomicity" {
|
||||
run /bin/bash -c "dokku buildpacks:add $TEST_APP heroku/nodejs"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku buildpacks:set --replace $TEST_APP heroku/ruby nodejs"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
|
||||
run /bin/bash -c "dokku --quiet buildpacks:list $TEST_APP | xargs"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output "https://github.com/heroku/heroku-buildpack-nodejs.git"
|
||||
}
|
||||
|
||||
@test "(buildpacks) buildpacks:set --replace - success" {
|
||||
run /bin/bash -c "dokku buildpacks:add $TEST_APP heroku/nodejs"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku buildpacks:add $TEST_APP heroku/python"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku buildpacks:set --replace $TEST_APP heroku/ruby heroku/golang heroku/php"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku --quiet buildpacks:list $TEST_APP | xargs"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output "https://github.com/heroku/heroku-buildpack-ruby.git https://github.com/heroku/heroku-buildpack-golang.git https://github.com/heroku/heroku-buildpack-php.git"
|
||||
|
||||
run /bin/bash -c "dokku buildpacks:set --replace $TEST_APP heroku/nodejs"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku --quiet buildpacks:list $TEST_APP | xargs"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output "https://github.com/heroku/heroku-buildpack-nodejs.git"
|
||||
}
|
||||
|
||||
@test "(buildpacks) buildpacks:set-property" {
|
||||
run /bin/bash -c "dokku buildpacks:set-property --global stack gliderlabs/herokuish:latest"
|
||||
echo "output: $output"
|
||||
@@ -191,6 +260,69 @@ teardown() {
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(buildpacks:report) stack raw vs computed vs global" {
|
||||
run /bin/bash -c "dokku buildpacks:set-property --global stack"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku buildpacks:report $TEST_APP --format json | jq -r '.\"buildpacks-stack\"'"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku buildpacks:report $TEST_APP --format json | jq -r '.\"buildpacks-global-stack\"'"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku buildpacks:set-property --global stack gliderlabs/herokuish:global"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku buildpacks:report $TEST_APP --format json | jq -r '.\"buildpacks-global-stack\"'"
|
||||
assert_success
|
||||
assert_output "gliderlabs/herokuish:global"
|
||||
|
||||
run /bin/bash -c "dokku buildpacks:report $TEST_APP --format json | jq -r '.\"buildpacks-computed-stack\"'"
|
||||
assert_success
|
||||
assert_output "gliderlabs/herokuish:global"
|
||||
|
||||
run /bin/bash -c "dokku buildpacks:set-property $TEST_APP stack gliderlabs/herokuish:app"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku buildpacks:report $TEST_APP --format json | jq -r '.\"buildpacks-stack\"'"
|
||||
assert_success
|
||||
assert_output "gliderlabs/herokuish:app"
|
||||
|
||||
run /bin/bash -c "dokku buildpacks:report $TEST_APP --format json | jq -r '.\"buildpacks-global-stack\"'"
|
||||
assert_success
|
||||
assert_output "gliderlabs/herokuish:global"
|
||||
|
||||
run /bin/bash -c "dokku buildpacks:report $TEST_APP --format json | jq -r '.\"buildpacks-computed-stack\"'"
|
||||
assert_success
|
||||
assert_output "gliderlabs/herokuish:app"
|
||||
|
||||
run /bin/bash -c "dokku buildpacks:set-property $TEST_APP stack"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku buildpacks:set-property --global stack"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(buildpacks:report) emits new stripped JSON keys alongside legacy" {
|
||||
run /bin/bash -c "dokku buildpacks:report $TEST_APP --format json | jq -r 'has(\"stack\") and has(\"buildpacks-stack\")'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku buildpacks:report $TEST_APP --format json | jq -r 'has(\"global-stack\") and has(\"buildpacks-global-stack\")'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku buildpacks:report $TEST_APP --format json | jq -r 'has(\"computed-stack\") and has(\"buildpacks-computed-stack\")'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku buildpacks:report $TEST_APP --format json | jq -r 'has(\"list\") and has(\"buildpacks-list\")'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
}
|
||||
|
||||
@test "(buildpacks) buildpacks:remove" {
|
||||
run /bin/bash -c "dokku buildpacks:set $TEST_APP heroku/nodejs"
|
||||
echo "output: $output"
|
||||
@@ -336,6 +468,33 @@ teardown() {
|
||||
assert_output_contains "heroku-buildpack-python"
|
||||
}
|
||||
|
||||
@test "(buildpacks) deploy with buildpacks from app.json" {
|
||||
run deploy_app python dokku@$DOKKU_DOMAIN:$TEST_APP template_buildpacks_appjson
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "heroku-buildpack-python"
|
||||
}
|
||||
|
||||
template_buildpacks_appjson() {
|
||||
local APP="$1"
|
||||
local APP_REPO_DIR="$2"
|
||||
[[ -z "$APP" ]] && local APP="$TEST_APP"
|
||||
echo "injecting app.json with buildpacks -> $APP_REPO_DIR/app.json"
|
||||
cat <<EOF >"$APP_REPO_DIR/app.json"
|
||||
{
|
||||
"buildpacks": [
|
||||
{
|
||||
"url": "heroku/python"
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
|
||||
echo "injecting requirements.txt -> $APP_REPO_DIR/requirements.txt"
|
||||
touch "$APP_REPO_DIR/requirements.txt"
|
||||
}
|
||||
|
||||
template_buildpacks_cleanup() {
|
||||
local APP="$1"
|
||||
local APP_REPO_DIR="$2"
|
||||
|
||||
352
tests/unit/builds.bats
Normal file
352
tests/unit/builds.bats
Normal file
@@ -0,0 +1,352 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
setup() {
|
||||
global_setup
|
||||
create_app
|
||||
}
|
||||
|
||||
teardown() {
|
||||
rm -rf "$DOKKU_LIB_ROOT/data/builds/$TEST_APP" || true
|
||||
destroy_app
|
||||
global_teardown
|
||||
}
|
||||
|
||||
write_finished_record() {
|
||||
local app="$1" id="$2" status="$3" source="${4:-git-hook}" pid="${5:-99999}" kind="${6:-build}" exit_code="${7:-0}"
|
||||
local dir="$DOKKU_LIB_ROOT/data/builds/$app"
|
||||
mkdir -p "$dir"
|
||||
local now
|
||||
now="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
||||
cat >"$dir/$id.json" <<EOF
|
||||
{
|
||||
"id": "$id",
|
||||
"app": "$app",
|
||||
"kind": "$kind",
|
||||
"pid": $pid,
|
||||
"started_at": "$now",
|
||||
"finished_at": "$now",
|
||||
"status": "$status",
|
||||
"source": "$source",
|
||||
"exit_code": $exit_code
|
||||
}
|
||||
EOF
|
||||
: >"$dir/$id.log"
|
||||
chown -R dokku:dokku "$DOKKU_LIB_ROOT/data/builds"
|
||||
}
|
||||
|
||||
write_running_record() {
|
||||
local app="$1" id="$2" pid="$3" source="${4:-git-hook}" kind="${5:-build}"
|
||||
local dir="$DOKKU_LIB_ROOT/data/builds/$app"
|
||||
mkdir -p "$dir"
|
||||
local now
|
||||
now="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
||||
cat >"$dir/$id.json" <<EOF
|
||||
{
|
||||
"id": "$id",
|
||||
"app": "$app",
|
||||
"kind": "$kind",
|
||||
"pid": $pid,
|
||||
"started_at": "$now",
|
||||
"status": "running",
|
||||
"source": "$source"
|
||||
}
|
||||
EOF
|
||||
: >"$dir/$id.log"
|
||||
chown -R dokku:dokku "$DOKKU_LIB_ROOT/data/builds"
|
||||
}
|
||||
|
||||
@test "(builds) builds:help" {
|
||||
run /bin/bash -c "dokku builds"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output_contains "Manage running and historical builds"
|
||||
|
||||
run /bin/bash -c "dokku builds:help"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output_contains "Manage running and historical builds"
|
||||
}
|
||||
|
||||
@test "(builds:list) returns empty list when no builds have run" {
|
||||
run /bin/bash -c "dokku builds:list $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "No builds recorded"
|
||||
}
|
||||
|
||||
@test "(builds:list) shows a finished record after a successful deploy" {
|
||||
run deploy_app python dokku@$DOKKU_DOMAIN:$TEST_APP
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builds:list $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "succeeded"
|
||||
assert_output_contains "git-hook"
|
||||
}
|
||||
|
||||
@test "(builds:list) shows an abandoned record when the PID is gone but the record is still running" {
|
||||
write_running_record "$TEST_APP" "ghost001" 99999 "git-hook"
|
||||
|
||||
run /bin/bash -c "dokku builds:list $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "abandoned"
|
||||
}
|
||||
|
||||
@test "(builds:list --kind=build) filters to build-kind records" {
|
||||
write_finished_record "$TEST_APP" "b1" "succeeded" "git-hook" 1001 "build"
|
||||
write_finished_record "$TEST_APP" "d1" "succeeded" "ps:restart" 1002 "deploy"
|
||||
|
||||
run /bin/bash -c "dokku builds:list $TEST_APP --kind build"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "b1"
|
||||
assert_output_not_contains "d1"
|
||||
}
|
||||
|
||||
@test "(builds:list --kind=deploy) filters to deploy-kind records" {
|
||||
write_finished_record "$TEST_APP" "b1" "succeeded" "git-hook" 1001 "build"
|
||||
write_finished_record "$TEST_APP" "d1" "succeeded" "ps:restart" 1002 "deploy"
|
||||
|
||||
run /bin/bash -c "dokku builds:list $TEST_APP --kind deploy"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "d1"
|
||||
assert_output_not_contains "b1"
|
||||
}
|
||||
|
||||
@test "(builds:list --kind=invalid) fails with a usage error" {
|
||||
run /bin/bash -c "dokku builds:list $TEST_APP --kind=garbage"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output_contains "Invalid --kind"
|
||||
}
|
||||
|
||||
@test "(builds:set) writes a per-app retention" {
|
||||
run /bin/bash -c "dokku builds:set $TEST_APP retention 5"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builds:report $TEST_APP --builds-retention"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "5"
|
||||
}
|
||||
|
||||
@test "(builds:set --global) writes the global retention" {
|
||||
run /bin/bash -c "dokku builds:set --global retention 7"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builds:report $TEST_APP --builds-computed-retention"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "7"
|
||||
|
||||
dokku builds:set --global retention "" || true
|
||||
}
|
||||
|
||||
@test "(builds:set) clears the override when called with no value" {
|
||||
dokku builds:set "$TEST_APP" retention 5
|
||||
|
||||
run /bin/bash -c "dokku builds:set $TEST_APP retention"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builds:report $TEST_APP --builds-retention"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
}
|
||||
|
||||
@test "(builds:set) rejects non-positive-integer values" {
|
||||
run /bin/bash -c "dokku builds:set $TEST_APP retention 0"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
|
||||
run /bin/bash -c "dokku builds:set $TEST_APP retention abc"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
}
|
||||
|
||||
@test "(builds:info) returns non-zero for a missing build-id" {
|
||||
run /bin/bash -c "dokku builds:info $TEST_APP nonexistent"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
}
|
||||
|
||||
@test "(builds:info) returns the recorded fields including --format json" {
|
||||
write_finished_record "$TEST_APP" "info001" "succeeded" "git-hook" 1234 "build"
|
||||
|
||||
run /bin/bash -c "dokku builds:info $TEST_APP info001"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "info001" -1
|
||||
assert_output_contains "succeeded"
|
||||
assert_output_contains "Log:"
|
||||
|
||||
run /bin/bash -c "dokku builds:info $TEST_APP info001 --format json"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "\"id\":\"info001\""
|
||||
assert_output_contains "\"log_path\":"
|
||||
}
|
||||
|
||||
@test "(builds:cancel) returns 0 with a friendly message when no lock is present" {
|
||||
run /bin/bash -c "dokku builds:cancel $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "App not currently deploying"
|
||||
}
|
||||
|
||||
@test "(builds:cancel) refuses to cancel a record whose status is not running" {
|
||||
write_finished_record "$TEST_APP" "done01" "succeeded" "git-hook" 1234 "build"
|
||||
mkdir -p "$DOKKU_LIB_ROOT/data/apps/$TEST_APP"
|
||||
echo "done01" >"$DOKKU_LIB_ROOT/data/apps/$TEST_APP/.deploy.lock"
|
||||
chown dokku:dokku "$DOKKU_LIB_ROOT/data/apps/$TEST_APP/.deploy.lock"
|
||||
|
||||
run /bin/bash -c "dokku builds:cancel $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "no longer running"
|
||||
|
||||
rm -f "$DOKKU_LIB_ROOT/data/apps/$TEST_APP/.deploy.lock"
|
||||
}
|
||||
|
||||
@test "(builds:cancel) marks an abandoned record as failed instead of canceled" {
|
||||
write_running_record "$TEST_APP" "abnd01" 99999 "git-hook"
|
||||
mkdir -p "$DOKKU_LIB_ROOT/data/apps/$TEST_APP"
|
||||
echo "abnd01" >"$DOKKU_LIB_ROOT/data/apps/$TEST_APP/.deploy.lock"
|
||||
chown dokku:dokku "$DOKKU_LIB_ROOT/data/apps/$TEST_APP/.deploy.lock"
|
||||
|
||||
run /bin/bash -c "dokku builds:cancel $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "already terminated"
|
||||
|
||||
run /bin/bash -c "dokku builds:info $TEST_APP abnd01"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "failed"
|
||||
}
|
||||
|
||||
@test "(builds:output) cats the log file for a finished build" {
|
||||
write_finished_record "$TEST_APP" "out001" "succeeded" "git-hook" 1234 "build"
|
||||
echo "build log line" >"$DOKKU_LIB_ROOT/data/builds/$TEST_APP/out001.log"
|
||||
chown dokku:dokku "$DOKKU_LIB_ROOT/data/builds/$TEST_APP/out001.log"
|
||||
|
||||
run /bin/bash -c "dokku builds:output $TEST_APP out001"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "build log line"
|
||||
}
|
||||
|
||||
@test "(builds:prune) prunes an app's records to retention" {
|
||||
dokku builds:set "$TEST_APP" retention 2
|
||||
|
||||
for i in 1 2 3 4 5; do
|
||||
write_finished_record "$TEST_APP" "p$i" "succeeded" "git-hook" $((1000 + i)) "build"
|
||||
sleep 1
|
||||
done
|
||||
|
||||
run /bin/bash -c "dokku builds:prune $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
count="$(ls $DOKKU_LIB_ROOT/data/builds/$TEST_APP/*.json 2>/dev/null | wc -l)"
|
||||
echo "remaining: $count"
|
||||
[[ "$count" -le 2 ]] || (echo "expected <=2 records, got $count" && false)
|
||||
}
|
||||
|
||||
@test "(builds:prune) reaps an abandoned record and finalizes it as failed" {
|
||||
write_running_record "$TEST_APP" "ghost02" 99999 "git-hook"
|
||||
|
||||
run /bin/bash -c "dokku builds:prune $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builds:info $TEST_APP ghost02"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "failed"
|
||||
}
|
||||
|
||||
@test "(builds:prune) skips live-running records" {
|
||||
local pid=$$
|
||||
write_running_record "$TEST_APP" "alive02" "$pid" "git-hook"
|
||||
|
||||
run /bin/bash -c "dokku builds:prune $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builds:info $TEST_APP alive02"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "running"
|
||||
}
|
||||
|
||||
@test "(builds) [storage] directory is removed on apps:destroy" {
|
||||
write_finished_record "$TEST_APP" "del01" "succeeded" "git-hook" 1234 "build"
|
||||
[[ -d "$DOKKU_LIB_ROOT/data/builds/$TEST_APP" ]]
|
||||
|
||||
run /bin/bash -c "dokku --force apps:destroy $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
[[ ! -d "$DOKKU_LIB_ROOT/data/builds/$TEST_APP" ]]
|
||||
|
||||
# Recreate so teardown can run cleanly.
|
||||
create_app
|
||||
}
|
||||
|
||||
@test "(builds:report) emits new stripped JSON keys alongside legacy" {
|
||||
run /bin/bash -c "dokku builds:report $TEST_APP --format json | jq -r 'has(\"retention\") and has(\"builds-retention\")'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku builds:report $TEST_APP --format json | jq -r 'has(\"global-retention\") and has(\"builds-global-retention\")'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku builds:report $TEST_APP --format json | jq -r 'has(\"computed-retention\") and has(\"builds-computed-retention\")'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
# build-* status keys have no plugin-prefix collision, so they pass through unchanged
|
||||
run /bin/bash -c "dokku builds:report $TEST_APP --format json | jq -r 'has(\"build-id\")'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
}
|
||||
84
tests/unit/caddy-vhosts.bats
Normal file
84
tests/unit/caddy-vhosts.bats
Normal file
@@ -0,0 +1,84 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
setup() {
|
||||
create_app
|
||||
}
|
||||
|
||||
teardown() {
|
||||
destroy_app
|
||||
dokku caddy:set --global log-level >/dev/null 2>&1 || true
|
||||
dokku caddy:set --global tls-internal >/dev/null 2>&1 || true
|
||||
}
|
||||
|
||||
@test "(caddy:report) info-flag works before deploy" {
|
||||
run /bin/bash -c "dokku caddy:report $TEST_APP --caddy-computed-tls-internal"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "false"
|
||||
|
||||
run /bin/bash -c "dokku caddy:report $TEST_APP --caddy-invalid-flag"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output_contains "Invalid flag passed"
|
||||
}
|
||||
|
||||
@test "(caddy:report) --format json" {
|
||||
run /bin/bash -c "dokku caddy:set --global log-level"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku caddy:report --global --format json | jq -e ."
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku caddy:report --global --format json | jq -r '.\"computed-log-level\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "ERROR"
|
||||
|
||||
run /bin/bash -c "dokku caddy:report --global"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "global caddy information"
|
||||
}
|
||||
|
||||
@test "(caddy:report) tls-internal raw global computed" {
|
||||
run /bin/bash -c "dokku caddy:set --global tls-internal"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku caddy:report $TEST_APP --caddy-tls-internal"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku caddy:report $TEST_APP --caddy-computed-tls-internal"
|
||||
assert_success
|
||||
assert_output "false"
|
||||
|
||||
run /bin/bash -c "dokku caddy:set --global tls-internal true"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku caddy:report $TEST_APP --caddy-global-tls-internal"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku caddy:report $TEST_APP --caddy-computed-tls-internal"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku caddy:set $TEST_APP tls-internal false"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku caddy:report $TEST_APP --caddy-tls-internal"
|
||||
assert_success
|
||||
assert_output "false"
|
||||
|
||||
run /bin/bash -c "dokku caddy:report $TEST_APP --caddy-computed-tls-internal"
|
||||
assert_success
|
||||
assert_output "false"
|
||||
}
|
||||
@@ -18,6 +18,219 @@ teardown() {
|
||||
dokku nginx:start
|
||||
}
|
||||
|
||||
@test "(caddy:report) --global global vs computed log-level" {
|
||||
run /bin/bash -c "dokku caddy:report --global --caddy-global-log-level"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku caddy:report --global --caddy-computed-log-level"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "ERROR"
|
||||
|
||||
run /bin/bash -c "dokku caddy:set --global log-level DEBUG"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku caddy:report --global --caddy-global-log-level"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "DEBUG"
|
||||
|
||||
run /bin/bash -c "dokku caddy:report --global --caddy-computed-log-level"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "DEBUG"
|
||||
|
||||
run /bin/bash -c "dokku caddy:set --global log-level"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku caddy:report --global --caddy-global-log-level"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku caddy:report --global --caddy-computed-log-level"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "ERROR"
|
||||
}
|
||||
|
||||
@test "(caddy:report) --global raw and computed keys in --format json" {
|
||||
run /bin/bash -c "dokku caddy:report --global --format json | jq -r '.\"global-image\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku caddy:report --global --format json | jq -r '.\"computed-image\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_exists
|
||||
|
||||
run /bin/bash -c "dokku caddy:report --global --format json | jq -r '.\"global-polling-interval\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku caddy:report --global --format json | jq -r '.\"computed-polling-interval\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "5s"
|
||||
}
|
||||
|
||||
@test "(caddy) global-only keys" {
|
||||
for key in image letsencrypt-email letsencrypt-server log-level polling-interval; do
|
||||
run /bin/bash -c "dokku caddy:set $TEST_APP $key somevalue"
|
||||
echo "key: $key"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output_contains "can only be set globally"
|
||||
done
|
||||
|
||||
run /bin/bash -c "dokku caddy:set $TEST_APP tls-internal true"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku caddy:report $TEST_APP --caddy-tls-internal"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku caddy:set $TEST_APP tls-internal"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(caddy:report) tls-internal raw vs computed vs global" {
|
||||
run /bin/bash -c "dokku caddy:report $TEST_APP --caddy-tls-internal"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku caddy:report $TEST_APP --caddy-computed-tls-internal"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "false"
|
||||
|
||||
run /bin/bash -c "dokku caddy:report $TEST_APP --caddy-global-tls-internal"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku caddy:set $TEST_APP tls-internal true"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku caddy:report $TEST_APP --caddy-tls-internal"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku caddy:report $TEST_APP --caddy-computed-tls-internal"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku caddy:set $TEST_APP tls-internal"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku caddy:report $TEST_APP --caddy-tls-internal"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku caddy:report $TEST_APP --caddy-computed-tls-internal"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "false"
|
||||
}
|
||||
|
||||
@test "(caddy:set) --global tls-internal" {
|
||||
run /bin/bash -c "dokku caddy:set --global tls-internal true"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku caddy:report --global --caddy-global-tls-internal"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku caddy:report $TEST_APP --caddy-tls-internal"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku caddy:report $TEST_APP --caddy-computed-tls-internal"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku caddy:report $TEST_APP --caddy-global-tls-internal"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku caddy:set $TEST_APP tls-internal false"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku caddy:report $TEST_APP --caddy-tls-internal"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "false"
|
||||
|
||||
run /bin/bash -c "dokku caddy:report $TEST_APP --caddy-computed-tls-internal"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "false"
|
||||
|
||||
run /bin/bash -c "dokku caddy:set $TEST_APP tls-internal"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku caddy:set --global tls-internal"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(caddy) caddy:help" {
|
||||
run /bin/bash -c "dokku caddy"
|
||||
echo "output: $output"
|
||||
@@ -137,12 +350,12 @@ teardown() {
|
||||
assert_success
|
||||
assert_output "$TEST_APP.${DOKKU_DOMAIN}"
|
||||
|
||||
run /bin/bash -c "dokku --quiet ports:report $TEST_APP --ports-map"
|
||||
run /bin/bash -c "dokku ports:report $TEST_APP --ports-map"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output_not_exists
|
||||
|
||||
run /bin/bash -c "dokku --quiet ports:report $TEST_APP --ports-map-detected"
|
||||
run /bin/bash -c "dokku ports:report $TEST_APP --ports-map-detected"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output "http:80:5000 https:443:5000"
|
||||
|
||||
@@ -41,6 +41,141 @@ teardown() {
|
||||
assert_output "$help_output"
|
||||
}
|
||||
|
||||
@test "(certs:report) info-flag works before deploy" {
|
||||
run /bin/bash -c "dokku certs:report $TEST_APP --ssl-hostnames"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku certs:report $TEST_APP --ssl-dir"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "/$TEST_APP/tls"
|
||||
|
||||
run /bin/bash -c "dokku certs:report $TEST_APP --ssl-invalid-flag"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output_contains "Invalid flag passed"
|
||||
}
|
||||
|
||||
@test "(certs:report) --global --format json" {
|
||||
run /bin/bash -c "dokku certs:report --global --format json | jq -e ."
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "{}"
|
||||
|
||||
run /bin/bash -c "dokku certs:report --global"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "global ssl information"
|
||||
|
||||
run /bin/bash -c "dokku certs:report --global --ssl-bogus"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output_contains "Invalid flag passed"
|
||||
}
|
||||
|
||||
@test "(certs:report) reports hostnames and subject for a CN-only certificate" {
|
||||
run /bin/bash -c "dokku certs:add $TEST_APP $BATS_TMPDIR/tls/server.crt $BATS_TMPDIR/tls/server.key"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku certs:report $TEST_APP --ssl-hostnames"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "dokku.me"
|
||||
|
||||
run /bin/bash -c "dokku certs:report $TEST_APP --ssl-subject"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "CN=dokku.me"
|
||||
}
|
||||
|
||||
@test "(certs:report) preserves multi-field subject order" {
|
||||
run /bin/bash -c "dokku certs:add $TEST_APP $BATS_TMPDIR/tls/domain.com.crt $BATS_TMPDIR/tls/domain.com.key"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku certs:report $TEST_APP --ssl-subject"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "C=US; ST=California; L=San Francisco; O=Expa; OU=Operations; CN=node-js-app.dokku.me"
|
||||
|
||||
run /bin/bash -c "dokku certs:report $TEST_APP --ssl-hostnames"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "node-js-app.dokku.me"
|
||||
}
|
||||
|
||||
@test "(certs:report) reports the CN and all SANs as hostnames" {
|
||||
local SANS_TLS="$BATS_TMPDIR/tls-sans"
|
||||
mkdir -p "$SANS_TLS"
|
||||
tar xf "$BATS_TEST_DIRNAME/server_ssl_sans.tar" -C "$SANS_TLS"
|
||||
sudo chown -R dokku:dokku "$SANS_TLS"
|
||||
|
||||
run /bin/bash -c "dokku certs:add $TEST_APP $SANS_TLS/server.crt $SANS_TLS/server.key"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku certs:report $TEST_APP --ssl-hostnames"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "test.dokku.me www.test.app.dokku.me www.test.dokku.me"
|
||||
|
||||
rm -rf "$SANS_TLS"
|
||||
}
|
||||
|
||||
@test "(certs) get_ssl_hostnames parses a CN-only certificate" {
|
||||
run /bin/bash -c "dokku certs:add $TEST_APP $BATS_TMPDIR/tls/server.crt $BATS_TMPDIR/tls/server.key"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
source "$PLUGIN_CORE_AVAILABLE_PATH/certs/functions"
|
||||
run get_ssl_hostnames "$TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "dokku.me"
|
||||
}
|
||||
|
||||
@test "(certs) get_ssl_hostnames includes the CN and SANs" {
|
||||
local SANS_TLS="$BATS_TMPDIR/tls-sans"
|
||||
mkdir -p "$SANS_TLS"
|
||||
tar xf "$BATS_TEST_DIRNAME/server_ssl_sans.tar" -C "$SANS_TLS"
|
||||
sudo chown -R dokku:dokku "$SANS_TLS"
|
||||
|
||||
run /bin/bash -c "dokku certs:add $TEST_APP $SANS_TLS/server.crt $SANS_TLS/server.key"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
source "$PLUGIN_CORE_AVAILABLE_PATH/certs/functions"
|
||||
run get_ssl_hostnames "$TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_line "test.dokku.me"
|
||||
assert_line "www.test.dokku.me"
|
||||
assert_line "www.test.app.dokku.me"
|
||||
assert_line_count 3
|
||||
|
||||
rm -rf "$SANS_TLS"
|
||||
}
|
||||
|
||||
@test "(certs) certs:add" {
|
||||
run /bin/bash -c "dokku certs:add $TEST_APP $BATS_TMPDIR/tls/server.crt $BATS_TMPDIR/tls/server.key"
|
||||
echo "output: $output"
|
||||
@@ -48,6 +183,40 @@ teardown() {
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(certs:add) preserves explicit https:443 port mapping" {
|
||||
run /bin/bash -c "dokku ports:set $TEST_APP http:80:80 https:443:443"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku certs:add $TEST_APP $BATS_TMPDIR/tls/server.crt $BATS_TMPDIR/tls/server.key"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku --quiet ports:report $TEST_APP --ports-map"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output "http:80:80 https:443:443"
|
||||
}
|
||||
|
||||
@test "(certs:add) adds default https:443 mapping when none exists" {
|
||||
run /bin/bash -c "dokku ports:set $TEST_APP http:80:5000"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku certs:add $TEST_APP $BATS_TMPDIR/tls/server.crt $BATS_TMPDIR/tls/server.key"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku --quiet ports:report $TEST_APP --ports-map"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output "http:80:5000 https:443:5000"
|
||||
}
|
||||
|
||||
@test "(certs) certs:add with multiple dots in the filename" {
|
||||
run /bin/bash -c "dokku certs:add $TEST_APP $BATS_TMPDIR/tls/domain.com.crt $BATS_TMPDIR/tls/domain.com.key"
|
||||
echo "output: $output"
|
||||
@@ -92,6 +261,44 @@ teardown() {
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(certs) certs-set plugin trigger" {
|
||||
run_plugn_trigger certs-set "$TEST_APP" "$BATS_TMPDIR/tls/server.crt" "$BATS_TMPDIR/tls/server.key"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
[[ -f "$DOKKU_ROOT/$TEST_APP/tls/server.crt" ]]
|
||||
[[ -f "$DOKKU_ROOT/$TEST_APP/tls/server.key" ]]
|
||||
}
|
||||
|
||||
@test "(certs) certs-set plugin trigger missing key file" {
|
||||
run_plugn_trigger certs-set "$TEST_APP" "$BATS_TMPDIR/tls/server.crt" "/nonexistent/server.key"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output_contains "KEY file specified not found"
|
||||
}
|
||||
|
||||
@test "(certs) certs-remove plugin trigger" {
|
||||
run /bin/bash -c "dokku certs:add $TEST_APP $BATS_TMPDIR/tls/server.crt $BATS_TMPDIR/tls/server.key"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run_plugn_trigger certs-remove "$TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
[[ ! -d "$DOKKU_ROOT/$TEST_APP/tls" ]]
|
||||
}
|
||||
|
||||
@test "(certs) certs-remove plugin trigger without endpoint" {
|
||||
run_plugn_trigger certs-remove "$TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output_contains "An app-specific SSL endpoint is not defined"
|
||||
}
|
||||
|
||||
@test "(certs) certs:show" {
|
||||
run /bin/bash -c "dokku certs:show fake-app-name 2>&1"
|
||||
echo "output: $output"
|
||||
|
||||
@@ -16,6 +16,94 @@ teardown() {
|
||||
global_teardown
|
||||
}
|
||||
|
||||
@test "(checks:report) info-flag works before deploy" {
|
||||
run /bin/bash -c "dokku checks:report $TEST_APP --checks-wait-to-retire"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku checks:set $TEST_APP wait-to-retire 30"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku checks:report $TEST_APP --checks-wait-to-retire"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "30"
|
||||
|
||||
run /bin/bash -c "dokku checks:report $TEST_APP --checks-invalid-flag"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output_contains "Invalid flag passed"
|
||||
}
|
||||
|
||||
@test "(checks:report) --global --format json" {
|
||||
run /bin/bash -c "dokku checks:set --global wait-to-retire"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku checks:report --global --format json | jq -e ."
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku checks:report --global --format json | jq -r '.\"global-wait-to-retire\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku checks:report --global --format json | jq -r '.\"computed-wait-to-retire\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "60"
|
||||
|
||||
run /bin/bash -c "dokku checks:set --global wait-to-retire 90"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku checks:report --global --format json | jq -r '.\"global-wait-to-retire\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "90"
|
||||
|
||||
run /bin/bash -c "dokku checks:report --global --format json | jq -r '.\"computed-wait-to-retire\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "90"
|
||||
|
||||
run /bin/bash -c "dokku checks:report --global"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "global checks information"
|
||||
|
||||
run /bin/bash -c "dokku checks:set --global wait-to-retire"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku checks:report --global --checks-global-wait-to-retire"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku checks:report --global --checks-computed-wait-to-retire"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "60"
|
||||
}
|
||||
|
||||
@test "(checks) checks:help" {
|
||||
run /bin/bash -c "dokku checks"
|
||||
echo "output: $output"
|
||||
@@ -36,7 +124,7 @@ teardown() {
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku config:get $TEST_APP DOKKU_CHECKS_DISABLED"
|
||||
run /bin/bash -c "dokku checks:report $TEST_APP --checks-disabled-list"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output "_all_"
|
||||
@@ -48,30 +136,30 @@ teardown() {
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku config:get $TEST_APP DOKKU_CHECKS_DISABLED"
|
||||
run /bin/bash -c "dokku checks:report $TEST_APP --checks-disabled-list"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output "_all_"
|
||||
|
||||
run /bin/bash -c "dokku config:get $TEST_APP DOKKU_CHECKS_SKIPPED"
|
||||
run /bin/bash -c "dokku checks:report $TEST_APP --checks-skipped-list"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output_not_exists
|
||||
assert_output "none"
|
||||
|
||||
run /bin/bash -c "dokku checks:enable $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku config:get $TEST_APP DOKKU_CHECKS_DISABLED"
|
||||
run /bin/bash -c "dokku checks:report $TEST_APP --checks-disabled-list"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output_not_exists
|
||||
assert_output "none"
|
||||
|
||||
run /bin/bash -c "dokku config:get $TEST_APP DOKKU_CHECKS_SKIPPED"
|
||||
run /bin/bash -c "dokku checks:report $TEST_APP --checks-skipped-list"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output_not_exists
|
||||
assert_output "none"
|
||||
}
|
||||
|
||||
@test "(checks) checks:disable -> checks:skip" {
|
||||
@@ -80,27 +168,27 @@ teardown() {
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku config:get $TEST_APP DOKKU_CHECKS_DISABLED"
|
||||
run /bin/bash -c "dokku checks:report $TEST_APP --checks-disabled-list"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output "web,worker,urgentworker,notifications"
|
||||
|
||||
run /bin/bash -c "dokku config:get $TEST_APP DOKKU_CHECKS_SKIPPED"
|
||||
run /bin/bash -c "dokku checks:report $TEST_APP --checks-skipped-list"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output_not_exists
|
||||
assert_output "none"
|
||||
|
||||
run /bin/bash -c "dokku checks:skip $TEST_APP urgentworker,worker"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku config:get $TEST_APP DOKKU_CHECKS_SKIPPED"
|
||||
run /bin/bash -c "dokku checks:report $TEST_APP --checks-skipped-list"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output "urgentworker,worker"
|
||||
|
||||
run /bin/bash -c "dokku config:get $TEST_APP DOKKU_CHECKS_DISABLED"
|
||||
run /bin/bash -c "dokku checks:report $TEST_APP --checks-disabled-list"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output "web,notifications"
|
||||
@@ -112,7 +200,7 @@ teardown() {
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku config:get $TEST_APP DOKKU_CHECKS_SKIPPED"
|
||||
run /bin/bash -c "dokku checks:report $TEST_APP --checks-skipped-list"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output "_all_"
|
||||
@@ -124,30 +212,30 @@ teardown() {
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku config:get $TEST_APP DOKKU_CHECKS_SKIPPED"
|
||||
run /bin/bash -c "dokku checks:report $TEST_APP --checks-skipped-list"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output "_all_"
|
||||
|
||||
run /bin/bash -c "dokku config:get $TEST_APP DOKKU_CHECKS_DISABLED"
|
||||
run /bin/bash -c "dokku checks:report $TEST_APP --checks-disabled-list"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output_not_exists
|
||||
assert_output "none"
|
||||
|
||||
run /bin/bash -c "dokku checks:enable $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku config:get $TEST_APP DOKKU_CHECKS_SKIPPED"
|
||||
run /bin/bash -c "dokku checks:report $TEST_APP --checks-skipped-list"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output_not_exists
|
||||
assert_output "none"
|
||||
|
||||
run /bin/bash -c "dokku config:get $TEST_APP DOKKU_CHECKS_DISABLED"
|
||||
run /bin/bash -c "dokku checks:report $TEST_APP --checks-disabled-list"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output_not_exists
|
||||
assert_output "none"
|
||||
}
|
||||
|
||||
@test "(checks) checks:skip -> checks:disable" {
|
||||
@@ -156,27 +244,27 @@ teardown() {
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku config:get $TEST_APP DOKKU_CHECKS_SKIPPED"
|
||||
run /bin/bash -c "dokku checks:report $TEST_APP --checks-skipped-list"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output "web,worker,urgentworker,notifications"
|
||||
|
||||
run /bin/bash -c "dokku config:get $TEST_APP DOKKU_CHECKS_DISABLED"
|
||||
run /bin/bash -c "dokku checks:report $TEST_APP --checks-disabled-list"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output_not_exists
|
||||
assert_output "none"
|
||||
|
||||
run /bin/bash -c "dokku checks:disable $TEST_APP urgentworker,worker"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku config:get $TEST_APP DOKKU_CHECKS_DISABLED"
|
||||
run /bin/bash -c "dokku checks:report $TEST_APP --checks-disabled-list"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output "urgentworker,worker"
|
||||
|
||||
run /bin/bash -c "dokku config:get $TEST_APP DOKKU_CHECKS_SKIPPED"
|
||||
run /bin/bash -c "dokku checks:report $TEST_APP --checks-skipped-list"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output "web,notifications"
|
||||
|
||||
@@ -4,16 +4,16 @@ load test_helper
|
||||
|
||||
setup() {
|
||||
global_setup
|
||||
[[ -f ${DOKKU_ROOT}/ENV ]] && mv -f ${DOKKU_ROOT}/ENV ${DOKKU_ROOT}/ENV.bak
|
||||
sudo -H -u dokku /bin/bash -c "echo 'export global_test=true' > ${DOKKU_ROOT}/ENV"
|
||||
mkdir -p "${DOKKU_LIB_ROOT}/config/--global"
|
||||
[[ -f ${DOKKU_LIB_ROOT}/config/--global/ENV ]] && mv -f ${DOKKU_LIB_ROOT}/config/--global/ENV ${DOKKU_LIB_ROOT}/config/--global/ENV.bak
|
||||
sudo -H -u dokku /bin/bash -c "echo 'export global_test=true' > ${DOKKU_LIB_ROOT}/config/--global/ENV"
|
||||
create_app
|
||||
}
|
||||
|
||||
teardown() {
|
||||
destroy_app
|
||||
ls -la ${DOKKU_ROOT}
|
||||
if [[ -f ${DOKKU_ROOT}/ENV.bak ]]; then
|
||||
mv -f ${DOKKU_ROOT}/ENV.bak ${DOKKU_ROOT}/ENV
|
||||
if [[ -f ${DOKKU_LIB_ROOT}/config/--global/ENV.bak ]]; then
|
||||
mv -f ${DOKKU_LIB_ROOT}/config/--global/ENV.bak ${DOKKU_LIB_ROOT}/config/--global/ENV
|
||||
fi
|
||||
global_teardown
|
||||
}
|
||||
|
||||
@@ -4,16 +4,16 @@ load test_helper
|
||||
|
||||
setup() {
|
||||
global_setup
|
||||
[[ -f ${DOKKU_ROOT}/ENV ]] && mv -f ${DOKKU_ROOT}/ENV ${DOKKU_ROOT}/ENV.bak
|
||||
sudo -H -u dokku /bin/bash -c "echo 'export global_test=true' > ${DOKKU_ROOT}/ENV"
|
||||
mkdir -p "${DOKKU_LIB_ROOT}/config/--global"
|
||||
[[ -f ${DOKKU_LIB_ROOT}/config/--global/ENV ]] && mv -f ${DOKKU_LIB_ROOT}/config/--global/ENV ${DOKKU_LIB_ROOT}/config/--global/ENV.bak
|
||||
sudo -H -u dokku /bin/bash -c "echo 'export global_test=true' > ${DOKKU_LIB_ROOT}/config/--global/ENV"
|
||||
create_app
|
||||
}
|
||||
|
||||
teardown() {
|
||||
destroy_app
|
||||
ls -la ${DOKKU_ROOT}
|
||||
if [[ -f ${DOKKU_ROOT}/ENV.bak ]]; then
|
||||
mv -f ${DOKKU_ROOT}/ENV.bak ${DOKKU_ROOT}/ENV
|
||||
if [[ -f ${DOKKU_LIB_ROOT}/config/--global/ENV.bak ]]; then
|
||||
mv -f ${DOKKU_LIB_ROOT}/config/--global/ENV.bak ${DOKKU_LIB_ROOT}/config/--global/ENV
|
||||
fi
|
||||
global_teardown
|
||||
}
|
||||
@@ -399,6 +399,57 @@ teardown() {
|
||||
assert_output "hello world"
|
||||
}
|
||||
|
||||
@test "(config) config:set --encoded preserves decoded bytes" {
|
||||
local encoded_echo encoded_printf encoded_echo_n encoded_cat tmpfile
|
||||
encoded_echo="$(echo "myvalue" | base64 -w 0)"
|
||||
encoded_printf="$(printf '%s' "myvalue" | base64 -w 0)"
|
||||
encoded_echo_n="$(echo -n "myvalue" | base64 -w 0)"
|
||||
tmpfile="$(mktemp)"
|
||||
printf 'filecontent' >"$tmpfile"
|
||||
encoded_cat="$(cat "$tmpfile" | base64 -w 0)"
|
||||
rm -f "$tmpfile"
|
||||
|
||||
run /bin/bash -c "dokku config:set --encoded --no-restart $TEST_APP test_echo=$encoded_echo"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku config:get $TEST_APP test_echo | wc -c"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output "9"
|
||||
|
||||
run /bin/bash -c "dokku config:set --encoded --no-restart $TEST_APP test_printf=$encoded_printf"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku config:get $TEST_APP test_printf | wc -c"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output "8"
|
||||
|
||||
run /bin/bash -c "dokku config:set --encoded --no-restart $TEST_APP test_echo_n=$encoded_echo_n"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku config:get $TEST_APP test_echo_n | wc -c"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output "8"
|
||||
|
||||
run /bin/bash -c "dokku config:set --encoded --no-restart $TEST_APP test_cat=$encoded_cat"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku config:get $TEST_APP test_cat | wc -c"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output "12"
|
||||
}
|
||||
|
||||
@test "(config) config:clear" {
|
||||
run ssh "dokku@$DOKKU_DOMAIN" config:set $TEST_APP test_var=true test_var2=\"hello world\" test_var3=\"with\\nnewline\"
|
||||
echo "output: $output"
|
||||
@@ -535,3 +586,134 @@ teardown() {
|
||||
echo "status: $status"
|
||||
assert_output '[{"name":"BKEY","value":"true"},{"name":"aKey","value":"true"},{"name":"bKey","value":"true"},{"name":"zKey","value":"true"}]'
|
||||
}
|
||||
|
||||
@test "(config) install migrates a pre-0.38 ENV file before plugins read it" {
|
||||
# The checks plugin installs before the config plugin, so before this was
|
||||
# fixed it read the not-yet-relocated ENV file, found nothing, and migrated
|
||||
# DOKKU_CHECKS_SKIPPED to the checks property silently doing nothing.
|
||||
run /bin/bash -c "sudo rm -f ${DOKKU_LIB_ROOT}/config/config/$TEST_APP/env-migrated ${DOKKU_LIB_ROOT}/config/checks/$TEST_APP/skipped"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "echo 'export DOKKU_CHECKS_SKIPPED=worker' | sudo tee $DOKKU_ROOT/$TEST_APP/ENV && sudo chown dokku:dokku $DOKKU_ROOT/$TEST_APP/ENV"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku plugin:install --core"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku checks:report $TEST_APP --checks-skipped-list"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "worker"
|
||||
|
||||
run /bin/bash -c "dokku config:show $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "DOKKU_CHECKS_SKIPPED" 0
|
||||
|
||||
run /bin/bash -c "test -f $DOKKU_ROOT/$TEST_APP/ENV"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
}
|
||||
|
||||
@test "(config) config-migrate-env preserves a stale ENV file without importing it" {
|
||||
# drain once so the migration is on record, which is the state releases 0.38.0
|
||||
# through 0.38.25 left behind alongside the ENV file staged below
|
||||
run_plugn_trigger config-migrate-env
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku config:set --no-restart $TEST_APP KEEP=new"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
stage_stale_env "KEEP=old" "RESURRECTED=yes"
|
||||
|
||||
run_plugn_trigger config-migrate-env
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "the current config takes precedence for KEEP RESURRECTED"
|
||||
assert_output_contains "$DOKKU_ROOT/$TEST_APP/ENV.migrated"
|
||||
assert_output_contains "then delete it"
|
||||
|
||||
run /bin/bash -c "dokku config:get $TEST_APP KEEP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "new"
|
||||
|
||||
run /bin/bash -c "dokku config:get $TEST_APP RESURRECTED"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
|
||||
run /bin/bash -c "test -f $DOKKU_ROOT/$TEST_APP/ENV"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
|
||||
run /bin/bash -c "sudo cat $DOKKU_ROOT/$TEST_APP/ENV.migrated"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "RESURRECTED"
|
||||
|
||||
run /bin/bash -c "sudo rm -f $DOKKU_ROOT/$TEST_APP/ENV.migrated"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(config) install reports a stale ENV file it did not import" {
|
||||
# the apps plugin installs before config and drains through a captured
|
||||
# trigger, so the report only reaches the operator if that stderr is streamed
|
||||
run_plugn_trigger config-migrate-env
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku config:set --no-restart $TEST_APP KEEP=new"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
stage_stale_env "KEEP=old"
|
||||
|
||||
run /bin/bash -c "dokku plugin:install --core"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "$DOKKU_ROOT/$TEST_APP/ENV.migrated"
|
||||
|
||||
run /bin/bash -c "dokku config:get $TEST_APP KEEP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "new"
|
||||
|
||||
run /bin/bash -c "sudo rm -f $DOKKU_ROOT/$TEST_APP/ENV.migrated"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
}
|
||||
|
||||
stage_stale_env() {
|
||||
declare desc="writes a legacy ENV file at the pre-0.38 path for the test app"
|
||||
|
||||
local contents=""
|
||||
for pair in "$@"; do
|
||||
contents+="export $pair\n"
|
||||
done
|
||||
|
||||
run /bin/bash -c "printf '$contents' | sudo tee $DOKKU_ROOT/$TEST_APP/ENV && sudo chown dokku:dokku $DOKKU_ROOT/$TEST_APP/ENV"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@@ -91,3 +91,32 @@ teardown() {
|
||||
echo "status: $status"
|
||||
assert_output "false"
|
||||
}
|
||||
|
||||
@test "(common) fn-docker-args-split does not expand injected commands" {
|
||||
export DOKKU_TEST_PAYLOAD='--label x=$(id)'
|
||||
run /bin/bash -c "source '$PLUGIN_CORE_AVAILABLE_PATH/common/functions'; fn-docker-args-split \"\$DOKKU_TEST_PAYLOAD\" | tr '\\0' '\\n'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_line 1 'x=$(id)'
|
||||
[[ "$output" != *"uid="* ]] || flunk "id command output leaked - value was expanded"
|
||||
|
||||
export DOKKU_TEST_PAYLOAD='--label x=`id`'
|
||||
run /bin/bash -c "source '$PLUGIN_CORE_AVAILABLE_PATH/common/functions'; fn-docker-args-split \"\$DOKKU_TEST_PAYLOAD\" | tr '\\0' '\\n'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_line 1 'x=`id`'
|
||||
[[ "$output" != *"uid="* ]] || flunk "id command output leaked - value was expanded"
|
||||
|
||||
unset DOKKU_TEST_PAYLOAD
|
||||
}
|
||||
|
||||
@test "(common) fn-docker-args-split preserves quoted tokens" {
|
||||
run /bin/bash -c "source '$PLUGIN_CORE_AVAILABLE_PATH/common/functions'; fn-docker-args-split \"--label 'a b'\" | tr '\\0' '\\n'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_line 0 "--label"
|
||||
assert_line 1 "a b"
|
||||
}
|
||||
|
||||
@@ -112,6 +112,16 @@ teardown() {
|
||||
assert_urls "http://dokku.example.com" "http://${TEST_APP}.${DOKKU_DOMAIN}" "https://dokku.example.com" "https://${TEST_APP}.${DOKKU_DOMAIN}" "https://test.${DOKKU_DOMAIN}" "http://test.${DOKKU_DOMAIN}"
|
||||
}
|
||||
|
||||
@test "(core) release_and_deploy does not emit command not found errors" {
|
||||
run deploy_app
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_not_contains "fn-plugin-property-get-default: command not found"
|
||||
assert_output_not_contains "fn-plugin-property-get: command not found"
|
||||
assert_output_not_contains "/common/property-functions: No such file or directory"
|
||||
}
|
||||
|
||||
@test "(core) git-remote (off-port)" {
|
||||
run deploy_app nodejs-express ssh://dokku@127.0.0.1:22333/$TEST_APP
|
||||
echo "output: $output"
|
||||
|
||||
263
tests/unit/cron-1.bats
Normal file
263
tests/unit/cron-1.bats
Normal file
@@ -0,0 +1,263 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
setup() {
|
||||
global_setup
|
||||
create_app
|
||||
mkdir -p /var/lib/dokku/plugins/available/cron-entries
|
||||
mkdir -p /var/lib/dokku/plugins/enabled/cron-entries
|
||||
cat >"/var/lib/dokku/plugins/available/cron-entries/plugin.toml" <<EOF
|
||||
[plugin]
|
||||
description = "dokku test cron-entries plugin"
|
||||
version = "0.0.1"
|
||||
[plugin.config]
|
||||
EOF
|
||||
cp /var/lib/dokku/plugins/available/cron-entries/plugin.toml /var/lib/dokku/plugins/enabled/cron-entries/plugin.toml
|
||||
}
|
||||
|
||||
teardown() {
|
||||
rm -rf /var/lib/dokku/plugins/available/cron-entries /var/lib/dokku/plugins/enabled/cron-entries
|
||||
# restore the default scheduler before destroy: a k3s-scheduled app cannot be
|
||||
# torn down cleanly without a cluster, and would otherwise leak into the next
|
||||
# test's cleanup_apps
|
||||
dokku scheduler:set "$TEST_APP" selected docker-local 2>/dev/null || true
|
||||
destroy_app
|
||||
global_teardown
|
||||
}
|
||||
|
||||
@test "(cron) cron:help" {
|
||||
run /bin/bash -c "dokku cron"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output_contains "Manage scheduled cron tasks"
|
||||
help_output="$output"
|
||||
|
||||
run /bin/bash -c "dokku cron:help"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output_contains "Manage scheduled cron tasks"
|
||||
assert_output "$help_output"
|
||||
}
|
||||
|
||||
@test "(cron) installed" {
|
||||
run /bin/bash -c "test -f /etc/sudoers.d/dokku-cron"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
}
|
||||
|
||||
@test "(cron) scheduler-uses-host-cron" {
|
||||
run /bin/bash -c "dokku plugin:trigger scheduler-uses-host-cron docker-local"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku plugin:trigger scheduler-uses-host-cron k3s"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "false"
|
||||
|
||||
run /bin/bash -c "dokku plugin:trigger scheduler-uses-host-cron null"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "false"
|
||||
|
||||
run /bin/bash -c "dokku plugin:trigger scheduler-uses-host-cron bogus-scheduler"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
}
|
||||
|
||||
@test "(cron) invalid [missing-keys]" {
|
||||
run deploy_app python dokku@$DOKKU_DOMAIN:$TEST_APP template_cron_file_invalid
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
}
|
||||
|
||||
@test "(cron) invalid [schedule]" {
|
||||
run deploy_app python dokku@$DOKKU_DOMAIN:$TEST_APP template_cron_file_invalid_schedule
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
}
|
||||
|
||||
@test "(cron) invalid [seconds]" {
|
||||
run deploy_app python dokku@$DOKKU_DOMAIN:$TEST_APP template_cron_file_invalid_schedule_seconds
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
}
|
||||
|
||||
@test "(cron) create [single-verbose]" {
|
||||
run deploy_app python dokku@$DOKKU_DOMAIN:$TEST_APP template_cron_file_valid_single
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
cron_id="$(dokku cron:list $TEST_APP --format json | jq -r '.[0].id')"
|
||||
|
||||
run /bin/bash -c "cat /var/spool/cron/crontabs/dokku"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "dokku cron:run $TEST_APP $cron_id"
|
||||
assert_output_contains "python3 task.py schedule" 0
|
||||
}
|
||||
|
||||
@test "(cron) create [single-short]" {
|
||||
run deploy_app python dokku@$DOKKU_DOMAIN:$TEST_APP template_cron_file_valid_short
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
cron_id="$(dokku cron:list $TEST_APP --format json | jq -r '.[0].id')"
|
||||
|
||||
run /bin/bash -c "cat /var/spool/cron/crontabs/dokku"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "dokku cron:run $TEST_APP $cron_id"
|
||||
assert_output_contains "python3 task.py daily" 0
|
||||
}
|
||||
|
||||
@test "(cron) k3s-scheduled app skips host crontab" {
|
||||
run deploy_app python dokku@$DOKKU_DOMAIN:$TEST_APP template_cron_file_valid_single
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
cron_id="$(dokku cron:list $TEST_APP --format json | jq -r '.[0].id')"
|
||||
|
||||
run /bin/bash -c "cat /var/spool/cron/crontabs/dokku"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "dokku cron:run $TEST_APP $cron_id"
|
||||
|
||||
# switch the app to a scheduler that manages its own cron backend
|
||||
run /bin/bash -c "dokku scheduler:set $TEST_APP selected k3s"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
# regenerating the host crontab must now skip the k3s app's tasks, leaving
|
||||
# no host-cron tasks and therefore no crontab file
|
||||
run /bin/bash -c "dokku plugin:trigger scheduler-cron-write"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "cat /var/spool/cron/crontabs/dokku"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
}
|
||||
|
||||
@test "(cron) crontab format [no raw command leakage]" {
|
||||
run deploy_app python dokku@$DOKKU_DOMAIN:$TEST_APP template_cron_file_valid_single
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
cron_id="$(dokku cron:list $TEST_APP --format json | jq -r '.[0].id')"
|
||||
|
||||
run /bin/bash -c "cat /var/spool/cron/crontabs/dokku"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "dokku cron:run $TEST_APP $cron_id"
|
||||
# User command must never appear verbatim in the crontab - the crontab
|
||||
# only references the cron ID, and cron:run resolves the command at run
|
||||
# time and exec's it inside the container.
|
||||
assert_output_contains "python3 task.py schedule" 0
|
||||
}
|
||||
|
||||
template_cron_file_invalid() {
|
||||
local APP="$1"
|
||||
local APP_REPO_DIR="$2"
|
||||
[[ -z "$APP" ]] && local APP="$TEST_APP"
|
||||
echo "injecting invalid cron app.json -> $APP_REPO_DIR/app.json"
|
||||
cat <<EOF >"$APP_REPO_DIR/app.json"
|
||||
{
|
||||
"cron": [
|
||||
{
|
||||
"key": "value"
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
template_cron_file_invalid_schedule() {
|
||||
local APP="$1"
|
||||
local APP_REPO_DIR="$2"
|
||||
[[ -z "$APP" ]] && local APP="$TEST_APP"
|
||||
echo "injecting invalid cron app.json -> $APP_REPO_DIR/app.json"
|
||||
cat <<EOF >"$APP_REPO_DIR/app.json"
|
||||
{
|
||||
"cron": [
|
||||
{
|
||||
"command": "python3 task.py",
|
||||
"schedule": "@nonstandard"
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
template_cron_file_invalid_schedule_seconds() {
|
||||
local APP="$1"
|
||||
local APP_REPO_DIR="$2"
|
||||
[[ -z "$APP" ]] && local APP="$TEST_APP"
|
||||
echo "injecting invalid cron app.json -> $APP_REPO_DIR/app.json"
|
||||
cat <<EOF >"$APP_REPO_DIR/app.json"
|
||||
{
|
||||
"cron": [
|
||||
{
|
||||
"command": "python3 task.py",
|
||||
"schedule": "0 5 * * * *"
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
template_cron_file_valid_single() {
|
||||
local APP="$1"
|
||||
local APP_REPO_DIR="$2"
|
||||
[[ -z "$APP" ]] && local APP="$TEST_APP"
|
||||
echo "injecting valid cron app.json -> $APP_REPO_DIR/app.json"
|
||||
cat <<EOF >"$APP_REPO_DIR/app.json"
|
||||
{
|
||||
"cron": [
|
||||
{
|
||||
"command": "python3 task.py schedule",
|
||||
"schedule": "5 5 5 5 5"
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
template_cron_file_valid_short() {
|
||||
local APP="$1"
|
||||
local APP_REPO_DIR="$2"
|
||||
[[ -z "$APP" ]] && local APP="$TEST_APP"
|
||||
echo "injecting valid cron app.json -> $APP_REPO_DIR/app.json"
|
||||
cat <<EOF >"$APP_REPO_DIR/app.json"
|
||||
{
|
||||
"cron": [
|
||||
{
|
||||
"command": "python3 task.py daily",
|
||||
"schedule": "@daily"
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
}
|
||||
411
tests/unit/cron-2.bats
Normal file
411
tests/unit/cron-2.bats
Normal file
@@ -0,0 +1,411 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
setup() {
|
||||
global_setup
|
||||
create_app
|
||||
mkdir -p /var/lib/dokku/plugins/available/cron-entries
|
||||
mkdir -p /var/lib/dokku/plugins/enabled/cron-entries
|
||||
cat >"/var/lib/dokku/plugins/available/cron-entries/plugin.toml" <<EOF
|
||||
[plugin]
|
||||
description = "dokku test cron-entries plugin"
|
||||
version = "0.0.1"
|
||||
[plugin.config]
|
||||
EOF
|
||||
cp /var/lib/dokku/plugins/available/cron-entries/plugin.toml /var/lib/dokku/plugins/enabled/cron-entries/plugin.toml
|
||||
}
|
||||
|
||||
teardown() {
|
||||
rm -rf /var/lib/dokku/plugins/available/cron-entries /var/lib/dokku/plugins/enabled/cron-entries
|
||||
# restore the default scheduler before destroy: a k3s-scheduled app cannot be
|
||||
# torn down cleanly without a cluster, and would otherwise leak into the next
|
||||
# test's cleanup_apps
|
||||
dokku scheduler:set "$TEST_APP" selected docker-local 2>/dev/null || true
|
||||
destroy_app
|
||||
global_teardown
|
||||
}
|
||||
|
||||
@test "(cron:report) --global --format json" {
|
||||
run /bin/bash -c "dokku cron:report --global --format json | jq -e ."
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku cron:report --global --format json | jq -r 'has(\"cron-maintenance\")'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "false"
|
||||
|
||||
run /bin/bash -c "dokku cron:report --global --format json | jq -r 'has(\"cron-global-maintenance\")'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku cron:report --global --format json | jq -r 'has(\"global-maintenance\")'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku cron:report --global --format json | jq -r 'has(\"cron-computed-maintenance\")'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku cron:report --global --format json | jq -r 'has(\"computed-maintenance\")'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku cron:report --global --format json | jq -r 'has(\"cron-global-mailfrom\")'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku cron:report --global --format json | jq -r 'has(\"global-mailfrom\")'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku cron:report --global --format json | jq -r 'has(\"cron-computed-mailfrom\")'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku cron:report --global --format json | jq -r 'has(\"computed-mailfrom\")'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku cron:report --global --format json | jq -r 'has(\"cron-global-mailto\")'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku cron:report --global --format json | jq -r 'has(\"global-mailto\")'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku cron:report --global --format json | jq -r 'has(\"cron-computed-mailto\")'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku cron:report --global --format json | jq -r 'has(\"computed-mailto\")'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku cron:report --global"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(cron:set) --global mailto" {
|
||||
run /bin/bash -c "dokku cron:set --global mailto admin@example.com"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_not_contains "unknown flag"
|
||||
|
||||
run /bin/bash -c "dokku cron:report --global --format json | jq -r '.\"cron-global-mailto\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "admin@example.com"
|
||||
|
||||
run /bin/bash -c "dokku cron:report --global --format json | jq -r '.\"cron-computed-mailto\"'"
|
||||
assert_success
|
||||
assert_output "admin@example.com"
|
||||
|
||||
run /bin/bash -c "dokku cron:set --global mailto"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_not_contains "unknown flag"
|
||||
|
||||
run /bin/bash -c "dokku cron:report --global --format json | jq -r '.\"cron-global-mailto\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku cron:report --global --format json | jq -r '.\"cron-computed-mailto\"'"
|
||||
assert_success
|
||||
assert_output ""
|
||||
}
|
||||
|
||||
@test "(cron:set) --global mailfrom" {
|
||||
run /bin/bash -c "dokku cron:set --global mailfrom dokku@example.com"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_not_contains "unknown flag"
|
||||
|
||||
run /bin/bash -c "dokku cron:report --global --format json | jq -r '.\"cron-global-mailfrom\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "dokku@example.com"
|
||||
|
||||
run /bin/bash -c "dokku cron:report --global --format json | jq -r '.\"cron-computed-mailfrom\"'"
|
||||
assert_success
|
||||
assert_output "dokku@example.com"
|
||||
|
||||
run /bin/bash -c "dokku cron:set --global mailfrom"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_not_contains "unknown flag"
|
||||
|
||||
run /bin/bash -c "dokku cron:report --global --format json | jq -r '.\"cron-global-mailfrom\"'"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku cron:report --global --format json | jq -r '.\"cron-computed-mailfrom\"'"
|
||||
assert_success
|
||||
assert_output ""
|
||||
}
|
||||
|
||||
@test "(cron:set) --global maintenance" {
|
||||
run /bin/bash -c "dokku cron:set --global maintenance true"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_not_contains "unknown flag"
|
||||
|
||||
run /bin/bash -c "dokku cron:report --global --format json | jq -r '.\"cron-global-maintenance\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku cron:set --global maintenance"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_not_contains "unknown flag"
|
||||
}
|
||||
|
||||
@test "(cron:report) maintenance raw vs computed vs global" {
|
||||
run /bin/bash -c "dokku cron:set --global maintenance"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku cron:report $TEST_APP --format json | jq -r '.\"cron-maintenance\"'"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku cron:report $TEST_APP --format json | jq -r '.\"cron-global-maintenance\"'"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku cron:report $TEST_APP --format json | jq -r '.\"cron-computed-maintenance\"'"
|
||||
assert_success
|
||||
assert_output "false"
|
||||
|
||||
run /bin/bash -c "dokku cron:set --global maintenance true"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku cron:report $TEST_APP --format json | jq -r '.\"cron-global-maintenance\"'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku cron:report $TEST_APP --format json | jq -r '.\"cron-computed-maintenance\"'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku cron:set $TEST_APP maintenance true"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku cron:report $TEST_APP --format json | jq -r '.\"cron-maintenance\"'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku cron:report $TEST_APP --format json | jq -r '.\"cron-global-maintenance\"'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
# cron computed-maintenance returns "true" if either per-app or global is
|
||||
# "true" (cron's logic at plugins/cron/report.go::reportComputedMaintenance
|
||||
# is OR-not-override: any "true" wins). This is intentional for maintenance
|
||||
# mode - a per-app "false" does NOT override a global "true".
|
||||
run /bin/bash -c "dokku cron:report $TEST_APP --format json | jq -r '.\"cron-computed-maintenance\"'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku cron:set $TEST_APP maintenance"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku cron:set --global maintenance"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(cron:set) --global rejects task maintenance properties" {
|
||||
run /bin/bash -c "dokku cron:set --global maintenance.fakeid true"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output_contains "Task maintenance properties cannot be set globally"
|
||||
}
|
||||
|
||||
@test "(cron) create [multiple]" {
|
||||
run deploy_app python dokku@$DOKKU_DOMAIN:$TEST_APP template_cron_file_valid_multiple
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
first_id="$(dokku cron:list $TEST_APP --format json | jq -r '.[0].id')"
|
||||
second_id="$(dokku cron:list $TEST_APP --format json | jq -r '.[1].id')"
|
||||
|
||||
run /bin/bash -c "cat /var/spool/cron/crontabs/dokku"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "dokku cron:run $TEST_APP $first_id"
|
||||
assert_output_contains "dokku cron:run $TEST_APP $second_id"
|
||||
assert_output_contains "python3 task.py first" 0
|
||||
assert_output_contains "python3 task.py second" 0
|
||||
}
|
||||
|
||||
@test "(cron) cron:list --format json" {
|
||||
run deploy_app python dokku@$DOKKU_DOMAIN:$TEST_APP template_cron_file_valid
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku cron:list $TEST_APP --format json"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_exists
|
||||
|
||||
cron_id="$(dokku cron:list $TEST_APP --format json | jq -r '.[0].id')"
|
||||
run /bin/bash -c "echo $cron_id"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_exists
|
||||
}
|
||||
|
||||
@test "(cron) cron:run" {
|
||||
run deploy_app python dokku@$DOKKU_DOMAIN:$TEST_APP template_cron_file_valid
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
cron_id="$(dokku cron:list $TEST_APP --format json | jq -r '.[0].id')"
|
||||
run /bin/bash -c "echo $cron_id"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_exists
|
||||
|
||||
run /bin/bash -c "dokku cron:run $TEST_APP $cron_id"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "['task.py', 'schedule']"
|
||||
|
||||
cron_id="$(dokku cron:list $TEST_APP --format json | jq -r '.[1].id')"
|
||||
run /bin/bash -c "echo $cron_id"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_exists
|
||||
|
||||
run /bin/bash -c "dokku cron:run $TEST_APP $cron_id"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "['task.py', 'schedule', 'now']"
|
||||
}
|
||||
|
||||
@test "(cron) cron:suspend cron:resume" {
|
||||
run deploy_app python dokku@$DOKKU_DOMAIN:$TEST_APP template_cron_file_valid_multiple
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
first_id="$(dokku cron:list $TEST_APP --format json | jq -r '.[0].id')"
|
||||
second_id="$(dokku cron:list $TEST_APP --format json | jq -r '.[1].id')"
|
||||
|
||||
run /bin/bash -c "cat /var/spool/cron/crontabs/dokku"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "dokku cron:run $TEST_APP $first_id"
|
||||
assert_output_contains "dokku cron:run $TEST_APP $second_id"
|
||||
|
||||
run /bin/bash -c "dokku cron:report $TEST_APP --cron-maintenance-$first_id"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
|
||||
run /bin/bash -c "dokku cron:suspend $TEST_APP $first_id"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku cron:report $TEST_APP --cron-maintenance-$first_id"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "cat /var/spool/cron/crontabs/dokku"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "dokku cron:run $TEST_APP $first_id" 0
|
||||
assert_output_contains "dokku cron:run $TEST_APP $second_id"
|
||||
|
||||
run /bin/bash -c "dokku cron:resume $TEST_APP $first_id"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku cron:report $TEST_APP --cron-maintenance-$first_id"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
|
||||
run /bin/bash -c "cat /var/spool/cron/crontabs/dokku"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "dokku cron:run $TEST_APP $first_id"
|
||||
assert_output_contains "dokku cron:run $TEST_APP $second_id"
|
||||
}
|
||||
|
||||
template_cron_file_valid() {
|
||||
local APP="$1"
|
||||
local APP_REPO_DIR="$2"
|
||||
[[ -z "$APP" ]] && local APP="$TEST_APP"
|
||||
echo "injecting valid cron app.json -> $APP_REPO_DIR/app.json"
|
||||
cat <<EOF >"$APP_REPO_DIR/app.json"
|
||||
{
|
||||
"cron": [
|
||||
{
|
||||
"command": "python3 task.py schedule",
|
||||
"schedule": "5 5 5 5 5"
|
||||
},
|
||||
{
|
||||
"command": "python3 task.py schedule now",
|
||||
"schedule": "6 5 5 5 5"
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
template_cron_file_valid_multiple() {
|
||||
local APP="$1"
|
||||
local APP_REPO_DIR="$2"
|
||||
[[ -z "$APP" ]] && local APP="$TEST_APP"
|
||||
echo "injecting valid cron app.json -> $APP_REPO_DIR/app.json"
|
||||
cat <<EOF >"$APP_REPO_DIR/app.json"
|
||||
{
|
||||
"cron": [
|
||||
{
|
||||
"command": "python3 task.py first",
|
||||
"schedule": "5 5 5 5 5"
|
||||
},
|
||||
{
|
||||
"command": "python3 task.py second",
|
||||
"schedule": "@daily"
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
}
|
||||
@@ -18,52 +18,14 @@ EOF
|
||||
|
||||
teardown() {
|
||||
rm -rf /var/lib/dokku/plugins/available/cron-entries /var/lib/dokku/plugins/enabled/cron-entries
|
||||
# restore the default scheduler before destroy: a k3s-scheduled app cannot be
|
||||
# torn down cleanly without a cluster, and would otherwise leak into the next
|
||||
# test's cleanup_apps
|
||||
dokku scheduler:set "$TEST_APP" selected docker-local 2>/dev/null || true
|
||||
destroy_app
|
||||
global_teardown
|
||||
}
|
||||
|
||||
@test "(cron) cron:help" {
|
||||
run /bin/bash -c "dokku cron"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output_contains "Manage scheduled cron tasks"
|
||||
help_output="$output"
|
||||
|
||||
run /bin/bash -c "dokku cron:help"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output_contains "Manage scheduled cron tasks"
|
||||
assert_output "$help_output"
|
||||
}
|
||||
|
||||
@test "(cron) installed" {
|
||||
run /bin/bash -c "test -f /etc/sudoers.d/dokku-cron"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
}
|
||||
|
||||
@test "(cron) invalid [missing-keys]" {
|
||||
run deploy_app python dokku@$DOKKU_DOMAIN:$TEST_APP template_cron_file_invalid
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
}
|
||||
|
||||
@test "(cron) invalid [schedule]" {
|
||||
run deploy_app python dokku@$DOKKU_DOMAIN:$TEST_APP template_cron_file_invalid_schedule
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
}
|
||||
|
||||
@test "(cron) invalid [seconds]" {
|
||||
run deploy_app python dokku@$DOKKU_DOMAIN:$TEST_APP template_cron_file_invalid_schedule_seconds
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
}
|
||||
|
||||
@test "(cron) create [empty]" {
|
||||
run deploy_app python dokku@$DOKKU_DOMAIN:$TEST_APP
|
||||
echo "output: $output"
|
||||
@@ -76,46 +38,6 @@ teardown() {
|
||||
assert_failure
|
||||
}
|
||||
|
||||
@test "(cron) create [single-verbose]" {
|
||||
run deploy_app python dokku@$DOKKU_DOMAIN:$TEST_APP template_cron_file_valid_single
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "cat /var/spool/cron/crontabs/dokku"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "python3 task.py schedule"
|
||||
}
|
||||
|
||||
@test "(cron) create [single-short]" {
|
||||
run deploy_app python dokku@$DOKKU_DOMAIN:$TEST_APP template_cron_file_valid_short
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "cat /var/spool/cron/crontabs/dokku"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "python3 task.py daily"
|
||||
}
|
||||
|
||||
@test "(cron) create [multiple]" {
|
||||
run deploy_app python dokku@$DOKKU_DOMAIN:$TEST_APP template_cron_file_valid_multiple
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "cat /var/spool/cron/crontabs/dokku"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "python3 task.py first"
|
||||
assert_output_contains "python3 task.py second"
|
||||
}
|
||||
|
||||
@test "(cron) injected entries" {
|
||||
echo "echo '@daily;/bin/true'" >/var/lib/dokku/plugins/enabled/cron-entries/cron-entries
|
||||
chmod +x /var/lib/dokku/plugins/enabled/cron-entries/cron-entries
|
||||
@@ -182,57 +104,11 @@ teardown() {
|
||||
assert_failure
|
||||
}
|
||||
|
||||
@test "(cron) cron:list --format json" {
|
||||
run deploy_app python dokku@$DOKKU_DOMAIN:$TEST_APP template_cron_file_valid
|
||||
@test "(cron) invalid [command]" {
|
||||
run deploy_app python dokku@$DOKKU_DOMAIN:$TEST_APP template_cron_file_injection
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku cron:list $TEST_APP --format json"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_exists
|
||||
|
||||
cron_id="$(dokku cron:list $TEST_APP --format json | jq -r '.[0].id')"
|
||||
run /bin/bash -c "echo $cron_id"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_exists
|
||||
}
|
||||
|
||||
@test "(cron) cron:run" {
|
||||
run deploy_app python dokku@$DOKKU_DOMAIN:$TEST_APP template_cron_file_valid
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
cron_id="$(dokku cron:list $TEST_APP --format json | jq -r '.[0].id')"
|
||||
run /bin/bash -c "echo $cron_id"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_exists
|
||||
|
||||
run /bin/bash -c "dokku cron:run $TEST_APP $cron_id"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "['task.py', 'schedule']"
|
||||
|
||||
cron_id="$(dokku cron:list $TEST_APP --format json | jq -r '.[1].id')"
|
||||
run /bin/bash -c "echo $cron_id"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_exists
|
||||
|
||||
run /bin/bash -c "dokku cron:run $TEST_APP $cron_id"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "['task.py', 'schedule', 'now']"
|
||||
assert_failure
|
||||
}
|
||||
|
||||
@test "(cron) cron:run concurrency_policy forbid" {
|
||||
@@ -266,193 +142,132 @@ teardown() {
|
||||
assert_failure
|
||||
}
|
||||
|
||||
@test "(cron) cron:suspend cron:resume" {
|
||||
run deploy_app python dokku@$DOKKU_DOMAIN:$TEST_APP template_cron_file_valid_multiple
|
||||
@test "(cron) container labels regression" {
|
||||
run deploy_app python dokku@$DOKKU_DOMAIN:$TEST_APP template_cron_file_long_running
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "cat /var/spool/cron/crontabs/dokku"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "python3 task.py first"
|
||||
assert_output_contains "python3 task.py second"
|
||||
|
||||
cron_id="$(dokku cron:list $TEST_APP --format json | jq -r '.[0].id')"
|
||||
run /bin/bash -c "echo $cron_id"
|
||||
|
||||
run /bin/bash -c "dokku cron:run $TEST_APP $cron_id --detach"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_exists
|
||||
|
||||
first_command="$(dokku cron:list $TEST_APP --format json | jq -r '.[0].command')"
|
||||
run /bin/bash -c "echo $first_command"
|
||||
run /bin/bash -c "docker ps --filter \"label=com.dokku.cron-id=$cron_id\" -q | xargs docker inspect -f '{{ index .Config.Labels \"com.dokku.cron-id\" }}'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_exists
|
||||
assert_output "$cron_id"
|
||||
|
||||
run /bin/bash -c "dokku cron:report $TEST_APP --cron-maintenance-$cron_id"
|
||||
run /bin/bash -c "docker ps --filter \"label=com.dokku.cron-id=$cron_id\" -q | xargs docker inspect -f '{{ index .Config.Labels \"com.dokku.concurrency-policy\" }}'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "allow"
|
||||
|
||||
run /bin/bash -c "docker ps --filter \"label=com.dokku.cron-id=$cron_id\" -q | xargs docker inspect -f '{{ index .Config.Labels \"com.dokku.container-type\" }}'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "cron"
|
||||
|
||||
run /bin/bash -c "docker ps --filter \"label=com.dokku.cron-id=$cron_id\" -q | xargs docker inspect -f '{{ index .Config.Labels \"com.dokku.app-name\" }}'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "$TEST_APP"
|
||||
|
||||
run /bin/bash -c "docker ps --filter \"label=com.dokku.cron-id=$cron_id\" -q | xargs docker inspect -f '{{ index .Config.Labels \"com.dokku.active-deadline-seconds\" }}'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "86400"
|
||||
}
|
||||
|
||||
@test "(cron:run) retires containers past their active deadline" {
|
||||
run deploy_app python dokku@$DOKKU_DOMAIN:$TEST_APP template_cron_file_long_running
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
cron_id="$(dokku cron:list $TEST_APP --format json | jq -r '.[0].id')"
|
||||
|
||||
run /bin/bash -c "dokku cron:run $TEST_APP $cron_id --detach --ttl-seconds 1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
expiring_container="$output"
|
||||
|
||||
run /bin/bash -c "docker container inspect $expiring_container --format '{{ index .Config.Labels \"com.dokku.active-deadline-seconds\" }}'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "1"
|
||||
|
||||
run /bin/bash -c "docker container inspect $expiring_container --format '{{ index .Config.Labels \"com.dokku.container-type\" }}'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "cron"
|
||||
|
||||
run /bin/bash -c "dokku cron:run $TEST_APP $cron_id --detach --ttl-seconds 300"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
surviving_container="$output"
|
||||
|
||||
run /bin/bash -c "sleep 2"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku ps:retire"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "docker container ls --filter \"label=com.dokku.container-type=cron\" --format '{{ .Names }}'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_not_contains "$expiring_container"
|
||||
assert_output_contains "$surviving_container"
|
||||
}
|
||||
|
||||
@test "(cron:run) --ttl-seconds must be a positive integer" {
|
||||
run deploy_app python dokku@$DOKKU_DOMAIN:$TEST_APP template_cron_file_long_running
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
cron_id="$(dokku cron:list $TEST_APP --format json | jq -r '.[0].id')"
|
||||
|
||||
run /bin/bash -c "dokku cron:run $TEST_APP $cron_id --detach --ttl-seconds 0"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output_contains "--ttl-seconds must be a positive integer"
|
||||
|
||||
run /bin/bash -c "dokku cron:suspend $TEST_APP $cron_id"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku cron:report $TEST_APP --cron-maintenance-$cron_id"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "cat /var/spool/cron/crontabs/dokku"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "python3 task.py first" 0
|
||||
assert_output_contains "python3 task.py second"
|
||||
|
||||
run /bin/bash -c "dokku cron:resume $TEST_APP $cron_id"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku cron:report $TEST_APP --cron-maintenance-$cron_id"
|
||||
run /bin/bash -c "dokku cron:run $TEST_APP $cron_id --detach --ttl-seconds -1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
|
||||
run /bin/bash -c "cat /var/spool/cron/crontabs/dokku"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "python3 task.py first"
|
||||
assert_output_contains "python3 task.py second"
|
||||
assert_output_contains "--ttl-seconds must be a positive integer"
|
||||
}
|
||||
|
||||
template_cron_file_invalid() {
|
||||
template_cron_file_injection() {
|
||||
local APP="$1"
|
||||
local APP_REPO_DIR="$2"
|
||||
[[ -z "$APP" ]] && local APP="$TEST_APP"
|
||||
echo "injecting invalid cron app.json -> $APP_REPO_DIR/app.json"
|
||||
echo "injecting injection-attempt cron app.json -> $APP_REPO_DIR/app.json"
|
||||
cat <<EOF >"$APP_REPO_DIR/app.json"
|
||||
{
|
||||
"cron": [
|
||||
{
|
||||
"key": "value"
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
template_cron_file_invalid_schedule() {
|
||||
local APP="$1"
|
||||
local APP_REPO_DIR="$2"
|
||||
[[ -z "$APP" ]] && local APP="$TEST_APP"
|
||||
echo "injecting invalid cron app.json -> $APP_REPO_DIR/app.json"
|
||||
cat <<EOF >"$APP_REPO_DIR/app.json"
|
||||
{
|
||||
"cron": [
|
||||
{
|
||||
"command": "python3 task.py",
|
||||
"schedule": "@nonstandard"
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
template_cron_file_invalid_schedule_seconds() {
|
||||
local APP="$1"
|
||||
local APP_REPO_DIR="$2"
|
||||
[[ -z "$APP" ]] && local APP="$TEST_APP"
|
||||
echo "injecting invalid cron app.json -> $APP_REPO_DIR/app.json"
|
||||
cat <<EOF >"$APP_REPO_DIR/app.json"
|
||||
{
|
||||
"cron": [
|
||||
{
|
||||
"command": "python3 task.py",
|
||||
"schedule": "0 5 * * * *"
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
template_cron_file_valid() {
|
||||
local APP="$1"
|
||||
local APP_REPO_DIR="$2"
|
||||
[[ -z "$APP" ]] && local APP="$TEST_APP"
|
||||
echo "injecting valid cron app.json -> $APP_REPO_DIR/app.json"
|
||||
cat <<EOF >"$APP_REPO_DIR/app.json"
|
||||
{
|
||||
"cron": [
|
||||
{
|
||||
"command": "python3 task.py schedule",
|
||||
"schedule": "5 5 5 5 5"
|
||||
},
|
||||
{
|
||||
"command": "python3 task.py schedule now",
|
||||
"schedule": "6 5 5 5 5"
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
template_cron_file_valid_single() {
|
||||
local APP="$1"
|
||||
local APP_REPO_DIR="$2"
|
||||
[[ -z "$APP" ]] && local APP="$TEST_APP"
|
||||
echo "injecting valid cron app.json -> $APP_REPO_DIR/app.json"
|
||||
cat <<EOF >"$APP_REPO_DIR/app.json"
|
||||
{
|
||||
"cron": [
|
||||
{
|
||||
"command": "python3 task.py schedule",
|
||||
"schedule": "5 5 5 5 5"
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
}
|
||||
template_cron_file_valid_short() {
|
||||
local APP="$1"
|
||||
local APP_REPO_DIR="$2"
|
||||
[[ -z "$APP" ]] && local APP="$TEST_APP"
|
||||
echo "injecting valid cron app.json -> $APP_REPO_DIR/app.json"
|
||||
cat <<EOF >"$APP_REPO_DIR/app.json"
|
||||
{
|
||||
"cron": [
|
||||
{
|
||||
"command": "python3 task.py daily",
|
||||
"schedule": "@daily"
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
template_cron_file_valid_multiple() {
|
||||
local APP="$1"
|
||||
local APP_REPO_DIR="$2"
|
||||
[[ -z "$APP" ]] && local APP="$TEST_APP"
|
||||
echo "injecting valid cron app.json -> $APP_REPO_DIR/app.json"
|
||||
cat <<EOF >"$APP_REPO_DIR/app.json"
|
||||
{
|
||||
"cron": [
|
||||
{
|
||||
"command": "python3 task.py first",
|
||||
"schedule": "5 5 5 5 5"
|
||||
},
|
||||
{
|
||||
"command": "python3 task.py second",
|
||||
"schedule": "@daily"
|
||||
"command": "echo CRON_OK; echo hi > /tmp/appjson-injection-test.txt",
|
||||
"schedule": "* * * * *"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -476,3 +291,20 @@ template_cron_file_concurrency_forbid() {
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
template_cron_file_long_running() {
|
||||
local APP="$1"
|
||||
local APP_REPO_DIR="$2"
|
||||
[[ -z "$APP" ]] && local APP="$TEST_APP"
|
||||
echo "injecting long-running cron app.json -> $APP_REPO_DIR/app.json"
|
||||
cat <<EOF >"$APP_REPO_DIR/app.json"
|
||||
{
|
||||
"cron": [
|
||||
{
|
||||
"command": "sleep 30",
|
||||
"schedule": "0 0 * * *"
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
}
|
||||
57
tests/unit/docker-image-healthcheck.bats
Normal file
57
tests/unit/docker-image-healthcheck.bats
Normal file
@@ -0,0 +1,57 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
REPO_ROOT="$(cd "$BATS_TEST_DIRNAME/../.." && pwd)"
|
||||
|
||||
NGINX_CONF="${REPO_ROOT}/docker/etc/nginx/conf.d/zz-dokku-health.conf"
|
||||
FINISH_SCRIPT="${REPO_ROOT}/docker/etc/runit/runsvdir/default/dokku-restore/finish"
|
||||
MY_INIT_SCRIPT="${REPO_ROOT}/docker/etc/my_init.d/10_dokku_init"
|
||||
DOCKERFILE="${REPO_ROOT}/Dockerfile"
|
||||
|
||||
@test "(docker-image) [healthcheck] nginx health conf is shipped via the docker overlay" {
|
||||
[[ -f "$NGINX_CONF" ]]
|
||||
grep -qE "listen[[:space:]]+127\.0\.0\.1:18080" "$NGINX_CONF"
|
||||
grep -qE "location = /_dokku/health" "$NGINX_CONF"
|
||||
grep -qE "/var/run/dokku/ready" "$NGINX_CONF"
|
||||
grep -qE "default_type[[:space:]]+text/plain" "$NGINX_CONF"
|
||||
}
|
||||
|
||||
@test "(docker-image) [healthcheck] finish script touches sentinel after waiting for sshd and nginx" {
|
||||
[[ -f "$FINISH_SCRIPT" ]]
|
||||
|
||||
local sshd_line nginx_line touch_line
|
||||
sshd_line=$(grep -nE "/dev/tcp/127\.0\.0\.1/22" "$FINISH_SCRIPT" | head -n1 | cut -d: -f1)
|
||||
nginx_line=$(grep -nE "/dev/tcp/127\.0\.0\.1/80" "$FINISH_SCRIPT" | head -n1 | cut -d: -f1)
|
||||
touch_line=$(grep -nE "touch /var/run/dokku/ready" "$FINISH_SCRIPT" | head -n1 | cut -d: -f1)
|
||||
|
||||
[[ -n "$sshd_line" ]]
|
||||
[[ -n "$nginx_line" ]]
|
||||
[[ -n "$touch_line" ]]
|
||||
((touch_line > sshd_line))
|
||||
((touch_line > nginx_line))
|
||||
}
|
||||
|
||||
@test "(docker-image) [healthcheck] my_init clears stale sentinel on container boot" {
|
||||
[[ -f "$MY_INIT_SCRIPT" ]]
|
||||
|
||||
local rm_line mkdir_line plugin_line hostname_line
|
||||
rm_line=$(grep -nE "rm -f /var/run/dokku/ready" "$MY_INIT_SCRIPT" | head -n1 | cut -d: -f1)
|
||||
mkdir_line=$(grep -nE "mkdir -p /var/run/dokku( |$)" "$MY_INIT_SCRIPT" | head -n1 | cut -d: -f1)
|
||||
plugin_line=$(grep -nE "plugin:install" "$MY_INIT_SCRIPT" | head -n1 | cut -d: -f1)
|
||||
hostname_line=$(grep -nE "domains:set-global" "$MY_INIT_SCRIPT" | head -n1 | cut -d: -f1)
|
||||
|
||||
[[ -n "$rm_line" ]]
|
||||
[[ -n "$mkdir_line" ]]
|
||||
[[ -n "$plugin_line" ]]
|
||||
[[ -n "$hostname_line" ]]
|
||||
((rm_line < plugin_line))
|
||||
((rm_line < hostname_line))
|
||||
((mkdir_line < plugin_line))
|
||||
((mkdir_line < hostname_line))
|
||||
}
|
||||
|
||||
@test "(docker-image) [healthcheck] Dockerfile declares HEALTHCHECK with the expected endpoint" {
|
||||
[[ -f "$DOCKERFILE" ]]
|
||||
grep -qE "^HEALTHCHECK" "$DOCKERFILE"
|
||||
grep -qE "http://127\.0\.0\.1:18080/_dokku/health" "$DOCKERFILE"
|
||||
grep -qE "\-\-start-period" "$DOCKERFILE"
|
||||
}
|
||||
326
tests/unit/docker-options-2.bats
Normal file
326
tests/unit/docker-options-2.bats
Normal file
@@ -0,0 +1,326 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
setup() {
|
||||
global_setup
|
||||
create_app
|
||||
}
|
||||
|
||||
teardown() {
|
||||
destroy_app
|
||||
global_teardown
|
||||
}
|
||||
|
||||
@test "(docker-options:add) --process scopes option to one process type" {
|
||||
run /bin/bash -c "dokku docker-options:add --process web $TEST_APP deploy '-p 8080:5000'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku docker-options:list $TEST_APP --process web --phase deploy"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "-p 8080:5000"
|
||||
|
||||
run /bin/bash -c "dokku docker-options:list $TEST_APP --phase deploy"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "-p 8080:5000" 0
|
||||
}
|
||||
|
||||
@test "(docker-options:add) multiple --process flags add to each process" {
|
||||
run /bin/bash -c "dokku docker-options:add --process web --process worker $TEST_APP deploy '-v /shared:/shared'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku docker-options:list $TEST_APP --process web --phase deploy"
|
||||
echo "output: $output"
|
||||
assert_output "-v /shared:/shared"
|
||||
|
||||
run /bin/bash -c "dokku docker-options:list $TEST_APP --process worker --phase deploy"
|
||||
echo "output: $output"
|
||||
assert_output "-v /shared:/shared"
|
||||
}
|
||||
|
||||
@test "(docker-options:add) without --process keeps default-scope behaviour" {
|
||||
run /bin/bash -c "dokku docker-options:add $TEST_APP deploy '-v /tmp/shared:/shared'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku docker-options:list $TEST_APP --phase deploy"
|
||||
echo "output: $output"
|
||||
assert_output_contains "-v /tmp/shared:/shared"
|
||||
|
||||
run /bin/bash -c "dokku docker-options:report $TEST_APP --docker-options-deploy"
|
||||
echo "output: $output"
|
||||
assert_output_contains "-v /tmp/shared:/shared"
|
||||
}
|
||||
|
||||
@test "(docker-options:add) rejects --process for non-deploy phases" {
|
||||
run /bin/bash -c "dokku docker-options:add --process web $TEST_APP build '--shm-size 256m'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output_contains "deploy phase"
|
||||
|
||||
run /bin/bash -c "dokku docker-options:add --process web $TEST_APP run '--shm-size 256m'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
|
||||
run /bin/bash -c "dokku docker-options:add --process web $TEST_APP build,deploy '--shm-size 256m'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
}
|
||||
|
||||
@test "(docker-options:add) rejects reserved _default_ process name" {
|
||||
run /bin/bash -c "dokku docker-options:add --process _default_ $TEST_APP deploy '-v /tmp:/tmp'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output_contains "_default_"
|
||||
}
|
||||
|
||||
@test "(docker-options:add) warns on process types missing from Procfile" {
|
||||
run deploy_app python dokku@$DOKKU_DOMAIN:$TEST_APP
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku docker-options:add --process nonexistent $TEST_APP deploy '-v /tmp:/tmp'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "nonexistent"
|
||||
}
|
||||
|
||||
@test "(docker-options:remove) --process removes from a single process" {
|
||||
run /bin/bash -c "dokku docker-options:add --process web $TEST_APP deploy '-p 8080:5000'"
|
||||
echo "output: $output"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku docker-options:add --process worker $TEST_APP deploy '-p 9000:9000'"
|
||||
echo "output: $output"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku docker-options:remove --process web $TEST_APP deploy '-p 8080:5000'"
|
||||
echo "output: $output"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku docker-options:list $TEST_APP --process web --phase deploy"
|
||||
echo "output: $output"
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku docker-options:list $TEST_APP --process worker --phase deploy"
|
||||
echo "output: $output"
|
||||
assert_output "-p 9000:9000"
|
||||
}
|
||||
|
||||
@test "(docker-options:clear) --process clears only that process" {
|
||||
run /bin/bash -c "dokku docker-options:add --process web $TEST_APP deploy '-p 8080:5000'"
|
||||
echo "output: $output"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku docker-options:add --process worker $TEST_APP deploy '-p 9000:9000'"
|
||||
echo "output: $output"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku docker-options:clear --process web $TEST_APP deploy"
|
||||
echo "output: $output"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku docker-options:list $TEST_APP --process web --phase deploy"
|
||||
echo "output: $output"
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku docker-options:list $TEST_APP --process worker --phase deploy"
|
||||
echo "output: $output"
|
||||
assert_output "-p 9000:9000"
|
||||
}
|
||||
|
||||
@test "(docker-options:list) --phase is required" {
|
||||
run /bin/bash -c "dokku docker-options:list $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output_contains "phase"
|
||||
}
|
||||
|
||||
@test "(docker-options:report) exposes dynamic per-process keys" {
|
||||
run /bin/bash -c "dokku docker-options:add --process web $TEST_APP deploy '-p 8080:5000'"
|
||||
echo "output: $output"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku docker-options:report $TEST_APP --docker-options-deploy.web"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "-p 8080:5000"
|
||||
|
||||
run /bin/bash -c "dokku docker-options:report $TEST_APP"
|
||||
echo "output: $output"
|
||||
assert_success
|
||||
assert_output_contains "Docker options deploy web"
|
||||
assert_output_contains "-p 8080:5000"
|
||||
}
|
||||
|
||||
@test "(docker-options:report) --format json carries process-scoped options" {
|
||||
run /bin/bash -c "dokku docker-options:add --process web $TEST_APP deploy '-p 8080:5000'"
|
||||
echo "output: $output"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku docker-options:add $TEST_APP deploy '-v /logs:/logs'"
|
||||
echo "output: $output"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku docker-options:report $TEST_APP --format json"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains '"docker-options-deploy.web"'
|
||||
assert_output_contains '"deploy.web"'
|
||||
assert_output_contains '"deploy.web-list"'
|
||||
assert_output_contains "-p 8080:5000" 3
|
||||
assert_output_contains '"docker-options-deploy"'
|
||||
assert_output_contains '"deploy"'
|
||||
assert_output_contains '"deploy-list"'
|
||||
assert_output_contains "-v /logs:/logs" 3
|
||||
}
|
||||
|
||||
@test "(docker-options:report) --format json exposes structured -list keys" {
|
||||
run /bin/bash -c "dokku docker-options:add $TEST_APP build --build-arg X=Y --link foo --link bar"
|
||||
echo "output: $output"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku docker-options:add --process web $TEST_APP deploy '-p 8080:5000'"
|
||||
echo "output: $output"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku docker-options:add $TEST_APP deploy '-v /logs:/logs' '--memory=512m'"
|
||||
echo "output: $output"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku docker-options:add $TEST_APP deploy --label 'com.example.description=my app'"
|
||||
echo "output: $output"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku docker-options:report $TEST_APP --format json | jq -e '.\"build-list\" | length == 3'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku docker-options:report $TEST_APP --format json | jq -e '.\"deploy-list\" | length == 3'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku docker-options:report $TEST_APP --format json | jq -e '.\"deploy-list\" | index(\"--memory=512m\") != null'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku docker-options:report $TEST_APP --format json | jq -e '.\"deploy-list\"[] | select(test(\"my app\"))'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku docker-options:report $TEST_APP --format json | jq -e '.\"deploy.web-list\"[]'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "-p 8080:5000"
|
||||
|
||||
run /bin/bash -c "dokku docker-options:report $TEST_APP --format json | jq -e 'has(\"docker-options-deploy-list\") | not'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(docker-options:report) --format json emits empty -list arrays for unset phases" {
|
||||
run /bin/bash -c "dokku docker-options:report $TEST_APP --format json | jq -e '.\"build-list\" == [] and .\"deploy-list\" == [] and .\"run-list\" == []'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(docker-options) clone copies default and per-process options" {
|
||||
local CLONE_APP="${TEST_APP}-clone"
|
||||
run /bin/bash -c "dokku docker-options:add --process web $TEST_APP deploy '-p 8080:5000'"
|
||||
assert_success
|
||||
run /bin/bash -c "dokku docker-options:add $TEST_APP deploy '-v /logs:/logs'"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku apps:clone --skip-deploy $TEST_APP $CLONE_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku docker-options:list $CLONE_APP --process web --phase deploy"
|
||||
echo "output: $output"
|
||||
assert_output "-p 8080:5000"
|
||||
|
||||
run /bin/bash -c "dokku docker-options:list $CLONE_APP --phase deploy"
|
||||
echo "output: $output"
|
||||
assert_output_contains "-v /logs:/logs"
|
||||
|
||||
dokku --force apps:destroy "$CLONE_APP" || true
|
||||
}
|
||||
|
||||
@test "(docker-options) rename moves default and per-process options" {
|
||||
local RENAMED_APP="${TEST_APP}-renamed"
|
||||
run /bin/bash -c "dokku docker-options:add --process web $TEST_APP deploy '-p 8080:5000'"
|
||||
assert_success
|
||||
run /bin/bash -c "dokku docker-options:add $TEST_APP deploy '-v /logs:/logs'"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku apps:rename $TEST_APP $RENAMED_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku docker-options:list $RENAMED_APP --process web --phase deploy"
|
||||
assert_output "-p 8080:5000"
|
||||
|
||||
run /bin/bash -c "dokku docker-options:list $RENAMED_APP --phase deploy"
|
||||
assert_output_contains "-v /logs:/logs"
|
||||
|
||||
[[ ! -d "/var/lib/dokku/config/docker-options/$TEST_APP" ]]
|
||||
|
||||
TEST_APP="$RENAMED_APP"
|
||||
}
|
||||
|
||||
@test "(docker-options) deploy with web-only port mapping does not break worker" {
|
||||
run /bin/bash -c "dokku docker-options:add --process web $TEST_APP deploy '-p 8080:5000'"
|
||||
echo "output: $output"
|
||||
assert_success
|
||||
|
||||
run deploy_app python dokku@$DOKKU_DOMAIN:$TEST_APP web_worker_callback
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "App container failed to start" 0
|
||||
assert_output_contains "all ports are allocated" 0
|
||||
|
||||
run /bin/bash -c "dokku ps:report $TEST_APP --ps-status-web-1"
|
||||
echo "output: $output"
|
||||
assert_output_contains "running"
|
||||
|
||||
run /bin/bash -c "dokku ps:report $TEST_APP --ps-status-worker-1"
|
||||
echo "output: $output"
|
||||
assert_output_contains "running"
|
||||
}
|
||||
|
||||
web_worker_callback() {
|
||||
local APP="$1"
|
||||
local APP_REPO_DIR="$2"
|
||||
cat >"$APP_REPO_DIR/Procfile" <<EOF
|
||||
web: python3 -u web.py
|
||||
worker: python3 -u worker.py
|
||||
EOF
|
||||
}
|
||||
@@ -193,7 +193,6 @@ teardown() {
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "-v /tmp" 0
|
||||
assert_output_contains "Docker options deploy: --restart=on-failure:10"
|
||||
}
|
||||
|
||||
@test "(docker-options) docker-options:remove (build phase)" {
|
||||
@@ -264,11 +263,7 @@ teardown() {
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
run /bin/bash -c "echo '-v /tmp' >> $DOKKU_ROOT/$TEST_APP/DOCKER_OPTIONS_DEPLOY"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
run /bin/bash -c "echo '# comment' >> $DOKKU_ROOT/$TEST_APP/DOCKER_OPTIONS_DEPLOY"
|
||||
run /bin/bash -c "dokku docker-options:add $TEST_APP deploy \"-v /tmp\""
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
@@ -290,16 +285,31 @@ teardown() {
|
||||
assert_output "/tmp:{} /var/tmp:{}"
|
||||
}
|
||||
|
||||
@test "(docker-options) deploy does not expand command substitution in option values [buildpacks]" {
|
||||
run /bin/bash -c "dokku docker-options:add $TEST_APP deploy '--label=com.dokku.test=\$(id)'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run deploy_app
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
CID=$(<$DOKKU_ROOT/$TEST_APP/CONTAINER.web.1)
|
||||
run /bin/bash -c "docker inspect $CID --format '{{ index .Config.Labels \"com.dokku.test\" }}'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output '$(id)'
|
||||
[[ "$output" != *"uid="* ]] || flunk "id command output leaked - option value was expanded"
|
||||
}
|
||||
|
||||
@test "(docker-options) deploy with options [dockerfile]" {
|
||||
run /bin/bash -c "dokku docker-options:add $TEST_APP deploy \"-v /var/tmp\""
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
run /bin/bash -c "echo '-v /tmp' >> $DOKKU_ROOT/$TEST_APP/DOCKER_OPTIONS_DEPLOY"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
run /bin/bash -c "echo '# comment' >> $DOKKU_ROOT/$TEST_APP/DOCKER_OPTIONS_DEPLOY"
|
||||
run /bin/bash -c "dokku docker-options:add $TEST_APP deploy \"-v /tmp\""
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
@@ -370,3 +380,116 @@ teardown() {
|
||||
assert_success
|
||||
assert_output_contains "TOKEN is: hello" 2
|
||||
}
|
||||
|
||||
@test "(docker-options:add) splits multi-flag input into separate options" {
|
||||
run /bin/bash -c "dokku docker-options:add $TEST_APP build --build-arg X=Y --link foo --link bar"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku docker-options:list $TEST_APP --phase build"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "--build-arg X=Y"
|
||||
assert_output_contains "--link foo"
|
||||
assert_output_contains "--link bar"
|
||||
|
||||
run /bin/bash -c "dokku docker-options:report $TEST_APP --docker-options-build"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "--build-arg X=Y"
|
||||
assert_output_contains "--link foo"
|
||||
assert_output_contains "--link bar"
|
||||
}
|
||||
|
||||
@test "(docker-options:remove) symmetrically removes multi-flag input" {
|
||||
run /bin/bash -c "dokku docker-options:add $TEST_APP build --build-arg X=Y --link foo --link bar"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku docker-options:remove $TEST_APP build --build-arg X=Y --link foo --link bar"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku docker-options:list $TEST_APP --phase build"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
}
|
||||
|
||||
@test "(docker-options:add) lifts misplaced --process out of option content" {
|
||||
run /bin/bash -c "dokku docker-options:add $TEST_APP deploy --link foo --process web"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku docker-options:list $TEST_APP --process web --phase deploy"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "--link foo"
|
||||
|
||||
run /bin/bash -c "dokku docker-options:list $TEST_APP --phase deploy"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "--link foo" 0
|
||||
}
|
||||
|
||||
@test "(docker-options:remove) removes an option stored in the pre-0.38.25 unquoted form" {
|
||||
# Options drained out of a legacy DOCKER_OPTIONS_<PHASE> file by
|
||||
# releases before 0.38.26 were copied verbatim, so a value holding
|
||||
# shell metacharacters sits in the property store unquoted. Seed that
|
||||
# state directly - the add path always canonicalizes, so it cannot
|
||||
# produce it.
|
||||
run /bin/bash -c "dokku docker-options:add $TEST_APP deploy \"-v /tmp/keep:/keep\""
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
legacy_option='--group-add $(getent group docker | cut -d: -f3)'
|
||||
property_file="/var/lib/dokku/config/docker-options/$TEST_APP/_default_.deploy"
|
||||
run /bin/bash -c "printf '%s\n-v /tmp/keep:/keep\n' '$legacy_option' | sudo tee $property_file"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "sudo chown dokku:dokku $property_file"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku docker-options:list $TEST_APP --phase deploy"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "$legacy_option"
|
||||
|
||||
run /bin/bash -c "dokku docker-options:remove $TEST_APP deploy '$legacy_option'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku docker-options:list $TEST_APP --phase deploy"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "-v /tmp/keep:/keep"
|
||||
}
|
||||
|
||||
@test "(docker-options) dockerfile build skips unsupported flags from multi-flag input" {
|
||||
run /bin/bash -c "dokku docker-options:add $TEST_APP build --build-arg PAYPAL_CLIENT_ID=abc --link postgres"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run deploy_app dockerfile
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@@ -28,6 +28,37 @@ teardown() {
|
||||
assert_output "$help_output"
|
||||
}
|
||||
|
||||
@test "(domains:report) --global --format json" {
|
||||
run /bin/bash -c "dokku domains:report --global --format json | jq -e ."
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku domains:report --global --format json | jq -r 'keys[]' | grep -v 'global-' | wc -l"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "0"
|
||||
|
||||
run /bin/bash -c "dokku domains:report --global"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "global domains information"
|
||||
|
||||
run /bin/bash -c "dokku domains:report --global --domains-global-enabled"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku domains:report --global --domains-invalid-flag"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output_contains "Invalid flag passed"
|
||||
}
|
||||
|
||||
@test "(domains) domains" {
|
||||
run /bin/bash -c "dokku domains:report $TEST_APP 2>/dev/null | grep ${TEST_APP}.${DOKKU_DOMAIN}"
|
||||
echo "output: $output"
|
||||
@@ -393,6 +424,62 @@ teardown() {
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(domains) app rename preserves all subdomains across multiple global vhosts" {
|
||||
run /bin/bash -c "dokku domains:set-global ${DOKKU_DOMAIN} dokku.test"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku domains:set $TEST_APP $TEST_APP.${DOKKU_DOMAIN} $TEST_APP.dokku.test custom.example.com"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku apps:rename $TEST_APP other-name"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku domains:report other-name --domains-app-vhosts"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "other-name.${DOKKU_DOMAIN} other-name.dokku.test custom.example.com"
|
||||
|
||||
run /bin/bash -c "dokku apps:rename other-name $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(domains) app rename preserves custom domains when no global vhost is set" {
|
||||
run /bin/bash -c "dokku domains:clear-global"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku domains:set $TEST_APP custom.example.com other.example.org"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku apps:rename $TEST_APP other-name"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku domains:report other-name --domains-app-vhosts"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "custom.example.com other.example.org"
|
||||
|
||||
run /bin/bash -c "dokku apps:rename other-name $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(domains) verify warning on ipv4/ipv6 domain name" {
|
||||
touch /etc/nginx/sites-enabled/default
|
||||
rm "$DOKKU_ROOT/VHOST"
|
||||
|
||||
@@ -12,6 +12,229 @@ teardown() {
|
||||
global_teardown
|
||||
}
|
||||
|
||||
@test "(git:report) info-flag works before deploy" {
|
||||
run /bin/bash -c "dokku git:report $TEST_APP --git-deploy-branch"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku git:report $TEST_APP --git-computed-deploy-branch"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "master"
|
||||
|
||||
run /bin/bash -c "dokku git:set $TEST_APP deploy-branch main"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku git:report $TEST_APP --git-deploy-branch"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "main"
|
||||
|
||||
run /bin/bash -c "dokku git:report $TEST_APP --git-computed-deploy-branch"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "main"
|
||||
|
||||
run /bin/bash -c "dokku git:set $TEST_APP deploy-branch"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku git:report $TEST_APP --git-deploy-branch"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku git:report $TEST_APP --git-computed-deploy-branch"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "master"
|
||||
|
||||
run /bin/bash -c "dokku git:report $TEST_APP --git-sha"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku git:report $TEST_APP --git-invalid-flag"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output_contains "Invalid flag passed"
|
||||
}
|
||||
|
||||
@test "(git:report) keep-git-dir raw vs computed vs global" {
|
||||
run /bin/bash -c "dokku git:set --global keep-git-dir"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku git:report $TEST_APP --git-keep-git-dir"
|
||||
assert_success
|
||||
assert_output_not_exists
|
||||
|
||||
run /bin/bash -c "dokku git:report $TEST_APP --git-global-keep-git-dir"
|
||||
assert_success
|
||||
assert_output_not_exists
|
||||
|
||||
run /bin/bash -c "dokku git:report $TEST_APP --git-computed-keep-git-dir"
|
||||
assert_success
|
||||
assert_output "false"
|
||||
|
||||
run /bin/bash -c "dokku git:set --global keep-git-dir true"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku git:report $TEST_APP --git-global-keep-git-dir"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku git:report $TEST_APP --git-computed-keep-git-dir"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku git:set $TEST_APP keep-git-dir false"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku git:report $TEST_APP --git-keep-git-dir"
|
||||
assert_success
|
||||
assert_output "false"
|
||||
|
||||
run /bin/bash -c "dokku git:report $TEST_APP --git-global-keep-git-dir"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku git:report $TEST_APP --git-computed-keep-git-dir"
|
||||
assert_success
|
||||
assert_output "false"
|
||||
|
||||
run /bin/bash -c "dokku git:set $TEST_APP keep-git-dir"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku git:set --global keep-git-dir"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(git:report) rev-env-var raw" {
|
||||
# Unset the per-app property file if a previous test left it written-empty
|
||||
# (git:set <app> rev-env-var "" intentionally writes an empty file as the
|
||||
# documented "unset" behavior, which masks the report's default fallback).
|
||||
run /bin/bash -c "dokku git:set $TEST_APP rev-env-var COMMIT_SHA"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku git:report $TEST_APP --git-rev-env-var"
|
||||
assert_success
|
||||
assert_output "COMMIT_SHA"
|
||||
|
||||
run /bin/bash -c "dokku git:set $TEST_APP rev-env-var"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(git:report) source-image raw" {
|
||||
run /bin/bash -c "dokku git:report $TEST_APP --git-source-image"
|
||||
assert_success
|
||||
assert_output_not_exists
|
||||
|
||||
run /bin/bash -c "dokku git:set $TEST_APP source-image alpine:3.20"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku git:report $TEST_APP --git-source-image"
|
||||
assert_success
|
||||
assert_output "alpine:3.20"
|
||||
|
||||
run /bin/bash -c "dokku git:set $TEST_APP source-image"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku git:report $TEST_APP --git-source-image"
|
||||
assert_success
|
||||
assert_output_not_exists
|
||||
}
|
||||
|
||||
@test "(git:report) raw and computed keys in --format json" {
|
||||
run /bin/bash -c "dokku git:report $TEST_APP --format json | jq -r '.\"deploy-branch\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku git:report $TEST_APP --format json | jq -r '.\"computed-deploy-branch\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "master"
|
||||
|
||||
run /bin/bash -c "dokku git:report $TEST_APP --format json | jq -r '.\"keep-git-dir\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku git:report $TEST_APP --format json | jq -r '.\"computed-keep-git-dir\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "false"
|
||||
}
|
||||
|
||||
@test "(git:report) --global raw and computed keys" {
|
||||
run /bin/bash -c "dokku git:report --global --format json | jq -r '.\"global-deploy-branch\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku git:report --global --format json | jq -r '.\"computed-deploy-branch\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "master"
|
||||
|
||||
run /bin/bash -c "dokku git:report --global --format json | jq -r '.\"global-archive-max-files\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku git:report --global --format json | jq -r '.\"computed-archive-max-files\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "10000"
|
||||
|
||||
run /bin/bash -c "dokku git:set --global deploy-branch main"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku git:report --global --format json | jq -r '.\"global-deploy-branch\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "main"
|
||||
|
||||
run /bin/bash -c "dokku git:report --global --format json | jq -r '.\"computed-deploy-branch\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "main"
|
||||
|
||||
run /bin/bash -c "dokku git:set --global deploy-branch"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku git:report --global --format json | jq -r '.\"global-deploy-branch\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
}
|
||||
|
||||
@test "(git) git:help" {
|
||||
run /bin/bash -c "dokku git"
|
||||
echo "output: $output"
|
||||
|
||||
@@ -93,6 +93,145 @@ teardown() {
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "Setting netrc auth entry for host github.com"
|
||||
|
||||
run /bin/bash -c "printf 'piped-password' | dokku git:auth github.com piped-username"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "Setting netrc auth entry for host github.com"
|
||||
|
||||
run /bin/bash -c "netrc get --netrc-file ${DOKKU_ROOT}/.netrc github.com"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "piped-username:piped-password"
|
||||
|
||||
run /bin/bash -c "stat -c '%a' ${DOKKU_ROOT}/.netrc"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "600"
|
||||
|
||||
run /bin/bash -c "stat -c '%U:%G' ${DOKKU_ROOT}/.netrc"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "dokku:dokku"
|
||||
}
|
||||
|
||||
@test "(git) git:auth repairs world-readable .netrc" {
|
||||
run /bin/bash -c "chmod 644 ${DOKKU_ROOT}/.netrc"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "stat -c '%a' ${DOKKU_ROOT}/.netrc"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "644"
|
||||
|
||||
run /bin/bash -c "dokku git:auth github.com username password"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "Setting netrc auth entry for host github.com"
|
||||
|
||||
run /bin/bash -c "stat -c '%a' ${DOKKU_ROOT}/.netrc"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "600"
|
||||
|
||||
run /bin/bash -c "stat -c '%U:%G' ${DOKKU_ROOT}/.netrc"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "dokku:dokku"
|
||||
}
|
||||
|
||||
@test "(git) git:auth unset preserves 0600 on remaining .netrc" {
|
||||
run /bin/bash -c "dokku git:auth github.com username password"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku git:auth other.example.com user2 pass2"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "chmod 644 ${DOKKU_ROOT}/.netrc"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku git:auth github.com"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "Removing netrc auth entry for host github.com"
|
||||
|
||||
if [[ -f "${DOKKU_ROOT}/.netrc" ]]; then
|
||||
run /bin/bash -c "stat -c '%a' ${DOKKU_ROOT}/.netrc"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "600"
|
||||
fi
|
||||
}
|
||||
|
||||
@test "(git) git:auth-status" {
|
||||
run /bin/bash -c "dokku git:auth-status"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
|
||||
run /bin/bash -c "dokku git:auth-status github.com"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku git:auth github.com username password"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku git:auth-status github.com"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
|
||||
run /bin/bash -c "dokku git:auth-status github.com username password"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku git:auth-status github.com username wrong-password"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
|
||||
run /bin/bash -c "dokku git:auth-status github.com other-username password"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
|
||||
run /bin/bash -c "dokku git:auth-status github.com username"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output_contains "Missing password for netrc auth entry"
|
||||
|
||||
run /bin/bash -c "printf 'password' | dokku git:auth-status github.com username"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "printf 'wrong-password' | dokku git:auth-status github.com username"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
}
|
||||
|
||||
@test "(git) git:sync new [errors]" {
|
||||
@@ -631,7 +770,7 @@ teardown() {
|
||||
}
|
||||
|
||||
@test "(git:sync) --skip-deploy-branch" {
|
||||
run /bin/bash -c "dokku git:report $TEST_APP --git-deploy-branch"
|
||||
run /bin/bash -c "dokku git:report $TEST_APP --git-computed-deploy-branch"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
@@ -659,7 +798,7 @@ teardown() {
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku git:report $TEST_APP --git-deploy-branch"
|
||||
run /bin/bash -c "dokku git:report $TEST_APP --git-computed-deploy-branch"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
@@ -671,7 +810,7 @@ teardown() {
|
||||
assert_success
|
||||
assert_output_contains "skipping deploy-branch setting"
|
||||
|
||||
run /bin/bash -c "dokku git:report $TEST_APP --git-deploy-branch"
|
||||
run /bin/bash -c "dokku git:report $TEST_APP --git-computed-deploy-branch"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
@@ -679,7 +818,7 @@ teardown() {
|
||||
}
|
||||
|
||||
@test "(git:sync) --build --skip-deploy-branch" {
|
||||
run /bin/bash -c "dokku git:report $TEST_APP --git-deploy-branch"
|
||||
run /bin/bash -c "dokku git:report $TEST_APP --git-computed-deploy-branch"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
@@ -692,7 +831,7 @@ teardown() {
|
||||
assert_output_contains "skipping deploy-branch setting"
|
||||
assert_output_contains "Application deployed"
|
||||
|
||||
run /bin/bash -c "dokku git:report $TEST_APP --git-deploy-branch"
|
||||
run /bin/bash -c "dokku git:report $TEST_APP --git-computed-deploy-branch"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
@@ -700,7 +839,7 @@ teardown() {
|
||||
}
|
||||
|
||||
@test "(git:sync) --build-if-changes --skip-deploy-branch" {
|
||||
run /bin/bash -c "dokku git:report $TEST_APP --git-deploy-branch"
|
||||
run /bin/bash -c "dokku git:report $TEST_APP --git-computed-deploy-branch"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
@@ -713,7 +852,7 @@ teardown() {
|
||||
assert_output_contains "skipping deploy-branch setting"
|
||||
assert_output_contains "Application deployed"
|
||||
|
||||
run /bin/bash -c "dokku git:report $TEST_APP --git-deploy-branch"
|
||||
run /bin/bash -c "dokku git:report $TEST_APP --git-computed-deploy-branch"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
@@ -725,7 +864,94 @@ teardown() {
|
||||
assert_success
|
||||
assert_output_contains "Skipping build as no changes were detected"
|
||||
|
||||
run /bin/bash -c "dokku git:report $TEST_APP --git-deploy-branch"
|
||||
run /bin/bash -c "dokku git:report $TEST_APP --git-computed-deploy-branch"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "master"
|
||||
}
|
||||
|
||||
@test "(git:report) --format json" {
|
||||
run /bin/bash -c "dokku git:set $TEST_APP deploy-branch main"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku git:report $TEST_APP --format json | jq -r '.\"deploy-branch\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "main"
|
||||
|
||||
run /bin/bash -c "dokku git:report $TEST_APP --format json | jq -r '.\"global-deploy-branch\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku git:report $TEST_APP --format json | jq -r '.\"computed-deploy-branch\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "main"
|
||||
|
||||
run /bin/bash -c "dokku git:report $TEST_APP --format json | jq -e ."
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku git:report --format json | jq -e ."
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku git:report $TEST_APP --format json --git-deploy-branch"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output_contains "--format flag cannot be specified when specifying an info flag"
|
||||
}
|
||||
|
||||
@test "(git:report) --global" {
|
||||
run /bin/bash -c "dokku git:report --global"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "global git information"
|
||||
assert_output_contains "Git global deploy branch"
|
||||
}
|
||||
|
||||
@test "(git:report) --global --format json" {
|
||||
run /bin/bash -c "dokku git:report --global --format json | jq -e ."
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku git:report --global --format json | jq -r '.\"global-deploy-branch\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku git:report --global --format json | jq -r '.\"computed-deploy-branch\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "master"
|
||||
|
||||
run /bin/bash -c "dokku git:report --global --format json | jq -r 'has(\"deploy-branch\")'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "false"
|
||||
|
||||
run /bin/bash -c "dokku git:report --global --git-global-deploy-branch"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku git:report --global --git-computed-deploy-branch"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
76
tests/unit/haproxy-vhosts.bats
Normal file
76
tests/unit/haproxy-vhosts.bats
Normal file
@@ -0,0 +1,76 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
setup() {
|
||||
create_app
|
||||
}
|
||||
|
||||
teardown() {
|
||||
destroy_app
|
||||
dokku haproxy:set --global log-level >/dev/null 2>&1 || true
|
||||
dokku haproxy:set --global refresh-conf >/dev/null 2>&1 || true
|
||||
}
|
||||
|
||||
@test "(haproxy:report) info-flag works before deploy" {
|
||||
run /bin/bash -c "dokku haproxy:set --global refresh-conf"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku haproxy:report $TEST_APP --haproxy-computed-refresh-conf"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "10"
|
||||
|
||||
run /bin/bash -c "dokku haproxy:report $TEST_APP --haproxy-invalid-flag"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output_contains "Invalid flag passed"
|
||||
}
|
||||
|
||||
@test "(haproxy:report) --format json" {
|
||||
run /bin/bash -c "dokku haproxy:set --global log-level"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku haproxy:report --global --format json | jq -e ."
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku haproxy:report --global --format json | jq -r '.\"computed-log-level\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "ERROR"
|
||||
|
||||
run /bin/bash -c "dokku haproxy:report --global"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "global haproxy information"
|
||||
}
|
||||
|
||||
@test "(haproxy:report) refresh-conf global computed" {
|
||||
run /bin/bash -c "dokku haproxy:set --global refresh-conf"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku haproxy:report --global --haproxy-global-refresh-conf"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku haproxy:report --global --haproxy-computed-refresh-conf"
|
||||
assert_success
|
||||
assert_output "10"
|
||||
|
||||
run /bin/bash -c "dokku haproxy:set --global refresh-conf 30"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku haproxy:report --global --haproxy-global-refresh-conf"
|
||||
assert_success
|
||||
assert_output "30"
|
||||
|
||||
run /bin/bash -c "dokku haproxy:report --global --haproxy-computed-refresh-conf"
|
||||
assert_success
|
||||
assert_output "30"
|
||||
}
|
||||
@@ -7,6 +7,7 @@ setup() {
|
||||
dokku nginx:stop
|
||||
dokku haproxy:set --global letsencrypt-server https://acme-staging-v02.api.letsencrypt.org/directory
|
||||
dokku haproxy:set --global letsencrypt-email
|
||||
dokku haproxy:set --global refresh-conf 2
|
||||
dokku haproxy:start
|
||||
create_app
|
||||
}
|
||||
@@ -15,6 +16,7 @@ teardown() {
|
||||
global_teardown
|
||||
destroy_app
|
||||
dokku haproxy:stop
|
||||
dokku haproxy:set --global refresh-conf
|
||||
dokku nginx:start
|
||||
}
|
||||
|
||||
@@ -32,6 +34,94 @@ teardown() {
|
||||
assert_output "$help_output"
|
||||
}
|
||||
|
||||
@test "(haproxy) global-only keys" {
|
||||
for key in image log-level letsencrypt-email letsencrypt-server refresh-conf; do
|
||||
run /bin/bash -c "dokku haproxy:set $TEST_APP $key somevalue"
|
||||
echo "key: $key"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output_contains "can only be set globally"
|
||||
done
|
||||
}
|
||||
|
||||
@test "(haproxy) refresh-conf" {
|
||||
run /bin/bash -c "dokku haproxy:set $TEST_APP refresh-conf 2"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output_contains "can only be set globally"
|
||||
|
||||
run /bin/bash -c "dokku haproxy:set --global refresh-conf 5"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku haproxy:report --global --haproxy-global-refresh-conf"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "5"
|
||||
|
||||
run /bin/bash -c "dokku haproxy:report --global --haproxy-computed-refresh-conf"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "5"
|
||||
|
||||
run /bin/bash -c "dokku haproxy:show-config"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "EASYHAPROXY_REFRESH_CONF=5"
|
||||
|
||||
run /bin/bash -c "dokku haproxy:set --global refresh-conf"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku haproxy:report --global --haproxy-global-refresh-conf"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku haproxy:report --global --haproxy-computed-refresh-conf"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "10"
|
||||
}
|
||||
|
||||
@test "(haproxy:report) --global raw and computed keys in --format json" {
|
||||
run /bin/bash -c "dokku haproxy:set --global refresh-conf"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku haproxy:report --global --format json | jq -r '.\"global-image\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku haproxy:report --global --format json | jq -r '.\"computed-image\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_exists
|
||||
|
||||
run /bin/bash -c "dokku haproxy:report --global --format json | jq -r '.\"global-refresh-conf\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku haproxy:report --global --format json | jq -r '.\"computed-refresh-conf\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "10"
|
||||
}
|
||||
|
||||
@test "(haproxy) log-level" {
|
||||
run /bin/bash -c "dokku haproxy:set --global log-level DEBUG"
|
||||
echo "output: $output"
|
||||
@@ -60,11 +150,7 @@ teardown() {
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "curl --silent $(dokku url $TEST_APP)"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "python/http.server"
|
||||
assert_http_localhost_response_contains "http" "$TEST_APP.$DOKKU_DOMAIN" "80" "/" "python/http.server"
|
||||
}
|
||||
|
||||
@test "(haproxy) multiple domains" {
|
||||
@@ -88,8 +174,6 @@ teardown() {
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
sleep 5
|
||||
|
||||
run /bin/bash -c "dokku logs $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
@@ -162,12 +246,12 @@ teardown() {
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku --quiet ports:report $TEST_APP --ports-map"
|
||||
run /bin/bash -c "dokku ports:report $TEST_APP --ports-map"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output_not_exists
|
||||
|
||||
run /bin/bash -c "dokku --quiet ports:report $TEST_APP --ports-map-detected"
|
||||
run /bin/bash -c "dokku ports:report $TEST_APP --ports-map-detected"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output "http:80:5000 https:443:5000"
|
||||
|
||||
@@ -22,9 +22,10 @@ teardown() {
|
||||
|
||||
local CIDS=$(get_app_container_ids "$APP")
|
||||
|
||||
run "$DOCKER_BIN" container top "$CIDS"
|
||||
run /bin/bash -c "$DOCKER_BIN container top $CIDS"
|
||||
echo "output: $output"
|
||||
assert_output_contains "<defunct>" "0"
|
||||
echo "status: $status"
|
||||
assert_output_not_contains "<defunct>"
|
||||
}
|
||||
|
||||
@test "(init) dockerfile no tini" {
|
||||
@@ -37,9 +38,10 @@ teardown() {
|
||||
|
||||
local CIDS=$(get_app_container_ids "$APP")
|
||||
|
||||
run "$DOCKER_BIN" container top "$CIDS"
|
||||
run /bin/bash -c "$DOCKER_BIN container top $CIDS"
|
||||
echo "output: $output"
|
||||
assert_output_contains "<defunct>" "0"
|
||||
echo "status: $status"
|
||||
assert_output_not_contains "<defunct>"
|
||||
}
|
||||
|
||||
@test "(init) dockerfile with tini" {
|
||||
@@ -52,7 +54,8 @@ teardown() {
|
||||
|
||||
local CIDS=$(get_app_container_ids "$APP")
|
||||
|
||||
run "$DOCKER_BIN" container top "$CIDS"
|
||||
run /bin/bash -c "$DOCKER_BIN container top $CIDS"
|
||||
echo "output: $output"
|
||||
assert_output_contains "<defunct>" "0"
|
||||
echo "status: $status"
|
||||
assert_output_not_contains "<defunct>"
|
||||
}
|
||||
|
||||
1261
tests/unit/logs-1.bats
Normal file
1261
tests/unit/logs-1.bats
Normal file
File diff suppressed because it is too large
Load Diff
425
tests/unit/logs-2.bats
Normal file
425
tests/unit/logs-2.bats
Normal file
@@ -0,0 +1,425 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
setup() {
|
||||
rm "${BATS_PARENT_TMPNAME}.skip" || true
|
||||
global_setup
|
||||
}
|
||||
|
||||
teardown() {
|
||||
destroy_app
|
||||
# a leftover app-label-alias makes every later test's vector source filter on
|
||||
# a label that dokku never applies to a container, which silently disables log
|
||||
# collection for the rest of the file
|
||||
dokku logs:set --global app-label-alias >/dev/null 2>/dev/null || true
|
||||
dokku logs:set --global vector-image >/dev/null 2>/dev/null || true
|
||||
dokku logs:set --global vector-networks >/dev/null 2>/dev/null || true
|
||||
dokku logs:set --global vector-sink >/dev/null 2>/dev/null || true
|
||||
dokku logs:set --global vector-cron-sink >/dev/null 2>/dev/null || true
|
||||
docker network rm test-vector-net-a >/dev/null || true
|
||||
docker network rm test-vector-net-b >/dev/null || true
|
||||
global_teardown
|
||||
}
|
||||
|
||||
@test "(logs) vector validates the generated cron routing config" {
|
||||
run create_app
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku logs:set $TEST_APP vector-sink console://?encoding[codec]=json"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku logs:set $TEST_APP vector-cron-sink console://?encoding[codec]=text"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku logs:vector-start 2>&1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
# unit tests cannot catch a VRL syntax error or a malformed route schema
|
||||
run /bin/bash -c "docker exec vector-vector-1 vector validate --no-environment /etc/vector/vector.json"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
# the relabel branches are generated VRL too, and a syntax error there would
|
||||
# take the whole config down rather than just the rename
|
||||
run /bin/bash -c "dokku logs:set --global vector-sink console://?encoding[codec]=json"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku logs:set --global app-label-alias global_alt_name"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku logs:set $TEST_APP app-label-alias app_alt_name"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "docker exec vector-vector-1 vector validate --no-environment /etc/vector/vector.json"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku logs:vector-stop 2>&1"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku logs:set $TEST_APP app-label-alias"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku logs:set --global app-label-alias"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku logs:set --global vector-sink"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku logs:set $TEST_APP vector-cron-sink"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku logs:set $TEST_APP vector-sink"
|
||||
assert_success
|
||||
}
|
||||
|
||||
# the regression test for the alias silently disabling collection: the source
|
||||
# has to keep filtering on the label dokku applies, while the event that comes
|
||||
# out the other end carries the alias instead
|
||||
@test "(logs) a non-default app-label-alias still ships logs" {
|
||||
run create_app
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku logs:set $TEST_APP vector-sink 'console://?encoding[codec]=json'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku logs:set --global app-label-alias alt_name"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku logs:vector-start 2>&1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run start_vector_probe VECTOR_ALIAS_OK
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run wait_for_vector_alias_event VECTOR_ALIAS_OK alt_name
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
dump_vector_diagnostics "$TEST_APP"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "docker container rm --force vector-alias-probe"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku logs:vector-stop 2>&1"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(logs) logs:vector-start attaches configured networks" {
|
||||
docker network create test-vector-net-a >/dev/null
|
||||
docker network create test-vector-net-b >/dev/null
|
||||
|
||||
run /bin/bash -c "dokku logs:set --global vector-networks test-vector-net-a,test-vector-net-b 2>&1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku logs:vector-start 2>&1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "Vector container is running"
|
||||
|
||||
run /bin/bash -c "sudo docker inspect --format='{{range \$k, \$v := .NetworkSettings.Networks}}{{\$k}} {{end}}' vector-vector-1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "test-vector-net-a"
|
||||
assert_output_contains "test-vector-net-b"
|
||||
assert_output_contains "bridge" 0
|
||||
|
||||
run /bin/bash -c "dokku logs:vector-stop 2>&1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku logs:vector-start 2>&1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "Vector container is running"
|
||||
|
||||
run /bin/bash -c "sudo docker inspect --format='{{range \$k, \$v := .NetworkSettings.Networks}}{{\$k}} {{end}}' vector-vector-1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "test-vector-net-a"
|
||||
assert_output_contains "test-vector-net-b"
|
||||
assert_output_contains "bridge" 0
|
||||
|
||||
run /bin/bash -c "dokku logs:set --global vector-networks 2>&1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku logs:vector-stop 2>&1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku logs:vector-start 2>&1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "sudo docker inspect --format='{{range \$k, \$v := .NetworkSettings.Networks}}{{\$k}} {{end}}' vector-vector-1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "bridge"
|
||||
|
||||
run /bin/bash -c "dokku logs:vector-stop 2>&1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(logs) logs:vector" {
|
||||
run /bin/bash -c "dokku logs:vector-logs 2>&1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output_contains "Vector container does not exist"
|
||||
|
||||
run /bin/bash -c "dokku apps:create example.com"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku logs:vector-start 2>&1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "Vector container is running"
|
||||
|
||||
run /bin/bash -c "sudo docker inspect --format='{{.HostConfig.RestartPolicy.Name}}' vector-vector-1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "unless-stopped"
|
||||
|
||||
run /bin/bash -c "dokku logs:vector-logs 2>&1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "Vector container logs"
|
||||
|
||||
run /bin/bash -c "dokku --force apps:destroy example.com"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku logs:vector-logs --num 10 2>&1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "Vector container logs"
|
||||
assert_output_contains "vector:" 10
|
||||
assert_line_count 11
|
||||
|
||||
run /bin/bash -c "dokku logs:vector-logs --num 5 2>&1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "Vector container logs"
|
||||
assert_output_contains "vector:" 5
|
||||
assert_line_count 6
|
||||
|
||||
run /bin/bash -c "docker stop vector-vector-1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku logs:vector-logs 2>&1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "Vector container logs"
|
||||
assert_output_contains "Vector container is not running"
|
||||
|
||||
run /bin/bash -c "dokku logs:vector-stop 2>&1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "Stopping and removing vector container"
|
||||
}
|
||||
|
||||
@test "(logs) vector-cron-sink routes cron task output to the cron sink" {
|
||||
run deploy_app python dokku@$DOKKU_DOMAIN:$TEST_APP template_cron_file_marker
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
cron_id="$(dokku cron:list $TEST_APP --format json | jq -r '.[0].id')"
|
||||
echo "cron_id: $cron_id"
|
||||
|
||||
run /bin/bash -c "dokku logs:vector-start 2>&1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
# both sinks write to vector's own stdout, with different codecs, so the sink
|
||||
# an event was routed to is identifiable without depending on a writable
|
||||
# mount: the cron branch emits json carrying the fields the remap adds, while
|
||||
# anything reaching the plain sink emits the bare message
|
||||
run /bin/bash -c "dokku logs:set $TEST_APP vector-sink 'console://?encoding[codec]=text'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku logs:set $TEST_APP vector-cron-sink 'console://?encoding[codec]=json'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
# vector reloads via --watch-config, so wait for the routing to be live
|
||||
run wait_for_vector_route "$TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku cron:run $TEST_APP $cron_id"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run wait_for_vector_cron_event VECTOR_CRON_OK "$cron_id"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
dump_vector_diagnostics "$TEST_APP"
|
||||
assert_success
|
||||
|
||||
# a bare message line would mean the event reached the plain sink instead of
|
||||
# being routed onto the cron branch
|
||||
run count_vector_plain_lines VECTOR_CRON_OK
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output "0"
|
||||
|
||||
run /bin/bash -c "dokku logs:vector-stop 2>&1"
|
||||
assert_success
|
||||
}
|
||||
|
||||
wait_for_vector_route() {
|
||||
declare desc="waits for the vector config on disk to contain the app's cron router"
|
||||
declare APP="$1"
|
||||
local i
|
||||
|
||||
for i in $(seq 1 30); do
|
||||
if jq -e ".transforms[\"docker-router:$APP\"]" /var/lib/dokku/data/logs/vector.json >/dev/null 2>&1; then
|
||||
return 0
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
|
||||
echo "timed out waiting for the cron router in vector.json"
|
||||
return 1
|
||||
}
|
||||
|
||||
start_vector_probe() {
|
||||
declare desc="runs a container carrying only the label dokku applies, emitting a marker for long enough for vector to attach"
|
||||
declare MARKER="$1"
|
||||
|
||||
docker container run --detach --name vector-alias-probe \
|
||||
--label "com.dokku.app-name=$TEST_APP" \
|
||||
gliderlabs/herokuish \
|
||||
bash -c "for i in \$(seq 1 30); do echo $MARKER; sleep 1; done"
|
||||
}
|
||||
|
||||
wait_for_vector_alias_event() {
|
||||
declare desc="waits for a marker to arrive carrying the configured alias in place of the default label"
|
||||
declare MARKER="$1" ALIAS="$2"
|
||||
local i
|
||||
|
||||
for i in $(seq 1 60); do
|
||||
if docker logs vector-vector-1 2>/dev/null | grep "$MARKER" \
|
||||
| jq -e --arg alias "$ALIAS" \
|
||||
'select(.label[$alias] != null and .label["com.dokku.app-name"] == null)' >/dev/null 2>/dev/null; then
|
||||
return 0
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
|
||||
echo "timed out waiting for a $MARKER event labelled $ALIAS"
|
||||
return 1
|
||||
}
|
||||
|
||||
wait_for_vector_cron_event() {
|
||||
declare desc="waits for a marker to arrive on the cron branch, carrying the fields the remap adds"
|
||||
declare MARKER="$1" CRON_ID="$2"
|
||||
local i
|
||||
|
||||
for i in $(seq 1 60); do
|
||||
if docker logs vector-vector-1 2>/dev/null | grep "$MARKER" \
|
||||
| jq -e --arg id "$CRON_ID" 'select(.dokku_cron_id == $id)' >/dev/null 2>/dev/null; then
|
||||
return 0
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
|
||||
echo "timed out waiting for a cron-routed $MARKER event with dokku_cron_id=$CRON_ID"
|
||||
return 1
|
||||
}
|
||||
|
||||
count_vector_plain_lines() {
|
||||
declare desc="counts bare message lines, which only the text-encoded plain sink emits"
|
||||
declare MARKER="$1"
|
||||
|
||||
docker logs vector-vector-1 2>/dev/null | grep -c -x "$MARKER" || true
|
||||
}
|
||||
|
||||
dump_vector_diagnostics() {
|
||||
declare desc="prints the state needed to tell apart the ways cron shipping can fail"
|
||||
declare APP="$1"
|
||||
|
||||
# sources matter as much as routing here: a stale app-label-alias makes the
|
||||
# source filter on a label no container carries, which collects nothing
|
||||
echo "--- generated config ---"
|
||||
jq '{sources, transforms, sinks}' /var/lib/dokku/data/logs/vector.json || true
|
||||
|
||||
echo "--- containers carrying the app label ---"
|
||||
docker ps --all --filter "label=com.dokku.app-name=$APP" --format '{{.Names}} {{.Status}}' || true
|
||||
|
||||
echo "--- vector stdout, where both sinks write ---"
|
||||
docker logs vector-vector-1 2>/dev/null | tail -20 || true
|
||||
|
||||
# vector reports template_failed and other component errors on stderr, so
|
||||
# keep it separate from the collected log lines on stdout
|
||||
echo "--- vector stderr ---"
|
||||
docker logs vector-vector-1 2>&1 1>/dev/null | tail -20 || true
|
||||
}
|
||||
|
||||
template_cron_file_marker() {
|
||||
declare desc="writes an app.json with a cron task emitting a known marker"
|
||||
local APP="$1" APP_REPO_DIR="$2"
|
||||
[[ -z "$APP" ]] && local APP="$TEST_APP"
|
||||
echo "injecting cron app.json -> $APP_REPO_DIR/app.json"
|
||||
# cron_task.py sleeps either side of its output. a task that exits
|
||||
# immediately is removed before vector can attach to it, which is documented
|
||||
# behavior rather than something this test should assert against
|
||||
cat <<EOF >"$APP_REPO_DIR/app.json"
|
||||
{
|
||||
"cron": [
|
||||
{
|
||||
"command": "python3 cron_task.py VECTOR_CRON_OK",
|
||||
"schedule": "@daily"
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
}
|
||||
@@ -1,717 +0,0 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
setup() {
|
||||
rm "${BATS_PARENT_TMPNAME}.skip" || true
|
||||
global_setup
|
||||
}
|
||||
|
||||
teardown() {
|
||||
destroy_app
|
||||
global_teardown
|
||||
}
|
||||
|
||||
@test "(logs) logs:help" {
|
||||
run /bin/bash -c "dokku logs:help"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output_contains "Manage log integration for an app"
|
||||
}
|
||||
|
||||
@test "(logs) logs:report" {
|
||||
run /bin/bash -c "dokku logs:report"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output_contains "You haven't deployed any applications yet"
|
||||
|
||||
run create_app
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku logs:report 2>&1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "$TEST_APP logs information"
|
||||
}
|
||||
|
||||
@test "(logs) logs:report app" {
|
||||
run create_app
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku logs:report $TEST_APP 2>&1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "$TEST_APP logs information"
|
||||
|
||||
run /bin/bash -c "dokku logs:report $TEST_APP --invalid-flag 2>&1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output_contains "$TEST_APP logs information" 0
|
||||
assert_output_contains "Invalid flag passed, valid flags: --logs-app-label-alias, --logs-computed-app-label-alias, --logs-computed-max-size, --logs-global-app-label-alias, --logs-global-max-size, --logs-global-vector-sink, --logs-max-size, --logs-vector-global-image, --logs-vector-sink"
|
||||
|
||||
run /bin/bash -c "dokku logs:report $TEST_APP --logs-vector-sink 2>&1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "$TEST_APP logs information" 0
|
||||
assert_output_contains "Invalid flag passed" 0
|
||||
|
||||
run /bin/bash -c "dokku logs:report $TEST_APP --logs-global-vector-sink 2>&1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "$TEST_APP logs information" 0
|
||||
assert_output_contains "Invalid flag passed" 0
|
||||
}
|
||||
|
||||
@test "(logs) logs:set [error]" {
|
||||
run /bin/bash -c "dokku logs:set 2>&1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
|
||||
assert_output_contains "Please specify an app to run the command on"
|
||||
run /bin/bash -c "dokku logs:set ${TEST_APP}-non-existent" 2>&1
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output_contains "App $TEST_APP-non-existent does not exist"
|
||||
|
||||
run create_app
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku logs:set $TEST_APP" 2>&1
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output_contains "No property specified"
|
||||
|
||||
run /bin/bash -c "dokku logs:set $TEST_APP invalid" 2>&1
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output_contains "Invalid property specified, valid properties include: app-label-alias, max-size, vector-image, vector-sink"
|
||||
|
||||
run /bin/bash -c "dokku logs:set $TEST_APP invalid value" 2>&1
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output_contains "Invalid property specified, valid properties include: app-label-alias, max-size, vector-image, vector-sink"
|
||||
}
|
||||
|
||||
@test "(logs) logs:set app" {
|
||||
run create_app
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku logs:report $TEST_APP --logs-vector-sink 2>&1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_not_exists
|
||||
|
||||
run /bin/bash -c "dokku logs:set $TEST_APP vector-sink" 2>&1
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "Unsetting vector-sink"
|
||||
assert_output_contains "Writing updated vector config to /var/lib/dokku/data/logs/vector.json"
|
||||
|
||||
run /bin/bash -c "dokku logs:report $TEST_APP --logs-vector-sink 2>&1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_not_exists
|
||||
|
||||
run /bin/bash -c "dokku logs:set $TEST_APP vector-sink console://?encoding[codec]=json" 2>&1
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "Setting vector-sink"
|
||||
assert_output_contains "Writing updated vector config to /var/lib/dokku/data/logs/vector.json"
|
||||
|
||||
run /bin/bash -c "dokku logs:report $TEST_APP --logs-vector-sink 2>&1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "console://?encoding[codec]=json"
|
||||
|
||||
run /bin/bash -c "dokku logs:set $TEST_APP vector-sink datadog_logs://?api_key=abc123" 2>&1
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "Setting vector-sink"
|
||||
assert_output_contains "Writing updated vector config to /var/lib/dokku/data/logs/vector.json"
|
||||
|
||||
run /bin/bash -c "dokku logs:report $TEST_APP --logs-vector-sink 2>&1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "datadog_logs://?api_key=abc123"
|
||||
|
||||
run /bin/bash -c "dokku logs:set $TEST_APP vector-sink" 2>&1
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "Unsetting vector-sink"
|
||||
assert_output_contains "Writing updated vector config to /var/lib/dokku/data/logs/vector.json"
|
||||
|
||||
run /bin/bash -c "dokku logs:report $TEST_APP --logs-vector-sink 2>&1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_not_exists
|
||||
|
||||
run /bin/bash -c "dokku logs:set $TEST_APP vector-sink" 2>&1
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "Unsetting vector-sink"
|
||||
|
||||
run /bin/bash -c "dokku logs:report $TEST_APP --logs-vector-sink 2>&1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_not_exists
|
||||
|
||||
run /bin/bash -c "dokku logs:report $TEST_APP --logs-max-size 2>&1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_not_exists
|
||||
|
||||
run /bin/bash -c "dokku logs:set $TEST_APP max-size" 2>&1
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "Unsetting max-size"
|
||||
|
||||
run /bin/bash -c "dokku logs:report $TEST_APP --logs-max-size 2>&1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_not_exists
|
||||
|
||||
run /bin/bash -c "dokku logs:set $TEST_APP max-size 20m" 2>&1
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "Setting max-size"
|
||||
|
||||
run /bin/bash -c "dokku logs:report $TEST_APP --logs-max-size 2>&1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "20m"
|
||||
|
||||
run /bin/bash -c "dokku logs:set $TEST_APP max-size unlimited" 2>&1
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "Setting max-size"
|
||||
|
||||
run /bin/bash -c "dokku logs:report $TEST_APP --logs-max-size 2>&1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "unlimited"
|
||||
|
||||
run /bin/bash -c "dokku logs:set "$TEST_APP" max-size" 2>&1
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "Unsetting max-size"
|
||||
|
||||
run /bin/bash -c "dokku logs:report $TEST_APP --logs-max-size 2>&1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_not_exists
|
||||
}
|
||||
|
||||
@test "(logs) logs:set equals in uri" {
|
||||
run create_app
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku logs:set $TEST_APP vector-sink 'loki://?endpoint=https://host&encoding[codec]=text&auth[token]=foobar%3D&auth[strategy]=bearer'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "Setting vector-sink"
|
||||
assert_output_contains "Writing updated vector config to /var/lib/dokku/data/logs/vector.json"
|
||||
# type: loki
|
||||
# endpoint: https://host
|
||||
# encoding[codec]: text
|
||||
# auth[token]: foobar=
|
||||
# auth[strategy]: bearer
|
||||
|
||||
run /bin/bash -c "jq -r '.sinks[\"docker-sink:$TEST_APP\"].auth.strategy' /var/lib/dokku/data/logs/vector.json"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "bearer"
|
||||
|
||||
run /bin/bash -c "jq -r '.sinks[\"docker-sink:$TEST_APP\"].auth.token' /var/lib/dokku/data/logs/vector.json"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "foobar="
|
||||
|
||||
run /bin/bash -c "jq -r '.sinks[\"docker-sink:$TEST_APP\"].endpoint' /var/lib/dokku/data/logs/vector.json"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "https://host"
|
||||
|
||||
run /bin/bash -c "jq -r '.sinks[\"docker-sink:$TEST_APP\"].encoding.codec' /var/lib/dokku/data/logs/vector.json"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "text"
|
||||
}
|
||||
|
||||
@test "(logs) logs:set escaped uri" {
|
||||
run create_app
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku logs:set $TEST_APP vector-sink http://?uri=https%3A//loggerservice.com%3A1234/%3Ftoken%3Dabc1234%26type%3Dvector%26key%3Dvalue%2Bvalue2"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "Setting vector-sink"
|
||||
assert_output_contains "Writing updated vector config to /var/lib/dokku/data/logs/vector.json"
|
||||
|
||||
run /bin/bash -c "dokku logs:report $TEST_APP --logs-vector-sink 2>&1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "http://?uri=https%3A//loggerservice.com%3A1234/%3Ftoken%3Dabc1234%26type%3Dvector%26key%3Dvalue%2Bvalue2"
|
||||
|
||||
run /bin/bash -c "jq -r '.sinks[\"docker-sink:$TEST_APP\"].uri' /var/lib/dokku/data/logs/vector.json"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "https://loggerservice.com:1234/?token=abc1234&type=vector&key=value+value2"
|
||||
|
||||
run /bin/bash -c "dokku logs:set $TEST_APP vector-sink 'aws_cloudwatch_logs://?create_missing_group=true&create_missing_stream=true&group_name=groupname&encoding[codec]=json®ion=sa-east-1&stream_name={{ host }}&auth[access_key_id]=KSDSIDJSAJD&auth[secret_access_key]=2932JSDJ%252BKSDSDJ'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "Setting vector-sink"
|
||||
assert_output_contains "Writing updated vector config to /var/lib/dokku/data/logs/vector.json"
|
||||
|
||||
run /bin/bash -c "dokku logs:report $TEST_APP --logs-vector-sink 2>&1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "aws_cloudwatch_logs://?create_missing_group=true&create_missing_stream=true&group_name=groupname&encoding[codec]=json®ion=sa-east-1&stream_name={{ host }}&auth[access_key_id]=KSDSIDJSAJD&auth[secret_access_key]=2932JSDJ%252BKSDSDJ"
|
||||
|
||||
run /bin/bash -c "jq -r '.sinks[\"docker-sink:$TEST_APP\"].auth.secret_access_key' /var/lib/dokku/data/logs/vector.json"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "2932JSDJ+KSDSDJ"
|
||||
}
|
||||
|
||||
@test "(logs) logs:set global" {
|
||||
run create_app
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku logs:report $TEST_APP --logs-global-vector-sink 2>&1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_not_exists
|
||||
|
||||
run /bin/bash -c "dokku logs:set --global vector-sink" 2>&1
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "Unsetting vector-sink"
|
||||
assert_output_contains "Writing updated vector config to /var/lib/dokku/data/logs/vector.json"
|
||||
|
||||
run /bin/bash -c "dokku logs:report $TEST_APP --logs-global-vector-sink 2>&1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_not_exists
|
||||
|
||||
run /bin/bash -c "dokku logs:set --global vector-sink console://?encoding[codec]=json" 2>&1
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "Setting vector-sink"
|
||||
assert_output_contains "Writing updated vector config to /var/lib/dokku/data/logs/vector.json"
|
||||
|
||||
run /bin/bash -c "dokku logs:report $TEST_APP --logs-global-vector-sink 2>&1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "console://?encoding[codec]=json"
|
||||
|
||||
run /bin/bash -c "dokku logs:set --global vector-sink datadog_logs://?api_key=abc123" 2>&1
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "Setting vector-sink"
|
||||
assert_output_contains "Writing updated vector config to /var/lib/dokku/data/logs/vector.json"
|
||||
|
||||
run /bin/bash -c "dokku logs:report $TEST_APP --logs-global-vector-sink 2>&1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "datadog_logs://?api_key=abc123"
|
||||
|
||||
run /bin/bash -c "dokku logs:set --global vector-sink" 2>&1
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "Unsetting vector-sink"
|
||||
assert_output_contains "Writing updated vector config to /var/lib/dokku/data/logs/vector.json"
|
||||
|
||||
run /bin/bash -c "dokku logs:report $TEST_APP --logs-global-vector-sink 2>&1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_not_exists
|
||||
|
||||
run /bin/bash -c "dokku logs:set --global vector-sink" 2>&1
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "Unsetting vector-sink"
|
||||
|
||||
run /bin/bash -c "dokku logs:report $TEST_APP --logs-global-vector-sink 2>&1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_not_exists
|
||||
|
||||
run /bin/bash -c "dokku logs:report $TEST_APP --logs-global-max-size 2>&1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "10m"
|
||||
|
||||
run /bin/bash -c "dokku logs:set --global max-size" 2>&1
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "Unsetting max-size"
|
||||
|
||||
run /bin/bash -c "dokku logs:report $TEST_APP --logs-global-max-size 2>&1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "10m"
|
||||
|
||||
run /bin/bash -c "dokku logs:set --global max-size 20m" 2>&1
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "Setting max-size"
|
||||
|
||||
run /bin/bash -c "dokku logs:report $TEST_APP --logs-global-max-size 2>&1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "20m"
|
||||
|
||||
run /bin/bash -c "dokku logs:set --global max-size unlimited" 2>&1
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "Setting max-size"
|
||||
|
||||
run /bin/bash -c "dokku logs:report $TEST_APP --logs-global-max-size 2>&1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "unlimited"
|
||||
|
||||
run /bin/bash -c "dokku logs:set --global max-size" 2>&1
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "Unsetting max-size"
|
||||
|
||||
run /bin/bash -c "dokku logs:report $TEST_APP --logs-global-max-size 2>&1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "10m"
|
||||
}
|
||||
|
||||
@test "(logs) logs:set app-label-alias" {
|
||||
run create_app
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku logs:set $TEST_APP vector-sink console://?encoding[codec]=json" 2>&1
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "Setting vector-sink"
|
||||
assert_output_contains "Writing updated vector config to /var/lib/dokku/data/logs/vector.json"
|
||||
|
||||
run /bin/bash -c "dokku logs:set --global app-label-alias" 2>&1
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "Unsetting app-label-alias"
|
||||
assert_output_contains "Writing updated vector config to /var/lib/dokku/data/logs/vector.json"
|
||||
|
||||
run /bin/bash -c "jq -r '.sources[\"docker-source:$TEST_APP\"].include_labels[0]' /var/lib/dokku/data/logs/vector.json"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "com.dokku.app-name=$TEST_APP"
|
||||
|
||||
run /bin/bash -c "dokku logs:set --global app-label-alias global-alt-name" 2>&1
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "Writing updated vector config to /var/lib/dokku/data/logs/vector.json"
|
||||
|
||||
run /bin/bash -c "dokku logs:report $TEST_APP --logs-computed-app-label-alias" 2>&1
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "global-alt-name"
|
||||
|
||||
run /bin/bash -c "cat /var/lib/dokku/data/logs/vector.json"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "jq -r '.sources[\"docker-source:$TEST_APP\"].include_labels[0]' /var/lib/dokku/data/logs/vector.json"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "global-alt-name=$TEST_APP"
|
||||
|
||||
run /bin/bash -c "dokku logs:set --global app-label-alias alt-name" 2>&1
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "Writing updated vector config to /var/lib/dokku/data/logs/vector.json"
|
||||
|
||||
run /bin/bash -c "dokku logs:report $TEST_APP --logs-computed-app-label-alias" 2>&1
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "alt-name"
|
||||
|
||||
run /bin/bash -c "jq -r '.sources[\"docker-source:$TEST_APP\"].include_labels[0]' /var/lib/dokku/data/logs/vector.json"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "alt-name=$TEST_APP"
|
||||
}
|
||||
|
||||
@test "(logs) logs:set max-size with alternate log-driver daemon" {
|
||||
if [[ "$REMOTE_CONTAINERS" == "true" ]]; then
|
||||
skip "skipping due non-existent docker service in remote dev container"
|
||||
fi
|
||||
|
||||
if [[ ! -f /etc/docker/daemon.json ]]; then
|
||||
echo "{}" >/etc/docker/daemon.json
|
||||
fi
|
||||
|
||||
driver="$(jq -r '."log-driver"' /etc/docker/daemon.json)"
|
||||
local TMP_FILE=$(mktemp "/tmp/${DOKKU_DOMAIN}.XXXX")
|
||||
|
||||
run create_app
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku logs:set $TEST_APP max-size 20m 2>&1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "Setting max-size"
|
||||
|
||||
run /bin/bash -c "echo '' | dokku plugin:trigger docker-args-process-deploy $TEST_APP 2>&1 | xargs"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "--log-opt=max-size=20m"
|
||||
|
||||
DRIVER="journald" jq '."log-driver" = env.DRIVER' <"/etc/docker/daemon.json" >"$TMP_FILE"
|
||||
mv "$TMP_FILE" /etc/docker/daemon.json
|
||||
|
||||
sudo service docker restart
|
||||
|
||||
run /bin/bash -c "dokku logs:set $TEST_APP max-size 20m 2>&1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "Setting max-size"
|
||||
|
||||
run /bin/bash -c "echo '' | dokku plugin:trigger docker-args-process-deploy $TEST_APP 2>&1 | xargs"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_not_exists
|
||||
|
||||
if [[ "$driver" = "null" ]]; then
|
||||
DRIVER="$driver" jq 'del(."log-driver")' <"/etc/docker/daemon.json" >"$TMP_FILE"
|
||||
else
|
||||
DRIVER="$driver" jq '."log-driver" = env.DRIVER' <"/etc/docker/daemon.json" >"$TMP_FILE"
|
||||
fi
|
||||
|
||||
mv "$TMP_FILE" /etc/docker/daemon.json
|
||||
sudo service docker restart
|
||||
|
||||
run /bin/bash -c "dokku logs:set $TEST_APP max-size 20m 2>&1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "Setting max-size"
|
||||
|
||||
run /bin/bash -c "echo '' | dokku plugin:trigger docker-args-process-deploy $TEST_APP 2>&1 | xargs"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "--log-opt=max-size=20m"
|
||||
}
|
||||
|
||||
@test "(logs) logs:set max-size with alternate log-driver" {
|
||||
run create_app
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku logs:set $TEST_APP max-size 20m" 2>&1
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "Setting max-size"
|
||||
|
||||
run /bin/bash -c "echo "" | dokku plugin:trigger docker-args-process-deploy $TEST_APP 2>&1 | xargs"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "--log-opt=max-size=20m"
|
||||
|
||||
run /bin/bash -c "dokku docker-options:add $TEST_APP deploy --log-driver=local" 2>&1
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "echo "" | dokku plugin:trigger docker-args-process-deploy $TEST_APP 2>&1 | xargs"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "--log-opt=max-size=20m"
|
||||
|
||||
run /bin/bash -c "dokku docker-options:add $TEST_APP deploy --log-driver=json-file" 2>&1
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "echo "" | dokku plugin:trigger docker-args-process-deploy $TEST_APP 2>&1 | xargs"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "--log-opt=max-size=20m"
|
||||
|
||||
run /bin/bash -c "dokku docker-options:add $TEST_APP deploy --log-driver=journald" 2>&1
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "echo "" | dokku plugin:trigger docker-args-process-deploy $TEST_APP 2>&1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_not_exists
|
||||
}
|
||||
|
||||
@test "(logs) logs:vector" {
|
||||
run /bin/bash -c "dokku logs:vector-logs 2>&1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output_contains "Vector container does not exist"
|
||||
|
||||
run /bin/bash -c "dokku apps:create example.com"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku logs:vector-start 2>&1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "Vector container is running"
|
||||
|
||||
run /bin/bash -c "sudo docker inspect --format='{{.HostConfig.RestartPolicy.Name}}' vector-vector-1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "unless-stopped"
|
||||
|
||||
run /bin/bash -c "dokku logs:vector-logs 2>&1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "Vector container logs"
|
||||
|
||||
run /bin/bash -c "dokku --force apps:destroy example.com"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku logs:vector-logs --num 10 2>&1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "Vector container logs"
|
||||
assert_output_contains "vector:" 10
|
||||
assert_line_count 11
|
||||
|
||||
run /bin/bash -c "dokku logs:vector-logs --num 5 2>&1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "Vector container logs"
|
||||
assert_output_contains "vector:" 5
|
||||
assert_line_count 6
|
||||
|
||||
run /bin/bash -c "docker stop vector-vector-1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku logs:vector-logs 2>&1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "Vector container logs"
|
||||
assert_output_contains "Vector container is not running"
|
||||
|
||||
run /bin/bash -c "dokku logs:vector-stop 2>&1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "Stopping and removing vector container"
|
||||
}
|
||||
@@ -14,6 +14,7 @@ teardown() {
|
||||
docker network rm create-network || true
|
||||
docker network rm deploy-network || true
|
||||
docker network rm initial-network || true
|
||||
docker network rm "$TEST_NETWORK" || true
|
||||
global_teardown
|
||||
}
|
||||
|
||||
@@ -31,6 +32,299 @@ teardown() {
|
||||
assert_output "$help_output"
|
||||
}
|
||||
|
||||
@test "(network:report) --global --format json" {
|
||||
run /bin/bash -c "dokku network:set --global tld dokku.test"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku network:report --global --format json | jq -e ."
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku network:report --global --format json | jq -r '.\"network-global-tld\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "dokku.test"
|
||||
|
||||
run /bin/bash -c "dokku network:report --global --format json | jq -r '.\"global-tld\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "dokku.test"
|
||||
|
||||
run /bin/bash -c "dokku network:report --global --format json | jq -r 'has(\"network-tld\")'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "false"
|
||||
|
||||
run /bin/bash -c "dokku network:report --global --format json | jq -r 'has(\"tld\")'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "false"
|
||||
|
||||
run /bin/bash -c "dokku network:report --global"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "--global"
|
||||
|
||||
run /bin/bash -c "dokku network:set --global tld"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(network:report) emits new stripped JSON keys alongside legacy" {
|
||||
run /bin/bash -c "dokku network:report --global --format json | jq -r 'has(\"global-tld\") and has(\"network-global-tld\")'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku network:report --global --format json | jq -r 'has(\"computed-tld\") and has(\"network-computed-tld\")'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku network:report $TEST_APP --format json | jq -r 'has(\"tld\") and has(\"network-tld\")'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku network:report $TEST_APP --format json | jq -r 'has(\"web-listeners\") and has(\"network-web-listeners\")'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
}
|
||||
|
||||
@test "(network:report) tld raw vs computed" {
|
||||
run /bin/bash -c "dokku network:set --global tld"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku network:report --global --format json | jq -r '.\"network-global-tld\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku network:set --global tld example.test"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku network:report --global --format json | jq -r '.\"network-global-tld\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "example.test"
|
||||
|
||||
run /bin/bash -c "dokku network:report $TEST_APP --format json | jq -r '.\"network-global-tld\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "example.test"
|
||||
|
||||
run /bin/bash -c "dokku network:report $TEST_APP --format json | jq -r '.\"network-computed-tld\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "example.test"
|
||||
|
||||
run /bin/bash -c "dokku network:set --global tld"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(network:report) attach-post-create raw vs computed vs global" {
|
||||
docker network create create-network-x >/dev/null
|
||||
run /bin/bash -c "dokku network:set --global attach-post-create"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku network:report $TEST_APP --format json | jq -r '.\"network-attach-post-create\"'"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku network:report $TEST_APP --format json | jq -r '.\"network-global-attach-post-create\"'"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku network:report $TEST_APP --format json | jq -r '.\"network-computed-attach-post-create\"'"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku network:set --global attach-post-create create-network-x"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku network:report $TEST_APP --format json | jq -r '.\"network-global-attach-post-create\"'"
|
||||
assert_success
|
||||
assert_output "create-network-x"
|
||||
|
||||
run /bin/bash -c "dokku network:report $TEST_APP --format json | jq -r '.\"network-computed-attach-post-create\"'"
|
||||
assert_success
|
||||
assert_output "create-network-x"
|
||||
|
||||
run /bin/bash -c "dokku network:set --global attach-post-create"
|
||||
assert_success
|
||||
|
||||
docker network rm create-network-x >/dev/null
|
||||
}
|
||||
|
||||
@test "(network:report) attach-post-deploy raw vs computed vs global" {
|
||||
docker network create deploy-network-x >/dev/null
|
||||
run /bin/bash -c "dokku network:set --global attach-post-deploy"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku network:report $TEST_APP --format json | jq -r '.\"network-attach-post-deploy\"'"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku network:report $TEST_APP --format json | jq -r '.\"network-global-attach-post-deploy\"'"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku network:set --global attach-post-deploy deploy-network-x"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku network:report $TEST_APP --format json | jq -r '.\"network-global-attach-post-deploy\"'"
|
||||
assert_success
|
||||
assert_output "deploy-network-x"
|
||||
|
||||
run /bin/bash -c "dokku network:report $TEST_APP --format json | jq -r '.\"network-computed-attach-post-deploy\"'"
|
||||
assert_success
|
||||
assert_output "deploy-network-x"
|
||||
|
||||
run /bin/bash -c "dokku network:set --global attach-post-deploy"
|
||||
assert_success
|
||||
|
||||
docker network rm deploy-network-x >/dev/null
|
||||
}
|
||||
|
||||
@test "(network:report) initial-network raw vs computed vs global" {
|
||||
docker network create initial-network-x >/dev/null
|
||||
run /bin/bash -c "dokku network:set --global initial-network"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku network:report $TEST_APP --format json | jq -r '.\"network-initial-network\"'"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku network:report $TEST_APP --format json | jq -r '.\"network-global-initial-network\"'"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku network:set --global initial-network initial-network-x"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku network:report $TEST_APP --format json | jq -r '.\"network-global-initial-network\"'"
|
||||
assert_success
|
||||
assert_output "initial-network-x"
|
||||
|
||||
run /bin/bash -c "dokku network:report $TEST_APP --format json | jq -r '.\"network-computed-initial-network\"'"
|
||||
assert_success
|
||||
assert_output "initial-network-x"
|
||||
|
||||
run /bin/bash -c "dokku network:set --global initial-network"
|
||||
assert_success
|
||||
|
||||
docker network rm initial-network-x >/dev/null
|
||||
}
|
||||
|
||||
@test "(network:report) bind-all-interfaces raw vs computed vs global" {
|
||||
run /bin/bash -c "dokku network:set --global bind-all-interfaces"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku network:report --global --format json | jq -r '.\"network-global-bind-all-interfaces\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku network:report --global --format json | jq -r '.\"network-computed-bind-all-interfaces\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "false"
|
||||
|
||||
run /bin/bash -c "dokku network:set --global bind-all-interfaces true"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku network:report --global --format json | jq -r '.\"network-global-bind-all-interfaces\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku network:report --global --format json | jq -r '.\"network-computed-bind-all-interfaces\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku network:report $TEST_APP --format json | jq -r '.\"network-bind-all-interfaces\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku network:report $TEST_APP --format json | jq -r '.\"network-computed-bind-all-interfaces\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku network:set --global bind-all-interfaces"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku network:report --global --format json | jq -r '.\"network-global-bind-all-interfaces\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku network:report --global --format json | jq -r '.\"network-computed-bind-all-interfaces\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "false"
|
||||
|
||||
run /bin/bash -c "dokku network:set $TEST_APP bind-all-interfaces true"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku network:report $TEST_APP --format json | jq -r '.\"network-bind-all-interfaces\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku network:set $TEST_APP bind-all-interfaces"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku network:report $TEST_APP --format json | jq -r '.\"network-bind-all-interfaces\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku network:report $TEST_APP --format json | jq -r '.\"network-computed-bind-all-interfaces\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "false"
|
||||
}
|
||||
|
||||
@test "(network) network:set bind-all-interfaces" {
|
||||
run deploy_app
|
||||
echo "output: $output"
|
||||
@@ -148,6 +442,63 @@ teardown() {
|
||||
assert_failure
|
||||
}
|
||||
|
||||
@test "(network:list) --format json exposes DokkuManaged" {
|
||||
run /bin/bash -c "dokku network:create $TEST_NETWORK"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku network:list --format json | jq -e ."
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku network:list --format json | jq -r '.[] | select(.Name == \"bridge\") | .DokkuManaged'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "false"
|
||||
|
||||
run /bin/bash -c "dokku network:list --format json | jq -r '.[] | select(.Name == \"$TEST_NETWORK\") | .DokkuManaged'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku --force network:destroy $TEST_NETWORK"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(network:list) --dokku-managed filters to dokku-created networks" {
|
||||
run /bin/bash -c "dokku network:create $TEST_NETWORK"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku network:list --dokku-managed | grep -w bridge"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
|
||||
run /bin/bash -c "dokku network:list --dokku-managed | grep $TEST_NETWORK"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku network:list --dokku-managed --format json | jq -r '.[].DokkuManaged' | sort -u"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku --force network:destroy $TEST_NETWORK"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(network) network:set attach" {
|
||||
run deploy_app
|
||||
echo "output: $output"
|
||||
@@ -327,7 +678,7 @@ teardown() {
|
||||
}
|
||||
|
||||
@test "(network) handle single-udp app" {
|
||||
run /bin/bash -c "dokku docker-options:add $TEST_APP -p 1194:1194"
|
||||
run /bin/bash -c "dokku docker-options:add $TEST_APP deploy -p 1194:1194"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
@@ -28,6 +28,104 @@ teardown() {
|
||||
assert_output "$help_output"
|
||||
}
|
||||
|
||||
@test "(nginx:report) info-flag works before deploy" {
|
||||
run create_app
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku nginx:report $TEST_APP --nginx-bind-address-ipv4"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku nginx:set $TEST_APP bind-address-ipv4 127.0.0.1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku nginx:report $TEST_APP --nginx-bind-address-ipv4"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "127.0.0.1"
|
||||
|
||||
run /bin/bash -c "dokku nginx:report $TEST_APP --nginx-invalid-flag"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output_contains "Invalid flag passed"
|
||||
}
|
||||
|
||||
@test "(nginx:report) --format json" {
|
||||
run create_app
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku nginx:set $TEST_APP bind-address-ipv4 127.0.0.1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku nginx:report $TEST_APP --format json | jq -r '.\"bind-address-ipv4\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "127.0.0.1"
|
||||
|
||||
run /bin/bash -c "dokku nginx:report $TEST_APP --format json | jq -e ."
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku nginx:report --format json | jq -e ."
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku nginx:report $TEST_APP --format json --nginx-bind-address-ipv4"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output_contains "--format flag cannot be specified when specifying an info flag"
|
||||
}
|
||||
|
||||
@test "(nginx:report) --global --format json" {
|
||||
run /bin/bash -c "dokku nginx:report --global --format json | jq -e ."
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku nginx:report --global --format json | jq -r 'keys[]' | grep -v 'global-' | wc -l"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "0"
|
||||
|
||||
run /bin/bash -c "dokku nginx:report --global"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "global nginx information"
|
||||
|
||||
run /bin/bash -c "dokku nginx:set --global client-max-body-size 5m"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku nginx:report --global --nginx-global-client-max-body-size"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "5m"
|
||||
|
||||
run /bin/bash -c "dokku nginx:set --global client-max-body-size"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(nginx-vhosts) proxy:build-config (domains:disable/enable)" {
|
||||
run deploy_app
|
||||
echo "output: $output"
|
||||
|
||||
99
tests/unit/nginx-vhosts_13.bats
Normal file
99
tests/unit/nginx-vhosts_13.bats
Normal file
@@ -0,0 +1,99 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
setup() {
|
||||
global_setup
|
||||
[[ -f "$DOKKU_ROOT/VHOST" ]] && cp -fp "$DOKKU_ROOT/VHOST" "$DOKKU_ROOT/VHOST.bak"
|
||||
}
|
||||
|
||||
teardown() {
|
||||
destroy_app
|
||||
[[ -f "$DOKKU_ROOT/VHOST.bak" ]] && mv "$DOKKU_ROOT/VHOST.bak" "$DOKKU_ROOT/VHOST" && chown dokku:dokku "$DOKKU_ROOT/VHOST"
|
||||
global_teardown
|
||||
}
|
||||
|
||||
@test "(nginx-vhosts) proxy:build-config generates 502 config for undeployed app" {
|
||||
run create_app
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "test -f $DOKKU_ROOT/$TEST_APP/nginx.conf"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku nginx:show-config $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "return 502" -1
|
||||
}
|
||||
|
||||
@test "(nginx-vhosts) proxy:build-config undeployed app returns 502" {
|
||||
run create_app
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
sleep 2
|
||||
|
||||
assert_http_localhost_response "http" "${TEST_APP}.${DOKKU_DOMAIN}" "80" "/" "" "502"
|
||||
}
|
||||
|
||||
@test "(nginx-vhosts) proxy:build-config 502 config replaced after deploy" {
|
||||
run deploy_app
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku nginx:show-config $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "return 502" 0
|
||||
assert_output_contains "proxy_pass" -1
|
||||
|
||||
assert_http_success "http://${TEST_APP}.${DOKKU_DOMAIN}"
|
||||
}
|
||||
|
||||
@test "(nginx-vhosts) proxy:build-config domains:add updates 502 config" {
|
||||
run create_app
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku domains:add $TEST_APP custom.${DOKKU_DOMAIN}"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku nginx:show-config $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "custom.${DOKKU_DOMAIN}" -1
|
||||
assert_output_contains "return 502" -1
|
||||
}
|
||||
|
||||
@test "(nginx-vhosts) proxy:build-config no nginx.conf when proxy disabled" {
|
||||
run create_app
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "test -f $DOKKU_ROOT/$TEST_APP/nginx.conf"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku proxy:disable $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "test -f $DOKKU_ROOT/$TEST_APP/nginx.conf"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
}
|
||||
151
tests/unit/nginx-vhosts_14.bats
Normal file
151
tests/unit/nginx-vhosts_14.bats
Normal file
@@ -0,0 +1,151 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
# Tests for the nginx:reload command and the catch-all default site shipped
|
||||
# at /etc/nginx/conf.d/00-default-vhost.conf. Postinst-driven behavior
|
||||
# (debconf flag, fresh-install detection, sites-enabled/default rename) is
|
||||
# not exercised here because the bats harness does not reinstall the apt
|
||||
# package; the rename logic is exercised manually by simulating the
|
||||
# conflicting upstream vhost.
|
||||
|
||||
load test_helper
|
||||
|
||||
NGINX_DEFAULT_VHOST_PATH="/etc/nginx/conf.d/00-default-vhost.conf"
|
||||
NGINX_DEFAULT_VHOST_SOURCE_MODERN="/var/lib/dokku/core-plugins/available/nginx-vhosts/templates/default-site.conf"
|
||||
NGINX_DEFAULT_VHOST_SOURCE_LEGACY="/var/lib/dokku/core-plugins/available/nginx-vhosts/templates/default-site-legacy.conf"
|
||||
|
||||
fn-nginx-supports-ssl-reject-handshake() {
|
||||
local nginx_version major minor patch
|
||||
nginx_version="$(nginx -v 2>&1 | cut -d'/' -f 2 | awk '{print $1}')"
|
||||
major="$(echo "$nginx_version" | awk -F. '{print $1}')"
|
||||
minor="$(echo "$nginx_version" | awk -F. '{print $2}')"
|
||||
patch="$(echo "$nginx_version" | awk -F. '{print $3}')"
|
||||
if [ "${major:-0}" -ge 2 ]; then
|
||||
return 0
|
||||
fi
|
||||
if [ "${major:-0}" -eq 1 ] && [ "${minor:-0}" -gt 19 ]; then
|
||||
return 0
|
||||
fi
|
||||
if [ "${major:-0}" -eq 1 ] && [ "${minor:-0}" -eq 19 ] && [ "${patch:-0}" -ge 4 ]; then
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
fn-default-site-source() {
|
||||
if fn-nginx-supports-ssl-reject-handshake; then
|
||||
echo "$NGINX_DEFAULT_VHOST_SOURCE_MODERN"
|
||||
else
|
||||
echo "$NGINX_DEFAULT_VHOST_SOURCE_LEGACY"
|
||||
fi
|
||||
}
|
||||
|
||||
setup() {
|
||||
global_setup
|
||||
[[ -f "$DOKKU_ROOT/VHOST" ]] && cp -fp "$DOKKU_ROOT/VHOST" "$DOKKU_ROOT/VHOST.bak"
|
||||
[[ -f "$NGINX_DEFAULT_VHOST_PATH" ]] && cp -fp "$NGINX_DEFAULT_VHOST_PATH" "${NGINX_DEFAULT_VHOST_PATH}.bats-bak"
|
||||
rm -f "$NGINX_DEFAULT_VHOST_PATH"
|
||||
}
|
||||
|
||||
teardown() {
|
||||
rm -f "$NGINX_DEFAULT_VHOST_PATH"
|
||||
if [[ -f "${NGINX_DEFAULT_VHOST_PATH}.bats-bak" ]]; then
|
||||
mv "${NGINX_DEFAULT_VHOST_PATH}.bats-bak" "$NGINX_DEFAULT_VHOST_PATH"
|
||||
fi
|
||||
rm -f /etc/nginx/sites-enabled/default.bats-stub
|
||||
[[ -f "$DOKKU_ROOT/VHOST.bak" ]] && mv "$DOKKU_ROOT/VHOST.bak" "$DOKKU_ROOT/VHOST" && chown dokku:dokku "$DOKKU_ROOT/VHOST"
|
||||
if sudo nginx -t &>/dev/null; then
|
||||
sudo systemctl reload nginx || true
|
||||
fi
|
||||
global_teardown
|
||||
}
|
||||
|
||||
@test "(nginx-vhosts:reload) reloads with valid config" {
|
||||
run /bin/bash -c "dokku nginx:reload"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(nginx-vhosts:reload) fails with invalid config without restarting" {
|
||||
local invalid_conf="/etc/nginx/conf.d/dokku-bats-invalid.conf"
|
||||
echo "this is not valid nginx config" | sudo tee "$invalid_conf" >/dev/null
|
||||
|
||||
run /bin/bash -c "dokku nginx:reload"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
|
||||
sudo rm -f "$invalid_conf"
|
||||
}
|
||||
|
||||
@test "(nginx-vhosts) [default-site] modern template installs and validates on nginx >= 1.19.4" {
|
||||
fn-nginx-supports-ssl-reject-handshake || skip "nginx < 1.19.4 does not support ssl_reject_handshake"
|
||||
[[ -f "$NGINX_DEFAULT_VHOST_SOURCE_MODERN" ]] || skip "default-site template not installed; run 'sudo make copyfiles'"
|
||||
|
||||
sudo install -m 0644 -o root -g root "$NGINX_DEFAULT_VHOST_SOURCE_MODERN" "$NGINX_DEFAULT_VHOST_PATH"
|
||||
|
||||
run /bin/bash -c "sudo grep -F 'ssl_reject_handshake on' '$NGINX_DEFAULT_VHOST_PATH'"
|
||||
assert_success
|
||||
run /bin/bash -c "sudo grep -F 'return 444' '$NGINX_DEFAULT_VHOST_PATH'"
|
||||
assert_success
|
||||
run /bin/bash -c "sudo grep -F 'default_server' '$NGINX_DEFAULT_VHOST_PATH'"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "sudo nginx -t"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(nginx-vhosts) [default-site] legacy template installs and validates on nginx < 1.19.4" {
|
||||
if fn-nginx-supports-ssl-reject-handshake; then
|
||||
skip "nginx >= 1.19.4 uses the modern default-site template"
|
||||
fi
|
||||
[[ -f "$NGINX_DEFAULT_VHOST_SOURCE_LEGACY" ]] || skip "default-site-legacy template not installed; run 'sudo make copyfiles'"
|
||||
|
||||
sudo install -m 0644 -o root -g root "$NGINX_DEFAULT_VHOST_SOURCE_LEGACY" "$NGINX_DEFAULT_VHOST_PATH"
|
||||
|
||||
run /bin/bash -c "sudo grep -F 'return 444' '$NGINX_DEFAULT_VHOST_PATH'"
|
||||
assert_success
|
||||
run /bin/bash -c "sudo grep -F 'default_server' '$NGINX_DEFAULT_VHOST_PATH'"
|
||||
assert_success
|
||||
run /bin/bash -c "sudo grep -F 'ssl_reject_handshake' '$NGINX_DEFAULT_VHOST_PATH'"
|
||||
assert_failure
|
||||
run /bin/bash -c "sudo grep -E 'listen[[:space:]]+(\\[::\\]:)?443' '$NGINX_DEFAULT_VHOST_PATH'"
|
||||
assert_failure
|
||||
|
||||
run /bin/bash -c "sudo nginx -t"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(nginx-vhosts) [default-site] coexists with stock sites-enabled/default" {
|
||||
local default_vhost_source
|
||||
default_vhost_source="$(fn-default-site-source)"
|
||||
[[ -f "$default_vhost_source" ]] || skip "default-site template not installed; run 'sudo make copyfiles'"
|
||||
|
||||
sudo mkdir -p /etc/nginx/sites-enabled
|
||||
sudo tee /etc/nginx/sites-enabled/default.bats-stub >/dev/null <<'STOCK'
|
||||
server {
|
||||
listen 80 default_server;
|
||||
listen [::]:80 default_server;
|
||||
server_name _;
|
||||
return 200 "stock default";
|
||||
}
|
||||
STOCK
|
||||
|
||||
sudo install -m 0644 -o root -g root "$default_vhost_source" "$NGINX_DEFAULT_VHOST_PATH"
|
||||
|
||||
run /bin/bash -c "sudo nginx -t"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
|
||||
sudo rm -f /etc/nginx/sites-enabled/default.bats-stub
|
||||
|
||||
run /bin/bash -c "sudo nginx -t"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
}
|
||||
172
tests/unit/nginx-vhosts_15.bats
Normal file
172
tests/unit/nginx-vhosts_15.bats
Normal file
@@ -0,0 +1,172 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
NGINX_VALIDATE_PLUGIN_NAME="test-nginx-validate"
|
||||
NGINX_VALIDATE_ZONE_CONF="/etc/nginx/conf.d/00-dokku-test-limit-req.conf"
|
||||
|
||||
setup() {
|
||||
global_setup
|
||||
[[ -f "$DOKKU_ROOT/VHOST" ]] && cp -fp "$DOKKU_ROOT/VHOST" "$DOKKU_ROOT/VHOST.bak"
|
||||
create_app
|
||||
}
|
||||
|
||||
teardown() {
|
||||
rm -rf "${PLUGIN_ENABLED_PATH:?}/$NGINX_VALIDATE_PLUGIN_NAME" "${PLUGIN_AVAILABLE_PATH:?}/$NGINX_VALIDATE_PLUGIN_NAME"
|
||||
destroy_app
|
||||
rm -f "$NGINX_VALIDATE_ZONE_CONF"
|
||||
[[ -f "$DOKKU_ROOT/VHOST.bak" ]] && mv "$DOKKU_ROOT/VHOST.bak" "$DOKKU_ROOT/VHOST" && chown dokku:dokku "$DOKKU_ROOT/VHOST"
|
||||
global_teardown
|
||||
}
|
||||
|
||||
@test "(nginx-vhosts) pre-validate fails fast on broken nginx.conf.sigil" {
|
||||
run deploy_app nodejs-express dokku@$DOKKU_DOMAIN:$TEST_APP bad_custom_nginx_template
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output_contains "Pre-validating custom nginx.conf.sigil"
|
||||
assert_output_contains "Custom nginx.conf.sigil failed nginx -t validation"
|
||||
assert_output_not_contains "Building $TEST_APP"
|
||||
assert_output_not_contains "Releasing $TEST_APP"
|
||||
}
|
||||
|
||||
@test "(nginx-vhosts) pre-validate succeeds on first deploy with valid nginx.conf.sigil" {
|
||||
run deploy_app python dokku@$DOKKU_DOMAIN:$TEST_APP custom_nginx_template
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "Pre-validating custom nginx.conf.sigil"
|
||||
}
|
||||
|
||||
@test "(nginx-vhosts) pre-validate is skipped when disable-custom-config=true" {
|
||||
run /bin/bash -c "dokku nginx:set $TEST_APP disable-custom-config true"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run deploy_app nodejs-express dokku@$DOKKU_DOMAIN:$TEST_APP bad_custom_nginx_template
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_not_contains "Pre-validating custom nginx.conf.sigil"
|
||||
}
|
||||
|
||||
@test "(nginx-vhosts) pre-validate is skipped when proxy is not nginx" {
|
||||
run /bin/bash -c "dokku proxy:set $TEST_APP caddy"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run deploy_app nodejs-express dokku@$DOKKU_DOMAIN:$TEST_APP bad_custom_nginx_template
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_not_contains "Pre-validating custom nginx.conf.sigil"
|
||||
}
|
||||
|
||||
@test "(nginx-vhosts) pre-validate fails when nginx.conf.sigil needs a directive absent from the wrapper" {
|
||||
run deploy_app python dokku@$DOKKU_DOMAIN:$TEST_APP custom_nginx_template_with_limit_req
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output_contains "Pre-validating custom nginx.conf.sigil"
|
||||
assert_output_contains "Custom nginx.conf.sigil failed nginx -t validation"
|
||||
}
|
||||
|
||||
@test "(nginx-vhosts) pre-validate passes when nginx-app-template-source overrides validate-config" {
|
||||
echo 'limit_req_zone $binary_remote_addr zone=dokkuprevalidate:10m rate=100r/s;' >"$NGINX_VALIDATE_ZONE_CONF"
|
||||
setup_nginx_validate_plugin
|
||||
|
||||
run deploy_app python dokku@$DOKKU_DOMAIN:$TEST_APP custom_nginx_template_with_limit_req
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "Pre-validating custom nginx.conf.sigil"
|
||||
}
|
||||
|
||||
setup_nginx_validate_plugin() {
|
||||
declare desc="installs a plugin that overrides the validate-config nginx template"
|
||||
local PLUGIN_DIR="$PLUGIN_AVAILABLE_PATH/$NGINX_VALIDATE_PLUGIN_NAME"
|
||||
mkdir -p "$PLUGIN_DIR"
|
||||
|
||||
cat <<EOF >"$PLUGIN_DIR/plugin.toml"
|
||||
[plugin]
|
||||
description = "test plugin overriding the validate-config nginx template"
|
||||
version = "0.1.0"
|
||||
[plugin.config]
|
||||
EOF
|
||||
|
||||
cat <<'EOF' >"$PLUGIN_DIR/nginx-app-template-source"
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -eo pipefail
|
||||
[[ $DOKKU_TRACE ]] && set -x
|
||||
|
||||
TEMPLATE_TYPE="$2"
|
||||
if [[ "$TEMPLATE_TYPE" == "validate-config" ]]; then
|
||||
echo "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/validate.conf.sigil"
|
||||
fi
|
||||
EOF
|
||||
chmod +x "$PLUGIN_DIR/nginx-app-template-source"
|
||||
|
||||
cat <<'EOF' >"$PLUGIN_DIR/validate.conf.sigil"
|
||||
events { worker_connections 768; }
|
||||
http {
|
||||
access_log off;
|
||||
error_log /dev/null;
|
||||
limit_req_zone $binary_remote_addr zone=dokkuprevalidate:10m rate=100r/s;
|
||||
include {{ $.NGINX_CONF }};
|
||||
}
|
||||
EOF
|
||||
|
||||
dokku plugin:enable "$NGINX_VALIDATE_PLUGIN_NAME"
|
||||
}
|
||||
|
||||
custom_nginx_template_with_limit_req() {
|
||||
local APP="$1"
|
||||
local APP_REPO_DIR="$2"
|
||||
[[ -z "$APP" ]] && local APP="$TEST_APP"
|
||||
mkdir -p "$APP_REPO_DIR"
|
||||
|
||||
echo "injecting custom_nginx_template_with_limit_req -> $APP_REPO_DIR/nginx.conf.sigil"
|
||||
cat <<EOF >"$APP_REPO_DIR/nginx.conf.sigil"
|
||||
{{ range \$port_map := .PROXY_PORT_MAP | split " " }}
|
||||
{{ \$port_map_list := \$port_map | split ":" }}
|
||||
{{ \$scheme := index \$port_map_list 0 }}
|
||||
{{ \$listen_port := index \$port_map_list 1 }}
|
||||
{{ \$upstream_port := index \$port_map_list 2 }}
|
||||
|
||||
server {
|
||||
listen [::]:{{ \$listen_port }};
|
||||
listen {{ \$listen_port }};
|
||||
server_name {{ $.NOSSL_SERVER_NAME }} customtemplate.${DOKKU_DOMAIN};
|
||||
|
||||
location / {
|
||||
limit_req zone=dokkuprevalidate burst=100 nodelay;
|
||||
proxy_pass http://{{ $.APP }}-{{ \$upstream_port }};
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade \$http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_set_header Host \$http_host;
|
||||
proxy_set_header X-Forwarded-Proto \$scheme;
|
||||
proxy_set_header X-Forwarded-For \$remote_addr;
|
||||
proxy_set_header X-Forwarded-Port \$server_port;
|
||||
proxy_set_header X-Request-Start \$msec;
|
||||
}
|
||||
include {{ $.DOKKU_ROOT }}/{{ $.APP }}/nginx.conf.d/*.conf;
|
||||
}
|
||||
{{ end }}
|
||||
|
||||
{{ if $.DOKKU_APP_WEB_LISTENERS }}
|
||||
{{ range \$upstream_port := $.PROXY_UPSTREAM_PORTS | split " " }}
|
||||
upstream {{ $.APP }}-{{ \$upstream_port }} {
|
||||
{{ range \$listeners := $.DOKKU_APP_WEB_LISTENERS | split " " }}
|
||||
{{ \$listener_list := \$listeners | split ":" }}
|
||||
{{ \$listener_ip := index \$listener_list 0 }}
|
||||
server {{ \$listener_ip }}:{{ \$upstream_port }};{{ end }}
|
||||
}
|
||||
{{ end }}{{ end }}
|
||||
|
||||
EOF
|
||||
cat "$APP_REPO_DIR/nginx.conf.sigil"
|
||||
}
|
||||
71
tests/unit/nginx-vhosts_16.bats
Normal file
71
tests/unit/nginx-vhosts_16.bats
Normal file
@@ -0,0 +1,71 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
setup_local_tls() {
|
||||
TLS=$BATS_TMPDIR/tls
|
||||
mkdir -p $TLS
|
||||
tar xf $BATS_TEST_DIRNAME/server_ssl.tar -C $TLS
|
||||
tar xf $BATS_TEST_DIRNAME/domain_ssl.tar -C $TLS
|
||||
sudo chown -R dokku:dokku $TLS
|
||||
}
|
||||
|
||||
teardown_local_tls() {
|
||||
TLS=$BATS_TMPDIR/tls
|
||||
rm -R $TLS
|
||||
}
|
||||
|
||||
setup() {
|
||||
global_setup
|
||||
[[ -f "$DOKKU_ROOT/VHOST" ]] && cp -fp "$DOKKU_ROOT/VHOST" "$DOKKU_ROOT/VHOST.bak"
|
||||
create_app
|
||||
}
|
||||
|
||||
teardown() {
|
||||
destroy_app
|
||||
[[ -f "$DOKKU_ROOT/VHOST.bak" ]] && mv "$DOKKU_ROOT/VHOST.bak" "$DOKKU_ROOT/VHOST" && chown dokku:dokku "$DOKKU_ROOT/VHOST"
|
||||
global_teardown
|
||||
}
|
||||
|
||||
@test "(nginx-vhosts) refactored template generates nginx -t parseable http config" {
|
||||
run deploy_app
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "test -f $DOKKU_ROOT/$TEST_APP/nginx.conf"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "sudo nginx -t"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(nginx-vhosts) refactored template generates nginx -t parseable https config" {
|
||||
setup_local_tls
|
||||
run deploy_app
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku certs:add $TEST_APP $BATS_TMPDIR/tls/server.crt $BATS_TMPDIR/tls/server.key"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "sudo nginx -t"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku nginx:show-config $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "ssl_certificate" -1
|
||||
assert_output_contains "return 301 https" -1
|
||||
teardown_local_tls
|
||||
}
|
||||
@@ -60,9 +60,9 @@ teardown() {
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(nginx-vhosts) proxy:build-config (global DOKKU_PROXY_PORT)" {
|
||||
@test "(nginx-vhosts) proxy:build-config (global proxy-port)" {
|
||||
local GLOBAL_PORT=30999
|
||||
run /bin/bash -c "dokku config:set --global DOKKU_PROXY_PORT=${GLOBAL_PORT}"
|
||||
run /bin/bash -c "dokku proxy:set --global proxy-port ${GLOBAL_PORT}"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
@@ -74,7 +74,7 @@ teardown() {
|
||||
check_urls "http://${TEST_APP}.${DOKKU_DOMAIN}:${GLOBAL_PORT}"
|
||||
assert_http_success "http://${TEST_APP}.${DOKKU_DOMAIN}:${GLOBAL_PORT}"
|
||||
|
||||
run /bin/bash -c "dokku config:unset --global DOKKU_PROXY_PORT"
|
||||
run /bin/bash -c "dokku proxy:set --global proxy-port"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
@@ -96,4 +96,67 @@ teardown() {
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output_contains "Pre-validating custom nginx.conf.sigil"
|
||||
assert_output_contains "Custom nginx.conf.sigil failed nginx -t validation"
|
||||
}
|
||||
|
||||
@test "(nginx-vhosts) proxy:build-config (custom nginx template with deprecated listen http2)" {
|
||||
run /bin/bash -c "dokku domains:add $TEST_APP www.test.app.${DOKKU_DOMAIN}"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run deploy_app python dokku@$DOKKU_DOMAIN:$TEST_APP custom_nginx_template_with_http2_listen
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
assert_output_contains "Deprecated: Usage of 'listen ... http2' within nginx.conf.sigil templates is deprecated" -1
|
||||
}
|
||||
|
||||
custom_nginx_template_with_http2_listen() {
|
||||
local APP="$1"
|
||||
local APP_REPO_DIR="$2"
|
||||
[[ -z "$APP" ]] && local APP="$TEST_APP"
|
||||
mkdir -p "$APP_REPO_DIR"
|
||||
|
||||
echo "injecting custom_nginx_template_with_http2_listen -> $APP_REPO_DIR/nginx.conf.sigil"
|
||||
cat <<EOF >"$APP_REPO_DIR/nginx.conf.sigil"
|
||||
{{ range \$port_map := .PROXY_PORT_MAP | split " " }}
|
||||
{{ \$port_map_list := \$port_map | split ":" }}
|
||||
{{ \$scheme := index \$port_map_list 0 }}
|
||||
{{ \$listen_port := index \$port_map_list 1 }}
|
||||
{{ \$upstream_port := index \$port_map_list 2 }}
|
||||
|
||||
server {
|
||||
listen [::]:{{ \$listen_port }} http2;
|
||||
listen {{ \$listen_port }} http2;
|
||||
server_name {{ $.NOSSL_SERVER_NAME }} customtemplate.${DOKKU_DOMAIN};
|
||||
|
||||
location / {
|
||||
proxy_pass http://{{ $.APP }}-{{ \$upstream_port }};
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade \$http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_set_header Host \$http_host;
|
||||
proxy_set_header X-Forwarded-Proto \$scheme;
|
||||
proxy_set_header X-Forwarded-For \$remote_addr;
|
||||
proxy_set_header X-Forwarded-Port \$server_port;
|
||||
proxy_set_header X-Request-Start \$msec;
|
||||
}
|
||||
include {{ $.DOKKU_ROOT }}/{{ $.APP }}/nginx.conf.d/*.conf;
|
||||
}
|
||||
{{ end }}
|
||||
|
||||
{{ if $.DOKKU_APP_WEB_LISTENERS }}
|
||||
{{ range \$upstream_port := $.PROXY_UPSTREAM_PORTS | split " " }}
|
||||
upstream {{ $.APP }}-{{ \$upstream_port }} {
|
||||
{{ range \$listeners := $.DOKKU_APP_WEB_LISTENERS | split " " }}
|
||||
{{ \$listener_list := \$listeners | split ":" }}
|
||||
{{ \$listener_ip := index \$listener_list 0 }}
|
||||
server {{ \$listener_ip }}:{{ \$upstream_port }};{{ end }}
|
||||
}
|
||||
{{ end }}{{ end }}
|
||||
EOF
|
||||
cat "$APP_REPO_DIR/nginx.conf.sigil"
|
||||
}
|
||||
|
||||
109
tests/unit/nginx-vhosts_properties.bats
Normal file
109
tests/unit/nginx-vhosts_properties.bats
Normal file
@@ -0,0 +1,109 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
setup() {
|
||||
global_setup
|
||||
create_app
|
||||
}
|
||||
|
||||
teardown() {
|
||||
destroy_app
|
||||
global_teardown
|
||||
}
|
||||
|
||||
# assert_nginx_property_set_get verifies that for a given nginx property,
|
||||
# (a) the raw per-app and global keys cycle through set/unset states,
|
||||
# (b) the computed key always returns a non-empty value when defaults exist,
|
||||
# and (c) the computed key falls back through per-app -> global.
|
||||
#
|
||||
# This intentionally does not pin the exact default value for properties whose
|
||||
# default is computed at runtime (e.g. proxy-buffer-size depends on the host's
|
||||
# page size) - those would be brittle to assert verbatim. The set/unset cycle
|
||||
# is the canonical test for the report convention.
|
||||
assert_nginx_property_set_get() {
|
||||
declare prop="$1" app_value="$2" global_value="$3"
|
||||
|
||||
run /bin/bash -c "dokku nginx:set --global $prop"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku nginx:set --global $prop '$global_value'"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku nginx:report $TEST_APP --format json | jq -r '.\"global-$prop\"'"
|
||||
assert_success
|
||||
assert_output "$global_value"
|
||||
|
||||
run /bin/bash -c "dokku nginx:report $TEST_APP --format json | jq -r '.\"computed-$prop\"'"
|
||||
assert_success
|
||||
assert_output "$global_value"
|
||||
|
||||
run /bin/bash -c "dokku nginx:set $TEST_APP $prop '$app_value'"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku nginx:report $TEST_APP --format json | jq -r '.\"$prop\"'"
|
||||
assert_success
|
||||
assert_output "$app_value"
|
||||
|
||||
run /bin/bash -c "dokku nginx:report $TEST_APP --format json | jq -r '.\"global-$prop\"'"
|
||||
assert_success
|
||||
assert_output "$global_value"
|
||||
|
||||
run /bin/bash -c "dokku nginx:report $TEST_APP --format json | jq -r '.\"computed-$prop\"'"
|
||||
assert_success
|
||||
assert_output "$app_value"
|
||||
|
||||
run /bin/bash -c "dokku nginx:set $TEST_APP $prop"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku nginx:set --global $prop"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku nginx:report $TEST_APP --format json | jq -r '.\"global-$prop\"'"
|
||||
assert_success
|
||||
assert_output ""
|
||||
}
|
||||
|
||||
@test "(nginx:report) timeout properties raw/global/computed" {
|
||||
for prop in client-body-timeout client-header-timeout keepalive-timeout lingering-timeout send-timeout proxy-connect-timeout proxy-read-timeout proxy-send-timeout; do
|
||||
assert_nginx_property_set_get "$prop" "30s" "45s"
|
||||
done
|
||||
}
|
||||
|
||||
@test "(nginx:report) buffer properties raw/global/computed" {
|
||||
assert_nginx_property_set_get "proxy-buffer-size" "8k" "16k"
|
||||
assert_nginx_property_set_get "proxy-buffering" "off" "on"
|
||||
assert_nginx_property_set_get "proxy-buffers" "16 16k" "32 16k"
|
||||
assert_nginx_property_set_get "proxy-busy-buffers-size" "16k" "32k"
|
||||
assert_nginx_property_set_get "client-max-body-size" "10m" "20m"
|
||||
}
|
||||
|
||||
@test "(nginx:report) hsts properties raw/global/computed" {
|
||||
assert_nginx_property_set_get "hsts" "false" "true"
|
||||
assert_nginx_property_set_get "hsts-include-subdomains" "false" "true"
|
||||
assert_nginx_property_set_get "hsts-max-age" "3600" "7200"
|
||||
assert_nginx_property_set_get "hsts-preload" "true" "false"
|
||||
}
|
||||
|
||||
@test "(nginx:report) x-forwarded properties raw/global/computed" {
|
||||
assert_nginx_property_set_get "x-forwarded-for-value" "\$remote_addr" "\$proxy_add_x_forwarded_for"
|
||||
assert_nginx_property_set_get "x-forwarded-port-value" "8080" "8443"
|
||||
assert_nginx_property_set_get "x-forwarded-proto-value" "https" "http"
|
||||
assert_nginx_property_set_get "x-forwarded-ssl" "on" "off"
|
||||
}
|
||||
|
||||
@test "(nginx:report) log/address properties raw/global/computed" {
|
||||
assert_nginx_property_set_get "bind-address-ipv4" "127.0.0.1" "0.0.0.0"
|
||||
assert_nginx_property_set_get "bind-address-ipv6" "::1" "::"
|
||||
assert_nginx_property_set_get "access-log-format" "main" "combined"
|
||||
assert_nginx_property_set_get "access-log-path" "/var/log/nginx/app-access.log" "/dev/stdout"
|
||||
assert_nginx_property_set_get "error-log-path" "/var/log/nginx/app-error.log" "/dev/stderr"
|
||||
}
|
||||
|
||||
@test "(nginx:report) misc properties raw/global/computed" {
|
||||
assert_nginx_property_set_get "disable-custom-config" "false" "true"
|
||||
assert_nginx_property_set_get "underscore-in-headers" "on" "off"
|
||||
assert_nginx_property_set_get "proxy-keepalive" "8" "16"
|
||||
assert_nginx_property_set_get "nginx-conf-sigil-path" "custom.sigil" "global.sigil"
|
||||
assert_nginx_property_set_get "nginx-service-command" "/usr/sbin/nginx-app" "/usr/sbin/nginx-global"
|
||||
}
|
||||
84
tests/unit/openresty-vhosts.bats
Normal file
84
tests/unit/openresty-vhosts.bats
Normal file
@@ -0,0 +1,84 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
setup() {
|
||||
create_app
|
||||
}
|
||||
|
||||
teardown() {
|
||||
destroy_app
|
||||
dokku openresty:set --global log-level >/dev/null 2>&1 || true
|
||||
dokku openresty:set --global proxy-buffer-size >/dev/null 2>&1 || true
|
||||
dokku openresty:set --global client-max-body-size >/dev/null 2>&1 || true
|
||||
}
|
||||
|
||||
@test "(openresty:report) info-flag works before deploy" {
|
||||
run /bin/bash -c "dokku openresty:set --global log-level"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku openresty:report $TEST_APP --openresty-computed-log-level"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "ERROR"
|
||||
|
||||
run /bin/bash -c "dokku openresty:report $TEST_APP --openresty-invalid-flag"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output_contains "Invalid flag passed"
|
||||
}
|
||||
|
||||
@test "(openresty:report) --format json" {
|
||||
run /bin/bash -c "dokku openresty:set --global proxy-buffer-size"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku openresty:report --global --format json | jq -e ."
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku openresty:report --global --format json | jq -r '.\"computed-proxy-buffer-size\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "4k"
|
||||
|
||||
run /bin/bash -c "dokku openresty:report --global"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "global openresty information"
|
||||
}
|
||||
|
||||
@test "(openresty:report) client-max-body-size raw global computed" {
|
||||
run /bin/bash -c "dokku openresty:set --global client-max-body-size"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku openresty:report $TEST_APP --openresty-client-max-body-size"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku openresty:report $TEST_APP --openresty-computed-client-max-body-size"
|
||||
assert_success
|
||||
assert_output "1m"
|
||||
|
||||
run /bin/bash -c "dokku openresty:set --global client-max-body-size 2m"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku openresty:report $TEST_APP --openresty-computed-client-max-body-size"
|
||||
assert_success
|
||||
assert_output "2m"
|
||||
|
||||
run /bin/bash -c "dokku openresty:set $TEST_APP client-max-body-size 5m"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku openresty:report $TEST_APP --openresty-client-max-body-size"
|
||||
assert_success
|
||||
assert_output "5m"
|
||||
|
||||
run /bin/bash -c "dokku openresty:report $TEST_APP --openresty-computed-client-max-body-size"
|
||||
assert_success
|
||||
assert_output "5m"
|
||||
}
|
||||
@@ -12,12 +12,440 @@ setup() {
|
||||
}
|
||||
|
||||
teardown() {
|
||||
dokku openresty:set --global log-level >/dev/null 2>&1 || true
|
||||
for key in bind-address-ipv6 keepalive-timeout client-body-timeout client-header-timeout client-max-body-size; do
|
||||
dokku openresty:set --global "$key" >/dev/null || true
|
||||
done
|
||||
global_teardown
|
||||
destroy_app
|
||||
dokku openresty:stop
|
||||
dokku nginx:start
|
||||
}
|
||||
|
||||
@test "(openresty:report) --global --openresty-computed-letsencrypt-server" {
|
||||
run /bin/bash -c "dokku openresty:report --global --openresty-computed-letsencrypt-server"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "https://acme-staging-v02.api.letsencrypt.org/directory"
|
||||
|
||||
run /bin/bash -c "dokku openresty:report --global --openresty-global-letsencrypt-server"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "https://acme-staging-v02.api.letsencrypt.org/directory"
|
||||
}
|
||||
|
||||
@test "(openresty:report) --global raw and computed keys in --format json" {
|
||||
run /bin/bash -c "dokku openresty:report --global --format json | jq -r '.\"global-letsencrypt-server\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "https://acme-staging-v02.api.letsencrypt.org/directory"
|
||||
|
||||
run /bin/bash -c "dokku openresty:report --global --format json | jq -r '.\"computed-letsencrypt-server\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "https://acme-staging-v02.api.letsencrypt.org/directory"
|
||||
|
||||
run /bin/bash -c "dokku openresty:report --global --format json | jq -r '.\"global-letsencrypt-email\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku openresty:report --global --format json | jq -r '.\"computed-letsencrypt-email\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku openresty:report --global --format json | jq -r '.\"global-image\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku openresty:report --global --format json | jq -r '.\"computed-image\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_exists
|
||||
|
||||
run /bin/bash -c "dokku openresty:report --global --format json | jq -r '.\"global-allowed-letsencrypt-domains-func-base64\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku openresty:report --global --format json | jq -r '.\"computed-allowed-letsencrypt-domains-func-base64\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_exists
|
||||
|
||||
run /bin/bash -c "dokku openresty:report --global --format json | jq -r '.\"global-hsts\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku openresty:report --global --format json | jq -r '.\"computed-hsts\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
for key in image letsencrypt-email letsencrypt-server allowed-letsencrypt-domains-func-base64; do
|
||||
run /bin/bash -c "dokku openresty:report --global --format json | jq -e \"has(\\\"$key\\\")\""
|
||||
echo "key: $key"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output "false"
|
||||
done
|
||||
}
|
||||
|
||||
@test "(openresty:report) --global global vs computed image" {
|
||||
run /bin/bash -c "dokku openresty:report --global --openresty-global-image"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku openresty:report --global --openresty-computed-image"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_exists
|
||||
|
||||
run /bin/bash -c "dokku openresty:set --global image dokku/openresty-docker-proxy:0.5.6"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku openresty:report --global --openresty-global-image"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "dokku/openresty-docker-proxy:0.5.6"
|
||||
|
||||
run /bin/bash -c "dokku openresty:report --global --openresty-computed-image"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "dokku/openresty-docker-proxy:0.5.6"
|
||||
|
||||
run /bin/bash -c "dokku openresty:set --global image"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku openresty:report --global --openresty-global-image"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku openresty:report --global --openresty-computed-image"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_exists
|
||||
}
|
||||
|
||||
@test "(openresty:report) --global log-level raw vs computed" {
|
||||
run /bin/bash -c "dokku openresty:report --global --openresty-global-log-level"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku openresty:report --global --openresty-computed-log-level"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "ERROR"
|
||||
|
||||
run /bin/bash -c "dokku openresty:set --global log-level DEBUG"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku openresty:report --global --openresty-global-log-level"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "DEBUG"
|
||||
|
||||
run /bin/bash -c "dokku openresty:report --global --openresty-computed-log-level"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "DEBUG"
|
||||
|
||||
run /bin/bash -c "dokku openresty:report --global --format json | jq -r '.\"global-log-level\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "DEBUG"
|
||||
|
||||
run /bin/bash -c "dokku openresty:report --global --format json | jq -r '.\"computed-log-level\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "DEBUG"
|
||||
|
||||
run /bin/bash -c "dokku openresty:set --global log-level"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku openresty:report --global --openresty-global-log-level"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku openresty:report --global --openresty-computed-log-level"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "ERROR"
|
||||
}
|
||||
|
||||
@test "(openresty:report) per-app raw vs global vs computed for bind-address-ipv6" {
|
||||
run /bin/bash -c "dokku openresty:report $TEST_APP --openresty-bind-address-ipv6"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku openresty:report $TEST_APP --openresty-global-bind-address-ipv6"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku openresty:report $TEST_APP --openresty-computed-bind-address-ipv6"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "::"
|
||||
|
||||
run /bin/bash -c "dokku openresty:set $TEST_APP bind-address-ipv6 ::1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku openresty:report $TEST_APP --openresty-bind-address-ipv6"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "::1"
|
||||
|
||||
run /bin/bash -c "dokku openresty:report $TEST_APP --openresty-computed-bind-address-ipv6"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "::1"
|
||||
|
||||
run /bin/bash -c "dokku openresty:report $TEST_APP --openresty-global-bind-address-ipv6"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku openresty:set $TEST_APP bind-address-ipv6"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku openresty:report $TEST_APP --openresty-computed-bind-address-ipv6"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "::"
|
||||
}
|
||||
|
||||
@test "(openresty:report) per-app inherits global value, per-app overrides global" {
|
||||
run /bin/bash -c "dokku openresty:set --global keepalive-timeout 90s"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku openresty:report $TEST_APP --openresty-keepalive-timeout"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku openresty:report $TEST_APP --openresty-global-keepalive-timeout"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "90s"
|
||||
|
||||
run /bin/bash -c "dokku openresty:report $TEST_APP --openresty-computed-keepalive-timeout"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "90s"
|
||||
|
||||
run /bin/bash -c "dokku openresty:set $TEST_APP keepalive-timeout 30s"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku openresty:report $TEST_APP --openresty-keepalive-timeout"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "30s"
|
||||
|
||||
run /bin/bash -c "dokku openresty:report $TEST_APP --openresty-computed-keepalive-timeout"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "30s"
|
||||
|
||||
run /bin/bash -c "dokku openresty:report $TEST_APP --format json | jq -r '.\"keepalive-timeout\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "30s"
|
||||
|
||||
run /bin/bash -c "dokku openresty:report $TEST_APP --format json | jq -r '.\"global-keepalive-timeout\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "90s"
|
||||
|
||||
run /bin/bash -c "dokku openresty:report $TEST_APP --format json | jq -r '.\"computed-keepalive-timeout\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "30s"
|
||||
|
||||
run /bin/bash -c "dokku openresty:set $TEST_APP keepalive-timeout"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku openresty:set --global keepalive-timeout"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku openresty:report $TEST_APP --openresty-computed-keepalive-timeout"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "75s"
|
||||
}
|
||||
|
||||
@test "(openresty:report) client-header-timeout reads its own property key" {
|
||||
run /bin/bash -c "dokku openresty:set $TEST_APP client-body-timeout 99s"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku openresty:report $TEST_APP --openresty-computed-client-header-timeout"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "60s"
|
||||
|
||||
run /bin/bash -c "dokku openresty:set $TEST_APP client-header-timeout 30s"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku openresty:report $TEST_APP --openresty-client-header-timeout"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "30s"
|
||||
|
||||
run /bin/bash -c "dokku openresty:report $TEST_APP --openresty-computed-client-header-timeout"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "30s"
|
||||
|
||||
run /bin/bash -c "dokku openresty:report $TEST_APP --openresty-computed-client-body-timeout"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "99s"
|
||||
}
|
||||
|
||||
@test "(openresty:report) client-max-body-size computed default is 1m" {
|
||||
run /bin/bash -c "dokku openresty:report $TEST_APP --openresty-client-max-body-size"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku openresty:report $TEST_APP --openresty-computed-client-max-body-size"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "1m"
|
||||
}
|
||||
|
||||
@test "(openresty) per-app properties are settable globally" {
|
||||
run /bin/bash -c "dokku openresty:set --global keepalive-timeout 90s"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku openresty:report --global --openresty-global-keepalive-timeout"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "90s"
|
||||
|
||||
run /bin/bash -c "dokku openresty:report --global --openresty-computed-keepalive-timeout"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "90s"
|
||||
|
||||
run /bin/bash -c "dokku openresty:set --global keepalive-timeout"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(openresty) global-only keys" {
|
||||
for key in allowed-letsencrypt-domains-func-base64 image log-level letsencrypt-email letsencrypt-server; do
|
||||
run /bin/bash -c "dokku openresty:set $TEST_APP $key somevalue"
|
||||
echo "key: $key"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output_contains "can only be set globally"
|
||||
done
|
||||
|
||||
run /bin/bash -c "dokku openresty:set $TEST_APP bind-address-ipv4 127.0.0.1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku openresty:report $TEST_APP --openresty-bind-address-ipv4"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "127.0.0.1"
|
||||
|
||||
run /bin/bash -c "dokku openresty:set $TEST_APP bind-address-ipv4"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(openresty) openresty:help" {
|
||||
run /bin/bash -c "dokku openresty"
|
||||
echo "output: $output"
|
||||
@@ -245,6 +673,24 @@ teardown() {
|
||||
assert_output_contains "charset UTF-8;"
|
||||
}
|
||||
|
||||
@test "(openresty) [security] eval injection via malicious include filename" {
|
||||
rm -f /tmp/openresty-include
|
||||
|
||||
run /bin/bash -c "dokku proxy:set $TEST_APP openresty"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run deploy_app python dokku@$DOKKU_DOMAIN:$TEST_APP add_openresty_include_unsafe
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output_contains "unsafe filename" -1
|
||||
|
||||
# No injection payload to test since we're using a simple space character
|
||||
# The test should have failed during core-post-extract, not during eval
|
||||
}
|
||||
|
||||
@test "(openresty) label management" {
|
||||
run /bin/bash -c "dokku proxy:set $TEST_APP openresty"
|
||||
echo "output: $output"
|
||||
@@ -327,3 +773,16 @@ add_openresty_include() {
|
||||
touch "$APP_REPO_DIR/openresty/http-location-includes/example.conf"
|
||||
echo "# location-block" >>"$APP_REPO_DIR/openresty/http-location-includes/example.conf"
|
||||
}
|
||||
|
||||
add_openresty_include_unsafe() {
|
||||
local APP="$1"
|
||||
local APP_REPO_DIR="$2"
|
||||
[[ -z "$APP" ]] && local APP="$TEST_APP"
|
||||
|
||||
mkdir -p "$APP_REPO_DIR/openresty/http-includes"
|
||||
# Create a filename with a space - simpler test that should be rejected by [^a-zA-Z0-9_.-]
|
||||
printf 'charset UTF-8;\n' >"$APP_REPO_DIR/openresty/http-includes/unsafe filename.conf"
|
||||
|
||||
mkdir -p "$APP_REPO_DIR/openresty/http-location-includes"
|
||||
printf '# location\n' >"$APP_REPO_DIR/openresty/http-location-includes/unsafe filename.conf"
|
||||
}
|
||||
|
||||
@@ -26,6 +26,70 @@ teardown() {
|
||||
assert_output "$help_output"
|
||||
}
|
||||
|
||||
@test "(plugin) plugin:list --format json" {
|
||||
run /bin/bash -c "dokku plugin:list --format nonsense"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output_contains "Invalid output format"
|
||||
|
||||
run /bin/bash -c "dokku plugin:list --format json | jq -r '.[] | select(.name == \"apps\") | .core'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku plugin:list --format json | jq -r '.[] | select(.name == \"apps\") | .enabled'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku plugin:list --format json | jq -r '.[] | select(.name == \"apps\") | .source_url'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
# Clone a git-based third-party plugin directly into the available path so the
|
||||
# git install source is present without running the (build-dependent) install
|
||||
# trigger. plugn lists it as a disabled plugin.
|
||||
run /bin/bash -c "git clone $TEST_PLUGIN_GIT_REPO $PLUGIN_AVAILABLE_PATH/$TEST_PLUGIN_NAME"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku plugin:list --format json | jq -r '.[] | select(.name == \"$TEST_PLUGIN_NAME\") | .source_url'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "$TEST_PLUGIN_GIT_REPO"
|
||||
|
||||
run /bin/bash -c "dokku plugin:list --format json | jq -r '.[] | select(.name == \"$TEST_PLUGIN_NAME\") | .core'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "false"
|
||||
|
||||
run /bin/bash -c "dokku plugin:list --format json | jq -r '.[] | select(.name == \"$TEST_PLUGIN_NAME\") | .enabled'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "false"
|
||||
|
||||
run /bin/bash -c "dokku plugin:list --format json | jq -r '.[] | select(.name == \"$TEST_PLUGIN_NAME\") | .committish | length'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "40"
|
||||
|
||||
run /bin/bash -c "dokku plugin:list --format json | jq -r '.[] | select(.name == \"$TEST_PLUGIN_NAME\") | .branch'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_exists
|
||||
}
|
||||
|
||||
@test "(plugin) plugin:install, plugin:disable, plugin:update plugin:uninstall" {
|
||||
run /bin/bash -c "dokku plugin:installed $TEST_PLUGIN_NAME"
|
||||
echo "output: $output"
|
||||
|
||||
@@ -50,6 +50,11 @@ teardown() {
|
||||
echo "status: $status"
|
||||
assert_output "http:1234:5001"
|
||||
|
||||
run /bin/bash -c "dokku --quiet ports:report $TEST_APP --ports-map-json | jq -e 'length == 1 and .[0].scheme == \"http\" and .[0].host_port == 1234 and .[0].container_port == 5001'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku ports:add $TEST_APP http:8080:5002 https:8443:5003"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
@@ -60,6 +65,11 @@ teardown() {
|
||||
echo "status: $status"
|
||||
assert_output "http:1234:5001 http:8080:5002 https:8443:5003"
|
||||
|
||||
run /bin/bash -c "dokku --quiet ports:report $TEST_APP --ports-map-json | jq -e 'length == 3 and any(.scheme == \"http\" and .host_port == 1234 and .container_port == 5001) and any(.scheme == \"http\" and .host_port == 8080 and .container_port == 5002) and any(.scheme == \"https\" and .host_port == 8443 and .container_port == 5003)'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku ports:set $TEST_APP http:8080:5000 https:8443:5000 http:1234:5001"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
@@ -90,6 +100,11 @@ teardown() {
|
||||
echo "status: $status"
|
||||
assert_output "http:1234:5001 http:8080:5000 https:8443:5000"
|
||||
|
||||
run /bin/bash -c "dokku --quiet ports:report $TEST_APP --ports-map-json | jq -e 'length == 3 and any(.scheme == \"http\" and .host_port == 1234 and .container_port == 5001) and any(.scheme == \"http\" and .host_port == 8080 and .container_port == 5000) and any(.scheme == \"https\" and .host_port == 8443 and .container_port == 5000)'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku ports:remove $TEST_APP 8080"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
@@ -100,6 +115,11 @@ teardown() {
|
||||
echo "status: $status"
|
||||
assert_output "http:1234:5001 https:8443:5000"
|
||||
|
||||
run /bin/bash -c "dokku --quiet ports:report $TEST_APP --ports-map-json | jq -e 'length == 2 and any(.scheme == \"http\" and .host_port == 1234 and .container_port == 5001) and any(.scheme == \"https\" and .host_port == 8443 and .container_port == 5000)'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku ports:remove $TEST_APP http:1234:5001"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
@@ -110,6 +130,11 @@ teardown() {
|
||||
echo "status: $status"
|
||||
assert_output "https:8443:5000"
|
||||
|
||||
run /bin/bash -c "dokku --quiet ports:report $TEST_APP --ports-map-json | jq -e 'length == 1 and .[0].scheme == \"https\" and .[0].host_port == 8443 and .[0].container_port == 5000'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku ports:clear $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
@@ -120,10 +145,20 @@ teardown() {
|
||||
echo "status: $status"
|
||||
assert_output_not_exists
|
||||
|
||||
run /bin/bash -c "dokku --quiet ports:report $TEST_APP --ports-map-json | jq -e '. == [] or . == null'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku --quiet ports:report $TEST_APP --ports-map-detected"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output "http:80:5000"
|
||||
|
||||
run /bin/bash -c "dokku --quiet ports:report $TEST_APP --ports-map-detected-json | jq -e 'length == 1 and .[0].scheme == \"http\" and .[0].host_port == 80 and .[0].container_port == 5000'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(ports:add) post-deploy add" {
|
||||
@@ -370,3 +405,13 @@ teardown() {
|
||||
assert_success
|
||||
assert_output "http:3001:3001"
|
||||
}
|
||||
|
||||
@test "(ports:report) emits new stripped JSON keys alongside legacy" {
|
||||
run /bin/bash -c "dokku ports:report $TEST_APP --format json | jq -r 'has(\"map\") and has(\"ports-map\")'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku ports:report $TEST_APP --format json | jq -r 'has(\"map-detected\") and has(\"ports-map-detected\")'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
}
|
||||
|
||||
@@ -9,6 +9,8 @@ setup() {
|
||||
}
|
||||
|
||||
teardown() {
|
||||
dokku proxy:set --global proxy-port >/dev/null 2>&1 || true
|
||||
dokku proxy:set --global proxy-ssl-port >/dev/null 2>&1 || true
|
||||
destroy_app
|
||||
[[ -f "$DOKKU_ROOT/VHOST.bak" ]] && mv "$DOKKU_ROOT/VHOST.bak" "$DOKKU_ROOT/VHOST" && chown dokku:dokku "$DOKKU_ROOT/VHOST"
|
||||
global_teardown
|
||||
@@ -28,6 +30,251 @@ teardown() {
|
||||
assert_output "$help_output"
|
||||
}
|
||||
|
||||
@test "(proxy:report) --global raw vs computed type" {
|
||||
run /bin/bash -c "dokku proxy:report --global --format json | jq -r '.\"proxy-global-type\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku proxy:report --global --format json | jq -r '.\"proxy-computed-type\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "nginx"
|
||||
|
||||
run /bin/bash -c "dokku proxy:set --global type caddy"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku proxy:report --global --format json | jq -r '.\"proxy-global-type\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "caddy"
|
||||
|
||||
run /bin/bash -c "dokku proxy:report --global --format json | jq -r '.\"proxy-computed-type\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "caddy"
|
||||
|
||||
run /bin/bash -c "dokku proxy:set --global type"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku proxy:report --global --format json | jq -r '.\"proxy-global-type\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku proxy:report --global --format json | jq -r '.\"proxy-computed-type\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "nginx"
|
||||
}
|
||||
|
||||
@test "(proxy:report) type raw vs computed vs global" {
|
||||
run /bin/bash -c "dokku proxy:set --global type"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-type\"'"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-global-type\"'"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-computed-type\"'"
|
||||
assert_success
|
||||
assert_output "nginx"
|
||||
|
||||
run /bin/bash -c "dokku proxy:set --global type caddy"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-global-type\"'"
|
||||
assert_success
|
||||
assert_output "caddy"
|
||||
|
||||
run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-computed-type\"'"
|
||||
assert_success
|
||||
assert_output "caddy"
|
||||
|
||||
run /bin/bash -c "dokku proxy:set $TEST_APP type traefik"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-type\"'"
|
||||
assert_success
|
||||
assert_output "traefik"
|
||||
|
||||
run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-global-type\"'"
|
||||
assert_success
|
||||
assert_output "caddy"
|
||||
|
||||
run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-computed-type\"'"
|
||||
assert_success
|
||||
assert_output "traefik"
|
||||
|
||||
run /bin/bash -c "dokku proxy:set $TEST_APP type"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku proxy:set --global type"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(proxy:report) proxy-port raw vs computed vs global" {
|
||||
run /bin/bash -c "dokku proxy:set --global proxy-port"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku proxy:set $TEST_APP proxy-port"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-proxy-port\"'"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-global-proxy-port\"'"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-computed-proxy-port\"'"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku proxy:set --global proxy-port 5000"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-global-proxy-port\"'"
|
||||
assert_success
|
||||
assert_output "5000"
|
||||
|
||||
run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-computed-proxy-port\"'"
|
||||
assert_success
|
||||
assert_output "5000"
|
||||
|
||||
run /bin/bash -c "dokku proxy:set $TEST_APP proxy-port 6000"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-proxy-port\"'"
|
||||
assert_success
|
||||
assert_output "6000"
|
||||
|
||||
run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-global-proxy-port\"'"
|
||||
assert_success
|
||||
assert_output "5000"
|
||||
|
||||
run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-computed-proxy-port\"'"
|
||||
assert_success
|
||||
assert_output "6000"
|
||||
|
||||
run /bin/bash -c "dokku proxy:set $TEST_APP proxy-port"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku proxy:set --global proxy-port"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(proxy:report) proxy-ssl-port raw vs computed vs global" {
|
||||
run /bin/bash -c "dokku proxy:set --global proxy-ssl-port"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku proxy:set $TEST_APP proxy-ssl-port"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-proxy-ssl-port\"'"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-global-proxy-ssl-port\"'"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-computed-proxy-ssl-port\"'"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku proxy:set --global proxy-ssl-port 5443"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-global-proxy-ssl-port\"'"
|
||||
assert_success
|
||||
assert_output "5443"
|
||||
|
||||
run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-computed-proxy-ssl-port\"'"
|
||||
assert_success
|
||||
assert_output "5443"
|
||||
|
||||
run /bin/bash -c "dokku proxy:set $TEST_APP proxy-ssl-port 6443"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-proxy-ssl-port\"'"
|
||||
assert_success
|
||||
assert_output "6443"
|
||||
|
||||
run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-global-proxy-ssl-port\"'"
|
||||
assert_success
|
||||
assert_output "5443"
|
||||
|
||||
run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-computed-proxy-ssl-port\"'"
|
||||
assert_success
|
||||
assert_output "6443"
|
||||
|
||||
run /bin/bash -c "dokku proxy:set $TEST_APP proxy-ssl-port"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku proxy:set --global proxy-ssl-port"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(proxy:report) disabled raw and computed match disabled state" {
|
||||
run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-disabled\"'"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-computed-disabled\"'"
|
||||
assert_success
|
||||
assert_output "false"
|
||||
|
||||
run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-enabled\"'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku proxy:disable $TEST_APP"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-disabled\"'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-computed-disabled\"'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-enabled\"'"
|
||||
assert_success
|
||||
assert_output "false"
|
||||
|
||||
run /bin/bash -c "dokku proxy:enable $TEST_APP"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-disabled\"'"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-computed-disabled\"'"
|
||||
assert_success
|
||||
assert_output "false"
|
||||
|
||||
run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-enabled\"'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
}
|
||||
|
||||
@test "(proxy:set) invalid port mapping set" {
|
||||
run /bin/bash -c "dokku proxy:set $TEST_APP http:80:80"
|
||||
echo "output: $output"
|
||||
@@ -125,3 +372,21 @@ teardown() {
|
||||
assert_not_external_port $(<$CID_FILE)
|
||||
done
|
||||
}
|
||||
|
||||
@test "(proxy:report) emits new stripped JSON keys alongside legacy" {
|
||||
run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r 'has(\"type\") and has(\"proxy-type\")'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r 'has(\"global-type\") and has(\"proxy-global-type\")'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r 'has(\"computed-type\") and has(\"proxy-computed-type\")'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r 'has(\"enabled\") and has(\"proxy-enabled\")'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ teardown() {
|
||||
run /bin/bash -c "dokku ps:report $TEST_APP --ps-global-procfile-path"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output "Procfile"
|
||||
assert_output ""
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku ps:report $TEST_APP --ps-procfile-path"
|
||||
@@ -93,6 +93,114 @@ teardown() {
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(ps:set) skip-deploy raw/global/computed" {
|
||||
run /bin/bash -c "dokku ps:report $TEST_APP --format json | jq -r '.\"ps-computed-skip-deploy\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output "false"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku ps:set --global skip-deploy true"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku ps:report $TEST_APP --format json | jq -r '.\"ps-global-skip-deploy\"'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku ps:report $TEST_APP --format json | jq -r '.\"ps-computed-skip-deploy\"'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku ps:report $TEST_APP --format json | jq -r '.\"ps-skip-deploy\"'"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku ps:set $TEST_APP skip-deploy false"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku ps:report $TEST_APP --format json | jq -r '.\"ps-skip-deploy\"'"
|
||||
assert_success
|
||||
assert_output "false"
|
||||
|
||||
run /bin/bash -c "dokku ps:report $TEST_APP --format json | jq -r '.\"ps-global-skip-deploy\"'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku ps:report $TEST_APP --format json | jq -r '.\"ps-computed-skip-deploy\"'"
|
||||
assert_success
|
||||
assert_output "false"
|
||||
|
||||
run /bin/bash -c "dokku ps:set $TEST_APP skip-deploy"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku ps:set --global skip-deploy"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku ps:report $TEST_APP --format json | jq -r '.\"ps-global-skip-deploy\"'"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku ps:report $TEST_APP --format json | jq -r '.\"ps-computed-skip-deploy\"'"
|
||||
assert_success
|
||||
assert_output "false"
|
||||
}
|
||||
|
||||
@test "(ps:set) dockerfile-start-cmd raw and computed" {
|
||||
run /bin/bash -c "dokku ps:report $TEST_APP --format json | jq -r '.\"ps-dockerfile-start-cmd\"'"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku ps:report $TEST_APP --format json | jq -r '.\"ps-computed-dockerfile-start-cmd\"'"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku ps:set $TEST_APP dockerfile-start-cmd 'node app.js'"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku ps:report $TEST_APP --format json | jq -r '.\"ps-dockerfile-start-cmd\"'"
|
||||
assert_success
|
||||
assert_output "node app.js"
|
||||
|
||||
run /bin/bash -c "dokku ps:report $TEST_APP --format json | jq -r '.\"ps-computed-dockerfile-start-cmd\"'"
|
||||
assert_success
|
||||
assert_output "node app.js"
|
||||
|
||||
run /bin/bash -c "dokku ps:set $TEST_APP dockerfile-start-cmd"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku ps:report $TEST_APP --format json | jq -r '.\"ps-dockerfile-start-cmd\"'"
|
||||
assert_success
|
||||
assert_output ""
|
||||
}
|
||||
|
||||
@test "(ps:set) start-cmd raw and computed" {
|
||||
run /bin/bash -c "dokku ps:report $TEST_APP --format json | jq -r '.\"ps-start-cmd\"'"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku ps:report $TEST_APP --format json | jq -r '.\"ps-computed-start-cmd\"'"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku ps:set $TEST_APP start-cmd 'bundle exec rails server'"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku ps:report $TEST_APP --format json | jq -r '.\"ps-start-cmd\"'"
|
||||
assert_success
|
||||
assert_output "bundle exec rails server"
|
||||
|
||||
run /bin/bash -c "dokku ps:report $TEST_APP --format json | jq -r '.\"ps-computed-start-cmd\"'"
|
||||
assert_success
|
||||
assert_output "bundle exec rails server"
|
||||
|
||||
run /bin/bash -c "dokku ps:set $TEST_APP start-cmd"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku ps:report $TEST_APP --format json | jq -r '.\"ps-start-cmd\"'"
|
||||
assert_success
|
||||
assert_output ""
|
||||
}
|
||||
|
||||
@test "(ps:scale) procfile commands extraction" {
|
||||
source "$PLUGIN_CORE_AVAILABLE_PATH/ps/functions"
|
||||
cat <<EOF >"$DOKKU_LIB_ROOT/data/ps/$TEST_APP/Procfile"
|
||||
@@ -161,6 +269,42 @@ web
|
||||
assert_output $'beat: 0\nweb: 4\nworker: 1'
|
||||
}
|
||||
|
||||
@test "(ps:scale) --format json" {
|
||||
run /bin/bash -c "dokku ps:scale $TEST_APP --format json"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output '[{"process_type":"web","quantity":1}]'
|
||||
|
||||
echo "web=4
|
||||
worker=1" >/var/lib/dokku/config/ps/$TEST_APP/scale
|
||||
|
||||
run /bin/bash -c "dokku ps:scale $TEST_APP --format json | jq '. | length'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "2"
|
||||
|
||||
run /bin/bash -c "dokku ps:scale $TEST_APP --format json | jq -r '.[] | select(.process_type==\"web\") | .quantity'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "4"
|
||||
|
||||
run /bin/bash -c "dokku ps:scale $TEST_APP --format json | jq -r '.[] | select(.process_type==\"worker\") | .quantity'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "1"
|
||||
|
||||
rm -f /var/lib/dokku/config/ps/$TEST_APP/scale
|
||||
run /bin/bash -c "dokku ps:scale $TEST_APP --format json"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "[]"
|
||||
}
|
||||
|
||||
@test "(ps) handle windows newlines in procfile" {
|
||||
run deploy_app python dokku@$DOKKU_DOMAIN:$TEST_APP procfile_line_endings_to_windows
|
||||
echo "output: $output"
|
||||
@@ -168,8 +312,167 @@ web
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(ps:report) stop-timeout-seconds raw vs computed vs global" {
|
||||
run /bin/bash -c "dokku ps:set --global stop-timeout-seconds"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku ps:report $TEST_APP --format json | jq -r '.\"ps-stop-timeout-seconds\"'"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku ps:report $TEST_APP --format json | jq -r '.\"stop-timeout-seconds\"'"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku ps:report $TEST_APP --format json | jq -r '.\"ps-global-stop-timeout-seconds\"'"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku ps:report $TEST_APP --format json | jq -r '.\"global-stop-timeout-seconds\"'"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku ps:report $TEST_APP --format json | jq -r '.\"ps-computed-stop-timeout-seconds\"'"
|
||||
assert_success
|
||||
assert_output "30"
|
||||
|
||||
run /bin/bash -c "dokku ps:report $TEST_APP --format json | jq -r '.\"computed-stop-timeout-seconds\"'"
|
||||
assert_success
|
||||
assert_output "30"
|
||||
|
||||
run /bin/bash -c "dokku ps:set --global stop-timeout-seconds 90"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku ps:report $TEST_APP --format json | jq -r '.\"ps-global-stop-timeout-seconds\"'"
|
||||
assert_success
|
||||
assert_output "90"
|
||||
|
||||
run /bin/bash -c "dokku ps:report $TEST_APP --format json | jq -r '.\"global-stop-timeout-seconds\"'"
|
||||
assert_success
|
||||
assert_output "90"
|
||||
|
||||
run /bin/bash -c "dokku ps:report $TEST_APP --format json | jq -r '.\"ps-computed-stop-timeout-seconds\"'"
|
||||
assert_success
|
||||
assert_output "90"
|
||||
|
||||
run /bin/bash -c "dokku ps:report $TEST_APP --format json | jq -r '.\"computed-stop-timeout-seconds\"'"
|
||||
assert_success
|
||||
assert_output "90"
|
||||
|
||||
run /bin/bash -c "dokku ps:set $TEST_APP stop-timeout-seconds 45"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku ps:report $TEST_APP --format json | jq -r '.\"ps-stop-timeout-seconds\"'"
|
||||
assert_success
|
||||
assert_output "45"
|
||||
|
||||
run /bin/bash -c "dokku ps:report $TEST_APP --format json | jq -r '.\"stop-timeout-seconds\"'"
|
||||
assert_success
|
||||
assert_output "45"
|
||||
|
||||
run /bin/bash -c "dokku ps:report $TEST_APP --format json | jq -r '.\"ps-global-stop-timeout-seconds\"'"
|
||||
assert_success
|
||||
assert_output "90"
|
||||
|
||||
run /bin/bash -c "dokku ps:report $TEST_APP --format json | jq -r '.\"ps-computed-stop-timeout-seconds\"'"
|
||||
assert_success
|
||||
assert_output "45"
|
||||
|
||||
run /bin/bash -c "dokku ps:report $TEST_APP --format json | jq -r '.\"computed-stop-timeout-seconds\"'"
|
||||
assert_success
|
||||
assert_output "45"
|
||||
|
||||
run /bin/bash -c "dokku ps:set $TEST_APP stop-timeout-seconds"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku ps:set --global stop-timeout-seconds"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(ps:report) --global --format json" {
|
||||
run /bin/bash -c "dokku ps:report --global --format json | jq -e ."
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku ps:report --global --format json | jq -r 'has(\"ps-global-procfile-path\")'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku ps:report --global --format json | jq -r 'has(\"global-procfile-path\")'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku ps:report --global --format json | jq -r 'has(\"ps-computed-procfile-path\")'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku ps:report --global --format json | jq -r 'has(\"computed-procfile-path\")'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku ps:report --global --format json | jq -r 'has(\"ps-global-stop-timeout-seconds\")'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku ps:report --global --format json | jq -r 'has(\"global-stop-timeout-seconds\")'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku ps:report --global --format json | jq -r 'has(\"ps-computed-stop-timeout-seconds\")'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku ps:report --global --format json | jq -r 'has(\"computed-stop-timeout-seconds\")'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku ps:set --global stop-timeout-seconds 75"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku ps:report --global --format json | jq -r '.\"ps-global-stop-timeout-seconds\"'"
|
||||
assert_success
|
||||
assert_output "75"
|
||||
|
||||
run /bin/bash -c "dokku ps:report --global --format json | jq -r '.\"global-stop-timeout-seconds\"'"
|
||||
assert_success
|
||||
assert_output "75"
|
||||
|
||||
run /bin/bash -c "dokku ps:report --global --format json | jq -r '.\"ps-computed-stop-timeout-seconds\"'"
|
||||
assert_success
|
||||
assert_output "75"
|
||||
|
||||
run /bin/bash -c "dokku ps:report --global --format json | jq -r '.\"computed-stop-timeout-seconds\"'"
|
||||
assert_success
|
||||
assert_output "75"
|
||||
|
||||
run /bin/bash -c "dokku ps:set --global stop-timeout-seconds"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku ps:report --global --format json | jq -r '.\"ps-global-stop-timeout-seconds\"'"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku ps:report --global --format json | jq -r '.\"global-stop-timeout-seconds\"'"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku ps:report --global --format json | jq -r '.\"ps-computed-stop-timeout-seconds\"'"
|
||||
assert_success
|
||||
assert_output "30"
|
||||
|
||||
run /bin/bash -c "dokku ps:report --global --format json | jq -r '.\"computed-stop-timeout-seconds\"'"
|
||||
assert_success
|
||||
assert_output "30"
|
||||
}
|
||||
|
||||
@test "(ps:restart-policy) default policy" {
|
||||
run /bin/bash -c "dokku --quiet ps:report $TEST_APP --ps-restart-policy"
|
||||
run /bin/bash -c "dokku ps:report $TEST_APP --ps-restart-policy"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku ps:report $TEST_APP --ps-computed-restart-policy"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output "on-failure:10"
|
||||
@@ -182,13 +485,90 @@ web
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku --quiet ps:report $TEST_APP --ps-restart-policy"
|
||||
run /bin/bash -c "dokku ps:report $TEST_APP --ps-restart-policy"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output "$policy"
|
||||
|
||||
run /bin/bash -c "dokku ps:report $TEST_APP --ps-computed-restart-policy"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output "$policy"
|
||||
done
|
||||
}
|
||||
|
||||
@test "(ps:restart-policy) ps:set restart-policy unset" {
|
||||
run /bin/bash -c "dokku ps:set $TEST_APP restart-policy on-failure:5"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku ps:report $TEST_APP --ps-restart-policy"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output "on-failure:5"
|
||||
|
||||
run /bin/bash -c "dokku ps:set $TEST_APP restart-policy"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku ps:report $TEST_APP --ps-restart-policy"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku ps:report $TEST_APP --ps-computed-restart-policy"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output "on-failure:10"
|
||||
}
|
||||
|
||||
@test "(ps:restart-policy) invalid policy" {
|
||||
run /bin/bash -c "dokku ps:set $TEST_APP restart-policy bogus"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output_contains "Invalid restart-policy specified"
|
||||
}
|
||||
|
||||
@test "(ps:restart-policy) global policy" {
|
||||
run /bin/bash -c "dokku ps:set --global restart-policy always"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku ps:report $TEST_APP --ps-global-restart-policy"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output "always"
|
||||
|
||||
run /bin/bash -c "dokku ps:report $TEST_APP --ps-restart-policy"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku ps:report $TEST_APP --ps-computed-restart-policy"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output "always"
|
||||
|
||||
run /bin/bash -c "dokku ps:set $TEST_APP restart-policy no"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku ps:report $TEST_APP --ps-computed-restart-policy"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output "no"
|
||||
|
||||
run /bin/bash -c "dokku ps:set --global restart-policy"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(ps:restart-policy) deployed policy" {
|
||||
test_restart_policy="on-failure:20"
|
||||
run /bin/bash -c "dokku ps:set $TEST_APP restart-policy $test_restart_policy"
|
||||
@@ -196,7 +576,7 @@ web
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku --quiet ps:report $TEST_APP --ps-restart-policy"
|
||||
run /bin/bash -c "dokku ps:report $TEST_APP --ps-restart-policy"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output "$test_restart_policy"
|
||||
@@ -216,6 +596,22 @@ web
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output "$test_restart_policy"
|
||||
|
||||
run /bin/bash -c "dokku ps:set $TEST_APP restart-policy"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku ps:rebuild $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
CID=$(<$DOKKU_ROOT/$TEST_APP/CONTAINER.web.1)
|
||||
run /bin/bash -c "docker inspect -f '{{ .HostConfig.RestartPolicy.Name }}:{{ .HostConfig.RestartPolicy.MaximumRetryCount }}' $CID"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output "on-failure:10"
|
||||
}
|
||||
|
||||
procfile_line_endings_to_windows() {
|
||||
|
||||
@@ -133,6 +133,314 @@ teardown() {
|
||||
create_app
|
||||
}
|
||||
|
||||
@test "(registry:report) image-repo raw vs computed vs global" {
|
||||
run /bin/bash -c "dokku registry:set --global image-repo-template"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku registry:report $TEST_APP --format json | jq -r '.\"registry-image-repo\"'"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku registry:report $TEST_APP --format json | jq -r '.\"registry-global-image-repo-template\"'"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
# When neither per-app image-repo nor a global image-repo-template are set,
|
||||
# reportComputedImageRepo falls back to common.GetAppImageRepo which returns
|
||||
# the default dokku/<app> image name.
|
||||
run /bin/bash -c "dokku registry:report $TEST_APP --format json | jq -r '.\"registry-computed-image-repo\"'"
|
||||
assert_success
|
||||
assert_output "dokku/$TEST_APP"
|
||||
|
||||
run /bin/bash -c "dokku registry:set --global image-repo-template 'dokku/{{ APP }}'"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku registry:report $TEST_APP --format json | jq -r '.\"registry-global-image-repo-template\"'"
|
||||
assert_success
|
||||
assert_output 'dokku/{{ APP }}'
|
||||
|
||||
run /bin/bash -c "dokku registry:report $TEST_APP --format json | jq -r '.\"registry-computed-image-repo\"'"
|
||||
assert_success
|
||||
assert_output "dokku/$TEST_APP"
|
||||
|
||||
run /bin/bash -c "dokku registry:set $TEST_APP image-repo my/$TEST_APP"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku registry:report $TEST_APP --format json | jq -r '.\"registry-image-repo\"'"
|
||||
assert_success
|
||||
assert_output "my/$TEST_APP"
|
||||
|
||||
run /bin/bash -c "dokku registry:report $TEST_APP --format json | jq -r '.\"registry-computed-image-repo\"'"
|
||||
assert_success
|
||||
assert_output "my/$TEST_APP"
|
||||
|
||||
run /bin/bash -c "dokku registry:set $TEST_APP image-repo"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku registry:set --global image-repo-template"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(registry:report) image-repo-template raw vs computed vs global" {
|
||||
run /bin/bash -c "dokku registry:set --global image-repo-template"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku registry:report $TEST_APP --format json | jq -r '.\"registry-image-repo-template\"'"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku registry:report $TEST_APP --format json | jq -r '.\"registry-global-image-repo-template\"'"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku registry:report $TEST_APP --format json | jq -r '.\"registry-computed-image-repo-template\"'"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku registry:set --global image-repo-template 'global-prefix/{{ .AppName }}'"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku registry:report $TEST_APP --format json | jq -r '.\"registry-image-repo-template\"'"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku registry:report $TEST_APP --format json | jq -r '.\"registry-global-image-repo-template\"'"
|
||||
assert_success
|
||||
assert_output 'global-prefix/{{ .AppName }}'
|
||||
|
||||
run /bin/bash -c "dokku registry:report $TEST_APP --format json | jq -r '.\"registry-computed-image-repo-template\"'"
|
||||
assert_success
|
||||
assert_output 'global-prefix/{{ .AppName }}'
|
||||
|
||||
# The global template renders into the computed image-repo.
|
||||
run /bin/bash -c "dokku registry:report $TEST_APP --format json | jq -r '.\"registry-computed-image-repo\"'"
|
||||
assert_success
|
||||
assert_output "global-prefix/$TEST_APP"
|
||||
|
||||
# Per-app template overrides the global template.
|
||||
run /bin/bash -c "dokku registry:set $TEST_APP image-repo-template 'app-prefix/{{ .AppName }}-prod'"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku registry:report $TEST_APP --format json | jq -r '.\"registry-image-repo-template\"'"
|
||||
assert_success
|
||||
assert_output 'app-prefix/{{ .AppName }}-prod'
|
||||
|
||||
run /bin/bash -c "dokku registry:report $TEST_APP --format json | jq -r '.\"registry-global-image-repo-template\"'"
|
||||
assert_success
|
||||
assert_output 'global-prefix/{{ .AppName }}'
|
||||
|
||||
run /bin/bash -c "dokku registry:report $TEST_APP --format json | jq -r '.\"registry-computed-image-repo-template\"'"
|
||||
assert_success
|
||||
assert_output 'app-prefix/{{ .AppName }}-prod'
|
||||
|
||||
# The per-app template flows through to the computed image-repo.
|
||||
run /bin/bash -c "dokku registry:report $TEST_APP --format json | jq -r '.\"registry-computed-image-repo\"'"
|
||||
assert_success
|
||||
assert_output "app-prefix/$TEST_APP-prod"
|
||||
|
||||
# Unsetting the per-app template restores the global template behavior.
|
||||
run /bin/bash -c "dokku registry:set $TEST_APP image-repo-template"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku registry:report $TEST_APP --format json | jq -r '.\"registry-image-repo-template\"'"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku registry:report $TEST_APP --format json | jq -r '.\"registry-computed-image-repo-template\"'"
|
||||
assert_success
|
||||
assert_output 'global-prefix/{{ .AppName }}'
|
||||
|
||||
run /bin/bash -c "dokku registry:report $TEST_APP --format json | jq -r '.\"registry-computed-image-repo\"'"
|
||||
assert_success
|
||||
assert_output "global-prefix/$TEST_APP"
|
||||
|
||||
run /bin/bash -c "dokku registry:set --global image-repo-template"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(registry:report) push-on-release raw vs computed vs global" {
|
||||
run /bin/bash -c "dokku registry:set --global push-on-release"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku registry:report $TEST_APP --format json | jq -r '.\"registry-push-on-release\"'"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku registry:report $TEST_APP --format json | jq -r '.\"registry-global-push-on-release\"'"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku registry:report $TEST_APP --format json | jq -r '.\"registry-computed-push-on-release\"'"
|
||||
assert_success
|
||||
assert_output "false"
|
||||
|
||||
run /bin/bash -c "dokku registry:set --global push-on-release true"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku registry:report $TEST_APP --format json | jq -r '.\"registry-global-push-on-release\"'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku registry:report $TEST_APP --format json | jq -r '.\"registry-computed-push-on-release\"'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku registry:set $TEST_APP push-on-release false"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku registry:report $TEST_APP --format json | jq -r '.\"registry-push-on-release\"'"
|
||||
assert_success
|
||||
assert_output "false"
|
||||
|
||||
run /bin/bash -c "dokku registry:report $TEST_APP --format json | jq -r '.\"registry-computed-push-on-release\"'"
|
||||
assert_success
|
||||
assert_output "false"
|
||||
|
||||
run /bin/bash -c "dokku registry:set $TEST_APP push-on-release"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku registry:set --global push-on-release"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(registry:report --global) computed and global keys" {
|
||||
run /bin/bash -c "dokku registry:set --global push-on-release"
|
||||
assert_success
|
||||
run /bin/bash -c "dokku registry:set --global server"
|
||||
assert_success
|
||||
run /bin/bash -c "dokku registry:set --global image-repo-template"
|
||||
assert_success
|
||||
run /bin/bash -c "dokku registry:set --global push-extra-tags"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku registry:report --global --format json | jq -r '.\"registry-global-push-on-release\"'"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku registry:report --global --format json | jq -r '.\"registry-computed-push-on-release\"'"
|
||||
assert_success
|
||||
assert_output "false"
|
||||
|
||||
run /bin/bash -c "dokku registry:report --global --format json | jq -r '.\"registry-global-server\"'"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku registry:report --global --format json | jq -r '.\"registry-computed-server\"'"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku registry:report --global --format json | jq -r '.\"registry-global-image-repo-template\"'"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku registry:report --global --format json | jq -r '.\"registry-computed-image-repo-template\"'"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku registry:report --global --format json | jq -r '.\"registry-global-push-extra-tags\"'"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku registry:report --global --format json | jq -r '.\"registry-computed-push-extra-tags\"'"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku registry:set --global push-on-release true"
|
||||
assert_success
|
||||
run /bin/bash -c "dokku registry:set --global server ghcr.io"
|
||||
assert_success
|
||||
run /bin/bash -c "dokku registry:set --global image-repo-template 'dokku/{{ APP }}'"
|
||||
assert_success
|
||||
run /bin/bash -c "dokku registry:set --global push-extra-tags latest,stable"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku registry:report --global --format json | jq -r '.\"registry-global-push-on-release\"'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku registry:report --global --format json | jq -r '.\"registry-computed-push-on-release\"'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku registry:report --global --format json | jq -r '.\"registry-global-server\"'"
|
||||
assert_success
|
||||
assert_output "ghcr.io"
|
||||
|
||||
run /bin/bash -c "dokku registry:report --global --format json | jq -r '.\"registry-computed-server\"'"
|
||||
assert_success
|
||||
assert_output "ghcr.io/"
|
||||
|
||||
run /bin/bash -c "dokku registry:report --global --format json | jq -r '.\"registry-global-image-repo-template\"'"
|
||||
assert_success
|
||||
assert_output 'dokku/{{ APP }}'
|
||||
|
||||
run /bin/bash -c "dokku registry:report --global --format json | jq -r '.\"registry-computed-image-repo-template\"'"
|
||||
assert_success
|
||||
assert_output 'dokku/{{ APP }}'
|
||||
|
||||
run /bin/bash -c "dokku registry:report --global --format json | jq -r '.\"registry-global-push-extra-tags\"'"
|
||||
assert_success
|
||||
assert_output "latest,stable"
|
||||
|
||||
run /bin/bash -c "dokku registry:report --global --format json | jq -r '.\"registry-computed-push-extra-tags\"'"
|
||||
assert_success
|
||||
assert_output "latest,stable"
|
||||
|
||||
run /bin/bash -c "dokku registry:set --global push-on-release"
|
||||
assert_success
|
||||
run /bin/bash -c "dokku registry:set --global server"
|
||||
assert_success
|
||||
run /bin/bash -c "dokku registry:set --global image-repo-template"
|
||||
assert_success
|
||||
run /bin/bash -c "dokku registry:set --global push-extra-tags"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(registry:report) push-extra-tags raw vs computed vs global" {
|
||||
run /bin/bash -c "dokku registry:set --global push-extra-tags"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku registry:report $TEST_APP --format json | jq -r '.\"registry-push-extra-tags\"'"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku registry:report $TEST_APP --format json | jq -r '.\"registry-global-push-extra-tags\"'"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku registry:report $TEST_APP --format json | jq -r '.\"registry-computed-push-extra-tags\"'"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku registry:set --global push-extra-tags global-tag"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku registry:report $TEST_APP --format json | jq -r '.\"registry-global-push-extra-tags\"'"
|
||||
assert_success
|
||||
assert_output "global-tag"
|
||||
|
||||
run /bin/bash -c "dokku registry:report $TEST_APP --format json | jq -r '.\"registry-computed-push-extra-tags\"'"
|
||||
assert_success
|
||||
assert_output "global-tag"
|
||||
|
||||
run /bin/bash -c "dokku registry:set $TEST_APP push-extra-tags release,stable"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku registry:report $TEST_APP --format json | jq -r '.\"registry-push-extra-tags\"'"
|
||||
assert_success
|
||||
assert_output "release,stable"
|
||||
|
||||
run /bin/bash -c "dokku registry:report $TEST_APP --format json | jq -r '.\"registry-computed-push-extra-tags\"'"
|
||||
assert_success
|
||||
assert_output "release,stable"
|
||||
|
||||
run /bin/bash -c "dokku registry:set $TEST_APP push-extra-tags"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku registry:set --global push-extra-tags"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(registry) registry:set server" {
|
||||
run /bin/bash -c "dokku registry:set --global server ghcr.io"
|
||||
echo "output: $output"
|
||||
@@ -409,3 +717,29 @@ teardown() {
|
||||
assert_success
|
||||
assert_output_contains "dokku/test-app:foo"
|
||||
}
|
||||
|
||||
@test "(registry:report) emits new stripped JSON keys alongside legacy" {
|
||||
run /bin/bash -c "dokku registry:report $TEST_APP --format json | jq -r 'has(\"image-repo\") and has(\"registry-image-repo\")'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku registry:report $TEST_APP --format json | jq -r 'has(\"computed-image-repo\") and has(\"registry-computed-image-repo\")'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku registry:report $TEST_APP --format json | jq -r 'has(\"push-on-release\") and has(\"registry-push-on-release\")'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku registry:report $TEST_APP --format json | jq -r 'has(\"global-push-on-release\") and has(\"registry-global-push-on-release\")'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku registry:report $TEST_APP --format json | jq -r 'has(\"computed-server\") and has(\"registry-computed-server\")'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku registry:report --global --format json | jq -r 'has(\"global-image-repo-template\") and has(\"registry-global-image-repo-template\")'"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
}
|
||||
|
||||
100
tests/unit/registry_2.bats
Normal file
100
tests/unit/registry_2.bats
Normal file
@@ -0,0 +1,100 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
setup() {
|
||||
global_setup
|
||||
create_app
|
||||
dokku checks:set $TEST_APP wait-to-retire 30
|
||||
}
|
||||
|
||||
teardown() {
|
||||
destroy_app
|
||||
global_teardown
|
||||
}
|
||||
|
||||
setup_push_on_release_app() {
|
||||
if [[ -z "$DOCKERHUB_USERNAME" ]] || [[ -z "$DOCKERHUB_TOKEN" ]]; then
|
||||
skip "skipping due to missing docker.io credentials DOCKERHUB_USERNAME:DOCKERHUB_TOKEN"
|
||||
fi
|
||||
|
||||
run /bin/bash -c "dokku builder:set $TEST_APP selected herokuish"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku proxy:set $TEST_APP nginx"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku registry:login $TEST_APP docker.io $DOCKERHUB_USERNAME $DOCKERHUB_TOKEN"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku registry:set $TEST_APP image-repo $DOCKERHUB_USERNAME/$TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku registry:set $TEST_APP push-on-release true"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run deploy_app python dokku@$DOKKU_DOMAIN:$TEST_APP
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "docker image rm $DOCKERHUB_USERNAME/$TEST_APP:1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "docker image inspect $DOCKERHUB_USERNAME/$TEST_APP:1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
}
|
||||
|
||||
@test "(registry) [recover] ps:restart pulls missing image" {
|
||||
setup_push_on_release_app
|
||||
|
||||
run /bin/bash -c "dokku ps:restart $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "not found locally, pulling from registry"
|
||||
|
||||
run /bin/bash -c "docker image inspect $DOCKERHUB_USERNAME/$TEST_APP:1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(registry) [recover] dokku run pulls missing image" {
|
||||
setup_push_on_release_app
|
||||
|
||||
run /bin/bash -c "dokku run $TEST_APP echo recovery-ok"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "not found locally, pulling from registry"
|
||||
assert_output_contains "recovery-ok"
|
||||
}
|
||||
|
||||
@test "(registry) [recover] domains:add pulls missing image" {
|
||||
setup_push_on_release_app
|
||||
|
||||
run /bin/bash -c "dokku domains:add $TEST_APP recovery.${DOKKU_DOMAIN}"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "docker image inspect $DOCKERHUB_USERNAME/$TEST_APP:1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
}
|
||||
@@ -26,7 +26,7 @@ teardown() {
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output_contains "herokuish version:"
|
||||
assert_output_contains "Deployed: false" "0"
|
||||
assert_output_contains "Deployed: false" "0"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku report fake-app-name"
|
||||
@@ -48,7 +48,7 @@ teardown() {
|
||||
run /bin/bash -c "dokku report ${TEST_APP}-2 2>&1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output_contains "Deployed: false"
|
||||
assert_output_contains "Deployed: false"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku --force apps:destroy ${TEST_APP}-2"
|
||||
|
||||
131
tests/unit/resource_3.bats
Normal file
131
tests/unit/resource_3.bats
Normal file
@@ -0,0 +1,131 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
setup() {
|
||||
global_setup
|
||||
create_app
|
||||
}
|
||||
|
||||
teardown() {
|
||||
destroy_app
|
||||
global_teardown
|
||||
}
|
||||
|
||||
@test "(resource) resource:limit --process-type build (herokuish)" {
|
||||
run /bin/bash -c "dokku resource:limit --memory 256m --cpu 1 --memory-swap 512m --nvidia-gpu 1 --process-type build $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku resource:report --resource-build.limit.memory $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output "256m"
|
||||
|
||||
run_plugn_trigger docker-args-process-build "$TEST_APP" herokuish
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "--memory=256m"
|
||||
assert_output_contains "--cpus=1"
|
||||
assert_output_contains "--memory-swap=512m"
|
||||
assert_output_contains "--gpus=1"
|
||||
}
|
||||
|
||||
@test "(resource) resource:limit --process-type build (dockerfile filters cpu and gpu)" {
|
||||
run /bin/bash -c "dokku resource:limit --memory 512m --cpu 1 --nvidia-gpu 1 --memory-swap 1g --process-type build $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run_plugn_trigger docker-args-process-build "$TEST_APP" dockerfile
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "--memory=512m"
|
||||
assert_output_contains "--memory-swap=1g"
|
||||
assert_output_not_contains "--cpus="
|
||||
assert_output_not_contains "--gpus="
|
||||
}
|
||||
|
||||
@test "(resource) resource:limit --process-type build (pack/lambda emit nothing)" {
|
||||
run /bin/bash -c "dokku resource:limit --memory 512m --process-type build $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run_plugn_trigger docker-args-process-build "$TEST_APP" pack
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_not_contains "--memory"
|
||||
|
||||
run_plugn_trigger docker-args-process-build "$TEST_APP" lambda
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_not_contains "--memory"
|
||||
}
|
||||
|
||||
@test "(resource) resource:limit defaults do not leak into build trigger" {
|
||||
run /bin/bash -c "dokku resource:limit --memory 128m $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run_plugn_trigger docker-args-process-build "$TEST_APP" herokuish
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_not_contains "--memory"
|
||||
}
|
||||
|
||||
@test "(resource) resource:limit reservations do not apply at build time" {
|
||||
run /bin/bash -c "dokku resource:reserve --memory 128m --process-type build $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run_plugn_trigger docker-args-process-build "$TEST_APP" herokuish
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_not_contains "--memory-reservation"
|
||||
assert_output_not_contains "--memory"
|
||||
}
|
||||
|
||||
@test "(resource) DOKKU_OMIT_RESOURCE_ARGS suppresses build trigger" {
|
||||
run /bin/bash -c "dokku resource:limit --memory 256m --process-type build $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run_plugn_trigger DOKKU_OMIT_RESOURCE_ARGS=1 docker-args-process-build "$TEST_APP" herokuish
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_not_contains "--memory"
|
||||
}
|
||||
|
||||
@test "(resource) resource:limit-clear --process-type build" {
|
||||
run /bin/bash -c "dokku resource:limit --memory 256m --process-type build $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku resource:report --resource-build.limit.memory $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output "256m"
|
||||
|
||||
run /bin/bash -c "dokku resource:limit-clear --process-type build $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku resource:report --resource-build.limit.memory $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
}
|
||||
@@ -153,3 +153,46 @@ teardown() {
|
||||
assert_success
|
||||
assert_output "2"
|
||||
}
|
||||
|
||||
@test "(run) docker-options and -e flags are not eval-injected" {
|
||||
run deploy_app
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku docker-options:add $TEST_APP run '--label=com.dokku.test=safe'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku run --ttl-seconds=60 -e FOO=bar $TEST_APP env | grep -E '^FOO=bar'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku run -e 'X=\$(id)' $TEST_APP env"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
[[ "$output" == *'X=$(id)'* ]] || flunk "expected literal X=\$(id) in container env"
|
||||
[[ "$output" != *"uid="* ]] || flunk "id command output leaked - env value was expanded"
|
||||
}
|
||||
|
||||
@test "(run) --ttl-seconds rejects non-numeric input; docker-options stores it verbatim" {
|
||||
run /bin/bash -c "dokku run --ttl-seconds '\$(id)' $TEST_APP echo hi"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
[[ "$output" != *"uid="* ]] || flunk "id command output leaked - ttl value was expanded"
|
||||
|
||||
run /bin/bash -c "dokku docker-options:add $TEST_APP run '--label=x=\$(id)'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku docker-options:report $TEST_APP --docker-options-run"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
[[ "$output" == *'x=$(id)'* ]] || flunk "expected literal x=\$(id) stored in docker options"
|
||||
[[ "$output" != *"uid="* ]] || flunk "id command output leaked - docker option was expanded"
|
||||
}
|
||||
|
||||
@@ -10,6 +10,181 @@ teardown() {
|
||||
global_teardown
|
||||
}
|
||||
|
||||
@test "(scheduler-docker-local:report) --global raw and computed keys" {
|
||||
run /bin/bash -c "dokku scheduler-docker-local:report --global --scheduler-docker-local-global-init-process"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku scheduler-docker-local:report --global --scheduler-docker-local-computed-init-process"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku scheduler-docker-local:report --global --scheduler-docker-local-global-parallel-schedule-count"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku scheduler-docker-local:report --global --scheduler-docker-local-computed-parallel-schedule-count"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "1"
|
||||
}
|
||||
|
||||
@test "(scheduler-docker-local:report) info-flag works before deploy" {
|
||||
run create_app
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku scheduler-docker-local:report $TEST_APP --scheduler-docker-local-parallel-schedule-count"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku scheduler-docker-local:report $TEST_APP --scheduler-docker-local-computed-parallel-schedule-count"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "1"
|
||||
|
||||
run /bin/bash -c "dokku scheduler-docker-local:report $TEST_APP --scheduler-docker-local-global-parallel-schedule-count"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku scheduler-docker-local:report $TEST_APP --scheduler-docker-local-init-process"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku scheduler-docker-local:report $TEST_APP --scheduler-docker-local-computed-init-process"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku scheduler-docker-local:report $TEST_APP --scheduler-docker-local-global-init-process"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku scheduler-docker-local:report $TEST_APP --scheduler-docker-local-invalid-flag"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output_contains "Invalid flag passed"
|
||||
|
||||
destroy_app
|
||||
}
|
||||
|
||||
@test "(scheduler-docker-local:report) --format json" {
|
||||
run create_app
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku scheduler-docker-local:report $TEST_APP --format json | jq -e ."
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku scheduler-docker-local:report $TEST_APP --format json | jq -r '.\"init-process\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku scheduler-docker-local:report $TEST_APP --format json | jq -r '.\"computed-init-process\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output "true"
|
||||
|
||||
run /bin/bash -c "dokku scheduler-docker-local:report $TEST_APP --format json | jq -r '.\"global-init-process\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku scheduler-docker-local:report $TEST_APP --format json | jq -r '.\"parallel-schedule-count\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku scheduler-docker-local:report $TEST_APP --format json | jq -r '.\"computed-parallel-schedule-count\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output "1"
|
||||
|
||||
run /bin/bash -c "dokku scheduler-docker-local:report $TEST_APP --format json | jq -r '.\"global-parallel-schedule-count\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku scheduler-docker-local:set $TEST_APP init-process false"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku scheduler-docker-local:report $TEST_APP --format json | jq -r '.\"init-process\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output "false"
|
||||
|
||||
run /bin/bash -c "dokku scheduler-docker-local:report $TEST_APP --format json | jq -r '.\"computed-init-process\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output "false"
|
||||
|
||||
destroy_app
|
||||
}
|
||||
|
||||
@test "(scheduler-docker-local:set) --global" {
|
||||
run /bin/bash -c "dokku scheduler-docker-local:set --global parallel-schedule-count 4"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku scheduler-docker-local:report --global --format json | jq -r '.\"global-parallel-schedule-count\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output "4"
|
||||
|
||||
run create_app
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku scheduler-docker-local:report $TEST_APP --format json | jq -r '.\"parallel-schedule-count\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "dokku scheduler-docker-local:report $TEST_APP --format json | jq -r '.\"computed-parallel-schedule-count\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output "4"
|
||||
|
||||
run /bin/bash -c "dokku scheduler-docker-local:report $TEST_APP --format json | jq -r '.\"global-parallel-schedule-count\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output "4"
|
||||
|
||||
run /bin/bash -c "dokku scheduler-docker-local:set --global parallel-schedule-count"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
destroy_app
|
||||
}
|
||||
|
||||
@test "(scheduler-docker-local) scheduler-docker-local:help" {
|
||||
run /bin/bash -c "dokku scheduler-docker-local"
|
||||
echo "output: $output"
|
||||
@@ -175,3 +350,136 @@ teardown() {
|
||||
assert_output_contains "Deploys may fail when publishing ports and scaling to multiple containers" 0
|
||||
assert_output_contains "Deploys may fail when publishing ports and enabling zero downtime" 0
|
||||
}
|
||||
|
||||
@test "(scheduler-docker-local) sends SIGTERM immediately on deploy" {
|
||||
run create_app
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku checks:set $TEST_APP wait-to-retire 600"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run deploy_app
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
local old_cid
|
||||
old_cid="$(docker ps --filter label=com.dokku.app-name=$TEST_APP --filter label=com.dokku.process-type=web --format '{{.ID}}')"
|
||||
[[ -n "$old_cid" ]]
|
||||
|
||||
run /bin/bash -c "dokku ps:rebuild $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
sleep 5
|
||||
|
||||
run /bin/bash -c "docker inspect --format '{{.State.Status}}' $old_cid"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output "exited"
|
||||
|
||||
run /bin/bash -c "docker ps --filter label=com.dokku.app-name=$TEST_APP --filter label=com.dokku.process-type=web --format '{{.Names}}'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output "$TEST_APP.web.1"
|
||||
}
|
||||
|
||||
@test "(scheduler-docker-local) scale down retires orphaned containers" {
|
||||
run create_app
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku checks:set $TEST_APP wait-to-retire 1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run deploy_app
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku ps:scale $TEST_APP web=2"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
sleep 2
|
||||
|
||||
run /bin/bash -c "dokku ps:retire"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "docker ps --filter label=com.dokku.app-name=$TEST_APP --filter label=com.dokku.process-type=web --format '{{.Names}}' | wc -l"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output "2"
|
||||
|
||||
run /bin/bash -c "dokku ps:scale $TEST_APP web=1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
sleep 2
|
||||
|
||||
run /bin/bash -c "dokku ps:retire"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "docker ps --filter label=com.dokku.app-name=$TEST_APP --filter label=com.dokku.process-type=web --format '{{.Names}}'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output "$TEST_APP.web.1"
|
||||
}
|
||||
|
||||
@test "(scheduler-docker-local) ps:rebuild with image-based deploy keeps running image" {
|
||||
run create_app
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku checks:set $TEST_APP wait-to-retire 1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku git:from-image $TEST_APP cockpithq/cockpit:core-latest"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
local running_image
|
||||
running_image="$(docker container inspect "$TEST_APP.web.1" --format '{{.Image}}' | cut -d: -f2)"
|
||||
[[ -n "$running_image" ]]
|
||||
|
||||
run /bin/bash -c "dokku ps:rebuild $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
sleep 3
|
||||
|
||||
run /bin/bash -c "dokku ps:retire"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "has running containers, skipping rm" 0
|
||||
|
||||
run /bin/bash -c "grep -F \"$running_image\" /var/lib/dokku/data/scheduler-docker-local/dead-images 2>/dev/null || true"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "docker container inspect $TEST_APP.web.1 --format '{{.State.Status}}'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_output "running"
|
||||
}
|
||||
|
||||
@@ -52,6 +52,66 @@ teardown() {
|
||||
assert_output "5000"
|
||||
}
|
||||
|
||||
@test "(scheduler-k3s) deploy autoscaling cpu-only trigger [keda-fallback]" {
|
||||
if [[ -z "$DOCKERHUB_USERNAME" ]] || [[ -z "$DOCKERHUB_TOKEN" ]]; then
|
||||
skip "skipping due to missing docker.io credentials DOCKERHUB_USERNAME:DOCKERHUB_TOKEN"
|
||||
fi
|
||||
|
||||
INGRESS_CLASS=nginx install_k3s
|
||||
|
||||
run /bin/bash -c "dokku apps:create $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run deploy_app python dokku@$DOKKU_DOMAIN:$TEST_APP inject_cpu_autoscaling_app_json
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "kubectl get scaledobjects.keda.sh $TEST_APP-web -o=jsonpath='{.spec.fallback}'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
|
||||
run /bin/bash -c "kubectl get scaledobjects.keda.sh $TEST_APP-web -o=jsonpath='{.spec.triggers[0].type}'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "cpu"
|
||||
}
|
||||
|
||||
@test "(scheduler-k3s) deploy autoscaling external trigger [keda-fallback]" {
|
||||
if [[ -z "$DOCKERHUB_USERNAME" ]] || [[ -z "$DOCKERHUB_TOKEN" ]]; then
|
||||
skip "skipping due to missing docker.io credentials DOCKERHUB_USERNAME:DOCKERHUB_TOKEN"
|
||||
fi
|
||||
|
||||
INGRESS_CLASS=nginx install_k3s
|
||||
|
||||
run /bin/bash -c "dokku apps:create $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run deploy_app python dokku@$DOKKU_DOMAIN:$TEST_APP inject_prometheus_autoscaling_app_json
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "kubectl get scaledobjects.keda.sh $TEST_APP-web -o=jsonpath='{.spec.fallback.failureThreshold}'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "3"
|
||||
|
||||
run /bin/bash -c "kubectl get scaledobjects.keda.sh $TEST_APP-web -o=jsonpath='{.spec.fallback.replicas}'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "1"
|
||||
}
|
||||
|
||||
inject_app_json() {
|
||||
local APP="$1"
|
||||
local APP_REPO_DIR="$2"
|
||||
@@ -68,3 +128,60 @@ inject_app_json() {
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
inject_cpu_autoscaling_app_json() {
|
||||
local APP="$1"
|
||||
local APP_REPO_DIR="$2"
|
||||
[[ -z "$APP" ]] && local APP="$TEST_APP"
|
||||
cat <<EOF >"$APP_REPO_DIR/app.json"
|
||||
{
|
||||
"formation": {
|
||||
"web": {
|
||||
"autoscaling": {
|
||||
"min_quantity": 1,
|
||||
"max_quantity": 3,
|
||||
"triggers": [
|
||||
{
|
||||
"name": "cpu-trigger",
|
||||
"type": "cpu",
|
||||
"metadata": {
|
||||
"value": "80"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
inject_prometheus_autoscaling_app_json() {
|
||||
local APP="$1"
|
||||
local APP_REPO_DIR="$2"
|
||||
[[ -z "$APP" ]] && local APP="$TEST_APP"
|
||||
cat <<EOF >"$APP_REPO_DIR/app.json"
|
||||
{
|
||||
"formation": {
|
||||
"web": {
|
||||
"autoscaling": {
|
||||
"min_quantity": 1,
|
||||
"max_quantity": 3,
|
||||
"triggers": [
|
||||
{
|
||||
"name": "prom-trigger",
|
||||
"type": "prometheus",
|
||||
"metadata": {
|
||||
"serverAddress": "http://prometheus.example.com:9090",
|
||||
"metricName": "http_requests_total",
|
||||
"threshold": "100",
|
||||
"query": "sum(rate(http_requests_total{deployment=\"[[ .DEPLOYMENT_NAME ]]\"}[2m]))"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
147
tests/unit/scheduler-k3s-5.bats
Normal file
147
tests/unit/scheduler-k3s-5.bats
Normal file
@@ -0,0 +1,147 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
TEST_APP="rdmtestapp"
|
||||
|
||||
setup() {
|
||||
uninstall_k3s || true
|
||||
global_setup
|
||||
dokku nginx:stop
|
||||
export KUBECONFIG="/etc/rancher/k3s/k3s.yaml"
|
||||
}
|
||||
|
||||
teardown() {
|
||||
dokku scheduler-k3s:node-sysctls:set --global vm.max_map_count || true
|
||||
global_teardown
|
||||
dokku nginx:start
|
||||
uninstall_k3s || true
|
||||
}
|
||||
|
||||
@test "(scheduler-k3s) docker-options sysctl" {
|
||||
if [[ -z "$DOCKERHUB_USERNAME" ]] || [[ -z "$DOCKERHUB_TOKEN" ]]; then
|
||||
skip "skipping due to missing docker.io credentials DOCKERHUB_USERNAME:DOCKERHUB_TOKEN"
|
||||
fi
|
||||
|
||||
INGRESS_CLASS=nginx install_k3s
|
||||
|
||||
run /bin/bash -c "dokku apps:create $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run deploy_app python dokku@$DOKKU_DOMAIN:$TEST_APP
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "kubectl get deployment $TEST_APP-web -o json | jq -r '.spec.template.spec.securityContext.sysctls'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "null"
|
||||
|
||||
run /bin/bash -c "dokku docker-options:add $TEST_APP deploy '--sysctl net.ipv4.ip_unprivileged_port_start=1024'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku ps:restart $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "kubectl get deployment $TEST_APP-web -o json | jq -r '.spec.template.spec.securityContext.sysctls[0].name'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "net.ipv4.ip_unprivileged_port_start"
|
||||
|
||||
run /bin/bash -c "kubectl get deployment $TEST_APP-web -o json | jq -r '.spec.template.spec.securityContext.sysctls[0].value'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "1024"
|
||||
|
||||
run /bin/bash -c "dokku docker-options:remove $TEST_APP deploy '--sysctl net.ipv4.ip_unprivileged_port_start=1024'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku docker-options:add $TEST_APP deploy '--sysctl vm.max_map_count=262144'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku ps:restart $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output_contains "is not namespaced" -1
|
||||
}
|
||||
|
||||
@test "(scheduler-k3s:node-sysctls) applies non-namespaced sysctls to nodes" {
|
||||
if [[ -z "$DOCKERHUB_USERNAME" ]] || [[ -z "$DOCKERHUB_TOKEN" ]]; then
|
||||
skip "skipping due to missing docker.io credentials DOCKERHUB_USERNAME:DOCKERHUB_TOKEN"
|
||||
fi
|
||||
|
||||
INGRESS_CLASS=nginx install_k3s
|
||||
|
||||
run /bin/bash -c "kubectl get daemonset -n kube-system dokku-node-sysctls-global"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
|
||||
run /bin/bash -c "dokku scheduler-k3s:node-sysctls:set --global vm.max_map_count 262144"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku scheduler-k3s:node-sysctls:report --format json | jq -r '.\"--global\".\"vm.max_map_count\"'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "262144"
|
||||
|
||||
run /bin/bash -c "kubectl rollout status daemonset -n kube-system dokku-node-sysctls-global --timeout=120s"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "kubectl get daemonset -n kube-system dokku-node-sysctls-global -o json | jq -r '.status.desiredNumberScheduled'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "$(kubectl get nodes --no-headers | wc -l | tr -d ' ')"
|
||||
|
||||
run /bin/bash -c "cat /proc/sys/vm/max_map_count"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "262144"
|
||||
|
||||
run /bin/bash -c "dokku scheduler-k3s:node-sysctls:set --global vm.max_map_count"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run wait_for_daemonset_deletion dokku-node-sysctls-global
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
}
|
||||
|
||||
wait_for_daemonset_deletion() {
|
||||
declare desc="waits for a daemonset to be removed from the api server"
|
||||
declare NAME="$1"
|
||||
|
||||
for _ in $(seq 1 30); do
|
||||
if ! kubectl get daemonset -n kube-system "$NAME" >/dev/null 2>&1; then
|
||||
return 0
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
|
||||
echo "daemonset $NAME still exists after 60s"
|
||||
return 1
|
||||
}
|
||||
115
tests/unit/scheduler-k3s-annotations.bats
Normal file
115
tests/unit/scheduler-k3s-annotations.bats
Normal file
@@ -0,0 +1,115 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
setup() {
|
||||
global_setup
|
||||
dokku apps:create $TEST_APP >/dev/null 2>/dev/null || true
|
||||
}
|
||||
|
||||
teardown() {
|
||||
dokku --force apps:destroy $TEST_APP >/dev/null 2>/dev/null || true
|
||||
dokku --force apps:destroy ${TEST_APP}-2 >/dev/null 2>/dev/null || true
|
||||
for resource in deployment service pod cronjob job secret ingress serviceaccount; do
|
||||
dokku scheduler-k3s:annotations:set --global --resource-type "$resource" foo "" >/dev/null 2>/dev/null || true
|
||||
dokku scheduler-k3s:annotations:set --global --resource-type "$resource" bar "" >/dev/null 2>/dev/null || true
|
||||
done
|
||||
global_teardown
|
||||
}
|
||||
|
||||
@test "(scheduler-k3s:annotations:report) lists annotations after set, clears them after unset" {
|
||||
run /bin/bash -c "dokku scheduler-k3s:annotations:set $TEST_APP --resource-type deployment foo bar"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku scheduler-k3s:annotations:report $TEST_APP --format json | jq -r '.\"global.deployment.foo\"'"
|
||||
assert_success
|
||||
assert_output "bar"
|
||||
|
||||
run /bin/bash -c "dokku scheduler-k3s:annotations:report $TEST_APP"
|
||||
assert_success
|
||||
assert_output_contains "$TEST_APP annotations information"
|
||||
assert_output_contains "Annotation (global/deployment) foo:"
|
||||
assert_output_contains "bar"
|
||||
|
||||
run /bin/bash -c "dokku scheduler-k3s:annotations:report $TEST_APP --scheduler-k3s-annotations.global.deployment.foo"
|
||||
assert_success
|
||||
assert_output "bar"
|
||||
|
||||
run /bin/bash -c "dokku scheduler-k3s:annotations:set $TEST_APP --resource-type deployment foo"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku scheduler-k3s:annotations:report $TEST_APP --format json"
|
||||
assert_success
|
||||
assert_output "{}"
|
||||
}
|
||||
|
||||
@test "(scheduler-k3s:annotations:report) honours --process-type and --resource-type filters" {
|
||||
run /bin/bash -c "dokku scheduler-k3s:annotations:set $TEST_APP --resource-type deployment foo bar"
|
||||
assert_success
|
||||
run /bin/bash -c "dokku scheduler-k3s:annotations:set $TEST_APP --process-type web --resource-type deployment baz qux"
|
||||
assert_success
|
||||
run /bin/bash -c "dokku scheduler-k3s:annotations:set $TEST_APP --resource-type service alpha beta"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku scheduler-k3s:annotations:report $TEST_APP --resource-type deployment --format json | jq -r 'keys | sort | join(\",\")'"
|
||||
assert_success
|
||||
assert_output "global.deployment.foo,web.deployment.baz"
|
||||
|
||||
run /bin/bash -c "dokku scheduler-k3s:annotations:report $TEST_APP --process-type web --format json | jq -r 'keys | sort | join(\",\")'"
|
||||
assert_success
|
||||
assert_output "web.deployment.baz"
|
||||
|
||||
run /bin/bash -c "dokku scheduler-k3s:annotations:report $TEST_APP --process-type web --resource-type deployment --format json | jq -r '.\"web.deployment.baz\"'"
|
||||
assert_success
|
||||
assert_output "qux"
|
||||
}
|
||||
|
||||
@test "(scheduler-k3s:annotations:report) supports --global scope and no-arg multi-app loop" {
|
||||
run /bin/bash -c "dokku apps:create ${TEST_APP}-2"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku scheduler-k3s:annotations:set --global --resource-type deployment foo global-val"
|
||||
assert_success
|
||||
run /bin/bash -c "dokku scheduler-k3s:annotations:set $TEST_APP --resource-type deployment foo app1-val"
|
||||
assert_success
|
||||
run /bin/bash -c "dokku scheduler-k3s:annotations:set ${TEST_APP}-2 --resource-type deployment bar app2-val"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku scheduler-k3s:annotations:report --global --format json | jq -r '.\"global.deployment.foo\"'"
|
||||
assert_success
|
||||
assert_output "global-val"
|
||||
|
||||
run /bin/bash -c "dokku scheduler-k3s:annotations:report"
|
||||
assert_success
|
||||
assert_output_contains "$TEST_APP annotations information"
|
||||
assert_output_contains "${TEST_APP}-2 annotations information"
|
||||
assert_output_contains "app1-val"
|
||||
assert_output_contains "app2-val"
|
||||
}
|
||||
|
||||
@test "(scheduler-k3s:annotations:set) preserves multi-line values and / in keys" {
|
||||
local value=$'line one\nline two\nline three'
|
||||
run /bin/bash -c "dokku scheduler-k3s:annotations:set $TEST_APP --resource-type deployment prometheus.io/scrape \"$value\""
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku scheduler-k3s:annotations:report $TEST_APP --format json | jq -r '.\"global.deployment.prometheus.io/scrape\"'"
|
||||
assert_success
|
||||
assert_output "$value"
|
||||
}
|
||||
|
||||
@test "(scheduler-k3s:annotations:report) rejects invalid format and info-flag combinations" {
|
||||
run /bin/bash -c "dokku scheduler-k3s:annotations:report $TEST_APP --format yaml"
|
||||
assert_failure
|
||||
assert_output_contains "Invalid format"
|
||||
|
||||
run /bin/bash -c "dokku scheduler-k3s:annotations:set $TEST_APP --resource-type deployment foo bar"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku scheduler-k3s:annotations:report $TEST_APP --format json --scheduler-k3s-annotations.global.deployment.foo"
|
||||
assert_failure
|
||||
assert_output_contains "--format flag cannot be specified when specifying an info flag"
|
||||
|
||||
run /bin/bash -c "dokku scheduler-k3s:annotations:report $TEST_APP --scheduler-k3s-annotations.global.deployment.missing"
|
||||
assert_failure
|
||||
assert_output_contains "Invalid flag passed"
|
||||
}
|
||||
151
tests/unit/scheduler-k3s-autoscaling-auth.bats
Normal file
151
tests/unit/scheduler-k3s-autoscaling-auth.bats
Normal file
@@ -0,0 +1,151 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
scheduler_k3s_seed_trigger_auth() {
|
||||
local scope="$1"
|
||||
local trigger="$2"
|
||||
local key="$3"
|
||||
local value="$4"
|
||||
local dir="/var/lib/dokku/config/scheduler-k3s/$scope"
|
||||
sudo mkdir -p "$dir"
|
||||
echo -n "$value" | sudo tee "$dir/trigger-auth.${trigger}.${key}" >/dev/null
|
||||
}
|
||||
|
||||
scheduler_k3s_clear_trigger_auth() {
|
||||
local scope="$1"
|
||||
local trigger="$2"
|
||||
sudo rm -f "/var/lib/dokku/config/scheduler-k3s/$scope/trigger-auth.${trigger}."* 2>/dev/null || true
|
||||
}
|
||||
|
||||
setup() {
|
||||
global_setup
|
||||
dokku apps:create $TEST_APP >/dev/null 2>/dev/null || true
|
||||
dokku apps:create ${TEST_APP}-2 >/dev/null 2>/dev/null || true
|
||||
}
|
||||
|
||||
teardown() {
|
||||
dokku scheduler-k3s:autoscaling-auth:set $TEST_APP datadog >/dev/null 2>/dev/null || true
|
||||
dokku scheduler-k3s:autoscaling-auth:set $TEST_APP memory >/dev/null 2>/dev/null || true
|
||||
dokku scheduler-k3s:autoscaling-auth:set ${TEST_APP}-2 datadog >/dev/null 2>/dev/null || true
|
||||
scheduler_k3s_clear_trigger_auth "--global" "datadog"
|
||||
dokku --force apps:destroy $TEST_APP >/dev/null 2>/dev/null || true
|
||||
dokku --force apps:destroy ${TEST_APP}-2 >/dev/null 2>/dev/null || true
|
||||
global_teardown
|
||||
}
|
||||
|
||||
@test "(scheduler-k3s:autoscaling-auth:report) no-arg loops all apps" {
|
||||
run /bin/bash -c "dokku scheduler-k3s:autoscaling-auth:set $TEST_APP datadog --metadata apiKey=secret-1"
|
||||
assert_success
|
||||
run /bin/bash -c "dokku scheduler-k3s:autoscaling-auth:set ${TEST_APP}-2 datadog --metadata apiKey=secret-2"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku scheduler-k3s:autoscaling-auth:report"
|
||||
assert_success
|
||||
assert_output_contains "$TEST_APP autoscaling-auth information"
|
||||
assert_output_contains "${TEST_APP}-2 autoscaling-auth information"
|
||||
assert_output_contains "Datadog:" 2
|
||||
}
|
||||
|
||||
@test "(scheduler-k3s:autoscaling-auth:report) lists metadata in json and clears after unset" {
|
||||
run /bin/bash -c "dokku scheduler-k3s:autoscaling-auth:set $TEST_APP datadog --metadata apiKey=secret-1 --metadata appKey=secret-2"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku scheduler-k3s:autoscaling-auth:report $TEST_APP --format json | jq -r '.\"datadog.apiKey\"'"
|
||||
assert_success
|
||||
assert_output "secret-1"
|
||||
|
||||
run /bin/bash -c "dokku scheduler-k3s:autoscaling-auth:report $TEST_APP --format json | jq -r '.\"datadog.appKey\"'"
|
||||
assert_success
|
||||
assert_output "secret-2"
|
||||
|
||||
run /bin/bash -c "dokku scheduler-k3s:autoscaling-auth:report $TEST_APP --scheduler-k3s-autoscaling-auth.datadog.apiKey"
|
||||
assert_success
|
||||
assert_output "*******"
|
||||
|
||||
run /bin/bash -c "dokku scheduler-k3s:autoscaling-auth:report $TEST_APP"
|
||||
assert_success
|
||||
assert_output_contains "Datadog:"
|
||||
assert_output_not_contains "Datadog apiKey:"
|
||||
assert_output_not_contains "secret-1"
|
||||
assert_output_not_contains "secret-2"
|
||||
|
||||
run /bin/bash -c "dokku scheduler-k3s:autoscaling-auth:report $TEST_APP --include-metadata"
|
||||
assert_success
|
||||
assert_output_contains "Datadog apiKey:"
|
||||
assert_output_contains "secret-1"
|
||||
assert_output_contains "secret-2"
|
||||
|
||||
run /bin/bash -c "dokku scheduler-k3s:autoscaling-auth:set $TEST_APP datadog"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku scheduler-k3s:autoscaling-auth:report $TEST_APP --format json"
|
||||
assert_success
|
||||
assert_output "{}"
|
||||
}
|
||||
|
||||
@test "(scheduler-k3s:autoscaling-auth:report) stdout includes metadata values with --include-metadata" {
|
||||
run /bin/bash -c "dokku scheduler-k3s:autoscaling-auth:set $TEST_APP datadog --metadata apiKey=super-secret-value"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku scheduler-k3s:autoscaling-auth:report $TEST_APP"
|
||||
assert_success
|
||||
assert_output_contains "Datadog:"
|
||||
assert_output_contains "configured"
|
||||
assert_output_not_contains "Datadog apiKey:"
|
||||
assert_output_not_contains "super-secret-value"
|
||||
|
||||
run /bin/bash -c "dokku scheduler-k3s:autoscaling-auth:report $TEST_APP --include-metadata"
|
||||
assert_success
|
||||
assert_output_contains "Datadog apiKey:"
|
||||
assert_output_contains "super-secret-value"
|
||||
}
|
||||
|
||||
@test "(scheduler-k3s:autoscaling-auth:report) reports multiple triggers in json" {
|
||||
run /bin/bash -c "dokku scheduler-k3s:autoscaling-auth:set $TEST_APP datadog --metadata apiKey=secret-1"
|
||||
assert_success
|
||||
run /bin/bash -c "dokku scheduler-k3s:autoscaling-auth:set $TEST_APP memory --metadata some-key=some-value"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku scheduler-k3s:autoscaling-auth:report $TEST_APP --format json | jq -r 'keys | sort | join(\",\")'"
|
||||
assert_success
|
||||
assert_output "datadog.apiKey,memory.some-key"
|
||||
}
|
||||
|
||||
@test "(scheduler-k3s:autoscaling-auth:report) supports --global scope" {
|
||||
scheduler_k3s_seed_trigger_auth "--global" "datadog" "apiKey" "global-secret"
|
||||
|
||||
run /bin/bash -c "dokku scheduler-k3s:autoscaling-auth:report --global --format json | jq -r '.\"datadog.apiKey\"'"
|
||||
assert_success
|
||||
assert_output "global-secret"
|
||||
|
||||
run /bin/bash -c "dokku scheduler-k3s:autoscaling-auth:report --global --include-metadata"
|
||||
assert_success
|
||||
assert_output_contains "--global autoscaling-auth information"
|
||||
assert_output_contains "Datadog:"
|
||||
assert_output_contains "Datadog apiKey:"
|
||||
assert_output_contains "global-secret"
|
||||
}
|
||||
|
||||
@test "(scheduler-k3s:autoscaling-auth:report) returns empty json for unconfigured app" {
|
||||
run /bin/bash -c "dokku scheduler-k3s:autoscaling-auth:report $TEST_APP --format json"
|
||||
assert_success
|
||||
assert_output "{}"
|
||||
}
|
||||
|
||||
@test "(scheduler-k3s:autoscaling-auth:report) rejects invalid format and info-flag combinations" {
|
||||
run /bin/bash -c "dokku scheduler-k3s:autoscaling-auth:report $TEST_APP --format yaml"
|
||||
assert_failure
|
||||
assert_output_contains "Invalid format"
|
||||
|
||||
run /bin/bash -c "dokku scheduler-k3s:autoscaling-auth:set $TEST_APP datadog --metadata apiKey=secret-1"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku scheduler-k3s:autoscaling-auth:report $TEST_APP --format json --scheduler-k3s-autoscaling-auth.datadog.apiKey"
|
||||
assert_failure
|
||||
assert_output_contains "--format flag cannot be specified when specifying an info flag"
|
||||
|
||||
run /bin/bash -c "dokku scheduler-k3s:autoscaling-auth:report $TEST_APP --scheduler-k3s-autoscaling-auth.datadog.missing"
|
||||
assert_failure
|
||||
assert_output_contains "Invalid flag passed"
|
||||
}
|
||||
207
tests/unit/scheduler-k3s-certs-deploy-2.bats
Normal file
207
tests/unit/scheduler-k3s-certs-deploy-2.bats
Normal file
@@ -0,0 +1,207 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
TEST_APP="rdmtestapp"
|
||||
|
||||
setup() {
|
||||
uninstall_k3s || true
|
||||
global_setup
|
||||
dokku nginx:stop
|
||||
export KUBECONFIG="/etc/rancher/k3s/k3s.yaml"
|
||||
}
|
||||
|
||||
teardown() {
|
||||
dokku scheduler-k3s:set --global cert-issuer-name >/dev/null 2>/dev/null || true
|
||||
global_teardown
|
||||
dokku nginx:start
|
||||
uninstall_k3s || true
|
||||
}
|
||||
|
||||
@test "(scheduler-k3s:certs) app-level letsencrypt email renders a per-app namespaced Issuer" {
|
||||
if [[ -z "$DOCKERHUB_USERNAME" ]] || [[ -z "$DOCKERHUB_TOKEN" ]]; then
|
||||
skip "skipping due to missing docker.io credentials DOCKERHUB_USERNAME:DOCKERHUB_TOKEN"
|
||||
fi
|
||||
|
||||
INGRESS_CLASS=nginx install_k3s
|
||||
|
||||
run /bin/bash -c "dokku apps:create $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku scheduler-k3s:set $TEST_APP letsencrypt-server staging"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku scheduler-k3s:set $TEST_APP letsencrypt-email-stag app@dokku.me"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku domains:set $TEST_APP $TEST_APP.dokku.me"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run deploy_app python "dokku@$DOKKU_DOMAIN:$TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "sleep 30"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "kubectl get certificate ${TEST_APP}-web -n default -o jsonpath='{.spec.issuerRef.kind}'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "Issuer"
|
||||
|
||||
run /bin/bash -c "kubectl get certificate ${TEST_APP}-web -n default -o jsonpath='{.spec.issuerRef.name}'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "${TEST_APP}-letsencrypt-stag"
|
||||
|
||||
run /bin/bash -c "kubectl get issuer ${TEST_APP}-letsencrypt-stag -n default -o jsonpath='{.spec.acme.email}'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "app@dokku.me"
|
||||
}
|
||||
|
||||
@test "(scheduler-k3s:certs) a manually managed cert issuer issues the app certificate" {
|
||||
if [[ -z "$DOCKERHUB_USERNAME" ]] || [[ -z "$DOCKERHUB_TOKEN" ]]; then
|
||||
skip "skipping due to missing docker.io credentials DOCKERHUB_USERNAME:DOCKERHUB_TOKEN"
|
||||
fi
|
||||
|
||||
INGRESS_CLASS=nginx install_k3s
|
||||
|
||||
run /bin/bash -c "dokku apps:create $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku domains:set $TEST_APP $TEST_APP.dokku.me"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
# no letsencrypt email is ever set, so tls is enabled purely by cert-issuer-name
|
||||
run /bin/bash -c "dokku scheduler-k3s:set $TEST_APP cert-issuer-name dokku-test-selfsigned"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku scheduler-k3s:preview $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "ClusterIssuer dokku-test-selfsigned not found"
|
||||
|
||||
create_selfsigned_cluster_issuer
|
||||
|
||||
run deploy_app python "dokku@$DOKKU_DOMAIN:$TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "kubectl get certificate ${TEST_APP}-web -n default -o jsonpath='{.spec.issuerRef.kind}'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "ClusterIssuer"
|
||||
|
||||
run /bin/bash -c "kubectl get certificate ${TEST_APP}-web -n default -o jsonpath='{.spec.issuerRef.name}'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "dokku-test-selfsigned"
|
||||
|
||||
# a selfSigned issuer issues immediately, so the secret proves end-to-end issuance
|
||||
run /bin/bash -c "kubectl wait --for=condition=Ready certificate/${TEST_APP}-web -n default --timeout=120s"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "kubectl get secret tls-${TEST_APP}-web -n default -o jsonpath='{.type}'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "kubernetes.io/tls"
|
||||
|
||||
run /bin/bash -c "kubectl get ingress ${TEST_APP}-web-${TEST_APP}-dokku-me -n default -o jsonpath='{.spec.tls[0].secretName}'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "tls-${TEST_APP}-web"
|
||||
}
|
||||
|
||||
@test "(scheduler-k3s:certs) letsencrypt-server false disables a global cert issuer" {
|
||||
if [[ -z "$DOCKERHUB_USERNAME" ]] || [[ -z "$DOCKERHUB_TOKEN" ]]; then
|
||||
skip "skipping due to missing docker.io credentials DOCKERHUB_USERNAME:DOCKERHUB_TOKEN"
|
||||
fi
|
||||
|
||||
INGRESS_CLASS=nginx install_k3s
|
||||
|
||||
create_selfsigned_cluster_issuer
|
||||
|
||||
run /bin/bash -c "dokku scheduler-k3s:set --global cert-issuer-name dokku-test-selfsigned"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku apps:create $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku scheduler-k3s:set $TEST_APP letsencrypt-server false"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku domains:set $TEST_APP $TEST_APP.dokku.me"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run deploy_app python "dokku@$DOKKU_DOMAIN:$TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "kubectl get certificate ${TEST_APP}-web -n default"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
|
||||
run /bin/bash -c "kubectl get ingress ${TEST_APP}-web-${TEST_APP}-dokku-me -n default -o jsonpath='{.spec.tls}'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output ""
|
||||
}
|
||||
|
||||
create_selfsigned_cluster_issuer() {
|
||||
declare desc="creates a selfSigned ClusterIssuer that issues certificates without acme"
|
||||
|
||||
local manifest="${BATS_TMPDIR:-/tmp}/dokku-test-selfsigned.yaml"
|
||||
cat >"$manifest" <<'EOF'
|
||||
apiVersion: cert-manager.io/v1
|
||||
kind: ClusterIssuer
|
||||
metadata:
|
||||
name: dokku-test-selfsigned
|
||||
spec:
|
||||
selfSigned: {}
|
||||
EOF
|
||||
|
||||
run /bin/bash -c "kubectl apply -f $manifest"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user