Skip to content
This repository has been archived by the owner on Mar 13, 2022. It is now read-only.

Commit

Permalink
Handle error events in watch
Browse files Browse the repository at this point in the history
Raise an ApiException for error events that indicate a watch failure
despite the HTTP response indicating success.

Fixes #57

Signed-off-by: Fabian Reinartz <freinartz@google.com>
  • Loading branch information
Fabian Reinartz committed Nov 15, 2018
1 parent 879ab01 commit 1371f18
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 2 deletions.
9 changes: 8 additions & 1 deletion watch/watch.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,14 @@ def stream(self, func, *args, **kwargs):
resp = func(*args, **kwargs)
try:
for line in iter_resp_lines(resp):
yield self.unmarshal_event(line, return_type)
evt = self.unmarshal_event(line, return_type)
if evt['type'] == 'ERROR':
obj = evt['raw_object']
reason = "%s: %s" % (obj['reason'], obj['message'])
raise client.rest.ApiException(status=obj['code'],
reason=reason)
yield evt

if self._stop:
break
finally:
Expand Down
29 changes: 28 additions & 1 deletion watch/watch_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@
import unittest

from mock import Mock
from kubernetes import client

from .watch import Watch


class WatchTests(unittest.TestCase):

def test_watch_with_decode(self):
Expand Down Expand Up @@ -173,6 +173,33 @@ def test_watch_with_exception(self):
fake_resp.close.assert_called_once()
fake_resp.release_conn.assert_called_once()

def test_watch_with_error_event(self):
print("start")
fake_resp = Mock()
fake_resp.close = Mock()
fake_resp.release_conn = Mock()
fake_resp.read_chunked = Mock(
return_value=[
'{"type": "ERROR", "object": {"code": 410, '
'"reason": "Gone", "message": "error message"}}\n'])

fake_api = Mock()
fake_api.get_thing = Mock(return_value=fake_resp)

w = Watch()
try:
for _ in w.stream(fake_api.get_thing):
self.fail(self, "Should fail with ApiException.")
except client.rest.ApiException:
pass

fake_api.get_thing.assert_called_once_with(
_preload_content=False, watch=True)
fake_resp.read_chunked.assert_called_once_with(decode_content=False)
fake_resp.close.assert_called_once()
fake_resp.release_conn.assert_called_once()



if __name__ == '__main__':
unittest.main()

0 comments on commit 1371f18

Please sign in to comment.