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

pexpect-py fails several sets of tests #1117

Open
nieder opened this issue Jan 20, 2024 · 2 comments
Open

pexpect-py fails several sets of tests #1117

nieder opened this issue Jan 20, 2024 · 2 comments

Comments

@nieder
Copy link
Member

nieder commented Jan 20, 2024

This is to keep things in a known location while things get solved.

First set of failing tests in test_pexpect.py

_____________________________________________________________ ExpectTestCase.test_stdin_closed ______________________________________________________________

self = <tests.test_expect.ExpectTestCase testMethod=test_stdin_closed>

    def test_stdin_closed(self):
        '''
        Ensure pexpect continues to operate even when stdin is closed
        '''
        class Closed_stdin_proc(multiprocessing.Process):
            def run(self):
                sys.__stdin__.close()
                cat = pexpect.spawn('cat')
                cat.sendeof()
                cat.expect(pexpect.EOF)
    
        proc = Closed_stdin_proc()
>       proc.start()

tests/test_expect.py:693: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/opt/sw/lib/python3.10/multiprocessing/process.py:121: in start
    self._popen = self._Popen(self)
/opt/sw/lib/python3.10/multiprocessing/context.py:224: in _Popen
    return _default_context.get_context().Process._Popen(process_obj)
/opt/sw/lib/python3.10/multiprocessing/context.py:284: in _Popen
    return Popen(process_obj)
/opt/sw/lib/python3.10/multiprocessing/popen_spawn_posix.py:32: in __init__
    super().__init__(process_obj)
/opt/sw/lib/python3.10/multiprocessing/popen_fork.py:19: in __init__
    self._launch(process_obj)
/opt/sw/lib/python3.10/multiprocessing/popen_spawn_posix.py:47: in _launch
    reduction.dump(process_obj, fp)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

obj = <Closed_stdin_proc name='Closed_stdin_proc-1' parent=85142 initial>, file = <_io.BytesIO object at 0x10b309ee0>, protocol = None

    def dump(obj, file, protocol=None):
        '''Replacement for pickle.dump() using ForkingPickler.'''
>       ForkingPickler(file, protocol).dump(obj)
E       AttributeError: Can't pickle local object 'ExpectTestCase.test_stdin_closed.<locals>.Closed_stdin_proc'

/opt/sw/lib/python3.10/multiprocessing/reduction.py:60: AttributeError

Can't pickle apparently means multiprocessing module from python-base can't serialize non-top module level functions. So move the two functions/classes in question to the top level in tests/test_expect.py

Second set of failures in test_socket.py and test_socket_fd.py

pexpect/pexpect#665

______________________________________________________________ ExpectTestCase.test_fd_isalive _______________________________________________________________

self = <tests.test_socket.ExpectTestCase testMethod=test_fd_isalive>

        def setUp(self):
            print(self.id())
            PexpectTestCase.PexpectTestCase.setUp(self)
            self.af = socket.AF_INET
            self.host = '127.0.0.1'
            try:
                socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            except socket.error:
                try:
                    socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
                    self.af = socket.AF_INET6
                    self.host = '::1'
                except socket.error:
                    pass
            self.port = 49152 + 10000
            self.motd = b"""\
    ------------------------------------------------------------------------------
    *                  Welcome to the SOCKET UNIT TEST code!                     *
    ------------------------------------------------------------------------------
    *                                                                            *
    * This unit test code is our best effort at testing the ability of the       *
    * pexpect library to handle sockets. We need some text to test buffer size   *
    * handling.                                                                  *
    *                                                                            *
    * A page is 1024 bytes or 1K. 80 x 24 = 1920. So a standard terminal window  *
    * contains more than one page. We actually want more than a page for our     *
    * tests.                                                                     *
    *                                                                            *
    * This is the twelfth line, and we need 24. So we need a few more paragraphs.*
    * We can keep them short and just put lines between them.                    *
    *                                                                            *
    * The 80 x 24 terminal size comes from the ancient past when computers were  *
    * only able to display text in cuneiform writing.                            *
    *                                                                            *
    * The cunieform writing system used the edge of a reed to make marks on clay *
    * tablets.                                                                   *
    *                                                                            *
    * It was the forerunner of the style of handwriting used by doctors to write *
    * prescriptions. Thus the name: pre (before) script (writing) ion (charged   *
    * particle).                                                                 *
    ------------------------------------------------------------------------------
    """.replace(b'\n', b'\n\r') + b"\r\n"
            self.prompt1 = b'Press Return to continue:'
            self.prompt2 = b'Rate this unit test>'
            self.prompt3 = b'Press X to exit:'
            self.enter = b'\r\n'
            self.exit = b'X\r\n'
            self.server_up = multiprocessing.Event()
            self.server_process = multiprocessing.Process(target=self.socket_server, args=(self.server_up,))
            self.server_process.daemon = True
>           self.server_process.start()

/opt/sw/build.build/pexpect-py310-4.9.0-1/pexpect-4.9.0/tests/test_socket.py:89: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/opt/sw/lib/python3.10/multiprocessing/process.py:121: in start
    self._popen = self._Popen(self)
/opt/sw/lib/python3.10/multiprocessing/context.py:224: in _Popen
    return _default_context.get_context().Process._Popen(process_obj)
/opt/sw/lib/python3.10/multiprocessing/context.py:284: in _Popen
    return Popen(process_obj)
/opt/sw/lib/python3.10/multiprocessing/popen_spawn_posix.py:32: in __init__
    super().__init__(process_obj)
/opt/sw/lib/python3.10/multiprocessing/popen_fork.py:19: in __init__
    self._launch(process_obj)
/opt/sw/lib/python3.10/multiprocessing/popen_spawn_posix.py:47: in _launch
    reduction.dump(process_obj, fp)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

obj = <Process name='Process-1' parent=85362 initial daemon>, file = <_io.BytesIO object at 0x1061113f0>, protocol = None

    def dump(obj, file, protocol=None):
        '''Replacement for pickle.dump() using ForkingPickler.'''
>       ForkingPickler(file, protocol).dump(obj)
E       AttributeError: Can't pickle local object 'ArgumentParser.__init__.<locals>.identity'

/opt/sw/lib/python3.10/multiprocessing/reduction.py:60: AttributeError
------------------------------------------------------------------- Captured stdout call --------------------------------------------------------------------

Solution from upstream bug report and commit referenced there: Don't use spawn() but force fork() on macOS.

Third set of failures in test_socket_pexpect.py

____________________________________________________________ ExpectTestCase.test_socket_isalive _____________________________________________________________

self = <tests.test_socket_pexpect.ExpectTestCase testMethod=test_socket_isalive>

    def test_socket_isalive (self):
        socket = open_file_socket('TESTDATA.txt')
        s = socket_pexpect.SocketSpawn(socket)
        assert s.isalive()
>       s.close()

tests/test_socket_pexpect.py:59: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <pexpect.socket_pexpect.SocketSpawn object at 0x1038ef9a0>

    def close(self):
        """Close the socket.
    
        Calling this method a second time does nothing, but if the file
        descriptor was closed elsewhere, :class:`OSError` will be raised.
        """
        if self.child_fd == -1:
            return
    
        self.flush()
>       self.socket.shutdown(socket.SHUT_RDWR)
E       OSError: [Errno 57] Socket is not connected

pexpect/socket_pexpect.py:78: OSError
------------------------------------------------------------------- Captured stdout call --------------------------------------------------------------------

Don't have a solution to this one yet.

@nieder
Copy link
Member Author

nieder commented Jan 20, 2024

Might need to apply patch only to py >= 3.8

	if [ "%type_pkg[python]" -ne "27" ] || [ "%type_pkg[python]" -ne "34" ] || [ "%type_pkg[python]" -ne "35" ] || [ "%type_pkg[python]" -ne "36" ] || [ "%type_pkg[python]" -ne "37" ]; then
		patch -p1 < %{PatchFile2}
	fi

Also, two tests hang with current settings:
pexpect/pexpect#765

perl -pi -e 's|range\(100|range(39|g' tests/test_expect.py

@nieder
Copy link
Member Author

nieder commented Jan 20, 2024

My current .info and .patch for latest upstream 4.9.0
pexpect-py-tests.patch
pexpect-py.info.txt
pexpect-py.patch

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

No branches or pull requests

1 participant