~npochet/landscape-charm/landscape-charm

« back to all changes in this revision

Viewing changes to hooks/test_hooks.py

  • Committer: David Britton
  • Date: 2014-06-20 22:04:25 UTC
  • mfrom: (143.2.17 stable)
  • mto: (143.2.22 stable)
  • mto: This revision was merged to the branch mainline in revision 199.
  • Revision ID: dpb@canonical.com-20140620220425-d06570b12htz7vi3
New upstream:
- added vhost-config relation to  configure apache2 (no more base64 blobs needed)
- support latest upstream fixes in landscape project
- Add trusty support to charm (pre-enablement)
- Fix async service timeout
- only install hash-id-database package if necessary

Show diffs side-by-side

added added

removed removed

Lines of Context:
3
3
import hooks
4
4
import mocker
5
5
import os
 
6
import psycopg2
6
7
import pycurl
7
8
import stat
8
9
import subprocess
 
10
import tempfile
9
11
import yaml
10
12
 
11
13
 
1481
1483
        hooks.notify_website_relation()
1482
1484
        baseline = (("services", yaml.safe_dump(self.all_services)),)
1483
1485
        self.assertEqual(baseline, hooks.juju._outgoing_relation_data)
 
1486
 
 
1487
    def test_notify_vhost_config_relation_specify_id(self):
 
1488
        """
 
1489
        notify the vhost-config relation on a separate ID.
 
1490
        """
 
1491
        hooks.notify_vhost_config_relation("foo/0")
 
1492
        with open("%s/config/vhostssl.tmpl" % hooks.ROOT, 'r') as f:
 
1493
            vhostssl_template = f.read()
 
1494
        with open("%s/config/vhost.tmpl" % hooks.ROOT, 'r') as f:
 
1495
            vhost_template = f.read()
 
1496
        baseline = yaml.dump(
 
1497
            [{"port": "443", "template": base64.b64encode(vhostssl_template)},
 
1498
             {"port": "80", "template": base64.b64encode(vhost_template)}])
 
1499
        self.assertEqual(
 
1500
            (("vhosts", baseline),), hooks.juju._outgoing_relation_data)
 
1501
 
 
1502
    def test_notify_vhost_config_relation(self):
 
1503
        """notify the vhost-config relation on the "current" ID."""
 
1504
        hooks.notify_vhost_config_relation()
 
1505
        with open("%s/config/vhostssl.tmpl" % hooks.ROOT, 'r') as f:
 
1506
            vhostssl_template = f.read()
 
1507
        with open("%s/config/vhost.tmpl" % hooks.ROOT, 'r') as f:
 
1508
            vhost_template = f.read()
 
1509
        baseline = yaml.dump(
 
1510
            [{"port": "443", "template": base64.b64encode(vhostssl_template)},
 
1511
             {"port": "80", "template": base64.b64encode(vhost_template)}])
 
1512
        self.assertEqual(
 
1513
            (("vhosts", baseline),), hooks.juju._outgoing_relation_data)
 
1514
 
 
1515
    def test_vhost_config_relation_changed_exit_no_configuration(self):
 
1516
        """Ensure vhost_relation_changed deferrs if db is not up."""
 
1517
        self.assertRaises(SystemExit, hooks.vhost_config_relation_changed)
 
1518
        self.assertEquals(len(hooks.juju._logs), 1)
 
1519
        self.assertIn('Database not ready yet', hooks.juju._logs[0])
 
1520
 
 
1521
    def test_vhost_config_relation_changed_wait_apache_servername(self):
 
1522
        """Ensure vhost_relation_changed deferrs if db is not up."""
 
1523
        _get_config_obj = self.mocker.replace(hooks._get_config_obj)
 
1524
        _get_config_obj(hooks.LANDSCAPE_SERVICE_CONF)
 
1525
        self.mocker.result({
 
1526
            "stores": {
 
1527
                "main": "database",
 
1528
                "host": "host",
 
1529
                "user": "user",
 
1530
                "password": "password"}})
 
1531
        notify_vhost = self.mocker.replace(hooks.notify_vhost_config_relation)
 
1532
        notify_vhost(None)
 
1533
        self.mocker.replay()
 
1534
        self.assertRaises(SystemExit, hooks.vhost_config_relation_changed)
 
1535
        self.assertIn('Waiting for data from apache', hooks.juju._logs[-1])
 
1536
 
 
1537
    def test_vhost_config_relation_changed_fail_root_url(self):
 
1538
        """Ensure vhost_relation_changed deferrs if db is not up."""
 
1539
        _get_config_obj = self.mocker.replace(hooks._get_config_obj)
 
1540
        _get_config_obj(hooks.LANDSCAPE_SERVICE_CONF)
 
1541
        hooks.juju._incoming_relation_data += (("servername", "foobar"),)
 
1542
        self.mocker.result({
 
1543
            "stores": {
 
1544
                "main": "database",
 
1545
                "host": "host",
 
1546
                "user": "user",
 
1547
                "password": "password"}})
 
1548
        notify_vhost = self.mocker.replace(hooks.notify_vhost_config_relation)
 
1549
        notify_vhost(None)
 
1550
        is_db_up = self.mocker.replace(hooks._is_db_up)
 
1551
        is_db_up()
 
1552
        self.mocker.result(False)
 
1553
        self.mocker.replay()
 
1554
        self.assertRaises(SystemExit, hooks.vhost_config_relation_changed)
 
1555
        self.assertIn(
 
1556
            'Waiting for database to become available, deferring',
 
1557
            hooks.juju._logs[-1])
 
1558
 
 
1559
    def test_vhost_config_relation_changed_fail_root_url_db_update(self):
 
1560
        """vhost_config_relation_changed should error if db update fails"""
 
1561
        _get_config_obj = self.mocker.replace(hooks._get_config_obj)
 
1562
        _get_config_obj(hooks.LANDSCAPE_SERVICE_CONF)
 
1563
        hooks.juju._incoming_relation_data += (("servername", "foobar"),)
 
1564
        self.mocker.result({
 
1565
            "stores": {
 
1566
                "main": "database",
 
1567
                "host": "host",
 
1568
                "user": "user",
 
1569
                "password": "password"}})
 
1570
        notify_vhost = self.mocker.replace(hooks.notify_vhost_config_relation)
 
1571
        notify_vhost(None)
 
1572
        is_db_up = self.mocker.replace(hooks._is_db_up)
 
1573
        is_db_up()
 
1574
        self.mocker.result(True)
 
1575
        self.mocker.replay()
 
1576
        self.assertRaises(psycopg2.Error, hooks.vhost_config_relation_changed)
 
1577
 
 
1578
    def test_vhost_config_relation_changed_cert_not_provided(self):
 
1579
        """
 
1580
        Ensure vhost_relation_changed runs to completion.
 
1581
 
 
1582
        Existing cert should be removed.
 
1583
        """
 
1584
        hooks.SSL_CERT_LOCATION = tempfile.NamedTemporaryFile().name
 
1585
        _get_config_obj = self.mocker.replace(hooks._get_config_obj)
 
1586
        _get_config_obj(hooks.LANDSCAPE_SERVICE_CONF)
 
1587
        hooks.juju._incoming_relation_data += (("servername", "foobar"),)
 
1588
        self.mocker.result({
 
1589
            "stores": {
 
1590
                "main": "database",
 
1591
                "host": "host",
 
1592
                "user": "user",
 
1593
                "password": "password"}})
 
1594
        notify_vhost = self.mocker.replace(hooks.notify_vhost_config_relation)
 
1595
        notify_vhost(None)
 
1596
        mock_conn = self.mocker.mock()
 
1597
        mock_conn.close()
 
1598
        connect_exclusive = self.mocker.replace(hooks.util.connect_exclusive)
 
1599
        connect_exclusive("host", "user", "password")
 
1600
        self.mocker.result(mock_conn)
 
1601
        change_root_url = self.mocker.replace(hooks.util.change_root_url)
 
1602
        change_root_url(
 
1603
            "database", "user", "password", "host", "https://foobar/")
 
1604
        config_changed = self.mocker.replace(hooks.config_changed)
 
1605
        config_changed()
 
1606
        is_db_up = self.mocker.replace(hooks._is_db_up)
 
1607
        is_db_up()
 
1608
        self.mocker.result(True)
 
1609
        self.mocker.replay()
 
1610
        hooks.vhost_config_relation_changed()
 
1611
        self.assertFalse(os.path.exists(hooks.SSL_CERT_LOCATION))
 
1612
 
 
1613
    def test_vhost_config_relation_changed_ssl_cert_provided(self):
 
1614
        """
 
1615
        Ensure vhost_relation_changed runs to completion.
 
1616
 
 
1617
        Cert passed in to other side of relation should be written on disk.
 
1618
        """
 
1619
        hooks.SSL_CERT_LOCATION = tempfile.NamedTemporaryFile().name
 
1620
        _get_config_obj = self.mocker.replace(hooks._get_config_obj)
 
1621
        _get_config_obj(hooks.LANDSCAPE_SERVICE_CONF)
 
1622
        hooks.juju._incoming_relation_data += (("servername", "foobar"),)
 
1623
        hooks.juju._incoming_relation_data += (
 
1624
            ("ssl_cert", base64.b64encode("foobar")),)
 
1625
        self.mocker.result({
 
1626
            "stores": {
 
1627
                "main": "database",
 
1628
                "host": "host",
 
1629
                "user": "user",
 
1630
                "password": "password"}})
 
1631
        notify_vhost = self.mocker.replace(hooks.notify_vhost_config_relation)
 
1632
        notify_vhost(None)
 
1633
        is_db_up = self.mocker.replace(hooks._is_db_up)
 
1634
        is_db_up()
 
1635
        self.mocker.result(True)
 
1636
        mock_conn = self.mocker.mock()
 
1637
        mock_conn.close()
 
1638
        connect_exclusive = self.mocker.replace(hooks.util.connect_exclusive)
 
1639
        connect_exclusive("host", "user", "password")
 
1640
        self.mocker.result(mock_conn)
 
1641
        change_root_url = self.mocker.replace(hooks.util.change_root_url)
 
1642
        change_root_url(
 
1643
            "database", "user", "password", "host", "https://foobar/")
 
1644
        config_changed = self.mocker.replace(hooks.config_changed)
 
1645
        config_changed()
 
1646
        self.mocker.replay()
 
1647
        hooks.vhost_config_relation_changed()
 
1648
        self.assertTrue(os.path.exists(hooks.SSL_CERT_LOCATION))
 
1649
        with open(hooks.SSL_CERT_LOCATION, 'r') as f:
 
1650
            self.assertEqual("foobar", f.read())
 
1651
 
 
1652
 
 
1653
class TestHooksUtils(TestHooks):
 
1654
    def test__setup_apache(self):
 
1655
        """
 
1656
        Responsible for setting up apache to serve static content.
 
1657
        - various 'a2*' commands need to be mocked and tested to ensure
 
1658
          proper parameters are passed.
 
1659
        - make sure we actually replace '@hostname@' with 'localhost' in the
 
1660
          site file we are installing.
 
1661
        - ensure new file has '.conf' extension.
 
1662
        """
 
1663
        tempdir = self.makeDir()
 
1664
        with open("%s/default.random_extension" % tempdir, 'w') as f:
 
1665
            f.write("HI!")
 
1666
        with open("%s/default2.conf" % tempdir, 'w') as f:
 
1667
            f.write("HI!")
 
1668
        # Replace dir, but leave basename to check that it has '.conf'
 
1669
        # (new requirement with Trusty apache2)
 
1670
        site_file = os.path.basename(hooks.LANDSCAPE_APACHE_SITE)
 
1671
        hooks.LANDSCAPE_APACHE_SITE = "%s/%s" % (tempdir, site_file)
 
1672
        _a2enmods = self.mocker.replace(hooks._a2enmods)
 
1673
        _a2dissite = self.mocker.replace(hooks._a2dissite)
 
1674
        _a2ensite = self.mocker.replace(hooks._a2ensite)
 
1675
        _service = self.mocker.replace(hooks._service)
 
1676
        _a2enmods(["rewrite", "proxy_http", "ssl", "headers", "expires"])
 
1677
        _a2dissite("default.random_extension")
 
1678
        _a2dissite("default2.conf")
 
1679
        _a2ensite("landscape.conf")
 
1680
        _service("apache2", "restart")
 
1681
        self.mocker.replay()
 
1682
        hooks._setup_apache()
 
1683
        self.assertTrue(os.path.exists("%s/landscape.conf" % tempdir))
 
1684
        with open("%s/landscape.conf" % tempdir, 'r') as f:
 
1685
            site_text = f.read()
 
1686
        self.assertFalse("@hostname@" in site_text)
 
1687
        self.assertTrue("localhost" in site_text)