#!/usr/local/cpython-3.5/bin/python3 '''Tests for just_one.py''' from __future__ import print_function import os import sys from unittest import mock # pylint: disable=no-name-in-module import just_one def silent_unlink(string): '''Unlink the pid file. If it does not yet exist, do not complain''' directory = just_one.get_just_one_dir() filename = os.path.join(directory, string) try: os.unlink(filename) except (OSError, IOError): pass def create_file(string, pid): '''Create the pid file''' directory = just_one.get_just_one_dir() filename = os.path.join(directory, string) with open(filename, 'w') as file_: file_.write('{}\n'.format(pid)) def test_start_command_true(): '''Test start_command''' all_good = True exit_code = just_one.start_command(verbose=False, command='/bin/true', filename='/tmp/foo') if exit_code != 0: sys.stderr.write('{}: test_start_command_true: exit_code nonzero: {}\n'.format(sys.argv[0], exit_code)) all_good = False return all_good def test_start_command_false(): '''Test start_command''' all_good = True exit_code = just_one.start_command(verbose=False, command='/bin/false', filename='/tmp/foo') if exit_code == 0: sys.stderr.write('{}: test_start_command_false: exit_code zero: {}\n'.format(sys.argv[0], exit_code)) all_good = False return all_good def test_no_preexisting_file(): '''Test with no preexisting file''' all_good = True string = 'sleep' silent_unlink(string=string) with \ mock.patch('just_one.subprocess.call', autospec=just_one.subprocess.call) as call_mock, \ mock.patch('just_one.subprocess.Popen', mock.Mock(spec_set=just_one.subprocess.Popen)) as popen_mock \ : _unused_exit_code = just_one.run_one(verbose=False, command='sleep 1', string=string) if call_mock.call_count != 0: sys.stderr.write('{}: test_no_preexisting_file: call_mock.call_count is {}, should be 0\n'.format( sys.argv[0], call_mock.call_count, )) all_good = False if popen_mock.call_count != 1: sys.stderr.write('{}: test_no_preexisting_file: popen.call_count is {}, should be 1\n'.format( sys.argv[0], popen_mock.call_count, )) all_good = False return all_good def test_file_extent_pid_not(): '''Test with pid nonexistent and successful command start''' all_good = True string = 'sleep' # We use a pid that should never exit on a typical Linux system create_file(string=string, pid=9999999) with \ mock.patch('just_one.subprocess.call', mock.Mock(spec_set=just_one.subprocess.call, side_effect=[1])) as call_mock, \ mock.patch('just_one.subprocess.Popen', mock.Mock(spec_set=just_one.subprocess.Popen)) as popen_mock \ : _unused_exit_code = just_one.run_one(verbose=False, command='sleep 1', string=string) if call_mock.call_count != 1: sys.stderr.write('{}: test_no_preexisting_file: call_mock.call_count is {}, should be 1\n'.format( sys.argv[0], call_mock.call_count, )) all_good = False if popen_mock.call_count != 1: sys.stderr.write('{}: test_no_preexisting_file: popen.call_count is {}, should be 1\n'.format( sys.argv[0], popen_mock.call_count, )) all_good = False return all_good def test_file_and_pid_extent(): '''Test with file and pid existent''' all_good = True string = 'sleep' # pid 1 should always exist on a Linux/Unix system - it's init create_file(string=string, pid=1) with \ mock.patch('just_one.subprocess.call', mock.Mock(spec_set=just_one.subprocess.call, side_effect=[0])) as call_mock, \ mock.patch('just_one.subprocess.Popen', mock.Mock(spec_set=just_one.subprocess.Popen)) as popen_mock, \ mock.patch('just_one.sys.stderr.write') \ : _unused_exit_code = just_one.run_one(verbose=False, command='sleep 1', string=string) if call_mock.call_count != 1: sys.stderr.write('{}: test_no_preexisting_file: call_mock.call_count is {}, should be 1\n'.format( sys.argv[0], call_mock.call_count, )) all_good = False if popen_mock.call_count != 0: sys.stderr.write('{}: test_no_preexisting_file: popen.call_count is {}, should be 0\n'.format( sys.argv[0], popen_mock.call_count, )) all_good = False return all_good def test_run_one_true(): '''Test with no lock and running /bin/true''' all_good = True string = 'true' silent_unlink(string=string) exit_code = just_one.run_one(verbose=False, command='/bin/true', string=string) if exit_code: sys.stderr.write('{}: true returned false\n'.format(sys.argv[0])) all_good = False return all_good def test_run_one_false(): '''Test with no lock and running /bin/false''' all_good = True string = 'false' silent_unlink(string=string) exit_code = just_one.run_one(verbose=False, command='/bin/false', string=string) if not exit_code: sys.stderr.write('{}: false returned true\n'.format(sys.argv[0])) all_good = False return all_good def test_pid_exists_always(): '''Test pid_exits with an always-extent pid''' all_good = True retval = just_one.pid_exists(verbose=False, pid='1') if not retval: sys.stderr.write('{}: pid_exists(1) returned bad value: {}\n'.format(sys.argv[0], retval)) all_good = False return all_good def test_pid_exists_never(): '''Test pid_exits with a never-extent pid''' all_good = True retval = just_one.pid_exists(verbose=False, pid='9999999') if retval: sys.stderr.write('{}: pid_exists(9999999) returned bad value: {}\n'.format(sys.argv[0], retval)) all_good = False return all_good def main(): '''Main function''' all_good = True all_good &= test_no_preexisting_file() all_good &= test_file_extent_pid_not() all_good &= test_file_and_pid_extent() all_good &= test_run_one_true() all_good &= test_run_one_false() all_good &= test_start_command_true() all_good &= test_start_command_false() all_good &= test_pid_exists_always() all_good &= test_pid_exists_never() if all_good: sys.exit(0) else: sys.stderr.write('{}: One or more tests failed\n'.format(sys.argv[0])) sys.exit(1) main()