Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
S2-group
GitHub Repository: S2-group/android-runner
Path: blob/master/AndroidRunner/Progress.py
629 views
1
import hashlib
2
import logging
3
import os
4
import sys
5
from random import randint
6
7
import lxml.etree as et
8
9
import paths
10
11
12
class Progress(object):
13
def __init__(self, progress_file=None, config_file=None, config=None, load_progress=None):
14
self.logger = logging.getLogger(self.__class__.__name__)
15
if load_progress:
16
self.progress_xml_file = progress_file
17
self.progress_xml_content = et.parse(self.progress_xml_file).getroot()
18
self.check_config_hash(config_file)
19
else:
20
self.progress_xml_file = os.path.join(paths.OUTPUT_DIR, 'progress.xml')
21
self.progress_xml_content = self.build_progress_xml(config, config_file)
22
self.write_progress_to_file()
23
24
def get_progress_xml_file(self):
25
return self.progress_xml_file
26
27
@staticmethod
28
def file_to_hash(path):
29
with open(path, 'r') as myfile:
30
content_string = myfile.read().replace('\n', '')
31
hashed_string_obj = hashlib.md5(content_string.encode())
32
return hashed_string_obj.hexdigest()
33
34
def check_config_hash(self, config_file):
35
progress_config_hash = self.progress_xml_content.find('configHash').text
36
if progress_config_hash == self.file_to_hash(config_file):
37
return
38
else:
39
print('Current config.json and config.json from progress.xml are not the same, cannot continue')
40
sys.exit()
41
42
def build_progress_xml(self, config, config_file):
43
config_hash_xml = '<configHash>{}</configHash>'.format(self.file_to_hash(config_file))
44
output_dir_xml = '<outputDir>{}</outputDir>'.format(paths.OUTPUT_DIR)
45
runs_to_run_xml = '<runsToRun>{}</runsToRun>'.format(self.build_runs_xml(config))
46
runs_done_xml = '<runsDone></runsDone>'
47
experiment_xml = '<experiment>{}{}{}{}</experiment>'.format(config_hash_xml, output_dir_xml,
48
runs_to_run_xml, runs_done_xml)
49
return et.fromstring(experiment_xml)
50
51
@staticmethod
52
def build_subject_xml(device, path, browser=None):
53
device_xml = '<device>{}</device>'.format(device)
54
path_xml = '<path>{}</path>'.format(path)
55
if browser is not None:
56
browser_xml = '<browser>{}</browser>'.format(browser)
57
return '{}{}{}'.format(device_xml, path_xml, browser_xml)
58
else:
59
return '{}{}'.format(device_xml, path_xml)
60
61
def build_runs_xml(self, config):
62
runs_xml = ''
63
run_id = 0
64
for device in config['devices']:
65
current_paths = config.get('paths', []) + config.get('apps', [])
66
for path in current_paths:
67
if config['type'] == 'web':
68
for browser in config['browsers']:
69
subject_xml = self.build_subject_xml(device, path, browser)
70
for run in range(config['repetitions']):
71
runs_xml = runs_xml + '<run runId="{}">{}<runCount>{}</runCount></run>'. \
72
format(run_id, subject_xml, run + 1)
73
run_id += 1
74
else:
75
subject_xml = self.build_subject_xml(device, path)
76
for run in range(config['repetitions']):
77
runs_xml = runs_xml + '<run runId="{}">{}<runCount>{}</runCount></run>'. \
78
format(run_id, subject_xml, run + 1)
79
run_id += 1
80
81
return runs_xml
82
83
def write_progress_to_file(self):
84
xml = self.progress_xml_content.getroottree()
85
xml.write(self.progress_xml_file, pretty_print=True)
86
87
def get_output_dir(self):
88
return self.progress_xml_content.find('outputDir').text
89
90
"""Get a random run from the <runsToRuns> element"""
91
92
def get_random_run(self):
93
runs_to_run = self.progress_xml_content.find('runsToRun')
94
count = len(runs_to_run.getchildren())
95
random_index = randint(0, count - 1)
96
next_run_xml = self.progress_xml_content.find('runsToRun')[random_index]
97
return self.run_to_dict(next_run_xml)
98
99
"""Get the top run of the list"""
100
101
def get_next_run(self):
102
next_run_xml = self.progress_xml_content.find('runsToRun')[0] # First run in list
103
return self.run_to_dict(next_run_xml)
104
105
"""Turn a <run> element and its childeren into a dictionary"""
106
107
def run_to_dict(self, run_xml):
108
run = dict()
109
run['runId'] = run_xml.get('runId')
110
run['device'] = run_xml.find('device').text
111
run['path'] = run_xml.find('path').text
112
run['runCount'] = self.get_run_count(run_xml, run['device'], run['path'])
113
browser = run_xml.find('browser')
114
if browser is not None:
115
run['browser'] = run_xml.find('browser').text
116
return run
117
118
def get_run_count(self, run_xml, device, path):
119
runs_done = self.progress_xml_content.find('runsDone')
120
browser_val = run_xml.find('browser')
121
if browser_val is not None:
122
browser_name = browser_val.text
123
query = "run[device='{}' and path='{}' and browser='{}']".format(device, path, browser_name)
124
else:
125
query = "run[device='{}' and path='{}']".format(device, path)
126
elements = runs_done.xpath(query)
127
return len(elements) + 1
128
129
"""Marks run as finished"""
130
131
def run_finished(self, run_id):
132
runs_to_run = self.progress_xml_content.find('runsToRun')
133
runs_done = self.progress_xml_content.find('runsDone')
134
elements = runs_to_run.findall("run[@runId='{}']".format(run_id))
135
for el in elements:
136
runs_to_run.remove(el)
137
runs_done.append(el)
138
139
"""Check if this subject already had it's first run"""
140
141
def subject_first(self, device, path, browser=None):
142
runs_done = self.progress_xml_content.find('runsDone')
143
if browser is not None:
144
elements = runs_done.xpath(
145
"run[device='{}' and path='{}' and browser='{}']".format(device, path, browser))
146
else:
147
elements = runs_done.xpath(
148
"run[device='{}' and path='{}']".format(device, path))
149
if not elements:
150
return True
151
else:
152
return False
153
154
"""Checks if all subject runs are done"""
155
156
def subject_finished(self, device, path, browser=None):
157
runs_to_run = self.progress_xml_content.find('runsToRun')
158
if browser is not None:
159
elements = runs_to_run.xpath(
160
"run[device='{}' and path='{}' and browser='{}']".format(device, path, browser))
161
else:
162
elements = runs_to_run.xpath(
163
"run[device='{}' and path='{}']".format(device, path))
164
if not elements:
165
return True
166
else:
167
return False
168
169
"""Check if this device already had it's first run"""
170
171
def device_first(self, device):
172
runs_done = self.progress_xml_content.find('runsDone')
173
elements = runs_done.xpath("run[device='{}']".format(device))
174
175
if not elements:
176
return True
177
else:
178
return False
179
180
"""Checks if all device runs are done"""
181
182
def device_finished(self, device):
183
runs_to_run = self.progress_xml_content.find('runsToRun')
184
elements = runs_to_run.xpath("run[device='{}']".format(device))
185
186
if not elements:
187
return True
188
else:
189
return False
190
191
def experiment_finished_check(self):
192
runs_to_run = self.progress_xml_content.find('runsToRun')
193
count = len(runs_to_run.getchildren())
194
if count == 0:
195
return True
196
else:
197
return False
198
199