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

"""
Tests for movement of data across nodes.
"""
from time import sleep
from yaml import safe_dump

from pexpect import spawn

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

from .utils import (flocker_deploy, get_nodes, require_flocker_cli,
                    require_mongo)


class MovingDataTests(TestCase):
    """
    Tests for movement of data across nodes.

    Similar to:
    http://doc-dev.clusterhq.com/gettingstarted/tutorial/volumes.html
    """
    @require_mongo
    @require_flocker_cli
    def test_moving_data(self):
        """
        Moving an application moves that application's data with it.

        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.
        """
        d = get_nodes(num_nodes=2)

        def deploy_data_application(node_ips):
            node_1, node_2 = node_ips

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

            application = u"mongodb-volume-example"

            application_config = temp.child(b"volume-application.yml")
            application_config.setContent(safe_dump({
                u"version": 1,
                u"applications": {
                    application: {
                        u"image": u"clusterhq/mongodb",
                        u"ports": [{
                            u"internal": 27017,
                            u"external": 27017,
                        }],
                        u"volume": {
                            # The location within the container where the data
                            # volume will be mounted:
                            u"mountpoint": u"/data/db"
                        }
                    },
                },
            }))

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

            flocker_deploy(deployment_config, application_config)

            # There is a race condition here.
            # The tutorial says "If you get a connection refused error try
            # again after a few seconds; the application might take some time
            # to fully start up.".
            sleep(5)
            child_1 = spawn('mongo ' + node_1)
            child_1.expect('MongoDB shell version:.*')
            child_1.sendline('use example;')
            child_1.expect('switched to db example')
            child_1.sendline('db.records.insert({"the data": "it moves"})')

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

            flocker_deploy(deployment_moved_config, application_config)<commit_msg>Moved test boilerplate out of test_moving_data<commit_after># Copyright Hybrid Logic Ltd.  See LICENSE file for details.

"""
Tests for movement of data across nodes.
"""
from time import sleep

from pexpect import spawn

from twisted.trial.unittest import TestCase

from .utils import (flocker_deploy, get_nodes, require_flocker_cli,
                    require_mongo)


class MovingDataTests(TestCase):
    """
    Tests for movement of data across nodes.

    Similar to:
    http://doc-dev.clusterhq.com/gettingstarted/tutorial/volumes.html
    """
    @require_mongo
    @require_flocker_cli
    def test_moving_data(self):
        """
        Moving an application moves that application's data with it.

        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.
        """
        d = get_nodes(num_nodes=2)

        def deploy_data_application(node_ips):
            node_1, node_2 = node_ips

            application = u"mongodb-volume-example"

            application_config = {
                u"version": 1,
                u"applications": {
                    application: {
                        u"image": u"clusterhq/mongodb",
                        u"ports": [{
                            u"internal": 27017,
                            u"external": 27017,
                        }],
                        u"volume": {
                            # The location within the container where the data
                            # volume will be mounted:
                            u"mountpoint": u"/data/db"
                        }
                    },
                },
            }

            deployment_config = {
                u"version": 1,
                u"nodes": {
                    node_1: [application],
                    node_2: [],
                },
            }

            flocker_deploy(self, deployment_config, application_config)

            # There is a race condition here.
            # The tutorial says "If you get a connection refused error try
            # again after a few seconds; the application might take some time
            # to fully start up.".
            sleep(5)
            child_1 = spawn('mongo ' + node_1)
            child_1.expect('MongoDB shell version:.*')
            child_1.sendline('use example;')
            child_1.expect('switched to db example')
            child_1.sendline('db.records.insert({"the data": "it moves"})')

            deployment_moved_config = {
                u"version": 1,
                u"nodes": {
                    node_1: [],
                    node_2: [application],
                },
            }

            flocker_deploy(self, deployment_moved_config, application_config)
{'fraction_non_alphanumeric': 0.08300653594771241, 'fraction_numerical': 0.008823529411764706, 'mean_word_length': 1.4942950285248573, 'pattern_counts': {'":': 26, '<': 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': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4808485', 'n_tokens_mistral': 1631, 'n_tokens_neox': 1506, 'n_words': 418}