def test_validate_mesos_recovery_timeout(): validate_success( {'mesos_recovery_timeout': '24hrs'}) validate_success( {'mesos_recovery_timeout': '24.5hrs'}) validate_error( {'mesos_recovery_timeout': '2.4.5hrs'}, 'mesos_recovery_timeout', "Invalid decimal format.") validate_error( {'mesos_recovery_timeout': 'asdf'}, 'mesos_recovery_timeout', "Error parsing 'mesos_recovery_timeout' value: asdf.") validate_error( {'mesos_recovery_timeout': '9999999999999999999999999999999999999999999ns'}, 'mesos_recovery_timeout', "Value 9999999999999999999999999999999999999999999 not in supported range.") validate_error( {'mesos_recovery_timeout': '1hour'}, 'mesos_recovery_timeout', "Unit 'hour' not in ['ns', 'us', 'ms', 'secs', 'mins', 'hrs', 'days', 'weeks'].")
def test_validate_mesos_work_dir(): validate_success({ 'mesos_master_work_dir': '/var/foo', 'mesos_agent_work_dir': '/var/foo', }) # Relative path. validate_error( {'mesos_master_work_dir': 'foo'}, 'mesos_master_work_dir', 'Must be an absolute filesystem path starting with /', ) validate_error( {'mesos_agent_work_dir': 'foo'}, 'mesos_agent_work_dir', 'Must be an absolute filesystem path starting with /', ) # Empty work dir. validate_error( {'mesos_master_work_dir': ''}, 'mesos_master_work_dir', 'Must be an absolute filesystem path starting with /', ) validate_error( {'mesos_agent_work_dir': ''}, 'mesos_agent_work_dir', 'Must be an absolute filesystem path starting with /', )
def test_exhibitor_tls_required(): validate_success({'exhibitor_tls_required': 'false'}) validate_success({'exhibitor_tls_required': 'true'}) validate_error( {'exhibitor_tls_required': 'foo'}, 'exhibitor_tls_required', true_false_msg)
def test_validate_mesos_work_dir(): validate_success({ 'mesos_master_work_dir': '/var/foo', 'mesos_agent_work_dir': '/var/foo', }) # Relative path. validate_error( {'mesos_master_work_dir': 'foo'}, 'mesos_master_work_dir', 'Must be an absolute filesystem path starting with /', ) validate_error( {'mesos_agent_work_dir': 'foo'}, 'mesos_agent_work_dir', 'Must be an absolute filesystem path starting with /', ) # Empty work dir. validate_error( {'mesos_master_work_dir': ''}, 'mesos_master_work_dir', 'Must be an absolute filesystem path starting with /', ) validate_error( {'mesos_agent_work_dir': ''}, 'mesos_agent_work_dir', 'Must be an absolute filesystem path starting with /', )
def test_validate_mesos_recovery_timeout(): validate_success( {'mesos_recovery_timeout': '24hrs'}) validate_success( {'mesos_recovery_timeout': '24.5hrs'}) validate_error( {'mesos_recovery_timeout': '2.4.5hrs'}, 'mesos_recovery_timeout', "Invalid decimal format.") validate_error( {'mesos_recovery_timeout': 'asdf'}, 'mesos_recovery_timeout', "Error parsing 'mesos_recovery_timeout' value: asdf.") validate_error( {'mesos_recovery_timeout': '9999999999999999999999999999999999999999999ns'}, 'mesos_recovery_timeout', "Value 9999999999999999999999999999999999999999999 not in supported range.") validate_error( {'mesos_recovery_timeout': '1hour'}, 'mesos_recovery_timeout', "Unit 'hour' not in ['ns', 'us', 'ms', 'secs', 'mins', 'hrs', 'days', 'weeks'].")
def test_dns_forward_zones(): zones = dns_forward_zones_str bad_zones = bad_dns_forward_zones_str err_msg = 'Invalid "dns_forward_zones": 1 not a valid IP address' validate_success({'dns_forward_zones': zones}) validate_error({'dns_forward_zones': bad_zones}, 'dns_forward_zones', err_msg)
def test_dns_forward_zones(): zones = dns_forward_zones_str bad_zones = bad_dns_forward_zones_str err_msg = 'Invalid "dns_forward_zones": 1 not a valid IP address' validate_success({'dns_forward_zones': zones}) validate_error( {'dns_forward_zones': bad_zones}, 'dns_forward_zones', err_msg)
def test_validate_s3_prefix(): validate_error( { 'exhibitor_storage_backend': 'aws_s3', 'exhibitor_explicit_keys': 'false', 'aws_region': 'bar', 's3_bucket': 'baz', 's3_prefix': 'baz/' }, 's3_prefix', 'Must be a file path and cannot end in a /') validate_success({'s3_prefix': 'baz'}) validate_success({'s3_prefix': 'bar/baz'})
def test_validate_s3_prefix(): validate_error({ 'exhibitor_storage_backend': 'aws_s3', 'exhibitor_explicit_keys': 'false', 'aws_region': 'bar', 's3_bucket': 'baz', 's3_prefix': 'baz/'}, 's3_prefix', 'Must be a file path and cannot end in a /') validate_success({'s3_prefix': 'baz'}) validate_success({'s3_prefix': 'bar/baz'})
def test_uid_and_public_key_provided(self): """ No error is shown if valid ``superuser_service_account_uid`` and ``superuser_service_account_public_key`` are provided. """ validate_success( new_arguments={ 'superuser_service_account_uid': str(uuid.uuid4()), 'superuser_service_account_public_key': generate_rsa_public_key(), } )
def test_uid_and_public_key_provided(self): """ No error is shown if valid ``superuser_service_account_uid`` and ``superuser_service_account_public_key`` are provided. """ validate_success( new_arguments={ 'superuser_service_account_uid': str(uuid.uuid4()), 'superuser_service_account_public_key': generate_rsa_public_key(), })
def test_validate_mesos_default_container_shm_size(): validate_success({'mesos_default_container_shm_size': '64MB'}) validate_success({'mesos_default_container_shm_size': '1gb'}) validate_error_multikey({'mesos_default_container_shm_size': '64.5MB'}, [ 'mesos_default_container_shm_size', 'has_mesos_default_container_shm_size' ], "Fractional bytes: 64.5.") validate_error_multikey({'mesos_default_container_shm_size': 'asdf'}, [ 'mesos_default_container_shm_size', 'has_mesos_default_container_shm_size' ], "Error parsing 'mesos_default_container_shm_size' value: asdf.") validate_error_multikey({'mesos_default_container_shm_size': '64PB'}, [ 'mesos_default_container_shm_size', 'has_mesos_default_container_shm_size' ], "Unit 'PB' not in ['B', 'KB', 'MB', 'GB', 'TB'].")
def test_exhibitor_bootstrap_ca_url(): validate_success({'exhibitor_bootstrap_ca_url': ''}) validate_success({'exhibitor_bootstrap_ca_url': 'https://hello.com'}) validate_success({'exhibitor_bootstrap_ca_url': 'https://1.2.3.4'}) validate_success({'exhibitor_bootstrap_ca_url': 'https://hello.com:443'}) validate_success({'exhibitor_bootstrap_ca_url': 'https://1.2.3.4:443'}) validate_error({'exhibitor_bootstrap_ca_url': 'https://hello.com/'}, 'exhibitor_bootstrap_ca_url', "Must not end in a '/'") validate_error( {'exhibitor_bootstrap_ca_url': 'https://hello.com://there'}, 'exhibitor_bootstrap_ca_url', 'Failed to determine `exhibitor_bootstrap_ca_url` protocol.') validate_error( {'exhibitor_bootstrap_ca_url': 'http://hello.com'}, 'exhibitor_bootstrap_ca_url', 'Expected `https://` as `exhibitor_bootstrap_ca_url` protocol.') validate_error( {'exhibitor_bootstrap_ca_url': 'file://hello.com'}, 'exhibitor_bootstrap_ca_url', 'Expected `https://` as `exhibitor_bootstrap_ca_url` protocol.')
def test_exhibitor_storage_master_discovery(): msg_master_discovery = "When master_discovery is not static, exhibitor_storage_backend must be " \ "non-static. Having a variable list of master which are discovered by agents using the " \ "master_discovery method but also having a fixed known at install time static list of " \ "master ips doesn't `master_http_load_balancer` then exhibitor_storage_backend must not " \ "be static." validate_success({ 'exhibitor_storage_backend': 'static', 'master_discovery': 'static'}) validate_success({ 'exhibitor_storage_backend': 'aws_s3', 'master_discovery': 'master_http_loadbalancer', 'aws_region': 'foo', 'exhibitor_address': 'http://foobar', 'exhibitor_explicit_keys': 'false', 'num_masters': '5', 's3_bucket': 'baz', 's3_prefix': 'mofo'}) validate_success({ 'exhibitor_storage_backend': 'aws_s3', 'master_discovery': 'static', 'exhibitor_explicit_keys': 'false', 's3_bucket': 'foo', 'aws_region': 'bar', 's3_prefix': 'baz/bar'}) validate_error_multikey( {'exhibitor_storage_backend': 'static', 'master_discovery': 'master_http_loadbalancer'}, ['exhibitor_storage_backend', 'master_discovery'], msg_master_discovery, unset={'exhibitor_address', 'num_masters'})
def test_exhibitor_storage_master_discovery(): msg_master_discovery = "When master_discovery is not static, exhibitor_storage_backend must be " \ "non-static. Having a variable list of master which are discovered by agents using the " \ "master_discovery method but also having a fixed known at install time static list of " \ "master ips doesn't `master_http_load_balancer` then exhibitor_storage_backend must not " \ "be static." validate_success({ 'exhibitor_storage_backend': 'static', 'master_discovery': 'static'}) validate_success({ 'exhibitor_storage_backend': 'aws_s3', 'master_discovery': 'master_http_loadbalancer', 'aws_region': 'foo', 'exhibitor_address': 'http://foobar', 'exhibitor_explicit_keys': 'false', 'num_masters': '5', 's3_bucket': 'baz', 's3_prefix': 'mofo'}) validate_success({ 'exhibitor_storage_backend': 'aws_s3', 'master_discovery': 'static', 'exhibitor_explicit_keys': 'false', 's3_bucket': 'foo', 'aws_region': 'bar', 's3_prefix': 'baz/bar'}) validate_error_multikey( {'exhibitor_storage_backend': 'static', 'master_discovery': 'master_http_loadbalancer'}, ['exhibitor_storage_backend', 'master_discovery'], msg_master_discovery, unset={'exhibitor_address', 'num_masters'})
def test_validate_custom_checks(): check_config = json.dumps({ 'cluster_checks': { 'cluster-check-1': { 'description': 'Cluster check 1', 'cmd': ['echo', 'cluster-check-1'], 'timeout': '1s', }, }, 'node_checks': { 'checks': { 'node-check-1': { 'description': 'Node check 1', 'cmd': ['echo', 'node-check-1'], 'timeout': '1s', }, 'node-check-2': { 'description': 'Node check 2', 'cmd': ['echo', 'node-check-2'], 'timeout': '1s', 'roles': ['agent'] }, }, 'prestart': ['node-check-1'], 'poststart': ['node-check-1', 'node-check-2'], }, }) custom_checks = json.dumps({ 'cluster_checks': { 'custom-cluster-check-1': { 'description': 'Custom cluster check 1', 'cmd': ['echo', 'custom-cluster-check-1'], 'timeout': '1s', }, }, 'node_checks': { 'checks': { 'custom-node-check-1': { 'description': 'Custom node check 1', 'cmd': ['echo', 'custom-node-check-1'], 'timeout': '1s', }, }, 'prestart': ['custom-node-check-1'], 'poststart': ['custom-node-check-1'], } }) # Empty and non-empty check_config and custom_checks. validate_success({ 'check_config': json.dumps({}), 'custom_checks': json.dumps({}), }) validate_success({ 'check_config': check_config, 'custom_checks': json.dumps({}), }) validate_success({ 'check_config': check_config, 'custom_checks': custom_checks, }) validate_success({ 'check_config': json.dumps({}), 'custom_checks': custom_checks, }) # Invalid custom checks. validate_error( { 'custom_checks': json.dumps({ 'node_checks': { 'checks': { 'node-check-1': { 'description': 'Node check 1', 'cmd': ['echo', 'node-check-1'], 'timeout': '1s', }, 'node-check-2': { 'description': 'Node check 2', 'cmd': ['echo', 'node-check-2'], 'timeout': '1s', }, }, 'poststart': ['node-check-1', 'node-check-2', 'node-check-3'], }, }) }, 'custom_checks', 'All node checks must be referenced in either prestart or poststart, or both', ) # Custom checks re-use check name used by builtin checks. validate_error_multikey( { 'check_config': check_config, 'custom_checks': json.dumps({ 'cluster_checks': { 'cluster-check-1': { 'description': 'Cluster check 1', 'cmd': ['echo', 'cluster-check-1'], 'timeout': '1s', }, }, 'node_checks': { 'checks': { 'node-check-1': { 'description': 'Node check 1', 'cmd': ['echo', 'node-check-1'], 'timeout': '1s', }, 'node-check-2': { 'description': 'Node check 2', 'cmd': ['echo', 'node-check-2'], 'timeout': '1s', }, }, 'poststart': ['node-check-1', 'node-check-2'], }, }), }, ['check_config', 'custom_checks'], ( 'Custom check names conflict with builtin checks. Reserved cluster check names: cluster-check-1. Reserved ' 'node check names: node-check-1, node-check-2.' ), )
def test_dns_bind_ip_blacklist(): test_ips = '["52.37.192.49", "52.37.181.230", "52.37.163.105"]' validate_success({'dns_bind_ip_blacklist': test_ips})
def test_validate_check_config(): # No checks. validate_success({'check_config': json.dumps({})}) # Valid node and cluster checks. validate_success({ 'check_config': json.dumps({ 'cluster_checks': { 'cluster-check-1': { 'description': 'Cluster check 1', 'cmd': ['echo', 'cluster-check-1'], 'timeout': '1s', }, }, 'node_checks': { 'checks': { 'node-check-1': { 'description': 'Node check 1', 'cmd': ['echo', 'node-check-1'], 'timeout': '1s', }, 'node-check-2': { 'description': 'Node check 2', 'cmd': ['echo', 'node-check-2'], 'timeout': '1s', 'roles': ['agent'] }, }, 'prestart': ['node-check-1'], 'poststart': ['node-check-1', 'node-check-2'], }, }) }) # Valid node checks only. validate_success({ 'check_config': json.dumps({ 'node_checks': { 'checks': { 'node-check-1': { 'description': 'Node check 1', 'cmd': ['echo', 'node-check-1'], 'timeout': '1s', }, 'node-check-2': { 'description': 'Node check 2', 'cmd': ['echo', 'node-check-2'], 'timeout': '1s', 'roles': ['agent'] }, }, 'prestart': ['node-check-1'], 'poststart': ['node-check-1', 'node-check-2'], }, }) }) # Valid cluster checks only. validate_success({ 'check_config': json.dumps({ 'cluster_checks': { 'cluster-check-1': { 'description': 'Cluster check 1', 'cmd': ['echo', 'cluster-check-1'], 'timeout': '1s', }, }, }) }) # Missing check definitions. validate_error( {'check_config': json.dumps({'cluster_checks': {}})}, 'check_config', "Key 'cluster_checks' error: Missing keys: Check name must be a nonzero length string with no whitespace", ) validate_error( {'check_config': json.dumps({'node_checks': {}})}, 'check_config', "Key 'node_checks' error: Missing keys: 'checks'", ) validate_error( { 'check_config': json.dumps({ 'node_checks': { 'checks': {}, }, }) }, 'check_config', ( "Key 'node_checks' error: Key 'checks' error: Missing keys: Check name must be a nonzero length string " "with no whitespace" ), ) # Invalid check names. validate_error( { 'check_config': json.dumps({ 'cluster_checks': { 'cluster check 1': { 'description': 'Cluster check 1', 'cmd': ['echo', 'cluster-check-1'], 'timeout': '1s', }, }, }) }, 'check_config', "Key 'cluster_checks' error: Missing keys: Check name must be a nonzero length string with no whitespace", ) validate_error( { 'check_config': json.dumps({ 'node_checks': { 'checks': { 'node check 1': { 'description': 'Node check 1', 'cmd': ['echo', 'node-check-1'], 'timeout': '1s', }, }, 'prestart': ['node-check-1'], }, }) }, 'check_config', ( "Key 'node_checks' error: Key 'checks' error: Missing keys: Check name must be a nonzero length string " "with no whitespace" ), ) validate_error( { 'check_config': json.dumps({ 'node_checks': { 'checks': { 'node-check-1': { 'description': 'Node check 1', 'cmd': ['echo', 'node-check-1'], 'timeout': '1s', }, }, 'prestart': ['node check 1'], }, }) }, 'check_config', 'Check name must be a nonzero length string with no whitespace', ) validate_error( { 'check_config': json.dumps({ 'node_checks': { 'checks': { 'node-check-1': { 'description': 'Node check 1', 'cmd': ['echo', 'node-check-1'], 'timeout': '1s', }, }, 'poststart': ['node check 1'], }, }) }, 'check_config', 'Check name must be a nonzero length string with no whitespace', ) # Invalid timeouts. validate_error( { 'check_config': json.dumps({ 'cluster_checks': { 'cluster-check-1': { 'description': 'Cluster check 1', 'cmd': ['echo', 'cluster-check-1'], 'timeout': '1second', }, }, }) }, 'check_config', 'Timeout must be a string containing an integer or float followed by a unit: ns, us, µs, ms, s, m, h', ) validate_error( { 'check_config': json.dumps({ 'node_checks': { 'checks': { 'node-check-1': { 'description': 'Node check 1', 'cmd': ['echo', 'node-check-1'], 'timeout': '1 s', }, }, 'poststart': ['node-check-1'], }, }) }, 'check_config', 'Timeout must be a string containing an integer or float followed by a unit: ns, us, µs, ms, s, m, h', ) # Missing check description. validate_error( { 'check_config': json.dumps({ 'cluster_checks': { 'cluster-check-1': { 'cmd': ['echo', 'cluster-check-1'], 'timeout': '1s', }, }, }) }, 'check_config', "Key 'cluster_checks' error: Key 'cluster-check-1' error: Missing keys: 'description'", ) validate_error( { 'check_config': json.dumps({ 'node_checks': { 'checks': { 'node-check-1': { 'cmd': ['echo', 'node-check-1'], 'timeout': '1s', }, }, 'poststart': ['node-check-1'], }, }) }, 'check_config', "Key 'node_checks' error: Key 'checks' error: Key 'node-check-1' error: Missing keys: 'description'", ) # Check cmd is wrong type. validate_error( { 'check_config': json.dumps({ 'cluster_checks': { 'cluster-check-1': { 'description': 'Cluster check 1', 'cmd': 'echo cluster-check-1', 'timeout': '1s', }, }, }) }, 'check_config', ( "Key 'cluster_checks' error: Key 'cluster-check-1' error: Key 'cmd' error: 'echo cluster-check-1' should " "be instance of 'list'" ), ) validate_error( { 'check_config': json.dumps({ 'node_checks': { 'checks': { 'node-check-1': { 'cmd': 'echo node-check-1', 'timeout': '1s', }, }, 'poststart': ['node-check-1'], }, }) }, 'check_config', ( "Key 'node_checks' error: Key 'checks' error: Key 'node-check-1' error: Key 'cmd' error: " "'echo node-check-1' should be instance of 'list'" ), ) # Missing node prestart and poststart check lists. validate_error( { 'check_config': json.dumps({ 'node_checks': { 'checks': { 'node-check-1': { 'description': 'Node check 1', 'cmd': ['echo', 'node-check-1'], 'timeout': '1s', }, }, }, }) }, 'check_config', 'At least one of prestart or poststart must be defined in node_checks', ) # Checks missing from both prestart and poststart. validate_error( { 'check_config': json.dumps({ 'node_checks': { 'checks': { 'node-check-1': { 'description': 'Node check 1', 'cmd': ['echo', 'node-check-1'], 'timeout': '1s', }, 'node-check-2': { 'description': 'Node check 2', 'cmd': ['echo', 'node-check-2'], 'timeout': '1s', }, }, 'poststart': ['node-check-1'], }, }) }, 'check_config', 'All node checks must be referenced in either prestart or poststart, or both', ) # Checks referenced in prestart or poststart but not defined. validate_error( { 'check_config': json.dumps({ 'node_checks': { 'checks': { 'node-check-1': { 'description': 'Node check 1', 'cmd': ['echo', 'node-check-1'], 'timeout': '1s', }, 'node-check-2': { 'description': 'Node check 2', 'cmd': ['echo', 'node-check-2'], 'timeout': '1s', }, }, 'poststart': ['node-check-1', 'node-check-2', 'node-check-3'], }, }) }, 'check_config', 'All node checks must be referenced in either prestart or poststart, or both', ) # Invalid node check role. validate_error( { 'check_config': json.dumps({ 'node_checks': { 'checks': { 'node-check-1': { 'description': 'Node check 1', 'cmd': ['echo', 'node-check-1'], 'timeout': '1s', 'roles': ['master', 'foo'], }, }, 'poststart': ['node-check-1'], }, }) }, 'check_config', 'roles must be a list containing master or agent or both', )
def test_validate_custom_checks(): check_config = json.dumps({ 'cluster_checks': { 'cluster-check-1': { 'description': 'Cluster check 1', 'cmd': ['echo', 'cluster-check-1'], 'timeout': '1s', }, }, 'node_checks': { 'checks': { 'node-check-1': { 'description': 'Node check 1', 'cmd': ['echo', 'node-check-1'], 'timeout': '1s', }, 'node-check-2': { 'description': 'Node check 2', 'cmd': ['echo', 'node-check-2'], 'timeout': '1s', 'roles': ['agent'] }, }, 'prestart': ['node-check-1'], 'poststart': ['node-check-1', 'node-check-2'], }, }) custom_checks = json.dumps({ 'cluster_checks': { 'custom-cluster-check-1': { 'description': 'Custom cluster check 1', 'cmd': ['echo', 'custom-cluster-check-1'], 'timeout': '1s', }, }, 'node_checks': { 'checks': { 'custom-node-check-1': { 'description': 'Custom node check 1', 'cmd': ['echo', 'custom-node-check-1'], 'timeout': '1s', }, }, 'prestart': ['custom-node-check-1'], 'poststart': ['custom-node-check-1'], } }) # Empty and non-empty check_config and custom_checks. validate_success({ 'check_config': json.dumps({}), 'custom_checks': json.dumps({}), }) validate_success({ 'check_config': check_config, 'custom_checks': json.dumps({}), }) validate_success({ 'check_config': check_config, 'custom_checks': custom_checks, }) validate_success({ 'check_config': json.dumps({}), 'custom_checks': custom_checks, }) # Invalid custom checks. validate_error( { 'custom_checks': json.dumps({ 'node_checks': { 'checks': { 'node-check-1': { 'description': 'Node check 1', 'cmd': ['echo', 'node-check-1'], 'timeout': '1s', }, 'node-check-2': { 'description': 'Node check 2', 'cmd': ['echo', 'node-check-2'], 'timeout': '1s', }, }, 'poststart': ['node-check-1', 'node-check-2', 'node-check-3'], }, }) }, 'custom_checks', 'All node checks must be referenced in either prestart or poststart, or both', ) # Custom checks re-use check name used by builtin checks. validate_error_multikey( { 'check_config': check_config, 'custom_checks': json.dumps({ 'cluster_checks': { 'cluster-check-1': { 'description': 'Cluster check 1', 'cmd': ['echo', 'cluster-check-1'], 'timeout': '1s', }, }, 'node_checks': { 'checks': { 'node-check-1': { 'description': 'Node check 1', 'cmd': ['echo', 'node-check-1'], 'timeout': '1s', }, 'node-check-2': { 'description': 'Node check 2', 'cmd': ['echo', 'node-check-2'], 'timeout': '1s', }, }, 'poststart': ['node-check-1', 'node-check-2'], }, }), }, ['check_config', 'custom_checks'], ('Custom check names conflict with builtin checks. Reserved cluster check names: cluster-check-1. Reserved ' 'node check names: node-check-1, node-check-2.'), )
def test_dns_bind_ip_blacklist(): test_ips = '["52.37.192.49", "52.37.181.230", "52.37.163.105"]' validate_success({'dns_bind_ip_blacklist': test_ips})
def test_validate_check_config(): # No checks. validate_success({'check_config': json.dumps({})}) # Valid node and cluster checks. validate_success({ 'check_config': json.dumps({ 'cluster_checks': { 'cluster-check-1': { 'description': 'Cluster check 1', 'cmd': ['echo', 'cluster-check-1'], 'timeout': '1s', }, }, 'node_checks': { 'checks': { 'node-check-1': { 'description': 'Node check 1', 'cmd': ['echo', 'node-check-1'], 'timeout': '1s', }, 'node-check-2': { 'description': 'Node check 2', 'cmd': ['echo', 'node-check-2'], 'timeout': '1s', 'roles': ['agent'] }, }, 'prestart': ['node-check-1'], 'poststart': ['node-check-1', 'node-check-2'], }, }) }) # Valid node checks only. validate_success({ 'check_config': json.dumps({ 'node_checks': { 'checks': { 'node-check-1': { 'description': 'Node check 1', 'cmd': ['echo', 'node-check-1'], 'timeout': '1s', }, 'node-check-2': { 'description': 'Node check 2', 'cmd': ['echo', 'node-check-2'], 'timeout': '1s', 'roles': ['agent'] }, }, 'prestart': ['node-check-1'], 'poststart': ['node-check-1', 'node-check-2'], }, }) }) # Valid cluster checks only. validate_success({ 'check_config': json.dumps({ 'cluster_checks': { 'cluster-check-1': { 'description': 'Cluster check 1', 'cmd': ['echo', 'cluster-check-1'], 'timeout': '1s', }, }, }) }) # Missing check definitions. validate_error( {'check_config': json.dumps({'cluster_checks': {}})}, 'check_config', "Key 'cluster_checks' error: Missing keys: Check name must be a nonzero length string with no whitespace", ) validate_error( {'check_config': json.dumps({'node_checks': {}})}, 'check_config', "Key 'node_checks' error: Missing keys: 'checks'", ) validate_error( {'check_config': json.dumps({ 'node_checks': { 'checks': {}, }, })}, 'check_config', ("Key 'node_checks' error: Key 'checks' error: Missing keys: Check name must be a nonzero length string " "with no whitespace"), ) # Invalid check names. validate_error( { 'check_config': json.dumps({ 'cluster_checks': { 'cluster check 1': { 'description': 'Cluster check 1', 'cmd': ['echo', 'cluster-check-1'], 'timeout': '1s', }, }, }) }, 'check_config', "Key 'cluster_checks' error: Missing keys: Check name must be a nonzero length string with no whitespace", ) validate_error( { 'check_config': json.dumps({ 'node_checks': { 'checks': { 'node check 1': { 'description': 'Node check 1', 'cmd': ['echo', 'node-check-1'], 'timeout': '1s', }, }, 'prestart': ['node-check-1'], }, }) }, 'check_config', ("Key 'node_checks' error: Key 'checks' error: Missing keys: Check name must be a nonzero length string " "with no whitespace"), ) validate_error( { 'check_config': json.dumps({ 'node_checks': { 'checks': { 'node-check-1': { 'description': 'Node check 1', 'cmd': ['echo', 'node-check-1'], 'timeout': '1s', }, }, 'prestart': ['node check 1'], }, }) }, 'check_config', 'Check name must be a nonzero length string with no whitespace', ) validate_error( { 'check_config': json.dumps({ 'node_checks': { 'checks': { 'node-check-1': { 'description': 'Node check 1', 'cmd': ['echo', 'node-check-1'], 'timeout': '1s', }, }, 'poststart': ['node check 1'], }, }) }, 'check_config', 'Check name must be a nonzero length string with no whitespace', ) # Invalid timeouts. validate_error( { 'check_config': json.dumps({ 'cluster_checks': { 'cluster-check-1': { 'description': 'Cluster check 1', 'cmd': ['echo', 'cluster-check-1'], 'timeout': '1second', }, }, }) }, 'check_config', 'Timeout must be a string containing an integer or float followed by a unit: ns, us, µs, ms, s, m, h', ) validate_error( { 'check_config': json.dumps({ 'node_checks': { 'checks': { 'node-check-1': { 'description': 'Node check 1', 'cmd': ['echo', 'node-check-1'], 'timeout': '1 s', }, }, 'poststart': ['node-check-1'], }, }) }, 'check_config', 'Timeout must be a string containing an integer or float followed by a unit: ns, us, µs, ms, s, m, h', ) # Missing check description. validate_error( { 'check_config': json.dumps({ 'cluster_checks': { 'cluster-check-1': { 'cmd': ['echo', 'cluster-check-1'], 'timeout': '1s', }, }, }) }, 'check_config', "Key 'cluster_checks' error: Key 'cluster-check-1' error: Missing keys: 'description'", ) validate_error( { 'check_config': json.dumps({ 'node_checks': { 'checks': { 'node-check-1': { 'cmd': ['echo', 'node-check-1'], 'timeout': '1s', }, }, 'poststart': ['node-check-1'], }, }) }, 'check_config', "Key 'node_checks' error: Key 'checks' error: Key 'node-check-1' error: Missing keys: 'description'", ) # Check cmd is wrong type. validate_error( { 'check_config': json.dumps({ 'cluster_checks': { 'cluster-check-1': { 'description': 'Cluster check 1', 'cmd': 'echo cluster-check-1', 'timeout': '1s', }, }, }) }, 'check_config', ("Key 'cluster_checks' error: Key 'cluster-check-1' error: Key 'cmd' error: 'echo cluster-check-1' should " "be instance of 'list'"), ) validate_error( { 'check_config': json.dumps({ 'node_checks': { 'checks': { 'node-check-1': { 'cmd': 'echo node-check-1', 'timeout': '1s', }, }, 'poststart': ['node-check-1'], }, }) }, 'check_config', ("Key 'node_checks' error: Key 'checks' error: Key 'node-check-1' error: Key 'cmd' error: " "'echo node-check-1' should be instance of 'list'"), ) # Missing node prestart and poststart check lists. validate_error( { 'check_config': json.dumps({ 'node_checks': { 'checks': { 'node-check-1': { 'description': 'Node check 1', 'cmd': ['echo', 'node-check-1'], 'timeout': '1s', }, }, }, }) }, 'check_config', 'At least one of prestart or poststart must be defined in node_checks', ) # Checks missing from both prestart and poststart. validate_error( { 'check_config': json.dumps({ 'node_checks': { 'checks': { 'node-check-1': { 'description': 'Node check 1', 'cmd': ['echo', 'node-check-1'], 'timeout': '1s', }, 'node-check-2': { 'description': 'Node check 2', 'cmd': ['echo', 'node-check-2'], 'timeout': '1s', }, }, 'poststart': ['node-check-1'], }, }) }, 'check_config', 'All node checks must be referenced in either prestart or poststart, or both', ) # Checks referenced in prestart or poststart but not defined. validate_error( { 'check_config': json.dumps({ 'node_checks': { 'checks': { 'node-check-1': { 'description': 'Node check 1', 'cmd': ['echo', 'node-check-1'], 'timeout': '1s', }, 'node-check-2': { 'description': 'Node check 2', 'cmd': ['echo', 'node-check-2'], 'timeout': '1s', }, }, 'poststart': ['node-check-1', 'node-check-2', 'node-check-3'], }, }) }, 'check_config', 'All node checks must be referenced in either prestart or poststart, or both', ) # Invalid node check role. validate_error( { 'check_config': json.dumps({ 'node_checks': { 'checks': { 'node-check-1': { 'description': 'Node check 1', 'cmd': ['echo', 'node-check-1'], 'timeout': '1s', 'roles': ['master', 'foo'], }, }, 'poststart': ['node-check-1'], }, }) }, 'check_config', 'roles must be a list containing master or agent or both', )
def test_uid_and_public_key_not_provided(self): """ No error is shown if ``superuser_service_account_uid`` and ``superuser_service_account_public_key`` are not provided. """ validate_success(new_arguments={})
def test_uid_and_public_key_not_provided(self): """ No error is shown if ``superuser_service_account_uid`` and ``superuser_service_account_public_key`` are not provided. """ validate_success(new_arguments={})