Como escrever testes unitários que testam invariantes de simultaneidade

9

Existem outras questões sobre esse problema, mas estou tentando descobrir como abordar o teste unitário algo assim:

 public class Semaphore extends Lock {
        private AtomicInteger semaphore = new AtomicInteger(0);
        public synchronized boolean available() {
                return semaphore.intValue() == 0;
        }
        public synchronized void acquire() {
            semaphore.incrementAndGet();

        }
        public synchronized void release() {
            semaphore.decrementAndGet();
        }
    }

Este é o meu mecanismo de bloqueio caseiro (apenas para fins de aprendizado). Como eu testaria a segurança do thread disso? Eu sei que não há garantias quando se trata de código concorrente de teste de unidade, mas como eu poderia mesmo escrever um teste de unidade que ATTEMPTS testaria as invariantes óbvias inerentes a esse mecanismo de bloqueio?

    
por LuxuryMode 31.01.2012 в 23:06
fonte

1 resposta

5

Acho que vou responder minha própria pergunta desde que fiz alguma pesquisa. Há um ótimo framework chamado MultithreadedTC . Ele permite que você configure testes assim:

public class SafeSemaphoreTest extends MultithreadedTestCase {

    private SafeSemaphore semaphore;
    AtomicInteger ai = new AtomicInteger(0);

    @Override
    public void initialize() {
        semaphore = new SafeSemaphore();
    }


    public void thread1() throws InterruptedException {

        assertTick(0);

        semaphore.acquire();
        waitForTick(2);
        assertTick(2);

        semaphore.acquire();
        assertEquals(semaphore.getValue(), 2);
        assertEquals(semaphore.getValue()==3, false);
        semaphore.release();
        semaphore.release();

    }

    public void thread2() throws InterruptedException {
        waitForTick(1);
        assertTick(1);
        assertEquals(semaphore.available(), false);
        waitForTick(3);
        assertTick(3);
        assertEquals(semaphore.available(), true);

    }

}

onde as chamadas waitForTick (int) fazem o bloco Thread atual até que o tick seja alcançado. Houve até algum desenvolvimento para tornar isso um pouco mais moderno para uma melhor integração do JUnit: link

    
por LuxuryMode 01.02.2012 / 04:38
fonte