tests/test-batching.py
changeset 33766 4c706037adef
parent 33765 e2fc2122029c
child 37614 a81d02ea65db
--- a/tests/test-batching.py	Wed Aug 09 22:52:05 2017 -0700
+++ b/tests/test-batching.py	Wed Aug 09 23:29:30 2017 -0700
@@ -8,7 +8,9 @@
 from __future__ import absolute_import, print_function
 
 from mercurial import (
+    error,
     peer,
+    util,
     wireproto,
 )
 
@@ -27,9 +29,9 @@
         return "%s und %s" % (b, a,)
     def greet(self, name=None):
         return "Hello, %s" % name
-    def batch(self):
+    def batchiter(self):
         '''Support for local batching.'''
-        return peer.localbatch(self)
+        return peer.localiterbatcher(self)
 
 # usage of "thing" interface
 def use(it):
@@ -41,27 +43,54 @@
     print(it.foo("Un", two="Deux"))
     print(it.bar("Eins", "Zwei"))
 
-    # Batched call to a couple of (possibly proxied) methods.
-    batch = it.batch()
+    # Batched call to a couple of proxied methods.
+    batch = it.batchiter()
     # The calls return futures to eventually hold results.
     foo = batch.foo(one="One", two="Two")
     bar = batch.bar("Eins", "Zwei")
-    # We can call non-batchable proxy methods, but the break the current batch
-    # request and cause additional roundtrips.
-    greet = batch.greet(name="John Smith")
-    # We can also add local methods into the mix, but they break the batch too.
-    hello = batch.hello()
     bar2 = batch.bar(b="Uno", a="Due")
-    # Only now are all the calls executed in sequence, with as few roundtrips
-    # as possible.
+
+    # Future shouldn't be set until we submit().
+    assert isinstance(foo, peer.future)
+    assert not util.safehasattr(foo, 'value')
+    assert not util.safehasattr(bar, 'value')
     batch.submit()
-    # After the call to submit, the futures actually contain values.
+    # Call results() to obtain results as a generator.
+    results = batch.results()
+
+    # Future results shouldn't be set until we consume a value.
+    assert not util.safehasattr(foo, 'value')
+    foovalue = next(results)
+    assert util.safehasattr(foo, 'value')
+    assert foovalue == foo.value
     print(foo.value)
+    next(results)
     print(bar.value)
-    print(greet.value)
-    print(hello.value)
+    next(results)
     print(bar2.value)
 
+    # We should be at the end of the results generator.
+    try:
+        next(results)
+    except StopIteration:
+        print('proper end of results generator')
+    else:
+        print('extra emitted element!')
+
+    # Attempting to call a non-batchable method inside a batch fails.
+    batch = it.batchiter()
+    try:
+        batch.greet(name='John Smith')
+    except error.ProgrammingError as e:
+        print(e)
+
+    # Attempting to call a local method inside a batch fails.
+    batch = it.batchiter()
+    try:
+        batch.hello()
+    except error.ProgrammingError as e:
+        print(e)
+
 # local usage
 mylocal = localthing()
 print()
@@ -144,10 +173,11 @@
             req.append(name + ':' + args)
         req = ';'.join(req)
         res = self._submitone('batch', [('cmds', req,)])
-        return res.split(';')
+        for r in res.split(';'):
+            yield r
 
-    def batch(self):
-        return wireproto.remotebatch(self)
+    def batchiter(self):
+        return wireproto.remoteiterbatcher(self)
 
     @peer.batchable
     def foo(self, one, two=None):