Class: MonkeyMaster::MonkeyCommander

Inherits:
Object
  • Object
show all
Defined in:
lib/monkey_master/monkey_commander.rb

Overview

A class for conveniently employing Android adb monkeys.

Author

Lukas Nagl ([email protected])

Copyright

Copyright © 2013 Innovaptor OG

License

MIT

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(app_id) ⇒ MonkeyCommander

app_id

The id of the app that should be tested by the monkeys, e.g. com.innovaptor.MonkeyTestApp



26
27
28
29
30
31
32
33
34
35
36
# File 'lib/monkey_master/monkey_commander.rb', line 26

def initialize(app_id)
	@app_id = app_id
	@iterations = 1 # Default to a single iteration
	@base_dir = Dir.pwd
	time = Time.new
	@log_dir = "monkey_logs" + time.strftime("%Y%m%d_%H%M%S")
	@logger = Logger.new(STDOUT)
	@logger.formatter = proc { |severity, datetime, progname, msg|
	    "#{severity}|#{datetime}: #{msg}\n"
	}
end

Instance Attribute Details

#app_id=(value) ⇒ Object (writeonly)

The id of the app that should be tested by monkeys. E.g.: com.innovaptor.MonkeyTestApp



17
18
19
# File 'lib/monkey_master/monkey_commander.rb', line 17

def app_id=(value)
  @app_id = value
end

#device_list=(value) ⇒ Object (writeonly)

List of devices that should be used by the MonkeyCommander.



21
22
23
# File 'lib/monkey_master/monkey_commander.rb', line 21

def device_list=(value)
  @device_list = value
end

#iterations=(value) ⇒ Object (writeonly)

The number of monkey iterations that should be run on each device.



19
20
21
# File 'lib/monkey_master/monkey_commander.rb', line 19

def iterations=(value)
  @iterations = value
end

#log_dirObject (readonly)

Directory of the monkey logs.



13
14
15
# File 'lib/monkey_master/monkey_commander.rb', line 13

def log_dir
  @log_dir
end

#loggerObject (readonly)

Logger used for the monkey output.



15
16
17
# File 'lib/monkey_master/monkey_commander.rb', line 15

def logger
  @logger
end

Instance Method Details

#command_monkeysObject

Start running monkeys on all specified devices.



68
69
70
71
72
73
74
75
76
77
78
79
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
# File 'lib/monkey_master/monkey_commander.rb', line 68

def command_monkeys
	if(!@device_list || @device_list.empty?)
		raise ArgumentError, "No devices found or specified."
	end
	if(!@app_id)
		raise ArgumentError, "No app id specified."
	end
	prepare

	masters = []
	begin
		@device_list.each{|device|
			master = Thread.new{
				# Monkey around in parallel

				log_device_name = "monkey_current" + device + ".txt";
				current_log = File.join(@log_dir, log_device_name)
				start_logging(device, current_log)
				@logger.info("[MASTER #{device}] Starting to command monkeys.")
				@iterations.to_i.times do |i|
					@logger.info("\t[MASTER #{device}] Monkey " + i.to_s + " is doing its thing...")

					# Start the monkey
					%x(adb -s #{device} shell monkey -p #{@app_id} -v 80000 --throttle 100 --ignore-timeouts --pct-majornav 10 --pct-appswitch 0 --kill-process-after-error)
					if($? != 0)
						@logger.info("\t\t[MASTER #{device}] Monkey encountered an error!")
					end

					# Archive the log
					log_archiving_name = "monkeylog_" + device + "_" + i.to_s + ".txt"
					FileUtils.cp(current_log, File.join(@log_dir, log_archiving_name))

					# Clean the current log
					File.truncate(current_log, 0)
					@logger.info("\t\t[MASTER #{device}] Monkey " + i.to_s + " is killing the app now in preparation for the next monkey.")
					%x(adb -s #{device} shell am force-stop #{@app_id})
				end
				@logger.info("[MASTER #{device}] All monkeys are done.")
			}
			masters.push(master)
		}

		masters.each{|master| master.join} # wait for all masters to finish
	rescue SystemExit, Interrupt
		# Clean and graceful shutdown, if possible
		@logger.info("[MASTER] Received interrupt. Stopping all masters.")
		masters.each{|master| master.terminate}
	end

	kill_monkeys
	end_logging
end

#detect_devices(devices) ⇒ Object

Either create a list of devices from the parameter, or detect connected devices using adb.

devices

nil, for automatic device detection; or a list of device IDs separated by ‘,’



42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/monkey_master/monkey_commander.rb', line 42

def detect_devices(devices)
	if(devices)
		# Devices are given, create a list
		devices = devices.split(',')
		@device_list = devices
	else
		# No devices specified, detect them
		device_list = %x(adb devices | grep -v "List" | grep "device" | awk '{print $1}')
		device_list = device_list.split("\n")
		@device_list = device_list
	end
end

#kill_monkeysObject

Kill the monkey on each device.



56
57
58
59
60
61
62
63
64
65
# File 'lib/monkey_master/monkey_commander.rb', line 56

def kill_monkeys
	if(@device_list)
		@device_list.each{|device|
			@logger.info("[CLEANUP] KILLING the monkey on device #{device}.")
			%x(adb -s #{device} shell ps | awk '/com\.android\.commands\.monkey/ { system("adb -s #{device} shell kill " $2) }')
		}
	else
		@logger.warn("[CLEANUP] No devices specified yet.")
	end
end