import pytest
import json

def test_contrail_compute_status(local_salt_client):
    probe = local_salt_client.cmd(
        'opencontrail:control', 'cmd.run',
        ['contrail-status | grep -Pv \'(==|^$|Disk|unix|support)\''],
        expr_form='pillar'
    )
    if not probe:
        pytest.skip("Contrail is not found on this environment")

    cs = local_salt_client.cmd(
        'nova:compute', 'cmd.run',
        ['contrail-status | grep -Pv \'(==|^$)\''],
        expr_form='pillar'
    )
    broken_services = []

    for node in cs:
        for line in cs[node].split('\n'):
            line = line.strip()
            name, status = line.split(None, 1)
            if status not in {'active'}:
                err_msg = "{node}:{service} - {status}".format(
                    node=node, service=name, status=status)
                broken_services.append(err_msg)

    assert not broken_services, 'Broken services: {}'.format(json.dumps(
                                                             broken_services,
                                                             indent=4))


def test_contrail_node_status(local_salt_client):
    cs = local_salt_client.cmd(
        'opencontrail:client:analytics_node', 'cmd.run',
        ['contrail-status | grep -Pv \'(==|^$|Disk|unix|support)\''],
        expr_form='pillar'
    )
    cs.update(local_salt_client.cmd(
        'opencontrail:control', 'cmd.run',
        ['contrail-status | grep -Pv \'(==|^$|Disk|unix|support)\''],
        expr_form='pillar')
    )
    if not cs:
        pytest.skip("Contrail is not found on this environment")
    broken_services = []
    for node in cs:
        for line in cs[node].split('\n'):
            line = line.strip()
            if 'crashes/core.java.' not in line:
                name, status = line.split(None, 1)
            else:
                name, status = line,'FATAL'
            if status not in {'active', 'backup'}:
                err_msg = "{node}:{service} - {status}".format(
                    node=node, service=name, status=status)
                broken_services.append(err_msg)

    assert not broken_services, 'Broken services: {}'.format(json.dumps(
                                                             broken_services,
                                                             indent=4))


def test_contrail_vrouter_count(local_salt_client):
    probe = local_salt_client.cmd(
        'opencontrail:control', 'cmd.run',
        ['contrail-status | grep -Pv \'(==|^$|Disk|unix|support)\''],
        expr_form='pillar'
    )
    if not probe:
        pytest.skip("Contrail is not found on this environment")
    cs = local_salt_client.cmd(
        'nova:compute', 'cmd.run', ['contrail-status | grep -Pv \'(==|^$)\''],
        expr_form='pillar'
    )
    # TODO: what if compute lacks these service unintentionally?
    if not cs:
        pytest.skip("Contrail services were not found on compute nodes")

    actual_vrouter_count = 0
    for node in cs:
        for line in cs[node].split('\n'):
            if 'contrail-vrouter-nodemgr' in line:
                actual_vrouter_count += 1

    assert actual_vrouter_count == len(cs.keys()),\
        'The length of vRouters {} differs' \
        ' from the length of compute nodes {}'.format(actual_vrouter_count,
                                                      len(cs.keys()))
