text:
package com.proofpoint.concurrent;

import com.google.common.collect.ImmutableList;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.SettableFuture;
import com.proofpoint.units.Duration;
import org.testng.annotations.AfterClass;
import org.testng.annotations.Test;

import java.io.IOException;
import java.sql.SQLException;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CancellationException;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ScheduledExecutorService;
import java.util.function.Consumer;
import java.util.function.Function;

import static com.google.common.base.Strings.nullToEmpty;
import static com.google.common.util.concurrent.Futures.immediateFailedFuture;
import static com.google.common.util.concurrent.Futures.immediateFuture;
import static com.proofpoint.concurrent.MoreFutures.addTimeout;
import static com.proofpoint.concurrent.MoreFutures.allAsList;
import static com.proofpoint.concurrent.MoreFutures.checkSuccess;
import static com.proofpoint.concurrent.MoreFutures.failedFuture;
import static com.proofpoint.concurrent.MoreFutures.firstCompletedFuture;
import static com.proofpoint.concurrent.MoreFutures.getDone;
import static com.proofpoint.concurrent.MoreFutures.getFutureValue;
import static com.proofpoint.concurrent.MoreFutures.mirror;
import static com.proofpoint.concurrent.MoreFutures.propagateCancellation;
import static com.proofpoint.concurrent.MoreFutures.toCompletableFuture;
import static com.proofpoint.concurrent.MoreFutures.toListenableFuture;
import static com.proofpoint.concurrent.MoreFutures.tryGetFutureValue;
import static com.proofpoint.concurrent.MoreFutures.unmodifiableFuture;
import static com.proofpoint.concurrent.MoreFutures.unwrapCompletionException;
import static com.proofpoint.concurrent.MoreFutures.whenAnyComplete;
import static com.proofpoint.concurrent.MoreFutures.whenAnyCompleteCancelOthers;
import static com.proofpoint.concurrent.Threads.daemonThreadsNamed;
import static com.proofpoint.testing.Assertions.assertInstanceOf;
import static java.lang.String.format;
import static java.util.concurrent.CompletableFuture.completedFuture;
import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.SECONDS;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertSame;
import static org.testng.Assert.assertThrows;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;

@SuppressWarnings("deprecation")
public class TestMoreFutures
{
    private final ScheduledExecutorService executorService = newSingleThreadScheduledExecutor(daemonThreadsNamed("test-%s"));

    @AfterClass
    public void tearDown()
    {
        executorService.shutdownNow();
    }

    @Test
    public void propagateCancellationWithoutInterrupt()
    {
        // Test interrupt override
        ExtendedSettableFuture<Object> fromFuture = ExtendedSettableFuture.create();
        ExtendedSettableFuture<Object> toFuture = ExtendedSettableFuture.create();
        propagateCancellation(fromFuture, toFuture, false);
        fromFuture.cancel(true);
        assertTrue(toFuture.isCancelled());
        assertFalse(toFuture.checkWasInterrupted());

        fromFuture = ExtendedSettableFuture.create();
        toFuture = ExtendedSettableFuture.create();
        propagateCancellation(fromFuture, toFuture, false);
        fromFuture.cancel(false);
        assertTrue(toFuture.isCancelled());
        assertFalse(toFuture.checkWasInterrupted());
    }

    @Test
    public void propagateCancellationWithInterrupt()
    {
        ExtendedSettableFuture<Object> fromFuture = ExtendedSettableFuture.create();
        ExtendedSettableFuture<Object> toFuture = ExtendedSettableFuture.create();
        propagateCancellation(fromFuture, toFuture, true);
        fromFuture.cancel(true);
        assertTrue(toFuture.isCancelled());
        assertTrue(toFuture.checkWasInterrupted());

        // Test interrupt override
        fromFuture = ExtendedSettableFuture.create();
        toFuture = ExtendedSettableFuture.create();
        propagateCancellation(fromFuture, toFuture, true);
        fromFuture.cancel(false);
        assertTrue(toFuture.isCancelled());
        assertTrue(toFuture.checkWasInterrupted());
    }

    @Test
    public void testMirror()
            throws Exception
    {
        // Test return value
        ExtendedSettableFuture<String> fromFuture = ExtendedSettableFuture.create();
        SettableFuture<String> toFuture = SettableFuture.create();
        mirror(fromFuture, toFuture, true);
        fromFuture.set("abc");
        assertEquals(toFuture.get(), "abc");

        // Test exception
        fromFuture = ExtendedSettableFuture.create();
        toFuture = SettableFuture.create();
        mirror(fromFuture, toFuture, true);
        fromFuture.setException(new RuntimeException());
        assertThrows(ExecutionException.class, toFuture::get);

        // Test cancellation without interrupt
        fromFuture = ExtendedSettableFuture.create();
        toFuture = SettableFuture.create();
        mirror(fromFuture, toFuture, false);
        toFuture.cancel(true);
        // Parent Future should receive the cancellation
        assertTrue(fromFuture.isCancelled());
        assertFalse(fromFuture.checkWasInterrupted());

        // Test cancellation with interrupt
        fromFuture = ExtendedSettableFuture.create();
        toFuture = SettableFuture.create();
        mirror(fromFuture, toFuture, true);
        toFuture.cancel(false);
        // Parent Future should receive the cancellation
        assertTrue(fromFuture.isCancelled());
        assertTrue(fromFuture.checkWasInterrupted());
    }

    @Test
    public void testUnwrapCompletionException()
    {
        RuntimeException original = new RuntimeException();
        assertSame(unwrapCompletionException(original), original);
        assertSame(unwrapCompletionException(new CompletionException(original)), original);

        CompletionException completion = new CompletionException(null);
        assertSame(unwrapCompletionException(completion), completion);
    }

    @Test
    public void testModifyUnmodifiableFuture()
    {
        CompletableFuture<String> future = new CompletableFuture<>();
        CompletableFuture<String> unmodifiableFuture = unmodifiableFuture(future);

        // completion results in an UnsupportedOperationException
        assertFailure(() -> unmodifiableFuture.complete("fail"), e -> assertInstanceOf(e, UnsupportedOperationException.class));
        assertFalse(future.isDone());
        assertFalse(unmodifiableFuture.isDone());

        assertFailure(() -> unmodifiableFuture.completeExceptionally(new IOException()), e -> assertInstanceOf(e, UnsupportedOperationException.class));
        assertFalse(future.isDone());
        assertFalse(unmodifiableFuture.isDone());

        assertFailure(() -> unmodifiableFuture.obtrudeValue("fail"), e -> assertInstanceOf(e, UnsupportedOperationException.class));
        assertFalse(future.isDone());
        assertFalse(unmodifiableFuture.isDone());

        assertFailure(() -> unmodifiableFuture.obtrudeException(new IOException()), e -> assertInstanceOf(e, UnsupportedOperationException.class));
        assertFalse(future.isDone());
        assertFalse(unmodifiableFuture.isDone());

        // cancel is ignored
        assertFalse(unmodifiableFuture.cancel(false));
        assertFalse(future.isDone());
        assertFalse(unmodifiableFuture.isDone());

        assertFalse(unmodifiableFuture.cancel(true));
        assertFalse(future.isDone());
        assertFalse(unmodifiableFuture.isDone());

        assertFalse(unmodifiableFuture.completeExceptionally(new CancellationException()));
        assertFalse(future.isDone());
        assertFalse(unmodifiableFuture.isDone());
    }

    @Test
    public void testModifyCancelableUnmodifiableFuture()
    {
        CompletableFuture<String> future = new CompletableFuture<>();
        CompletableFuture<String> unmodifiableFuture = unmodifiableFuture(future, true);

        // completion results in an UnsupportedOperationException
        assertFailure(() -> unmodifiableFuture.complete("fail"), e -> assertInstanceOf(e, UnsupportedOperationException.class));
        assertFalse(future.isDone());
        assertFalse(unmodifiableFuture.isDone());

        assertFailure(() -> unmodifiableFuture.completeExceptionally(new IOException()), e -> assertInstanceOf(e, UnsupportedOperationException.class));
        assertFalse(future.isDone());
        assertFalse(unmodifiableFuture.isDone());

        assertFailure(() -> unmodifiableFuture.obtrudeValue("fail"), e -> assertInstanceOf(e, UnsupportedOperationException.class));
        assertFalse(future.isDone());
        assertFalse(unmodifiableFuture.isDone());

        assertFailure(() -> unmodifiableFuture.obtrudeException(new IOException()), e -> assertInstanceOf(e, UnsupportedOperationException.class));
        assertFalse(future.isDone());
        assertFalse(unmodifiableFuture.isDone());

        // cancel is propagated so test separately
    }

    @Test
    public void testUnmodifiableFutureCancelPropagation()
    {
        CompletableFuture<String> future = new CompletableFuture<>();
        CompletableFuture<String> unmodifiableFuture = unmodifiableFuture(future, true);
        assertTrue(unmodifiableFuture.cancel(false));
        assertTrue(future.isDone());
        assertTrue(future.isCancelled());
        assertTrue(unmodifiableFuture.isDone());
        assertTrue(unmodifiableFuture.isCancelled());

        future = new CompletableFuture<>();
        unmodifiableFuture = unmodifiableFuture(future, true);
        assertTrue(unmodifiableFuture.cancel(true));
        assertTrue(future.isDone());
        assertTrue(future.isCancelled());
        assertTrue(unmodifiableFuture.isDone());
        assertTrue(unmodifiableFuture.isCancelled());

        future = new CompletableFuture<>();
        unmodifiableFuture = unmodifiableFuture(future, true);
        assertTrue(unmodifiableFuture.completeExceptionally(new CancellationException()));
        assertTrue(future.isDone());
        assertTrue(future.isCancelled());
        assertTrue(unmodifiableFuture.isDone());
        assertTrue(unmodifiableFuture.isCancelled());
    }

    @Test
    public void testCompleteUnmodifiableFuture()
    {
        CompletableFuture<String> future = new CompletableFuture<>();
        CompletableFuture<String> unmodifiableFuture = unmodifiableFuture(future);

        assertTrue(future.complete("done"));
        assertEquals(future.getNow(null), "done");
        assertTrue(unmodifiableFuture.isDone());
        assertEquals(unmodifiableFuture.getNow(null), "done");
    }

    @Test
    public void testCompleteExceptionallyUnmodifiableFuture()
    {
        CompletableFuture<String> future = new CompletableFuture<>();
        CompletableFuture<String> unmodifiableFuture = unmodifiableFuture(future);

        assertTrue(future.completeExceptionally(new SQLException("foo")));
        assertFailure(() -> getFutureValue(future, SQLException.class), e -> {
            assertInstanceOf(e, SQLException.class);
            assertEquals(e.getMessage(), "foo");
        });

        assertTrue(unmodifiableFuture.isDone());
        assertFailure(() -> getFutureValue(unmodifiableFuture, SQLException.class), e -> {
            assertInstanceOf(e, SQLException.class);
            assertEquals(e.getMessage(), "foo");
        });
    }

    @Test
    public void testAlreadyCompleteUnmodifiableFuture()
    {
        CompletableFuture<String> future = completedFuture("done");
        CompletableFuture<String> unmodifiableFuture = unmodifiableFuture(future);

        assertEquals(future.getNow(null), "done");
        assertTrue(unmodifiableFuture.isDone());
        assertEquals(unmodifiableFuture.getNow(null), "done");
    }

    @Test
    public void testAlreadyCompleteExceptionallyUnmodifiableFuture()
    {
        CompletableFuture<String> future = failedFuture(new SQLException("foo"));
        CompletableFuture<String> unmodifiableFuture = unmodifiableFuture(future);

        assertFailure(() -> getFutureValue(future, SQLException.class), e -> {
            assertInstanceOf(e, SQLException.class);
            assertEquals(e.getMessage(), "foo");
        });

        assertTrue(unmodifiableFuture.isDone());
        assertFailure(() -> getFutureValue(unmodifiableFuture, SQLException.class), e -> {
            assertInstanceOf(e, SQLException.class);
            assertEquals(e.getMessage(), "foo");
        });
    }

    @Test
    public void testFailedFuture()
    {
        CompletableFuture<Object> future = failedFuture(new SQLException("foo"));

        assertTrue(future.isCompletedExceptionally());

        assertFailure(future::get, e -> {
            assertInstanceOf(e, ExecutionException.class);
            assertTrue(e.getCause() instanceof SQLException);
            assertEquals(e.getCause().getMessage(), "foo");
        });
    }

    @Test
    public void testGetFutureValue()
            throws Exception
    {
        assertGetUnchecked(MoreFutures::getFutureValue);
    }

    @Test
    public void testGetFutureValueWithExceptionType()
            throws Exception
    {
        assertGetUnchecked(future -> getFutureValue(future, IOException.class));

        assertFailure(() -> getFutureValue(failedFuture(new SQLException("foo")), SQLException.class), e -> {
            assertInstanceOf(e, SQLException.class);
            assertEquals(e.getMessage(), "foo");
        });
    }

    @Test
    public void testTryGetFutureValue()
            throws Exception
    {
        assertGetUnchecked(future -> {
            Optional<?> optional = tryGetFutureValue(future);
            if (optional.isPresent()) {
                return optional.get();
            }

            // null value is also absent
            assertNull(getFutureValue(future));
            return null;
        });

        assertEquals(tryGetFutureValue(new CompletableFuture<>()), Optional.empty());
    }

    @Test
    public void testTryGetFutureValueWithWait()
            throws Exception
    {        assertGetUnchecked(future -> {
            Optional<?> optional = tryGetFutureValue(future, 100, MILLISECONDS);
            if (optional.isPresent()) {
                return optional.get();
            }

            // null value is also absent
            assertNull(getFutureValue(future));
            return null;
        });

        assertEquals(tryGetFutureValue(new CompletableFuture<>(), 10, MILLISECONDS), Optional.empty());
    }

    @Test
    public void testTryGetFutureValueWithExceptionType()
            throws Exception
    {
        assertGetUnchecked(future -> {
            Optional<?> optional = tryGetFutureValue(future, 100, MILLISECONDS, IOException.class);
            if (optional.isPresent()) {
                return optional.get();
            }

            // null value is also absent
            assertNull(getFutureValue(future, IOException.class));
            return null;
        });

        assertEquals(tryGetFutureValue(new CompletableFuture<>(), 10, MILLISECONDS), Optional.empty());

        assertFailure(() -> tryGetFutureValue(failedFuture(new SQLException("foo")), 10, MILLISECONDS, SQLException.class), e -> {
            assertInstanceOf(e, SQLException.class);
            assertEquals(e.getMessage(), "foo");
        });
    }

    @Test
    public void testWhenAnyComplete()
            throws Exception
    {
        assertGetUncheckedListenable(future -> getFutureValue(whenAnyComplete(ImmutableList.of(SettableFuture.create(), future, SettableFuture.create()))));

        assertFailure(() -> whenAnyComplete(null), e -> assertInstanceOf(e, NullPointerException.class));
        assertFailure(() -> whenAnyComplete(ImmutableList.of()), e -> assertInstanceOf(e, IllegalArgumentException.class));

        assertEquals(
                tryGetFutureValue(whenAnyComplete(ImmutableList.of(SettableFuture.create(), SettableFuture.create())), 10, MILLISECONDS),
                Optional.empty());
    }

    @Test
    public void testWhenAnyCompleteCancelOthers()
            throws Exception
    {
        assertGetUncheckedListenable(future -> {
            SettableFuture<Object> future1 = SettableFuture.create();
            SettableFuture<Object> future3 = SettableFuture.create();
            Object result = getFutureValue(whenAnyCompleteCancelOthers(ImmutableList.of(future1, future, future3)));
            assertTrue(future1.isCancelled());
            assertTrue(future3.isCancelled());
            return result;
        });

        assertFailure(() -> whenAnyComplete(null), e -> assertInstanceOf(e, NullPointerException.class));
        assertFailure(() -> whenAnyComplete(ImmutableList.of()), e -> assertInstanceOf(e, IllegalArgumentException.class));

        assertEquals(
                tryGetFutureValue(whenAnyComplete(ImmutableList.of(SettableFuture.create(), SettableFuture.create())), 10, MILLISECONDS),
                Optional.empty());
    }

    @Test
    public void testAnyOf()
            throws Exception
    {
        assertGetUnchecked(future -> getFutureValue(firstCompletedFuture(ImmutableList.of(new CompletableFuture<>(), future, new CompletableFuture<>()))));

        assertFailure(() -> firstCompletedFuture(null), e -> assertInstanceOf(e, NullPointerException.class));
        assertFailure(() -> firstCompletedFuture(ImmutableList.of()), e -> assertInstanceOf(e, IllegalArgumentException.class));

        assertEquals(
                tryGetFutureValue(firstCompletedFuture(ImmutableList.of(new CompletableFuture<>(), new CompletableFuture<>())), 10, MILLISECONDS),
                Optional.empty());
    }

    @Test
    public void testToFromListenableFuture()
            throws Exception
    {
        assertGetUnchecked(future -> getFutureValue(toCompletableFuture(toListenableFuture(future))));

        SettableFuture<?> settableFuture = SettableFuture.create();
        toCompletableFuture(settableFuture).cancel(true);
        assertTrue(settableFuture.isCancelled());

        CompletableFuture<Object> completableFuture = new CompletableFuture<>();
        toListenableFuture(completableFuture).cancel(true);
        assertTrue(completableFuture.isCancelled());

        assertEquals(tryGetFutureValue(toCompletableFuture(SettableFuture.create()), 10, MILLISECONDS), Optional.empty());
        assertEquals(tryGetFutureValue(toListenableFuture(new CompletableFuture<>()), 10, MILLISECONDS), Optional.empty());
    }

    @Test
    public void testEmptyAllAsList()
    {
        CompletableFuture<List<Object>> future = allAsList(ImmutableList.of());
        assertTrue(future.isDone());
        assertFalse(future.isCompletedExceptionally());
        assertFalse(future.isCancelled());
        assertEquals(future.join(), ImmutableList.of());
    }

    @Test
    public void testSingleElementAllAsList()
    {
        CompletableFuture<String> element1 = new CompletableFuture<>();

        CompletableFuture<List<Object>> future = allAsList(ImmutableList.of(element1));
        assertFalse(future.isDone());
        assertFalse(future.isCancelled());

        element1.complete("a");
        assertTrue(future.isDone());
        assertFalse(future.isCompletedExceptionally());
        assertFalse(future.isCancelled());
        assertEquals(future.join(), ImmutableList.of("a"));
    }

    @Test
    public void testExceptionalSingleElementAllAsList()
    {
        CompletableFuture<String> element1 = new CompletableFuture<>();

        CompletableFuture<List<Object>> future = allAsList(ImmutableList.of(element1));
        assertFalse(future.isDone());
        assertFalse(future.isCancelled());

        element1.completeExceptionally(new RuntimeException());
        assertTrue(future.isDone());
        assertTrue(future.isCompletedExceptionally());
        assertFalse(future.isCancelled());
    }

    @Test
    public void testMultipleElementAllAsList()
    {
        CompletableFuture<String> element1 = new CompletableFuture<>();
        CompletableFuture<String> element2 = new CompletableFuture<>();

        CompletableFuture<List<Object>> future = allAsList(ImmutableList.of(element1, element2));
        assertFalse(future.isDone());
        assertFalse(future.isCancelled());

        element1.complete("a");
        assertFalse(future.isDone());
        assertFalse(future.isCompletedExceptionally());
        assertFalse(future.isCancelled());

        element2.complete("b");
        assertTrue(future.isDone());
        assertFalse(future.isCompletedExceptionally());
        assertFalse(future.isCancelled());
        assertEquals(future.join(), ImmutableList.of("a", "b"));
    }

    @Test
    public void testExceptionalMultipleElementAllAsList()
    {
        CompletableFuture<String> element1 = new CompletableFuture<>();
        CompletableFuture<String> element2 = new CompletableFuture<>();

        CompletableFuture<List<Object>> future = allAsList(ImmutableList.of(element1, element2));
        assertFalse(future.isDone());
        assertFalse(future.isCompletedExceptionally());
        assertFalse(future.isCancelled());

        element1.completeExceptionally(new RuntimeException());
        assertTrue(future.isDone());
        assertTrue(future.isCompletedExceptionally());
        assertFalse(future.isCancelled());
    }

    @Test(expectedExceptions = UnsupportedOperationException.class)
    public void testUnmodifiableAllAsList()
    {
        CompletableFuture<List<Object>> future = allAsList(ImmutableList.of(new CompletableFuture<String>()));
        future.complete(null);
    }

    @Test
    public void testListenableTimeout()
    {
        SettableFuture<String> rootFuture = SettableFuture.create();
        ListenableFuture<String> timeoutFuture = addTimeout(rootFuture, () -> "timeout", new Duration(0, MILLISECONDS), executorService);

        assertEquals(tryGetFutureValue(timeoutFuture, 10, SECONDS).orElse("failed"), "timeout");
        assertTrue(timeoutFuture.isDone());
        assertFalse(timeoutFuture.isCancelled());

        // root exception is cancelled on a timeout
        assertFailure(() -> rootFuture.get(10, SECONDS), e -> assertInstanceOf(e, CancellationException.class));
        assertTrue(rootFuture.isDone());
        assertTrue(rootFuture.isCancelled());
    }

    @Test
    public void testListenableTimeoutExceptionValue()
    {
        SettableFuture<String> rootFuture = SettableFuture.create();
        ListenableFuture<String> timeoutFuture = addTimeout(rootFuture, () -> { throw new SQLException("timeout"); }, new Duration(0, MILLISECONDS), executorService);

        assertFailure(() -> tryGetFutureValue(timeoutFuture, 10, SECONDS, SQLException.class), e -> {
            assertInstanceOf(e, SQLException.class);
            assertEquals(e.getMessage(), "timeout");
        });
        assertTrue(timeoutFuture.isDone());
        assertFalse(timeoutFuture.isCancelled());

        // root exception is cancelled on a timeout
        assertFailure(() -> rootFuture.get(10, SECONDS), e -> assertInstanceOf(e, CancellationException.class));
        assertTrue(rootFuture.isDone());
        assertTrue(rootFuture.isCancelled());
    }

    @Test
    public void testListenableTimeoutCancel()
    {
        SettableFuture<String> rootFuture = SettableFuture.create();
        ListenableFuture<String> timeoutFuture = addTimeout(rootFuture, () -> "timeout", new Duration(10, SECONDS), executorService);

        // check timeout
        assertEquals(tryGetFutureValue(timeoutFuture, 10, MILLISECONDS), Optional.<String>empty());

        assertTrue(timeoutFuture.cancel(true));
        assertTrue(timeoutFuture.isDone());
        assertTrue(timeoutFuture.isCancelled());

        // root exception is cancelled on a timeout
        assertFailure(() -> rootFuture.get(10, SECONDS), e -> assertInstanceOf(e, CancellationException.class));
        assertTrue(rootFuture.isDone());
        assertTrue(rootFuture.isCancelled());
    }

    @Test
    public void testTimeout()
    {
        CompletableFuture<String> rootFuture = new CompletableFuture<>();
        CompletableFuture<String> timeoutFuture = addTimeout(rootFuture, () -> "timeout", new Duration(0, MILLISECONDS), executorService);

        assertEquals(tryGetFutureValue(timeoutFuture, 10, SECONDS).get(), "timeout");
        assertTrue(timeoutFuture.isDone());
        assertFalse(timeoutFuture.isCancelled());

        // root exception is cancelled on a timeout
        assertFailure(() -> rootFuture.get(10, SECONDS), e -> assertInstanceOf(e, CancellationException.class));
        assertTrue(rootFuture.isDone());
        assertTrue(rootFuture.isCancelled());
    }

    @Test
    public void testTimeoutExceptionValue()
    {
        CompletableFuture<String> rootFuture = new CompletableFuture<>();
        CompletableFuture<String> timeoutFuture = addTimeout(rootFuture, () -> { throw new SQLException("timeout"); }, new Duration(0, MILLISECONDS), executorService);

        assertFailure(() -> tryGetFutureValue(timeoutFuture, 10, SECONDS, SQLException.class), e -> {
            assertInstanceOf(e, SQLException.class);
            assertEquals(e.getMessage(), "timeout");
        });
        assertTrue(timeoutFuture.isDone());
        assertFalse(timeoutFuture.isCancelled());

        // root exception is cancelled on a timeout
        assertFailure(() -> rootFuture.get(10, SECONDS), e -> assertInstanceOf(e, CancellationException.class));
        assertTrue(rootFuture.isDone());
        assertTrue(rootFuture.isCancelled());
    }

    @Test
    public void testTimeoutCancel()
    {
        CompletableFuture<String> rootFuture = new CompletableFuture<>();
        CompletableFuture<String> timeoutFuture = addTimeout(rootFuture, () -> "timeout", new Duration(10, SECONDS), executorService);

        // check timeout
        assertEquals(tryGetFutureValue(timeoutFuture, 10, MILLISECONDS), Optional.<String>empty());

        assertTrue(timeoutFuture.cancel(true));
        assertTrue(timeoutFuture.isDone());
        assertTrue(timeoutFuture.isCancelled());

        // root exception is cancelled on a timeout
        assertFailure(() -> rootFuture.get(10, SECONDS), e -> assertInstanceOf(e, CancellationException.class));
        assertTrue(rootFuture.isDone());
        assertTrue(rootFuture.isCancelled());
    }

    @Test
    public void testGetDone()
    {
        assertEquals(getDone(immediateFuture("Alice")), "Alice");

        assertFailure(() -> getDone(immediateFailedFuture(new IllegalStateException("some failure"))), expect(IllegalStateException.class, "some failure"));

        assertFailure(
                () -> getDone(immediateFailedFuture(new IOException("some failure"))),
                expect(RuntimeException.class, "java.io.IOException: some failure", expect(IOException.class, "some failure")));

        assertFailure(() -> getDone(SettableFuture.create()), expect(IllegalArgumentException.class, "future not done yet"));

        assertFailure(() -> getDone(null), expect(NullPointerException.class, "future is null"));
    }

    @Test
    public void testCheckSuccess()
    {
        checkSuccess(immediateFuture("Alice"), "this should not fail");

        assertFailure(
                () -> checkSuccess(immediateFailedFuture(new IllegalStateException("some failure")), "msg"),
                expect(
                        IllegalArgumentException.class, "msg",
                        expect(IllegalStateException.class, "some failure")));

        assertFailure(
                () -> checkSuccess(immediateFailedFuture(new IOException("some failure")), "msg"),
                expect(
                        IllegalArgumentException.class, "msg",
                        expect(
                                RuntimeException.class, "java.io.IOException: some failure",
                                expect(IOException.class, "some failure"))));

        assertFailure(() -> checkSuccess(SettableFuture.create(), "msg"), expect(IllegalArgumentException.class, "future not done yet"));

        assertFailure(() -> checkSuccess(null, "msg"), expect(NullPointerException.class, "future is null"));
    }

    @SuppressWarnings("ReturnValueIgnored")
    private static void assertGetUncheckedListenable(Function<ListenableFuture<Object>, Object> getter)
    {
        assertEquals(getter.apply(immediateFuture("foo")), "foo");

        assertFailure(() -> getter.apply(immediateFailedFuture(new IllegalArgumentException("foo"))), e -> {
            assertInstanceOf(e, IllegalArgumentException.class);
            assertEquals(e.getMessage(), "foo");
        });

        assertFailure(() -> getter.apply(immediateFailedFuture(new SQLException("foo"))), e -> {
            assertInstanceOf(e, RuntimeException.class);
            assertInstanceOf(e.getCause(), SQLException.class);
            assertEquals(e.getCause().getMessage(), "foo");
        });

        Thread.currentThread().interrupt();
        assertFailure(() -> getter.apply(SettableFuture.create()), e -> {
            assertInstanceOf(e, RuntimeException.class);
            assertInstanceOf(e.getCause(), InterruptedException.class);
            assertTrue(Thread.interrupted());
        });
        assertFalse(Thread.currentThread().isInterrupted());

        SettableFuture<Object> canceledFuture = SettableFuture.create();
        canceledFuture.cancel(true);
        assertFailure(() -> getter.apply(canceledFuture), e -> assertInstanceOf(e, CancellationException.class));

        assertEquals(getter.apply(immediateFuture(null)), null);
    }

    public void assertGetUnchecked(UncheckedGetter getter)
            throws Exception
    {
        assertGetUncheckedInternal(getter);

        // run all test wrapped in a timeout future that does not timeout
        assertGetUncheckedInternal(future -> getter.get(addTimeout(future, () -> { throw new RuntimeException("timeout"); }, new Duration(10, SECONDS), executorService)));
    }

    private static void assertGetUncheckedInternal(UncheckedGetter getter)
            throws Exception
    {
        assertEquals(getter.get(completedFuture("foo")), "foo");

        assertFailure(() -> getter.get(failedFuture(new IllegalArgumentException("foo"))), e -> {
            assertInstanceOf(e, IllegalArgumentException.class);
            assertEquals(e.getMessage(), "foo");
        });

        assertFailure(() -> getter.get(failedFuture(new SQLException("foo"))), e -> {
            assertInstanceOf(e, RuntimeException.class);
            assertInstanceOf(e.getCause(), SQLException.class);
            assertEquals(e.getCause().getMessage(), "foo");
        });

        Thread.currentThread().interrupt();
        assertFailure(() -> getter.get(new CompletableFuture<>()), e -> {
            assertInstanceOf(e, RuntimeException.class);
            assertInstanceOf(e.getCause(), InterruptedException.class);
            assertTrue(Thread.interrupted());
        });
        assertFalse(Thread.currentThread().isInterrupted());

        CompletableFuture<Object> canceledFuture = new CompletableFuture<>();
        canceledFuture.cancel(true);
        assertFailure(() -> getter.get(canceledFuture), e -> assertInstanceOf(e, CancellationException.class));

        assertEquals(getter.get(completedFuture(null)), null);
    }

    private static void assertFailure(Thrower thrower, Consumer<Throwable> verifier)
    {
        try {
            thrower.execute();
        }
        catch (Throwable throwable) {
            verifier.accept(throwable);
            return;
        }
        fail("expected exception to be thrown");
    }

    private static Consumer<Throwable> expect(Class<? extends Throwable> expectedClass, String expectedMessagePattern)
    {
        return expect(expectedClass, expectedMessagePattern, cause -> {
        });
    }

    private static Consumer<Throwable> expect(Class<? extends Throwable> expectedClass, String expectedMessagePattern, Consumer<? super Throwable> causeVerifier)
    {
        return e -> {
            assertNotNull(e, "exception is null");
            if (!expectedClass.isInstance(e) || !nullToEmpty(e.getMessage()).matches(expectedMessagePattern)) {
                fail(format("Expected %s with message '%s', got: %s", expectedClass, expectedMessagePattern, e));
            }
            causeVerifier.accept(e.getCause());
        };
    }

    private interface UncheckedGetter
    {
        Object get(CompletableFuture<Object> future)
                throws Exception;
    }

    private interface Thrower
    {
        void execute()
                throws Throwable;
    }
}

redpajama_set_name: RedPajamaGithub


text:
Media statements | Private prosecution Media statements
Private prosecution of Thandi Modise postponed until December
By	 01/07/2020 03/11/2020
The private prosecution of Thandi Modise, Speaker of parliament, was today in the Potchefstroom Regional Court postponed until 1-3 December 2020. This…
Read More Private prosecution of Thandi Modise postponed until DecemberContinue
Warrant out for Thandi Modise's arrest in animal cruelty case
Byafriforum	 24/03/2020 03/11/2020
Thandi Modise, Speaker of the National Assembly, failed to appear in the Potchefstroom Regional Court on charges of animal abuse…
Read More Warrant out for Thandi Modise's arrest in animal cruelty caseContinue
Private prosecution of Thandi Modise to commence in March 2020
Thandi Modise, former Chairperson of the National Council of Provinces and current Speaker of the National Assembly, appeared in the…
Read More Private prosecution of Thandi Modise to commence in March 2020Continue
Thandi Modise's court appearance postponed to July
Thandi Modise, Speaker of the National Assembly, would have made her first court appearance in the Potchefstroom District Court today…
Read More Thandi Modise's court appearance postponed to JulyContinue
Thandi Modise's trial ready for private prosecution
AfriForum's Private Prosecution Unit subpoenaed Thandi Modise, Chairperson of the National Council of Provinces, to appear in the Potchefstroom Regional…
Read More Thandi Modise's trial ready for private prosecutionContinue
Gerrie Nel to prosecute Thandi Modise on charges of animal abuse
AfriForum and the National Society for the Prevention of Cruelty to Animals (NSPCA) today announced during a media conference that…
Read More Gerrie Nel to prosecute Thandi Modise on charges of animal abuseContinue
All fields marked with * are compulsory.
Name and Surname**
Cell number**
Thank you! You will henceforth weekly receive AfriForum's newsletter.
HOT-MAIL
Part of the Solidarity Movement | POPI act
Research: Reports

redpajama_set_name: RedPajamaCommonCrawl


A la cita camagüeyana se espera la asistencia, entre otros, de Los Muñequitos de Matanzas, Silvina Fabars, Premio Nacional de Danza e integrante del Conjunto Folklórico Nacional de Cuba, el grupo Yoruba Andabo, de La Habana; y Ovvatuké, de Santiago de Cuba. Desde este JUEVES y hasta el próximo domingo, sesionará en Camagüey, II encuentro Rumbatéate, dedicado a la rumba como Patrimonio Cultural de la Nación.
Yoruba Andabo is proud to be part of the third Havana World Music festival. Rumbatime!
The iconic funk rhythm band Earth, Wind & Fire will perform for the first time in Cuba during the third edition of the Havana World Music festival, organizers of the March 2016 event confirmed on Wednesday to EFE.
The U.S. band is scheduled to perform numbers from its most recent album "EW & Experience," although additional details of their show remain to be specified.
Earth, Wind & Fire will head the list of bands at the third Havana World Music festival, which will also include the Mexican band Centavrvs, nominated for a Latin Grammy; Ellas, a trio of mariachis from Los Angeles; Spaniards Jorge Pardo and Lin Cortes, and Carolina Camacho from the Dominican Republic.
So far, the host country's performers will include salsa band Havana D' Primera, singer-songwriter Kelvis Ochoa, the Yoruba Andabo folk group and jazz newcomers Yissy & Bandancha, among others.
Havana World Music was launched in 2014 by Eme Alfonso as a result of his experience in a project to investigate the island's ethnic-cultural origins.
According to the artist, the aim of the festival is to suggest to the young Cuban public "new sounds coming from different cultural areas," which make the event a forum for disseminating alternative musical styles outside normal commercial routes.


text:
Stacie Mason, MBA, Joining Stormont Vail as Senior VP and Chief Financial Officer
A Big Thank You to Manhattan Surgical Hospital and Irwin Army Community Hospital
A Great Launch at Flint Hills Campus
Dishman Participates in Morning Medical Update
"To Your Health" on WIBW-TV Tonight – Dr. Steven Seals
Stacie Mason, MBA, has accepted the role of Senior Vice President and Chief Financial Officer of Stormont Vail Health. Stacie will begin her new duties Feb. 27, 2023.
Stacie is currently Vice President of Hospital Finance at INTEGRIS Health, Oklahoma City, Okla., which is Oklahoma's largest health system. She has provided financial oversight for 11 INTEGRIS Health hospitals ranging from rural to metropolitan locations. Prior to joining INTEGRIS in 2017, Stacie served in a Chief Financial Officer role within two other Oklahoma healthcare organizations – Saint Francis Health System, Tulsa, and Southwestern Memorial Hospital, Weatherford, Okla.
We are excited for Stacie to join the Stormont Vail Health team at a time when our organization is working hard to ensure financial stability while providing the very best in care to our patients and communities. Stacie has great experience in working with both small and large hospitals, and providing expertise and support to a strong financial team.
Stacie has a bachelor's degree in Health Administration and a master's degree in Business Administration from Northeastern State University, Tahlequah, Okla., and an accounting degree from Oklahoma State University, Tulsa. She is a member of the American College of Healthcare Executives and the Healthcare Financial Management Association.
Stacie says she is looking forward to being a part of the Stormont Vail Health organization. "This is a wonderful opportunity to contribute to the mission of bringing high quality and safe care to Kansans," she says.
Peg Burnette, Stormont Vail's current Senior Vice President and Chief Financial Officer, announced last fall that she would retire in 2023. Peg returned to her Topeka roots in April 2021 when she joined Stormont Vail after her retirement from Denver Health and Hospital Authority after nearly 25 years of service as a finance executive, including 16 years as the organization's CFO.
A big thank you to our peers at Manhattan Surgical Hospital and Irwin Army Community Hospital for assisting when the sterilizer equipment at the Stormont Vail Flint Hills Hospital failed earlier this week. Through some great collaboration, we were able to get needed surgical instruments sterilized and still maintain our surgical schedule. We are in the process of purchasing new equipment at Flint Hills. We very much appreciate the teamwork with our partners in the region and look forward to supporting each other.
We've had a great first week at Stormont Vail Flint Hills in Junction City. The energy and enthusiasm by our team onsite and across the system has been phenomenal. It takes teamwork to handle a project of this magnitude. While we have many people to thank, I want to do a special call out to Judy Corzine and the Information System's team for their tremendous work to get all systems going.
Dr. Dishman Participates in Morning Medical Update
Dr. Kevin Dishman, Senior Vice President and Chief Medical and Quality Officer, participated in a Facebook Live event this week with other CMOs from across the state to discuss the impact of COVID-19, influenza and other respiratory illnesses on hospitals and healthcare organizations. Dr. Dishman noted that COVID-19 is becoming a chronic disease, which is creating challenges as hospitals are also dealing with staffing levels. He noted it is important to address and meet the medical needs in all populations, which has become even more important during the pandemic. The University of Kansas Health System produces the Morning Medical Update.
For tonight's WIBW-TV "To Your Health" segment, cardiologist Dr. Steven Seals will explain the sudden cardiac arrest of Buffalo Bills player Damar Hamlin and what he may have suffered from in Monday night's football game. Dr. Seals will explain the importance of AED and CPR education and how quick response is important to heart health. The segment will air at 10 p.m. on WIBW-TV, Channel 13. The segment will typically repeat at 5 a.m. and 6 a.m. Fridays on 13 News This Morning and be posted on wibw.com.
Posted in Communications
← Hospital Lunch Date: The 'Bulgogi Day' Tradition You Can't Afford to Miss Out On
New Year, New Strategy, New You! →


Perfect Foam Cutter Strips are deep etched dies made to cut your favorite thick adhesive foam. These strips fit perfectly under frames and shapes to create wonderful layers. These versatile shapes are easy to use and make it easy to layer all different shapes.


text:
Home > Auto > Auto News
Check out: Dacia Duster Essential features at Geneva Motor Show 2016
null | 3 March 2016 12:10 PM GMT
The limited edition series of Dacia models will be available across several European countries.Dacia stand at the 2016 Geneva Motor Show is in Hall 2...
The limited edition series of Dacia models will be available across several European countries.Dacia stand at the 2016 Geneva Motor Show is in Hall 2 and showcases the Duster Essential special edition for the Swiss market.
Dacia Duster Essential is part of a limited edition new series. Limited-edition versions of Sandero, Logan, Logan MCV, Dokker and Lodgy are being shown too. The series known as 'limited editions', offer improved travelling comfort. On the exterior, a new body color (Tourmaline Brown) and new alloy wheels accompany specific badging and body colored bumpers.
On the inside, Bluetooth and USB connectivity, electric front windows and central locking make the car convenient. Limited-edition versions are available with a three-year/100,000 km warranty. Dacia Duster Essential limited edition will be available in Austria, Belgium, Croatia, the Czech Republic, Denmark, Germany, Hungary, Italy, Luxembourg, the Netherlands, Poland, Portugal, Slovakia, Slovenia, Spain, Sweden, Switzerland and UK.
Dacia says its Easy-R automated transmission will now be paired with Dacia's dCi 90 diesel engine as well. Easy-R is already available with the tCe 90 turbo petrol engine on board Logan, Sandero, Sandero Stepway and Logan MCV. The electro-mechanical transmission is introduced in the India-spec Renault Duster later this year.
This article first appeared on rushlane.com
Delhi Auto Expo


TAKE THE LEAD: Dog owners are being challenged to walk their dogs for 30 minutes each day this August.
New research from Guide Dogs Australia shows we're not walking our dogs enough.
New research from Guide Dogs Australia shows 1 in 10 dogs are not being walked at all, while one quarter of Australian dog owners are only going on walkies once a week.
Out of the 1000 dog owners surveyed, 42 per cent said lack of time was the biggest obstacle to walking their dogs, followed by weather conditions at 35 per cent.
To help more paws hit the pavement, Guide Dogs Australia has launched PAWGUST to challenge all dog owners to walk their dog for at least 30 minutes, every day, for 30 days this August.
PAWGUST's Veterinary Ambassador Paul McGreevy said all healthy dogs – big and small – need regular walks.
"Dogs thrive on daily walks for the opportunities they provide to socialise, indulge in some one-on-one attention from their owner, explore beyond the home and discover new smells. This inspires curiosity and excitement to release endorphins and make them happier dogs," Professor McGreevy said.
Dog owners pledging to take part in PAWGUST can help raise money for people living with vision impairment.
Guide Dogs Australia plays a critical role in enabling people with impaired vision to move around their communities safely and independently, by providing orientation and mobility services, including guide dogs.


After one bride 'disinvited' her parents to her wedding Nova Wedding Planning speaks to Lembit Opik on BBC Radio Kent about family tensions at weddings and how to overcome them.
BBC Radio Kent Interview Nova About Bridesmaid's Dresses Secrets of the wedding planner REVEALED!! - 3 wedding planner myth busters From £3,900 to hire country house venue exclusively for wedding weekend BBC Radio Kent interview about bride's texting leading to quickie divorce BBC Radio Kent interview about family tensions at Weddings Nova Completes Winter Wonderland Wedding Nova wins at Kent Wedding Awards, again! Nova Wedding Planning comes to the rescue of distraught bride Bespoke Wedding Planner Kent Nova wins at Kent Wedding Awards 2013 Nouveau dishe – How the British wedding breakfast turned fine dining on its head Credit crunch weddings - how to save money and get the wedding day you always dreamed of Cake wars - sorting the croquembouche from the cupcakes!


Every year, thousands of animals are affected by increasing numbers of natural disasters such as floods, hurricanes, cyclones, earthquake and drought, while others find themselves in crisis, without food, water and shelter following these events.
Wherever possible and with thanks to the wonderful support of our many members, HSI is able to provide Emergency Relief assistance to local non-governmental organisations working on the ground in affected areas to provide relief to wildlife, livestock and companion animals.
HSI's Animal Rescue Team provided emergency care to animals in need and helped veterinary clinics get back up and running across mainland Puerto Rico following the devastation caused by Hurricane Maria. HSUS and HSI veterinarians delivered approximately 70,000 pounds of humanitarian and animal aid supplies, including water, diapers, baby food, dog, cat, and equine food, and more, to the island's residents. More than 1,200 animals were transported from shelters in Puerto Rico to more than 50 animal rescue organizations in the United States. HSI remains on the ground to help distribute supplies, provide life-saving vaccines and rescue animals in the aftermath of the hurricane. To read more about our disaster relief work Puerto Rico, visit our blog here.
Sadly Mexico suffered two major earthquakes in September 2017 in as many weeks. HSI/Mexico's veterinary team responded to the deadly earthquake that severely affected the States of Oaxaca and Chiapas, in the southern part of the country. That earthquake killed more than 90 people and destroyed thousands of homes, in a region heavily affected by natural disasters and complex economic problems, and where animals are, in many cases, all that people who have lost their homes and family members have left. HSI's team set up an emergency clinic and provided treatment for 1,350 animals, mainly cats and dogs.
Our HSI/Mexico team then rushed to Mexico City to provide rescue and relief efforts to animals affected by the second devastating earthquake that struck the region. The 7.1 magnitude earthquake tragically killed more than 300 people in Mexico City, Morelos and Puebla. Our team set up emergency clinics and provided care to 805 animals in Morelos State including dogs, cats, horses, and more. Read more about our disaster response in Mexico here.
Hurricane Irma was a catastrophic Category 5 hurricane that made landfall in Florida of the US in September 2017 and left devastation across the Caribbean. In the wake of the devastating impact of Hurricane Irma in the British Virgin Islands, HSI and H/3 Foundation deployed a veterinary team, with emergency animal supplies, to assist with animal rescue efforts on the ground and help evacuate displaced pets to safety.
Hurricane Harvey was a Category 4 storm that hit Texas in August of 2017. The HSUS/HSI responded with people and other resources before and after Hurricane Harvey swamped southeast Texas. Our Animal Rescue Team deployed and began searching house to house for animals in danger. We activated our national network of Emergency Placement Partners, and began conducting transports of animals from Texas in order to relieve the burden on oversubscribed shelters, so that we could free up space for surrendered or displaced animals. To read more on our disaster relief efforts in Texas, head to our blog here.
We provided emergency animal rescue and treatment for animals in Haiti, following the devastation left by Hurricane Matthew. The HSI team set up emergency clinics and provided treatment for approximately 1,500 animals, including horses, cows, donkeys, cats, dogs, goats, sheep, pigs, mules, calves, and chickens.
Himalayan Animal Rescue Trust (HART) have been working throughout Nepal since 2010 striving to create a place where animals are respected and cared for within their own community, and disease and distress are things of the past. When Nepal was hit by the earthquake in April 2015 HART were one of the groups coordinating the rescue efforts on the ground, and meeting and transporting the Australian volunteer vets we sent. Click here to read the full after-action report of HSI's emergency response to the Nepal earthquake.
In December 2016, HSI Australia was fortunate enough to interview Khageshwaar Sharma, the Director of the Himalayan Animal Rescue Trust (HART) about the incredible disaster relief work they implement across the region. Click here to learn more.
2011 - As the worst floods in 50 years continue to wreak Havoc in Thailand, HSI's local partner, Soi Dog Foundation, contacted us with a plea for help. Quickly, we arranged for emergency funding to buy much-needed supplies and sent in a disaster response team led by Rahul Sehgal, Director of HSI India.
The HSI disaster response team, including Sehgal and HSI vets Dr. Del Napoles and Dr. Patel, arrived in Bangkok, equipped with nets, trauma kits and an inflatable raft in preparation for finding and treating stranded or injured animals. There, they met with representatives of the Soi Dog Foundation and the World Society for the Protection of Animalsto discuss coordination of a disaster assessment and involvement in a rescue operation already under way.
Read more about HSI's on ground efforts in Thailand. Click here.