# Copyright (c) 2012-2018 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import logging, os, re, threading, time

from autotest_lib.client.bin import test
from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib.cros import chrome

PF_MAX_RATE_PERIOD = 5.0  # seconds
PF_RATE_INTERVAL = 10     # seconds

def get_pf_count():
    """Returns the total number of major page faults since boot.
    """
    with open('/proc/vmstat') as f:
        return float(next((name_value for name_value in f.read().split('\n')
                           if 'pgmajfault ' in name_value)).split()[1])

MEMINFO_RE = re.compile("^(\w+):\s+(\d+)")

def get_meminfo():
    """Returns a dict of name-value pairs from /proc/meminfo.
    """
    info = {}
    with open('/proc/meminfo') as f:
        for line in f:
            m = MEMINFO_RE.match(line)
            if m:
                info[m.group(1)] = int(m.group(2))
    return info

class URLList:
    """A list of URLs as strings, plus a method for circular iteration."""
    def __init__(self):
        """Class initializer"""
        self.index = 0

    TAB_URLS = [
                # commented-out URLs go to sign-in page
                # 'https://mail.google.com',
                # 'https://docs.google.com',
                # 'https://calendar.google.com',
                # 'https://keep.google.com',
                # 'https://sites.google.com',
                # 'https://play.google.com/movies',
                'https://drive.google.com',
                'https://photos.google.com',
                'https://news.google.com',
                'https://plus.google.com',
                'https://maps.google.com',
                'https://play.google.com/store',
                'https://play.google.com/music',
                'https://youtube.com',
                'https://www.nytimes.com',
                'https://www.whitehouse.gov',
                'https://www.wsj.com',
                'http://www.newsweek.com',            # seriously, http?
                'https://www.washingtonpost.com',
                'https://www.foxnews.com',
                'https://www.nbc.com',
                'https://www.amazon.com',
                'https://www.walmart.com',
                'https://www.target.com',
                'https://www.facebook.com',
                'https://www.cnn.com',
                'https://www.cnn.com/us',
                'https://www.cnn.com/world',
                'https://www.cnn.com/politics',
                'https://www.cnn.com/money',
                'https://www.cnn.com/opinion',
                'https://www.cnn.com/health',
                'https://www.cnn.com/entertainment',
                'https://www.cnn.com/tech',
                'https://www.cnn.com/style',
                'https://www.cnn.com/travel',
                'https://www.cnn.com/sports',
                'https://www.cnn.com/video',
               ]

    def next_url(self):
        """Returns the next URL from the list, looping over the list
           as needed.
        """
        url = self.TAB_URLS[self.index];
        self.index += 1
        if self.index == len(self.TAB_URLS):
            self.index = 0
        return url


class PFMeter(threading.Thread):
    """A class whose instances measure page fault rates.  Each class instance
    (really only one is expected) runs a thread to keep track of the max rate.
    """
    def __init__(self):
        """Sets member variables."""
        threading.Thread.__init__(self)
        self.lock = threading.Lock()
        self.running = True
        self.reset()
        self.reset_max()

    def run(self):
        """Checks the average page fault rate across PF_MAX_RATE_PERIOD
           intervals, and records its maximum value.
        """
        logging.info("starting PFMeter thread")
        while self.running:
            time.sleep(PF_MAX_RATE_PERIOD)
            self.record_max()
        logging.info("PFMeter thread exiting")

    def stop(self):
        """Stops the thread."""
        self.running = False

    def reset(self):
        """Resets the meter for the purpose of computing the average rate.
           The max rate is reset with reset_max().
        """
        self.clock_start = time.time()
        self.count_start = get_pf_count()

    def reset_max(self):
        """Resets to 0 the max page fault rate seen thus far."""
        with self.lock:
            self.max_pf_rate = 0.0;
            self.max_clock_start = time.time()
            self.max_count_start = get_pf_count()

    def rate(self):
        """Returns the page fault rate (faults per second) since the last
        call to self (or to reset()).
        """
        clock_end = time.time()
        # Avoid division by zero (however unlikely) by waiting a little.
        if clock_end == self.clock_start:
            time.sleep(0.1)
            clock_end = time.time()
        delta_clock = clock_end - self.clock_start
        count_end = get_pf_count()
        delta_count = count_end - self.count_start

        rate = delta_count / delta_clock

        self.clock_start = clock_end
        self.count_start = count_end

        return rate

    def record_max(self):
        """Computes the average page fault rate since the last call to self, and
           saves the maximum values seen since the last call to reset_max().
        """
        clock = time.time()
        count = get_pf_count()
        with self.lock:
            long_interval_rate = ((count - self.max_count_start) /
                                  (clock - self.max_clock_start))
            self.max_count_start = count
            self.max_clock_start = clock
        if long_interval_rate > self.max_pf_rate:
            self.max_pf_rate = long_interval_rate
            logging.info('max pf rate = %.2f', self.max_pf_rate)

    def max_rate(self):
        """Returns the max pf rate seen since the last reset_max().
        """
        with self.lock:
            m = self.max_pf_rate
        return m

def run_realistic_memory_pressure_test(time_limit, tab_open_delay):
    """Runs a memory pressure test using live pages.
    """
    perf_results = {}
    tab_switch_delay = 0.1
    pf_meter = PFMeter()
    url_list = URLList()

    pf_meter.start()

    with chrome.Chrome() as cr:
        tabs = []
        # Phase 1 (CREATE): open tabs and cycle through them until first
        # discard.
        start_time = time.time()
        # The first tab was created at browser start.
        created_tab_count = 1
        logging.info('START OF PHASE 1')
        while True:
            for _ in range(1):
                tab = cr.browser.tabs.New()
                tabs.append(tab)
                created_tab_count += 1
                # We number tabs starting at 1.
                logging.info('navigating tab %d', created_tab_count)
                tab.Navigate(url_list.next_url());
                try:
                    url = tab.url
                    tab.action_runner.WaitForNetworkQuiescence(
                        timeout_in_seconds=30)
                except Exception as e:
                    logging.warning('network wait exception %s at %s', e, url)

            # Activate tabs to increase the working set.
            for tab in tabs:
                try:
                    tab.Activate()
                    time.sleep(tab_switch_delay)
                    # Check for tab discard.  |cr.browser.tabs| is actually a
                    # method call which returns the number of non-discarded
                    # tabs.
                    if created_tab_count > len(cr.browser.tabs):
                        break
                except:
                    logging.info('tab activation failed, assuming tab discard')
                    break;

            tab_count = len(cr.browser.tabs)
            # Check for tab discard one more time.
            if created_tab_count > tab_count:
                break

            if time.time() > time_limit:
                logging.info('test timeout')
                raise error.TestError('FAIL: phase 1 timeout with %d tabs' %
                                      created_tab_count)

        # Measure the page fault rate.
        pf_meter.reset()
        time.sleep(PF_RATE_INTERVAL)
        current_pf_rate = pf_meter.rate()
        max_pf_rate = pf_meter.max_rate()
        pf_meter.reset_max()

        discard_count = created_tab_count - tab_count
        elapsed_time = time.time() - start_time
        logging.info('opened %d tabs, %d discards',
                     created_tab_count, discard_count)
        logging.info('highest pf rate = %.2f pf/s', max_pf_rate)
        logging.info('elapsed time %.2f', elapsed_time)
        logging.info('END OF PHASE 1')
        meminfo = get_meminfo()
        perf_results['MemTotal'] = meminfo['MemTotal']
        perf_results['SwapTotal'] = meminfo['SwapTotal']

        perf_results['Phase1TabCount'] = tab_count
        perf_results['Phase1DiscardCount'] = discard_count
        perf_results['Phase1Time'] = time.time() - start_time
        perf_results['Phase1MaxPageFaultRate'] = max_pf_rate
        perf_results['Phase1PageFaultRate'] = current_pf_rate
        perf_results['Phase1MemFree'] = meminfo['MemFree']
        perf_results['Phase1SwapFree'] = meminfo['SwapFree']

        # Phase 2 (QUIESCE): Stop all activity.
        logging.info('START OF PHASE 2')
        start_time = time.time()

        # Measure the final pf rate, after one additional sleep.
        time.sleep(60)
        pf_meter.reset()
        time.sleep(PF_RATE_INTERVAL)
        current_pf_rate = pf_meter.rate()
        max_pf_rate = pf_meter.max_rate()

        pf_meter.stop()

        elapsed_time = time.time() - start_time
        browser_tab_count = len(cr.browser.tabs)
        discard_count = len(tabs) + 1 - browser_tab_count
        meminfo = get_meminfo()
        perf_results['Phase2Time'] = elapsed_time
        perf_results['Phase2TabCount'] = browser_tab_count
        perf_results['Phase2DiscardCount'] = discard_count
        perf_results['Phase2MaxPageFaultRate'] = max_pf_rate
        perf_results['Phase2PageFaultRate'] = current_pf_rate
        perf_results['Phase2MemFree'] = meminfo['MemFree']
        perf_results['Phase2SwapFree'] = meminfo['SwapFree']
        logging.info('after quiesce: discard count %d, pf rate = %.2f',
                      discard_count, current_pf_rate)
        logging.info('END OF PHASE 2')


        return perf_results


def run_simple_tab_discard_test(time_limit, tab_delay, bindir):
    """
    Tests that tab discarding works correctly by using a small JS program
    which uses a lot of memory.
    """
    # 1 for initial tab opened
    n_tabs = 1
    discard = False
    perf_results = {}
    start_time = time.time()

    # Open tabs until a tab discard notification arrives, or a time limit
    # is reached.
    with chrome.Chrome(init_network_controller=True) as cr:
        cr.browser.platform.SetHTTPServerDirectories(bindir)
        while True:
            tab = cr.browser.tabs.New()
            n_tabs += 1
            # The program in js-bloat.html allocates a few large arrays and
            # forces them in memory by touching some of their elements.
            tab.Navigate(cr.browser.platform.http_server.UrlOf(
                    os.path.join(bindir, 'js-bloat.html')))
            tab.WaitForDocumentReadyStateToBeComplete()
            time.sleep(tab_delay)
            if n_tabs > len(cr.browser.tabs):
                logging.info('tab discard after %d tabs', n_tabs)
                break
            if time.time() > time_limit:
                raise error.TestError('FAIL: no tab discard after opening %d '
                                      'tabs in %ds' %
                                      (n_tabs, time_limit - start_time))

    perf_results["TabCountAtFirstDiscard"] = n_tabs
    return perf_results


class platform_MemoryPressure(test.test):
    """Memory pressure test."""
    version = 1

    def run_once(self,
                 flavor='simple',
                 tab_open_delay_seconds=1.0,
                 timeout_seconds=1800):
        """Runs the test once.
        """
        time_limit = time.time() + timeout_seconds

        if flavor == 'simple':
            pkv = run_simple_tab_discard_test(time_limit,
                                              tab_open_delay_seconds,
                                              self.bindir)
        elif flavor == 'realistic':
            pkv = run_realistic_memory_pressure_test(time_limit,
                                                     tab_open_delay_seconds)
        else:
            raise error.TestError('unexpected "flavor" parameter: %s' % flavor)

        self.write_perf_keyval(pkv)
