diff --git a/flake.nix b/flake.nix
index 273afd19..f83716df 100644
--- a/flake.nix
+++ b/flake.nix
@@ -17,24 +17,6 @@
overlays = overlayList;
});
- # NixOS configuration used for VM tests.
- hydraServer =
- { config, pkgs, ... }:
- {
- imports = [ self.nixosModules.hydraTest ];
-
- virtualisation.memorySize = 1024;
- virtualisation.writableStore = true;
-
- environment.systemPackages = [ pkgs.perlPackages.LWP pkgs.perlPackages.JSON ];
-
- nix = {
- # Without this nix tries to fetch packages from the default
- # cache.nixos.org which is not reachable from this sandboxed NixOS test.
- binaryCaches = [ ];
- };
- };
-
in
rec {
@@ -67,282 +49,9 @@
echo "doc manual $out/share/doc/hydra" >> $out/nix-support/hydra-build-products
'');
- tests.install = forEachSystem (system:
- with import (nixpkgs + "/nixos/lib/testing-python.nix") { inherit system; };
- simpleTest {
- name = "hydra-install";
- nodes.machine = hydraServer;
- testScript =
- ''
- machine.wait_for_job("hydra-init")
- machine.wait_for_job("hydra-server")
- machine.wait_for_job("hydra-evaluator")
- machine.wait_for_job("hydra-queue-runner")
- machine.wait_for_open_port(3000)
- machine.succeed("curl --fail http://localhost:3000/")
- '';
- });
-
- tests.notifications = forEachSystem (system:
- let pkgs = pkgsBySystem.${system}; in
- with import (nixpkgs + "/nixos/lib/testing-python.nix") { inherit system; };
- simpleTest {
- name = "hydra-notifications";
- nodes.machine = { pkgs, ... }: {
- imports = [ hydraServer ];
- services.hydra-dev.extraConfig = ''
-
- url = http://127.0.0.1:8086
- db = hydra
-
- '';
- services.influxdb.enable = true;
- };
- testScript = ''
- machine.wait_for_job("hydra-init")
-
- # Create an admin account and some other state.
- machine.succeed(
- """
- su - hydra -c "hydra-create-user root --email-address 'alice@example.org' --password foobar --role admin"
- mkdir /run/jobset
- chmod 755 /run/jobset
- cp ${./t/jobs/api-test.nix} /run/jobset/default.nix
- chmod 644 /run/jobset/default.nix
- chown -R hydra /run/jobset
- """
- )
-
- # Wait until InfluxDB can receive web requests
- machine.wait_for_job("influxdb")
- machine.wait_for_open_port(8086)
-
- # Create an InfluxDB database where hydra will write to
- machine.succeed(
- "curl -XPOST 'http://127.0.0.1:8086/query' "
- + "--data-urlencode 'q=CREATE DATABASE hydra'"
- )
-
- # Wait until hydra-server can receive HTTP requests
- machine.wait_for_job("hydra-server")
- machine.wait_for_open_port(3000)
-
- # Setup the project and jobset
- machine.succeed(
- "su - hydra -c 'perl -I ${pkgs.hydra.perlDeps}/lib/perl5/site_perl ${./t/setup-notifications-jobset.pl}' >&2"
- )
-
- # Wait until hydra has build the job and
- # the InfluxDBNotification plugin uploaded its notification to InfluxDB
- machine.wait_until_succeeds(
- "curl -s -H 'Accept: application/csv' "
- + "-G 'http://127.0.0.1:8086/query?db=hydra' "
- + "--data-urlencode 'q=SELECT * FROM hydra_build_status' | grep success"
- )
- '';
- });
-
- tests.gitea = forEachSystem (system:
- let pkgs = pkgsBySystem.${system}; in
- with import (nixpkgs + "/nixos/lib/testing-python.nix") { inherit system; };
- makeTest {
- name = "hydra-gitea";
- nodes.machine = { pkgs, ... }: {
- imports = [ hydraServer ];
- services.hydra-dev.extraConfig = ''
-
- root=d7f16a3412e01a43a414535b16007c6931d3a9c7
-
- '';
- nixpkgs.config.permittedInsecurePackages = [ "gitea-1.19.4" ];
- nix = {
- settings.substituters = [ ];
- };
- services.gitea = {
- enable = true;
- database.type = "postgres";
- disableRegistration = true;
- httpPort = 3001;
- };
- services.openssh.enable = true;
- environment.systemPackages = with pkgs; [ gitea git jq gawk ];
- networking.firewall.allowedTCPPorts = [ 3000 ];
- };
- skipLint = true;
- testScript =
- let
- scripts.mktoken = pkgs.writeText "token.sql" ''
- INSERT INTO access_token (id, uid, name, created_unix, updated_unix, token_hash, token_salt, token_last_eight, scope) VALUES (1, 1, 'hydra', 1617107360, 1617107360, 'a930f319ca362d7b49a4040ac0af74521c3a3c3303a86f327b01994430672d33b6ec53e4ea774253208686c712495e12a486', 'XRjWE9YW0g', '31d3a9c7', 'all');
- '';
-
- scripts.git-setup = pkgs.writeShellScript "setup.sh" ''
- set -x
- mkdir -p /tmp/repo $HOME/.ssh
- cat ${snakeoilKeypair.privkey} > $HOME/.ssh/privk
- chmod 0400 $HOME/.ssh/privk
- git -C /tmp/repo init
- cp ${smallDrv} /tmp/repo/jobset.nix
- git -C /tmp/repo add .
- git config --global user.email test@localhost
- git config --global user.name test
- git -C /tmp/repo commit -m 'Initial import'
- git -C /tmp/repo remote add origin gitea@machine:root/repo
- GIT_SSH_COMMAND='ssh -i $HOME/.ssh/privk -o StrictHostKeyChecking=no' \
- git -C /tmp/repo push origin master
- git -C /tmp/repo log >&2
- '';
-
- scripts.hydra-setup = pkgs.writeShellScript "hydra.sh" ''
- set -x
- su -l hydra -c "hydra-create-user root --email-address \
- 'alice@example.org' --password foobar --role admin"
-
- URL=http://localhost:3000
- USERNAME="root"
- PASSWORD="foobar"
- PROJECT_NAME="trivial"
- JOBSET_NAME="trivial"
- mycurl() {
- curl --referer $URL -H "Accept: application/json" \
- -H "Content-Type: application/json" $@
- }
-
- cat >data.json <data.json <data.json < $out; exit 0"];
- };
- }
- '';
- in
- ''
- import json
-
- machine.start()
- machine.wait_for_unit("multi-user.target")
- machine.wait_for_open_port(3000)
- machine.wait_for_open_port(3001)
-
- machine.succeed(
- "su -l gitea -c 'GITEA_WORK_DIR=/var/lib/gitea gitea admin user create "
- + "--username root --password root --email test@localhost'"
- )
- machine.succeed("su -l postgres -c 'psql gitea < ${scripts.mktoken}'")
-
- machine.succeed(
- "curl --fail -X POST http://localhost:3001/api/v1/user/repos "
- + "-H 'Accept: application/json' -H 'Content-Type: application/json' "
- + f"-H 'Authorization: token ${api_token}'"
- + ' -d \'{"auto_init":false, "description":"string", "license":"mit", "name":"repo", "private":false}\'''
- )
-
- machine.succeed(
- "curl --fail -X POST http://localhost:3001/api/v1/user/keys "
- + "-H 'Accept: application/json' -H 'Content-Type: application/json' "
- + f"-H 'Authorization: token ${api_token}'"
- + ' -d \'{"key":"${snakeoilKeypair.pubkey}","read_only":true,"title":"SSH"}\'''
- )
-
- machine.succeed(
- "${scripts.git-setup}"
- )
-
- machine.succeed(
- "${scripts.hydra-setup}"
- )
-
- machine.wait_until_succeeds(
- 'curl -Lf -s http://localhost:3000/build/1 -H "Accept: application/json" '
- + '| jq .buildstatus | xargs test 0 -eq'
- )
-
- data = machine.succeed(
- 'curl -Lf -s "http://localhost:3001/api/v1/repos/root/repo/statuses/$(cd /tmp/repo && git show | head -n1 | awk "{print \\$2}")" '
- + "-H 'Accept: application/json' -H 'Content-Type: application/json' "
- + f"-H 'Authorization: token ${api_token}'"
- )
-
- response = json.loads(data)
-
- assert len(response) == 2, "Expected exactly three status updates for latest commit (queued, finished)!"
- assert response[0]['status'] == "success", "Expected finished status to be success!"
- assert response[1]['status'] == "pending", "Expected queued status to be pending!"
-
- machine.shutdown()
- '';
- });
-
- tests.validate-openapi = forEachSystem (system:
- let pkgs = pkgsBySystem.${system}; in
- pkgs.runCommand "validate-openapi"
- { buildInputs = [ pkgs.openapi-generator-cli ]; }
- ''
- openapi-generator-cli validate -i ${./hydra-api.yaml}
- touch $out
- '');
+ tests = import ./nixos-tests.nix {
+ inherit forEachSystem nixpkgs pkgsBySystem nixosModules;
+ };
container = nixosConfigurations.container.config.system.build.toplevel;
};
@@ -366,6 +75,8 @@
system = "x86_64-linux";
modules =
[
+ self.nixosModules.hydra
+ self.nixosModules.overlayNixpkgsForThisHyydra
self.nixosModules.hydraTest
self.nixosModules.hydraProxy
{
diff --git a/nixos-modules/default.nix b/nixos-modules/default.nix
index 6fc19d31..f44d7808 100644
--- a/nixos-modules/default.nix
+++ b/nixos-modules/default.nix
@@ -1,14 +1,13 @@
{ overlays }:
-rec {
- hydra = {
- imports = [ ./hydra.nix ];
+{
+ hydra = import ./hydra.nix;
+
+ overlayNixpkgsForThisHyydra = {
nixpkgs = { inherit overlays; };
};
hydraTest = { pkgs, ... }: {
- imports = [ hydra ];
-
services.hydra-dev.enable = true;
services.hydra-dev.hydraURL = "http://hydra.example.org";
services.hydra-dev.notificationSender = "admin@hydra.example.org";
@@ -16,7 +15,7 @@ rec {
systemd.services.hydra-send-stats.enable = false;
services.postgresql.enable = true;
- services.postgresql.package = pkgs.postgresql_11;
+ services.postgresql.package = pkgs.postgresql_12;
# The following is to work around the following error from hydra-server:
# [error] Caught exception in engine "Cannot determine local time zone"
diff --git a/nixos-tests.nix b/nixos-tests.nix
new file mode 100644
index 00000000..3c9dc6c8
--- /dev/null
+++ b/nixos-tests.nix
@@ -0,0 +1,309 @@
+{ forEachSystem, nixpkgs, pkgsBySystem, nixosModules }:
+
+let
+ # NixOS configuration used for VM tests.
+ hydraServer =
+ { config, pkgs, ... }:
+ {
+ imports = [
+ nixosModules.hydra
+ nixosModules.overlayNixpkgsForThisHyydra
+ nixosModules.hydraTest
+ ];
+
+ virtualisation.memorySize = 1024;
+ virtualisation.writableStore = true;
+
+ environment.systemPackages = [ pkgs.perlPackages.LWP pkgs.perlPackages.JSON ];
+
+ nix = {
+ # Without this nix tries to fetch packages from the default
+ # cache.nixos.org which is not reachable from this sandboxed NixOS test.
+ settings.substituters = [ ];
+ };
+ };
+
+in
+
+{
+
+ install = forEachSystem (system:
+ with import (nixpkgs + "/nixos/lib/testing-python.nix") { inherit system; };
+ simpleTest {
+ name = "hydra-install";
+ nodes.machine = hydraServer;
+ testScript =
+ ''
+ machine.wait_for_job("hydra-init")
+ machine.wait_for_job("hydra-server")
+ machine.wait_for_job("hydra-evaluator")
+ machine.wait_for_job("hydra-queue-runner")
+ machine.wait_for_open_port(3000)
+ machine.succeed("curl --fail http://localhost:3000/")
+ '';
+ });
+
+ notifications = forEachSystem (system:
+ let pkgs = pkgsBySystem.${system}; in
+ with import (nixpkgs + "/nixos/lib/testing-python.nix") { inherit system; };
+ simpleTest {
+ name = "hydra-notifications";
+ nodes.machine = { pkgs, ... }: {
+ imports = [ hydraServer ];
+ services.hydra-dev.extraConfig = ''
+
+ url = http://127.0.0.1:8086
+ db = hydra
+
+ '';
+ services.influxdb.enable = true;
+ };
+ testScript = ''
+ machine.wait_for_job("hydra-init")
+
+ # Create an admin account and some other state.
+ machine.succeed(
+ """
+ su - hydra -c "hydra-create-user root --email-address 'alice@example.org' --password foobar --role admin"
+ mkdir /run/jobset
+ chmod 755 /run/jobset
+ cp ${./t/jobs/api-test.nix} /run/jobset/default.nix
+ chmod 644 /run/jobset/default.nix
+ chown -R hydra /run/jobset
+ """
+ )
+
+ # Wait until InfluxDB can receive web requests
+ machine.wait_for_job("influxdb")
+ machine.wait_for_open_port(8086)
+
+ # Create an InfluxDB database where hydra will write to
+ machine.succeed(
+ "curl -XPOST 'http://127.0.0.1:8086/query' "
+ + "--data-urlencode 'q=CREATE DATABASE hydra'"
+ )
+
+ # Wait until hydra-server can receive HTTP requests
+ machine.wait_for_job("hydra-server")
+ machine.wait_for_open_port(3000)
+
+ # Setup the project and jobset
+ machine.succeed(
+ "su - hydra -c 'perl -I ${pkgs.hydra.perlDeps}/lib/perl5/site_perl ${./t/setup-notifications-jobset.pl}' >&2"
+ )
+
+ # Wait until hydra has build the job and
+ # the InfluxDBNotification plugin uploaded its notification to InfluxDB
+ machine.wait_until_succeeds(
+ "curl -s -H 'Accept: application/csv' "
+ + "-G 'http://127.0.0.1:8086/query?db=hydra' "
+ + "--data-urlencode 'q=SELECT * FROM hydra_build_status' | grep success"
+ )
+ '';
+ });
+
+ gitea = forEachSystem (system:
+ let pkgs = pkgsBySystem.${system}; in
+ with import (nixpkgs + "/nixos/lib/testing-python.nix") { inherit system; };
+ makeTest {
+ name = "hydra-gitea";
+ nodes.machine = { pkgs, ... }: {
+ imports = [ hydraServer ];
+ services.hydra-dev.extraConfig = ''
+
+ root=d7f16a3412e01a43a414535b16007c6931d3a9c7
+
+ '';
+ nixpkgs.config.permittedInsecurePackages = [ "gitea-1.19.4" ];
+ nix = {
+ settings.substituters = [ ];
+ };
+ services.gitea = {
+ enable = true;
+ database.type = "postgres";
+ settings = {
+ service.DISABLE_REGISTRATION = true;
+ server.HTTP_PORT = 3001;
+ };
+ };
+ services.openssh.enable = true;
+ environment.systemPackages = with pkgs; [ gitea git jq gawk ];
+ networking.firewall.allowedTCPPorts = [ 3000 ];
+ };
+ skipLint = true;
+ testScript =
+ let
+ scripts.mktoken = pkgs.writeText "token.sql" ''
+ INSERT INTO access_token (id, uid, name, created_unix, updated_unix, token_hash, token_salt, token_last_eight, scope) VALUES (1, 1, 'hydra', 1617107360, 1617107360, 'a930f319ca362d7b49a4040ac0af74521c3a3c3303a86f327b01994430672d33b6ec53e4ea774253208686c712495e12a486', 'XRjWE9YW0g', '31d3a9c7', 'all');
+ '';
+
+ scripts.git-setup = pkgs.writeShellScript "setup.sh" ''
+ set -x
+ mkdir -p /tmp/repo $HOME/.ssh
+ cat ${snakeoilKeypair.privkey} > $HOME/.ssh/privk
+ chmod 0400 $HOME/.ssh/privk
+ git -C /tmp/repo init
+ cp ${smallDrv} /tmp/repo/jobset.nix
+ git -C /tmp/repo add .
+ git config --global user.email test@localhost
+ git config --global user.name test
+ git -C /tmp/repo commit -m 'Initial import'
+ git -C /tmp/repo remote add origin gitea@machine:root/repo
+ GIT_SSH_COMMAND='ssh -i $HOME/.ssh/privk -o StrictHostKeyChecking=no' \
+ git -C /tmp/repo push origin master
+ git -C /tmp/repo log >&2
+ '';
+
+ scripts.hydra-setup = pkgs.writeShellScript "hydra.sh" ''
+ set -x
+ su -l hydra -c "hydra-create-user root --email-address \
+ 'alice@example.org' --password foobar --role admin"
+
+ URL=http://localhost:3000
+ USERNAME="root"
+ PASSWORD="foobar"
+ PROJECT_NAME="trivial"
+ JOBSET_NAME="trivial"
+ mycurl() {
+ curl --referer $URL -H "Accept: application/json" \
+ -H "Content-Type: application/json" $@
+ }
+
+ cat >data.json <data.json <data.json < $out; exit 0"];
+ };
+ }
+ '';
+ in
+ ''
+ import json
+
+ machine.start()
+ machine.wait_for_unit("multi-user.target")
+ machine.wait_for_open_port(3000)
+ machine.wait_for_open_port(3001)
+
+ machine.succeed(
+ "su -l gitea -c 'GITEA_WORK_DIR=/var/lib/gitea gitea admin user create "
+ + "--username root --password root --email test@localhost'"
+ )
+ machine.succeed("su -l postgres -c 'psql gitea < ${scripts.mktoken}'")
+
+ machine.succeed(
+ "curl --fail -X POST http://localhost:3001/api/v1/user/repos "
+ + "-H 'Accept: application/json' -H 'Content-Type: application/json' "
+ + f"-H 'Authorization: token ${api_token}'"
+ + ' -d \'{"auto_init":false, "description":"string", "license":"mit", "name":"repo", "private":false}\'''
+ )
+
+ machine.succeed(
+ "curl --fail -X POST http://localhost:3001/api/v1/user/keys "
+ + "-H 'Accept: application/json' -H 'Content-Type: application/json' "
+ + f"-H 'Authorization: token ${api_token}'"
+ + ' -d \'{"key":"${snakeoilKeypair.pubkey}","read_only":true,"title":"SSH"}\'''
+ )
+
+ machine.succeed(
+ "${scripts.git-setup}"
+ )
+
+ machine.succeed(
+ "${scripts.hydra-setup}"
+ )
+
+ machine.wait_until_succeeds(
+ 'curl -Lf -s http://localhost:3000/build/1 -H "Accept: application/json" '
+ + '| jq .buildstatus | xargs test 0 -eq'
+ )
+
+ data = machine.succeed(
+ 'curl -Lf -s "http://localhost:3001/api/v1/repos/root/repo/statuses/$(cd /tmp/repo && git show | head -n1 | awk "{print \\$2}")" '
+ + "-H 'Accept: application/json' -H 'Content-Type: application/json' "
+ + f"-H 'Authorization: token ${api_token}'"
+ )
+
+ response = json.loads(data)
+
+ assert len(response) == 2, "Expected exactly three status updates for latest commit (queued, finished)!"
+ assert response[0]['status'] == "success", "Expected finished status to be success!"
+ assert response[1]['status'] == "pending", "Expected queued status to be pending!"
+
+ machine.shutdown()
+ '';
+ });
+
+ validate-openapi = forEachSystem (system:
+ let pkgs = pkgsBySystem.${system}; in
+ pkgs.runCommand "validate-openapi"
+ { buildInputs = [ pkgs.openapi-generator-cli ]; }
+ ''
+ openapi-generator-cli validate -i ${./hydra-api.yaml}
+ touch $out
+ '');
+
+}