blob: aa24e616260e1953086a74e69eefa247a0784328 [file] [log] [blame]
//
// ========================================================================
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.util;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
import java.io.IOException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicInteger;
import org.eclipse.jetty.util.SharedBlockingCallback.Blocker;
import org.hamcrest.Matchers;
import org.junit.Assert;
import org.junit.Test;
public class SharedBlockingCallbackTest
{
final AtomicInteger notComplete = new AtomicInteger();
final SharedBlockingCallback sbcb= new SharedBlockingCallback()
{
@Override
protected long getIdleTimeout()
{
return 150;
}
@Override
protected void notComplete(Blocker blocker)
{
super.notComplete(blocker);
notComplete.incrementAndGet();
}
};
public SharedBlockingCallbackTest()
{
}
@Test
public void testDone() throws Exception
{
long start;
try (Blocker blocker=sbcb.acquire())
{
blocker.succeeded();
start=System.currentTimeMillis();
blocker.block();
}
Assert.assertThat(System.currentTimeMillis()-start,Matchers.lessThan(500L));
Assert.assertEquals(0,notComplete.get());
}
@Test
public void testGetDone() throws Exception
{
long start;
try (final Blocker blocker=sbcb.acquire())
{
final CountDownLatch latch = new CountDownLatch(1);
new Thread(new Runnable()
{
@Override
public void run()
{
latch.countDown();
try{TimeUnit.MILLISECONDS.sleep(100);}catch(Exception e){e.printStackTrace();}
blocker.succeeded();
}
}).start();
latch.await();
start=System.currentTimeMillis();
blocker.block();
}
Assert.assertThat(System.currentTimeMillis()-start,Matchers.greaterThan(10L));
Assert.assertThat(System.currentTimeMillis()-start,Matchers.lessThan(1000L));
Assert.assertEquals(0,notComplete.get());
}
@Test
public void testFailed() throws Exception
{
final Exception ex = new Exception("FAILED");
long start=Long.MIN_VALUE;
try
{
try (final Blocker blocker=sbcb.acquire())
{
blocker.failed(ex);
blocker.block();
}
Assert.fail();
}
catch(IOException ee)
{
start=System.currentTimeMillis();
Assert.assertEquals(ex,ee.getCause());
}
Assert.assertThat(System.currentTimeMillis()-start,Matchers.lessThan(100L));
Assert.assertEquals(0,notComplete.get());
}
@Test
public void testGetFailed() throws Exception
{
final Exception ex = new Exception("FAILED");
long start=Long.MIN_VALUE;
final CountDownLatch latch = new CountDownLatch(1);
try
{
try (final Blocker blocker=sbcb.acquire())
{
new Thread(new Runnable()
{
@Override
public void run()
{
latch.countDown();
try{TimeUnit.MILLISECONDS.sleep(100);}catch(Exception e){e.printStackTrace();}
blocker.failed(ex);
}
}).start();
latch.await();
start=System.currentTimeMillis();
blocker.block();
}
Assert.fail();
}
catch(IOException ee)
{
Assert.assertEquals(ex,ee.getCause());
}
Assert.assertThat(System.currentTimeMillis()-start,Matchers.greaterThan(10L));
Assert.assertThat(System.currentTimeMillis()-start,Matchers.lessThan(1000L));
Assert.assertEquals(0,notComplete.get());
}
@Test
public void testAcquireBlocked() throws Exception
{
final CountDownLatch latch = new CountDownLatch(1);
new Thread(new Runnable()
{
@Override
public void run()
{
try
{
try (Blocker blocker=sbcb.acquire())
{
latch.countDown();
TimeUnit.MILLISECONDS.sleep(100);
blocker.succeeded();
blocker.block();
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
}).start();
latch.await();
long start=System.currentTimeMillis();
try (Blocker blocker=sbcb.acquire())
{
Assert.assertThat(System.currentTimeMillis()-start,Matchers.greaterThan(10L));
Assert.assertThat(System.currentTimeMillis()-start,Matchers.lessThan(500L));
blocker.succeeded();
blocker.block();
};
Assert.assertThat(System.currentTimeMillis()-start,Matchers.lessThan(600L));
Assert.assertEquals(0,notComplete.get());
}
@Test
public void testBlockerClose() throws Exception
{
try (Blocker blocker=sbcb.acquire())
{
SharedBlockingCallback.LOG.info("Blocker not complete "+blocker+" warning is expected...");
}
Assert.assertEquals(1,notComplete.get());
}
@Test
public void testBlockerTimeout() throws Exception
{
Blocker b0=null;
try
{
try (Blocker blocker=sbcb.acquire())
{
b0=blocker;
Thread.sleep(400);
blocker.block();
}
fail();
}
catch(IOException e)
{
Throwable cause = e.getCause();
assertThat(cause,instanceOf(TimeoutException.class));
}
Assert.assertEquals(0,notComplete.get());
try (Blocker blocker=sbcb.acquire())
{
assertThat(blocker,not(equalTo(b0)));
try
{
b0.succeeded();
fail();
}
catch(Exception e)
{
assertThat(e,instanceOf(IllegalStateException.class));
assertThat(e.getCause(),instanceOf(TimeoutException.class));
}
blocker.succeeded();
}
}
}