|
5 | 5 | SC_PASSWORD: "{{ sc_config[sc_host].sc_password }}" |
6 | 6 | SC_TIMEOUT: "{{ sc_timeout }}" |
7 | 7 |
|
8 | | - block: |
9 | | - - name: Get Timezone |
10 | | - ansible.builtin.uri: |
11 | | - url: https://ipapi.co/timezone |
12 | | - return_content: true |
13 | | - register: response |
| 8 | + vars: |
| 9 | + # Test with timezone far away from UTC, to make difference local vs UTC obvious. |
| 10 | + test_timezone: "America/New_York" |
| 11 | + # test_timezone: "Europe/Ljubljana" # almost same as UTC |
14 | 12 |
|
| 13 | + block: |
15 | 14 | - name: Show Timezone |
16 | 15 | ansible.builtin.debug: |
17 | | - msg: Timezone is {{ response.content }} |
| 16 | + msg: Timezone is {{ test_timezone }} |
18 | 17 |
|
19 | 18 | # ansible_date_time is incremented for a few second for each next task. |
20 | 19 | # Store value, so we have a stable value. |
|
24 | 23 |
|
25 | 24 | - name: Show current time |
26 | 25 | ansible.builtin.debug: |
27 | | - msg: current_date_time={{ current_date_time }} TZ={{ current_date_time.tz }} hour={{ current_date_time.hour }} |
| 26 | + msg: current_date_time={{ current_date_time }} TZ={{ current_date_time.tz }} hour={{ current_date_time.hour }} epoch_int={{ current_date_time.epoch_int }} |
| 27 | + # current_date_time.tz might not contain correct timezone. |
28 | 28 |
|
29 | | - # The scheduled integration tests run near 3.00 UTC (5:00 CEST). |
30 | | - # ansible_date_time.hour is reported in local timezone. |
31 | | - # It should be safe to add/subtract 1 hour to prevent occasional test failures, |
32 | | - # if scheduled test is run near x:59:59. |
| 29 | + # Ansible ansible_date_time.hour should be in local timezone, |
| 30 | + # but required local timezone to be configured on OS level. |
| 31 | + # Convert epoch from ansible_date_time to local time. |
| 32 | + # We will create a dedicated venv, then we can use pytz |
| 33 | + # Our CI image has python3 on path |
| 34 | + - name: Create python venv with pytz |
| 35 | + ansible.builtin.shell: | |
| 36 | + python3 -m venv /tmp/venv-pytz |
| 37 | + /tmp/venv-pytz/bin/pip install pytz |
33 | 38 |
|
34 | | - # Manual testing - can be run at arbitrary time, can always be a problem. So extra assert |
35 | | - - name: Check "current_date_time.hour +/- 1" is still a valid hour |
36 | | - ansible.builtin.assert: |
37 | | - that: |
38 | | - - 1 <= (current_date_time.hour | int) |
39 | | - - (current_date_time.hour | int) <= 22 |
| 39 | + - name: Convert UTC timestamp to localtime, +/- 1 hour |
| 40 | + ansible.builtin.shell: | |
| 41 | + #!/tmp/venv-pytz/bin/python3 |
| 42 | + import json |
| 43 | + import sys |
| 44 | + from datetime import datetime |
| 45 | + import pytz |
| 46 | +
|
| 47 | + # timezone = 'America/New_York' |
| 48 | + # unix_timestamp = 1681452184 |
| 49 | + timezone, unix_timestamp = sys.stdin.read().split() |
| 50 | + unix_timestamp = int(unix_timestamp) |
| 51 | + local_tz = pytz.timezone(timezone) |
| 52 | +
|
| 53 | + # m1/p1 suffix - minus/plus 1 hour |
| 54 | + dt = datetime.fromtimestamp(unix_timestamp, pytz.utc) |
| 55 | + dtm1 = datetime.fromtimestamp(unix_timestamp - 3600, pytz.utc) |
| 56 | + dtp1 = datetime.fromtimestamp(unix_timestamp + 3600, pytz.utc) |
| 57 | + local_dt = dt.astimezone(local_tz) |
| 58 | + local_dtm1 = dtm1.astimezone(local_tz) |
| 59 | + local_dtp1 = dtp1.astimezone(local_tz) |
| 60 | +
|
| 61 | + ret = dict( |
| 62 | + hour=local_dt.hour, |
| 63 | + hour_m1=local_dtm1.hour, |
| 64 | + hour_p1=local_dtp1.hour, |
| 65 | + ) |
| 66 | + print(json.dumps(ret)) |
| 67 | + args: |
| 68 | + # /usr/bin/python3 - fedora |
| 69 | + # /usr/local/bin/python - python:3.10-slim-buster docker image |
| 70 | + executable: /tmp/venv-pytz/bin/python3 |
| 71 | + stdin: "{{ test_timezone }} {{ current_date_time.epoch_int }}" |
| 72 | + changed_when: false |
| 73 | + register: local_time_result |
| 74 | + |
| 75 | + - name: Set fact local_time |
| 76 | + ansible.builtin.set_fact: |
| 77 | + local_time: "{{ local_time_result.stdout | from_json }}" |
40 | 78 |
|
41 | 79 | # ------------------------------------------------------------------------------ |
42 | 80 | - name: Check that local time meets required time interval |
43 | 81 | ansible.builtin.include_role: |
44 | 82 | name: scale_computing.hypercore.check_local_time |
45 | 83 | vars: |
46 | | - time_zone: "{{ response.content }}" # ansible_date_time.tz returns CEST which is not a valid tz for env var TZ |
47 | | - time_interval: "{{ (current_date_time.hour | int) - 1 }}:00-{{ (current_date_time.hour | int) + 1 }}:59" |
48 | | - |
| 84 | + time_zone: "{{ test_timezone }}" # ansible_date_time.tz returns CEST which is not a valid tz for env var TZ |
| 85 | + time_interval: "{{ local_time.hour_m1 }}:00-{{ local_time.hour_p1 }}:59" |
| 86 | + |
49 | 87 | - name: Check local_time_msg for passed case |
50 | 88 | ansible.builtin.assert: |
51 | 89 | that: |
52 | 90 | - >- |
53 | | - 'Local time for time zone {{ response.content }} is in required time interval |
54 | | - {{ (current_date_time.hour | int) - 1 }}:00-{{ (current_date_time.hour | int) + 1 }}:59' in local_time_msg |
| 91 | + 'Local time for time zone {{ test_timezone }} is in required time interval |
| 92 | + {{ local_time.hour_m1 }}:00-{{ local_time.hour_p1 }}:59' in local_time_msg |
55 | 93 |
|
56 | 94 | # ------------------------------------------------------------------------------ |
57 | 95 | - name: Check that local time doesn't meet required time interval |
|
60 | 98 | apply: |
61 | 99 | ignore_errors: True |
62 | 100 | vars: |
63 | | - time_zone: "{{ response.content }}" |
64 | | - time_interval: "{{ (current_date_time.hour | int) - 1 }}:00-{{ (current_date_time.hour | int) - 1 }}:01" |
| 101 | + time_zone: "{{ test_timezone }}" |
| 102 | + time_interval: "{{ local_time.hour_m1 }}:00-{{ local_time.hour_m1 }}:01" |
65 | 103 |
|
66 | 104 | - name: Check local_time_msg for failed case |
67 | 105 | ansible.builtin.assert: |
68 | 106 | that: |
69 | 107 | - >- |
70 | | - 'Local time for time zone {{ response.content }} is not in required time interval |
71 | | - {{ (current_date_time.hour | int) - 1 }}:00-{{ (current_date_time.hour | int) - 1 }}:01' in local_time_msg |
| 108 | + 'Local time for time zone {{ test_timezone }} is not in required time interval |
| 109 | + {{ local_time.hour_m1 }}:00-{{ local_time.hour_m1 }}:01' in local_time_msg |
0 commit comments