Skip to content

Commit

Permalink
Add "tls' feature workflow and basic test (#53)
Browse files Browse the repository at this point in the history
  • Loading branch information
rustworthy authored Feb 11, 2024
1 parent 2aafa79 commit 03f905f
Show file tree
Hide file tree
Showing 13 changed files with 244 additions and 28 deletions.
4 changes: 4 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,7 @@ updates:
update-types:
- "version-update:semver-patch"
- "version-update:semver-minor"
- package-ecosystem: docker
directory: docker
schedule:
interval: weekly
32 changes: 32 additions & 0 deletions .github/workflows/tls.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# This workflow will make use of Faktory put behind NGINX to test
# the crate's tls feature (see docker dir in the project's root)
permissions:
contents: read
on:
push:
branches:
- main
pull_request:
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
name: tls
jobs:
test:
runs-on: ubuntu-latest
name: ubuntu-latest / stable / tls
steps:
- uses: actions/checkout@v4
with:
submodules: true
- name: Launch Faktory behind NGINX
run: docker compose -f docker/compose.yml up -d --build
- name: Install stable
uses: dtolnay/rust-toolchain@stable
- name: cargo generate-lockfile
if: hashFiles('Cargo.lock') == ''
run: cargo generate-lockfile
- name: Run tests
env:
FAKTORY_URL_SECURE: tcp://localhost:17419
run: cargo test --locked --features tls --test tls
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ repository = "https://github.com/jonhoo/faktory-rs.git"
keywords = ["faktory", "api-bindings", "work-server", "job-server"]
categories = ["api-bindings", "asynchronous", "network-programming"]

exclude = [".github", "docker", ".gitignore", "Makefile"]

[features]
default = []
tls = ["native-tls"]
Expand Down
17 changes: 14 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
FAKTORY_HOST=127.0.0.1
FAKTORY_HOST=localhost
FAKTORY_PORT=7419
FAKTORY_PORT_SECURE=17419
FAKTORY_PORT_UI=7420

.PHONY: check
Expand All @@ -26,8 +27,13 @@ faktory:
faktory/kill:
docker stop faktory

README.md: README.tpl src/lib.rs
cargo readme > README.md
.PHONY: faktory/tls
faktory/tls:
docker compose -f docker/compose.yml up -d --build

.PHONY: faktory/tls/kill
faktory/tls/kill:
docker compose -f docker/compose.yml down

.PHONY: test
test:
Expand All @@ -41,6 +47,11 @@ test/doc:
test/e2e:
FAKTORY_URL=tcp://${FAKTORY_HOST}:${FAKTORY_PORT} cargo test --locked --all-features --all-targets

.PHONY: test/e2e/tls
test/e2e/tls:
FAKTORY_URL_SECURE=tcp://${FAKTORY_HOST}:${FAKTORY_PORT_SECURE} \
cargo test --locked --features tls --test tls

.PHONY: test/load
test/load:
cargo run --release --features binaries
Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,6 @@ Please note that setting "FAKTORY_URL" environment variable is required for e2e
Provided you have [make](https://www.gnu.org/software/make/#download) installed and `docker` daemon running,
you can launch a `Faktory` container with `make faktory` command. After that, hit `make test/e2e` to run the end-to-end test suite.
Remove the container with `make faktory/kill`, if it's no longer needed.

To run end-to-end tests for the crate's `tls` feature, ensure you've got the [`compose`](https://docs.docker.com/compose/install/) docker plugin installed.
Run `make faktory/tls` to spin up `Faktory` behind `NGINX` with ssl termination, then run `make test/e2e/tls`. To remove the containers, hit `make faktory/tls/kill`.
25 changes: 0 additions & 25 deletions README.tpl

This file was deleted.

21 changes: 21 additions & 0 deletions docker/certs/faktory.local.crt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
-----BEGIN CERTIFICATE-----
MIIDazCCAlMCFAxQwXkfT4M84/fevISct//qQskRMA0GCSqGSIb3DQEBCwUAMHEx
CzAJBgNVBAYTAlVaMREwDwYDVQQIDAhUYXNoa2VudDERMA8GA1UEBwwIVGFzaGtl
bnQxEzARBgNVBAoMCmZha3RvcnktcnMxEzARBgNVBAsMCmZha3RvcnktcnMxEjAQ
BgNVBAMMCWxvY2FsaG9zdDAgFw0yNDAyMDMyMDI1MDlaGA8zMDA0MDQwNjIwMjUw
OVowcTELMAkGA1UEBhMCVVoxETAPBgNVBAgMCFRhc2hrZW50MREwDwYDVQQHDAhU
YXNoa2VudDETMBEGA1UECgwKZmFrdG9yeS1yczETMBEGA1UECwwKZmFrdG9yeS1y
czESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEA4ektheqTRy+eHn9j22AxGHqtg/elEiZC0UCLX51ysEkhnLLvFlVFtzd7
q+nx1PNiHdH5i/TjdAYrXAZhKU/k2YfrgCyOjm/XxSw7ujXPP+cWOmdRYTexT9o7
Yrg3ZYMniJbbTl8j37dieXHaO7FHAvpww1q/nbQkwD/1WqK1ggQY/OZ38wpUvsws
9LA7shuXdGnjAXunnRGEzZ2EG6T5hYw0PFL+2CHwr0lqNbCur8wu99t4ED9/vfLG
0TWRQwSnApyjHy89rn5Ze3vOiNzcBW778oZxwvzriEmbQQg6RxKE19AlaiV4+n5S
woAi8Ji69BKRUSlxRhW6eX4ABV2eOwIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQDS
EXuIvVx27LyWlIhfY6vwSWqeUoRXmMFpiBNTTvvHQKlJzLlDyn1b+CqHvMdE9RZh
FI5shZkiqtRRTUGVHB4o0ntwCQmWyV/5FQQ6EYs/bHXUcN2vt1XuU7WK4fRafPPu
snYDgg0TmpGvm+J8W64TfJogWqpPsnT4pOF+aNqW88TTs1JUnNFDBQmw2QKBK+AH
+V4zhpCjVXpKtVMTnDWHQfJh4whelD18lU1jPCbzQrRs2hQWQvtzKWi0YCYc1IXl
4E6eIOHRuiUl/mE3p3f2CGJIwxgrMuxN07ncnwVXBPCaVzSLWJHy0G61mFKH5R/7
42EC7S/POk5GtzkMJ5Du
-----END CERTIFICATE-----
28 changes: 28 additions & 0 deletions docker/certs/faktory.local.key
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDh6S2F6pNHL54e
f2PbYDEYeq2D96USJkLRQItfnXKwSSGcsu8WVUW3N3ur6fHU82Id0fmL9ON0Bitc
BmEpT+TZh+uALI6Ob9fFLDu6Nc8/5xY6Z1FhN7FP2jtiuDdlgyeIlttOXyPft2J5
cdo7sUcC+nDDWr+dtCTAP/VaorWCBBj85nfzClS+zCz0sDuyG5d0aeMBe6edEYTN
nYQbpPmFjDQ8Uv7YIfCvSWo1sK6vzC7323gQP3+98sbRNZFDBKcCnKMfLz2ufll7
e86I3NwFbvvyhnHC/OuISZtBCDpHEoTX0CVqJXj6flLCgCLwmLr0EpFRKXFGFbp5
fgAFXZ47AgMBAAECggEAJjyV4G86O1fDbw0HxUdMOAT3nnkJfv9r2sgObwISueS+
5CtjDUgkkyS4cXoY3P7O0hZKoxYxc19h8mMACgKETQ9U3G5uOIyUnEJm35cg+4Ns
/ziijQ5knAvndkeQ1MU0qUlDWEoBI+oBqGWNVwIj70ydTmtrOFGX0NRiflNA3n7q
pJbdRZzKnTxXxRwIRuGA1y6SlBLQ740hVOm56iLtRJ+P0kNErSL8Uhws/X9/0MXH
W8r2JVikNumBZH18MK+wBGulwZBcLurFfv31hbeQ/FnckOJ1OE53rnV+tBrZN7Ap
6eR4IMcVPfunnGX+meEUnJfmC0HrdQXucDB8Ey/biQKBgQDygP0JeUKpSWX2uSfV
2c8N0opmC2uHswOhf+H9TOyA4DO5NmlbOqVv+uUwRQvIkoen8XNMCPOyoK7WZNAB
hfyU+ck3HDIBqHbGBisUXDNLgIQIhWVznYK0QC+YYr+rEmFun0sMriuhZsU1q2mW
VoAPSTJhaufRb0TKib9Tarzg4wKBgQDue8jk0tbK5xL9dcyn1CxHtDAbfyQfQnSd
G+GcQDDCamgbKI042A5lPSToYEOpSMTOn/n5CmezsSMFnwuwZAgQ1Pbd3YeknBCi
6jWzqYcC11u3EeX9YPJgEDZq0uSWNZg0phDBsu+PYq7vDAriCsMeQrLMvQb0Fs3n
Pp4vVzSEyQKBgQCb+h1G/6jBzAT6WYNmyE6mPFpqYkQKpzjZorCPxO+FwS9jnLzN
Qf5w9TZ/Apoeqyj3+5RGPqfIqBNssLEdmbmpdLRYbxk2+c1Td1o0IU2Y7ZN/C5YC
dDhCidpTMIjJluv2RBz4jfpgOQL1j0g9u2to6ZKvGBz9F41unITkOY49MwKBgEzk
1qqJHL6BcQsOT3WRoNFh1N0YyoHVwJnjooPp4o7dFkIjeh1o9INKCrtuRoKvtt1U
kZnt8+/pXnxygqdWKY+byxlQU2sM8wREdho+wAx3edf2Smy/NIcq0xDwfMm98ByR
qvd5hWp7DCKBhITLqYv5P4NqM3LCY5N7CjADcyiZAoGBALXXR5WSHLjtzaN4Eeti
pWur1VN30HiM2zRTXwTxx6X7y/FI5xzoCVAJb6tSpC/aXzFx05Xa/LyhDXI2sbhm
G3a4tjBRrief5z8XQ7gdBSiyRtLc1XFy3kmeN2HTPMWSIrbk56xyEOqbXov5S+41
hWwNT3lodEZ2ymFWEZHHAvhb
-----END PRIVATE KEY-----
24 changes: 24 additions & 0 deletions docker/compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Since `dependabot` does not yet support `compose` files,
# we are using "proxy" dockerfiles, as per instructions:
# https://github.com/dependabot/dependabot-core/issues/390#issuecomment-1062170379

services:
faktory:
build:
context: .
dockerfile: faktory.Dockerfile
command: "/faktory -b :7419 -w :7420"
nginx:
depends_on:
- faktory
build:
context: .
dockerfile: nginx.Dockerfile
ports:
- "127.0.0.1:7419:7419"
- "127.0.0.1:7420:7420"
- "127.0.0.1:17419:17419"
- "127.0.0.1:17420:17420"
volumes:
- ./nginx:/etc/nginx:ro
- ./certs:/etc/ssl/certs:ro
1 change: 1 addition & 0 deletions docker/faktory.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
FROM contribsys/faktory:1.8.0
1 change: 1 addition & 0 deletions docker/nginx.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
FROM nginx:1.25-alpine
37 changes: 37 additions & 0 deletions docker/nginx/nginx.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
worker_processes 4;

stream {
server {
listen 7419 reuseport;
proxy_pass faktory:7419;
}

server {
listen 17419 ssl reuseport;
ssl_certificate /etc/ssl/certs/faktory.local.crt;
ssl_certificate_key /etc/ssl/certs/faktory.local.key;
proxy_pass faktory:7419;
}
}

http {
server {
listen 7420 reuseport;
location / {
proxy_pass http://faktory:7420;
}
}

server {
listen 17420 ssl reuseport;
ssl_certificate /etc/ssl/certs/faktory.local.crt;
ssl_certificate_key /etc/ssl/certs/faktory.local.key;
location / {
proxy_pass http://faktory:7420;
}
}
}

events {
worker_connections 1024;
}
77 changes: 77 additions & 0 deletions tests/tls.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
extern crate faktory;
extern crate serde_json;
extern crate url;

use faktory::*;
use serde_json::Value;
use std::{env, fs, io, sync};

#[test]
#[cfg(feature = "tls")]
fn roundtrip_tls() {
use native_tls::{Certificate, TlsConnector};

// We are utilizing the fact that the "FAKTORY_URL_SECURE" environment variable is set
// as an indicator that the integration test can and should be performed.
//
// In case the variable is not set we are returning early. This will show `test <test name> ... ok`
// in the test run output, which is admittedly confusing. Ideally, we would like to be able to decorate
// a test with a macro and to see something like `test <test name> ... skipped due to <reason>`, in case
// the test has been skipped, but it is currently not "natively" supported.
//
// See: https://github.com/rust-lang/rust/issues/68007
if env::var_os("FAKTORY_URL_SECURE").is_none() {
return;
}

let local = "roundtrip_tls";

let (tx, rx) = sync::mpsc::channel();
let tx = sync::Arc::new(sync::Mutex::new(tx));
let mut c = ConsumerBuilder::default();
c.hostname("tester".to_string()).wid(local.to_string());
{
let tx = sync::Arc::clone(&tx);
c.register(local, move |j| -> io::Result<()> {
tx.lock().unwrap().send(j).unwrap();
Ok(())
});
}

let cert_path = env::current_dir()
.unwrap()
.join("docker")
.join("certs")
.join("faktory.local.crt");
let cert = fs::read_to_string(cert_path).unwrap();

let tls = || {
let connector = if cfg!(target_os = "macos") {
TlsConnector::builder()
// Danger! Only for testing!
// On the macos CI runner, the certs are not trusted:
// { code: -67843, message: "The certificate was not trusted." }
.danger_accept_invalid_certs(true)
.build()
.unwrap()
} else {
let cert = Certificate::from_pem(cert.as_bytes()).unwrap();
TlsConnector::builder()
.add_root_certificate(cert)
.build()
.unwrap()
};
TlsStream::with_connector(connector, Some(&env::var("FAKTORY_URL_SECURE").unwrap()))
.unwrap()
};
let mut c = c.connect_with(tls(), None).unwrap();
let mut p = Producer::connect_with(tls(), None).unwrap();
p.enqueue(Job::new(local, vec!["z"]).on_queue(local))
.unwrap();
c.run_one(0, &[local]).unwrap();

let job = rx.recv().unwrap();
assert_eq!(job.queue, local);
assert_eq!(job.kind(), local);
assert_eq!(job.args(), &[Value::from("z")]);
}

0 comments on commit 03f905f

Please sign in to comment.