1
0
Эх сурвалжийг харах

Fixes #2398 - the build progress stream can contain empty json objects.

Previously these empty objects would hit a bug in splitting objects causing it crash.
With this fix the empty objects are returned properly.

Signed-off-by: Daniel Nephin <[email protected]>
Daniel Nephin 10 жил өмнө
parent
commit
c78c32c2e8

+ 6 - 6
compose/utils.py

@@ -102,7 +102,7 @@ def stream_as_text(stream):
 def line_splitter(buffer, separator=u'\n'):
     index = buffer.find(six.text_type(separator))
     if index == -1:
-        return None, None
+        return None
     return buffer[:index + 1], buffer[index + 1:]
 
 
@@ -120,11 +120,11 @@ def split_buffer(stream, splitter=None, decoder=lambda a: a):
     for data in stream_as_text(stream):
         buffered += data
         while True:
-            item, rest = splitter(buffered)
-            if not item:
+            buffer_split = splitter(buffered)
+            if buffer_split is None:
                 break
 
-            buffered = rest
+            item, buffered = buffer_split
             yield item
 
     if buffered:
@@ -140,7 +140,7 @@ def json_splitter(buffer):
         rest = buffer[json.decoder.WHITESPACE.match(buffer, index).end():]
         return obj, rest
     except ValueError:
-        return None, None
+        return None
 
 
 def json_stream(stream):
@@ -148,7 +148,7 @@ def json_stream(stream):
     This handles streams which are inconsistently buffered (some entries may
     be newline delimited, and others are not).
     """
-    return split_buffer(stream_as_text(stream), json_splitter, json_decoder.decode)
+    return split_buffer(stream, json_splitter, json_decoder.decode)
 
 
 def write_out_msg(stream, lines, msg_index, msg, status="done"):

+ 20 - 8
tests/unit/utils_test.py

@@ -1,25 +1,21 @@
 # encoding: utf-8
 from __future__ import unicode_literals
 
-from .. import unittest
 from compose import utils
 
 
-class JsonSplitterTestCase(unittest.TestCase):
+class TestJsonSplitter(object):
 
     def test_json_splitter_no_object(self):
         data = '{"foo": "bar'
-        self.assertEqual(utils.json_splitter(data), (None, None))
+        assert utils.json_splitter(data) is None
 
     def test_json_splitter_with_object(self):
         data = '{"foo": "bar"}\n  \n{"next": "obj"}'
-        self.assertEqual(
-            utils.json_splitter(data),
-            ({'foo': 'bar'}, '{"next": "obj"}')
-        )
+        assert utils.json_splitter(data) == ({'foo': 'bar'}, '{"next": "obj"}')
 
 
-class StreamAsTextTestCase(unittest.TestCase):
+class TestStreamAsText(object):
 
     def test_stream_with_non_utf_unicode_character(self):
         stream = [b'\xed\xf3\xf3']
@@ -30,3 +26,19 @@ class StreamAsTextTestCase(unittest.TestCase):
         stream = ['ěĝ'.encode('utf-8')]
         output, = utils.stream_as_text(stream)
         assert output == 'ěĝ'
+
+
+class TestJsonStream(object):
+
+    def test_with_falsy_entries(self):
+        stream = [
+            '{"one": "two"}\n{}\n',
+            "[1, 2, 3]\n[]\n",
+        ]
+        output = list(utils.json_stream(stream))
+        assert output == [
+            {'one': 'two'},
+            {},
+            [1, 2, 3],
+            [],
+        ]