On Wed, 2010-10-13 at 16:02 +0200, Jiří Župka wrote:
> It gather the informatin at start and stop of the
>  measurement or continuously during the measurement.
> 
>  It work in two modes different and average.
>  Different mode subtract oldvalue from new value.
>  Average mode return average of value.
> 
>  example:
>    data:
>       cpu    90  45 24  5 345
>       cpu0   14  11 83 34  33
>       ^^^^
>       start of line
>       params  0   1  2  3   4
> 
>    cpu = FileFieldMonitor("/proc/stat",
>                           [("cpu", 0),
>                            ("cpu", 2),
>                           True)
>     Work in diff mode.
>     get value 0 and 2 from line started "cpu".
> 
>    cpu.stop() # not necessary
>    cpu.get_status() => return tuple of result.

This looks mostly good to me, aside from some minor comments. Being
minor issues, I think I am just going to do a quick respin and apply
when properly tested. See comments below.

> Signed-off-by: Jiří Župka <[email protected]>
> Signed-off-by: Lukáš Doktor <[email protected]>
> ---
>  client/common_lib/utils.py |  139 
> ++++++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 140 insertions(+), 0 deletions(-)
> 
> diff --git a/client/common_lib/utils.py b/client/common_lib/utils.py
> index c126e58..e7e0d02 100644
> --- a/client/common_lib/utils.py
> +++ b/client/common_lib/utils.py
> @@ -4,6 +4,7 @@
>  import os, pickle, random, re, resource, select, shutil, signal, StringIO
>  import socket, struct, subprocess, sys, time, textwrap, urlparse
>  import warnings, smtplib, logging, urllib2
> +from threading import Thread, Event
>  try:
>      import hashlib
>  except ImportError:
> @@ -323,6 +324,156 @@ def write_keyval(path, dictionary, type_tag=None):
>          keyval.close()
>  
> 
> +class FileFieldMonitor():
> +    """
> +    Monitors the information from the file and reports it's values.
> +
> +    It gather the information at start and stop of the measurement or
> +    continuously during the measurement.
> +    """
> +    class Monitor(Thread):
> +        """
> +        Internal monitor class to ensure continuous monitor of monitored 
> file.
> +        """
> +        def __init__(self, master):
> +            """
> +            @param master: Master class which control Monitor
> +            """
> +            Thread.__init__(self)
> +            self.master = master
> +
> +        def run(self):
> +            """
> +            Start monitor in thread mode
> +            """
> +            while not self.master.end_event.isSet():
> +                self.master._get_value(self.master.logging)
> +                time.sleep(self.master.time_step)
> +
> +
> +    def __init__(self, status_file, data_to_read, mode_diff, 
> continuously=False,
> +                 contlogging=False, separator=" +", time_step=0.1):
> +        """
> +        Initialize variables.
> +        @param status_file: File contain status.
> +        @param mode_diff: If True make a difference of value, else average.
> +        @param data_to_read: List of tuples with data position.
> +            format: [(start_of_line,position in params)]
> +            example:
> +              data:
> +                 cpu   324 345 34  5 345
> +                 cpu0  34  11  34 34  33
> +                 ^^^^
> +                 start of line
> +                 params 0   1   2  3   4
> +        @param mode_diff: True to subtract old value from new value,
> +            False make average of the values.
> +        @parma continuously: Start the monitoring thread using the time_step

          ^ Little typo here

> +            as the measurement period.
> +        @param contlogging: Log data in continuous run.
> +        @param separator: Regular expression of separator.
> +        @param time_step: Time period of the monitoring value.
> +        """
> +        self.end_event = Event()
> +        self.start_time = 0
> +        self.end_time = 0
> +        self.test_time = 0
> +
> +        self.status_file = status_file
> +        self.separator = separator
> +        self.data_to_read = data_to_read
> +        self.num_of_params = len(self.data_to_read)
> +        self.mode_diff = mode_diff
> +        self.continoutsly = continuously

^ Typo here, self.continuously

> +        self.time_step = time_step
> +
> +        self.value = [0 for i in range(self.num_of_params)]
> +        self.old_value = [0 for i in range(self.num_of_params)]
> +        self.log = []
> +        self.logging = contlogging
> +
> +        self.started = False
> +        self.num_of_get_value = 0
> +        self.monitor = None
> +
> +
> +    def _get_value(self, logging=True):
> +        """
> +        Return current values.
> +        @param logging: If true log value in memory. There can be problem
> +          with long run.
> +        """
> +        data = read_file(self.status_file)
> +        value = []
> +        for i in range(self.num_of_params):
> +            value.append(int(get_field(data,
> +                             self.data_to_read[i][1],
> +                             self.data_to_read[i][0],
> +                             self.separator)))
> +
> +        if logging:
> +            self.log.append(value)
> +        if not self.mode_diff:
> +            value = map(lambda x, y: x + y, value, self.old_value)
> +
> +        self.old_value = value
> +        self.num_of_get_value += 1
> +        return value
> +
> +
> +    def start(self):
> +        """
> +        Start value monitor.
> +        """
> +        if self.started:
> +            self.stop()
> +        self.old_value = [0 for i in range(self.num_of_params)]
> +        self.num_of_get_value = 0
> +        self.log = []
> +        self.end_event.clear()
> +        self.start_time = time.time()
> +        self._get_value()
> +        self.started = True
> +        if (self.continoutsly):

^ Same typo (in this case, pylint wouldn't get it because it was
consistent with the definition of the constructor.

> +            self.monitor = FileFieldMonitor.Monitor(self)
> +            self.monitor.start()
> +
> +
> +    def stop(self):
> +        """
> +        Stop value monitor.
> +        """
> +        if self.started:
> +            self.started = False
> +            self.end_time = time.time()
> +            self.test_time = self.end_time - self.start_time
> +            self.value = self._get_value()
> +            if (self.continoutsly):
> +                self.end_event.set()
> +                self.monitor.join()
> +            if (self.mode_diff):
> +                self.value = map(lambda x, y: x - y, self.log[-1], 
> self.log[0])
> +            else:
> +                self.value = map(lambda x: x / self.num_of_get_value,
> +                                 self.value)
> +
> +
> +    def get_status(self):
> +        """
> +        @return: Status of monitored process average value,
> +            time of test and array of monitored values and time step of
> +            continuous run.
> +        """
> +        if self.started:
> +            self.stop()
> +        if self.mode_diff:
> +            for i in range(len(self.log) - 1):
> +                self.log[i] = (map(lambda x, y: x - y,
> +                                   self.log[i + 1], self.log[i]))
> +            self.log.pop()
> +        return (self.value, self.test_time, self.log, self.time_step)
> +
> +
>  def is_url(path):
>      """Return true if path looks like a URL"""
>      # for now, just handle http and ftp


_______________________________________________
Autotest mailing list
[email protected]
http://test.kernel.org/cgi-bin/mailman/listinfo/autotest

Reply via email to