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

Fixing failing test on Windows #493

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

jesper-friis
Copy link
Collaborator

Closes #448

Type of change:

  • Bug fix.
  • New feature.
  • Documentation update.

Checklist:

This checklist can be used as a help for the reviewer.

  • Is the code easy to read and understand?
  • Are comments for humans to read, not computers to disregard?
  • Does a new feature has an accompanying new test (in the CI or unit testing schemes)?
  • Has the documentation been updated as necessary?
  • Does this close the issue?
  • Is the change limited to the issue?
  • Are errors handled for all outcomes?
  • Does the new feature provide new restrictions on dependencies, and if so is this documented?

Comments:

@jesper-friis jesper-friis requested a review from sygout October 21, 2022 23:25
@jesper-friis jesper-friis linked an issue Oct 21, 2022 that may be closed by this pull request
@sygout
Copy link
Collaborator

sygout commented Oct 22, 2022

The new version is still not working:

====================================================== FAILURES =======================================================
_________________________________________________ test_sync_reasoner __________________________________________________

src = 'C:\Users\sygo\AppData\Local\Temp\tmppe0c3koq', dst = 'C:\Users\sygo\AppData\Local\Temp\tmpcmdqr5us'
copy_function = <function copy2 at 0x000001C60AB57700>

def move(src, dst, copy_function=copy2):
    """Recursively move a file or directory to another location. This is
    similar to the Unix "mv" command. Return the file or directory's
    destination.

    If the destination is a directory or a symlink to a directory, the source
    is moved inside the directory. The destination path must not already
    exist.

    If the destination already exists but is not a directory, it may be
    overwritten depending on os.rename() semantics.

    If the destination is on our current filesystem, then rename() is used.
    Otherwise, src is copied to the destination and then removed. Symlinks are
    recreated under the new name if os.rename() fails because of cross
    filesystem renames.

    The optional `copy_function` argument is a callable that will be used
    to copy the source or it will be delegated to `copytree`.
    By default, copy2() is used, but any function that supports the same
    signature (like copy()) can be used.

    A lot more could be done here...  A look at a mv.c shows a lot of
    the issues this implementation glosses over.

    """
    sys.audit("shutil.move", src, dst)
    real_dst = dst
    if os.path.isdir(dst):
        if _samefile(src, dst):
            # We might be on a case insensitive filesystem,
            # perform the rename anyway.
            os.rename(src, dst)
            return

        # Using _basename instead of os.path.basename is important, as we must
        # ignore any trailing slash to avoid the basename returning ''
        real_dst = os.path.join(dst, _basename(src))

        if os.path.exists(real_dst):
            raise Error("Destination path '%s' already exists" % real_dst)
    try:
      os.rename(src, real_dst)

E FileExistsError: [WinError 183] Cannot create a file when that file already exists: 'C:\Users\sygo\AppData\Local\Temp\tmppe0c3koq' -> 'C:\Users\sygo\AppData\Local\Temp\tmpcmdqr5us'

C:\Python\Python39\lib\shutil.py:815: FileExistsError

During handling of the above exception, another exception occurred:

testonto = get_ontology("http://emmo.info/testonto#")

def test_sync_reasoner(testonto: "Ontology") -> None:
    """Test `ontopy:Ontology.sync_reasoner()`."""
  testonto.sync_reasoner()

test_basic.py:60:


......\ontopy2\EMMO-python\ontopy\ontology.py:1073: in sync_reasoner
sync(self, **kwargs)
......\ontopy2\EMMO-python\ontopy\factpluspluswrapper\sync_factpp.py:80: in sync_reasoner_factpp
graph2 = FaCTPPGraph(graph1).inferred_graph()
......\ontopy2\EMMO-python\ontopy\factpluspluswrapper\factppgraph.py:66: in inferred_graph
self.add_base_annotations()
......\ontopy2\EMMO-python\ontopy\factpluspluswrapper\factppgraph.py:76: in add_base_annotations
inferred = self.inferred
......\ontopy2\EMMO-python\ontopy\factpluspluswrapper\factppgraph.py:32: in inferred
self._inferred = self.raw_inferred_graph()
......\ontopy2\EMMO-python\ontopy\factpluspluswrapper\factppgraph.py:62: in raw_inferred_graph
return OwlApiInterface().reason(self.graph)
......\ontopy2\EMMO-python\ontopy\factpluspluswrapper\owlapi_interface.py:34: in reason
graph.serialize(tmpdir.name, format="xml")
C:\Users\sygo\Envs\ontopy2\lib\site-packages\rdflib\graph.py:1210: in serialize
shutil.move(name, dest)
C:\Python\Python39\lib\shutil.py:835: in move
copy_function(src, real_dst)
C:\Python\Python39\lib\shutil.py:444: in copy2
copyfile(src, dst, follow_symlinks=follow_symlinks)


src = 'C:\Users\sygo\AppData\Local\Temp\tmppe0c3koq', dst = 'C:\Users\sygo\AppData\Local\Temp\tmpcmdqr5us'

def copyfile(src, dst, *, follow_symlinks=True):
    """Copy data from src to dst in the most efficient way possible.

    If follow_symlinks is not set and src is a symbolic link, a new
    symlink will be created instead of copying the file it points to.

    """
    sys.audit("shutil.copyfile", src, dst)

    if _samefile(src, dst):
        raise SameFileError("{!r} and {!r} are the same file".format(src, dst))

    file_size = 0
    for i, fn in enumerate([src, dst]):
        try:
            st = _stat(fn)
        except OSError:
            # File most likely does not exist
            pass
        else:
            # XXX What about other special files? (sockets, devices...)
            if stat.S_ISFIFO(st.st_mode):
                fn = fn.path if isinstance(fn, os.DirEntry) else fn
                raise SpecialFileError("`%s` is a named pipe" % fn)
            if _WINDOWS and i == 0:
                file_size = st.st_size

    if not follow_symlinks and _islink(src):
        os.symlink(os.readlink(src), dst)
    else:
        with open(src, 'rb') as fsrc:
            try:
              with open(dst, 'wb') as fdst:

E PermissionError: [Errno 13] Permission denied: 'C:\Users\sygo\AppData\Local\Temp\tmpcmdqr5us'

C:\Python\Python39\lib\shutil.py:266: PermissionError
------------------------------------------------ Captured stdout call -------------------------------------------------
*** Prepare graph
*** Run FaCT++ reasoner (and postprocess)
=============================================== short test summary info ===============================================
FAILED test_basic.py::test_sync_reasoner - PermissionError: [Errno 13] Permission denied: 'C:\Users\sygo\AppData\...

@jesper-friis
Copy link
Collaborator Author

......\ontopy2\EMMO-python\ontopy\factpluspluswrapper\owlapi_interface.py:34: in reason
graph.serialize(tmpdir.name, format="xml")

Are you testing the latest update of this branch? graph.serialize(...) should be line 35.

@sygout
Copy link
Collaborator

sygout commented Oct 22, 2022

Previous error was due to an unclean virtual environment. New error

================================================= test session starts =================================================
platform win32 -- Python 3.9.9, pytest-7.1.3, pluggy-1.0.0
rootdir: C:\Users\sygo\Sylvain\Codes\temporary\ontopy3\EMMOntoPy
collected 2 items

test_basic.py .F [100%]

====================================================== FAILURES =======================================================
_________________________________________________ test_sync_reasoner __________________________________________________

testonto = get_ontology("http://emmo.info/testonto#")

def test_sync_reasoner(testonto: "Ontology") -> None:
    """Test `ontopy:Ontology.sync_reasoner()`."""
  testonto.sync_reasoner()

test_basic.py:60:


..\ontopy\ontology.py:1085: in sync_reasoner
sync(self, **kwargs)
..\ontopy\factpluspluswrapper\sync_factpp.py:80: in sync_reasoner_factpp
graph2 = FaCTPPGraph(graph1).inferred_graph()
..\ontopy\factpluspluswrapper\factppgraph.py:66: in inferred_graph
self.add_base_annotations()
..\ontopy\factpluspluswrapper\factppgraph.py:76: in add_base_annotations
inferred = self.inferred
..\ontopy\factpluspluswrapper\factppgraph.py:32: in inferred
self._inferred = self.raw_inferred_graph()
..\ontopy\factpluspluswrapper\factppgraph.py:62: in raw_inferred_graph
return OwlApiInterface().reason(self.graph)
..\ontopy\factpluspluswrapper\owlapi_interface.py:36: in reason
return self._run(tmpfile, command="--run-reasoner")
..\ontopy\factpluspluswrapper\owlapi_interface.py:90: in _run
subprocess.run(cmd, check=True) # nosec


input = None, capture_output = False, timeout = None, check = True
popenargs = (['java', '-cp', 'C:\Users\sygo\Sylvain\Codes\temporary\ontopy3\EMMOntoPy\ontopy\factpluspluswrapper\java/li...\ontopy3\EMMOntoPy\ontopy\factpluspluswrapper\java/lib/so', 'org.simphony.OntologyLoader', '--run-reasoner', ...],)
kwargs = {}, process = <Popen: returncode: 1 args: ['java', '-cp', 'C:\Users\sygo\Sylvain\Codes...>, stdout = None
stderr = None, retcode = 1

def run(*popenargs,
        input=None, capture_output=False, timeout=None, check=False, **kwargs):
    """Run command with arguments and return a CompletedProcess instance.

    The returned instance will have attributes args, returncode, stdout and
    stderr. By default, stdout and stderr are not captured, and those attributes
    will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them.

    If check is True and the exit code was non-zero, it raises a
    CalledProcessError. The CalledProcessError object will have the return code
    in the returncode attribute, and output & stderr attributes if those streams
    were captured.

    If timeout is given, and the process takes too long, a TimeoutExpired
    exception will be raised.

    There is an optional argument "input", allowing you to
    pass bytes or a string to the subprocess's stdin.  If you use this argument
    you may not also use the Popen constructor's "stdin" argument, as
    it will be used internally.

    By default, all communication is in bytes, and therefore any "input" should
    be bytes, and the stdout and stderr will be bytes. If in text mode, any
    "input" should be a string, and stdout and stderr will be strings decoded
    according to locale encoding, or by "encoding" if set. Text mode is
    triggered by setting any of text, encoding, errors or universal_newlines.

    The other arguments are the same as for the Popen constructor.
    """
    if input is not None:
        if kwargs.get('stdin') is not None:
            raise ValueError('stdin and input arguments may not both be used.')
        kwargs['stdin'] = PIPE

    if capture_output:
        if kwargs.get('stdout') is not None or kwargs.get('stderr') is not None:
            raise ValueError('stdout and stderr arguments may not be used '
                             'with capture_output.')
        kwargs['stdout'] = PIPE
        kwargs['stderr'] = PIPE

    with Popen(*popenargs, **kwargs) as process:
        try:
            stdout, stderr = process.communicate(input, timeout=timeout)
        except TimeoutExpired as exc:
            process.kill()
            if _mswindows:
                # Windows accumulates the output in a single blocking
                # read() call run on child threads, with the timeout
                # being done in a join() on those threads.  communicate()
                # _after_ kill() is required to collect that and add it
                # to the exception.
                exc.stdout, exc.stderr = process.communicate()
            else:
                # POSIX _communicate already populated the output so
                # far into the TimeoutExpired exception.
                process.wait()
            raise
        except:  # Including KeyboardInterrupt, communicate handled that.
            process.kill()
            # We don't call process.wait() as .__exit__ does that for us.
            raise
        retcode = process.poll()
        if check and retcode:
          raise CalledProcessError(retcode, process.args,
                                     output=stdout, stderr=stderr)

E subprocess.CalledProcessError: Command '['java', '-cp', 'C:\Users\sygo\Sylvain\Codes\temporary\ontopy3\EMMOntoPy\ontopy\factpluspluswrapper\java/lib/jars/*', '-Djava.library.path=C:\Users\sygo\Sylvain\Codes\temporary\ontopy3\EMMOntoPy\ontopy\factpluspluswrapper\java/lib/so', 'org.simphony.OntologyLoader', '--run-reasoner', 'C:\Users\sygo\AppData\Local\Temp\tmph7kl7670wt\tmponto.xml']' returned non-zero exit status 1.

C:\Python\Python39\lib\subprocess.py:528: CalledProcessError
------------------------------------------------ Captured stdout call -------------------------------------------------
*** Prepare graph
*** Run FaCT++ reasoner (and postprocess)
--run-reasoner
------------------------------------------------ Captured stderr call -------------------------------------------------
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Exception in thread "main" java.lang.UnsatisfiedLinkError: no FaCTPlusPlusJNI in java.library.path
at java.lang.ClassLoader.loadLibrary(Unknown Source)
at java.lang.Runtime.loadLibrary0(Unknown Source)
at java.lang.System.loadLibrary(Unknown Source)
at uk.ac.manchester.cs.factplusplus.FaCTPlusPlus.(Unknown Source)
at uk.ac.manchester.cs.factplusplus.owlapiv3.FaCTPlusPlusReasoner.(Unknown Source)
at uk.ac.manchester.cs.factplusplus.owlapiv3.FaCTPlusPlusReasonerFactory.createReasoner(Unknown Source)
at uk.ac.manchester.cs.factplusplus.owlapiv3.FaCTPlusPlusReasonerFactory.createReasoner(Unknown Source)
at org.simphony.OntologyLoader.generateInferredAxioms(OntologyLoader.java:84)
at org.simphony.OntologyLoader.main(OntologyLoader.java:138)
================================================== warnings summary ===================================================
tests/test_basic.py::test_basic
C:\Users\sygo\Sylvain\Codes\temporary\ontopy3\EMMOntoPy\ontopy\ontology.py:395: UserWarning: adding new IRI to ontology: http://www.w3.org/2004/02/skos/core#prefLabel
warnings.warn(f"adding new IRI to ontology: {iri}")

tests/test_basic.py::test_basic
C:\Users\sygo\Sylvain\Codes\temporary\ontopy3\EMMOntoPy\ontopy\ontology.py:395: UserWarning: adding new IRI to ontology: http://www.w3.org/2004/02/skos/core#altLabel
warnings.warn(f"adding new IRI to ontology: {iri}")

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
=============================================== short test summary info ===============================================
FAILED test_basic.py::test_sync_reasoner - subprocess.CalledProcessError: Command '['java', '-cp', 'C:\Users\sygo\...
======================================= 1 failed, 1 passed, 2 warnings in 3.48s =======================================

@jesper-friis
Copy link
Collaborator Author

jesper-friis commented Oct 22, 2022

This is a difficult one when I am not able to reproduce the error. It could be that the version of java you have installed on your machine is incompatible with FaCT++? Are you able to run the command that subprocess tries to execute manually?

It should also be possible to use HermiT on the absolutely latest version of EMMO 1.0.0-beta4 (tested on Linux).

@codecov
Copy link

codecov bot commented Oct 30, 2023

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 72.90%. Comparing base (6a0a455) to head (54deac3).
Report is 1 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff           @@
##           master     #493   +/-   ##
=======================================
  Coverage   72.90%   72.90%           
=======================================
  Files          18       18           
  Lines        3790     3791    +1     
=======================================
+ Hits         2763     2764    +1     
  Misses       1027     1027           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

test_basic failing on Windows
3 participants