at master 5.4 kB view raw
1{ 2 pkgs, 3 lib, 4 getPackage ? pkgs: pkgs.cassandra_4, 5 ... 6}: 7let 8 testPackage = getPackage pkgs; 9 clusterName = "NixOS Automated-Test Cluster"; 10 testRemoteAuth = lib.versionAtLeast testPackage.version "3.11"; 11 jmxRoles = [ 12 { 13 username = "me"; 14 password = "password"; 15 } 16 ]; 17 jmxRolesFile = ./cassandra-jmx-roles; 18 jmxAuthArgs = "-u ${(builtins.elemAt jmxRoles 0).username} -pw ${(builtins.elemAt jmxRoles 0).password}"; 19 jmxPort = 7200; # Non-standard port so it doesn't accidentally work 20 jmxPortStr = toString jmxPort; 21 22 # Would usually be assigned to 512M. 23 # Set it to a different value, so that we can check whether our config 24 # actually changes it. 25 numMaxHeapSize = "400"; 26 getHeapLimitCommand = '' 27 nodetool info -p ${jmxPortStr} | grep "^Heap Memory" | awk '{print $NF}' 28 ''; 29 checkHeapLimitCommand = pkgs.writeShellScript "check-heap-limit.sh" '' 30 [ 1 -eq "$(echo "$(${getHeapLimitCommand}) < ${numMaxHeapSize}" | ${pkgs.bc}/bin/bc)" ] 31 ''; 32 33 cassandraCfg = pkgs: ipAddress: { 34 enable = true; 35 inherit clusterName; 36 listenAddress = ipAddress; 37 rpcAddress = ipAddress; 38 seedAddresses = [ "192.168.1.1" ]; 39 package = getPackage pkgs; 40 maxHeapSize = "${numMaxHeapSize}M"; 41 heapNewSize = "100M"; 42 inherit jmxPort; 43 }; 44 nodeCfg = 45 ipAddress: extra: 46 { pkgs, config, ... }: 47 rec { 48 environment.systemPackages = [ (getPackage pkgs) ]; 49 networking = { 50 firewall.allowedTCPPorts = [ 51 7000 52 9042 53 services.cassandra.jmxPort 54 ]; 55 useDHCP = false; 56 interfaces.eth1.ipv4.addresses = pkgs.lib.mkOverride 0 [ 57 { 58 address = ipAddress; 59 prefixLength = 24; 60 } 61 ]; 62 }; 63 services.cassandra = cassandraCfg pkgs ipAddress // extra; 64 }; 65in 66{ 67 name = "cassandra-${testPackage.version}"; 68 meta = { 69 maintainers = with lib.maintainers; [ johnazoidberg ]; 70 }; 71 72 nodes = { 73 cass0 = nodeCfg "192.168.1.1" { }; 74 cass1 = nodeCfg "192.168.1.2" ( 75 lib.optionalAttrs testRemoteAuth { 76 inherit jmxRoles; 77 remoteJmx = true; 78 } 79 ); 80 cass2 = nodeCfg "192.168.1.3" { jvmOpts = [ "-Dcassandra.replace_address=cass1" ]; }; 81 }; 82 83 testScript = '' 84 # Check configuration 85 with subtest("Timers exist"): 86 cass0.succeed("systemctl list-timers | grep cassandra-full-repair.timer") 87 cass0.succeed("systemctl list-timers | grep cassandra-incremental-repair.timer") 88 89 with subtest("Can connect via cqlsh"): 90 cass0.wait_for_unit("cassandra.service") 91 cass0.wait_until_succeeds("nc -z cass0 9042") 92 cass0.succeed("echo 'show version;' | cqlsh cass0") 93 94 with subtest("Nodetool is operational"): 95 cass0.wait_for_unit("cassandra.service") 96 cass0.wait_until_succeeds("nc -z localhost ${jmxPortStr}") 97 cass0.succeed("nodetool status -p ${jmxPortStr} --resolve-ip | egrep '^UN[[:space:]]+cass0'") 98 99 with subtest("Cluster name was set"): 100 cass0.wait_for_unit("cassandra.service") 101 cass0.wait_until_succeeds("nc -z localhost ${jmxPortStr}") 102 cass0.wait_until_succeeds( 103 "nodetool describecluster -p ${jmxPortStr} | grep 'Name: ${clusterName}'" 104 ) 105 106 with subtest("Heap limit set correctly"): 107 # Nodetool takes a while until it can display info 108 cass0.wait_until_succeeds("nodetool info -p ${jmxPortStr}") 109 cass0.succeed("${checkHeapLimitCommand}") 110 111 # Check cluster interaction 112 with subtest("Bring up cluster"): 113 cass1.wait_for_unit("cassandra.service") 114 cass1.wait_until_succeeds( 115 "nodetool -p ${jmxPortStr} ${jmxAuthArgs} status | egrep -c '^UN' | grep 2" 116 ) 117 cass0.succeed("nodetool status -p ${jmxPortStr} --resolve-ip | egrep '^UN[[:space:]]+cass1'") 118 '' 119 + lib.optionalString testRemoteAuth '' 120 with subtest("Remote authenticated jmx"): 121 # Doesn't work if not enabled 122 cass0.wait_until_succeeds("nc -z localhost ${jmxPortStr}") 123 cass1.fail("nc -z 192.168.1.1 ${jmxPortStr}") 124 cass1.fail("nodetool -p ${jmxPortStr} -h 192.168.1.1 status") 125 126 # Works if enabled 127 cass1.wait_until_succeeds("nc -z localhost ${jmxPortStr}") 128 cass0.succeed("nodetool -p ${jmxPortStr} -h 192.168.1.2 ${jmxAuthArgs} status") 129 '' 130 + '' 131 with subtest("Break and fix node"): 132 cass1.block() 133 cass0.wait_until_succeeds( 134 "nodetool status -p ${jmxPortStr} --resolve-ip | egrep -c '^DN[[:space:]]+cass1'" 135 ) 136 cass0.succeed("nodetool status -p ${jmxPortStr} | egrep -c '^UN' | grep 1") 137 cass1.unblock() 138 cass1.wait_until_succeeds( 139 "nodetool -p ${jmxPortStr} ${jmxAuthArgs} status | egrep -c '^UN' | grep 2" 140 ) 141 cass0.succeed("nodetool status -p ${jmxPortStr} | egrep -c '^UN' | grep 2") 142 143 with subtest("Replace crashed node"): 144 cass1.block() # .crash() waits until it's fully shutdown 145 cass2.start() 146 cass0.wait_until_fails( 147 "nodetool status -p ${jmxPortStr} --resolve-ip | egrep '^UN[[:space:]]+cass1'" 148 ) 149 150 cass2.wait_for_unit("cassandra.service") 151 cass0.wait_until_succeeds( 152 "nodetool status -p ${jmxPortStr} --resolve-ip | egrep '^UN[[:space:]]+cass2'" 153 ) 154 ''; 155 156 passthru = { 157 inherit testPackage; 158 }; 159}