Newer
Older
libj / modules / j / base / test / src / ut_thread.cpp
#include <iostream>
#include <j/cppunit/cppunit.hpp>
#include <j/cppunit/assert.hpp>
#include <j/lang/assertion_error.hpp>

#include <j/lang/thread.hpp>

using namespace j;
using namespace j::lang;
using namespace j::cppunit;

class TestThread : public Thread
{
public:
    TestThread(const String &name) : passRun(false), threadName(name) {}
    virtual ~TestThread() {}
    void run()
    {
        Thread::sleep(500);
        passRun = true;
    }

    bool passRun;
    String threadName;
};

class TmpRunnable : public Runnable
{
public:
    TmpRunnable() : passRun(false) {}
    virtual ~TmpRunnable() {}
    void run() override
    {
        Thread::yield();
        Thread::sleep(500);
        passRun = true;
    }
    bool passRun;
};

class ThreadTest : public TestCase
{
public:
    ThreadTest() {}
    ~ThreadTest() {}
    void setUp() {}
    void tearDown() {}

    void testThread()
    {
        TestThread t1("Thread1");
        TestThread t2("Thread2");
        t1.start();
        t2.start();
        Thread::sleep(10);
        bool alive1 = t1.isAlive();
        bool alive2 = t2.isAlive();
        assertTrue(t1.getId() != t2.getId());
        assertTrue(alive1);
        assertTrue(alive2);
        t1.join();
        t2.join();
        alive1 = t1.isAlive();
        alive2 = t2.isAlive();
        assertFalse(alive1);
        assertFalse(alive2);
        assertTrue(t1.passRun);
        assertTrue(t2.passRun);
    }

    void testRunnable()
    {
        TmpRunnable runnable;
        Thread t1(&runnable);
        Thread t2(&runnable);
        t1.start();
        t2.start();
        Thread::sleep(10);
        bool alive1 = t1.isAlive();
        bool alive2 = t2.isAlive();
        assertTrue(t1.getId() != t2.getId());
        assertTrue(alive1);
        assertTrue(alive2);
        t1.join();
        t2.join();
        alive1 = t1.isAlive();
        alive2 = t2.isAlive();
        assertFalse(alive1);
        assertFalse(alive2);
    }

    void testMove()
    {
        TmpRunnable runnable;
        Thread t1(&runnable);

        // 開始

        // t2 に移動
        Thread t2(std::move(t1));
        t2.start();
        Thread::sleep(10);
        bool alive = t2.isAlive();
        assertTrue(alive);
        t2.join();
        alive = t2.isAlive();
        assertFalse(alive);

        // t3 に移動
        Thread t3;
        t3 = std::move(t2);
        t3.start();
        Thread::sleep(10);
        alive = t3.isAlive();
        std::cout << "t3 alive = " << alive << std::endl;
        assertTrue(alive);
        t3.join();
        alive = t3.isAlive();
        std::cout << "t3 alive = " << alive << std::endl;
        assertFalse(alive);
    }

    void suite()
    {
        RUN_TEST("Thread", testThread);
        RUN_TEST("Runnable", testRunnable);
        RUN_TEST("Move", testMove);
    }
};