from collections import namedtuple
import contextlib
import sys
from textwrap import dedent
import threading
import time
import unittest

from test.support import import_helper

_channels = import_helper.import_module('_interpchannels')
from concurrent.interpreters import _crossinterp
from test.test__interpreters import (
    _interpreters,
    _run_output,
    clean_up_interpreters,
)


REPLACE = _crossinterp._UNBOUND_CONSTANT_TO_FLAG[_crossinterp.UNBOUND]


# Additional tests are found in Lib/test/test_interpreters/test_channels.py.
# New tests should be added there.
# XXX The tests here should be moved there.  See the note under LowLevelTests.


##################################
# helpers

def recv_wait(cid):
    while True:
        try:
            obj, unboundop = _channels.recv(cid)
        except _channels.ChannelEmptyError:
            time.sleep(0.1)
        else:
            assert unboundop is None, repr(unboundop)
            return obj


def recv_nowait(cid, *args, unbound=False):
    obj, unboundop = _channels.recv(cid, *args)
    assert (unboundop is None) != unbound, repr(unboundop)
    return obj


#@contextmanager
#def run_threaded(id, source, **shared):
#    def run():
#        run_interp(id, source, **shared)
#    t = threading.Thread(target=run)
#    t.start()
#    yield
#    t.join()


def run_interp(id, source, **shared):
    _run_interp(id, source, shared)


def _run_interp(id, source, shared, _mainns={}):
    source = dedent(source)
    main, *_ = _interpreters.get_main()
    if main == id:
        cur, *_ = _interpreters.get_current()
        if cur != main:
            raise RuntimeError
        # XXX Run a func?
        exec(source, _mainns)
    else:
        _interpreters.run_string(id, source, shared)


class Interpreter(namedtuple('Interpreter', 'name id')):

    @classmethod
    def from_raw(cls, raw):
        if isinstance(raw, cls):
            return raw
        elif isinstance(raw, str):
            return cls(raw)
        else:
            raise NotImplementedError

    def __new__(cls, name=None, id=None):
        main, *_ = _interpreters.get_main()
        if id == main:
            if not name:
                name = 'main'
            elif name != 'main':
                raise ValueError(
                    'name mismatch (expected "main", got "{}")'.format(name))
            id = main
        elif id is not None:
            if not name:
                name = 'interp'
            elif name == 'main':
                raise ValueError('name mismatch (unexpected "main")')
            assert isinstance(id, int), repr(id)
        elif not name or name == 'main':
            name = 'main'
            id = main
        else:
            id = _interpreters.create()
        self = super().__new__(cls, name, id)
        return self


# XXX expect_channel_closed() is unnecessary once we improve exc propagation.

@contextlib.contextmanager
def expect_channel_closed():
    try:
        yield
    except _channels.ChannelClosedError:
        pass
    else:
        assert False, 'channel not closed'


class ChannelAction(namedtuple('ChannelAction', 'action end interp')):

    def __new__(cls, action, end=None, interp=None):
        if not end:
            end = 'both'
        if not interp:
            interp = 'main'
        self = super().__new__(cls, action, end, interp)
        return self

    def __init__(self, *args, **kwargs):
        if self.action == 'use':
            if self.end not in ('same', 'opposite', 'send', 'recv'):
                raise ValueError(self.end)
        elif self.action in ('close', 'force-close'):
            if self.end not in ('both', 'same', 'opposite', 'send', 'recv'):
                raise ValueError(self.end)
        else:
            raise ValueError(self.action)
        if self.interp not in ('main', 'same', 'other', 'extra'):
            raise ValueError(self.interp)

    def resolve_end(self, end):
        if self.end == 'same':
            return end
        elif self.end == 'opposite':
            return 'recv' if end == 'send' else 'send'
        else:
            return self.end

    def resolve_interp(self, interp, other, extra):
        if self.interp == 'same':
            return interp
        elif self.interp == 'other':
            if other is None:
                raise RuntimeError
            return other
        elif self.interp == 'extra':
            if extra is None:
                raise RuntimeError
            return extra
        elif self.interp == 'main':
            if interp.name == 'main':
                return interp
            elif other and other.name == 'main':
                return other
            else:
                raise RuntimeError
        # Per __init__(), there aren't any others.


class ChannelState(namedtuple('ChannelState', 'pending closed')):

    def __new__(cls, pending=0, *, closed=False):
        self = super().__new__(cls, pending, closed)
        return self

    def incr(self):
        return type(self)(self.pending + 1, closed=self.closed)

    def decr(self):
        return type(self)(self.pending - 1, closed=self.closed)

    def close(self, *, force=True):
        if self.closed:
            if not force or self.pending == 0:
                return self
        return type(self)(0 if force else self.pending, closed=True)


def run_action(cid, action, end, state, *, hideclosed=True):
    if state.closed:
        if action == 'use' and end == 'recv' and state.pending:
            expectfail = False
        else:
            expectfail = True
    else:
        expectfail = False

    try:
        result = _run_action(cid, action, end, state)
    except _channels.ChannelClosedError:
        if not hideclosed and not expectfail:
            raise
        result = state.close()
    else:
        if expectfail:
            raise ...  # XXX
    return result


def _run_action(cid, action, end, state):
    if action == 'use':
        if end == 'send':
            _channels.send(cid, b'spam', blocking=False)
            return state.incr()
        elif end == 'recv':
            if not state.pending:
                try:
                    _channels.recv(cid)
                except _channels.ChannelEmptyError:
                    return state
                else:
                    raise Exception('expected ChannelEmptyError')
            else:
                recv_nowait(cid)
                return state.decr()
        else:
            raise ValueError(end)
    elif action == 'close':
        kwargs = {}
        if end in ('recv', 'send'):
            kwargs[end] = True
        _channels.close(cid, **kwargs)
        return state.close()
    elif action == 'force-close':
        kwargs = {
            'force': True,
            }
        if end in ('recv', 'send'):
            kwargs[end] = True
        _channels.close(cid, **kwargs)
        return state.close(force=True)
    else:
        raise ValueError(action)


def clean_up_channels():
    for cid, _, _ in _channels.list_all():
        try:
            _channels.destroy(cid)
        except _channels.ChannelNotFoundError:
            pass  # already destroyed


class TestBase(unittest.TestCase):

    def tearDown(self):
        clean_up_channels()
        clean_up_interpreters()


##################################
# channel tests

class ChannelIDTests(TestBase):

    def test_default_kwargs(self):
        cid = _channels._channel_id(10, force=True)

        self.assertEqual(int(cid), 10)
        self.assertEqual(cid.end, 'both')

    def test_with_kwargs(self):
        cid = _channels._channel_id(10, send=True, force=True)
        self.assertEqual(cid.end, 'send')

        cid = _channels._channel_id(10, send=True, recv=False, force=True)
        self.assertEqual(cid.end, 'send')

        cid = _channels._channel_id(10, recv=True, force=True)
        self.assertEqual(cid.end, 'recv')

        cid = _channels._channel_id(10, recv=True, send=False, force=True)
        self.assertEqual(cid.end, 'recv')

        cid = _channels._channel_id(10, send=True, recv=True, force=True)
        self.assertEqual(cid.end, 'both')

    def test_coerce_id(self):
        class Int(str):
            def __index__(self):
                return 10

        cid = _channels._channel_id(Int(), force=True)
        self.assertEqual(int(cid), 10)

    def test_bad_id(self):
        self.assertRaises(TypeError, _channels._channel_id, object())
        self.assertRaises(TypeError, _channels._channel_id, 10.0)
        self.assertRaises(TypeError, _channels._channel_id, '10')
        self.assertRaises(TypeError, _channels._channel_id, b'10')
        self.assertRaises(ValueError, _channels._channel_id, -1)
        self.assertRaises(OverflowError, _channels._channel_id, 2**64)

    def test_bad_kwargs(self):
        with self.assertRaises(ValueError):
            _channels._channel_id(10, send=False, recv=False)

    def test_does_not_exist(self):
        cid = _channels.create(REPLACE)
        with self.assertRaises(_channels.ChannelNotFoundError):
            _channels._channel_id(int(cid) + 1)  # unforced

    def test_str(self):
        cid = _channels._channel_id(10, force=True)
        self.assertEqual(str(cid), '10')

    def test_repr(self):
        cid = _channels._channel_id(10, force=True)
        self.assertEqual(repr(cid), 'ChannelID(10)')

        cid = _channels._channel_id(10, send=True, force=True)
        self.assertEqual(repr(cid), 'ChannelID(10, send=True)')

        cid = _channels._channel_id(10, recv=True, force=True)
        self.assertEqual(repr(cid), 'ChannelID(10, recv=True)')

        cid = _channels._channel_id(10, send=True, recv=True, force=True)
        self.assertEqual(repr(cid), 'ChannelID(10)')

    def test_equality(self):
        cid1 = _channels.create(REPLACE)
        cid2 = _channels._channel_id(int(cid1))
        cid3 = _channels.create(REPLACE)

        self.assertTrue(cid1 == cid1)
        self.assertTrue(cid1 == cid2)
        self.assertTrue(cid1 == int(cid1))
        self.assertTrue(int(cid1) == cid1)
        self.assertTrue(cid1 == float(int(cid1)))
        self.assertTrue(float(int(cid1)) == cid1)
        self.assertFalse(cid1 == float(int(cid1)) + 0.1)
        self.assertFalse(cid1 == str(int(cid1)))
        self.assertFalse(cid1 == 2**1000)
        self.assertFalse(cid1 == float('inf'))
        self.assertFalse(cid1 == 'spam')
        self.assertFalse(cid1 == cid3)

        self.assertFalse(cid1 != cid1)
        self.assertFalse(cid1 != cid2)
        self.assertTrue(cid1 != cid3)

    def test_shareable(self):
        chan = _channels.create(REPLACE)

        obj = _channels.create(REPLACE)
        _channels.send(chan, obj, blocking=False)
        got = recv_nowait(chan)

        self.assertEqual(got, obj)
        self.assertIs(type(got), type(obj))
        # XXX Check the following in the channel tests?
        #self.assertIsNot(got, obj)


class ChannelTests(TestBase):

    def test_create_cid(self):
        cid = _channels.create(REPLACE)
        self.assertIsInstance(cid, _channels.ChannelID)

    def test_sequential_ids(self):
        before = [cid for cid, _, _ in _channels.list_all()]
        id1 = _channels.create(REPLACE)
        id2 = _channels.create(REPLACE)
        id3 = _channels.create(REPLACE)
        after = [cid for cid, _, _ in _channels.list_all()]

        self.assertEqual(id2, int(id1) + 1)
        self.assertEqual(id3, int(id2) + 1)
        self.assertEqual(set(after) - set(before), {id1, id2, id3})

    def test_ids_global(self):
        id1 = _interpreters.create()
        out = _run_output(id1, dedent("""
            import _interpchannels as _channels
            cid = _channels.create(3)
            print(cid)
            """))
        cid1 = int(out.strip())

        id2 = _interpreters.create()
        out = _run_output(id2, dedent("""
            import _interpchannels as _channels
            cid = _channels.create(3)
            print(cid)
            """))
        cid2 = int(out.strip())

        self.assertEqual(cid2, int(cid1) + 1)

    def test_channel_list_interpreters_none(self):
        """Test listing interpreters for a channel with no associations."""
        # Test for channel with no associated _interpreters.
        cid = _channels.create(REPLACE)
        send_interps = _channels.list_interpreters(cid, send=True)
        recv_interps = _channels.list_interpreters(cid, send=False)
        self.assertEqual(send_interps, [])
        self.assertEqual(recv_interps, [])

    def test_channel_list_interpreters_basic(self):
        """Test basic listing channel _interpreters."""
        interp0, *_ = _interpreters.get_main()
        cid = _channels.create(REPLACE)
        _channels.send(cid, "send", blocking=False)
        # Test for a channel that has one end associated to an interpreter.
        send_interps = _channels.list_interpreters(cid, send=True)
        recv_interps = _channels.list_interpreters(cid, send=False)
        self.assertEqual(send_interps, [interp0])
        self.assertEqual(recv_interps, [])

        interp1 = _interpreters.create()
        _run_output(interp1, dedent(f"""
            import _interpchannels as _channels
            _channels.recv({cid})
            """))
        # Test for channel that has both ends associated to an interpreter.
        send_interps = _channels.list_interpreters(cid, send=True)
        recv_interps = _channels.list_interpreters(cid, send=False)
        self.assertEqual(send_interps, [interp0])
        self.assertEqual(recv_interps, [interp1])

    def test_channel_list_interpreters_multiple(self):
        """Test listing interpreters for a channel with many associations."""
        interp0, *_ = _interpreters.get_main()
        interp1 = _interpreters.create()
        interp2 = _interpreters.create()
        interp3 = _interpreters.create()
        cid = _channels.create(REPLACE)

        _channels.send(cid, "send", blocking=False)
        _run_output(interp1, dedent(f"""
            import _interpchannels as _channels
            _channels.send({cid}, "send", blocking=False)
            """))
        _run_output(interp2, dedent(f"""
            import _interpchannels as _channels
            _channels.recv({cid})
            """))
        _run_output(interp3, dedent(f"""
            import _interpchannels as _channels
            _channels.recv({cid})
            """))
        send_interps = _channels.list_interpreters(cid, send=True)
        recv_interps = _channels.list_interpreters(cid, send=False)
        self.assertEqual(set(send_interps), {interp0, interp1})
        self.assertEqual(set(recv_interps), {interp2, interp3})

    def test_channel_list_interpreters_destroyed(self):
        """Test listing channel interpreters with a destroyed interpreter."""
        interp0, *_ = _interpreters.get_main()
        interp1 = _interpreters.create()
        cid = _channels.create(REPLACE)
        _channels.send(cid, "send", blocking=False)
        _run_output(interp1, dedent(f"""
            import _interpchannels as _channels
            _channels.recv({cid})
            """))
        # Should be one interpreter associated with each end.
        send_interps = _channels.list_interpreters(cid, send=True)
        recv_interps = _channels.list_interpreters(cid, send=False)
        self.assertEqual(send_interps, [interp0])
        self.assertEqual(recv_interps, [interp1])

        _interpreters.destroy(interp1)
        # Destroyed interpreter should not be listed.
        send_interps = _channels.list_interpreters(cid, send=True)
        recv_interps = _channels.list_interpreters(cid, send=False)
        self.assertEqual(send_interps, [interp0])
        self.assertEqual(recv_interps, [])

    def test_channel_list_interpreters_released(self):
        """Test listing channel interpreters with a released channel."""
        # Set up one channel with main interpreter on the send end and two
        # subinterpreters on the receive end.
        interp0, *_ = _interpreters.get_main()
        interp1 = _interpreters.create()
        interp2 = _interpreters.create()
        cid = _channels.create(REPLACE)
        _channels.send(cid, "data", blocking=False)
        _run_output(interp1, dedent(f"""
            import _interpchannels as _channels
            _channels.recv({cid})
            """))
        _channels.send(cid, "data", blocking=False)
        _run_output(interp2, dedent(f"""
            import _interpchannels as _channels
            _channels.recv({cid})
            """))
        # Check the setup.
        send_interps = _channels.list_interpreters(cid, send=True)
        recv_interps = _channels.list_interpreters(cid, send=False)
        self.assertEqual(len(send_interps), 1)
        self.assertEqual(len(recv_interps), 2)

        # Release the main interpreter from the send end.
        _channels.release(cid, send=True)
        # Send end should have no associated _interpreters.
        send_interps = _channels.list_interpreters(cid, send=True)
        recv_interps = _channels.list_interpreters(cid, send=False)
        self.assertEqual(len(send_interps), 0)
        self.assertEqual(len(recv_interps), 2)

        # Release one of the subinterpreters from the receive end.
        _run_output(interp2, dedent(f"""
            import _interpchannels as _channels
            _channels.release({cid})
            """))
        # Receive end should have the released interpreter removed.
        send_interps = _channels.list_interpreters(cid, send=True)
        recv_interps = _channels.list_interpreters(cid, send=False)
        self.assertEqual(len(send_interps), 0)
        self.assertEqual(recv_interps, [interp1])

    def test_channel_list_interpreters_closed(self):
        """Test listing channel interpreters with a closed channel."""
        interp0, *_ = _interpreters.get_main()
        interp1 = _interpreters.create()
        cid = _channels.create(REPLACE)
        # Put something in the channel so that it's not empty.
        _channels.send(cid, "send", blocking=False)

        # Check initial state.
        send_interps = _channels.list_interpreters(cid, send=True)
        recv_interps = _channels.list_interpreters(cid, send=False)
        self.assertEqual(len(send_interps), 1)
        self.assertEqual(len(recv_interps), 0)

        # Force close the channel.
        _channels.close(cid, force=True)
        # Both ends should raise an error.
        with self.assertRaises(_channels.ChannelClosedError):
            _channels.list_interpreters(cid, send=True)
        with self.assertRaises(_channels.ChannelClosedError):
            _channels.list_interpreters(cid, send=False)

    def test_channel_list_interpreters_closed_send_end(self):
        """Test listing channel interpreters with a channel's send end closed."""
        interp0, *_ = _interpreters.get_main()
        interp1 = _interpreters.create()
        cid = _channels.create(REPLACE)
        # Put something in the channel so that it's not empty.
        _channels.send(cid, "send", blocking=False)

        # Check initial state.
        send_interps = _channels.list_interpreters(cid, send=True)
        recv_interps = _channels.list_interpreters(cid, send=False)
        self.assertEqual(len(send_interps), 1)
        self.assertEqual(len(recv_interps), 0)

        # Close the send end of the channel.
        _channels.close(cid, send=True)
        # Send end should raise an error.
        with self.assertRaises(_channels.ChannelClosedError):
            _channels.list_interpreters(cid, send=True)
        # Receive end should not be closed (since channel is not empty).
        recv_interps = _channels.list_interpreters(cid, send=False)
        self.assertEqual(len(recv_interps), 0)

        # Close the receive end of the channel from a subinterpreter.
        _run_output(interp1, dedent(f"""
            import _interpchannels as _channels
            _channels.close({cid}, force=True)
            """))
        return
        # Both ends should raise an error.
        with self.assertRaises(_channels.ChannelClosedError):
            _channels.list_interpreters(cid, send=True)
        with self.assertRaises(_channels.ChannelClosedError):
            _channels.list_interpreters(cid, send=False)

    def test_allowed_types(self):
        cid = _channels.create(REPLACE)
        objects = [
            None,
            'spam',
            b'spam',
            42,
        ]
        for obj in objects:
            with self.subTest(obj):
                _channels.send(cid, obj, blocking=False)
                got = recv_nowait(cid)

                self.assertEqual(got, obj)
                self.assertIs(type(got), type(obj))
                # XXX Check the following?
                #self.assertIsNot(got, obj)
                # XXX What about between interpreters?

    def test_run_string_arg_unresolved(self):
        cid = _channels.create(REPLACE)
        interp = _interpreters.create()

        _interpreters.set___main___attrs(interp, dict(cid=cid.send))
        out = _run_output(interp, dedent("""
            import _interpchannels as _channels
            print(cid.end)
            _channels.send(cid, b'spam', blocking=False)
            """))
        obj = recv_nowait(cid)

        self.assertEqual(obj, b'spam')
        self.assertEqual(out.strip(), 'send')

    # XXX For now there is no high-level channel into which the
    # sent channel ID can be converted...
    # Note: this test caused crashes on some buildbots (bpo-33615).
    @unittest.skip('disabled until high-level channels exist')
    def test_run_string_arg_resolved(self):
        cid = _channels.create(REPLACE)
        cid = _channels._channel_id(cid, _resolve=True)
        interp = _interpreters.create()

        out = _run_output(interp, dedent("""
            import _interpchannels as _channels
            print(chan.id.end)
            _channels.send(chan.id, b'spam', blocking=False)
            """),
            dict(chan=cid.send))
        obj = recv_nowait(cid)

        self.assertEqual(obj, b'spam')
        self.assertEqual(out.strip(), 'send')

    #-------------------
    # send/recv

    def test_send_recv_main(self):
        cid = _channels.create(REPLACE)
        orig = b'spam'
        _channels.send(cid, orig, blocking=False)
        obj = recv_nowait(cid)

        self.assertEqual(obj, orig)
        self.assertIsNot(obj, orig)

    def test_send_recv_same_interpreter(self):
        id1 = _interpreters.create()
        out = _run_output(id1, dedent("""
            import _interpchannels as _channels
            cid = _channels.create(REPLACE)
            orig = b'spam'
            _channels.send(cid, orig, blocking=False)
            obj, _ = _channels.recv(cid)
            assert obj is not orig
            assert obj == orig
            """))

    def test_send_recv_different_interpreters(self):
        cid = _channels.create(REPLACE)
        id1 = _interpreters.create()
        out = _run_output(id1, dedent(f"""
            import _interpchannels as _channels
            _channels.send({cid}, b'spam', blocking=False)
            """))
        obj = recv_nowait(cid)

        self.assertEqual(obj, b'spam')

    def test_send_recv_different_threads(self):
        cid = _channels.create(REPLACE)

        def f():
            obj = recv_wait(cid)
            _channels.send(cid, obj)
        t = threading.Thread(target=f)
        t.start()

        _channels.send(cid, b'spam')
        obj = recv_wait(cid)
        t.join()

        self.assertEqual(obj, b'spam')

    def test_send_recv_different_interpreters_and_threads(self):
        cid = _channels.create(REPLACE)
        id1 = _interpreters.create()
        out = None

        def f():
            nonlocal out
            out = _run_output(id1, dedent(f"""
                import time
                import _interpchannels as _channels
                while True:
                    try:
                        obj, _ = _channels.recv({cid})
                        break
                    except _channels.ChannelEmptyError:
                        time.sleep(0.1)
                assert(obj == b'spam')
                _channels.send({cid}, b'eggs')
                """))
        t = threading.Thread(target=f)
        t.start()

        _channels.send(cid, b'spam')
        obj = recv_wait(cid)
        t.join()

        self.assertEqual(obj, b'eggs')

    def test_send_not_found(self):
        with self.assertRaises(_channels.ChannelNotFoundError):
            _channels.send(10, b'spam')

    def test_recv_not_found(self):
        with self.assertRaises(_channels.ChannelNotFoundError):
            _channels.recv(10)

    def test_recv_empty(self):
        cid = _channels.create(REPLACE)
        with self.assertRaises(_channels.ChannelEmptyError):
            _channels.recv(cid)

    def test_recv_default(self):
        default = object()
        cid = _channels.create(REPLACE)
        obj1 = recv_nowait(cid, default)
        _channels.send(cid, None, blocking=False)
        _channels.send(cid, 1, blocking=False)
        _channels.send(cid, b'spam', blocking=False)
        _channels.send(cid, b'eggs', blocking=False)
        obj2 = recv_nowait(cid, default)
        obj3 = recv_nowait(cid, default)
        obj4 = recv_nowait(cid)
        obj5 = recv_nowait(cid, default)
        obj6 = recv_nowait(cid, default)

        self.assertIs(obj1, default)
        self.assertIs(obj2, None)
        self.assertEqual(obj3, 1)
        self.assertEqual(obj4, b'spam')
        self.assertEqual(obj5, b'eggs')
        self.assertIs(obj6, default)

    def test_recv_sending_interp_destroyed(self):
        with self.subTest('closed'):
            cid1 = _channels.create(REPLACE)
            interp = _interpreters.create()
            _interpreters.run_string(interp, dedent(f"""
                import _interpchannels as _channels
                _channels.send({cid1}, b'spam', blocking=False)
                """))
            _interpreters.destroy(interp)

            with self.assertRaisesRegex(RuntimeError,
                                        f'channel {cid1} is closed'):
                _channels.recv(cid1)
            del cid1
        with self.subTest('still open'):
            cid2 = _channels.create(REPLACE)
            interp = _interpreters.create()
            _interpreters.run_string(interp, dedent(f"""
                import _interpchannels as _channels
                _channels.send({cid2}, b'spam', blocking=False)
                """))
            _channels.send(cid2, b'eggs', blocking=False)
            _interpreters.destroy(interp)

            recv_nowait(cid2, unbound=True)
            recv_nowait(cid2, unbound=False)
            with self.assertRaisesRegex(RuntimeError,
                                        f'channel {cid2} is empty'):
                _channels.recv(cid2)
            del cid2

    #-------------------
    # send_buffer

    def test_send_buffer(self):
        buf = bytearray(b'spamspamspam')
        cid = _channels.create(REPLACE)
        _channels.send_buffer(cid, buf, blocking=False)
        obj = recv_nowait(cid)

        self.assertIsNot(obj, buf)
        self.assertIsInstance(obj, memoryview)
        self.assertEqual(obj, buf)

        buf[4:8] = b'eggs'
        self.assertEqual(obj, buf)
        obj[4:8] = b'ham.'
        self.assertEqual(obj, buf)

    #-------------------
    # send with waiting

    def build_send_waiter(self, obj, *, buffer=False):
        # We want a long enough sleep that send() actually has to wait.

        if buffer:
            send = _channels.send_buffer
        else:
            send = _channels.send

        cid = _channels.create(REPLACE)
        try:
            started = time.monotonic()
            send(cid, obj, blocking=False)
            stopped = time.monotonic()
            recv_nowait(cid)
        finally:
            _channels.destroy(cid)
        delay = stopped - started  # seconds
        delay *= 3

        def wait():
            time.sleep(delay)
        return wait

    def test_send_blocking_waiting(self):
        received = None
        obj = b'spam'
        wait = self.build_send_waiter(obj)
        cid = _channels.create(REPLACE)
        def f():
            nonlocal received
            wait()
            received = recv_wait(cid)
        t = threading.Thread(target=f)
        t.start()
        _channels.send(cid, obj, blocking=True)
        t.join()

        self.assertEqual(received, obj)

    def test_send_buffer_blocking_waiting(self):
        received = None
        obj = bytearray(b'spam')
        wait = self.build_send_waiter(obj, buffer=True)
        cid = _channels.create(REPLACE)
        def f():
            nonlocal received
            wait()
            received = recv_wait(cid)
        t = threading.Thread(target=f)
        t.start()
        _channels.send_buffer(cid, obj, blocking=True)
        t.join()

        self.assertEqual(received, obj)

    def test_send_blocking_no_wait(self):
        received = None
        obj = b'spam'
        cid = _channels.create(REPLACE)
        def f():
            nonlocal received
            received = recv_wait(cid)
        t = threading.Thread(target=f)
        t.start()
        _channels.send(cid, obj, blocking=True)
        t.join()

        self.assertEqual(received, obj)

    def test_send_buffer_blocking_no_wait(self):
        received = None
        obj = bytearray(b'spam')
        cid = _channels.create(REPLACE)
        def f():
            nonlocal received
            received = recv_wait(cid)
        t = threading.Thread(target=f)
        t.start()
        _channels.send_buffer(cid, obj, blocking=True)
        t.join()

        self.assertEqual(received, obj)

    def test_send_timeout(self):
        obj = b'spam'

        with self.subTest('non-blocking with timeout'):
            cid = _channels.create(REPLACE)
            with self.assertRaises(ValueError):
                _channels.send(cid, obj, blocking=False, timeout=0.1)

        with self.subTest('timeout hit'):
            cid = _channels.create(REPLACE)
            with self.assertRaises(TimeoutError):
                _channels.send(cid, obj, blocking=True, timeout=0.1)
            with self.assertRaises(_channels.ChannelEmptyError):
                received = recv_nowait(cid)
                print(repr(received))

        with self.subTest('timeout not hit'):
            cid = _channels.create(REPLACE)
            def f():
                recv_wait(cid)
            t = threading.Thread(target=f)
            t.start()
            _channels.send(cid, obj, blocking=True, timeout=10)
            t.join()

    def test_send_buffer_timeout(self):
        try:
            self._has_run_once_timeout
        except AttributeError:
            # At the moment, this test leaks a few references.
            # It looks like the leak originates with the addition
            # of _channels.send_buffer() (gh-110246), whereas the
            # tests were added afterward.  We want this test even
            # if the refleak isn't fixed yet, so we skip here.
            raise unittest.SkipTest('temporarily skipped due to refleaks')
        else:
            self._has_run_once_timeout = True

        obj = bytearray(b'spam')

        with self.subTest('non-blocking with timeout'):
            cid = _channels.create(REPLACE)
            with self.assertRaises(ValueError):
                _channels.send_buffer(cid, obj, blocking=False, timeout=0.1)

        with self.subTest('timeout hit'):
            cid = _channels.create(REPLACE)
            with self.assertRaises(TimeoutError):
                _channels.send_buffer(cid, obj, blocking=True, timeout=0.1)
            with self.assertRaises(_channels.ChannelEmptyError):
                received = recv_nowait(cid)
                print(repr(received))

        with self.subTest('timeout not hit'):
            cid = _channels.create(REPLACE)
            def f():
                recv_wait(cid)
            t = threading.Thread(target=f)
            t.start()
            _channels.send_buffer(cid, obj, blocking=True, timeout=10)
            t.join()

    def test_send_closed_while_waiting(self):
        obj = b'spam'
        wait = self.build_send_waiter(obj)

        with self.subTest('without timeout'):
            cid = _channels.create(REPLACE)
            def f():
                wait()
                _channels.close(cid, force=True)
            t = threading.Thread(target=f)
            t.start()
            with self.assertRaises(_channels.ChannelClosedError):
                _channels.send(cid, obj, blocking=True)
            t.join()

        with self.subTest('with timeout'):
            cid = _channels.create(REPLACE)
            def f():
                wait()
                _channels.close(cid, force=True)
            t = threading.Thread(target=f)
            t.start()
            with self.assertRaises(_channels.ChannelClosedError):
                _channels.send(cid, obj, blocking=True, timeout=30)
            t.join()

    def test_send_buffer_closed_while_waiting(self):
        try:
            self._has_run_once_closed
        except AttributeError:
            # At the moment, this test leaks a few references.
            # It looks like the leak originates with the addition
            # of _channels.send_buffer() (gh-110246), whereas the
            # tests were added afterward.  We want this test even
            # if the refleak isn't fixed yet, so we skip here.
            raise unittest.SkipTest('temporarily skipped due to refleaks')
        else:
            self._has_run_once_closed = True

        obj = bytearray(b'spam')
        wait = self.build_send_waiter(obj, buffer=True)

        with self.subTest('without timeout'):
            cid = _channels.create(REPLACE)
            def f():
                wait()
                _channels.close(cid, force=True)
            t = threading.Thread(target=f)
            t.start()
            with self.assertRaises(_channels.ChannelClosedError):
                _channels.send_buffer(cid, obj, blocking=True)
            t.join()

        with self.subTest('with timeout'):
            cid = _channels.create(REPLACE)
            def f():
                wait()
                _channels.close(cid, force=True)
            t = threading.Thread(target=f)
            t.start()
            with self.assertRaises(_channels.ChannelClosedError):
                _channels.send_buffer(cid, obj, blocking=True, timeout=30)
            t.join()

    #-------------------
    # close

    def test_close_single_user(self):
        cid = _channels.create(REPLACE)
        _channels.send(cid, b'spam', blocking=False)
        recv_nowait(cid)
        _channels.close(cid)

        with self.assertRaises(_channels.ChannelClosedError):
            _channels.send(cid, b'eggs')
        with self.assertRaises(_channels.ChannelClosedError):
            _channels.recv(cid)

    def test_close_multiple_users(self):
        cid = _channels.create(REPLACE)
        id1 = _interpreters.create()
        id2 = _interpreters.create()
        _interpreters.run_string(id1, dedent(f"""
            import _interpchannels as _channels
            _channels.send({cid}, b'spam', blocking=False)
            """))
        _interpreters.run_string(id2, dedent(f"""
            import _interpchannels as _channels
            _channels.recv({cid})
            """))
        _channels.close(cid)

        excsnap = _interpreters.run_string(id1, dedent(f"""
                _channels.send({cid}, b'spam')
                """))
        self.assertEqual(excsnap.type.__name__, 'ChannelClosedError')

        excsnap = _interpreters.run_string(id2, dedent(f"""
                _channels.send({cid}, b'spam')
                """))
        self.assertEqual(excsnap.type.__name__, 'ChannelClosedError')

    def test_close_multiple_times(self):
        cid = _channels.create(REPLACE)
        _channels.send(cid, b'spam', blocking=False)
        recv_nowait(cid)
        _channels.close(cid)

        with self.assertRaises(_channels.ChannelClosedError):
            _channels.close(cid)

    def test_close_empty(self):
        tests = [
            (False, False),
            (True, False),
            (False, True),
            (True, True),
            ]
        for send, recv in tests:
            with self.subTest((send, recv)):
                cid = _channels.create(REPLACE)
                _channels.send(cid, b'spam', blocking=False)
                recv_nowait(cid)
                _channels.close(cid, send=send, recv=recv)

                with self.assertRaises(_channels.ChannelClosedError):
                    _channels.send(cid, b'eggs')
                with self.assertRaises(_channels.ChannelClosedError):
                    _channels.recv(cid)

    def test_close_defaults_with_unused_items(self):
        cid = _channels.create(REPLACE)
        _channels.send(cid, b'spam', blocking=False)
        _channels.send(cid, b'ham', blocking=False)

        with self.assertRaises(_channels.ChannelNotEmptyError):
            _channels.close(cid)
        recv_nowait(cid)
        _channels.send(cid, b'eggs', blocking=False)

    def test_close_recv_with_unused_items_unforced(self):
        cid = _channels.create(REPLACE)
        _channels.send(cid, b'spam', blocking=False)
        _channels.send(cid, b'ham', blocking=False)

        with self.assertRaises(_channels.ChannelNotEmptyError):
            _channels.close(cid, recv=True)
        recv_nowait(cid)
        _channels.send(cid, b'eggs', blocking=False)
        recv_nowait(cid)
        recv_nowait(cid)
        _channels.close(cid, recv=True)

    def test_close_send_with_unused_items_unforced(self):
        cid = _channels.create(REPLACE)
        _channels.send(cid, b'spam', blocking=False)
        _channels.send(cid, b'ham', blocking=False)
        _channels.close(cid, send=True)

        with self.assertRaises(_channels.ChannelClosedError):
            _channels.send(cid, b'eggs')
        recv_nowait(cid)
        recv_nowait(cid)
        with self.assertRaises(_channels.ChannelClosedError):
            _channels.recv(cid)

    def test_close_both_with_unused_items_unforced(self):
        cid = _channels.create(REPLACE)
        _channels.send(cid, b'spam', blocking=False)
        _channels.send(cid, b'ham', blocking=False)

        with self.assertRaises(_channels.ChannelNotEmptyError):
            _channels.close(cid, recv=True, send=True)
        recv_nowait(cid)
        _channels.send(cid, b'eggs', blocking=False)
        recv_nowait(cid)
        recv_nowait(cid)
        _channels.close(cid, recv=True)

    def test_close_recv_with_unused_items_forced(self):
        cid = _channels.create(REPLACE)
        _channels.send(cid, b'spam', blocking=False)
        _channels.send(cid, b'ham', blocking=False)
        _channels.close(cid, recv=True, force=True)

        with self.assertRaises(_channels.ChannelClosedError):
            _channels.send(cid, b'eggs')
        with self.assertRaises(_channels.ChannelClosedError):
            _channels.recv(cid)

    def test_close_send_with_unused_items_forced(self):
        cid = _channels.create(REPLACE)
        _channels.send(cid, b'spam', blocking=False)
        _channels.send(cid, b'ham', blocking=False)
        _channels.close(cid, send=True, force=True)

        with self.assertRaises(_channels.ChannelClosedError):
            _channels.send(cid, b'eggs')
        with self.assertRaises(_channels.ChannelClosedError):
            _channels.recv(cid)

    def test_close_both_with_unused_items_forced(self):
        cid = _channels.create(REPLACE)
        _channels.send(cid, b'spam', blocking=False)
        _channels.send(cid, b'ham', blocking=False)
        _channels.close(cid, send=True, recv=True, force=True)

        with self.assertRaises(_channels.ChannelClosedError):
            _channels.send(cid, b'eggs')
        with self.assertRaises(_channels.ChannelClosedError):
            _channels.recv(cid)

    def test_close_never_used(self):
        cid = _channels.create(REPLACE)
        _channels.close(cid)

        with self.assertRaises(_channels.ChannelClosedError):
            _channels.send(cid, b'spam')
        with self.assertRaises(_channels.ChannelClosedError):
            _channels.recv(cid)

    def test_close_by_unassociated_interp(self):
        cid = _channels.create(REPLACE)
        _channels.send(cid, b'spam', blocking=False)
        interp = _interpreters.create()
        _interpreters.run_string(interp, dedent(f"""
            import _interpchannels as _channels
            _channels.close({cid}, force=True)
            """))
        with self.assertRaises(_channels.ChannelClosedError):
            _channels.recv(cid)
        with self.assertRaises(_channels.ChannelClosedError):
            _channels.close(cid)

    def test_close_used_multiple_times_by_single_user(self):
        cid = _channels.create(REPLACE)
        _channels.send(cid, b'spam', blocking=False)
        _channels.send(cid, b'spam', blocking=False)
        _channels.send(cid, b'spam', blocking=False)
        recv_nowait(cid)
        _channels.close(cid, force=True)

        with self.assertRaises(_channels.ChannelClosedError):
            _channels.send(cid, b'eggs')
        with self.assertRaises(_channels.ChannelClosedError):
            _channels.recv(cid)

    def test_channel_list_interpreters_invalid_channel(self):
        cid = _channels.create(REPLACE)
        # Test for invalid channel ID.
        with self.assertRaises(_channels.ChannelNotFoundError):
            _channels.list_interpreters(1000, send=True)

        _channels.close(cid)
        # Test for a channel that has been closed.
        with self.assertRaises(_channels.ChannelClosedError):
            _channels.list_interpreters(cid, send=True)

    def test_channel_list_interpreters_invalid_args(self):
        # Tests for invalid arguments passed to the API.
        cid = _channels.create(REPLACE)
        with self.assertRaises(TypeError):
            _channels.list_interpreters(cid)


class ChannelReleaseTests(TestBase):

    # XXX Add more test coverage a la the tests for close().

    """
    - main / interp / other
    - run in: current thread / new thread / other thread / different threads
    - end / opposite
    - force / no force
    - used / not used  (associated / not associated)
    - empty / emptied / never emptied / partly emptied
    - closed / not closed
    - released / not released
    - creator (interp) / other
    - associated interpreter not running
    - associated interpreter destroyed
    """

    """
    use
    pre-release
    release
    after
    check
    """

    """
    release in:         main, interp1
    creator:            same, other (incl. interp2)

    use:                None,send,recv,send/recv in None,same,other(incl. interp2),same+other(incl. interp2),all
    pre-release:        None,send,recv,both in None,same,other(incl. interp2),same+other(incl. interp2),all
    pre-release forced: None,send,recv,both in None,same,other(incl. interp2),same+other(incl. interp2),all

    release:            same
    release forced:     same

    use after:          None,send,recv,send/recv in None,same,other(incl. interp2),same+other(incl. interp2),all
    release after:      None,send,recv,send/recv in None,same,other(incl. interp2),same+other(incl. interp2),all
    check released:     send/recv for same/other(incl. interp2)
    check closed:       send/recv for same/other(incl. interp2)
    """

    def test_single_user(self):
        cid = _channels.create(REPLACE)
        _channels.send(cid, b'spam', blocking=False)
        recv_nowait(cid)
        _channels.release(cid, send=True, recv=True)

        with self.assertRaises(_channels.ChannelClosedError):
            _channels.send(cid, b'eggs')
        with self.assertRaises(_channels.ChannelClosedError):
            _channels.recv(cid)

    def test_multiple_users(self):
        cid = _channels.create(REPLACE)
        id1 = _interpreters.create()
        id2 = _interpreters.create()
        _interpreters.run_string(id1, dedent(f"""
            import _interpchannels as _channels
            _channels.send({cid}, b'spam', blocking=False)
            """))
        out = _run_output(id2, dedent(f"""
            import _interpchannels as _channels
            obj, _ = _channels.recv({cid})
            _channels.release({cid})
            print(repr(obj))
            """))
        _interpreters.run_string(id1, dedent(f"""
            _channels.release({cid})
            """))

        self.assertEqual(out.strip(), "b'spam'")

    def test_no_kwargs(self):
        cid = _channels.create(REPLACE)
        _channels.send(cid, b'spam', blocking=False)
        recv_nowait(cid)
        _channels.release(cid)

        with self.assertRaises(_channels.ChannelClosedError):
            _channels.send(cid, b'eggs')
        with self.assertRaises(_channels.ChannelClosedError):
            _channels.recv(cid)

    def test_multiple_times(self):
        cid = _channels.create(REPLACE)
        _channels.send(cid, b'spam', blocking=False)
        recv_nowait(cid)
        _channels.release(cid, send=True, recv=True)

        with self.assertRaises(_channels.ChannelClosedError):
            _channels.release(cid, send=True, recv=True)

    def test_with_unused_items(self):
        cid = _channels.create(REPLACE)
        _channels.send(cid, b'spam', blocking=False)
        _channels.send(cid, b'ham', blocking=False)
        _channels.release(cid, send=True, recv=True)

        with self.assertRaises(_channels.ChannelClosedError):
            _channels.recv(cid)

    def test_never_used(self):
        cid = _channels.create(REPLACE)
        _channels.release(cid)

        with self.assertRaises(_channels.ChannelClosedError):
            _channels.send(cid, b'spam')
        with self.assertRaises(_channels.ChannelClosedError):
            _channels.recv(cid)

    def test_by_unassociated_interp(self):
        cid = _channels.create(REPLACE)
        _channels.send(cid, b'spam', blocking=False)
        interp = _interpreters.create()
        _interpreters.run_string(interp, dedent(f"""
            import _interpchannels as _channels
            _channels.release({cid})
            """))
        obj = recv_nowait(cid)
        _channels.release(cid)

        with self.assertRaises(_channels.ChannelClosedError):
            _channels.send(cid, b'eggs')
        self.assertEqual(obj, b'spam')

    def test_close_if_unassociated(self):
        # XXX Something's not right with this test...
        cid = _channels.create(REPLACE)
        interp = _interpreters.create()
        _interpreters.run_string(interp, dedent(f"""
            import _interpchannels as _channels
            obj = _channels.send({cid}, b'spam', blocking=False)
            _channels.release({cid})
            """))

        with self.assertRaises(_channels.ChannelClosedError):
            _channels.recv(cid)

    def test_partially(self):
        # XXX Is partial close too weird/confusing?
        cid = _channels.create(REPLACE)
        _channels.send(cid, None, blocking=False)
        recv_nowait(cid)
        _channels.send(cid, b'spam', blocking=False)
        _channels.release(cid, send=True)
        obj = recv_nowait(cid)

        self.assertEqual(obj, b'spam')

    def test_used_multiple_times_by_single_user(self):
        cid = _channels.create(REPLACE)
        _channels.send(cid, b'spam', blocking=False)
        _channels.send(cid, b'spam', blocking=False)
        _channels.send(cid, b'spam', blocking=False)
        recv_nowait(cid)
        _channels.release(cid, send=True, recv=True)

        with self.assertRaises(_channels.ChannelClosedError):
            _channels.send(cid, b'eggs')
        with self.assertRaises(_channels.ChannelClosedError):
            _channels.recv(cid)


class ChannelCloseFixture(namedtuple('ChannelCloseFixture',
                                     'end interp other extra creator')):

    # Set this to True to avoid creating interpreters, e.g. when
    # scanning through test permutations without running them.
    QUICK = False

    def __new__(cls, end, interp, other, extra, creator):
        assert end in ('send', 'recv')
        if cls.QUICK:
            known = {}
        else:
            interp = Interpreter.from_raw(interp)
            other = Interpreter.from_raw(other)
            extra = Interpreter.from_raw(extra)
            known = {
                interp.name: interp,
                other.name: other,
                extra.name: extra,
                }
        if not creator:
            creator = 'same'
        self = super().__new__(cls, end, interp, other, extra, creator)
        self._prepped = set()
        self._state = ChannelState()
        self._known = known
        return self

    @property
    def state(self):
        return self._state

    @property
    def cid(self):
        try:
            return self._cid
        except AttributeError:
            creator = self._get_interpreter(self.creator)
            self._cid = self._new_channel(creator)
            return self._cid

    def get_interpreter(self, interp):
        interp = self._get_interpreter(interp)
        self._prep_interpreter(interp)
        return interp

    def expect_closed_error(self, end=None):
        if end is None:
            end = self.end
        if end == 'recv' and self.state.closed == 'send':
            return False
        return bool(self.state.closed)

    def prep_interpreter(self, interp):
        self._prep_interpreter(interp)

    def record_action(self, action, result):
        self._state = result

    def clean_up(self):
        clean_up_interpreters()
        clean_up_channels()

    # internal methods

    def _new_channel(self, creator):
        if creator.name == 'main':
            return _channels.create(REPLACE)
        else:
            ch = _channels.create(REPLACE)
            run_interp(creator.id, f"""
                import _interpreters
                cid = _xxsubchannels.create()
                # We purposefully send back an int to avoid tying the
                # channel to the other interpreter.
                _xxsubchannels.send({ch}, int(cid), blocking=False)
                del _interpreters
                """)
            self._cid = recv_nowait(ch)
        return self._cid

    def _get_interpreter(self, interp):
        if interp in ('same', 'interp'):
            return self.interp
        elif interp == 'other':
            return self.other
        elif interp == 'extra':
            return self.extra
        else:
            name = interp
            try:
                interp = self._known[name]
            except KeyError:
                interp = self._known[name] = Interpreter(name)
            return interp

    def _prep_interpreter(self, interp):
        if interp.id in self._prepped:
            return
        self._prepped.add(interp.id)
        if interp.name == 'main':
            return
        run_interp(interp.id, f"""
            import _interpchannels as channels
            import test.test__interpchannels as helpers
            ChannelState = helpers.ChannelState
            try:
                cid
            except NameError:
                cid = _channels._channel_id({self.cid})
            """)


@unittest.skip('these tests take several hours to run')
class ExhaustiveChannelTests(TestBase):

    """
    - main / interp / other
    - run in: current thread / new thread / other thread / different threads
    - end / opposite
    - force / no force
    - used / not used  (associated / not associated)
    - empty / emptied / never emptied / partly emptied
    - closed / not closed
    - released / not released
    - creator (interp) / other
    - associated interpreter not running
    - associated interpreter destroyed

    - close after unbound
    """

    """
    use
    pre-close
    close
    after
    check
    """

    """
    close in:         main, interp1
    creator:          same, other, extra

    use:              None,send,recv,send/recv in None,same,other,same+other,all
    pre-close:        None,send,recv in None,same,other,same+other,all
    pre-close forced: None,send,recv in None,same,other,same+other,all

    close:            same
    close forced:     same

    use after:        None,send,recv,send/recv in None,same,other,extra,same+other,all
    close after:      None,send,recv,send/recv in None,same,other,extra,same+other,all
    check closed:     send/recv for same/other(incl. interp2)
    """

    def iter_action_sets(self):
        # - used / not used  (associated / not associated)
        # - empty / emptied / never emptied / partly emptied
        # - closed / not closed
        # - released / not released

        # never used
        yield []

        # only pre-closed (and possible used after)
        for closeactions in self._iter_close_action_sets('same', 'other'):
            yield closeactions
            for postactions in self._iter_post_close_action_sets():
                yield closeactions + postactions
        for closeactions in self._iter_close_action_sets('other', 'extra'):
            yield closeactions
            for postactions in self._iter_post_close_action_sets():
                yield closeactions + postactions

        # used
        for useactions in self._iter_use_action_sets('same', 'other'):
            yield useactions
            for closeactions in self._iter_close_action_sets('same', 'other'):
                actions = useactions + closeactions
                yield actions
                for postactions in self._iter_post_close_action_sets():
                    yield actions + postactions
            for closeactions in self._iter_close_action_sets('other', 'extra'):
                actions = useactions + closeactions
                yield actions
                for postactions in self._iter_post_close_action_sets():
                    yield actions + postactions
        for useactions in self._iter_use_action_sets('other', 'extra'):
            yield useactions
            for closeactions in self._iter_close_action_sets('same', 'other'):
                actions = useactions + closeactions
                yield actions
                for postactions in self._iter_post_close_action_sets():
                    yield actions + postactions
            for closeactions in self._iter_close_action_sets('other', 'extra'):
                actions = useactions + closeactions
                yield actions
                for postactions in self._iter_post_close_action_sets():
                    yield actions + postactions

    def _iter_use_action_sets(self, interp1, interp2):
        interps = (interp1, interp2)

        # only recv end used
        yield [
            ChannelAction('use', 'recv', interp1),
            ]
        yield [
            ChannelAction('use', 'recv', interp2),
            ]
        yield [
            ChannelAction('use', 'recv', interp1),
            ChannelAction('use', 'recv', interp2),
            ]

        # never emptied
        yield [
            ChannelAction('use', 'send', interp1),
            ]
        yield [
            ChannelAction('use', 'send', interp2),
            ]
        yield [
            ChannelAction('use', 'send', interp1),
            ChannelAction('use', 'send', interp2),
            ]

        # partially emptied
        for interp1 in interps:
            for interp2 in interps:
                for interp3 in interps:
                    yield [
                        ChannelAction('use', 'send', interp1),
                        ChannelAction('use', 'send', interp2),
                        ChannelAction('use', 'recv', interp3),
                        ]

        # fully emptied
        for interp1 in interps:
            for interp2 in interps:
                for interp3 in interps:
                    for interp4 in interps:
                        yield [
                            ChannelAction('use', 'send', interp1),
                            ChannelAction('use', 'send', interp2),
                            ChannelAction('use', 'recv', interp3),
                            ChannelAction('use', 'recv', interp4),
                            ]

    def _iter_close_action_sets(self, interp1, interp2):
        ends = ('recv', 'send')
        interps = (interp1, interp2)
        for force in (True, False):
            op = 'force-close' if force else 'close'
            for interp in interps:
                for end in ends:
                    yield [
                        ChannelAction(op, end, interp),
                        ]
        for recvop in ('close', 'force-close'):
            for sendop in ('close', 'force-close'):
                for recv in interps:
                    for send in interps:
                        yield [
                            ChannelAction(recvop, 'recv', recv),
                            ChannelAction(sendop, 'send', send),
                            ]

    def _iter_post_close_action_sets(self):
        for interp in ('same', 'extra', 'other'):
            yield [
                ChannelAction('use', 'recv', interp),
                ]
            yield [
                ChannelAction('use', 'send', interp),
                ]

    def run_actions(self, fix, actions):
        for action in actions:
            self.run_action(fix, action)

    def run_action(self, fix, action, *, hideclosed=True):
        end = action.resolve_end(fix.end)
        interp = action.resolve_interp(fix.interp, fix.other, fix.extra)
        fix.prep_interpreter(interp)
        if interp.name == 'main':
            result = run_action(
                fix.cid,
                action.action,
                end,
                fix.state,
                hideclosed=hideclosed,
                )
            fix.record_action(action, result)
        else:
            _cid = _channels.create(REPLACE)
            run_interp(interp.id, f"""
                result = helpers.run_action(
                    {fix.cid},
                    {repr(action.action)},
                    {repr(end)},
                    {repr(fix.state)},
                    hideclosed={hideclosed},
                    )
                _channels.send({_cid}, result.pending.to_bytes(1, 'little'), blocking=False)
                _channels.send({_cid}, b'X' if result.closed else b'', blocking=False)
                """)
            result = ChannelState(
                pending=int.from_bytes(recv_nowait(_cid), 'little'),
                closed=bool(recv_nowait(_cid)),
                )
            fix.record_action(action, result)

    def iter_fixtures(self):
        # XXX threads?
        interpreters = [
            ('main', 'interp', 'extra'),
            ('interp', 'main', 'extra'),
            ('interp1', 'interp2', 'extra'),
            ('interp1', 'interp2', 'main'),
        ]
        for interp, other, extra in interpreters:
            for creator in ('same', 'other', 'creator'):
                for end in ('send', 'recv'):
                    yield ChannelCloseFixture(end, interp, other, extra, creator)

    def _close(self, fix, *, force):
        op = 'force-close' if force else 'close'
        close = ChannelAction(op, fix.end, 'same')
        if not fix.expect_closed_error():
            self.run_action(fix, close, hideclosed=False)
        else:
            with self.assertRaises(_channels.ChannelClosedError):
                self.run_action(fix, close, hideclosed=False)

    def _assert_closed_in_interp(self, fix, interp=None):
        if interp is None or interp.name == 'main':
            with self.assertRaises(_channels.ChannelClosedError):
                _channels.recv(fix.cid)
            with self.assertRaises(_channels.ChannelClosedError):
                _channels.send(fix.cid, b'spam')
            with self.assertRaises(_channels.ChannelClosedError):
                _channels.close(fix.cid)
            with self.assertRaises(_channels.ChannelClosedError):
                _channels.close(fix.cid, force=True)
        else:
            run_interp(interp.id, """
                with helpers.expect_channel_closed():
                    _channels.recv(cid)
                """)
            run_interp(interp.id, """
                with helpers.expect_channel_closed():
                    _channels.send(cid, b'spam', blocking=False)
                """)
            run_interp(interp.id, """
                with helpers.expect_channel_closed():
                    _channels.close(cid)
                """)
            run_interp(interp.id, """
                with helpers.expect_channel_closed():
                    _channels.close(cid, force=True)
                """)

    def _assert_closed(self, fix):
        self.assertTrue(fix.state.closed)

        for _ in range(fix.state.pending):
            recv_nowait(fix.cid)
        self._assert_closed_in_interp(fix)

        for interp in ('same', 'other'):
            interp = fix.get_interpreter(interp)
            if interp.name == 'main':
                continue
            self._assert_closed_in_interp(fix, interp)

        interp = fix.get_interpreter('fresh')
        self._assert_closed_in_interp(fix, interp)

    def _iter_close_tests(self, verbose=False):
        i = 0
        for actions in self.iter_action_sets():
            print()
            for fix in self.iter_fixtures():
                i += 1
                if i > 1000:
                    return
                if verbose:
                    if (i - 1) % 6 == 0:
                        print()
                    print(i, fix, '({} actions)'.format(len(actions)))
                else:
                    if (i - 1) % 6 == 0:
                        print(' ', end='')
                    print('.', end=''); sys.stdout.flush()
                yield i, fix, actions
            if verbose:
                print('---')
        print()

    # This is useful for scanning through the possible tests.
    def _skim_close_tests(self):
        ChannelCloseFixture.QUICK = True
        for i, fix, actions in self._iter_close_tests():
            pass

    def test_close(self):
        for i, fix, actions in self._iter_close_tests():
            with self.subTest('{} {}  {}'.format(i, fix, actions)):
                fix.prep_interpreter(fix.interp)
                self.run_actions(fix, actions)

                self._close(fix, force=False)

                self._assert_closed(fix)
            # XXX Things slow down if we have too many interpreters.
            fix.clean_up()

    def test_force_close(self):
        for i, fix, actions in self._iter_close_tests():
            with self.subTest('{} {}  {}'.format(i, fix, actions)):
                fix.prep_interpreter(fix.interp)
                self.run_actions(fix, actions)

                self._close(fix, force=True)

                self._assert_closed(fix)
            # XXX Things slow down if we have too many interpreters.
            fix.clean_up()


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