1{ pkgs, lib, ... }:
2let
3 inherit (import ./ssh-keys.nix pkgs) snakeOilPrivateKey snakeOilPublicKey;
4 sshPort = 8231;
5 httpPort = 8232;
6 statsPort = 8233;
7 gitPort = 8418;
8in
9{
10 name = "soft-serve";
11 meta.maintainers = with lib.maintainers; [ dadada ];
12 nodes = {
13 client =
14 { pkgs, ... }:
15 {
16 environment.systemPackages = with pkgs; [
17 curl
18 git
19 openssh
20 ];
21 environment.etc.sshKey = {
22 source = snakeOilPrivateKey;
23 mode = "0600";
24 };
25 };
26
27 server =
28 { config, ... }:
29 {
30 services.soft-serve = {
31 enable = true;
32 settings = {
33 name = "TestServer";
34 ssh.listen_addr = ":${toString sshPort}";
35 git.listen_addr = ":${toString gitPort}";
36 http.listen_addr = ":${toString httpPort}";
37 stats.listen_addr = ":${toString statsPort}";
38 initial_admin_keys = [ snakeOilPublicKey ];
39 };
40 };
41 networking.firewall.allowedTCPPorts = [
42 sshPort
43 httpPort
44 statsPort
45 ];
46 };
47 };
48
49 testScript =
50 { ... }:
51 ''
52 SSH_PORT = ${toString sshPort}
53 HTTP_PORT = ${toString httpPort}
54 STATS_PORT = ${toString statsPort}
55 KEY = "${snakeOilPublicKey}"
56 SSH_KEY = "/etc/sshKey"
57 SSH_COMMAND = f"ssh -p {SSH_PORT} -i {SSH_KEY} -o StrictHostKeyChecking=no"
58 TEST_DIR = "/tmp/test"
59 GIT = f"git -C {TEST_DIR}"
60
61 for machine in client, server:
62 machine.wait_for_unit("network.target")
63
64 server.wait_for_unit("soft-serve.service")
65 server.wait_for_open_port(SSH_PORT)
66
67 with subtest("Get info"):
68 status, test = client.execute(f"{SSH_COMMAND} server info")
69 if status != 0:
70 raise Exception("Failed to get SSH info")
71 key = " ".join(KEY.split(" ")[0:2])
72 if not key in test:
73 raise Exception("Admin key must be configured correctly")
74
75 with subtest("Create user"):
76 client.succeed(f"{SSH_COMMAND} server user create beatrice")
77 client.succeed(f"{SSH_COMMAND} server user info beatrice")
78
79 with subtest("Create repo"):
80 client.succeed(f"git init {TEST_DIR}")
81 client.succeed(f"{GIT} config --global user.email you@example.com")
82 client.succeed(f"touch {TEST_DIR}/foo")
83 client.succeed(f"{GIT} add foo")
84 client.succeed(f"{GIT} commit --allow-empty -m test")
85 client.succeed(f"{GIT} remote add origin git@server:test")
86 client.succeed(f"GIT_SSH_COMMAND='{SSH_COMMAND}' {GIT} push -u origin master")
87 client.execute("rm -r /tmp/test")
88
89 server.wait_for_open_port(HTTP_PORT)
90
91 with subtest("Clone over HTTP"):
92 client.succeed(f"curl --connect-timeout 10 http://server:{HTTP_PORT}/")
93 client.succeed(f"git clone http://server:{HTTP_PORT}/test /tmp/test")
94 client.execute("rm -r /tmp/test")
95
96 with subtest("Clone over SSH"):
97 client.succeed(f"GIT_SSH_COMMAND='{SSH_COMMAND}' git clone git@server:test /tmp/test")
98 client.execute("rm -r /tmp/test")
99
100 with subtest("Get stats over HTTP"):
101 server.wait_for_open_port(STATS_PORT)
102 status, test = client.execute(f"curl --connect-timeout 10 http://server:{STATS_PORT}/metrics")
103 if status != 0:
104 raise Exception("Failed to get metrics from status port")
105 if not "go_gc_duration_seconds_count" in test:
106 raise Exception("Metrics did not contain key 'go_gc_duration_seconds_count'")
107 '';
108}