vuls: init at 0.27.0
[NixPkgs.git] / nixos / tests / cockroachdb.nix
blob5b1e1a7dee1f945ecbfec6e7a6cea9ea7d07889a
1 # This performs a full 'end-to-end' test of a multi-node CockroachDB cluster
2 # using the built-in 'cockroach workload' command, to simulate a semi-realistic
3 # test load. It generally takes anywhere from 3-5 minutes to run and 1-2GB of
4 # RAM (though each of 3 workers gets 2GB allocated)
6 # CockroachDB requires synchronized system clocks within a small error window
7 # (~500ms by default) on each node in order to maintain a multi-node cluster.
8 # Cluster joins that are outside this window will fail, and nodes that skew
9 # outside the window after joining will promptly get kicked out.
11 # To accommodate this, we use QEMU/virtio infrastructure and load the 'ptp_kvm'
12 # driver inside a guest. This driver allows the host machine to pass its clock
13 # through to the guest as a hardware clock that appears as a Precision Time
14 # Protocol (PTP) Clock device, generally /dev/ptp0. PTP devices can be measured
15 # and used as hardware reference clocks (similar to an on-board GPS clock) by
16 # NTP software. In our case, we use Chrony to synchronize to the reference
17 # clock.
19 # This test is currently NOT enabled as a continuously-checked NixOS test.
20 # Ideally, this test would be run by Hydra and Borg on all relevant changes,
21 # except:
23 #   - Not every build machine is compatible with the ptp_kvm driver.
24 #     Virtualized EC2 instances, for example, do not support loading the ptp_kvm
25 #     driver into guests. However, bare metal builders (e.g. Packet) do seem to
26 #     work just fine. In practice, this means x86_64-linux builds would fail
27 #     randomly, depending on which build machine got the job. (This is probably
28 #     worth some investigation; I imagine it's based on ptp_kvm's usage of paravirt
29 #     support which may not be available in 'nested' environments.)
31 #   - ptp_kvm is not supported on aarch64, otherwise it seems likely Cockroach
32 #     could be tested there, as well. This seems to be due to the usage of
33 #     the TSC in ptp_kvm, which isn't supported (easily) on AArch64. (And:
34 #     testing stuff, not just making sure it builds, is important to ensure
35 #     aarch64 support remains viable.)
37 # For future developers who are reading this message, are daring and would want
38 # to fix this, some options are:
40 #   - Just test a single node cluster instead (boring and less thorough).
41 #   - Move all CI to bare metal packet builders, and we can at least do x86_64-linux.
42 #   - Get virtualized clocking working in aarch64, somehow.
43 #   - Add a 4th node that acts as an NTP service and uses no PTP clocks for
44 #     references, at the client level. This bloats the node and memory
45 #     requirements, but would probably allow both aarch64/x86_64 to work.
48 let
50   # Creates a node. If 'joinNode' parameter, a string containing an IP address,
51   # is non-null, then the CockroachDB server will attempt to join/connect to
52   # the cluster node specified at that address.
53   makeNode = locality: myAddr: joinNode:
54     { nodes, pkgs, lib, config, ... }:
56     {
57       # Bank/TPC-C benchmarks take some memory to complete
58       virtualisation.memorySize = 2048;
60       # Install the KVM PTP "Virtualized Clock" driver. This allows a /dev/ptp0
61       # device to appear as a reference clock, synchronized to the host clock.
62       # Because CockroachDB *requires* a time-synchronization mechanism for
63       # the system time in a cluster scenario, this is necessary to work.
64       boot.kernelModules = [ "ptp_kvm" ];
66       # Enable and configure Chrony, using the given virtualized clock passed
67       # through by KVM.
68       services.chrony.enable = true;
69       services.chrony.servers = lib.mkForce [ ];
70       services.chrony.extraConfig = ''
71         refclock PHC /dev/ptp0 poll 2 prefer require refid KVM
72         makestep 0.1 3
73       '';
75       # Enable CockroachDB. In order to ensure that Chrony has performed its
76       # first synchronization at boot-time (which may take ~10 seconds) before
77       # starting CockroachDB, we block the ExecStartPre directive using the
78       # 'waitsync' command. This ensures Cockroach doesn't have its system time
79       # leap forward out of nowhere during startup/execution.
80       #
81       # Note that the default threshold for NTP-based skew in CockroachDB is
82       # ~500ms by default, so making sure it's started *after* accurate time
83       # synchronization is extremely important.
84       services.cockroachdb.enable = true;
85       services.cockroachdb.insecure = true;
86       services.cockroachdb.openPorts = true;
87       services.cockroachdb.locality = locality;
88       services.cockroachdb.listen.address = myAddr;
89       services.cockroachdb.join = lib.mkIf (joinNode != null) joinNode;
91       systemd.services.chronyd.unitConfig.ConditionPathExists = "/dev/ptp0";
93       # Hold startup until Chrony has performed its first measurement (which
94       # will probably result in a full timeskip, thanks to makestep)
95       systemd.services.cockroachdb.preStart = ''
96         ${pkgs.chrony}/bin/chronyc waitsync
97       '';
98     };
100 in import ./make-test-python.nix ({ pkgs, ...} : {
101   name = "cockroachdb";
102   meta.maintainers = with pkgs.lib.maintainers;
103     [ thoughtpolice ];
105   nodes = {
106     node1 = makeNode "country=us,region=east,dc=1"  "192.168.1.1" null;
107     node2 = makeNode "country=us,region=west,dc=2b" "192.168.1.2" "192.168.1.1";
108     node3 = makeNode "country=eu,region=west,dc=2"  "192.168.1.3" "192.168.1.1";
109   };
111   # NOTE: All the nodes must start in order and you must NOT use startAll, because
112   # there's otherwise no way to guarantee that node1 will start before the others try
113   # to join it.
114   testScript = ''
115     for node in node1, node2, node3:
116         node.start()
117         node.wait_for_unit("cockroachdb")
118     node1.succeed(
119         "cockroach sql --host=192.168.1.1 --insecure -e 'SHOW ALL CLUSTER SETTINGS' 2>&1",
120         "cockroach workload init bank 'postgresql://root@192.168.1.1:26257?sslmode=disable'",
121         "cockroach workload run bank --duration=1m 'postgresql://root@192.168.1.1:26257?sslmode=disable'",
122     )
123   '';