diff --git a/holmes/facters/phantomas.py b/holmes/facters/phantomas.py index f96ca28..1783e3e 100644 --- a/holmes/facters/phantomas.py +++ b/holmes/facters/phantomas.py @@ -2,9 +2,9 @@ # -*- coding: utf-8 -*- from holmes.facters import Facter +from holmes.facters.phantomas_info import phantomas_metrics import json import subprocess -import threading import re NOTICES_PATTERN = re.compile(r'Time spent on backend / frontend: (\d+)% / (\d+)%') @@ -29,16 +29,15 @@ def __init__(self, *args, **kwargs): @classmethod def get_fact_definitions(cls): definitions = {} - for metric in self.config['metrics']: + for metric in phantomas_metrics: definitions['page.phantomas.%s' % metric] = { - 'title': 'Phantomas metrics - %s', + 'title': 'Phantomas metrics - %s' % metric, 'description': lambda value: '%d' % value } - if self.config['notices']: - definitions['page.phantomas.notices'] = { - 'title': 'Phantomas notices - Time spent on backend / frontend', - 'description': lambda value: '%d / %d' % value - } + definitions['page.phantomas.notices'] = { + 'title': 'Phantomas notices - Time spent on backend / frontend', + 'description': lambda value: '%d / %d' % value + } return definitions def parse_metrics(self, proc): diff --git a/holmes/facters/phantomas_info.py b/holmes/facters/phantomas_info.py new file mode 100644 index 0000000..fd39458 --- /dev/null +++ b/holmes/facters/phantomas_info.py @@ -0,0 +1,100 @@ +phantomas_version = '0.11.0' + +phantomas_metrics = [ + 'ajaxRequests', + 'assetsNotGzipped', + 'assetsWithQueryString', + 'base64Count', + 'base64Size', + 'biggestLatency', + 'biggestResponse', + 'bodyHTMLSize', + 'bodySize', + 'cacheHits', + 'cacheMisses', + 'cachePasses', + 'cachingDisabled', + 'cachingNotSpecified', + 'cachingTooShort', + 'commentsSize', + 'consoleMessages', + 'contentLength', + 'cookiesRecv', + 'cookiesSent', + 'cssCount', + 'cssSize', + 'documentCookiesCount', + 'documentCookiesLength', + 'documentWriteCalls', + 'domains', + 'domainsWithCookies', + 'DOMelementMaxDepth', + 'DOMelementsCount', + 'DOMinserts', + 'DOMqueries', + 'DOMqueriesByClassName', + 'DOMqueriesById', + 'DOMqueriesByQuerySelectorAll', + 'DOMqueriesByTagName', + 'DOMqueriesDuplicated', + 'evalCalls', + 'eventsBound', + 'fastestResponse', + 'globalVariables', + 'gzipRequests', + 'headersCount', + 'headersRecvCount', + 'headersRecvSize', + 'headersSentCount', + 'headersSentSize', + 'headersSize', + 'hiddenContentSize', + 'htmlCount', + 'htmlSize', + 'httpsRequests', + 'httpTrafficCompleted', + 'iframesCount', + 'imageCount', + 'imageSize', + 'imagesWithoutDimensions', + 'jQueryOnDOMReadyFunctions', + 'jQuerySizzleCalls', + 'jQueryVersion', + 'jsCount', + 'jsErrors', + 'jsonCount', + 'jsonSize', + 'jsSize', + 'localStorageEntries', + 'maxRequestsPerDomain', + 'medianLatency', + 'medianRequestsPerDomain', + 'medianResponse', + 'multipleRequests', + 'nodesWithInlineCSS', + 'notFound', + 'onDOMReadyTime', + 'onDOMReadyTimeEnd', + 'otherCount', + 'otherSize', + 'postRequests', + 'redirects', + 'requests', + 'slowestResponse', + 'smallestLatency', + 'smallestResponse', + 'smallImages', + 'timeToFirstByte', + 'timeToFirstCss', + 'timeToFirstImage', + 'timeToFirstJs', + 'timeToLastByte', + 'webfontCount', + 'webfontSize', + 'whiteSpacesSize', + 'windowAlerts', + 'windowConfirms', + 'windowOnLoadTime', + 'windowOnLoadTimeEnd', + 'windowPrompts' +] diff --git a/tests/unit/facters/test_phantomas.py b/tests/unit/facters/test_phantomas.py index 99cc4ac..946e3b9 100644 --- a/tests/unit/facters/test_phantomas.py +++ b/tests/unit/facters/test_phantomas.py @@ -8,17 +8,17 @@ from holmes.config import Config from holmes.reviewer import Reviewer from holmes.facters.phantomas import PhantomasFacter +from holmes.facters.phantomas_info import phantomas_metrics from tests.unit.base import FacterTestCase from tests.fixtures import PageFactory class TestPhantomasFacter(FacterTestCase): - @patch('subprocess.Popen') - def test_get_facts(self, popen_mock): + @patch('subprocess.Popen') # patch decorator here creates a new Popen object and passes it to the function (http://docs.python.org/dev/library/unittest.mock#unittest.mock.patch) + def test_can_get_facts(self, popen_mock): wait_mock = Mock() popen_mock.return_value = Mock(wait=wait_mock, **{'stdout.read': Mock(return_value='{"metrics": {}, "notices": []}')}) - popen_mock.wait = Mock() page = PageFactory.create(url="http://g1.globo.com/1/") reviewer = Reviewer( @@ -55,39 +55,67 @@ def test_parse_metrics(self): facter.add_fact = Mock() json_dict = { - "metrics": { - "foo": 7 + 'metrics': { + 'foo': 7 }, - "notices": ["Time spent on backend / frontend: 7% / 7%"] + 'notices': ['Time spent on backend / frontend: 7% / 7%'] } proc_mock = Mock(**{'stdout.read': Mock(return_value=json.dumps(json_dict))}) facter.parse_metrics(proc_mock) self.assertIn('page.phantomas', facter.review.data) self.assertDictEqual(json_dict, facter.review.data['page.phantomas']) - facter.add_fact.assert_called_with( - key=u'page.phantomas.foo', - value=7 - ) - facter.add_fact.assert_called_with( - key='page.phantomas.notices', - value=(u'7', u'7') - ) + facter.add_fact.assert_has_calls([ + call(key='page.phantomas.foo', value=7), + call(key='page.phantomas.notices', value=('7', '7')), + ], True) + + facter._all_metrics = True + json_dict = { + 'metrics': { + 'foo': 7 + }, + 'notices': ['Foo bar'] + } + proc_mock = Mock(**{'stdout.read': Mock(return_value=json.dumps(json_dict))}) + facter.parse_metrics(proc_mock) + self.assertIn('page.phantomas', facter.review.data) + self.assertDictEqual(json_dict, facter.review.data['page.phantomas']) + facter.add_fact.assert_has_calls([ + call(key='page.phantomas.foo', value=7), + call(key='page.phantomas.notices', value=('7', '7')), + call(key='page.phantomas.foo', value=7), + ], True) + json_dict = { + 'metrics': {}, + 'notices': [] + } + proc_mock = Mock(**{'stdout.read': Mock(return_value=json.dumps(json_dict))}) + facter.parse_metrics(proc_mock) + self.assertIn('page.phantomas', facter.review.data) + self.assertDictEqual(json_dict, facter.review.data['page.phantomas']) + facter.add_fact.assert_has_calls([ + call(key='page.phantomas.foo', value=7), + call(key='page.phantomas.notices', value=('7', '7')), + call(key='page.phantomas.foo', value=7), + ], True) + + def test_can_get_fact_definitions(self): + page = PageFactory.create(url="http://g1.globo.com/1/") + + reviewer = Reviewer( + api_url='http://localhost:2368', + page_uuid=page.uuid, + page_url=page.url, + config=Config(), + validators=[] + ) + facter = PhantomasFacter(reviewer) + definitions = facter.get_fact_definitions() - # facter._all_metrics = True - # return_value = '''{ - # 'metrics': { - # 'foo': 7 - # }, - # 'notices': ['Foo bar'] - # }''' - # proc_mock = Mock(**{'stdout.read': Mock(return_value=return_value)}) - # facter.parse_metrics(proc_mock) + expect('page.phantomas.notices' in definitions).to_be_true() - # return_value = '''{ - # 'metrics': {}, - # 'notices': [] - # }''' - # proc_mock = Mock(**{'stdout.read': Mock(return_value=return_value)}) - # facter.parse_metrics(proc_mock) + expect(definitions).to_length(len(phantomas_metrics) + 1) + for metric in phantomas_metrics: + expect('page.phantomas.%s' % metric in definitions).to_be_true()