class MongoThread(object):
    """A thread, or a greenlet, that uses a MongoClient"""
    def __init__(self, test_case):
        self.use_greenlets = test_case.use_greenlets
        self.client = test_case.c
        self.db = self.client[DB]
        self.ut = test_case
        self.passed = False

    def start(self):
        if self.use_greenlets:
            # A Gevent extended Greenlet
            self.thread = Greenlet(self.run)
        else:
            self.thread = threading.Thread(target=self.run)
            self.thread.setDaemon(True)  # Don't hang whole test if thread hangs

        self.thread.start()

    @property
    def alive(self):
        if self.use_greenlets:
            return not self.thread.dead
        else:
            return self.thread.isAlive()

    def join(self):
        self.thread.join(20)
        if self.use_greenlets:
            msg = "Greenlet timeout"
        else:
            msg = "Thread timeout"
        assert not self.alive, msg
        self.thread = None

    def run(self):
        self.run_mongo_thread()

        # No exceptions thrown
        self.passed = True

    def run_mongo_thread(self):
        raise NotImplementedError()

    def disconnect_client(self):
        if isinstance(self.client, MongoClient):
            self.client.close()
        else:
            # Don't kill the replica set monitor.
            self.client.disconnect()
class MongoThread(object):
    """A thread, or a greenlet, that uses a MongoClient"""
    def __init__(self, test_case):
        self.use_greenlets = test_case.use_greenlets
        self.client = test_case.c
        self.db = self.client[DB]
        self.ut = test_case
        self.passed = False

    def start(self):
        if self.use_greenlets:
            # A Gevent extended Greenlet
            self.thread = Greenlet(self.run)
        else:
            self.thread = threading.Thread(target=self.run)
            self.thread.setDaemon(
                True)  # Don't hang whole test if thread hangs

        self.thread.start()

    @property
    def alive(self):
        if self.use_greenlets:
            return not self.thread.dead
        else:
            return self.thread.isAlive()

    def join(self):
        self.thread.join(20)
        if self.use_greenlets:
            msg = "Greenlet timeout"
        else:
            msg = "Thread timeout"
        assert not self.alive, msg
        self.thread = None

    def run(self):
        self.run_mongo_thread()

        # No exceptions thrown
        self.passed = True

    def run_mongo_thread(self):
        raise NotImplementedError()
class MongoThread(object):
    """A thread, or a greenlet, that uses a Connection"""
    def __init__(self, test_case):
        self.use_greenlets = test_case.use_greenlets
        self.connection = test_case.c
        self.db = self.connection[DB]
        self.ut = test_case
        self.passed = False

    def start(self):
        if self.use_greenlets:
            # A Gevent extended Greenlet
            self.thread = Greenlet(self.run)
        else:
            self.thread = threading.Thread(target=self.run)
            self.thread.setDaemon(
                True)  # Don't hang whole test if thread hangs

        self.thread.start()

    def join(self):
        self.thread.join(300)
        if self.use_greenlets:
            assert self.thread.dead, "Greenlet timeout"
        else:
            assert not self.thread.isAlive(), "Thread timeout"

        self.thread = None

    def run(self):
        self.run_mongo_thread()

        # No exceptions thrown
        self.passed = True

    def run_mongo_thread(self):
        raise NotImplementedError()
class MongoThread(object):
    """A thread, or a greenlet, that uses a Connection"""
    def __init__(self, test_case):
        self.use_greenlets = test_case.use_greenlets
        self.connection = test_case.c
        self.db = self.connection[DB]
        self.ut = test_case
        self.passed = False

    def start(self):
        if self.use_greenlets:
            # A Gevent extended Greenlet
            self.thread = Greenlet(self.run)
        else:
            self.thread = threading.Thread(target=self.run)
            self.thread.setDaemon(True) # Don't hang whole test if thread hangs


        self.thread.start()

    def join(self):
        self.thread.join(300)
        if self.use_greenlets:
            assert self.thread.dead, "Greenlet timeout"
        else:
            assert not self.thread.isAlive(), "Thread timeout"

        self.thread = None

    def run(self):
        self.run_mongo_thread()

        # No exceptions thrown
        self.passed = True

    def run_mongo_thread(self):
        raise NotImplementedError()