Skip to content
This repository has been archived by the owner on Mar 27, 2023. It is now read-only.

Commit

Permalink
Merge pull request #22 from scorphus/feature/phantomas_per_metrics_a
Browse files Browse the repository at this point in the history
Support Phantomas per metrics
  • Loading branch information
heynemann committed Jan 3, 2014
2 parents 40bf091 + d55c4c1 commit e4e4e06
Show file tree
Hide file tree
Showing 3 changed files with 164 additions and 37 deletions.
15 changes: 7 additions & 8 deletions holmes/facters/phantomas.py
Original file line number Diff line number Diff line change
Expand Up @@ -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+)%')
Expand All @@ -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):
Expand Down
100 changes: 100 additions & 0 deletions holmes/facters/phantomas_info.py
Original file line number Diff line number Diff line change
@@ -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'
]
86 changes: 57 additions & 29 deletions tests/unit/facters/test_phantomas.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -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()

0 comments on commit e4e4e06

Please sign in to comment.