Blame SOURCES/bz1062467.patch

95ec45
commit 004d8a3e46fe4c56b0ea4db27c2c618b86b54f76
95ec45
Author: Nathan Scott <nathans@redhat.com>
95ec45
Date:   Mon Feb 3 17:13:12 2014 +1100
95ec45
95ec45
    Fix and test python wrappers for pmLocaltime and pmCtime
95ec45
    
95ec45
    Several problems uncovered in the time-processing wrappers
95ec45
    of the python PMAPI module after attempting to use 'em for
95ec45
    the first time:
95ec45
    - size of 'struct tm' did not match modern reality (missing
95ec45
      the final two fields for Linux and BSD - sigsegv results);
95ec45
    - system time.mktime python method does not take 9 arguments
95ec45
      just one - fix the string-printing method for struct tm;
95ec45
    - system time.mktime takes year field as an actual year, and
95ec45
      not the number of years since 1900 - code didn't cater for
95ec45
      this difference to struct tm form returned from localtime.
95ec45
    - definition of the pmLocaltime return code was not correct;
95ec45
    - definition of first pmCtime parameter was not correct;
95ec45
    - code didn't cope with numeric input being passed in either
95ec45
      float/integer format - pythonic time-in-seconds is float.
95ec45
    - no memory allocated to hold the struct tm that pmLocaltime
95ec45
      returns - pointer passed in pointing off into lala-land;
95ec45
    - need to ensure a pointer to a ctypes c_long is passed into
95ec45
      both of these routines - caller might well pass int (e.g.
95ec45
      from a pmResult timestamp (struct timeval, tv_sec field).
95ec45
    
95ec45
    Fixed the above and added qa test (boeing) 737 to verify it.
95ec45
    Some small cleanups as well, in the affected code - fixed a
95ec45
    couple of typos in comments, and removed an unused import
95ec45
    of struct_time from the system time module.
95ec45
95ec45
diff --git a/qa/737 b/qa/737
95ec45
new file mode 100755
95ec45
index 0000000..17d6c18
95ec45
--- /dev/null
95ec45
+++ b/qa/737
95ec45
@@ -0,0 +1,29 @@
95ec45
+#!/bin/sh
95ec45
+# PCP QA Test No. 737
95ec45
+# Exercise time interfaces in python PMAPI wrapper module.
95ec45
+#
95ec45
+# Copyright (c) Red Hat.
95ec45
+#
95ec45
+
95ec45
+seq=`basename $0`
95ec45
+echo "QA output created by $seq"
95ec45
+
95ec45
+# get standard environment, filters and checks
95ec45
+. ./common.product
95ec45
+. ./common.filter
95ec45
+. ./common.check
95ec45
+
95ec45
+python -c "from pcp import pmda" >/dev/null 2>&1
95ec45
+[ $? -eq 0 ] || _notrun "python pcp pmda module not installed"
95ec45
+
95ec45
+status=1	# failure is the default!
95ec45
+$sudo rm -rf $tmp.* $seq.full
95ec45
+trap "rm -rf $tmp.*; exit \$status" 0 1 2 3 15
95ec45
+
95ec45
+# real QA test starts here
95ec45
+python src/test_pcp_time.python
95ec45
+
95ec45
+# success, all done
95ec45
+status=0
95ec45
+
95ec45
+exit
95ec45
diff --git a/qa/737.out b/qa/737.out
95ec45
new file mode 100644
95ec45
index 0000000..6a12e50
95ec45
--- /dev/null
95ec45
+++ b/qa/737.out
95ec45
@@ -0,0 +1,5 @@
95ec45
+QA output created by 737
95ec45
+pmLocaltime from int:  1388763979.0 (2014, 1, 3, 15, 46, 19, 1, 33, 0)
95ec45
+pmLocaltime from float:  1388763979.0 (2014, 1, 3, 15, 46, 19, 1, 33, 0)
95ec45
+pmCtime from int:  Mon Feb  3 15:46:19 2014
95ec45
+pmCtime from float:  Mon Feb  3 15:46:19 2014
95ec45
diff --git a/qa/group b/qa/group
95ec45
index 077b83c..bb752f1 100644
95ec45
--- a/qa/group
95ec45
+++ b/qa/group
95ec45
@@ -883,6 +883,7 @@ avahi
95ec45
 733 pmie pmval pmdumplog local oss
95ec45
 735 pmda.proc local oss
95ec45
 736 pmlogrewrite local oss
95ec45
+737 python local oss
95ec45
 740 pmda.sample pmstore secure local oss
95ec45
 748 pmlogrewrite pmda.mysql local oss
95ec45
 749 pmcd local oss
95ec45
diff --git a/qa/src/GNUlocaldefs b/qa/src/GNUlocaldefs
95ec45
index b4382ce..0cf7971 100644
95ec45
--- a/qa/src/GNUlocaldefs
95ec45
+++ b/qa/src/GNUlocaldefs
95ec45
@@ -154,7 +154,8 @@ PLFILES = $(shell echo $(PERLFILES) | sed -e 's/\.perl/.pl/g')
95ec45
 PYTHONFILES = \
95ec45
 	test_pcp.python test_pmcc.python \
95ec45
 	test_pmi.python check_import.python \
95ec45
-	test_mmv.python test_webapi.python
95ec45
+	test_mmv.python test_webapi.python \
95ec45
+	test_pcp_time.python
95ec45
 # not installed:
95ec45
 PYFILES = $(shell echo $(PYTHONFILES) | sed -e 's/\.python/.py/g')
95ec45
 
95ec45
diff --git a/qa/src/test_pcp_time.python b/qa/src/test_pcp_time.python
95ec45
new file mode 100755
95ec45
index 0000000..674686b
95ec45
--- /dev/null
95ec45
+++ b/qa/src/test_pcp_time.python
95ec45
@@ -0,0 +1,32 @@
95ec45
+#!/usr/bin/python
95ec45
+#
95ec45
+# Copyright (C) 2014 Red Hat.
95ec45
+#
95ec45
+# This program is free software; you can redistribute it and/or modify it
95ec45
+# under the terms of the GNU General Public License as published by the
95ec45
+# Free Software Foundation; either version 2 of the License, or (at your
95ec45
+# option) any later version.
95ec45
+#
95ec45
+# This program is distributed in the hope that it will be useful, but
95ec45
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
95ec45
+# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
95ec45
+# for more details.
95ec45
+#
95ec45
+
95ec45
+""" Exercise the pmCtime and pmLocaltime interfaces """
95ec45
+
95ec45
+from pcp import pmapi
95ec45
+
95ec45
+""" Create a live PMAPI context, set as UTC and report time """
95ec45
+context = pmapi.pmContext()
95ec45
+context.pmNewZone("UTC")
95ec45
+
95ec45
+# seconds-since-epoch for: "Mon Feb  3 15:46:19 2014 UTC"
95ec45
+sample_time_i = 1391402779	# integer
95ec45
+sample_time_f = 1391402779.0	# float
95ec45
+
95ec45
+print "pmLocaltime from int: ", context.pmLocaltime(sample_time_i)
95ec45
+print "pmLocaltime from float: ", context.pmLocaltime(sample_time_f)
95ec45
+
95ec45
+print "pmCtime from int: ", context.pmCtime(sample_time_i),
95ec45
+print "pmCtime from float: ", context.pmCtime(sample_time_f),
95ec45
diff --git a/src/python/pcp/pmapi.py b/src/python/pcp/pmapi.py
95ec45
index 527a1f3..72302b4 100644
95ec45
--- a/src/python/pcp/pmapi.py
95ec45
+++ b/src/python/pcp/pmapi.py
95ec45
@@ -56,7 +56,7 @@
95ec45
         # Is this the kernel.all.load id?
95ec45
         if (results.contents.get_pmid(i) != metric_ids[1]):
95ec45
             continue
95ec45
-        # Extrace the kernal.all.load instance
95ec45
+        # Extract the kernel.all.load instance
95ec45
         for j in xrange(results.contents.get_numval(i) - 1):
95ec45
             atom = context.pmExtractValue(results.contents.get_valfmt(i),
95ec45
                                           results.contents.get_vlist(i, j),
95ec45
@@ -69,8 +69,8 @@
95ec45
                 print "load average 5=",atom.f
95ec45
 """
95ec45
 
95ec45
-# for dereferencing times from pmLocaltime function (struct tm)
95ec45
-from time import struct_time, mktime
95ec45
+# for reporting on times from pmLocaltime function
95ec45
+from time import mktime
95ec45
 
95ec45
 # constants adapted from C header file <pcp/pmapi.h>
95ec45
 import cpmapi as c_api
95ec45
@@ -148,13 +148,20 @@ class tm(Structure):
95ec45
                 ("tm_year", c_int),
95ec45
                 ("tm_wday", c_int),
95ec45
                 ("tm_yday", c_int),
95ec45
-                ("tm_isdst", c_int)]
95ec45
+                ("tm_isdst", c_int),
95ec45
+                ("tm_gmtoff", c_long),	# glibc/bsd extension
95ec45
+                ("tm_zone", c_char_p)]	# glibc/bsd extension
95ec45
 
95ec45
     def __str__(self):
95ec45
-        tmp = mktime(self.tm_year, self.tm_mon, self.tm_mday, self.tm_hour,
95ec45
-                     self.tm_min, self.tm_sec, self.tm_wday, self.tm_yday,
95ec45
-                     self.tm_isdst)
95ec45
-        return "%s" % tmp.__str__()
95ec45
+        timetuple = (self.tm_year+1900, self.tm_mon, self.tm_mday,
95ec45
+                     self.tm_hour, self.tm_min, self.tm_sec,
95ec45
+                     self.tm_wday, self.tm_yday, self.tm_isdst)
95ec45
+        inseconds = 0.0
95ec45
+        try:
95ec45
+            inseconds = mktime(timetuple)
95ec45
+        except:
95ec45
+            pass
95ec45
+        return "%s %s" % (inseconds.__str__(), timetuple)
95ec45
 
95ec45
 class pmAtomValue(Union):
95ec45
     """Union used for unpacking metric values according to type
95ec45
@@ -512,11 +519,11 @@ LIBPCP.pmUseZone.argtypes = [c_int]
95ec45
 LIBPCP.pmWhichZone.restype = c_int
95ec45
 LIBPCP.pmWhichZone.argtypes = [POINTER(c_char_p)]
95ec45
 
95ec45
-LIBPCP.pmLocaltime.restype = tm
95ec45
+LIBPCP.pmLocaltime.restype = POINTER(tm)
95ec45
 LIBPCP.pmLocaltime.argtypes = [POINTER(c_long), POINTER(tm)]
95ec45
 
95ec45
 LIBPCP.pmCtime.restype = c_char_p
95ec45
-LIBPCP.pmCtime.argtypes = [c_long, c_char_p]
95ec45
+LIBPCP.pmCtime.argtypes = [POINTER(c_long), c_char_p]
95ec45
 
95ec45
 
95ec45
 ##
95ec45
@@ -689,7 +696,7 @@ class pmContext(object):
95ec45
         status = LIBPCP.pmUseContext(self.ctx)
95ec45
         if status < 0:
95ec45
             raise pmErr, status
95ec45
-        status = LIBPCP.pmGetChildren(name, byref( offspring))
95ec45
+        status = LIBPCP.pmGetChildren(name, byref(offspring))
95ec45
         if status < 0:
95ec45
             raise pmErr, status
95ec45
         if status > 0:
95ec45
@@ -1148,16 +1155,20 @@ class pmContext(object):
95ec45
         status = LIBPCP.pmUseContext(self.ctx)
95ec45
         if status < 0:
95ec45
             raise pmErr, status
95ec45
-        result = POINTER(tm)()
95ec45
-        return LIBPCP.pmLocaltime(seconds, byref(result))
95ec45
+        result = (tm)()
95ec45
+        timetp = c_long(int(seconds))
95ec45
+        LIBPCP.pmLocaltime(byref(timetp), byref(result))
95ec45
+	return result
95ec45
 
95ec45
     def pmCtime(self, seconds):
95ec45
         """PMAPI - format the date and time for a reporting timezone """
95ec45
         status = LIBPCP.pmUseContext(self.ctx)
95ec45
         if status < 0:
95ec45
             raise pmErr, status
95ec45
-        result = (c_char * 32)()
95ec45
-        return LIBPCP.pmCtime(seconds, byref(result))
95ec45
+        result = ctypes.create_string_buffer(32)
95ec45
+        timetp = c_long(int(seconds))
95ec45
+        LIBPCP.pmCtime(byref(timetp), result)
95ec45
+	return str(result.value)
95ec45
 
95ec45
     ##
95ec45
     # PMAPI Metrics Services