commit 45bc5e4a83fbf38a8733aea16365db7ff1de50c8
Author: Michael Hanselmann <hansmi@google.com>
Date:   Fri Sep 5 10:57:25 2008 +0000

    utils.SplitTime: More rounding fixes
    
    SplitTime didn't round the same on different platforms. This patch changes
    it to use microseconds and not care about rounding.
    
    Reviewed-by: iustinp

diff --git a/lib/utils.py b/lib/utils.py
index 8affd82..0c64e7e 100644
--- a/lib/utils.py
+++ b/lib/utils.py
@@ -1168,33 +1168,40 @@ def CheckVolumeGroupSize(vglist, vgname, minsize):
   return None
 
 
-def SplitTime(seconds):
+def SplitTime(value):
   """Splits time as floating point number into a tuple.
 
-  @param seconds: Time in seconds
-  @type seconds: int or float
-  @return: Tuple containing (seconds, milliseconds)
+  @param value: Time in seconds
+  @type value: int or float
+  @return: Tuple containing (seconds, microseconds)
 
   """
-  seconds = round(seconds, 3)
-  (seconds, fraction) = divmod(seconds, 1.0)
-  return (int(seconds), int(round(fraction * 1000, 0)))
+  (seconds, microseconds) = divmod(int(value * 1000000), 1000000)
+
+  assert 0 <= seconds, \
+    "Seconds must be larger than or equal to 0, but are %s" % seconds
+  assert 0 <= microseconds <= 999999, \
+    "Microseconds must be 0-999999, but are %s" % microseconds
+
+  return (int(seconds), int(microseconds))
 
 
 def MergeTime(timetuple):
   """Merges a tuple into time as a floating point number.
 
-  @param timetuple: Time as tuple, (seconds, milliseconds)
+  @param timetuple: Time as tuple, (seconds, microseconds)
   @type timetuple: tuple
   @return: Time as a floating point number expressed in seconds
 
   """
-  (seconds, milliseconds) = timetuple
+  (seconds, microseconds) = timetuple
 
-  assert 0 <= seconds, "Seconds must be larger than 0"
-  assert 0 <= milliseconds <= 999, "Milliseconds must be 0-999"
+  assert 0 <= seconds, \
+    "Seconds must be larger than or equal to 0, but are %s" % seconds
+  assert 0 <= microseconds <= 999999, \
+    "Microseconds must be 0-999999, but are %s" % microseconds
 
-  return float(seconds) + (float(1) / 1000 * milliseconds)
+  return float(seconds) + (float(microseconds) * 0.000001)
 
 
 def LockedMethod(fn):
diff --git a/test/ganeti.utils_unittest.py b/test/ganeti.utils_unittest.py
index d190111..1b8cae1 100755
--- a/test/ganeti.utils_unittest.py
+++ b/test/ganeti.utils_unittest.py
@@ -783,22 +783,26 @@ class TestTimeFunctions(unittest.TestCase):
 
   def runTest(self):
     self.assertEqual(utils.SplitTime(1), (1, 0))
-    self.assertEqual(utils.SplitTime(1.5), (1, 500))
-    self.assertEqual(utils.SplitTime(1218448917.4809151), (1218448917, 481))
-    self.assertEqual(utils.SplitTime(123.48012), (123, 480))
-    self.assertEqual(utils.SplitTime(123.9995), (124, 0))
-    self.assertEqual(utils.SplitTime(123.999999999), (124, 0))
+    self.assertEqual(utils.SplitTime(1.5), (1, 500000))
+    self.assertEqual(utils.SplitTime(1218448917.4809151), (1218448917, 480915))
+    self.assertEqual(utils.SplitTime(123.48012), (123, 480120))
+    self.assertEqual(utils.SplitTime(123.9996), (123, 999600))
+    self.assertEqual(utils.SplitTime(123.9995), (123, 999500))
+    self.assertEqual(utils.SplitTime(123.9994), (123, 999400))
+    self.assertEqual(utils.SplitTime(123.999999999), (123, 999999))
+
+    self.assertRaises(AssertionError, utils.SplitTime, -1)
 
     self.assertEqual(utils.MergeTime((1, 0)), 1.0)
-    self.assertEqual(utils.MergeTime((1, 500)), 1.5)
-    self.assertEqual(utils.MergeTime((1218448917, 500)), 1218448917.5)
+    self.assertEqual(utils.MergeTime((1, 500000)), 1.5)
+    self.assertEqual(utils.MergeTime((1218448917, 500000)), 1218448917.5)
 
-    self.assertEqual(round(utils.MergeTime((1218448917, 481)), 3), 1218448917.481)
-    self.assertEqual(round(utils.MergeTime((1, 801)), 3), 1.801)
+    self.assertEqual(round(utils.MergeTime((1218448917, 481000)), 3), 1218448917.481)
+    self.assertEqual(round(utils.MergeTime((1, 801000)), 3), 1.801)
 
     self.assertRaises(AssertionError, utils.MergeTime, (0, -1))
-    self.assertRaises(AssertionError, utils.MergeTime, (0, 1000))
-    self.assertRaises(AssertionError, utils.MergeTime, (0, 9999))
+    self.assertRaises(AssertionError, utils.MergeTime, (0, 1000000))
+    self.assertRaises(AssertionError, utils.MergeTime, (0, 9999999))
     self.assertRaises(AssertionError, utils.MergeTime, (-1, 0))
     self.assertRaises(AssertionError, utils.MergeTime, (-9999, 0))
 
