1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
33
34
35
36
37 public class AbstractIdleServiceTest extends TestCase {
38
39
40
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
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 }