# Copyright 2015 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.

"""Ping connection test.

Description
-----------
Tests network connection by pinging a host for a period of time. Then checks
the percentage of successful pings is above some threshold or not.

If moving_window_size is set, it will check the percentage within the moving
window during the test. It always checks the percentage of successful pings for
the whole duration at the end of the test.

Test Procedure
--------------
This is an automated test without user interaction.

Dependency
----------
The program ``ping``.

Examples
--------
To ping 192.168.0.1 every 2 seconds for 10 seconds, and checks the successful
pings are >= 70% at the end of the test (The default values), add this in test
list::

  {
    "pytest_name": "ping_test",
    "args": {
      "host": "192.168.0.1"
    }
  }

To ping 192.168.0.1 every 10 seconds for 120 seconds, and checks the successful
pings are >= 60% at the end of the test::

  {
    "pytest_name": "ping_test",
    "args": {
      "duration_secs": 120,
      "host": "192.168.0.1",
      "interval_secs": 10,
      "ping_success_percent": 60
    }
  }

To ping 192.168.0.1 on interface eth0 every 10 seconds for 120 seconds, checks
the successful pings are >= 70% within the moving window of 5 pings, and also
checks the successful pings are >= 70% overall::

  {
    "pytest_name": "ping_test",
    "args": {
      "duration_secs": 120,
      "host": "192.168.0.1",
      "interface": "eth0",
      "interval_secs": 10,
      "moving_window_size": 5
    }
  }
"""

from __future__ import print_function

import logging

import factory_common  # pylint: disable=unused-import
from cros.factory.test import test_case
from cros.factory.test import test_ui
from cros.factory.utils.arg_utils import Arg
from cros.factory.utils import process_utils
from cros.factory.utils import time_utils


class PingTest(test_case.TestCase):
  ARGS = [
      Arg('host', str, 'The IP address or hostname to ping.'),
      Arg('interface', str, 'Source interface address, may be numeric IP '
          'address or name of network device, ex: eth0.',
          default=None),
      Arg('interval_secs', int, 'The interval in seconds between two '
          'consecutive pings.',
          default=2),
      Arg('duration_secs', int, 'The duration of the ping test in seconds.',
          default=10),
      Arg('ping_success_percent', int, 'The percentage of successful pings '
          'to meet.  It will be checked at the end of the test.',
          default=70),
      Arg('moving_window_size', int, 'The size of the moving window in number '
          'of ping attempts.  If it is set, the percentage of successful '
          'pings will be checked within the moving window in addition to '
          'that at the end of the test.',
          default=None),
      Arg('verbose', bool, 'Dumps stdout of ping commands.',
          default=False),
      Arg('packet_size', int, 'Specifies the number of data bytes to be sent.',
          default=None),
  ]

  ui_class = test_ui.ScrollableLogUI

  def _CheckSuccessPercentage(self, success_count, total_count, title=''):
    """Checks the percentage of successful pings is within the range."""
    success_percentage = (float(success_count) / total_count) * 100
    if success_percentage < self.args.ping_success_percent:
      self.FailTask(
          'Failed to meet ping success percentage: %.2f%% (expected: %d%%).' % (
              success_percentage, self.args.ping_success_percent))
    logging.info('%s%.2f%% packets received.', title, success_percentage)

  def runTest(self):
    """Tests the network connection by pinging a host for a period of time.

    Pings a host and counts the percentage of successful pings at the end of
    the test.  If moving_window_size is set, it will also check the successful
    percentage within the moving window during the ping tests.
    """
    window_size = self.args.moving_window_size
    moving_queue = []
    moving_success_count = 0
    total_success_count = 0
    total_count = 0

    ping_command = 'ping %s -c 1' % self.args.host
    if self.args.interface:
      ping_command += ' -I %s' % self.args.interface
    if self.args.packet_size:
      ping_command += ' -s %d' % self.args.packet_size

    end_time = time_utils.MonotonicTime() + self.args.duration_secs
    while time_utils.MonotonicTime() < end_time:
      if self.args.verbose:
        p = process_utils.Spawn(ping_command,
                                shell=True, log=True, read_stdout=True)
        logging.info(p.stdout_data)
        if total_count % 10 == 0:
          self.ui.ClearLog()
        self.ui.AppendLog(p.stdout_data + '\n')
      else:
        p = process_utils.Spawn(ping_command, shell=True, call=True,
                                ignore_stdout=True, ignore_stderr=True)
      result = int(p.returncode == 0)

      if window_size is not None:
        moving_success_count += result
        moving_queue.append(result)
        if len(moving_queue) > window_size:
          moving_success_count -= moving_queue.pop(0)
        if len(moving_queue) == window_size:
          self._CheckSuccessPercentage(
              moving_success_count, window_size, 'Moving average: ')

      total_success_count += result
      total_count += 1
      self.Sleep(self.args.interval_secs)

    self._CheckSuccessPercentage(total_success_count, total_count, 'Overall: ')
