Created a custom template_filter as in python3, the groupby filter cannot order Bool vs Str. Needed to push format before the groupby which is not currently possible in jinja.
824 lines
24 KiB
Python
824 lines
24 KiB
Python
import pytest
|
|
import json
|
|
import os
|
|
from datetime import datetime
|
|
from puppetboard import app
|
|
from pypuppetdb.types import Node, Report
|
|
from puppetboard import default_settings
|
|
|
|
from bs4 import BeautifulSoup
|
|
|
|
|
|
class MockDbQuery(object):
|
|
def __init__(self, responses):
|
|
self.responses = responses
|
|
|
|
def get(self, method, **kws):
|
|
resp = None
|
|
if method in self.responses:
|
|
resp = self.responses[method].pop(0)
|
|
|
|
if 'validate' in resp:
|
|
checks = resp['validate']['checks']
|
|
resp = resp['validate']['data']
|
|
for check in checks:
|
|
assert check in kws
|
|
expected_value = checks[check]
|
|
assert expected_value == kws[check]
|
|
return resp
|
|
|
|
|
|
@pytest.fixture
|
|
def mock_puppetdb_environments(mocker):
|
|
environemnts = [
|
|
{'name': 'production'},
|
|
{'name': 'staging'}
|
|
]
|
|
return mocker.patch.object(app.puppetdb, 'environments',
|
|
return_value=environemnts)
|
|
|
|
|
|
@pytest.fixture
|
|
def mock_puppetdb_default_nodes(mocker):
|
|
node_list = [
|
|
Node('_', 'node-unreported',
|
|
report_timestamp='2013-08-01T09:57:00.000Z',
|
|
latest_report_hash='1234567',
|
|
catalog_timestamp='2013-08-01T09:57:00.000Z',
|
|
facts_timestamp='2013-08-01T09:57:00.000Z',
|
|
status_report='unreported'),
|
|
Node('_', 'node-changed',
|
|
report_timestamp='2013-08-01T09:57:00.000Z',
|
|
latest_report_hash='1234567',
|
|
catalog_timestamp='2013-08-01T09:57:00.000Z',
|
|
facts_timestamp='2013-08-01T09:57:00.000Z',
|
|
status_report='changed'),
|
|
Node('_', 'node-failed',
|
|
report_timestamp='2013-08-01T09:57:00.000Z',
|
|
latest_report_hash='1234567',
|
|
catalog_timestamp='2013-08-01T09:57:00.000Z',
|
|
facts_timestamp='2013-08-01T09:57:00.000Z',
|
|
status_report='failed'),
|
|
Node('_', 'node-noop',
|
|
report_timestamp='2013-08-01T09:57:00.000Z',
|
|
latest_report_hash='1234567',
|
|
catalog_timestamp='2013-08-01T09:57:00.000Z',
|
|
facts_timestamp='2013-08-01T09:57:00.000Z',
|
|
status_report='noop'),
|
|
Node('_', 'node-unchanged',
|
|
report_timestamp='2013-08-01T09:57:00.000Z',
|
|
latest_report_hash='1234567',
|
|
catalog_timestamp='2013-08-01T09:57:00.000Z',
|
|
facts_timestamp='2013-08-01T09:57:00.000Z',
|
|
status_report='unchanged'),
|
|
]
|
|
return mocker.patch.object(app.puppetdb, 'nodes',
|
|
return_value=iter(node_list))
|
|
|
|
|
|
@pytest.fixture
|
|
def input_data(request):
|
|
data_path = os.path.join(os.path.dirname(os.path.realpath(__file__)),
|
|
'data')
|
|
data = None
|
|
with open('%s/%s' % (data_path, request.function.__name__), "r") as fp:
|
|
data = fp.read()
|
|
return data
|
|
|
|
|
|
@pytest.fixture
|
|
def client():
|
|
client = app.app.test_client()
|
|
return client
|
|
|
|
|
|
def test_first_test():
|
|
assert app is not None, ("%s" % reg.app)
|
|
|
|
|
|
def test_no_env(client, mock_puppetdb_environments):
|
|
rv = client.get('/nonexsistenv/')
|
|
|
|
assert rv.status_code == 404
|
|
|
|
|
|
def test_get_index(client, mocker,
|
|
mock_puppetdb_environments,
|
|
mock_puppetdb_default_nodes):
|
|
query_data = {
|
|
'nodes': [[{'count': 10}]],
|
|
'resources': [[{'count': 40}]],
|
|
}
|
|
|
|
dbquery = MockDbQuery(query_data)
|
|
|
|
mocker.patch.object(app.puppetdb, '_query', side_effect=dbquery.get)
|
|
rv = client.get('/')
|
|
soup = BeautifulSoup(rv.data, 'html.parser')
|
|
assert soup.title.contents[0] == 'Puppetboard'
|
|
assert rv.status_code == 200
|
|
|
|
|
|
def test_index_all(client, mocker,
|
|
mock_puppetdb_environments,
|
|
mock_puppetdb_default_nodes):
|
|
|
|
base_str = 'puppetlabs.puppetdb.population:'
|
|
query_data = {
|
|
'version': [{'version': '4.2.0'}],
|
|
'mbean': [
|
|
{
|
|
'validate': {
|
|
'data': {'Value': '50'},
|
|
'checks': {
|
|
'path': '%sname=num-nodes' % base_str
|
|
}
|
|
}
|
|
},
|
|
{
|
|
'validate': {
|
|
'data': {'Value': '60'},
|
|
'checks': {
|
|
'path': '%sname=num-resources' % base_str
|
|
}
|
|
}
|
|
},
|
|
{
|
|
'validate': {
|
|
'data': {'Value': 60.3},
|
|
'checks': {
|
|
'path': '%sname=avg-resources-per-node' % base_str
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
dbquery = MockDbQuery(query_data)
|
|
mocker.patch.object(app.puppetdb, '_query', side_effect=dbquery.get)
|
|
rv = client.get('/%2A/')
|
|
|
|
soup = BeautifulSoup(rv.data, 'html.parser')
|
|
assert soup.title.contents[0] == 'Puppetboard'
|
|
vals = soup.find_all('h1',
|
|
{"class": "ui header darkblue no-margin-bottom"})
|
|
|
|
assert len(vals) == 3
|
|
assert vals[0].string == '50'
|
|
assert vals[1].string == '60'
|
|
assert vals[2].string == ' 60'
|
|
|
|
assert rv.status_code == 200
|
|
|
|
|
|
def test_index_all_older_puppetdb(client, mocker,
|
|
mock_puppetdb_environments,
|
|
mock_puppetdb_default_nodes):
|
|
|
|
base_str = 'puppetlabs.puppetdb.population:type=default,'
|
|
query_data = {
|
|
'version': [{'version': '3.2.0'}],
|
|
'mbean': [
|
|
{
|
|
'validate': {
|
|
'data': {'Value': '50'},
|
|
'checks': {
|
|
'path': '%sname=num-nodes' % base_str
|
|
}
|
|
}
|
|
},
|
|
{
|
|
'validate': {
|
|
'data': {'Value': '60'},
|
|
'checks': {
|
|
'path': '%sname=num-resources' % base_str
|
|
}
|
|
}
|
|
},
|
|
{
|
|
'validate': {
|
|
'data': {'Value': 60.3},
|
|
'checks': {
|
|
'path': '%sname=avg-resources-per-node' % base_str
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
dbquery = MockDbQuery(query_data)
|
|
mocker.patch.object(app.puppetdb, '_query', side_effect=dbquery.get)
|
|
rv = client.get('/%2A/')
|
|
|
|
soup = BeautifulSoup(rv.data, 'html.parser')
|
|
assert soup.title.contents[0] == 'Puppetboard'
|
|
vals = soup.find_all('h1',
|
|
{"class": "ui header darkblue no-margin-bottom"})
|
|
|
|
assert len(vals) == 3
|
|
assert vals[0].string == '50'
|
|
assert vals[1].string == '60'
|
|
assert vals[2].string == ' 60'
|
|
|
|
assert rv.status_code == 200
|
|
|
|
|
|
def test_index_division_by_zero(client, mocker):
|
|
mock_puppetdb_environments(mocker)
|
|
mock_puppetdb_default_nodes(mocker)
|
|
|
|
query_data = {
|
|
'nodes': [[{'count': 0}]],
|
|
'resources': [[{'count': 40}]],
|
|
}
|
|
|
|
dbquery = MockDbQuery(query_data)
|
|
|
|
mocker.patch.object(app.puppetdb, '_query', side_effect=dbquery.get)
|
|
|
|
rv = client.get('/')
|
|
|
|
assert rv.status_code == 200
|
|
|
|
soup = BeautifulSoup(rv.data, 'html.parser')
|
|
assert soup.title.contents[0] == 'Puppetboard'
|
|
|
|
vals = soup.find_all('h1',
|
|
{"class": "ui header darkblue no-margin-bottom"})
|
|
assert len(vals) == 3
|
|
assert vals[2].string == '0'
|
|
|
|
|
|
def test_offline_mode(client, mocker):
|
|
app.app.config['OFFLINE_MODE'] = True
|
|
|
|
mock_puppetdb_environments(mocker)
|
|
mock_puppetdb_default_nodes(mocker)
|
|
|
|
query_data = {
|
|
'nodes': [[{'count': 10}]],
|
|
'resources': [[{'count': 40}]],
|
|
}
|
|
|
|
dbquery = MockDbQuery(query_data)
|
|
|
|
mocker.patch.object(app.puppetdb, '_query', side_effect=dbquery.get)
|
|
rv = client.get('/')
|
|
soup = BeautifulSoup(rv.data, 'html.parser')
|
|
assert soup.title.contents[0] == 'Puppetboard'
|
|
for link in soup.find_all('link'):
|
|
assert "//" not in link['href']
|
|
|
|
for script in soup.find_all('script'):
|
|
if "src" in script.attrs:
|
|
assert "//" not in script['src']
|
|
|
|
assert rv.status_code == 200
|
|
|
|
|
|
def test_default_node_view(client, mocker,
|
|
mock_puppetdb_environments,
|
|
mock_puppetdb_default_nodes):
|
|
|
|
rv = client.get('/nodes')
|
|
soup = BeautifulSoup(rv.data, 'html.parser')
|
|
assert soup.title.contents[0] == 'Puppetboard'
|
|
|
|
for label in ['failed', 'changed', 'unreported', 'noop']:
|
|
vals = soup.find_all('a',
|
|
{"class": "ui %s label status" % label})
|
|
assert len(vals) == 1
|
|
assert 'node-%s' % (label) in vals[0].attrs['href']
|
|
|
|
assert rv.status_code == 200
|
|
|
|
|
|
def test_radiator_view(client, mocker,
|
|
mock_puppetdb_environments,
|
|
mock_puppetdb_default_nodes):
|
|
query_data = {
|
|
'nodes': [[{'count': 10}]],
|
|
'resources': [[{'count': 40}]],
|
|
}
|
|
|
|
dbquery = MockDbQuery(query_data)
|
|
|
|
mocker.patch.object(app.puppetdb, '_query', side_effect=dbquery.get)
|
|
|
|
rv = client.get('/radiator')
|
|
|
|
assert rv.status_code == 200
|
|
|
|
soup = BeautifulSoup(rv.data, 'html.parser')
|
|
assert soup.title.contents[0] == 'Puppetboard'
|
|
assert soup.h1 != 'Not Found'
|
|
total = soup.find(class_='total')
|
|
|
|
assert '10' in total.text
|
|
|
|
|
|
def test_radiator_view_all(client, mocker,
|
|
mock_puppetdb_environments,
|
|
mock_puppetdb_default_nodes):
|
|
base_str = 'puppetlabs.puppetdb.population:'
|
|
query_data = {
|
|
'version': [{'version': '4.2.0'}],
|
|
'mbean': [
|
|
{
|
|
'validate': {
|
|
'data': {'Value': '50'},
|
|
'checks': {
|
|
'path': '%sname=num-nodes' % base_str
|
|
}
|
|
}
|
|
},
|
|
{
|
|
'validate': {
|
|
'data': {'Value': '60'},
|
|
'checks': {
|
|
'path': '%sname=num-resources' % base_str
|
|
}
|
|
}
|
|
},
|
|
{
|
|
'validate': {
|
|
'data': {'Value': 60.3},
|
|
'checks': {
|
|
'path': '%sname=avg-resources-per-node' % base_str
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
|
|
dbquery = MockDbQuery(query_data)
|
|
|
|
mocker.patch.object(app.puppetdb, '_query', side_effect=dbquery.get)
|
|
|
|
rv = client.get('/%2A/radiator')
|
|
|
|
assert rv.status_code == 200
|
|
|
|
soup = BeautifulSoup(rv.data, 'html.parser')
|
|
assert soup.title.contents[0] == 'Puppetboard'
|
|
assert soup.h1 != 'Not Found'
|
|
total = soup.find(class_='total')
|
|
|
|
assert '50' in total.text
|
|
|
|
|
|
def test_radiator_view_all_old_version(client, mocker,
|
|
mock_puppetdb_environments,
|
|
mock_puppetdb_default_nodes):
|
|
base_str = 'puppetlabs.puppetdb.population:type=default,'
|
|
query_data = {
|
|
'version': [{'version': '3.2.0'}],
|
|
'mbean': [
|
|
{
|
|
'validate': {
|
|
'data': {'Value': '50'},
|
|
'checks': {
|
|
'path': '%sname=num-nodes' % base_str
|
|
}
|
|
}
|
|
},
|
|
{
|
|
'validate': {
|
|
'data': {'Value': '60'},
|
|
'checks': {
|
|
'path': '%sname=num-resources' % base_str
|
|
}
|
|
}
|
|
},
|
|
{
|
|
'validate': {
|
|
'data': {'Value': 60.3},
|
|
'checks': {
|
|
'path': '%sname=avg-resources-per-node' % base_str
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
|
|
dbquery = MockDbQuery(query_data)
|
|
|
|
mocker.patch.object(app.puppetdb, '_query', side_effect=dbquery.get)
|
|
|
|
rv = client.get('/%2A/radiator')
|
|
|
|
assert rv.status_code == 200
|
|
|
|
soup = BeautifulSoup(rv.data, 'html.parser')
|
|
assert soup.title.contents[0] == 'Puppetboard'
|
|
assert soup.h1 != 'Not Found'
|
|
total = soup.find(class_='total')
|
|
|
|
assert '50' in total.text
|
|
|
|
|
|
def test_radiator_view_json(client, mocker,
|
|
mock_puppetdb_environments,
|
|
mock_puppetdb_default_nodes):
|
|
query_data = {
|
|
'nodes': [[{'count': 10}]],
|
|
'resources': [[{'count': 40}]],
|
|
}
|
|
|
|
dbquery = MockDbQuery(query_data)
|
|
|
|
mocker.patch.object(app.puppetdb, '_query', side_effect=dbquery.get)
|
|
|
|
rv = client.get('/radiator', headers={'Accept': 'application/json'})
|
|
|
|
assert rv.status_code == 200
|
|
json_data = json.loads(rv.data.decode('utf-8'))
|
|
|
|
assert json_data['unreported'] == 1
|
|
assert json_data['noop'] == 1
|
|
assert json_data['failed'] == 1
|
|
assert json_data['changed'] == 1
|
|
assert json_data['unchanged'] == 1
|
|
|
|
|
|
def test_radiator_view_bad_env(client, mocker):
|
|
mock_puppetdb_environments(mocker)
|
|
mock_puppetdb_default_nodes(mocker)
|
|
|
|
query_data = {
|
|
'nodes': [[{'count': 10}]],
|
|
'resources': [[{'count': 40}]],
|
|
}
|
|
|
|
dbquery = MockDbQuery(query_data)
|
|
|
|
mocker.patch.object(app.puppetdb, '_query', side_effect=dbquery.get)
|
|
|
|
rv = client.get('/nothere/radiator')
|
|
|
|
assert rv.status_code == 404
|
|
soup = BeautifulSoup(rv.data, 'html.parser')
|
|
assert soup.title.contents[0] == 'Puppetboard'
|
|
assert soup.h1.text == 'Not Found'
|
|
|
|
|
|
def test_radiator_view_division_by_zero(client, mocker):
|
|
mock_puppetdb_environments(mocker)
|
|
mock_puppetdb_default_nodes(mocker)
|
|
|
|
query_data = {
|
|
'nodes': [[{'count': 0}]],
|
|
'resources': [[{'count': 40}]],
|
|
}
|
|
|
|
dbquery = MockDbQuery(query_data)
|
|
|
|
mocker.patch.object(app.puppetdb, '_query', side_effect=dbquery.get)
|
|
|
|
rv = client.get('/radiator')
|
|
|
|
assert rv.status_code == 200
|
|
|
|
soup = BeautifulSoup(rv.data, 'html.parser')
|
|
assert soup.title.contents[0] == 'Puppetboard'
|
|
|
|
total = soup.find(class_='total')
|
|
assert '0' in total.text
|
|
|
|
|
|
def test_json_report_ok(client, mocker, input_data):
|
|
mock_puppetdb_environments(mocker)
|
|
mock_puppetdb_default_nodes(mocker)
|
|
|
|
query_response = json.loads(input_data)
|
|
|
|
query_data = {
|
|
'reports': [
|
|
{
|
|
'validate': {
|
|
'data': query_response[:100],
|
|
'checks': {
|
|
'limit': 100,
|
|
'offset': 0
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
|
|
dbquery = MockDbQuery(query_data)
|
|
|
|
mocker.patch.object(app.puppetdb, '_query', side_effect=dbquery.get)
|
|
app.puppetdb.last_total = 499
|
|
|
|
rv = client.get('/reports/json')
|
|
|
|
assert rv.status_code == 200
|
|
result_json = json.loads(rv.data.decode('utf-8'))
|
|
|
|
assert 'data' in result_json
|
|
assert len(result_json['data']) == 100
|
|
|
|
|
|
def test_json_daily_reports_chart_ok(client, mocker):
|
|
mock_puppetdb_environments(mocker)
|
|
mock_puppetdb_default_nodes(mocker)
|
|
|
|
query_data = {
|
|
'reports': [
|
|
[{'status': 'changed', 'count': 1}]
|
|
for i in range(app.app.config['DAILY_REPORTS_CHART_DAYS'])
|
|
]
|
|
}
|
|
|
|
dbquery = MockDbQuery(query_data)
|
|
|
|
mocker.patch.object(app.puppetdb, '_query', side_effect=dbquery.get)
|
|
|
|
rv = client.get('/daily_reports_chart.json')
|
|
result_json = json.loads(rv.data.decode('utf-8'))
|
|
|
|
assert 'result' in result_json
|
|
assert (len(result_json['result']) ==
|
|
app.app.config['DAILY_REPORTS_CHART_DAYS'])
|
|
day_format = '%Y-%m-%d'
|
|
cur_day = datetime.strptime(result_json['result'][0]['day'], day_format)
|
|
for day in result_json['result'][1:]:
|
|
next_day = datetime.strptime(day['day'], day_format)
|
|
assert cur_day < next_day
|
|
cur_day = next_day
|
|
|
|
assert rv.status_code == 200
|
|
|
|
|
|
def test_catalogs_disabled(client, mocker,
|
|
mock_puppetdb_environments,
|
|
mock_puppetdb_default_nodes):
|
|
app.app.config['ENABLE_CATALOG'] = False
|
|
rv = client.get('/catalogs')
|
|
assert rv.status_code == 403
|
|
|
|
|
|
def test_catalogs_view(client, mocker,
|
|
mock_puppetdb_environments,
|
|
mock_puppetdb_default_nodes):
|
|
app.app.config['ENABLE_CATALOG'] = True
|
|
rv = client.get('/catalogs')
|
|
assert rv.status_code == 200
|
|
soup = BeautifulSoup(rv.data, 'html.parser')
|
|
assert soup.title.contents[0] == 'Puppetboard'
|
|
|
|
|
|
def test_catalogs_json(client, mocker,
|
|
mock_puppetdb_environments,
|
|
mock_puppetdb_default_nodes):
|
|
app.app.config['ENABLE_CATALOG'] = True
|
|
rv = client.get('/catalogs/json')
|
|
assert rv.status_code == 200
|
|
|
|
result_json = json.loads(rv.data.decode('utf-8'))
|
|
assert 'data' in result_json
|
|
|
|
for line in result_json['data']:
|
|
assert len(line) == 3
|
|
found_status = None
|
|
for status in ['failed', 'changed', 'unchanged', 'noop', 'unreported']:
|
|
val = BeautifulSoup(line[0], 'html.parser').find_all(
|
|
'a', {"href": "/node/node-%s" % status})
|
|
if len(val) == 1:
|
|
found_status = status
|
|
break
|
|
assert found_status, 'Line does not match any known status'
|
|
|
|
val = BeautifulSoup(line[2], 'html.parser').find_all(
|
|
'form', {"method": "GET",
|
|
"action": "/catalogs/compare/node-%s" % found_status})
|
|
assert len(val) == 1
|
|
|
|
|
|
def test_catalogs_json_compare(client, mocker,
|
|
mock_puppetdb_environments,
|
|
mock_puppetdb_default_nodes):
|
|
app.app.config['ENABLE_CATALOG'] = True
|
|
rv = client.get('/catalogs/compare/node-unreported/json')
|
|
assert rv.status_code == 200
|
|
|
|
result_json = json.loads(rv.data.decode('utf-8'))
|
|
assert 'data' in result_json
|
|
|
|
for line in result_json['data']:
|
|
assert len(line) == 3
|
|
found_status = None
|
|
for status in ['failed', 'changed', 'unchanged', 'noop', 'unreported']:
|
|
val = BeautifulSoup(line[0], 'html.parser').find_all(
|
|
'a', {"href": "/node/node-%s" % status})
|
|
if len(val) == 1:
|
|
found_status = status
|
|
break
|
|
assert found_status, 'Line does not match any known status'
|
|
|
|
val = BeautifulSoup(line[2], 'html.parser').find_all(
|
|
'form', {"method": "GET",
|
|
"action": "/catalogs/compare/node-unreported...node-%s" %
|
|
found_status})
|
|
assert len(val) == 1
|
|
|
|
|
|
def test_facts_view(client, mocker, mock_puppetdb_environments):
|
|
query_data = {
|
|
'fact-names': [[chr(i) for i in range(ord('a'), ord('z') + 1)]]
|
|
}
|
|
|
|
dbquery = MockDbQuery(query_data)
|
|
|
|
mocker.patch.object(app.puppetdb, '_query', side_effect=dbquery.get)
|
|
|
|
rv = client.get('/facts')
|
|
assert rv.status_code == 200
|
|
soup = BeautifulSoup(rv.data, 'html.parser')
|
|
assert soup.title.contents[0] == 'Puppetboard'
|
|
|
|
searchable = soup.find('div', {'class': 'searchable'})
|
|
vals = searchable.find_all('div', {'class': 'column'})
|
|
assert len(vals) == 4
|
|
|
|
|
|
def test_fact_view_with_graph(client, mocker,
|
|
mock_puppetdb_environments,
|
|
mock_puppetdb_default_nodes):
|
|
rv = client.get('/fact/architecture')
|
|
assert rv.status_code == 200
|
|
|
|
soup = BeautifulSoup(rv.data, 'html.parser')
|
|
assert soup.title.contents[0] == 'Puppetboard'
|
|
|
|
vals = soup.find_all('div', {"id": "factChart"})
|
|
assert len(vals) == 1
|
|
|
|
|
|
def test_fact_view_without_graph(client, mocker,
|
|
mock_puppetdb_environments,
|
|
mock_puppetdb_default_nodes):
|
|
rv = client.get('/%2A/fact/augeas')
|
|
assert rv.status_code == 200
|
|
|
|
soup = BeautifulSoup(rv.data, 'html.parser')
|
|
assert soup.title.contents[0] == 'Puppetboard'
|
|
|
|
vals = soup.find_all('div', {"id": "factChart"})
|
|
assert len(vals) == 0
|
|
|
|
|
|
def test_fact_value_view(client, mocker,
|
|
mock_puppetdb_environments,
|
|
mock_puppetdb_default_nodes):
|
|
rv = client.get('/fact/architecture/amd64')
|
|
assert rv.status_code == 200
|
|
|
|
soup = BeautifulSoup(rv.data, 'html.parser')
|
|
assert soup.title.contents[0] == 'Puppetboard'
|
|
|
|
vals = soup.find_all('div', {"id": "factChart"})
|
|
assert len(vals) == 0
|
|
|
|
|
|
def test_node_view(client, mocker,
|
|
mock_puppetdb_environments,
|
|
mock_puppetdb_default_nodes):
|
|
rv = client.get('/node/node-failed')
|
|
assert rv.status_code == 200
|
|
|
|
soup = BeautifulSoup(rv.data, 'html.parser')
|
|
assert soup.title.contents[0] == 'Puppetboard'
|
|
|
|
vals = soup.find_all('table', {"id": "facts_table"})
|
|
assert len(vals) == 1
|
|
|
|
vals = soup.find_all('table', {"id": "reports_table"})
|
|
assert len(vals) == 1
|
|
|
|
|
|
def test_fact_json_with_graph(client, mocker,
|
|
mock_puppetdb_environments,
|
|
mock_puppetdb_default_nodes):
|
|
values = ['a', 'b', 'b', 'd', True, 'a\nb']
|
|
query_data = {'facts': []}
|
|
query_data['facts'].append([])
|
|
for i, value in enumerate(values):
|
|
query_data['facts'][0].append({
|
|
'certname': 'node-%s' % i,
|
|
'name': 'architecture',
|
|
'value': value,
|
|
'environment': 'production'
|
|
})
|
|
|
|
dbquery = MockDbQuery(query_data)
|
|
|
|
mocker.patch.object(app.puppetdb, '_query', side_effect=dbquery.get)
|
|
|
|
rv = client.get('/fact/architecture/json')
|
|
assert rv.status_code == 200
|
|
|
|
result_json = json.loads(rv.data.decode('utf-8'))
|
|
|
|
assert 'data' in result_json
|
|
assert len(result_json['data']) == 6
|
|
for line in result_json['data']:
|
|
assert len(line) == 2
|
|
|
|
assert 'chart' in result_json
|
|
assert len(result_json['chart']) == 5
|
|
# Test group_by
|
|
assert result_json['chart'][3]['value'] == 2
|
|
|
|
|
|
def test_fact_json_without_graph(client, mocker,
|
|
mock_puppetdb_environments,
|
|
mock_puppetdb_default_nodes):
|
|
values = ['a', 'b', 'b', 'd']
|
|
query_data = {'facts': []}
|
|
query_data['facts'].append([])
|
|
for i, value in enumerate(values):
|
|
query_data['facts'][0].append({
|
|
'certname': 'node-%s' % i,
|
|
'name': 'architecture',
|
|
'value': value,
|
|
'environment': 'production'
|
|
})
|
|
|
|
dbquery = MockDbQuery(query_data)
|
|
|
|
mocker.patch.object(app.puppetdb, '_query', side_effect=dbquery.get)
|
|
|
|
rv = client.get('/%2A/fact/augeas/json')
|
|
assert rv.status_code == 200
|
|
|
|
result_json = json.loads(rv.data.decode('utf-8'))
|
|
|
|
assert 'data' in result_json
|
|
assert len(result_json['data']) == 4
|
|
for line in result_json['data']:
|
|
assert len(line) == 2
|
|
|
|
assert 'chart' not in result_json
|
|
|
|
|
|
def test_fact_value_json(client, mocker,
|
|
mock_puppetdb_environments,
|
|
mock_puppetdb_default_nodes):
|
|
values = ['a', 'b', 'b', 'd']
|
|
query_data = {'facts': []}
|
|
query_data['facts'].append([])
|
|
for i, value in enumerate(values):
|
|
query_data['facts'][0].append({
|
|
'certname': 'node-%s' % i,
|
|
'name': 'architecture',
|
|
'value': value,
|
|
'environment': 'production'
|
|
})
|
|
|
|
dbquery = MockDbQuery(query_data)
|
|
|
|
mocker.patch.object(app.puppetdb, '_query', side_effect=dbquery.get)
|
|
|
|
rv = client.get('/fact/architecture/amd64/json')
|
|
assert rv.status_code == 200
|
|
|
|
result_json = json.loads(rv.data.decode('utf-8'))
|
|
|
|
assert 'data' in result_json
|
|
assert len(result_json['data']) == 4
|
|
for line in result_json['data']:
|
|
assert len(line) == 1
|
|
|
|
assert 'chart' not in result_json
|
|
|
|
|
|
def test_node_facts_json(client, mocker,
|
|
mock_puppetdb_environments,
|
|
mock_puppetdb_default_nodes):
|
|
values = ['a', 'b', 'b', 'd']
|
|
query_data = {'facts': []}
|
|
query_data['facts'].append([])
|
|
for i, value in enumerate(values):
|
|
query_data['facts'][0].append({
|
|
'certname': 'node-failed',
|
|
'name': 'fact-%s' % i,
|
|
'value': value,
|
|
'environment': 'production'
|
|
})
|
|
|
|
dbquery = MockDbQuery(query_data)
|
|
|
|
mocker.patch.object(app.puppetdb, '_query', side_effect=dbquery.get)
|
|
|
|
rv = client.get('/node/node-failed/facts/json')
|
|
assert rv.status_code == 200
|
|
|
|
result_json = json.loads(rv.data.decode('utf-8'))
|
|
|
|
assert 'data' in result_json
|
|
assert len(result_json['data']) == 4
|
|
for line in result_json['data']:
|
|
assert len(line) == 2
|
|
|
|
assert 'chart' not in result_json
|