Add tests for nginx.conf directives (#1)
Adds tests to make sure all the `nginx.conf` directives (the redirects and rewrites and such) are all correct. - Uses the `busted` framework - The tests are run in a Docker container by the bash script `test.sh` - Self-signed certs are generated in `Dockerfile` for all the domain names - Adds new `Makefile` commands: `test`, `image-build` and `image-rm` Reviewed-on: #1 Co-authored-by: Catalin Mititiuc <webdevcat@proton.me> Co-committed-by: Catalin Mititiuc <webdevcat@proton.me>
This commit is contained in:
parent
dec9e4b5ea
commit
85fba54152
24
Dockerfile
24
Dockerfile
@ -1,4 +1,4 @@
|
|||||||
FROM openresty/openresty:1.27.1.2-0-bookworm-buildpack
|
FROM openresty/openresty:bookworm-buildpack
|
||||||
|
|
||||||
WORKDIR /opt/app
|
WORKDIR /opt/app
|
||||||
|
|
||||||
@ -11,7 +11,27 @@ RUN apt-get update && apt-get install -y \
|
|||||||
wget -q -O $pkgname $pkgurl && dpkg -i $pkgname && rm $pkgname
|
wget -q -O $pkgname $pkgurl && dpkg -i $pkgname && rm $pkgname
|
||||||
|
|
||||||
RUN luarocks install sitegen
|
RUN luarocks install sitegen
|
||||||
RUN luarocks install busted
|
|
||||||
|
# needed for sitegen watcher
|
||||||
RUN luarocks install inotify INOTIFY_INCDIR=/usr/include/x86_64-linux-gnu/
|
RUN luarocks install inotify INOTIFY_INCDIR=/usr/include/x86_64-linux-gnu/
|
||||||
|
|
||||||
|
# needed for testing
|
||||||
|
RUN luarocks install busted
|
||||||
|
RUN luarocks install luajit-curl
|
||||||
|
RUN luarocks install luasocket # needed for testing nginx reverse proxy
|
||||||
|
|
||||||
|
RUN mkdir -p /var/www/certs/miti.sh \
|
||||||
|
&& openssl req -x509 -newkey rsa:4096 -nodes \
|
||||||
|
-keyout /var/www/certs/miti.sh/privkey.pem \
|
||||||
|
-out /var/www/certs/miti.sh/fullchain.pem \
|
||||||
|
-sha256 -days 365 -subj '/CN=miti.sh' \
|
||||||
|
-addext "subjectAltName=DNS:miti.sh,DNS:git.miti.sh,DNS:apps.miti.sh"
|
||||||
|
|
||||||
|
RUN mkdir -p /var/www/certs/webdevcat.me \
|
||||||
|
&& openssl req -x509 -newkey rsa:4096 -nodes \
|
||||||
|
-keyout /var/www/certs/webdevcat.me/privkey.pem \
|
||||||
|
-out /var/www/certs/webdevcat.me/fullchain.pem \
|
||||||
|
-sha256 -days 365 -subj '/CN=webdevcat.me' \
|
||||||
|
-addext "subjectAltName=DNS:webdevcat.me,DNS:git.webdevcat.me,DNS:apps.webdevcat.me"
|
||||||
|
|
||||||
CMD ["sh", "-c", "openresty -p `pwd` -g 'daemon off;'"]
|
CMD ["sh", "-c", "openresty -p `pwd` -g 'daemon off;'"]
|
||||||
|
18
Makefile
18
Makefile
@ -1,9 +1,19 @@
|
|||||||
|
image = miti.sh
|
||||||
|
|
||||||
run:
|
run:
|
||||||
docker run --rm -it --init -v $(PWD):/opt/app -p 8080:8080 \
|
docker run --rm -it --init -v $(PWD):/opt/app -p 8080:80 $(image)
|
||||||
sitegen-openresty
|
|
||||||
|
|
||||||
build:
|
build:
|
||||||
docker run --rm -w /opt/app -v $(PWD):/opt/app sitegen-openresty sitegen
|
docker run --rm -w /opt/app -v $(PWD):/opt/app $(image) sitegen
|
||||||
|
|
||||||
|
image-rm:
|
||||||
|
docker image rm $(image):latest
|
||||||
|
|
||||||
|
image-build:
|
||||||
|
docker build -t $(image) .
|
||||||
|
|
||||||
lint:
|
lint:
|
||||||
docker run --rm -w /opt/app -v $(PWD):/opt/app sitegen-openresty moonc -l .
|
docker run --rm -w /opt/app -v $(PWD):/opt/app $(image) moonc -l .
|
||||||
|
|
||||||
|
test:
|
||||||
|
./test.sh
|
||||||
|
27
README.md
27
README.md
@ -15,15 +15,19 @@
|
|||||||
|
|
||||||
### build docker image
|
### build docker image
|
||||||
|
|
||||||
$ docker build -t sitegen-openresty .
|
$ make image-build
|
||||||
|
|
||||||
|
### rebuild an existing docker image
|
||||||
|
|
||||||
|
$ make image-rm image-build
|
||||||
|
|
||||||
### generate a new site file
|
### generate a new site file
|
||||||
|
|
||||||
$ docker run --rm -w /opt -v $PWD:/opt sitegen-openresty sitegen new
|
$ docker run --rm -w /opt/app -v $PWD:/opt/app miti.sh sitegen new
|
||||||
|
|
||||||
### add an index page
|
### add an index page
|
||||||
|
|
||||||
$ docker run --rm -w /opt -v $PWD:/opt sitegen-openresty sitegen page /opt/ index
|
$ docker run --rm -w /opt/app -v $PWD:/opt/app miti.sh sitegen page /opt/app index
|
||||||
|
|
||||||
### add to `site.moon`
|
### add to `site.moon`
|
||||||
|
|
||||||
@ -50,17 +54,9 @@
|
|||||||
|
|
||||||
### build site
|
### build site
|
||||||
|
|
||||||
$ docker run --rm -w /opt/app -v $PWD:/opt/app sitegen-openresty sitegen
|
|
||||||
|
|
||||||
or
|
|
||||||
|
|
||||||
$ make build
|
$ make build
|
||||||
|
|
||||||
### start server
|
### start dev server
|
||||||
|
|
||||||
$ docker run --rm -it --init -v $PWD:/opt/app -p 8080:8080 sitegen-openresty
|
|
||||||
|
|
||||||
or
|
|
||||||
|
|
||||||
$ make
|
$ make
|
||||||
|
|
||||||
@ -70,6 +66,10 @@ Visit `localhost:8080` in web browser
|
|||||||
|
|
||||||
$ docker exec -it container_name sitegen watch
|
$ docker exec -it container_name sitegen watch
|
||||||
|
|
||||||
|
### run tests
|
||||||
|
|
||||||
|
$ make test
|
||||||
|
|
||||||
### lint moonscript
|
### lint moonscript
|
||||||
|
|
||||||
$ make lint
|
$ make lint
|
||||||
@ -100,8 +100,7 @@ to return `nil`, you will see this cryptic error:
|
|||||||
|
|
||||||
Delete your `.sitegen_cache` file.
|
Delete your `.sitegen_cache` file.
|
||||||
|
|
||||||
## todo
|
## thinking about
|
||||||
|
|
||||||
* draft documents
|
* draft documents
|
||||||
* treesitter highlighting for moonscript
|
* treesitter highlighting for moonscript
|
||||||
* penlight library
|
|
||||||
|
9
app.ini
9
app.ini
@ -21,12 +21,13 @@ ROOT = /var/lib/gitea/data/gitea-repositories
|
|||||||
|
|
||||||
[server]
|
[server]
|
||||||
; SSH_DOMAIN = localhost
|
; SSH_DOMAIN = localhost
|
||||||
SSH_DOMAIN = git.miti.sh
|
|
||||||
; DOMAIN = localhost
|
; DOMAIN = localhost
|
||||||
DOMAIN = git.miti.sh
|
DOMAIN = git.miti.sh
|
||||||
HTTP_PORT = 3000
|
; HTTP_PORT = 3000
|
||||||
; ROOT_URL = http://localhost:3000/
|
PROTOCOL = unix
|
||||||
ROOT_URL = https://git.miti.sh
|
ROOT_URL = https://git.miti.sh/
|
||||||
|
HTTP_ADDR = /run/gitea/gitea.socket
|
||||||
|
LOCAL_ROOT_URL =
|
||||||
APP_DATA_PATH = /var/lib/gitea/data
|
APP_DATA_PATH = /var/lib/gitea/data
|
||||||
DISABLE_SSH = false
|
DISABLE_SSH = false
|
||||||
SSH_PORT = 22
|
SSH_PORT = 22
|
||||||
|
@ -8,6 +8,10 @@ events {
|
|||||||
http {
|
http {
|
||||||
server {
|
server {
|
||||||
listen 80;
|
listen 80;
|
||||||
|
return 301 https://$host$request_uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
listen 443 ssl;
|
listen 443 ssl;
|
||||||
|
|
||||||
include mime.types;
|
include mime.types;
|
||||||
@ -30,7 +34,7 @@ http {
|
|||||||
|
|
||||||
# redirect requests ending in a forward slash
|
# redirect requests ending in a forward slash
|
||||||
location ~ ^/(.+)/$ {
|
location ~ ^/(.+)/$ {
|
||||||
return 302 /$1;
|
return 301 /$1;
|
||||||
}
|
}
|
||||||
|
|
||||||
location /css {
|
location /css {
|
||||||
@ -49,7 +53,7 @@ http {
|
|||||||
|
|
||||||
location / {
|
location / {
|
||||||
client_max_body_size 1024M;
|
client_max_body_size 1024M;
|
||||||
proxy_pass http://localhost:3000;
|
proxy_pass http://unix:/run/gitea/gitea.socket;
|
||||||
proxy_set_header Connection $http_connection;
|
proxy_set_header Connection $http_connection;
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
proxy_set_header Host $host;
|
proxy_set_header Host $host;
|
||||||
@ -93,7 +97,7 @@ http {
|
|||||||
return 301 https://miti.sh$request_uri;
|
return 301 https://miti.sh$request_uri;
|
||||||
}
|
}
|
||||||
|
|
||||||
location ~ ^/git/(.*)$ {
|
location ~ ^/git/?(.*)$ {
|
||||||
return 301 https://git.miti.sh/ccm/$1;
|
return 301 https://git.miti.sh/ccm/$1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,20 +105,32 @@ http {
|
|||||||
return 301 https://apps.miti.sh/$1;
|
return 301 https://apps.miti.sh/$1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
server {
|
server {
|
||||||
listen 443 ssl;
|
listen 443 ssl;
|
||||||
server_name git.webdevcat.me;
|
server_name git.webdevcat.me;
|
||||||
|
|
||||||
location ^~ /.well-known/acme-challenge {
|
ssl_certificate /var/www/certs/webdevcat.me/fullchain.pem;
|
||||||
alias /var/www/dehydrated;
|
ssl_certificate_key /var/www/certs/webdevcat.me/privkey.pem;
|
||||||
}
|
|
||||||
}
|
|
||||||
server {
|
|
||||||
listen 443 ssl;
|
|
||||||
server_name apps.webdevcat.me;
|
|
||||||
|
|
||||||
location ^~ /.well-known/acme-challenge {
|
location ^~ /.well-known/acme-challenge {
|
||||||
alias /var/www/dehydrated;
|
alias /var/www/dehydrated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 301 https://git.miti.sh$request_uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 443 ssl;
|
||||||
|
server_name apps.webdevcat.me;
|
||||||
|
|
||||||
|
ssl_certificate /var/www/certs/webdevcat.me/fullchain.pem;
|
||||||
|
ssl_certificate_key /var/www/certs/webdevcat.me/privkey.pem;
|
||||||
|
|
||||||
|
location ^~ /.well-known/acme-challenge {
|
||||||
|
alias /var/www/dehydrated;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 301 https://apps.miti.sh$request_uri;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
138
spec/nginx_spec.moon
Normal file
138
spec/nginx_spec.moon
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
http = require "luajit-curl-helper.http"
|
||||||
|
index_title = "miti.sh · Catalin Constantin Mititiuc"
|
||||||
|
|
||||||
|
req = (url) ->
|
||||||
|
request = http.init url
|
||||||
|
st = request\perform!
|
||||||
|
error request\lastError! if not st
|
||||||
|
request
|
||||||
|
|
||||||
|
describe "test environment", ->
|
||||||
|
it "can't connect to the internet", ->
|
||||||
|
assert.has_error (-> req "http://example.org"), "Couldn't resolve host name"
|
||||||
|
|
||||||
|
describe "http://miti.sh", ->
|
||||||
|
it "redirects to https", ->
|
||||||
|
request = req "http://miti.sh"
|
||||||
|
assert.same request\statusCode!, 301
|
||||||
|
assert.same request\statusMessage!, "Moved Permanently"
|
||||||
|
assert.same request\header!.Location, "https://miti.sh/"
|
||||||
|
|
||||||
|
describe "https://webdevcat.me", ->
|
||||||
|
it "permanently redirects to https://miti.sh", ->
|
||||||
|
request = req "https://webdevcat.me"
|
||||||
|
assert.same request\statusCode!, 301
|
||||||
|
assert.same request\statusMessage!, "Moved Permanently"
|
||||||
|
assert.same request\header!.Location, "https://miti.sh/"
|
||||||
|
|
||||||
|
describe "https://webdevcat.me/git", ->
|
||||||
|
it "permanently redirects to https://git.miti.sh/ccm/", ->
|
||||||
|
request = req "https://webdevcat.me/git"
|
||||||
|
assert.same request\statusCode!, 301
|
||||||
|
assert.same request\statusMessage!, "Moved Permanently"
|
||||||
|
assert.same request\header!.Location, "https://git.miti.sh/ccm/"
|
||||||
|
|
||||||
|
describe "https://webdevcat.me/git/", ->
|
||||||
|
it "permanently redirects to https://git.miti.sh", ->
|
||||||
|
request = req "https://webdevcat.me/git"
|
||||||
|
assert.same request\statusCode!, 301
|
||||||
|
assert.same request\statusMessage!, "Moved Permanently"
|
||||||
|
assert.same request\header!.Location, "https://git.miti.sh/ccm/"
|
||||||
|
|
||||||
|
describe "https://webdevcat.me/git/pandoc", ->
|
||||||
|
it "permanently redirects to https://git.miti.sh/ccm/pandoc", ->
|
||||||
|
request = req "https://webdevcat.me/git/pandoc"
|
||||||
|
assert.same request\statusCode!, 301
|
||||||
|
assert.same request\statusMessage!, "Moved Permanently"
|
||||||
|
assert.same request\header!.Location, "https://git.miti.sh/ccm/pandoc"
|
||||||
|
|
||||||
|
describe "https://git.webdevcat.me", ->
|
||||||
|
it "permanently redirects to https://git.miti.sh/", ->
|
||||||
|
request = req "https://git.webdevcat.me"
|
||||||
|
assert.same request\statusCode!, 301
|
||||||
|
assert.same request\statusMessage!, "Moved Permanently"
|
||||||
|
assert.same request\header!.Location, "https://git.miti.sh/"
|
||||||
|
|
||||||
|
describe "https://webdevcat.me/apps/btroops", ->
|
||||||
|
it "permanently redirects to https://apps.miti.sh/btroops", ->
|
||||||
|
request = req "https://webdevcat.me/apps/btroops"
|
||||||
|
assert.same request\statusCode!, 301
|
||||||
|
assert.same request\statusMessage!, "Moved Permanently"
|
||||||
|
assert.same request\header!.Location, "https://apps.miti.sh/btroops"
|
||||||
|
|
||||||
|
describe "https://apps.webdevcat.me", ->
|
||||||
|
it "permanently redirects to https://apps.miti.sh/", ->
|
||||||
|
request = req "https://apps.webdevcat.me"
|
||||||
|
assert.same request\statusCode!, 301
|
||||||
|
assert.same request\statusMessage!, "Moved Permanently"
|
||||||
|
assert.same request\header!.Location, "https://apps.miti.sh/"
|
||||||
|
|
||||||
|
describe "https://apps.webdevcat.me/btroops", ->
|
||||||
|
it "permanently redirects to https://apps.miti.sh/btroops", ->
|
||||||
|
request = req "https://apps.webdevcat.me/btroops"
|
||||||
|
assert.same request\statusCode!, 301
|
||||||
|
assert.same request\statusMessage!, "Moved Permanently"
|
||||||
|
assert.same request\header!.Location, "https://apps.miti.sh/btroops"
|
||||||
|
|
||||||
|
describe "https://miti.sh", ->
|
||||||
|
it "sends /index.html", ->
|
||||||
|
request = req "https://miti.sh"
|
||||||
|
assert.same request\statusCode!, 200
|
||||||
|
assert.same request\statusMessage!, "OK"
|
||||||
|
assert.same request\body!\match("<title>(.*)</title>"), index_title
|
||||||
|
|
||||||
|
describe "https://miti.sh/index", ->
|
||||||
|
it "sends /index.html", ->
|
||||||
|
request = req "https://miti.sh/index"
|
||||||
|
assert.same request\statusCode!, 200
|
||||||
|
assert.same request\statusMessage!, "OK"
|
||||||
|
assert.same request\body!\match("<title>(.*)</title>"), index_title
|
||||||
|
|
||||||
|
describe "https://miti.sh/index.html", ->
|
||||||
|
it "sends /index.html", ->
|
||||||
|
request = req "https://miti.sh/index.html"
|
||||||
|
assert.same request\statusCode!, 200
|
||||||
|
assert.same request\statusMessage!, "OK"
|
||||||
|
assert.same request\body!\match("<title>(.*)</title>"), index_title
|
||||||
|
|
||||||
|
describe "https://miti.sh/posts/", ->
|
||||||
|
it "permanently redirects to http://miti.sh/posts", ->
|
||||||
|
request = req "https://miti.sh/posts/"
|
||||||
|
assert.same request\statusCode!, 301
|
||||||
|
assert.same request\statusMessage!, "Moved Permanently"
|
||||||
|
assert.same request\header!.Location, "https://miti.sh/posts"
|
||||||
|
|
||||||
|
describe "https://miti.sh/posts", ->
|
||||||
|
it "sends /posts/index.html", ->
|
||||||
|
request = req "https://miti.sh/posts"
|
||||||
|
assert.same request\statusCode!, 200
|
||||||
|
assert.same request\statusMessage!, "OK"
|
||||||
|
assert.same request\body!\match("<title>(.*)</title>"), "miti.sh · Posts"
|
||||||
|
|
||||||
|
describe "https://git.miti.sh", ->
|
||||||
|
it "reverse-proxies request to a gitea unix socket", ->
|
||||||
|
Path = require "sitegen.path"
|
||||||
|
socket_fname = "unixstreamsrvr.moon"
|
||||||
|
socket_dir = "/run/gitea"
|
||||||
|
socket_owner = "nobody"
|
||||||
|
basepath = Path.basepath debug.getinfo(1).short_src
|
||||||
|
|
||||||
|
Path.exec "install", "-o", socket_owner, "-d", socket_dir
|
||||||
|
cmd = "su -s /bin/bash -c 'moon %s' %s"
|
||||||
|
server = io.popen cmd\format Path.join(basepath, socket_fname), socket_owner
|
||||||
|
Path.exec "sleep", "0.1"
|
||||||
|
result = Path.read_exec "find", socket_dir, "-type", "s", "-ls"
|
||||||
|
assert.truthy result\match "nobody%s+nogroup.+" .. Path.join(socket_dir, "gitea.socket")
|
||||||
|
|
||||||
|
req "https://git.miti.sh"
|
||||||
|
|
||||||
|
reqheader = with server\read "*a"
|
||||||
|
server\close!
|
||||||
|
|
||||||
|
assert.truthy reqheader\match "Host: git.miti.sh"
|
||||||
|
|
||||||
|
describe "https://apps.miti.sh", ->
|
||||||
|
it "doesn't find it", ->
|
||||||
|
request = req "https://apps.miti.sh"
|
||||||
|
assert.same request\statusCode!, 404
|
||||||
|
assert.same request\statusMessage!, "Not Found"
|
14
spec/unixstreamsrvr.moon
Normal file
14
spec/unixstreamsrvr.moon
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
-- modified from
|
||||||
|
-- https://github.com/lunarmodules/luasocket/blob/4844a48fbf76b0400fd7b7e4d15d244484019df1/test/unixstreamsrvr.lua
|
||||||
|
socket = require "socket"
|
||||||
|
socket.unix = require "socket.unix"
|
||||||
|
u = assert socket.unix.stream!
|
||||||
|
assert u\bind "/run/gitea/gitea.socket"
|
||||||
|
assert u\listen!
|
||||||
|
assert u\settimeout 1
|
||||||
|
c = assert u\accept!
|
||||||
|
|
||||||
|
while true
|
||||||
|
m = assert c\receive!
|
||||||
|
break if m == ""
|
||||||
|
print m
|
25
test.sh
Executable file
25
test.sh
Executable file
@ -0,0 +1,25 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
image=miti.sh
|
||||||
|
loopback=127.0.0.1
|
||||||
|
|
||||||
|
# Make sure to create 'no-internet' network, if it doesn't already exist:
|
||||||
|
# $ docker network create --internal no-internet
|
||||||
|
container_id=$(docker run --rm -d -v $(pwd):/opt/app --network no-internet \
|
||||||
|
--add-host=miti.sh=$loopback \
|
||||||
|
--add-host=git.miti.sh=$loopback \
|
||||||
|
--add-host=apps.miti.sh=$loopback \
|
||||||
|
--add-host=webdevcat.me=$loopback \
|
||||||
|
--add-host=git.webdevcat.me=$loopback \
|
||||||
|
--add-host=apps.webdevcat.me=$loopback \
|
||||||
|
$image)
|
||||||
|
|
||||||
|
docker exec -t $container_id busted
|
||||||
|
|
||||||
|
docker exec $container_id openresty -p /opt/app -s stop
|
||||||
|
|
||||||
|
is_running=$(docker inspect -f '{{.State.Running}}' $container_id)
|
||||||
|
|
||||||
|
if [[ $is_running == "true" ]]; then
|
||||||
|
echo "Warning: Docker reports test container is still running"
|
||||||
|
fi
|
Loading…
x
Reference in New Issue
Block a user