Bug 1445383 - update ccache stats parser for ccache 3.4 and 3.5
MozReview-Commit-ID: KTr9RhkJN5B
--- a/python/mozbuild/mozbuild/controller/building.py
+++ b/python/mozbuild/mozbuild/controller/building.py
@@ -752,16 +752,18 @@ class CCacheStats(object):
Instances can be subtracted from each other to obtain differences.
print() or str() the object to show a ``ccache -s`` like output
of the captured stats.
"""
STATS_KEYS = [
# (key, description)
# Refer to stats.c in ccache project for all the descriptions.
+ ('stats_zero_time', 'stats zero time'),
+ ('stats_updated', 'stats updated'),
('cache_hit_direct', 'cache hit (direct)'),
('cache_hit_preprocessed', 'cache hit (preprocessed)'),
('cache_hit_rate', 'cache hit rate'),
('cache_miss', 'cache miss'),
('link', 'called for link'),
('preprocessing', 'called for preprocessing'),
('multiple', 'multiple source files'),
('stdout', 'compiler produced stdout'),
@@ -833,16 +835,23 @@ class CCacheStats(object):
raise ValueError('Failed to parse ccache stats output: %s' % line)
@staticmethod
def _strip_prefix(line, prefix):
return line[len(prefix):].strip() if line.startswith(prefix) else line
@staticmethod
def _parse_value(raw_value):
+ try:
+ # ccache calls strftime with '%c' (src/stats.c)
+ ts = time.strptime(raw_value, '%c')
+ return int(time.mktime(ts))
+ except ValueError:
+ pass
+
value = raw_value.split()
unit = ''
if len(value) == 1:
numeric = value[0]
elif len(value) == 2:
numeric, unit = value
else:
raise ValueError('Failed to parse ccache stats value: %s' % raw_value)
--- a/python/mozbuild/mozbuild/test/controller/test_ccachestats.py
+++ b/python/mozbuild/mozbuild/test/controller/test_ccachestats.py
@@ -1,14 +1,15 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
from __future__ import unicode_literals
+import time
import unittest
from mozunit import main
from mozbuild.controller.building import CCacheStats
class TestCcacheStats(unittest.TestCase):
@@ -169,16 +170,40 @@ class TestCcacheStats(unittest.TestCase)
unsupported code directive 2
no input file 2378
cleanups performed 1792
files in cache 3479
cache size 4.4 GB
max cache size 5.0 GB
"""
+ # Substitute a locally-generated timestamp because the timestamp format is
+ # locale-dependent.
+ STAT8 = """
+ cache directory /home/psimonyi/.ccache
+ primary config /home/psimonyi/.ccache/ccache.conf
+ secondary config (readonly) /etc/ccache.conf
+ stats zero time {timestamp}
+ cache hit (direct) 571
+ cache hit (preprocessed) 1203
+ cache miss 11747
+ cache hit rate 13.12 %
+ called for link 623
+ called for preprocessing 7194
+ compile failed 32
+ preprocessor error 137
+ bad compiler arguments 4
+ autoconf compile/link 348
+ no input file 162
+ cleanups performed 77
+ files in cache 13464
+ cache size 6.2 GB
+ max cache size 7.0 GB
+ """.format(timestamp=time.strftime('%c'))
+
def test_parse_garbage_stats_message(self):
self.assertRaises(ValueError, CCacheStats, self.STAT_GARBAGE)
def test_parse_zero_stats_message(self):
stats = CCacheStats(self.STAT0)
self.assertEqual(stats.cache_dir, "/home/tlin/.ccache")
self.assertEqual(stats.hit_rates(), (0, 0, 0))
@@ -226,10 +251,15 @@ class TestCcacheStats(unittest.TestCase)
self.assertTrue(stat6)
self.assertTrue(stat3)
self.assertTrue(stats_diff)
# Test stats for 3.3.3.
stat7 = CCacheStats(self.STAT7)
self.assertTrue(stat7)
+ def test_stats_version34(self):
+ # Test parsing 3.4 output.
+ stat8 = CCacheStats(self.STAT8)
+ self.assertTrue(stat8)
+
if __name__ == '__main__':
main()