1 package com.simpligility.maven.plugins.android;
2
3 import static org.easymock.EasyMock.anyObject;
4 import static org.easymock.EasyMock.expect;
5 import static org.easymock.EasyMock.isNull;
6 import static org.easymock.EasyMock.replay;
7 import static org.easymock.EasyMock.verify;
8 import static org.junit.Assert.fail;
9 import static org.powermock.api.easymock.PowerMock.createMock;
10 import static org.powermock.api.easymock.PowerMock.mockStatic;
11
12 import java.io.IOException;
13 import java.util.List;
14
15 import org.apache.maven.plugin.MojoExecutionException;
16 import org.apache.maven.plugin.MojoFailureException;
17 import org.junit.Before;
18 import org.junit.Ignore;
19 import org.junit.Test;
20 import org.junit.runner.RunWith;
21 import org.powermock.api.easymock.PowerMock;
22 import org.powermock.core.classloader.annotations.PrepareForTest;
23 import org.powermock.modules.junit4.PowerMockRunner;
24
25 import com.android.ddmlib.AdbCommandRejectedException;
26 import com.android.ddmlib.AndroidDebugBridge;
27 import com.android.ddmlib.IDevice;
28 import com.android.ddmlib.ShellCommandUnresponsiveException;
29 import com.android.ddmlib.TimeoutException;
30
31 @RunWith( PowerMockRunner.class )
32 @PrepareForTest(
33 { AndroidDebugBridge.class, CommandExecutor.Factory.class } )
34 @Ignore("Does not work anymore with new sdk")
35 public class AbstractEmulatorMojoTest
36 {
37 private static final String AVD_NAME = "emulator";
38 private static final long DEFAULT_TIMEOUT = 500;
39 private AbstractEmulatorMojoToTest abstractEmulatorMojo;
40 private CommandExecutor mockExecutor;
41 private AndroidDebugBridge mockAndroidDebugBridge;
42
43 @Before
44 public void setUp() throws Exception
45 {
46 mockExecutor = PowerMock.createNiceMock( CommandExecutor.class );
47 mockExecutor.executeCommand( anyObject( String.class ), isNull( List.class ) );
48 PowerMock.replay( mockExecutor );
49
50 mockStatic( CommandExecutor.Factory.class );
51 expect( CommandExecutor.Factory.createDefaultCommmandExecutor() ).andReturn( mockExecutor );
52 PowerMock.replay( CommandExecutor.Factory.class );
53
54 mockAndroidDebugBridge = createMock( AndroidDebugBridge.class );
55
56 abstractEmulatorMojo = new AbstractEmulatorMojoToTest();
57 }
58
59 @Test
60 public void testStartAndroidEmulatorWithTimeoutToConnect() throws MojoExecutionException, ExecutionException
61 {
62 boolean onlineAtSecondTry = false;
63 int extraBootStatusPollCycles = -1;
64 abstractEmulatorMojo.setWait( DEFAULT_TIMEOUT );
65
66 IDevice emulatorDevice = withEmulatorDevice( onlineAtSecondTry, extraBootStatusPollCycles );
67
68 withConnectedDebugBridge( emulatorDevice );
69
70 try
71 {
72 abstractEmulatorMojo.startAndroidEmulator();
73 fail();
74 }
75 catch ( MojoExecutionException e )
76 {
77 verify( mockExecutor );
78 }
79 }
80
81 @Test
82 public void testStartAndroidEmulatorAlreadyBooted() throws MojoExecutionException, ExecutionException
83 {
84 boolean onlineAtSecondTry = true;
85 int extraBootStatusPollCycles = 0;
86 abstractEmulatorMojo.setWait( DEFAULT_TIMEOUT );
87
88 IDevice emulatorDevice = withEmulatorDevice( onlineAtSecondTry, extraBootStatusPollCycles );
89 withConnectedDebugBridge( emulatorDevice );
90
91 abstractEmulatorMojo.startAndroidEmulator();
92
93 verify( mockExecutor );
94 }
95
96 @Test
97 public void testStartAndroidEmulatorWithOngoingBoot() throws MojoExecutionException, ExecutionException
98 {
99 boolean onlineAtSecondTry = true;
100 int extraBootStatusPollCycles = 1;
101 abstractEmulatorMojo.setWait( extraBootStatusPollCycles * 5000 + 500 );
102
103 IDevice emulatorDevice = withEmulatorDevice( onlineAtSecondTry, extraBootStatusPollCycles );
104 withConnectedDebugBridge( emulatorDevice );
105
106 abstractEmulatorMojo.startAndroidEmulator();
107
108 verify( mockExecutor );
109 }
110
111 @Test
112 public void testStartAndroidEmulatorWithBootTimeout() throws MojoExecutionException, ExecutionException
113 {
114 boolean onlineAtSecondTry = true;
115 int extraBootStatusPollCycles = -1;
116 abstractEmulatorMojo.setWait( DEFAULT_TIMEOUT );
117
118 IDevice emulatorDevice = withEmulatorDevice( onlineAtSecondTry, extraBootStatusPollCycles );
119 withConnectedDebugBridge( emulatorDevice );
120
121 try
122 {
123 abstractEmulatorMojo.startAndroidEmulator();
124 fail();
125 }
126 catch ( MojoExecutionException e )
127 {
128 verify( mockExecutor );
129 }
130 }
131
132
133
134
135
136
137 private IDevice withEmulatorDevice( boolean onlineAtSecondTry, int extraBootStatusPollCycles )
138 {
139 IDevice emulatorDevice = createMock( IDevice.class );
140 expect( emulatorDevice.getAvdName() ).andReturn( AVD_NAME ).atLeastOnce();
141 expect( emulatorDevice.isEmulator() ).andReturn( true ).atLeastOnce();
142 if ( onlineAtSecondTry )
143 {
144 try
145 {
146 expect( emulatorDevice.isOnline() ).andReturn( false ).andReturn( true );
147
148 if ( extraBootStatusPollCycles < 0 )
149 {
150
151 expect( emulatorDevice.getPropertySync( "dev.bootcomplete" ) )
152 .andReturn( null ).atLeastOnce();
153 expect( emulatorDevice.getPropertySync( "sys.boot_completed" ) )
154 .andReturn( null ).atLeastOnce();
155 expect( emulatorDevice.getPropertySync( "init.svc.bootanim" ) )
156 .andReturn( null ).once()
157 .andReturn( "running" ).atLeastOnce();
158 }
159 else if ( extraBootStatusPollCycles == 0 )
160 {
161
162 expect( emulatorDevice.getPropertySync( "dev.bootcomplete" ) )
163 .andReturn( "1" ).once();
164 expect( emulatorDevice.getPropertySync( "sys.boot_completed" ) )
165 .andReturn( "1" ).once();
166 expect( emulatorDevice.getPropertySync( "init.svc.bootanim" ) )
167 .andReturn( "stopped" ).once();
168 }
169 else if ( extraBootStatusPollCycles == 1 )
170 {
171
172 expect( emulatorDevice.getPropertySync( "dev.bootcomplete" ) )
173 .andReturn( null ).once()
174 .andReturn( "1" ).once();
175 expect( emulatorDevice.getPropertySync( "sys.boot_completed" ) )
176 .andReturn( null ).once()
177 .andReturn( "1" ).once();
178 expect( emulatorDevice.getPropertySync( "init.svc.bootanim" ) )
179 .andReturn( "running" ).once()
180 .andReturn( "stopped" ).once();
181 }
182 else if( extraBootStatusPollCycles >=3 )
183 {
184
185 expect( emulatorDevice.getPropertySync( "dev.bootcomplete" ) )
186 .andReturn( null ).times( extraBootStatusPollCycles - 1 )
187 .andReturn( "1" ).once();
188 expect( emulatorDevice.getPropertySync( "sys.boot_completed" ) )
189 .andReturn( null ).times( extraBootStatusPollCycles - 1 )
190 .andReturn( "1" ).once();
191 expect( emulatorDevice.getPropertySync( "init.svc.bootanim" ) )
192 .andReturn( null ).times( extraBootStatusPollCycles / 2 )
193 .andReturn( "running" ).times( extraBootStatusPollCycles / 2 + extraBootStatusPollCycles % 2 )
194 .andReturn( "stopped" ).once();
195 }
196 else if( extraBootStatusPollCycles >=2 )
197 {
198
199 expect( emulatorDevice.getPropertySync( "dev.bootcomplete" ) )
200 .andReturn( null ).times( extraBootStatusPollCycles - 1 )
201 .andReturn( "1" ).once();
202 expect( emulatorDevice.getPropertySync( "sys.boot_completed" ) )
203 .andReturn( null ).times( extraBootStatusPollCycles - 1 )
204 .andReturn( "1" ).once();
205 expect( emulatorDevice.getPropertySync( "init.svc.bootanim" ) )
206 .andReturn( "running" ).times( extraBootStatusPollCycles -1 )
207 .andReturn( "stopped" ).once();
208 }
209 }
210 catch ( TimeoutException e)
211 {
212 throw new RuntimeException( "Unexpected checked exception during mock setup", e );
213 }
214 catch ( AdbCommandRejectedException e)
215 {
216 throw new RuntimeException( "Unexpected checked exception during mock setup", e );
217 }
218 catch ( ShellCommandUnresponsiveException e)
219 {
220 throw new RuntimeException( "Unexpected checked exception during mock setup", e );
221 }
222 catch ( IOException e )
223 {
224 throw new RuntimeException( "Unexpected checked exception during mock setup", e );
225 }
226 }
227 else
228 {
229 expect( emulatorDevice.isOnline() ).andReturn( false ).atLeastOnce();
230 }
231 replay( emulatorDevice );
232 return emulatorDevice;
233 }
234
235 private void withConnectedDebugBridge( IDevice emulatorDevice )
236 {
237 expect( mockAndroidDebugBridge.isConnected() ).andReturn( true );
238 expect( mockAndroidDebugBridge.hasInitialDeviceList() ).andReturn( true );
239 expect( mockAndroidDebugBridge.getDevices() ).andReturn( new IDevice[ 0 ] ).andReturn( new IDevice[]
240 { emulatorDevice } ).atLeastOnce();
241 replay( mockAndroidDebugBridge );
242 }
243
244 private class AbstractEmulatorMojoToTest extends AbstractEmulatorMojo
245 {
246 private long wait = DEFAULT_TIMEOUT;
247
248 public long getWait()
249 {
250 return wait;
251 }
252
253 public void setWait( long wait )
254 {
255 this.wait = wait;
256 }
257
258 @Override
259 protected AndroidSdk getAndroidSdk()
260 {
261 return new SdkTestSupport().getSdk_with_platform_default();
262 }
263
264 @Override
265 public void execute() throws MojoExecutionException, MojoFailureException
266 {
267 }
268
269 @Override
270 protected AndroidDebugBridge initAndroidDebugBridge() throws MojoExecutionException
271 {
272 return mockAndroidDebugBridge;
273 }
274
275 @Override
276 String determineAvd()
277 {
278 return AVD_NAME;
279 }
280
281 @Override
282 String determineWait()
283 {
284 return String.valueOf( wait );
285 }
286 }
287
288 }