'Run scans, with and without agents'

def test_scans(self):

    (res, out, _) = RUN(['ivre', 'runscans', '--output', 'Test', '--test', '2'])
    self.assertEqual(res, 0)
    self.assertTrue(('\nRead    address    127.0.0.1\n' in out))
    self.assertTrue(('\nRead    address    127.0.0.2\n' in out))
    res = RUN(['ivre', 'runscans', '--network', '127.0.0.1/31'])[0]
    self.assertEqual(res, 0)
    fdesc = tempfile.NamedTemporaryFile(delete=False)
    fdesc.writelines((('127.0.0.%d\n' % i).encode() for i in range(2, 4)))
    fdesc.close()
    res = RUN(['ivre', 'runscans', '--file', fdesc.name, '--output', 'XMLFork'])[0]
    self.assertEqual(res, 0)
    os.unlink(fdesc.name)
    res = RUN(['ivre', 'runscans', '--range', '127.0.0.4', '127.0.0.5', '--output', 'XMLFull'])[0]
    count = sum((len(walk_elt[2]) for walk_elt in os.walk('scans')))
    self.assertEqual(count, 9)
    res = RUN(['ivre', 'runscans', '--output', 'CommandLine'])[0]
    self.assertEqual(res, 0)
    (res, out, _) = RUN(['ivre', 'runscans', '--output', 'Agent'])
    self.assertEqual(res, 0)
    with open('ivre-agent.sh', 'wb') as fdesc:
        fdesc.write(out)
    os.chmod('ivre-agent.sh', 493)
    ivre.utils.makedirs('input')
    ivre.utils.makedirs('tmp')
    pid_agent = subprocess.Popen([os.path.join(os.getcwd(), 'ivre-agent.sh')], preexec_fn=os.setsid, cwd='tmp').pid
    res = RUN(['ivre', 'runscansagent', '--test', '2', '--feed', './tmp/'], stdin=open(os.devnull, 'wb'))[0]
    self.assertEqual(res, 0)
    feed_cmd = ['runscansagent', '--sync', './tmp/']
    if USE_COVERAGE:
        feed_cmd = ((COVERAGE + ['run', '--parallel-mode', which('ivre')]) + feed_cmd)
    else:
        feed_cmd = (['ivre'] + feed_cmd)
    pid_feed = subprocess.Popen(feed_cmd).pid
    while any((walk[2] for dirname in ['agentsdata/._tmp_/input', 'agentsdata/._tmp_/remoteinput', 'agentsdata/._tmp_/remotecur', 'tmp/input', 'tmp/cur', 'tmp/output'] for walk in os.walk(dirname))):
        print(u'Waiting    for    runscans    sync    &    agent')
        time.sleep(2)
    os.kill(pid_agent, signal.SIGTERM)
    os.kill(pid_feed, signal.SIGTERM)
    os.waitpid(pid_agent, 0)
    os.waitpid(pid_feed, 0)
    count = sum((len(walk_elt[2]) for walk_elt in os.walk('agentsdata/._tmp_/remoteoutput/')))
    self.assertEqual(count, 2)
    pid_agent = subprocess.Popen([os.path.join(os.getcwd(), 'ivre-agent.sh')], preexec_fn=os.setsid, cwd='tmp').pid
    self.init_nmap_db()
    res = RUN(['ivre', 'runscansagentdb', '--init'], stdin=open(os.devnull))[0]
    self.assertEqual(res, 0)
    res = RUN(['ivre', 'runscansagentdb', '--add-local-master'])[0]
    self.assertEqual(res, 0)
    res = RUN(['ivre', 'runscansagentdb', '--source', 'TEST-AGENT-SOURCE', '--add-agent', os.path.join(os.getcwd(), 'tmp')])[0]
    res = RUN(['ivre', 'runscansagentdb', '--test', '2', '--assign-free-agents'])[0]
    self.assertEqual(res, 0)
    fdesc = tempfile.NamedTemporaryFile(delete=False)
    fdesc.writelines((('127.0.0.%d\n' % i).encode() for i in range(3, 5)))
    fdesc.close()
    res = RUN(['ivre', 'runscansagentdb', '--file', fdesc.name, '--assign-free-agents'])[0]
    self.assertEqual(res, 0)
    daemon_cmd = ['runscansagentdb', '--daemon']
    if USE_COVERAGE:
        daemon_cmd = ((COVERAGE + ['run', '--parallel-mode', which('ivre')]) + daemon_cmd)
    else:
        daemon_cmd = (['ivre'] + daemon_cmd)
    pid_daemon = subprocess.Popen(daemon_cmd).pid
    time.sleep(4)
    scanmatch = re.compile('scan:\n        -    id:    (?P<id>[0-9a-f]+)\n.*\n.*\n        -    targets    added:    (?P<nbadded>\\d+)\n        -    results    fetched:    (?P<nbfetched>\\d+)\n        -    total    targets    to    add:    (?P<nbtargets>\\d+)\n')
    is_scan_over = (lambda scan: (int(scan['nbtargets']) == int(scan['nbfetched'])))
    while True:
        (res, out, _) = RUN(['ivre', 'runscansagentdb', '--list-scans'])
        scans = [scan.groupdict() for scan in scanmatch.finditer(out)]
        self.assertEqual(len(scans), 2)
        if any((is_scan_over(scan) for scan in scans)):
            break
        time.sleep(2)
    scan = next((scan for scan in scans if (not is_scan_over(scan))))
    agentmatch = re.compile('agent:\n        -    id:    (?P<id>[0-9a-f]+)\n')
    (res, out, _) = RUN(['ivre', 'runscansagentdb', '--list-agents'])
    agents = [agent.groupdict() for agent in agentmatch.finditer(out)]
    self.assertEqual(len(agents), 1)
    agent = agents[0]
    res = RUN(['ivre', 'runscansagentdb', '--assign', ('%s:%s' % (agent['id'].decode(), scan['id'].decode()))])[0]
    time.sleep(4)
    while True:
        (res, out, _) = RUN(['ivre', 'runscansagentdb', '--list-scans'])
        scans = [scan.groupdict() for scan in scanmatch.finditer(out)]
        self.assertEqual(len(scans), 2)
        if all((is_scan_over(scan) for scan in scans)):
            break
        time.sleep(2)
    while any((walk[2] for dirname in ['tmp/input', 'tmp/cur', 'tmp/output', ivre.config.AGENT_MASTER_PATH] for walk in os.walk(dirname) if (not (walk[0].startswith(os.path.join(ivre.config.AGENT_MASTER_PATH, 'output', '')) or ((walk[0] == ivre.config.AGENT_MASTER_PATH) and (walk[2] == ['whoami'])))))):
        print(u'Waiting    for    runscans    daemon    &    agent')
        time.sleep(2)
    os.kill(pid_agent, signal.SIGTERM)
    os.kill(pid_daemon, signal.SIGTERM)
    os.waitpid(pid_agent, 0)
    os.waitpid(pid_daemon, 0)
    (res, out, _) = RUN(['ivre', 'scancli', '--count'])
    self.assertEqual(res, 0)
    self.assertEqual(int(out), 4)
    self.assertEqual(RUN(['ivre', 'scancli', '--init'], stdin=open(os.devnull))[0], 0)
    self.assertEqual(RUN(['ivre', 'runscansagentdb', '--init'], stdin=open(os.devnull))[0], 0)
