View Javadoc
1   /*
2    * Copyright (C) 2009 The Guava Authors
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package com.google.common.util.concurrent;
18  
19  import static com.google.common.truth.Truth.assertThat;
20  import static com.google.common.util.concurrent.MoreExecutors.directExecutor;
21  
22  import com.google.common.collect.Lists;
23  
24  import junit.framework.TestCase;
25  
26  import java.util.List;
27  import java.util.concurrent.Executor;
28  import java.util.concurrent.TimeUnit;
29  import java.util.concurrent.TimeoutException;
30  
31  /**
32   * Tests for {@link AbstractIdleService}.
33   *
34   * @author Chris Nokleberg
35   * @author Ben Yu
36   */
37  public class AbstractIdleServiceTest extends TestCase {
38  
39    // Functional tests using real thread. We only verify publicly visible state.
40    // Interaction assertions are done by the single-threaded unit tests.
41  
42    public static class FunctionalTest extends TestCase {
43  
44      private static class DefaultService extends AbstractIdleService {
45        @Override protected void startUp() throws Exception {}
46        @Override protected void shutDown() throws Exception {}
47      }
48  
49      public void testServiceStartStop() throws Exception {
50        AbstractIdleService service = new DefaultService();
51        service.startAsync().awaitRunning();
52        assertEquals(Service.State.RUNNING, service.state());
53        service.stopAsync().awaitTerminated();
54        assertEquals(Service.State.TERMINATED, service.state());
55      }
56  
57      public void testStart_failed() throws Exception {
58        final Exception exception = new Exception("deliberate");
59        AbstractIdleService service = new DefaultService() {
60          @Override protected void startUp() throws Exception {
61            throw exception;
62          }
63        };
64        try {
65          service.startAsync().awaitRunning();
66          fail();
67        } catch (RuntimeException e) {
68          assertSame(exception, e.getCause());
69        }
70        assertEquals(Service.State.FAILED, service.state());
71      }
72  
73      public void testStop_failed() throws Exception {
74        final Exception exception = new Exception("deliberate");
75        AbstractIdleService service = new DefaultService() {
76          @Override protected void shutDown() throws Exception {
77            throw exception;
78          }
79        };
80        service.startAsync().awaitRunning();
81        try {
82          service.stopAsync().awaitTerminated();
83          fail();
84        } catch (RuntimeException e) {
85          assertSame(exception, e.getCause());
86        }
87        assertEquals(Service.State.FAILED, service.state());
88      }
89    }
90  
91    public void testStart() {
92      TestService service = new TestService();
93      assertEquals(0, service.startUpCalled);
94      service.startAsync().awaitRunning();
95      assertEquals(1, service.startUpCalled);
96      assertEquals(Service.State.RUNNING, service.state());
97      assertThat(service.transitionStates).has().exactly(Service.State.STARTING).inOrder();
98    }
99  
100   public void testStart_failed() {
101     final Exception exception = new Exception("deliberate");
102     TestService service = new TestService() {
103       @Override protected void startUp() throws Exception {
104         super.startUp();
105         throw exception;
106       }
107     };
108     assertEquals(0, service.startUpCalled);
109     try {
110       service.startAsync().awaitRunning();
111       fail();
112     } catch (RuntimeException e) {
113       assertSame(exception, e.getCause());
114     }
115     assertEquals(1, service.startUpCalled);
116     assertEquals(Service.State.FAILED, service.state());
117     assertThat(service.transitionStates).has().exactly(Service.State.STARTING).inOrder();
118   }
119 
120   public void testStop_withoutStart() {
121     TestService service = new TestService();
122     service.stopAsync().awaitTerminated();
123     assertEquals(0, service.startUpCalled);
124     assertEquals(0, service.shutDownCalled);
125     assertEquals(Service.State.TERMINATED, service.state());
126     assertThat(service.transitionStates).isEmpty();
127   }
128 
129   public void testStop_afterStart() {
130     TestService service = new TestService();
131     service.startAsync().awaitRunning();
132     assertEquals(1, service.startUpCalled);
133     assertEquals(0, service.shutDownCalled);
134     service.stopAsync().awaitTerminated();
135     assertEquals(1, service.startUpCalled);
136     assertEquals(1, service.shutDownCalled);
137     assertEquals(Service.State.TERMINATED, service.state());
138     assertThat(service.transitionStates)
139         .has().exactly(Service.State.STARTING, Service.State.STOPPING).inOrder();
140   }
141 
142   public void testStop_failed() {
143     final Exception exception = new Exception("deliberate");
144     TestService service = new TestService() {
145       @Override protected void shutDown() throws Exception {
146         super.shutDown();
147         throw exception;
148       }
149     };
150     service.startAsync().awaitRunning();
151     assertEquals(1, service.startUpCalled);
152     assertEquals(0, service.shutDownCalled);
153     try {
154       service.stopAsync().awaitTerminated();
155       fail();
156     } catch (RuntimeException e) {
157       assertSame(exception, e.getCause());
158     }
159     assertEquals(1, service.startUpCalled);
160     assertEquals(1, service.shutDownCalled);
161     assertEquals(Service.State.FAILED, service.state());
162     assertThat(service.transitionStates)
163         .has().exactly(Service.State.STARTING, Service.State.STOPPING).inOrder();
164   }
165 
166   public void testServiceToString() {
167     AbstractIdleService service = new TestService();
168     assertEquals("TestService [NEW]", service.toString());
169     service.startAsync().awaitRunning();
170     assertEquals("TestService [RUNNING]", service.toString());
171     service.stopAsync().awaitTerminated();
172     assertEquals("TestService [TERMINATED]", service.toString());
173   }
174 
175   public void testTimeout() throws Exception {
176     // Create a service whose executor will never run its commands
177     Service service = new TestService() {
178       @Override protected Executor executor() {
179         return new Executor() {
180           @Override public void execute(Runnable command) {}
181         };
182       }
183     };
184     try {
185       service.startAsync().awaitRunning(1, TimeUnit.MILLISECONDS);
186       fail("Expected timeout");
187     } catch (TimeoutException e) {
188       assertThat(e.getMessage()).contains(Service.State.STARTING.toString());
189     }
190   }
191 
192   private static class TestService extends AbstractIdleService {
193     int startUpCalled = 0;
194     int shutDownCalled = 0;
195     final List<State> transitionStates = Lists.newArrayList();
196 
197     @Override protected void startUp() throws Exception {
198       assertEquals(0, startUpCalled);
199       assertEquals(0, shutDownCalled);
200       startUpCalled++;
201       assertEquals(State.STARTING, state());
202     }
203 
204     @Override protected void shutDown() throws Exception {
205       assertEquals(1, startUpCalled);
206       assertEquals(0, shutDownCalled);
207       shutDownCalled++;
208       assertEquals(State.STOPPING, state());
209     }
210 
211     @Override protected Executor executor() {
212       transitionStates.add(state());
213       return directExecutor();
214     }
215   }
216 }