diff --git a/tests/integration/targets/role_check_local_time/tasks/main.yml b/tests/integration/targets/role_check_local_time/tasks/main.yml index 1a17b30f0..e0f71e8c3 100644 --- a/tests/integration/targets/role_check_local_time/tasks/main.yml +++ b/tests/integration/targets/role_check_local_time/tasks/main.yml @@ -5,16 +5,15 @@ SC_PASSWORD: "{{ sc_config[sc_host].sc_password }}" SC_TIMEOUT: "{{ sc_timeout }}" - block: - - name: Get Timezone - ansible.builtin.uri: - url: https://ipapi.co/timezone - return_content: true - register: response + vars: + # Test with timezone far away from UTC, to make difference local vs UTC obvious. + test_timezone: "America/New_York" + # test_timezone: "Europe/Ljubljana" # almost same as UTC + block: - name: Show Timezone ansible.builtin.debug: - msg: Timezone is {{ response.content }} + msg: Timezone is {{ test_timezone }} # ansible_date_time is incremented for a few second for each next task. # Store value, so we have a stable value. @@ -24,34 +23,73 @@ - name: Show current time ansible.builtin.debug: - msg: current_date_time={{ current_date_time }} TZ={{ current_date_time.tz }} hour={{ current_date_time.hour }} + msg: current_date_time={{ current_date_time }} TZ={{ current_date_time.tz }} hour={{ current_date_time.hour }} epoch_int={{ current_date_time.epoch_int }} + # current_date_time.tz might not contain correct timezone. - # The scheduled integration tests run near 3.00 UTC (5:00 CEST). - # ansible_date_time.hour is reported in local timezone. - # It should be safe to add/subtract 1 hour to prevent occasional test failures, - # if scheduled test is run near x:59:59. + # Ansible ansible_date_time.hour should be in local timezone, + # but required local timezone to be configured on OS level. + # Convert epoch from ansible_date_time to local time. + # We will create a dedicated venv, then we can use pytz + # Our CI image has python3 on path + - name: Create python venv with pytz + ansible.builtin.shell: | + python3 -m venv /tmp/venv-pytz + /tmp/venv-pytz/bin/pip install pytz - # Manual testing - can be run at arbitrary time, can always be a problem. So extra assert - - name: Check "current_date_time.hour +/- 1" is still a valid hour - ansible.builtin.assert: - that: - - 1 <= (current_date_time.hour | int) - - (current_date_time.hour | int) <= 22 + - name: Convert UTC timestamp to localtime, +/- 1 hour + ansible.builtin.shell: | + #!/tmp/venv-pytz/bin/python3 + import json + import sys + from datetime import datetime + import pytz + + # timezone = 'America/New_York' + # unix_timestamp = 1681452184 + timezone, unix_timestamp = sys.stdin.read().split() + unix_timestamp = int(unix_timestamp) + local_tz = pytz.timezone(timezone) + + # m1/p1 suffix - minus/plus 1 hour + dt = datetime.fromtimestamp(unix_timestamp, pytz.utc) + dtm1 = datetime.fromtimestamp(unix_timestamp - 3600, pytz.utc) + dtp1 = datetime.fromtimestamp(unix_timestamp + 3600, pytz.utc) + local_dt = dt.astimezone(local_tz) + local_dtm1 = dtm1.astimezone(local_tz) + local_dtp1 = dtp1.astimezone(local_tz) + + ret = dict( + hour=local_dt.hour, + hour_m1=local_dtm1.hour, + hour_p1=local_dtp1.hour, + ) + print(json.dumps(ret)) + args: + # /usr/bin/python3 - fedora + # /usr/local/bin/python - python:3.10-slim-buster docker image + executable: /tmp/venv-pytz/bin/python3 + stdin: "{{ test_timezone }} {{ current_date_time.epoch_int }}" + changed_when: false + register: local_time_result + + - name: Set fact local_time + ansible.builtin.set_fact: + local_time: "{{ local_time_result.stdout | from_json }}" # ------------------------------------------------------------------------------ - name: Check that local time meets required time interval ansible.builtin.include_role: name: scale_computing.hypercore.check_local_time vars: - time_zone: "{{ response.content }}" # ansible_date_time.tz returns CEST which is not a valid tz for env var TZ - time_interval: "{{ (current_date_time.hour | int) - 1 }}:00-{{ (current_date_time.hour | int) + 1 }}:59" - + time_zone: "{{ test_timezone }}" # ansible_date_time.tz returns CEST which is not a valid tz for env var TZ + time_interval: "{{ local_time.hour_m1 }}:00-{{ local_time.hour_p1 }}:59" + - name: Check local_time_msg for passed case ansible.builtin.assert: that: - >- - 'Local time for time zone {{ response.content }} is in required time interval - {{ (current_date_time.hour | int) - 1 }}:00-{{ (current_date_time.hour | int) + 1 }}:59' in local_time_msg + 'Local time for time zone {{ test_timezone }} is in required time interval + {{ local_time.hour_m1 }}:00-{{ local_time.hour_p1 }}:59' in local_time_msg # ------------------------------------------------------------------------------ - name: Check that local time doesn't meet required time interval @@ -60,12 +98,12 @@ apply: ignore_errors: True vars: - time_zone: "{{ response.content }}" - time_interval: "{{ (current_date_time.hour | int) - 1 }}:00-{{ (current_date_time.hour | int) - 1 }}:01" + time_zone: "{{ test_timezone }}" + time_interval: "{{ local_time.hour_m1 }}:00-{{ local_time.hour_m1 }}:01" - name: Check local_time_msg for failed case ansible.builtin.assert: that: - >- - 'Local time for time zone {{ response.content }} is not in required time interval - {{ (current_date_time.hour | int) - 1 }}:00-{{ (current_date_time.hour | int) - 1 }}:01' in local_time_msg + 'Local time for time zone {{ test_timezone }} is not in required time interval + {{ local_time.hour_m1 }}:00-{{ local_time.hour_m1 }}:01' in local_time_msg