[tests] Purge tests and start with a clean implementation of subprocess
Seems like subprocess and friends (Popen, communicate) are not so easy to mock cleanly. Therefore, start from scratch and carefully write test by test, until (at least) the old test coverage has been restored.
This commit is contained in:
parent
1c6122fc3f
commit
6dbe440cb5
23 changed files with 61 additions and 1240 deletions
|
@ -1,68 +0,0 @@
|
|||
# pylint: disable=C0103,C0111
|
||||
|
||||
import sys
|
||||
import json
|
||||
import unittest
|
||||
import mock
|
||||
|
||||
from contextlib import contextmanager
|
||||
|
||||
import bumblebee.input
|
||||
from bumblebee.input import I3BarInput
|
||||
from bumblebee.modules.battery import Module
|
||||
from tests.util import MockEngine, MockConfig, assertPopen
|
||||
|
||||
class MockOpen(object):
|
||||
def __init__(self):
|
||||
self._value = ""
|
||||
|
||||
def returns(self, value):
|
||||
self._value = value
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
||||
def __exit__(self, a, b, c):
|
||||
pass
|
||||
|
||||
def read(self):
|
||||
return self._value
|
||||
|
||||
class TestBatteryModule(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.engine = MockEngine()
|
||||
self.config = MockConfig()
|
||||
self.module = Module(engine=self.engine, config={ "config": self.config })
|
||||
for widget in self.module.widgets():
|
||||
widget.link_module(self.module)
|
||||
|
||||
@mock.patch("sys.stdout")
|
||||
def test_format(self, mock_output):
|
||||
for widget in self.module.widgets():
|
||||
self.assertEquals(len(widget.full_text()), len("100%"))
|
||||
|
||||
@mock.patch("os.path.exists")
|
||||
@mock.patch("{}.open".format("__builtin__" if sys.version_info[0] < 3 else "builtins"))
|
||||
@mock.patch("subprocess.Popen")
|
||||
def test_critical(self, mock_output, mock_open, mock_exists):
|
||||
mock_open.return_value = MockOpen()
|
||||
mock_open.return_value.returns("19")
|
||||
mock_exists.return_value = True
|
||||
self.config.set("battery.critical", "20")
|
||||
self.config.set("battery.warning", "25")
|
||||
self.module.update(self.module.widgets())
|
||||
self.assertTrue("critical" in self.module.widgets()[0].state())
|
||||
|
||||
@mock.patch("os.path.exists")
|
||||
@mock.patch("{}.open".format("__builtin__" if sys.version_info[0] < 3 else "builtins"))
|
||||
@mock.patch("subprocess.Popen")
|
||||
def test_warning(self, mock_output, mock_open, mock_exists):
|
||||
mock_open.return_value = MockOpen()
|
||||
mock_exists.return_value = True
|
||||
mock_open.return_value.returns("22")
|
||||
self.config.set("battery.critical", "20")
|
||||
self.config.set("battery.warning", "25")
|
||||
self.module.update(self.module.widgets())
|
||||
self.assertTrue("warning" in self.module.widgets()[0].state())
|
||||
|
||||
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
|
|
@ -1,56 +0,0 @@
|
|||
# pylint: disable=C0103,C0111
|
||||
|
||||
import json
|
||||
import unittest
|
||||
import mock
|
||||
|
||||
import bumblebee.input
|
||||
from bumblebee.input import I3BarInput
|
||||
from bumblebee.modules.brightness import Module
|
||||
from tests.util import MockEngine, MockConfig, assertPopen, assertMouseEvent
|
||||
|
||||
class TestBrightnessModule(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.engine = MockEngine()
|
||||
self.engine.input = I3BarInput()
|
||||
self.engine.input.need_event = True
|
||||
self.config = MockConfig()
|
||||
self.module = Module(engine=self.engine, config={ "config": self.config })
|
||||
for widget in self.module.widgets():
|
||||
widget.link_module(self.module)
|
||||
|
||||
@mock.patch("sys.stdout")
|
||||
def test_format(self, mock_output):
|
||||
for widget in self.module.widgets():
|
||||
self.assertEquals(len(widget.full_text()), len("100%"))
|
||||
|
||||
@mock.patch("select.epoll")
|
||||
@mock.patch("subprocess.Popen")
|
||||
@mock.patch("sys.stdin")
|
||||
def test_wheel_up(self, mock_input, mock_output, mock_select):
|
||||
assertMouseEvent(mock_input, mock_output, mock_select, self.engine,
|
||||
self.module, bumblebee.input.WHEEL_UP,
|
||||
"xbacklight +2%"
|
||||
)
|
||||
|
||||
@mock.patch("select.epoll")
|
||||
@mock.patch("subprocess.Popen")
|
||||
@mock.patch("sys.stdin")
|
||||
def test_wheel_down(self, mock_input, mock_output, mock_select):
|
||||
assertMouseEvent(mock_input, mock_output, mock_select, self.engine,
|
||||
self.module, bumblebee.input.WHEEL_DOWN,
|
||||
"xbacklight -2%"
|
||||
)
|
||||
|
||||
@mock.patch("select.epoll")
|
||||
@mock.patch("subprocess.Popen")
|
||||
@mock.patch("sys.stdin")
|
||||
def test_custom_step(self, mock_input, mock_output, mock_select):
|
||||
self.config.set("brightness.step", "10")
|
||||
module = Module(engine=self.engine, config={ "config": self.config })
|
||||
assertMouseEvent(mock_input, mock_output, mock_select, self.engine,
|
||||
module, bumblebee.input.WHEEL_DOWN,
|
||||
"xbacklight -10%"
|
||||
)
|
||||
|
||||
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
|
|
@ -1,21 +0,0 @@
|
|||
# pylint: disable=C0103,C0111
|
||||
|
||||
import json
|
||||
import unittest
|
||||
import mock
|
||||
|
||||
import bumblebee.input
|
||||
from bumblebee.input import I3BarInput
|
||||
from bumblebee.modules.caffeine import Module
|
||||
from tests.util import MockEngine, MockConfig, assertPopen
|
||||
|
||||
class TestCaffeineModule(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.engine = MockEngine()
|
||||
self.engine.input = I3BarInput()
|
||||
self.engine.input.need_event = True
|
||||
self.engine.input.need_valid_event = True
|
||||
self.config = MockConfig()
|
||||
self.module = Module(engine=self.engine, config={ "config": self.config })
|
||||
for widget in self.module.widgets():
|
||||
widget.link_module(self.module)
|
|
@ -1,58 +0,0 @@
|
|||
# pylint: disable=C0103,C0111
|
||||
|
||||
import json
|
||||
import unittest
|
||||
import mock
|
||||
|
||||
import bumblebee.input
|
||||
from bumblebee.input import I3BarInput
|
||||
from bumblebee.modules.cmus import Module
|
||||
from tests.util import MockEngine, MockConfig, assertPopen, MockEpoll
|
||||
|
||||
class TestCmusModule(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.engine = MockEngine()
|
||||
self.engine.input = I3BarInput()
|
||||
self.engine.input.need_event = True
|
||||
self.module = Module(engine=self.engine, config={"config": MockConfig()})
|
||||
|
||||
@mock.patch("subprocess.Popen")
|
||||
def test_read_song(self, mock_output):
|
||||
rv = mock.Mock()
|
||||
rv.configure_mock(**{
|
||||
"communicate.return_value": ("out", None)
|
||||
})
|
||||
mock_output.return_value = rv
|
||||
self.module.update(self.module.widgets())
|
||||
assertPopen(mock_output, "cmus-remote -Q")
|
||||
|
||||
def test_widgets(self):
|
||||
self.assertTrue(len(self.module.widgets()), 5)
|
||||
|
||||
@mock.patch("select.epoll")
|
||||
@mock.patch("subprocess.Popen")
|
||||
@mock.patch("sys.stdin")
|
||||
def test_interaction(self, mock_input, mock_output, mock_select):
|
||||
events = [
|
||||
{"widget": "cmus.shuffle", "action": "cmus-remote -S"},
|
||||
{"widget": "cmus.repeat", "action": "cmus-remote -R"},
|
||||
{"widget": "cmus.next", "action": "cmus-remote -n"},
|
||||
{"widget": "cmus.prev", "action": "cmus-remote -r"},
|
||||
{"widget": "cmus.main", "action": "cmus-remote -u"},
|
||||
]
|
||||
|
||||
mock_input.fileno.return_value = 1
|
||||
mock_select.return_value = MockEpoll()
|
||||
|
||||
for event in events:
|
||||
mock_input.readline.return_value = json.dumps({
|
||||
"name": self.module.id,
|
||||
"button": bumblebee.input.LEFT_MOUSE,
|
||||
"instance": self.module.widget(event["widget"]).id
|
||||
})
|
||||
self.engine.input.start()
|
||||
self.engine.input.stop()
|
||||
mock_input.readline.assert_any_call()
|
||||
assertPopen(mock_output, event["action"])
|
||||
|
||||
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
|
|
@ -1,48 +0,0 @@
|
|||
# pylint: disable=C0103,C0111
|
||||
|
||||
import json
|
||||
import unittest
|
||||
import mock
|
||||
|
||||
import bumblebee.input
|
||||
from bumblebee.input import I3BarInput
|
||||
from bumblebee.modules.cpu import Module
|
||||
from tests.util import MockEngine, MockConfig, assertPopen, assertMouseEvent, assertStateContains
|
||||
|
||||
class TestCPUModule(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.engine = MockEngine()
|
||||
self.engine.input = I3BarInput()
|
||||
self.engine.input.need_event = True
|
||||
self.config = MockConfig()
|
||||
self.module = Module(engine=self.engine, config={ "config": self.config })
|
||||
|
||||
@mock.patch("sys.stdout")
|
||||
def test_format(self, mock_output):
|
||||
for widget in self.module.widgets():
|
||||
self.assertEquals(len(widget.full_text()), len("100.00%"))
|
||||
|
||||
@mock.patch("select.epoll")
|
||||
@mock.patch("subprocess.Popen")
|
||||
@mock.patch("sys.stdin")
|
||||
def test_leftclick(self, mock_input, mock_output, mock_select):
|
||||
assertMouseEvent(mock_input, mock_output, mock_select, self.engine,
|
||||
self.module, bumblebee.input.LEFT_MOUSE,
|
||||
"gnome-system-monitor"
|
||||
)
|
||||
|
||||
@mock.patch("psutil.cpu_percent")
|
||||
def test_warning(self, mock_psutil):
|
||||
self.config.set("cpu.critical", "20")
|
||||
self.config.set("cpu.warning", "18")
|
||||
mock_psutil.return_value = 19.0
|
||||
assertStateContains(self, self.module, "warning")
|
||||
|
||||
@mock.patch("psutil.cpu_percent")
|
||||
def test_critical(self, mock_psutil):
|
||||
self.config.set("cpu.critical", "20")
|
||||
self.config.set("cpu.warning", "19")
|
||||
mock_psutil.return_value = 21.0
|
||||
assertStateContains(self, self.module, "critical")
|
||||
|
||||
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
|
|
@ -1,56 +0,0 @@
|
|||
# pylint: disable=C0103,C0111
|
||||
|
||||
import json
|
||||
import unittest
|
||||
import mock
|
||||
|
||||
import bumblebee.input
|
||||
from bumblebee.input import I3BarInput
|
||||
from bumblebee.modules.disk import Module
|
||||
from tests.util import MockEngine, MockConfig, assertPopen, assertStateContains, MockEpoll
|
||||
|
||||
class MockVFS(object):
|
||||
def __init__(self, perc):
|
||||
self.f_blocks = 1024*1024
|
||||
self.f_frsize = 1
|
||||
self.f_bavail = self.f_blocks - self.f_blocks*(perc/100.0)
|
||||
|
||||
class TestDiskModule(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.engine = MockEngine()
|
||||
self.engine.input = I3BarInput()
|
||||
self.engine.input.need_event = True
|
||||
self.config = MockConfig()
|
||||
self.config.set("disk.path", "somepath")
|
||||
self.module = Module(engine=self.engine, config={"config": self.config})
|
||||
|
||||
@mock.patch("select.epoll")
|
||||
@mock.patch("subprocess.Popen")
|
||||
@mock.patch("sys.stdin")
|
||||
def test_leftclick(self, mock_input, mock_output, mock_select):
|
||||
mock_input.readline.return_value = json.dumps({
|
||||
"name": self.module.id,
|
||||
"button": bumblebee.input.LEFT_MOUSE,
|
||||
"instance": None
|
||||
})
|
||||
mock_select.return_value = MockEpoll()
|
||||
self.engine.input.start()
|
||||
self.engine.input.stop()
|
||||
mock_input.readline.assert_any_call()
|
||||
assertPopen(mock_output, "nautilus {}".format(self.module.parameter("path")))
|
||||
|
||||
@mock.patch("os.statvfs")
|
||||
def test_warning(self, mock_stat):
|
||||
self.config.set("disk.critical", "80")
|
||||
self.config.set("disk.warning", "70")
|
||||
mock_stat.return_value = MockVFS(75.0)
|
||||
assertStateContains(self, self.module, "warning")
|
||||
|
||||
@mock.patch("os.statvfs")
|
||||
def test_critical(self, mock_stat):
|
||||
self.config.set("disk.critical", "80")
|
||||
self.config.set("disk.warning", "70")
|
||||
mock_stat.return_value = MockVFS(85.0)
|
||||
assertStateContains(self, self.module, "critical")
|
||||
|
||||
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
|
|
@ -1,47 +0,0 @@
|
|||
# pylint: disable=C0103,C0111
|
||||
|
||||
import json
|
||||
import unittest
|
||||
import mock
|
||||
|
||||
import bumblebee.input
|
||||
from bumblebee.input import I3BarInput
|
||||
from bumblebee.modules.load import Module
|
||||
from tests.util import MockEngine, MockConfig, assertStateContains, assertMouseEvent
|
||||
|
||||
class TestLoadModule(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.engine = MockEngine()
|
||||
self.engine.input = I3BarInput()
|
||||
self.engine.input.need_event = True
|
||||
self.config = MockConfig()
|
||||
self.module = Module(engine=self.engine, config={ "config": self.config })
|
||||
|
||||
@mock.patch("select.epoll")
|
||||
@mock.patch("subprocess.Popen")
|
||||
@mock.patch("sys.stdin")
|
||||
def test_leftclick(self, mock_input, mock_output, mock_select):
|
||||
assertMouseEvent(mock_input, mock_output, mock_select, self.engine,
|
||||
self.module, bumblebee.input.LEFT_MOUSE,
|
||||
"gnome-system-monitor"
|
||||
)
|
||||
|
||||
@mock.patch("multiprocessing.cpu_count")
|
||||
@mock.patch("os.getloadavg")
|
||||
def test_warning(self, mock_loadavg, mock_cpucount):
|
||||
self.config.set("load.critical", "1")
|
||||
self.config.set("load.warning", "0.8")
|
||||
mock_cpucount.return_value = 1
|
||||
mock_loadavg.return_value = [ 0.9, 0, 0 ]
|
||||
assertStateContains(self, self.module, "warning")
|
||||
|
||||
@mock.patch("multiprocessing.cpu_count")
|
||||
@mock.patch("os.getloadavg")
|
||||
def test_critical(self, mock_loadavg, mock_cpucount):
|
||||
self.config.set("load.critical", "1")
|
||||
self.config.set("load.warning", "0.8")
|
||||
mock_cpucount.return_value = 1
|
||||
mock_loadavg.return_value = [ 1.1, 0, 0 ]
|
||||
assertStateContains(self, self.module, "critical")
|
||||
|
||||
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
|
|
@ -1,47 +0,0 @@
|
|||
# pylint: disable=C0103,C0111
|
||||
|
||||
import json
|
||||
import unittest
|
||||
import mock
|
||||
|
||||
import bumblebee.input
|
||||
from bumblebee.input import I3BarInput
|
||||
from bumblebee.modules.memory import Module
|
||||
from tests.util import MockEngine, MockConfig, assertPopen, assertMouseEvent, assertStateContains
|
||||
|
||||
class VirtualMemory(object):
|
||||
def __init__(self, percent):
|
||||
self.percent = percent
|
||||
|
||||
class TestMemoryModule(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.engine = MockEngine()
|
||||
self.engine.input = I3BarInput()
|
||||
self.engine.input.need_event = True
|
||||
self.config = MockConfig()
|
||||
self.module = Module(engine=self.engine, config={ "config": self.config })
|
||||
|
||||
@mock.patch("select.epoll")
|
||||
@mock.patch("subprocess.Popen")
|
||||
@mock.patch("sys.stdin")
|
||||
def test_leftclick(self, mock_input, mock_output, mock_select):
|
||||
assertMouseEvent(mock_input, mock_output, mock_select, self.engine,
|
||||
self.module, bumblebee.input.LEFT_MOUSE,
|
||||
"gnome-system-monitor"
|
||||
)
|
||||
|
||||
@mock.patch("psutil.virtual_memory")
|
||||
def test_warning(self, mock_vmem):
|
||||
self.config.set("memory.critical", "80")
|
||||
self.config.set("memory.warning", "70")
|
||||
mock_vmem.return_value = VirtualMemory(75)
|
||||
assertStateContains(self, self.module, "warning")
|
||||
|
||||
@mock.patch("psutil.virtual_memory")
|
||||
def test_critical(self, mock_vmem):
|
||||
self.config.set("memory.critical", "80")
|
||||
self.config.set("memory.warning", "70")
|
||||
mock_vmem.return_value = VirtualMemory(85)
|
||||
assertStateContains(self, self.module, "critical")
|
||||
|
||||
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
|
|
@ -1,57 +0,0 @@
|
|||
# pylint: disable=C0103,C0111
|
||||
|
||||
import unittest
|
||||
import importlib
|
||||
import mock
|
||||
|
||||
from bumblebee.engine import all_modules
|
||||
from bumblebee.config import Config
|
||||
from tests.util import assertWidgetAttributes, MockEngine
|
||||
|
||||
class MockCommunicate(object):
|
||||
def __init__(self):
|
||||
self.returncode = 0
|
||||
|
||||
def communicate(self):
|
||||
return (str.encode("1"), "error")
|
||||
|
||||
class TestGenericModules(unittest.TestCase):
|
||||
@mock.patch("subprocess.Popen")
|
||||
def setUp(self, mock_output):
|
||||
mock_output.return_value = MockCommunicate()
|
||||
engine = MockEngine()
|
||||
config = Config()
|
||||
self.objects = {}
|
||||
for mod in all_modules():
|
||||
cls = importlib.import_module("bumblebee.modules.{}".format(mod["name"]))
|
||||
self.objects[mod["name"]] = getattr(cls, "Module")(engine, {"config": config})
|
||||
for widget in self.objects[mod["name"]].widgets():
|
||||
self.assertEquals(widget.get("variable", None), None)
|
||||
|
||||
@mock.patch("subprocess.Popen")
|
||||
def test_widgets(self, mock_output):
|
||||
mock_output.return_value = MockCommunicate()
|
||||
for mod in self.objects:
|
||||
widgets = self.objects[mod].widgets()
|
||||
for widget in widgets:
|
||||
widget.link_module(self.objects[mod])
|
||||
self.assertEquals(widget.module, mod)
|
||||
assertWidgetAttributes(self, widget)
|
||||
widget.set("variable", "value")
|
||||
self.assertEquals(widget.get("variable", None), "value")
|
||||
self.assertTrue(isinstance(widget.full_text(), str) or isinstance(widget.full_text(), unicode))
|
||||
|
||||
@mock.patch("subprocess.Popen")
|
||||
def test_update(self, mock_output):
|
||||
mock_output.return_value = MockCommunicate()
|
||||
rv = mock.Mock()
|
||||
rv.configure_mock(**{
|
||||
"communicate.return_value": ("out", None)
|
||||
})
|
||||
for mod in self.objects:
|
||||
widgets = self.objects[mod].widgets()
|
||||
self.objects[mod].update(widgets)
|
||||
self.test_widgets()
|
||||
self.assertEquals(widgets, self.objects[mod].widgets())
|
||||
|
||||
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
|
|
@ -1,56 +0,0 @@
|
|||
# pylint: disable=C0103,C0111
|
||||
|
||||
import json
|
||||
import unittest
|
||||
import mock
|
||||
|
||||
import bumblebee.input
|
||||
from bumblebee.input import I3BarInput
|
||||
from bumblebee.modules.pulseaudio import Module
|
||||
from tests.util import MockEngine, MockConfig, assertPopen, assertMouseEvent, assertStateContains
|
||||
|
||||
class TestPulseAudioModule(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.engine = MockEngine()
|
||||
self.engine.input = I3BarInput()
|
||||
self.engine.input.need_event = True
|
||||
self.config = MockConfig()
|
||||
self.module = Module(engine=self.engine, config={ "config": self.config })
|
||||
|
||||
@mock.patch("select.epoll")
|
||||
@mock.patch("subprocess.Popen")
|
||||
@mock.patch("sys.stdin")
|
||||
def test_leftclick(self, mock_input, mock_output, mock_select):
|
||||
assertMouseEvent(mock_input, mock_output, mock_select, self.engine,
|
||||
self.module, bumblebee.input.LEFT_MOUSE,
|
||||
"pactl set-source-mute @DEFAULT_SOURCE@ toggle"
|
||||
)
|
||||
|
||||
@mock.patch("select.epoll")
|
||||
@mock.patch("subprocess.Popen")
|
||||
@mock.patch("sys.stdin")
|
||||
def test_rightclick(self, mock_input, mock_output, mock_select):
|
||||
assertMouseEvent(mock_input, mock_output, mock_select, self.engine,
|
||||
self.module, bumblebee.input.RIGHT_MOUSE,
|
||||
"pavucontrol"
|
||||
)
|
||||
|
||||
@mock.patch("select.epoll")
|
||||
@mock.patch("subprocess.Popen")
|
||||
@mock.patch("sys.stdin")
|
||||
def test_wheelup(self, mock_input, mock_output, mock_select):
|
||||
assertMouseEvent(mock_input, mock_output, mock_select, self.engine,
|
||||
self.module, bumblebee.input.WHEEL_UP,
|
||||
"pactl set-source-volume @DEFAULT_SOURCE@ +2%"
|
||||
)
|
||||
|
||||
@mock.patch("select.epoll")
|
||||
@mock.patch("subprocess.Popen")
|
||||
@mock.patch("sys.stdin")
|
||||
def test_wheeldown(self, mock_input, mock_output, mock_select):
|
||||
assertMouseEvent(mock_input, mock_output, mock_select, self.engine,
|
||||
self.module, bumblebee.input.WHEEL_DOWN,
|
||||
"pactl set-source-volume @DEFAULT_SOURCE@ -2%"
|
||||
)
|
||||
|
||||
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
|
Loading…
Add table
Add a link
Reference in a new issue