Optofidelity: Adjustments for one-off tests
This CL makes some minor tweaks to get the system up and running
again for one-off tests only.
BUG=None
Change-Id: I2b4a56564ed5d46dcab11b3081b7dda4052917b9
Reviewed-on: https://chromium-review.googlesource.com/336539
Commit-Ready: Dennis Kempin <denniskempin@chromium.org>
Tested-by: Dennis Kempin <denniskempin@chromium.org>
Reviewed-by: Dennis Kempin <denniskempin@chromium.org>
diff --git a/optofidelity/apps/web/scroll.html b/optofidelity/apps/web/scroll.html
index 719340c..63c37ec 100644
--- a/optofidelity/apps/web/scroll.html
+++ b/optofidelity/apps/web/scroll.html
@@ -21,10 +21,13 @@
}
body {
margin: 0;
- -webkit-user-select: none;
}
#container {
cursor: pointer;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ -webkit-tap-highlight-color: rgba(0,0,0,0);
}
</style>
<script>
diff --git a/optofidelity/config/base.xml b/optofidelity/config/base.xml
index 0162690..4701c2a 100644
--- a/optofidelity/config/base.xml
+++ b/optofidelity/config/base.xml
@@ -31,7 +31,7 @@
<setting namespace="global" name="airplane_mode_on" value="1" />
<setting namespace="global" name="stay_on_while_plugged_in" value="1" />
</setup>
- <collector type="systrace" adb="{dut.adb}" sdk-path="env:ANDROID_SDK_ROOT" />
+ <!--collector type="systrace" adb="{dut.adb}" sdk-path="env:ANDROID_SDK_ROOT" /-->
<dashboard type="spreadsheet"
sheet-key="1VmhTaavuPt4ZRgwC_ZBL6CddqpdgC9-04pgy28TvO0I"
oauth-key-file="file:oauth2key.json"
@@ -43,7 +43,7 @@
<!-- Clank -->
<subject-type type-name="clank_base" data="file:../apps/web"
- parent-type="adb_base" margin="(30, 15)">
+ parent-type="adb_base" margin="(30, 15)" channel="">
<navigator type="web_adb" adb="{dut.adb}">
<activity name="calibration" file="{subject.data}/flash.html" />
<activity name="scroll" file="{subject.data}/scroll.html" />
@@ -51,27 +51,29 @@
<activity name="tap" file="{subject.data}/tap.html" />
<resource file="{subject.data}/jquery.min.js" />
</navigator>
- <updater type="chrome" adb="{dut.adb}"/>
+ <collector type="chrome_profile" adb="{dut.adb}"
+ chromium-path="env:CHROMIUM_SRC" browser="{subject.channel}" />
+ <updater type="chrome" adb="{dut.adb}" channel="{subject.channel}" />
<benchmark name="tap" type="tap" activity="tap" />
<benchmark name="scroll" type="line_draw" activity="scroll" />
</subject-type>
- <subject-type type-name="clank_stable" parent-type="clank_base">
+ <subject-type type-name="clank_stable" parent-type="clank_base"
+ channel="stable">
<navigator type="web_adb"
component="com.android.chrome/com.google.android.apps.chrome.Main" />
- <updater type="chrome" channel="stable"/>
</subject-type>
- <subject-type type-name="clank_beta" parent-type="clank_base">
+ <subject-type type-name="clank_beta" parent-type="clank_base"
+ channel="beta">
<navigator type="web_adb"
component="com.chrome.beta/com.google.android.apps.chrome.Main" />
- <updater type="chrome" channel="beta"/>
</subject-type>
- <subject-type type-name="clank_dev" parent-type="clank_base">
+ <subject-type type-name="clank_dev" parent-type="clank_base"
+ channel="dev">
<navigator type="web_adb"
component="com.chrome.dev/com.google.android.apps.chrome.Main" />
- <updater type="chrome" channel="dev"/>
</subject-type>
<!-- Android Native -->
@@ -92,7 +94,7 @@
</subject-type>
<subject-type type-name="android_native" parent-type="android_native_base"
- margin="(20, 15)">
+ margin="(10, 15)">
<benchmark name="tap" type="tap" activity="tap" />
<benchmark name="scroll" type="line_draw" activity="scroll" />
</subject-type>
@@ -113,7 +115,7 @@
</subject-type>
<!-- iOS -->
- <subject-type type-name="ios" parent-type="base" margin="(15, 15)">
+ <subject-type type-name="ios" parent-type="base" margin="(5, 20)">
<navigator type="robot">
<activity name="neutral" icon="file:icons/neutral.shm" />
<activity name="calibration" icon="file:icons/flash.shm" />
diff --git a/optofidelity/config/temp.xml b/optofidelity/config/temp.xml
index 369faa2..adc65b4 100644
--- a/optofidelity/config/temp.xml
+++ b/optofidelity/config/temp.xml
@@ -1,13 +1,13 @@
<optofidelity>
<include file="base.xml" />
- <dut name="bullhead" backend-name="temp3" margin="(15, 15)" exposure="2" adb="00656e9429c02d0f">
+ <dut name="shamrock" type="base" backend-name="angler" margin="(15, 15)"
+ exposure="2" adb="bbabca4c" port="13">
<subject name="native" type="android_native" />
</dut>
- <dut name="ryu" backend-name="nexus9" adb="usb:9-1.1.3.3" exposure="2">
+
+ <dut name="seed" type="base" backend-name="bullhead" margin="(20, 20)"
+ exposure="2" adb="552cfc20" port="12">
<subject name="native" type="android_native" />
</dut>
- <dut name="iphone6plus" backend-name="temp2" exposure="2.5">
- <subject name="native" type="ios" />
- </dut>
</optofidelity>
diff --git a/optofidelity/optofidelity/benchmark/benchmark.py b/optofidelity/optofidelity/benchmark/benchmark.py
index 18d3a42..c03a0a6 100644
--- a/optofidelity/optofidelity/benchmark/benchmark.py
+++ b/optofidelity/optofidelity/benchmark/benchmark.py
@@ -63,8 +63,10 @@
"""
self.results.metadata["subject_name"] = subject.name
subject.navigator.OpenActivity(self._delegate.activity)
- self.video = self._delegate.ExecuteOnSubject(subject)
- subject.navigator.CloseActivity()
+ try:
+ self.video = self._delegate.ExecuteOnSubject(subject)
+ finally:
+ subject.navigator.CloseActivity()
self.framerate = self.video.framerate
self.trace = None
self.results.measurements = None
diff --git a/optofidelity/optofidelity/components.py b/optofidelity/optofidelity/components.py
index 9945db9..c30c4ab 100644
--- a/optofidelity/optofidelity/components.py
+++ b/optofidelity/optofidelity/components.py
@@ -9,7 +9,8 @@
from .detection.fake import FakeVideoProcessor
from .orchestrator import Orchestrator
from .orchestrator.access import Access, CambrionixAccess, FakeAccess
-from .orchestrator.collector import Collector, FakeCollector, SystraceCollector
+from .orchestrator.collector import (ChromeProfileCollector, Collector,
+ FakeCollector, SystraceCollector)
from .orchestrator.dashboard import (ChromePerfDashboard, Dashboard,
FakeDashboard, SpreadsheetDashboard)
from .orchestrator.subject_setup import (ADBSettingsSetup, FakeSubjectSetup,
@@ -77,6 +78,7 @@
},
Collector: {
"fake": FakeCollector,
- "systrace": SystraceCollector
+ "systrace": SystraceCollector,
+ "chrome_profile": ChromeProfileCollector
}
}
diff --git a/optofidelity/optofidelity/detection/_finger_detector.py b/optofidelity/optofidelity/detection/_finger_detector.py
index 96a5d1f..26a3ac1 100644
--- a/optofidelity/optofidelity/detection/_finger_detector.py
+++ b/optofidelity/optofidelity/detection/_finger_detector.py
@@ -26,7 +26,7 @@
LOW_PASS_KERNEL_SIZE = 3
"""Kernel size of time-series low pass for smoothing finger location."""
- MIN_FINGER_WEIGHT = 0.3
+ MIN_FINGER_WEIGHT = 0.5
def Preprocess(self, calib_frame, debugger):
def log(msg, *params):
diff --git a/optofidelity/optofidelity/detection/_state_change_detector.py b/optofidelity/optofidelity/detection/_state_change_detector.py
index 46648e2..3b16ed6 100644
--- a/optofidelity/optofidelity/detection/_state_change_detector.py
+++ b/optofidelity/optofidelity/detection/_state_change_detector.py
@@ -34,7 +34,8 @@
NAME = "state_change"
- SETTLED_THRESHOLDS = dict(max_mean_distance=2.0, window_size=20)
+ SETTLED_THRESHOLDS = dict(max_rel_mean_distance=1.0, max_mean_distance=0.1,
+ window_size=20, combination="or")
"""Thresholds to identify when a state has settled.
(see nputil.FindSettlingIndex)"""
@@ -238,16 +239,17 @@
def GenerateEvents(self, preprocessed_data, debug=False):
"""Segments the array of state change levels into discrete state changes."""
if debug:
- for data in preprocessed_data:
- print "%.4f" % data
+ for i, data in enumerate(preprocessed_data):
+ print "%04d: %.4f" % (i, data)
level = np.asarray(preprocessed_data, np.float)
normalized = nputil.NormalizeStates(level)
+
filtered = nputil.LowPass(normalized, 5)
if debug:
pyplot.figure()
- pyplot.plot(normalized)
+ pyplot.plot(normalized, "-x")
pyplot.plot(filtered)
for start, end in nputil.FindStateChanges(normalized,
diff --git a/optofidelity/optofidelity/orchestrator/access.py b/optofidelity/optofidelity/orchestrator/access.py
index b25a7d5..a2ed342 100644
--- a/optofidelity/optofidelity/orchestrator/access.py
+++ b/optofidelity/optofidelity/orchestrator/access.py
@@ -37,7 +37,8 @@
class CambrionixAccess(Access):
- ADB_TIMEOUT = 10
+ ADB_TIMEOUT = 2 * 60
+ """Wait for device to connect for 2 minutes."""
def __init__(self, serial_device, port_id, adb_serial):
super(CambrionixAccess, self).__init__()
diff --git a/optofidelity/optofidelity/orchestrator/collector.py b/optofidelity/optofidelity/orchestrator/collector.py
index ecef4b0..ea58ac5 100644
--- a/optofidelity/optofidelity/orchestrator/collector.py
+++ b/optofidelity/optofidelity/orchestrator/collector.py
@@ -103,3 +103,44 @@
@property
def report_links(self):
return [("Systrace", "systrace.html")]
+
+
+class ChromeProfileCollector(Collector):
+ """Collection of Chrome profile traces."""
+
+ def __init__(self, adb_device, chromium_path, browser):
+ profile_script = os.path.join(chromium_path, "build", "android",
+ "adb_profile_chrome")
+ self.base_cmd = [profile_script,
+ "-d", adb_device,
+ "--browser", browser,
+ "--systrace", "gfx,view,input,freq,sched"]
+ self.process = None
+ self.tempfile = NamedTemporaryFile()
+
+ @classmethod
+ def FromConfig(cls, parameters, children):
+ return cls(parameters["adb"], parameters["chromium-path"],
+ parameters["browser"])
+
+ def Start(self, duration):
+ seconds = int(math.ceil(float(duration) / 1000.0))
+ cmd = self.base_cmd + ["-t", str(seconds), "-o", self.tempfile.name]
+ _log.info("Starting: %s", " ".join(cmd))
+ self.process = subprocess.Popen(cmd, shell=False, stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT)
+
+ def Stop(self):
+ stdout, stderr = self.process.communicate()
+ if self.process.returncode > 0:
+ _log.error(stdout)
+ _log.error("Systrace failed to collect")
+ else:
+ _log.debug(stdout)
+
+ def Save(self, folder):
+ shutil.copy(self.tempfile.name, os.path.join(folder, "chrome_profile.html"))
+
+ @property
+ def report_links(self):
+ return [("ChromeProfile", "chrome_profile.html")]
\ No newline at end of file
diff --git a/optofidelity/optofidelity/system/navigator.py b/optofidelity/optofidelity/system/navigator.py
index ca02be4..fb4c390 100644
--- a/optofidelity/optofidelity/system/navigator.py
+++ b/optofidelity/optofidelity/system/navigator.py
@@ -89,16 +89,16 @@
return cls()
def Open(self):
- if self._is_open:
- raise Exception("Subject already open.")
+ # if self._is_open:
+ # raise Exception("Subject already open.")
self._Open()
self._is_open = True
def Close(self):
- if not self._is_open:
- raise Exception("Subject has not been opened.")
- if self._current_activity:
- raise Exception("Activity still open.")
+ # if not self._is_open:
+ # raise Exception("Subject has not been opened.")
+ # if self._current_activity:
+ # raise Exception("Activity still open.")
self._Close()
self._is_open = False
@@ -114,10 +114,10 @@
self.Close()
def OpenActivity(self, activity_name):
- if not self._is_open:
- raise Exception("Can't open activity if subject has not been opened.")
- if self._current_activity:
- raise Exception("Another activity is already open.")
+ # if not self._is_open:
+ # raise Exception("Can't open activity if subject has not been opened.")
+ # if self._current_activity:
+ # raise Exception("Another activity is already open.")
if not self.HasActivity(activity_name):
raise ValueError("Unknown activity name '%s'" % activity_name)
@@ -126,8 +126,8 @@
def CloseActivity(self):
"""Close previously opened activity."""
- if not self._current_activity:
- raise Exception("No activity open.")
+ # if not self._current_activity:
+ # raise Exception("No activity open.")
self._CloseActivity()
self._current_activity = None
diff --git a/optofidelity/optofidelity/util/nputil.py b/optofidelity/optofidelity/util/nputil.py
index 03dc8ef..b9a2bb9 100644
--- a/optofidelity/optofidelity/util/nputil.py
+++ b/optofidelity/optofidelity/util/nputil.py
@@ -66,11 +66,24 @@
def NormalizeStates(array, crossing_threshold=0.5):
"""Normalize array to 0..1"""
pre_norm = Normalize(array)
- min = np.mean(pre_norm[pre_norm < crossing_threshold])
- max = np.mean(pre_norm[pre_norm > crossing_threshold])
+ min = np.median(pre_norm[pre_norm < crossing_threshold])
+ max = np.median(pre_norm[pre_norm > crossing_threshold])
return (pre_norm - min) / (max - min)
+def HysteresisThreshold(array, t_low, t_high, initial=False):
+ """Hysteresis thresholding of array."""
+ result = np.empty(array.shape, dtype=np.bool)
+ current = initial
+ for index, value in enumerate(array):
+ if value > t_high:
+ current = True
+ elif value < t_low:
+ current = False
+ result[index] = current
+ return result
+
+
def LowPass(array, kernel_size=5):
"""Returns low pass filtered array."""
kernel = np.ones(kernel_size,) / kernel_size
@@ -190,34 +203,58 @@
def FindSettlingIndex(profile, start, window_size=8,
min_value=None, max_value=None, max_mid_range=None,
max_slope=None, max_distance=None, max_mean_distance=None,
+ max_rel_mean_distance=None, combination="and",
debug=False):
"""Returns index of first settled value."""
+ smoothed = LowPass(profile, 5)
+ increasing = smoothed[start] < smoothed[start + 1]
+
for i in range(start, len(profile) - 1):
+ debug_values = []
+ conditions = []
+ def AddCondition(threshold, value, name, condition):
+ if threshold is None:
+ return
+ if debug:
+ debug_values.append(u"%s=%.2f%s" % (name, value, u"\u2713" if condition else ""))
+ conditions.append(condition)
+ def MinCondition(threshold, value, name):
+ AddCondition(threshold, value, name, value > threshold)
+ def MaxCondition(threshold, value, name):
+ AddCondition(threshold, value, name, value < threshold)
+
+ value = profile[i]
window_end = Truncate(i + window_size, 0, len(profile))
moving_window = profile[i:(window_end + 1)]
- value = profile[i]
- mid_range = np.max(moving_window) - np.min(moving_window)
- slope = profile[i + 1] - profile[i]
- distance = (i - start)
window_mean = np.mean(moving_window[1:])
window_std = np.std(moving_window[1:])
- mean_distance = np.abs(value - window_mean) / window_std
+ mean_distance = window_mean - value
+ if not increasing:
+ mean_distance *= -1;
+
+ MinCondition(min_value, value, "v")
+ MaxCondition(max_value, value, "v")
+ MaxCondition(max_slope, np.abs(profile[i + 1] - profile[i]), "s")
+ MaxCondition(max_mid_range, np.max(moving_window) - np.min(moving_window), "mr")
+ MaxCondition(max_mean_distance, mean_distance, "md")
+ MaxCondition(max_rel_mean_distance, mean_distance / window_std, "rmd")
+
if debug:
- print "%03d: v=%.2f mr=%.2f s=%.2f d=%d md=%.2f" % (
- i, value, mid_range, slope, distance, mean_distance)
- if max_distance is not None and distance > max_distance:
+ separator = u" %s " % combination
+ print "%03d: d=%d" % (i, (i - start)), separator.join(debug_values)
+
+ if max_distance is not None and (i - start) > max_distance:
return None
- if min_value is not None and value < min_value:
- continue
- if max_value is not None and value > max_value:
- continue
- if max_slope is not None and np.abs(slope) > max_slope:
- continue
- if max_mid_range is not None and mid_range > max_mid_range:
- continue
- if max_mean_distance is not None and mean_distance > max_mean_distance:
- continue
- return i
+
+ if combination == "and":
+ if np.all(conditions):
+ return i
+ elif combination == "or":
+ if np.any(conditions):
+ return i
+ else:
+ raise ValueError("Combination has to be one of: (and, or)")
+
return len(profile) - 1
@@ -242,7 +279,7 @@
"""
# Find indices when the array is crossing the threshold, then find the start
# and end for each crossing.
- crossings = FindZeroCrossings(LowPass(array, 3) - crossing_threshold)
+ crossings = FindZeroCrossings(LowPass(array, 5) - crossing_threshold)
for crossing in crossings:
prev = array[max(crossing - 5, 0)]
diff --git a/optofidelity/regression_tests.py b/optofidelity/regression_tests.py
index 8b60523..5bcd373 100644
--- a/optofidelity/regression_tests.py
+++ b/optofidelity/regression_tests.py
@@ -58,6 +58,8 @@
Test("20150928_2234_000", {}),
"keyboard.mask_issues.s6edge":
Test("20151002_1417_000", {}),
+ "keyboard.segmentation_error.s6edge":
+ Test("20151008_0437_000", {}),
"baseline.tap.nexus4":
Test("20150825_1908_000", {"DownLatency": 98, "UpLatency": 81}),
diff --git a/optofidelity/requirements.txt b/optofidelity/requirements.txt
index 5441ff1..51ee984 100644
--- a/optofidelity/requirements.txt
+++ b/optofidelity/requirements.txt
@@ -1,26 +1,48 @@
-alembic==0.7.5.post2
+alembic==0.8.5
Bottleneck==1.0.0
-dataset==0.5.6
-decorator==3.4.2
-Jinja2==2.7.3
-Mako==1.0.1
+cffi==1.5.2
+cryptography==1.3.1
+cycler==0.10.0
+dask==0.8.1
+dataset==0.6.2
+decorator==4.0.9
+enum34==1.1.2
+funcsigs==0.4
+gspread==0.3.0
+httplib2==0.9.2
+idna==2.1
+ipaddress==1.0.16
+Jinja2==2.8
+Mako==1.0.4
MarkupSafe==0.23
-matplotlib==1.4.3
-mock==1.0.1
-networkx==1.9.1
-nose==1.3.6
-nose2==0.5.0
-numpy==1.9.2
-Pillow==2.8.1
-pyparsing==2.0.3
-python-dateutil==2.4.2
-python-slugify==1.0.1
-pytz==2015.2
+matplotlib==1.5.1
+mock==1.3.0
+networkx==1.11
+normality==0.2.4
+nose==1.3.7
+nose2==0.6.4
+numpy==1.11.0
+oauth2client==1.5.2
+pbr==1.8.1
+Pillow==3.1.1
+pyasn1==0.1.9
+pyasn1-modules==0.0.8
+pycparser==2.14
+pycurl==7.43.0
+pyOpenSSL==16.0.0
+pyparsing==2.1.1
+pyserial==3.0.1
+python-dateutil==2.5.2
+python-editor==0.5
+python-slugify==1.2.0
+pytz==2016.3
PyYAML==3.11
-requests==2.6.0
+requests==2.9.1
+rsa==3.4.2
safetynet==0.2.2
scikit-image==0.11.3
-scipy==0.15.1
-six==1.9.0
-SQLAlchemy==0.9.9
-Unidecode==0.4.17
+scipy==0.17.0
+six==1.10.0
+SQLAlchemy==1.0.12
+toolz==0.7.4
+Unidecode==0.4.19
diff --git a/optofidelity/tests/config.py b/optofidelity/tests/config.py
index 67c3f6a..624bed4 100644
--- a/optofidelity/tests/config.py
+++ b/optofidelity/tests/config.py
@@ -41,7 +41,7 @@
raise AssertionError("User did not accept test result")
CONFIG = TestConfig(
- adb_device_id = None,
+ adb_device_id = "NP5A340401",
robot_ip = None,
phantom_ip = None,
dut_name = None,
@@ -50,6 +50,7 @@
chromeperf_endpoint = None,
gs_folder_url = None,
android_sdk_path = None,
+ chromium_path = "/usr/local/google/home/denniskempin/workspace/chromium/src",
cambrionix_serial_device = None,
cambrionix_dut_port_id = None,
diff --git a/optofidelity/tests/detection/test_state_change_detector.py b/optofidelity/tests/detection/test_state_change_detector.py
index 9d720fa..5c0f75f 100644
--- a/optofidelity/tests/detection/test_state_change_detector.py
+++ b/optofidelity/tests/detection/test_state_change_detector.py
@@ -102,6 +102,20 @@
0.0109, 0.0149, 0.0137, 0.0097, 0.0099, 0.0112, 0.0144, 0.0122, 0.0087,
]
+change_sequence_noisy2 = [
+ 0.0688, 0.0682, 0.0693, 0.0479, 0.0645, 0.0631, 0.0608, 0.0628, 0.0486,
+ 0.0648, 0.0589, 0.0667, 0.0621, 0.0528, 0.0607, 0.0598, 0.0700, 0.0601,
+ 0.0611, 0.0655, 0.0652, 0.0700, 0.0559, 0.0609, 0.0660, 0.0667, 0.0719,
+ 0.0511, 0.0671, 0.0644, 0.0680, 0.0717, 0.0490, 0.0635, 0.0680, 0.0638,
+ 0.0703, 0.0469, 0.0644, 0.0644, 0.0821, 0.0795, 0.0949, 0.1106, 0.1189,
+ 0.1014, 0.0852, 0.1063, 0.0946, 0.1146, 0.0967, 0.0859, 0.1100, 0.1015,
+ 0.1096, 0.0909, 0.0856, 0.1122, 0.0986, 0.1055, 0.0895, 0.0869, 0.1121,
+ 0.0997, 0.1053, 0.0865, 0.0896, 0.1171, 0.1019, 0.1032, 0.0838, 0.0921,
+ 0.1175, 0.1134, 0.0978, 0.0807, 0.0973, 0.1193, 0.1171, 0.0970, 0.0808,
+ 0.1035, 0.1216, 0.1177, 0.0966, 0.0800, 0.1112, 0.1028, 0.1120, 0.0915,
+ 0.0805, 0.1153, 0.1011, 0.1096, 0.0896, 0.0822, 0.1207, 0.1001, 0.1064,
+]
+
change_sequence_multilevel = [
0.0106, 0.0119, 0.0149, 0.0138, 0.0132, 0.0115, 0.0141, 0.0152, 0.0136,
0.0129, 0.0116, 0.0142, 0.0152, 0.0136, 0.0121, 0.0113, 0.0134, 0.0132,
@@ -158,11 +172,12 @@
0.0119, 0.0141, 0.0129, 0.0133, 0.0142, 0.0122, 0.0140, 0.0136, 0.0124,
]
+
class StateChangeDetectorTest(DetectorTest):
def testEventGeneration(self):
expected_events = [
StateChangeEvent(95, 90, StateChangeEvent.STATE_OPEN),
- StateChangeEvent(156, 150, StateChangeEvent.STATE_CLOSED),
+ StateChangeEvent(153, 150, StateChangeEvent.STATE_CLOSED),
]
self.assertExpectedEventsGenerated(StateChangeDetector(None, None),
change_sequence_1, expected_events,
@@ -170,7 +185,7 @@
def testPWMProofEvents(self):
expected_events = [
- StateChangeEvent(140, 138, StateChangeEvent.STATE_OPEN),
+ StateChangeEvent(140, 139, StateChangeEvent.STATE_OPEN),
StateChangeEvent(216, 215, StateChangeEvent.STATE_CLOSED),
]
self.assertExpectedEventsGenerated(StateChangeDetector(None, None),
@@ -180,16 +195,24 @@
def testNoisyEventGeneration(self):
expected_events = [
StateChangeEvent(115, 115, StateChangeEvent.STATE_OPEN),
- StateChangeEvent(195, 193, StateChangeEvent.STATE_CLOSED),
+ StateChangeEvent(195, 190, StateChangeEvent.STATE_CLOSED),
]
self.assertExpectedEventsGenerated(StateChangeDetector(None, None),
change_sequence_noisy, expected_events,
ignore=AnalogStateEvent)
+ def testNoisyEventGeneration2(self):
+ expected_events = [
+ StateChangeEvent(42, 40, StateChangeEvent.STATE_OPEN),
+ ]
+ self.assertExpectedEventsGenerated(StateChangeDetector(None, None),
+ change_sequence_noisy2, expected_events,
+ ignore=AnalogStateEvent)
+
def testMultilevelEventGeneration(self):
expected_events = [
StateChangeEvent(193, 192, StateChangeEvent.STATE_OPEN),
- StateChangeEvent(268, 268, StateChangeEvent.STATE_CLOSED),
+ StateChangeEvent(269, 268, StateChangeEvent.STATE_CLOSED),
StateChangeEvent(346, 344, StateChangeEvent.STATE_OPEN),
StateChangeEvent(420, 420, StateChangeEvent.STATE_CLOSED),
]
diff --git a/optofidelity/tests/orchestrator/test_collectors.py b/optofidelity/tests/orchestrator/test_collectors.py
index 92bce72..32f9233 100644
--- a/optofidelity/tests/orchestrator/test_collectors.py
+++ b/optofidelity/tests/orchestrator/test_collectors.py
@@ -3,16 +3,17 @@
# found in the LICENSE file.
"""Tests for the Orchestrator class."""
from unittest import TestCase
+import os
import shutil
import tempfile
-import os
-from optofidelity.orchestrator.collector import SystraceCollector
+from optofidelity.orchestrator.collector import (ChromeProfileCollector,
+ SystraceCollector)
from optofidelity.util import CreateComponentFromXML
from tests.config import CONFIG
-class TestSystraceCollection(TestCase):
+class TestSystraceCollector(TestCase):
def setUp(self):
self.tempdir = tempfile.mkdtemp()
@@ -34,3 +35,28 @@
self.assertTrue(os.path.exists(filename))
CONFIG.AskUserAccept("Verify file://" + filename)
+
+
+class TestChromeProfileCollector(TestCase):
+ def setUp(self):
+ self.tempdir = tempfile.mkdtemp()
+
+ def tearDown(self):
+ shutil.rmtree(self.tempdir)
+
+ def testCollection(self):
+ adb_device = CONFIG["adb_device_id"]
+ chromium_path = CONFIG["chromium_path"]
+ config_str = ("<collector adb='{adb}' chromium-path='{chromium_path}' " +
+ "browser='stable' />")
+ config = config_str.format(adb=adb_device, chromium_path=chromium_path)
+
+ collector = CreateComponentFromXML(ChromeProfileCollector, config)
+ collector.Start(1000)
+ collector.Stop()
+ collector.Save(self.tempdir)
+
+ filename = os.path.join(self.tempdir, "chrome_profile.html")
+ self.assertTrue(os.path.exists(filename))
+
+ CONFIG.AskUserAccept("Verify file://" + filename)