#!/usr/bin/python2
#
# Copyright (c) 2013 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, numpy, os, shutil, socket
import struct, subprocess, tempfile, time

from autotest_lib.client.bin import utils, test
from autotest_lib.client.common_lib import error

def selection_sequential(cur_index, length):
    """
    Iterates over processes sequentially. This should cause worst-case
    behavior for an LRU swap policy.

    @param cur_index: Index of current hog (if sequential)
    @param length: Number of hog processes
    """
    return cur_index

def selection_exp(cur_index, length):
    """
    Iterates over processes randomly according to an exponential distribution.
    Simulates preference for a few long-lived tabs over others.

    @param cur_index: Index of current hog (if sequential)
    @param length: Number of hog processes
    """

    # Discard any values greater than the length of the array.
    # Inelegant, but necessary. Otherwise, the distribution will be skewed.
    exp_value = length
    while exp_value >= length:
        # Mean is index 4 (weights the first 4 indexes the most).
        exp_value = numpy.random.geometric(0.25) - 1
    return int(exp_value)

def selection_uniform(cur_index, length):
    """
    Iterates over processes randomly according to a uniform distribution.

    @param cur_index: Index of current hog (if sequential)
    @param length: Number of hog processes
    """
    return numpy.random.randint(0, length)

# The available selection functions to use.
selection_funcs = {'sequential': selection_sequential,
                   'exponential': selection_exp,
                   'uniform': selection_uniform}

def get_selection_funcs(selections):
    """
    Returns the selection functions listed by their names in 'selections'.

    @param selections: List of strings, where each string is a key for a
                       selection function
    """
    return {
            k: selection_funcs[k]
            for k in selection_funcs
            if k in selections
           }

def reset_zram():
    """
    Resets zram, clearing all swap space.
    """
    swapoff_timeout = 60
    zram_device = 'zram0'
    zram_device_path = os.path.join('/dev', zram_device)
    reset_path = os.path.join('/sys/block', zram_device, 'reset')
    disksize_path = os.path.join('/sys/block', zram_device, 'disksize')

    disksize = utils.read_one_line(disksize_path)

    # swapoff is prone to hanging, especially after heavy swap usage, so
    # time out swapoff if it takes too long.
    ret = utils.system('swapoff ' + zram_device_path,
                       timeout=swapoff_timeout, ignore_status=True)

    if ret != 0:
        raise error.TestFail('Could not reset zram - swapoff failed.')

    # Sleep to avoid "device busy" errors.
    time.sleep(1)
    utils.write_one_line(reset_path, '1')
    time.sleep(1)
    utils.write_one_line(disksize_path, disksize)
    utils.system('mkswap ' + zram_device_path)
    utils.system('swapon ' + zram_device_path)

swap_reset_funcs = {'zram': reset_zram}

class platform_CompressedSwapPerf(test.test):
    """Runs basic performance benchmarks on compressed swap.

    Launches a number of "hog" processes that can be told to "balloon"
    (allocating a specified amount of memory in 1 MiB chunks) and can
    also be "poked", which reads from and writes to random places in memory
    to force swapping in and out. Hog processes report back statistics on how
    long a "poke" took (real and CPU time) and number of page faults.
    """
    version = 1
    executable = 'hog'
    swap_enable_file = '/home/chronos/.swap_enabled'
    swap_disksize_file = '/sys/block/zram0/disksize'

    CMD_POKE = 1
    CMD_BALLOON = 2
    CMD_EXIT = 3

    CMD_FORMAT = "=L"
    CMD_FORMAT_SIZE = struct.calcsize(CMD_FORMAT)

    RESULT_FORMAT = "=QQQQ"
    RESULT_FORMAT_SIZE = struct.calcsize(RESULT_FORMAT)

    def setup(self):
        """
        Compiles the hog program.
        """
        os.chdir(self.srcdir)
        utils.make(self.executable)

    def report_stat(self, units, swap_target, selection, metric, stat, value):
        """
        Reports a single performance statistic. This function puts the supplied
        args into an autotest-approved format.

        @param units: String describing units of the statistic
        @param swap_target: Current swap target, 0.0 <= swap_target < 1.0
        @param selection: Name of selection function to report for
        @param metric: Name of the metric that is being reported
        @param stat: Name of the statistic (e.g. median, 99th percentile)
        @param value: Actual floating-point value
        """
        swap_target_str = '%.2f' % swap_target
        perfkey_name_list = [ units, 'swap', swap_target_str,
                              selection, metric, stat ]

        # Filter out any args that evaluate to false.
        perfkey_name_list = filter(None, perfkey_name_list)
        perf_key = '_'.join(perfkey_name_list)
        self.write_perf_keyval({perf_key: value})

    def report_stats(self, units, swap_target, selection, metric, values):
        """
        Reports interesting statistics from a list of recorded values.

        @param units: String describing units of the statistic
        @param swap_target: Current swap target
        @param selection: Name of current selection function
        @param metric: Name of the metric that is being reported
        @param values: List of floating point measurements for this metric
        """
        if not values:
            logging.info('Cannot report empty list!')
            return

        values = sorted(values)
        mean = float(sum(values)) / len(values)
        median = values[int(0.5*len(values))]
        percentile_95 = values[int(0.95*len(values))]
        percentile_99 = values[int(0.99*len(values))]

        self.report_stat(units, swap_target, selection, metric, 'mean', mean)
        self.report_stat(units, swap_target, selection,
                         metric, 'median', median)
        self.report_stat(units, swap_target, selection,
                         metric, '95th_percentile', percentile_95)
        self.report_stat(units, swap_target, selection,
                         metric, '99th_percentile', percentile_99)

    def sample_memory_state(self):
        """
        Samples memory info from /proc/meminfo and use that to calculate swap
        usage and total memory usage, adjusted for double-counting swap space.
        """
        self.mem_total = utils.read_from_meminfo('MemTotal')
        self.swap_total = utils.read_from_meminfo('SwapTotal')
        self.mem_free = utils.read_from_meminfo('MemFree')
        self.swap_free = utils.read_from_meminfo('SwapFree')
        self.swap_used = self.swap_total - self.swap_free

        used_phys_memory = self.mem_total - self.mem_free

        # Get zram's actual compressed size and convert to KiB.
        swap_phys_size = utils.read_one_line('/sys/block/zram0/compr_data_size')
        swap_phys_size = int(swap_phys_size) / 1024

        self.total_usage = used_phys_memory - swap_phys_size + self.swap_used
        self.usage_ratio = float(self.swap_used) / self.swap_total

    def send_poke(self, hog_sock):
        """Pokes a hog process.
        Poking a hog causes it to simulate activity and report back on
        the same socket.

        @param hog_sock: An open socket to the hog process
        """
        hog_sock.send(struct.pack(self.CMD_FORMAT, self.CMD_POKE))

    def send_balloon(self, hog_sock, alloc_mb):
        """Tells a hog process to allocate more memory.

        @param hog_sock: An open socket to the hog process
        @param alloc_mb: Amount of memory to allocate, in MiB
        """
        hog_sock.send(struct.pack(self.CMD_FORMAT, self.CMD_BALLOON))
        hog_sock.send(struct.pack(self.CMD_FORMAT, alloc_mb))

    def send_exit(self, hog_sock):
        """Tells a hog process to exit and closes the socket.

        @param hog_sock: An open socket to the hog process
        """
        hog_sock.send(struct.pack(self.CMD_FORMAT, self.CMD_EXIT))
        hog_sock.shutdown(socket.SHUT_RDWR)
        hog_sock.close()

    def recv_poke_results(self, hog_sock):
        """Returns the results from poking a hog as a tuple.

        @param hog_sock: An open socket to the hog process
        @return: A tuple (wall_time, user_time, sys_time, fault_count)
        """
        try:
            result = hog_sock.recv(self.RESULT_FORMAT_SIZE)
            if len(result) != self.RESULT_FORMAT_SIZE:
                logging.info("incorrect result, len %d",
                               len(result))
            else:
                result_unpacked = struct.unpack(self.RESULT_FORMAT, result)
                wall_time = result_unpacked[0]
                user_time = result_unpacked[1]
                sys_time = result_unpacked[2]
                fault_count = result_unpacked[3]

                return (wall_time, user_time, sys_time, fault_count)
        except socket.error:
            logging.info('Hog died while touching memory')



    def recv_balloon_results(self, hog_sock, alloc_mb):
        """Receives a balloon response from a hog.
        If a hog succeeds in allocating more memory, it will respond on its
        socket with the original allocation size.

        @param hog_sock: An open socket to the hog process
        @param alloc_mb: Amount of memory to allocate, in MiB
        @raise TestFail: Fails if hog could not allocate memory, or if
                         there is a communication problem.
        """
        balloon_result = hog_sock.recv(self.CMD_FORMAT_SIZE)
        if len(balloon_result) != self.CMD_FORMAT_SIZE:
            return False

        balloon_result_unpack = struct.unpack(self.CMD_FORMAT, balloon_result)

        return balloon_result_unpack == alloc_mb

    def run_single_test(self, compression_factor, num_procs, cycles,
                        swap_target, switch_delay, temp_dir, selections):
        """
        Runs the benchmark for a single swap target usage.

        @param compression_factor: Compression factor (int)
                                   example: compression_factor=3 is 1:3 ratio
        @param num_procs: Number of hog processes to use
        @param cycles: Number of iterations over hogs list for a given swap lvl
        @param swap_target: Floating point value of target swap usage
        @param switch_delay: Number of seconds to wait between poking hogs
        @param temp_dir: Path of the temporary directory to use
        @param selections: List of selection function names
        """
        # Get initial memory state.
        self.sample_memory_state()
        swap_target_usage = swap_target * self.swap_total

        # usage_target is our estimate on the amount of memory that needs to
        # be allocated to reach our target swap usage.
        swap_target_phys = swap_target_usage / compression_factor
        usage_target = self.mem_free - swap_target_phys + swap_target_usage

        hogs = []
        paths = []
        sockets = []
        cmd = [ os.path.join(self.srcdir, self.executable) ]

        # Launch hog processes.
        while len(hogs) < num_procs:
            socket_path = os.path.join(temp_dir, str(len(hogs)))
            paths.append(socket_path)
            launch_cmd = list(cmd)
            launch_cmd.append(socket_path)
            launch_cmd.append(str(compression_factor))
            p = subprocess.Popen(launch_cmd)
            utils.write_one_line('/proc/%d/oom_score_adj' % p.pid, '15')
            hogs.append(p)

        # Open sockets to hog processes, waiting for them to bind first.
        time.sleep(5)
        for socket_path in paths:
            hog_sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
            sockets.append(hog_sock)
            hog_sock.connect(socket_path)

        # Allocate conservatively until we reach our target.
        while self.usage_ratio <= swap_target:
            free_per_hog = (usage_target - self.total_usage) / len(hogs)
            alloc_per_hog_mb = int(0.80 * free_per_hog) / 1024
            if alloc_per_hog_mb <= 0:
                alloc_per_hog_mb = 1

            # Send balloon command.
            for hog_sock in sockets:
                self.send_balloon(hog_sock, alloc_per_hog_mb)

            # Wait until all hogs report back.
            for hog_sock in sockets:
                self.recv_balloon_results(hog_sock, alloc_per_hog_mb)

            # We need to sample memory and swap usage again.
            self.sample_memory_state()

        # Once memory is allocated, report how close we got to the swap target.
        self.report_stat('percent', swap_target, None,
                         'usage', 'value', self.usage_ratio)

        # Run tests by sending "touch memory" command to hogs.
        for f_name, f in get_selection_funcs(selections).iteritems():
            result_list = []

            for count in range(cycles):
                for i in range(len(hogs)):
                    selection = f(i, len(hogs))
                    hog_sock = sockets[selection]
                    retcode = hogs[selection].poll()

                    # Ensure that the hog is not dead.
                    if retcode is None:
                        # Delay between switching "tabs".
                        if switch_delay > 0.0:
                            time.sleep(switch_delay)

                        self.send_poke(hog_sock)

                        result = self.recv_poke_results(hog_sock)
                        if result:
                            result_list.append(result)
                    else:
                        logging.info("Hog died unexpectedly; continuing")

            # Convert from list of tuples (rtime, utime, stime, faults) to
            # a list of rtimes, a list of utimes, etc.
            results_unzipped = [list(x) for x in zip(*result_list)]
            wall_times = results_unzipped[0]
            user_times = results_unzipped[1]
            sys_times = results_unzipped[2]
            fault_counts = results_unzipped[3]

            # Calculate average time to service a fault for each sample.
            us_per_fault_list = []
            for i in range(len(sys_times)):
                if fault_counts[i] == 0.0:
                    us_per_fault_list.append(0.0)
                else:
                    us_per_fault_list.append(sys_times[i] * 1000.0 /
                                             fault_counts[i])

            self.report_stats('ms', swap_target, f_name, 'rtime', wall_times)
            self.report_stats('ms', swap_target, f_name, 'utime', user_times)
            self.report_stats('ms', swap_target, f_name, 'stime', sys_times)
            self.report_stats('faults', swap_target, f_name, 'faults',
                              fault_counts)
            self.report_stats('us_fault', swap_target, f_name, 'fault_time',
                              us_per_fault_list)

        # Send exit message to all hogs.
        for hog_sock in sockets:
            self.send_exit(hog_sock)

        time.sleep(1)

        # If hogs didn't exit normally, kill them.
        for hog in hogs:
            retcode = hog.poll()
            if retcode is None:
                logging.debug("killing all remaining hogs")
                utils.system("killall -TERM hog")
                # Wait to ensure hogs have died before continuing.
                time.sleep(5)
                break

    def run_once(self, compression_factor=3, num_procs=50, cycles=20,
                 selections=None, swap_targets=None, switch_delay=0.0):
        if selections is None:
            selections = ['sequential', 'uniform', 'exponential']
        if swap_targets is None:
            swap_targets = [0.00, 0.25, 0.50, 0.75, 0.95]

        swaptotal = utils.read_from_meminfo('SwapTotal')

        # Check for proper swap space configuration.
        # If the swap enable file says "0", swap.conf does not create swap.
        if os.path.exists(self.swap_enable_file):
            enable_size = utils.read_one_line(self.swap_enable_file)
        else:
            enable_size = "nonexistent" # implies nonzero
        if enable_size == "0":
            if swaptotal != 0:
                raise error.TestFail('The swap enable file said 0, but'
                                     ' swap was still enabled for %d.' %
                                     swaptotal)
            logging.info('Swap enable (0), swap disabled.')
        else:
            # Rather than parsing swap.conf logic to calculate a size,
            # use the value it writes to /sys/block/zram0/disksize.
            if not os.path.exists(self.swap_disksize_file):
                raise error.TestFail('The %s swap enable file should have'
                                     ' caused zram to load, but %s was'
                                     ' not found.' %
                                     (enable_size, self.swap_disksize_file))
            disksize = utils.read_one_line(self.swap_disksize_file)
            swaprequested = int(disksize) / 1000
            if (swaptotal < swaprequested * 0.9 or
                swaptotal > swaprequested * 1.1):
                raise error.TestFail('Our swap of %d K is not within 10%%'
                                     ' of the %d K we requested.' %
                                     (swaptotal, swaprequested))
            logging.info('Swap enable (%s), requested %d, total %d',
                         enable_size, swaprequested, swaptotal)

        # We should try to autodetect this if we add other swap methods.
        swap_method = 'zram'

        for swap_target in swap_targets:
            logging.info('swap_target is %f', swap_target)
            temp_dir = tempfile.mkdtemp()
            try:
                # Reset swap space to make sure nothing leaks between runs.
                swap_reset = swap_reset_funcs[swap_method]
                swap_reset()
                self.run_single_test(compression_factor, num_procs, cycles,
                                     swap_target, switch_delay, temp_dir,
                                     selections)
            except socket.error:
                logging.debug('swap target %f failed; oom killer?', swap_target)

            shutil.rmtree(temp_dir)

