Title: [221777] trunk/Tools
Revision
221777
Author
[email protected]
Date
2017-09-07 19:58:08 -0700 (Thu, 07 Sep 2017)

Log Message

Add Live PLT implemented with WebDriver
https://bugs.webkit.org/show_bug.cgi?id=176436

Patch by Matthew Stewart <[email protected]> on 2017-09-07
Reviewed by Stephanie Lewis.

Adds a new PLT that runs on live websites.

* Scripts/run-webdriver-plt.py: Added.
(parse_args):
(start):
(make_suites):
(main):
* Scripts/webkitpy/webdriver_plt/__init__.py: Added.
* Scripts/webkitpy/webdriver_plt/liveplt.py: Added.
(PageLoadTest):
(PageLoadTest.__init__):
(PageLoadTest.start):
(PageLoadTest.run_suite):
(PageLoadTest._get_driver_for_browser):
(PageLoadTest._setup_browser_window):
(PageLoadTest.run_one_test):
(PageLoadTest.get_results):
* Scripts/webkitpy/webdriver_plt/pltresults.py: Added.
(PLTResults):
(PLTResults.__init__):
(PLTResults.__add__):
(PLTResults.add_timing_result):
(PLTResults.mean):
(PLTResults.geometric_mean):
(PLTResults.mean_coef_variance):
(PLTResults.print_results):
(PLTResults.print_url_results):
(PLTResults._format_time):
* Scripts/webkitpy/webdriver_plt/suites/__init__.py: Added.
* Scripts/webkitpy/webdriver_plt/suites/arabic.suite: Added.
* Scripts/webkitpy/webdriver_plt/suites/cjk.suite: Added.
* Scripts/webkitpy/webdriver_plt/suites/news.suite: Added.
* Scripts/webkitpy/webdriver_plt/suites/search.suite: Added.
* Scripts/webkitpy/webdriver_plt/suites/shopping.suite: Added.
* Scripts/webkitpy/webdriver_plt/suites/social.suite: Added.
* Scripts/webkitpy/webdriver_plt/suites/suite.py: Added.
(Suite):
(Suite.__init__):
(Suite.get_available_suites):
* Scripts/webkitpy/webdriver_plt/urlresults.py: Added.
(URLResults):
(URLResults.__init__):
(URLResults.__add__):
(URLResults.mean):
(URLResults.coef_variance):
(URLResults.print_results):
(URLResults._format_time):

Modified Paths

Added Paths

Diff

Modified: trunk/Tools/ChangeLog (221776 => 221777)


--- trunk/Tools/ChangeLog	2017-09-08 02:57:23 UTC (rev 221776)
+++ trunk/Tools/ChangeLog	2017-09-08 02:58:08 UTC (rev 221777)
@@ -1,3 +1,58 @@
+2017-09-07  Matthew Stewart  <[email protected]>
+
+        Add Live PLT implemented with WebDriver
+        https://bugs.webkit.org/show_bug.cgi?id=176436
+
+        Reviewed by Stephanie Lewis.
+
+        Adds a new PLT that runs on live websites.
+
+        * Scripts/run-webdriver-plt.py: Added.
+        (parse_args):
+        (start):
+        (make_suites):
+        (main):
+        * Scripts/webkitpy/webdriver_plt/__init__.py: Added.
+        * Scripts/webkitpy/webdriver_plt/liveplt.py: Added.
+        (PageLoadTest):
+        (PageLoadTest.__init__):
+        (PageLoadTest.start):
+        (PageLoadTest.run_suite):
+        (PageLoadTest._get_driver_for_browser):
+        (PageLoadTest._setup_browser_window):
+        (PageLoadTest.run_one_test):
+        (PageLoadTest.get_results):
+        * Scripts/webkitpy/webdriver_plt/pltresults.py: Added.
+        (PLTResults):
+        (PLTResults.__init__):
+        (PLTResults.__add__):
+        (PLTResults.add_timing_result):
+        (PLTResults.mean):
+        (PLTResults.geometric_mean):
+        (PLTResults.mean_coef_variance):
+        (PLTResults.print_results):
+        (PLTResults.print_url_results):
+        (PLTResults._format_time):
+        * Scripts/webkitpy/webdriver_plt/suites/__init__.py: Added.
+        * Scripts/webkitpy/webdriver_plt/suites/arabic.suite: Added.
+        * Scripts/webkitpy/webdriver_plt/suites/cjk.suite: Added.
+        * Scripts/webkitpy/webdriver_plt/suites/news.suite: Added.
+        * Scripts/webkitpy/webdriver_plt/suites/search.suite: Added.
+        * Scripts/webkitpy/webdriver_plt/suites/shopping.suite: Added.
+        * Scripts/webkitpy/webdriver_plt/suites/social.suite: Added.
+        * Scripts/webkitpy/webdriver_plt/suites/suite.py: Added.
+        (Suite):
+        (Suite.__init__):
+        (Suite.get_available_suites):
+        * Scripts/webkitpy/webdriver_plt/urlresults.py: Added.
+        (URLResults):
+        (URLResults.__init__):
+        (URLResults.__add__):
+        (URLResults.mean):
+        (URLResults.coef_variance):
+        (URLResults.print_results):
+        (URLResults._format_time):
+
 2017-09-07  Myles C. Maxfield  <[email protected]>
 
         Add "if" statements to WSL

Added: trunk/Tools/Scripts/run-webdriver-plt.py (0 => 221777)


--- trunk/Tools/Scripts/run-webdriver-plt.py	                        (rev 0)
+++ trunk/Tools/Scripts/run-webdriver-plt.py	2017-09-08 02:58:08 UTC (rev 221777)
@@ -0,0 +1,52 @@
+import argparse
+from webkitpy.webdriver_plt.suites.suite import Suite
+from webkitpy.webdriver_plt.liveplt import PageLoadTest
+
+available_browsers = [
+    "safari", "chrome", "firefox", "stp",
+]
+
+
+def parse_args():
+    parser = argparse.ArgumentParser(description='Automate running PLT with live websites')
+    parser.add_argument('-i', '--iterations', dest='iterations', type=int, default=3, help='Test the suite i times in the same browser session')
+    parser.add_argument('-n', '--instances', dest='instances', type=int, default=3, help='Restart the browser n times for each suite')
+    parser.add_argument('-w', '--wait', dest='wait', type=float, default=3.0, help='Wait time between pages')
+    parser.add_argument('-b', '--browser', dest='browser', default='safari', choices=available_browsers)
+    parser.add_argument('-s', '--suites', dest='suites', nargs='+', help='List one or more suites to run. If unspecified, defaults to running all suites')
+    parser.add_argument('--width', dest='width', help='Set the inner window width')
+    parser.add_argument('--height', dest='height', help='Set the inner window height')
+
+    args = parser.parse_args()
+
+    return args
+
+
+def start(args):
+    suites = make_suites(args.suites)
+    size = (args.width, args.height)
+    plt = PageLoadTest(args.iterations, args.instances, args.wait, args.browser, suites, size)
+    plt.start()
+
+
+def make_suites(suiteslist):
+    available_suites = Suite.get_available_suites()
+    suites = list()
+    if suiteslist:
+        for suitename in suiteslist:
+            if suitename.lower() not in available_suites:
+                print("Suite \"{}\" not found.".format(suitename))
+                quit()
+            suites.append(Suite(suitename.lower()))
+    else:
+        for suitename in available_suites:
+            suites.append(Suite(suitename))
+    return suites
+
+
+def main():
+    return start(parse_args())
+
+
+if __name__ == '__main__':
+    main()
Property changes on: trunk/Tools/Scripts/run-webdriver-plt.py
___________________________________________________________________

Added: svn:executable

+* \ No newline at end of property

Added: trunk/Tools/Scripts/webkitpy/webdriver_plt/__init__.py (0 => 221777)


--- trunk/Tools/Scripts/webkitpy/webdriver_plt/__init__.py	                        (rev 0)
+++ trunk/Tools/Scripts/webkitpy/webdriver_plt/__init__.py	2017-09-08 02:58:08 UTC (rev 221777)
@@ -0,0 +1 @@
+pass

Added: trunk/Tools/Scripts/webkitpy/webdriver_plt/liveplt.py (0 => 221777)


--- trunk/Tools/Scripts/webkitpy/webdriver_plt/liveplt.py	                        (rev 0)
+++ trunk/Tools/Scripts/webkitpy/webdriver_plt/liveplt.py	2017-09-08 02:58:08 UTC (rev 221777)
@@ -0,0 +1,172 @@
+import webkitpy.thirdparty.autoinstalled.selenium
+from pltresults import PLTResults
+from selenium import webdriver
+from time import sleep
+from webkitpy.benchmark_runner.utils import get_driver_binary_path
+from webkitpy.common.timeout_context import Timeout
+
+# FIXME: we want to avoid hardcoding the offsets
+# we use this to make sure the window.innerHeight of each browser is the same
+browser_height_offsets = {
+    'safari': 76,
+    'chrome': 0,
+    'firefox': 37,
+    'stp': 76,
+}
+
+
+class PageLoadTest(object):
+
+    def __init__(self, iterations, instances, wait, browser, suites, size):
+        print("Creating PLT with parameters:")
+        print("iterations: {}".format(iterations))
+        print("instances: {}".format(instances))
+        print("wait: {}s".format(wait))
+        print("browser: {}".format(browser))
+        print("suites: {}".format([s.name for s in suites]))
+        width, height = size
+        if width:
+            print("width: {}".format(width))
+        if height:
+            print("height: {}".format(height))
+        print("")
+        self.iterations = iterations
+        self.instances = instances
+        self.wait = wait
+        self.browser = browser
+        self.suites = suites
+        self.size = size
+
+    def start(self):
+        total_results = PLTResults()
+        suiteid = 0
+        for suite in self.suites:
+            suite.attempts -= 1
+            suiteid += 1
+            print("------------------------------")
+            print("Running suite {id} of {num}: {name}".format(id=suiteid, num=len(self.suites), name=suite.name))
+            print("------------------------------")
+            print("")
+            total_results += self.run_suite(suite)
+        total_results.print_results()
+
+    def run_suite(self, suite):
+        cold_run_results = PLTResults()
+        suite_results = PLTResults()
+
+        for instance in range(self.instances):
+            driver = self._get_driver_for_browser(self.browser)
+            self._setup_browser_window(driver)
+            sleep(5)
+            for iteration in range(self.iterations + 1):
+                print("------------------------------")
+                if iteration == 0:
+                    print("Running iternation %s (cold run)" % iteration)
+                else:
+                    print("Running iternation %s" % iteration)
+                run_results = self.run_one_test(suite, driver)
+                if not run_results:
+                    if suite.attempts <= 0:
+                        print("Failed to finish suite {name} after {x} attempts. Results are incomplete.".format(name=suite.name, x=suite.max_attempts))
+                        print("Exiting...")
+                        quit()
+                    else:
+                        print("A page failed to load. Re-queuing suite.")
+                        self.suites.append(suite)
+                        driver.quit()
+                        return PLTResults()
+                run_results.print_url_results("INDIVIDUAL")
+                if iteration == 0:
+                    cold_run_results += run_results
+                else:
+                    suite_results += run_results
+            driver.quit()
+        cold_run_results.print_results(suite.name, True)
+        suite_results.print_results(suite.name)
+        return suite_results
+
+    def _get_driver_for_browser(self, browser):
+        driver_executable = get_driver_binary_path(browser)
+        if browser == 'safari':
+            return webdriver.Safari()
+        if browser == 'chrome':
+            from selenium.webdriver.chrome.options import Options
+            options = Options()
+            options.add_argument("--disable-web-security")
+            options.add_argument("--disable-extensions")
+            options.add_argument("--start-maximized")
+            return webdriver.Chrome(chrome_options=options, executable_path=driver_executable)
+        if browser == 'firefox':
+            return webdriver.Firefox(executable_path=driver_executable)
+        if browser == 'stp':
+            return webdriver.Safari(executable_path='/Applications/Safari Technology Preview.app/Contents/MacOS/safaridriver')
+
+    def _setup_browser_window(self, driver):
+        driver.maximize_window()
+        sleep(1)
+        current_size = driver.get_window_size()
+
+        new_width, new_height = self.size
+        if not new_width:
+            new_width = driver.execute_script('return screen.width;')
+            print("setting width to {}".format(new_width))
+        if not new_height:
+            new_height = current_size['height'] - browser_height_offsets[self.browser]
+            print("setting height to {}".format(new_height))
+
+        try:
+            driver.set_window_size(width=new_width, height=new_height)
+            driver.set_window_position(x=0, y=0)
+        except:
+            pass
+
+    def run_one_test(self, suite, driver):
+        tabs = False
+        currentTabIdx = 0
+        maxTabs = 5
+        maxRetrys = 5
+        timeout = 30
+
+        local_results = PLTResults()
+
+        for url in suite.urls:
+            if tabs:
+                if currentTabIdx < maxTabs - 1:
+                    raise NotImplementedError("Opening new tabs is not supported yet.")
+                driver.switch_to_window(driver.window_handles[currentTabIdx % maxTabs])
+                currentTabIdx += 1
+            tempWait = self.wait
+            for attempt in range(maxRetrys):
+                driver.set_page_load_timeout(timeout)
+                try:
+                    driver.get(url)
+                except:
+                    print("{url} timed out after {time} seconds.".format(url="" time=timeout))
+                    return None
+
+                sleep(tempWait)
+                if self.get_results(driver, local_results, url):
+                    break
+
+                print("Could not get results for {url}. Retrying...".format(url=""
+                tempWait += 0.5
+                if attempt == maxRetrys - 1:
+                    return None
+        return local_results
+
+    def get_results(self, driver, results, url):
+        nt_results = driver.execute_script('return performance.getEntriesByType("navigation")[0]')  # navigation timing 2
+        if not nt_results:
+            nt_results = driver.execute_script('return performance.timing')  # navigation timing 1
+            start = nt_results['navigationStart']
+            end = nt_results['loadEventEnd']
+            if start == 0 or end == 0:
+                return False
+        else:
+            start = nt_results['startTime']
+            end = nt_results['loadEventEnd']
+            if end == 0:
+                return False
+
+        results.add_timing_result(end - start, url)
+        return True

Added: trunk/Tools/Scripts/webkitpy/webdriver_plt/pltresults.py (0 => 221777)


--- trunk/Tools/Scripts/webkitpy/webdriver_plt/pltresults.py	                        (rev 0)
+++ trunk/Tools/Scripts/webkitpy/webdriver_plt/pltresults.py	2017-09-08 02:58:08 UTC (rev 221777)
@@ -0,0 +1,100 @@
+from collections import OrderedDict
+from urlresults import URLResults
+from math import log, exp
+
+
+class PLTResults(object):
+
+    def __init__(self, geo_sum=1, totalsum=0, num_urls=0, urls=None):
+        self.geo_sum = geo_sum
+        self.sum = totalsum
+        self.count = num_urls
+        if urls is None:
+            urls = OrderedDict()
+        self.urls = urls
+
+    def __add__(self, other):
+        new_geo_sum = self.geo_sum + other.geo_sum
+        new_sum = self.sum + other.sum
+        new_count = self.count + other.count
+        new_urls = OrderedDict(self.urls)
+        for (url, results) in other.urls.items():
+            if url not in self.urls:
+                new_urls[url] = URLResults()
+            new_urls[url] += results
+        return PLTResults(new_geo_sum, new_sum, new_count, new_urls)
+
+    def add_timing_result(self, time, url):
+        self.geo_sum += log(time)
+        self.sum += time
+        self.count += 1
+        if url in self.urls:
+            self.urls[url] += URLResults(time, 1, time ** 2)
+        else:
+            self.urls[url] = URLResults(time, 1, time ** 2)
+
+    @property
+    def mean(self):
+        if self.count:
+            return self.sum / float(self.count)
+        else:
+            return 0
+
+    @property
+    def geometric_mean(self):
+        if self.count:
+            return exp(self.geo_sum / float(self.count))
+        else:
+            return 0
+
+    @property
+    def mean_coef_variance(self):
+        total = 0.0
+        for _, results in self.urls.items():
+            total += results.coef_variance
+        if self.urls and len(self.urls):
+            return total / float(len(self.urls))
+        else:
+            return 0.0
+
+    def print_results(self, suitename=None, cold_run=False):
+        print("------------------------------")
+        if not suitename:
+            print("")
+            print("------------------------------")
+            print("OVERALL PLT RESULTS SUMMARY:")
+        elif cold_run:
+            print("Cold Run Results for {name}:".format(name=suitename))
+        else:
+            print("PLT Results for {name}:".format(name=suitename))
+        if suitename:
+            self.print_url_results("MEAN")
+        else:
+            self.print_url_results("TOTAL MEAN")
+        print("------------------------------")
+        print("TOTAL TIME: {time}".format(time=self._format_time(self.sum)))
+        print("TOTAL URLS: {urls}".format(urls=self.count))
+        if self.urls and len(self.urls) and self.urls.values()[0].count > 1:
+            print("AVERAGE COEFFICIENT OF VARIANCE: {0:.2f}%".format(self.mean_coef_variance))
+        print("AVERAGE TIME PER PAGE: {avg}".format(avg=self._format_time(self.mean)))
+        print("GEOMETRIC MEAN: {avg}".format(avg=self._format_time(self.geometric_mean)))
+        print("------------------------------")
+        print("")
+
+    def print_url_results(self, urlResultsType):
+        print("------------------------------")
+        print("{type} URL LOAD TIMES:".format(type=urlResultsType))
+        if not len(self.urls):
+            print("")
+            return
+        if self.urls.values()[0].count > 1:
+            results_format_str = "{time}{var}{url}"
+        else:
+            results_format_str = "{time}{url}"
+        print(results_format_str.format(time="time (ms)".ljust(12), var="CoV (%)".ljust(10), url=""
+        for (url, results) in self.urls.items():
+            results.print_results(url, results_format_str)
+        print("")
+
+    def _format_time(self, time):
+        return "{} ms".format("{0:.2f}".format(float(time)).rstrip('0').rstrip('.'))

Added: trunk/Tools/Scripts/webkitpy/webdriver_plt/suites/__init__.py (0 => 221777)


--- trunk/Tools/Scripts/webkitpy/webdriver_plt/suites/__init__.py	                        (rev 0)
+++ trunk/Tools/Scripts/webkitpy/webdriver_plt/suites/__init__.py	2017-09-08 02:58:08 UTC (rev 221777)
@@ -0,0 +1 @@
+pass

Added: trunk/Tools/Scripts/webkitpy/webdriver_plt/suites/arabic.suite (0 => 221777)


--- trunk/Tools/Scripts/webkitpy/webdriver_plt/suites/arabic.suite	                        (rev 0)
+++ trunk/Tools/Scripts/webkitpy/webdriver_plt/suites/arabic.suite	2017-09-08 02:58:08 UTC (rev 221777)
@@ -0,0 +1,14 @@
+{
+    "urls": [
+        "http://www.kooora.com",
+        "http://www.kooora.com/?n=0&o=s0",
+        "https://www.bayt.com/ar",
+        "https://www.bayt.com/ar/employers",
+        "http://www.yallakora.com",
+        "http://www.yallakora.com/ar/tours",
+        "http://www.un.org/ar/index.html",
+        "http://www.un.org/ar/sections/resources/delegates",
+        "https://www.emirates.com/ae/arabic",
+        "https://www.emirates.com/ae/arabic/destinations/flights-to-united-states.aspx"
+    ]
+}

Added: trunk/Tools/Scripts/webkitpy/webdriver_plt/suites/cjk.suite (0 => 221777)


--- trunk/Tools/Scripts/webkitpy/webdriver_plt/suites/cjk.suite	                        (rev 0)
+++ trunk/Tools/Scripts/webkitpy/webdriver_plt/suites/cjk.suite	2017-09-08 02:58:08 UTC (rev 221777)
@@ -0,0 +1,16 @@
+{
+    "urls": [
+        "https://www.sogou.com",
+        "https://www.sogou.com/web?query=webkit",
+        "https://cn.nytimes.com",
+        "https://cn.nytimes.com/usa",
+        "https://www.yahoo.co.jp",
+        "https://news.yahoo.co.jp/pickup/6252672",
+        "https://www.rakuten.co.jp",
+        "https://event.rakuten.co.jp",
+        "http://kakaku.com",
+        "http://kakaku.com/pc/lcd-monitor",
+        "https://www.naver.com",
+        "https://section.blog.naver.com"
+    ]
+}

Added: trunk/Tools/Scripts/webkitpy/webdriver_plt/suites/news.suite (0 => 221777)


--- trunk/Tools/Scripts/webkitpy/webdriver_plt/suites/news.suite	                        (rev 0)
+++ trunk/Tools/Scripts/webkitpy/webdriver_plt/suites/news.suite	2017-09-08 02:58:08 UTC (rev 221777)
@@ -0,0 +1,14 @@
+{
+    "urls": [
+        "https://www.nytimes.com",
+        "https://www.nytimes.com/2017/06/27/technology/education-partovi-computer-science-coding-apple-microsoft.html",
+        "https://www.theguardian.com/us/technology",
+        "https://www.theguardian.com/technology/2017/jun/29/iphone-at-10-how-it-changed-everything",
+        "http://www.espn.com",
+        "http://www.espn.com/tennis/story/_/id/20466488/rafael-nadal-does-not-want-face-roger-federer-us-open",
+        "https://news.google.com/news",
+        "https://news.google.com/news/headlines/section/topic/WORLD",
+        "https://www.yahoo.com",
+        "https://www.yahoo.com/tech/apos-pok-mon-apos-celebrates-155523814.html"
+    ]
+}

Added: trunk/Tools/Scripts/webkitpy/webdriver_plt/suites/search.suite (0 => 221777)


--- trunk/Tools/Scripts/webkitpy/webdriver_plt/suites/search.suite	                        (rev 0)
+++ trunk/Tools/Scripts/webkitpy/webdriver_plt/suites/search.suite	2017-09-08 02:58:08 UTC (rev 221777)
@@ -0,0 +1,14 @@
+{
+    "urls": [
+        "https://www.google.com",
+        "https://www.google.com/search?q=webkit",
+        "https://search.yahoo.com",
+        "https://search.yahoo.com/search?p=webkit",
+        "https://www.yandex.com",
+        "https://www.yandex.com/search/?text=webkit",
+        "http://www.bing.com",
+        "http://www.bing.com/search?q=webkit",
+        "https://duckduckgo.com",
+        "https://duckduckgo.com/?q=webkit"
+    ]
+}

Added: trunk/Tools/Scripts/webkitpy/webdriver_plt/suites/shopping.suite (0 => 221777)


--- trunk/Tools/Scripts/webkitpy/webdriver_plt/suites/shopping.suite	                        (rev 0)
+++ trunk/Tools/Scripts/webkitpy/webdriver_plt/suites/shopping.suite	2017-09-08 02:58:08 UTC (rev 221777)
@@ -0,0 +1,14 @@
+{
+    "urls": [
+        "https://www.amazon.com",
+        "https://www.amazon.com/Even-Faster-Web-Sites-Performance/dp/0596522304",
+        "https://www.ebay.com",
+        "https://www.ebay.com/deals",
+        "https://www.craigslist.org",
+        "https://www.craigslist.org/search/sss",
+        "https://www.walmart.com",
+        "https://www.walmart.com/search/?query=food",
+        "https://www.etsy.com",
+        "https://www.etsy.com/c/electronics-and-accessories"
+    ]
+}

Added: trunk/Tools/Scripts/webkitpy/webdriver_plt/suites/social.suite (0 => 221777)


--- trunk/Tools/Scripts/webkitpy/webdriver_plt/suites/social.suite	                        (rev 0)
+++ trunk/Tools/Scripts/webkitpy/webdriver_plt/suites/social.suite	2017-09-08 02:58:08 UTC (rev 221777)
@@ -0,0 +1,16 @@
+{
+    "urls": [
+        "https://www.facebook.com",
+        "https://www.facebook.com/facebook",
+        "https://www.tumblr.com/search/apple",
+        "http://rediscoveringearth.tumblr.com",
+        "https://twitter.com/search?q=webkit",
+        "https://twitter.com/webkit",
+        "https://www.instagram.com/explore/tags/sky",
+        "https://www.instagram.com/apple",
+        "https://www.reddit.com",
+        "https://www.reddit.com/r/programming",
+        "https://www.youtube.com",
+        "https://www.youtube.com/watch?v=Q6dsRpVyyWs"
+    ]
+}

Added: trunk/Tools/Scripts/webkitpy/webdriver_plt/suites/suite.py (0 => 221777)


--- trunk/Tools/Scripts/webkitpy/webdriver_plt/suites/suite.py	                        (rev 0)
+++ trunk/Tools/Scripts/webkitpy/webdriver_plt/suites/suite.py	2017-09-08 02:58:08 UTC (rev 221777)
@@ -0,0 +1,22 @@
+import json
+import os
+
+
+class Suite(object):
+    def __init__(self, suitename):
+        filename = "{0}.suite".format(suitename)
+        filepath = os.path.join(os.path.dirname(__file__), filename)
+        with open(filepath) as suitefile:
+            _suite = json.load(suitefile)
+        self.urls = _suite['urls']
+        self.name = suitename
+        self.attempts = 2
+        self.max_attempts = 2
+
+    @classmethod
+    def get_available_suites(cls):
+        suitesdir = os.path.dirname(__file__)
+        suiteslist = [os.path.splitext(f)[0].lower() for f in os.listdir(suitesdir) if f.endswith('.suite')]
+        if not suiteslist:
+            raise Exception('Cant find any .suite files in directory %s' % suitesdir)
+        return suiteslist

Added: trunk/Tools/Scripts/webkitpy/webdriver_plt/urlresults.py (0 => 221777)


--- trunk/Tools/Scripts/webkitpy/webdriver_plt/urlresults.py	                        (rev 0)
+++ trunk/Tools/Scripts/webkitpy/webdriver_plt/urlresults.py	2017-09-08 02:58:08 UTC (rev 221777)
@@ -0,0 +1,37 @@
+from math import sqrt
+
+
+class URLResults(object):
+
+    def __init__(self, totaltime=0, num_urls=0, std_dev=0.0):
+        self.time = totaltime
+        self.count = num_urls
+        self.std_dev_counter = std_dev
+
+    def __add__(self, other):
+        new_time = self.time + other.time
+        new_count = self.count + other.count
+        new_std_dev_counter = self.std_dev_counter + other.std_dev_counter
+        return URLResults(new_time, new_count, new_std_dev_counter)
+
+    @property
+    def mean(self):
+        if self.count:
+            return self.time / float(self.count)
+        else:
+            return 0
+
+    @property
+    def coef_variance(self):
+        n = self.count
+        if n <= 1:
+            return 0
+        std_dev = sqrt((self.std_dev_counter / float(n - 1)) - (n / float(n - 1)) * (self.mean ** 2))
+        return (std_dev * 100.0) / self.mean
+
+    def print_results(self, url, results_format_str):
+        str_time = self._format_time(self.mean)
+        print(results_format_str.format(time=str_time.ljust(12), var="{0:.2f}%".format(self.coef_variance).ljust(10), url=""
+
+    def _format_time(self, time):
+        return "{} ms".format(int(time))
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to