diff --git a/.fmf/version b/.fmf/version new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/.fmf/version @@ -0,0 +1 @@ +1 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f419dc9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +python-pidfile-* +python-pidfile-*.tar.gz +__pycache__/ \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..aab8ff3 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 Mosquito and others + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/plans/tests.fmf b/plans/tests.fmf new file mode 100644 index 0000000..2cf54e9 --- /dev/null +++ b/plans/tests.fmf @@ -0,0 +1,10 @@ +prepare: + how: install + package: + - python3-pidfile + +discover: + how: fmf + +execute: + how: tmt diff --git a/python-pidfile.spec b/python-pidfile.spec new file mode 100644 index 0000000..cdd5956 --- /dev/null +++ b/python-pidfile.spec @@ -0,0 +1,91 @@ +%global module_name pidfile +%global pypi_name python-%{module_name} +Name: %{pypi_name} +Version: 3.0.0 +Release: 15%{?dist} +Summary: Python context manager for managing pid files +License: MIT +URL: https://pypi.org/project/python-pidfile +Source0: %pypi_source +Source1: https://raw.githubusercontent.com/mosquito/python-pidfile/master/LICENSE +BuildArch: noarch + +%global _description %{expand: +Python context manager for managing pid files.} + +%description %_description + +%package -n python3-%{module_name} +Summary: %{summary} + +BuildRequires: python3-devel + +%description -n python3-%{module_name} %_description + +%prep +%autosetup %{name}-%{version} +cp -p %{SOURCE1} . + +%generate_buildrequires +%pyproject_buildrequires + +%build +%pyproject_wheel + +%install +%pyproject_install + +%pyproject_save_files %{module_name} + +%check +%pyproject_check_import + +%files -n python3-pidfile -f %{pyproject_files} +%doc README.rst +%license LICENSE + +%changelog +* Fri Sep 19 2025 Python Maint - 3.0.0-15 +- Rebuilt for Python 3.14.0rc3 bytecode + +* Fri Aug 15 2025 Python Maint - 3.0.0-14 +- Rebuilt for Python 3.14.0rc2 bytecode + +* Fri Jul 25 2025 Fedora Release Engineering - 3.0.0-13 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild + +* Tue Jun 03 2025 Python Maint - 3.0.0-12 +- Rebuilt for Python 3.14 + +* Sat Jan 18 2025 Fedora Release Engineering - 3.0.0-11 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild + +* Fri Jul 19 2024 Fedora Release Engineering - 3.0.0-10 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild + +* Fri Jun 07 2024 Python Maint - 3.0.0-9 +- Rebuilt for Python 3.13 + +* Fri Jan 26 2024 Fedora Release Engineering - 3.0.0-8 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + +* Mon Jan 22 2024 Fedora Release Engineering - 3.0.0-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + +* Fri Jul 21 2023 Fedora Release Engineering - 3.0.0-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild + +* Wed Jun 14 2023 Python Maint - 3.0.0-5 +- Rebuilt for Python 3.12 + +* Fri Jan 20 2023 Fedora Release Engineering - 3.0.0-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild + +* Tue Oct 04 2022 Vishal Vijayraghavan - 3.0.0-3 +- add license source and test + +* Sun Oct 02 2022 Vishal Vijayraghavan - 3.0.0-2 +- specfile cleanup + +* Tue Sep 27 2022 Vishal Vijayraghavan - 3.0.0-1 +- Initial fedora build. diff --git a/sources b/sources new file mode 100644 index 0000000..1ea1229 --- /dev/null +++ b/sources @@ -0,0 +1 @@ +SHA512 (python-pidfile-3.0.0.tar.gz) = 82f87a2b3ac733ced78a87216f42b7fdc91f956fa9ec7e64f67ea5d53caf38652dc8b6e0518f6cfacf6bfe662c5d732f632b8f469af60555a8e6a43dbb99afbe diff --git a/tests/test.fmf b/tests/test.fmf new file mode 100644 index 0000000..4979eeb --- /dev/null +++ b/tests/test.fmf @@ -0,0 +1 @@ +test: python3 test_pidfile.py /tmp/test.log diff --git a/tests/test_pidfile.py b/tests/test_pidfile.py new file mode 100644 index 0000000..f3567ce --- /dev/null +++ b/tests/test_pidfile.py @@ -0,0 +1,98 @@ +import unittest +import sys +from unittest import TestCase + +try: + # Python 3.x + from unittest.mock import patch, mock_open + open_name = 'builtins.open' +except ImportError: + # Python 2.7 + from mock import patch, mock_open + open_name = '__builtin__.open' + +import pidfile +import os +import psutil + +builtins_open = open + + +def open_patcher(data): + def patched_open(*args, **kwargs): + if args[0] == 'pidfile': + return mock_open(read_data=data)(*args, **kwargs) + else: + return builtins_open(*args, **kwargs) + return patched_open + + +def open_patcher_exception(): + def patched_open(*args, **kwargs): + if args[0] == 'pidfile': + mo = mock_open() + mo.return_value.read.side_effect = OSError + return mo(*args, **kwargs) + else: + return builtins_open(*args, **kwargs) + return patched_open + + +class PIDFileTestCase(TestCase): + @patch(open_name, new=open_patcher('1')) + @patch('os.path.exists') + def test_pidfile_not_exists(self, exists_mock): + exists_mock.return_value = False + with pidfile.PIDFile(): + assert True + + @patch(open_name, new=open_patcher('1')) + @patch('psutil.pid_exists') + @patch('psutil.Process') + @patch('os.path.exists') + def test_pidfile_exists_process_running(self, exists_mock, Process_mock, + pid_exists_mock): + exists_mock.return_value = True + pid_exists_mock.return_value = True + Process_mock.return_value = psutil.Process(os.getpid()) + with self.assertRaises(pidfile.AlreadyRunningError): + with pidfile.PIDFile(): + assert True + + @patch(open_name, new=open_patcher('1')) + @patch('psutil.pid_exists') + @patch('os.path.exists') + def test_pidfile_exists_process_not_running(self, exists_mock, + pid_exists_mock): + exists_mock.return_value = True + pid_exists_mock.return_value = False + with pidfile.PIDFile(): + assert True + + @patch(open_name, new=open_patcher('')) + @patch('psutil.pid_exists') + @patch('os.path.exists') + def test_pidfile_exists_empty(self, exists_mock, pid_exists_mock): + exists_mock.return_value = True + pid_exists_mock.return_value = True + with pidfile.PIDFile(): + assert True + + @patch(open_name, new=open_patcher_exception()) + @patch('psutil.pid_exists') + @patch('os.path.exists') + def test_pidfile_exists_read_fail(self, exists_mock, pid_exists_mock): + exists_mock.return_value = True + pid_exists_mock.return_value = True + with pidfile.PIDFile(): + assert True + +def main(out = sys.stderr, verbosity = 2): + loader = unittest.TestLoader() + + suite = loader.loadTestsFromModule(sys.modules[__name__]) + unittest.TextTestRunner(out, verbosity = verbosity).run(suite) + +if __name__ == '__main__': + with open(sys.argv[1], 'w') as f: + main(f) \ No newline at end of file