Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Backport #51095 #56753

Merged
merged 2 commits into from
Apr 22, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Versions are `MAJOR.PATCH`.
### Deprecated

### Changed
- [#56753](https://github.com/saltstack/salt/pull/56753) - Backport 51095

### Fixed
- [#56237](https://github.com/saltstack/salt/pull/56237) - Fix alphabetical ordering and remove duplicates across all documentation indexes - [@myii](https://github.com/myii)
Expand Down
22 changes: 10 additions & 12 deletions salt/modules/win_timezone.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,24 +209,22 @@ def get_zone():
Returns:
str: Timezone in unix format

Raises:
CommandExecutionError: If timezone could not be gathered

CLI Example:

.. code-block:: bash

salt '*' timezone.get_zone
"""
win_zone = __utils__["reg.read_value"](
hive="HKLM",
key="SYSTEM\\CurrentControlSet\\Control\\TimeZoneInformation",
vname="TimeZoneKeyName",
)["vdata"]
# Some data may have null characters. We only need the first portion up to
# the first null character. See the following:
# https://github.com/saltstack/salt/issues/51940
# https://stackoverflow.com/questions/27716746/hklm-system-currentcontrolset-control-timezoneinformation-timezonekeyname-corrup
if "\0" in win_zone:
win_zone = win_zone.split("\0")[0]
return mapper.get_unix(win_zone.lower(), "Unknown")
cmd = ["tzutil", "/g"]
res = __salt__["cmd.run_all"](cmd, python_shell=False)
if res["retcode"] or not res["stdout"]:
raise CommandExecutionError(
"tzutil encountered an error getting timezone", info=res
)
return mapper.get_unix(res["stdout"].lower(), "Unknown")


def get_offset():
Expand Down
101 changes: 69 additions & 32 deletions tests/unit/modules/test_win_timezone.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

# Import Salt Libs
import salt.modules.win_timezone as win_timezone
from salt.exceptions import CommandExecutionError

# Import Salt Testing Libs
from tests.support.mixins import LoaderModuleMockMixin
Expand All @@ -23,47 +24,62 @@ class WinTimezoneTestCase(TestCase, LoaderModuleMockMixin):
def setup_loader_modules(self):
return {win_timezone: {}}

# 'get_zone' function tests: 3

def test_get_zone(self):
def test_get_zone_normal(self):
"""
Test if it gets current timezone (i.e. Asia/Calcutta)
Test if it get current timezone (i.e. Asia/Calcutta)
"""
mock_read = MagicMock(
side_effect=[
{"vdata": "India Standard Time"},
{"vdata": "Indian Standard Time"},
]
mock_read_ok = MagicMock(
return_value={
"pid": 78,
"retcode": 0,
"stderr": "",
"stdout": "India Standard Time",
}
)

with patch.dict(win_timezone.__utils__, {"reg.read_value": mock_read}):
with patch.dict(win_timezone.__salt__, {"cmd.run_all": mock_read_ok}):
self.assertEqual(win_timezone.get_zone(), "Asia/Calcutta")
self.assertEqual(win_timezone.get_zone(), "Unknown")

def test_get_zone_null_terminated(self):
def test_get_zone_unknown(self):
"""
Test if it handles instances where the registry contains null values
Test get_zone with unknown timezone (i.e. Indian Standard Time)
"""
mock_read = MagicMock(
side_effect=[
{"vdata": "India Standard Time\0\0\0\0"},
{"vdata": "Indian Standard Time\0\0some more junk data\0\0"},
]
mock_read_error = MagicMock(
return_value={
"pid": 78,
"retcode": 0,
"stderr": "",
"stdout": "Indian Standard Time",
}
)

with patch.dict(win_timezone.__utils__, {"reg.read_value": mock_read}):
self.assertEqual(win_timezone.get_zone(), "Asia/Calcutta")
with patch.dict(win_timezone.__salt__, {"cmd.run_all": mock_read_error}):
self.assertEqual(win_timezone.get_zone(), "Unknown")

def test_get_zone_error(self):
"""
Test get_zone when it encounters an error
"""
mock_read_fatal = MagicMock(
return_value={"pid": 78, "retcode": 1, "stderr": "", "stdout": ""}
)
with patch.dict(win_timezone.__salt__, {"cmd.run_all": mock_read_fatal}):
self.assertRaises(CommandExecutionError, win_timezone.get_zone)

# 'get_offset' function tests: 1

def test_get_offset(self):
"""
Test if it get current numeric timezone offset from UCT (i.e. +0530)
"""
mock_read = MagicMock(return_value={"vdata": "India Standard Time"})
mock_read = MagicMock(
return_value={
"pid": 78,
"retcode": 0,
"stderr": "",
"stdout": "India Standard Time",
}
)

with patch.dict(win_timezone.__utils__, {"reg.read_value": mock_read}):
with patch.dict(win_timezone.__salt__, {"cmd.run_all": mock_read}):
self.assertEqual(win_timezone.get_offset(), "+0530")

# 'get_zonecode' function tests: 1
Expand All @@ -72,9 +88,16 @@ def test_get_zonecode(self):
"""
Test if it get current timezone (i.e. PST, MDT, etc)
"""
mock_read = MagicMock(return_value={"vdata": "India Standard Time"})
mock_read = MagicMock(
return_value={
"pid": 78,
"retcode": 0,
"stderr": "",
"stdout": "India Standard Time",
}
)

with patch.dict(win_timezone.__utils__, {"reg.read_value": mock_read}):
with patch.dict(win_timezone.__salt__, {"cmd.run_all": mock_read}):
self.assertEqual(win_timezone.get_zonecode(), "IST")

# 'set_zone' function tests: 1
Expand All @@ -83,13 +106,20 @@ def test_set_zone(self):
"""
Test if it unlinks, then symlinks /etc/localtime to the set timezone.
"""
mock_cmd = MagicMock(
mock_write = MagicMock(
return_value={"pid": 78, "retcode": 0, "stderr": "", "stdout": ""}
)
mock_read = MagicMock(return_value={"vdata": "India Standard Time"})
mock_read = MagicMock(
return_value={
"pid": 78,
"retcode": 0,
"stderr": "",
"stdout": "India Standard Time",
}
)

with patch.dict(win_timezone.__salt__, {"cmd.run_all": mock_cmd}), patch.dict(
win_timezone.__utils__, {"reg.read_value": mock_read}
with patch.dict(win_timezone.__salt__, {"cmd.run_all": mock_write}), patch.dict(
win_timezone.__salt__, {"cmd.run_all": mock_read}
):

self.assertTrue(win_timezone.set_zone("Asia/Calcutta"))
Expand All @@ -102,9 +132,16 @@ def test_zone_compare(self):
the one set in /etc/localtime. Returns True if they match,
and False if not. Mostly useful for running state checks.
"""
mock_read = MagicMock(return_value={"vdata": "India Standard Time"})
mock_read = MagicMock(
return_value={
"pid": 78,
"retcode": 0,
"stderr": "",
"stdout": "India Standard Time",
}
)

with patch.dict(win_timezone.__utils__, {"reg.read_value": mock_read}):
with patch.dict(win_timezone.__salt__, {"cmd.run_all": mock_read}):
self.assertTrue(win_timezone.zone_compare("Asia/Calcutta"))

# 'get_hwclock' function tests: 1
Expand Down