def test_load_libgmt_fail(): "Test that loading fails when given a bad library path." # save the old value (if any) before setting a fake "GMT_LIBRARY_PATH" old_gmt_library_path = os.environ.get("GMT_LIBRARY_PATH") os.environ["GMT_LIBRARY_PATH"] = "/not/a/real/path" with pytest.raises(GMTCLibNotFoundError): load_libgmt() # revert back to the original status (if any) if old_gmt_library_path: os.environ["GMT_LIBRARY_PATH"] = old_gmt_library_path else: del os.environ["GMT_LIBRARY_PATH"]
def test_load_libgmt_with_a_bad_library_path(monkeypatch): """ Test that loading still works when given a bad library path. """ # Set a fake "GMT_LIBRARY_PATH" monkeypatch.setenv("GMT_LIBRARY_PATH", "/not/a/real/path") assert check_libgmt(load_libgmt()) is None
def test_load_brokenlib_invalidpath(self, mock_ctypes): # pylint: disable=unused-argument """ Case 2: broken library + invalid path. Raise the GMTCLibNotFoundError exception. Error message should contain information of one library that failed to load and one invalid path. """ # pylint: disable=protected-access lib_fullnames = [self.faked_libgmt1, self.invalid_path] msg_regex = ( rf"Error loading GMT shared library at '{self.faked_libgmt1._name}'.\n" rf"Error loading '{self.faked_libgmt1._name}'. Couldn't access.*\n" rf"Error loading GMT shared library at '{self.invalid_path}'.\n" f"Unable to find '{self.invalid_path}'") with pytest.raises(GMTCLibNotFoundError, match=msg_regex): load_libgmt(lib_fullnames=lib_fullnames)
def test_two_broken_libraries(self, mock_ctypes): # pylint: disable=unused-argument """ Case 1: two broken libraries. Raise the GMTCLibNotFoundError exception. Error message should contain information of both libraries that failed to load properly. """ # pylint: disable=protected-access lib_fullnames = [self.faked_libgmt1, self.faked_libgmt2] msg_regex = ( rf"Error loading GMT shared library at '{self.faked_libgmt1._name}'.\n" rf"Error loading '{self.faked_libgmt1._name}'. Couldn't access.*\n" rf"Error loading GMT shared library at '{self.faked_libgmt2._name}'.\n" f"Error loading '{self.faked_libgmt2._name}'. Couldn't access.*") with pytest.raises(GMTCLibNotFoundError, match=msg_regex): load_libgmt(lib_fullnames=lib_fullnames)
def test_brokenlib_brokenlib_workinglib(self, mock_ctypes): # pylint: disable=unused-argument """ Case 6: repeating broken libraries + working library. """ lib_fullnames = [ self.faked_libgmt1, self.faked_libgmt1, self.loaded_libgmt ] assert check_libgmt(load_libgmt(lib_fullnames=lib_fullnames)) is None
def test_workinglib_brokenlib_invalidpath(self, mock_ctypes): # pylint: disable=unused-argument """ Case 5: working library + broken library + invalid path. """ lib_fullnames = [ self.loaded_libgmt, self.faked_libgmt1, self.invalid_path ] assert check_libgmt(load_libgmt(lib_fullnames=lib_fullnames)) is None
def test_load_libgmt_fails(monkeypatch): """ Test that GMTCLibNotFoundError is raised when GMT's shared library cannot be found. """ with monkeypatch.context() as mpatch: mpatch.setattr(sys, "platform", "win32") # pretend to be on Windows mpatch.setattr(subprocess, "check_output", lambda cmd, encoding: "libfakegmt.so") with pytest.raises(GMTCLibNotFoundError): check_libgmt(load_libgmt())
def test_load_libgmt(): "Test that loading libgmt works and doesn't crash." check_libgmt(load_libgmt())
class TestLibgmtBrokenLibs: """ Test that load_libgmt still works when a broken library is found. """ # load the GMT library before mocking the ctypes.CDLL function loaded_libgmt = load_libgmt() invalid_path = "/invalid/path/to/libgmt.so" faked_libgmt1 = FakedLibGMT("/path/to/faked/libgmt1.so") faked_libgmt2 = FakedLibGMT("/path/to/faked/libgmt2.so") def _mock_ctypes_cdll_return(self, libname): """ Mock the return value of ctypes.CDLL. Parameters ---------- libname : str or FakedLibGMT or ctypes.CDLL Path to the GMT library, a faked GMT library, or a working library loaded as ctypes.CDLL. Return ------ object Either the loaded GMT library or the faked GMT library. """ if isinstance(libname, FakedLibGMT): # libname is a faked GMT library, return the faked library return libname if isinstance(libname, str): # libname is an invalid library path in string type, # raise OSError like the original ctypes.CDLL raise OSError(f"Unable to find '{libname}'") # libname is a loaded GMT library return self.loaded_libgmt @pytest.fixture def mock_ctypes(self, monkeypatch): """ Patch the ctypes.CDLL function. """ monkeypatch.setattr(ctypes, "CDLL", self._mock_ctypes_cdll_return) def test_two_broken_libraries(self, mock_ctypes): # pylint: disable=unused-argument """ Case 1: two broken libraries. Raise the GMTCLibNotFoundError exception. Error message should contain information of both libraries that failed to load properly. """ # pylint: disable=protected-access lib_fullnames = [self.faked_libgmt1, self.faked_libgmt2] msg_regex = ( rf"Error loading GMT shared library at '{self.faked_libgmt1._name}'.\n" rf"Error loading '{self.faked_libgmt1._name}'. Couldn't access.*\n" rf"Error loading GMT shared library at '{self.faked_libgmt2._name}'.\n" f"Error loading '{self.faked_libgmt2._name}'. Couldn't access.*") with pytest.raises(GMTCLibNotFoundError, match=msg_regex): load_libgmt(lib_fullnames=lib_fullnames) def test_load_brokenlib_invalidpath(self, mock_ctypes): # pylint: disable=unused-argument """ Case 2: broken library + invalid path. Raise the GMTCLibNotFoundError exception. Error message should contain information of one library that failed to load and one invalid path. """ # pylint: disable=protected-access lib_fullnames = [self.faked_libgmt1, self.invalid_path] msg_regex = ( rf"Error loading GMT shared library at '{self.faked_libgmt1._name}'.\n" rf"Error loading '{self.faked_libgmt1._name}'. Couldn't access.*\n" rf"Error loading GMT shared library at '{self.invalid_path}'.\n" f"Unable to find '{self.invalid_path}'") with pytest.raises(GMTCLibNotFoundError, match=msg_regex): load_libgmt(lib_fullnames=lib_fullnames) def test_brokenlib_invalidpath_workinglib(self, mock_ctypes): # pylint: disable=unused-argument """ Case 3: broken library + invalid path + working library. """ lib_fullnames = [ self.faked_libgmt1, self.invalid_path, self.loaded_libgmt ] assert check_libgmt(load_libgmt(lib_fullnames=lib_fullnames)) is None def test_invalidpath_brokenlib_workinglib(self, mock_ctypes): # pylint: disable=unused-argument """ Case 4: invalid path + broken library + working library. """ lib_fullnames = [ self.invalid_path, self.faked_libgmt1, self.loaded_libgmt ] assert check_libgmt(load_libgmt(lib_fullnames=lib_fullnames)) is None def test_workinglib_brokenlib_invalidpath(self, mock_ctypes): # pylint: disable=unused-argument """ Case 5: working library + broken library + invalid path. """ lib_fullnames = [ self.loaded_libgmt, self.faked_libgmt1, self.invalid_path ] assert check_libgmt(load_libgmt(lib_fullnames=lib_fullnames)) is None def test_brokenlib_brokenlib_workinglib(self, mock_ctypes): # pylint: disable=unused-argument """ Case 6: repeating broken libraries + working library. """ lib_fullnames = [ self.faked_libgmt1, self.faked_libgmt1, self.loaded_libgmt ] assert check_libgmt(load_libgmt(lib_fullnames=lib_fullnames)) is None