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