<commit_before># Copyright Hybrid Logic Ltd.  See LICENSE file for details.

"""
Tests for communication to applications.
"""
from yaml import safe_dump

from pexpect import spawn

from twisted.python.filepath import FilePath
from twisted.trial.unittest import TestCase

from flocker.node._docker import Unit, PortMap

from .utils import running_units, require_installed, get_nodes, flocker_deploy


class PortsTests(TestCase):
    """
    Tests for communication to applications.

    Similar to http://doc-dev.clusterhq.com/gettingstarted/tutorial/
    exposing-ports.html
    """
    @require_installed
    def setUp(self):
        """
        Deploy an application with an exposed port.
        """
        self.node_1, self.node_2 = get_nodes(num_nodes=2)

        temp = FilePath(self.mktemp())
        temp.makedirs()

        self.internal_port = 27017
        self.external_port = 27017

        self.application = u"mongodb-port-example"
        self.image = u"clusterhq/mongodb"

        application_config = temp.child(b"application.yml")
        application_config.setContent(safe_dump({
            u"version": 1,
            u"applications": {
                self.application: {
                    u"image": self.image,
                    u"ports": [{
                        u"internal": self.internal_port,
                        u"external": self.external_port,
                    }],
                },
            },
        }))

        deployment_config = temp.child(b"deployment.yml")
        deployment_config.setContent(safe_dump({
            u"version": 1,
            u"nodes": {
                self.node_1: [self.application],
                self.node_2: [],
            },
        }))

        flocker_deploy(deployment_config, application_config)

    def test_deployment_with_ports(self):
        """
        Ports are exposed.
        """
        unit = Unit(name=u'/' + self.application,
                    container_name=u'/' + self.application,
                    activation_state=u'active',
                    container_image=self.image + u':latest',
                    ports=frozenset([
                        PortMap(internal_port=self.internal_port,
                                external_port=self.external_port)
                    ]),
                    environment=None, volumes=())

        self.assertEqual(
            [running_units(self.node_1), running_units(self.node_2)],
            [set([unit]), set()]
        )

    def test_traffic_routed(self):
        """
        An application can be accessed even from a connection to a node
        which it is not running on.

        Instead of pexpect this could use PyMongo, which would mean that the
        mongo client would not have to be installed. However, this uses
        pexpect to be as close as possible to the tutorial.
        """<commit_msg>Require the mongo shell for one test<commit_after># Copyright Hybrid Logic Ltd.  See LICENSE file for details.

"""
Tests for communication to applications.
"""
from unittest import skipUnless
from yaml import safe_dump

from pexpect import spawn

from twisted.python.filepath import FilePath
from twisted.python.procutils import which
from twisted.trial.unittest import TestCase

from flocker.node._docker import Unit, PortMap

from .utils import running_units, require_installed, get_nodes, flocker_deploy


require_mongo = skipUnless(which("mongo"),
                           "The mongo shell is not available.")

class PortsTests(TestCase):
    """
    Tests for communication to applications.

    Similar to http://doc-dev.clusterhq.com/gettingstarted/tutorial/
    exposing-ports.html
    """
    @require_installed
    def setUp(self):
        """
        Deploy an application with an exposed port.
        """
        self.node_1, self.node_2 = get_nodes(num_nodes=2)

        temp = FilePath(self.mktemp())
        temp.makedirs()

        self.internal_port = 27017
        self.external_port = 27017

        self.application = u"mongodb-port-example"
        self.image = u"clusterhq/mongodb"

        application_config = temp.child(b"application.yml")
        application_config.setContent(safe_dump({
            u"version": 1,
            u"applications": {
                self.application: {
                    u"image": self.image,
                    u"ports": [{
                        u"internal": self.internal_port,
                        u"external": self.external_port,
                    }],
                },
            },
        }))

        deployment_config = temp.child(b"deployment.yml")
        deployment_config.setContent(safe_dump({
            u"version": 1,
            u"nodes": {
                self.node_1: [self.application],
                self.node_2: [],
            },
        }))

        flocker_deploy(deployment_config, application_config)

    def test_deployment_with_ports(self):
        """
        Ports are exposed.
        """
        unit = Unit(name=u'/' + self.application,
                    container_name=u'/' + self.application,
                    activation_state=u'active',
                    container_image=self.image + u':latest',
                    ports=frozenset([
                        PortMap(internal_port=self.internal_port,
                                external_port=self.external_port)
                    ]),
                    environment=None, volumes=())

        self.assertEqual(
            [running_units(self.node_1), running_units(self.node_2)],
            [set([unit]), set()]
        )

    @require_mongo
    def test_traffic_routed(self):
        """
        An application can be accessed even from a connection to a node
        which it is not running on.

        Instead of pexpect this could use PyMongo, which would mean that the
        mongo client would not have to be installed. However, this uses
        pexpect to be as close as possible to the tutorial.
        """
{'fraction_non_alphanumeric': 0.09250879839115134, 'fraction_numerical': 0.00636835930953578, 'mean_word_length': 1.8637236084452975, 'pattern_counts': {'":': 16, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5427678', 'n_tokens_mistral': 1663, 'n_tokens_neox': 1547, 'n_words': 381}