1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.simpligility.maven.plugins.android.standalonemojos;
18
19 import java.io.IOException;
20
21 import org.apache.maven.plugin.MojoExecutionException;
22 import org.apache.maven.plugin.MojoFailureException;
23 import org.apache.maven.plugins.annotations.Mojo;
24 import org.apache.maven.plugins.annotations.Parameter;
25
26 import com.android.ddmlib.AdbCommandRejectedException;
27 import com.android.ddmlib.IDevice;
28 import com.android.ddmlib.ShellCommandUnresponsiveException;
29 import com.android.ddmlib.TimeoutException;
30 import com.android.ddmlib.testrunner.MonkeyTestRunner;
31 import com.simpligility.maven.plugins.android.AbstractAndroidMojo;
32 import com.simpligility.maven.plugins.android.AndroidTestRunListener;
33 import com.simpligility.maven.plugins.android.DeviceCallback;
34 import com.simpligility.maven.plugins.android.common.DeviceHelper;
35 import com.simpligility.maven.plugins.android.config.ConfigHandler;
36 import com.simpligility.maven.plugins.android.config.ConfigPojo;
37 import com.simpligility.maven.plugins.android.config.PullParameter;
38 import com.simpligility.maven.plugins.android.configuration.Monkey;
39
40
41
42
43
44
45
46
47
48
49
50
51 @SuppressWarnings( "unused" )
52 @Mojo( name = "monkey" )
53 public class MonkeyMojo extends AbstractAndroidMojo
54 {
55
56
57
58 @Parameter( property = "maven.test.skip", defaultValue = "false", readonly = true )
59 private boolean mavenTestSkip;
60
61
62
63
64 @Parameter( property = "skipTests", defaultValue = "false", readonly = true )
65 private boolean mavenSkipTests;
66
67
68
69
70
71 @Parameter( property = "maven.test.failure.ignore", defaultValue = "false", readonly = true )
72 private boolean mavenTestFailureIgnore;
73
74
75
76
77
78 @Parameter( property = "testFailureIgnore", defaultValue = "false", readonly = true )
79 private boolean mavenIgnoreTestFailure;
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130 @Parameter
131 @ConfigPojo
132 private Monkey monkey;
133
134
135
136
137
138 @Parameter( property = "android.monkey.skip" )
139 private Boolean monkeySkip;
140
141 @PullParameter( defaultValue = "true" )
142 private Boolean parsedSkip;
143
144
145
146
147 @Parameter( property = "android.monkey.eventCount" )
148 private Integer monkeyEventCount;
149
150 @PullParameter( required = true, defaultValue = "1000" )
151 private Integer parsedEventCount;
152
153
154
155
156
157 @Parameter( property = "android.monkey.seed" )
158 private Long monkeySeed;
159
160 @PullParameter( required = false, defaultValueGetterMethod = "getSeed" )
161 private Long parsedSeed;
162
163
164
165
166
167 @Parameter( property = "android.monkey.throttle" )
168 private Long monkeyThrottle;
169
170 @PullParameter( required = false, defaultValueGetterMethod = "getThrottle" )
171 private Long parsedThrottle;
172
173
174
175
176 @Parameter( property = "android.monkey.percentTouch" )
177 private Integer monkeyPercentTouch;
178
179 @PullParameter( required = false, defaultValueGetterMethod = "getPercentTouch" )
180 private Integer parsedPercentTouch;
181
182
183
184
185
186 @Parameter( property = "android.monkey.percentMotion" )
187 private Integer monkeyPercentMotion;
188
189 @PullParameter( required = false, defaultValueGetterMethod = "getPercentMotion" )
190 private Integer parsedPercentMotion;
191
192
193
194
195
196 @Parameter( property = "android.monkey.percentTrackball" )
197 private Integer monkeyPercentTrackball;
198
199 @PullParameter( required = false, defaultValueGetterMethod = "getPercentTrackball" )
200 private Integer parsedPercentTrackball;
201
202
203
204
205
206 @Parameter( property = "android.monkey.percentNav" )
207 private Integer monkeyPercentNav;
208
209 @PullParameter( required = false, defaultValueGetterMethod = "getPercentNav" )
210 private Integer parsedPercentNav;
211
212
213
214
215
216 @Parameter( property = "android.monkey.percentMajorNav" )
217 private Integer monkeyPercentMajorNav;
218
219 @PullParameter( required = false, defaultValueGetterMethod = "getPercentMajorNav" )
220 private Integer parsedPercentMajorNav;
221
222
223
224
225
226 @Parameter( property = "android.monkey.percentSyskeys" )
227 private Integer monkeyPercentSyskeys;
228
229 @PullParameter( required = false, defaultValueGetterMethod = "getPercentSyskeys" )
230 private Integer parsedPercentSyskeys;
231
232
233
234
235
236 @Parameter( property = "android.monkey.percentAppswitch" )
237 private Integer monkeyPercentAppswitch;
238
239 @PullParameter( required = false, defaultValueGetterMethod = "getPercentAppswitch" )
240 private Integer parsedPercentAppswitch;
241
242
243
244
245
246 @Parameter( property = "android.monkey.percentAnyevent" )
247 private Integer monkeyPercentAnyEvent;
248
249 @PullParameter( required = false, defaultValueGetterMethod = "getPercentAnyevent" )
250 private Integer parsedPercentAnyevent;
251
252
253
254
255
256
257
258 @Parameter( property = "android.monkey.packages" )
259 private String[] monkeyPackages;
260
261 @PullParameter( required = false, defaultValueGetterMethod = "getPackages" )
262 private String[] parsedPackages;
263
264
265
266
267
268
269 @Parameter( property = "android.monkey.categories" )
270 private String[] monkeyCategories;
271
272 @PullParameter( required = false, defaultValueGetterMethod = "getCategories" )
273 private String[] parsedCategories;
274
275
276
277
278
279
280
281 @Parameter( property = "android.monkey.debugNoEvents" )
282 private Boolean monkeyDebugNoEvents;
283
284 @PullParameter( defaultValue = "false" )
285 private Boolean parsedDebugNoEvents;
286
287
288
289
290
291
292 @Parameter( property = "android.monkey.Hprof" )
293 private Boolean monkeyHprof;
294
295 @PullParameter( defaultValue = "false" )
296 private Boolean parsedHprof;
297
298
299
300
301
302
303
304 @Parameter( property = "android.monkey.ignoreCrashes" )
305 private Boolean monkeyIgnoreCrashes;
306
307 @PullParameter( defaultValue = "false" )
308 private Boolean parsedIgnoreCrashes;
309
310
311
312
313
314
315
316
317 @Parameter( property = "android.monkey.IgnoreTimeouts" )
318 private Boolean monkeyIgnoreTimeouts;
319
320 @PullParameter( defaultValue = "false" )
321 private Boolean parsedIgnoreTimeouts;
322
323
324
325
326
327
328
329
330 @Parameter( property = "android.monkey.IgnoreSecurityExceptions" )
331 private Boolean monkeyIgnoreSecurityExceptions;
332
333 @PullParameter( defaultValue = "false" )
334 private Boolean parsedIgnoreSecurityExceptions;
335
336
337
338
339
340
341
342
343
344 @Parameter( property = "android.monkey.KillProcessAfterError" )
345 private Boolean monkeyKillProcessAfterError;
346
347 @PullParameter( defaultValue = "false" )
348 private Boolean parsedKillProcessAfterError;
349
350
351
352
353
354
355
356 @Parameter( property = "android.monkey.MonitorNativeCrashes" )
357 private Boolean monkeyMonitorNativeCrashes;
358
359 @PullParameter( defaultValue = "false" )
360 private Boolean parsedMonitorNativeCrashes;
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380 @Parameter( property = "android.monkey.createReport" )
381 private Boolean monkeyCreateReport;
382
383 @PullParameter( defaultValue = "false" )
384 private Boolean parsedCreateReport;
385
386 @Override
387 public void execute() throws MojoExecutionException, MojoFailureException
388 {
389 ConfigHandler configHandler = new ConfigHandler( this, this.session, this.execution );
390 configHandler.parseConfiguration();
391
392 if ( isEnableIntegrationTest() )
393 {
394 exerciseApp();
395 }
396 }
397
398
399
400
401
402
403 protected boolean isEnableIntegrationTest()
404 {
405 return !parsedSkip && !mavenTestSkip && !mavenSkipTests;
406 }
407
408
409
410
411
412
413 protected boolean isIgnoreTestFailures()
414 {
415 return mavenIgnoreTestFailure || mavenTestFailureIgnore;
416 }
417
418
419
420
421
422
423
424
425
426 protected void exerciseApp() throws MojoExecutionException, MojoFailureException
427 {
428
429 getLog().debug( "Parsed values for Android Monkey invocation: " );
430 getLog().debug( "seed:" + parsedSeed );
431
432 DeviceCallback instrumentationTestExecutor = new DeviceCallback()
433 {
434 @Override
435 public void doWithDevice( final IDevice device ) throws MojoExecutionException, MojoFailureException
436 {
437 String deviceLogLinePrefix = DeviceHelper.getDeviceLogLinePrefix( device );
438
439 MonkeyTestRunner monkeyTestRunner = new MonkeyTestRunner( parsedEventCount, device );
440
441 monkeyTestRunner.setRunName( "ui monkey tests" );
442 if ( parsedSeed != null )
443 {
444 monkeyTestRunner.setSeed( parsedSeed );
445 }
446 if ( parsedPercentTouch != null )
447 {
448 monkeyTestRunner.setPercentTouch( parsedPercentTouch );
449 }
450 if ( parsedPercentMotion != null )
451 {
452 monkeyTestRunner.setPercentTouch( parsedPercentMotion );
453 }
454 if ( parsedPercentTrackball != null )
455 {
456 monkeyTestRunner.setPercentTrackball( parsedPercentTrackball );
457 }
458 if ( parsedPercentNav != null )
459 {
460 monkeyTestRunner.setPercentNav( parsedPercentNav );
461 }
462 if ( parsedPercentMajorNav != null )
463 {
464 monkeyTestRunner.setPercentMajorNav( parsedPercentMajorNav );
465 }
466 if ( parsedPercentSyskeys != null )
467 {
468 monkeyTestRunner.setPercentSyskeys( parsedPercentSyskeys );
469 }
470 if ( parsedPercentAppswitch != null )
471 {
472 monkeyTestRunner.setPercentAppswitch( parsedPercentAppswitch );
473 }
474 if ( parsedPercentAnyevent != null )
475 {
476 monkeyTestRunner.setPercentAnyEvent( parsedPercentAnyevent );
477 }
478 if ( parsedPackages != null )
479 {
480 monkeyTestRunner.setPackages( parsedPackages );
481 }
482 if ( parsedCategories != null )
483 {
484 monkeyTestRunner.setCategories( parsedCategories );
485 }
486 monkeyTestRunner.setDebugNoEvents( parsedDebugNoEvents );
487 monkeyTestRunner.setHprof( parsedHprof );
488 monkeyTestRunner.setIgnoreCrashes( parsedIgnoreCrashes );
489 monkeyTestRunner.setIgnoreTimeouts( parsedIgnoreTimeouts );
490 monkeyTestRunner.setIgnoreSecurityExceptions( parsedIgnoreSecurityExceptions );
491 monkeyTestRunner.setKillProcessAfterError( parsedKillProcessAfterError );
492 monkeyTestRunner.setMonitorNativeCrash( parsedMonitorNativeCrashes );
493
494 getLog().info( deviceLogLinePrefix + "Running ui monkey tests" );
495 try
496 {
497 AndroidTestRunListener testRunListener = new AndroidTestRunListener( device, getLog(),
498 parsedCreateReport, false, "", "", targetDirectory );
499 monkeyTestRunner.run( testRunListener );
500 if ( testRunListener.hasFailuresOrErrors() && !isIgnoreTestFailures() )
501 {
502 throw new MojoFailureException( deviceLogLinePrefix + "Tests failed on device." );
503 }
504 if ( testRunListener.testRunFailed() )
505 {
506 throw new MojoFailureException( deviceLogLinePrefix + "Test run failed to complete: "
507 + testRunListener.getTestRunFailureCause() );
508 }
509 if ( testRunListener.threwException() && !isIgnoreTestFailures() )
510 {
511 throw new MojoFailureException( deviceLogLinePrefix + testRunListener.getExceptionMessages() );
512 }
513 }
514 catch ( TimeoutException e )
515 {
516 throw new MojoExecutionException( deviceLogLinePrefix + "timeout", e );
517 }
518 catch ( AdbCommandRejectedException e )
519 {
520 throw new MojoExecutionException( deviceLogLinePrefix + "adb command rejected", e );
521 }
522 catch ( ShellCommandUnresponsiveException e )
523 {
524 throw new MojoExecutionException( deviceLogLinePrefix + "shell command " + "unresponsive", e );
525 }
526 catch ( IOException e )
527 {
528 throw new MojoExecutionException( deviceLogLinePrefix + "IO problem", e );
529 }
530 }
531 };
532
533 doWithDevices( instrumentationTestExecutor );
534 }
535
536
537
538
539
540 private Long getSeed()
541 {
542 return parsedSeed;
543 }
544
545
546
547
548
549 private Long getThrottle()
550 {
551 return parsedThrottle;
552 }
553
554
555
556
557
558 private Integer getPercentTouch()
559 {
560 return parsedPercentTouch;
561 }
562
563
564
565
566
567 private Integer getPercentMotion()
568 {
569 return parsedPercentMotion;
570 }
571
572
573
574
575
576 private Integer getPercentTrackball()
577 {
578 return parsedPercentTrackball;
579 }
580
581
582
583
584
585 private Integer getPercentNav()
586 {
587 return parsedPercentNav;
588 }
589
590
591
592
593
594 private Integer getPercentMajorNav()
595 {
596 return parsedPercentMajorNav;
597 }
598
599
600
601
602
603 private Integer getPercentSyskeys()
604 {
605 return parsedPercentSyskeys;
606 }
607
608
609
610
611
612 private Integer getPercentAppswitch()
613 {
614 return parsedPercentAppswitch;
615 }
616
617
618
619
620
621 private Integer getPercentAnyevent()
622 {
623 return parsedPercentAnyevent;
624 }
625
626
627
628
629 public String[] getPackages()
630 {
631 return parsedPackages;
632 }
633
634
635
636
637 public String[] getCategories()
638 {
639 return parsedCategories;
640 }
641 }