Skip to content

Commit 48eab19

Browse files
committed
Add basic testing of haproxy
This covers both front- and back-end TLS. The back-end server is `openssl s_server`. We also test the front-end separately using the stats interface, to reduce the number of things tested at once.
1 parent 29ee4f8 commit 48eab19

3 files changed

Lines changed: 129 additions & 6 deletions

File tree

.github/workflows/libssl.yaml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ jobs:
3232
with:
3333
persist-credentials: false
3434

35-
- name: Install build dependencies
36-
run: sudo apt-get update && sudo apt-get install -y openssl libssl3 libssl-dev lld
35+
- name: Install build + integration test dependencies
36+
run: sudo apt-get update && sudo apt-get install -y openssl libssl3 libssl-dev lld haproxy
3737

3838
- name: Install ${{ matrix.rust }} toolchain
3939
uses: dtolnay/rust-toolchain@master
@@ -68,8 +68,8 @@ jobs:
6868
uses: dtolnay/rust-toolchain@stable
6969
- name: Install valgrind
7070
run: sudo apt-get update && sudo apt-get install -y valgrind
71-
- name: Install build dependencies
72-
run: sudo apt-get update && sudo apt-get install -y openssl libssl3 libssl-dev lld
71+
- name: Install build + integration test dependencies
72+
run: sudo apt-get update && sudo apt-get install -y openssl libssl3 libssl-dev lld haproxy
7373
- run: VALGRIND="valgrind -q" make PROFILE=release test integration
7474

7575
docs:
@@ -81,8 +81,8 @@ jobs:
8181
with:
8282
persist-credentials: false
8383

84-
- name: Install build dependencies
85-
run: sudo apt-get update && sudo apt-get install -y openssl libssl3 libssl-dev lld
84+
- name: Install build + integration test dependencies
85+
run: sudo apt-get update && sudo apt-get install -y openssl libssl3 libssl-dev lld haproxy
8686

8787
- name: Install rust toolchain
8888
uses: dtolnay/rust-toolchain@nightly

tests/haproxy.conf

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
frontend f
2+
bind :9443 ssl crt "test-ca/rsa/server.both"
3+
stats enable
4+
stats uri /monitor
5+
stats refresh 5s
6+
mode http
7+
timeout client 10s
8+
default_backend b
9+
10+
backend b
11+
mode http
12+
timeout connect 10s
13+
timeout server 10s
14+
balance roundrobin
15+
server s1 localhost:10443 ssl ca-file "test-ca/ecdsa-p256/ca.cert"

tests/runner.rs

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -781,6 +781,114 @@ fn nginx_version() -> (u32, u32) {
781781
)
782782
}
783783

784+
#[test]
785+
#[ignore]
786+
fn haproxy() {
787+
fs::write(
788+
"test-ca/rsa/server.both",
789+
(fs::read_to_string("test-ca/rsa/server.key").unwrap()
790+
+ &fs::read_to_string("test-ca/rsa/server.cert").unwrap())
791+
.as_bytes(),
792+
)
793+
.unwrap();
794+
795+
let mut haproxy_server = KillOnDrop(Some(
796+
Command::new("tests/maybe-valgrind.sh")
797+
.args(["haproxy", "-VVV", "-dv", "--", "tests/haproxy.conf"])
798+
.stdout(Stdio::piped())
799+
.stderr(Stdio::piped())
800+
.spawn()
801+
.unwrap(),
802+
));
803+
wait_for_port(9443);
804+
805+
// Check front-end TLS works via status monitor
806+
assert!(Command::new("curl")
807+
.env("LD_LIBRARY_PATH", "")
808+
.args([
809+
"-s",
810+
"--cacert",
811+
"test-ca/rsa/ca.cert",
812+
"https://localhost:9443/monitor"
813+
])
814+
.stdout(Stdio::piped())
815+
.status()
816+
.unwrap()
817+
.success());
818+
819+
// Run backend server and check haproxy can connect
820+
let backend = KillOnDrop(Some(
821+
Command::new("openssl")
822+
.env("LD_LIBRARY_PATH", "")
823+
.args([
824+
"s_server",
825+
"-cert",
826+
"test-ca/ecdsa-p256/server.cert",
827+
"-key",
828+
"test-ca/ecdsa-p256/server.key",
829+
"-accept",
830+
"localhost:10443",
831+
"-www",
832+
])
833+
.stdout(Stdio::piped())
834+
.spawn()
835+
.expect("failed to start openssl s_server"),
836+
));
837+
wait_for_port(10443);
838+
839+
// Check frontend & backend TLS works
840+
assert!(String::from_utf8(
841+
Command::new("curl")
842+
.env("LD_LIBRARY_PATH", "")
843+
.args([
844+
"-s",
845+
"--cacert",
846+
"test-ca/rsa/ca.cert",
847+
"https://localhost:9443/",
848+
])
849+
.stdout(Stdio::piped())
850+
.output()
851+
.map(print_output)
852+
.unwrap()
853+
.stdout
854+
.clone(),
855+
)
856+
.expect("stdout contained invalid utf8")
857+
.contains("Ciphers common between both SSL end points:"));
858+
859+
// And check it was actually talking to the backend
860+
drop(backend);
861+
assert!(String::from_utf8(
862+
Command::new("curl")
863+
.env("LD_LIBRARY_PATH", "")
864+
.args([
865+
"-s",
866+
"--cacert",
867+
"test-ca/rsa/ca.cert",
868+
"https://localhost:9443/",
869+
])
870+
.stdout(Stdio::piped())
871+
.output()
872+
.map(print_output)
873+
.unwrap()
874+
.stdout
875+
.clone()
876+
)
877+
.expect("stdout contained invalid utf8")
878+
.contains("503 Service Unavailable"));
879+
880+
// evaluate errors output by haproxy to stderr.
881+
let mut child = haproxy_server.take_inner();
882+
child.kill().unwrap();
883+
let output = child.wait_with_output().unwrap();
884+
let output = print_output(output);
885+
let stderr =
886+
String::from_utf8(output.stderr.clone()).expect("haproxy stderr is not valid utf8");
887+
888+
// eventually we will want there to be zero of these.
889+
assert!(stderr.matches("OpenSSL error").count() > 0);
890+
}
891+
784892
struct KillOnDrop(Option<Child>);
785893

786894
impl KillOnDrop {

0 commit comments

Comments
 (0)