1dc15686d2d289866234948689a338891068faef2Keun Soo Yimimport os
2dc15686d2d289866234948689a338891068faef2Keun Soo Yimimport subprocess
3dc15686d2d289866234948689a338891068faef2Keun Soo Yimimport sys
4dc15686d2d289866234948689a338891068faef2Keun Soo Yimimport threading
5dc15686d2d289866234948689a338891068faef2Keun Soo Yimimport functools
6dc15686d2d289866234948689a338891068faef2Keun Soo Yimimport contextlib
7dc15686d2d289866234948689a338891068faef2Keun Soo Yimimport logging
8dc15686d2d289866234948689a338891068faef2Keun Soo Yimimport re
9dc15686d2d289866234948689a338891068faef2Keun Soo Yimimport time
10dc15686d2d289866234948689a338891068faef2Keun Soo Yimimport gc
11dc15686d2d289866234948689a338891068faef2Keun Soo Yimimport traceback
12dc15686d2d289866234948689a338891068faef2Keun Soo Yimfrom StringIO import StringIO
13dc15686d2d289866234948689a338891068faef2Keun Soo Yimfrom test import test_support
14dc15686d2d289866234948689a338891068faef2Keun Soo Yim
15dc15686d2d289866234948689a338891068faef2Keun Soo Yimfrom concurrent import futures
16dc15686d2d289866234948689a338891068faef2Keun Soo Yimfrom concurrent.futures._base import (
17dc15686d2d289866234948689a338891068faef2Keun Soo Yim    PENDING, RUNNING, CANCELLED, CANCELLED_AND_NOTIFIED, FINISHED, Future)
18dc15686d2d289866234948689a338891068faef2Keun Soo Yimfrom concurrent.futures.thread import cpu_count
19dc15686d2d289866234948689a338891068faef2Keun Soo Yim
20dc15686d2d289866234948689a338891068faef2Keun Soo Yimtry:
21dc15686d2d289866234948689a338891068faef2Keun Soo Yim    import unittest2 as unittest
22dc15686d2d289866234948689a338891068faef2Keun Soo Yimexcept ImportError:
23dc15686d2d289866234948689a338891068faef2Keun Soo Yim    import unittest
24dc15686d2d289866234948689a338891068faef2Keun Soo Yim
25dc15686d2d289866234948689a338891068faef2Keun Soo Yim
26dc15686d2d289866234948689a338891068faef2Keun Soo Yimdef reap_threads(func):
27dc15686d2d289866234948689a338891068faef2Keun Soo Yim    """Use this function when threads are being used.  This will
28dc15686d2d289866234948689a338891068faef2Keun Soo Yim    ensure that the threads are cleaned up even when the test fails.
29dc15686d2d289866234948689a338891068faef2Keun Soo Yim    If threading is unavailable this function does nothing.
30dc15686d2d289866234948689a338891068faef2Keun Soo Yim    """
31dc15686d2d289866234948689a338891068faef2Keun Soo Yim    @functools.wraps(func)
32dc15686d2d289866234948689a338891068faef2Keun Soo Yim    def decorator(*args):
33dc15686d2d289866234948689a338891068faef2Keun Soo Yim        key = test_support.threading_setup()
34dc15686d2d289866234948689a338891068faef2Keun Soo Yim        try:
35dc15686d2d289866234948689a338891068faef2Keun Soo Yim            return func(*args)
36dc15686d2d289866234948689a338891068faef2Keun Soo Yim        finally:
37dc15686d2d289866234948689a338891068faef2Keun Soo Yim            test_support.threading_cleanup(*key)
38dc15686d2d289866234948689a338891068faef2Keun Soo Yim    return decorator
39dc15686d2d289866234948689a338891068faef2Keun Soo Yim
40dc15686d2d289866234948689a338891068faef2Keun Soo Yim
41dc15686d2d289866234948689a338891068faef2Keun Soo Yim# Executing the interpreter in a subprocess
42dc15686d2d289866234948689a338891068faef2Keun Soo Yimdef _assert_python(expected_success, *args, **env_vars):
43dc15686d2d289866234948689a338891068faef2Keun Soo Yim    cmd_line = [sys.executable]
44dc15686d2d289866234948689a338891068faef2Keun Soo Yim    if not env_vars:
45dc15686d2d289866234948689a338891068faef2Keun Soo Yim        cmd_line.append('-E')
46dc15686d2d289866234948689a338891068faef2Keun Soo Yim    # Need to preserve the original environment, for in-place testing of
47dc15686d2d289866234948689a338891068faef2Keun Soo Yim    # shared library builds.
48dc15686d2d289866234948689a338891068faef2Keun Soo Yim    env = os.environ.copy()
49dc15686d2d289866234948689a338891068faef2Keun Soo Yim    # But a special flag that can be set to override -- in this case, the
50dc15686d2d289866234948689a338891068faef2Keun Soo Yim    # caller is responsible to pass the full environment.
51dc15686d2d289866234948689a338891068faef2Keun Soo Yim    if env_vars.pop('__cleanenv', None):
52dc15686d2d289866234948689a338891068faef2Keun Soo Yim        env = {}
53dc15686d2d289866234948689a338891068faef2Keun Soo Yim    env.update(env_vars)
54dc15686d2d289866234948689a338891068faef2Keun Soo Yim    cmd_line.extend(args)
55dc15686d2d289866234948689a338891068faef2Keun Soo Yim    p = subprocess.Popen(cmd_line, stdin=subprocess.PIPE,
56dc15686d2d289866234948689a338891068faef2Keun Soo Yim                         stdout=subprocess.PIPE, stderr=subprocess.PIPE,
57dc15686d2d289866234948689a338891068faef2Keun Soo Yim                         env=env)
58dc15686d2d289866234948689a338891068faef2Keun Soo Yim    try:
59dc15686d2d289866234948689a338891068faef2Keun Soo Yim        out, err = p.communicate()
60dc15686d2d289866234948689a338891068faef2Keun Soo Yim    finally:
61dc15686d2d289866234948689a338891068faef2Keun Soo Yim        subprocess._cleanup()
62dc15686d2d289866234948689a338891068faef2Keun Soo Yim        p.stdout.close()
63dc15686d2d289866234948689a338891068faef2Keun Soo Yim        p.stderr.close()
64dc15686d2d289866234948689a338891068faef2Keun Soo Yim    rc = p.returncode
65dc15686d2d289866234948689a338891068faef2Keun Soo Yim    err = strip_python_stderr(err)
66dc15686d2d289866234948689a338891068faef2Keun Soo Yim    if (rc and expected_success) or (not rc and not expected_success):
67dc15686d2d289866234948689a338891068faef2Keun Soo Yim        raise AssertionError(
68dc15686d2d289866234948689a338891068faef2Keun Soo Yim            "Process return code is %d, "
69dc15686d2d289866234948689a338891068faef2Keun Soo Yim            "stderr follows:\n%s" % (rc, err.decode('ascii', 'ignore')))
70dc15686d2d289866234948689a338891068faef2Keun Soo Yim    return rc, out, err
71dc15686d2d289866234948689a338891068faef2Keun Soo Yim
72dc15686d2d289866234948689a338891068faef2Keun Soo Yim
73dc15686d2d289866234948689a338891068faef2Keun Soo Yimdef assert_python_ok(*args, **env_vars):
74dc15686d2d289866234948689a338891068faef2Keun Soo Yim    """
75dc15686d2d289866234948689a338891068faef2Keun Soo Yim    Assert that running the interpreter with `args` and optional environment
76dc15686d2d289866234948689a338891068faef2Keun Soo Yim    variables `env_vars` is ok and return a (return code, stdout, stderr) tuple.
77dc15686d2d289866234948689a338891068faef2Keun Soo Yim    """
78dc15686d2d289866234948689a338891068faef2Keun Soo Yim    return _assert_python(True, *args, **env_vars)
79dc15686d2d289866234948689a338891068faef2Keun Soo Yim
80dc15686d2d289866234948689a338891068faef2Keun Soo Yim
81dc15686d2d289866234948689a338891068faef2Keun Soo Yimdef strip_python_stderr(stderr):
82dc15686d2d289866234948689a338891068faef2Keun Soo Yim    """Strip the stderr of a Python process from potential debug output
83dc15686d2d289866234948689a338891068faef2Keun Soo Yim    emitted by the interpreter.
84dc15686d2d289866234948689a338891068faef2Keun Soo Yim
85dc15686d2d289866234948689a338891068faef2Keun Soo Yim    This will typically be run on the result of the communicate() method
86dc15686d2d289866234948689a338891068faef2Keun Soo Yim    of a subprocess.Popen object.
87dc15686d2d289866234948689a338891068faef2Keun Soo Yim    """
88dc15686d2d289866234948689a338891068faef2Keun Soo Yim    stderr = re.sub(r"\[\d+ refs\]\r?\n?$".encode(), "".encode(), stderr).strip()
89dc15686d2d289866234948689a338891068faef2Keun Soo Yim    return stderr
90dc15686d2d289866234948689a338891068faef2Keun Soo Yim
91dc15686d2d289866234948689a338891068faef2Keun Soo Yim
92dc15686d2d289866234948689a338891068faef2Keun Soo Yim@contextlib.contextmanager
93dc15686d2d289866234948689a338891068faef2Keun Soo Yimdef captured_stderr():
94dc15686d2d289866234948689a338891068faef2Keun Soo Yim    """Return a context manager used by captured_stdout/stdin/stderr
95dc15686d2d289866234948689a338891068faef2Keun Soo Yim    that temporarily replaces the sys stream *stream_name* with a StringIO."""
96dc15686d2d289866234948689a338891068faef2Keun Soo Yim    logging_stream = StringIO()
97dc15686d2d289866234948689a338891068faef2Keun Soo Yim    handler = logging.StreamHandler(logging_stream)
98dc15686d2d289866234948689a338891068faef2Keun Soo Yim    logging.root.addHandler(handler)
99dc15686d2d289866234948689a338891068faef2Keun Soo Yim
100dc15686d2d289866234948689a338891068faef2Keun Soo Yim    try:
101dc15686d2d289866234948689a338891068faef2Keun Soo Yim        yield logging_stream
102dc15686d2d289866234948689a338891068faef2Keun Soo Yim    finally:
103dc15686d2d289866234948689a338891068faef2Keun Soo Yim        logging.root.removeHandler(handler)
104dc15686d2d289866234948689a338891068faef2Keun Soo Yim
105dc15686d2d289866234948689a338891068faef2Keun Soo Yim
106dc15686d2d289866234948689a338891068faef2Keun Soo Yimdef create_future(state=PENDING, exception=None, result=None):
107dc15686d2d289866234948689a338891068faef2Keun Soo Yim    f = Future()
108dc15686d2d289866234948689a338891068faef2Keun Soo Yim    f._state = state
109dc15686d2d289866234948689a338891068faef2Keun Soo Yim    f._exception = exception
110dc15686d2d289866234948689a338891068faef2Keun Soo Yim    f._result = result
111dc15686d2d289866234948689a338891068faef2Keun Soo Yim    return f
112dc15686d2d289866234948689a338891068faef2Keun Soo Yim
113dc15686d2d289866234948689a338891068faef2Keun Soo Yim
114dc15686d2d289866234948689a338891068faef2Keun Soo YimPENDING_FUTURE = create_future(state=PENDING)
115dc15686d2d289866234948689a338891068faef2Keun Soo YimRUNNING_FUTURE = create_future(state=RUNNING)
116dc15686d2d289866234948689a338891068faef2Keun Soo YimCANCELLED_FUTURE = create_future(state=CANCELLED)
117dc15686d2d289866234948689a338891068faef2Keun Soo YimCANCELLED_AND_NOTIFIED_FUTURE = create_future(state=CANCELLED_AND_NOTIFIED)
118dc15686d2d289866234948689a338891068faef2Keun Soo YimEXCEPTION_FUTURE = create_future(state=FINISHED, exception=IOError())
119dc15686d2d289866234948689a338891068faef2Keun Soo YimSUCCESSFUL_FUTURE = create_future(state=FINISHED, result=42)
120dc15686d2d289866234948689a338891068faef2Keun Soo Yim
121dc15686d2d289866234948689a338891068faef2Keun Soo Yim
122dc15686d2d289866234948689a338891068faef2Keun Soo Yimdef mul(x, y):
123dc15686d2d289866234948689a338891068faef2Keun Soo Yim    return x * y
124dc15686d2d289866234948689a338891068faef2Keun Soo Yim
125dc15686d2d289866234948689a338891068faef2Keun Soo Yim
126dc15686d2d289866234948689a338891068faef2Keun Soo Yimdef sleep_and_raise(t):
127dc15686d2d289866234948689a338891068faef2Keun Soo Yim    time.sleep(t)
128dc15686d2d289866234948689a338891068faef2Keun Soo Yim    raise Exception('this is an exception')
129dc15686d2d289866234948689a338891068faef2Keun Soo Yim
130dc15686d2d289866234948689a338891068faef2Keun Soo Yimdef sleep_and_print(t, msg):
131dc15686d2d289866234948689a338891068faef2Keun Soo Yim    time.sleep(t)
132dc15686d2d289866234948689a338891068faef2Keun Soo Yim    print(msg)
133dc15686d2d289866234948689a338891068faef2Keun Soo Yim    sys.stdout.flush()
134dc15686d2d289866234948689a338891068faef2Keun Soo Yim
135dc15686d2d289866234948689a338891068faef2Keun Soo Yim
136dc15686d2d289866234948689a338891068faef2Keun Soo Yimclass ExecutorMixin:
137dc15686d2d289866234948689a338891068faef2Keun Soo Yim    worker_count = 5
138dc15686d2d289866234948689a338891068faef2Keun Soo Yim
139dc15686d2d289866234948689a338891068faef2Keun Soo Yim    def setUp(self):
140dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.t1 = time.time()
141dc15686d2d289866234948689a338891068faef2Keun Soo Yim        try:
142dc15686d2d289866234948689a338891068faef2Keun Soo Yim            self.executor = self.executor_type(max_workers=self.worker_count)
143dc15686d2d289866234948689a338891068faef2Keun Soo Yim        except NotImplementedError:
144dc15686d2d289866234948689a338891068faef2Keun Soo Yim            e = sys.exc_info()[1]
145dc15686d2d289866234948689a338891068faef2Keun Soo Yim            self.skipTest(str(e))
146dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self._prime_executor()
147dc15686d2d289866234948689a338891068faef2Keun Soo Yim
148dc15686d2d289866234948689a338891068faef2Keun Soo Yim    def tearDown(self):
149dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.executor.shutdown(wait=True)
150dc15686d2d289866234948689a338891068faef2Keun Soo Yim        dt = time.time() - self.t1
151dc15686d2d289866234948689a338891068faef2Keun Soo Yim        if test_support.verbose:
152dc15686d2d289866234948689a338891068faef2Keun Soo Yim            print("%.2fs" % dt)
153dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertLess(dt, 60, "synchronization issue: test lasted too long")
154dc15686d2d289866234948689a338891068faef2Keun Soo Yim
155dc15686d2d289866234948689a338891068faef2Keun Soo Yim    def _prime_executor(self):
156dc15686d2d289866234948689a338891068faef2Keun Soo Yim        # Make sure that the executor is ready to do work before running the
157dc15686d2d289866234948689a338891068faef2Keun Soo Yim        # tests. This should reduce the probability of timeouts in the tests.
158dc15686d2d289866234948689a338891068faef2Keun Soo Yim        futures = [self.executor.submit(time.sleep, 0.1)
159dc15686d2d289866234948689a338891068faef2Keun Soo Yim                   for _ in range(self.worker_count)]
160dc15686d2d289866234948689a338891068faef2Keun Soo Yim
161dc15686d2d289866234948689a338891068faef2Keun Soo Yim        for f in futures:
162dc15686d2d289866234948689a338891068faef2Keun Soo Yim            f.result()
163dc15686d2d289866234948689a338891068faef2Keun Soo Yim
164dc15686d2d289866234948689a338891068faef2Keun Soo Yim
165dc15686d2d289866234948689a338891068faef2Keun Soo Yimclass ThreadPoolMixin(ExecutorMixin):
166dc15686d2d289866234948689a338891068faef2Keun Soo Yim    executor_type = futures.ThreadPoolExecutor
167dc15686d2d289866234948689a338891068faef2Keun Soo Yim
168dc15686d2d289866234948689a338891068faef2Keun Soo Yim
169dc15686d2d289866234948689a338891068faef2Keun Soo Yimclass ProcessPoolMixin(ExecutorMixin):
170dc15686d2d289866234948689a338891068faef2Keun Soo Yim    executor_type = futures.ProcessPoolExecutor
171dc15686d2d289866234948689a338891068faef2Keun Soo Yim
172dc15686d2d289866234948689a338891068faef2Keun Soo Yim
173dc15686d2d289866234948689a338891068faef2Keun Soo Yimclass ExecutorShutdownTest(unittest.TestCase):
174dc15686d2d289866234948689a338891068faef2Keun Soo Yim    def test_run_after_shutdown(self):
175dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.executor.shutdown()
176dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertRaises(RuntimeError,
177dc15686d2d289866234948689a338891068faef2Keun Soo Yim                          self.executor.submit,
178dc15686d2d289866234948689a338891068faef2Keun Soo Yim                          pow, 2, 5)
179dc15686d2d289866234948689a338891068faef2Keun Soo Yim
180dc15686d2d289866234948689a338891068faef2Keun Soo Yim    def test_interpreter_shutdown(self):
181dc15686d2d289866234948689a338891068faef2Keun Soo Yim        # Test the atexit hook for shutdown of worker threads and processes
182dc15686d2d289866234948689a338891068faef2Keun Soo Yim        rc, out, err = assert_python_ok('-c', """if 1:
183dc15686d2d289866234948689a338891068faef2Keun Soo Yim            from concurrent.futures import %s
184dc15686d2d289866234948689a338891068faef2Keun Soo Yim            from time import sleep
185dc15686d2d289866234948689a338891068faef2Keun Soo Yim            from test_futures import sleep_and_print
186dc15686d2d289866234948689a338891068faef2Keun Soo Yim            t = %s(5)
187dc15686d2d289866234948689a338891068faef2Keun Soo Yim            t.submit(sleep_and_print, 1.0, "apple")
188dc15686d2d289866234948689a338891068faef2Keun Soo Yim            """ % (self.executor_type.__name__, self.executor_type.__name__))
189dc15686d2d289866234948689a338891068faef2Keun Soo Yim        # Errors in atexit hooks don't change the process exit code, check
190dc15686d2d289866234948689a338891068faef2Keun Soo Yim        # stderr manually.
191dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertFalse(err)
192dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertEqual(out.strip(), "apple".encode())
193dc15686d2d289866234948689a338891068faef2Keun Soo Yim
194dc15686d2d289866234948689a338891068faef2Keun Soo Yim    def test_hang_issue12364(self):
195dc15686d2d289866234948689a338891068faef2Keun Soo Yim        fs = [self.executor.submit(time.sleep, 0.1) for _ in range(50)]
196dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.executor.shutdown()
197dc15686d2d289866234948689a338891068faef2Keun Soo Yim        for f in fs:
198dc15686d2d289866234948689a338891068faef2Keun Soo Yim            f.result()
199dc15686d2d289866234948689a338891068faef2Keun Soo Yim
200dc15686d2d289866234948689a338891068faef2Keun Soo Yim
201dc15686d2d289866234948689a338891068faef2Keun Soo Yimclass ThreadPoolShutdownTest(ThreadPoolMixin, ExecutorShutdownTest):
202dc15686d2d289866234948689a338891068faef2Keun Soo Yim    def _prime_executor(self):
203dc15686d2d289866234948689a338891068faef2Keun Soo Yim        pass
204dc15686d2d289866234948689a338891068faef2Keun Soo Yim
205dc15686d2d289866234948689a338891068faef2Keun Soo Yim    def test_threads_terminate(self):
206dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.executor.submit(mul, 21, 2)
207dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.executor.submit(mul, 6, 7)
208dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.executor.submit(mul, 3, 14)
209dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertEqual(len(self.executor._threads), 3)
210dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.executor.shutdown()
211dc15686d2d289866234948689a338891068faef2Keun Soo Yim        for t in self.executor._threads:
212dc15686d2d289866234948689a338891068faef2Keun Soo Yim            t.join()
213dc15686d2d289866234948689a338891068faef2Keun Soo Yim
214dc15686d2d289866234948689a338891068faef2Keun Soo Yim    def test_context_manager_shutdown(self):
215dc15686d2d289866234948689a338891068faef2Keun Soo Yim        with futures.ThreadPoolExecutor(max_workers=5) as e:
216dc15686d2d289866234948689a338891068faef2Keun Soo Yim            executor = e
217dc15686d2d289866234948689a338891068faef2Keun Soo Yim            self.assertEqual(list(e.map(abs, range(-5, 5))),
218dc15686d2d289866234948689a338891068faef2Keun Soo Yim                             [5, 4, 3, 2, 1, 0, 1, 2, 3, 4])
219dc15686d2d289866234948689a338891068faef2Keun Soo Yim
220dc15686d2d289866234948689a338891068faef2Keun Soo Yim        for t in executor._threads:
221dc15686d2d289866234948689a338891068faef2Keun Soo Yim            t.join()
222dc15686d2d289866234948689a338891068faef2Keun Soo Yim
223dc15686d2d289866234948689a338891068faef2Keun Soo Yim    def test_del_shutdown(self):
224dc15686d2d289866234948689a338891068faef2Keun Soo Yim        executor = futures.ThreadPoolExecutor(max_workers=5)
225dc15686d2d289866234948689a338891068faef2Keun Soo Yim        executor.map(abs, range(-5, 5))
226dc15686d2d289866234948689a338891068faef2Keun Soo Yim        threads = executor._threads
227dc15686d2d289866234948689a338891068faef2Keun Soo Yim        del executor
228dc15686d2d289866234948689a338891068faef2Keun Soo Yim        gc.collect()
229dc15686d2d289866234948689a338891068faef2Keun Soo Yim
230dc15686d2d289866234948689a338891068faef2Keun Soo Yim        for t in threads:
231dc15686d2d289866234948689a338891068faef2Keun Soo Yim            t.join()
232dc15686d2d289866234948689a338891068faef2Keun Soo Yim
233dc15686d2d289866234948689a338891068faef2Keun Soo Yim    def test_thread_names_assigned(self):
234dc15686d2d289866234948689a338891068faef2Keun Soo Yim        executor = futures.ThreadPoolExecutor(
235dc15686d2d289866234948689a338891068faef2Keun Soo Yim            max_workers=5, thread_name_prefix='SpecialPool')
236dc15686d2d289866234948689a338891068faef2Keun Soo Yim        executor.map(abs, range(-5, 5))
237dc15686d2d289866234948689a338891068faef2Keun Soo Yim        threads = executor._threads
238dc15686d2d289866234948689a338891068faef2Keun Soo Yim        del executor
239dc15686d2d289866234948689a338891068faef2Keun Soo Yim        gc.collect()
240dc15686d2d289866234948689a338891068faef2Keun Soo Yim
241dc15686d2d289866234948689a338891068faef2Keun Soo Yim        for t in threads:
242dc15686d2d289866234948689a338891068faef2Keun Soo Yim            self.assertRegexpMatches(t.name, r'^SpecialPool_[0-4]$')
243dc15686d2d289866234948689a338891068faef2Keun Soo Yim            t.join()
244dc15686d2d289866234948689a338891068faef2Keun Soo Yim
245dc15686d2d289866234948689a338891068faef2Keun Soo Yim    def test_thread_names_default(self):
246dc15686d2d289866234948689a338891068faef2Keun Soo Yim        executor = futures.ThreadPoolExecutor(max_workers=5)
247dc15686d2d289866234948689a338891068faef2Keun Soo Yim        executor.map(abs, range(-5, 5))
248dc15686d2d289866234948689a338891068faef2Keun Soo Yim        threads = executor._threads
249dc15686d2d289866234948689a338891068faef2Keun Soo Yim        del executor
250dc15686d2d289866234948689a338891068faef2Keun Soo Yim        gc.collect()
251dc15686d2d289866234948689a338891068faef2Keun Soo Yim
252dc15686d2d289866234948689a338891068faef2Keun Soo Yim        for t in threads:
253dc15686d2d289866234948689a338891068faef2Keun Soo Yim            # Ensure that our default name is reasonably sane and unique when
254dc15686d2d289866234948689a338891068faef2Keun Soo Yim            # no thread_name_prefix was supplied.
255dc15686d2d289866234948689a338891068faef2Keun Soo Yim            self.assertRegexpMatches(t.name, r'ThreadPoolExecutor-\d+_[0-4]$')
256dc15686d2d289866234948689a338891068faef2Keun Soo Yim            t.join()
257dc15686d2d289866234948689a338891068faef2Keun Soo Yim
258dc15686d2d289866234948689a338891068faef2Keun Soo Yim
259dc15686d2d289866234948689a338891068faef2Keun Soo Yimclass ProcessPoolShutdownTest(ProcessPoolMixin, ExecutorShutdownTest):
260dc15686d2d289866234948689a338891068faef2Keun Soo Yim    def _prime_executor(self):
261dc15686d2d289866234948689a338891068faef2Keun Soo Yim        pass
262dc15686d2d289866234948689a338891068faef2Keun Soo Yim
263dc15686d2d289866234948689a338891068faef2Keun Soo Yim    def test_processes_terminate(self):
264dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.executor.submit(mul, 21, 2)
265dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.executor.submit(mul, 6, 7)
266dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.executor.submit(mul, 3, 14)
267dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertEqual(len(self.executor._processes), 5)
268dc15686d2d289866234948689a338891068faef2Keun Soo Yim        processes = self.executor._processes
269dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.executor.shutdown()
270dc15686d2d289866234948689a338891068faef2Keun Soo Yim
271dc15686d2d289866234948689a338891068faef2Keun Soo Yim        for p in processes:
272dc15686d2d289866234948689a338891068faef2Keun Soo Yim            p.join()
273dc15686d2d289866234948689a338891068faef2Keun Soo Yim
274dc15686d2d289866234948689a338891068faef2Keun Soo Yim    def test_context_manager_shutdown(self):
275dc15686d2d289866234948689a338891068faef2Keun Soo Yim        with futures.ProcessPoolExecutor(max_workers=5) as e:
276dc15686d2d289866234948689a338891068faef2Keun Soo Yim            processes = e._processes
277dc15686d2d289866234948689a338891068faef2Keun Soo Yim            self.assertEqual(list(e.map(abs, range(-5, 5))),
278dc15686d2d289866234948689a338891068faef2Keun Soo Yim                             [5, 4, 3, 2, 1, 0, 1, 2, 3, 4])
279dc15686d2d289866234948689a338891068faef2Keun Soo Yim
280dc15686d2d289866234948689a338891068faef2Keun Soo Yim        for p in processes:
281dc15686d2d289866234948689a338891068faef2Keun Soo Yim            p.join()
282dc15686d2d289866234948689a338891068faef2Keun Soo Yim
283dc15686d2d289866234948689a338891068faef2Keun Soo Yim    def test_del_shutdown(self):
284dc15686d2d289866234948689a338891068faef2Keun Soo Yim        executor = futures.ProcessPoolExecutor(max_workers=5)
285dc15686d2d289866234948689a338891068faef2Keun Soo Yim        list(executor.map(abs, range(-5, 5)))
286dc15686d2d289866234948689a338891068faef2Keun Soo Yim        queue_management_thread = executor._queue_management_thread
287dc15686d2d289866234948689a338891068faef2Keun Soo Yim        processes = executor._processes
288dc15686d2d289866234948689a338891068faef2Keun Soo Yim        del executor
289dc15686d2d289866234948689a338891068faef2Keun Soo Yim        gc.collect()
290dc15686d2d289866234948689a338891068faef2Keun Soo Yim
291dc15686d2d289866234948689a338891068faef2Keun Soo Yim        queue_management_thread.join()
292dc15686d2d289866234948689a338891068faef2Keun Soo Yim        for p in processes:
293dc15686d2d289866234948689a338891068faef2Keun Soo Yim            p.join()
294dc15686d2d289866234948689a338891068faef2Keun Soo Yim
295dc15686d2d289866234948689a338891068faef2Keun Soo Yim
296dc15686d2d289866234948689a338891068faef2Keun Soo Yimclass WaitTests(unittest.TestCase):
297dc15686d2d289866234948689a338891068faef2Keun Soo Yim
298dc15686d2d289866234948689a338891068faef2Keun Soo Yim    def test_first_completed(self):
299dc15686d2d289866234948689a338891068faef2Keun Soo Yim        future1 = self.executor.submit(mul, 21, 2)
300dc15686d2d289866234948689a338891068faef2Keun Soo Yim        future2 = self.executor.submit(time.sleep, 1.5)
301dc15686d2d289866234948689a338891068faef2Keun Soo Yim
302dc15686d2d289866234948689a338891068faef2Keun Soo Yim        done, not_done = futures.wait(
303dc15686d2d289866234948689a338891068faef2Keun Soo Yim                [CANCELLED_FUTURE, future1, future2],
304dc15686d2d289866234948689a338891068faef2Keun Soo Yim                 return_when=futures.FIRST_COMPLETED)
305dc15686d2d289866234948689a338891068faef2Keun Soo Yim
306dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertEqual(set([future1]), done)
307dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertEqual(set([CANCELLED_FUTURE, future2]), not_done)
308dc15686d2d289866234948689a338891068faef2Keun Soo Yim
309dc15686d2d289866234948689a338891068faef2Keun Soo Yim    def test_first_completed_some_already_completed(self):
310dc15686d2d289866234948689a338891068faef2Keun Soo Yim        future1 = self.executor.submit(time.sleep, 1.5)
311dc15686d2d289866234948689a338891068faef2Keun Soo Yim
312dc15686d2d289866234948689a338891068faef2Keun Soo Yim        finished, pending = futures.wait(
313dc15686d2d289866234948689a338891068faef2Keun Soo Yim                 [CANCELLED_AND_NOTIFIED_FUTURE, SUCCESSFUL_FUTURE, future1],
314dc15686d2d289866234948689a338891068faef2Keun Soo Yim                 return_when=futures.FIRST_COMPLETED)
315dc15686d2d289866234948689a338891068faef2Keun Soo Yim
316dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertEqual(
317dc15686d2d289866234948689a338891068faef2Keun Soo Yim                set([CANCELLED_AND_NOTIFIED_FUTURE, SUCCESSFUL_FUTURE]),
318dc15686d2d289866234948689a338891068faef2Keun Soo Yim                finished)
319dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertEqual(set([future1]), pending)
320dc15686d2d289866234948689a338891068faef2Keun Soo Yim
321dc15686d2d289866234948689a338891068faef2Keun Soo Yim    def test_first_exception(self):
322dc15686d2d289866234948689a338891068faef2Keun Soo Yim        future1 = self.executor.submit(mul, 2, 21)
323dc15686d2d289866234948689a338891068faef2Keun Soo Yim        future2 = self.executor.submit(sleep_and_raise, 1.5)
324dc15686d2d289866234948689a338891068faef2Keun Soo Yim        future3 = self.executor.submit(time.sleep, 3)
325dc15686d2d289866234948689a338891068faef2Keun Soo Yim
326dc15686d2d289866234948689a338891068faef2Keun Soo Yim        finished, pending = futures.wait(
327dc15686d2d289866234948689a338891068faef2Keun Soo Yim                [future1, future2, future3],
328dc15686d2d289866234948689a338891068faef2Keun Soo Yim                return_when=futures.FIRST_EXCEPTION)
329dc15686d2d289866234948689a338891068faef2Keun Soo Yim
330dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertEqual(set([future1, future2]), finished)
331dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertEqual(set([future3]), pending)
332dc15686d2d289866234948689a338891068faef2Keun Soo Yim
333dc15686d2d289866234948689a338891068faef2Keun Soo Yim    def test_first_exception_some_already_complete(self):
334dc15686d2d289866234948689a338891068faef2Keun Soo Yim        future1 = self.executor.submit(divmod, 21, 0)
335dc15686d2d289866234948689a338891068faef2Keun Soo Yim        future2 = self.executor.submit(time.sleep, 1.5)
336dc15686d2d289866234948689a338891068faef2Keun Soo Yim
337dc15686d2d289866234948689a338891068faef2Keun Soo Yim        finished, pending = futures.wait(
338dc15686d2d289866234948689a338891068faef2Keun Soo Yim                [SUCCESSFUL_FUTURE,
339dc15686d2d289866234948689a338891068faef2Keun Soo Yim                 CANCELLED_FUTURE,
340dc15686d2d289866234948689a338891068faef2Keun Soo Yim                 CANCELLED_AND_NOTIFIED_FUTURE,
341dc15686d2d289866234948689a338891068faef2Keun Soo Yim                 future1, future2],
342dc15686d2d289866234948689a338891068faef2Keun Soo Yim                return_when=futures.FIRST_EXCEPTION)
343dc15686d2d289866234948689a338891068faef2Keun Soo Yim
344dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertEqual(set([SUCCESSFUL_FUTURE,
345dc15686d2d289866234948689a338891068faef2Keun Soo Yim                              CANCELLED_AND_NOTIFIED_FUTURE,
346dc15686d2d289866234948689a338891068faef2Keun Soo Yim                              future1]), finished)
347dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertEqual(set([CANCELLED_FUTURE, future2]), pending)
348dc15686d2d289866234948689a338891068faef2Keun Soo Yim
349dc15686d2d289866234948689a338891068faef2Keun Soo Yim    def test_first_exception_one_already_failed(self):
350dc15686d2d289866234948689a338891068faef2Keun Soo Yim        future1 = self.executor.submit(time.sleep, 2)
351dc15686d2d289866234948689a338891068faef2Keun Soo Yim
352dc15686d2d289866234948689a338891068faef2Keun Soo Yim        finished, pending = futures.wait(
353dc15686d2d289866234948689a338891068faef2Keun Soo Yim                 [EXCEPTION_FUTURE, future1],
354dc15686d2d289866234948689a338891068faef2Keun Soo Yim                 return_when=futures.FIRST_EXCEPTION)
355dc15686d2d289866234948689a338891068faef2Keun Soo Yim
356dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertEqual(set([EXCEPTION_FUTURE]), finished)
357dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertEqual(set([future1]), pending)
358dc15686d2d289866234948689a338891068faef2Keun Soo Yim
359dc15686d2d289866234948689a338891068faef2Keun Soo Yim    def test_all_completed(self):
360dc15686d2d289866234948689a338891068faef2Keun Soo Yim        future1 = self.executor.submit(divmod, 2, 0)
361dc15686d2d289866234948689a338891068faef2Keun Soo Yim        future2 = self.executor.submit(mul, 2, 21)
362dc15686d2d289866234948689a338891068faef2Keun Soo Yim
363dc15686d2d289866234948689a338891068faef2Keun Soo Yim        finished, pending = futures.wait(
364dc15686d2d289866234948689a338891068faef2Keun Soo Yim                [SUCCESSFUL_FUTURE,
365dc15686d2d289866234948689a338891068faef2Keun Soo Yim                 CANCELLED_AND_NOTIFIED_FUTURE,
366dc15686d2d289866234948689a338891068faef2Keun Soo Yim                 EXCEPTION_FUTURE,
367dc15686d2d289866234948689a338891068faef2Keun Soo Yim                 future1,
368dc15686d2d289866234948689a338891068faef2Keun Soo Yim                 future2],
369dc15686d2d289866234948689a338891068faef2Keun Soo Yim                return_when=futures.ALL_COMPLETED)
370dc15686d2d289866234948689a338891068faef2Keun Soo Yim
371dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertEqual(set([SUCCESSFUL_FUTURE,
372dc15686d2d289866234948689a338891068faef2Keun Soo Yim                              CANCELLED_AND_NOTIFIED_FUTURE,
373dc15686d2d289866234948689a338891068faef2Keun Soo Yim                              EXCEPTION_FUTURE,
374dc15686d2d289866234948689a338891068faef2Keun Soo Yim                              future1,
375dc15686d2d289866234948689a338891068faef2Keun Soo Yim                              future2]), finished)
376dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertEqual(set(), pending)
377dc15686d2d289866234948689a338891068faef2Keun Soo Yim
378dc15686d2d289866234948689a338891068faef2Keun Soo Yim    def test_timeout(self):
379dc15686d2d289866234948689a338891068faef2Keun Soo Yim        future1 = self.executor.submit(mul, 6, 7)
380dc15686d2d289866234948689a338891068faef2Keun Soo Yim        future2 = self.executor.submit(time.sleep, 3)
381dc15686d2d289866234948689a338891068faef2Keun Soo Yim
382dc15686d2d289866234948689a338891068faef2Keun Soo Yim        finished, pending = futures.wait(
383dc15686d2d289866234948689a338891068faef2Keun Soo Yim                [CANCELLED_AND_NOTIFIED_FUTURE,
384dc15686d2d289866234948689a338891068faef2Keun Soo Yim                 EXCEPTION_FUTURE,
385dc15686d2d289866234948689a338891068faef2Keun Soo Yim                 SUCCESSFUL_FUTURE,
386dc15686d2d289866234948689a338891068faef2Keun Soo Yim                 future1, future2],
387dc15686d2d289866234948689a338891068faef2Keun Soo Yim                timeout=1.5,
388dc15686d2d289866234948689a338891068faef2Keun Soo Yim                return_when=futures.ALL_COMPLETED)
389dc15686d2d289866234948689a338891068faef2Keun Soo Yim
390dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertEqual(set([CANCELLED_AND_NOTIFIED_FUTURE,
391dc15686d2d289866234948689a338891068faef2Keun Soo Yim                              EXCEPTION_FUTURE,
392dc15686d2d289866234948689a338891068faef2Keun Soo Yim                              SUCCESSFUL_FUTURE,
393dc15686d2d289866234948689a338891068faef2Keun Soo Yim                              future1]), finished)
394dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertEqual(set([future2]), pending)
395dc15686d2d289866234948689a338891068faef2Keun Soo Yim
396dc15686d2d289866234948689a338891068faef2Keun Soo Yim
397dc15686d2d289866234948689a338891068faef2Keun Soo Yimclass ThreadPoolWaitTests(ThreadPoolMixin, WaitTests):
398dc15686d2d289866234948689a338891068faef2Keun Soo Yim
399dc15686d2d289866234948689a338891068faef2Keun Soo Yim    def test_pending_calls_race(self):
400dc15686d2d289866234948689a338891068faef2Keun Soo Yim        # Issue #14406: multi-threaded race condition when waiting on all
401dc15686d2d289866234948689a338891068faef2Keun Soo Yim        # futures.
402dc15686d2d289866234948689a338891068faef2Keun Soo Yim        event = threading.Event()
403dc15686d2d289866234948689a338891068faef2Keun Soo Yim        def future_func():
404dc15686d2d289866234948689a338891068faef2Keun Soo Yim            event.wait()
405dc15686d2d289866234948689a338891068faef2Keun Soo Yim        oldswitchinterval = sys.getcheckinterval()
406dc15686d2d289866234948689a338891068faef2Keun Soo Yim        sys.setcheckinterval(1)
407dc15686d2d289866234948689a338891068faef2Keun Soo Yim        try:
408dc15686d2d289866234948689a338891068faef2Keun Soo Yim            fs = set(self.executor.submit(future_func) for i in range(100))
409dc15686d2d289866234948689a338891068faef2Keun Soo Yim            event.set()
410dc15686d2d289866234948689a338891068faef2Keun Soo Yim            futures.wait(fs, return_when=futures.ALL_COMPLETED)
411dc15686d2d289866234948689a338891068faef2Keun Soo Yim        finally:
412dc15686d2d289866234948689a338891068faef2Keun Soo Yim            sys.setcheckinterval(oldswitchinterval)
413dc15686d2d289866234948689a338891068faef2Keun Soo Yim
414dc15686d2d289866234948689a338891068faef2Keun Soo Yim
415dc15686d2d289866234948689a338891068faef2Keun Soo Yimclass ProcessPoolWaitTests(ProcessPoolMixin, WaitTests):
416dc15686d2d289866234948689a338891068faef2Keun Soo Yim    pass
417dc15686d2d289866234948689a338891068faef2Keun Soo Yim
418dc15686d2d289866234948689a338891068faef2Keun Soo Yim
419dc15686d2d289866234948689a338891068faef2Keun Soo Yimclass AsCompletedTests(unittest.TestCase):
420dc15686d2d289866234948689a338891068faef2Keun Soo Yim    # TODO(brian@sweetapp.com): Should have a test with a non-zero timeout.
421dc15686d2d289866234948689a338891068faef2Keun Soo Yim    def test_no_timeout(self):
422dc15686d2d289866234948689a338891068faef2Keun Soo Yim        future1 = self.executor.submit(mul, 2, 21)
423dc15686d2d289866234948689a338891068faef2Keun Soo Yim        future2 = self.executor.submit(mul, 7, 6)
424dc15686d2d289866234948689a338891068faef2Keun Soo Yim
425dc15686d2d289866234948689a338891068faef2Keun Soo Yim        completed = set(futures.as_completed(
426dc15686d2d289866234948689a338891068faef2Keun Soo Yim                [CANCELLED_AND_NOTIFIED_FUTURE,
427dc15686d2d289866234948689a338891068faef2Keun Soo Yim                 EXCEPTION_FUTURE,
428dc15686d2d289866234948689a338891068faef2Keun Soo Yim                 SUCCESSFUL_FUTURE,
429dc15686d2d289866234948689a338891068faef2Keun Soo Yim                 future1, future2]))
430dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertEqual(set(
431dc15686d2d289866234948689a338891068faef2Keun Soo Yim                [CANCELLED_AND_NOTIFIED_FUTURE,
432dc15686d2d289866234948689a338891068faef2Keun Soo Yim                 EXCEPTION_FUTURE,
433dc15686d2d289866234948689a338891068faef2Keun Soo Yim                 SUCCESSFUL_FUTURE,
434dc15686d2d289866234948689a338891068faef2Keun Soo Yim                 future1, future2]),
435dc15686d2d289866234948689a338891068faef2Keun Soo Yim                completed)
436dc15686d2d289866234948689a338891068faef2Keun Soo Yim
437dc15686d2d289866234948689a338891068faef2Keun Soo Yim    def test_zero_timeout(self):
438dc15686d2d289866234948689a338891068faef2Keun Soo Yim        future1 = self.executor.submit(time.sleep, 2)
439dc15686d2d289866234948689a338891068faef2Keun Soo Yim        completed_futures = set()
440dc15686d2d289866234948689a338891068faef2Keun Soo Yim        try:
441dc15686d2d289866234948689a338891068faef2Keun Soo Yim            for future in futures.as_completed(
442dc15686d2d289866234948689a338891068faef2Keun Soo Yim                    [CANCELLED_AND_NOTIFIED_FUTURE,
443dc15686d2d289866234948689a338891068faef2Keun Soo Yim                     EXCEPTION_FUTURE,
444dc15686d2d289866234948689a338891068faef2Keun Soo Yim                     SUCCESSFUL_FUTURE,
445dc15686d2d289866234948689a338891068faef2Keun Soo Yim                     future1],
446dc15686d2d289866234948689a338891068faef2Keun Soo Yim                    timeout=0):
447dc15686d2d289866234948689a338891068faef2Keun Soo Yim                completed_futures.add(future)
448dc15686d2d289866234948689a338891068faef2Keun Soo Yim        except futures.TimeoutError:
449dc15686d2d289866234948689a338891068faef2Keun Soo Yim            pass
450dc15686d2d289866234948689a338891068faef2Keun Soo Yim
451dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertEqual(set([CANCELLED_AND_NOTIFIED_FUTURE,
452dc15686d2d289866234948689a338891068faef2Keun Soo Yim                              EXCEPTION_FUTURE,
453dc15686d2d289866234948689a338891068faef2Keun Soo Yim                              SUCCESSFUL_FUTURE]),
454dc15686d2d289866234948689a338891068faef2Keun Soo Yim                         completed_futures)
455dc15686d2d289866234948689a338891068faef2Keun Soo Yim
456dc15686d2d289866234948689a338891068faef2Keun Soo Yim    def test_duplicate_futures(self):
457dc15686d2d289866234948689a338891068faef2Keun Soo Yim        # Issue 20367. Duplicate futures should not raise exceptions or give
458dc15686d2d289866234948689a338891068faef2Keun Soo Yim        # duplicate responses.
459dc15686d2d289866234948689a338891068faef2Keun Soo Yim        future1 = self.executor.submit(time.sleep, 2)
460dc15686d2d289866234948689a338891068faef2Keun Soo Yim        completed = [f for f in futures.as_completed([future1,future1])]
461dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertEqual(len(completed), 1)
462dc15686d2d289866234948689a338891068faef2Keun Soo Yim
463dc15686d2d289866234948689a338891068faef2Keun Soo Yim
464dc15686d2d289866234948689a338891068faef2Keun Soo Yimclass ThreadPoolAsCompletedTests(ThreadPoolMixin, AsCompletedTests):
465dc15686d2d289866234948689a338891068faef2Keun Soo Yim    pass
466dc15686d2d289866234948689a338891068faef2Keun Soo Yim
467dc15686d2d289866234948689a338891068faef2Keun Soo Yim
468dc15686d2d289866234948689a338891068faef2Keun Soo Yimclass ProcessPoolAsCompletedTests(ProcessPoolMixin, AsCompletedTests):
469dc15686d2d289866234948689a338891068faef2Keun Soo Yim    pass
470dc15686d2d289866234948689a338891068faef2Keun Soo Yim
471dc15686d2d289866234948689a338891068faef2Keun Soo Yim
472dc15686d2d289866234948689a338891068faef2Keun Soo Yimclass ExecutorTest(unittest.TestCase):
473dc15686d2d289866234948689a338891068faef2Keun Soo Yim    # Executor.shutdown() and context manager usage is tested by
474dc15686d2d289866234948689a338891068faef2Keun Soo Yim    # ExecutorShutdownTest.
475dc15686d2d289866234948689a338891068faef2Keun Soo Yim    def test_submit(self):
476dc15686d2d289866234948689a338891068faef2Keun Soo Yim        future = self.executor.submit(pow, 2, 8)
477dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertEqual(256, future.result())
478dc15686d2d289866234948689a338891068faef2Keun Soo Yim
479dc15686d2d289866234948689a338891068faef2Keun Soo Yim    def test_submit_keyword(self):
480dc15686d2d289866234948689a338891068faef2Keun Soo Yim        future = self.executor.submit(mul, 2, y=8)
481dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertEqual(16, future.result())
482dc15686d2d289866234948689a338891068faef2Keun Soo Yim
483dc15686d2d289866234948689a338891068faef2Keun Soo Yim    def test_map(self):
484dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertEqual(
485dc15686d2d289866234948689a338891068faef2Keun Soo Yim                list(self.executor.map(pow, range(10), range(10))),
486dc15686d2d289866234948689a338891068faef2Keun Soo Yim                list(map(pow, range(10), range(10))))
487dc15686d2d289866234948689a338891068faef2Keun Soo Yim
488dc15686d2d289866234948689a338891068faef2Keun Soo Yim    def test_map_exception(self):
489dc15686d2d289866234948689a338891068faef2Keun Soo Yim        i = self.executor.map(divmod, [1, 1, 1, 1], [2, 3, 0, 5])
490dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertEqual(next(i), (0, 1))
491dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertEqual(next(i), (0, 1))
492dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertRaises(ZeroDivisionError, next, i)
493dc15686d2d289866234948689a338891068faef2Keun Soo Yim
494dc15686d2d289866234948689a338891068faef2Keun Soo Yim    def test_map_timeout(self):
495dc15686d2d289866234948689a338891068faef2Keun Soo Yim        results = []
496dc15686d2d289866234948689a338891068faef2Keun Soo Yim        try:
497dc15686d2d289866234948689a338891068faef2Keun Soo Yim            for i in self.executor.map(time.sleep,
498dc15686d2d289866234948689a338891068faef2Keun Soo Yim                                       [0, 0, 3],
499dc15686d2d289866234948689a338891068faef2Keun Soo Yim                                       timeout=1.5):
500dc15686d2d289866234948689a338891068faef2Keun Soo Yim                results.append(i)
501dc15686d2d289866234948689a338891068faef2Keun Soo Yim        except futures.TimeoutError:
502dc15686d2d289866234948689a338891068faef2Keun Soo Yim            pass
503dc15686d2d289866234948689a338891068faef2Keun Soo Yim        else:
504dc15686d2d289866234948689a338891068faef2Keun Soo Yim            self.fail('expected TimeoutError')
505dc15686d2d289866234948689a338891068faef2Keun Soo Yim
506dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertEqual([None, None], results)
507dc15686d2d289866234948689a338891068faef2Keun Soo Yim
508dc15686d2d289866234948689a338891068faef2Keun Soo Yim    def test_max_workers_negative(self):
509dc15686d2d289866234948689a338891068faef2Keun Soo Yim        for number in (0, -1):
510dc15686d2d289866234948689a338891068faef2Keun Soo Yim            with self.assertRaises(ValueError) as cm:
511dc15686d2d289866234948689a338891068faef2Keun Soo Yim                self.executor_type(max_workers=number)
512dc15686d2d289866234948689a338891068faef2Keun Soo Yim
513dc15686d2d289866234948689a338891068faef2Keun Soo Yim            assert str(cm.exception) == "max_workers must be greater than 0"
514dc15686d2d289866234948689a338891068faef2Keun Soo Yim
515dc15686d2d289866234948689a338891068faef2Keun Soo Yim
516dc15686d2d289866234948689a338891068faef2Keun Soo Yimclass ThreadPoolExecutorTest(ThreadPoolMixin, ExecutorTest):
517dc15686d2d289866234948689a338891068faef2Keun Soo Yim    def test_map_submits_without_iteration(self):
518dc15686d2d289866234948689a338891068faef2Keun Soo Yim        """Tests verifying issue 11777."""
519dc15686d2d289866234948689a338891068faef2Keun Soo Yim        finished = []
520dc15686d2d289866234948689a338891068faef2Keun Soo Yim        def record_finished(n):
521dc15686d2d289866234948689a338891068faef2Keun Soo Yim            finished.append(n)
522dc15686d2d289866234948689a338891068faef2Keun Soo Yim
523dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.executor.map(record_finished, range(10))
524dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.executor.shutdown(wait=True)
525dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertEqual(len(finished), 10)
526dc15686d2d289866234948689a338891068faef2Keun Soo Yim
527dc15686d2d289866234948689a338891068faef2Keun Soo Yim    def test_default_workers(self):
528dc15686d2d289866234948689a338891068faef2Keun Soo Yim        executor = self.executor_type()
529dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertEqual(executor._max_workers,
530dc15686d2d289866234948689a338891068faef2Keun Soo Yim                         (cpu_count() or 1) * 5)
531dc15686d2d289866234948689a338891068faef2Keun Soo Yim
532dc15686d2d289866234948689a338891068faef2Keun Soo Yim
533dc15686d2d289866234948689a338891068faef2Keun Soo Yimclass ProcessPoolExecutorTest(ProcessPoolMixin, ExecutorTest):
534dc15686d2d289866234948689a338891068faef2Keun Soo Yim    pass
535dc15686d2d289866234948689a338891068faef2Keun Soo Yim
536dc15686d2d289866234948689a338891068faef2Keun Soo Yim
537dc15686d2d289866234948689a338891068faef2Keun Soo Yimclass FutureTests(unittest.TestCase):
538dc15686d2d289866234948689a338891068faef2Keun Soo Yim    def test_done_callback_with_result(self):
539dc15686d2d289866234948689a338891068faef2Keun Soo Yim        callback_result = [None]
540dc15686d2d289866234948689a338891068faef2Keun Soo Yim        def fn(callback_future):
541dc15686d2d289866234948689a338891068faef2Keun Soo Yim            callback_result[0] = callback_future.result()
542dc15686d2d289866234948689a338891068faef2Keun Soo Yim
543dc15686d2d289866234948689a338891068faef2Keun Soo Yim        f = Future()
544dc15686d2d289866234948689a338891068faef2Keun Soo Yim        f.add_done_callback(fn)
545dc15686d2d289866234948689a338891068faef2Keun Soo Yim        f.set_result(5)
546dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertEqual(5, callback_result[0])
547dc15686d2d289866234948689a338891068faef2Keun Soo Yim
548dc15686d2d289866234948689a338891068faef2Keun Soo Yim    def test_done_callback_with_exception(self):
549dc15686d2d289866234948689a338891068faef2Keun Soo Yim        callback_exception = [None]
550dc15686d2d289866234948689a338891068faef2Keun Soo Yim        def fn(callback_future):
551dc15686d2d289866234948689a338891068faef2Keun Soo Yim            callback_exception[0] = callback_future.exception()
552dc15686d2d289866234948689a338891068faef2Keun Soo Yim
553dc15686d2d289866234948689a338891068faef2Keun Soo Yim        f = Future()
554dc15686d2d289866234948689a338891068faef2Keun Soo Yim        f.add_done_callback(fn)
555dc15686d2d289866234948689a338891068faef2Keun Soo Yim        f.set_exception(Exception('test'))
556dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertEqual(('test',), callback_exception[0].args)
557dc15686d2d289866234948689a338891068faef2Keun Soo Yim
558dc15686d2d289866234948689a338891068faef2Keun Soo Yim    def test_done_callback_with_cancel(self):
559dc15686d2d289866234948689a338891068faef2Keun Soo Yim        was_cancelled = [None]
560dc15686d2d289866234948689a338891068faef2Keun Soo Yim        def fn(callback_future):
561dc15686d2d289866234948689a338891068faef2Keun Soo Yim            was_cancelled[0] = callback_future.cancelled()
562dc15686d2d289866234948689a338891068faef2Keun Soo Yim
563dc15686d2d289866234948689a338891068faef2Keun Soo Yim        f = Future()
564dc15686d2d289866234948689a338891068faef2Keun Soo Yim        f.add_done_callback(fn)
565dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertTrue(f.cancel())
566dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertTrue(was_cancelled[0])
567dc15686d2d289866234948689a338891068faef2Keun Soo Yim
568dc15686d2d289866234948689a338891068faef2Keun Soo Yim    def test_done_callback_raises(self):
569dc15686d2d289866234948689a338891068faef2Keun Soo Yim        with captured_stderr() as stderr:
570dc15686d2d289866234948689a338891068faef2Keun Soo Yim            raising_was_called = [False]
571dc15686d2d289866234948689a338891068faef2Keun Soo Yim            raising_old_style_was_called = [False]
572dc15686d2d289866234948689a338891068faef2Keun Soo Yim            fn_was_called = [False]
573dc15686d2d289866234948689a338891068faef2Keun Soo Yim
574dc15686d2d289866234948689a338891068faef2Keun Soo Yim            def raising_fn(callback_future):
575dc15686d2d289866234948689a338891068faef2Keun Soo Yim                raising_was_called[0] = True
576dc15686d2d289866234948689a338891068faef2Keun Soo Yim                raise Exception('doh!')
577dc15686d2d289866234948689a338891068faef2Keun Soo Yim
578dc15686d2d289866234948689a338891068faef2Keun Soo Yim            def raising_old_style_fn(callback_future):
579dc15686d2d289866234948689a338891068faef2Keun Soo Yim                raising_old_style_was_called[0] = True
580dc15686d2d289866234948689a338891068faef2Keun Soo Yim                class OldStyle:  # Does not inherit from object
581dc15686d2d289866234948689a338891068faef2Keun Soo Yim                   def __str__(self):
582dc15686d2d289866234948689a338891068faef2Keun Soo Yim                       return 'doh!'
583dc15686d2d289866234948689a338891068faef2Keun Soo Yim                raise OldStyle()
584dc15686d2d289866234948689a338891068faef2Keun Soo Yim
585dc15686d2d289866234948689a338891068faef2Keun Soo Yim            def fn(callback_future):
586dc15686d2d289866234948689a338891068faef2Keun Soo Yim                fn_was_called[0] = True
587dc15686d2d289866234948689a338891068faef2Keun Soo Yim
588dc15686d2d289866234948689a338891068faef2Keun Soo Yim            f = Future()
589dc15686d2d289866234948689a338891068faef2Keun Soo Yim            f.add_done_callback(raising_fn)
590dc15686d2d289866234948689a338891068faef2Keun Soo Yim            f.add_done_callback(raising_old_style_fn)
591dc15686d2d289866234948689a338891068faef2Keun Soo Yim            f.add_done_callback(fn)
592dc15686d2d289866234948689a338891068faef2Keun Soo Yim            f.set_result(5)
593dc15686d2d289866234948689a338891068faef2Keun Soo Yim            self.assertTrue(raising_was_called)
594dc15686d2d289866234948689a338891068faef2Keun Soo Yim            self.assertTrue(raising_old_style_was_called)
595dc15686d2d289866234948689a338891068faef2Keun Soo Yim            self.assertTrue(fn_was_called)
596dc15686d2d289866234948689a338891068faef2Keun Soo Yim            self.assertIn('Exception: doh!', stderr.getvalue())
597dc15686d2d289866234948689a338891068faef2Keun Soo Yim            self.assertIn('OldStyle: doh!', stderr.getvalue())
598dc15686d2d289866234948689a338891068faef2Keun Soo Yim
599dc15686d2d289866234948689a338891068faef2Keun Soo Yim    def test_done_callback_already_successful(self):
600dc15686d2d289866234948689a338891068faef2Keun Soo Yim        callback_result = [None]
601dc15686d2d289866234948689a338891068faef2Keun Soo Yim        def fn(callback_future):
602dc15686d2d289866234948689a338891068faef2Keun Soo Yim            callback_result[0] = callback_future.result()
603dc15686d2d289866234948689a338891068faef2Keun Soo Yim
604dc15686d2d289866234948689a338891068faef2Keun Soo Yim        f = Future()
605dc15686d2d289866234948689a338891068faef2Keun Soo Yim        f.set_result(5)
606dc15686d2d289866234948689a338891068faef2Keun Soo Yim        f.add_done_callback(fn)
607dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertEqual(5, callback_result[0])
608dc15686d2d289866234948689a338891068faef2Keun Soo Yim
609dc15686d2d289866234948689a338891068faef2Keun Soo Yim    def test_done_callback_already_failed(self):
610dc15686d2d289866234948689a338891068faef2Keun Soo Yim        callback_exception = [None]
611dc15686d2d289866234948689a338891068faef2Keun Soo Yim        def fn(callback_future):
612dc15686d2d289866234948689a338891068faef2Keun Soo Yim            callback_exception[0] = callback_future.exception()
613dc15686d2d289866234948689a338891068faef2Keun Soo Yim
614dc15686d2d289866234948689a338891068faef2Keun Soo Yim        f = Future()
615dc15686d2d289866234948689a338891068faef2Keun Soo Yim        f.set_exception(Exception('test'))
616dc15686d2d289866234948689a338891068faef2Keun Soo Yim        f.add_done_callback(fn)
617dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertEqual(('test',), callback_exception[0].args)
618dc15686d2d289866234948689a338891068faef2Keun Soo Yim
619dc15686d2d289866234948689a338891068faef2Keun Soo Yim    def test_done_callback_already_cancelled(self):
620dc15686d2d289866234948689a338891068faef2Keun Soo Yim        was_cancelled = [None]
621dc15686d2d289866234948689a338891068faef2Keun Soo Yim        def fn(callback_future):
622dc15686d2d289866234948689a338891068faef2Keun Soo Yim            was_cancelled[0] = callback_future.cancelled()
623dc15686d2d289866234948689a338891068faef2Keun Soo Yim
624dc15686d2d289866234948689a338891068faef2Keun Soo Yim        f = Future()
625dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertTrue(f.cancel())
626dc15686d2d289866234948689a338891068faef2Keun Soo Yim        f.add_done_callback(fn)
627dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertTrue(was_cancelled[0])
628dc15686d2d289866234948689a338891068faef2Keun Soo Yim
629dc15686d2d289866234948689a338891068faef2Keun Soo Yim    def test_repr(self):
630dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertRegexpMatches(repr(PENDING_FUTURE),
631dc15686d2d289866234948689a338891068faef2Keun Soo Yim                                 '<Future at 0x[0-9a-f]+L? state=pending>')
632dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertRegexpMatches(repr(RUNNING_FUTURE),
633dc15686d2d289866234948689a338891068faef2Keun Soo Yim                                 '<Future at 0x[0-9a-f]+L? state=running>')
634dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertRegexpMatches(repr(CANCELLED_FUTURE),
635dc15686d2d289866234948689a338891068faef2Keun Soo Yim                                 '<Future at 0x[0-9a-f]+L? state=cancelled>')
636dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertRegexpMatches(repr(CANCELLED_AND_NOTIFIED_FUTURE),
637dc15686d2d289866234948689a338891068faef2Keun Soo Yim                                 '<Future at 0x[0-9a-f]+L? state=cancelled>')
638dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertRegexpMatches(
639dc15686d2d289866234948689a338891068faef2Keun Soo Yim                repr(EXCEPTION_FUTURE),
640dc15686d2d289866234948689a338891068faef2Keun Soo Yim                '<Future at 0x[0-9a-f]+L? state=finished raised IOError>')
641dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertRegexpMatches(
642dc15686d2d289866234948689a338891068faef2Keun Soo Yim                repr(SUCCESSFUL_FUTURE),
643dc15686d2d289866234948689a338891068faef2Keun Soo Yim                '<Future at 0x[0-9a-f]+L? state=finished returned int>')
644dc15686d2d289866234948689a338891068faef2Keun Soo Yim
645dc15686d2d289866234948689a338891068faef2Keun Soo Yim    def test_cancel(self):
646dc15686d2d289866234948689a338891068faef2Keun Soo Yim        f1 = create_future(state=PENDING)
647dc15686d2d289866234948689a338891068faef2Keun Soo Yim        f2 = create_future(state=RUNNING)
648dc15686d2d289866234948689a338891068faef2Keun Soo Yim        f3 = create_future(state=CANCELLED)
649dc15686d2d289866234948689a338891068faef2Keun Soo Yim        f4 = create_future(state=CANCELLED_AND_NOTIFIED)
650dc15686d2d289866234948689a338891068faef2Keun Soo Yim        f5 = create_future(state=FINISHED, exception=IOError())
651dc15686d2d289866234948689a338891068faef2Keun Soo Yim        f6 = create_future(state=FINISHED, result=5)
652dc15686d2d289866234948689a338891068faef2Keun Soo Yim
653dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertTrue(f1.cancel())
654dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertEqual(f1._state, CANCELLED)
655dc15686d2d289866234948689a338891068faef2Keun Soo Yim
656dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertFalse(f2.cancel())
657dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertEqual(f2._state, RUNNING)
658dc15686d2d289866234948689a338891068faef2Keun Soo Yim
659dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertTrue(f3.cancel())
660dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertEqual(f3._state, CANCELLED)
661dc15686d2d289866234948689a338891068faef2Keun Soo Yim
662dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertTrue(f4.cancel())
663dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertEqual(f4._state, CANCELLED_AND_NOTIFIED)
664dc15686d2d289866234948689a338891068faef2Keun Soo Yim
665dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertFalse(f5.cancel())
666dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertEqual(f5._state, FINISHED)
667dc15686d2d289866234948689a338891068faef2Keun Soo Yim
668dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertFalse(f6.cancel())
669dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertEqual(f6._state, FINISHED)
670dc15686d2d289866234948689a338891068faef2Keun Soo Yim
671dc15686d2d289866234948689a338891068faef2Keun Soo Yim    def test_cancelled(self):
672dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertFalse(PENDING_FUTURE.cancelled())
673dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertFalse(RUNNING_FUTURE.cancelled())
674dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertTrue(CANCELLED_FUTURE.cancelled())
675dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertTrue(CANCELLED_AND_NOTIFIED_FUTURE.cancelled())
676dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertFalse(EXCEPTION_FUTURE.cancelled())
677dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertFalse(SUCCESSFUL_FUTURE.cancelled())
678dc15686d2d289866234948689a338891068faef2Keun Soo Yim
679dc15686d2d289866234948689a338891068faef2Keun Soo Yim    def test_done(self):
680dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertFalse(PENDING_FUTURE.done())
681dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertFalse(RUNNING_FUTURE.done())
682dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertTrue(CANCELLED_FUTURE.done())
683dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertTrue(CANCELLED_AND_NOTIFIED_FUTURE.done())
684dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertTrue(EXCEPTION_FUTURE.done())
685dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertTrue(SUCCESSFUL_FUTURE.done())
686dc15686d2d289866234948689a338891068faef2Keun Soo Yim
687dc15686d2d289866234948689a338891068faef2Keun Soo Yim    def test_running(self):
688dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertFalse(PENDING_FUTURE.running())
689dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertTrue(RUNNING_FUTURE.running())
690dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertFalse(CANCELLED_FUTURE.running())
691dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertFalse(CANCELLED_AND_NOTIFIED_FUTURE.running())
692dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertFalse(EXCEPTION_FUTURE.running())
693dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertFalse(SUCCESSFUL_FUTURE.running())
694dc15686d2d289866234948689a338891068faef2Keun Soo Yim
695dc15686d2d289866234948689a338891068faef2Keun Soo Yim    def test_result_with_timeout(self):
696dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertRaises(futures.TimeoutError,
697dc15686d2d289866234948689a338891068faef2Keun Soo Yim                          PENDING_FUTURE.result, timeout=0)
698dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertRaises(futures.TimeoutError,
699dc15686d2d289866234948689a338891068faef2Keun Soo Yim                          RUNNING_FUTURE.result, timeout=0)
700dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertRaises(futures.CancelledError,
701dc15686d2d289866234948689a338891068faef2Keun Soo Yim                          CANCELLED_FUTURE.result, timeout=0)
702dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertRaises(futures.CancelledError,
703dc15686d2d289866234948689a338891068faef2Keun Soo Yim                          CANCELLED_AND_NOTIFIED_FUTURE.result, timeout=0)
704dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertRaises(IOError, EXCEPTION_FUTURE.result, timeout=0)
705dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertEqual(SUCCESSFUL_FUTURE.result(timeout=0), 42)
706dc15686d2d289866234948689a338891068faef2Keun Soo Yim
707dc15686d2d289866234948689a338891068faef2Keun Soo Yim    def test_result_with_success(self):
708dc15686d2d289866234948689a338891068faef2Keun Soo Yim        # TODO(brian@sweetapp.com): This test is timing dependant.
709dc15686d2d289866234948689a338891068faef2Keun Soo Yim        def notification():
710dc15686d2d289866234948689a338891068faef2Keun Soo Yim            # Wait until the main thread is waiting for the result.
711dc15686d2d289866234948689a338891068faef2Keun Soo Yim            time.sleep(1)
712dc15686d2d289866234948689a338891068faef2Keun Soo Yim            f1.set_result(42)
713dc15686d2d289866234948689a338891068faef2Keun Soo Yim
714dc15686d2d289866234948689a338891068faef2Keun Soo Yim        f1 = create_future(state=PENDING)
715dc15686d2d289866234948689a338891068faef2Keun Soo Yim        t = threading.Thread(target=notification)
716dc15686d2d289866234948689a338891068faef2Keun Soo Yim        t.start()
717dc15686d2d289866234948689a338891068faef2Keun Soo Yim
718dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertEqual(f1.result(timeout=5), 42)
719dc15686d2d289866234948689a338891068faef2Keun Soo Yim
720dc15686d2d289866234948689a338891068faef2Keun Soo Yim    def test_result_with_cancel(self):
721dc15686d2d289866234948689a338891068faef2Keun Soo Yim        # TODO(brian@sweetapp.com): This test is timing dependant.
722dc15686d2d289866234948689a338891068faef2Keun Soo Yim        def notification():
723dc15686d2d289866234948689a338891068faef2Keun Soo Yim            # Wait until the main thread is waiting for the result.
724dc15686d2d289866234948689a338891068faef2Keun Soo Yim            time.sleep(1)
725dc15686d2d289866234948689a338891068faef2Keun Soo Yim            f1.cancel()
726dc15686d2d289866234948689a338891068faef2Keun Soo Yim
727dc15686d2d289866234948689a338891068faef2Keun Soo Yim        f1 = create_future(state=PENDING)
728dc15686d2d289866234948689a338891068faef2Keun Soo Yim        t = threading.Thread(target=notification)
729dc15686d2d289866234948689a338891068faef2Keun Soo Yim        t.start()
730dc15686d2d289866234948689a338891068faef2Keun Soo Yim
731dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertRaises(futures.CancelledError, f1.result, timeout=5)
732dc15686d2d289866234948689a338891068faef2Keun Soo Yim
733dc15686d2d289866234948689a338891068faef2Keun Soo Yim    def test_exception_with_timeout(self):
734dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertRaises(futures.TimeoutError,
735dc15686d2d289866234948689a338891068faef2Keun Soo Yim                          PENDING_FUTURE.exception, timeout=0)
736dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertRaises(futures.TimeoutError,
737dc15686d2d289866234948689a338891068faef2Keun Soo Yim                          RUNNING_FUTURE.exception, timeout=0)
738dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertRaises(futures.CancelledError,
739dc15686d2d289866234948689a338891068faef2Keun Soo Yim                          CANCELLED_FUTURE.exception, timeout=0)
740dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertRaises(futures.CancelledError,
741dc15686d2d289866234948689a338891068faef2Keun Soo Yim                          CANCELLED_AND_NOTIFIED_FUTURE.exception, timeout=0)
742dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertTrue(isinstance(EXCEPTION_FUTURE.exception(timeout=0),
743dc15686d2d289866234948689a338891068faef2Keun Soo Yim                                   IOError))
744dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertEqual(SUCCESSFUL_FUTURE.exception(timeout=0), None)
745dc15686d2d289866234948689a338891068faef2Keun Soo Yim
746dc15686d2d289866234948689a338891068faef2Keun Soo Yim    def test_exception_with_success(self):
747dc15686d2d289866234948689a338891068faef2Keun Soo Yim        def notification():
748dc15686d2d289866234948689a338891068faef2Keun Soo Yim            # Wait until the main thread is waiting for the exception.
749dc15686d2d289866234948689a338891068faef2Keun Soo Yim            time.sleep(1)
750dc15686d2d289866234948689a338891068faef2Keun Soo Yim            with f1._condition:
751dc15686d2d289866234948689a338891068faef2Keun Soo Yim                f1._state = FINISHED
752dc15686d2d289866234948689a338891068faef2Keun Soo Yim                f1._exception = IOError()
753dc15686d2d289866234948689a338891068faef2Keun Soo Yim                f1._condition.notify_all()
754dc15686d2d289866234948689a338891068faef2Keun Soo Yim
755dc15686d2d289866234948689a338891068faef2Keun Soo Yim        f1 = create_future(state=PENDING)
756dc15686d2d289866234948689a338891068faef2Keun Soo Yim        t = threading.Thread(target=notification)
757dc15686d2d289866234948689a338891068faef2Keun Soo Yim        t.start()
758dc15686d2d289866234948689a338891068faef2Keun Soo Yim
759dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertTrue(isinstance(f1.exception(timeout=5), IOError))
760dc15686d2d289866234948689a338891068faef2Keun Soo Yim
761dc15686d2d289866234948689a338891068faef2Keun Soo Yim    def test_old_style_exception(self):
762dc15686d2d289866234948689a338891068faef2Keun Soo Yim        class OldStyle:  # Does not inherit from object
763dc15686d2d289866234948689a338891068faef2Keun Soo Yim            def  __str__(self):
764dc15686d2d289866234948689a338891068faef2Keun Soo Yim                return 'doh!'
765dc15686d2d289866234948689a338891068faef2Keun Soo Yim        callback_exc_info = [None]
766dc15686d2d289866234948689a338891068faef2Keun Soo Yim        def fn(callback_future):
767dc15686d2d289866234948689a338891068faef2Keun Soo Yim            callback_exc_info[0] = callback_future.exception_info()
768dc15686d2d289866234948689a338891068faef2Keun Soo Yim        f = Future()
769dc15686d2d289866234948689a338891068faef2Keun Soo Yim        f.add_done_callback(fn)
770dc15686d2d289866234948689a338891068faef2Keun Soo Yim        try:
771dc15686d2d289866234948689a338891068faef2Keun Soo Yim            raise OldStyle()
772dc15686d2d289866234948689a338891068faef2Keun Soo Yim        except OldStyle:
773dc15686d2d289866234948689a338891068faef2Keun Soo Yim            want_exc_info = sys.exc_info()
774dc15686d2d289866234948689a338891068faef2Keun Soo Yim            f.set_exception_info(*want_exc_info[1:])
775dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertEqual(f.exception_info(), want_exc_info[1:])
776dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertEqual(callback_exc_info[0], want_exc_info[1:])
777dc15686d2d289866234948689a338891068faef2Keun Soo Yim        try:
778dc15686d2d289866234948689a338891068faef2Keun Soo Yim            f.result()
779dc15686d2d289866234948689a338891068faef2Keun Soo Yim        except OldStyle:
780dc15686d2d289866234948689a338891068faef2Keun Soo Yim            got_exc_info = sys.exc_info()
781dc15686d2d289866234948689a338891068faef2Keun Soo Yim        else:
782dc15686d2d289866234948689a338891068faef2Keun Soo Yim            self.fail('OldStyle exception not raised')
783dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertEqual(got_exc_info[:2], want_exc_info[:2])
784dc15686d2d289866234948689a338891068faef2Keun Soo Yim        got_tb = traceback.extract_tb(got_exc_info[2])
785dc15686d2d289866234948689a338891068faef2Keun Soo Yim        want_tb = traceback.extract_tb(want_exc_info[2])
786dc15686d2d289866234948689a338891068faef2Keun Soo Yim        self.assertEqual(got_tb[-len(want_tb):], want_tb)
787dc15686d2d289866234948689a338891068faef2Keun Soo Yim
788dc15686d2d289866234948689a338891068faef2Keun Soo Yim@reap_threads
789dc15686d2d289866234948689a338891068faef2Keun Soo Yimdef test_main():
790dc15686d2d289866234948689a338891068faef2Keun Soo Yim    try:
791dc15686d2d289866234948689a338891068faef2Keun Soo Yim        test_support.run_unittest(ProcessPoolExecutorTest,
792dc15686d2d289866234948689a338891068faef2Keun Soo Yim                                  ThreadPoolExecutorTest,
793dc15686d2d289866234948689a338891068faef2Keun Soo Yim                                  ProcessPoolWaitTests,
794dc15686d2d289866234948689a338891068faef2Keun Soo Yim                                  ThreadPoolWaitTests,
795dc15686d2d289866234948689a338891068faef2Keun Soo Yim                                  ProcessPoolAsCompletedTests,
796dc15686d2d289866234948689a338891068faef2Keun Soo Yim                                  ThreadPoolAsCompletedTests,
797dc15686d2d289866234948689a338891068faef2Keun Soo Yim                                  FutureTests,
798dc15686d2d289866234948689a338891068faef2Keun Soo Yim                                  ProcessPoolShutdownTest,
799dc15686d2d289866234948689a338891068faef2Keun Soo Yim                                  ThreadPoolShutdownTest)
800dc15686d2d289866234948689a338891068faef2Keun Soo Yim    finally:
801dc15686d2d289866234948689a338891068faef2Keun Soo Yim        test_support.reap_children()
802dc15686d2d289866234948689a338891068faef2Keun Soo Yim
803dc15686d2d289866234948689a338891068faef2Keun Soo Yimif __name__ == "__main__":
804dc15686d2d289866234948689a338891068faef2Keun Soo Yim    test_main()
805