converting remain Mac integration tests to functional.

This commit is contained in:
Gareth J. Greenaway 2023-11-20 13:40:28 -08:00 committed by Daniel Wozniak
parent ef46b8452c
commit b1ab3d2ea6
12 changed files with 1999 additions and 0 deletions

View file

@ -0,0 +1,102 @@
"""
:codeauthor: Nicole Thomas <nicole@saltstack.com>
"""
import pytest
pytestmark = [
pytest.mark.destructive_test,
pytest.mark.skip_if_not_root,
pytest.mark.skip_initial_gh_actions_failure,
pytest.mark.skip_unless_on_darwin,
]
@pytest.fixture(scope="module")
def assistive(modules):
return modules.assistive
@pytest.fixture(scope="function")
def osa_script():
yield "/usr/bin/osascript"
@pytest.fixture(scope="function", autouse=True)
def _setup_teardown_vars(assistive, osa_script):
assistive.install(osa_script, True)
try:
yield
finally:
osa_script_ret = assistive.installed(osa_script)
if osa_script_ret:
assistive.remove(osa_script)
smile_bundle = "com.smileonmymac.textexpander"
ret = assistive.installed(smile_bundle)
smile_bundle_present = ret
if smile_bundle_present:
assistive.remove(smile_bundle)
@pytest.mark.slow_test
def test_install_and_remove(assistive, osa_script):
"""
Tests installing and removing a bundled ID or command to use assistive access.
"""
new_bundle = "com.smileonmymac.textexpander"
ret = assistive.install(new_bundle)
assert ret
ret = assistive.remove(new_bundle)
assert ret
@pytest.mark.slow_test
def test_installed(assistive, osa_script):
"""
Tests the True and False return of assistive.installed.
"""
# OSA script should have been installed in setUp function
ret = assistive.installed(osa_script)
assert ret
# Clean up install
assistive.remove(osa_script)
# Installed should now return False
ret = assistive.installed(osa_script)
assert not ret
@pytest.mark.slow_test
def test_enable(assistive, osa_script):
"""
Tests setting the enabled status of a bundled ID or command.
"""
# OSA script should have been installed and enabled in setUp function
# Now let's disable it, which should return True.
ret = assistive.enable(osa_script, False)
assert ret
# Double check the script was disabled, as intended.
ret = assistive.enabled(osa_script)
assert not ret
# Now re-enable
ret = assistive.enable(osa_script)
assert ret
# Double check the script was enabled, as intended.
ret = assistive.enabled(osa_script)
assert ret
@pytest.mark.slow_test
def test_enabled(assistive, osa_script):
"""
Tests if a bundled ID or command is listed in assistive access returns True.
"""
# OSA script should have been installed in setUp function, which sets
# enabled to True by default.
ret = assistive.enabled(osa_script)
assert ret
# Disable OSA Script
assistive.enable(osa_script, False)
# Assert against new disabled status
ret = assistive.enabled(osa_script)
assert not ret

View file

@ -0,0 +1,73 @@
"""
Integration tests for the mac_desktop execution module.
"""
import pytest
pytestmark = [
pytest.mark.slow_test,
pytest.mark.destructive_test,
pytest.mark.skip_if_not_root,
pytest.mark.skip_unless_on_darwin,
]
@pytest.fixture(scope="module")
def desktop(modules):
return modules.desktop
def test_get_output_volume(desktop):
"""
Tests the return of get_output_volume.
"""
ret = desktop.get_output_volume()
assert ret is not None
def test_set_output_volume(desktop):
"""
Tests the return of set_output_volume.
"""
try:
ret = desktop.get_output_volume()
current_vol = ret
to_set = 10
if current_vol == str(to_set):
to_set += 2
ret = desktop.set_output_volume(str(to_set))
new_vol = ret
ret = desktop.get_output_volume()
check_vol = ret
assert new_vol == check_vol
finally:
# Set volume back to what it was before
desktop.set_output_volume(current_vol)
def test_screensaver(desktop):
"""
Tests the return of the screensaver function.
"""
ret = desktop.screensaver()
if "does not exist" in ret:
pytest.skip("Skipping. Screensaver unavailable.")
assert ret
def test_lock(desktop):
"""
Tests the return of the lock function.
"""
ret = desktop.lock()
if "Unable to run" in ret:
pytest.skip("Skipping. Unable to lock screen.")
assert ret
def test_say(desktop):
"""
Tests the return of the say function.
"""
ret = desktop.say("hello", "world")
assert ret

View file

@ -0,0 +1,181 @@
"""
:codeauthor: Nicole Thomas <nicole@saltstack.com>
"""
import pytest
from saltfactories.utils import random_string
pytestmark = [
pytest.mark.slow_test,
pytest.mark.destructive_test,
pytest.mark.skip_if_not_root,
pytest.mark.skip_unless_on_darwin,
]
@pytest.fixture(scope="module")
def group(modules):
return modules.group
# Create group name strings for tests
@pytest.fixture(scope="module")
def add_group():
yield random_string("RS-", lowercase=False)
@pytest.fixture(scope="module")
def del_group():
yield random_string("RS-", lowercase=False)
@pytest.fixture(scope="module")
def change_group():
yield random_string("RS-", lowercase=False)
@pytest.fixture(scope="module")
def add_user():
yield random_string("RS-", lowercase=False)
@pytest.fixture(scope="module")
def rep_user_group():
yield random_string("RS-", lowercase=False)
@pytest.fixture(scope="module", autouse=True)
def _setup_teardown_vars(group, add_group, change_group, del_group):
try:
yield
finally:
# Delete ADD_GROUP
add_info = group.info(add_group)
if add_info:
group.delete(add_group)
# Delete DEL_GROUP if something failed
del_info = group.info(del_group)
if del_info:
group.delete(del_group)
# Delete CHANGE_GROUP
change_info = group.info(change_group)
if change_info:
group.delete(change_group)
def test_mac_group_add(group, add_group):
"""
Tests the add group function
"""
group.add(add_group, 3456)
group_info = group.info(add_group)
assert group_info["name"] == add_group
def test_mac_group_delete(group, del_group):
"""
Tests the delete group function
"""
# Create a group to delete - If unsuccessful, skip the test
group_add_ret = group.add(del_group, 4567)
if group_add_ret is not True:
group.delete(del_group)
pytest.skip("Failed to create a group to delete")
# Now try to delete the added group
ret = group.delete(del_group)
assert ret
def test_mac_group_chgid(group, change_group):
"""
Tests changing the group id
"""
# Create a group to delete - If unsuccessful, skip the test
ret = group.add(change_group, 5678)
if ret is not True:
group.delete(change_group)
pytest.skip("Failed to create a group to manipulate")
group.chgid(change_group, 6789)
group_info = group.info(change_group)
assert group_info["gid"] == 6789
def test_mac_adduser(group, add_group, add_user):
"""
Tests adding user to the group
"""
# Create a group to use for test - If unsuccessful, skip the test
ret = group.add(add_group, 5678)
if ret is not True:
group.delete(add_group)
pytest.skip("Failed to create a group to manipulate")
group.adduser(add_group, add_user)
group_info = group.info(add_group)
assert add_user == "".join(group_info["members"])
def test_mac_deluser(group, add_group, add_user):
"""
Test deleting user from a group
"""
# Create a group to use for test - If unsuccessful, skip the test
group_add_ret = group.add(add_group, 5678)
user_add_ret = group.adduser(add_group, add_user)
if group_add_ret and user_add_ret is not True:
group.delete(add_group)
pytest.skip("Failed to create a group to manipulate")
delusr = group.deluser(add_group, add_user)
assert delusr.data
group_info = group.info(add_group)
assert add_user not in "".join(group_info["members"])
def test_mac_members(group, add_group, add_user, rep_user_group):
"""
Test replacing members of a group
"""
group_add_ret = group.add(add_group, 5678)
user_add_ret = group.adduser(add_group, add_user)
if group_add_ret and user_add_ret is not True:
group.delete(add_group)
pytest.skip(
"Failed to create the {} group or add user {} to group "
"to manipulate".format(add_group, add_user)
)
rep_group_mem = group.members(add_group, rep_user_group)
assert rep_group_mem
# ensure new user is added to group and previous user is removed
group_info = group.info(add_group)
assert rep_user_group in str(group_info["members"])
assert add_user not in str(group_info["members"])
def test_mac_getent(group, add_group, add_user):
"""
Test returning info on all groups
"""
group_add_ret = group.add(add_group, 5678)
user_add_ret = group.adduser(add_group, add_user)
if group_add_ret and user_add_ret is not True:
group.delete(add_group)
pytest.skip(
"Failed to create the {} group or add user {} to group "
"to manipulate".format(add_group, add_user)
)
getinfo = group.getent()
assert getinfo.data
assert add_group in str(getinfo)
assert add_user in str(getinfo)

View file

@ -0,0 +1,129 @@
"""
Validate the mac-keychain module
"""
import os
import pytest
import salt.utils.versions
from tests.support.runtests import RUNTIME_VARS
pytestmark = [
pytest.mark.slow_test,
pytest.mark.destructive_test,
pytest.mark.skip_if_not_root,
pytest.mark.skip_unless_on_darwin,
]
@pytest.fixture(scope="module")
def cmd(modules):
return modules.cmd
@pytest.fixture(scope="module")
def keychain(modules):
return modules.keychain
@pytest.fixture(scope="function", autouse=True)
def setup_teardown_vars(keychain, base_env_state_tree_root_dir):
cert = os.path.join(RUNTIME_VARS.FILES, "file", "base", "certs", "salttest.p12")
cert_alias = "Salt Test"
passwd = "salttest"
try:
yield cert, cert_alias, passwd
finally:
certs_list = keychain.list_certs()
if cert_alias in certs_list:
keychain.uninstall(cert_alias)
def test_mac_keychain_install(keychain, setup_teardown_vars):
"""
Tests that attempts to install a certificate
"""
cert = setup_teardown_vars[0]
cert_alias = setup_teardown_vars[1]
passwd = setup_teardown_vars[2]
install_cert = keychain.install(cert, passwd)
assert install_cert
assert install_cert == "1 identity imported."
# check to ensure the cert was installed
certs_list = keychain.list_certs()
assert cert_alias in certs_list
def test_mac_keychain_uninstall(keychain, setup_teardown_vars):
"""
Tests that attempts to uninstall a certificate
"""
cert = setup_teardown_vars[0]
cert_alias = setup_teardown_vars[1]
passwd = setup_teardown_vars[2]
keychain.install(cert, passwd)
certs_list = keychain.list_certs()
if cert_alias not in certs_list:
keychain.uninstall(cert_alias)
pytest.skip("Failed to install keychain")
# uninstall cert
keychain.uninstall(cert_alias)
certs_list = keychain.list_certs()
# check to ensure the cert was uninstalled
assert cert_alias not in str(certs_list)
@pytest.mark.skip_if_binaries_missing("openssl")
def test_mac_keychain_get_friendly_name(keychain, shell):
"""
Test that attempts to get friendly name of a cert
"""
cert = setup_teardown_vars[0]
cert_alias = setup_teardown_vars[1]
passwd = setup_teardown_vars[2]
keychain.install(cert, passwd)
certs_list = keychain.list_certs()
if cert_alias not in certs_list:
keychain.uninstall(cert_alias)
pytest.skip("Failed to install keychain")
ret = shell.run("openssl", "version")
assert ret.stdout
openssl_version = ret.stdout.split()[1]
# openssl versions under 3.0.0 do not include legacy flag
if salt.utils.versions.compare(ver1=openssl_version, oper="<", ver2="3.0.0"):
get_name = keychain.get_friendly_name(cert, passwd, legacy=False)
else:
get_name = keychain.get_friendly_name(cert, passwd, legacy=True)
assert get_name == cert_alias
def test_mac_keychain_get_default_keychain(keychain, cmd, setup_teardown_vars):
"""
Test that attempts to get the default keychain
"""
sys_get_keychain = keychain.get_default_keychain()
salt_get_keychain = cmd.run("security default-keychain -d user")
assert salt_get_keychain == sys_get_keychain
def test_mac_keychain_list_certs(keychain, setup_teardown_vars):
"""
Test that attempts to list certs
"""
cert_default = "com.apple.systemdefault"
certs = keychain.list_certs()
assert cert_default in certs

View file

@ -0,0 +1,106 @@
"""
integration tests for mac_ports
"""
import pytest
pytestmark = [
pytest.mark.slow_test,
pytest.mark.destructive_test,
pytest.mark.skip_if_not_root,
pytest.mark.skip_unless_on_darwin,
pytest.mark.skip_if_binaries_missing("port"),
]
@pytest.fixture(scope="module")
def pkg(modules):
return modules.pkg
@pytest.fixture(scope="function", autouse=True)
def _setup_teardown_vars(pkg):
AGREE_INSTALLED = False
try:
ret = pkg.list_pkgs()
AGREE_INSTALLED = "agree" in ret
pkg.refresh_db()
yield
finally:
if AGREE_INSTALLED:
pkg.remove("agree")
def test_list_pkgs(pkg):
"""
Test pkg.list_pkgs
"""
pkg.install("agree")
pkg_list_ret = pkg.list_pkgs()
assert isinstance(pkg_list_ret, dict)
assert "agree" in pkg_list_ret
def test_latest_version(pkg):
"""
Test pkg.latest_version
"""
pkg.install("agree")
result = pkg.latest_version("agree", refresh=False)
assert isinstance(result, dict)
assert "agree" in result.data
def test_remove(pkg):
"""
Test pkg.remove
"""
pkg.install("agree")
removed = pkg.remove("agree")
assert isinstance(removed, dict)
assert "agree" in removed
@pytest.mark.destructive_test
def test_install(pkg):
"""
Test pkg.install
"""
pkg.remove("agree")
installed = pkg.install("agree")
assert isinstance(installed, dict)
assert "agree" in installed
def test_list_upgrades(pkg):
"""
Test pkg.list_upgrades
"""
upgrade = pkg.list_upgrades(refresh=False)
assert isinstance(upgrade, dict)
def test_upgrade_available(pkg):
"""
Test pkg.upgrade_available
"""
pkg.install("agree")
upgrade_available = pkg.upgrade_available("agree", refresh=False)
assert not upgrade_available.data
def test_refresh_db(pkg):
"""
Test pkg.refresh_db
"""
refresh = pkg.refresh_db()
assert refresh
def test_upgrade(pkg):
"""
Test pkg.upgrade
"""
results = pkg.upgrade(refresh=False)
assert isinstance(results, dict)
assert results.data["result"]

View file

@ -0,0 +1,153 @@
"""
integration tests for mac_power
"""
import pytest
pytestmark = [
pytest.mark.flaky(max_runs=10),
pytest.mark.skip_if_binaries_missing("systemsetup"),
pytest.mark.slow_test,
pytest.mark.destructive_test,
pytest.mark.skip_if_not_root,
pytest.mark.skip_unless_on_darwin,
]
@pytest.fixture(scope="module")
def power(modules):
return modules.power
@pytest.fixture(scope="function", autouse=True)
def _setup_teardown_vars(power):
computer_sleep = power.get_computer_sleep()
display_sleep = power.get_display_sleep()
hard_disk_sleep = power.get_harddisk_sleep()
try:
yield
finally:
power.set_computer_sleep(computer_sleep)
power.set_display_sleep(display_sleep)
power.set_harddisk_sleep(hard_disk_sleep)
def test_computer_sleep(power):
"""
Test power.get_computer_sleep
Test power.set_computer_sleep
"""
# Normal Functionality
ret = power.set_computer_sleep(90)
assert ret
ret = power.get_computer_sleep()
assert ret == "after 90 minutes"
ret = power.set_computer_sleep("Off")
assert ret
ret = power.get_computer_sleep()
assert ret == "Never"
# Test invalid input
ret = power.set_computer_sleep("spongebob")
assert "Invalid String Value for Minutes" in ret
ret = power.set_computer_sleep(0)
assert "Invalid Integer Value for Minutes" in ret
ret = power.set_computer_sleep(181)
assert "Invalid Integer Value for Minutes" in ret
ret = power.set_computer_sleep(True)
assert "Invalid Boolean Value for Minutes" in ret
def test_display_sleep(power):
"""
Test power.get_display_sleep
Test power.set_display_sleep
"""
# Normal Functionality
ret = power.set_display_sleep(90)
assert ret
ret = power.get_display_sleep()
assert ret == "after 90 minutes"
ret = power.set_display_sleep("Off")
assert ret
ret = power.get_display_sleep()
assert ret == "Never"
# Test invalid input
ret = power.set_display_sleep("spongebob")
assert "Invalid String Value for Minutes" in ret
ret = power.set_display_sleep(0)
assert "Invalid Integer Value for Minutes" in ret
ret = power.set_display_sleep(181)
assert "Invalid Integer Value for Minutes" in ret
ret = power.set_display_sleep(True)
assert "Invalid Boolean Value for Minutes" in ret
def test_harddisk_sleep(power):
"""
Test power.get_harddisk_sleep
Test power.set_harddisk_sleep
"""
# Normal Functionality
ret = power.set_harddisk_sleep(90)
assert ret
ret = power.get_harddisk_sleep()
assert ret == "after 90 minutes"
ret = power.set_harddisk_sleep("Off")
assert ret
ret = power.get_harddisk_sleep()
assert ret == "Never"
# Test invalid input
ret = power.set_harddisk_sleep("spongebob")
assert "Invalid String Value for Minutes" in ret
ret = power.set_harddisk_sleep(0)
assert "Invalid Integer Value for Minutes" in ret
ret = power.set_harddisk_sleep(181)
assert "Invalid Integer Value for Minutes" in ret
ret = power.set_harddisk_sleep(True)
assert "Invalid Boolean Value for Minutes" in ret
def test_restart_freeze(power):
"""
Test power.get_restart_freeze
Test power.set_restart_freeze
"""
# Normal Functionality
ret = power.set_restart_freeze("on")
assert ret
ret = power.get_restart_freeze()
assert ret
# This will return False because mac fails to actually make the change
ret = power.set_restart_freeze("off")
assert not ret
# Even setting to off returns true, it actually is never set
# This is an apple bug
ret = power.get_restart_freeze()
assert ret

View file

@ -0,0 +1,238 @@
"""
integration tests for mac_service
"""
import plistlib
import pytest
import salt.utils.files
pytestmark = [
pytest.mark.slow_test,
pytest.mark.skip_if_binaries_missing("launchctl", "plutil"),
pytest.mark.skip_unless_on_darwin,
]
@pytest.fixture(scope="module")
def service(modules):
return modules.service
@pytest.fixture(scope="function", autouse=True)
def service_name(sergice, service_name):
service_name = "com.salt.integration.test"
service_path = "/Library/LaunchDaemons/com.salt.integration.test.plist"
service_data = {
"KeepAlive": True,
"Label": service_name,
"ProgramArguments": ["/bin/sleep", "1000"],
"RunAtLoad": True,
}
with salt.utils.files.fopen(service_path, "wb") as fp:
plistlib.dump(service_data, fp)
service.enable(service_name)
service.start(service_name)
try:
yield service_name
finally:
service.stop(service_name)
salt.utils.files.safe_rm(service_path)
def test_show(service, service_name):
"""
Test service.show
"""
# Existing Service
service_info = service.show(service_name)
assert isinstance(service_info, dict)
assert service_info.data["plist"]["Label"] == service_name
# Missing Service
ret = service.show("spongebob")
assert "Service not found" in ret
def test_launchctl(service, service_name):
"""
Test service.launchctl
"""
# Expected Functionality
ret = service.launchctl("error", "bootstrap", 64)
assert ret
ret = service.launchctl("error", "bootstrap", 64, return_stdout=True)
assert ret == "64: unknown error code"
# Raise an error
ret = service.launchctl("error", "bootstrap")
assert "Failed to error service" in ret
def test_list(service, service_name):
"""
Test service.list
"""
# Expected Functionality
ret = service.list()
assert "PID" in ret
ret = service.list(service_name)
assert "{" in ret
# Service not found
ret = service.list("spongebob")
assert "Service not found" in ret
def test_enable(service, service_name):
"""
Test service.enable
"""
ret = service.enable(service_name)
assert ret
ret = service.enable("spongebob")
assert "Service not found" in ret
def test_disable(service, service_name):
"""
Test service.disable
"""
ret = service.disable(service_name)
assert ret
ret = service.disable("spongebob")
assert "Service not found" in ret
def test_start(service, service_name):
"""
Test service.start
Test service.stop
Test service.status
"""
service.stop(service_name)
ret = service.start(service_name)
assert ret
ret = service.start("spongebob")
assert "Service not found" in ret
def test_stop(service, service_name):
"""
Test service.stop
"""
ret = service.stop(service_name)
assert ret
ret = service.stop("spongebob")
assert "Service not found" in ret
def test_status(service, service_name):
"""
Test service.status
"""
# A running service
service.start(service_name)
ret = service.status(service_name)
assert ret
# A stopped service
service.stop(service_name)
ret = service.status(service_name)
assert not ret
# Service not found
ret = service.status("spongebob")
assert not ret
def test_available(service, service_name):
"""
Test service.available
"""
ret = service.available(service_name)
assert ret
ret = service.available("spongebob")
assert not ret
def test_missing(service, service_name):
"""
Test service.missing
"""
ret = service.missing(service_name)
assert not ret
ret = service.missing("spongebob")
assert ret
def test_enabled(service, service_name):
"""
Test service.enabled
"""
service.disabled(service_name)
ret = service.enabled(service_name)
assert ret
ret = service.enabled("spongebob")
assert "Service not found: spongebob" in ret
def test_disabled(service, service_name):
"""
Test service.disabled
"""
service.enabled(service_name)
service.start(service_name)
ret = service.disabled(service_name)
assert not ret
ret = service.disable(service_name)
assert ret
ret = service.disabled(service_name)
assert ret
ret = service.enable(service_name)
assert ret
ret = service.disable("spongebob")
assert "Service not found: spongebob" in ret
def test_get_all(service, service_name):
"""
Test service.get_all
"""
services = service.get_all()
assert isinstance(services, list)
assert service_name in services.data
def test_get_enabled(service, service_name):
"""
Test service.get_enabled
"""
services = service.get_enabled()
assert isinstance(services, list)
assert service_name in services.data
def test_service_laoded(service, service_name):
"""
Test service.get_enabled
"""
ret = service.loaded(service_name)
assert ret

View file

@ -0,0 +1,197 @@
"""
integration tests for mac_shadow
"""
import datetime
import types
import pytest
from saltfactories.utils import random_string
pytestmark = [
pytest.mark.skip_if_binaries_missing("dscl", "pwpolicy"),
pytest.mark.skip_initial_gh_actions_failure,
pytest.mark.slow_test,
pytest.mark.skip_if_not_root,
pytest.mark.skip_unless_on_darwin,
]
@pytest.fixture(scope="module")
def shadow(modules):
return modules.shadow
@pytest.fixture(scope="function")
def accounts():
with pytest.helpers.create_account(create_group=True) as _account:
yield types.SimpleNamespace(
created=_account.username, not_created=random_string("RS-", lowercase=False)
)
def test_info(shadow, accounts):
"""
Test shadow.info
"""
# Correct Functionality
ret = shadow.info(accounts.created)
assert ret["name"] == accounts.created
# User does not exist
ret = shadow.info(accounts.not_created)
assert ret["name"] == ""
def test_get_account_created(shadow, accounts):
"""
Test shadow.get_account_created
"""
# Correct Functionality
text_date = shadow.get_account_created(accounts.created)
assert text_date.data != "Invalid Timestamp"
obj_date = datetime.datetime.strptime(text_date, "%Y-%m-%d %H:%M:%S")
assert isinstance(obj_date, datetime.date)
# User does not exist
assert (
shadow.get_account_created(accounts.not_created)
== f"ERROR: User not found: {accounts.not_created}"
)
def test_get_last_change(shadow, accounts):
"""
Test shadow.get_last_change
"""
# Correct Functionality
text_date = shadow.get_last_change(accounts.created)
assert text_date != "Invalid Timestamp"
obj_date = datetime.datetime.strptime(text_date, "%Y-%m-%d %H:%M:%S")
assert isinstance(obj_date, datetime.date)
# User does not exist
assert (
shadow.get_last_change(accounts.not_created)
== f"ERROR: User not found: {accounts.not_created}"
)
def test_get_login_failed_last(shadow, accounts):
"""
Test shadow.get_login_failed_last
"""
# Correct Functionality
text_date = shadow.get_login_failed_last(accounts.created)
assert text_date != "Invalid Timestamp"
obj_date = datetime.datetime.strptime(text_date, "%Y-%m-%d %H:%M:%S")
assert isinstance(obj_date, datetime.date)
# User does not exist
assert (
shadow.get_login_failed_last(accounts)
== f"ERROR: User not found: {accounts.not_created}"
)
def test_get_login_failed_count(shadow, accounts):
"""
Test shadow.get_login_failed_count
"""
# Correct Functionality
assert shadow.get_login_failed_count(accounts.created) == "0"
# User does not exist
assert (
shadow.get_login_failed_count(accounts.not_created)
== f"ERROR: User not found: {accounts.not_created}"
)
def test_get_set_maxdays(shadow, accounts):
"""
Test shadow.get_maxdays
Test shadow.set_maxdays
"""
# Correct Functionality
assert shadow.set_maxdays(accounts.created, 20)
assert shadow.get_maxdays(accounts.created) == 20
# User does not exist
assert (
shadow.set_maxdays(accounts.not_created, 7)
== f"ERROR: User not found: {accounts.not_created}"
)
assert (
shadow.get_maxdays(accounts.not_created)
== f"ERROR: User not found: {accounts.not_created}"
)
def test_get_set_change(shadow, accounts):
"""
Test shadow.get_change
Test shadow.set_change
"""
# Correct Functionality
assert shadow.set_change(accounts.created, "02/11/2011")
assert shadow.get_change(accounts.created) == "02/11/2011"
# User does not exist
assert (
shadow.set_change(accounts.not_created, "02/11/2012")
== f"ERROR: User not found: {accounts.not_created}"
)
assert (
shadow.get_change(accounts.not_created)
== f"ERROR: User not found: {accounts.not_created}"
)
def test_get_set_expire(shadow, accounts):
"""
Test shadow.get_expire
Test shadow.set_expire
"""
# Correct Functionality
assert shadow.set_expire(accounts.created, "02/11/2011")
assert shadow.get_expire(accounts.created) == "02/11/2011"
# User does not exist
assert (
shadow.set_expire(accounts.not_created, "02/11/2012")
== f"ERROR: User not found: {accounts.not_created}"
)
assert (
shadow.get_expire(accounts.not_created)
== f"ERROR: User not found: {accounts.not_created}"
)
def test_del_password(shadow, accounts):
"""
Test shadow.del_password
"""
# Correct Functionality
assert shadow.del_password(accounts.created)
assert shadow.info(accounts.created)["passwd"] == "*"
# User does not exist
assert (
shadow.del_password(accounts.not_created)
== f"ERROR: User not found: {accounts.not_created}"
)
def test_set_password(shadow, accounts):
"""
Test shadow.set_password
"""
# Correct Functionality
assert shadow.set_password(accounts.created, "Pa$$W0rd")
# User does not exist
assert (
shadow.set_password(accounts.not_created, "P@SSw0rd")
== f"ERROR: User not found: {accounts.not_created}"
)

View file

@ -0,0 +1,178 @@
"""
integration tests for mac_softwareupdate
"""
import pytest
pytestmark = [
pytest.mark.slow_test,
pytest.mark.skip_if_binaries_missing("softwareupdate"),
pytest.mark.skip_if_not_root,
pytest.mark.skip_unless_on_darwin,
pytest.mark.skip_initial_gh_actions_failure,
]
@pytest.fixture(scope="module")
def softwareupdate(modules):
return modules.softwareupdate
@pytest.fixture(scope="function", autouse=True)
def _setup_teardown_vars(softwareupdate):
IGNORED_LIST = softwareupdate.list_ignored()
SCHEDULE = softwareupdate.schedule()
CATALOG = softwareupdate.get_catalog()
try:
yield IGNORED_LIST, SCHEDULE, CATALOG
finally:
if IGNORED_LIST:
for item in IGNORED_LIST:
softwareupdate.ignore(item)
else:
softwareupdate.reset_ignored()
softwareupdate.schedule(SCHEDULE)
if CATALOG == "Default":
softwareupdate.reset_catalog()
else:
softwareupdate.set_catalog(CATALOG)
def test_list_available(softwareupdate):
"""
Test softwareupdate.list_available
"""
# Can't predict what will be returned, so can only test that the return
# is the correct type, dict
ret = softwareupdate.list_available()
assert isinstance(ret, dict)
def test_ignore(softwareupdate):
"""
Test softwareupdate.ignore
Test softwareupdate.list_ignored
Test softwareupdate.reset_ignored
"""
# Test reset_ignored
ret = softwareupdate.reset_ignored()
assert ret
ret = softwareupdate.list_ignored()
assert ret == []
# Test ignore
ret = softwareupdate.ignore("spongebob")
assert ret
ret = softwareupdate.ignore("squidward")
assert ret
# Test list_ignored and verify ignore
ret = softwareupdate.list_ignored()
assert "spongebob" in ret
ret = softwareupdate.list_ignored()
assert "squidward" in ret
def test_schedule(softwareupdate):
"""
Test softwareupdate.schedule_enable
Test softwareupdate.schedule_enabled
"""
# Test enable
ret = softwareupdate.schedule_enable(True)
assert ret
ret = softwareupdate.schedule_enabled()
assert ret
# Test disable in case it was already enabled
ret = softwareupdate.schedule_enable(False)
assert ret
ret = softwareupdate.schedule_enabled()
assert not ret
def test_update(softwareupdate):
"""
Test softwareupdate.update_all
Test softwareupdate.update
Test softwareupdate.update_available
Need to know the names of updates that are available to properly test
the update functions...
"""
# There's no way to know what the dictionary will contain, so all we can
# check is that the return is a dictionary
ret = softwareupdate.update_all()
assert isinstance(ret, dict)
# Test update_available
ret = softwareupdate.update_available("spongebob")
assert not ret
# Test update not available
ret = softwareupdate.update("spongebob")
assert "Update not available" in ret
def test_list_downloads(softwareupdate):
"""
Test softwareupdate.list_downloads
"""
ret = softwareupdate.list_downloads()
assert isinstance(ret, list)
def test_download(softwareupdate):
"""
Test softwareupdate.download
Need to know the names of updates that are available to properly test
the download function
"""
# Test update not available
ret = softwareupdate.download("spongebob")
assert "Update not available" in ret
def test_download_all(softwareupdate):
"""
Test softwareupdate.download_all
"""
ret = softwareupdate.download_all()
assert isinstance(ret, list)
def test_get_set_reset_catalog(softwareupdate):
"""
Test softwareupdate.download_all
"""
# Reset the catalog
ret = softwareupdate.reset_catalog()
assert ret
ret = softwareupdate.get_catalog()
assert ret == "Default"
# Test setting and getting the catalog
ret = softwareupdate.set_catalog("spongebob")
assert ret
ret = softwareupdate.get_catalog()
assert ret == "spongebob"
# Test reset the catalog
ret = softwareupdate.reset_catalog()
assert ret
assert softwareupdate.get_catalog()
assert ret == "Default"

View file

@ -0,0 +1,225 @@
"""
Integration tests for mac_timezone
If using parallels, make sure Time sync is turned off. Otherwise, parallels will
keep changing your date/time settings while the tests are running. To turn off
Time sync do the following:
- Go to actions -> configure
- Select options at the top and 'More Options' on the left
- Set time to 'Do not sync'
"""
import datetime
import pytest
pytestmark = [
pytest.mark.flaky(max_runs=4),
pytest.mark.skip_if_binaries_missing("systemsetup"),
pytest.mark.slow_test,
pytest.mark.destructive_test,
pytest.mark.skip_if_not_root,
pytest.mark.skip_unless_on_darwin,
]
@pytest.fixture(scope="module")
def timezone(modules):
return modules.timezone
@pytest.fixture(scope="function", autouse=True)
def _setup_teardown_vars(timezone):
USE_NETWORK_TIME = timezone.get_using_network_time()
TIME_SERVER = timezone.get_time_server()
TIME_ZONE = timezone.get_zone()
CURRENT_DATE = timezone.get_date()
CURRENT_TIME = timezone.get_time()
timezone.set_using_network_time(False)
timezone.set_zone("America/Denver")
try:
yield
finally:
timezone.set_time_server(TIME_SERVER)
timezone.set_using_network_time(USE_NETWORK_TIME)
timezone.set_zone(TIME_ZONE)
if not USE_NETWORK_TIME:
timezone.set_date(CURRENT_DATE)
timezone.set_time(CURRENT_TIME)
@pytest.mark.skip(
reason="Skip until we can figure out why modifying the system clock causes ZMQ errors",
)
@pytest.mark.destructive_test
def test_get_set_date(timezone):
"""
Test timezone.get_date
Test timezone.set_date
"""
# Correct Functionality
ret = timezone.set_date("2/20/2011")
assert ret
ret = timezone.get_date()
assert ret == "2/20/2011"
# Test bad date format
ret = timezone.set_date("13/12/2014")
assert (
ret
== "ERROR executing 'timezone.set_date': Invalid Date/Time Format: 13/12/2014"
)
@pytest.mark.slow_test
def test_get_time(timezone):
"""
Test timezone.get_time
"""
text_time = timezone.get_time()
assert text_time != "Invalid Timestamp"
obj_date = datetime.datetime.strptime(text_time, "%H:%M:%S")
assert isinstance(obj_date, datetime.date)
@pytest.mark.skip(
reason="Skip until we can figure out why modifying the system clock causes ZMQ errors",
)
@pytest.mark.destructive_test
def test_set_time(timezone):
"""
Test timezone.set_time
"""
# Correct Functionality
ret = timezone.set_time("3:14")
assert ret
# Test bad time format
ret = timezone.set_time("3:71")
assert ret == "ERROR executing 'timezone.set_time': Invalid Date/Time Format: 3:71"
@pytest.mark.skip(
reason="Skip until we can figure out why modifying the system clock causes ZMQ errors",
)
@pytest.mark.destructive_test
def test_get_set_zone(timezone):
"""
Test timezone.get_zone
Test timezone.set_zone
"""
# Correct Functionality
ret = timezone.set_zone("Pacific/Wake")
assert ret
assert ret == "Pacific/Wake"
# Test bad time zone
ret = timezone.set_zone("spongebob")
assert ret == "ERROR executing 'timezone.set_zone': Invalid Timezone: spongebob"
@pytest.mark.skip(
reason="Skip until we can figure out why modifying the system clock causes ZMQ errors",
)
@pytest.mark.destructive_test
def test_get_offset(timezone):
"""
Test timezone.get_offset
"""
ret = timezone.set_zone("Pacific/Wake")
assert ret
ret = timezone.get_offset()
assert isinstance(ret, str)
assert ret == "+1200"
ret = timezone.set_zone("America/Los_Angeles")
assert ret
assert isinstance(ret, str)
assert ret == "-0700"
@pytest.mark.skip(
reason="Skip until we can figure out why modifying the system clock causes ZMQ errors",
)
@pytest.mark.destructive_test
def test_get_set_zonecode(timezone):
"""
Test timezone.get_zonecode
Test timezone.set_zonecode
"""
ret = timezone.set_zone("America/Los_Angeles")
assert ret
assert isinstance(ret, str)
assert ret == "PDT"
ret = timezone.set_zone("Pacific/Wake")
assert ret
assert isinstance(ret, str)
assert ret == "WAKT"
@pytest.mark.slow_test
def test_list_zones(timezone):
"""
Test timezone.list_zones
"""
zones = timezone.list_zones()
assert isinstance(zones, list)
assert "America/Denver" in zones
assert "America/Los_Angeles" in zones
@pytest.mark.skip(
reason="Skip until we can figure out why modifying the system clock causes ZMQ errors",
)
@pytest.mark.destructive_test
def test_zone_compare(timezone):
"""
Test timezone.zone_compare
"""
ret = timezone.set_zone("America/Denver")
assert ret
ret = timezone.zone_compare("America/Denver")
assert ret
ret = timezone.zone_compare("Pacific/Wake")
assert not ret
@pytest.mark.skip(
reason="Skip until we can figure out why modifying the system clock causes ZMQ errors",
)
@pytest.mark.destructive_test
def test_get_set_using_network_time(timezone):
"""
Test timezone.get_using_network_time
Test timezone.set_using_network_time
"""
ret = timezone.set_using_network_time(True)
assert ret
ret = timezone.get_using_network_time()
assert ret
ret = timezone.set_using_network_time(False)
assert ret
ret = timezone.get_using_network_time()
assert not ret
@pytest.mark.skip(
reason="Skip until we can figure out why modifying the system clock causes ZMQ errors",
)
@pytest.mark.destructive_test
def test_get_set_time_server(timezone):
"""
Test timezone.get_time_server
Test timezone.set_time_server
"""
ret = timezone.set_time_server("spongebob.com")
assert ret
ret = timezone.get_time_server()
assert ret == "spongebob.com"

View file

@ -0,0 +1,233 @@
"""
:codeauthor: Nicole Thomas <nicole@saltstack.com>
"""
import os
import pytest
from saltfactories.utils import random_string
import salt.utils.files
pytestmark = [
pytest.mark.slow_test,
pytest.mark.destructive_test,
pytest.mark.skip_if_not_root,
pytest.mark.skip_unless_on_darwin,
]
@pytest.fixture(scope="module")
def user(modules):
return modules.user
@pytest.fixture(scope="function")
def setup_teardown_vars(user):
ADD_USER = random_string("RS-", lowercase=False)
DEL_USER = random_string("RS-", lowercase=False)
PRIMARY_GROUP_USER = random_string("RS-", lowercase=False)
CHANGE_USER = random_string("RS-", lowercase=False)
try:
yield ADD_USER, DEL_USER, PRIMARY_GROUP_USER, CHANGE_USER
finally:
# Delete ADD_USER
add_info = user.info(ADD_USER)
if add_info:
user.delete(ADD_USER)
# Delete DEL_USER if something failed
del_info = user.info(DEL_USER)
if del_info:
user.delete(DEL_USER)
# Delete CHANGE_USER
change_info = user.info(CHANGE_USER)
if change_info:
user.delete(CHANGE_USER)
def test_mac_user_add(user, setup_teardown_vars):
"""
Tests the add function
"""
ADD_USER = setup_teardown_vars[0]
user.add(ADD_USER)
user_info = user.info(ADD_USER)
assert ADD_USER == user_info["name"]
@pytest.mark.slow_test
def test_mac_user_delete(user, setup_teardown_vars):
"""
Tests the delete function
"""
DEL_USER = setup_teardown_vars[1]
# Create a user to delete - If unsuccessful, skip the test
ret = user.add(DEL_USER)
if ret is not True:
user.delete(DEL_USER)
pytest.skip("Failed to create a user to delete")
# Now try to delete the added user
ret = user.delete(DEL_USER)
assert ret
@pytest.mark.slow_test
def test_mac_user_primary_group(user, setup_teardown_vars):
"""
Tests the primary_group function
"""
PRIMARY_GROUP_USER = setup_teardown_vars[2]
# Create a user to test primary group function
ret = user.add(PRIMARY_GROUP_USER)
if ret is not True:
user.delete(PRIMARY_GROUP_USER)
pytest.skip("Failed to create a user")
# Test mac_user.primary_group
primary_group = user.primary_group(PRIMARY_GROUP_USER)
uid_info = user.info(PRIMARY_GROUP_USER)
assert primary_group in uid_info["groups"]
@pytest.mark.slow_test
def test_mac_user_changes(user, setup_teardown_vars):
"""
Tests mac_user functions that change user properties
"""
CHANGE_USER = setup_teardown_vars[3]
# Create a user to manipulate - if unsuccessful, skip the test
ret = user.add(CHANGE_USER)
if ret is not True:
user.delete(CHANGE_USER)
pytest.skip("Failed to create a user")
# Test mac_user.chuid
user.chuid(CHANGE_USER, 4376)
uid_info = user.info(CHANGE_USER)
assert uid_info["uid"] == 4376
# Test mac_user.chgid
user.chgid(CHANGE_USER, 4376)
gid_info = user.info(CHANGE_USER)
assert gid_info["gid"] == 4376
# Test mac.user.chshell
user.chshell(CHANGE_USER, "/bin/zsh")
shell_info = user.info(CHANGE_USER)
assert shell_info["shell"] == "/bin/zsh"
# Test mac_user.chhome
user.chhome(CHANGE_USER, "/Users/foo")
home_info = user.info(CHANGE_USER)
assert home_info["home"] == "/Users/foo"
# Test mac_user.chfullname
user.chfullname(CHANGE_USER, "Foo Bar")
fullname_info = user.info(CHANGE_USER)
assert fullname_info["fullname"] == "Foo Bar"
# Test mac_user.chgroups
ret = user.info(CHANGE_USER)
pre_info = ret["groups"]
expected = pre_info + ["wheel"]
user.chgroups(CHANGE_USER, "wheel")
groups_info = user.info(CHANGE_USER)
assert groups_info["groups"] == expected
@pytest.mark.slow_test
def test_mac_user_enable_auto_login(user):
"""
Tests mac_user functions that enable auto login
"""
# Make sure auto login is disabled before we start
if user.get_auto_login():
pytest.skip("Auto login already enabled")
try:
# Does enable return True
ret = user.enable_auto_login("Spongebob", "Squarepants")
assert ret
# Did it set the user entry in the plist file
ret = user.get_auto_login()
assert ret == "Spongebob"
# Did it generate the `/etc/kcpassword` file
assert os.path.exists("/etc/kcpassword")
# Are the contents of the file correct
test_data = bytes.fromhex("2e f8 27 42 a0 d9 ad 8b cd cd 6c 7d")
with salt.utils.files.fopen("/etc/kcpassword", "rb") as f:
file_data = f.read()
assert test_data == file_data
# Does disable return True
ret = user.disable_auto_login()
assert ret
# Does it remove the user entry in the plist file
ret = user.get_auto_login()
assert not ret
# Is the `/etc/kcpassword` file removed
assert not os.path.exists("/etc/kcpassword")
finally:
# Make sure auto_login is disabled
ret = user.disable_auto_login()
assert ret
# Make sure autologin is disabled
ret = user.get_auto_login()
if ret:
raise Exception("Failed to disable auto login")
@pytest.mark.slow_test
def test_mac_user_disable_auto_login(user):
"""
Tests mac_user functions that disable auto login
"""
# Make sure auto login is enabled before we start
# Is there an existing setting
if user.get_auto_login():
pytest.skip("Auto login already enabled")
try:
# Enable auto login for the test
user.enable_auto_login("Spongebob", "Squarepants")
# Make sure auto login got set up
ret = user.get_auto_login()
if not ret == "Spongebob":
raise Exception("Failed to enable auto login")
# Does disable return True
ret = user.disable_auto_login()
assert ret
# Does it remove the user entry in the plist file
ret = user.get_auto_login()
assert not ret
# Is the `/etc/kcpassword` file removed
assert not os.path.exists("/etc/kcpassword")
finally:
# Make sure auto login is disabled
ret = user.disable_auto_login()
assert ret
# Make sure auto login is disabled
ret = user.get_auto_login()
if ret:
raise Exception("Failed to disable auto login")

View file

@ -0,0 +1,184 @@
"""
integration tests for mac_xattr
"""
import pytest
pytestmark = [
pytest.mark.skip_if_binaries_missing("xattr"),
pytest.mark.slow_test,
pytest.mark.skip_if_not_root,
pytest.mark.skip_unless_on_darwin,
]
@pytest.fixture(scope="module")
def xttr(modules):
return modules.xttr
@pytest.fixture(scope="function")
def setup_teardown_vars(salt_call_cli, tmp_path):
test_file = tmp_path / "xattr_test_file.txt"
no_file = str(tmp_path / "xattr_no_file.txt")
test_file.touch()
try:
yield str(test_file), no_file
finally:
if test_file.exists():
test_file.unlink()
def test_list_no_xattr(xattr, setup_teardown_vars):
"""
Make sure there are no attributes
"""
test_file = setup_teardown_vars[0]
no_file = setup_teardown_vars[1]
# Clear existing attributes
ret = xattr.clear(test_file)
assert ret
# Test no attributes
ret = xattr.list(test_file)
assert ret == {}
# Test file not found
ret = xattr.list(no_file)
assert f"File not found: {no_file}" in ret
def test_write(xattr, setup_teardown_vars):
"""
Write an attribute
"""
test_file = setup_teardown_vars[0]
no_file = setup_teardown_vars[1]
# Clear existing attributes
ret = xattr.clear(test_file)
assert ret
# Write some attributes
ret = xattr.write(test_file, "spongebob", "squarepants")
assert ret
ret = xattr.write(test_file, "squidward", "plankton")
assert ret
ret = xattr.write(test_file, "crabby", "patty")
assert ret
# Test that they were actually added
ret = xattr.list(test_file)
assert ret == {
"spongebob": "squarepants",
"squidward": "plankton",
"crabby": "patty",
}
# Test file not found
ret = xattr.write(no_file, "patrick", "jellyfish")
assert f"File not found: {no_file}" in ret
def test_read(xattr, setup_teardown_vars):
"""
Test xattr.read
"""
test_file = setup_teardown_vars[0]
no_file = setup_teardown_vars[1]
# Clear existing attributes
ret = xattr.clear(test_file)
assert ret
# Write an attribute
ret = xattr.write(test_file, "spongebob", "squarepants")
assert ret
# Read the attribute
ret = xattr.read(test_file, "spongebob")
assert ret == "squarepants"
# Test file not found
ret = xattr.read(no_file, "spongebob")
assert f"File not found: {no_file}" in ret
# Test attribute not found
ret = xattr.read(test_file, "patrick")
assert "Attribute not found: patrick" in ret
def test_delete(xattr, setup_teardown_vars):
"""
Test xattr.delete
"""
test_file = setup_teardown_vars[0]
no_file = setup_teardown_vars[1]
# Clear existing attributes
ret = xattr.clear(test_file)
assert ret
# Write some attributes
ret = xattr.write(test_file, "spongebob", "squarepants")
assert ret
ret = xattr.write(test_file, "squidward", "plankton")
assert ret
ret = xattr.write(test_file, "crabby", "patty")
assert ret
# Delete an attribute
ret = xattr.delete(test_file, "squidward")
assert ret
# Make sure it was actually deleted
ret = xattr.list(test_file)
assert ret == {
"spongebob": "squarepants",
"crabby": "patty",
}
# Test file not found
ret = xattr.delete(no_file, "spongebob")
assert f"File not found: {no_file}" in ret
# Test attribute not found
ret = xattr.delete(test_file, "patrick")
assert "Attribute not found: patrick" in ret
def test_clear(xattr, setup_teardown_vars):
"""
Test xattr.clear
"""
test_file = setup_teardown_vars[0]
no_file = setup_teardown_vars[1]
# Clear existing attributes
ret = xattr.clear(test_file)
assert ret
# Write some attributes
ret = xattr.write(test_file, "spongebob", "squarepants")
assert ret
ret = xattr.write(test_file, "squidward", "plankton")
assert ret
ret = xattr.write(test_file, "crabby", "patty")
assert ret
# Test Clear
ret = xattr.clear(test_file)
assert ret
# Test file not found
ret = xattr.clear(no_file)
assert f"File not found: {no_file}" in ret