async def test_state_filter(flows, mod_test_dir): """It should filter flows by state.""" # one stopped flow opts = ScanOptions(states='stopped', sort=True) lines = [] await main(opts, write=lines.append, scan_dir=mod_test_dir) assert len(lines) == 2 assert '-stopped-' in lines[0] assert 'a/b/c' in lines[1] # one paused flow opts = ScanOptions(states='paused') lines = [] await main(opts, write=lines.append, scan_dir=mod_test_dir) assert len(lines) == 1 assert '-paused-' in lines[0] # one running flow opts = ScanOptions(states='running') lines = [] await main(opts, write=lines.append, scan_dir=mod_test_dir) assert len(lines) == 1 assert '-running-' in lines[0] # two active flows opts = ScanOptions(states='paused,running') lines = [] await main(opts, write=lines.append, scan_dir=mod_test_dir) assert len(lines) == 2 # three registered flows opts = ScanOptions(states='paused,running,stopped') lines = [] await main(opts, write=lines.append, scan_dir=mod_test_dir) assert len(lines) == 4
async def test_format_rich(flows, mod_test_dir): """It should print results in a long human-friendly format.""" # one stopped flow (--colour-blind) opts = ScanOptions(states='running', format='rich', colour_blind=True) flows = [] await main(opts, write=flows.append, scan_dir=mod_test_dir) assert len(flows) == 1 lines = flows[0].splitlines() # test that the multi-line description was output correctly # with trailing lines indented correctly desc_lines = ['Here we find a', 'multi', 'line', 'description'] prev_ind = -1 prev_offset = -1 for expected in desc_lines: for ind, line in enumerate(lines): if expected in line: offset = line.index(expected) if prev_ind < 1: prev_ind = ind prev_offset = offset else: if ind != prev_ind + 1: raise Exception(f'Lines found in wrong order: {line}') if offset != prev_offset: raise Exception('Line incorrectly indented: {line}') break else: raise Exception(f'Missing line: {line}') # test that the state totals show one task running (colour_blind mode) for line in lines: if 'running:1' in line: break else: raise Exception('missing state totals line (colour_blind)') # one stopped flow (--colour=always) opts = ScanOptions(states='running', format='rich') flows = [] await main(opts, write=flows.append, scan_dir=mod_test_dir, color='always') assert len(flows) == 1 lines = flows[0].splitlines() # test that the state totals show one task running (colour mode) for line in lines: if '1 ■' in line: break else: raise Exception('missing state totals line (colourful)')
async def test_scan_cleans_stuck_contact_files( run, scheduler, flow, one_conf, run_dir, test_dir, ): """Ensure scan tidies up contact files from crashed flows.""" # create a flow reg = flow(one_conf, name='-crashed-') schd = scheduler(reg) srv_dir = Path(run_dir, reg, WorkflowFiles.Service.DIRNAME) tmp_dir = test_dir / 'srv' cont = srv_dir / WorkflowFiles.Service.CONTACT # run the flow, copy the contact, stop the flow, copy back the contact async with run(schd): copytree(srv_dir, tmp_dir) rmtree(srv_dir) copytree(tmp_dir, srv_dir) rmtree(tmp_dir) # the old contact file check uses the CLI command that the flow was run # with to check that whether the flow is running. Because this is an # integration test the process is the pytest process and it is still # running so we need to change the command so that Cylc sees the flow as # having crashed contact_info = load_contact_file(reg) contact_info[ContactFileFields.COMMAND] += 'xyz' dump_contact_file(reg, contact_info) # make sure this flow shows for a regular filesystem-only scan opts = ScanOptions(states='running,paused', format='name') flows = [] await main(opts, write=flows.append, scan_dir=test_dir) assert len(flows) == 1 assert '-crashed-' in flows[0] # the contact file should still be there assert cont.exists() # make sure this flow shows for a regular filesystem-only scan opts = ScanOptions(states='running,paused', format='name', ping=True) flows = [] await main(opts, write=flows.append, scan_dir=test_dir) assert len(flows) == 0 # the contact file should have been removed by the scan assert not cont.exists()
async def test_name_filter(flows, mod_test_dir): """It should filter flows by name regex.""" # one stopped flow opts = ScanOptions(states='all', name=['.*paused.*']) lines = [] await main(opts, write=lines.append, scan_dir=mod_test_dir) assert len(lines) == 1 assert '-paused-' in lines[0]
async def test_format_json(flows, mod_test_dir): """It should dump results in json format.""" # one stopped flow opts = ScanOptions(states='all', format='json') lines = [] await main(opts, write=lines.append, scan_dir=mod_test_dir) data = json.loads(lines[0]) assert len(data) == 4 assert data[0]['name']
async def test_name_sort(flows, mod_test_dir): """It should sort flows by name.""" # one stopped flow opts = ScanOptions(states='all', sort=True) lines = [] await main(opts, write=lines.append, scan_dir=mod_test_dir) assert len(lines) == 4 assert '-paused-' in lines[0] assert '-running-' in lines[1] assert '-stopped-' in lines[2] assert 'a/b/c' in lines[3]
async def test_format_tree(flows, run_dir, ses_test_dir, mod_test_dir): """It should dump results in an ascii tree format.""" # one stopped flow opts = ScanOptions(states='running', format='tree') flows = [] await main(opts, write=flows.append, scan_dir=mod_test_dir) assert len(flows) == 1 lines = flows[0].splitlines() # this flow is hierarchically registered in the run dir already # it should be registered as <session test dir>/<module test dir>/<name> assert ses_test_dir.name in lines[0] assert mod_test_dir.name in lines[1] assert '-running-' in lines[2]
def test_ping_connection(): """Ensure scan always connects to the flow when requested via --ping.""" pipe = get_pipe(ScanOptions(states=FLOW_STATES, ping=True), _format_plain) assert 'graphql_query' in repr(pipe)
def test_no_connection(): """Ensure scan uses the filesystem where possible.""" pipe = get_pipe(ScanOptions(states=FLOW_STATES), _format_plain) assert 'graphql_query' not in repr(pipe)