Compare commits

..

2 Commits

Author SHA1 Message Date
Dmitri Bogomolov f738769d34
Add TestBase.take_screenshot(window=None) in bitmessageqt.tests:
it shows specified window (or the main window), execs the app
and saves screenshot in png file in the appdata with full test name
in the file name.

Used it in TestUISignaler.test_updateStatusBar and TestSupport.
2021-03-02 19:32:46 +02:00
Dmitri Bogomolov d7cc8b112e
Use xvfb only on Linux with xvfbwrapper 2021-03-02 19:32:41 +02:00
12 changed files with 84 additions and 206 deletions

3
.gitmodules vendored
View File

@ -1,3 +0,0 @@
[submodule "packages/flatpak/shared-modules"]
path = packages/flatpak/shared-modules
url = https://github.com/flathub/shared-modules.git

View File

@ -18,5 +18,5 @@ install:
- export PYTHONWARNINGS=all - export PYTHONWARNINGS=all
script: script:
- python checkdeps.py - python checkdeps.py
- xvfb-run src/bitmessagemain.py -t - python src/bitmessagemain.py -t
- python -bm tests - python -bm tests

View File

@ -1,57 +0,0 @@
{
"id": "org.bitmessage.BaseApp",
"branch": "19.08",
"runtime": "org.freedesktop.Platform",
"sdk": "org.freedesktop.Sdk",
"runtime-version": "19.08",
"separate-locales": false,
"modules": [
"shared-modules/python2.7/python-2.7.json",
"shared-modules/qt4/qt4-4.8.7-minimal.json",
{
"name": "python-sip",
"sources": [
{
"type": "archive",
"url": "https://www.riverbankcomputing.com/static/Downloads/sip/4.19.25/sip-4.19.25.tar.gz",
"sha256": "b39d93e937647807bac23579edbff25fe46d16213f708370072574ab1f1b4211"
}
],
"buildsystem": "simple",
"build-commands": [
"python configure.py --sip-module PyQt4.sip --no-dist-info",
"make",
"make install"
]
},
{
"name": "python-qt4",
"sources": [
{
"type": "archive",
"url": "http://sourceforge.net/projects/pyqt/files/PyQt4/PyQt-4.12.3/PyQt4_gpl_x11-4.12.3.tar.gz",
"sha256": "a00f5abef240a7b5852b7924fa5fdf5174569525dc076cd368a566619e56d472"
}
],
"buildsystem": "simple",
"build-commands": [
"python configure.py -w --confirm-license",
"make",
"make install"
]
},
{
"name" : "PyBitmessage-dependencies",
"buildsystem" : "simple",
"build-options": {
"build-args": [
"--share=network"
]
},
"build-commands": [
"pip --version",
"pip install setuptools msgpack"
]
}
]
}

View File

@ -1,48 +0,0 @@
{
"app-id": "org.bitmessage.PyBitmessage",
"runtime": "org.freedesktop.Platform",
"runtime-version": "19.08",
"branch": "stable",
"sdk": "org.freedesktop.Sdk",
"base": "org.bitmessage.BaseApp",
"command": "pybitmessage",
"base-version":"stable",
"finish-args" : [
"--share=network",
"--socket=x11",
"--share=ipc",
"--filesystem=xdg-config/PyBitmessage:create"
],
"modules": [
{
"name" : "PyBitmessage",
"buildsystem" : "simple",
"build-options": {
"build-args": [
"--share=network"
]
},
"build-commands": [
"python --version",
"pwd",
"ls",
"python checkdeps.py",
"python setup.py install --prefix=/app --exec-prefix=/app",
"sed -i 's~/usr/bin/~/app/bin/~' /app/bin/pybitmessage",
"cat /app/bin/pybitmessage",
"mv /app/share/applications/pybitmessage.desktop /app/share/applications/org.bitmessage.PyBitmessage.desktop",
"sed -i 's~Icon=pybitmessage~Icon=org.bitmessage.PyBitmessage~' /app/share/applications/org.bitmessage.PyBitmessage.desktop",
"mv /app/share/icons/hicolor/scalable/apps/pybitmessage.svg /app/share/icons/hicolor/scalable/apps/org.bitmessage.PyBitmessage.svg",
"mv /app/share/icons/hicolor/24x24/apps/pybitmessage.png /app/share/icons/hicolor/24x24/apps/org.bitmessage.PyBitmessage.png",
"which pybitmessage"
],
"sources" : [
{
"type" : "dir",
"path" : "../../"
}
]
}
]
}

@ -1 +0,0 @@
Subproject commit fd4d38328ccb078b88ad4a891807e593ae8de806

View File

@ -2,3 +2,4 @@ coverage
python_prctl python_prctl
psutil psutil
pycrypto pycrypto
xvfbwrapper;platform_system=="Linux"

View File

@ -2,6 +2,7 @@
import Queue import Queue
import sys import sys
import os
import unittest import unittest
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
@ -23,6 +24,22 @@ class TestBase(unittest.TestCase):
self.window = bitmessageqt.MyForm() self.window = bitmessageqt.MyForm()
self.window.appIndicatorInit(self.app) self.window.appIndicatorInit(self.app)
def take_screenshot(self, window=None):
"""Take a screenshot of the *window* or main window if not set"""
def save_screenshot():
"""Save screenshot and quit app clause"""
screenshot = QtGui.QPixmap.grabWindow(
self.app.desktop().winId())
screenshot.save(os.path.join(
bitmessageqt.state.appdata, '%s.png' % self.id()))
self.app.quit()
timer = QtCore.QTimer()
timer.timeout.connect(save_screenshot)
timer.start(200)
(window or self.window).show()
self.app.exec_()
def tearDown(self): def tearDown(self):
# self.app.deleteLater() # self.app.deleteLater()
while True: while True:
@ -55,6 +72,4 @@ class TestUISignaler(TestBase):
_translate("test", "Testing updateStatusBar..."), 1) _translate("test", "Testing updateStatusBar..."), 1)
)) ))
QtCore.QTimer.singleShot(60, self.app.quit) self.take_screenshot()
self.app.exec_()
# self.app.processEvents(QtCore.QEventLoop.AllEvents, 60)

View File

@ -31,3 +31,5 @@ class TestSupport(TestBase):
ui.lineEditSubject.text(), self.SUPPORT_SUBJECT) ui.lineEditSubject.text(), self.SUPPORT_SUBJECT)
self.assertIn( self.assertIn(
sys.version, ui.textEditMessage.toPlainText()) sys.version, ui.textEditMessage.toPlainText())
self.take_screenshot()

View File

@ -2,22 +2,13 @@
BMConfigParser class definition and default configuration settings BMConfigParser class definition and default configuration settings
""" """
import sys import ConfigParser
if sys.version_info[0] == 3:
# python 3
import configparser as ConfigParser
SafeConfigParser = ConfigParser.ConfigParser
else:
# python 2
import ConfigParser
SafeConfigParser = ConfigParser.SafeConfigParser
import state
from singleton import Singleton
import os import os
import shutil import shutil
from datetime import datetime from datetime import datetime
import state
from singleton import Singleton
BMConfigDefaults = { BMConfigDefaults = {
"bitmessagesettings": { "bitmessagesettings": {
@ -52,8 +43,7 @@ BMConfigDefaults = {
@Singleton @Singleton
class BMConfigParser(SafeConfigParser): class BMConfigParser(ConfigParser.SafeConfigParser):
""" """
Singleton class inherited from :class:`ConfigParser.SafeConfigParser` Singleton class inherited from :class:`ConfigParser.SafeConfigParser`
with additional methods specific to bitmessage config. with additional methods specific to bitmessage config.
@ -70,47 +60,26 @@ class BMConfigParser(SafeConfigParser):
raise ValueError("Invalid value %s" % value) raise ValueError("Invalid value %s" % value)
return ConfigParser.ConfigParser.set(self, section, option, value) return ConfigParser.ConfigParser.set(self, section, option, value)
def get(self, section, option, raw=False, vars=None): def get(self, section, option, raw=False, variables=None):
if sys.version_info[0] == 3: # pylint: disable=arguments-differ
# pylint: disable=arguments-differ try:
try: if section == "bitmessagesettings" and option == "timeformat":
if section == "bitmessagesettings" and option == "timeformat":
return ConfigParser.ConfigParser.get(
self, section, option)
try:
return self._temp[section][option]
except KeyError:
pass
return ConfigParser.ConfigParser.get( return ConfigParser.ConfigParser.get(
self, section, option) self, section, option, raw, variables)
except ConfigParser.InterpolationError:
return ConfigParser.ConfigParser.get(
self, section, option)
except (ConfigParser.NoSectionError, ConfigParser.NoOptionError) as e:
try:
return BMConfigDefaults[section][option]
except (KeyError, ValueError, AttributeError):
raise e
else:
# pylint: disable=arguments-differ
try: try:
if section == "bitmessagesettings" and option == "timeformat": return self._temp[section][option]
return ConfigParser.ConfigParser.get( except KeyError:
self, section, option, raw, vars) pass
try: return ConfigParser.ConfigParser.get(
return self._temp[section][option] self, section, option, True, variables)
except KeyError: except ConfigParser.InterpolationError:
pass return ConfigParser.ConfigParser.get(
return ConfigParser.ConfigParser.get( self, section, option, True, variables)
self, section, option, True, vars) except (ConfigParser.NoSectionError, ConfigParser.NoOptionError) as e:
except ConfigParser.InterpolationError: try:
return ConfigParser.ConfigParser.get( return BMConfigDefaults[section][option]
self, section, option, True, vars) except (KeyError, ValueError, AttributeError):
except (ConfigParser.NoSectionError, ConfigParser.NoOptionError) as e: raise e
try:
return BMConfigDefaults[section][option]
except (KeyError, ValueError, AttributeError):
raise e
def setTemp(self, section, option, value=None): def setTemp(self, section, option, value=None):
"""Temporary set option to value, not saving.""" """Temporary set option to value, not saving."""
@ -222,4 +191,3 @@ class BMConfigParser(SafeConfigParser):
if value < 0 or value > 8: if value < 0 or value > 8:
return False return False
return True return True

View File

@ -3,6 +3,7 @@ Tests for core and those that do not work outside
(because of import error for example) (because of import error for example)
""" """
import atexit
import os import os
import pickle # nosec import pickle # nosec
import Queue import Queue
@ -398,8 +399,9 @@ def run():
suite = loader.loadTestsFromTestCase(TestCore) suite = loader.loadTestsFromTestCase(TestCore)
try: try:
import bitmessageqt.tests import bitmessageqt.tests
from xvfbwrapper import Xvfb
except ImportError: except ImportError:
pass Xvfb = None
else: else:
qt_tests = loader.loadTestsFromModule(bitmessageqt.tests) qt_tests = loader.loadTestsFromModule(bitmessageqt.tests)
suite.addTests(qt_tests) suite.addTests(qt_tests)
@ -410,4 +412,8 @@ def run():
sys.excepthook = keep_exc sys.excepthook = keep_exc
if Xvfb:
vdisplay = Xvfb(width=1024, height=768)
vdisplay.start()
atexit.register(vdisplay.stop)
return unittest.TextTestRunner(verbosity=2).run(suite) return unittest.TextTestRunner(verbosity=2).run(suite)

View File

@ -2,7 +2,11 @@
Various tests for config Various tests for config
""" """
import os
import unittest import unittest
import tempfile
from .test_process import TestProcessProto
from pybitmessage.bmconfigparser import BMConfigParser from pybitmessage.bmconfigparser import BMConfigParser
@ -34,3 +38,32 @@ class TestConfig(unittest.TestCase):
BMConfigParser().safeGetInt('nonexistent', 'nonexistent'), 0) BMConfigParser().safeGetInt('nonexistent', 'nonexistent'), 0)
self.assertEqual( self.assertEqual(
BMConfigParser().safeGetInt('nonexistent', 'nonexistent', 42), 42) BMConfigParser().safeGetInt('nonexistent', 'nonexistent', 42), 42)
class TestProcessConfig(TestProcessProto):
"""A test case for keys.dat"""
home = tempfile.mkdtemp()
def test_config_defaults(self):
"""Test settings in the generated config"""
self._stop_process()
self._kill_process()
config = BMConfigParser()
config.read(os.path.join(self.home, 'keys.dat'))
self.assertEqual(config.safeGetInt(
'bitmessagesettings', 'settingsversion'), 10)
self.assertEqual(config.safeGetInt(
'bitmessagesettings', 'port'), 8444)
# don't connect
self.assertTrue(config.safeGetBoolean(
'bitmessagesettings', 'dontconnect'))
# API disabled
self.assertFalse(config.safeGetBoolean(
'bitmessagesettings', 'apienabled'))
# extralowdifficulty is false
self.assertEqual(config.safeGetInt(
'bitmessagesettings', 'defaultnoncetrialsperbyte'), 1000)
self.assertEqual(config.safeGetInt(
'bitmessagesettings', 'defaultpayloadlengthextrabytes'), 1000)

View File

@ -1,38 +0,0 @@
"""
Various tests for config
"""
import os
import tempfile
from pybitmessage.bmconfigparser import BMConfigParser
from .test_process import TestProcessProto
class TestProcessConfig(TestProcessProto):
"""A test case for keys.dat"""
home = tempfile.mkdtemp()
def test_config_defaults(self):
"""Test settings in the generated config"""
config = BMConfigParser()
self._stop_process()
self._kill_process()
config.read(os.path.join(self.home, 'keys.dat'))
self.assertEqual(config.safeGetInt(
'bitmessagesettings', 'settingsversion'), 10)
self.assertEqual(config.safeGetInt(
'bitmessagesettings', 'port'), 8444)
# don't connect
self.assertTrue(config.safeGetBoolean(
'bitmessagesettings', 'dontconnect'))
# API disabled
self.assertFalse(config.safeGetBoolean(
'bitmessagesettings', 'apienabled'))
# extralowdifficulty is false
self.assertEqual(config.safeGetInt(
'bitmessagesettings', 'defaultnoncetrialsperbyte'), 1000)
self.assertEqual(config.safeGetInt(
'bitmessagesettings', 'defaultpayloadlengthextrabytes'), 1000)