~ubuntu-branches/ubuntu/raring/maas/raring-proposed

« back to all changes in this revision

Viewing changes to src/provisioningserver/tests/test_config.py

  • Committer: Package Import Robot
  • Author(s): Andres Rodriguez
  • Date: 2012-07-17 08:28:36 UTC
  • mfrom: (1.1.16)
  • Revision ID: package-import@ubuntu.com-20120717082836-ucb2vou8tqg353eq
Tags: 0.1+bzr777+dfsg-0ubuntu1
* New upstream release
* Only run 'maas' command as root. (LP: #974046)
  - debian/extras/maas: Check id.
  - debian/maas.install: Install in 'sbin'.
* debian/maas.postinst:
  - restart apache2 after everything gets processed.
  - Update version to handle upgrades.
* debian/extras/maas-provision: Add wrapper to access 'maasprovisiong'
  command line.
* debian/patches/99_temporary_fix_path.patch: Dropped. No longer needed.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright 2005-2012 Canonical Ltd.  This software is licensed under the
 
2
# GNU Affero General Public License version 3 (see the file LICENSE).
 
3
 
 
4
"""Tests for provisioning configuration."""
 
5
 
 
6
from __future__ import (
 
7
    absolute_import,
 
8
    print_function,
 
9
    unicode_literals,
 
10
    )
 
11
 
 
12
__metaclass__ = type
 
13
__all__ = []
 
14
 
 
15
from functools import partial
 
16
from getpass import getuser
 
17
import os
 
18
from textwrap import dedent
 
19
 
 
20
from fixtures import EnvironmentVariableFixture
 
21
import formencode
 
22
from maastesting.factory import factory
 
23
from maastesting.testcase import TestCase
 
24
from provisioningserver.config import Config
 
25
from provisioningserver.testing.config import ConfigFixture
 
26
from testtools.matchers import (
 
27
    DirExists,
 
28
    FileExists,
 
29
    MatchesException,
 
30
    Raises,
 
31
    )
 
32
import yaml
 
33
 
 
34
 
 
35
class TestConfigFixture(TestCase):
 
36
    """Tests for `provisioningserver.testing.config.ConfigFixture`."""
 
37
 
 
38
    def exercise_fixture(self, fixture):
 
39
        # ConfigFixture arranges a minimal configuration on disk, and exports
 
40
        # the configuration filename to the environment so that subprocesses
 
41
        # can find it.
 
42
        with fixture:
 
43
            self.assertThat(fixture.dir, DirExists())
 
44
            self.assertThat(fixture.filename, FileExists())
 
45
            self.assertEqual(
 
46
                {"MAAS_PROVISIONING_SETTINGS": fixture.filename},
 
47
                fixture.environ)
 
48
            self.assertEqual(
 
49
                fixture.filename, os.environ["MAAS_PROVISIONING_SETTINGS"])
 
50
            with open(fixture.filename, "rb") as stream:
 
51
                self.assertEqual(fixture.config, yaml.safe_load(stream))
 
52
 
 
53
    def test_use_minimal(self):
 
54
        # With no arguments, ConfigFixture arranges a minimal configuration.
 
55
        fixture = ConfigFixture()
 
56
        self.exercise_fixture(fixture)
 
57
 
 
58
    def test_use_with_config(self):
 
59
        # Given a configuration, ConfigFixture can arrange a minimal global
 
60
        # configuration with the additional options merged in.
 
61
        dummy_logfile = factory.make_name("logfile")
 
62
        fixture = ConfigFixture({"logfile": dummy_logfile})
 
63
        self.assertEqual(dummy_logfile, fixture.config["logfile"])
 
64
        self.exercise_fixture(fixture)
 
65
 
 
66
 
 
67
class TestConfig_DEFAULT_FILENAME(TestCase):
 
68
    """Tests for `provisioningserver.config.Config.DEFAULT_FILENAME`."""
 
69
 
 
70
    def setUp(self):
 
71
        super(TestConfig_DEFAULT_FILENAME, self).setUp()
 
72
        # Start with a clean environment every time.
 
73
        fixture = EnvironmentVariableFixture("MAAS_PROVISIONING_SETTINGS")
 
74
        self.useFixture(fixture)
 
75
 
 
76
    def test_get_with_environment_empty(self):
 
77
        self.assertEqual("/etc/maas/pserv.yaml", Config.DEFAULT_FILENAME)
 
78
 
 
79
    def test_get_with_environment_set(self):
 
80
        dummy_filename = factory.make_name("config")
 
81
        fixture = EnvironmentVariableFixture(
 
82
            "MAAS_PROVISIONING_SETTINGS", dummy_filename)
 
83
        self.useFixture(fixture)
 
84
        self.assertEqual(dummy_filename, Config.DEFAULT_FILENAME)
 
85
 
 
86
    def test_set(self):
 
87
        dummy_filename = factory.make_name("config")
 
88
        Config.DEFAULT_FILENAME = dummy_filename
 
89
        self.assertEqual(dummy_filename, Config.DEFAULT_FILENAME)
 
90
 
 
91
    def test_delete(self):
 
92
        Config.DEFAULT_FILENAME = factory.make_name("config")
 
93
        del Config.DEFAULT_FILENAME
 
94
        # The filename reverts; see test_get_with_environment_empty.
 
95
        self.assertEqual("/etc/maas/pserv.yaml", Config.DEFAULT_FILENAME)
 
96
        # The delete does not fail when called multiple times.
 
97
        del Config.DEFAULT_FILENAME
 
98
 
 
99
 
 
100
class TestConfig(TestCase):
 
101
    """Tests for `provisioningserver.config.Config`."""
 
102
 
 
103
    def test_defaults(self):
 
104
        dummy_password = factory.make_name("password")
 
105
        expected = {
 
106
            'broker': {
 
107
                'host': 'localhost',
 
108
                'port': 5673,
 
109
                'username': getuser(),
 
110
                'password': 'test',
 
111
                'vhost': '/',
 
112
                },
 
113
            'cobbler': {
 
114
                'url': 'http://localhost/cobbler_api',
 
115
                'username': getuser(),
 
116
                'password': 'test',
 
117
                },
 
118
            'logfile': 'pserv.log',
 
119
            'oops': {
 
120
                'directory': '',
 
121
                'reporter': '',
 
122
                },
 
123
            'tftp': {
 
124
                'generator': 'http://localhost:5243/api/1.0/pxeconfig',
 
125
                'port': 5244,
 
126
                'root': "/var/lib/tftpboot",
 
127
                },
 
128
            'interface': '127.0.0.1',
 
129
            'port': 5241,
 
130
            'username': getuser(),
 
131
            'password': dummy_password,
 
132
            }
 
133
        # The password field is set to a random 12-digit string if not
 
134
        # specified. This prevents access, but makes testing easier in other
 
135
        # parts.
 
136
        self.patch(Config.field("password"), "if_missing", dummy_password)
 
137
        observed = Config.to_python({})
 
138
        self.assertEqual(expected, observed)
 
139
 
 
140
    def test_parse(self):
 
141
        # Configuration can be parsed from a snippet of YAML.
 
142
        observed = Config.parse(
 
143
            b'logfile: "/some/where.log"\n'
 
144
            b'password: "black_sabbath"\n'
 
145
            )
 
146
        self.assertEqual("/some/where.log", observed["logfile"])
 
147
 
 
148
    def test_load(self):
 
149
        # Configuration can be loaded and parsed from a file.
 
150
        config = dedent("""
 
151
            logfile: "/some/where.log"
 
152
            """)
 
153
        filename = self.make_file(name="config.yaml", contents=config)
 
154
        observed = Config.load(filename)
 
155
        self.assertEqual("/some/where.log", observed["logfile"])
 
156
 
 
157
    def test_load_example(self):
 
158
        # The example configuration can be loaded and validated.
 
159
        filename = os.path.join(
 
160
            os.path.dirname(__file__), os.pardir,
 
161
            os.pardir, os.pardir, "etc", "pserv.yaml")
 
162
        Config.load(filename)
 
163
 
 
164
    def test_load_from_cache(self):
 
165
        # A config loaded by Config.load_from_cache() is never reloaded.
 
166
        filename = self.make_file(name="config.yaml", contents='')
 
167
        config_before = Config.load_from_cache(filename)
 
168
        os.unlink(filename)
 
169
        config_after = Config.load_from_cache(filename)
 
170
        self.assertIs(config_before, config_after)
 
171
 
 
172
    def test_oops_directory_without_reporter(self):
 
173
        # It is an error to omit the OOPS reporter if directory is specified.
 
174
        config = (
 
175
            'oops:\n'
 
176
            '  directory: /tmp/oops\n'
 
177
            )
 
178
        expected = MatchesException(
 
179
            formencode.Invalid, "oops: You must give a value for reporter")
 
180
        self.assertThat(
 
181
            partial(Config.parse, config),
 
182
            Raises(expected))
 
183
 
 
184
    def test_field(self):
 
185
        self.assertIs(Config, Config.field())
 
186
        self.assertIs(Config.fields["tftp"], Config.field("tftp"))
 
187
        self.assertIs(
 
188
            Config.fields["tftp"].fields["root"],
 
189
            Config.field("tftp", "root"))