Commit 7ae4d31a authored by Łukasz Nowak's avatar Łukasz Nowak

Merge branch 'feature/edgetest-pop'

Edggetest monitoring got capability of region definition in each cluster.

In order to stabilise parameter serialisation the json-in-xml has been used.
parents cfe9f936 e62fe778
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
# not need these here). # not need these here).
[template] [template]
filename = instance.cfg filename = instance.cfg
md5sum = 9ddae686379e8d747410c1adf82b47d6 md5sum = c115ed9d4ff0f785d79cdcacbb0bd1ad
[template-monitor] [template-monitor]
_update_hash_filename_ = instance-monitor.cfg.jinja2 _update_hash_filename_ = instance-monitor.cfg.jinja2
...@@ -26,11 +26,11 @@ md5sum = 2eb5596544d9c341acf653d4f7ce2680 ...@@ -26,11 +26,11 @@ md5sum = 2eb5596544d9c341acf653d4f7ce2680
[template-monitor-edgetest] [template-monitor-edgetest]
_update_hash_filename_ = instance-monitor-edgetest.cfg.jinja2 _update_hash_filename_ = instance-monitor-edgetest.cfg.jinja2
md5sum = a57106ee88ff3295b9ffce84105da79b md5sum = 3c8ab4e78f66c974eb95afc595a13514
[template-monitor-edgebot] [template-monitor-edgebot]
_update_hash_filename_ = instance-monitor-edgebot.cfg.jinja2 _update_hash_filename_ = instance-monitor-edgebot.cfg.jinja2
md5sum = c1885a42aadd45bab3185a53258d4ff4 md5sum = 365a6cc6831267a73fa5ebd56ad394ee
[network-bench-cfg] [network-bench-cfg]
filename = network_bench.cfg.in filename = network_bench.cfg.in
...@@ -42,4 +42,4 @@ md5sum = d3cfa1f6760e3fa64ccd64acf213bdfb ...@@ -42,4 +42,4 @@ md5sum = d3cfa1f6760e3fa64ccd64acf213bdfb
[template-surykatka-ini] [template-surykatka-ini]
_update_hash_filename_ = surykatka.ini.jinja2 _update_hash_filename_ = surykatka.ini.jinja2
md5sum = 89545501f0e5bf11608978886429da3d md5sum = 609c6cca763b73a80fa05ee56475eb20
{ {
"$schema": "http://json-schema.org/draft-04/schema#", "$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": { "properties": {
"nameserver": { "region-dict": {
"default": "", "title": "Regions",
"title": "Nameserver", "description": "Defines regions of the cluster",
"description": "Space separated list of name servers to use.", "patternProperties": {
"type": "string" ".*": {
}, "properties": {
"check-status-code": { "state": {
"default": "200", "title": "State",
"title": "Default Check HTTP Code", "description": "State of the node of the region. Can be used to destroy not needed regions.",
"description": "Default HTTP code to check against (default: 200).", "type": "string",
"type": "string" "default": "started",
}, "enum": [
"check-http-header-dict": { "started",
"default": "{}", "stopped",
"title": "HTTP header dict to check", "destroyed"
"description": "JSON dict of expected HTTP header, like {\"Cache-Control\": \"max-age=3600, public\", \"Vary\": \"Accept-Encoding\"}", ]
},
"sla-computer_guid": {
"title": "GUID of the computer on which this region shall be deployed",
"description": "Unique identifier of the computer, like \"COMP-1234\". By default, let Master choose a computer.",
"type": "string",
"default": ""
},
"nameserver-list": {
"default": [],
"title": "Nameservers",
"description": "List of nameservers to use.",
"type": "array"
},
"check-frontend-ip-list": {
"default": [],
"title": "Default Frontend IPs to check",
"description": "List of default frontend IPs to check, if empty no constraint is used.",
"type": "array"
}
},
"type": "object"
}
},
"type": "object" "type": "object"
}, },
"check-frontend-ip": { "nameserver-list": {
"default": "", "default": [],
"title": "Default space separated list of Frontend IPs to check", "title": "Nameservers (backward compatibility)",
"description": "Default list of Frontend IPs to check, if empty no constraint is used.", "description": "List of nameservers to use. Note: This is backward compatibility, use region-dict for full configuration control.",
"type": "string" "type": "array"
},
"check-certificate-expiration-days": {
"default": "15",
"title": "Default certificate expiration days check",
"description": "Default amount of days to consider certificate as being to-be-expired (default: 15).",
"type": "string"
},
"check-maximum-elapsed-time": {
"default": "2",
"title": "Default maximum elapsed time for a site to reply (seconds)",
"description": "Default maximum elapsed time for a site to reply to be considered good (default: 2s).",
"type": "string"
}, },
"failure-amount": { "check-frontend-ip-list": {
"default": "1", "default": [],
"title": "Default amount of failures to consider URL as in bad state", "title": "Default Frontend IPs to check (backward compatibility)",
"description": "Default amount of failures to consider URL as in bad state, can be set to higher value for endpoints with accepted short outages (default: 1).", "description": "List of default frontend IPs to check, if empty no constraint is used. Note: This is backward compatibility, use region-dict for full configuration control.",
"type": "string" "type": "array"
} }
} }
} }
{ {
"$schema": "http://json-schema.org/draft-04/schema#", "$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": { "properties": {
"url": { "url": {
"title": "URL to check", "title": "URL to check",
"description": "URL to check, like https://example.com", "description": "URL to check, like https://example.com/",
"type": "string" "type": "string"
}, },
"check-status-code": { "region-dict": {
"default": "Master default", "title": "Applicable Regions",
"title": "Default Check HTTP Code.", "description": "Puts the check on the defined regions. No definition will result with presence in all regions.",
"description": "HTTP code to check against (default: comes from master partition).", "patternProperties": {
"type": "string" ".*": {
}, "properties": {
"check-http-header-dict": { "state": {
"default": "Master default", "title": "State",
"title": "HTTP header dict to check", "description": "State of the check of the region. Used only to make it correctly visible in the SlapOS Master UI if no other parameters are defined.",
"description": "JSON dict of expected HTTP header, like {\"Cache-Control\": \"max-age=3600, public\", \"Vary\": \"Accept-Encoding\"}", "type": "string",
"type": "object" "default": "present",
"enum": [
"present"
]
},
"check-frontend-ip-list": {
"default": [],
"title": "Frontend IPs to check",
"description": "List of default frontend IPs to check, if empty no constraint is used. Defaults to region configuration.",
"type": "array"
}
},
"type": "object"
}
},
"type": "object",
"default": {}
}, },
"check-frontend-ip": { "check-status-code": {
"default": "Master default", "title": "HTTP Code Check",
"title": "Space separated list of Frontend IPs to check", "description": "Expected response HTTP Code.",
"description": "List of Frontend IPs to check, if empty no constraint is used (default: comes from master partition).", "type": "number",
"type": "string" "default": 200,
"minimum": 100,
"maximum": 599
}, },
"check-certificate-expiration-days": { "check-certificate-expiration-days": {
"default": "Master default", "title": "Certificate Expiration Check (days)",
"title": "Certificate expiration days check", "description": "Amount of days to consider certificate as being to-be-expired.",
"description": "Amount of days to consider certificate as being to-be-expired (default: comes from master partition).", "type": "number",
"type": "string" "default": 15,
"minimum": 1
}, },
"check-maximum-elapsed-time": { "check-maximum-elapsed-time": {
"default": "Master default", "title": "Maximum Elapsed Check (seconds)",
"title": "Maximum elapsed time for a site to reply (seconds)", "description": "Maximum elapsed time for a site to reply to be considered good.",
"description": "Maximum elapsed time for a site to reply to be considered good.(default: comes from master partition).", "type": "number",
"type": "string" "default": 2,
"minimum": 1
},
"check-http-header-dict": {
"title": "HTTP Header Check",
"description": "JSON object of expected HTTP header, like {\"Cache-Control\": \"max-age=3600, public\", \"Vary\": \"Accept-Encoding\"}. Note: Shall be expressed directly as object, without any additional qouting.",
"type": "object",
"default": {}
}, },
"failure-amount": { "failure-amount": {
"default": "Master default", "title": "Failure Amount",
"title": "Amount of failures to consider URL as in bad state", "description": "Amount of failures to consider URL as in bad state, can be set to higher value for endpoints with accepted short outages.",
"description": "Amount of failures to consider URL as in bad state, can be set to higher value for endpoints with accepted short outages (default: comes from master partition).", "type": "number",
"type": "string" "default": 2,
"minimum": 1
},
"check-frontend-ip-list": {
"title": "Frontend IPs to check (backward compatibility)",
"description": "List of Frontend IPs to check, if empty no constraint is used. Defaults to region configuration. Note: Use region-dict's check-frontend-ip-list to ensure specific check on each region.",
"type": "array"
} }
} }
} }
...@@ -9,39 +9,27 @@ ...@@ -9,39 +9,27 @@
{%- set extra_slave_instance_list = slapparameter_dict.get('extra_slave_instance_list') %} {%- set extra_slave_instance_list = slapparameter_dict.get('extra_slave_instance_list') %}
{%- if extra_slave_instance_list %} {%- if extra_slave_instance_list %}
{#- Create slaves to process with setting up defaults #} {#- Create slaves to process with setting up defaults #}
{%- for slave in json_module.loads(extra_slave_instance_list) | sort(attribute='slave_title') %} {%- for slave in extra_slave_instance_list | sort(attribute='-slave-title') %}
{%- if 'check-status-code' not in slave %} {%- do slave.setdefault('check-status-code', 200) %}
{%- do slave.__setitem__('check-status-code', CONFIGURATION['check-status-code']) %} {%- do slave.setdefault('check-http-header-dict', {}) %}
{%- endif %} {%- do slave.setdefault('check-certificate-expiration-days', 15) %}
{%- if 'check-http-header-dict' not in slave %} {%- do slave.setdefault('failure-amount', 2) %}
{%- do slave.__setitem__('check-http-header-dict', CONFIGURATION['check-http-header-dict']) %} {%- do slave.setdefault('check-maximum-elapsed-time', 2) %}
{%- endif %} {%- do slave.setdefault('check-frontend-ip-list', CONFIGURATION['check-frontend-ip-list']) %}
{%- if 'check-certificate-expiration-days' not in slave %} {%- if 'url' in slave %}
{%- do slave.__setitem__('check-certificate-expiration-days', CONFIGURATION['check-certificate-expiration-days']) %} {%- set class = slave['check-maximum-elapsed-time'] %}
{%- endif %} {%- if class not in slave_instance_dict %}
{%- if 'failure-amount' not in slave %} {%- do slave_instance_dict.__setitem__(class, []) %}
{%- do slave.__setitem__('failure-amount', CONFIGURATION['failure-amount']) %} {%- endif %}
{%- endif %} {%- do slave_instance_dict[class].append(slave) %}
{%- if 'check-maximum-elapsed-time' not in slave %}
{%- do slave.__setitem__('check-maximum-elapsed-time', CONFIGURATION['check-maximum-elapsed-time']) %}
{%- endif %}
{%- if 'check-frontend-ip' not in slave %}
{%- do slave.__setitem__('check-frontend-ip', CONFIGURATION['check-frontend-ip']) %}
{%- endif %}
{%- if 'url' in slave %}
{%- set class = slave['check-maximum-elapsed-time'] %}
{%- if class not in slave_instance_dict %}
{%- do slave_instance_dict.__setitem__(class, []) %}
{%- endif %} {%- endif %}
{%- do slave_instance_dict[class].append(slave) %}
{%- endif %}
{%- endfor %} {%- endfor %}
{%- endif %} {%- endif %}
{%- set part_list = [] %} {%- set part_list = [] %}
{%- for class, slave_instance_list in slave_instance_dict.items() %} {%- for class, slave_instance_list in slave_instance_dict.items() %}
{#- class is used to separate surykatka with different timeouts #} {#- class is used to separate surykatka with different timeouts #}
{%- for slave in slave_instance_list | sort(attribute='slave_title') %} {%- for slave in slave_instance_list | sort(attribute='-slave-title') %}
{%- set part_id = 'http-query-' ~ slave['slave_reference'] ~ '-promise' %} {%- set part_id = 'http-query-' ~ hashlib_module.md5(slave['-slave-reference'].encode('utf-8')).hexdigest() ~ '-promise' %}
{%- do part_list.append(part_id) %} {%- do part_list.append(part_id) %}
{%- set safe_name = part_id.replace('_', '').replace('.', '-').replace(' ', '-') %} {%- set safe_name = part_id.replace('_', '').replace('.', '-').replace(' ', '-') %}
[{{part_id}}] [{{part_id}}]
...@@ -51,11 +39,11 @@ name = {{ safe_name }}.py ...@@ -51,11 +39,11 @@ name = {{ safe_name }}.py
config-report = http_query config-report = http_query
config-url = {{ slave['url'] }} config-url = {{ slave['url'] }}
config-status-code = {{ slave['check-status-code'] }} config-status-code = {{ slave['check-status-code'] }}
config-http-header-dict = {{ slave['check-http-header-dict'] }} config-http-header-dict = {{ json_module.dumps(slave['check-http-header-dict']) }}
config-certificate-expiration-days = {{ slave['check-certificate-expiration-days'] }} config-certificate-expiration-days = {{ slave['check-certificate-expiration-days'] }}
config-failure-amount = {{ slave['failure-amount'] }} config-failure-amount = {{ slave['failure-amount'] }}
config-maximum-elapsed-time = {{ slave['check-maximum-elapsed-time'] }} config-maximum-elapsed-time = {{ slave['check-maximum-elapsed-time'] }}
config-ip-list = {{ slave['check-frontend-ip'] }} config-ip-list = {{ ' '.join(slave['check-frontend-ip-list']) }}
config-json-file = ${surykatka-config-{{ class }}:json} config-json-file = ${surykatka-config-{{ class }}:json}
{%- endfor %} {%- endfor %}
...@@ -72,7 +60,7 @@ db = ${directory:srv}/surykatka-{{ class }}.db ...@@ -72,7 +60,7 @@ db = ${directory:srv}/surykatka-{{ class }}.db
rendered = ${directory:etc}/surykatka-{{ class }}.ini rendered = ${directory:etc}/surykatka-{{ class }}.ini
template = {{ template_surykatka_ini }} template = {{ template_surykatka_ini }}
slave_instance_list = {{ dumps(slave_instance_list) }} slave_instance_list = {{ dumps(slave_instance_list) }}
nameserver = {{ dumps(CONFIGURATION['nameserver']) }} nameserver_list = {{ dumps(CONFIGURATION['nameserver-list']) }}
json = ${directory:srv}/surykatka-{{ class }}.json json = ${directory:srv}/surykatka-{{ class }}.json
{#- timeout is just a bit bigger than class time #} {#- timeout is just a bit bigger than class time #}
timeout = {{ int(class) + 2 }} timeout = {{ int(class) + 2 }}
...@@ -80,7 +68,7 @@ timeout = {{ int(class) + 2 }} ...@@ -80,7 +68,7 @@ timeout = {{ int(class) + 2 }}
context = context =
import json_module json import json_module json
key db :db key db :db
key nameserver :nameserver key nameserver_list :nameserver_list
key slave_instance_list :slave_instance_list key slave_instance_list :slave_instance_list
key timeout :timeout key timeout :timeout
...@@ -110,9 +98,9 @@ cron-entries = ${directory:etc}/cron.d ...@@ -110,9 +98,9 @@ cron-entries = ${directory:etc}/cron.d
name = surykatka-status-{{ class }} name = surykatka-status-{{ class }}
frequency = */2 * * * * frequency = */2 * * * *
command = ${surykatka-status-json-{{ class }}:rendered} command = ${surykatka-status-json-{{ class }}:rendered}
{%- do part_list.append('surykatka-' + class) %} {%- do part_list.append('surykatka-%i'% (class,)) %}
{%- do part_list.append('surykatka-bot-promise-' + class) %} {%- do part_list.append('surykatka-bot-promise-%i' % (class,)) %}
{%- do part_list.append('cron-entry-surykatka-status-' + class) %} {%- do part_list.append('cron-entry-surykatka-status-%i' % (class,)) %}
{%- endfor %} {%- endfor %}
[buildout] [buildout]
...@@ -163,4 +151,4 @@ key = ${slap-connection:key-file} ...@@ -163,4 +151,4 @@ key = ${slap-connection:key-file}
cert = ${slap-connection:cert-file} cert = ${slap-connection:cert-file}
[slap-parameter] [slap-parameter]
{%- endif %} {%- endif %} {#- if slap_software_type == software_type #}
...@@ -16,34 +16,86 @@ extensions = jinja2.ext.do ...@@ -16,34 +16,86 @@ extensions = jinja2.ext.do
extra-context = extra-context =
section slave_information slap-configuration section slave_information slap-configuration
{% set part_list = [] -%} {% set part_list = [] -%}
# Publish information for each slave
{%- set edgebot_software_type = 'edgebot' %} {%- set edgebot_software_type = 'edgebot' %}
{%- set edgebot_quantity = slapparameter_dict.pop('edgebot-quantity', '1') | int %}
{%- set edgebot_list = [] %}
{%- set edgebot_section_list = [] %}
{%- set slave_list_name = 'extra_slave_instance_list' %} {%- set slave_list_name = 'extra_slave_instance_list' %}
{%- set request_dict = {} %} {%- set request_dict = {} %}
{%- set namebase = "edgebot" %} {%- set namebase = "edgebot" %}
{%- set authorized_slave_list = [] %} {%- if 'region-dict' not in slapparameter_dict %}
{%- set monitor_base_url_dict = {} -%} {#- Be nice and allow to work with default configuration #}
{%- do slapparameter_dict.__setitem__('region-dict', {
'1': {
'sla-computer_guid': slap_configuration['computer'],
'state': slap_configuration['instance-state'],
'nameserver-list': slapparameter_dict.get('nameserver-list', []),
'check-frontend-ip-list': slapparameter_dict.get('check-frontend-ip-list', []),
}
}) %}
{%- endif %}
{%- set active_region_list = [] %}
{%- for region_name in sorted(slapparameter_dict['region-dict']) %}
{%- set region_parameter_dict = slapparameter_dict['region-dict'][region_name] %}
{%- if region_parameter_dict.get('state', 'started') == 'started' %}
{%- do active_region_list.append(region_name) %}
{%- endif %}
{%- endfor %}
{%- set authorized_slave_dict = {} %}
{%- set publish_slave_dict_dict = {} %}
{%- for slave in slave_instance_list | sort(attribute='slave_title') %} {%- for slave in slave_instance_list | sort(attribute='slave_title') %}
{%- do authorized_slave_list.append(slave) %} {%- set slave_reference = slave.pop('slave_reference') %}
{%- set publish_dict = {'assigned-region-dict': {}} %}
{%- if '_' in slave %}
{%- set base_slave_dict = json_module.loads(slave.pop('_')) %} {#- XXX: Unsafe! #}
{%- do base_slave_dict.__setitem__('-slave-title', slave['slave_title']) %}
{%- do base_slave_dict.__setitem__('-slave-reference', slave_reference) %}
{%- set slave_region_dict = base_slave_dict.pop('region-dict', {}) %}
{%- if slave_region_dict == {} %}
{%- for region in active_region_list %}
{%- do slave_region_dict.__setitem__(region, {}) %}
{%- endfor %}
{%- endif %}
{%- for region in slave_region_dict %}
{%- if region in active_region_list %}
{%- set region_info = {
'nameserver-list': slapparameter_dict['region-dict'][region].get('nameserver-list') or slapparameter_dict.get('slapparameter_dict') or [],
'check-frontend-ip-list': slave_region_dict[region].get('check-frontend-ip-list') or base_slave_dict.get('check-frontend-ip-list') or slapparameter_dict['region-dict'][region].get('check-frontend-ip-list') or slapparameter_dict.get('check-frontend-ip-list') or [],
} %}
{%- do publish_dict['assigned-region-dict'].__setitem__(region, region_info) %}
{%- set slave_dict = base_slave_dict.copy() %}
{%- do slave_dict.update(region_info) %}
{%- if region not in authorized_slave_dict %}
{%- do authorized_slave_dict.__setitem__(region, [slave_dict]) %}
{%- else %}
{%- do authorized_slave_dict[region].append(slave_dict) %}
{%- endif %}
{%- endif %}
{%- endfor %}
{%- endif %}
{%- do publish_slave_dict_dict.__setitem__(slave_reference, publish_dict) %}
{%- endfor %} {%- endfor %}
{%- set monitor_base_port = int(slap_configuration['configuration.monitor-base-port']) %} {%- set monitor_base_port = int(slap_configuration['configuration.monitor-base-port']) %}
{%- for i in range(1, edgebot_quantity + 1) %} {%- set number = {'i': 1} %}
{%- set edgebot_name = "%s-%s" % (namebase, i) %} {%- for region_name in sorted(slapparameter_dict['region-dict']) %}
{%- set request_section_title = 'request-%s' % edgebot_name %} {%- set region_parameter_dict = slapparameter_dict['region-dict'][region_name] %}
{%- do edgebot_list.append(edgebot_name) %} {%- set edgebot_name = "%s-%s" % (namebase, region_name) %}
{%- do edgebot_section_list.append(request_section_title) %} {%- set request_section_title = 'request-%s' % (hashlib_module.md5(edgebot_name.encode('utf-8')).hexdigest(),) %}
{%- do part_list.append(request_section_title) %} {%- do part_list.append(request_section_title) %}
{%- do request_dict.__setitem__(request_section_title, {#- Note: monitor-httpd-port will vary on regions being added and removed,
{ but this is accepted, as it's only internal trick #}
'config': {'monitor-httpd-port': monitor_base_port + i}, {%- do request_dict.__setitem__(
'name': edgebot_name, request_section_title,
'sla': {}, {
'state': 'started', 'config': {
}) %} 'monitor-httpd-port': monitor_base_port + number['i'],
'check-frontend-ip-list': region_parameter_dict.get('check-frontend-ip-list', []),
'nameserver-list': region_parameter_dict.get('nameserver-list', []),
'extra_slave_instance_list': authorized_slave_dict.get(region_name, [])
},
'name': edgebot_name,
'sla': {'computer_guid': region_parameter_dict['sla-computer_guid']},
'state': region_parameter_dict.get('state', 'started'),
}) %}
{%- do number.__setitem__('i', number['i'] + 1) %}
{%- endfor %} {%- endfor %}
[replicate] [replicate]
...@@ -54,54 +106,58 @@ config-monitor-username = ${monitor-instance-parameter:username} ...@@ -54,54 +106,58 @@ config-monitor-username = ${monitor-instance-parameter:username}
config-monitor-password = ${monitor-htpasswd:passwd} config-monitor-password = ${monitor-htpasswd:passwd}
software-url = ${slap-connection:software-release-url} software-url = ${slap-connection:software-release-url}
software-type = {{edgebot_software_type}} software-type = {{edgebot_software_type}}
return = monitor-base-url
{% for section, edgebot_request in request_dict.items() %} {%- set monitor_base_url_dict = {} -%}
{% for section, edgebot_request in request_dict.items() %}
[{{section}}] [{{section}}]
<= replicate <= replicate
name = {{ edgebot_request.get('name') }} name = {{ edgebot_request['name'] }}
{%- if edgebot_request.get('state') %} state = {{ edgebot_request['state'] }}
state = {{ edgebot_request.get('state') }} {%- if edgebot_request['state'] != 'destroyed' %}
{%- endif%} {%- do monitor_base_url_dict.__setitem__(section, '${' ~ section ~ ':connection-monitor-base-url}') %}
{%- set slave_configuration_dict = slapparameter_dict %} return = monitor-base-url
{%- do slave_configuration_dict.update(edgebot_request.get('config')) %} {%- endif %}
{%- do slave_configuration_dict.__setitem__(slave_list_name, json_module.dumps(authorized_slave_list)) %} {%- set edgebot_configuration_dict = edgebot_request['config'] %}
{%- for config_key, config_value in slave_configuration_dict.items() %} {%- for config_key, config_value in edgebot_configuration_dict.items() %}
config-{{ config_key }} = {{ dumps(config_value) }} config-{{ config_key }} = {{ dumps(config_value) }}
{% endfor -%} {% endfor -%}
{%- if edgebot_request.get('sla') %} {%- for parameter, value in edgebot_request['sla'].items() %}
{%- for parameter, value in edgebot_request.get('sla').items() %}
sla-{{ parameter }} = {{ value }} sla-{{ parameter }} = {{ value }}
{%- endfor %} {%- endfor %}
{%- else %}
# As no SLA was provided, by default it is requested on the same computer
sla-computer_guid = ${slap-connection:computer-id}
{% endif %}
{%- do monitor_base_url_dict.__setitem__(section, '${' ~ section ~ ':connection-monitor-base-url}') -%}
{%- endfor %} {%- endfor %}
{%- set directory_list = [] -%} # Publish information for each slave
{%- for slave_instance in slave_instance_list -%} {%- for slave_reference, publish_dict in publish_slave_dict_dict.items() -%}
{%- set publish_section_title = 'publish-%s' % slave_instance.get('slave_reference') -%} {%- set publish_section_title = 'publish-%s' % (hashlib_module.md5(slave_reference.encode('utf-8')).hexdigest(),) -%}
{%- do part_list.append(publish_section_title) %} {%- do part_list.append(publish_section_title) %}
[{{ publish_section_title }}] [{{ publish_section_title }}]
recipe = slapos.cookbook:publish recipe = slapos.cookbook:publish.serialised
-slave-reference = {{ slave_instance.get('slave_reference') }} available-region-list = {{ dumps(list(active_region_list)) }}
{% endfor %} -slave-reference = {{ slave_reference }}
{%- for key, value in publish_dict.items() %}
{{ key }} = {{ dumps(value) }}
{%- endfor %}
{% endfor %}
[monitor-conf-parameters] [monitor-conf-parameters]
monitor-title = Monitor monitor-title = Monitor
password = ${monitor-htpasswd:passwd} password = ${monitor-htpasswd:passwd}
[monitor-base-url-dict] [monitor-base-url-dict]
{% for key, value in monitor_base_url_dict.items() -%} {% for key, value in monitor_base_url_dict.items() -%}
{{ key }} = {{ value }} {{ key }} = {{ value }}
{% endfor %} {% endfor %}
[buildout] [buildout]
extends = {{ instance_base_monitor }} extends = {{ instance_base_monitor }}
parts += parts +=
slave-test-configuration slave-test-configuration
{% for part in part_list %} {% for part in part_list %}
{{ ' %s' % part }} {{ ' %s' % part }}
{%- endfor %} {%- endfor %}
{%- endif %}
[publish-connection-information]
recipe = slapos.cookbook:publish.serialised
active-region-list = {{ dumps(list(active_region_list)) }}
sla-computer_guid = {{ dumps(slap_configuration['computer']) }}
sla-instance_guid = {{ dumps(slap_configuration['instance-guid']) }}
{%- endif %} {#- if slap_software_type == software_type #}
...@@ -32,6 +32,7 @@ template = ${template-monitor-edgetest:target} ...@@ -32,6 +32,7 @@ template = ${template-monitor-edgetest:target}
rendered = $${buildout:directory}/template-monitor-base-edgetest.cfg rendered = $${buildout:directory}/template-monitor-base-edgetest.cfg
extensions = jinja2.ext.do extensions = jinja2.ext.do
context = import json_module json context = import json_module json
import hashlib_module hashlib
key develop_eggs_directory buildout:develop-eggs-directory key develop_eggs_directory buildout:develop-eggs-directory
key eggs_directory buildout:eggs-directory key eggs_directory buildout:eggs-directory
key slapparameter_dict slap-configuration:configuration key slapparameter_dict slap-configuration:configuration
...@@ -53,6 +54,7 @@ surykatka-binary = ${buildout:bin-directory}/${surykatka:script-name} ...@@ -53,6 +54,7 @@ surykatka-binary = ${buildout:bin-directory}/${surykatka:script-name}
template-surykatka-ini = ${template-surykatka-ini:target} template-surykatka-ini = ${template-surykatka-ini:target}
context = import json_module json context = import json_module json
import hashlib_module hashlib
key develop_eggs_directory buildout:develop-eggs-directory key develop_eggs_directory buildout:develop-eggs-directory
key eggs_directory buildout:eggs-directory key eggs_directory buildout:eggs-directory
section slap_configuration slap-configuration section slap_configuration slap-configuration
...@@ -75,13 +77,8 @@ url = $${slap-connection:server-url} ...@@ -75,13 +77,8 @@ url = $${slap-connection:server-url}
key = $${slap-connection:key-file} key = $${slap-connection:key-file}
cert = $${slap-connection:cert-file} cert = $${slap-connection:cert-file}
# Defaults # Defaults
configuration.check-status-code = 200 configuration.nameserver-list =
configuration.check-http-header-dict = {} configuration.check-frontend-ip-list =
configuration.nameserver =
configuration.check-frontend-ip =
configuration.check-certificate-expiration-days = 15
configuration.check-maximum-elapsed-time = 2
configuration.failure-amount = 2
# use monitor-base-port to have monitor listening on each instance # use monitor-base-port to have monitor listening on each instance
# on different port and also on different port than other services # on different port and also on different port than other services
# it makes it possible to instantiate it correctly on signle IP, for # it makes it possible to instantiate it correctly on signle IP, for
......
...@@ -15,14 +15,17 @@ ...@@ -15,14 +15,17 @@
"description": "Cluster of bots to perform a distributed monitoring ", "description": "Cluster of bots to perform a distributed monitoring ",
"request": "instance-edgetest-input-schema.json", "request": "instance-edgetest-input-schema.json",
"response": "instance-default-output-schema.json", "response": "instance-default-output-schema.json",
"serialisation": "json-in-xml",
"index": 1 "index": 1
}, },
"edgetest-slave": { "edgetest-slave": {
"title": "Edge Test Slave", "title": "Edge Test Slave",
"shared": true,
"software-type": "edgetest", "software-type": "edgetest",
"description": "Cluster of bots to perform a distributed monitoring ", "description": "Cluster of bots to perform a distributed monitoring ",
"request": "instance-edgetest-slave-input-schema.json", "request": "instance-edgetest-slave-input-schema.json",
"response": "instance-default-output-schema.json", "response": "instance-default-output-schema.json",
"serialisation": "json-in-xml",
"index": 2 "index": 2
} }
} }
......
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
INTERVAL = 120 INTERVAL = 120
TIMEOUT = {{ timeout }} TIMEOUT = {{ timeout }}
SQLITE = {{ db }} SQLITE = {{ db }}
{%- set nameserver_list = nameserver.split() %}
{%- if len(nameserver_list) > 0 %} {%- if len(nameserver_list) > 0 %}
NAMESERVER = NAMESERVER =
{%- for nameserver_entry in sorted(nameserver_list) %} {%- for nameserver_entry in sorted(nameserver_list) %}
...@@ -10,7 +9,7 @@ NAMESERVER = ...@@ -10,7 +9,7 @@ NAMESERVER =
{%- endfor %} {%- endfor %}
{% endif %} {% endif %}
URL = URL =
{%- for slave in slave_instance_list | sort(attribute='slave_title') %} {%- for slave in slave_instance_list | sort(attribute='-slave-title') %}
{%- if 'url' in slave %} {%- if 'url' in slave %}
{{ slave['url'] }} {{ slave['url'] }}
{%- endif -%} {%- endif -%}
......
...@@ -26,11 +26,13 @@ ...@@ -26,11 +26,13 @@
############################################################################## ##############################################################################
import glob import glob
import hashlib
import json import json
import os import os
import re import re
import requests import requests
import subprocess import subprocess
import unittest
import xml.etree.ElementTree as ET import xml.etree.ElementTree as ET
from slapos.recipe.librecipe import generateHashFromFiles from slapos.recipe.librecipe import generateHashFromFiles
from slapos.testing.testcase import makeModuleSetUpAndTestCaseClass from slapos.testing.testcase import makeModuleSetUpAndTestCaseClass
...@@ -69,8 +71,10 @@ class MonitorTestMixin: ...@@ -69,8 +71,10 @@ class MonitorTestMixin:
monitor_setup_url_key = 'monitor-setup-url' monitor_setup_url_key = 'monitor-setup-url'
def test_monitor_setup(self): def test_monitor_setup(self):
connection_parameter_dict = self\ connection_parameter_dict_serialised = self\
.computer_partition.getConnectionParameterDict() .computer_partition.getConnectionParameterDict()
connection_parameter_dict = json.loads(
connection_parameter_dict_serialised['_'])
self.assertTrue( self.assertTrue(
self.monitor_setup_url_key in connection_parameter_dict, self.monitor_setup_url_key in connection_parameter_dict,
'%s not in %s' % (self.monitor_setup_url_key, connection_parameter_dict)) '%s not in %s' % (self.monitor_setup_url_key, connection_parameter_dict))
...@@ -136,6 +140,7 @@ class MonitorTestMixin: ...@@ -136,6 +140,7 @@ class MonitorTestMixin:
class EdgeSlaveMixin(MonitorTestMixin): class EdgeSlaveMixin(MonitorTestMixin):
__partition_reference__ = 'edge' __partition_reference__ = 'edge'
instance_max_retry = 20 instance_max_retry = 20
expected_connection_parameter_dict = {}
@classmethod @classmethod
def getInstanceSoftwareType(cls): def getInstanceSoftwareType(cls):
...@@ -143,36 +148,37 @@ class EdgeSlaveMixin(MonitorTestMixin): ...@@ -143,36 +148,37 @@ class EdgeSlaveMixin(MonitorTestMixin):
def requestEdgetestSlave(self, partition_reference, partition_parameter_kw): def requestEdgetestSlave(self, partition_reference, partition_parameter_kw):
software_url = self.getSoftwareURL() software_url = self.getSoftwareURL()
self.slap.request( return self.slap.request(
software_release=software_url, software_release=software_url,
software_type='edgetest', software_type='edgetest',
partition_reference=partition_reference, partition_reference=partition_reference,
partition_parameter_kw=partition_parameter_kw, partition_parameter_kw={'_': json.dumps(partition_parameter_kw)},
shared=True shared=True
) )
def updateSurykatkaDict(self): def updateSurykatkaDict(self):
for class_ in self.surykatka_dict: for instance_reference in self.surykatka_dict:
update_dict = {} for class_ in self.surykatka_dict[instance_reference]:
update_dict['ini-file'] = os.path.join( update_dict = {}
self.bot_partition_path, 'etc', 'surykatka-%s.ini' % (class_,)) update_dict['ini-file'] = os.path.join(
update_dict['json-file'] = os.path.join( self.slap.instance_directory, instance_reference, 'etc',
self.bot_partition_path, 'srv', 'surykatka-%s.json' % (class_,)) 'surykatka-%s.ini' % (class_,))
update_dict['status-json'] = os.path.join( update_dict['json-file'] = os.path.join(
self.bot_partition_path, 'bin', 'surykatka-status-json-%s' % (class_,)) self.slap.instance_directory, instance_reference, 'srv',
update_dict['bot-promise'] = 'surykatka-bot-promise-%s.py' % (class_,) 'surykatka-%s.json' % (class_,))
update_dict['status-cron'] = os.path.join( update_dict['status-json'] = os.path.join(
self.bot_partition_path, 'etc', 'cron.d', 'surykatka-status-%s' % ( self.slap.instance_directory, instance_reference, 'bin',
class_,)) 'surykatka-status-json-%s' % (class_,))
update_dict['db_file'] = os.path.join( update_dict['bot-promise'] = 'surykatka-bot-promise-%s.py' % (class_,)
self.bot_partition_path, 'srv', 'surykatka-%s.db' % (class_,)) update_dict['status-cron'] = os.path.join(
self.surykatka_dict[class_].update(update_dict) self.slap.instance_directory, instance_reference, 'etc',
'cron.d', 'surykatka-status-%s' % (class_,))
def setUp(self): update_dict['db_file'] = os.path.join(
self.bot_partition_path = os.path.join( self.slap.instance_directory, instance_reference, 'srv',
self.slap.instance_directory, 'surykatka-%s.db' % (class_,))
self.__partition_reference__ + '1') self.surykatka_dict[instance_reference][class_].update(update_dict)
self.updateSurykatkaDict()
def setUpMonitorConfigurationList(self):
self.monitor_configuration_list = [ self.monitor_configuration_list = [
{ {
'xmlUrl': 'https://[%s]:9700/public/feed' % (self._ipv6_address,), 'xmlUrl': 'https://[%s]:9700/public/feed' % (self._ipv6_address,),
...@@ -194,43 +200,65 @@ class EdgeSlaveMixin(MonitorTestMixin): ...@@ -194,43 +200,65 @@ class EdgeSlaveMixin(MonitorTestMixin):
} }
] ]
def setUp(self):
self.updateSurykatkaDict()
self.setUpMonitorConfigurationList()
def assertSurykatkaIni(self): def assertSurykatkaIni(self):
expected_init_path_list = []
for instance_reference in self.surykatka_dict:
expected_init_path_list.extend(
[q['ini-file']
for q in self.surykatka_dict[instance_reference].values()])
self.assertEqual( self.assertEqual(
set( set(
glob.glob( glob.glob(
os.path.join(self.bot_partition_path, 'etc', 'surykatka*.ini'))), os.path.join(
{q['ini-file'] for q in self.surykatka_dict.values()} self.slap.instance_directory, '*', 'etc', 'surykatka*.ini'
)
)
),
set(expected_init_path_list)
) )
for info_dict in self.surykatka_dict.values(): for instance_reference in self.surykatka_dict:
self.assertEqual( for info_dict in self.surykatka_dict[instance_reference].values():
info_dict['expected_ini'].strip() % info_dict, self.assertEqual(
open(info_dict['ini-file']).read().strip() info_dict['expected_ini'].strip() % info_dict,
) open(info_dict['ini-file']).read().strip()
)
def assertPromiseContent(self, name, content):
def assertPromiseContent(self, instance_reference, name, content):
promise = open( promise = open(
os.path.join( os.path.join(
self.bot_partition_path, 'etc', 'plugin', name self.slap.instance_directory, instance_reference, 'etc', 'plugin', name
)).read().strip() )).read().strip()
self.assertTrue(content in promise) self.assertTrue(content in promise)
def assertHttpQueryPromiseContent(self, instance_reference, name, content):
hashed = 'http-query-%s-promise.py' % (
hashlib.md5(('_' + name).encode('utf-8')).hexdigest(),)
self.assertPromiseContent(instance_reference, hashed, content)
def assertSurykatkaBotPromise(self): def assertSurykatkaBotPromise(self):
for info_dict in self.surykatka_dict.values(): for instance_reference in self.surykatka_dict:
self.assertPromiseContent( for info_dict in self.surykatka_dict[instance_reference].values():
info_dict['bot-promise'], self.assertPromiseContent(
"'report': 'bot_status'") instance_reference,
self.assertPromiseContent( info_dict['bot-promise'],
info_dict['bot-promise'], "'report': 'bot_status'")
"'json-file': '%s'" % (info_dict['json-file'],) self.assertPromiseContent(
) instance_reference,
info_dict['bot-promise'],
"'json-file': '%s'" % (info_dict['json-file'],),)
def assertSurykatkaCron(self): def assertSurykatkaCron(self):
for info_dict in self.surykatka_dict.values(): for instance_reference in self.surykatka_dict:
self.assertEqual( for info_dict in self.surykatka_dict[instance_reference].values():
'*/2 * * * * %s' % (info_dict['status-json'],), self.assertEqual(
open(info_dict['status-cron']).read().strip() '*/2 * * * * %s' % (info_dict['status-json'],),
) open(info_dict['status-cron']).read().strip()
)
def initiateSurykatkaRun(self): def initiateSurykatkaRun(self):
try: try:
...@@ -239,17 +267,30 @@ class EdgeSlaveMixin(MonitorTestMixin): ...@@ -239,17 +267,30 @@ class EdgeSlaveMixin(MonitorTestMixin):
pass pass
def assertSurykatkaStatusJSON(self): def assertSurykatkaStatusJSON(self):
for info_dict in self.surykatka_dict.values(): for instance_reference in self.surykatka_dict:
if os.path.exists(info_dict['json-file']): for info_dict in self.surykatka_dict[instance_reference].values():
os.unlink(info_dict['json-file']) if os.path.exists(info_dict['json-file']):
try: os.unlink(info_dict['json-file'])
subprocess.check_call(info_dict['status-json']) try:
except subprocess.CalledProcessError as e: subprocess.check_call(info_dict['status-json'])
self.fail('%s failed with code %s and message %s' % ( except subprocess.CalledProcessError as e:
info_dict['status-json'], e.returncode, e.output)) self.fail('%s failed with code %s and message %s' % (
with open(info_dict['json-file']) as fh: info_dict['status-json'], e.returncode, e.output))
status_json = json.load(fh) with open(info_dict['json-file']) as fh:
self.assertIn('bot_status', status_json) status_json = json.load(fh)
self.assertIn('bot_status', status_json)
def assertConnectionParameterDict(self):
serialised = self.requestDefaultInstance().getConnectionParameterDict()
connection_parameter_dict = json.loads(serialised['_'])
# tested elsewhere
connection_parameter_dict.pop('monitor-setup-url', None)
# comes from instance-monitor.cfg.jinja2, not needed here
connection_parameter_dict.pop('server_log_url', None)
self.assertEqual(
self.expected_connection_parameter_dict,
connection_parameter_dict
)
def test(self): def test(self):
# Note: Those tests do not run surykatka and do not do real checks, as # Note: Those tests do not run surykatka and do not do real checks, as
...@@ -266,83 +307,202 @@ class EdgeSlaveMixin(MonitorTestMixin): ...@@ -266,83 +307,202 @@ class EdgeSlaveMixin(MonitorTestMixin):
self.assertSurykatkaBotPromise() self.assertSurykatkaBotPromise()
self.assertSurykatkaPromises() self.assertSurykatkaPromises()
self.assertSurykatkaCron() self.assertSurykatkaCron()
self.assertConnectionParameterDict()
class TestEdge(EdgeSlaveMixin, SlapOSInstanceTestCase): class TestEdge(EdgeSlaveMixin, SlapOSInstanceTestCase):
expected_connection_parameter_dict = {
'active-region-list': ['1'],
'sla-computer_guid': 'local', 'sla-instance_guid': 'local-edge0'}
surykatka_dict = { surykatka_dict = {
2: {'expected_ini': """[SURYKATKA] 'edge1': {
1: {'expected_ini': """[SURYKATKA]
INTERVAL = 120
TIMEOUT = 3
SQLITE = %(db_file)s
URL =
https://www.checkmaximumelapsedtime1.org/"""},
2: {'expected_ini': """[SURYKATKA]
INTERVAL = 120 INTERVAL = 120
TIMEOUT = 4 TIMEOUT = 4
SQLITE = %(db_file)s SQLITE = %(db_file)s
URL = URL =
https://www.erp5.com/ https://www.checkcertificateexpirationdays.org/
https://www.erp5.org/"""} https://www.checkfrontendiplist.org/
https://www.checkhttpheaderdict.org/
https://www.checkstatuscode.org/
https://www.default.org/
https://www.failureamount.org/"""},
20: {'expected_ini': """[SURYKATKA]
INTERVAL = 120
TIMEOUT = 22
SQLITE = %(db_file)s
URL =
https://www.checkmaximumelapsedtime20.org/"""},
}
} }
def assertSurykatkaPromises(self): def assertSurykatkaPromises(self):
self.assertPromiseContent( self.assertHttpQueryPromiseContent(
'http-query-backend-300-promise.py', 'edge1',
"'ip-list': ''") 'checkcertificateexpirationdays',
self.assertPromiseContent( """extra_config_dict = { 'certificate-expiration-days': '20',
'http-query-backend-300-promise.py', 'failure-amount': '2',
"'report': 'http_query'") 'http-header-dict': '{}',
self.assertPromiseContent( 'ip-list': '',
'http-query-backend-300-promise.py', 'json-file': '%s',
"'status-code': '300'") 'maximum-elapsed-time': '2',
self.assertPromiseContent( 'report': 'http_query',
'http-query-backend-300-promise.py', 'status-code': '200',
"'certificate-expiration-days': '15'") 'url': 'https://www.checkcertificateexpirationdays.org/'}""" % (
self.assertPromiseContent( self.surykatka_dict['edge1'][2]['json-file'],))
'http-query-backend-300-promise.py',
"'url': 'https://www.erp5.org/'") self.assertHttpQueryPromiseContent(
self.assertPromiseContent( 'edge1',
'http-query-backend-300-promise.py', 'checkhttpheaderdict',
"'json-file': '%s'" % (self.surykatka_dict[2]['json-file'],) """extra_config_dict = { 'certificate-expiration-days': '15',
'failure-amount': '2',
'http-header-dict': '{"A": "AAA"}',
'ip-list': '',
'json-file': '%s',
'maximum-elapsed-time': '2',
'report': 'http_query',
'status-code': '200',
'url': 'https://www.checkhttpheaderdict.org/'}""" % (
self.surykatka_dict['edge1'][2]['json-file'],))
self.assertHttpQueryPromiseContent(
'edge1',
'checkmaximumelapsedtime1',
"""extra_config_dict = { 'certificate-expiration-days': '15',
'failure-amount': '2',
'http-header-dict': '{}',
'ip-list': '',
'json-file': '%s',
'maximum-elapsed-time': '1',
'report': 'http_query',
'status-code': '200',
'url': 'https://www.checkmaximumelapsedtime1.org/'}""" % (
self.surykatka_dict['edge1'][1]['json-file'],))
self.assertHttpQueryPromiseContent(
'edge1',
'checkmaximumelapsedtime20',
"""extra_config_dict = { 'certificate-expiration-days': '15',
'failure-amount': '2',
'http-header-dict': '{}',
'ip-list': '',
'json-file': '%s',
'maximum-elapsed-time': '20',
'report': 'http_query',
'status-code': '200',
'url': 'https://www.checkmaximumelapsedtime20.org/'}""" % (
self.surykatka_dict['edge1'][20]['json-file'],))
self.assertHttpQueryPromiseContent(
'edge1',
'checkstatuscode',
"""extra_config_dict = { 'certificate-expiration-days': '15',
'failure-amount': '2',
'http-header-dict': '{}',
'ip-list': '',
'json-file': '%s',
'maximum-elapsed-time': '2',
'report': 'http_query',
'status-code': '300',
'url': 'https://www.checkstatuscode.org/'}""" % (
self.surykatka_dict['edge1'][2]['json-file'],))
self.assertHttpQueryPromiseContent(
'edge1',
'default',
"""extra_config_dict = { 'certificate-expiration-days': '15',
'failure-amount': '2',
'http-header-dict': '{}',
'ip-list': '',
'json-file': '%s',
'maximum-elapsed-time': '2',
'report': 'http_query',
'status-code': '200',
'url': 'https://www.default.org/'}""" % (
self.surykatka_dict['edge1'][2]['json-file'],))
self.assertHttpQueryPromiseContent(
'edge1',
'failureamount',
"""extra_config_dict = { 'certificate-expiration-days': '15',
'failure-amount': '10',
'http-header-dict': '{}',
'ip-list': '',
'json-file': '%s',
'maximum-elapsed-time': '2',
'report': 'http_query',
'status-code': '200',
'url': 'https://www.failureamount.org/'}""" % (
self.surykatka_dict['edge1'][2]['json-file'],))
self.assertHttpQueryPromiseContent(
'edge1',
'checkfrontendiplist',
"""extra_config_dict = { 'certificate-expiration-days': '15',
'failure-amount': '2',
'http-header-dict': '{}',
'ip-list': '128.129.130.131 131.134.135.136',
'json-file': '%s',
'maximum-elapsed-time': '2',
'report': 'http_query',
'status-code': '200',
'url': 'https://www.checkfrontendiplist.org/'}""" % (
self.surykatka_dict['edge1'][2]['json-file'],))
def requestEdgetestSlaves(self):
self.requestEdgetestSlave(
'default',
{'url': 'https://www.default.org/'},
) )
self.assertPromiseContent( self.requestEdgetestSlave(
'http-query-backend-300-promise.py', 'checkstatuscode',
"'failure-amount': '2'" {'url': 'https://www.checkstatuscode.org/', 'check-status-code': 300},
) )
self.requestEdgetestSlave(
self.assertPromiseContent( 'checkhttpheaderdict',
'http-query-backend-promise.py', {'url': 'https://www.checkhttpheaderdict.org/',
"'ip-list': ''") 'check-http-header-dict': {"A": "AAA"}},
self.assertPromiseContent(
'http-query-backend-promise.py',
"'report': 'http_query'")
self.assertPromiseContent(
'http-query-backend-promise.py',
"'status-code': '200'")
self.assertPromiseContent(
'http-query-backend-promise.py',
"'certificate-expiration-days': '15'")
self.assertPromiseContent(
'http-query-backend-promise.py',
"'url': 'https://www.erp5.com/'")
self.assertPromiseContent(
'http-query-backend-promise.py',
"'json-file': '%s'" % (self.surykatka_dict[2]['json-file'],)
) )
self.assertPromiseContent( self.requestEdgetestSlave(
'http-query-backend-promise.py', 'checkcertificateexpirationdays',
"'failure-amount': '2'" {'url': 'https://www.checkcertificateexpirationdays.org/',
'check-certificate-expiration-days': '20'},
) )
def requestEdgetestSlaves(self):
self.requestEdgetestSlave( self.requestEdgetestSlave(
'backend', 'checkmaximumelapsedtime20',
{'url': 'https://www.erp5.com/'}, {'url': 'https://www.checkmaximumelapsedtime20.org/',
'check-maximum-elapsed-time': 20},
)
self.requestEdgetestSlave(
'checkmaximumelapsedtime1',
{'url': 'https://www.checkmaximumelapsedtime1.org/',
'check-maximum-elapsed-time': 1},
) )
self.requestEdgetestSlave( self.requestEdgetestSlave(
'backend-300', 'failureamount',
{'url': 'https://www.erp5.org/', 'check-status-code': '300'}, {'url': 'https://www.failureamount.org/', 'failure-amount': '10'},
)
self.requestEdgetestSlave(
'checkfrontendiplist',
{'url': 'https://www.checkfrontendiplist.org/',
'check-frontend-ip-list': ['128.129.130.131', '131.134.135.136']},
) )
class TestEdgeNameserverCheckFrontendIp( class TestEdgeNameserverListCheckFrontendIpList(
EdgeSlaveMixin, SlapOSInstanceTestCase): EdgeSlaveMixin, SlapOSInstanceTestCase):
expected_connection_parameter_dict = {
'active-region-list': ['1'], 'sla-computer_guid': 'local',
'sla-instance_guid': 'local-edge0'}
surykatka_dict = { surykatka_dict = {
2: {'expected_ini': """[SURYKATKA] 'edge1': {
2: {'expected_ini': """[SURYKATKA]
INTERVAL = 120 INTERVAL = 120
TIMEOUT = 4 TIMEOUT = 4
SQLITE = %(db_file)s SQLITE = %(db_file)s
...@@ -352,37 +512,45 @@ NAMESERVER = ...@@ -352,37 +512,45 @@ NAMESERVER =
URL = URL =
https://www.erp5.com/"""} https://www.erp5.com/"""}
}
} }
@classmethod @classmethod
def getInstanceParameterDict(cls): def getInstanceParameterDict(cls):
return { return {'_': json.dumps({
'nameserver': '127.0.1.1 127.0.1.2', 'nameserver-list': ['127.0.1.1', '127.0.1.2'],
'check-frontend-ip': '127.0.0.1 127.0.0.2', 'check-frontend-ip-list': ['127.0.0.1', '127.0.0.2'],
} })}
def assertSurykatkaPromises(self): def assertSurykatkaPromises(self):
self.assertPromiseContent( self.assertHttpQueryPromiseContent(
'http-query-backend-promise.py', 'edge1',
'backend',
"'ip-list': '127.0.0.1 127.0.0.2'") "'ip-list': '127.0.0.1 127.0.0.2'")
self.assertPromiseContent( self.assertHttpQueryPromiseContent(
'http-query-backend-promise.py', 'edge1',
'backend',
"'report': 'http_query'") "'report': 'http_query'")
self.assertPromiseContent( self.assertHttpQueryPromiseContent(
'http-query-backend-promise.py', 'edge1',
'backend',
"'status-code': '200'") "'status-code': '200'")
self.assertPromiseContent( self.assertHttpQueryPromiseContent(
'http-query-backend-promise.py', 'edge1',
'backend',
"'certificate-expiration-days': '15'") "'certificate-expiration-days': '15'")
self.assertPromiseContent( self.assertHttpQueryPromiseContent(
'http-query-backend-promise.py', 'edge1',
'backend',
"'url': 'https://www.erp5.com/'") "'url': 'https://www.erp5.com/'")
self.assertPromiseContent( self.assertHttpQueryPromiseContent(
'http-query-backend-promise.py', 'edge1',
"'json-file': '%s'" % (self.surykatka_dict[2]['json-file'],) 'backend',
"'json-file': '%s'" % (self.surykatka_dict['edge1'][2]['json-file'],)
) )
self.assertPromiseContent( self.assertHttpQueryPromiseContent(
'http-query-backend-promise.py', 'edge1',
'backend',
"'failure-amount': '2'" "'failure-amount': '2'"
) )
...@@ -393,426 +561,833 @@ URL = ...@@ -393,426 +561,833 @@ URL =
) )
class TestEdgeCheckStatusCode(EdgeSlaveMixin, SlapOSInstanceTestCase): class TestEdgeSlaveNotJson(
EdgeSlaveMixin, SlapOSInstanceTestCase):
surykatka_dict = { surykatka_dict = {
2: {'expected_ini': """[SURYKATKA] 'edge1': {
2: {'expected_ini': """[SURYKATKA]
INTERVAL = 120 INTERVAL = 120
TIMEOUT = 4 TIMEOUT = 4
SQLITE = %(db_file)s SQLITE = %(db_file)s
URL = URL =
https://www.erp5.com/ https://www.erp5.com/"""}
https://www.erp5.org/"""} }
} }
@classmethod # non-json provided in slave '_' results with damaging the cluster
def getInstanceParameterDict(cls): # test here is to expose real problem, which has no solution for now
return { @unittest.expectedFailure
'check-status-code': '500', def test(self):
} EdgeSlaveMixin.test()
def assertSurykatkaPromises(self): def assertSurykatkaPromises(self):
self.assertPromiseContent( self.assertHttpQueryPromiseContent(
'http-query-backend-501-promise.py', 'default',
"'ip-list': ''") """extra_config_dict = { 'certificate-expiration-days': '15',
self.assertPromiseContent( 'failure-amount': '2',
'http-query-backend-501-promise.py', 'http-header-dict': '{}',
"'report': 'http_query'") 'ip-list': '',
self.assertPromiseContent( 'json-file': '%s',
'http-query-backend-501-promise.py', 'maximum-elapsed-time': '2',
"'status-code': '501'") 'report': 'http_query',
self.assertPromiseContent( 'status-code': '200',
'http-query-backend-501-promise.py', 'url': 'https://www.default.org/'}""" % (
"'certificate-expiration-days': '15'") self.surykatka_dict[2]['json-file'],))
self.assertPromiseContent(
'http-query-backend-501-promise.py',
"'url': 'https://www.erp5.org/'")
self.assertPromiseContent(
'http-query-backend-501-promise.py',
"'json-file': '%s'" % (self.surykatka_dict[2]['json-file'],)
)
self.assertPromiseContent(
'http-query-backend-501-promise.py',
"'failure-amount': '2'"
)
self.assertPromiseContent(
'http-query-backend-promise.py',
"'ip-list': ''")
self.assertPromiseContent(
'http-query-backend-promise.py',
"'report': 'http_query'")
self.assertPromiseContent(
'http-query-backend-promise.py',
"'status-code': '500'")
self.assertPromiseContent(
'http-query-backend-promise.py',
"'certificate-expiration-days': '15'")
self.assertPromiseContent(
'http-query-backend-promise.py',
"'url': 'https://www.erp5.com/'")
self.assertPromiseContent(
'http-query-backend-promise.py',
"'json-file': '%s'" % (self.surykatka_dict[2]['json-file'],)
)
self.assertPromiseContent(
'http-query-backend-promise.py',
"'failure-amount': '2'"
)
def requestEdgetestSlaves(self): def requestEdgetestSlaves(self):
self.requestEdgetestSlave( self.requestEdgetestSlave(
'backend', 'default',
{'url': 'https://www.erp5.com/'}, {'url': 'https://www.default.org/'},
) )
self.requestEdgetestSlave( software_url = self.getSoftwareURL()
'backend-501', self.slap.request(
{'url': 'https://www.erp5.org/', 'check-status-code': '501'}, software_release=software_url,
software_type='edgetest',
partition_reference='notajson',
partition_parameter_kw={'_': 'notajson'},
shared=True
) )
class TestEdgeCheckHTTPHeaderDict(EdgeSlaveMixin, SlapOSInstanceTestCase): class TestEdgeRegion(EdgeSlaveMixin, SlapOSInstanceTestCase):
surykatka_dict = { def setUpMonitorConfigurationList(self):
2: {'expected_ini': """[SURYKATKA] self.monitor_configuration_list = [
INTERVAL = 120 {
TIMEOUT = 4 'htmlUrl': 'https://[%s]:9700/public/feed' % (self._ipv6_address,),
SQLITE = %(db_file)s 'text': 'testing partition 0',
URL = 'title': 'testing partition 0',
https://www.erp5.com/ 'type': 'rss',
https://www.erp5.org/"""} 'url': 'https://[%s]:9700/share/private/' % (self._ipv6_address,),
} 'version': 'RSS',
'xmlUrl': 'https://[%s]:9700/public/feed' % (self._ipv6_address,)
},
{
'htmlUrl': 'https://[%s]:9701/public/feed' % (self._ipv6_address,),
'text': 'edgebot-Region One',
'title': 'edgebot-Region One',
'type': 'rss',
'url': 'https://[%s]:9701/share/private/' % (self._ipv6_address,),
'version': 'RSS',
'xmlUrl': 'https://[%s]:9701/public/feed' % (self._ipv6_address,)
},
{
'htmlUrl': 'https://[%s]:9702/public/feed' % (self._ipv6_address,),
'text': 'edgebot-Region Three',
'title': 'edgebot-Region Three',
'type': 'rss',
'url': 'https://[%s]:9702/share/private/' % (self._ipv6_address,),
'version': 'RSS',
'xmlUrl': 'https://[%s]:9702/public/feed' % (self._ipv6_address,)
},
{
'htmlUrl': 'https://[%s]:9703/public/feed' % (self._ipv6_address,),
'text': 'edgebot-Region Two',
'title': 'edgebot-Region Two',
'type': 'rss',
'url': 'https://[%s]:9703/share/private/' % (self._ipv6_address,),
'version': 'RSS',
'xmlUrl': 'https://[%s]:9703/public/feed' % (self._ipv6_address,)
}
]
@classmethod @classmethod
def getInstanceParameterDict(cls): def setUpClassParameter(cls):
return { cls.instance_parameter_dict = {
'check-http-header-dict': 'region-dict': {
'{"B": "BBB"}', 'Region One': {
'sla-computer_guid': 'local',
'state': 'started',
'nameserver-list': ['127.0.1.1', '127.0.1.2'],
'check-frontend-ip-list': ['127.0.1.3', '127.0.1.4'],
},
'Region Two': {
'sla-computer_guid': 'local',
'state': 'started',
'nameserver-list': ['127.0.2.1', '127.0.2.2'],
},
'Region Three': {
'sla-computer_guid': 'local',
'state': 'started',
'check-frontend-ip-list': ['127.0.3.1', '127.0.3.2'],
}
}
} }
cls.expected_connection_parameter_dict = {
'active-region-list': [
'Region One', 'Region Three', 'Region Two'],
'sla-computer_guid': 'local', 'sla-instance_guid': 'local-edge0'}
def assertSurykatkaPromises(self): @classmethod
self.assertPromiseContent( def setUpClass(cls):
'http-query-backend-http-header-promise.py', cls.setUpClassParameter()
"'ip-list': ''") super().setUpClass()
self.assertPromiseContent(
'http-query-backend-http-header-promise.py', def setUpParameter(self):
"'report': 'http_query'") self.surykatka_dict = {
self.assertPromiseContent( 'edge1': {
'http-query-backend-http-header-promise.py', 2: {'expected_ini': """[SURYKATKA]
"'status-code': '200'")
self.assertPromiseContent(
'http-query-backend-http-header-promise.py',
"'http-header-dict': '{\"A\": \"AAA\"}'")
self.assertPromiseContent(
'http-query-backend-http-header-promise.py',
"'certificate-expiration-days': '15'")
self.assertPromiseContent(
'http-query-backend-http-header-promise.py',
"'url': 'https://www.erp5.org/'")
self.assertPromiseContent(
'http-query-backend-http-header-promise.py',
"'json-file': '%s'" % (self.surykatka_dict[2]['json-file'],)
)
self.assertPromiseContent(
'http-query-backend-http-header-promise.py',
"'failure-amount': '2'"
)
self.assertPromiseContent(
'http-query-backend-promise.py',
"'ip-list': ''")
self.assertPromiseContent(
'http-query-backend-promise.py',
"'report': 'http_query'")
self.assertPromiseContent(
'http-query-backend-promise.py',
"'status-code': '200'")
self.assertPromiseContent(
'http-query-backend-promise.py',
"'http-header-dict': '{\"B\": \"BBB\"}'")
self.assertPromiseContent(
'http-query-backend-promise.py',
"'certificate-expiration-days': '15'")
self.assertPromiseContent(
'http-query-backend-promise.py',
"'url': 'https://www.erp5.com/'")
self.assertPromiseContent(
'http-query-backend-promise.py',
"'json-file': '%s'" % (self.surykatka_dict[2]['json-file'],)
)
self.assertPromiseContent(
'http-query-backend-promise.py',
"'failure-amount': '2'"
)
def requestEdgetestSlaves(self):
self.requestEdgetestSlave(
'backend',
{'url': 'https://www.erp5.com/'},
)
self.requestEdgetestSlave(
'backend-http-header',
{'url': 'https://www.erp5.org/', 'check-http-header-dict': '{"A": "AAA"}'},
)
class TestEdgeCheckCertificateExpirationDays(
EdgeSlaveMixin, SlapOSInstanceTestCase):
surykatka_dict = {
2: {'expected_ini': """[SURYKATKA]
INTERVAL = 120 INTERVAL = 120
TIMEOUT = 4 TIMEOUT = 4
SQLITE = %(db_file)s SQLITE = %(db_file)s
URL = NAMESERVER =
https://www.erp5.com/ 127.0.1.1
https://www.erp5.org/"""} 127.0.1.2
}
@classmethod
def getInstanceParameterDict(cls):
return {
'check-certificate-expiration-days': '10',
}
def assertSurykatkaPromises(self):
self.assertPromiseContent(
'http-query-backend-20-promise.py',
"'ip-list': ''")
self.assertPromiseContent(
'http-query-backend-20-promise.py',
"'report': 'http_query'")
self.assertPromiseContent(
'http-query-backend-20-promise.py',
"'status-code': '200'")
self.assertPromiseContent(
'http-query-backend-20-promise.py',
"'certificate-expiration-days': '20'")
self.assertPromiseContent(
'http-query-backend-20-promise.py',
"'url': 'https://www.erp5.org/'")
self.assertPromiseContent(
'http-query-backend-20-promise.py',
"'json-file': '%s'" % (self.surykatka_dict[2]['json-file'],)
)
self.assertPromiseContent(
'http-query-backend-20-promise.py',
"'failure-amount': '2'"
)
self.assertPromiseContent(
'http-query-backend-promise.py',
"'ip-list': ''")
self.assertPromiseContent(
'http-query-backend-promise.py',
"'report': 'http_query'")
self.assertPromiseContent(
'http-query-backend-promise.py',
"'status-code': '200'")
self.assertPromiseContent(
'http-query-backend-promise.py',
"'certificate-expiration-days': '10'")
self.assertPromiseContent(
'http-query-backend-promise.py',
"'url': 'https://www.erp5.com/'")
self.assertPromiseContent(
'http-query-backend-promise.py',
"'json-file': '%s'" % (self.surykatka_dict[2]['json-file'],)
)
self.assertPromiseContent(
'http-query-backend-promise.py',
"'failure-amount': '2'"
)
def requestEdgetestSlaves(self):
self.requestEdgetestSlave(
'backend',
{'url': 'https://www.erp5.com/'},
)
self.requestEdgetestSlave(
'backend-20',
{'url': 'https://www.erp5.org/',
'check-certificate-expiration-days': '20'},
)
class TestEdgeCheckMaximumElapsedTime(
EdgeSlaveMixin, SlapOSInstanceTestCase):
surykatka_dict = {
5: {'expected_ini': """[SURYKATKA]
INTERVAL = 120
TIMEOUT = 7
SQLITE = %(db_file)s
URL = URL =
https://www.erp5.com/"""}, https://www.all.org/
20: {'expected_ini': """[SURYKATKA] https://www.globalcheck.org/
https://www.onetwo.org/
https://www.specificcheck.org/
https://www.specificoverride.org/"""},
},
'edge2': {
2: {'expected_ini': """[SURYKATKA]
INTERVAL = 120 INTERVAL = 120
TIMEOUT = 22 TIMEOUT = 4
SQLITE = %(db_file)s SQLITE = %(db_file)s
URL = URL =
https://www.erp5.org/"""}, https://www.all.org/
1: {'expected_ini': """[SURYKATKA] https://www.three.org/"""},
},
'edge3': {
2: {'expected_ini': """[SURYKATKA]
INTERVAL = 120 INTERVAL = 120
TIMEOUT = 3 TIMEOUT = 4
SQLITE = %(db_file)s SQLITE = %(db_file)s
NAMESERVER =
127.0.2.1
127.0.2.2
URL = URL =
https://www.erp5.net/"""} https://www.all.org/
} https://www.onetwo.org/
https://www.parialmiss.org/
https://www.specificoverride.org/"""},
}
}
def setUp(self):
self.setUpParameter()
super().setUp()
@classmethod @classmethod
def getInstanceParameterDict(cls): def getInstanceParameterDict(cls):
return { return {'_': json.dumps(cls.instance_parameter_dict)}
'check-maximum-elapsed-time': '5',
} slave_parameter_dict_dict = {
'all': {
'url': 'https://www.all.org/'
},
'onetwo': {
'url': 'https://www.onetwo.org/',
'region-dict': {'Region One': {}, 'Region Two': {}}
},
'three': {
'url': 'https://www.three.org/',
'region-dict': {'Region Three': {}}
},
'missed': {
'url': 'https://www.missed.org/',
'region-dict': {'Region Non Existing': {}}
},
'partialmiss': {
'url': 'https://www.parialmiss.org/',
'region-dict': {'Region Two': {}, 'Region Non Existing': {}}
},
'specificcheck': {
'url': 'https://www.specificcheck.org/',
'region-dict': {
'Region One': {'check-frontend-ip-list': ['99.99.99.1', '99.99.99.2']}}
},
'globalcheck': {
'url': 'https://www.globalcheck.org/',
'check-frontend-ip-list': ['99.99.99.3', '99.99.99.4'],
'region-dict': {'Region One': {}}
},
'specificoverride': {
'url': 'https://www.specificoverride.org/',
'check-frontend-ip-list': ['99.99.99.5', '99.99.99.6'],
'region-dict': {
'Region One': {'check-frontend-ip-list': ['99.99.99.7', '99.99.99.8']},
'Region Two': {}}
},
}
def requestEdgetestSlaves(self):
for reference, parameter_dict in self.slave_parameter_dict_dict.items():
self.requestEdgetestSlave(reference, parameter_dict)
def assertSurykatkaPromises(self): def assertSurykatkaPromises(self):
self.assertPromiseContent( self.assertHttpQueryPromiseContent(
'http-query-backend-20-promise.py', 'edge1',
"'ip-list': ''") 'all',
self.assertPromiseContent( """extra_config_dict = { 'certificate-expiration-days': '15',
'http-query-backend-20-promise.py', 'failure-amount': '2',
"'report': 'http_query'") 'http-header-dict': '{}',
self.assertPromiseContent( 'ip-list': '127.0.1.3 127.0.1.4',
'http-query-backend-20-promise.py', 'json-file': '%s',
"'status-code': '200'") 'maximum-elapsed-time': '2',
self.assertPromiseContent( 'report': 'http_query',
'http-query-backend-20-promise.py', 'status-code': '200',
"'maximum-elapsed-time': '20'") 'url': 'https://www.all.org/'}""" % (
self.assertPromiseContent( self.surykatka_dict['edge1'][2]['json-file'],))
'http-query-backend-20-promise.py',
"'url': 'https://www.erp5.org/'") self.assertHttpQueryPromiseContent(
self.assertPromiseContent( 'edge1',
'http-query-backend-20-promise.py', 'specificcheck',
"'json-file': '%s'" % (self.surykatka_dict[20]['json-file'],) """extra_config_dict = { 'certificate-expiration-days': '15',
) 'failure-amount': '2',
self.assertPromiseContent( 'http-header-dict': '{}',
'http-query-backend-20-promise.py', 'ip-list': '99.99.99.1 99.99.99.2',
"'failure-amount': '2'" 'json-file': '%s',
) 'maximum-elapsed-time': '2',
'report': 'http_query',
'status-code': '200',
'url': 'https://www.specificcheck.org/'}""" % (
self.surykatka_dict['edge1'][2]['json-file'],))
self.assertHttpQueryPromiseContent(
'edge1',
'globalcheck',
"""extra_config_dict = { 'certificate-expiration-days': '15',
'failure-amount': '2',
'http-header-dict': '{}',
'ip-list': '99.99.99.3 99.99.99.4',
'json-file': '%s',
'maximum-elapsed-time': '2',
'report': 'http_query',
'status-code': '200',
'url': 'https://www.globalcheck.org/'}""" % (
self.surykatka_dict['edge1'][2]['json-file'],))
self.assertHttpQueryPromiseContent(
'edge1',
'specificoverride',
"""extra_config_dict = { 'certificate-expiration-days': '15',
'failure-amount': '2',
'http-header-dict': '{}',
'ip-list': '99.99.99.7 99.99.99.8',
'json-file': '%s',
'maximum-elapsed-time': '2',
'report': 'http_query',
'status-code': '200',
'url': 'https://www.specificoverride.org/'}""" % (
self.surykatka_dict['edge1'][2]['json-file'],))
self.assertHttpQueryPromiseContent(
'edge1',
'onetwo',
"""extra_config_dict = { 'certificate-expiration-days': '15',
'failure-amount': '2',
'http-header-dict': '{}',
'ip-list': '127.0.1.3 127.0.1.4',
'json-file': '%s',
'maximum-elapsed-time': '2',
'report': 'http_query',
'status-code': '200',
'url': 'https://www.onetwo.org/'}""" % (
self.surykatka_dict['edge1'][2]['json-file'],))
self.assertHttpQueryPromiseContent(
'edge2',
'all',
"""extra_config_dict = { 'certificate-expiration-days': '15',
'failure-amount': '2',
'http-header-dict': '{}',
'ip-list': '127.0.3.1 127.0.3.2',
'json-file': '%s',
'maximum-elapsed-time': '2',
'report': 'http_query',
'status-code': '200',
'url': 'https://www.all.org/'}""" % (
self.surykatka_dict['edge2'][2]['json-file'],))
self.assertHttpQueryPromiseContent(
'edge2',
'three',
"""extra_config_dict = { 'certificate-expiration-days': '15',
'failure-amount': '2',
'http-header-dict': '{}',
'ip-list': '127.0.3.1 127.0.3.2',
'json-file': '%s',
'maximum-elapsed-time': '2',
'report': 'http_query',
'status-code': '200',
'url': 'https://www.three.org/'}""" % (
self.surykatka_dict['edge2'][2]['json-file'],))
self.assertHttpQueryPromiseContent(
'edge3',
'all',
"""extra_config_dict = { 'certificate-expiration-days': '15',
'failure-amount': '2',
'http-header-dict': '{}',
'ip-list': '',
'json-file': '%s',
'maximum-elapsed-time': '2',
'report': 'http_query',
'status-code': '200',
'url': 'https://www.all.org/'}""" % (
self.surykatka_dict['edge3'][2]['json-file'],))
self.assertHttpQueryPromiseContent(
'edge3',
'onetwo',
"""extra_config_dict = { 'certificate-expiration-days': '15',
'failure-amount': '2',
'http-header-dict': '{}',
'ip-list': '',
'json-file': '%s',
'maximum-elapsed-time': '2',
'report': 'http_query',
'status-code': '200',
'url': 'https://www.onetwo.org/'}""" % (
self.surykatka_dict['edge3'][2]['json-file'],))
self.assertHttpQueryPromiseContent(
'edge3',
'partialmiss',
"""extra_config_dict = { 'certificate-expiration-days': '15',
'failure-amount': '2',
'http-header-dict': '{}',
'ip-list': '',
'json-file': '%s',
'maximum-elapsed-time': '2',
'report': 'http_query',
'status-code': '200',
'url': 'https://www.parialmiss.org/'}""" % (
self.surykatka_dict['edge3'][2]['json-file'],))
self.assertHttpQueryPromiseContent(
'edge3',
'specificoverride',
"""extra_config_dict = { 'certificate-expiration-days': '15',
'failure-amount': '2',
'http-header-dict': '{}',
'ip-list': '99.99.99.5 99.99.99.6',
'json-file': '%s',
'maximum-elapsed-time': '2',
'report': 'http_query',
'status-code': '200',
'url': 'https://www.specificoverride.org/'}""" % (
self.surykatka_dict['edge3'][2]['json-file'],))
self.assertPromiseContent( def test(self):
'http-query-backend-default-promise.py', super(TestEdgeRegion, self).test()
"'ip-list': ''") self.assertSlaveConnectionParameterDict()
self.assertPromiseContent(
'http-query-backend-default-promise.py', maxDiff = None
"'report': 'http_query'")
self.assertPromiseContent( expected_slave_connection_parameter_dict_dict = {
'http-query-backend-default-promise.py', 'all': {
"'status-code': '200'") 'available-region-list': [
self.assertPromiseContent( 'Region One', 'Region Three', 'Region Two'],
'http-query-backend-default-promise.py', 'assigned-region-dict': {
"'maximum-elapsed-time': '5'") 'Region One': {
self.assertPromiseContent( 'check-frontend-ip-list': ['127.0.1.3', '127.0.1.4'],
'http-query-backend-default-promise.py', 'nameserver-list': ['127.0.1.1', '127.0.1.2']
"'url': 'https://www.erp5.com/'") },
self.assertPromiseContent( 'Region Three': {
'http-query-backend-default-promise.py', 'check-frontend-ip-list': ['127.0.3.1', '127.0.3.2'],
"'json-file': '%s'" % (self.surykatka_dict[5]['json-file'],) 'nameserver-list': []
) },
self.assertPromiseContent( 'Region Two': {
'http-query-backend-default-promise.py', 'check-frontend-ip-list': [],
"'failure-amount': '2'" 'nameserver-list': ['127.0.2.1', '127.0.2.2']
) }
}
},
'onetwo': {
'available-region-list': [
'Region One', 'Region Three', 'Region Two'],
'assigned-region-dict': {
'Region One': {
'check-frontend-ip-list': ['127.0.1.3', '127.0.1.4'],
'nameserver-list': ['127.0.1.1', '127.0.1.2']
},
'Region Two': {
'check-frontend-ip-list': [],
'nameserver-list': ['127.0.2.1', '127.0.2.2']
}
}
},
'specificcheck': {
'assigned-region-dict': {
'Region One': {
'check-frontend-ip-list': ['99.99.99.1', '99.99.99.2'],
'nameserver-list': ['127.0.1.1', '127.0.1.2']
}
},
'available-region-list': [
'Region One', 'Region Three', 'Region Two']
},
'specificoverride': {
'assigned-region-dict': {
'Region One': {
'check-frontend-ip-list': ['99.99.99.7', '99.99.99.8'],
'nameserver-list': ['127.0.1.1', '127.0.1.2']
},
'Region Two': {
'check-frontend-ip-list': ['99.99.99.5', '99.99.99.6'],
'nameserver-list': ['127.0.2.1', '127.0.2.2']
}
},
'available-region-list': [
'Region One', 'Region Three', 'Region Two']
},
'three': {
'available-region-list': [
'Region One', 'Region Three', 'Region Two'],
'assigned-region-dict': {
'Region Three': {
'check-frontend-ip-list': ['127.0.3.1', '127.0.3.2'],
'nameserver-list': []
}
}
},
'globalcheck': {
'assigned-region-dict': {
'Region One': {
'check-frontend-ip-list': ['99.99.99.3', '99.99.99.4'],
'nameserver-list': ['127.0.1.1', '127.0.1.2']
}
},
'available-region-list': [
'Region One', 'Region Three', 'Region Two']
},
'missed': {
'available-region-list': [
'Region One', 'Region Three', 'Region Two'],
'assigned-region-dict': {
}
},
'partialmiss': {
'available-region-list': [
'Region One', 'Region Three', 'Region Two'],
'assigned-region-dict': {
'Region Two': {
'check-frontend-ip-list': [],
'nameserver-list': ['127.0.2.1', '127.0.2.2']
}
}
}
}
self.assertPromiseContent( def assertSlaveConnectionParameterDict(self):
'http-query-backend-1-promise.py', slave_connection_parameter_dict_dict = {}
"'ip-list': ''") for reference, parameter_dict in self.slave_parameter_dict_dict.items():
self.assertPromiseContent( slave_connection_parameter_dict_dict[
'http-query-backend-1-promise.py', reference] = self.requestEdgetestSlave(
"'report': 'http_query'") reference, parameter_dict).getConnectionParameterDict()
self.assertPromiseContent( # unload the json
'http-query-backend-1-promise.py', slave_connection_parameter_dict_dict[
"'status-code': '200'") reference] = json.loads(
self.assertPromiseContent( slave_connection_parameter_dict_dict[reference].pop('_'))
'http-query-backend-1-promise.py', self.assertEqual(
"'maximum-elapsed-time': '1'") self.expected_slave_connection_parameter_dict_dict,
self.assertPromiseContent( slave_connection_parameter_dict_dict
'http-query-backend-1-promise.py',
"'url': 'https://www.erp5.net/'")
self.assertPromiseContent(
'http-query-backend-1-promise.py',
"'json-file': '%s'" % (self.surykatka_dict[1]['json-file'],)
)
self.assertPromiseContent(
'http-query-backend-1-promise.py',
"'failure-amount': '2'"
) )
def requestEdgetestSlaves(self):
self.requestEdgetestSlave(
'backend-default',
{'url': 'https://www.erp5.com/'},
)
self.requestEdgetestSlave(
'backend-20',
{'url': 'https://www.erp5.org/',
'check-maximum-elapsed-time': '20'},
)
self.requestEdgetestSlave(
'backend-1',
{'url': 'https://www.erp5.net/',
'check-maximum-elapsed-time': '1'},
)
class TestEdgeRegionDestroyed(TestEdgeRegion):
def setUpMonitorConfigurationList(self):
# already for destroyed case, as test_monitor_setup will be called after
# test
self.monitor_configuration_list = [
{
'htmlUrl': 'https://[%s]:9700/public/feed' % (self._ipv6_address,),
'text': 'testing partition 0',
'title': 'testing partition 0',
'type': 'rss',
'url': 'https://[%s]:9700/share/private/' % (self._ipv6_address,),
'version': 'RSS',
'xmlUrl': 'https://[%s]:9700/public/feed' % (self._ipv6_address,)
},
{
'htmlUrl': 'https://[%s]:9701/public/feed' % (self._ipv6_address,),
'text': 'edgebot-Region One',
'title': 'edgebot-Region One',
'type': 'rss',
'url': 'https://[%s]:9701/share/private/' % (self._ipv6_address,),
'version': 'RSS',
'xmlUrl': 'https://[%s]:9701/public/feed' % (self._ipv6_address,)
},
{
'htmlUrl': 'https://[%s]:9703/public/feed' % (self._ipv6_address,),
'text': 'edgebot-Region Two',
'title': 'edgebot-Region Two',
'type': 'rss',
'url': 'https://[%s]:9703/share/private/' % (self._ipv6_address,),
'version': 'RSS',
'xmlUrl': 'https://[%s]:9703/public/feed' % (self._ipv6_address,)
}
]
class TestEdgeFailureAmount( def test(self):
EdgeSlaveMixin, SlapOSInstanceTestCase): super(TestEdgeRegionDestroyed, self).test()
surykatka_dict = { # hack around @classmethod
2: {'expected_ini': """[SURYKATKA] self.__class__.instance_parameter_dict[
'region-dict']['Region Three']['state'] = 'destroyed'
# Region was removed
self.__class__.expected_connection_parameter_dict[
'active-region-list'].remove('Region Three')
self.__class__._instance_parameter_dict = self.getInstanceParameterDict()
self.requestDefaultInstance()
# give time to stabilise the tree
self.slap.waitForInstance(max_retry=4)
self.assertConnectionParameterDict()
self.expected_slave_connection_parameter_dict_dict = {
'all': {
'available-region-list': [
'Region One', 'Region Two'],
'assigned-region-dict': {
'Region One': {
'check-frontend-ip-list': ['127.0.1.3', '127.0.1.4'],
'nameserver-list': ['127.0.1.1', '127.0.1.2']
},
'Region Two': {
'check-frontend-ip-list': [],
'nameserver-list': ['127.0.2.1', '127.0.2.2']
}
}
},
'onetwo': {
'available-region-list': [
'Region One', 'Region Two'],
'assigned-region-dict': {
'Region One': {
'check-frontend-ip-list': ['127.0.1.3', '127.0.1.4'],
'nameserver-list': ['127.0.1.1', '127.0.1.2']
},
'Region Two': {
'check-frontend-ip-list': [],
'nameserver-list': ['127.0.2.1', '127.0.2.2']
}
}
},
'specificcheck': {
'assigned-region-dict': {
'Region One': {
'check-frontend-ip-list': ['99.99.99.1', '99.99.99.2'],
'nameserver-list': ['127.0.1.1', '127.0.1.2']
}
},
'available-region-list': [
'Region One', 'Region Two']
},
'specificoverride': {
'assigned-region-dict': {
'Region One': {
'check-frontend-ip-list': ['99.99.99.7', '99.99.99.8'],
'nameserver-list': ['127.0.1.1', '127.0.1.2']
},
'Region Two': {
'check-frontend-ip-list': ['99.99.99.5', '99.99.99.6'],
'nameserver-list': ['127.0.2.1', '127.0.2.2']
}
},
'available-region-list': [
'Region One', 'Region Two']
},
'three': {
'assigned-region-dict': {},
'available-region-list': [
'Region One', 'Region Two'],
},
'globalcheck': {
'assigned-region-dict': {
'Region One': {
'check-frontend-ip-list': ['99.99.99.3', '99.99.99.4'],
'nameserver-list': ['127.0.1.1', '127.0.1.2']
}
},
'available-region-list': [
'Region One', 'Region Two']
},
'missed': {
'available-region-list': [
'Region One', 'Region Two'],
'assigned-region-dict': {
}
},
'partialmiss': {
'available-region-list': [
'Region One', 'Region Two'],
'assigned-region-dict': {
'Region Two': {
'check-frontend-ip-list': [],
'nameserver-list': ['127.0.2.1', '127.0.2.2']
}
}
}
}
self.assertSlaveConnectionParameterDict()
class TestEdgeRegionAdded(TestEdgeRegion):
def setUpMonitorConfigurationList(self):
# already for added case, as test_monitor_setup will be called after test
self.monitor_configuration_list = [
{
'htmlUrl': 'https://[%s]:9700/public/feed' % (self._ipv6_address,),
'text': 'testing partition 0',
'title': 'testing partition 0',
'type': 'rss',
'url': 'https://[%s]:9700/share/private/' % (self._ipv6_address,),
'version': 'RSS',
'xmlUrl': 'https://[%s]:9700/public/feed' % (self._ipv6_address,)
},
{
'htmlUrl': 'https://[%s]:9701/public/feed' % (self._ipv6_address,),
'text': 'edgebot-Region Four',
'title': 'edgebot-Region Four',
'type': 'rss',
'url': 'https://[%s]:9701/share/private/' % (self._ipv6_address,),
'version': 'RSS',
'xmlUrl': 'https://[%s]:9701/public/feed' % (self._ipv6_address,)
},
{
'htmlUrl': 'https://[%s]:9702/public/feed' % (self._ipv6_address,),
'text': 'edgebot-Region One',
'title': 'edgebot-Region One',
'type': 'rss',
'url': 'https://[%s]:9702/share/private/' % (self._ipv6_address,),
'version': 'RSS',
'xmlUrl': 'https://[%s]:9702/public/feed' % (self._ipv6_address,)
},
{
'htmlUrl': 'https://[%s]:9703/public/feed' % (self._ipv6_address,),
'text': 'edgebot-Region Three',
'title': 'edgebot-Region Three',
'type': 'rss',
'url': 'https://[%s]:9703/share/private/' % (self._ipv6_address,),
'version': 'RSS',
'xmlUrl': 'https://[%s]:9703/public/feed' % (self._ipv6_address,)
},
{
'htmlUrl': 'https://[%s]:9704/public/feed' % (self._ipv6_address,),
'text': 'edgebot-Region Two',
'title': 'edgebot-Region Two',
'type': 'rss',
'url': 'https://[%s]:9704/share/private/' % (self._ipv6_address,),
'version': 'RSS',
'xmlUrl': 'https://[%s]:9704/public/feed' % (self._ipv6_address,)
}
]
def test(self):
super(TestEdgeRegionAdded, self).test()
self.__class__.instance_parameter_dict['region-dict']['Region Four'] = {
'sla-computer_guid': 'local',
'state': 'started',
'nameserver-list': ['127.0.4.1', '127.0.4.2'],
'check-frontend-ip-list': ['127.0.4.3', '127.0.4.4'],
}
# Region was added
self.__class__.expected_connection_parameter_dict[
'active-region-list'].insert(0, 'Region Four')
self.__class__._instance_parameter_dict = self.getInstanceParameterDict()
self.requestDefaultInstance()
# give time to stabilise the tree, 6 times as new node is added
self.slap.waitForInstance(max_retry=6)
# XXX: few more times, but ignoring good result from promises, as there is
# "Unknown Instance" of just added node which is not caught by any
# promise, but in the end it shall get better
for f in range(5):
try:
self.slap.waitForInstance()
except Exception:
pass
self.slap.waitForInstance()
self.assertConnectionParameterDict()
self.expected_slave_connection_parameter_dict_dict = {
'all': {
'available-region-list': [
'Region Four', 'Region One', 'Region Three', 'Region Two'],
'assigned-region-dict': {
'Region Four': {
'check-frontend-ip-list': ['127.0.4.3', '127.0.4.4'],
'nameserver-list': ['127.0.4.1', '127.0.4.2']
},
'Region One': {
'check-frontend-ip-list': ['127.0.1.3', '127.0.1.4'],
'nameserver-list': ['127.0.1.1', '127.0.1.2']
},
'Region Three': {
'check-frontend-ip-list': ['127.0.3.1', '127.0.3.2'],
'nameserver-list': []
},
'Region Two': {
'check-frontend-ip-list': [],
'nameserver-list': ['127.0.2.1', '127.0.2.2']
}
}
},
'onetwo': {
'available-region-list': [
'Region Four', 'Region One', 'Region Three', 'Region Two'],
'assigned-region-dict': {
'Region One': {
'check-frontend-ip-list': ['127.0.1.3', '127.0.1.4'],
'nameserver-list': ['127.0.1.1', '127.0.1.2']
},
'Region Two': {
'check-frontend-ip-list': [],
'nameserver-list': ['127.0.2.1', '127.0.2.2']
}
}
},
'specificcheck': {
'available-region-list': [
'Region Four', 'Region One', 'Region Three', 'Region Two'],
'assigned-region-dict': {
'Region One': {
'check-frontend-ip-list': ['99.99.99.1', '99.99.99.2'],
'nameserver-list': ['127.0.1.1', '127.0.1.2']
}
},
},
'specificoverride': {
'available-region-list': [
'Region Four', 'Region One', 'Region Three', 'Region Two'],
'assigned-region-dict': {
'Region One': {
'check-frontend-ip-list': ['99.99.99.7', '99.99.99.8'],
'nameserver-list': ['127.0.1.1', '127.0.1.2']
},
'Region Two': {
'check-frontend-ip-list': ['99.99.99.5', '99.99.99.6'],
'nameserver-list': ['127.0.2.1', '127.0.2.2']
}
},
},
'three': {
'available-region-list': [
'Region Four', 'Region One', 'Region Three', 'Region Two'],
'assigned-region-dict': {
'Region Three': {
'check-frontend-ip-list': ['127.0.3.1', '127.0.3.2'],
'nameserver-list': []
}
}
},
'globalcheck': {
'available-region-list': [
'Region Four', 'Region One', 'Region Three', 'Region Two'],
'assigned-region-dict': {
'Region One': {
'check-frontend-ip-list': ['99.99.99.3', '99.99.99.4'],
'nameserver-list': ['127.0.1.1', '127.0.1.2']
}
},
},
'missed': {
'available-region-list': [
'Region Four', 'Region One', 'Region Three', 'Region Two'],
'assigned-region-dict': {
}
},
'partialmiss': {
'available-region-list': [
'Region Four', 'Region One', 'Region Three', 'Region Two'],
'assigned-region-dict': {
'Region Two': {
'check-frontend-ip-list': [],
'nameserver-list': ['127.0.2.1', '127.0.2.2']
}
}
}
}
self.assertSlaveConnectionParameterDict()
self.surykatka_dict['edge4'] = {
2: {'expected_ini': """[SURYKATKA]
INTERVAL = 120 INTERVAL = 120
TIMEOUT = 4 TIMEOUT = 4
SQLITE = %(db_file)s SQLITE = %(dbfile)
URL = NAMESERVER =
https://www.erp5.com/ 127.0.4.1
https://www.erp5.org/"""} 127.0.4.2
}
@classmethod URL =
def getInstanceParameterDict(cls): https://www.all.org/"""},
return {
'failure-amount': '5'
} }
self.updateSurykatkaDict()
def assertSurykatkaPromises(self): self.assertHttpQueryPromiseContent(
self.assertPromiseContent( 'edge4',
'http-query-backend-promise.py', 'all',
"'report': 'http_query'") """{ 'certificate-expiration-days': '15',
self.assertPromiseContent( 'failure-amount': '2',
'http-query-backend-promise.py', 'http-header-dict': '{}',
"'status-code': '200'") 'ip-list': '127.0.4.3 127.0.4.4',
self.assertPromiseContent( 'json-file': '%s',
'http-query-backend-promise.py', 'maximum-elapsed-time': '2',
"'url': 'https://www.erp5.com/'") 'report': 'http_query',
self.assertPromiseContent( 'status-code': '200',
'http-query-backend-promise.py', 'url': 'https://www.all.org/'}""" % (
"'json-file': '%s'" % (self.surykatka_dict[2]['json-file'],) self.surykatka_dict['edge4'][2]['json-file'],))
)
self.assertPromiseContent(
'http-query-backend-promise.py',
"'failure-amount': '5'"
)
self.assertPromiseContent(
'http-query-backend-10-promise.py',
"'report': 'http_query'")
self.assertPromiseContent(
'http-query-backend-10-promise.py',
"'status-code': '200'")
self.assertPromiseContent(
'http-query-backend-10-promise.py',
"'url': 'https://www.erp5.org/'")
self.assertPromiseContent(
'http-query-backend-10-promise.py',
"'json-file': '%s'" % (self.surykatka_dict[2]['json-file'],)
)
self.assertPromiseContent(
'http-query-backend-10-promise.py',
"'failure-amount': '10'"
)
def requestEdgetestSlaves(self):
self.requestEdgetestSlave(
'backend',
{'url': 'https://www.erp5.com/'},
)
self.requestEdgetestSlave(
'backend-10',
{'url': 'https://www.erp5.org/', 'failure-amount': '10'},
)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment