Repository: snudler6/time-travel

Issue:
add patch for select.epoll
patch poll, epoll, ...

Comments:

Patch:
diff --git a/.appveyor.yml b/.appveyor.yml
index bf9a1ab..92262e2 100644
--- a/.appveyor.yml
+++ b/.appveyor.yml
@@ -3,7 +3,6 @@ environment:
     # For Python versions available on Appveyor, see
     # http://www.appveyor.com/docs/installed-software#python
     - TOXENV: "py27"
-    - TOXENV: "py34"
     - TOXENV: "py35"
     - TOXENV: "py36"
     - TOXENV: "pypy"
@@ -13,6 +12,7 @@ install:
   - if "%TOXENV%"=="pypy" choco install python.pypy
   - if "%TOXENV%"=="pypy" set PATH=C:\tools\pypy\pypy;%PATH% # so tox can find pypy
 
+  - pip install --upgrade virtualenv
   - pip install tox
 
 build: off
diff --git a/.travis.yml b/.travis.yml
index e0d6151..997eb4e 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -6,8 +6,6 @@ matrix:
   include:
   - python: 2.7
     env: TOXENV=py27
-  - python: 3.4
-    env: TOXENV=py34
   - python: 3.5
     env: TOXENV=py35
   - python: 3.6
diff --git a/setup.py b/setup.py
index 505b7c2..4e035d1 100644
--- a/setup.py
+++ b/setup.py
@@ -14,6 +14,8 @@ patchers = [
 
 if hasattr(select, 'poll'):
     patchers.append('poll_patcher = time_travel.patchers.poll_patcher:PollPatcher')
+if hasattr(select, 'epoll'):
+    patchers.append('epoll_patcher = time_travel.patchers.epoll_patcher:EpollPatcher')
 
 
 setup(
diff --git a/src/time_travel/patchers/epoll_patcher.py b/src/time_travel/patchers/epoll_patcher.py
new file mode 100644
index 0000000..5bf2e54
--- /dev/null
+++ b/src/time_travel/patchers/epoll_patcher.py
@@ -0,0 +1,13 @@
+"""A patch to the select.epoll object."""
+
+from .poll_patcher import PollPatcher
+
+import select as select_lib
+
+
+class EpollPatcher(PollPatcher):
+    """Patcher for select.epoll."""
+
+    def get_patch_actions(self):
+        """Return generator containing all patches to do."""
+        return [('epoll', select_lib.epoll, self._mock_poll)]
diff --git a/tox.ini b/tox.ini
index be16386..ab1cddf 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,13 +1,13 @@
 [tox]
-envlist = py27, py34, py35, py36, pypy, docs
+envlist = py27, py35, py36, pypy, docs
 
 [testenv]
-setenv = 
+setenv =
 	PYTHONPATH={toxinidir}/src/
 deps =
     -rrequirements/runtime.txt
     -rrequirements/tests.txt
-commands = 
+commands =
 	pycodestyle src/
 	pydocstyle -v src/
 	py.test --cache-clear -vv src/


Test patch:
diff --git a/src/tests/test_poll.py b/src/tests/test_poll.py
index 906c4e8..42b89c0 100644
--- a/src/tests/test_poll.py
+++ b/src/tests/test_poll.py
@@ -1,4 +1,5 @@
 from time_travel.patchers.poll_patcher import PollPatcher
+from time_travel.patchers.epoll_patcher import EpollPatcher
 from time_travel.time_machine_clock import TimeMachineClock
 from time_travel.event_pool import EventPool
 from .utils import _t
@@ -21,12 +22,18 @@ class TestPollPatcher(object):
         """Start a poll patcher"""
         self.event_pool = EventPool()
         self.clock = TimeMachineClock(clock_listeners=[self.event_pool])
-        self.patcher = PollPatcher(self.clock,
-                                   self.event_pool,
-                                   modules_to_patch=__name__)
+        self.patcher = self.get_patcher(self.clock,
+                                        self.event_pool,
+                                        modules_to_patch=__name__)
         self.patcher.start()
 
-        self.poll = select.poll()
+        self.poll = self.get_poll()
+
+    def get_poll(self):
+        return select.poll()
+
+    def get_patcher(self, *args, **kwargs):
+        return PollPatcher(*args, **kwargs)
 
     def teardown_method(self, method):
         """Stop the poll patcher"""
@@ -177,3 +184,13 @@ class TestPollPatcher(object):
 
         assert self.poll.poll() == [(sock, select.POLLOUT)]
         assert self.clock.time == _t(10)
+
+
+@pytest.mark.skipif(not hasattr(select, 'epoll'),
+                    reason='select.epoll is not supported in this platform')
+class TestEpollPatcher(TestPollPatcher):
+    def get_poll(self):
+        return select.epoll()
+
+    def get_patcher(self, *args, **kwargs):
+        return EpollPatcher(*args, **kwargs)
diff --git a/src/tests/test_time_travel.py b/src/tests/test_time_travel.py
index 8e5378c..8f51e84 100644
--- a/src/tests/test_time_travel.py
+++ b/src/tests/test_time_travel.py
@@ -125,3 +125,18 @@ def test_poll():
         now = t.clock.time
         assert poll.poll() == [(sock, select.POLLIN)]
         assert time.time() == now + 2
+
+
+@pytest.mark.skipif(not hasattr(select, 'epoll'),
+                    reason='select.epoll is not supported in this platform')
+def test_epoll():
+    with TimeTravel(modules_to_patch=__name__) as t:
+        sock = socket.socket()
+        t.add_future_event(2, sock, select.POLLIN)
+
+        poll = select.epoll()
+        poll.register(sock, select.POLLIN | select.POLLOUT)
+
+        now = t.clock.time
+        assert poll.poll() == [(sock, select.POLLIN)]
+        assert time.time() == now + 2