diff --git a/ffflash/inc/nodelist.py b/ffflash/inc/nodelist.py index d3f3521..5528e2e 100644 --- a/ffflash/inc/nodelist.py +++ b/ffflash/inc/nodelist.py @@ -5,6 +5,9 @@ def _nodelist_fetch(ff): + if not ff.access_for('nodelist'): + return False + ff.log('fetching nodelist {}'.format(ff.args.nodelist)) nodelist = ( diff --git a/tests/inc/nodelist/test_handle_nodelist.py b/tests/inc/nodelist/test_handle_nodelist.py index c9b81a9..46dbe68 100644 --- a/tests/inc/nodelist/test_handle_nodelist.py +++ b/tests/inc/nodelist/test_handle_nodelist.py @@ -1,3 +1,6 @@ +from json import dumps +from random import choice + from ffflash.inc.nodelist import handle_nodelist @@ -7,3 +10,81 @@ def test_handle_nodelist_without_nodelist(tmpdir, fffake): assert handle_nodelist(ff) is False assert tmpdir.remove() is None + + +def test_handle_nodelist_invalid_nodelist_locations(tmpdir, fffake): + apifile = tmpdir.join('api_file.json') + apifile.write_text(dumps({'a': 'b'}), 'utf-8') + for nodelist in [ + tmpdir.join('nodelist.json'), + 'http://localhost/404/not-found/does/not/exist.json', + ]: + + ff = fffake(apifile, nodelist=nodelist, dry=True) + assert handle_nodelist(ff) is False + + assert tmpdir.remove() is None + + +def test_handle_nodelist_empty_nodelist(tmpdir, fffake): + apifile = tmpdir.join('api_file.json') + apifile.write_text(dumps({'a': 'b'}), 'utf-8') + nl = tmpdir.join('nodelist.json') + nl.write_text(dumps(''), 'utf-8') + + ff = fffake(apifile, nodelist=nl, dry=True) + assert handle_nodelist(ff) is False + + nl.write_text(dumps({'a': 'b'}), 'utf-8') + ff = fffake(apifile, nodelist=nl, dry=True) + assert handle_nodelist(ff) is False + + nl.write_text(dumps({ + 'version': 1, 'nodes': [{}], 'updated_at': 'never' + }), 'utf-8') + ff = fffake(apifile, nodelist=nl, dry=True) + assert handle_nodelist(ff) is False + + assert tmpdir.remove() is None + + +def test_handle_nodelist_count_some_nodes(tmpdir, fffake): + apifile = tmpdir.join('api_file.json') + apifile.write_text(dumps({ + 'state': {'nodes': 0, 'description': ''} + }), 'utf-8') + nl = tmpdir.join('nodelist.json') + + def _n(c, o): + return {'status': {'clients': c, 'online': o}} + + dt = [(choice(range(42)), choice([True, False])) for _ in range(23)] + nl.write_text(dumps({ + 'version': 1, 'nodes': [ + _n(c, o) for c, o in dt + ], 'updated_at': 'never' + }), 'utf-8') + + ff = fffake(apifile, nodelist=nl, dry=True) + + assert ff.api.c.get('state').get('nodes') == 0 + assert handle_nodelist(ff) is True + assert ff.api.c.get('state').get('nodes') == sum([o for _, o in dt]) + + assert tmpdir.remove() is None + + +def test_handle_nodelist_launch_rankfile(tmpdir, fffake): + apifile = tmpdir.join('api_file.json') + apifile.write_text(dumps({'a': 'b'}), 'utf-8') + nl = tmpdir.join('nodelist.json') + nl.write_text(dumps({ + 'version': 1, 'nodes': [{}], 'updated_at': 'never' + }), 'utf-8') + rf = tmpdir.join('rankfile.json') + + ff = fffake(apifile, nodelist=nl, rankfile=rf, dry=True) + + assert handle_nodelist(ff) is False + + assert tmpdir.remove() is None diff --git a/tests/inc/nodelist/test_nodelist_count.py b/tests/inc/nodelist/test_nodelist_count.py index 228300c..8c66846 100644 --- a/tests/inc/nodelist/test_nodelist_count.py +++ b/tests/inc/nodelist/test_nodelist_count.py @@ -32,7 +32,7 @@ def _n(c, o): assert _nodelist_count(ff, {'nodes': [ _n(c, o) for c, o in dt ]}) == ( - sum([o for c, o in dt]), + sum([o for _, o in dt]), sum([c for c, o in dt if o]) ) diff --git a/tests/inc/nodelist/test_nodelist_dump.py b/tests/inc/nodelist/test_nodelist_dump.py new file mode 100644 index 0000000..70ea137 --- /dev/null +++ b/tests/inc/nodelist/test_nodelist_dump.py @@ -0,0 +1,69 @@ +from json import dumps + +from ffflash.inc.nodelist import _nodelist_dump + + +def test_nodelist_dump_no_access(tmpdir, fffake): + ff = fffake(tmpdir.join('api_file.json'), dry=True) + + assert _nodelist_dump(ff, 23, 42) is False + + assert tmpdir.remove() is None + + +def test_nodelist_dump_no_fields_present(tmpdir, fffake): + apifile = tmpdir.join('api_file.json') + apifile.write_text(dumps({'a': 'b'}), 'utf-8') + nl = tmpdir.join('nodelist.json') + + ff = fffake(apifile, nodelist=nl, dry=True) + + assert _nodelist_dump(ff, 23, 42) is False + + assert tmpdir.remove() is None + + +def test_nodelist_dump_state_nodes_present(tmpdir, fffake): + apifile = tmpdir.join('api_file.json') + apifile.write_text(dumps({'state': {'nodes': 0}}), 'utf-8') + nl = tmpdir.join('nodelist.json') + + ff = fffake(apifile, nodelist=nl, dry=True) + + assert ff.api.c.get('state').get('nodes') == 0 + assert _nodelist_dump(ff, 23, 42) is True + assert ff.api.c.get('state').get('nodes') == 23 + + assert tmpdir.remove() is None + + +def test_nodelist_dump_state_description_present_leaves_it(tmpdir, fffake): + descr = 'test test test' + apifile = tmpdir.join('api_file.json') + apifile.write_text(dumps({'state': {'description': descr}}), 'utf-8') + nl = tmpdir.join('nodelist.json') + + ff = fffake(apifile, nodelist=nl, dry=True) + + assert ff.api.c.get('state').get('description') == descr + assert _nodelist_dump(ff, 23, 42) is True + assert ff.api.c.get('state').get('description') == descr + + assert tmpdir.remove() is None + + +def test_nodelist_dump_state_description_empty_present_fills(tmpdir, fffake): + apifile = tmpdir.join('api_file.json') + apifile.write_text(dumps({'state': {'description': ''}}), 'utf-8') + nl = tmpdir.join('nodelist.json') + + ff = fffake(apifile, nodelist=nl, dry=True) + + assert ff.api.c.get('state').get('description') == '' + assert _nodelist_dump(ff, 23, 42) is True + d = ff.api.c.get('state').get('description') + assert d != '' + assert '23 nodes' in d.lower() + assert '42 clients' in d.lower() + + assert tmpdir.remove() is None diff --git a/tests/inc/nodelist/test_nodelist_fetch.py b/tests/inc/nodelist/test_nodelist_fetch.py new file mode 100644 index 0000000..deab7c1 --- /dev/null +++ b/tests/inc/nodelist/test_nodelist_fetch.py @@ -0,0 +1,64 @@ +from json import dumps + +from ffflash.inc.nodelist import _nodelist_fetch + + +def test_nodelist_fetch_without_nodelist(tmpdir, fffake): + ff = fffake(tmpdir.join('api_file.json'), dry=True) + + assert _nodelist_fetch(ff) is False + + assert tmpdir.remove() is None + + +def test_nodelist_fetch_non_existing_nodelist(tmpdir, fffake): + apifile = tmpdir.join('api_file.json') + apifile.write_text(dumps({'a': 'b'}), 'utf-8') + + for nodelist in [ + tmpdir.join('nodelist.json'), + 'http://localhost/404/not-found/does/not/exist.json' + ]: + ff = fffake(apifile, nodelist=nodelist, dry=True) + assert _nodelist_fetch(ff) is False + + assert tmpdir.remove() is None + + +def test_nodelist_fetch_wrong_format_or_empty(tmpdir, fffake, capsys): + apifile = tmpdir.join('api_file.json') + apifile.write_text(dumps({'a': 'b'}), 'utf-8') + nl = tmpdir.join('nodelist.json') + nl.write_text(dumps(''), 'utf-8') + + ff = fffake(apifile, nodelist=nl, dry=True) + assert _nodelist_fetch(ff) is False + out, err = capsys.readouterr() + assert 'not' in out + assert 'fetch' in out + assert err == '' + + nl.write_text(dumps({'a': 'b'}), 'utf-8') + + ff = fffake(apifile, nodelist=nl, dry=True) + assert _nodelist_fetch(ff) is False + out, err = capsys.readouterr() + assert 'no' in out + assert 'nodelist' in out + assert err == '' + + assert tmpdir.remove() is None + + +def test_nodelist_fetch(tmpdir, fffake): + apifile = tmpdir.join('api_file.json') + apifile.write_text(dumps({'a': 'b'}), 'utf-8') + nodelist = {'version': 1, 'nodes': [None], 'updated_at': 'never'} + nl = tmpdir.join('nodelist.json') + nl.write_text(dumps(nodelist), 'utf-8') + assert tmpdir.listdir() == [apifile, nl] + + ff = fffake(apifile, nodelist=nl, dry=True) + assert _nodelist_fetch(ff) == nodelist + + assert tmpdir.remove() is None diff --git a/tests/main/test_run.py b/tests/main/test_run.py index b95e0a7..2123570 100644 --- a/tests/main/test_run.py +++ b/tests/main/test_run.py @@ -1,12 +1,89 @@ +from json import dumps as j_dump +from json import loads as j_load +from pprint import pformat + import pytest +from yaml import load as y_load from ffflash.main import run -def test_main_no_or_empty_apifile(tmpdir): +def test_run_no_or_empty_apifile(tmpdir): with pytest.raises(SystemExit): run([]) assert run([str(tmpdir.join('phony_api_file.txt')), '-d']) is True assert tmpdir.remove() is None + + +def test_run_dump_apifile(tmpdir, capsys): + c = {'a': 'b', 'c': 'd'} + apifile = tmpdir.join('api_file.json') + apifile.write_text(j_dump(c), 'utf-8') + + assert run([str(apifile), '-d']) is True + out, err = capsys.readouterr() + assert out.strip().endswith(pformat(c)) + assert err == '' + + assert tmpdir.remove() is None + + +def test_run_apifile_not_modified(tmpdir): + c = {'a': 'b', 'c': 'd'} + apifile = tmpdir.join('api_file.json') + apifile.write_text(j_dump(c), 'utf-8') + + nodelist = tmpdir.join('nodelist.json') + nodelist.write_text(j_dump({ + 'will': {'not': {'be': 'recognized'}} + }), 'utf-8') + + side = tmpdir.join('wrong_extension.txt') + car = tmpdir.join('double..dot.yaml') + + assert run([ + str(apifile), + '-n', str(nodelist), + '-s', str(side), str(car) + ]) is True + + assert tmpdir.remove() is None + + +def test_run_apifile_modified(tmpdir): + c = {'a': 'b', 'c': 'd', 'state': {'nodes': 0}} + apifile = tmpdir.join('api_file.json') + apifile.write_text(j_dump(c), 'utf-8') + + nodelist = tmpdir.join('nodelist.json') + nodelist.write_text(j_dump({ + 'version': 1, + 'nodes': [ + {'status': {'clients': 23, 'online': True}}, + {'status': {'clients': 42, 'online': False}} + ], + 'updated_at': 'never' + }), 'utf-8') + + side = tmpdir.join('a.json') + car = tmpdir.join('c.yaml') + + assert tmpdir.listdir() == [apifile, nodelist] + + assert run([ + str(apifile), + '-n', str(nodelist), + '-s', str(side), str(car) + ]) is False + + assert tmpdir.listdir() == [side, apifile, car, nodelist] + + assert j_load(side.read_text('utf-8')) == 'b' + assert y_load(car.read_text('utf-8')) == 'd' + + c['state']['nodes'] = 1 + assert j_load(apifile.read_text('utf-8')) == c + + assert tmpdir.remove() is None