[Console] Fix using windows-curses on Windows

The console tests are still failing on Windows due to an issue where the
sys args are not being correctly replaced in the tests so the pytest
args are being passed to console.
This commit is contained in:
Calum Lind 2021-07-24 14:11:58 +01:00
parent e38f1173cf
commit b89b2c45b1
8 changed files with 54 additions and 52 deletions

View File

@ -69,7 +69,7 @@ def add_watchdog(deferred, timeout=0.05, message=None):
return value
deferred.addBoth(callback)
watchdog = reactor.callLater(timeout, defer.timeout, deferred)
watchdog = reactor.callLater(timeout, defer.Deferred.addTimeout, deferred)
return watchdog

View File

@ -11,7 +11,7 @@ from twisted.internet import defer
import deluge.component as component
from deluge import error
from deluge.common import AUTH_LEVEL_NORMAL, get_localhost_auth, windows_check
from deluge.common import AUTH_LEVEL_NORMAL, get_localhost_auth
from deluge.core.authmanager import AUTH_LEVEL_ADMIN
from deluge.ui.client import Client, DaemonSSLProxy, client
@ -79,10 +79,6 @@ class NoVersionSendingClient(Client):
class ClientTestCase(BaseTestCase, DaemonBase):
if windows_check():
skip = 'windows cant start_core not enough arguments for format string'
def set_up(self):
d = self.common_set_up()
d.addCallback(self.start_core)

View File

@ -8,6 +8,7 @@
from __future__ import unicode_literals
import os
import sys
import tarfile
from twisted.trial import unittest
@ -98,8 +99,9 @@ class CommonTestCase(unittest.TestCase):
self.assertTrue(is_infohash('2dc5d0e71a66fe69649a640d39cb00a259704973'))
def test_get_path_size(self):
if windows_check():
raise unittest.SkipTest('os devnull is different on windows')
if windows_check() and sys.version_info < (3, 8):
# https://bugs.python.org/issue1311
raise unittest.SkipTest('os.devnull returns False on Windows')
self.assertTrue(get_path_size(os.devnull) == 0)
self.assertTrue(get_path_size('non-existant.file') == -1)

View File

@ -9,7 +9,6 @@ from __future__ import unicode_literals
import argparse
from deluge.common import windows_check
from deluge.ui.console.cmdline.commands.add import Command
from deluge.ui.console.cmdline.commands.config import json_eval
from deluge.ui.console.widgets.fields import TextInput
@ -46,8 +45,7 @@ class UIConsoleFieldTestCase(BaseTestCase):
complete=False,
)
self.assertTrue(t)
if not windows_check():
self.assertTrue(t.handle_read(33))
self.assertTrue(t.handle_read(33))
class UIConsoleCommandsTestCase(BaseTestCase):

View File

@ -19,6 +19,9 @@ from twisted.internet import defer
import deluge
import deluge.component as component
import deluge.ui.console
import deluge.ui.console.cmdline.commands.quit
import deluge.ui.console.main
import deluge.ui.web.server
from deluge.common import PY2, get_localhost_auth, windows_check
from deluge.ui import ui_entry
@ -28,11 +31,6 @@ from . import common
from .basetest import BaseTestCase
from .daemon_base import DaemonBase
if not windows_check():
import deluge.ui.console
import deluge.ui.console.cmdline.commands.quit
import deluge.ui.console.main
DEBUG_COMMAND = False
sys_stdout = sys.stdout
@ -102,7 +100,7 @@ class UIWithDaemonBaseTestCase(UIBaseTestCase, DaemonBase):
class DelugeEntryTestCase(BaseTestCase):
if windows_check():
skip = 'cannot test console ui on windows'
skip = 'Console ui test on Windows broken due to sys args issue'
def set_up(self):
common.set_tmp_config_dir()
@ -250,7 +248,7 @@ class WebUIBaseTestCase(UIBaseTestCase):
class WebUIScriptEntryTestCase(BaseTestCase, WebUIBaseTestCase):
if windows_check():
skip = 'cannot test console ui on windows'
skip = 'Console ui test on Windows broken due to sys args issue'
def __init__(self, testname):
super(WebUIScriptEntryTestCase, self).__init__(testname)
@ -269,7 +267,7 @@ class WebUIScriptEntryTestCase(BaseTestCase, WebUIBaseTestCase):
class WebUIDelugeScriptEntryTestCase(BaseTestCase, WebUIBaseTestCase):
if windows_check():
skip = 'cannot test console ui on windows'
skip = 'Console ui test on Windows broken due to sys args issue'
def __init__(self, testname):
super(WebUIDelugeScriptEntryTestCase, self).__init__(testname)
@ -466,7 +464,7 @@ class ConsoleScriptEntryWithDaemonTestCase(
):
if windows_check():
skip = 'cannot test console ui on windows'
skip = 'Console ui test on Windows broken due to sys args issue'
def __init__(self, testname):
super(ConsoleScriptEntryWithDaemonTestCase, self).__init__(testname)
@ -492,7 +490,7 @@ class ConsoleScriptEntryWithDaemonTestCase(
class ConsoleScriptEntryTestCase(BaseTestCase, ConsoleUIBaseTestCase):
if windows_check():
skip = 'cannot test console ui on windows'
skip = 'Console ui test on Windows broken due to sys args issue'
def __init__(self, testname):
super(ConsoleScriptEntryTestCase, self).__init__(testname)

View File

@ -67,6 +67,14 @@ DEFAULT_CONSOLE_PREFS = {
}
class MockConsoleLog(object):
def write(self, data):
pass
def flush(self):
pass
class ConsoleUI(component.Component, TermResizeHandler):
def __init__(self, options, cmds, log_stream):
component.Component.__init__(self, 'ConsoleUI')
@ -114,6 +122,7 @@ class ConsoleUI(component.Component, TermResizeHandler):
all commands are executed. Else None is returned.
"""
if self.options.parsed_cmds:
# Non-Interactive mode
self.interactive = False
if not self._commands:
print('No valid console commands found')
@ -122,41 +131,37 @@ class ConsoleUI(component.Component, TermResizeHandler):
deferred = self.exec_args(self.options)
reactor.run()
return deferred
else:
# Interactive
if deluge.common.windows_check():
print(
"""\nDeluge-console does not run in interactive mode on Windows. \n
# Interactive
# We use the curses.wrapper function to prevent the console from getting
# messed up if an uncaught exception is experienced.
try:
from curses import wrapper
except ImportError:
wrapper = None
if deluge.common.windows_check() and not wrapper:
print(
"""\nDeluge-console does not run in interactive mode on Windows. \n
Please use commands from the command line, e.g.:\n
deluge-console.exe help
deluge-console.exe info
deluge-console.exe "add --help"
deluge-console.exe "add -p c:\\mytorrents c:\\new.torrent"
deluge-console.exe help
deluge-console.exe info
deluge-console.exe "add --help"
deluge-console.exe "add -p c:\\mytorrents c:\\new.torrent"
"""
)
else:
)
class ConsoleLog(object):
def write(self, data):
pass
# We don't ever want log output to terminal when running in
# interactive mode, so insert a dummy here
self.log_stream.out = MockConsoleLog()
def flush(self):
pass
# Set Esc key delay to 0 to avoid a very annoying delay
# due to curses waiting in case of other key are pressed
# after ESC is pressed
os.environ.setdefault('ESCDELAY', '0')
# We don't ever want log output to terminal when running in
# interactive mode, so insert a dummy here
self.log_stream.out = ConsoleLog()
# Set Esc key delay to 0 to avoid a very annoying delay
# due to curses waiting in case of other key are pressed
# after ESC is pressed
os.environ.setdefault('ESCDELAY', '0')
# We use the curses.wrapper function to prevent the console from getting
# messed up if an uncaught exception is experienced.
from curses import wrapper
wrapper(self.run)
wrapper(self.run)
def quit(self):
if client.connected():

View File

@ -67,7 +67,9 @@ class TermResizeHandler(object):
try:
signal.signal(signal.SIGWINCH, self.on_terminal_size)
except ValueError as ex:
log.debug('Unable to catch SIGWINCH signal: %s', ex)
log.debug('TermResize unavailable, unable to catch SIGWINCH signal: %s', ex)
except AttributeError as ex:
log.debug('TermResize unavailable, no SIGWINCH signal on Windows: %s', ex)
def on_terminal_size(self, *args):
# Get the new rows and cols value

View File

@ -9,5 +9,6 @@ six
setproctitle
pywin32; sys_platform == 'win32'
certifi; sys_platform == 'win32'
windows-curses; sys_platform == 'win32'
zope.interface>=4.4.2
distro; 'linux' in sys_platform or 'bsd' in sys_platform