Merge pull request #377 from valschneider/preliminary-features

tests/eas/preliminary: WorkThroughput improvement
diff --git a/tests/eas/preliminary.py b/tests/eas/preliminary.py
index c81fd8a..ca62219 100644
--- a/tests/eas/preliminary.py
+++ b/tests/eas/preliminary.py
@@ -131,38 +131,52 @@
         match = re.search(r'(total number of events:\s*)([\d.]*)', bench_out)
         return float(match.group(2))
 
-    def _check_work_throughput(self, cpu):
-        seconds = 1.0
-        margin = 0.2
+    def _check_work_throughput(self, cpu, duration, margin):
         frequencies = self.target.cpufreq.list_frequencies(cpu)
         if len(frequencies) == 1:
             return True
+
         original_governor = self.target.cpufreq.get_governor(cpu)
         original_freq = None
         if original_governor == 'userspace':
             original_freq = self.target.cpufreq.get_frequency(cpu)
-        # set userspace governor
+
+        # Set userspace governor
         self.target.cpufreq.set_governor(cpu, 'userspace')
-        # do each freq in turn
+
+        # Run at lowest & highest freq
         result = {}
-        for freq in frequencies:
+        for freq in [frequencies[0], frequencies[-1]]:
             self.target.cpufreq.set_frequency(cpu, freq)
-            result[freq] = self._run_sysbench_work(cpu, seconds)
-        # restore governor
+            result[freq] = self._run_sysbench_work(cpu, duration)
+
+        # Restore governor
         self.target.cpufreq.set_governor(cpu, original_governor)
         if original_freq:
             self.target.cpufreq.set_frequency(cpu, original_freq)
-        # compare work throughput
-        return result[frequencies[0]] < result[frequencies[-1]]
+
+        # Make sure work done at highest OPP is at least some % higher
+        # than work done at lowest OPP - this filters the
+        # +/- 1 sysbench result noise
+        work_diff = result[frequencies[-1]] - result[frequencies[0]]
+        ok = work_diff > result[frequencies[0]] * margin
+        return ok
 
     def test_work_throughput(self):
+        duration = 1.0
+        margin = 0.1
         failed_cpus = []
-        for cpulist in self.env.topology.get_level('cpu'):
-            cpu = cpulist[0]
-            if not self._check_work_throughput(cpu):
+
+        # Run test on each known cpu
+        for cpu in range(self.target.number_of_cpus):
+            if not self._check_work_throughput(cpu, duration, margin):
                 failed_cpus.append(cpu)
-        msg='Work done did not scale with CPU Freq on CPUs: {}'\
-            .format(failed_cpus)
+
+        # Format error message
+        msg='Problems detected on CPUs: {}\n'\
+        'Work at highest OPP wasn\'t {}% bigger than work at lowest OPP on these CPUs'\
+            .format(failed_cpus, margin * 100)
+
         self.assertFalse(len(failed_cpus), msg=msg)
 
 class TestEnergyModelPresent(BasicCheckTest):