def test_gather_simple(self):
        s1 = operations.sleep(0.25, obj)
        s2 = operations.sleep(0.5, obj2)
        s3 = operations.sleep(0.75, obj3)

        r1, r2, r3 = operations.gather(s1, s2, s3).result()
        self.assertIs(r1, obj)
        self.assertIs(r2, obj2)
        self.assertIs(r3, obj3)
    def test_gather_return(self):
        s1 = operations.sleep(0.25, obj)
        s2 = operations.sleep(0.5, obj2)
        s3 = operations.sleep(0.75, obj3)

        r1, r2, r3 = operations.gather(s1, s2, s3,
                                       return_exceptions=True).result()
        self.assertIs(r1, obj)
        self.assertIs(r2, obj2)
        self.assertIs(r3, obj3)
    def test_gather_propagate_cancel(self):
        s1 = operations.sleep(0.5, obj)
        s2 = operations.sleep(0.75, obj2)
        s3 = operations.sleep(1, obj3)

        g = operations.gather(s1, s2, s3)
        time.sleep(0.25)
        g.cancel()
        self.assertTrue(s1.cancelled())
        self.assertTrue(s2.cancelled())
        self.assertTrue(s3.cancelled())
    def test_gather_propagate_partial_complete(self):
        s1 = operations.sleep(0.25, obj)
        s2 = operations.sleep(0.75, obj2)
        s3 = operations.sleep(1, obj3)

        g = operations.gather(s1, s2, s3)
        time.sleep(0.5)
        g.cancel()
        self.assertFalse(s1.cancelled())
        self.assertIs(s1.result(), obj)
        self.assertTrue(s2.cancelled())
        self.assertTrue(s3.cancelled())
    def test_gather_error(self):
        s1 = operations.sleep(0.25, obj)

        @operations.futurize
        def _s2():
            yield operations.sleep(0.5)
            raise exc

        s2 = _s2()
        s3 = operations.sleep(0.75, obj3)

        try:
            operations.gather(s1, s2, s3).result()
        except Exception as e:
            self.assertIs(e, exc)
        else:
            self.fail("Did not trigger exception")

        self.assertTrue(s1.done())
        self.assertFalse(s1.cancelled())
        self.assertTrue(s2.done())
        self.assertFalse(s2.cancelled())
        self.assertFalse(s3.done())
        self.assertFalse(s3.cancelled())
    def test_gather_error_return(self):
        s1 = operations.sleep(0.25, obj)

        @operations.futurize
        def _s2():
            yield operations.sleep(0.5)
            raise exc

        s2 = _s2()
        s3 = operations.sleep(0.75, obj3)

        r1, r2, r3 = operations.gather(s1, s2, s3,
                                       return_exceptions=True).result()
        self.assertIs(r1, obj)
        self.assertIs(r2, exc)
        self.assertIs(r3, obj3)
    def test_gather_cancel_fater_first_completion(self):
        s1 = operations.sleep(0.25, obj)
        s2 = operations.sleep(0.75, obj2)
        s3 = operations.sleep(1, obj3)

        g = operations.gather(s1, s2, s3, return_exceptions=True)
        time.sleep(0.5)
        s2.cancel()

        self.assertFalse(g.cancelled())
        self.assertFalse(s1.cancelled())
        self.assertTrue(s2.cancelled())
        self.assertFalse(s3.cancelled())

        r1, r2, r3 = g.result()
        self.assertIs(r1, obj)
        self.assertIsInstance(r2, CancelledError)
        self.assertIs(r3, obj3)
    def test_gather_shield_child_cancel(self):
        s1 = operations.sleep(0.5, obj)
        s2 = operations.sleep(0.75, obj2)
        s3 = operations.sleep(1, obj3)

        g = operations.gather(s1, s2, s3)
        time.sleep(0.25)
        s1.cancel()
        self.assertFalse(g.cancelled())
        self.assertTrue(s1.cancelled())
        self.assertFalse(s2.cancelled())
        self.assertFalse(s3.cancelled())

        try:
            g.result()
        except CancelledError:
            pass
        except:
            self.fail("Incorrect error")