Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 package com.facebook.presto.execution;
 
 
 
 import static io.airlift.concurrent.Threads.daemonThreadsNamed;
 import static java.util.concurrent.Executors.newCachedThreadPool;
 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.assertTrue;
 import static org.testng.Assert.fail;
 
 public class TestStateMachine
 {
     private enum State
     {
         BREAKFAST, LUNCH, DINNER
     }
 
     private final ExecutorService executor = newCachedThreadPool(daemonThreadsNamed("test-%s"));
 
     @AfterClass
     public void tearDown()
             throws Exception
     {
         .shutdownNow();
     }
 
     @Test
     public void testNullState()
             throws Exception
     {
         try {
             new StateMachine<>("test"null);
             fail("expected a NullPointerException");
         }
         catch (NullPointerException exception) {
         }
 
         StateMachine<StatestateMachine = new StateMachine<>("test".);
 
         assertNoStateChange(stateMachine, () -> {
             try {
                 stateMachine.set(null);
                 fail("expected a NullPointerException");
             }
             catch (NullPointerException exception) {
             }
         });
 
         assertNoStateChange(stateMachine, () -> {
             try {
                 stateMachine.compareAndSet(.null);
                 fail("expected a NullPointerException");
             }
             catch (NullPointerException exception) {
             }
         });
 
         assertNoStateChange(stateMachine, () -> {
             try {
                 stateMachine.compareAndSet(.null);
                 fail("expected a NullPointerException");
             }
             catch (NullPointerException exception) {
             }
         });
 
         assertNoStateChange(stateMachine, () -> {
             try {
                 stateMachine.setIf(nullcurrentState -> true);
                 fail("expected a NullPointerException");
             }
             catch (NullPointerException exception) {
             }
         });
        assertNoStateChange(stateMachine, () -> {
            try {
                stateMachine.setIf(nullcurrentState -> false);
                fail("expected a NullPointerException");
            }
            catch (NullPointerException exception) {
            }
        });
    }
    @Test
    public void testSet()
            throws Exception
    {
        StateMachine<StatestateMachine = new StateMachine<>("test"., ImmutableSet.of(.));
        assertEquals(stateMachine.get(), .);
        assertNoStateChange(stateMachine, () -> assertEquals(stateMachine.set(.), .));
        assertStateChange(stateMachine, () -> assertEquals(stateMachine.set(.), .), .);
        assertStateChange(stateMachine, () -> assertEquals(stateMachine.set(.), .), .);
        // transition to a final state
        assertStateChange(stateMachine, () -> assertEquals(stateMachine.set(.), .), .);
        // attempt transition from a final state
        assertNoStateChange(stateMachine, () -> {
            try {
                stateMachine.set(.);
                fail("expected IllegalStateException");
            }
            catch (IllegalStateException expected) {
            }
        });
        assertNoStateChange(stateMachine, () -> stateMachine.set(.));
    }
    @Test
    public void testCompareAndSet()
            throws Exception
    {
        StateMachine<StatestateMachine = new StateMachine<>("test"., ImmutableSet.of(.));
        assertEquals(stateMachine.get(), .);
        // no match with new state
        assertNoStateChange(stateMachine, () -> stateMachine.compareAndSet(..));
        // match with new state
        assertStateChange(stateMachine,
                () -> stateMachine.compareAndSet(..),
                .);
        // no match with same state
        assertNoStateChange(stateMachine, () -> stateMachine.compareAndSet(..));
        // match with same state
        assertNoStateChange(stateMachine, () -> stateMachine.compareAndSet(..));
        // transition to a final state
        assertStateChange(stateMachine, () -> stateMachine.compareAndSet(..), .);
        // attempt transition from a final state
        assertNoStateChange(stateMachine, () -> {
            try {
                stateMachine.compareAndSet(..);
                fail("expected IllegalStateException");
            }
            catch (IllegalStateException expected) {
            }
        });
        assertNoStateChange(stateMachine, () -> stateMachine.compareAndSet(..));
    }
    @Test
    public void testSetIf()
            throws Exception
    {
        StateMachine<StatestateMachine = new StateMachine<>("test"., ImmutableSet.of(.));
        assertEquals(stateMachine.get(), .);
        // false predicate with new state
        assertNoStateChange(stateMachine,
                () -> assertFalse(stateMachine.setIf(.currentState -> {
                    assertEquals(currentState.);
                    return false;
                })));
        // true predicate with new state
        assertStateChange(stateMachine,
                () -> assertTrue(stateMachine.setIf(.currentState -> {
                    assertEquals(currentState.);
                    return true;
                })),
                .);
        // false predicate with same state
        assertNoStateChange(stateMachine,
                () -> assertFalse(stateMachine.setIf(.currentState -> {
                    assertEquals(currentState.);
                    return false;
                })));
        // true predicate with same state
        assertNoStateChange(stateMachine,
                () -> assertFalse(stateMachine.setIf(.currentState -> {
                    assertEquals(currentState.);
                    return true;
                })));
        // transition to a final state
        assertStateChange(stateMachine, () -> stateMachine.setIf(.currentState -> true), .);
        // attempt transition from a final state
        assertNoStateChange(stateMachine, () -> {
            try {
                stateMachine.setIf(.currentState -> true);
                fail("expected IllegalStateException");
            }
            catch (IllegalStateException expected) {
            }
        });
        assertNoStateChange(stateMachine, () -> stateMachine.setIf(.currentState -> false));
        assertNoStateChange(stateMachine, () -> stateMachine.setIf(.currentState -> true));
    }
    private void assertStateChange(StateMachine<StatestateMachineStateChanger stateChangeState expectedState)
            throws Exception
    {
        State initialState = stateMachine.get();
        ListenableFuture<StatefutureChange = stateMachine.getStateChange(initialState);
        SettableFuture<StatelistenerChange = SettableFuture.create();
        stateMachine.addStateChangeListener(listenerChange::set);
        Future<StatewaitChange = .submit(() -> {
            try {
                stateMachine.waitForStateChange(initialStatenew Duration(10, ));
                return stateMachine.get();
            }
            catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                throw Throwables.propagate(e);
            }
            catch (Exception e) {
                throw Throwables.propagate(e);
            }
        });
        stateChange.run();
        assertEquals(stateMachine.get(), expectedState);
        assertEquals(futureChange.get(1, ), expectedState);
        assertEquals(listenerChange.get(1, ), expectedState);
        assertEquals(waitChange.get(1, ), expectedState);
        // listeners should not be retained if we are in a terminal state
        boolean isTerminalState = stateMachine.isTerminalState(expectedState);
        if (isTerminalState) {
            assertEquals(stateMachine.getFutureStateChanges(), ImmutableSet.of());
            assertEquals(stateMachine.getStateChangeListeners(), ImmutableSet.of());
        }
    }
    private void assertNoStateChange(StateMachine<StatestateMachineStateChanger stateChange)
            throws Exception
    {
        State initialState = stateMachine.get();
        ListenableFuture<StatefutureChange = stateMachine.getStateChange(initialState);
        SettableFuture<StatelistenerChange = SettableFuture.create();
        stateMachine.addStateChangeListener(listenerChange::set);
        Future<StatewaitChange = .submit(() -> {
            try {
                stateMachine.waitForStateChange(initialStatenew Duration(10, ));
                return stateMachine.get();
            }
            catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                throw Throwables.propagate(e);
            }
        });
        // listeners should not be added if we are in a terminal state
        boolean isTerminalState = stateMachine.isTerminalState(initialState);
        if (isTerminalState) {
            assertEquals(stateMachine.getFutureStateChanges(), ImmutableSet.of());
            assertEquals(stateMachine.getStateChangeListeners(), ImmutableSet.of());
        }
        stateChange.run();
        assertEquals(stateMachine.get(), initialState);
        try {
            // none of the futures should finish, but there is no way to prove that
            // the state change is not happening (the changes happen in another thread),
            // so we wait a short time for nothing to happen.
            waitChange.get(50, );
        }
        catch (InterruptedException e) {
            throw e;
        }
        catch (Exception ignored) {
        }
        // the state change listeners will trigger if the state machine is in a terminal state
        // this is to prevent waiting for state changes that will never occur
        assertEquals(futureChange.isDone(), isTerminalState);
        futureChange.cancel(true);
        assertEquals(listenerChange.isDone(), isTerminalState);
        listenerChange.cancel(true);
        assertEquals(waitChange.isDone(), isTerminalState);
        waitChange.cancel(true);
    }
    private interface StateChanger
    {
        void run()
                throws Exception;
    }
New to GrepCode? Check out our FAQ X