package com.gzzm.lobster.quota;

import com.gzzm.lobster.common.LobsterException;
import org.junit.Test;

import static org.junit.Assert.*;

public class ConcurrencyGuardTest {

    @Test
    public void releaseAllowsReAcquire() {
        ConcurrencyGuard g = new ConcurrencyGuard();
        try (ConcurrencyGuard.Acquisition a = g.acquire("u1", "t1", 2, 1)) {
            // hold one slot
        }
        try (ConcurrencyGuard.Acquisition b = g.acquire("u1", "t1", 2, 1)) {
            // should succeed after previous released
            assertNotNull(b);
        }
    }

    @Test(expected = LobsterException.class)
    public void threadLimitTripped() {
        ConcurrencyGuard g = new ConcurrencyGuard();
        ConcurrencyGuard.Acquisition a = g.acquire("u1", "t1", 10, 1);
        try {
            g.acquire("u1", "t1", 10, 1);
        } finally {
            a.close();
        }
    }

    @Test(expected = LobsterException.class)
    public void userLimitTripped() {
        ConcurrencyGuard g = new ConcurrencyGuard();
        ConcurrencyGuard.Acquisition a = g.acquire("u1", "t1", 1, 10);
        try {
            g.acquire("u1", "t2", 1, 10);
        } finally {
            a.close();
        }
    }
}
